blob: 4750c5dc0ba73c540072b34b8fe859fce83e299b [file] [log] [blame]
// Copyright 2018 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 <fcntl.h>
#include <fidl/fuchsia.driver.test/cpp/wire.h>
#include <fidl/fuchsia.hardware.nand/cpp/wire.h>
#include <lib/component/incoming/cpp/protocol.h>
#include <lib/device-watcher/cpp/device-watcher.h>
#include <lib/driver_test_realm/realm_builder/cpp/lib.h>
#include <lib/fdio/fd.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <utility>
#include <bind/fuchsia/platform/cpp/bind.h>
#include <fbl/string.h>
#include <fbl/unique_fd.h>
#include <gtest/gtest.h>
#include <ramdevice-client/ramnand.h>
#include "src/lib/testing/predicates/status.h"
namespace {
fuchsia_hardware_nand::wire::RamNandInfo BuildConfig() {
return {
.nand_info = {.page_size = 4096,
.pages_per_block = 4,
.num_blocks = 5,
.ecc_bits = 6,
.oob_size = 0,
.nand_class = fuchsia_hardware_nand::wire::Class::kTest,
.partition_guid{}},
};
}
} // namespace
namespace ram_nand::testing {
class RamNandIntegrationTest : public ::testing::Test {
public:
void SetUp() override {
// Connect to DriverTestRealm.
zx::result client_end = component::Connect<fuchsia_driver_test::Realm>();
ASSERT_OK(client_end);
fidl::WireSyncClient client(std::move(client_end.value()));
// Start DriverTestRealm.
fidl::Arena arena;
const fidl::WireResult result =
client->Start(fuchsia_driver_test::wire::RealmArgs::Builder(arena)
.root_driver("fuchsia-boot:///platform-bus#meta/platform-bus.cm")
.software_devices(std::vector{fuchsia_driver_test::wire::SoftwareDevice{
.device_name = "ram-nand",
.device_id = bind_fuchsia_platform::BIND_PLATFORM_DEV_DID_RAM_NAND,
}})
.Build());
ASSERT_OK(result.status());
ASSERT_TRUE(result->is_ok());
// Wait for the ram-nand driver to be bound.
zx::result channel = device_watcher::RecursiveWaitForFile(ramdevice_client::RamNand::kBasePath);
ASSERT_OK(channel);
}
};
class NandDevice {
public:
static zx::result<NandDevice> Create(
fuchsia_hardware_nand::wire::RamNandInfo config = BuildConfig()) {
std::optional<ramdevice_client::RamNand> ram_nand;
if (zx_status_t status = ramdevice_client::RamNand::Create(std::move(config), &ram_nand);
status != ZX_OK) {
return zx::error(status);
}
return zx::ok(NandDevice(std::move(ram_nand.value())));
}
NandDevice(const NandDevice&) = delete;
NandDevice& operator=(const NandDevice&) = delete;
NandDevice(NandDevice&&) = default;
NandDevice& operator=(NandDevice&&) = default;
~NandDevice() = default;
const char* path() { return ram_nand_.path(); }
const char* filename() { return ram_nand_.filename(); }
private:
explicit NandDevice(ramdevice_client::RamNand ram_nand) : ram_nand_(std::move(ram_nand)) {}
ramdevice_client::RamNand ram_nand_;
};
TEST_F(RamNandIntegrationTest, TrivialLifetime) {
std::unique_ptr<device_watcher::DirWatcher> watcher;
fbl::unique_fd dir_fd(open(ramdevice_client::RamNand::kBasePath, O_RDONLY | O_DIRECTORY));
ASSERT_TRUE(dir_fd);
ASSERT_EQ(device_watcher::DirWatcher::Create(dir_fd.get(), &watcher), ZX_OK);
fbl::String path;
fbl::String filename;
{
zx::result result = NandDevice::Create();
ASSERT_OK(result.status_value());
NandDevice& device = result.value();
path = fbl::String(device.path());
filename = fbl::String(device.filename());
}
ASSERT_EQ(watcher->WaitForRemoval(filename, zx::sec(5)), ZX_OK);
fbl::unique_fd found(open(path.c_str(), O_RDWR));
ASSERT_FALSE(found);
}
TEST_F(RamNandIntegrationTest, ExportConfig) {
fuchsia_hardware_nand::wire::RamNandInfo config = BuildConfig();
config.export_nand_config = true;
zx::result device = NandDevice::Create(std::move(config));
ASSERT_OK(device.status_value());
}
TEST_F(RamNandIntegrationTest, ExportPartitions) {
fuchsia_hardware_nand::wire::RamNandInfo config = BuildConfig();
config.export_partition_map = true;
zx::result device = NandDevice::Create(std::move(config));
ASSERT_OK(device.status_value());
}
TEST_F(RamNandIntegrationTest, CreateFailure) {
fuchsia_hardware_nand::wire::RamNandInfo config = BuildConfig();
config.nand_info.num_blocks = 0;
zx::result device = NandDevice::Create(std::move(config));
ASSERT_STATUS(device.status_value(), ZX_ERR_INVALID_ARGS);
}
} // namespace ram_nand::testing