| // Copyright 2016 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/sys/appmgr/namespace_builder.h" |
| |
| #include <fcntl.h> |
| #include <lib/zx/channel.h> |
| #include <zircon/syscalls/object.h> |
| |
| #include <string> |
| #include <vector> |
| |
| #include <gtest/gtest.h> |
| |
| #include "fuchsia/sys/cpp/fidl.h" |
| #include "rapidjson/document.h" |
| #include "src/lib/json_parser/json_parser.h" |
| #include "zircon/types.h" |
| |
| namespace component { |
| namespace { |
| |
| TEST(NamespaceBuilder, SystemData) { |
| rapidjson::Document document; |
| document.SetObject(); |
| rapidjson::Document::AllocatorType& allocator = document.GetAllocator(); |
| rapidjson::Value system_array(rapidjson::kArrayType); |
| system_array.PushBack("deprecated-data", allocator); |
| system_array.PushBack("deprecated-data/subdir", allocator); |
| system_array.PushBack("data", allocator); |
| system_array.PushBack("data/subdir", allocator); |
| document.AddMember("system", system_array, allocator); |
| rapidjson::Value services_array(rapidjson::kArrayType); |
| document.AddMember("services", services_array, allocator); |
| SandboxMetadata sandbox; |
| |
| json::JSONParser parser; |
| sandbox.Parse(document, &parser); |
| EXPECT_FALSE(parser.HasError()) << parser.error_str(); |
| |
| fbl::unique_fd dir(open(".", O_RDONLY)); |
| NamespaceBuilder builder = NamespaceBuilder(std::move(dir), "test_namespace"); |
| zx_status_t status = builder.AddSandbox(sandbox, [] { return zx::channel(); }); |
| EXPECT_EQ(ZX_OK, status); |
| |
| fdio_flat_namespace_t* ns = builder.Build(); |
| EXPECT_EQ(0u, ns->count); |
| |
| std::vector<std::string> paths; |
| for (size_t i = 0; i < ns->count; ++i) |
| paths.push_back(ns->path[i]); |
| |
| EXPECT_TRUE(std::find(paths.begin(), paths.end(), "/system/data") == paths.end()); |
| EXPECT_TRUE(std::find(paths.begin(), paths.end(), "/system/deprecated-data") == paths.end()); |
| |
| for (size_t i = 0; i < ns->count; ++i) { |
| zx_handle_close(ns->handle[i]); |
| } |
| } |
| |
| zx_koid_t GetRelatedKoid(const zx::unowned_channel& object) { |
| zx_info_handle_basic info = {}; |
| zx_status_t status = |
| object->get_info(ZX_INFO_HANDLE_BASIC, &info, sizeof(info), nullptr, nullptr); |
| ZX_ASSERT_MSG(status == ZX_OK, "Failed to get object info: %s", zx_status_get_string(status)); |
| return info.related_koid; |
| } |
| |
| zx_koid_t GetKoid(const zx::unowned_channel& object) { |
| zx_info_handle_basic info = {}; |
| zx_status_t status = |
| object->get_info(ZX_INFO_HANDLE_BASIC, &info, sizeof(info), nullptr, nullptr); |
| ZX_ASSERT_MSG(status == ZX_OK, "Failed to get object info: %s", zx_status_get_string(status)); |
| return info.koid; |
| } |
| |
| TEST(NamespaceBuilder, FlatNamespaceAreAddedToComponent) { |
| fbl::unique_fd dir(open(".", O_RDONLY)); |
| NamespaceBuilder builder = NamespaceBuilder(std::move(dir), "test_namespace"); |
| auto flat_namespace = fuchsia::sys::FlatNamespace::New(); |
| zx::channel client, server; |
| ASSERT_EQ(zx::channel::create(0, &client, &server), ZX_OK); |
| // The related Koid should equal the Koid of the opposite end of a channel. |
| // So the related Koid of the client end should equal the Koid of the server |
| // end here, and vice versa. |
| ASSERT_EQ(GetRelatedKoid(client.borrow()), GetKoid(server.borrow())); |
| flat_namespace->directories.push_back(std::move(client)); |
| flat_namespace->paths.push_back("/dev/class/usb-device"); |
| builder.AddFlatNamespace(std::move(flat_namespace)); |
| |
| fdio_flat_namespace_t* ns = builder.Build(); |
| EXPECT_EQ(1u, ns->count); |
| |
| std::vector<std::string> paths; |
| EXPECT_EQ(std::string(ns->path[0]), std::string("/dev/class/usb-device")); |
| // Assert that the channel in |ns| is connected to the server end. |
| EXPECT_EQ(GetRelatedKoid(zx::unowned_channel(ns->handle[0])), GetKoid(server.borrow())); |
| |
| for (size_t i = 0; i < ns->count; ++i) { |
| zx_handle_close(ns->handle[i]); |
| } |
| } |
| |
| } // namespace |
| } // namespace component |