blob: aa86e5ed3448df665443d4a9a9543a556ba0a4e7 [file] [log] [blame]
// Copyright 2019 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 "driver_tests.h"
#include <fuchsia/device/test/c/fidl.h>
#include <lib/driver-integration-test/fixture.h>
#include <lib/fdio/fdio.h>
#include <lib/zx/channel.h>
#include <array>
#include <ddk/platform-defs.h>
#include <fbl/unique_fd.h>
#include <zxtest/zxtest.h>
using driver_integration_test::IsolatedDevmgr;
const board_test::DeviceEntry kDeviceEntry = []() {
board_test::DeviceEntry entry = {};
strcpy(entry.name, kFakeBusDriverName);
entry.vid = PDEV_VID_TEST;
entry.pid = PDEV_PID_PCI_TEST;
entry.did = 0;
return entry;
}();
class PciDriverTests : public zxtest::Test {
protected:
IsolatedDevmgr devmgr_;
fbl::unique_fd pcictl_fd_;
fbl::unique_fd protocol_fd_;
};
// This test builds the foundation for PCI Protocol tests. After the
// IsolatedDevmgr loads a new platform bus, it will bind the fake PCI bus
// driver. The fake bus driver creates a real device backed by the fake ecam,
// which results in our protocol test driver being loaded. The protocol test
// driver exposes a FIDL RunTests interface for the test runner to request tests
// be run and receive a summary report. Protocol tests are run in the proxied
// devhost against the real PCI protcol implementation speaking to a real PCI
// device interface, backed by the fake bus driver.
//
// Illustrated:
//
// TestRunner(driver_tests) -> pbus -> fake_pci <-> ProtocolTestDriver(pci.proxy)
// \---------------> Fuchsia.Device.Test <-------------/
TEST_F(PciDriverTests, TestRunner) {
IsolatedDevmgr::Args args;
// /boot/driver is used for finding and loading a platform bus driver, while
// /boot/driver/test is where pcictl's .so will be due it being build via the
// test_driver() rule.
args.driver_search_paths.push_back("/boot/driver");
args.device_list.push_back(kDeviceEntry);
args.disable_block_watcher = true;
args.disable_netsvc = true;
zx_status_t st = IsolatedDevmgr::Create(&args, &devmgr_);
ASSERT_OK(st);
// The final path is made up of the FakeBusDriver, the bind point it creates, and
// the final protocol test driver.
std::array<char, 64> proto_driver_path = {};
snprintf(proto_driver_path.data(), proto_driver_path.max_size(),
"sys/platform/%02x:%02x:%01x/%s/%02x:%02x.%1x/%s", kDeviceEntry.vid, kDeviceEntry.pid,
kDeviceEntry.did, kDeviceEntry.name, PCI_TEST_BUS_ID, PCI_TEST_DEV_ID, PCI_TEST_FUNC_ID,
kProtocolTestDriverName);
st = devmgr_integration_test::RecursiveWaitForFile(devmgr_.devfs_root(), proto_driver_path.data(),
&protocol_fd_);
ASSERT_OK(st);
zx::channel ch;
struct fuchsia_device_test_TestReport report = {};
ASSERT_OK(fdio_get_service_handle(protocol_fd_.release(), ch.reset_and_get_address()));
// Flush the ouput to this point so it doesn't interleave with the proxy's
// test output.
fflush(stdout);
ASSERT_OK(fuchsia_device_test_TestRunTests(ch.get(), &st, &report));
ASSERT_OK(st);
ASSERT_NE(report.test_count, 0);
ASSERT_EQ(report.test_count, report.success_count);
EXPECT_EQ(report.failure_count, 0);
}