1// Copyright 2014 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 "components/data_reduction_proxy/browser/data_reduction_proxy_settings_test_utils.h"
6
7#include "base/command_line.h"
8#include "base/message_loop/message_loop.h"
9#include "base/prefs/pref_registry_simple.h"
10#include "base/prefs/scoped_user_pref_update.h"
11#include "base/strings/string_number_conversions.h"
12#include "components/data_reduction_proxy/common/data_reduction_proxy_pref_names.h"
13#include "components/data_reduction_proxy/common/data_reduction_proxy_switches.h"
14
15using testing::_;
16using testing::AnyNumber;
17using testing::Return;
18
19namespace {
20
21const char kDataReductionProxy[] = "https://foo.com:443/";
22const char kDataReductionProxyFallback[] = "http://bar.com:80/";
23const char kDataReductionProxyKey[] = "12345";
24
25const char kProbeURLWithOKResponse[] = "http://ok.org/";
26const char kWarmupURLWithNoContentResponse[] = "http://warm.org/";
27
28const char kProxy[] = "proxy";
29
30}  // namespace
31
32namespace data_reduction_proxy {
33
34// Transform "normal"-looking headers (\n-separated) to the appropriate
35// input format for ParseRawHeaders (\0-separated).
36void HeadersToRaw(std::string* headers) {
37  std::replace(headers->begin(), headers->end(), '\n', '\0');
38  if (!headers->empty())
39    *headers += '\0';
40}
41
42ProbeURLFetchResult FetchResult(bool enabled, bool success) {
43  if (enabled) {
44    if (success)
45      return SUCCEEDED_PROXY_ALREADY_ENABLED;
46    return FAILED_PROXY_DISABLED;
47  }
48  if (success)
49    return SUCCEEDED_PROXY_ENABLED;
50  return FAILED_PROXY_ALREADY_DISABLED;
51}
52
53TestDataReductionProxyConfig::TestDataReductionProxyConfig()
54    : enabled_(false),
55      restricted_(false),
56      fallback_restricted_(false) {}
57
58void TestDataReductionProxyConfig::Enable(
59    bool restricted,
60    bool fallback_restricted,
61    const std::string& primary_origin,
62    const std::string& fallback_origin,
63    const std::string& ssl_origin) {
64  enabled_ = true;
65  restricted_ = restricted;
66  fallback_restricted_ = fallback_restricted;
67  origin_ = primary_origin;
68  fallback_origin_ = fallback_origin;
69  ssl_origin_ = ssl_origin;
70}
71
72void TestDataReductionProxyConfig::Disable() {
73  enabled_ = false;
74  restricted_ = false;
75  fallback_restricted_ = false;
76  origin_ = "";
77  fallback_origin_ = "";
78  ssl_origin_ = "";
79}
80
81// static
82void DataReductionProxySettingsTestBase::AddTestProxyToCommandLine() {
83  CommandLine::ForCurrentProcess()->AppendSwitchASCII(
84      switches::kDataReductionProxy, kDataReductionProxy);
85  CommandLine::ForCurrentProcess()->AppendSwitchASCII(
86      switches::kDataReductionProxyFallback, kDataReductionProxyFallback);
87  CommandLine::ForCurrentProcess()->AppendSwitchASCII(
88      switches::kDataReductionProxyKey, kDataReductionProxyKey);
89  CommandLine::ForCurrentProcess()->AppendSwitchASCII(
90      switches::kDataReductionProxyProbeURL, kProbeURLWithOKResponse);
91}
92
93DataReductionProxySettingsTestBase::DataReductionProxySettingsTestBase()
94    : testing::Test() {
95}
96
97DataReductionProxySettingsTestBase::~DataReductionProxySettingsTestBase() {}
98
99void DataReductionProxySettingsTestBase::AddProxyToCommandLine() {
100  AddTestProxyToCommandLine();
101}
102
103// testing::Test implementation:
104void DataReductionProxySettingsTestBase::SetUp() {
105  PrefRegistrySimple* registry = pref_service_.registry();
106  registry->RegisterListPref(prefs::kDailyHttpOriginalContentLength);
107  registry->RegisterListPref(prefs::kDailyHttpReceivedContentLength);
108  registry->RegisterInt64Pref(prefs::kDailyHttpContentLengthLastUpdateDate,
109                              0L);
110  registry->RegisterDictionaryPref(kProxy);
111  registry->RegisterBooleanPref(prefs::kDataReductionProxyEnabled, false);
112  registry->RegisterBooleanPref(prefs::kDataReductionProxyAltEnabled, false);
113  registry->RegisterBooleanPref(prefs::kDataReductionProxyWasEnabledBefore,
114                                false);
115  AddProxyToCommandLine();
116  ResetSettings(true, true, false, true);
117
118  ListPrefUpdate original_update(&pref_service_,
119                                 prefs::kDailyHttpOriginalContentLength);
120  ListPrefUpdate received_update(&pref_service_,
121                                 prefs::kDailyHttpReceivedContentLength);
122  for (int64 i = 0; i < kNumDaysInHistory; i++) {
123    original_update->Insert(0,
124                            new base::StringValue(base::Int64ToString(2 * i)));
125    received_update->Insert(0, new base::StringValue(base::Int64ToString(i)));
126  }
127  last_update_time_ = base::Time::Now().LocalMidnight();
128  pref_service_.SetInt64(
129      prefs::kDailyHttpContentLengthLastUpdateDate,
130      last_update_time_.ToInternalValue());
131}
132
133template <class C>
134void DataReductionProxySettingsTestBase::ResetSettings(bool allowed,
135                                                       bool fallback_allowed,
136                                                       bool alt_allowed,
137                                                       bool promo_allowed) {
138  int flags = 0;
139  if (allowed)
140    flags |= DataReductionProxyParams::kAllowed;
141  if (fallback_allowed)
142    flags |= DataReductionProxyParams::kFallbackAllowed;
143  if (alt_allowed)
144    flags |= DataReductionProxyParams::kAlternativeAllowed;
145  if (promo_allowed)
146    flags |= DataReductionProxyParams::kPromoAllowed;
147  MockDataReductionProxySettings<C>* settings =
148      new MockDataReductionProxySettings<C>(flags);
149  EXPECT_CALL(*settings, GetOriginalProfilePrefs())
150      .Times(AnyNumber())
151      .WillRepeatedly(Return(&pref_service_));
152  EXPECT_CALL(*settings, GetLocalStatePrefs())
153      .Times(AnyNumber())
154      .WillRepeatedly(Return(&pref_service_));
155  EXPECT_CALL(*settings, GetURLFetcherForAvailabilityCheck()).Times(0);
156  EXPECT_CALL(*settings, GetURLFetcherForWarmup()).Times(0);
157  EXPECT_CALL(*settings, LogProxyState(_, _, _)).Times(0);
158  settings_.reset(settings);
159  settings_->configurator_.reset(new TestDataReductionProxyConfig());
160}
161
162// Explicitly generate required instantiations.
163template void
164DataReductionProxySettingsTestBase::ResetSettings<DataReductionProxySettings>(
165    bool allowed, bool fallback_allowed, bool alt_allowed, bool promo_allowed);
166
167template <class C>
168void DataReductionProxySettingsTestBase::SetProbeResult(
169    const std::string& test_url,
170    const std::string& warmup_test_url,
171    const std::string& response,
172    ProbeURLFetchResult result,
173    bool success,
174    int expected_calls)  {
175  MockDataReductionProxySettings<C>* settings =
176      static_cast<MockDataReductionProxySettings<C>*>(settings_.get());
177  if (0 == expected_calls) {
178    EXPECT_CALL(*settings, GetURLFetcherForAvailabilityCheck()).Times(0);
179    EXPECT_CALL(*settings, GetURLFetcherForWarmup()).Times(0);
180    EXPECT_CALL(*settings, RecordProbeURLFetchResult(_)).Times(0);
181  } else {
182    EXPECT_CALL(*settings, RecordProbeURLFetchResult(result)).Times(1);
183    EXPECT_CALL(*settings, GetURLFetcherForAvailabilityCheck())
184        .Times(expected_calls)
185        .WillRepeatedly(Return(new net::FakeURLFetcher(
186            GURL(test_url),
187            settings,
188            response,
189            success ? net::HTTP_OK : net::HTTP_INTERNAL_SERVER_ERROR,
190            success ? net::URLRequestStatus::SUCCESS :
191                      net::URLRequestStatus::FAILED)));
192    EXPECT_CALL(*settings, GetURLFetcherForWarmup())
193        .Times(expected_calls)
194        .WillRepeatedly(Return(new net::FakeURLFetcher(
195            GURL(warmup_test_url),
196            settings,
197            "",
198            success ? net::HTTP_NO_CONTENT : net::HTTP_INTERNAL_SERVER_ERROR,
199                success ? net::URLRequestStatus::SUCCESS :
200                          net::URLRequestStatus::FAILED)));
201  }
202}
203
204// Explicitly generate required instantiations.
205template void
206DataReductionProxySettingsTestBase::SetProbeResult<DataReductionProxySettings>(
207    const std::string& test_url,
208    const std::string& warmup_test_url,
209    const std::string& response,
210    ProbeURLFetchResult result,
211    bool success,
212    int expected_calls);
213
214void DataReductionProxySettingsTestBase::CheckProxyConfigs(
215    bool expected_enabled,
216    bool expected_restricted,
217    bool expected_fallback_restricted) {
218  TestDataReductionProxyConfig* config =
219      static_cast<TestDataReductionProxyConfig*>(
220          settings_->configurator_.get());
221  ASSERT_EQ(expected_restricted, config->restricted_);
222  ASSERT_EQ(expected_fallback_restricted, config->fallback_restricted_);
223  ASSERT_EQ(expected_enabled, config->enabled_);
224}
225
226void DataReductionProxySettingsTestBase::CheckProbe(
227    bool initially_enabled,
228    const std::string& probe_url,
229    const std::string& warmup_url,
230    const std::string& response,
231    bool request_succeeded,
232    bool expected_enabled,
233    bool expected_restricted,
234    bool expected_fallback_restricted) {
235  pref_service_.SetBoolean(prefs::kDataReductionProxyEnabled,
236                           initially_enabled);
237  if (initially_enabled)
238    settings_->enabled_by_user_ = true;
239  settings_->restricted_by_carrier_ = false;
240  SetProbeResult(probe_url,
241                 warmup_url,
242                 response,
243                 FetchResult(initially_enabled,
244                             request_succeeded && (response == "OK")),
245                 request_succeeded,
246                 initially_enabled ? 1 : 0);
247  settings_->MaybeActivateDataReductionProxy(false);
248  base::MessageLoop::current()->RunUntilIdle();
249  CheckProxyConfigs(expected_enabled,
250                    expected_restricted,
251                    expected_fallback_restricted);
252}
253
254void DataReductionProxySettingsTestBase::CheckProbeOnIPChange(
255    const std::string& probe_url,
256    const std::string& warmup_url,
257    const std::string& response,
258    bool request_succeeded,
259    bool expected_restricted,
260    bool expected_fallback_restricted) {
261  SetProbeResult(probe_url,
262                 warmup_url,
263                 response,
264                 FetchResult(!settings_->restricted_by_carrier_,
265                             request_succeeded && (response == "OK")),
266                 request_succeeded,
267                 1);
268  settings_->OnIPAddressChanged();
269  base::MessageLoop::current()->RunUntilIdle();
270  CheckProxyConfigs(true, expected_restricted, expected_fallback_restricted);
271}
272
273void DataReductionProxySettingsTestBase::CheckOnPrefChange(
274    bool enabled,
275    bool expected_enabled,
276    bool managed) {
277  // Always have a sucessful probe for pref change tests.
278  SetProbeResult(kProbeURLWithOKResponse,
279                 kWarmupURLWithNoContentResponse,
280                 "OK",
281                 FetchResult(enabled, true),
282                 true,
283                 expected_enabled ? 1 : 0);
284  if (managed) {
285    pref_service_.SetManagedPref(prefs::kDataReductionProxyEnabled,
286                                 base::Value::CreateBooleanValue(enabled));
287  } else {
288    pref_service_.SetBoolean(prefs::kDataReductionProxyEnabled, enabled);
289  }
290  base::MessageLoop::current()->RunUntilIdle();
291  // Never expect the proxy to be restricted for pref change tests.
292  CheckProxyConfigs(expected_enabled, false, false);
293}
294
295void DataReductionProxySettingsTestBase::CheckInitDataReductionProxy(
296    bool enabled_at_startup) {
297  base::MessageLoopForUI loop;
298  SetProbeResult(kProbeURLWithOKResponse,
299                 kWarmupURLWithNoContentResponse,
300                 "OK",
301                 FetchResult(enabled_at_startup, true),
302                 true,
303                 enabled_at_startup ? 1 : 0);
304  scoped_ptr<DataReductionProxyConfigurator> configurator(
305      new TestDataReductionProxyConfig());
306  settings_->SetProxyConfigurator(configurator.Pass());
307  scoped_refptr<net::TestURLRequestContextGetter> request_context =
308      new net::TestURLRequestContextGetter(base::MessageLoopProxy::current());
309  settings_->InitDataReductionProxySettings(&pref_service_,
310                                            &pref_service_,
311                                            request_context.get());
312
313  base::MessageLoop::current()->RunUntilIdle();
314  CheckProxyConfigs(enabled_at_startup, false, false);
315}
316
317}  // namespace data_reduction_proxy
318