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 <map> 6#include <string> 7#include <vector> 8 9#include "base/strings/string_number_conversions.h" 10#include "base/strings/string_tokenizer.h" 11#include "google_apis/gcm/engine/registration_request.h" 12#include "google_apis/gcm/monitoring/fake_gcm_stats_recorder.h" 13#include "net/url_request/test_url_fetcher_factory.h" 14#include "net/url_request/url_request_status.h" 15#include "net/url_request/url_request_test_util.h" 16#include "testing/gtest/include/gtest/gtest.h" 17 18namespace gcm { 19 20namespace { 21const uint64 kAndroidId = 42UL; 22const char kAppId[] = "TestAppId"; 23const char kDeveloperId[] = "Project1"; 24const char kLoginHeader[] = "AidLogin"; 25const char kRegistrationURL[] = "http://foo.bar/register"; 26const uint64 kSecurityToken = 77UL; 27 28// Backoff policy for testing registration request. 29const net::BackoffEntry::Policy kDefaultBackoffPolicy = { 30 // Number of initial errors (in sequence) to ignore before applying 31 // exponential back-off rules. 32 // Explicitly set to 2 to skip the delay on the first retry, as we are not 33 // trying to test the backoff itself, but rather the fact that retry happens. 34 2, 35 36 // Initial delay for exponential back-off in ms. 37 15000, // 15 seconds. 38 39 // Factor by which the waiting time will be multiplied. 40 2, 41 42 // Fuzzing percentage. ex: 10% will spread requests randomly 43 // between 90%-100% of the calculated time. 44 0.5, // 50%. 45 46 // Maximum amount of time we are willing to delay our request in ms. 47 1000 * 60 * 5, // 5 minutes. 48 49 // Time to keep an entry from being discarded even when it 50 // has no significant state, -1 to never discard. 51 -1, 52 53 // Don't use initial delay unless the last request was an error. 54 false, 55}; 56 57} // namespace 58 59class RegistrationRequestTest : public testing::Test { 60 public: 61 RegistrationRequestTest(); 62 virtual ~RegistrationRequestTest(); 63 64 void RegistrationCallback(RegistrationRequest::Status status, 65 const std::string& registration_id); 66 67 void CreateRequest(const std::string& sender_ids); 68 void SetResponseStatusAndString(net::HttpStatusCode status_code, 69 const std::string& response_body); 70 void CompleteFetch(); 71 void set_max_retry_count(int max_retry_count) { 72 max_retry_count_ = max_retry_count; 73 } 74 75 protected: 76 int max_retry_count_; 77 RegistrationRequest::Status status_; 78 std::string registration_id_; 79 bool callback_called_; 80 std::map<std::string, std::string> extras_; 81 scoped_ptr<RegistrationRequest> request_; 82 base::MessageLoop message_loop_; 83 net::TestURLFetcherFactory url_fetcher_factory_; 84 scoped_refptr<net::TestURLRequestContextGetter> url_request_context_getter_; 85 FakeGCMStatsRecorder recorder_; 86}; 87 88RegistrationRequestTest::RegistrationRequestTest() 89 : max_retry_count_(2), 90 status_(RegistrationRequest::SUCCESS), 91 callback_called_(false), 92 url_request_context_getter_(new net::TestURLRequestContextGetter( 93 message_loop_.message_loop_proxy())) {} 94 95RegistrationRequestTest::~RegistrationRequestTest() {} 96 97void RegistrationRequestTest::RegistrationCallback( 98 RegistrationRequest::Status status, 99 const std::string& registration_id) { 100 status_ = status; 101 registration_id_ = registration_id; 102 callback_called_ = true; 103} 104 105void RegistrationRequestTest::CreateRequest(const std::string& sender_ids) { 106 std::vector<std::string> senders; 107 base::StringTokenizer tokenizer(sender_ids, ","); 108 while (tokenizer.GetNext()) 109 senders.push_back(tokenizer.token()); 110 111 request_.reset(new RegistrationRequest( 112 GURL(kRegistrationURL), 113 RegistrationRequest::RequestInfo(kAndroidId, 114 kSecurityToken, 115 kAppId, 116 senders), 117 kDefaultBackoffPolicy, 118 base::Bind(&RegistrationRequestTest::RegistrationCallback, 119 base::Unretained(this)), 120 max_retry_count_, 121 url_request_context_getter_.get(), 122 &recorder_)); 123} 124 125void RegistrationRequestTest::SetResponseStatusAndString( 126 net::HttpStatusCode status_code, 127 const std::string& response_body) { 128 net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0); 129 ASSERT_TRUE(fetcher); 130 fetcher->set_response_code(status_code); 131 fetcher->SetResponseString(response_body); 132} 133 134void RegistrationRequestTest::CompleteFetch() { 135 registration_id_.clear(); 136 status_ = RegistrationRequest::SUCCESS; 137 callback_called_ = false; 138 139 net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0); 140 ASSERT_TRUE(fetcher); 141 fetcher->delegate()->OnURLFetchComplete(fetcher); 142} 143 144TEST_F(RegistrationRequestTest, RequestSuccessful) { 145 set_max_retry_count(0); 146 CreateRequest("sender1,sender2"); 147 request_->Start(); 148 149 SetResponseStatusAndString(net::HTTP_OK, "token=2501"); 150 CompleteFetch(); 151 152 EXPECT_TRUE(callback_called_); 153 EXPECT_EQ(RegistrationRequest::SUCCESS, status_); 154 EXPECT_EQ("2501", registration_id_); 155} 156 157TEST_F(RegistrationRequestTest, RequestDataAndURL) { 158 CreateRequest(kDeveloperId); 159 request_->Start(); 160 161 // Get data sent by request. 162 net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0); 163 ASSERT_TRUE(fetcher); 164 165 EXPECT_EQ(GURL(kRegistrationURL), fetcher->GetOriginalURL()); 166 167 // Verify that authorization header was put together properly. 168 net::HttpRequestHeaders headers; 169 fetcher->GetExtraRequestHeaders(&headers); 170 std::string auth_header; 171 headers.GetHeader(net::HttpRequestHeaders::kAuthorization, &auth_header); 172 base::StringTokenizer auth_tokenizer(auth_header, " :"); 173 ASSERT_TRUE(auth_tokenizer.GetNext()); 174 EXPECT_EQ(kLoginHeader, auth_tokenizer.token()); 175 ASSERT_TRUE(auth_tokenizer.GetNext()); 176 EXPECT_EQ(base::Uint64ToString(kAndroidId), auth_tokenizer.token()); 177 ASSERT_TRUE(auth_tokenizer.GetNext()); 178 EXPECT_EQ(base::Uint64ToString(kSecurityToken), auth_tokenizer.token()); 179 180 std::map<std::string, std::string> expected_pairs; 181 expected_pairs["app"] = kAppId; 182 expected_pairs["sender"] = kDeveloperId; 183 expected_pairs["device"] = base::Uint64ToString(kAndroidId); 184 185 // Verify data was formatted properly. 186 std::string upload_data = fetcher->upload_data(); 187 base::StringTokenizer data_tokenizer(upload_data, "&="); 188 while (data_tokenizer.GetNext()) { 189 std::map<std::string, std::string>::iterator iter = 190 expected_pairs.find(data_tokenizer.token()); 191 ASSERT_TRUE(iter != expected_pairs.end()); 192 ASSERT_TRUE(data_tokenizer.GetNext()); 193 EXPECT_EQ(iter->second, data_tokenizer.token()); 194 // Ensure that none of the keys appears twice. 195 expected_pairs.erase(iter); 196 } 197 198 EXPECT_EQ(0UL, expected_pairs.size()); 199} 200 201TEST_F(RegistrationRequestTest, RequestRegistrationWithMultipleSenderIds) { 202 CreateRequest("sender1,sender2@gmail.com"); 203 request_->Start(); 204 205 net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0); 206 ASSERT_TRUE(fetcher); 207 208 // Verify data was formatted properly. 209 std::string upload_data = fetcher->upload_data(); 210 base::StringTokenizer data_tokenizer(upload_data, "&="); 211 212 // Skip all tokens until you hit entry for senders. 213 while (data_tokenizer.GetNext() && data_tokenizer.token() != "sender") 214 continue; 215 216 ASSERT_TRUE(data_tokenizer.GetNext()); 217 std::string senders(net::UnescapeURLComponent(data_tokenizer.token(), 218 net::UnescapeRule::URL_SPECIAL_CHARS)); 219 base::StringTokenizer sender_tokenizer(senders, ","); 220 ASSERT_TRUE(sender_tokenizer.GetNext()); 221 EXPECT_EQ("sender1", sender_tokenizer.token()); 222 ASSERT_TRUE(sender_tokenizer.GetNext()); 223 EXPECT_EQ("sender2@gmail.com", sender_tokenizer.token()); 224} 225 226TEST_F(RegistrationRequestTest, ResponseParsing) { 227 CreateRequest("sender1,sender2"); 228 request_->Start(); 229 230 SetResponseStatusAndString(net::HTTP_OK, "token=2501"); 231 CompleteFetch(); 232 233 EXPECT_TRUE(callback_called_); 234 EXPECT_EQ(RegistrationRequest::SUCCESS, status_); 235 EXPECT_EQ("2501", registration_id_); 236} 237 238TEST_F(RegistrationRequestTest, ResponseHttpStatusNotOK) { 239 CreateRequest("sender1,sender2"); 240 request_->Start(); 241 242 SetResponseStatusAndString(net::HTTP_UNAUTHORIZED, "token=2501"); 243 CompleteFetch(); 244 245 EXPECT_FALSE(callback_called_); 246 247 SetResponseStatusAndString(net::HTTP_OK, "token=2501"); 248 CompleteFetch(); 249 250 EXPECT_TRUE(callback_called_); 251 EXPECT_EQ(RegistrationRequest::SUCCESS, status_); 252 EXPECT_EQ("2501", registration_id_); 253} 254 255TEST_F(RegistrationRequestTest, ResponseMissingRegistrationId) { 256 CreateRequest("sender1,sender2"); 257 request_->Start(); 258 259 SetResponseStatusAndString(net::HTTP_OK, ""); 260 CompleteFetch(); 261 262 EXPECT_FALSE(callback_called_); 263 264 SetResponseStatusAndString(net::HTTP_OK, "some error in response"); 265 CompleteFetch(); 266 267 EXPECT_FALSE(callback_called_); 268 269 // Ensuring a retry happened and succeeds. 270 SetResponseStatusAndString(net::HTTP_OK, "token=2501"); 271 CompleteFetch(); 272 273 EXPECT_TRUE(callback_called_); 274 EXPECT_EQ(RegistrationRequest::SUCCESS, status_); 275 EXPECT_EQ("2501", registration_id_); 276} 277 278TEST_F(RegistrationRequestTest, ResponseDeviceRegistrationError) { 279 CreateRequest("sender1,sender2"); 280 request_->Start(); 281 282 SetResponseStatusAndString(net::HTTP_OK, "Error=PHONE_REGISTRATION_ERROR"); 283 CompleteFetch(); 284 285 EXPECT_FALSE(callback_called_); 286 287 // Ensuring a retry happened and succeeds. 288 SetResponseStatusAndString(net::HTTP_OK, "token=2501"); 289 CompleteFetch(); 290 291 EXPECT_TRUE(callback_called_); 292 EXPECT_EQ(RegistrationRequest::SUCCESS, status_); 293 EXPECT_EQ("2501", registration_id_); 294} 295 296TEST_F(RegistrationRequestTest, ResponseAuthenticationError) { 297 CreateRequest("sender1,sender2"); 298 request_->Start(); 299 300 SetResponseStatusAndString(net::HTTP_UNAUTHORIZED, 301 "Error=AUTHENTICATION_FAILED"); 302 CompleteFetch(); 303 304 EXPECT_FALSE(callback_called_); 305 306 // Ensuring a retry happened and succeeds. 307 SetResponseStatusAndString(net::HTTP_OK, "token=2501"); 308 CompleteFetch(); 309 310 EXPECT_TRUE(callback_called_); 311 EXPECT_EQ(RegistrationRequest::SUCCESS, status_); 312 EXPECT_EQ("2501", registration_id_); 313} 314 315TEST_F(RegistrationRequestTest, ResponseInvalidParameters) { 316 CreateRequest("sender1,sender2"); 317 request_->Start(); 318 319 SetResponseStatusAndString(net::HTTP_OK, "Error=INVALID_PARAMETERS"); 320 CompleteFetch(); 321 322 EXPECT_TRUE(callback_called_); 323 EXPECT_EQ(RegistrationRequest::INVALID_PARAMETERS, status_); 324 EXPECT_EQ(std::string(), registration_id_); 325} 326 327TEST_F(RegistrationRequestTest, ResponseInvalidSender) { 328 CreateRequest("sender1,sender2"); 329 request_->Start(); 330 331 SetResponseStatusAndString(net::HTTP_OK, "Error=INVALID_SENDER"); 332 CompleteFetch(); 333 334 EXPECT_TRUE(callback_called_); 335 EXPECT_EQ(RegistrationRequest::INVALID_SENDER, status_); 336 EXPECT_EQ(std::string(), registration_id_); 337} 338 339TEST_F(RegistrationRequestTest, ResponseInvalidSenderBadRequest) { 340 CreateRequest("sender1"); 341 request_->Start(); 342 343 SetResponseStatusAndString(net::HTTP_BAD_REQUEST, "Error=INVALID_SENDER"); 344 CompleteFetch(); 345 346 EXPECT_TRUE(callback_called_); 347 EXPECT_EQ(RegistrationRequest::INVALID_SENDER, status_); 348 EXPECT_EQ(std::string(), registration_id_); 349} 350 351TEST_F(RegistrationRequestTest, RequestNotSuccessful) { 352 CreateRequest("sender1,sender2"); 353 request_->Start(); 354 355 net::URLRequestStatus request_status(net::URLRequestStatus::FAILED, 1); 356 SetResponseStatusAndString(net::HTTP_OK, "token=2501"); 357 net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0); 358 ASSERT_TRUE(fetcher); 359 fetcher->set_status(request_status); 360 361 CompleteFetch(); 362 363 EXPECT_FALSE(callback_called_); 364 365 // Ensuring a retry happened and succeeded. 366 SetResponseStatusAndString(net::HTTP_OK, "token=2501"); 367 CompleteFetch(); 368 369 EXPECT_TRUE(callback_called_); 370 EXPECT_EQ(RegistrationRequest::SUCCESS, status_); 371 EXPECT_EQ("2501", registration_id_); 372} 373 374TEST_F(RegistrationRequestTest, ResponseHttpNotOk) { 375 CreateRequest("sender1,sender2"); 376 request_->Start(); 377 378 SetResponseStatusAndString(net::HTTP_GATEWAY_TIMEOUT, "token=2501"); 379 CompleteFetch(); 380 381 EXPECT_FALSE(callback_called_); 382 383 // Ensuring a retry happened and succeeded. 384 SetResponseStatusAndString(net::HTTP_OK, "token=2501"); 385 CompleteFetch(); 386 387 EXPECT_TRUE(callback_called_); 388 EXPECT_EQ(RegistrationRequest::SUCCESS, status_); 389 EXPECT_EQ("2501", registration_id_); 390} 391 392TEST_F(RegistrationRequestTest, MaximumAttemptsReachedWithZeroRetries) { 393 set_max_retry_count(0); 394 CreateRequest("sender1,sender2"); 395 request_->Start(); 396 397 SetResponseStatusAndString(net::HTTP_GATEWAY_TIMEOUT, "token=2501"); 398 CompleteFetch(); 399 400 EXPECT_TRUE(callback_called_); 401 EXPECT_EQ(RegistrationRequest::REACHED_MAX_RETRIES, status_); 402 EXPECT_EQ(std::string(), registration_id_); 403} 404 405TEST_F(RegistrationRequestTest, MaximumAttemptsReached) { 406 CreateRequest("sender1,sender2"); 407 request_->Start(); 408 409 SetResponseStatusAndString(net::HTTP_GATEWAY_TIMEOUT, "token=2501"); 410 CompleteFetch(); 411 412 EXPECT_FALSE(callback_called_); 413 414 SetResponseStatusAndString(net::HTTP_GATEWAY_TIMEOUT, "token=2501"); 415 CompleteFetch(); 416 417 EXPECT_FALSE(callback_called_); 418 419 SetResponseStatusAndString(net::HTTP_GATEWAY_TIMEOUT, "token=2501"); 420 CompleteFetch(); 421 422 EXPECT_TRUE(callback_called_); 423 EXPECT_EQ(RegistrationRequest::REACHED_MAX_RETRIES, status_); 424 EXPECT_EQ(std::string(), registration_id_); 425} 426 427} // namespace gcm 428