[fdf][tests] Create non-bindable test
Write a test that checks the compat shim successfully
handles a NON_BINDABLE parent creating their own local
child device.
Run this test 200 times locally to make sure there's no
flakes.
Multiply: nonbindable-test
Fixed: 98842
Change-Id: I30098e5bbeb32f7b93da6b0417e5af12b875f48c
Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/693162
Commit-Queue: David Gilhooley <dgilhooley@google.com>
Reviewed-by: Sarah Chan <spqchan@google.com>
diff --git a/build/drivers/all_drivers_list.txt b/build/drivers/all_drivers_list.txt
index b70a868..9e35041 100644
--- a/build/drivers/all_drivers_list.txt
+++ b/build/drivers/all_drivers_list.txt
@@ -223,6 +223,7 @@
//src/devices/tests/fidl-protocol:parent-driver
//src/devices/tests/isolateddevmgr:isolateddevmgr-test-driver-driver
//src/devices/tests/mock-device:mock-device-driver
+//src/devices/tests/nonbindable:driver
//src/devices/tests/string-bind-test:child-driver-driver
//src/devices/tests/string-bind-test:parent-driver-driver
//src/devices/tests/sysdev:sysdev-driver
@@ -337,4 +338,4 @@
//src/ui/light/drivers/aml-light:aml-light-driver
//src/ui/light/drivers/gpio-light:gpio-light-driver
//tools/create/goldens/my-driver-cpp:driver
-//zircon/third_party/dev/ethernet/e1000:e1000-driver
+//zircon/third_party/dev/ethernet/e1000:e1000-driver
\ No newline at end of file
diff --git a/src/devices/tests/BUILD.gn b/src/devices/tests/BUILD.gn
index 495cdd0..1de9e21 100644
--- a/src/devices/tests/BUILD.gn
+++ b/src/devices/tests/BUILD.gn
@@ -32,6 +32,7 @@
"fx-logger:tests",
"isolateddevmgr:tests",
"libdriver-integration-test",
+ "nonbindable:tests",
"string-bind-test",
"v2:tests",
]
@@ -70,6 +71,7 @@
"fidl-protocol:parent",
"isolateddevmgr:isolateddevmgr-test-driver",
"mock-device:mock-device",
+ "nonbindable:drivers",
"string-bind-test:child-driver",
"string-bind-test:parent-driver",
"sysdev:sysdev",
diff --git a/src/devices/tests/nonbindable/BUILD.gn b/src/devices/tests/nonbindable/BUILD.gn
new file mode 100644
index 0000000..7b1d5d8
--- /dev/null
+++ b/src/devices/tests/nonbindable/BUILD.gn
@@ -0,0 +1,67 @@
+# 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.
+
+import("//build/bind/bind.gni")
+import("//build/components.gni")
+import("//build/drivers.gni")
+import("//build/test.gni")
+
+group("tests") {
+ testonly = true
+ deps = [ ":pkg" ]
+}
+
+group("drivers") {
+ testonly = true
+ deps = [ ":component" ]
+}
+
+driver_bind_rules("bind") {
+ rules = "nonbindable.bind"
+ header_output = "nonbindable-bind.h"
+ bind_output = "nonbindable.bindbc"
+ deps = [
+ "//src/devices/bind/fuchsia.pci",
+ "//src/devices/bind/fuchsia.test",
+ ]
+}
+
+fuchsia_driver("driver") {
+ output_name = "test-nonbindable"
+ sources = [ "nonbindable.cc" ]
+ deps = [
+ ":bind",
+ "//src/devices/lib/driver",
+ "//src/lib/ddktl",
+ "//zircon/system/ulib/fbl",
+ "//zircon/system/ulib/zx",
+ ]
+}
+
+fuchsia_driver_component("component") {
+ component_name = "test-nonbindable"
+ deps = [ ":driver" ]
+ info = "component-info.json"
+ colocate = true
+}
+
+test("nonbindable-test") {
+ sources = [ "test.cc" ]
+ deps = [
+ ":component",
+ "//sdk/fidl/fuchsia.driver.test:fuchsia.driver.test_llcpp",
+ "//sdk/fidl/fuchsia.io:fuchsia.io_llcpp",
+ "//sdk/lib/device-watcher/cpp",
+ "//sdk/lib/driver_test_realm",
+ "//src/devices/internal/drivers/fragment",
+ "//src/devices/misc/drivers/test-parent",
+ "//src/lib/fxl/test:gtest_main",
+ "//zircon/system/ulib/service:service-llcpp",
+ ]
+}
+
+fuchsia_unittest_package("pkg") {
+ package_name = "nonbindable-test"
+ deps = [ ":nonbindable-test" ]
+}
diff --git a/src/devices/tests/nonbindable/component-info.json b/src/devices/tests/nonbindable/component-info.json
new file mode 100644
index 0000000..01b7fad
--- /dev/null
+++ b/src/devices/tests/nonbindable/component-info.json
@@ -0,0 +1,10 @@
+{
+ "short_description": "Driver Framework nonbindable test driver",
+ "manufacturer": "",
+ "families": [],
+ "models": [],
+ "areas": [
+ "DriverFramework",
+ "Test"
+ ]
+}
diff --git a/src/devices/tests/nonbindable/nonbindable.bind b/src/devices/tests/nonbindable/nonbindable.bind
new file mode 100644
index 0000000..cf99322
--- /dev/null
+++ b/src/devices/tests/nonbindable/nonbindable.bind
@@ -0,0 +1,7 @@
+// 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.
+
+using fuchsia.test;
+
+fuchsia.BIND_PROTOCOL == fuchsia.test.BIND_PROTOCOL.PARENT;
diff --git a/src/devices/tests/nonbindable/nonbindable.cc b/src/devices/tests/nonbindable/nonbindable.cc
new file mode 100644
index 0000000..732a6f2
--- /dev/null
+++ b/src/devices/tests/nonbindable/nonbindable.cc
@@ -0,0 +1,61 @@
+// 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 "src/devices/tests/nonbindable/nonbindable.h"
+
+#include "src/devices/tests/nonbindable/nonbindable-bind.h"
+
+namespace auto_bind {
+
+class Child;
+using ChildDeviceType = ddk::Device<Child>;
+class Child : public ChildDeviceType {
+ public:
+ explicit Child(zx_device_t* parent) : ChildDeviceType(parent) {}
+ virtual ~Child() = default;
+
+ zx_status_t Bind() { return DdkAdd(ddk::DeviceAddArgs("child")); }
+
+ void DdkRelease() { delete this; }
+};
+
+zx_status_t Nonbindable::Bind(void* ctx, zx_device_t* dev) {
+ auto device = std::make_unique<Nonbindable>(dev);
+ zx_status_t status = device->Bind();
+ if (status != ZX_OK) {
+ return status;
+ }
+ __UNUSED auto ptr = device.release();
+ return ZX_OK;
+}
+
+zx_status_t Nonbindable::Bind() {
+ constexpr uint32_t flags = DEVICE_ADD_NON_BINDABLE;
+ return DdkAdd(ddk::DeviceAddArgs("nonbindable").set_flags(flags));
+}
+
+void Nonbindable::DdkInit(ddk::InitTxn txn) {
+ auto child = std::make_unique<Child>(zxdev());
+ zx_status_t status = child->Bind();
+ if (status != ZX_OK) {
+ txn.Reply(status);
+ }
+
+ __UNUSED auto ptr = child.release();
+
+ txn.Reply(ZX_OK);
+}
+
+void Nonbindable::DdkRelease() { delete this; }
+
+static zx_driver_ops_t auto_bind_driver_ops = []() -> zx_driver_ops_t {
+ zx_driver_ops_t ops = {};
+ ops.version = DRIVER_OPS_VERSION;
+ ops.bind = Nonbindable::Bind;
+ return ops;
+}();
+
+} // namespace auto_bind
+
+ZIRCON_DRIVER(Nonbindable, auto_bind::auto_bind_driver_ops, "zircon", "0.1");
diff --git a/src/devices/tests/nonbindable/nonbindable.h b/src/devices/tests/nonbindable/nonbindable.h
new file mode 100644
index 0000000..762cd99
--- /dev/null
+++ b/src/devices/tests/nonbindable/nonbindable.h
@@ -0,0 +1,27 @@
+// 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.
+
+#ifndef SRC_DEVICES_TESTS_NONBINDABLE_NONBINDABLE_H_
+#define SRC_DEVICES_TESTS_NONBINDABLE_NONBINDABLE_H_
+
+#include <ddktl/device.h>
+
+namespace auto_bind {
+
+class Nonbindable;
+using DeviceType = ddk::Device<Nonbindable, ddk::Initializable>;
+class Nonbindable : public DeviceType {
+ public:
+ explicit Nonbindable(zx_device_t* parent) : DeviceType(parent) {}
+ virtual ~Nonbindable() = default;
+
+ static zx_status_t Bind(void* ctx, zx_device_t* dev);
+ zx_status_t Bind();
+ void DdkInit(ddk::InitTxn txn);
+ void DdkRelease();
+};
+
+} // namespace auto_bind
+
+#endif // SRC_DEVICES_TESTS_NONBINDABLE_NONBINDABLE_H_
diff --git a/src/devices/tests/nonbindable/test.cc b/src/devices/tests/nonbindable/test.cc
new file mode 100644
index 0000000..23a5ba5
--- /dev/null
+++ b/src/devices/tests/nonbindable/test.cc
@@ -0,0 +1,31 @@
+// 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.driver.test/cpp/wire.h>
+#include <fidl/fuchsia.io/cpp/wire.h>
+#include <lib/fdio/directory.h>
+#include <lib/service/llcpp/service.h>
+
+#include <gtest/gtest.h>
+#include <sdk/lib/device-watcher/cpp/device-watcher.h>
+
+TEST(NonbindableTest, DriversExist) {
+ {
+ // Connect to DriverTestRealm.
+ auto client_end = service::Connect<fuchsia_driver_test::Realm>();
+ ASSERT_EQ(client_end.status_value(), ZX_OK);
+ auto client = fidl::BindSyncClient(std::move(*client_end));
+
+ // Start the DriverTestRealm with correct arguments.
+ fidl::Arena arena;
+ auto args = fuchsia_driver_test::wire::RealmArgs::Builder(arena);
+ args.use_driver_framework_v2(true);
+ args.root_driver("fuchsia-boot:///#meta/test-parent-sys.cm");
+ auto wire_result = client->Start(args.Build());
+ ASSERT_EQ(wire_result.status(), ZX_OK);
+ }
+
+ fbl::unique_fd out;
+ ASSERT_EQ(ZX_OK, device_watcher::RecursiveWaitForFile("/dev/sys/test/nonbindable/child", &out));
+}