blob: 6af9a753a988fa7dcd80078e8bdaa845a0747825 [file] [log] [blame]
// Copyright 2018 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/run_test_component/test_metadata.h"
#include <fuchsia/boot/cpp/fidl.h>
#include <fuchsia/device/cpp/fidl.h>
#include <fuchsia/kernel/cpp/fidl.h>
#include <fuchsia/scheduler/cpp/fidl.h>
#include <fuchsia/sys/cpp/fidl.h>
#include <fuchsia/sys/test/cpp/fidl.h>
#include <fuchsia/sysmem/cpp/fidl.h>
#include <fuchsia/vulkan/loader/cpp/fidl.h>
#include <string>
#include <utility>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "src/lib/files/directory.h"
#include "src/lib/files/file.h"
#include "src/lib/files/scoped_temp_dir.h"
#include "src/lib/fxl/strings/string_printf.h"
#include "src/lib/fxl/strings/substitute.h"
namespace run {
namespace {
using fuchsia::sys::LaunchInfo;
constexpr char kRequiredCmxElements[] = R"(
"program": {
"binary": "path"
},
"sandbox": {
"services": []
})";
class TestMetadataTest : public ::testing::Test {
protected:
void SetUp() override { ASSERT_NE("", tmp_dir_.path()) << "Cannot acccess /tmp"; }
void ExpectFailedParse(const std::string& json, const std::string& expected_error) {
std::string error;
TestMetadata tm;
EXPECT_FALSE(ParseFrom(&tm, json));
EXPECT_TRUE(tm.HasError());
EXPECT_THAT(tm.error_str(), ::testing::HasSubstr(expected_error));
}
bool ParseFrom(TestMetadata* tm, const std::string& json) {
const bool ret = tm->ParseFromString(json, "");
EXPECT_EQ(ret, !tm->HasError());
return ret;
}
std::string CreateManifestJson(std::string additional_elements = "") {
if (additional_elements == "") {
return fxl::Substitute("{$0}", kRequiredCmxElements);
} else {
return fxl::Substitute("{$0, $1}", kRequiredCmxElements, additional_elements);
}
}
private:
files::ScopedTempDir tmp_dir_;
};
TEST_F(TestMetadataTest, InvalidJson) {
const std::string json = R"JSON({,,,})JSON";
ExpectFailedParse(json, "Missing a name for object member.");
}
TEST_F(TestMetadataTest, NoFacet) {
const std::string json = CreateManifestJson();
TestMetadata tm;
EXPECT_TRUE(ParseFrom(&tm, json));
EXPECT_TRUE(tm.is_null());
}
TEST_F(TestMetadataTest, NoFuchsiaTestFacet) {
const std::string json = CreateManifestJson(R"(
"facets": {
})");
TestMetadata tm;
EXPECT_TRUE(ParseFrom(&tm, json));
EXPECT_TRUE(tm.is_null());
}
TEST_F(TestMetadataTest, NoServices) {
const std::string json = CreateManifestJson(R"(
"facets": {
"fuchsia.test": {
}
})");
TestMetadata tm;
EXPECT_TRUE(ParseFrom(&tm, json));
EXPECT_FALSE(tm.is_null());
ASSERT_FALSE(tm.HasServices());
}
TEST_F(TestMetadataTest, InvalidTestFacet) {
const std::string json = CreateManifestJson(R"(
"facets": {
"fuchsia.test": [
]
})");
ExpectFailedParse(json, "'fuchsia.test' in 'facets' should be an object.");
}
TEST_F(TestMetadataTest, InvalidServicesType) {
const std::string json = CreateManifestJson(R"(
"facets": {
"fuchsia.test": {
"injected-services": []
}
})");
ExpectFailedParse(json,
"'injected-services' in 'fuchsia.test' should be an "
"object.");
}
TEST_F(TestMetadataTest, InvalidSystemServicesType) {
std::string json = CreateManifestJson(R"(
"facets": {
"fuchsia.test": {
"system-services": "string"
}
})");
auto expected_error = "'system-services' in 'fuchsia.test' should be a string array.";
ExpectFailedParse(json, expected_error);
json = CreateManifestJson(R"(
"facets": {
"fuchsia.test": {
"system-services": {}
}
})");
ExpectFailedParse(json, expected_error);
json = CreateManifestJson(R"(
"facets": {
"fuchsia.test": {
"system-services": [ 2, 3 ]
}
})");
ExpectFailedParse(json, expected_error);
json = CreateManifestJson(R"(
"facets": {
"fuchsia.test": {
"system-services": [ "fuchsia.device.NameProvider", "invalid_service" ]
}
})");
ExpectFailedParse(json, "'system-services' cannot contain 'invalid_service'.");
}
TEST_F(TestMetadataTest, InvalidServices) {
std::string json = CreateManifestJson(R"(
"facets": {
"fuchsia.test": {
"injected-services": {
1: "url"
}
}
})");
ExpectFailedParse(json, "Missing a name for object member.");
json = CreateManifestJson(R"(
"facets": {
"fuchsia.test": {
"injected-services": {
"1": 2
}
}
})");
ExpectFailedParse(json, "'1' must be a string or a non-empty array of strings.");
json = CreateManifestJson(R"(
"facets": {
"fuchsia.test": {
"injected-services": {
"1": [2]
}
}
})");
ExpectFailedParse(json, "'1' must be a string or a non-empty array of strings.");
}
TEST_F(TestMetadataTest, EmptyServices) {
std::string json = CreateManifestJson(R"(
"facets": {
"fuchsia.test": {
"injected-services": {
}
}
})");
TestMetadata tm;
EXPECT_TRUE(ParseFrom(&tm, json));
EXPECT_FALSE(tm.HasError());
EXPECT_FALSE(tm.HasServices());
}
TEST_F(TestMetadataTest, ValidServices) {
std::string json = CreateManifestJson(R"(
"facets": {
"fuchsia.test": {
"injected-services": {
"1": "url1",
"2": ["url2", "--a=b", "c"],
"3": "url3"
}
}
})");
TestMetadata tm;
EXPECT_TRUE(ParseFrom(&tm, json));
auto services = tm.TakeServices();
ASSERT_EQ(3u, services.size());
EXPECT_EQ(services[0].first, "1");
EXPECT_TRUE(fidl::Equals(services[0].second, LaunchInfo{.url = "url1"}));
LaunchInfo launch_info{.url = "url2"};
launch_info.arguments.emplace({"--a=b", "c"});
EXPECT_EQ(services[1].first, "2");
EXPECT_TRUE(fidl::Equals(services[1].second, launch_info));
EXPECT_EQ(services[2].first, "3");
EXPECT_TRUE(fidl::Equals(services[2].second, LaunchInfo{.url = "url3"}));
EXPECT_EQ(tm.system_services().size(), 0u);
}
TEST_F(TestMetadataTest, ValidSystemServices) {
std::string json = CreateManifestJson(
R"(
"facets": {
"fuchsia.test": {
"system-services": [
"fuchsia.boot.FactoryItems",
"fuchsia.boot.ReadOnlyLog",
"fuchsia.boot.RootResource",
"fuchsia.boot.WriteOnlyLog",
"fuchsia.device.NameProvider",
"fuchsia.kernel.Counter",
"fuchsia.kernel.CpuResource",
"fuchsia.kernel.DebugResource",
"fuchsia.kernel.HypervisorResource",
"fuchsia.kernel.InfoResource",
"fuchsia.kernel.IoportResource",
"fuchsia.kernel.IrqResource",
"fuchsia.kernel.MmioResource",
"fuchsia.kernel.PowerResource",
"fuchsia.kernel.RootJob",
"fuchsia.kernel.SmcResource",
"fuchsia.kernel.VmexResource",
"fuchsia.scheduler.ProfileProvider",
"fuchsia.sys.test.CacheControl",
"fuchsia.sysmem.Allocator",
"fuchsia.ui.scenic.Scenic",
"fuchsia.ui.policy.Presenter",
"fuchsia.vulkan.loader.Loader"
]
}
})");
{
TestMetadata tm;
EXPECT_TRUE(ParseFrom(&tm, json));
EXPECT_THAT(
tm.system_services(),
::testing::ElementsAre(
fuchsia::boot::FactoryItems::Name_, fuchsia::boot::ReadOnlyLog::Name_,
fuchsia::boot::RootResource::Name_, fuchsia::boot::WriteOnlyLog::Name_,
fuchsia::device::NameProvider::Name_, fuchsia::kernel::Counter::Name_,
fuchsia::kernel::CpuResource::Name_, fuchsia::kernel::DebugResource::Name_,
fuchsia::kernel::HypervisorResource::Name_, fuchsia::kernel::InfoResource::Name_,
fuchsia::kernel::IoportResource::Name_, fuchsia::kernel::IrqResource::Name_,
fuchsia::kernel::MmioResource::Name_, fuchsia::kernel::PowerResource::Name_,
fuchsia::kernel::RootJob::Name_, fuchsia::kernel::SmcResource::Name_,
fuchsia::kernel::VmexResource::Name_, fuchsia::scheduler::ProfileProvider::Name_,
fuchsia::sys::test::CacheControl::Name_, fuchsia::sysmem::Allocator::Name_,
fuchsia::ui::scenic::Scenic::Name_, fuchsia::ui::policy::Presenter::Name_,
fuchsia::vulkan::loader::Loader::Name_));
}
}
} // namespace
} // namespace run