blob: ed7d8024a5ef4cc9d7ffd63a1b7f38c9868ef6b0 [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 "src/devices/bin/driver_manager/v1/driver_development.h"
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <zxtest/zxtest.h>
#include "multiple_device_test.h"
class DriverDevelopmentTest : public MultipleDeviceTestCase {};
TEST_F(DriverDevelopmentTest, DeviceInfo) {
std::vector<fbl::RefPtr<Device>> devices;
size_t parent_index;
ASSERT_NO_FATAL_FAILURE(
AddDevice(platform_bus()->device, "parent-device", 0 /* protocol id */, "", &parent_index));
devices.push_back(device(parent_index)->device);
devices[0]->flags = DEV_CTX_BOUND;
auto arena = std::make_unique<fidl::Arena<512>>();
auto result = GetDeviceInfo(*arena, devices);
ASSERT_EQ(ZX_OK, result.status_value());
auto endpoints = fidl::CreateEndpoints<fuchsia_driver_development::DeviceInfoIterator>();
auto iterator = std::make_unique<DeviceInfoIterator>(std::move(arena), std::move(*result));
async::Loop loop = async::Loop(&kAsyncLoopConfigNeverAttachToThread);
fidl::BindServer(loop.dispatcher(), std::move(endpoints->server), std::move(iterator));
auto client = fidl::WireClient(std::move(endpoints->client), loop.dispatcher());
bool was_called = false;
client->GetNext().Then(
[&was_called](
fidl::WireUnownedResult<::fuchsia_driver_development::DeviceInfoIterator::GetNext>&
result) {
was_called = true;
auto count = result->drivers.count();
ASSERT_EQ(count, 1);
ASSERT_EQ(std::string(result->drivers[0].topological_path().get()),
std::string("/dev/sys/platform-bus/parent-device"));
ASSERT_EQ(result->drivers[0].flags(), fuchsia_driver_development::DeviceFlags::kBound);
});
loop.RunUntilIdle();
ASSERT_TRUE(was_called);
}
TEST_F(DriverDevelopmentTest, DriverInfo) {
Driver driver;
driver.name = "test";
std::vector<const Driver*> drivers;
driver.bytecode_version = 2;
auto bind_rules = std::make_unique<uint8_t[]>(1);
driver.binding = std::move(bind_rules);
drivers.push_back(&driver);
auto arena = std::make_unique<fidl::Arena<512>>();
auto result = GetDriverInfo(*arena, drivers);
ASSERT_EQ(ZX_OK, result.status_value());
auto endpoints = fidl::CreateEndpoints<fuchsia_driver_development::DriverInfoIterator>();
auto iterator = std::make_unique<DriverInfoIterator>(std::move(arena), std::move(*result));
async::Loop loop = async::Loop(&kAsyncLoopConfigNeverAttachToThread);
fidl::BindServer(loop.dispatcher(), std::move(endpoints->server), std::move(iterator));
auto client = fidl::WireClient(std::move(endpoints->client), loop.dispatcher());
bool was_called = false;
client->GetNext().Then(
[&was_called](
fidl::WireUnownedResult<::fuchsia_driver_development::DriverInfoIterator::GetNext>&
result) {
was_called = true;
auto count = result->drivers.count();
ASSERT_EQ(count, 1);
ASSERT_EQ(std::string(result->drivers[0].name().get()), std::string("test"));
});
loop.RunUntilIdle();
ASSERT_TRUE(was_called);
}
TEST_F(DriverDevelopmentTest, UnknownFlagsWork) {
std::vector<fbl::RefPtr<Device>> devices;
size_t parent_index;
ASSERT_NO_FATAL_FAILURE(
AddDevice(platform_bus()->device, "parent-device", 0 /* protocol id */, "", &parent_index));
devices.push_back(device(parent_index)->device);
// Give our device some unknown flags.
devices[0]->flags = 0xF000;
auto arena = std::make_unique<fidl::Arena<512>>();
auto result = GetDeviceInfo(*arena, devices);
ASSERT_EQ(ZX_OK, result.status_value());
auto endpoints = fidl::CreateEndpoints<fuchsia_driver_development::DeviceInfoIterator>();
auto iterator = std::make_unique<DeviceInfoIterator>(std::move(arena), std::move(*result));
async::Loop loop = async::Loop(&kAsyncLoopConfigNeverAttachToThread);
fidl::BindServer(loop.dispatcher(), std::move(endpoints->server), std::move(iterator));
auto client = fidl::WireClient(std::move(endpoints->client), loop.dispatcher());
bool was_called = false;
client->GetNext().Then(
[&was_called](
fidl::WireUnownedResult<::fuchsia_driver_development::DeviceInfoIterator::GetNext>&
result) {
was_called = true;
auto count = result->drivers.count();
ASSERT_EQ(count, 1);
ASSERT_EQ(static_cast<uint32_t>(result->drivers[0].flags()), 0);
});
loop.RunUntilIdle();
ASSERT_TRUE(was_called);
}