blob: a19e938eab7d377c677f1c927abbe3c5ffa48ae5 [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 <fcntl.h>
#include <fuchsia/hardware/ethertap/cpp/fidl.h>
#include <fuchsia/sys/cpp/fidl.h>
#include <lib/devmgr-integration-test/fixture.h>
#include <lib/fdio/directory.h>
#include <lib/gtest/real_loop_fixture.h>
#include <lib/sys/cpp/component_context.h>
#include "isolated_devmgr.h"
namespace isolated_devmgr {
namespace testing {
constexpr zx::duration kTimeout = zx::sec(30);
class DevmgrTest : public ::gtest::RealLoopFixture {
protected:
static constexpr const char* kSysdevDriver = "/boot/driver/test/sysdev.so";
std::unique_ptr<IsolatedDevmgr> CreateDevmgr() {
devmgr_launcher::Args args;
args.sys_device_driver = kSysdevDriver;
args.stdio = fbl::unique_fd(open("/dev/null", O_RDWR));
args.load_drivers.push_back("/boot/driver/ethernet.so");
args.load_drivers.push_back("/boot/driver/ethertap.so");
args.disable_block_watcher = true;
args.disable_netsvc = true;
args.use_system_svchost = true;
return IsolatedDevmgr::Create(std::move(args));
}
fidl::InterfaceHandle<fuchsia::hardware::ethertap::TapDevice> CreateTapDevice(
const zx::channel& devfs) {
fidl::SynchronousInterfacePtr<fuchsia::hardware::ethertap::TapControl>
tapctl;
fdio_service_connect_at(devfs.get(), "misc/tapctl",
tapctl.NewRequest().TakeChannel().release());
fuchsia::hardware::ethertap::Config config;
config.mtu = 1500;
config.options = 0;
config.features = 0;
const uint8_t mac[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
memcpy(config.mac.octets.data(), mac, sizeof(mac));
fidl::InterfaceHandle<fuchsia::hardware::ethertap::TapDevice> device;
zx_status_t o_status;
if (tapctl->OpenDevice("tap_device", std::move(config), device.NewRequest(),
&o_status) != ZX_OK ||
o_status != ZX_OK) {
// discard channel
device = nullptr;
}
return device;
}
};
TEST_F(DevmgrTest, CreateTap) {
auto devmgr = CreateDevmgr();
ASSERT_TRUE(devmgr);
ASSERT_EQ(devmgr->WaitForFile("misc/tapctl"), ZX_OK);
fidl::InterfaceHandle<fuchsia::io::Directory> dir;
devmgr->Connect(dir.NewRequest().TakeChannel());
auto tap = CreateTapDevice(dir.channel());
ASSERT_TRUE(tap);
// after having created tap, we should be able to see an ethernet device show
// up:
ASSERT_EQ(devmgr->WaitForFile("class/ethernet/000"), ZX_OK);
}
TEST_F(DevmgrTest, DISABLED_ExceptionCallback) {
auto devmgr = CreateDevmgr();
ASSERT_TRUE(devmgr);
ASSERT_EQ(devmgr->WaitForFile("misc/tapctl"), ZX_OK);
bool exception = false;
devmgr->SetExceptionCallback([&exception]() { exception = true; });
// TODO(brunodalbo): Cause devmgr crash here so we can
// validate that the exception callback works and
// enable this test. There's no good way to cause a crash
// today.
ASSERT_TRUE(RunLoopWithTimeoutOrUntil([&exception]() { return exception; },
kTimeout));
}
TEST_F(DevmgrTest, ExposedThroughComponent) {
auto ctx = sys::ComponentContext::Create();
fidl::InterfacePtr<fuchsia::sys::Launcher> launcher;
ctx->svc()->Connect(launcher.NewRequest());
zx::channel req;
auto services = sys::ServiceDirectory::CreateWithRequest(&req);
fuchsia::sys::LaunchInfo info;
info.directory_request = std::move(req);
info.url =
"fuchsia-pkg://fuchsia.com/isolated_devmgr_tests#meta/"
"isolated_devmgr.cmx";
fidl::InterfacePtr<fuchsia::sys::ComponentController> ctlr;
launcher->CreateComponent(std::move(info), ctlr.NewRequest());
ctlr.set_error_handler(
[](zx_status_t err) { FAIL() << "Controller shouldn't exit"; });
zx::channel devfs_req, devfs;
zx::channel::create(0, &devfs_req, &devfs);
services->Connect("fuchsia.example.IsolatedDevmgr", std::move(devfs_req));
auto tap = CreateTapDevice(devfs);
ASSERT_TRUE(tap);
}
} // namespace testing
} // namespace isolated_devmgr