blob: 6cdba01751a91169096a9bd65927691a7b165531 [file] [log] [blame]
// Copyright 2022 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.driver.coding/cpp/driver/fidl.h>
#include <lib/fdf/cpp/channel.h>
#include <lib/zx/channel.h>
#include <utility>
#include <vector>
#include <zxtest/zxtest.h>
// TODO(https://fxbug.dev/42181666): These are manual tests for driver endpoints and
// encoding over the driver transport. We should support them in GIDL.
namespace {
const std::vector<uint8_t> kGoldenBytes = {
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // table vector count
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // presence
0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x01, 0x00, // inlined handle 1
0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x01, 0x00, // inlined handle 2
0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x01, 0x00, // inlined handle 3
0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x01, 0x00, // inlined handle 4
0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x01, 0x00, // inlined handle 5
0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x01, 0x00, // inlined handle 6
};
TEST(StandaloneResourceTypeCoding, Encode) {
// Set up an object.
zx::channel zircon_handle_1, zircon_handle_2;
ASSERT_OK(zx::channel::create(0, &zircon_handle_1, &zircon_handle_2));
zx::result driver_handles = fdf::ChannelPair::Create(0);
ASSERT_OK(driver_handles.status_value());
zx::result zircon_endpoints = fidl::CreateEndpoints<test_driver_coding::ZirconChannelProtocol>();
ASSERT_OK(zircon_endpoints.status_value());
zx::result driver_endpoints = fdf::CreateEndpoints<test_driver_coding::DriverChannelProtocol>();
ASSERT_OK(driver_endpoints.status_value());
zx_handle_t expected_zircon_handle = zircon_handle_1.get();
fdf_handle_t expected_driver_handle = driver_handles->end0.get();
zx_handle_t expected_zircon_client_end = zircon_endpoints->client.handle()->get();
zx_handle_t expected_zircon_server_end = zircon_endpoints->server.handle()->get();
fdf_handle_t expected_driver_client_end = driver_endpoints->client.handle()->get();
fdf_handle_t expected_driver_server_end = driver_endpoints->server.handle()->get();
test_driver_coding::MixedResources obj{{
.zircon_handle = std::move(zircon_handle_1),
.driver_handle = std::move(driver_handles->end0),
.zircon_client_end = std::move(zircon_endpoints->client),
.zircon_server_end = std::move(zircon_endpoints->server),
.driver_client_end = std::move(driver_endpoints->client),
.driver_server_end = std::move(driver_endpoints->server),
}};
// Perform encoding.
fidl::OwnedEncodeResult encoded =
fidl::internal::EncodeWithTransport<fidl::internal::DriverTransport>(std::move(obj));
ASSERT_TRUE(encoded.message().ok(), "Error encoding: %s",
encoded.message().error().FormatDescription().c_str());
fidl::WireFormatMetadata metadata = encoded.wire_format_metadata();
EXPECT_TRUE(metadata.is_valid());
EXPECT_EQ(fidl::internal::WireFormatVersion::kV2, metadata.wire_format_version());
fidl::OutgoingMessage::CopiedBytes bytes = encoded.message().CopyBytes();
EXPECT_EQ(kGoldenBytes.size(), bytes.size());
EXPECT_BYTES_EQ(kGoldenBytes.data(), bytes.data(), kGoldenBytes.size());
const fidl_handle_t* handles = encoded.message().handles();
EXPECT_EQ(expected_zircon_handle, handles[0]);
EXPECT_EQ(expected_driver_handle, handles[1]);
EXPECT_EQ(expected_zircon_client_end, handles[2]);
EXPECT_EQ(expected_zircon_server_end, handles[3]);
EXPECT_EQ(expected_driver_client_end, handles[4]);
EXPECT_EQ(expected_driver_server_end, handles[5]);
}
TEST(StandaloneResourceTypeCoding, Decode) {
// Set up some handles.
zx::channel zircon_handle_1, zircon_handle_2;
ASSERT_OK(zx::channel::create(0, &zircon_handle_1, &zircon_handle_2));
zx::result driver_handles = fdf::ChannelPair::Create(0);
ASSERT_OK(driver_handles.status_value());
zx::result zircon_endpoints = fidl::CreateEndpoints<test_driver_coding::ZirconChannelProtocol>();
ASSERT_OK(zircon_endpoints.status_value());
zx::result driver_endpoints = fdf::CreateEndpoints<test_driver_coding::DriverChannelProtocol>();
ASSERT_OK(driver_endpoints.status_value());
zx_handle_t expected_zircon_handle = zircon_handle_1.release();
fdf_handle_t expected_driver_handle = driver_handles->end0.release();
zx_handle_t expected_zircon_client_end = zircon_endpoints->client.TakeHandle().release();
zx_handle_t expected_zircon_server_end = zircon_endpoints->server.TakeHandle().release();
fdf_handle_t expected_driver_client_end = driver_endpoints->client.TakeHandle().release();
fdf_handle_t expected_driver_server_end = driver_endpoints->server.TakeHandle().release();
std::vector<uint8_t> bytes = kGoldenBytes;
std::vector<fidl_handle_t> handles = {
expected_zircon_handle, expected_driver_handle, expected_zircon_client_end,
expected_zircon_server_end, expected_driver_client_end, expected_driver_server_end,
};
fidl::WireFormatMetadata metadata =
fidl::internal::WireFormatMetadataForVersion(fidl::internal::WireFormatVersion::kV2);
fidl::EncodedMessage message = fidl::EncodedMessage::Create<fidl::internal::DriverTransport>(
cpp20::span(bytes), handles.data(), nullptr, static_cast<uint32_t>(handles.size()));
// Perform decoding.
fit::result decoded =
fidl::StandaloneDecode<test_driver_coding::MixedResources>(std::move(message), metadata);
ASSERT_TRUE(decoded.is_ok());
test_driver_coding::MixedResources& value = decoded.value();
EXPECT_EQ(expected_zircon_handle, value.zircon_handle()->get());
EXPECT_EQ(expected_driver_handle, value.driver_handle()->get());
EXPECT_EQ(expected_zircon_client_end, value.zircon_client_end()->handle()->get());
EXPECT_EQ(expected_zircon_server_end, value.zircon_server_end()->handle()->get());
EXPECT_EQ(expected_driver_client_end, value.driver_client_end()->handle()->get());
EXPECT_EQ(expected_driver_server_end, value.driver_server_end()->handle()->get());
}
} // namespace