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