1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "services/service_manager/public/cpp/manifest.h"
6
7 #include <set>
8 #include <string>
9
10 #include "base/files/file_path.h"
11 #include "base/no_destructor.h"
12 #include "base/stl_util.h"
13 #include "services/service_manager/public/cpp/manifest_builder.h"
14 #include "services/service_manager/public/mojom/connector.mojom.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17
18 using ::testing::ElementsAre;
19
20 namespace service_manager {
21
22 const char kTestServiceName[] = "test_service";
23
GetPackagedService1Manifest()24 const Manifest& GetPackagedService1Manifest() {
25 static base::NoDestructor<Manifest> manifest{ManifestBuilder()
26 .WithServiceName("service_1")
27 .WithDisplayName("Service 1")
28 .Build()};
29 return *manifest;
30 }
31
GetPackagedService2Manifest()32 const Manifest& GetPackagedService2Manifest() {
33 static base::NoDestructor<Manifest> manifest{ManifestBuilder()
34 .WithServiceName("service_2")
35 .WithDisplayName("Service 2")
36 .Build()};
37 return *manifest;
38 }
39
CreateTestManifest()40 Manifest CreateTestManifest() {
41 static base::NoDestructor<Manifest> manifest{
42 ManifestBuilder()
43 .WithServiceName(kTestServiceName)
44 .WithDisplayName("The Test Service, Obviously")
45 .WithOptions(
46 ManifestOptionsBuilder()
47 .WithSandboxType("none")
48 .WithInstanceSharingPolicy(
49 Manifest::InstanceSharingPolicy::kSharedAcrossGroups)
50 .CanConnectToInstancesWithAnyId(true)
51 .CanConnectToInstancesInAnyGroup(true)
52 .CanRegisterOtherServiceInstances(false)
53 .Build())
54 .ExposeCapability("capability_1",
55 Manifest::InterfaceList<mojom::Connector,
56 mojom::ProcessMetadata>())
57 .ExposeCapability("capability_2",
58 Manifest::InterfaceList<mojom::Connector>())
59 .RequireCapability("service_42", "computation")
60 .RequireCapability("frobinator", "frobination")
61 .ExposeInterfaceFilterCapability_Deprecated(
62 "navigation:frame", "filter_capability_1",
63 Manifest::InterfaceList<mojom::Connector>())
64 .RequireInterfaceFilterCapability_Deprecated(
65 "browser", "navigation:frame", "some_filter_capability")
66 .RequireInterfaceFilterCapability_Deprecated(
67 "browser", "navigation:frame", "another_filter_capability")
68 .PackageService(GetPackagedService1Manifest())
69 .PackageService(GetPackagedService2Manifest())
70 .PreloadFile("file1_key",
71 base::FilePath(FILE_PATH_LITERAL("AUTOEXEC.BAT")))
72 .PreloadFile("file2_key",
73 base::FilePath(FILE_PATH_LITERAL("CONFIG.SYS")))
74 .PreloadFile("file3_key", base::FilePath(FILE_PATH_LITERAL(".vimrc")))
75 .Build()};
76 return *manifest;
77 }
78
TEST(ManifestTest,BasicBuilder)79 TEST(ManifestTest, BasicBuilder) {
80 auto manifest = CreateTestManifest();
81 EXPECT_EQ(kTestServiceName, manifest.service_name);
82 EXPECT_EQ("none", manifest.options.sandbox_type);
83 EXPECT_TRUE(manifest.options.can_connect_to_instances_in_any_group);
84 EXPECT_TRUE(manifest.options.can_connect_to_instances_with_any_id);
85 EXPECT_FALSE(manifest.options.can_register_other_service_instances);
86 EXPECT_EQ(Manifest::InstanceSharingPolicy::kSharedAcrossGroups,
87 manifest.options.instance_sharing_policy);
88
89 EXPECT_EQ(2u, manifest.exposed_capabilities.size());
90 EXPECT_THAT(
91 manifest.exposed_capabilities["capability_1"],
92 ElementsAre(mojom::Connector::Name_, mojom::ProcessMetadata::Name_));
93 EXPECT_THAT(manifest.exposed_capabilities["capability_2"],
94 ElementsAre(mojom::Connector::Name_));
95
96 EXPECT_EQ(2u, manifest.required_capabilities.size());
97 EXPECT_THAT(manifest.required_capabilities["service_42"],
98 ElementsAre("computation"));
99 EXPECT_THAT(manifest.required_capabilities["frobinator"],
100 ElementsAre("frobination"));
101
102 EXPECT_EQ(1u, manifest.exposed_interface_filter_capabilities.size());
103 EXPECT_THAT(
104 manifest.exposed_interface_filter_capabilities["navigation:frame"]
105 ["filter_capability_1"],
106 ElementsAre(mojom::Connector::Name_));
107
108 EXPECT_EQ(1u, manifest.required_interface_filter_capabilities.size());
109 EXPECT_THAT(
110 manifest.required_interface_filter_capabilities["navigation:frame"]
111 ["browser"],
112 ElementsAre("another_filter_capability", "some_filter_capability"));
113
114 EXPECT_EQ(2u, manifest.packaged_services.size());
115 EXPECT_EQ(manifest.packaged_services[0].service_name,
116 GetPackagedService1Manifest().service_name);
117 EXPECT_EQ(3u, manifest.preloaded_files.size());
118 }
119
TEST(ManifestTest,Amend)120 TEST(ManifestTest, Amend) {
121 // Verify that everything is properly merged when amending potentially
122 // overlapping capability metadata.
123 Manifest manifest =
124 ManifestBuilder()
125 .ExposeCapability("cap1", {"interface1", "interface2"})
126 .RequireCapability("service1", "cap2")
127 .RequireCapability("service2", "cap3")
128 .ExposeInterfaceFilterCapability_Deprecated(
129 "filter1", "filtercap1", {"interface3", "interface4"})
130 .RequireInterfaceFilterCapability_Deprecated("service3", "filter2",
131 "filtercap2")
132 .Build();
133
134 Manifest overlay = ManifestBuilder()
135 .ExposeCapability("cap1", {"xinterface1"})
136 .ExposeCapability("xcap1", {"xinterface2"})
137 .RequireCapability("xservice1", "xcap2")
138 .ExposeInterfaceFilterCapability_Deprecated(
139 "filter1", "filtercap1", {"xinterface3"})
140 .ExposeInterfaceFilterCapability_Deprecated(
141 "xfilter1", "xfiltercap1", {"xinterface4"})
142 .RequireInterfaceFilterCapability_Deprecated(
143 "xservice2", "xfilter2", "xfiltercap2")
144 .Build();
145
146 manifest.Amend(std::move(overlay));
147
148 auto& exposed_capabilities = manifest.exposed_capabilities;
149 ASSERT_EQ(2u, exposed_capabilities.size());
150 EXPECT_THAT(exposed_capabilities["cap1"],
151 ElementsAre("interface1", "interface2", "xinterface1"));
152 EXPECT_THAT(exposed_capabilities["xcap1"], ElementsAre("xinterface2"));
153
154 auto& required_capabilities = manifest.required_capabilities;
155 ASSERT_EQ(3u, required_capabilities.size());
156 EXPECT_THAT(required_capabilities["service1"], ElementsAre("cap2"));
157 EXPECT_THAT(required_capabilities["service2"], ElementsAre("cap3"));
158 EXPECT_THAT(required_capabilities["xservice1"], ElementsAre("xcap2"));
159
160 auto& exposed_filters = manifest.exposed_interface_filter_capabilities;
161 ASSERT_EQ(2u, exposed_filters.size());
162 EXPECT_THAT(exposed_filters["filter1"]["filtercap1"],
163 ElementsAre("interface3", "interface4", "xinterface3"));
164 EXPECT_THAT(exposed_filters["xfilter1"]["xfiltercap1"],
165 ElementsAre("xinterface4"));
166
167 auto& required_filters = manifest.required_interface_filter_capabilities;
168 ASSERT_EQ(2u, required_filters.size());
169 EXPECT_THAT(required_filters["filter2"]["service3"],
170 ElementsAre("filtercap2"));
171 EXPECT_THAT(required_filters["xfilter2"]["xservice2"],
172 ElementsAre("xfiltercap2"));
173 }
174
175 } // namespace service_manager
176