| // Copyright 2015 The Chromium OS 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 "webservd/config.h" |
| |
| #include <base/files/file_util.h> |
| #include <base/files/scoped_temp_dir.h> |
| #include <base/strings/string_util.h> |
| #include <brillo/errors/error_codes.h> |
| #include <gtest/gtest.h> |
| |
| #include "webservd/error_codes.h" |
| #include "webservd/protocol_handler.h" |
| |
| namespace { |
| |
| const char kTestConfig[] = R"({ |
| "protocol_handlers": [ |
| { |
| "name": "ue_p2p", |
| "port": 16725, |
| "dummy_data_to_ignore": 123, |
| }, |
| ], |
| "dummy_data_to_ignore2": "ignore me", |
| "log_directory": "/var/log/mylogs", |
| })"; |
| |
| const char kMultipleHandlers[] = R"({ |
| "protocol_handlers": [ |
| { |
| "name": "http", |
| "port": 80 |
| }, |
| { |
| "name": "http", |
| "port": 8080 |
| } |
| ] |
| })"; |
| |
| const char kInvalidConfig_NotDict[] = R"({ |
| "protocol_handlers": [ |
| "not_a_dict" |
| ] |
| })"; |
| |
| const char kInvalidConfig_NoName[] = R"({ |
| "protocol_handlers": [ |
| { |
| "port": 80, |
| "use_tls": true |
| } |
| ] |
| })"; |
| |
| const char kInvalidConfig_NoPort[] = R"({ |
| "protocol_handlers": [ |
| { |
| "name": "http", |
| "use_tls": true |
| } |
| ] |
| })"; |
| |
| const char kInvalidConfig_InvalidPort[] = R"({ |
| "protocol_handlers": [ |
| { |
| "name": "https", |
| "port": 65536 |
| } |
| ] |
| })"; |
| |
| void ValidateConfig(const webservd::Config& config) { |
| EXPECT_FALSE(config.use_debug); |
| EXPECT_EQ("/var/log/mylogs", config.log_directory); |
| |
| ASSERT_EQ(1u, config.protocol_handlers.size()); |
| |
| auto it = config.protocol_handlers.begin(); |
| EXPECT_EQ("ue_p2p", it->name); |
| EXPECT_EQ(16725u, it->port); |
| EXPECT_FALSE(it->use_tls); |
| EXPECT_TRUE(it->certificate.empty()); |
| EXPECT_TRUE(it->certificate_fingerprint.empty()); |
| EXPECT_TRUE(it->private_key.empty()); |
| } |
| |
| } // anonymous namespace |
| |
| namespace webservd { |
| |
| TEST(Config, LoadDefault) { |
| Config config; |
| LoadDefaultConfig(&config); |
| EXPECT_FALSE(config.use_debug); |
| EXPECT_EQ("/var/log/webservd", config.log_directory); |
| |
| ASSERT_EQ(2u, config.protocol_handlers.size()); |
| |
| for (const auto& handler_config : config.protocol_handlers) { |
| if (handler_config.name == "http") { |
| EXPECT_EQ(80u, handler_config.port); |
| EXPECT_FALSE(handler_config.use_tls); |
| EXPECT_TRUE(handler_config.certificate.empty()); |
| EXPECT_TRUE(handler_config.certificate_fingerprint.empty()); |
| EXPECT_TRUE(handler_config.private_key.empty()); |
| } else if (handler_config.name == "https") { |
| EXPECT_EQ(443u, handler_config.port); |
| EXPECT_TRUE(handler_config.use_tls); |
| |
| // TLS keys/certificates are set later in webservd::Server, not on load. |
| EXPECT_TRUE(handler_config.certificate.empty()); |
| EXPECT_TRUE(handler_config.certificate_fingerprint.empty()); |
| EXPECT_TRUE(handler_config.private_key.empty()); |
| } else { |
| FAIL() << "Unexpected handler: " << handler_config.name; |
| } |
| } |
| } |
| |
| TEST(Config, LoadConfigFromString) { |
| Config config; |
| ASSERT_TRUE(LoadConfigFromString(kTestConfig, &config, nullptr)); |
| ValidateConfig(config); |
| } |
| |
| TEST(Config, LoadConfigFromFile) { |
| base::ScopedTempDir temp; |
| ASSERT_TRUE(temp.CreateUniqueTempDir()); |
| base::FilePath config_path{temp.GetPath().Append("test.config")}; |
| // For the record: I hate base::WriteFile() and its usage of ints. |
| int data_len = sizeof(kTestConfig) - 1; |
| ASSERT_EQ(data_len, base::WriteFile(config_path, kTestConfig, data_len)); |
| |
| Config config; |
| LoadConfigFromFile(config_path, &config); |
| ValidateConfig(config); |
| } |
| |
| TEST(Config, MultipleHandlers) { |
| Config config; |
| ASSERT_TRUE(LoadConfigFromString(kMultipleHandlers, &config, nullptr)); |
| ASSERT_EQ(2u, config.protocol_handlers.size()); |
| |
| auto it = config.protocol_handlers.begin(); |
| EXPECT_EQ("http", it->name); |
| EXPECT_EQ(80, it->port); |
| ++it; |
| EXPECT_EQ("http", it->name); |
| EXPECT_EQ(8080, it->port); |
| } |
| |
| TEST(Config, ParseError_ProtocolHandlersNotDict) { |
| brillo::ErrorPtr error; |
| Config config; |
| ASSERT_FALSE(LoadConfigFromString(kInvalidConfig_NotDict, &config, &error)); |
| EXPECT_EQ(brillo::errors::json::kDomain, error->GetDomain()); |
| EXPECT_EQ(brillo::errors::json::kObjectExpected, error->GetCode()); |
| EXPECT_EQ("Protocol handler definition must be a JSON object", |
| error->GetMessage()); |
| } |
| |
| TEST(Config, ParseError_NoName) { |
| brillo::ErrorPtr error; |
| Config config; |
| ASSERT_FALSE(LoadConfigFromString(kInvalidConfig_NoName, &config, &error)); |
| EXPECT_EQ(webservd::errors::kDomain, error->GetDomain()); |
| EXPECT_EQ(webservd::errors::kInvalidConfig, error->GetCode()); |
| EXPECT_EQ("Protocol handler definition must include its name", |
| error->GetMessage()); |
| } |
| |
| TEST(Config, ParseError_NoPort) { |
| brillo::ErrorPtr error; |
| Config config; |
| ASSERT_FALSE(LoadConfigFromString(kInvalidConfig_NoPort, &config, &error)); |
| EXPECT_EQ(webservd::errors::kDomain, error->GetDomain()); |
| EXPECT_EQ(webservd::errors::kInvalidConfig, error->GetCode()); |
| EXPECT_EQ("Unable to parse config for protocol handler 'http'", |
| error->GetMessage()); |
| EXPECT_EQ(webservd::errors::kDomain, error->GetInnerError()->GetDomain()); |
| EXPECT_EQ(webservd::errors::kInvalidConfig, |
| error->GetInnerError()->GetCode()); |
| EXPECT_EQ("Port is missing", error->GetInnerError()->GetMessage()); |
| } |
| |
| TEST(Config, ParseError_InvalidPort) { |
| brillo::ErrorPtr error; |
| Config config; |
| ASSERT_FALSE( |
| LoadConfigFromString(kInvalidConfig_InvalidPort, &config, &error)); |
| EXPECT_EQ(webservd::errors::kDomain, error->GetDomain()); |
| EXPECT_EQ(webservd::errors::kInvalidConfig, error->GetCode()); |
| EXPECT_EQ("Unable to parse config for protocol handler 'https'", |
| error->GetMessage()); |
| EXPECT_EQ(webservd::errors::kDomain, error->GetInnerError()->GetDomain()); |
| EXPECT_EQ(webservd::errors::kInvalidConfig, |
| error->GetInnerError()->GetCode()); |
| EXPECT_EQ("Invalid port value: 65536", error->GetInnerError()->GetMessage()); |
| } |
| |
| } // namespace webservd |