| // Copyright 2017 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <fidl/test/handles/cpp/fidl.h> |
| #include <lib/fidl/cpp/message.h> |
| #include <lib/zx/channel.h> |
| #include <lib/zx/event.h> |
| |
| #include <zxtest/zxtest.h> |
| |
| namespace { |
| |
| TEST(Message, BasicTests) { |
| uint8_t byte_buffer[ZX_CHANNEL_MAX_MSG_BYTES]; |
| zx_handle_info_t handle_info_buffer[ZX_CHANNEL_MAX_MSG_HANDLES]; |
| zx_handle_disposition_t handle_disposition_buffer[ZX_CHANNEL_MAX_MSG_HANDLES]; |
| |
| fidl_message_header_t header = { |
| .txid = 5u, |
| .ordinal = 42u, |
| }; |
| char data[4] = "abc"; |
| fidl_string_t str = { |
| .size = 3, |
| .data = data, |
| }; |
| memcpy(byte_buffer, &header, sizeof(header)); |
| memcpy(byte_buffer + sizeof(header), &str, sizeof(str)); |
| memcpy(byte_buffer + sizeof(header) + sizeof(str), data, 3); |
| memset(byte_buffer + sizeof(header) + sizeof(str), 0, 5); |
| |
| fidl::HLCPPOutgoingMessage outgoing_message( |
| fidl::BytePart(byte_buffer, ZX_CHANNEL_MAX_MSG_BYTES, sizeof(header) + sizeof(str) + 8), |
| fidl::HandleDispositionPart(handle_disposition_buffer, ZX_CHANNEL_MAX_MSG_HANDLES)); |
| |
| EXPECT_EQ(outgoing_message.txid(), 5u); |
| EXPECT_EQ(outgoing_message.ordinal(), 42u); |
| |
| fidl::BytePart payload = fidl::BytePart(outgoing_message.body_view().bytes(), 0); |
| fidl_string_t* payload_str = reinterpret_cast<fidl_string_t*>(payload.data()); |
| EXPECT_EQ(3, payload_str->size); |
| EXPECT_STREQ("abc", payload_str->data); |
| |
| zx::channel h1, h2; |
| EXPECT_EQ(zx::channel::create(0, &h1, &h2), ZX_OK); |
| |
| ASSERT_EQ(ZX_OK, outgoing_message.Write(h1.get(), 0u)); |
| |
| memset(byte_buffer, 0, ZX_CHANNEL_MAX_MSG_BYTES); |
| |
| EXPECT_EQ(outgoing_message.txid(), 0u); |
| EXPECT_EQ(outgoing_message.ordinal(), 0u); |
| |
| fidl::HLCPPIncomingMessage incoming_message( |
| fidl::BytePart(byte_buffer, ZX_CHANNEL_MAX_MSG_BYTES), |
| fidl::HandleInfoPart(handle_info_buffer, ZX_CHANNEL_MAX_MSG_HANDLES)); |
| ASSERT_EQ(ZX_OK, incoming_message.Read(h2.get(), 0u)); |
| |
| EXPECT_EQ(incoming_message.txid(), 5u); |
| EXPECT_EQ(incoming_message.ordinal(), 42u); |
| } |
| |
| TEST(Message, ReadErrorCodes) { |
| // Create a Message buffer. |
| constexpr size_t kBufferSize = 100; |
| uint8_t byte_buffer[kBufferSize]; |
| fidl::HLCPPIncomingMessage message(fidl::BytePart::WrapEmpty(byte_buffer), |
| fidl::HandleInfoPart()); |
| |
| // Create a channel. |
| zx::channel client, server; |
| EXPECT_OK(zx::channel::create(0, &client, &server)); |
| |
| // Read from an empty channel. |
| EXPECT_EQ(message.Read(client.get(), /*flags=*/0), ZX_ERR_SHOULD_WAIT); |
| |
| // Read with invalid flags. |
| EXPECT_EQ(message.Read(client.get(), /*flags=*/~0), ZX_ERR_NOT_SUPPORTED); |
| |
| // Read a message smaller than the FIDL header size. |
| { |
| uint8_t write_buffer[1] = {0}; |
| EXPECT_OK( |
| server.write(/*flags=*/0, &write_buffer, sizeof(write_buffer), /*handles=*/nullptr, 0)); |
| EXPECT_EQ(message.Read(client.get(), /*flags=*/0), ZX_ERR_INVALID_ARGS); |
| } |
| |
| // Read a message larger than our receive buffer. |
| { |
| uint8_t write_buffer[kBufferSize + 1]; |
| memset(write_buffer, 0xff, sizeof(write_buffer)); |
| EXPECT_OK( |
| server.write(/*flags=*/0, &write_buffer, sizeof(write_buffer), /*handles=*/nullptr, 0)); |
| EXPECT_EQ(message.Read(client.get(), /*flags=*/ZX_CHANNEL_READ_MAY_DISCARD), |
| ZX_ERR_BUFFER_TOO_SMALL); |
| } |
| |
| // Read from closed channel. |
| server.reset(); |
| EXPECT_EQ(message.Read(client.get(), /*flags=*/0), ZX_ERR_PEER_CLOSED); |
| } |
| |
| TEST(MessagePart, IsStlContainerTest) { |
| EXPECT_EQ(sizeof(uint8_t), sizeof(fidl::BytePart::value_type)); |
| EXPECT_EQ(sizeof(zx_handle_t), sizeof(fidl::HandlePart::value_type)); |
| |
| EXPECT_EQ(sizeof(const uint8_t*), sizeof(fidl::BytePart::const_iterator)); |
| EXPECT_EQ(sizeof(const zx_handle_t*), sizeof(fidl::HandlePart::const_iterator)); |
| } |
| |
| TEST(MessagePart, Size) { |
| fidl::HLCPPOutgoingMessage message; |
| |
| EXPECT_EQ(message.bytes().size(), 0u); |
| |
| uint8_t dummy_msg[42]; |
| fidl::MessagePart msg(dummy_msg, 42, 10); |
| |
| EXPECT_EQ(msg.size(), 10u); |
| |
| fidl::MessagePart new_msg = std::move(msg); |
| |
| EXPECT_EQ(new_msg.size(), 10u); |
| EXPECT_EQ(msg.size(), 0u); |
| } |
| |
| TEST(MessagePart, WrapArray) { |
| uint8_t dummy[42]; |
| |
| auto full = fidl::MessagePart<uint8_t>::WrapFull(dummy); |
| EXPECT_EQ(full.data(), dummy); |
| EXPECT_EQ(full.actual(), 42); |
| EXPECT_EQ(full.capacity(), 42); |
| |
| auto empty = fidl::MessagePart<uint8_t>::WrapEmpty(dummy); |
| EXPECT_EQ(empty.data(), dummy); |
| EXPECT_EQ(empty.actual(), 0); |
| EXPECT_EQ(empty.capacity(), 42); |
| } |
| |
| } // namespace |