blob: de6ec6780b9bb6c3707be2e990386bab42cbcb07 [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 <fuchsia/modular/test/harness/cpp/fidl.h>
#include <lib/fidl/cpp/binding.h>
#include <lib/modular/testing/cpp/test_harness_launcher.h>
#include <lib/sys/cpp/testing/fake_launcher.h>
#include <zircon/assert.h>
#include "src/lib/testing/loop_fixture/real_loop_fixture.h"
namespace {
constexpr char kTestHarnessUrl[] =
"fuchsia-pkg://fuchsia.com/modular_test_harness#meta/"
"modular_test_harness.cmx";
} // namespace
class FakeController : public fuchsia::sys::ComponentController {
public:
FakeController(fidl::InterfaceRequest<fuchsia::sys::ComponentController> ctrl)
: loop_(&kAsyncLoopConfigNoAttachToCurrentThread), binding_(this) {
loop_.StartThread();
binding_.Bind(std::move(ctrl), loop_.dispatcher());
}
~FakeController() {
loop_.Quit();
loop_.JoinThreads();
}
bool is_bound() { return binding_.is_bound(); }
private:
// |fuchsia::sys::ComponentController|
void Kill() override { binding_.Unbind(); }
// |fuchsia::sys::ComponentController|
void Detach() override {
// Unimplemented.
ZX_ASSERT(false);
}
async::Loop loop_;
fidl::Binding<fuchsia::sys::ComponentController> binding_;
};
class TestHarnessLauncherTest : public gtest::RealLoopFixture {
public:
TestHarnessLauncherTest() {
fake_launcher_.RegisterComponent(
kTestHarnessUrl, [this](fuchsia::sys::LaunchInfo info,
fidl::InterfaceRequest<fuchsia::sys::ComponentController> ctrl) {
fake_ctrl_ = std::make_unique<FakeController>(std::move(ctrl));
});
}
protected:
fuchsia::sys::LauncherPtr GetTestHarnessLauncher() {
fuchsia::sys::LauncherPtr launcher;
fake_launcher_.GetHandler()(launcher.NewRequest());
return launcher;
}
bool is_running() { return fake_ctrl_ && fake_ctrl_->is_bound(); }
private:
sys::testing::FakeLauncher fake_launcher_;
std::unique_ptr<FakeController> fake_ctrl_;
};
// Test that the TestHarnessLauncher is able to launch modular_test_harness.cmx.
TEST_F(TestHarnessLauncherTest, CanLaunchTestHarness) {
modular_testing::TestHarnessLauncher launcher(GetTestHarnessLauncher());
RunLoopUntil([this] { return is_running(); });
}
// Test that TestHarnessLauncher will destroy the modular_test_harness.cmx
// component before the destructor returns.
TEST_F(TestHarnessLauncherTest, CleanupInDestructor) {
// Test that modular_test_harness.cmx is not running.
{
modular_testing::TestHarnessLauncher launcher(GetTestHarnessLauncher());
RunLoopUntil([this] { return is_running(); });
EXPECT_TRUE(launcher.is_test_harness_running());
}
// Test that the modular_test_harness.cmx is no longer running after
// TestHarnessLauncher is destroyed.
EXPECT_FALSE(is_running());
}
// Test that TestHarnessLauncher will terminates the modular_test_harness.cmx
// component when calling StopTestHarness.
TEST_F(TestHarnessLauncherTest, StopTestHarness) {
// Test that modular_test_harness.cmx is not running.
{
modular_testing::TestHarnessLauncher launcher(GetTestHarnessLauncher());
RunLoopUntil([this] { return is_running(); });
EXPECT_TRUE(launcher.is_test_harness_running());
launcher.StopTestHarness();
RunLoopUntil([&] { return !launcher.is_test_harness_running(); });
RunLoopUntil([this] { return !is_running(); });
}
// Test that the modular_test_harness.cmx is no longer running after
// TestHarnessLauncher is destroyed.
EXPECT_FALSE(is_running());
}