| // Copyright 2015 The Chromium 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 "components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h" |
| |
| #include "base/message_loop/message_loop.h" |
| #include "base/prefs/testing_pref_service.h" |
| #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.h" |
| #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client.h" |
| #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.h" |
| #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator_test_utils.h" |
| #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor.h" |
| #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_mutable_config_values.h" |
| #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.h" |
| #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs.h" |
| #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h" |
| #include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_store.h" |
| #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h" |
| #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.h" |
| #include "net/socket/socket_test_util.h" |
| #include "net/url_request/url_request_context_storage.h" |
| #include "net/url_request/url_request_intercepting_job_factory.h" |
| #include "net/url_request/url_request_job_factory_impl.h" |
| #include "net/url_request/url_request_test_util.h" |
| |
| namespace { |
| |
| const char kTestKey[] = "test-key"; |
| |
| const net::BackoffEntry::Policy kTestBackoffPolicy = { |
| 0, // num_errors_to_ignore |
| 10 * 1000, // initial_delay_ms |
| 2, // multiply_factor |
| 0, // jitter_factor |
| 30 * 60 * 1000, // maximum_backoff_ms |
| -1, // entry_lifetime_ms |
| true, // always_use_initial_delay |
| }; |
| |
| } // namespace |
| |
| namespace data_reduction_proxy { |
| |
| TestDataReductionProxyRequestOptions::TestDataReductionProxyRequestOptions( |
| Client client, |
| const std::string& version, |
| DataReductionProxyConfig* config) |
| : DataReductionProxyRequestOptions(client, version, config) { |
| } |
| |
| std::string TestDataReductionProxyRequestOptions::GetDefaultKey() const { |
| return kTestKey; |
| } |
| |
| base::Time TestDataReductionProxyRequestOptions::Now() const { |
| return base::Time::UnixEpoch() + now_offset_; |
| } |
| |
| void TestDataReductionProxyRequestOptions::RandBytes(void* output, |
| size_t length) const { |
| char* c = static_cast<char*>(output); |
| for (size_t i = 0; i < length; ++i) { |
| c[i] = 'a'; |
| } |
| } |
| |
| // Time after the unix epoch that Now() reports. |
| void TestDataReductionProxyRequestOptions::set_offset( |
| const base::TimeDelta& now_offset) { |
| now_offset_ = now_offset; |
| } |
| |
| MockDataReductionProxyRequestOptions::MockDataReductionProxyRequestOptions( |
| Client client, |
| const std::string& version, |
| DataReductionProxyConfig* config) |
| : DataReductionProxyRequestOptions(client, version, config) { |
| } |
| |
| MockDataReductionProxyRequestOptions::~MockDataReductionProxyRequestOptions() { |
| } |
| |
| TestDataReductionProxyConfigServiceClient:: |
| TestDataReductionProxyConfigServiceClient( |
| scoped_ptr<DataReductionProxyParams> params, |
| DataReductionProxyRequestOptions* request_options, |
| DataReductionProxyMutableConfigValues* config_values, |
| DataReductionProxyConfig* config) |
| : DataReductionProxyConfigServiceClient(params.Pass(), |
| kTestBackoffPolicy, |
| request_options, |
| config_values, |
| config), |
| tick_clock_(base::Time::UnixEpoch()), |
| test_backoff_entry_(&kTestBackoffPolicy, &tick_clock_) { |
| } |
| |
| TestDataReductionProxyConfigServiceClient:: |
| ~TestDataReductionProxyConfigServiceClient() { |
| } |
| |
| void TestDataReductionProxyConfigServiceClient::SetNow(const base::Time& time) { |
| tick_clock_.SetTime(time); |
| } |
| |
| void TestDataReductionProxyConfigServiceClient::SetCustomReleaseTime( |
| const base::TimeTicks& release_time) { |
| test_backoff_entry_.SetCustomReleaseTime(release_time); |
| } |
| |
| base::TimeDelta TestDataReductionProxyConfigServiceClient::GetDelay() const { |
| return config_refresh_timer_.GetCurrentDelay(); |
| } |
| |
| base::Time TestDataReductionProxyConfigServiceClient::Now() { |
| return tick_clock_.Now(); |
| } |
| |
| net::BackoffEntry* |
| TestDataReductionProxyConfigServiceClient::GetBackoffEntry() { |
| return &test_backoff_entry_; |
| } |
| |
| TestDataReductionProxyConfigServiceClient::TestTickClock::TestTickClock( |
| const base::Time& initial_time) |
| : time_(initial_time) { |
| } |
| |
| base::TimeTicks |
| TestDataReductionProxyConfigServiceClient::TestTickClock::NowTicks() { |
| return base::TimeTicks::UnixEpoch() + (time_ - base::Time::UnixEpoch()); |
| } |
| |
| base::Time |
| TestDataReductionProxyConfigServiceClient::TestTickClock::Now() { |
| return time_; |
| } |
| |
| void TestDataReductionProxyConfigServiceClient::TestTickClock::SetTime( |
| const base::Time& time) { |
| time_ = time; |
| } |
| |
| MockDataReductionProxyService::MockDataReductionProxyService( |
| scoped_ptr<DataReductionProxyCompressionStats> compression_stats, |
| DataReductionProxySettings* settings, |
| net::URLRequestContextGetter* request_context, |
| scoped_refptr<base::SingleThreadTaskRunner> io_task_runner) |
| : DataReductionProxyService( |
| compression_stats.Pass(), settings, request_context, io_task_runner) { |
| } |
| |
| MockDataReductionProxyService::~MockDataReductionProxyService() { |
| } |
| |
| TestDataReductionProxyIOData::TestDataReductionProxyIOData( |
| scoped_refptr<base::SingleThreadTaskRunner> task_runner, |
| scoped_ptr<DataReductionProxyConfig> config, |
| scoped_ptr<DataReductionProxyEventStore> event_store, |
| scoped_ptr<DataReductionProxyRequestOptions> request_options, |
| scoped_ptr<DataReductionProxyConfigurator> configurator, |
| scoped_ptr<DataReductionProxyConfigServiceClient> config_client) |
| : DataReductionProxyIOData() { |
| io_task_runner_ = task_runner; |
| ui_task_runner_ = task_runner; |
| config_ = config.Pass(); |
| event_store_ = event_store.Pass(); |
| request_options_ = request_options.Pass(); |
| configurator_ = configurator.Pass(); |
| config_client_ = config_client.Pass(); |
| bypass_stats_.reset(new DataReductionProxyBypassStats( |
| config_.get(), base::Bind(&DataReductionProxyIOData::SetUnreachable, |
| base::Unretained(this)))); |
| io_task_runner_ = task_runner; |
| ui_task_runner_ = task_runner; |
| } |
| |
| TestDataReductionProxyIOData::~TestDataReductionProxyIOData() { |
| shutdown_on_ui_ = true; |
| } |
| |
| DataReductionProxyTestContext::Builder::Builder() |
| : params_flags_(0), |
| params_definitions_(0), |
| client_(Client::UNKNOWN), |
| request_context_(nullptr), |
| mock_socket_factory_(nullptr), |
| use_mock_config_(false), |
| use_test_configurator_(false), |
| use_mock_service_(false), |
| use_mock_request_options_(false), |
| use_config_client_(false), |
| use_test_config_client_(false), |
| skip_settings_initialization_(false) { |
| } |
| |
| DataReductionProxyTestContext::Builder& |
| DataReductionProxyTestContext::Builder::WithParamsFlags(int params_flags) { |
| params_flags_ = params_flags; |
| return *this; |
| } |
| |
| DataReductionProxyTestContext::Builder& |
| DataReductionProxyTestContext::Builder::WithParamsDefinitions( |
| unsigned int params_definitions) { |
| params_definitions_ = params_definitions; |
| return *this; |
| } |
| |
| DataReductionProxyTestContext::Builder& |
| DataReductionProxyTestContext::Builder::WithURLRequestContext( |
| net::URLRequestContext* request_context) { |
| request_context_ = request_context; |
| return *this; |
| } |
| |
| DataReductionProxyTestContext::Builder& |
| DataReductionProxyTestContext::Builder::WithMockClientSocketFactory( |
| net::MockClientSocketFactory* mock_socket_factory) { |
| mock_socket_factory_ = mock_socket_factory; |
| return *this; |
| } |
| |
| DataReductionProxyTestContext::Builder& |
| DataReductionProxyTestContext::Builder::WithClient(Client client) { |
| client_ = client; |
| return *this; |
| } |
| |
| DataReductionProxyTestContext::Builder& |
| DataReductionProxyTestContext::Builder::WithMockConfig() { |
| use_mock_config_ = true; |
| return *this; |
| } |
| |
| DataReductionProxyTestContext::Builder& |
| DataReductionProxyTestContext::Builder::WithTestConfigurator() { |
| use_test_configurator_ = true; |
| return *this; |
| } |
| |
| DataReductionProxyTestContext::Builder& |
| DataReductionProxyTestContext::Builder::WithMockDataReductionProxyService() { |
| use_mock_service_ = true; |
| return *this; |
| } |
| |
| DataReductionProxyTestContext::Builder& |
| DataReductionProxyTestContext::Builder::WithMockRequestOptions() { |
| use_mock_request_options_ = true; |
| return *this; |
| } |
| |
| DataReductionProxyTestContext::Builder& |
| DataReductionProxyTestContext::Builder::WithConfigClient() { |
| use_config_client_ = true; |
| return *this; |
| } |
| |
| DataReductionProxyTestContext::Builder& |
| DataReductionProxyTestContext::Builder::WithTestConfigClient() { |
| use_config_client_ = true; |
| use_test_config_client_ = true; |
| return *this; |
| } |
| |
| DataReductionProxyTestContext::Builder& |
| DataReductionProxyTestContext::Builder::SkipSettingsInitialization() { |
| skip_settings_initialization_ = true; |
| return *this; |
| } |
| |
| scoped_ptr<DataReductionProxyTestContext> |
| DataReductionProxyTestContext::Builder::Build() { |
| // Check for invalid builder combinations. |
| DCHECK(!(use_mock_config_ && use_config_client_)); |
| scoped_ptr<base::MessageLoopForIO> loop(new base::MessageLoopForIO()); |
| |
| unsigned int test_context_flags = 0; |
| scoped_refptr<base::SingleThreadTaskRunner> task_runner = |
| base::MessageLoopProxy::current(); |
| scoped_refptr<net::URLRequestContextGetter> request_context_getter; |
| scoped_ptr<TestingPrefServiceSimple> pref_service( |
| new TestingPrefServiceSimple()); |
| scoped_ptr<net::TestNetLog> net_log(new net::TestNetLog()); |
| if (request_context_) { |
| request_context_getter = new net::TrivialURLRequestContextGetter( |
| request_context_, task_runner); |
| } else { |
| scoped_ptr<net::TestURLRequestContext> test_request_context( |
| new net::TestURLRequestContext(true)); |
| if (mock_socket_factory_) |
| test_request_context->set_client_socket_factory(mock_socket_factory_); |
| test_request_context->Init(); |
| request_context_getter = new net::TestURLRequestContextGetter( |
| task_runner, test_request_context.Pass()); |
| } |
| |
| scoped_ptr<DataReductionProxyEventStore> event_store( |
| new DataReductionProxyEventStore(task_runner)); |
| scoped_ptr<DataReductionProxyConfigurator> configurator; |
| if (use_test_configurator_) { |
| test_context_flags |= USE_TEST_CONFIGURATOR; |
| configurator.reset(new TestDataReductionProxyConfigurator( |
| net_log.get(), event_store.get())); |
| } else { |
| configurator.reset( |
| new DataReductionProxyConfigurator(net_log.get(), event_store.get())); |
| } |
| |
| scoped_ptr<TestDataReductionProxyConfig> config; |
| scoped_ptr<DataReductionProxyConfigServiceClient> config_client; |
| DataReductionProxyMutableConfigValues* raw_mutable_config = nullptr; |
| scoped_ptr<TestDataReductionProxyParams> params( |
| new TestDataReductionProxyParams(params_flags_, params_definitions_)); |
| TestDataReductionProxyParams* raw_params = params.get(); |
| if (use_config_client_) { |
| test_context_flags |= USE_CONFIG_CLIENT; |
| scoped_ptr<DataReductionProxyMutableConfigValues> mutable_config = |
| DataReductionProxyMutableConfigValues::CreateFromParams(params.get()); |
| raw_mutable_config = mutable_config.get(); |
| config.reset(new TestDataReductionProxyConfig( |
| mutable_config.Pass(), task_runner, net_log.get(), configurator.get(), |
| event_store.get())); |
| } else if (use_mock_config_) { |
| test_context_flags |= USE_MOCK_CONFIG; |
| config.reset(new MockDataReductionProxyConfig( |
| params.Pass(), task_runner, net_log.get(), configurator.get(), |
| event_store.get())); |
| } else { |
| config.reset(new TestDataReductionProxyConfig( |
| params.Pass(), task_runner, net_log.get(), configurator.get(), |
| event_store.get())); |
| } |
| |
| scoped_ptr<DataReductionProxyRequestOptions> request_options; |
| if (use_mock_request_options_) { |
| test_context_flags |= USE_MOCK_REQUEST_OPTIONS; |
| request_options.reset(new MockDataReductionProxyRequestOptions( |
| client_, std::string(), config.get())); |
| } else { |
| request_options.reset( |
| new DataReductionProxyRequestOptions(client_, config.get())); |
| } |
| |
| if (use_test_config_client_) { |
| test_context_flags |= USE_TEST_CONFIG_CLIENT; |
| config_client.reset(new TestDataReductionProxyConfigServiceClient( |
| params.Pass(), request_options.get(), raw_mutable_config, |
| config.get())); |
| } else if (use_config_client_) { |
| config_client.reset(new DataReductionProxyConfigServiceClient( |
| params.Pass(), GetBackoffPolicy(), request_options.get(), |
| raw_mutable_config, config.get())); |
| } |
| |
| scoped_ptr<DataReductionProxySettings> settings( |
| new DataReductionProxySettings()); |
| if (skip_settings_initialization_) |
| test_context_flags |= SKIP_SETTINGS_INITIALIZATION; |
| |
| if (use_mock_service_) |
| test_context_flags |= USE_MOCK_SERVICE; |
| |
| RegisterSimpleProfilePrefs(pref_service->registry()); |
| |
| scoped_ptr<TestDataReductionProxyIOData> io_data( |
| new TestDataReductionProxyIOData( |
| task_runner, config.Pass(), event_store.Pass(), |
| request_options.Pass(), configurator.Pass(), config_client.Pass())); |
| io_data->InitOnUIThread(pref_service.get()); |
| |
| scoped_ptr<DataReductionProxyTestContext> test_context( |
| new DataReductionProxyTestContext( |
| loop.Pass(), task_runner, pref_service.Pass(), net_log.Pass(), |
| request_context_getter, mock_socket_factory_, io_data.Pass(), |
| settings.Pass(), raw_params, test_context_flags)); |
| |
| if (!skip_settings_initialization_) |
| test_context->InitSettingsWithoutCheck(); |
| |
| return test_context.Pass(); |
| } |
| |
| DataReductionProxyTestContext::DataReductionProxyTestContext( |
| scoped_ptr<base::MessageLoop> loop, |
| scoped_refptr<base::SingleThreadTaskRunner> task_runner, |
| scoped_ptr<TestingPrefServiceSimple> simple_pref_service, |
| scoped_ptr<net::TestNetLog> net_log, |
| scoped_refptr<net::URLRequestContextGetter> request_context_getter, |
| net::MockClientSocketFactory* mock_socket_factory, |
| scoped_ptr<TestDataReductionProxyIOData> io_data, |
| scoped_ptr<DataReductionProxySettings> settings, |
| TestDataReductionProxyParams* params, |
| unsigned int test_context_flags) |
| : test_context_flags_(test_context_flags), |
| loop_(loop.Pass()), |
| task_runner_(task_runner), |
| simple_pref_service_(simple_pref_service.Pass()), |
| net_log_(net_log.Pass()), |
| request_context_getter_(request_context_getter), |
| mock_socket_factory_(mock_socket_factory), |
| io_data_(io_data.Pass()), |
| settings_(settings.Pass()), |
| params_(params) { |
| } |
| |
| DataReductionProxyTestContext::~DataReductionProxyTestContext() { |
| } |
| |
| void DataReductionProxyTestContext::RunUntilIdle() { |
| base::MessageLoop::current()->RunUntilIdle(); |
| } |
| |
| void DataReductionProxyTestContext::InitSettings() { |
| DCHECK(test_context_flags_ & |
| DataReductionProxyTestContext::SKIP_SETTINGS_INITIALIZATION); |
| InitSettingsWithoutCheck(); |
| } |
| |
| void DataReductionProxyTestContext::InitSettingsWithoutCheck() { |
| settings_->InitDataReductionProxySettings( |
| simple_pref_service_.get(), io_data_.get(), |
| CreateDataReductionProxyServiceInternal()); |
| io_data_->SetDataReductionProxyService( |
| settings_->data_reduction_proxy_service()->GetWeakPtr()); |
| settings_->data_reduction_proxy_service()->SetIOData(io_data_->GetWeakPtr()); |
| } |
| |
| scoped_ptr<DataReductionProxyService> |
| DataReductionProxyTestContext::CreateDataReductionProxyService() { |
| DCHECK(test_context_flags_ & |
| DataReductionProxyTestContext::SKIP_SETTINGS_INITIALIZATION); |
| return CreateDataReductionProxyServiceInternal(); |
| } |
| |
| scoped_ptr<DataReductionProxyService> |
| DataReductionProxyTestContext::CreateDataReductionProxyServiceInternal() { |
| scoped_ptr<DataReductionProxyCompressionStats> compression_stats = |
| make_scoped_ptr(new DataReductionProxyCompressionStats( |
| simple_pref_service_.get(), task_runner_, base::TimeDelta())); |
| |
| if (test_context_flags_ & DataReductionProxyTestContext::USE_MOCK_SERVICE) { |
| return make_scoped_ptr(new MockDataReductionProxyService( |
| compression_stats.Pass(), settings_.get(), |
| request_context_getter_.get(), task_runner_)); |
| } else { |
| return make_scoped_ptr(new DataReductionProxyService( |
| compression_stats.Pass(), settings_.get(), |
| request_context_getter_.get(), task_runner_)); |
| } |
| } |
| |
| void DataReductionProxyTestContext::AttachToURLRequestContext( |
| net::URLRequestContextStorage* request_context_storage) const { |
| DCHECK(request_context_storage); |
| |
| // |request_context_storage| takes ownership of the network delegate. |
| request_context_storage->set_network_delegate( |
| io_data()->CreateNetworkDelegate( |
| scoped_ptr<net::NetworkDelegate>(new net::TestNetworkDelegate()), |
| true).release()); |
| |
| // |request_context_storage| takes ownership of the job factory. |
| request_context_storage->set_job_factory( |
| new net::URLRequestInterceptingJobFactory( |
| scoped_ptr<net::URLRequestJobFactory>( |
| new net::URLRequestJobFactoryImpl()), |
| io_data()->CreateInterceptor().Pass())); |
| } |
| |
| void DataReductionProxyTestContext:: |
| EnableDataReductionProxyWithSecureProxyCheckSuccess() { |
| DCHECK(mock_socket_factory_); |
| // This won't actually update the proxy config when using a test configurator. |
| DCHECK(!(test_context_flags_ & |
| DataReductionProxyTestContext::USE_TEST_CONFIGURATOR)); |
| // |settings_| needs to have been initialized, since a |
| // |DataReductionProxyService| is needed in order to issue the secure proxy |
| // check. |
| DCHECK(data_reduction_proxy_service()); |
| |
| // Enable the Data Reduction Proxy, simulating a successful secure proxy |
| // check. |
| net::MockRead mock_reads[] = { |
| net::MockRead("HTTP/1.1 200 OK\r\n\r\n"), |
| net::MockRead("OK"), |
| net::MockRead(net::SYNCHRONOUS, net::OK), |
| }; |
| net::StaticSocketDataProvider socket_data_provider( |
| mock_reads, arraysize(mock_reads), nullptr, 0); |
| mock_socket_factory_->AddSocketDataProvider(&socket_data_provider); |
| |
| // Set the pref to cause the secure proxy check to be issued. |
| pref_service()->SetBoolean(prefs::kDataReductionProxyEnabled, true); |
| RunUntilIdle(); |
| } |
| |
| TestDataReductionProxyConfigurator* |
| DataReductionProxyTestContext::test_configurator() const { |
| DCHECK(test_context_flags_ & |
| DataReductionProxyTestContext::USE_TEST_CONFIGURATOR); |
| return reinterpret_cast<TestDataReductionProxyConfigurator*>( |
| io_data_->configurator()); |
| } |
| |
| MockDataReductionProxyConfig* DataReductionProxyTestContext::mock_config() |
| const { |
| DCHECK(test_context_flags_ & DataReductionProxyTestContext::USE_MOCK_CONFIG); |
| return reinterpret_cast<MockDataReductionProxyConfig*>(io_data_->config()); |
| } |
| |
| DataReductionProxyService* |
| DataReductionProxyTestContext::data_reduction_proxy_service() const { |
| return settings_->data_reduction_proxy_service(); |
| } |
| |
| MockDataReductionProxyService* |
| DataReductionProxyTestContext::mock_data_reduction_proxy_service() |
| const { |
| DCHECK(!(test_context_flags_ & |
| DataReductionProxyTestContext::SKIP_SETTINGS_INITIALIZATION)); |
| DCHECK(test_context_flags_ & DataReductionProxyTestContext::USE_MOCK_SERVICE); |
| return reinterpret_cast<MockDataReductionProxyService*>( |
| data_reduction_proxy_service()); |
| } |
| |
| MockDataReductionProxyRequestOptions* |
| DataReductionProxyTestContext::mock_request_options() const { |
| DCHECK(test_context_flags_ & |
| DataReductionProxyTestContext::USE_MOCK_REQUEST_OPTIONS); |
| return reinterpret_cast<MockDataReductionProxyRequestOptions*>( |
| io_data_->request_options()); |
| } |
| |
| TestDataReductionProxyConfig* DataReductionProxyTestContext::config() const { |
| return reinterpret_cast<TestDataReductionProxyConfig*>(io_data_->config()); |
| } |
| |
| DataReductionProxyMutableConfigValues* |
| DataReductionProxyTestContext::mutable_config_values() { |
| DCHECK(test_context_flags_ & |
| DataReductionProxyTestContext::USE_CONFIG_CLIENT); |
| return reinterpret_cast<DataReductionProxyMutableConfigValues*>( |
| config()->config_values()); |
| } |
| |
| TestDataReductionProxyConfigServiceClient* |
| DataReductionProxyTestContext::test_config_client() { |
| DCHECK(test_context_flags_ & |
| DataReductionProxyTestContext::USE_TEST_CONFIG_CLIENT); |
| return reinterpret_cast<TestDataReductionProxyConfigServiceClient*>( |
| io_data_->config_client()); |
| } |
| |
| DataReductionProxyBypassStats::UnreachableCallback |
| DataReductionProxyTestContext::unreachable_callback() const { |
| return base::Bind(&DataReductionProxySettings::SetUnreachable, |
| base::Unretained(settings_.get())); |
| } |
| |
| } // namespace data_reduction_proxy |