blob: b4de7c7104adb502253d7c8640698f5dbf8b62ba [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/boot/c/fidl.h>
#include <fuchsia/kernel/llcpp/fidl.h>
#include <fuchsia/scheduler/c/fidl.h>
#include <lib/fdio/directory.h>
#include <lib/zx/channel.h>
#include <lib/zx/debuglog.h>
#include <lib/zx/profile.h>
#include <lib/zx/vmo.h>
#include <zxtest/zxtest.h>
#include "zircon/rights.h"
namespace {
// These are integration tests of svchost which check whether certain services are present in
// the /svc directory exposed by svchost. To verify that the services are actually present we need
// to minimally test that they work, since fdio_service_connect succeeding does not actually mean
// the remote end exists (i.e. you won't observe a PEER_CLOSED error until actually trying to use
// the channel).
constexpr char kFactoryItemsPath[] = "/svc/" fuchsia_boot_FactoryItems_Name;
constexpr char kItemsPath[] = "/svc/" fuchsia_boot_Items_Name;
constexpr char kProfileProviderPath[] = "/svc/" fuchsia_scheduler_ProfileProvider_Name;
constexpr char kReadOnlyLogPath[] = "/svc/" fuchsia_boot_ReadOnlyLog_Name;
constexpr char kRootJobPath[] = "/svc/" fuchsia_boot_RootJob_Name;
constexpr char kRootJobForInspectPath[] = "/svc/" fuchsia_boot_RootJobForInspect_Name;
constexpr char kRootResourcePath[] = "/svc/" fuchsia_boot_RootResource_Name;
constexpr char kWriteOnlyLogPath[] = "/svc/" fuchsia_boot_WriteOnlyLog_Name;
TEST(SvchostTest, FuchsiaBootFactoryItemsPresent) {
zx::channel client, server;
zx_status_t status = zx::channel::create(0, &client, &server);
ASSERT_EQ(ZX_OK, status, "zx::channel::create failed");
status = fdio_service_connect(kFactoryItemsPath, server.release());
ASSERT_EQ(ZX_OK, status, "fdio_service_connect failed");
zx::vmo payload;
uint32_t length;
status = fuchsia_boot_FactoryItemsGet(client.get(), 0, payload.reset_and_get_address(), &length);
ASSERT_EQ(ZX_OK, status, "fuchsia_boot_FactoryItemsGet failed");
}
TEST(SvchostTest, FuchsiaBootItemsPresent) {
zx::channel client, server;
zx_status_t status = zx::channel::create(0, &client, &server);
ASSERT_EQ(ZX_OK, status, "zx::channel::create failed");
status = fdio_service_connect(kItemsPath, server.release());
ASSERT_EQ(ZX_OK, status, "fdio_service_connect failed");
zx::vmo payload;
uint32_t length;
status = fuchsia_boot_ItemsGet(client.get(), 0, 0, payload.reset_and_get_address(), &length);
ASSERT_EQ(ZX_OK, status, "fuchsia_boot_ItemsGet failed");
}
TEST(SvchostTest, FuchsiaReadOnlyBootLogPresent) {
zx::channel client, server;
zx_status_t status = zx::channel::create(0, &client, &server);
ASSERT_EQ(ZX_OK, status, "zx::channel::create failed");
status = fdio_service_connect(kReadOnlyLogPath, server.release());
ASSERT_EQ(ZX_OK, status, "fdio_service_connect failed");
zx::debuglog log;
status = fuchsia_boot_ReadOnlyLogGet(client.get(), log.reset_and_get_address());
ASSERT_EQ(ZX_OK, status, "fuchsia_boot_ReadOnlyLogGet failed");
}
TEST(SvchostTest, FuchsiaWriteOnlyBootLogPresent) {
zx::channel client, server;
zx_status_t status = zx::channel::create(0, &client, &server);
ASSERT_EQ(ZX_OK, status, "zx::channel::create failed");
status = fdio_service_connect(kWriteOnlyLogPath, server.release());
ASSERT_EQ(ZX_OK, status, "fdio_service_connect failed");
zx::debuglog log;
status = fuchsia_boot_WriteOnlyLogGet(client.get(), log.reset_and_get_address());
ASSERT_EQ(ZX_OK, status, "fuchsia_boot_WriteOnlyLogGet failed");
}
TEST(SvchostTest, FuchsiaSchedulerProfileProviderPresent) {
zx::channel client, server;
zx_status_t status = zx::channel::create(0, &client, &server);
ASSERT_EQ(ZX_OK, status, "zx::channel::create failed");
status = fdio_service_connect(kProfileProviderPath, server.release());
ASSERT_EQ(ZX_OK, status, "fdio_service_connect failed");
zx_status_t fidl_status = ZX_ERR_INTERNAL;
zx::profile profile;
status = fuchsia_scheduler_ProfileProviderGetProfile(client.get(), 0, "", 0, &fidl_status,
profile.reset_and_get_address());
ASSERT_EQ(ZX_OK, status, "fuchsia_scheduler_ProfileProviderGetProfile failed");
}
TEST(SvchostTest, FuchsiaRootResourcePresent) {
zx::channel client, server;
zx_status_t status = zx::channel::create(0, &client, &server);
ASSERT_EQ(ZX_OK, status, "zx::channel::create failed");
status = fdio_service_connect(kRootResourcePath, server.release());
ASSERT_EQ(ZX_OK, status, "fdio_service_connect failed");
zx::resource resource;
status = fuchsia_boot_RootResourceGet(client.get(), resource.reset_and_get_address());
ASSERT_EQ(ZX_OK, status, "fuchsia_boot_RootResourceGet failed");
}
TEST(SvchostTest, FuchsiaRootJobPresent) {
zx::channel client, server;
zx_status_t status = zx::channel::create(0, &client, &server);
ASSERT_EQ(ZX_OK, status, "zx::channel::create failed");
status = fdio_service_connect(kRootJobPath, server.release());
ASSERT_EQ(ZX_OK, status, "fdio_service_connect failed");
zx::job job;
status = fuchsia_boot_RootJobGet(client.get(), job.reset_and_get_address());
ASSERT_EQ(ZX_OK, status, "fuchsia_boot_RootJobGet failed");
}
TEST(SvchostTest, FuchsiaRootJobForInspectPresent) {
zx::channel client, server;
zx_status_t status = zx::channel::create(0, &client, &server);
ASSERT_EQ(ZX_OK, status, "zx::channel::create failed");
status = fdio_service_connect(kRootJobForInspectPath, server.release());
ASSERT_EQ(ZX_OK, status, "fdio_service_connect failed");
zx::job job;
status = fuchsia_boot_RootJobForInspectGet(client.get(), job.reset_and_get_address());
ASSERT_EQ(ZX_OK, status, "fuchsia_boot_RootJobForInspectGet failed");
ASSERT_TRUE(job.is_valid());
zx_info_handle_basic_t info;
status =
job.get_info(ZX_INFO_HANDLE_BASIC, &info, sizeof(zx_info_handle_basic_t), nullptr, nullptr);
ASSERT_EQ(ZX_OK, status, "zx_object_get_info failed");
ASSERT_EQ(ZX_RIGHT_DUPLICATE | ZX_RIGHT_TRANSFER | ZX_RIGHT_INSPECT | ZX_RIGHT_ENUMERATE |
ZX_RIGHT_GET_PROPERTY,
info.rights);
}
TEST(SvchostTest, FuchsiaKernelStatsPresent) {
zx::channel client, server;
zx_status_t status = zx::channel::create(0, &client, &server);
ASSERT_EQ(ZX_OK, status, "zx::channel::create failed");
fbl::String service_path = fbl::String::Concat({"/svc/", llcpp::fuchsia::kernel::Stats::Name});
status = fdio_service_connect(service_path.c_str(), server.release());
ASSERT_EQ(ZX_OK, status, "fdio_service_connect failed");
llcpp::fuchsia::kernel::Stats::SyncClient stats_client(std::move(client));
llcpp::fuchsia::kernel::Stats::ResultOf::GetMemoryStats mem_result =
stats_client.GetMemoryStats();
ASSERT_EQ(ZX_OK, mem_result.status(), "GetMemoryStats failed");
auto mem_stats = mem_result.Unwrap();
ASSERT_GT(mem_stats->stats.total_bytes(), 0);
llcpp::fuchsia::kernel::Stats::ResultOf::GetCpuStats cpu_result = stats_client.GetCpuStats();
ASSERT_EQ(ZX_OK, cpu_result.status(), "GetCpuStats failed");
auto cpu_stats = cpu_result.Unwrap();
ASSERT_GT(cpu_stats->stats.actual_num_cpus, 0);
ASSERT_EQ(cpu_stats->stats.actual_num_cpus, cpu_stats->stats.per_cpu_stats.count());
}
} // namespace