Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / metrics / variations / variations_service_unittest.cc
1 // Copyright (c) 2012 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 "chrome/browser/metrics/variations/variations_service.h"
6
7 #include <vector>
8
9 #include "base/base64.h"
10 #include "base/prefs/testing_pref_service.h"
11 #include "base/sha1.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "base/strings/string_util.h"
14 #include "chrome/browser/web_resource/resource_request_allowed_notifier_test_util.h"
15 #include "chrome/common/pref_names.h"
16 #include "chrome/test/base/testing_browser_process.h"
17 #include "chrome/test/base/testing_pref_service_syncable.h"
18 #include "components/variations/proto/study.pb.h"
19 #include "components/variations/proto/variations_seed.pb.h"
20 #include "content/public/test/test_browser_thread.h"
21 #include "net/base/url_util.h"
22 #include "net/http/http_response_headers.h"
23 #include "net/http/http_status_code.h"
24 #include "net/url_request/test_url_fetcher_factory.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26
27 #if defined(OS_CHROMEOS)
28 #include "chrome/browser/chromeos/settings/cros_settings.h"
29 #include "chrome/browser/chromeos/settings/device_settings_service.h"
30 #include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h"
31 #endif
32
33 namespace chrome_variations {
34
35 namespace {
36
37 // A test class used to validate expected functionality in VariationsService.
38 class TestVariationsService : public VariationsService {
39  public:
40   TestVariationsService(TestRequestAllowedNotifier* test_notifier,
41                         PrefService* local_state)
42       : VariationsService(test_notifier, local_state),
43         fetch_attempted_(false) {
44     // Set this so StartRepeatedVariationsSeedFetch can be called in tests.
45     SetCreateTrialsFromSeedCalledForTesting(true);
46   }
47
48   virtual ~TestVariationsService() {
49   }
50
51   bool fetch_attempted() const { return fetch_attempted_; }
52
53  protected:
54   virtual void DoActualFetch() OVERRIDE {
55     fetch_attempted_ = true;
56   }
57
58  private:
59   bool fetch_attempted_;
60
61   DISALLOW_COPY_AND_ASSIGN(TestVariationsService);
62 };
63
64 // Populates |seed| with simple test data. The resulting seed will contain one
65 // study called "test", which contains one experiment called "abc" with
66 // probability weight 100. |seed|'s study field will be cleared before adding
67 // the new study.
68 VariationsSeed CreateTestSeed() {
69   VariationsSeed seed;
70   Study* study = seed.add_study();
71   study->set_name("test");
72   study->set_default_experiment_name("abc");
73   Study_Experiment* experiment = study->add_experiment();
74   experiment->set_name("abc");
75   experiment->set_probability_weight(100);
76   seed.set_serial_number("123");
77   return seed;
78 }
79
80 // Serializes |seed| to protobuf binary format.
81 std::string SerializeSeed(const VariationsSeed& seed) {
82   std::string serialized_seed;
83   seed.SerializeToString(&serialized_seed);
84   return serialized_seed;
85 }
86
87 // Serializes |seed| to base64-encoded protobuf binary format.
88 std::string SerializeSeedBase64(const VariationsSeed& seed, std::string* hash) {
89   std::string serialized_seed = SerializeSeed(seed);
90   if (hash != NULL) {
91     std::string sha1 = base::SHA1HashString(serialized_seed);
92     *hash = base::HexEncode(sha1.data(), sha1.size());
93   }
94   std::string base64_serialized_seed;
95   base::Base64Encode(serialized_seed, &base64_serialized_seed);
96   return base64_serialized_seed;
97 }
98
99 // Simulates a variations service response by setting a date header and the
100 // specified HTTP |response_code| on |fetcher|.
101 void SimulateServerResponse(int response_code, net::TestURLFetcher* fetcher) {
102   ASSERT_TRUE(fetcher);
103   scoped_refptr<net::HttpResponseHeaders> headers(
104       new net::HttpResponseHeaders("date:Wed, 13 Feb 2013 00:25:24 GMT\0\0"));
105   fetcher->set_response_headers(headers);
106   fetcher->set_response_code(response_code);
107 }
108
109 }  // namespace
110
111 class VariationsServiceTest : public ::testing::Test {
112  protected:
113   VariationsServiceTest() {}
114
115  private:
116 #if defined(OS_CHROMEOS)
117   // Not used directly. Initializes CrosSettings for testing.
118   chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
119   chromeos::ScopedTestCrosSettings test_cros_settings_;
120 #endif
121
122   DISALLOW_COPY_AND_ASSIGN(VariationsServiceTest);
123 };
124
125 #if !defined(OS_CHROMEOS)
126 TEST_F(VariationsServiceTest, VariationsURLIsValid) {
127 #if defined(OS_ANDROID)
128   // Android uses profile prefs as the PrefService to generate the URL.
129   TestingPrefServiceSyncable prefs;
130   VariationsService::RegisterProfilePrefs(prefs.registry());
131 #else
132   TestingPrefServiceSimple prefs;
133   VariationsService::RegisterPrefs(prefs.registry());
134 #endif
135   const std::string default_variations_url =
136       VariationsService::GetDefaultVariationsServerURLForTesting();
137
138   std::string value;
139   GURL url = VariationsService::GetVariationsServerURL(&prefs);
140   EXPECT_TRUE(StartsWithASCII(url.spec(), default_variations_url, true));
141   EXPECT_FALSE(net::GetValueForKeyInQuery(url, "restrict", &value));
142
143   prefs.SetString(prefs::kVariationsRestrictParameter, "restricted");
144   url = VariationsService::GetVariationsServerURL(&prefs);
145   EXPECT_TRUE(StartsWithASCII(url.spec(), default_variations_url, true));
146   EXPECT_TRUE(net::GetValueForKeyInQuery(url, "restrict", &value));
147   EXPECT_EQ("restricted", value);
148 }
149 #else
150 class VariationsServiceTestChromeOS : public VariationsServiceTest {
151  protected:
152   VariationsServiceTestChromeOS() {}
153
154   virtual void SetUp() OVERRIDE {
155     cros_settings_ = chromeos::CrosSettings::Get();
156     DCHECK(cros_settings_ != NULL);
157     // Remove the real DeviceSettingsProvider and replace it with a stub that
158     // allows modifications in a test.
159     device_settings_provider_ = cros_settings_->GetProvider(
160         chromeos::kReportDeviceVersionInfo);
161     EXPECT_TRUE(device_settings_provider_ != NULL);
162     EXPECT_TRUE(cros_settings_->RemoveSettingsProvider(
163         device_settings_provider_));
164     cros_settings_->AddSettingsProvider(&stub_settings_provider_);
165   }
166
167   virtual void TearDown() OVERRIDE {
168     // Restore the real DeviceSettingsProvider.
169     EXPECT_TRUE(
170         cros_settings_->RemoveSettingsProvider(&stub_settings_provider_));
171     cros_settings_->AddSettingsProvider(device_settings_provider_);
172   }
173
174   void SetVariationsRestrictParameterPolicyValue(std::string value) {
175     cros_settings_->SetString(chromeos::kVariationsRestrictParameter, value);
176   }
177
178  private:
179   chromeos::CrosSettings* cros_settings_;
180   chromeos::StubCrosSettingsProvider stub_settings_provider_;
181   chromeos::CrosSettingsProvider* device_settings_provider_;
182
183   DISALLOW_COPY_AND_ASSIGN(VariationsServiceTestChromeOS);
184 };
185
186 TEST_F(VariationsServiceTestChromeOS, VariationsURLIsValid) {
187   TestingPrefServiceSimple prefs;
188   VariationsService::RegisterPrefs(prefs.registry());
189   const std::string default_variations_url =
190       VariationsService::GetDefaultVariationsServerURLForTesting();
191
192   std::string value;
193   GURL url = VariationsService::GetVariationsServerURL(&prefs);
194   EXPECT_TRUE(StartsWithASCII(url.spec(), default_variations_url, true));
195   EXPECT_FALSE(net::GetValueForKeyInQuery(url, "restrict", &value));
196
197   SetVariationsRestrictParameterPolicyValue("restricted");
198   url = VariationsService::GetVariationsServerURL(&prefs);
199   EXPECT_TRUE(StartsWithASCII(url.spec(), default_variations_url, true));
200   EXPECT_TRUE(net::GetValueForKeyInQuery(url, "restrict", &value));
201   EXPECT_EQ("restricted", value);
202 }
203 #endif
204
205 TEST_F(VariationsServiceTest, VariationsURLHasOSNameParam) {
206   TestingPrefServiceSimple prefs;
207   VariationsService::RegisterPrefs(prefs.registry());
208   const GURL url = VariationsService::GetVariationsServerURL(&prefs);
209
210   std::string value;
211   EXPECT_TRUE(net::GetValueForKeyInQuery(url, "osname", &value));
212   EXPECT_FALSE(value.empty());
213 }
214
215 TEST_F(VariationsServiceTest, RequestsInitiallyNotAllowed) {
216   base::MessageLoopForUI message_loop;
217   content::TestBrowserThread ui_thread(content::BrowserThread::UI,
218                                        &message_loop);
219   TestingPrefServiceSimple prefs;
220   VariationsService::RegisterPrefs(prefs.registry());
221
222   // Pass ownership to TestVariationsService, but keep a weak pointer to
223   // manipulate it for this test.
224   TestRequestAllowedNotifier* test_notifier = new TestRequestAllowedNotifier;
225   TestVariationsService test_service(test_notifier, &prefs);
226
227   // Force the notifier to initially disallow requests.
228   test_notifier->SetRequestsAllowedOverride(false);
229   test_service.StartRepeatedVariationsSeedFetch();
230   EXPECT_FALSE(test_service.fetch_attempted());
231
232   test_notifier->NotifyObserver();
233   EXPECT_TRUE(test_service.fetch_attempted());
234 }
235
236 TEST_F(VariationsServiceTest, RequestsInitiallyAllowed) {
237   base::MessageLoopForUI message_loop;
238   content::TestBrowserThread ui_thread(content::BrowserThread::UI,
239                                        &message_loop);
240   TestingPrefServiceSimple prefs;
241   VariationsService::RegisterPrefs(prefs.registry());
242
243   // Pass ownership to TestVariationsService, but keep a weak pointer to
244   // manipulate it for this test.
245   TestRequestAllowedNotifier* test_notifier = new TestRequestAllowedNotifier;
246   TestVariationsService test_service(test_notifier, &prefs);
247
248   test_notifier->SetRequestsAllowedOverride(true);
249   test_service.StartRepeatedVariationsSeedFetch();
250   EXPECT_TRUE(test_service.fetch_attempted());
251 }
252
253 TEST_F(VariationsServiceTest, SeedStoredWhenOKStatus) {
254   base::MessageLoop message_loop;
255   content::TestBrowserThread io_thread(content::BrowserThread::IO,
256                                        &message_loop);
257   TestingPrefServiceSimple prefs;
258   VariationsService::RegisterPrefs(prefs.registry());
259
260   VariationsService variations_service(new TestRequestAllowedNotifier, &prefs);
261
262   net::TestURLFetcherFactory factory;
263   variations_service.DoActualFetch();
264
265   net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
266   SimulateServerResponse(net::HTTP_OK, fetcher);
267   const VariationsSeed seed = CreateTestSeed();
268   fetcher->SetResponseString(SerializeSeed(seed));
269
270   EXPECT_TRUE(prefs.FindPreference(prefs::kVariationsSeed)->IsDefaultValue());
271   variations_service.OnURLFetchComplete(fetcher);
272   EXPECT_FALSE(prefs.FindPreference(prefs::kVariationsSeed)->IsDefaultValue());
273   const std::string expected_base64 = SerializeSeedBase64(seed, NULL);
274   EXPECT_EQ(expected_base64, prefs.GetString(prefs::kVariationsSeed));
275 }
276
277 TEST_F(VariationsServiceTest, SeedNotStoredWhenNonOKStatus) {
278   const int non_ok_status_codes[] = {
279     net::HTTP_NO_CONTENT,
280     net::HTTP_NOT_MODIFIED,
281     net::HTTP_NOT_FOUND,
282     net::HTTP_INTERNAL_SERVER_ERROR,
283     net::HTTP_SERVICE_UNAVAILABLE,
284   };
285
286   base::MessageLoop message_loop;
287   content::TestBrowserThread io_thread(content::BrowserThread::IO,
288                                        &message_loop);
289   TestingPrefServiceSimple prefs;
290   VariationsService::RegisterPrefs(prefs.registry());
291
292   VariationsService variations_service(new TestRequestAllowedNotifier, &prefs);
293   for (size_t i = 0; i < arraysize(non_ok_status_codes); ++i) {
294     net::TestURLFetcherFactory factory;
295     variations_service.DoActualFetch();
296     EXPECT_TRUE(prefs.FindPreference(prefs::kVariationsSeed)->IsDefaultValue());
297
298     net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
299     SimulateServerResponse(non_ok_status_codes[i], fetcher);
300     variations_service.OnURLFetchComplete(fetcher);
301
302     EXPECT_TRUE(prefs.FindPreference(prefs::kVariationsSeed)->IsDefaultValue());
303   }
304 }
305
306 TEST_F(VariationsServiceTest, SeedDateUpdatedOn304Status) {
307   base::MessageLoop message_loop;
308   content::TestBrowserThread io_thread(content::BrowserThread::IO,
309                                        &message_loop);
310   TestingPrefServiceSimple prefs;
311   VariationsService::RegisterPrefs(prefs.registry());
312
313   VariationsService variations_service(new TestRequestAllowedNotifier, &prefs);
314   net::TestURLFetcherFactory factory;
315   variations_service.DoActualFetch();
316   EXPECT_TRUE(
317       prefs.FindPreference(prefs::kVariationsSeedDate)->IsDefaultValue());
318
319   net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
320   SimulateServerResponse(net::HTTP_NOT_MODIFIED, fetcher);
321   variations_service.OnURLFetchComplete(fetcher);
322   EXPECT_FALSE(
323       prefs.FindPreference(prefs::kVariationsSeedDate)->IsDefaultValue());
324 }
325
326 }  // namespace chrome_variations