Upstream version 11.40.277.0
[platform/framework/web/crosswalk.git] / src / google_apis / gcm / engine / checkin_request_unittest.cc
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 <string>
6
7 #include "google_apis/gcm/engine/checkin_request.h"
8 #include "google_apis/gcm/monitoring/fake_gcm_stats_recorder.h"
9 #include "google_apis/gcm/protocol/checkin.pb.h"
10 #include "net/base/backoff_entry.h"
11 #include "net/url_request/test_url_fetcher_factory.h"
12 #include "net/url_request/url_request_test_util.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14
15 namespace gcm {
16
17 namespace {
18
19 const net::BackoffEntry::Policy kDefaultBackoffPolicy = {
20   // Number of initial errors (in sequence) to ignore before applying
21   // exponential back-off rules.
22   // Explicitly set to 1 to skip the delay of the first Retry, as we are not
23   // trying to test the backoff itself, but rather the fact that retry happens.
24   1,
25
26   // Initial delay for exponential back-off in ms.
27   15000,  // 15 seconds.
28
29   // Factor by which the waiting time will be multiplied.
30   2,
31
32   // Fuzzing percentage. ex: 10% will spread requests randomly
33   // between 90%-100% of the calculated time.
34   0.5,  // 50%.
35
36   // Maximum amount of time we are willing to delay our request in ms.
37   1000 * 60 * 5, // 5 minutes.
38
39   // Time to keep an entry from being discarded even when it
40   // has no significant state, -1 to never discard.
41   -1,
42
43   // Don't use initial delay unless the last request was an error.
44   false,
45 };
46
47 }
48
49 const uint64 kAndroidId = 42UL;
50 const uint64 kBlankAndroidId = 999999UL;
51 const uint64 kBlankSecurityToken = 999999UL;
52 const char kCheckinURL[] = "http://foo.bar/checkin";
53 const char kChromeVersion[] = "Version String";
54 const uint64 kSecurityToken = 77;
55 const char kSettingsDigest[] = "settings_digest";
56 const char kEmailAddress[] = "test_user@gmail.com";
57 const char kTokenValue[] = "token_value";
58
59 class CheckinRequestTest : public testing::Test {
60  public:
61   enum ResponseScenario {
62     VALID_RESPONSE,  // Both android_id and security_token set in response.
63     MISSING_ANDROID_ID,  // android_id is missing.
64     MISSING_SECURITY_TOKEN,  // security_token is missing.
65     ANDROID_ID_IS_ZER0,  // android_id is 0.
66     SECURITY_TOKEN_IS_ZERO  // security_token is 0.
67   };
68
69   CheckinRequestTest();
70   virtual ~CheckinRequestTest();
71
72   void FetcherCallback(
73       const checkin_proto::AndroidCheckinResponse& response);
74
75   void CreateRequest(uint64 android_id, uint64 security_token);
76
77   void SetResponseStatusAndString(
78       net::HttpStatusCode status_code,
79       const std::string& response_data);
80
81   void CompleteFetch();
82
83   void SetResponse(ResponseScenario response_scenario);
84
85  protected:
86   bool callback_called_;
87   uint64 android_id_;
88   uint64 security_token_;
89   int checkin_device_type_;
90   base::MessageLoop message_loop_;
91   net::TestURLFetcherFactory url_fetcher_factory_;
92   scoped_refptr<net::TestURLRequestContextGetter> url_request_context_getter_;
93   checkin_proto::ChromeBuildProto chrome_build_proto_;
94   scoped_ptr<CheckinRequest> request_;
95   FakeGCMStatsRecorder recorder_;
96 };
97
98 CheckinRequestTest::CheckinRequestTest()
99     : callback_called_(false),
100       android_id_(kBlankAndroidId),
101       security_token_(kBlankSecurityToken),
102       checkin_device_type_(0),
103       url_request_context_getter_(new net::TestURLRequestContextGetter(
104           message_loop_.message_loop_proxy())) {
105 }
106
107 CheckinRequestTest::~CheckinRequestTest() {}
108
109 void CheckinRequestTest::FetcherCallback(
110     const checkin_proto::AndroidCheckinResponse& checkin_response) {
111   callback_called_ = true;
112   if (checkin_response.has_android_id())
113     android_id_ = checkin_response.android_id();
114   if (checkin_response.has_security_token())
115     security_token_ = checkin_response.security_token();
116 }
117
118 void CheckinRequestTest::CreateRequest(uint64 android_id,
119                                        uint64 security_token) {
120   // First setup a chrome_build protobuf.
121   chrome_build_proto_.set_platform(
122       checkin_proto::ChromeBuildProto::PLATFORM_LINUX);
123   chrome_build_proto_.set_channel(
124       checkin_proto::ChromeBuildProto::CHANNEL_CANARY);
125   chrome_build_proto_.set_chrome_version(kChromeVersion);
126
127   std::map<std::string, std::string> account_tokens;
128   account_tokens[kEmailAddress] = kTokenValue;
129
130   CheckinRequest::RequestInfo request_info(android_id,
131                                            security_token,
132                                            account_tokens,
133                                            kSettingsDigest,
134                                            chrome_build_proto_);
135   // Then create a request with that protobuf and specified android_id,
136   // security_token.
137   request_.reset(new CheckinRequest(
138       GURL(kCheckinURL),
139       request_info,
140       kDefaultBackoffPolicy,
141       base::Bind(&CheckinRequestTest::FetcherCallback, base::Unretained(this)),
142       url_request_context_getter_.get(),
143       &recorder_));
144
145   // Setting android_id_ and security_token_ to blank value, not used elsewhere
146   // in the tests.
147   callback_called_ = false;
148   android_id_ = kBlankAndroidId;
149   security_token_ = kBlankSecurityToken;
150 }
151
152 void CheckinRequestTest::SetResponseStatusAndString(
153     net::HttpStatusCode status_code,
154     const std::string& response_data) {
155   net::TestURLFetcher* fetcher =
156       url_fetcher_factory_.GetFetcherByID(0);
157   ASSERT_TRUE(fetcher);
158   fetcher->set_response_code(status_code);
159   fetcher->SetResponseString(response_data);
160 }
161
162 void CheckinRequestTest::CompleteFetch() {
163   net::TestURLFetcher* fetcher =
164       url_fetcher_factory_.GetFetcherByID(0);
165   ASSERT_TRUE(fetcher);
166   fetcher->delegate()->OnURLFetchComplete(fetcher);
167 }
168
169 void CheckinRequestTest::SetResponse(ResponseScenario response_scenario) {
170   checkin_proto::AndroidCheckinResponse response;
171   response.set_stats_ok(true);
172
173   uint64 android_id = response_scenario == ANDROID_ID_IS_ZER0 ? 0 : kAndroidId;
174   uint64 security_token =
175       response_scenario == SECURITY_TOKEN_IS_ZERO ? 0 : kSecurityToken;
176
177   if (response_scenario != MISSING_ANDROID_ID)
178     response.set_android_id(android_id);
179
180   if (response_scenario != MISSING_SECURITY_TOKEN)
181     response.set_security_token(security_token);
182
183   std::string response_string;
184   response.SerializeToString(&response_string);
185   SetResponseStatusAndString(net::HTTP_OK, response_string);
186 }
187
188 TEST_F(CheckinRequestTest, FetcherDataAndURL) {
189   CreateRequest(kAndroidId, kSecurityToken);
190   request_->Start();
191
192   // Get data sent by request.
193   net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
194   ASSERT_TRUE(fetcher);
195   EXPECT_EQ(GURL(kCheckinURL), fetcher->GetOriginalURL());
196
197   checkin_proto::AndroidCheckinRequest request_proto;
198   request_proto.ParseFromString(fetcher->upload_data());
199   EXPECT_EQ(kAndroidId, static_cast<uint64>(request_proto.id()));
200   EXPECT_EQ(kSecurityToken, request_proto.security_token());
201   EXPECT_EQ(chrome_build_proto_.platform(),
202             request_proto.checkin().chrome_build().platform());
203   EXPECT_EQ(chrome_build_proto_.chrome_version(),
204             request_proto.checkin().chrome_build().chrome_version());
205   EXPECT_EQ(chrome_build_proto_.channel(),
206             request_proto.checkin().chrome_build().channel());
207   EXPECT_EQ(2, request_proto.account_cookie_size());
208   EXPECT_EQ(kEmailAddress, request_proto.account_cookie(0));
209   EXPECT_EQ(kTokenValue, request_proto.account_cookie(1));
210
211 #if defined(CHROME_OS)
212   EXPECT_EQ(checkin_proto::DEVICE_CHROME_OS, request_proto.checkin().type());
213 #else
214   EXPECT_EQ(checkin_proto::DEVICE_CHROME_BROWSER,
215             request_proto.checkin().type());
216 #endif
217
218   EXPECT_EQ(kSettingsDigest, request_proto.digest());
219 }
220
221 TEST_F(CheckinRequestTest, ResponseBodyEmpty) {
222   CreateRequest(0u, 0u);
223   request_->Start();
224
225   SetResponseStatusAndString(net::HTTP_OK, std::string());
226   CompleteFetch();
227
228   EXPECT_FALSE(callback_called_);
229
230   SetResponse(VALID_RESPONSE);
231   CompleteFetch();
232
233   EXPECT_TRUE(callback_called_);
234   EXPECT_EQ(kAndroidId, android_id_);
235   EXPECT_EQ(kSecurityToken, security_token_);
236 }
237
238 TEST_F(CheckinRequestTest, ResponseBodyCorrupted) {
239   CreateRequest(0u, 0u);
240   request_->Start();
241
242   SetResponseStatusAndString(net::HTTP_OK, "Corrupted response body");
243   CompleteFetch();
244
245   EXPECT_FALSE(callback_called_);
246
247   SetResponse(VALID_RESPONSE);
248   CompleteFetch();
249
250   EXPECT_TRUE(callback_called_);
251   EXPECT_EQ(kAndroidId, android_id_);
252   EXPECT_EQ(kSecurityToken, security_token_);
253 }
254
255 TEST_F(CheckinRequestTest, ResponseHttpStatusUnauthorized) {
256   CreateRequest(0u, 0u);
257   request_->Start();
258
259   SetResponseStatusAndString(net::HTTP_UNAUTHORIZED, std::string());
260   CompleteFetch();
261
262   EXPECT_TRUE(callback_called_);
263   EXPECT_EQ(kBlankAndroidId, android_id_);
264   EXPECT_EQ(kBlankSecurityToken, security_token_);
265 }
266
267 TEST_F(CheckinRequestTest, ResponseHttpStatusBadRequest) {
268   CreateRequest(0u, 0u);
269   request_->Start();
270
271   SetResponseStatusAndString(net::HTTP_BAD_REQUEST, std::string());
272   CompleteFetch();
273
274   EXPECT_TRUE(callback_called_);
275   EXPECT_EQ(kBlankAndroidId, android_id_);
276   EXPECT_EQ(kBlankSecurityToken, security_token_);
277 }
278
279 TEST_F(CheckinRequestTest, ResponseHttpStatusNotOK) {
280   CreateRequest(0u, 0u);
281   request_->Start();
282
283   SetResponseStatusAndString(net::HTTP_INTERNAL_SERVER_ERROR, std::string());
284   CompleteFetch();
285
286   EXPECT_FALSE(callback_called_);
287
288   SetResponse(VALID_RESPONSE);
289   CompleteFetch();
290
291   EXPECT_TRUE(callback_called_);
292   EXPECT_EQ(kAndroidId, android_id_);
293   EXPECT_EQ(kSecurityToken, security_token_);
294 }
295
296 TEST_F(CheckinRequestTest, ResponseMissingAndroidId) {
297   CreateRequest(0u, 0u);
298   request_->Start();
299
300   SetResponse(MISSING_ANDROID_ID);
301   CompleteFetch();
302
303   EXPECT_FALSE(callback_called_);
304
305   SetResponse(VALID_RESPONSE);
306   CompleteFetch();
307
308   EXPECT_TRUE(callback_called_);
309   EXPECT_EQ(kAndroidId, android_id_);
310   EXPECT_EQ(kSecurityToken, security_token_);
311 }
312
313 TEST_F(CheckinRequestTest, ResponseMissingSecurityToken) {
314   CreateRequest(0u, 0u);
315   request_->Start();
316
317   SetResponse(MISSING_SECURITY_TOKEN);
318   CompleteFetch();
319
320   EXPECT_FALSE(callback_called_);
321
322   SetResponse(VALID_RESPONSE);
323   CompleteFetch();
324
325   EXPECT_TRUE(callback_called_);
326   EXPECT_EQ(kAndroidId, android_id_);
327   EXPECT_EQ(kSecurityToken, security_token_);
328 }
329
330 TEST_F(CheckinRequestTest, AndroidIdEqualsZeroInResponse) {
331   CreateRequest(0u, 0u);
332   request_->Start();
333
334   SetResponse(ANDROID_ID_IS_ZER0);
335   CompleteFetch();
336
337   EXPECT_FALSE(callback_called_);
338
339   SetResponse(VALID_RESPONSE);
340   CompleteFetch();
341
342   EXPECT_TRUE(callback_called_);
343   EXPECT_EQ(kAndroidId, android_id_);
344   EXPECT_EQ(kSecurityToken, security_token_);
345 }
346
347 TEST_F(CheckinRequestTest, SecurityTokenEqualsZeroInResponse) {
348   CreateRequest(0u, 0u);
349   request_->Start();
350
351   SetResponse(SECURITY_TOKEN_IS_ZERO);
352   CompleteFetch();
353
354   EXPECT_FALSE(callback_called_);
355
356   SetResponse(VALID_RESPONSE);
357   CompleteFetch();
358
359   EXPECT_TRUE(callback_called_);
360   EXPECT_EQ(kAndroidId, android_id_);
361   EXPECT_EQ(kSecurityToken, security_token_);
362 }
363
364 TEST_F(CheckinRequestTest, SuccessfulFirstTimeCheckin) {
365   CreateRequest(0u, 0u);
366   request_->Start();
367
368   SetResponse(VALID_RESPONSE);
369   CompleteFetch();
370
371   EXPECT_TRUE(callback_called_);
372   EXPECT_EQ(kAndroidId, android_id_);
373   EXPECT_EQ(kSecurityToken, security_token_);
374 }
375
376 TEST_F(CheckinRequestTest, SuccessfulSubsequentCheckin) {
377   CreateRequest(kAndroidId, kSecurityToken);
378   request_->Start();
379
380   SetResponse(VALID_RESPONSE);
381   CompleteFetch();
382
383   EXPECT_TRUE(callback_called_);
384   EXPECT_EQ(kAndroidId, android_id_);
385   EXPECT_EQ(kSecurityToken, security_token_);
386 }
387
388 }  // namespace gcm