blob: 11147675cc1620cbc82ebe6c3f1ea9a6be535102 [file] [log] [blame]
[email protected]848b1b62014-01-30 23:51:041// 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
[email protected]cd57f372014-06-09 17:13:065#include "components/gcm_driver/gcm_client_impl.h"
[email protected]848b1b62014-01-30 23:51:046
avi26062922015-12-26 00:14:187#include <stdint.h>
8
johnme627dc8c72016-08-19 21:49:399#include <initializer_list>
dchenga77e28eb2016-04-21 21:34:3710#include <memory>
11
[email protected]fdeaf9732014-04-11 21:02:1512#include "base/command_line.h"
jianli00b4600f2015-02-10 23:32:4913#include "base/files/file_path.h"
14#include "base/files/file_util.h"
[email protected]848b1b62014-01-30 23:51:0415#include "base/files/scoped_temp_dir.h"
avi26062922015-12-26 00:14:1816#include "base/macros.h"
dchenga77e28eb2016-04-21 21:34:3717#include "base/memory/ptr_util.h"
[email protected]764c0442014-05-01 04:30:5518#include "base/strings/string_number_conversions.h"
johnme6d6c7802016-09-29 22:27:1619#include "base/test/histogram_tester.h"
jianli78b56042015-06-17 01:21:2220#include "base/test/test_mock_time_task_runner.h"
gab7966d312016-05-11 20:35:0121#include "base/threading/thread_task_runner_handle.h"
[email protected]764c0442014-05-01 04:30:5522#include "base/time/clock.h"
chirantan26436e402014-10-24 19:44:4223#include "base/timer/timer.h"
[email protected]446f73c22014-05-14 20:47:1824#include "google_apis/gcm/base/fake_encryptor.h"
[email protected]848b1b62014-01-30 23:51:0425#include "google_apis/gcm/base/mcs_message.h"
26#include "google_apis/gcm/base/mcs_util.h"
27#include "google_apis/gcm/engine/fake_connection_factory.h"
28#include "google_apis/gcm/engine/fake_connection_handler.h"
[email protected]764c0442014-05-01 04:30:5529#include "google_apis/gcm/engine/gservices_settings.h"
[email protected]436bcb82014-04-18 00:40:5730#include "google_apis/gcm/monitoring/gcm_stats_recorder.h"
[email protected]848b1b62014-01-30 23:51:0431#include "google_apis/gcm/protocol/android_checkin.pb.h"
32#include "google_apis/gcm/protocol/checkin.pb.h"
33#include "google_apis/gcm/protocol/mcs.pb.h"
johnme627dc8c72016-08-19 21:49:3934#include "net/test/gtest_util.h"
35#include "net/test/scoped_disable_exit_on_dfatal.h"
[email protected]848b1b62014-01-30 23:51:0436#include "net/url_request/test_url_fetcher_factory.h"
37#include "net/url_request/url_fetcher_delegate.h"
38#include "net/url_request/url_request_test_util.h"
johnme627dc8c72016-08-19 21:49:3939#include "testing/gtest/include/gtest/gtest-spi.h"
[email protected]848b1b62014-01-30 23:51:0440#include "testing/gtest/include/gtest/gtest.h"
Chris Mumforda884aa1f2017-10-24 22:46:3241#include "third_party/leveldatabase/leveldb_chrome.h"
[email protected]848b1b62014-01-30 23:51:0442
43namespace gcm {
44
45namespace {
46
47enum LastEvent {
48 NONE,
49 LOADING_COMPLETED,
[email protected]848b1b62014-01-30 23:51:0450 REGISTRATION_COMPLETED,
[email protected]e4007042014-02-15 20:34:2851 UNREGISTRATION_COMPLETED,
[email protected]848b1b62014-01-30 23:51:0452 MESSAGE_SEND_ERROR,
[email protected]292af2b22014-08-06 19:42:4553 MESSAGE_SEND_ACK,
[email protected]848b1b62014-01-30 23:51:0454 MESSAGE_RECEIVED,
55 MESSAGES_DELETED,
56};
57
jianlic02d25e2015-05-27 22:24:3158const char kChromeVersion[] = "45.0.0.1";
avi26062922015-12-26 00:14:1859const uint64_t kDeviceAndroidId = 54321;
60const uint64_t kDeviceSecurityToken = 12345;
61const uint64_t kDeviceAndroidId2 = 11111;
62const uint64_t kDeviceSecurityToken2 = 2222;
63const int64_t kSettingsCheckinInterval = 16 * 60 * 60;
johnme627dc8c72016-08-19 21:49:3964const char kProductCategoryForSubtypes[] = "com.chrome.macosx";
65const char kExtensionAppId[] = "abcdefghijklmnopabcdefghijklmnop";
66const char kSubtypeAppId[] = "app_id";
[email protected]3a20a4d2014-03-21 22:54:2167const char kSender[] = "project_id";
68const char kSender2[] = "project_id2";
[email protected]848b1b62014-01-30 23:51:0469const char kRegistrationResponsePrefix[] = "token=";
[email protected]e4007042014-02-15 20:34:2870const char kUnregistrationResponsePrefix[] = "deleted=";
petera5aedc52015-07-22 10:47:3071const char kRawData[] = "example raw data";
[email protected]848b1b62014-01-30 23:51:0472
jianlic02d25e2015-05-27 22:24:3173const char kInstanceID[] = "iid_1";
74const char kScope[] = "GCM";
75const char kDeleteTokenResponse[] = "token=foo";
76
[email protected]848b1b62014-01-30 23:51:0477// Helper for building arbitrary data messages.
78MCSMessage BuildDownstreamMessage(
79 const std::string& project_id,
johnme627dc8c72016-08-19 21:49:3980 const std::string& category,
81 const std::string& subtype,
petera5aedc52015-07-22 10:47:3082 const std::map<std::string, std::string>& data,
83 const std::string& raw_data) {
[email protected]848b1b62014-01-30 23:51:0484 mcs_proto::DataMessageStanza data_message;
[email protected]848b1b62014-01-30 23:51:0485 data_message.set_from(project_id);
johnme627dc8c72016-08-19 21:49:3986 data_message.set_category(category);
[email protected]848b1b62014-01-30 23:51:0487 for (std::map<std::string, std::string>::const_iterator iter = data.begin();
88 iter != data.end();
89 ++iter) {
90 mcs_proto::AppData* app_data = data_message.add_app_data();
91 app_data->set_key(iter->first);
92 app_data->set_value(iter->second);
93 }
johnme627dc8c72016-08-19 21:49:3994 if (!subtype.empty()) {
95 mcs_proto::AppData* app_data = data_message.add_app_data();
96 app_data->set_key("subtype");
97 app_data->set_value(subtype);
98 }
petera5aedc52015-07-22 10:47:3099 data_message.set_raw_data(raw_data);
[email protected]848b1b62014-01-30 23:51:04100 return MCSMessage(kDataMessageStanzaTag, data_message);
101}
102
fgorski58b9dfc2014-09-29 16:46:18103GCMClient::AccountTokenInfo MakeAccountToken(const std::string& email,
104 const std::string& token) {
105 GCMClient::AccountTokenInfo account_token;
106 account_token.email = email;
107 account_token.access_token = token;
108 return account_token;
109}
110
111std::map<std::string, std::string> MakeEmailToTokenMap(
112 const std::vector<GCMClient::AccountTokenInfo>& account_tokens) {
113 std::map<std::string, std::string> email_token_map;
114 for (std::vector<GCMClient::AccountTokenInfo>::const_iterator iter =
115 account_tokens.begin(); iter != account_tokens.end(); ++iter) {
116 email_token_map[iter->email] = iter->access_token;
117 }
118 return email_token_map;
119}
120
[email protected]848b1b62014-01-30 23:51:04121class FakeMCSClient : public MCSClient {
122 public:
123 FakeMCSClient(base::Clock* clock,
[email protected]2bbe0a682014-03-26 00:08:31124 ConnectionFactory* connection_factory,
[email protected]436bcb82014-04-18 00:40:57125 GCMStore* gcm_store,
126 GCMStatsRecorder* recorder);
dcheng00ea022b2014-10-21 11:24:56127 ~FakeMCSClient() override;
avi26062922015-12-26 00:14:18128 void Login(uint64_t android_id, uint64_t security_token) override;
dcheng00ea022b2014-10-21 11:24:56129 void SendMessage(const MCSMessage& message) override;
[email protected]848b1b62014-01-30 23:51:04130
avi26062922015-12-26 00:14:18131 uint64_t last_android_id() const { return last_android_id_; }
132 uint64_t last_security_token() const { return last_security_token_; }
133 uint8_t last_message_tag() const { return last_message_tag_; }
[email protected]848b1b62014-01-30 23:51:04134 const mcs_proto::DataMessageStanza& last_data_message_stanza() const {
135 return last_data_message_stanza_;
136 }
137
138 private:
avi26062922015-12-26 00:14:18139 uint64_t last_android_id_;
140 uint64_t last_security_token_;
141 uint8_t last_message_tag_;
[email protected]848b1b62014-01-30 23:51:04142 mcs_proto::DataMessageStanza last_data_message_stanza_;
143};
144
145FakeMCSClient::FakeMCSClient(base::Clock* clock,
[email protected]2bbe0a682014-03-26 00:08:31146 ConnectionFactory* connection_factory,
[email protected]436bcb82014-04-18 00:40:57147 GCMStore* gcm_store,
148 GCMStatsRecorder* recorder)
chirantan192a9212014-12-06 03:30:45149 : MCSClient("", clock, connection_factory, gcm_store, recorder),
[email protected]848b1b62014-01-30 23:51:04150 last_android_id_(0u),
151 last_security_token_(0u),
152 last_message_tag_(kNumProtoTypes) {
153}
154
155FakeMCSClient::~FakeMCSClient() {
156}
157
avi26062922015-12-26 00:14:18158void FakeMCSClient::Login(uint64_t android_id, uint64_t security_token) {
[email protected]848b1b62014-01-30 23:51:04159 last_android_id_ = android_id;
160 last_security_token_ = security_token;
161}
162
163void FakeMCSClient::SendMessage(const MCSMessage& message) {
164 last_message_tag_ = message.tag();
165 if (last_message_tag_ == kDataMessageStanzaTag) {
166 last_data_message_stanza_.CopyFrom(
167 reinterpret_cast<const mcs_proto::DataMessageStanza&>(
168 message.GetProtobuf()));
169 }
170}
171
[email protected]764c0442014-05-01 04:30:55172class AutoAdvancingTestClock : public base::Clock {
173 public:
174 explicit AutoAdvancingTestClock(base::TimeDelta auto_increment_time_delta);
dcheng00ea022b2014-10-21 11:24:56175 ~AutoAdvancingTestClock() override;
[email protected]764c0442014-05-01 04:30:55176
dcheng00ea022b2014-10-21 11:24:56177 base::Time Now() override;
[email protected]764c0442014-05-01 04:30:55178 void Advance(TimeDelta delta);
179 int call_count() const { return call_count_; }
180
181 private:
182 int call_count_;
183 base::TimeDelta auto_increment_time_delta_;
184 base::Time now_;
185
186 DISALLOW_COPY_AND_ASSIGN(AutoAdvancingTestClock);
187};
188
189AutoAdvancingTestClock::AutoAdvancingTestClock(
190 base::TimeDelta auto_increment_time_delta)
191 : call_count_(0), auto_increment_time_delta_(auto_increment_time_delta) {
192}
193
194AutoAdvancingTestClock::~AutoAdvancingTestClock() {
195}
196
197base::Time AutoAdvancingTestClock::Now() {
198 call_count_++;
199 now_ += auto_increment_time_delta_;
200 return now_;
201}
202
203void AutoAdvancingTestClock::Advance(base::TimeDelta delta) {
204 now_ += delta;
205}
206
[email protected]2bbe0a682014-03-26 00:08:31207class FakeGCMInternalsBuilder : public GCMInternalsBuilder {
208 public:
[email protected]764c0442014-05-01 04:30:55209 FakeGCMInternalsBuilder(base::TimeDelta clock_step);
dcheng00ea022b2014-10-21 11:24:56210 ~FakeGCMInternalsBuilder() override;
[email protected]2bbe0a682014-03-26 00:08:31211
dchenga77e28eb2016-04-21 21:34:37212 std::unique_ptr<base::Clock> BuildClock() override;
213 std::unique_ptr<MCSClient> BuildMCSClient(
214 const std::string& version,
215 base::Clock* clock,
216 ConnectionFactory* connection_factory,
217 GCMStore* gcm_store,
218 GCMStatsRecorder* recorder) override;
219 std::unique_ptr<ConnectionFactory> BuildConnectionFactory(
[email protected]2bbe0a682014-03-26 00:08:31220 const std::vector<GURL>& endpoints,
221 const net::BackoffEntry::Policy& backoff_policy,
mmenkee65e7af2015-10-13 17:16:42222 net::HttpNetworkSession* gcm_network_session,
223 net::HttpNetworkSession* http_network_session,
mostynbfe59f482014-10-06 15:04:46224 GCMStatsRecorder* recorder) override;
[email protected]764c0442014-05-01 04:30:55225
226 private:
227 base::TimeDelta clock_step_;
[email protected]2bbe0a682014-03-26 00:08:31228};
229
[email protected]764c0442014-05-01 04:30:55230FakeGCMInternalsBuilder::FakeGCMInternalsBuilder(base::TimeDelta clock_step)
231 : clock_step_(clock_step) {
232}
[email protected]2bbe0a682014-03-26 00:08:31233
234FakeGCMInternalsBuilder::~FakeGCMInternalsBuilder() {}
235
dchenga77e28eb2016-04-21 21:34:37236std::unique_ptr<base::Clock> FakeGCMInternalsBuilder::BuildClock() {
237 return base::WrapUnique<base::Clock>(new AutoAdvancingTestClock(clock_step_));
[email protected]2bbe0a682014-03-26 00:08:31238}
239
dchenga77e28eb2016-04-21 21:34:37240std::unique_ptr<MCSClient> FakeGCMInternalsBuilder::BuildMCSClient(
[email protected]2bbe0a682014-03-26 00:08:31241 const std::string& version,
242 base::Clock* clock,
243 ConnectionFactory* connection_factory,
[email protected]436bcb82014-04-18 00:40:57244 GCMStore* gcm_store,
245 GCMStatsRecorder* recorder) {
dchenga77e28eb2016-04-21 21:34:37246 return base::WrapUnique<MCSClient>(
247 new FakeMCSClient(clock, connection_factory, gcm_store, recorder));
[email protected]2bbe0a682014-03-26 00:08:31248}
249
dchenga77e28eb2016-04-21 21:34:37250std::unique_ptr<ConnectionFactory>
251FakeGCMInternalsBuilder::BuildConnectionFactory(
[email protected]2bbe0a682014-03-26 00:08:31252 const std::vector<GURL>& endpoints,
253 const net::BackoffEntry::Policy& backoff_policy,
mmenkee65e7af2015-10-13 17:16:42254 net::HttpNetworkSession* gcm_network_session,
255 net::HttpNetworkSession* http_network_session,
[email protected]9df5b932014-04-30 00:39:06256 GCMStatsRecorder* recorder) {
dchenga77e28eb2016-04-21 21:34:37257 return base::WrapUnique<ConnectionFactory>(new FakeConnectionFactory());
[email protected]2bbe0a682014-03-26 00:08:31258}
259
[email protected]848b1b62014-01-30 23:51:04260} // namespace
261
262class GCMClientImplTest : public testing::Test,
263 public GCMClient::Delegate {
264 public:
265 GCMClientImplTest();
dcheng30a1b1542014-10-29 21:27:50266 ~GCMClientImplTest() override;
[email protected]848b1b62014-01-30 23:51:04267
dcheng30a1b1542014-10-29 21:27:50268 void SetUp() override;
[email protected]848b1b62014-01-30 23:51:04269
fgorski5df101702014-10-28 02:09:31270 void SetUpUrlFetcherFactory();
271
[email protected]764c0442014-05-01 04:30:55272 void BuildGCMClient(base::TimeDelta clock_step);
[email protected]848b1b62014-01-30 23:51:04273 void InitializeGCMClient();
[email protected]1abdf202014-06-13 19:38:53274 void StartGCMClient();
jianli7a0c9b62015-05-26 23:24:47275 void Register(const std::string& app_id,
276 const std::vector<std::string>& senders);
277 void Unregister(const std::string& app_id);
[email protected]848b1b62014-01-30 23:51:04278 void ReceiveMessageFromMCS(const MCSMessage& message);
[email protected]292af2b22014-08-06 19:42:45279 void ReceiveOnMessageSentToMCS(
280 const std::string& app_id,
281 const std::string& message_id,
282 const MCSClient::MessageSendStatus status);
zea76342abf2016-11-01 17:26:04283 void FailCheckin(net::HttpStatusCode response_code);
avi26062922015-12-26 00:14:18284 void CompleteCheckin(uint64_t android_id,
285 uint64_t security_token,
[email protected]764c0442014-05-01 04:30:55286 const std::string& digest,
287 const std::map<std::string, std::string>& settings);
zea76342abf2016-11-01 17:26:04288 void CompleteCheckinImpl(uint64_t android_id,
289 uint64_t security_token,
290 const std::string& digest,
291 const std::map<std::string, std::string>& settings,
292 net::HttpStatusCode response_code);
[email protected]848b1b62014-01-30 23:51:04293 void CompleteRegistration(const std::string& registration_id);
[email protected]e4007042014-02-15 20:34:28294 void CompleteUnregistration(const std::string& app_id);
fgorskie45a34f2014-10-08 17:37:46295 void VerifyPendingRequestFetcherDeleted();
[email protected]848b1b62014-01-30 23:51:04296
[email protected]3a20a4d2014-03-21 22:54:21297 bool ExistsRegistration(const std::string& app_id) const;
298 void AddRegistration(const std::string& app_id,
299 const std::vector<std::string>& sender_ids,
300 const std::string& registration_id);
301
[email protected]848b1b62014-01-30 23:51:04302 // GCMClient::Delegate overrides (for verification).
jianli7a0c9b62015-05-26 23:24:47303 void OnRegisterFinished(const linked_ptr<RegistrationInfo>& registration_info,
dcheng00ea022b2014-10-21 11:24:56304 const std::string& registration_id,
305 GCMClient::Result result) override;
jianli7a0c9b62015-05-26 23:24:47306 void OnUnregisterFinished(
307 const linked_ptr<RegistrationInfo>& registration_info,
308 GCMClient::Result result) override;
dcheng00ea022b2014-10-21 11:24:56309 void OnSendFinished(const std::string& app_id,
310 const std::string& message_id,
311 GCMClient::Result result) override {}
312 void OnMessageReceived(const std::string& registration_id,
mvanouwerkerkf8633deb2015-07-13 11:04:06313 const IncomingMessage& message) override;
dcheng00ea022b2014-10-21 11:24:56314 void OnMessagesDeleted(const std::string& app_id) override;
315 void OnMessageSendError(
[email protected]c6fe36b2014-03-11 10:58:12316 const std::string& app_id,
mostynbfe59f482014-10-06 15:04:46317 const gcm::GCMClient::SendErrorDetails& send_error_details) override;
dcheng00ea022b2014-10-21 11:24:56318 void OnSendAcknowledged(const std::string& app_id,
319 const std::string& message_id) override;
fgorski5df101702014-10-28 02:09:31320 void OnGCMReady(const std::vector<AccountMapping>& account_mappings,
321 const base::Time& last_token_fetch_time) override;
dcheng00ea022b2014-10-21 11:24:56322 void OnActivityRecorded() override {}
323 void OnConnected(const net::IPEndPoint& ip_endpoint) override {}
324 void OnDisconnected() override {}
johnme93ec7932016-11-17 14:26:58325 void OnStoreReset() override {}
[email protected]848b1b62014-01-30 23:51:04326
[email protected]848b1b62014-01-30 23:51:04327 GCMClientImpl* gcm_client() const { return gcm_client_.get(); }
jianlif3e52af42015-01-21 23:18:47328 GCMClientImpl::State gcm_client_state() const {
329 return gcm_client_->state_;
330 }
[email protected]848b1b62014-01-30 23:51:04331 FakeMCSClient* mcs_client() const {
332 return reinterpret_cast<FakeMCSClient*>(gcm_client_->mcs_client_.get());
333 }
[email protected]2bbe0a682014-03-26 00:08:31334 ConnectionFactory* connection_factory() const {
335 return gcm_client_->connection_factory_.get();
336 }
[email protected]848b1b62014-01-30 23:51:04337
[email protected]7df5ef22014-07-17 07:35:58338 const GCMClientImpl::CheckinInfo& device_checkin_info() const {
339 return gcm_client_->device_checkin_info_;
340 }
341
[email protected]3a20a4d2014-03-21 22:54:21342 void reset_last_event() {
343 last_event_ = NONE;
344 last_app_id_.clear();
345 last_registration_id_.clear();
346 last_message_id_.clear();
347 last_result_ = GCMClient::UNKNOWN_ERROR;
fgorski5df101702014-10-28 02:09:31348 last_account_mappings_.clear();
349 last_token_fetch_time_ = base::Time();
[email protected]3a20a4d2014-03-21 22:54:21350 }
351
[email protected]848b1b62014-01-30 23:51:04352 LastEvent last_event() const { return last_event_; }
353 const std::string& last_app_id() const { return last_app_id_; }
354 const std::string& last_registration_id() const {
355 return last_registration_id_;
356 }
357 const std::string& last_message_id() const { return last_message_id_; }
358 GCMClient::Result last_result() const { return last_result_; }
mvanouwerkerkf8633deb2015-07-13 11:04:06359 const IncomingMessage& last_message() const { return last_message_; }
[email protected]c6fe36b2014-03-11 10:58:12360 const GCMClient::SendErrorDetails& last_error_details() const {
361 return last_error_details_;
362 }
fgorski5df101702014-10-28 02:09:31363 const base::Time& last_token_fetch_time() const {
364 return last_token_fetch_time_;
365 }
366 const std::vector<AccountMapping>& last_account_mappings() {
367 return last_account_mappings_;
368 }
[email protected]848b1b62014-01-30 23:51:04369
[email protected]06e45272014-05-06 03:41:34370 const GServicesSettings& gservices_settings() const {
371 return gcm_client_->gservices_settings_;
[email protected]764c0442014-05-01 04:30:55372 }
373
jianli00b4600f2015-02-10 23:32:49374 const base::FilePath& temp_directory_path() const {
vabr0c237ae2016-09-14 09:24:28375 return temp_directory_.GetPath();
jianli00b4600f2015-02-10 23:32:49376 }
377
jianli9f9a73672015-06-16 19:39:34378 base::FilePath gcm_store_path() const {
379 // Pass an non-existent directory as store path to match the exact
380 // behavior in the production code. Currently GCMStoreImpl checks if
381 // the directory exist or not to determine the store existence.
vabr0c237ae2016-09-14 09:24:28382 return temp_directory_.GetPath().Append(FILE_PATH_LITERAL("GCM Store"));
jianli9f9a73672015-06-16 19:39:34383 }
384
avi26062922015-12-26 00:14:18385 int64_t CurrentTime();
[email protected]d3ba08d92014-04-04 23:03:55386
387 // Tooling.
[email protected]d3ba08d92014-04-04 23:03:55388 void PumpLoopUntilIdle();
[email protected]764c0442014-05-01 04:30:55389 bool CreateUniqueTempDir();
390 AutoAdvancingTestClock* clock() const {
391 return reinterpret_cast<AutoAdvancingTestClock*>(gcm_client_->clock_.get());
[email protected]a0144ceb2014-04-04 23:49:34392 }
jianlic02d25e2015-05-27 22:24:31393 net::TestURLFetcherFactory* url_fetcher_factory() {
394 return &url_fetcher_factory_;
395 }
jianli78b56042015-06-17 01:21:22396 base::TestMockTimeTaskRunner* task_runner() {
397 return task_runner_.get();
398 }
[email protected]d3ba08d92014-04-04 23:03:55399
[email protected]764c0442014-05-01 04:30:55400 private:
wkormanc1e71b62015-11-09 22:56:04401 // Must be declared first so that it is destroyed last. Injected to
402 // GCM client.
403 base::ScopedTempDir temp_directory_;
404
[email protected]848b1b62014-01-30 23:51:04405 // Variables used for verification.
406 LastEvent last_event_;
407 std::string last_app_id_;
408 std::string last_registration_id_;
409 std::string last_message_id_;
410 GCMClient::Result last_result_;
mvanouwerkerkf8633deb2015-07-13 11:04:06411 IncomingMessage last_message_;
[email protected]c6fe36b2014-03-11 10:58:12412 GCMClient::SendErrorDetails last_error_details_;
fgorski5df101702014-10-28 02:09:31413 base::Time last_token_fetch_time_;
414 std::vector<AccountMapping> last_account_mappings_;
[email protected]848b1b62014-01-30 23:51:04415
dchenga77e28eb2016-04-21 21:34:37416 std::unique_ptr<GCMClientImpl> gcm_client_;
[email protected]848b1b62014-01-30 23:51:04417
[email protected]848b1b62014-01-30 23:51:04418 net::TestURLFetcherFactory url_fetcher_factory_;
419
jianli78b56042015-06-17 01:21:22420 scoped_refptr<base::TestMockTimeTaskRunner> task_runner_;
421 base::ThreadTaskRunnerHandle task_runner_handle_;
422
wkormanc1e71b62015-11-09 22:56:04423 // Injected to GCM client.
[email protected]848b1b62014-01-30 23:51:04424 scoped_refptr<net::TestURLRequestContextGetter> url_request_context_getter_;
425};
426
427GCMClientImplTest::GCMClientImplTest()
428 : last_event_(NONE),
429 last_result_(GCMClient::UNKNOWN_ERROR),
jianli78b56042015-06-17 01:21:22430 task_runner_(new base::TestMockTimeTaskRunner),
431 task_runner_handle_(task_runner_),
skyostilb0daa012015-06-02 19:03:48432 url_request_context_getter_(
jianli78b56042015-06-17 01:21:22433 new net::TestURLRequestContextGetter(task_runner_)) {
[email protected]848b1b62014-01-30 23:51:04434}
435
436GCMClientImplTest::~GCMClientImplTest() {}
437
438void GCMClientImplTest::SetUp() {
[email protected]fdeaf9732014-04-11 21:02:15439 testing::Test::SetUp();
[email protected]764c0442014-05-01 04:30:55440 ASSERT_TRUE(CreateUniqueTempDir());
[email protected]764c0442014-05-01 04:30:55441 BuildGCMClient(base::TimeDelta());
[email protected]848b1b62014-01-30 23:51:04442 InitializeGCMClient();
[email protected]1abdf202014-06-13 19:38:53443 StartGCMClient();
fgorski5df101702014-10-28 02:09:31444 SetUpUrlFetcherFactory();
johnme0fb2fc02016-07-14 14:47:44445 ASSERT_NO_FATAL_FAILURE(
446 CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken, std::string(),
447 std::map<std::string, std::string>()));
[email protected]848b1b62014-01-30 23:51:04448}
449
fgorski5df101702014-10-28 02:09:31450void GCMClientImplTest::SetUpUrlFetcherFactory() {
451 url_fetcher_factory_.set_remove_fetcher_on_delete(true);
452}
453
[email protected]848b1b62014-01-30 23:51:04454void GCMClientImplTest::PumpLoopUntilIdle() {
jianli78b56042015-06-17 01:21:22455 task_runner_->RunUntilIdle();
[email protected]848b1b62014-01-30 23:51:04456}
457
[email protected]764c0442014-05-01 04:30:55458bool GCMClientImplTest::CreateUniqueTempDir() {
459 return temp_directory_.CreateUniqueTempDir();
460}
461
462void GCMClientImplTest::BuildGCMClient(base::TimeDelta clock_step) {
dchenga77e28eb2016-04-21 21:34:37463 gcm_client_.reset(new GCMClientImpl(base::WrapUnique<GCMInternalsBuilder>(
[email protected]764c0442014-05-01 04:30:55464 new FakeGCMInternalsBuilder(clock_step))));
465}
466
zea76342abf2016-11-01 17:26:04467void GCMClientImplTest::FailCheckin(net::HttpStatusCode response_code) {
468 std::map<std::string, std::string> settings;
469 CompleteCheckinImpl(0, 0, GServicesSettings::CalculateDigest(settings),
470 settings, response_code);
471}
472
[email protected]764c0442014-05-01 04:30:55473void GCMClientImplTest::CompleteCheckin(
avi26062922015-12-26 00:14:18474 uint64_t android_id,
475 uint64_t security_token,
[email protected]764c0442014-05-01 04:30:55476 const std::string& digest,
477 const std::map<std::string, std::string>& settings) {
zea76342abf2016-11-01 17:26:04478 CompleteCheckinImpl(android_id, security_token, digest, settings,
479 net::HTTP_OK);
480}
481
482void GCMClientImplTest::CompleteCheckinImpl(
483 uint64_t android_id,
484 uint64_t security_token,
485 const std::string& digest,
486 const std::map<std::string, std::string>& settings,
487 net::HttpStatusCode response_code) {
[email protected]848b1b62014-01-30 23:51:04488 checkin_proto::AndroidCheckinResponse response;
489 response.set_stats_ok(true);
490 response.set_android_id(android_id);
491 response.set_security_token(security_token);
492
[email protected]764c0442014-05-01 04:30:55493 // For testing G-services settings.
494 if (!digest.empty()) {
495 response.set_digest(digest);
496 for (std::map<std::string, std::string>::const_iterator it =
497 settings.begin();
498 it != settings.end();
499 ++it) {
500 checkin_proto::GservicesSetting* setting = response.add_setting();
501 setting->set_name(it->first);
502 setting->set_value(it->second);
503 }
[email protected]aae544d72014-05-20 06:53:10504 response.set_settings_diff(false);
[email protected]764c0442014-05-01 04:30:55505 }
506
[email protected]848b1b62014-01-30 23:51:04507 std::string response_string;
508 response.SerializeToString(&response_string);
509
510 net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
511 ASSERT_TRUE(fetcher);
zea76342abf2016-11-01 17:26:04512 fetcher->set_response_code(response_code);
[email protected]848b1b62014-01-30 23:51:04513 fetcher->SetResponseString(response_string);
514 fetcher->delegate()->OnURLFetchComplete(fetcher);
jianlid7e80f22015-06-18 22:21:31515 // Give a chance for GCMStoreImpl::Backend to finish persisting data.
516 PumpLoopUntilIdle();
[email protected]848b1b62014-01-30 23:51:04517}
518
519void GCMClientImplTest::CompleteRegistration(
520 const std::string& registration_id) {
521 std::string response(kRegistrationResponsePrefix);
522 response.append(registration_id);
523 net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
524 ASSERT_TRUE(fetcher);
525 fetcher->set_response_code(net::HTTP_OK);
526 fetcher->SetResponseString(response);
527 fetcher->delegate()->OnURLFetchComplete(fetcher);
jianlid7e80f22015-06-18 22:21:31528 // Give a chance for GCMStoreImpl::Backend to finish persisting data.
529 PumpLoopUntilIdle();
[email protected]e4007042014-02-15 20:34:28530}
531
532void GCMClientImplTest::CompleteUnregistration(
533 const std::string& app_id) {
534 std::string response(kUnregistrationResponsePrefix);
535 response.append(app_id);
536 net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
537 ASSERT_TRUE(fetcher);
538 fetcher->set_response_code(net::HTTP_OK);
539 fetcher->SetResponseString(response);
540 fetcher->delegate()->OnURLFetchComplete(fetcher);
jianlid7e80f22015-06-18 22:21:31541 // Give a chance for GCMStoreImpl::Backend to finish persisting data.
542 PumpLoopUntilIdle();
fgorskie45a34f2014-10-08 17:37:46543}
544
545void GCMClientImplTest::VerifyPendingRequestFetcherDeleted() {
546 net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
547 EXPECT_FALSE(fetcher);
[email protected]3a20a4d2014-03-21 22:54:21548}
549
550bool GCMClientImplTest::ExistsRegistration(const std::string& app_id) const {
jianli7a0c9b62015-05-26 23:24:47551 return ExistsGCMRegistrationInMap(gcm_client_->registrations_, app_id);
[email protected]3a20a4d2014-03-21 22:54:21552}
553
554void GCMClientImplTest::AddRegistration(
555 const std::string& app_id,
556 const std::vector<std::string>& sender_ids,
557 const std::string& registration_id) {
jianli7a0c9b62015-05-26 23:24:47558 linked_ptr<GCMRegistrationInfo> registration(new GCMRegistrationInfo);
559 registration->app_id = app_id;
[email protected]3a20a4d2014-03-21 22:54:21560 registration->sender_ids = sender_ids;
jianli7a0c9b62015-05-26 23:24:47561 gcm_client_->registrations_[registration] = registration_id;
[email protected]848b1b62014-01-30 23:51:04562}
563
564void GCMClientImplTest::InitializeGCMClient() {
[email protected]848b1b62014-01-30 23:51:04565 clock()->Advance(base::TimeDelta::FromMilliseconds(1));
[email protected]2bbe0a682014-03-26 00:08:31566
[email protected]848b1b62014-01-30 23:51:04567 // Actual initialization.
[email protected]8ad80512014-05-23 09:40:47568 GCMClient::ChromeBuildInfo chrome_build_info;
jianlic02d25e2015-05-27 22:24:31569 chrome_build_info.version = kChromeVersion;
johnme627dc8c72016-08-19 21:49:39570 chrome_build_info.product_category_for_subtypes = kProductCategoryForSubtypes;
dchenga77e28eb2016-04-21 21:34:37571 gcm_client_->Initialize(chrome_build_info, gcm_store_path(), task_runner_,
572 url_request_context_getter_,
573 base::WrapUnique<Encryptor>(new FakeEncryptor), this);
[email protected]1abdf202014-06-13 19:38:53574}
[email protected]d3a4b2e2014-02-27 13:46:54575
[email protected]1abdf202014-06-13 19:38:53576void GCMClientImplTest::StartGCMClient() {
[email protected]2bbe0a682014-03-26 00:08:31577 // Start loading and check-in.
jianlif3e52af42015-01-21 23:18:47578 gcm_client_->Start(GCMClient::IMMEDIATE_START);
[email protected]d3a4b2e2014-02-27 13:46:54579
[email protected]848b1b62014-01-30 23:51:04580 PumpLoopUntilIdle();
[email protected]848b1b62014-01-30 23:51:04581}
582
jianli7a0c9b62015-05-26 23:24:47583void GCMClientImplTest::Register(const std::string& app_id,
584 const std::vector<std::string>& senders) {
dchenga77e28eb2016-04-21 21:34:37585 std::unique_ptr<GCMRegistrationInfo> gcm_info(new GCMRegistrationInfo);
jianli7a0c9b62015-05-26 23:24:47586 gcm_info->app_id = app_id;
587 gcm_info->sender_ids = senders;
588 gcm_client()->Register(make_linked_ptr<RegistrationInfo>(gcm_info.release()));
589}
590
591void GCMClientImplTest::Unregister(const std::string& app_id) {
dchenga77e28eb2016-04-21 21:34:37592 std::unique_ptr<GCMRegistrationInfo> gcm_info(new GCMRegistrationInfo);
jianli7a0c9b62015-05-26 23:24:47593 gcm_info->app_id = app_id;
594 gcm_client()->Unregister(
595 make_linked_ptr<RegistrationInfo>(gcm_info.release()));
596}
597
[email protected]848b1b62014-01-30 23:51:04598void GCMClientImplTest::ReceiveMessageFromMCS(const MCSMessage& message) {
[email protected]dd47c4ce2014-08-05 23:38:50599 gcm_client_->recorder_.RecordConnectionInitiated(std::string());
600 gcm_client_->recorder_.RecordConnectionSuccess();
[email protected]848b1b62014-01-30 23:51:04601 gcm_client_->OnMessageReceivedFromMCS(message);
602}
603
[email protected]292af2b22014-08-06 19:42:45604void GCMClientImplTest::ReceiveOnMessageSentToMCS(
605 const std::string& app_id,
606 const std::string& message_id,
607 const MCSClient::MessageSendStatus status) {
608 gcm_client_->OnMessageSentToMCS(0LL, app_id, message_id, status);
609}
610
fgorskid578c18b2014-09-24 23:40:17611void GCMClientImplTest::OnGCMReady(
fgorski5df101702014-10-28 02:09:31612 const std::vector<AccountMapping>& account_mappings,
613 const base::Time& last_token_fetch_time) {
[email protected]848b1b62014-01-30 23:51:04614 last_event_ = LOADING_COMPLETED;
fgorski5df101702014-10-28 02:09:31615 last_account_mappings_ = account_mappings;
616 last_token_fetch_time_ = last_token_fetch_time;
[email protected]848b1b62014-01-30 23:51:04617}
618
mvanouwerkerkf8633deb2015-07-13 11:04:06619void GCMClientImplTest::OnMessageReceived(const std::string& registration_id,
620 const IncomingMessage& message) {
[email protected]848b1b62014-01-30 23:51:04621 last_event_ = MESSAGE_RECEIVED;
622 last_app_id_ = registration_id;
623 last_message_ = message;
[email protected]848b1b62014-01-30 23:51:04624}
625
jianli7a0c9b62015-05-26 23:24:47626void GCMClientImplTest::OnRegisterFinished(
627 const linked_ptr<RegistrationInfo>& registration_info,
628 const std::string& registration_id,
629 GCMClient::Result result) {
[email protected]848b1b62014-01-30 23:51:04630 last_event_ = REGISTRATION_COMPLETED;
jianli7a0c9b62015-05-26 23:24:47631 last_app_id_ = registration_info->app_id;
[email protected]848b1b62014-01-30 23:51:04632 last_registration_id_ = registration_id;
633 last_result_ = result;
634}
635
jianli7a0c9b62015-05-26 23:24:47636void GCMClientImplTest::OnUnregisterFinished(
637 const linked_ptr<RegistrationInfo>& registration_info,
638 GCMClient::Result result) {
[email protected]e4007042014-02-15 20:34:28639 last_event_ = UNREGISTRATION_COMPLETED;
jianli7a0c9b62015-05-26 23:24:47640 last_app_id_ = registration_info->app_id;
[email protected]0e88e1d12014-03-19 06:53:08641 last_result_ = result;
[email protected]e4007042014-02-15 20:34:28642}
643
[email protected]848b1b62014-01-30 23:51:04644void GCMClientImplTest::OnMessagesDeleted(const std::string& app_id) {
645 last_event_ = MESSAGES_DELETED;
646 last_app_id_ = app_id;
647}
648
[email protected]c6fe36b2014-03-11 10:58:12649void GCMClientImplTest::OnMessageSendError(
650 const std::string& app_id,
651 const gcm::GCMClient::SendErrorDetails& send_error_details) {
[email protected]848b1b62014-01-30 23:51:04652 last_event_ = MESSAGE_SEND_ERROR;
653 last_app_id_ = app_id;
[email protected]c6fe36b2014-03-11 10:58:12654 last_error_details_ = send_error_details;
[email protected]848b1b62014-01-30 23:51:04655}
656
[email protected]292af2b22014-08-06 19:42:45657void GCMClientImplTest::OnSendAcknowledged(const std::string& app_id,
658 const std::string& message_id) {
659 last_event_ = MESSAGE_SEND_ACK;
660 last_app_id_ = app_id;
661 last_message_id_ = message_id;
662}
663
avi26062922015-12-26 00:14:18664int64_t GCMClientImplTest::CurrentTime() {
[email protected]848b1b62014-01-30 23:51:04665 return clock()->Now().ToInternalValue() / base::Time::kMicrosecondsPerSecond;
666}
667
[email protected]848b1b62014-01-30 23:51:04668TEST_F(GCMClientImplTest, LoadingCompleted) {
669 EXPECT_EQ(LOADING_COMPLETED, last_event());
670 EXPECT_EQ(kDeviceAndroidId, mcs_client()->last_android_id());
671 EXPECT_EQ(kDeviceSecurityToken, mcs_client()->last_security_token());
[email protected]7df5ef22014-07-17 07:35:58672
673 // Checking freshly loaded CheckinInfo.
674 EXPECT_EQ(kDeviceAndroidId, device_checkin_info().android_id);
675 EXPECT_EQ(kDeviceSecurityToken, device_checkin_info().secret);
676 EXPECT_TRUE(device_checkin_info().last_checkin_accounts.empty());
677 EXPECT_TRUE(device_checkin_info().accounts_set);
678 EXPECT_TRUE(device_checkin_info().account_tokens.empty());
[email protected]848b1b62014-01-30 23:51:04679}
680
jianli00b4600f2015-02-10 23:32:49681TEST_F(GCMClientImplTest, LoadingBusted) {
682 // Close the GCM store.
683 gcm_client()->Stop();
684 PumpLoopUntilIdle();
685
686 // Mess up the store.
Chris Mumforda884aa1f2017-10-24 22:46:32687 EXPECT_TRUE(leveldb_chrome::CorruptClosedDBForTesting(gcm_store_path()));
jianli00b4600f2015-02-10 23:32:49688
689 // Restart GCM client. The store should be reset and the loading should
690 // complete successfully.
691 reset_last_event();
692 BuildGCMClient(base::TimeDelta());
693 InitializeGCMClient();
694 StartGCMClient();
johnme0fb2fc02016-07-14 14:47:44695 ASSERT_NO_FATAL_FAILURE(
696 CompleteCheckin(kDeviceAndroidId2, kDeviceSecurityToken2, std::string(),
697 std::map<std::string, std::string>()));
jianli00b4600f2015-02-10 23:32:49698
699 EXPECT_EQ(LOADING_COMPLETED, last_event());
700 EXPECT_EQ(kDeviceAndroidId2, mcs_client()->last_android_id());
701 EXPECT_EQ(kDeviceSecurityToken2, mcs_client()->last_security_token());
702}
703
johnme6d6c7802016-09-29 22:27:16704TEST_F(GCMClientImplTest, LoadingWithEmptyDirectory) {
705 // Close the GCM store.
706 gcm_client()->Stop();
707 PumpLoopUntilIdle();
708
709 // Make the store directory empty, to simulate a previous destroy store
710 // operation failing to delete the store directory.
711 ASSERT_TRUE(base::DeleteFile(gcm_store_path(), true /* recursive */));
712 ASSERT_TRUE(base::CreateDirectory(gcm_store_path()));
713
714 base::HistogramTester histogram_tester;
715
716 // Restart GCM client. The store should be considered to not exist.
717 BuildGCMClient(base::TimeDelta());
718 InitializeGCMClient();
719 gcm_client()->Start(GCMClient::DELAYED_START);
720 PumpLoopUntilIdle();
721 histogram_tester.ExpectUniqueSample("GCM.LoadStatus",
722 13 /* STORE_DOES_NOT_EXIST */, 1);
723 // Since the store does not exist, the database should not have been opened.
724 histogram_tester.ExpectTotalCount("GCM.Database.Open", 0);
725 // Without a store, DELAYED_START loading should only reach INITIALIZED state.
726 EXPECT_EQ(GCMClientImpl::INITIALIZED, gcm_client_state());
727
728 // The store directory should still exist (and be empty). If not, then the
729 // DELAYED_START load has probably reset the store, rather than leaving that
730 // to the next IMMEDIATE_START load as expected.
731 ASSERT_TRUE(base::DirectoryExists(gcm_store_path()));
732 ASSERT_FALSE(
733 base::PathExists(gcm_store_path().Append(FILE_PATH_LITERAL("CURRENT"))));
734
735 // IMMEDIATE_START loading should successfully create a new store despite the
736 // empty directory.
737 reset_last_event();
738 StartGCMClient();
739 ASSERT_NO_FATAL_FAILURE(
740 CompleteCheckin(kDeviceAndroidId2, kDeviceSecurityToken2, std::string(),
741 std::map<std::string, std::string>()));
742 EXPECT_EQ(LOADING_COMPLETED, last_event());
743 EXPECT_EQ(GCMClientImpl::READY, gcm_client_state());
744 EXPECT_EQ(kDeviceAndroidId2, mcs_client()->last_android_id());
745 EXPECT_EQ(kDeviceSecurityToken2, mcs_client()->last_security_token());
746}
747
jianli78b56042015-06-17 01:21:22748TEST_F(GCMClientImplTest, DestroyStoreWhenNotNeeded) {
749 // Close the GCM store.
750 gcm_client()->Stop();
751 PumpLoopUntilIdle();
752
753 // Restart GCM client. The store is loaded successfully.
754 reset_last_event();
755 BuildGCMClient(base::TimeDelta());
756 InitializeGCMClient();
757 gcm_client()->Start(GCMClient::DELAYED_START);
758 PumpLoopUntilIdle();
759
760 EXPECT_EQ(GCMClientImpl::LOADED, gcm_client_state());
761 EXPECT_TRUE(device_checkin_info().android_id);
762 EXPECT_TRUE(device_checkin_info().secret);
763
764 // Fast forward the clock to trigger the store destroying logic.
765 task_runner()->FastForwardBy(base::TimeDelta::FromMilliseconds(300000));
766 PumpLoopUntilIdle();
767
768 EXPECT_EQ(GCMClientImpl::INITIALIZED, gcm_client_state());
769 EXPECT_FALSE(device_checkin_info().android_id);
770 EXPECT_FALSE(device_checkin_info().secret);
771}
772
[email protected]848b1b62014-01-30 23:51:04773TEST_F(GCMClientImplTest, RegisterApp) {
johnme627dc8c72016-08-19 21:49:39774 EXPECT_FALSE(ExistsRegistration(kExtensionAppId));
[email protected]3a20a4d2014-03-21 22:54:21775
[email protected]848b1b62014-01-30 23:51:04776 std::vector<std::string> senders;
777 senders.push_back("sender");
johnme627dc8c72016-08-19 21:49:39778 Register(kExtensionAppId, senders);
johnme0fb2fc02016-07-14 14:47:44779 ASSERT_NO_FATAL_FAILURE(CompleteRegistration("reg_id"));
[email protected]848b1b62014-01-30 23:51:04780
781 EXPECT_EQ(REGISTRATION_COMPLETED, last_event());
johnme627dc8c72016-08-19 21:49:39782 EXPECT_EQ(kExtensionAppId, last_app_id());
[email protected]848b1b62014-01-30 23:51:04783 EXPECT_EQ("reg_id", last_registration_id());
784 EXPECT_EQ(GCMClient::SUCCESS, last_result());
johnme627dc8c72016-08-19 21:49:39785 EXPECT_TRUE(ExistsRegistration(kExtensionAppId));
[email protected]3a20a4d2014-03-21 22:54:21786}
787
[email protected]3904d2b2014-03-22 01:34:31788TEST_F(GCMClientImplTest, DISABLED_RegisterAppFromCache) {
johnme627dc8c72016-08-19 21:49:39789 EXPECT_FALSE(ExistsRegistration(kExtensionAppId));
[email protected]3a20a4d2014-03-21 22:54:21790
791 std::vector<std::string> senders;
792 senders.push_back("sender");
johnme627dc8c72016-08-19 21:49:39793 Register(kExtensionAppId, senders);
johnme0fb2fc02016-07-14 14:47:44794 ASSERT_NO_FATAL_FAILURE(CompleteRegistration("reg_id"));
johnme627dc8c72016-08-19 21:49:39795 EXPECT_TRUE(ExistsRegistration(kExtensionAppId));
[email protected]3a20a4d2014-03-21 22:54:21796
johnme627dc8c72016-08-19 21:49:39797 EXPECT_EQ(kExtensionAppId, last_app_id());
[email protected]3a20a4d2014-03-21 22:54:21798 EXPECT_EQ("reg_id", last_registration_id());
799 EXPECT_EQ(GCMClient::SUCCESS, last_result());
800 EXPECT_EQ(REGISTRATION_COMPLETED, last_event());
801
802 // Recreate GCMClient in order to load from the persistent store.
[email protected]764c0442014-05-01 04:30:55803 BuildGCMClient(base::TimeDelta());
[email protected]3a20a4d2014-03-21 22:54:21804 InitializeGCMClient();
[email protected]1abdf202014-06-13 19:38:53805 StartGCMClient();
[email protected]3a20a4d2014-03-21 22:54:21806
johnme627dc8c72016-08-19 21:49:39807 EXPECT_TRUE(ExistsRegistration(kExtensionAppId));
[email protected]848b1b62014-01-30 23:51:04808}
809
jianli055634b2015-06-29 21:32:12810TEST_F(GCMClientImplTest, RegisterPreviousSenderAgain) {
johnme627dc8c72016-08-19 21:49:39811 EXPECT_FALSE(ExistsRegistration(kExtensionAppId));
jianli055634b2015-06-29 21:32:12812
813 // Register a sender.
814 std::vector<std::string> senders;
815 senders.push_back("sender");
johnme627dc8c72016-08-19 21:49:39816 Register(kExtensionAppId, senders);
johnme0fb2fc02016-07-14 14:47:44817 ASSERT_NO_FATAL_FAILURE(CompleteRegistration("reg_id"));
jianli055634b2015-06-29 21:32:12818
819 EXPECT_EQ(REGISTRATION_COMPLETED, last_event());
johnme627dc8c72016-08-19 21:49:39820 EXPECT_EQ(kExtensionAppId, last_app_id());
jianli055634b2015-06-29 21:32:12821 EXPECT_EQ("reg_id", last_registration_id());
822 EXPECT_EQ(GCMClient::SUCCESS, last_result());
johnme627dc8c72016-08-19 21:49:39823 EXPECT_TRUE(ExistsRegistration(kExtensionAppId));
jianli055634b2015-06-29 21:32:12824
825 reset_last_event();
826
827 // Register a different sender. Different registration ID from previous one
828 // should be returned.
829 std::vector<std::string> senders2;
830 senders2.push_back("sender2");
johnme627dc8c72016-08-19 21:49:39831 Register(kExtensionAppId, senders2);
johnme0fb2fc02016-07-14 14:47:44832 ASSERT_NO_FATAL_FAILURE(CompleteRegistration("reg_id2"));
jianli055634b2015-06-29 21:32:12833
834 EXPECT_EQ(REGISTRATION_COMPLETED, last_event());
johnme627dc8c72016-08-19 21:49:39835 EXPECT_EQ(kExtensionAppId, last_app_id());
jianli055634b2015-06-29 21:32:12836 EXPECT_EQ("reg_id2", last_registration_id());
837 EXPECT_EQ(GCMClient::SUCCESS, last_result());
johnme627dc8c72016-08-19 21:49:39838 EXPECT_TRUE(ExistsRegistration(kExtensionAppId));
jianli055634b2015-06-29 21:32:12839
840 reset_last_event();
841
842 // Register the 1st sender again. Different registration ID from previous one
843 // should be returned.
844 std::vector<std::string> senders3;
845 senders3.push_back("sender");
johnme627dc8c72016-08-19 21:49:39846 Register(kExtensionAppId, senders3);
johnme0fb2fc02016-07-14 14:47:44847 ASSERT_NO_FATAL_FAILURE(CompleteRegistration("reg_id"));
jianli055634b2015-06-29 21:32:12848
849 EXPECT_EQ(REGISTRATION_COMPLETED, last_event());
johnme627dc8c72016-08-19 21:49:39850 EXPECT_EQ(kExtensionAppId, last_app_id());
jianli055634b2015-06-29 21:32:12851 EXPECT_EQ("reg_id", last_registration_id());
852 EXPECT_EQ(GCMClient::SUCCESS, last_result());
johnme627dc8c72016-08-19 21:49:39853 EXPECT_TRUE(ExistsRegistration(kExtensionAppId));
jianli055634b2015-06-29 21:32:12854}
855
[email protected]e4007042014-02-15 20:34:28856TEST_F(GCMClientImplTest, UnregisterApp) {
johnme627dc8c72016-08-19 21:49:39857 EXPECT_FALSE(ExistsRegistration(kExtensionAppId));
[email protected]3a20a4d2014-03-21 22:54:21858
859 std::vector<std::string> senders;
860 senders.push_back("sender");
johnme627dc8c72016-08-19 21:49:39861 Register(kExtensionAppId, senders);
johnme0fb2fc02016-07-14 14:47:44862 ASSERT_NO_FATAL_FAILURE(CompleteRegistration("reg_id"));
johnme627dc8c72016-08-19 21:49:39863 EXPECT_TRUE(ExistsRegistration(kExtensionAppId));
[email protected]3a20a4d2014-03-21 22:54:21864
johnme627dc8c72016-08-19 21:49:39865 Unregister(kExtensionAppId);
866 ASSERT_NO_FATAL_FAILURE(CompleteUnregistration(kExtensionAppId));
[email protected]e4007042014-02-15 20:34:28867
868 EXPECT_EQ(UNREGISTRATION_COMPLETED, last_event());
johnme627dc8c72016-08-19 21:49:39869 EXPECT_EQ(kExtensionAppId, last_app_id());
[email protected]e4007042014-02-15 20:34:28870 EXPECT_EQ(GCMClient::SUCCESS, last_result());
johnme627dc8c72016-08-19 21:49:39871 EXPECT_FALSE(ExistsRegistration(kExtensionAppId));
[email protected]e4007042014-02-15 20:34:28872}
873
fgorskie45a34f2014-10-08 17:37:46874// Tests that stopping the GCMClient also deletes pending registration requests.
875// This is tested by checking that url fetcher contained in the request was
876// deleted.
877TEST_F(GCMClientImplTest, DeletePendingRequestsWhenStopping) {
878 std::vector<std::string> senders;
879 senders.push_back("sender");
johnme627dc8c72016-08-19 21:49:39880 Register(kExtensionAppId, senders);
fgorskie45a34f2014-10-08 17:37:46881
882 gcm_client()->Stop();
jianlid7e80f22015-06-18 22:21:31883 PumpLoopUntilIdle();
fgorskie45a34f2014-10-08 17:37:46884 VerifyPendingRequestFetcherDeleted();
885}
886
[email protected]848b1b62014-01-30 23:51:04887TEST_F(GCMClientImplTest, DispatchDownstreamMessage) {
[email protected]3a20a4d2014-03-21 22:54:21888 // Register to receive messages from kSender and kSender2 only.
889 std::vector<std::string> senders;
890 senders.push_back(kSender);
891 senders.push_back(kSender2);
johnme627dc8c72016-08-19 21:49:39892 AddRegistration(kExtensionAppId, senders, "reg_id");
[email protected]3a20a4d2014-03-21 22:54:21893
[email protected]848b1b62014-01-30 23:51:04894 std::map<std::string, std::string> expected_data;
895 expected_data["message_type"] = "gcm";
896 expected_data["key"] = "value";
897 expected_data["key2"] = "value2";
[email protected]3a20a4d2014-03-21 22:54:21898
899 // Message for kSender will be received.
johnme627dc8c72016-08-19 21:49:39900 MCSMessage message(BuildDownstreamMessage(
901 kSender, kExtensionAppId, std::string() /* subtype */, expected_data,
902 std::string() /* raw_data */));
[email protected]848b1b62014-01-30 23:51:04903 EXPECT_TRUE(message.IsValid());
904 ReceiveMessageFromMCS(message);
905
906 expected_data.erase(expected_data.find("message_type"));
907 EXPECT_EQ(MESSAGE_RECEIVED, last_event());
johnme627dc8c72016-08-19 21:49:39908 EXPECT_EQ(kExtensionAppId, last_app_id());
[email protected]848b1b62014-01-30 23:51:04909 EXPECT_EQ(expected_data.size(), last_message().data.size());
910 EXPECT_EQ(expected_data, last_message().data);
[email protected]3a20a4d2014-03-21 22:54:21911 EXPECT_EQ(kSender, last_message().sender_id);
912
913 reset_last_event();
914
915 // Message for kSender2 will be received.
johnme627dc8c72016-08-19 21:49:39916 MCSMessage message2(BuildDownstreamMessage(
917 kSender2, kExtensionAppId, std::string() /* subtype */, expected_data,
918 std::string() /* raw_data */));
[email protected]3a20a4d2014-03-21 22:54:21919 EXPECT_TRUE(message2.IsValid());
920 ReceiveMessageFromMCS(message2);
921
922 EXPECT_EQ(MESSAGE_RECEIVED, last_event());
johnme627dc8c72016-08-19 21:49:39923 EXPECT_EQ(kExtensionAppId, last_app_id());
[email protected]3a20a4d2014-03-21 22:54:21924 EXPECT_EQ(expected_data.size(), last_message().data.size());
925 EXPECT_EQ(expected_data, last_message().data);
926 EXPECT_EQ(kSender2, last_message().sender_id);
[email protected]848b1b62014-01-30 23:51:04927}
928
petera5aedc52015-07-22 10:47:30929TEST_F(GCMClientImplTest, DispatchDownstreamMessageRawData) {
930 std::vector<std::string> senders(1, kSender);
johnme627dc8c72016-08-19 21:49:39931 AddRegistration(kExtensionAppId, senders, "reg_id");
petera5aedc52015-07-22 10:47:30932
933 std::map<std::string, std::string> expected_data;
934
johnme627dc8c72016-08-19 21:49:39935 MCSMessage message(BuildDownstreamMessage(kSender, kExtensionAppId,
936 std::string() /* subtype */,
937 expected_data, kRawData));
petera5aedc52015-07-22 10:47:30938 EXPECT_TRUE(message.IsValid());
939 ReceiveMessageFromMCS(message);
940
941 EXPECT_EQ(MESSAGE_RECEIVED, last_event());
johnme627dc8c72016-08-19 21:49:39942 EXPECT_EQ(kExtensionAppId, last_app_id());
petera5aedc52015-07-22 10:47:30943 EXPECT_EQ(expected_data.size(), last_message().data.size());
944 EXPECT_EQ(kSender, last_message().sender_id);
945 EXPECT_EQ(kRawData, last_message().raw_data);
946}
947
[email protected]848b1b62014-01-30 23:51:04948TEST_F(GCMClientImplTest, DispatchDownstreamMessageSendError) {
949 std::map<std::string, std::string> expected_data;
950 expected_data["message_type"] = "send_error";
951 expected_data["google.message_id"] = "007";
[email protected]c6fe36b2014-03-11 10:58:12952 expected_data["error_details"] = "some details";
johnme627dc8c72016-08-19 21:49:39953 MCSMessage message(BuildDownstreamMessage(
954 kSender, kExtensionAppId, std::string() /* subtype */, expected_data,
955 std::string() /* raw_data */));
[email protected]848b1b62014-01-30 23:51:04956 EXPECT_TRUE(message.IsValid());
957 ReceiveMessageFromMCS(message);
958
959 EXPECT_EQ(MESSAGE_SEND_ERROR, last_event());
johnme627dc8c72016-08-19 21:49:39960 EXPECT_EQ(kExtensionAppId, last_app_id());
[email protected]c6fe36b2014-03-11 10:58:12961 EXPECT_EQ("007", last_error_details().message_id);
962 EXPECT_EQ(1UL, last_error_details().additional_data.size());
mvanouwerkerkf8633deb2015-07-13 11:04:06963 MessageData::const_iterator iter =
[email protected]c6fe36b2014-03-11 10:58:12964 last_error_details().additional_data.find("error_details");
965 EXPECT_TRUE(iter != last_error_details().additional_data.end());
966 EXPECT_EQ("some details", iter->second);
[email protected]848b1b62014-01-30 23:51:04967}
968
969TEST_F(GCMClientImplTest, DispatchDownstreamMessgaesDeleted) {
970 std::map<std::string, std::string> expected_data;
971 expected_data["message_type"] = "deleted_messages";
johnme627dc8c72016-08-19 21:49:39972 MCSMessage message(BuildDownstreamMessage(
973 kSender, kExtensionAppId, std::string() /* subtype */, expected_data,
974 std::string() /* raw_data */));
[email protected]848b1b62014-01-30 23:51:04975 EXPECT_TRUE(message.IsValid());
976 ReceiveMessageFromMCS(message);
977
978 EXPECT_EQ(MESSAGES_DELETED, last_event());
johnme627dc8c72016-08-19 21:49:39979 EXPECT_EQ(kExtensionAppId, last_app_id());
[email protected]848b1b62014-01-30 23:51:04980}
981
982TEST_F(GCMClientImplTest, SendMessage) {
mvanouwerkerkf8633deb2015-07-13 11:04:06983 OutgoingMessage message;
[email protected]848b1b62014-01-30 23:51:04984 message.id = "007";
985 message.time_to_live = 500;
986 message.data["key"] = "value";
johnme627dc8c72016-08-19 21:49:39987 gcm_client()->Send(kExtensionAppId, kSender, message);
[email protected]848b1b62014-01-30 23:51:04988
989 EXPECT_EQ(kDataMessageStanzaTag, mcs_client()->last_message_tag());
johnme627dc8c72016-08-19 21:49:39990 EXPECT_EQ(kExtensionAppId,
991 mcs_client()->last_data_message_stanza().category());
[email protected]3a20a4d2014-03-21 22:54:21992 EXPECT_EQ(kSender, mcs_client()->last_data_message_stanza().to());
[email protected]848b1b62014-01-30 23:51:04993 EXPECT_EQ(500, mcs_client()->last_data_message_stanza().ttl());
994 EXPECT_EQ(CurrentTime(), mcs_client()->last_data_message_stanza().sent());
995 EXPECT_EQ("007", mcs_client()->last_data_message_stanza().id());
[email protected]848b1b62014-01-30 23:51:04996 EXPECT_EQ("[email protected]", mcs_client()->last_data_message_stanza().from());
[email protected]3a20a4d2014-03-21 22:54:21997 EXPECT_EQ(kSender, mcs_client()->last_data_message_stanza().to());
[email protected]848b1b62014-01-30 23:51:04998 EXPECT_EQ("key", mcs_client()->last_data_message_stanza().app_data(0).key());
999 EXPECT_EQ("value",
1000 mcs_client()->last_data_message_stanza().app_data(0).value());
1001}
1002
[email protected]292af2b22014-08-06 19:42:451003TEST_F(GCMClientImplTest, SendMessageAcknowledged) {
johnme627dc8c72016-08-19 21:49:391004 ReceiveOnMessageSentToMCS(kExtensionAppId, "007", MCSClient::SENT);
[email protected]292af2b22014-08-06 19:42:451005 EXPECT_EQ(MESSAGE_SEND_ACK, last_event());
johnme627dc8c72016-08-19 21:49:391006 EXPECT_EQ(kExtensionAppId, last_app_id());
[email protected]292af2b22014-08-06 19:42:451007 EXPECT_EQ("007", last_message_id());
1008}
1009
[email protected]764c0442014-05-01 04:30:551010class GCMClientImplCheckinTest : public GCMClientImplTest {
1011 public:
1012 GCMClientImplCheckinTest();
dcheng30a1b1542014-10-29 21:27:501013 ~GCMClientImplCheckinTest() override;
[email protected]764c0442014-05-01 04:30:551014
dcheng30a1b1542014-10-29 21:27:501015 void SetUp() override;
[email protected]764c0442014-05-01 04:30:551016};
1017
1018GCMClientImplCheckinTest::GCMClientImplCheckinTest() {
1019}
1020
1021GCMClientImplCheckinTest::~GCMClientImplCheckinTest() {
1022}
1023
1024void GCMClientImplCheckinTest::SetUp() {
1025 testing::Test::SetUp();
[email protected]764c0442014-05-01 04:30:551026 // Creating unique temp directory that will be used by GCMStore shared between
1027 // GCM Client and G-services settings.
1028 ASSERT_TRUE(CreateUniqueTempDir());
[email protected]764c0442014-05-01 04:30:551029 // Time will be advancing one hour every time it is checked.
1030 BuildGCMClient(base::TimeDelta::FromSeconds(kSettingsCheckinInterval));
1031 InitializeGCMClient();
[email protected]1abdf202014-06-13 19:38:531032 StartGCMClient();
[email protected]764c0442014-05-01 04:30:551033}
1034
1035TEST_F(GCMClientImplCheckinTest, GServicesSettingsAfterInitialCheckin) {
1036 std::map<std::string, std::string> settings;
1037 settings["checkin_interval"] = base::Int64ToString(kSettingsCheckinInterval);
1038 settings["checkin_url"] = "http://alternative.url/checkin";
[email protected]8ab0c4b22014-05-10 20:40:131039 settings["gcm_hostname"] = "alternative.gcm.host";
1040 settings["gcm_secure_port"] = "7777";
[email protected]764c0442014-05-01 04:30:551041 settings["gcm_registration_url"] = "http://alternative.url/registration";
johnme0fb2fc02016-07-14 14:47:441042 ASSERT_NO_FATAL_FAILURE(
1043 CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken,
1044 GServicesSettings::CalculateDigest(settings), settings));
[email protected]f09354512014-05-02 00:51:131045 EXPECT_EQ(base::TimeDelta::FromSeconds(kSettingsCheckinInterval),
[email protected]aae544d72014-05-20 06:53:101046 gservices_settings().GetCheckinInterval());
[email protected]06e45272014-05-06 03:41:341047 EXPECT_EQ(GURL("http://alternative.url/checkin"),
[email protected]aae544d72014-05-20 06:53:101048 gservices_settings().GetCheckinURL());
[email protected]06e45272014-05-06 03:41:341049 EXPECT_EQ(GURL("http://alternative.url/registration"),
[email protected]aae544d72014-05-20 06:53:101050 gservices_settings().GetRegistrationURL());
[email protected]8ab0c4b22014-05-10 20:40:131051 EXPECT_EQ(GURL("https://alternative.gcm.host:7777"),
[email protected]aae544d72014-05-20 06:53:101052 gservices_settings().GetMCSMainEndpoint());
[email protected]8ab0c4b22014-05-10 20:40:131053 EXPECT_EQ(GURL("https://alternative.gcm.host:443"),
[email protected]aae544d72014-05-20 06:53:101054 gservices_settings().GetMCSFallbackEndpoint());
[email protected]764c0442014-05-01 04:30:551055}
1056
1057// This test only checks that periodic checkin happens.
1058TEST_F(GCMClientImplCheckinTest, PeriodicCheckin) {
1059 std::map<std::string, std::string> settings;
riceaf44cda22015-09-24 14:08:511060 settings["checkin_interval"] = base::Int64ToString(kSettingsCheckinInterval);
[email protected]764c0442014-05-01 04:30:551061 settings["checkin_url"] = "http://alternative.url/checkin";
[email protected]8ab0c4b22014-05-10 20:40:131062 settings["gcm_hostname"] = "alternative.gcm.host";
1063 settings["gcm_secure_port"] = "7777";
[email protected]764c0442014-05-01 04:30:551064 settings["gcm_registration_url"] = "http://alternative.url/registration";
johnme0fb2fc02016-07-14 14:47:441065 ASSERT_NO_FATAL_FAILURE(
1066 CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken,
1067 GServicesSettings::CalculateDigest(settings), settings));
[email protected]7df5ef22014-07-17 07:35:581068
[email protected]764c0442014-05-01 04:30:551069 EXPECT_EQ(2, clock()->call_count());
1070
1071 PumpLoopUntilIdle();
johnme0fb2fc02016-07-14 14:47:441072 ASSERT_NO_FATAL_FAILURE(
1073 CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken,
1074 GServicesSettings::CalculateDigest(settings), settings));
[email protected]764c0442014-05-01 04:30:551075}
1076
[email protected]06e45272014-05-06 03:41:341077TEST_F(GCMClientImplCheckinTest, LoadGSettingsFromStore) {
1078 std::map<std::string, std::string> settings;
riceaf44cda22015-09-24 14:08:511079 settings["checkin_interval"] = base::Int64ToString(kSettingsCheckinInterval);
[email protected]06e45272014-05-06 03:41:341080 settings["checkin_url"] = "http://alternative.url/checkin";
[email protected]8ab0c4b22014-05-10 20:40:131081 settings["gcm_hostname"] = "alternative.gcm.host";
1082 settings["gcm_secure_port"] = "7777";
[email protected]06e45272014-05-06 03:41:341083 settings["gcm_registration_url"] = "http://alternative.url/registration";
johnme0fb2fc02016-07-14 14:47:441084 ASSERT_NO_FATAL_FAILURE(
1085 CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken,
1086 GServicesSettings::CalculateDigest(settings), settings));
[email protected]06e45272014-05-06 03:41:341087
1088 BuildGCMClient(base::TimeDelta());
1089 InitializeGCMClient();
[email protected]1abdf202014-06-13 19:38:531090 StartGCMClient();
[email protected]06e45272014-05-06 03:41:341091
1092 EXPECT_EQ(base::TimeDelta::FromSeconds(kSettingsCheckinInterval),
[email protected]aae544d72014-05-20 06:53:101093 gservices_settings().GetCheckinInterval());
[email protected]06e45272014-05-06 03:41:341094 EXPECT_EQ(GURL("http://alternative.url/checkin"),
[email protected]aae544d72014-05-20 06:53:101095 gservices_settings().GetCheckinURL());
[email protected]06e45272014-05-06 03:41:341096 EXPECT_EQ(GURL("http://alternative.url/registration"),
[email protected]aae544d72014-05-20 06:53:101097 gservices_settings().GetRegistrationURL());
[email protected]8ab0c4b22014-05-10 20:40:131098 EXPECT_EQ(GURL("https://alternative.gcm.host:7777"),
[email protected]aae544d72014-05-20 06:53:101099 gservices_settings().GetMCSMainEndpoint());
[email protected]8ab0c4b22014-05-10 20:40:131100 EXPECT_EQ(GURL("https://alternative.gcm.host:443"),
[email protected]aae544d72014-05-20 06:53:101101 gservices_settings().GetMCSFallbackEndpoint());
[email protected]06e45272014-05-06 03:41:341102}
1103
[email protected]7df5ef22014-07-17 07:35:581104// This test only checks that periodic checkin happens.
1105TEST_F(GCMClientImplCheckinTest, CheckinWithAccounts) {
1106 std::map<std::string, std::string> settings;
riceaf44cda22015-09-24 14:08:511107 settings["checkin_interval"] = base::Int64ToString(kSettingsCheckinInterval);
[email protected]7df5ef22014-07-17 07:35:581108 settings["checkin_url"] = "http://alternative.url/checkin";
1109 settings["gcm_hostname"] = "alternative.gcm.host";
1110 settings["gcm_secure_port"] = "7777";
1111 settings["gcm_registration_url"] = "http://alternative.url/registration";
johnme0fb2fc02016-07-14 14:47:441112 ASSERT_NO_FATAL_FAILURE(
1113 CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken,
1114 GServicesSettings::CalculateDigest(settings), settings));
[email protected]7df5ef22014-07-17 07:35:581115
fgorski58b9dfc2014-09-29 16:46:181116 std::vector<GCMClient::AccountTokenInfo> account_tokens;
1117 account_tokens.push_back(MakeAccountToken("[email protected]", "token1"));
1118 account_tokens.push_back(MakeAccountToken("[email protected]", "token2"));
1119 gcm_client()->SetAccountTokens(account_tokens);
[email protected]7df5ef22014-07-17 07:35:581120
1121 EXPECT_TRUE(device_checkin_info().last_checkin_accounts.empty());
1122 EXPECT_TRUE(device_checkin_info().accounts_set);
fgorski58b9dfc2014-09-29 16:46:181123 EXPECT_EQ(MakeEmailToTokenMap(account_tokens),
1124 device_checkin_info().account_tokens);
[email protected]7df5ef22014-07-17 07:35:581125
1126 PumpLoopUntilIdle();
johnme0fb2fc02016-07-14 14:47:441127 ASSERT_NO_FATAL_FAILURE(
1128 CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken,
1129 GServicesSettings::CalculateDigest(settings), settings));
[email protected]7df5ef22014-07-17 07:35:581130
1131 std::set<std::string> accounts;
1132 accounts.insert("[email protected]");
1133 accounts.insert("[email protected]");
1134 EXPECT_EQ(accounts, device_checkin_info().last_checkin_accounts);
1135 EXPECT_TRUE(device_checkin_info().accounts_set);
fgorski58b9dfc2014-09-29 16:46:181136 EXPECT_EQ(MakeEmailToTokenMap(account_tokens),
1137 device_checkin_info().account_tokens);
[email protected]7df5ef22014-07-17 07:35:581138}
1139
1140// This test only checks that periodic checkin happens.
1141TEST_F(GCMClientImplCheckinTest, CheckinWhenAccountRemoved) {
1142 std::map<std::string, std::string> settings;
riceaf44cda22015-09-24 14:08:511143 settings["checkin_interval"] = base::Int64ToString(kSettingsCheckinInterval);
[email protected]7df5ef22014-07-17 07:35:581144 settings["checkin_url"] = "http://alternative.url/checkin";
1145 settings["gcm_hostname"] = "alternative.gcm.host";
1146 settings["gcm_secure_port"] = "7777";
1147 settings["gcm_registration_url"] = "http://alternative.url/registration";
johnme0fb2fc02016-07-14 14:47:441148 ASSERT_NO_FATAL_FAILURE(
1149 CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken,
1150 GServicesSettings::CalculateDigest(settings), settings));
[email protected]7df5ef22014-07-17 07:35:581151
fgorski58b9dfc2014-09-29 16:46:181152 std::vector<GCMClient::AccountTokenInfo> account_tokens;
1153 account_tokens.push_back(MakeAccountToken("[email protected]", "token1"));
1154 account_tokens.push_back(MakeAccountToken("[email protected]", "token2"));
1155 gcm_client()->SetAccountTokens(account_tokens);
[email protected]7df5ef22014-07-17 07:35:581156 PumpLoopUntilIdle();
johnme0fb2fc02016-07-14 14:47:441157 ASSERT_NO_FATAL_FAILURE(
1158 CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken,
1159 GServicesSettings::CalculateDigest(settings), settings));
[email protected]7df5ef22014-07-17 07:35:581160
1161 EXPECT_EQ(2UL, device_checkin_info().last_checkin_accounts.size());
1162 EXPECT_TRUE(device_checkin_info().accounts_set);
fgorski58b9dfc2014-09-29 16:46:181163 EXPECT_EQ(MakeEmailToTokenMap(account_tokens),
1164 device_checkin_info().account_tokens);
[email protected]7df5ef22014-07-17 07:35:581165
fgorski58b9dfc2014-09-29 16:46:181166 account_tokens.erase(account_tokens.begin() + 1);
1167 gcm_client()->SetAccountTokens(account_tokens);
[email protected]7df5ef22014-07-17 07:35:581168
1169 PumpLoopUntilIdle();
johnme0fb2fc02016-07-14 14:47:441170 ASSERT_NO_FATAL_FAILURE(
1171 CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken,
1172 GServicesSettings::CalculateDigest(settings), settings));
[email protected]7df5ef22014-07-17 07:35:581173
1174 std::set<std::string> accounts;
1175 accounts.insert("[email protected]");
1176 EXPECT_EQ(accounts, device_checkin_info().last_checkin_accounts);
1177 EXPECT_TRUE(device_checkin_info().accounts_set);
fgorski58b9dfc2014-09-29 16:46:181178 EXPECT_EQ(MakeEmailToTokenMap(account_tokens),
1179 device_checkin_info().account_tokens);
[email protected]7df5ef22014-07-17 07:35:581180}
1181
1182// This test only checks that periodic checkin happens.
1183TEST_F(GCMClientImplCheckinTest, CheckinWhenAccountReplaced) {
1184 std::map<std::string, std::string> settings;
riceaf44cda22015-09-24 14:08:511185 settings["checkin_interval"] = base::Int64ToString(kSettingsCheckinInterval);
[email protected]7df5ef22014-07-17 07:35:581186 settings["checkin_url"] = "http://alternative.url/checkin";
1187 settings["gcm_hostname"] = "alternative.gcm.host";
1188 settings["gcm_secure_port"] = "7777";
1189 settings["gcm_registration_url"] = "http://alternative.url/registration";
johnme0fb2fc02016-07-14 14:47:441190 ASSERT_NO_FATAL_FAILURE(
1191 CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken,
1192 GServicesSettings::CalculateDigest(settings), settings));
[email protected]7df5ef22014-07-17 07:35:581193
fgorski58b9dfc2014-09-29 16:46:181194 std::vector<GCMClient::AccountTokenInfo> account_tokens;
1195 account_tokens.push_back(MakeAccountToken("[email protected]", "token1"));
1196 gcm_client()->SetAccountTokens(account_tokens);
[email protected]7df5ef22014-07-17 07:35:581197
1198 PumpLoopUntilIdle();
johnme0fb2fc02016-07-14 14:47:441199 ASSERT_NO_FATAL_FAILURE(
1200 CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken,
1201 GServicesSettings::CalculateDigest(settings), settings));
[email protected]7df5ef22014-07-17 07:35:581202
1203 std::set<std::string> accounts;
1204 accounts.insert("[email protected]");
1205 EXPECT_EQ(accounts, device_checkin_info().last_checkin_accounts);
1206
1207 // This should trigger another checkin, because the list of accounts is
1208 // different.
fgorski58b9dfc2014-09-29 16:46:181209 account_tokens.clear();
1210 account_tokens.push_back(MakeAccountToken("[email protected]", "token2"));
1211 gcm_client()->SetAccountTokens(account_tokens);
[email protected]7df5ef22014-07-17 07:35:581212
1213 PumpLoopUntilIdle();
johnme0fb2fc02016-07-14 14:47:441214 ASSERT_NO_FATAL_FAILURE(
1215 CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken,
1216 GServicesSettings::CalculateDigest(settings), settings));
[email protected]7df5ef22014-07-17 07:35:581217
1218 accounts.clear();
1219 accounts.insert("[email protected]");
1220 EXPECT_EQ(accounts, device_checkin_info().last_checkin_accounts);
1221 EXPECT_TRUE(device_checkin_info().accounts_set);
fgorski58b9dfc2014-09-29 16:46:181222 EXPECT_EQ(MakeEmailToTokenMap(account_tokens),
1223 device_checkin_info().account_tokens);
[email protected]7df5ef22014-07-17 07:35:581224}
1225
zea76342abf2016-11-01 17:26:041226TEST_F(GCMClientImplCheckinTest, ResetStoreWhenCheckinRejected) {
1227 base::HistogramTester histogram_tester;
1228 std::map<std::string, std::string> settings;
1229 ASSERT_NO_FATAL_FAILURE(FailCheckin(net::HTTP_UNAUTHORIZED));
1230 PumpLoopUntilIdle();
1231
1232 // Store should have been destroyed. Restart client and verify the initial
1233 // checkin response is persisted.
1234 BuildGCMClient(base::TimeDelta());
1235 InitializeGCMClient();
1236 StartGCMClient();
1237 ASSERT_NO_FATAL_FAILURE(
1238 CompleteCheckin(kDeviceAndroidId2, kDeviceSecurityToken2,
1239 GServicesSettings::CalculateDigest(settings), settings));
1240
1241 EXPECT_EQ(LOADING_COMPLETED, last_event());
1242 EXPECT_EQ(kDeviceAndroidId2, mcs_client()->last_android_id());
1243 EXPECT_EQ(kDeviceSecurityToken2, mcs_client()->last_security_token());
1244}
1245
[email protected]1abdf202014-06-13 19:38:531246class GCMClientImplStartAndStopTest : public GCMClientImplTest {
jianli78b56042015-06-17 01:21:221247 public:
[email protected]1abdf202014-06-13 19:38:531248 GCMClientImplStartAndStopTest();
dcheng30a1b1542014-10-29 21:27:501249 ~GCMClientImplStartAndStopTest() override;
[email protected]1abdf202014-06-13 19:38:531250
dcheng30a1b1542014-10-29 21:27:501251 void SetUp() override;
fgorski5df101702014-10-28 02:09:311252
1253 void DefaultCompleteCheckin();
[email protected]1abdf202014-06-13 19:38:531254};
1255
1256GCMClientImplStartAndStopTest::GCMClientImplStartAndStopTest() {
1257}
1258
1259GCMClientImplStartAndStopTest::~GCMClientImplStartAndStopTest() {
1260}
1261
1262void GCMClientImplStartAndStopTest::SetUp() {
1263 testing::Test::SetUp();
1264 ASSERT_TRUE(CreateUniqueTempDir());
[email protected]1abdf202014-06-13 19:38:531265 BuildGCMClient(base::TimeDelta());
1266 InitializeGCMClient();
1267}
1268
fgorski5df101702014-10-28 02:09:311269void GCMClientImplStartAndStopTest::DefaultCompleteCheckin() {
1270 SetUpUrlFetcherFactory();
johnme0fb2fc02016-07-14 14:47:441271 ASSERT_NO_FATAL_FAILURE(
1272 CompleteCheckin(kDeviceAndroidId, kDeviceSecurityToken, std::string(),
1273 std::map<std::string, std::string>()));
fgorski5df101702014-10-28 02:09:311274 PumpLoopUntilIdle();
1275}
1276
[email protected]1abdf202014-06-13 19:38:531277TEST_F(GCMClientImplStartAndStopTest, StartStopAndRestart) {
jianlif3e52af42015-01-21 23:18:471278 // GCMClientImpl should be in INITIALIZED state at first.
1279 EXPECT_EQ(GCMClientImpl::INITIALIZED, gcm_client_state());
1280
1281 // Delay start the GCM.
1282 gcm_client()->Start(GCMClient::DELAYED_START);
[email protected]1abdf202014-06-13 19:38:531283 PumpLoopUntilIdle();
jianli9f9a73672015-06-16 19:39:341284 EXPECT_EQ(GCMClientImpl::INITIALIZED, gcm_client_state());
[email protected]1abdf202014-06-13 19:38:531285
1286 // Stop the GCM.
1287 gcm_client()->Stop();
1288 PumpLoopUntilIdle();
jianlif3e52af42015-01-21 23:18:471289 EXPECT_EQ(GCMClientImpl::INITIALIZED, gcm_client_state());
[email protected]1abdf202014-06-13 19:38:531290
jianlif3e52af42015-01-21 23:18:471291 // Restart the GCM without delay.
1292 gcm_client()->Start(GCMClient::IMMEDIATE_START);
[email protected]1abdf202014-06-13 19:38:531293 PumpLoopUntilIdle();
jianlif3e52af42015-01-21 23:18:471294 EXPECT_EQ(GCMClientImpl::INITIAL_DEVICE_CHECKIN, gcm_client_state());
[email protected]1abdf202014-06-13 19:38:531295}
1296
jianli9f9a73672015-06-16 19:39:341297TEST_F(GCMClientImplStartAndStopTest, DelayedStartAndStopImmediately) {
jianlif3e52af42015-01-21 23:18:471298 // GCMClientImpl should be in INITIALIZED state at first.
1299 EXPECT_EQ(GCMClientImpl::INITIALIZED, gcm_client_state());
[email protected]1abdf202014-06-13 19:38:531300
jianlif3e52af42015-01-21 23:18:471301 // Delay start the GCM and then stop it immediately.
1302 gcm_client()->Start(GCMClient::DELAYED_START);
1303 gcm_client()->Stop();
[email protected]1abdf202014-06-13 19:38:531304 PumpLoopUntilIdle();
jianlif3e52af42015-01-21 23:18:471305 EXPECT_EQ(GCMClientImpl::INITIALIZED, gcm_client_state());
jianli9f9a73672015-06-16 19:39:341306}
1307
1308TEST_F(GCMClientImplStartAndStopTest, ImmediateStartAndStopImmediately) {
1309 // GCMClientImpl should be in INITIALIZED state at first.
1310 EXPECT_EQ(GCMClientImpl::INITIALIZED, gcm_client_state());
jianlif3e52af42015-01-21 23:18:471311
1312 // Start the GCM and then stop it immediately.
1313 gcm_client()->Start(GCMClient::IMMEDIATE_START);
1314 gcm_client()->Stop();
1315 PumpLoopUntilIdle();
1316 EXPECT_EQ(GCMClientImpl::INITIALIZED, gcm_client_state());
[email protected]1abdf202014-06-13 19:38:531317}
1318
jianli9f9a73672015-06-16 19:39:341319TEST_F(GCMClientImplStartAndStopTest, DelayedStartStopAndRestart) {
jianlif3e52af42015-01-21 23:18:471320 // GCMClientImpl should be in INITIALIZED state at first.
1321 EXPECT_EQ(GCMClientImpl::INITIALIZED, gcm_client_state());
[email protected]1abdf202014-06-13 19:38:531322
jianlif3e52af42015-01-21 23:18:471323 // Delay start the GCM and then stop and restart it immediately.
1324 gcm_client()->Start(GCMClient::DELAYED_START);
1325 gcm_client()->Stop();
1326 gcm_client()->Start(GCMClient::DELAYED_START);
[email protected]1abdf202014-06-13 19:38:531327 PumpLoopUntilIdle();
jianli9f9a73672015-06-16 19:39:341328 EXPECT_EQ(GCMClientImpl::INITIALIZED, gcm_client_state());
1329}
1330
1331TEST_F(GCMClientImplStartAndStopTest, ImmediateStartStopAndRestart) {
1332 // GCMClientImpl should be in INITIALIZED state at first.
1333 EXPECT_EQ(GCMClientImpl::INITIALIZED, gcm_client_state());
jianlif3e52af42015-01-21 23:18:471334
1335 // Start the GCM and then stop and restart it immediately.
1336 gcm_client()->Start(GCMClient::IMMEDIATE_START);
1337 gcm_client()->Stop();
1338 gcm_client()->Start(GCMClient::IMMEDIATE_START);
1339 PumpLoopUntilIdle();
1340 EXPECT_EQ(GCMClientImpl::INITIAL_DEVICE_CHECKIN, gcm_client_state());
1341}
1342
jianli9f9a73672015-06-16 19:39:341343TEST_F(GCMClientImplStartAndStopTest, ImmediateStartAndThenImmediateStart) {
jianlif3e52af42015-01-21 23:18:471344 // GCMClientImpl should be in INITIALIZED state at first.
1345 EXPECT_EQ(GCMClientImpl::INITIALIZED, gcm_client_state());
1346
jianli9f9a73672015-06-16 19:39:341347 // Start the GCM immediately and complete the checkin.
1348 gcm_client()->Start(GCMClient::IMMEDIATE_START);
1349 PumpLoopUntilIdle();
1350 EXPECT_EQ(GCMClientImpl::INITIAL_DEVICE_CHECKIN, gcm_client_state());
johnme0fb2fc02016-07-14 14:47:441351 ASSERT_NO_FATAL_FAILURE(DefaultCompleteCheckin());
jianli9f9a73672015-06-16 19:39:341352 EXPECT_EQ(GCMClientImpl::READY, gcm_client_state());
1353
1354 // Stop the GCM.
1355 gcm_client()->Stop();
1356 PumpLoopUntilIdle();
1357 EXPECT_EQ(GCMClientImpl::INITIALIZED, gcm_client_state());
1358
1359 // Start the GCM immediately. GCMClientImpl should be in READY state.
1360 BuildGCMClient(base::TimeDelta());
1361 InitializeGCMClient();
1362 gcm_client()->Start(GCMClient::IMMEDIATE_START);
1363 PumpLoopUntilIdle();
1364 EXPECT_EQ(GCMClientImpl::READY, gcm_client_state());
1365}
1366
1367TEST_F(GCMClientImplStartAndStopTest, ImmediateStartAndThenDelayStart) {
1368 // GCMClientImpl should be in INITIALIZED state at first.
1369 EXPECT_EQ(GCMClientImpl::INITIALIZED, gcm_client_state());
1370
1371 // Start the GCM immediately and complete the checkin.
1372 gcm_client()->Start(GCMClient::IMMEDIATE_START);
1373 PumpLoopUntilIdle();
1374 EXPECT_EQ(GCMClientImpl::INITIAL_DEVICE_CHECKIN, gcm_client_state());
johnme0fb2fc02016-07-14 14:47:441375 ASSERT_NO_FATAL_FAILURE(DefaultCompleteCheckin());
jianli9f9a73672015-06-16 19:39:341376 EXPECT_EQ(GCMClientImpl::READY, gcm_client_state());
1377
1378 // Stop the GCM.
1379 gcm_client()->Stop();
1380 PumpLoopUntilIdle();
1381 EXPECT_EQ(GCMClientImpl::INITIALIZED, gcm_client_state());
1382
1383 // Delay start the GCM. GCMClientImpl should be in LOADED state.
1384 BuildGCMClient(base::TimeDelta());
1385 InitializeGCMClient();
jianlif3e52af42015-01-21 23:18:471386 gcm_client()->Start(GCMClient::DELAYED_START);
1387 PumpLoopUntilIdle();
1388 EXPECT_EQ(GCMClientImpl::LOADED, gcm_client_state());
jianli9f9a73672015-06-16 19:39:341389}
1390
johnme902c4062015-08-21 22:06:171391TEST_F(GCMClientImplStartAndStopTest, DelayedStartRace) {
1392 // GCMClientImpl should be in INITIALIZED state at first.
1393 EXPECT_EQ(GCMClientImpl::INITIALIZED, gcm_client_state());
1394
1395 // Delay start the GCM, then start it immediately while it's still loading.
1396 gcm_client()->Start(GCMClient::DELAYED_START);
1397 gcm_client()->Start(GCMClient::IMMEDIATE_START);
1398 PumpLoopUntilIdle();
1399 EXPECT_EQ(GCMClientImpl::INITIAL_DEVICE_CHECKIN, gcm_client_state());
johnme0fb2fc02016-07-14 14:47:441400 ASSERT_NO_FATAL_FAILURE(DefaultCompleteCheckin());
johnme902c4062015-08-21 22:06:171401 EXPECT_EQ(GCMClientImpl::READY, gcm_client_state());
1402}
1403
jianli9f9a73672015-06-16 19:39:341404TEST_F(GCMClientImplStartAndStopTest, DelayedStart) {
1405 // GCMClientImpl should be in INITIALIZED state at first.
1406 EXPECT_EQ(GCMClientImpl::INITIALIZED, gcm_client_state());
1407
1408 // Delay start the GCM. The store will not be loaded and GCMClientImpl should
1409 // still be in INITIALIZED state.
1410 gcm_client()->Start(GCMClient::DELAYED_START);
1411 PumpLoopUntilIdle();
1412 EXPECT_EQ(GCMClientImpl::INITIALIZED, gcm_client_state());
jianlif3e52af42015-01-21 23:18:471413
1414 // Start the GCM immediately and complete the checkin.
1415 gcm_client()->Start(GCMClient::IMMEDIATE_START);
1416 PumpLoopUntilIdle();
1417 EXPECT_EQ(GCMClientImpl::INITIAL_DEVICE_CHECKIN, gcm_client_state());
johnme0fb2fc02016-07-14 14:47:441418 ASSERT_NO_FATAL_FAILURE(DefaultCompleteCheckin());
jianlif3e52af42015-01-21 23:18:471419 EXPECT_EQ(GCMClientImpl::READY, gcm_client_state());
1420
1421 // Registration.
1422 std::vector<std::string> senders;
1423 senders.push_back("sender");
johnme627dc8c72016-08-19 21:49:391424 Register(kExtensionAppId, senders);
johnme0fb2fc02016-07-14 14:47:441425 ASSERT_NO_FATAL_FAILURE(CompleteRegistration("reg_id"));
jianlif3e52af42015-01-21 23:18:471426 EXPECT_EQ(GCMClientImpl::READY, gcm_client_state());
1427
1428 // Stop the GCM.
1429 gcm_client()->Stop();
1430 PumpLoopUntilIdle();
1431 EXPECT_EQ(GCMClientImpl::INITIALIZED, gcm_client_state());
1432
1433 // Delay start the GCM. GCM is indeed started without delay because the
1434 // registration record has been found.
jianli9f9a73672015-06-16 19:39:341435 BuildGCMClient(base::TimeDelta());
1436 InitializeGCMClient();
jianlif3e52af42015-01-21 23:18:471437 gcm_client()->Start(GCMClient::DELAYED_START);
1438 PumpLoopUntilIdle();
1439 EXPECT_EQ(GCMClientImpl::READY, gcm_client_state());
[email protected]1abdf202014-06-13 19:38:531440}
1441
fgorski5df101702014-10-28 02:09:311442// Test for known account mappings and last token fetching time being passed
1443// to OnGCMReady.
1444TEST_F(GCMClientImplStartAndStopTest, OnGCMReadyAccountsAndTokenFetchingTime) {
1445 // Start the GCM and wait until it is ready.
jianlif3e52af42015-01-21 23:18:471446 gcm_client()->Start(GCMClient::IMMEDIATE_START);
fgorski5df101702014-10-28 02:09:311447 PumpLoopUntilIdle();
johnme0fb2fc02016-07-14 14:47:441448 ASSERT_NO_FATAL_FAILURE(DefaultCompleteCheckin());
fgorski5df101702014-10-28 02:09:311449
1450 base::Time expected_time = base::Time::Now();
1451 gcm_client()->SetLastTokenFetchTime(expected_time);
1452 AccountMapping expected_mapping;
1453 expected_mapping.account_id = "accId";
1454 expected_mapping.email = "[email protected]";
1455 expected_mapping.status = AccountMapping::MAPPED;
1456 expected_mapping.status_change_timestamp = expected_time;
1457 gcm_client()->UpdateAccountMapping(expected_mapping);
1458 PumpLoopUntilIdle();
1459
1460 // Stop the GCM.
1461 gcm_client()->Stop();
1462 PumpLoopUntilIdle();
1463
1464 // Restart the GCM.
jianlif3e52af42015-01-21 23:18:471465 gcm_client()->Start(GCMClient::IMMEDIATE_START);
fgorski5df101702014-10-28 02:09:311466 PumpLoopUntilIdle();
1467
1468 EXPECT_EQ(LOADING_COMPLETED, last_event());
1469 EXPECT_EQ(expected_time, last_token_fetch_time());
1470 ASSERT_EQ(1UL, last_account_mappings().size());
1471 const AccountMapping& actual_mapping = last_account_mappings()[0];
1472 EXPECT_EQ(expected_mapping.account_id, actual_mapping.account_id);
1473 EXPECT_EQ(expected_mapping.email, actual_mapping.email);
1474 EXPECT_EQ(expected_mapping.status, actual_mapping.status);
1475 EXPECT_EQ(expected_mapping.status_change_timestamp,
1476 actual_mapping.status_change_timestamp);
1477}
1478
jianlic02d25e2015-05-27 22:24:311479
1480class GCMClientInstanceIDTest : public GCMClientImplTest {
1481 public:
1482 GCMClientInstanceIDTest();
1483 ~GCMClientInstanceIDTest() override;
1484
1485 void AddInstanceID(const std::string& app_id,
1486 const std::string& instance_id);
1487 void RemoveInstanceID(const std::string& app_id);
1488 void GetToken(const std::string& app_id,
1489 const std::string& authorized_entity,
1490 const std::string& scope);
1491 void DeleteToken(const std::string& app_id,
1492 const std::string& authorized_entity,
1493 const std::string& scope);
1494 void CompleteDeleteToken();
1495 bool ExistsToken(const std::string& app_id,
1496 const std::string& authorized_entity,
1497 const std::string& scope) const;
1498};
1499
1500GCMClientInstanceIDTest::GCMClientInstanceIDTest() {
1501}
1502
1503GCMClientInstanceIDTest::~GCMClientInstanceIDTest() {
1504}
1505
1506void GCMClientInstanceIDTest::AddInstanceID(const std::string& app_id,
1507 const std::string& instance_id) {
1508 gcm_client()->AddInstanceIDData(app_id, instance_id, "123");
1509}
1510
1511void GCMClientInstanceIDTest::RemoveInstanceID(const std::string& app_id) {
1512 gcm_client()->RemoveInstanceIDData(app_id);
1513}
1514
1515void GCMClientInstanceIDTest::GetToken(const std::string& app_id,
1516 const std::string& authorized_entity,
1517 const std::string& scope) {
dchenga77e28eb2016-04-21 21:34:371518 std::unique_ptr<InstanceIDTokenInfo> instance_id_info(
1519 new InstanceIDTokenInfo);
jianlic02d25e2015-05-27 22:24:311520 instance_id_info->app_id = app_id;
1521 instance_id_info->authorized_entity = authorized_entity;
1522 instance_id_info->scope = scope;
1523 gcm_client()->Register(
1524 make_linked_ptr<RegistrationInfo>(instance_id_info.release()));
1525}
1526
1527void GCMClientInstanceIDTest::DeleteToken(const std::string& app_id,
1528 const std::string& authorized_entity,
1529 const std::string& scope) {
dchenga77e28eb2016-04-21 21:34:371530 std::unique_ptr<InstanceIDTokenInfo> instance_id_info(
1531 new InstanceIDTokenInfo);
jianlic02d25e2015-05-27 22:24:311532 instance_id_info->app_id = app_id;
1533 instance_id_info->authorized_entity = authorized_entity;
1534 instance_id_info->scope = scope;
1535 gcm_client()->Unregister(
1536 make_linked_ptr<RegistrationInfo>(instance_id_info.release()));
1537}
1538
1539void GCMClientInstanceIDTest::CompleteDeleteToken() {
1540 std::string response(kDeleteTokenResponse);
1541 net::TestURLFetcher* fetcher = url_fetcher_factory()->GetFetcherByID(0);
1542 ASSERT_TRUE(fetcher);
1543 fetcher->set_response_code(net::HTTP_OK);
1544 fetcher->SetResponseString(response);
1545 fetcher->delegate()->OnURLFetchComplete(fetcher);
jianlid7e80f22015-06-18 22:21:311546 // Give a chance for GCMStoreImpl::Backend to finish persisting data.
1547 PumpLoopUntilIdle();
jianlic02d25e2015-05-27 22:24:311548}
1549
1550bool GCMClientInstanceIDTest::ExistsToken(const std::string& app_id,
1551 const std::string& authorized_entity,
1552 const std::string& scope) const {
dchenga77e28eb2016-04-21 21:34:371553 std::unique_ptr<InstanceIDTokenInfo> instance_id_info(
1554 new InstanceIDTokenInfo);
jianlic02d25e2015-05-27 22:24:311555 instance_id_info->app_id = app_id;
1556 instance_id_info->authorized_entity = authorized_entity;
1557 instance_id_info->scope = scope;
1558 return gcm_client()->registrations_.count(
1559 make_linked_ptr<RegistrationInfo>(instance_id_info.release())) > 0;
1560}
1561
1562TEST_F(GCMClientInstanceIDTest, GetToken) {
johnme627dc8c72016-08-19 21:49:391563 AddInstanceID(kExtensionAppId, kInstanceID);
jianlic02d25e2015-05-27 22:24:311564
1565 // Get a token.
johnme627dc8c72016-08-19 21:49:391566 EXPECT_FALSE(ExistsToken(kExtensionAppId, kSender, kScope));
1567 GetToken(kExtensionAppId, kSender, kScope);
johnme0fb2fc02016-07-14 14:47:441568 ASSERT_NO_FATAL_FAILURE(CompleteRegistration("token1"));
jianlic02d25e2015-05-27 22:24:311569
1570 EXPECT_EQ(REGISTRATION_COMPLETED, last_event());
johnme627dc8c72016-08-19 21:49:391571 EXPECT_EQ(kExtensionAppId, last_app_id());
jianlic02d25e2015-05-27 22:24:311572 EXPECT_EQ("token1", last_registration_id());
1573 EXPECT_EQ(GCMClient::SUCCESS, last_result());
johnme627dc8c72016-08-19 21:49:391574 EXPECT_TRUE(ExistsToken(kExtensionAppId, kSender, kScope));
jianlic02d25e2015-05-27 22:24:311575
1576 // Get another token.
johnme627dc8c72016-08-19 21:49:391577 EXPECT_FALSE(ExistsToken(kExtensionAppId, kSender2, kScope));
1578 GetToken(kExtensionAppId, kSender2, kScope);
johnme0fb2fc02016-07-14 14:47:441579 ASSERT_NO_FATAL_FAILURE(CompleteRegistration("token2"));
jianlic02d25e2015-05-27 22:24:311580
1581 EXPECT_EQ(REGISTRATION_COMPLETED, last_event());
johnme627dc8c72016-08-19 21:49:391582 EXPECT_EQ(kExtensionAppId, last_app_id());
jianlic02d25e2015-05-27 22:24:311583 EXPECT_EQ("token2", last_registration_id());
1584 EXPECT_EQ(GCMClient::SUCCESS, last_result());
johnme627dc8c72016-08-19 21:49:391585 EXPECT_TRUE(ExistsToken(kExtensionAppId, kSender2, kScope));
jianlic02d25e2015-05-27 22:24:311586 // The 1st token still exists.
johnme627dc8c72016-08-19 21:49:391587 EXPECT_TRUE(ExistsToken(kExtensionAppId, kSender, kScope));
1588}
1589
1590// Most tests in this file use kExtensionAppId which is special-cased by
1591// InstanceIDUsesSubtypeForAppId in gcm_client_impl.cc. This test uses
1592// kSubtypeAppId to cover the alternate case.
1593TEST_F(GCMClientInstanceIDTest, GetTokenWithSubtype) {
1594 ASSERT_EQ(GCMClientImpl::READY, gcm_client_state());
1595
1596 AddInstanceID(kSubtypeAppId, kInstanceID);
1597
1598 EXPECT_FALSE(ExistsToken(kSubtypeAppId, kSender, kScope));
1599
1600 // Get a token.
1601 GetToken(kSubtypeAppId, kSender, kScope);
1602 ASSERT_NO_FATAL_FAILURE(CompleteRegistration("token1"));
1603 EXPECT_EQ(REGISTRATION_COMPLETED, last_event());
1604 EXPECT_EQ(kSubtypeAppId, last_app_id());
1605 EXPECT_EQ("token1", last_registration_id());
1606 EXPECT_EQ(GCMClient::SUCCESS, last_result());
1607 EXPECT_TRUE(ExistsToken(kSubtypeAppId, kSender, kScope));
1608
1609 // Delete the token.
1610 DeleteToken(kSubtypeAppId, kSender, kScope);
1611 ASSERT_NO_FATAL_FAILURE(CompleteDeleteToken());
1612 EXPECT_FALSE(ExistsToken(kSubtypeAppId, kSender, kScope));
jianlic02d25e2015-05-27 22:24:311613}
1614
jianli70715cc2015-06-23 21:46:481615TEST_F(GCMClientInstanceIDTest, DeleteInvalidToken) {
johnme627dc8c72016-08-19 21:49:391616 AddInstanceID(kExtensionAppId, kInstanceID);
jianli70715cc2015-06-23 21:46:481617
1618 // Delete an invalid token.
johnme627dc8c72016-08-19 21:49:391619 DeleteToken(kExtensionAppId, "Foo@#$", kScope);
jianli70715cc2015-06-23 21:46:481620 PumpLoopUntilIdle();
1621
1622 EXPECT_EQ(UNREGISTRATION_COMPLETED, last_event());
johnme627dc8c72016-08-19 21:49:391623 EXPECT_EQ(kExtensionAppId, last_app_id());
jianli70715cc2015-06-23 21:46:481624 EXPECT_EQ(GCMClient::INVALID_PARAMETER, last_result());
1625
1626 reset_last_event();
1627
1628 // Delete a non-existing token.
johnme627dc8c72016-08-19 21:49:391629 DeleteToken(kExtensionAppId, kSender, kScope);
jianli70715cc2015-06-23 21:46:481630 PumpLoopUntilIdle();
1631
1632 EXPECT_EQ(UNREGISTRATION_COMPLETED, last_event());
johnme627dc8c72016-08-19 21:49:391633 EXPECT_EQ(kExtensionAppId, last_app_id());
jianli70715cc2015-06-23 21:46:481634 EXPECT_EQ(GCMClient::INVALID_PARAMETER, last_result());
1635}
1636
jianlic02d25e2015-05-27 22:24:311637TEST_F(GCMClientInstanceIDTest, DeleteSingleToken) {
johnme627dc8c72016-08-19 21:49:391638 AddInstanceID(kExtensionAppId, kInstanceID);
jianlic02d25e2015-05-27 22:24:311639
1640 // Get a token.
johnme627dc8c72016-08-19 21:49:391641 EXPECT_FALSE(ExistsToken(kExtensionAppId, kSender, kScope));
1642 GetToken(kExtensionAppId, kSender, kScope);
johnme0fb2fc02016-07-14 14:47:441643 ASSERT_NO_FATAL_FAILURE(CompleteRegistration("token1"));
jianlic02d25e2015-05-27 22:24:311644
1645 EXPECT_EQ(REGISTRATION_COMPLETED, last_event());
johnme627dc8c72016-08-19 21:49:391646 EXPECT_EQ(kExtensionAppId, last_app_id());
jianlic02d25e2015-05-27 22:24:311647 EXPECT_EQ("token1", last_registration_id());
1648 EXPECT_EQ(GCMClient::SUCCESS, last_result());
johnme627dc8c72016-08-19 21:49:391649 EXPECT_TRUE(ExistsToken(kExtensionAppId, kSender, kScope));
jianlic02d25e2015-05-27 22:24:311650
jianli70715cc2015-06-23 21:46:481651 reset_last_event();
1652
jianlic02d25e2015-05-27 22:24:311653 // Get another token.
johnme627dc8c72016-08-19 21:49:391654 EXPECT_FALSE(ExistsToken(kExtensionAppId, kSender2, kScope));
1655 GetToken(kExtensionAppId, kSender2, kScope);
johnme0fb2fc02016-07-14 14:47:441656 ASSERT_NO_FATAL_FAILURE(CompleteRegistration("token2"));
jianlic02d25e2015-05-27 22:24:311657
1658 EXPECT_EQ(REGISTRATION_COMPLETED, last_event());
johnme627dc8c72016-08-19 21:49:391659 EXPECT_EQ(kExtensionAppId, last_app_id());
jianlic02d25e2015-05-27 22:24:311660 EXPECT_EQ("token2", last_registration_id());
1661 EXPECT_EQ(GCMClient::SUCCESS, last_result());
johnme627dc8c72016-08-19 21:49:391662 EXPECT_TRUE(ExistsToken(kExtensionAppId, kSender2, kScope));
jianlic02d25e2015-05-27 22:24:311663 // The 1st token still exists.
johnme627dc8c72016-08-19 21:49:391664 EXPECT_TRUE(ExistsToken(kExtensionAppId, kSender, kScope));
jianlic02d25e2015-05-27 22:24:311665
jianli70715cc2015-06-23 21:46:481666 reset_last_event();
1667
jianlic02d25e2015-05-27 22:24:311668 // Delete the 2nd token.
johnme627dc8c72016-08-19 21:49:391669 DeleteToken(kExtensionAppId, kSender2, kScope);
johnme0fb2fc02016-07-14 14:47:441670 ASSERT_NO_FATAL_FAILURE(CompleteDeleteToken());
jianlic02d25e2015-05-27 22:24:311671
1672 EXPECT_EQ(UNREGISTRATION_COMPLETED, last_event());
johnme627dc8c72016-08-19 21:49:391673 EXPECT_EQ(kExtensionAppId, last_app_id());
jianlic02d25e2015-05-27 22:24:311674 EXPECT_EQ(GCMClient::SUCCESS, last_result());
1675 // The 2nd token is gone while the 1st token still exists.
johnme627dc8c72016-08-19 21:49:391676 EXPECT_TRUE(ExistsToken(kExtensionAppId, kSender, kScope));
1677 EXPECT_FALSE(ExistsToken(kExtensionAppId, kSender2, kScope));
jianlic02d25e2015-05-27 22:24:311678
jianli70715cc2015-06-23 21:46:481679 reset_last_event();
1680
jianlic02d25e2015-05-27 22:24:311681 // Delete the 1st token.
johnme627dc8c72016-08-19 21:49:391682 DeleteToken(kExtensionAppId, kSender, kScope);
johnme0fb2fc02016-07-14 14:47:441683 ASSERT_NO_FATAL_FAILURE(CompleteDeleteToken());
jianlic02d25e2015-05-27 22:24:311684
1685 EXPECT_EQ(UNREGISTRATION_COMPLETED, last_event());
johnme627dc8c72016-08-19 21:49:391686 EXPECT_EQ(kExtensionAppId, last_app_id());
jianlic02d25e2015-05-27 22:24:311687 EXPECT_EQ(GCMClient::SUCCESS, last_result());
1688 // Both tokens are gone now.
johnme627dc8c72016-08-19 21:49:391689 EXPECT_FALSE(ExistsToken(kExtensionAppId, kSender, kScope));
1690 EXPECT_FALSE(ExistsToken(kExtensionAppId, kSender, kScope));
jianli70715cc2015-06-23 21:46:481691
1692 reset_last_event();
1693
1694 // Trying to delete the token again will get an error.
johnme627dc8c72016-08-19 21:49:391695 DeleteToken(kExtensionAppId, kSender, kScope);
jianli70715cc2015-06-23 21:46:481696 PumpLoopUntilIdle();
1697
1698 EXPECT_EQ(UNREGISTRATION_COMPLETED, last_event());
johnme627dc8c72016-08-19 21:49:391699 EXPECT_EQ(kExtensionAppId, last_app_id());
jianli70715cc2015-06-23 21:46:481700 EXPECT_EQ(GCMClient::INVALID_PARAMETER, last_result());
jianlic02d25e2015-05-27 22:24:311701}
1702
jianliea8534872015-06-22 21:06:221703TEST_F(GCMClientInstanceIDTest, DeleteAllTokens) {
johnme627dc8c72016-08-19 21:49:391704 AddInstanceID(kExtensionAppId, kInstanceID);
jianlic02d25e2015-05-27 22:24:311705
1706 // Get a token.
johnme627dc8c72016-08-19 21:49:391707 EXPECT_FALSE(ExistsToken(kExtensionAppId, kSender, kScope));
1708 GetToken(kExtensionAppId, kSender, kScope);
johnme0fb2fc02016-07-14 14:47:441709 ASSERT_NO_FATAL_FAILURE(CompleteRegistration("token1"));
jianlic02d25e2015-05-27 22:24:311710
1711 EXPECT_EQ(REGISTRATION_COMPLETED, last_event());
johnme627dc8c72016-08-19 21:49:391712 EXPECT_EQ(kExtensionAppId, last_app_id());
jianlic02d25e2015-05-27 22:24:311713 EXPECT_EQ("token1", last_registration_id());
1714 EXPECT_EQ(GCMClient::SUCCESS, last_result());
johnme627dc8c72016-08-19 21:49:391715 EXPECT_TRUE(ExistsToken(kExtensionAppId, kSender, kScope));
jianlic02d25e2015-05-27 22:24:311716
jianli70715cc2015-06-23 21:46:481717 reset_last_event();
1718
jianlic02d25e2015-05-27 22:24:311719 // Get another token.
johnme627dc8c72016-08-19 21:49:391720 EXPECT_FALSE(ExistsToken(kExtensionAppId, kSender2, kScope));
1721 GetToken(kExtensionAppId, kSender2, kScope);
johnme0fb2fc02016-07-14 14:47:441722 ASSERT_NO_FATAL_FAILURE(CompleteRegistration("token2"));
jianlic02d25e2015-05-27 22:24:311723
1724 EXPECT_EQ(REGISTRATION_COMPLETED, last_event());
johnme627dc8c72016-08-19 21:49:391725 EXPECT_EQ(kExtensionAppId, last_app_id());
jianlic02d25e2015-05-27 22:24:311726 EXPECT_EQ("token2", last_registration_id());
1727 EXPECT_EQ(GCMClient::SUCCESS, last_result());
johnme627dc8c72016-08-19 21:49:391728 EXPECT_TRUE(ExistsToken(kExtensionAppId, kSender2, kScope));
jianlic02d25e2015-05-27 22:24:311729 // The 1st token still exists.
johnme627dc8c72016-08-19 21:49:391730 EXPECT_TRUE(ExistsToken(kExtensionAppId, kSender, kScope));
jianlic02d25e2015-05-27 22:24:311731
jianli70715cc2015-06-23 21:46:481732 reset_last_event();
1733
jianlic02d25e2015-05-27 22:24:311734 // Delete all tokens.
johnme627dc8c72016-08-19 21:49:391735 DeleteToken(kExtensionAppId, "*", "*");
johnme0fb2fc02016-07-14 14:47:441736 ASSERT_NO_FATAL_FAILURE(CompleteDeleteToken());
jianlic02d25e2015-05-27 22:24:311737
1738 EXPECT_EQ(UNREGISTRATION_COMPLETED, last_event());
johnme627dc8c72016-08-19 21:49:391739 EXPECT_EQ(kExtensionAppId, last_app_id());
jianlic02d25e2015-05-27 22:24:311740 EXPECT_EQ(GCMClient::SUCCESS, last_result());
1741 // All tokens are gone now.
johnme627dc8c72016-08-19 21:49:391742 EXPECT_FALSE(ExistsToken(kExtensionAppId, kSender, kScope));
1743 EXPECT_FALSE(ExistsToken(kExtensionAppId, kSender, kScope));
jianlic02d25e2015-05-27 22:24:311744}
1745
jianliea8534872015-06-22 21:06:221746TEST_F(GCMClientInstanceIDTest, DeleteAllTokensBeforeGetAnyToken) {
johnme627dc8c72016-08-19 21:49:391747 AddInstanceID(kExtensionAppId, kInstanceID);
jianliea8534872015-06-22 21:06:221748
1749 // Delete all tokens without getting a token first.
johnme627dc8c72016-08-19 21:49:391750 DeleteToken(kExtensionAppId, "*", "*");
jianliea8534872015-06-22 21:06:221751 // No need to call CompleteDeleteToken since unregistration request should
1752 // not be triggered.
1753 PumpLoopUntilIdle();
1754
1755 EXPECT_EQ(UNREGISTRATION_COMPLETED, last_event());
johnme627dc8c72016-08-19 21:49:391756 EXPECT_EQ(kExtensionAppId, last_app_id());
jianliea8534872015-06-22 21:06:221757 EXPECT_EQ(GCMClient::SUCCESS, last_result());
1758}
1759
johnme627dc8c72016-08-19 21:49:391760TEST_F(GCMClientInstanceIDTest, DispatchDownstreamMessageWithoutSubtype) {
1761 AddInstanceID(kExtensionAppId, kInstanceID);
1762 GetToken(kExtensionAppId, kSender, kScope);
1763 ASSERT_NO_FATAL_FAILURE(CompleteRegistration("token1"));
johnme627dc8c72016-08-19 21:49:391764
1765 std::map<std::string, std::string> expected_data;
1766
Peter Beverlooc66fc63c2017-07-07 22:58:211767 MCSMessage message(BuildDownstreamMessage(
johnme627dc8c72016-08-19 21:49:391768 kSender, kExtensionAppId, std::string() /* subtype */, expected_data,
1769 std::string() /* raw_data */));
Peter Beverlooc66fc63c2017-07-07 22:58:211770 EXPECT_TRUE(message.IsValid());
1771 ReceiveMessageFromMCS(message);
johnme627dc8c72016-08-19 21:49:391772
1773 EXPECT_EQ(MESSAGE_RECEIVED, last_event());
1774 EXPECT_EQ(kExtensionAppId, last_app_id());
1775 EXPECT_EQ(expected_data.size(), last_message().data.size());
1776 EXPECT_EQ(expected_data, last_message().data);
1777 EXPECT_EQ(kSender, last_message().sender_id);
johnme627dc8c72016-08-19 21:49:391778}
1779
1780TEST_F(GCMClientInstanceIDTest, DispatchDownstreamMessageWithSubtype) {
1781 AddInstanceID(kSubtypeAppId, kInstanceID);
1782 GetToken(kSubtypeAppId, kSender, kScope);
1783 ASSERT_NO_FATAL_FAILURE(CompleteRegistration("token1"));
johnme627dc8c72016-08-19 21:49:391784
1785 std::map<std::string, std::string> expected_data;
1786
Peter Beverlooc66fc63c2017-07-07 22:58:211787 MCSMessage message(BuildDownstreamMessage(
johnme627dc8c72016-08-19 21:49:391788 kSender, kProductCategoryForSubtypes, kSubtypeAppId /* subtype */,
1789 expected_data, std::string() /* raw_data */));
Peter Beverlooc66fc63c2017-07-07 22:58:211790 EXPECT_TRUE(message.IsValid());
1791 ReceiveMessageFromMCS(message);
johnme627dc8c72016-08-19 21:49:391792
1793 EXPECT_EQ(MESSAGE_RECEIVED, last_event());
1794 EXPECT_EQ(kSubtypeAppId, last_app_id());
1795 EXPECT_EQ(expected_data.size(), last_message().data.size());
1796 EXPECT_EQ(expected_data, last_message().data);
1797 EXPECT_EQ(kSender, last_message().sender_id);
johnme627dc8c72016-08-19 21:49:391798}
1799
1800TEST_F(GCMClientInstanceIDTest, DispatchDownstreamMessageWithFakeSubtype) {
1801 // Victim non-extension registration.
1802 AddInstanceID(kSubtypeAppId, "iid_1");
1803 GetToken(kSubtypeAppId, kSender, kScope);
1804 ASSERT_NO_FATAL_FAILURE(CompleteRegistration("token1"));
1805
1806 // Malicious extension registration.
1807 AddInstanceID(kExtensionAppId, "iid_2");
1808 GetToken(kExtensionAppId, kSender, kScope);
1809 ASSERT_NO_FATAL_FAILURE(CompleteRegistration("token2"));
1810
1811 std::map<std::string, std::string> expected_data;
1812
1813 // Message for kExtensionAppId should be delivered to the extension rather
1814 // than the victim app, despite the malicious subtype property attempting to
1815 // impersonate victim app.
1816 MCSMessage message(BuildDownstreamMessage(
1817 kSender, kExtensionAppId /* category */, kSubtypeAppId /* subtype */,
1818 expected_data, std::string() /* raw_data */));
1819 EXPECT_TRUE(message.IsValid());
1820 ReceiveMessageFromMCS(message);
1821
1822 EXPECT_EQ(MESSAGE_RECEIVED, last_event());
1823 EXPECT_EQ(kExtensionAppId, last_app_id());
1824 EXPECT_EQ(expected_data.size(), last_message().data.size());
1825 EXPECT_EQ(expected_data, last_message().data);
1826 EXPECT_EQ(kSender, last_message().sender_id);
1827}
1828
[email protected]848b1b62014-01-30 23:51:041829} // namespace gcm