blob: dd13a61cf1523b936c4bf51cfdfea241e46bbcab [file] [log] [blame]
// Copyright 2020 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/cpp/wire.h>
#include <lib/devmgr-integration-test/fixture.h>
#include <lib/fdio/directory.h>
#include <ddktl/device.h>
#include <zxtest/zxtest.h>
#include "src/devices/testing/mock-ddk/mock-device.h"
namespace {
using devmgr_integration_test::IsolatedDevmgr;
TEST(MetadataTest, RunTests) {
const char kDriver[] = "/boot/driver/ddk-metadata-test-driver.so";
auto args = IsolatedDevmgr::DefaultArgs();
args.sys_device_driver = "/boot/driver/test-parent-sys.so";
IsolatedDevmgr devmgr;
ASSERT_OK(IsolatedDevmgr::Create(std::move(args), &devmgr));
zx::channel sys_chan;
{
fbl::unique_fd fd;
ASSERT_OK(device_watcher::RecursiveWaitForFile(devmgr.devfs_root(), "sys/test/test", &fd));
ASSERT_OK(fdio_get_service_handle(fd.release(), sys_chan.reset_and_get_address()));
}
fidl::WireSyncClient<fuchsia_device::Controller> sys_dev(std::move(sys_chan));
auto result = sys_dev->Bind(fidl::StringView{kDriver});
ASSERT_OK(result.status());
// The driver will run its tests in its bind routine, and return ZX_OK on success.
ASSERT_FALSE(result->is_error());
}
// Test the Metadata struct helper:
TEST(MetadataTest, GetMetadataStructTest) {
auto parent = MockDevice::FakeRootParent(); // Hold on to the parent during the test.
constexpr size_t kMetadataType = 5;
struct MetadataType {
int data[4];
float data1;
};
MetadataType metadata_source;
parent->SetMetadata(kMetadataType, &metadata_source, sizeof(metadata_source));
auto metadata_result = ddk::GetMetadata<MetadataType>(parent.get(), kMetadataType);
ASSERT_TRUE(metadata_result.is_ok());
ASSERT_BYTES_EQ(metadata_result.value().get(), &metadata_source, sizeof(MetadataType));
}
// Test the Metadata Array helper:
TEST(MetadataTest, MetadataArrayTests) {
auto parent = MockDevice::FakeRootParent(); // Hold on to the parent during the test.
constexpr size_t kMetadataType = 5;
struct MetadataType {
int data[4];
float data1;
};
constexpr size_t kMetadataArrayLen = 5;
MetadataType metadata_source[kMetadataArrayLen];
parent->SetMetadata(kMetadataType, &metadata_source, sizeof(metadata_source));
auto metadata_result = ddk::GetMetadataArray<MetadataType>(parent.get(), kMetadataType);
ASSERT_TRUE(metadata_result.is_ok());
ASSERT_EQ(metadata_result->size(), kMetadataArrayLen);
for (size_t i = 0; i < metadata_result->size(); ++i) {
ASSERT_BYTES_EQ(&metadata_result.value()[i], &metadata_source[i], sizeof(MetadataType));
}
}
// Simple device to test DeviceAddArgs
class TestDevice : public ddk::Device<TestDevice> {
public:
TestDevice(zx_device_t* parent) : ddk::Device<TestDevice>(parent) {}
void DdkRelease() {
// DdkRelease must delete this before it returns.
delete this;
}
};
TEST(MetadataTest, DeviceAddArgTests) {
// We use two parents here because if we added the metadata to the normal parent,
// it would be accessible through the child by recursion.
auto parent = MockDevice::FakeRootParent(); // Hold on to the parent during the test.
auto metadata_parent = MockDevice::FakeRootParent(); // This will actually have the metadata
constexpr size_t kMetadataType = 5;
struct MetadataType {
int data[4];
float data1;
};
constexpr size_t kMetadataArrayLen = 5;
MetadataType metadata_source[kMetadataArrayLen];
metadata_parent->SetMetadata(kMetadataType, &metadata_source, sizeof(metadata_source));
// Bind a new device:
auto dev = std::make_unique<TestDevice>(parent.get());
// Now, add the child, but allow it to get the metadata from the metadata_parent:
auto args = ddk::DeviceAddArgs("dut").forward_metadata(metadata_parent.get(), kMetadataType);
ASSERT_EQ(args.get().metadata_count, 1);
ASSERT_EQ(args.get().metadata_list[0].type, kMetadataType);
ASSERT_OK(dev->DdkAdd(args));
auto dev_ptr = dev.release();
// Now the metadata should be available in the device:
auto metadata_result = ddk::GetMetadataArray<MetadataType>(dev_ptr->zxdev(), kMetadataType);
ASSERT_TRUE(metadata_result.is_ok());
ASSERT_EQ(metadata_result->size(), kMetadataArrayLen);
for (size_t i = 0; i < metadata_result->size(); ++i) {
ASSERT_BYTES_EQ(&metadata_result.value()[i], &metadata_source[i], sizeof(MetadataType));
}
}
} // namespace