blob: 79a6df593e760da836da6852e045064218d1a7d9 [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/fuchsia.device.test/cpp/wire.h>
#include <fidl/fuchsia.device/cpp/wire.h>
#include <fuchsia/driver/development/cpp/fidl.h>
#include <fuchsia/driver/test/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/ddk/driver.h>
#include <lib/device-watcher/cpp/device-watcher.h>
#include <lib/driver_test_realm/realm_builder/cpp/lib.h>
#include <lib/fdio/directory.h>
#include <lib/sys/cpp/component_context.h>
#include <bind/bindlib/codegen/testlib/cpp/bind.h>
#include <bind/bindlibparent/codegen/testlib/cpp/bind.h>
#include <bind/fuchsia/cpp/bind.h>
#include <fbl/unique_fd.h>
#include <gtest/gtest.h>
namespace lib = bind_bindlib_codegen_testlib;
namespace parent = bind_bindlibparent_codegen_testlib;
const std::string kChildDevicePath = "/dev/sys/test/parent";
class BindLibToFidlCodeGenTest : public testing::Test {
protected:
void SetUp() override {
// Create and build the realm.
realm_builder_ = component_testing::RealmBuilder::Create();
driver_test_realm::Setup(*realm_builder_);
realm_ = realm_builder_->Build(loop_.dispatcher());
// Start DriverTestRealm.
fidl::SynchronousInterfacePtr<fuchsia::driver::test::Realm> driver_test_realm;
ASSERT_EQ(ZX_OK, realm_->component().Connect(driver_test_realm.NewRequest()));
auto args = fuchsia::driver::test::RealmArgs();
fuchsia::driver::test::Realm_Start_Result realm_result;
ASSERT_EQ(ZX_OK, driver_test_realm->Start(std::move(args), &realm_result));
ASSERT_FALSE(realm_result.is_err());
// Connect to dev.
fidl::InterfaceHandle<fuchsia::io::Node> dev;
zx_status_t status =
realm_->component().Connect("dev-topological", dev.NewRequest().TakeChannel());
ASSERT_EQ(status, ZX_OK);
// Turn it into a file descriptor.
fbl::unique_fd dev_fd;
ASSERT_EQ(fdio_fd_create(dev.TakeChannel().release(), dev_fd.reset_and_get_address()), ZX_OK);
// Wait for the child device to bind and appear. The child device should bind with its string
// properties.
zx::result channel =
device_watcher::RecursiveWaitForFile(dev_fd.get(), "sys/test/parent/child");
ASSERT_EQ(channel.status_value(), ZX_OK);
// Connect to the DriverDevelopment service.
status = realm_->component().Connect(driver_dev_.NewRequest());
ASSERT_EQ(status, ZX_OK);
}
async::Loop loop_{&kAsyncLoopConfigNeverAttachToThread};
std::optional<component_testing::RealmBuilder> realm_builder_;
std::optional<component_testing::RealmRoot> realm_;
fuchsia::driver::development::ManagerSyncPtr driver_dev_;
};
// TODO(b/316176095): Re-enable test after ensuring it works with DFv2.
TEST_F(BindLibToFidlCodeGenTest, DISABLED_DeviceProperties) {
fuchsia::driver::development::NodeInfoIteratorSyncPtr iterator;
ASSERT_EQ(ZX_OK, driver_dev_->GetNodeInfo({kChildDevicePath}, iterator.NewRequest(),
/* exact_match= */ true));
std::vector<fuchsia::driver::development::NodeInfo> devices;
ASSERT_EQ(iterator->GetNext(&devices), ZX_OK);
auto& props = devices[0].node_property_list();
ASSERT_EQ(static_cast<size_t>(9), props.size());
ASSERT_EQ(bind_fuchsia::PROTOCOL, props[0].key.string_value());
ASSERT_TRUE(props[0].value.is_int_value());
ASSERT_EQ(3u, props[0].value.int_value());
ASSERT_EQ(bind_fuchsia::PCI_VID, props[1].key.string_value());
ASSERT_TRUE(props[1].value.is_int_value());
ASSERT_EQ(lib::BIND_PCI_VID_PIE, props[1].value.int_value());
ASSERT_EQ(bind_fuchsia::PCI_DID, props[2].key.string_value());
ASSERT_TRUE(props[2].value.is_int_value());
ASSERT_EQ(1234u, props[2].value.int_value());
ASSERT_EQ("bindlib.codegen.testlib.kinglet", props[3].key.string_value());
ASSERT_EQ(lib::KINGLET, props[3].key.string_value());
ASSERT_TRUE(props[3].value.is_string_value());
ASSERT_EQ("firecrest", props[3].value.string_value());
ASSERT_EQ("bindlib.codegen.testlib.Moon", props[4].key.string_value());
ASSERT_EQ(lib::MOON, props[4].key.string_value());
ASSERT_TRUE(props[4].value.is_enum_value());
ASSERT_EQ("bindlib.codegen.testlib.Moon.Half", props[4].value.enum_value());
ASSERT_EQ(lib::MOON_HALF, props[4].value.enum_value());
ASSERT_EQ("bindlib.codegen.testlib.bobolink", props[5].key.string_value());
ASSERT_EQ(lib::BOBOLINK, props[5].key.string_value());
ASSERT_TRUE(props[5].value.is_int_value());
ASSERT_EQ(static_cast<uint32_t>(10), props[5].value.int_value());
ASSERT_EQ("bindlib.codegen.testlib.flag", props[6].key.string_value());
ASSERT_EQ(lib::FLAG, props[6].key.string_value());
ASSERT_TRUE(props[6].value.is_bool_value());
ASSERT_TRUE(props[6].value.bool_value());
ASSERT_EQ(lib::FLAG_ENABLE, props[6].value.bool_value());
ASSERT_EQ("bindlibparent.codegen.testlib.Pizza", props[7].key.string_value());
ASSERT_EQ(parent::PIZZA, props[7].key.string_value());
ASSERT_TRUE(props[7].value.is_string_value());
ASSERT_EQ("pepperoni pizza", props[7].value.string_value());
ASSERT_EQ(parent::PIZZA_PEPPERONI, props[7].value.string_value());
ASSERT_EQ("bindlibparent.codegen.testlib.Grit", props[8].key.string_value());
ASSERT_EQ(parent::GRIT, props[8].key.string_value());
ASSERT_TRUE(props[8].value.is_int_value());
ASSERT_EQ(static_cast<uint32_t>(100), props[8].value.int_value());
ASSERT_EQ(parent::GRIT_COARSE, props[8].value.int_value());
}