• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "webservd/config.h"
16 
17 #include <base/files/file_util.h>
18 #include <base/files/scoped_temp_dir.h>
19 #include <base/strings/string_util.h>
20 #include <brillo/errors/error_codes.h>
21 #include <gtest/gtest.h>
22 
23 #include "webservd/error_codes.h"
24 #include "webservd/protocol_handler.h"
25 
26 namespace {
27 
28 const char kTestConfig[] = R"({
29   "protocol_handlers": [
30     {
31       "name": "ue_p2p",
32       "port": 16725,
33       "dummy_data_to_ignore": 123,
34     },
35   ],
36   "dummy_data_to_ignore2": "ignore me",
37   "log_directory": "/var/log/mylogs",
38 })";
39 
40 const char kMultipleHandlers[] = R"({
41   "protocol_handlers": [
42     {
43       "name": "http",
44       "port": 80
45     },
46     {
47       "name": "http",
48       "port": 8080
49     }
50   ]
51 })";
52 
53 const char kInvalidConfig_NotDict[] = R"({
54   "protocol_handlers": [
55     "not_a_dict"
56   ]
57 })";
58 
59 const char kInvalidConfig_NoName[] = R"({
60   "protocol_handlers": [
61     {
62       "port": 80,
63       "use_tls": true
64     }
65   ]
66 })";
67 
68 const char kInvalidConfig_NoPort[] = R"({
69   "protocol_handlers": [
70     {
71       "name": "http",
72       "use_tls": true
73     }
74   ]
75 })";
76 
77 const char kInvalidConfig_InvalidPort[] = R"({
78   "protocol_handlers": [
79     {
80       "name": "https",
81       "port": 65536
82     }
83   ]
84 })";
85 
ValidateConfig(const webservd::Config & config)86 void ValidateConfig(const webservd::Config& config) {
87   EXPECT_FALSE(config.use_debug);
88   EXPECT_EQ("/var/log/mylogs", config.log_directory);
89 
90   ASSERT_EQ(1u, config.protocol_handlers.size());
91 
92   auto it = config.protocol_handlers.begin();
93   EXPECT_EQ("ue_p2p", it->name);
94   EXPECT_EQ(16725u, it->port);
95   EXPECT_FALSE(it->use_tls);
96   EXPECT_TRUE(it->certificate.empty());
97   EXPECT_TRUE(it->certificate_fingerprint.empty());
98   EXPECT_TRUE(it->private_key.empty());
99 }
100 
101 }  // anonymous namespace
102 
103 namespace webservd {
104 
TEST(Config,LoadDefault)105 TEST(Config, LoadDefault) {
106   Config config;
107   LoadDefaultConfig(&config);
108   EXPECT_FALSE(config.use_debug);
109   EXPECT_EQ("/var/log/webservd", config.log_directory);
110 
111   ASSERT_EQ(2u, config.protocol_handlers.size());
112 
113   for (const auto& handler_config : config.protocol_handlers) {
114     if (handler_config.name == "http") {
115       EXPECT_EQ(80u, handler_config.port);
116       EXPECT_FALSE(handler_config.use_tls);
117       EXPECT_TRUE(handler_config.certificate.empty());
118       EXPECT_TRUE(handler_config.certificate_fingerprint.empty());
119       EXPECT_TRUE(handler_config.private_key.empty());
120     } else if (handler_config.name == "https") {
121       EXPECT_EQ(443u, handler_config.port);
122       EXPECT_TRUE(handler_config.use_tls);
123 
124       // TLS keys/certificates are set later in webservd::Server, not on load.
125       EXPECT_TRUE(handler_config.certificate.empty());
126       EXPECT_TRUE(handler_config.certificate_fingerprint.empty());
127       EXPECT_TRUE(handler_config.private_key.empty());
128     } else {
129       FAIL() << "Unexpected handler: " << handler_config.name;
130     }
131   }
132 }
133 
TEST(Config,LoadConfigFromString)134 TEST(Config, LoadConfigFromString) {
135   Config config;
136   ASSERT_TRUE(LoadConfigFromString(kTestConfig, &config, nullptr));
137   ValidateConfig(config);
138 }
139 
TEST(Config,LoadConfigFromFile)140 TEST(Config, LoadConfigFromFile) {
141   base::ScopedTempDir temp;
142   ASSERT_TRUE(temp.CreateUniqueTempDir());
143   base::FilePath config_path{temp.path().Append("test.config")};
144   // For the record: I hate base::WriteFile() and its usage of ints.
145   int data_len = sizeof(kTestConfig) - 1;
146   ASSERT_EQ(data_len, base::WriteFile(config_path, kTestConfig, data_len));
147 
148   Config config;
149   LoadConfigFromFile(config_path, &config);
150   ValidateConfig(config);
151 }
152 
TEST(Config,MultipleHandlers)153 TEST(Config, MultipleHandlers) {
154   Config config;
155   ASSERT_TRUE(LoadConfigFromString(kMultipleHandlers, &config, nullptr));
156   ASSERT_EQ(2u, config.protocol_handlers.size());
157 
158   auto it = config.protocol_handlers.begin();
159   EXPECT_EQ("http", it->name);
160   EXPECT_EQ(80, it->port);
161   ++it;
162   EXPECT_EQ("http", it->name);
163   EXPECT_EQ(8080, it->port);
164 }
165 
TEST(Config,ParseError_ProtocolHandlersNotDict)166 TEST(Config, ParseError_ProtocolHandlersNotDict) {
167   brillo::ErrorPtr error;
168   Config config;
169   ASSERT_FALSE(LoadConfigFromString(kInvalidConfig_NotDict, &config, &error));
170   EXPECT_EQ(brillo::errors::json::kDomain, error->GetDomain());
171   EXPECT_EQ(brillo::errors::json::kObjectExpected, error->GetCode());
172   EXPECT_EQ("Protocol handler definition must be a JSON object",
173             error->GetMessage());
174 }
175 
TEST(Config,ParseError_NoName)176 TEST(Config, ParseError_NoName) {
177   brillo::ErrorPtr error;
178   Config config;
179   ASSERT_FALSE(LoadConfigFromString(kInvalidConfig_NoName, &config, &error));
180   EXPECT_EQ(webservd::errors::kDomain, error->GetDomain());
181   EXPECT_EQ(webservd::errors::kInvalidConfig, error->GetCode());
182   EXPECT_EQ("Protocol handler definition must include its name",
183             error->GetMessage());
184 }
185 
TEST(Config,ParseError_NoPort)186 TEST(Config, ParseError_NoPort) {
187   brillo::ErrorPtr error;
188   Config config;
189   ASSERT_FALSE(LoadConfigFromString(kInvalidConfig_NoPort, &config, &error));
190   EXPECT_EQ(webservd::errors::kDomain, error->GetDomain());
191   EXPECT_EQ(webservd::errors::kInvalidConfig, error->GetCode());
192   EXPECT_EQ("Unable to parse config for protocol handler 'http'",
193             error->GetMessage());
194   EXPECT_EQ(webservd::errors::kDomain, error->GetInnerError()->GetDomain());
195   EXPECT_EQ(webservd::errors::kInvalidConfig,
196             error->GetInnerError()->GetCode());
197   EXPECT_EQ("Port is missing", error->GetInnerError()->GetMessage());
198 }
199 
TEST(Config,ParseError_InvalidPort)200 TEST(Config, ParseError_InvalidPort) {
201   brillo::ErrorPtr error;
202   Config config;
203   ASSERT_FALSE(LoadConfigFromString(kInvalidConfig_InvalidPort, &config,
204                &error));
205   EXPECT_EQ(webservd::errors::kDomain, error->GetDomain());
206   EXPECT_EQ(webservd::errors::kInvalidConfig, error->GetCode());
207   EXPECT_EQ("Unable to parse config for protocol handler 'https'",
208             error->GetMessage());
209   EXPECT_EQ(webservd::errors::kDomain, error->GetInnerError()->GetDomain());
210   EXPECT_EQ(webservd::errors::kInvalidConfig,
211             error->GetInnerError()->GetCode());
212   EXPECT_EQ("Invalid port value: 65536", error->GetInnerError()->GetMessage());
213 }
214 
215 }  // namespace webservd
216