blob: 43787f004beeb734ccdd974272e6313d6548db21 [file] [log] [blame]
// Copyright 2024 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/graphics/display/drivers/aml-canvas/aml-canvas-driver.h"
#include <fidl/fuchsia.hardware.amlogiccanvas/cpp/wire.h>
#include <lib/async_patterns/testing/cpp/dispatcher_bound.h>
#include <lib/component/incoming/cpp/service.h>
#include <lib/driver/compat/cpp/logging.h>
#include <lib/driver/testing/cpp/driver_lifecycle.h>
#include <lib/driver/testing/cpp/driver_runtime.h>
#include <lib/driver/testing/cpp/test_environment.h>
#include <lib/driver/testing/cpp/test_node.h>
#include <gtest/gtest.h>
#include "src/devices/bus/testing/fake-pdev/fake-pdev.h"
#include "src/lib/testing/predicates/status.h"
namespace aml_canvas {
namespace {
class AmlCanvasDriverTest : public ::testing::Test {
public:
void SetUp() override {
zx::result create_start_args_zx_result =
node_server_.SyncCall(&fdf_testing::TestNode::CreateStartArgsAndServe);
ASSERT_TRUE(create_start_args_zx_result.is_ok());
auto [start_args, incoming_directory_server, outgoing_directory_client] =
std::move(create_start_args_zx_result).value();
start_args_ = std::move(start_args);
driver_outgoing_ = std::move(outgoing_directory_client);
zx::result init_result = test_environment_.SyncCall(&fdf_testing::TestEnvironment::Initialize,
std::move(incoming_directory_server));
ASSERT_EQ(ZX_OK, init_result.status_value());
zx::vmo mmio_vmo;
static constexpr uint64_t kMmioVmoSize = 0x2000;
ASSERT_OK(zx::vmo::create(kMmioVmoSize, 0, &mmio_vmo));
fake_pdev::FakePDevFidl::Config config;
config.use_fake_bti = true;
config.mmios[0] = fake_pdev::MmioInfo{
.vmo = std::move(mmio_vmo),
.offset = 0,
.size = kMmioVmoSize,
};
fake_pdev_.SyncCall(&fake_pdev::FakePDevFidl::SetConfig, std::move(config));
auto instance_handler = fake_pdev_.SyncCall(&fake_pdev::FakePDevFidl::GetInstanceHandler,
async_patterns::PassDispatcher);
test_environment_.SyncCall([&](fdf_testing::TestEnvironment* env) {
const zx::result result =
env->incoming_directory().AddService<fuchsia_hardware_platform_device::Service>(
std::move(instance_handler));
ASSERT_TRUE(result.is_ok());
});
}
void TearDown() override {
driver_.reset();
test_environment_.reset();
fake_pdev_.reset();
node_server_.reset();
}
fidl::ClientEnd<fuchsia_io::Directory> CreateDriverSvcClient() {
// Open the svc directory in the driver's outgoing, and store a client to it.
auto svc_endpoints = fidl::Endpoints<fuchsia_io::Directory>::Create();
zx_status_t status = fdio_open_at(driver_outgoing_.handle()->get(), "/svc",
static_cast<uint32_t>(fuchsia_io::OpenFlags::kDirectory),
svc_endpoints.server.TakeChannel().release());
EXPECT_EQ(ZX_OK, status);
return std::move(svc_endpoints.client);
}
void StartDriver() {
zx::result start_result = runtime_.RunToCompletion(driver_.SyncCall(
&fdf_testing::DriverUnderTest<AmlCanvasDriver>::Start, (std::move(start_args_))));
ASSERT_OK(start_result.status_value());
}
void StopDriver() {
zx::result stop_result = runtime_.RunToCompletion(
driver_.SyncCall(&fdf_testing::DriverUnderTest<AmlCanvasDriver>::PrepareStop));
ASSERT_OK(stop_result.status_value());
}
fdf_testing::DriverRuntime& runtime() { return runtime_; }
async_patterns::TestDispatcherBound<fdf_testing::DriverUnderTest<AmlCanvasDriver>>& driver() {
return driver_;
}
async_dispatcher_t* driver_async_dispatcher() { return driver_dispatcher_->async_dispatcher(); }
async_dispatcher_t* env_async_dispatcher() { return env_dispatcher_->async_dispatcher(); }
private:
// Attaches a foreground dispatcher for us automatically.
fdf_testing::DriverRuntime runtime_;
// Env and driver dispatchers run in the background because we need to make
// sync calls into them.
fdf::UnownedSynchronizedDispatcher driver_dispatcher_ = runtime_.StartBackgroundDispatcher();
fdf::UnownedSynchronizedDispatcher env_dispatcher_ = runtime_.StartBackgroundDispatcher();
async_patterns::TestDispatcherBound<fdf_testing::TestNode> node_server_{
env_async_dispatcher(), std::in_place, std::string("root")};
async_patterns::TestDispatcherBound<fake_pdev::FakePDevFidl> fake_pdev_{env_async_dispatcher(),
std::in_place};
async_patterns::TestDispatcherBound<fdf_testing::TestEnvironment> test_environment_{
env_async_dispatcher(), std::in_place};
async_patterns::TestDispatcherBound<fdf_testing::DriverUnderTest<AmlCanvasDriver>> driver_{
driver_async_dispatcher(), std::in_place};
fuchsia_driver_framework::DriverStartArgs start_args_;
fidl::ClientEnd<fuchsia_io::Directory> driver_outgoing_;
};
TEST_F(AmlCanvasDriverTest, Lifecycle) {
StartDriver();
StopDriver();
}
TEST_F(AmlCanvasDriverTest, ServesAmlogicCanvasDeviceProtocol) {
StartDriver();
zx::result canvas_client_end =
component::ConnectAtMember<fuchsia_hardware_amlogiccanvas::Service::Device>(
CreateDriverSvcClient());
ASSERT_OK(canvas_client_end.status_value());
StopDriver();
}
} // namespace
} // namespace aml_canvas