| // 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 |