blob: 5549974ba0dcc85966b5bc9aa1313694d8686d31 [file] [log] [blame]
// 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