blob: ba79a56d0c6cd8b4ae396a481bbd0fd106e78edf [file] [log] [blame]
/*
* Copyright 2014 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Author: morlovich@google.com (Maksim Orlovich)
#include "pagespeed/system/system_rewrite_options.h"
#include <functional>
#include "net/instaweb/rewriter/public/rewrite_options_test_base.h"
#include "pagespeed/kernel/base/google_message_handler.h"
#include "pagespeed/kernel/base/gtest.h"
#include "pagespeed/kernel/base/null_thread_system.h"
#include "pagespeed/kernel/base/scoped_ptr.h"
namespace net_instaweb {
class SystemRewriteOptionsTest
: public RewriteOptionsTestBase<SystemRewriteOptions> {
protected:
SystemRewriteOptionsTest() : options_("test", &thread_system_) {
}
// Helper for testing options consisting of single integer. Validates that
// setting an option with option_name changes return value of getter and that
// errors are reported on incorrect values.
void TestIntOption(const char* option_name,
std::function<int(SystemRewriteOptions*)> getter) {
GoogleString msg;
RewriteOptions::OptionSettingResult result =
options_.ParseAndSetOptionFromName1(
option_name, "1234", &msg,
&handler_);
EXPECT_EQ(result, RewriteOptions::kOptionOk);
EXPECT_EQ(1234, getter(&options_));
EXPECT_EQ("", msg);
result = options_.ParseAndSetOptionFromName1(
option_name, "1a", &msg, &handler_);
EXPECT_EQ(result, RewriteOptions::kOptionValueInvalid);
EXPECT_EQ(1234, getter(&options_));
EXPECT_NE("", msg);
}
void TestExternalCacheSingleOption(
const char* option_name,
std::function<ExternalServerSpec(SystemRewriteOptions*)> getter,
int default_port) {
EXPECT_TRUE(getter(&options_).empty());
GoogleString msg;
{
auto result = options_.ParseAndSetOptionFromName1(
option_name, "host1:1234", &msg, &handler_);
EXPECT_EQ(result, RewriteOptions::kOptionOk);
EXPECT_EQ(msg, "");
const ExternalServerSpec &spec = getter(&options_);
EXPECT_EQ("host1", spec.host);
EXPECT_EQ(1234, spec.port);
}
{
auto result = options_.ParseAndSetOptionFromName1(
option_name, "host5:port", &msg, &handler_);
EXPECT_EQ(result, RewriteOptions::kOptionValueInvalid);
EXPECT_NE(msg, "");
const ExternalServerSpec &spec = getter(&options_);
// No data was overwritten
EXPECT_EQ("host1", spec.host);
EXPECT_EQ(1234, spec.port);
}
}
void TestExternalCacheMultipleOption(
const char* option_name,
std::function<ExternalClusterSpec(SystemRewriteOptions*)> getter,
int default_port) {
EXPECT_TRUE(getter(&options_).empty());
EXPECT_EQ(0, getter(&options_).servers.size());
GoogleString msg;
{
auto result = options_.ParseAndSetOptionFromName1(
option_name, "host1:1234,host2,host3:4567", &msg, &handler_);
EXPECT_EQ(result, RewriteOptions::kOptionOk);
EXPECT_EQ(msg, "");
const ExternalClusterSpec &spec = getter(&options_);
ASSERT_EQ(3, spec.servers.size());
EXPECT_EQ("host1", spec.servers[0].host);
EXPECT_EQ(1234, spec.servers[0].port);
EXPECT_EQ("host2", spec.servers[1].host);
EXPECT_EQ(default_port, spec.servers[1].port);
EXPECT_EQ("host3", spec.servers[2].host);
EXPECT_EQ(4567, spec.servers[2].port);
}
{
auto result = options_.ParseAndSetOptionFromName1(
option_name, "host4,host5:port", &msg, &handler_);
EXPECT_EQ(result, RewriteOptions::kOptionValueInvalid);
EXPECT_NE(msg, "");
const ExternalClusterSpec &spec = getter(&options_);
// No data was overwritten
ASSERT_EQ(3, spec.servers.size());
EXPECT_EQ("host1", spec.servers[0].host);
EXPECT_EQ(1234, spec.servers[0].port);
EXPECT_EQ("host2", spec.servers[1].host);
EXPECT_EQ(default_port, spec.servers[1].port);
EXPECT_EQ("host3", spec.servers[2].host);
EXPECT_EQ(4567, spec.servers[2].port);
}
}
NullThreadSystem thread_system_;
GoogleMessageHandler handler_;
SystemRewriteOptions options_;
};
TEST_F(SystemRewriteOptionsTest, StaticAssetCdn) {
// Check parsing.
EXPECT_FALSE(options_.has_static_assets_to_cdn());
GoogleString msg;
RewriteOptions::OptionSettingResult result =
options_.ParseAndSetOptionFromName1(
SystemRewriteOptions::kStaticAssetCDN, "foo.com", &msg, &handler_);
EXPECT_EQ(result, RewriteOptions::kOptionValueInvalid);
EXPECT_EQ("Cannot set option StaticAssetCDN to foo.com. "
"Not enough arguments.", msg);
EXPECT_FALSE(options_.has_static_assets_to_cdn());
result = options_.ParseAndSetOptionFromName1(
SystemRewriteOptions::kStaticAssetCDN, "foo.com, Weird", &msg, &handler_);
EXPECT_EQ(result, RewriteOptions::kOptionValueInvalid);
EXPECT_EQ("Cannot set option StaticAssetCDN to foo.com, Weird. "
"Invalid static asset label: Weird",
msg);
EXPECT_FALSE(options_.has_static_assets_to_cdn());
result = options_.ParseAndSetOptionFromName1(
SystemRewriteOptions::kStaticAssetCDN,
"//foo.com, ADD_INSTRUMENTATION_JS, BLANK_GIF", &msg, &handler_);
EXPECT_EQ(result, RewriteOptions::kOptionOk) << msg;
EXPECT_TRUE(options_.has_static_assets_to_cdn());
EXPECT_EQ("//foo.com", options_.static_assets_cdn_base());
const SystemRewriteOptions::StaticAssetSet& assets =
options_.static_assets_to_cdn();
EXPECT_EQ(2, assets.size());
EXPECT_TRUE(assets.find(StaticAssetEnum::ADD_INSTRUMENTATION_JS) !=
assets.end());
EXPECT_TRUE(assets.find(StaticAssetEnum::BLANK_GIF) !=
assets.end());
// Check conversion into proto.
StaticAssetConfig proto_conf;
options_.FillInStaticAssetCDNConf(&proto_conf);
ASSERT_EQ(2, proto_conf.asset_size());
const StaticAssetConfig::Asset& a1 = proto_conf.asset(0);
EXPECT_EQ(StaticAssetEnum::ADD_INSTRUMENTATION_JS, a1.role());
EXPECT_EQ("add_instrumentation.js", a1.name());
EXPECT_EQ("opt", a1.opt_hash());
EXPECT_EQ("dbg", a1.debug_hash());
const StaticAssetConfig::Asset& a2 = proto_conf.asset(1);
EXPECT_EQ(StaticAssetEnum::BLANK_GIF, a2.role());
EXPECT_EQ("blank.gif", a2.name());
EXPECT_EQ("opt", a2.opt_hash());
EXPECT_EQ("dbg", a2.debug_hash());
// Test merging.
// Merge of something w/o these options.
scoped_ptr<SystemRewriteOptions> options2(
new SystemRewriteOptions(&thread_system_));
options_.Merge(*options2);
EXPECT_TRUE(options_.has_static_assets_to_cdn());
EXPECT_EQ("//foo.com", options_.static_assets_cdn_base());
const SystemRewriteOptions::StaticAssetSet& assets2 =
options_.static_assets_to_cdn();
EXPECT_EQ(2, assets2.size());
EXPECT_TRUE(assets2.find(StaticAssetEnum::ADD_INSTRUMENTATION_JS) !=
assets2.end());
EXPECT_TRUE(assets2.find(StaticAssetEnum::BLANK_GIF) !=
assets2.end());
// Merge of something with the same path --- overwrites both.
scoped_ptr<SystemRewriteOptions> options3(
new SystemRewriteOptions(&thread_system_));
result = options3->ParseAndSetOptionFromName1(
SystemRewriteOptions::kStaticAssetCDN,
"//foo.com, BLANK_GIF, MOBILIZE_JS", &msg, &handler_);
ASSERT_EQ(result, RewriteOptions::kOptionOk) << msg;
options_.Merge(*options3);
EXPECT_TRUE(options_.has_static_assets_to_cdn());
EXPECT_EQ("//foo.com", options_.static_assets_cdn_base());
const SystemRewriteOptions::StaticAssetSet& assets3 =
options_.static_assets_to_cdn();
EXPECT_EQ(2, assets3.size());
EXPECT_TRUE(assets3.find(StaticAssetEnum::BLANK_GIF) != assets3.end());
EXPECT_TRUE(assets3.find(StaticAssetEnum::MOBILIZE_JS) != assets3.end());
// Merge of something with different path --- overwrites as well.
scoped_ptr<SystemRewriteOptions> options4(
new SystemRewriteOptions(&thread_system_));
result = options4->ParseAndSetOptionFromName1(
SystemRewriteOptions::kStaticAssetCDN,
"//bar.com, MOBILIZE_JS", &msg, &handler_);
ASSERT_EQ(result, RewriteOptions::kOptionOk) << msg;
options_.Merge(*options4);
EXPECT_TRUE(options_.has_static_assets_to_cdn());
EXPECT_EQ("//bar.com", options_.static_assets_cdn_base());
const SystemRewriteOptions::StaticAssetSet& assets4 =
options_.static_assets_to_cdn();
EXPECT_EQ(1, assets4.size());
EXPECT_TRUE(assets4.find(StaticAssetEnum::MOBILIZE_JS) != assets4.end());
}
TEST_F(SystemRewriteOptionsTest, CentralControllerInitValue) {
EXPECT_EQ("", options_.controller_port());
}
TEST_F(SystemRewriteOptionsTest, CentralControllerTcpPort) {
GoogleString msg;
EXPECT_EQ(options_.ParseAndSetOptionFromName1(
SystemRewriteOptions::kCentralControllerPort, "1234", &msg,
&handler_), RewriteOptions::kOptionOk);
EXPECT_EQ(options_.controller_port(), "localhost:1234");
EXPECT_EQ("", msg);
}
TEST_F(SystemRewriteOptionsTest, CentralControllerUnixPort) {
GoogleString msg;
EXPECT_EQ(options_.ParseAndSetOptionFromName1(
SystemRewriteOptions::kCentralControllerPort, "unix:a", &msg,
&handler_), RewriteOptions::kOptionOk);
EXPECT_EQ(options_.controller_port(), "unix:a");
EXPECT_EQ("", msg);
}
TEST_F(SystemRewriteOptionsTest, CentralControllerTooShortUnixPort) {
GoogleString msg;
EXPECT_EQ(options_.ParseAndSetOptionFromName1(
SystemRewriteOptions::kCentralControllerPort, "unix:", &msg,
&handler_), RewriteOptions::kOptionValueInvalid);
EXPECT_EQ(options_.controller_port(), "");
EXPECT_NE("", msg);
}
TEST_F(SystemRewriteOptionsTest, CentralControllerBadTcpPort) {
GoogleString msg;
EXPECT_EQ(options_.ParseAndSetOptionFromName1(
SystemRewriteOptions::kCentralControllerPort, "123a", &msg,
&handler_), RewriteOptions::kOptionValueInvalid);
EXPECT_EQ(options_.controller_port(), "");
EXPECT_NE("", msg);
}
TEST_F(SystemRewriteOptionsTest, RedisServer) {
TestExternalCacheSingleOption(SystemRewriteOptions::kRedisServer,
&SystemRewriteOptions::redis_server,
SystemRewriteOptions::kRedisDefaultPort);
}
TEST_F(SystemRewriteOptionsTest, MemcachedServer) {
TestExternalCacheMultipleOption(SystemRewriteOptions::kMemcachedServers,
&SystemRewriteOptions::memcached_servers,
SystemRewriteOptions::kMemcachedDefaultPort);
}
TEST_F(SystemRewriteOptionsTest, RedisReconnectionDelayInitValue) {
EXPECT_GT(options_.redis_reconnection_delay_ms(), 0);
}
TEST_F(SystemRewriteOptionsTest, RedisReconnectionDelay) {
TestIntOption(SystemRewriteOptions::kRedisReconnectionDelayMs,
&SystemRewriteOptions::redis_reconnection_delay_ms);
}
TEST_F(SystemRewriteOptionsTest, RedisTimeoutInitValue) {
EXPECT_GT(options_.redis_timeout_us(), 0);
}
TEST_F(SystemRewriteOptionsTest, RedisTimeout) {
TestIntOption(SystemRewriteOptions::kRedisTimeoutUs,
&SystemRewriteOptions::redis_timeout_us);
}
} // namespace net_instaweb