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.
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"
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.
26 // Initial delay for exponential back-off in ms.
29 // Factor by which the waiting time will be multiplied.
32 // Fuzzing percentage. ex: 10% will spread requests randomly
33 // between 90%-100% of the calculated time.
36 // Maximum amount of time we are willing to delay our request in ms.
37 1000 * 60 * 5, // 5 minutes.
39 // Time to keep an entry from being discarded even when it
40 // has no significant state, -1 to never discard.
43 // Don't use initial delay unless the last request was an error.
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";
59 class CheckinRequestTest
: public testing::Test
{
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.
70 ~CheckinRequestTest() override
;
73 const checkin_proto::AndroidCheckinResponse
& response
);
75 void CreateRequest(uint64 android_id
, uint64 security_token
);
77 void SetResponseStatusAndString(
78 net::HttpStatusCode status_code
,
79 const std::string
& response_data
);
83 void SetResponse(ResponseScenario response_scenario
);
86 bool callback_called_
;
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_
;
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())) {
107 CheckinRequestTest::~CheckinRequestTest() {}
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();
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
);
127 std::map
<std::string
, std::string
> account_tokens
;
128 account_tokens
[kEmailAddress
] = kTokenValue
;
130 CheckinRequest::RequestInfo
request_info(android_id
,
134 chrome_build_proto_
);
135 // Then create a request with that protobuf and specified android_id,
137 request_
.reset(new CheckinRequest(
140 kDefaultBackoffPolicy
,
141 base::Bind(&CheckinRequestTest::FetcherCallback
, base::Unretained(this)),
142 url_request_context_getter_
.get(),
145 // Setting android_id_ and security_token_ to blank value, not used elsewhere
147 callback_called_
= false;
148 android_id_
= kBlankAndroidId
;
149 security_token_
= kBlankSecurityToken
;
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
);
162 void CheckinRequestTest::CompleteFetch() {
163 net::TestURLFetcher
* fetcher
=
164 url_fetcher_factory_
.GetFetcherByID(0);
165 ASSERT_TRUE(fetcher
);
166 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
169 void CheckinRequestTest::SetResponse(ResponseScenario response_scenario
) {
170 checkin_proto::AndroidCheckinResponse response
;
171 response
.set_stats_ok(true);
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
;
177 if (response_scenario
!= MISSING_ANDROID_ID
)
178 response
.set_android_id(android_id
);
180 if (response_scenario
!= MISSING_SECURITY_TOKEN
)
181 response
.set_security_token(security_token
);
183 std::string response_string
;
184 response
.SerializeToString(&response_string
);
185 SetResponseStatusAndString(net::HTTP_OK
, response_string
);
188 TEST_F(CheckinRequestTest
, FetcherDataAndURL
) {
189 CreateRequest(kAndroidId
, kSecurityToken
);
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());
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));
211 #if defined(CHROME_OS)
212 EXPECT_EQ(checkin_proto::DEVICE_CHROME_OS
, request_proto
.checkin().type());
214 EXPECT_EQ(checkin_proto::DEVICE_CHROME_BROWSER
,
215 request_proto
.checkin().type());
218 EXPECT_EQ(kSettingsDigest
, request_proto
.digest());
221 TEST_F(CheckinRequestTest
, ResponseBodyEmpty
) {
222 CreateRequest(0u, 0u);
225 SetResponseStatusAndString(net::HTTP_OK
, std::string());
228 EXPECT_FALSE(callback_called_
);
230 SetResponse(VALID_RESPONSE
);
233 EXPECT_TRUE(callback_called_
);
234 EXPECT_EQ(kAndroidId
, android_id_
);
235 EXPECT_EQ(kSecurityToken
, security_token_
);
238 TEST_F(CheckinRequestTest
, ResponseBodyCorrupted
) {
239 CreateRequest(0u, 0u);
242 SetResponseStatusAndString(net::HTTP_OK
, "Corrupted response body");
245 EXPECT_FALSE(callback_called_
);
247 SetResponse(VALID_RESPONSE
);
250 EXPECT_TRUE(callback_called_
);
251 EXPECT_EQ(kAndroidId
, android_id_
);
252 EXPECT_EQ(kSecurityToken
, security_token_
);
255 TEST_F(CheckinRequestTest
, ResponseHttpStatusUnauthorized
) {
256 CreateRequest(0u, 0u);
259 SetResponseStatusAndString(net::HTTP_UNAUTHORIZED
, std::string());
262 EXPECT_TRUE(callback_called_
);
263 EXPECT_EQ(kBlankAndroidId
, android_id_
);
264 EXPECT_EQ(kBlankSecurityToken
, security_token_
);
267 TEST_F(CheckinRequestTest
, ResponseHttpStatusBadRequest
) {
268 CreateRequest(0u, 0u);
271 SetResponseStatusAndString(net::HTTP_BAD_REQUEST
, std::string());
274 EXPECT_TRUE(callback_called_
);
275 EXPECT_EQ(kBlankAndroidId
, android_id_
);
276 EXPECT_EQ(kBlankSecurityToken
, security_token_
);
279 TEST_F(CheckinRequestTest
, ResponseHttpStatusNotOK
) {
280 CreateRequest(0u, 0u);
283 SetResponseStatusAndString(net::HTTP_INTERNAL_SERVER_ERROR
, std::string());
286 EXPECT_FALSE(callback_called_
);
288 SetResponse(VALID_RESPONSE
);
291 EXPECT_TRUE(callback_called_
);
292 EXPECT_EQ(kAndroidId
, android_id_
);
293 EXPECT_EQ(kSecurityToken
, security_token_
);
296 TEST_F(CheckinRequestTest
, ResponseMissingAndroidId
) {
297 CreateRequest(0u, 0u);
300 SetResponse(MISSING_ANDROID_ID
);
303 EXPECT_FALSE(callback_called_
);
305 SetResponse(VALID_RESPONSE
);
308 EXPECT_TRUE(callback_called_
);
309 EXPECT_EQ(kAndroidId
, android_id_
);
310 EXPECT_EQ(kSecurityToken
, security_token_
);
313 TEST_F(CheckinRequestTest
, ResponseMissingSecurityToken
) {
314 CreateRequest(0u, 0u);
317 SetResponse(MISSING_SECURITY_TOKEN
);
320 EXPECT_FALSE(callback_called_
);
322 SetResponse(VALID_RESPONSE
);
325 EXPECT_TRUE(callback_called_
);
326 EXPECT_EQ(kAndroidId
, android_id_
);
327 EXPECT_EQ(kSecurityToken
, security_token_
);
330 TEST_F(CheckinRequestTest
, AndroidIdEqualsZeroInResponse
) {
331 CreateRequest(0u, 0u);
334 SetResponse(ANDROID_ID_IS_ZER0
);
337 EXPECT_FALSE(callback_called_
);
339 SetResponse(VALID_RESPONSE
);
342 EXPECT_TRUE(callback_called_
);
343 EXPECT_EQ(kAndroidId
, android_id_
);
344 EXPECT_EQ(kSecurityToken
, security_token_
);
347 TEST_F(CheckinRequestTest
, SecurityTokenEqualsZeroInResponse
) {
348 CreateRequest(0u, 0u);
351 SetResponse(SECURITY_TOKEN_IS_ZERO
);
354 EXPECT_FALSE(callback_called_
);
356 SetResponse(VALID_RESPONSE
);
359 EXPECT_TRUE(callback_called_
);
360 EXPECT_EQ(kAndroidId
, android_id_
);
361 EXPECT_EQ(kSecurityToken
, security_token_
);
364 TEST_F(CheckinRequestTest
, SuccessfulFirstTimeCheckin
) {
365 CreateRequest(0u, 0u);
368 SetResponse(VALID_RESPONSE
);
371 EXPECT_TRUE(callback_called_
);
372 EXPECT_EQ(kAndroidId
, android_id_
);
373 EXPECT_EQ(kSecurityToken
, security_token_
);
376 TEST_F(CheckinRequestTest
, SuccessfulSubsequentCheckin
) {
377 CreateRequest(kAndroidId
, kSecurityToken
);
380 SetResponse(VALID_RESPONSE
);
383 EXPECT_TRUE(callback_called_
);
384 EXPECT_EQ(kAndroidId
, android_id_
);
385 EXPECT_EQ(kSecurityToken
, security_token_
);