| Index: google_apis/gcm/engine/user_list_unittest.cc
|
| diff --git a/google_apis/gcm/engine/user_list_unittest.cc b/google_apis/gcm/engine/user_list_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..09947b987a4889921eb7f7f72be6dbbc1ffed431
|
| --- /dev/null
|
| +++ b/google_apis/gcm/engine/user_list_unittest.cc
|
| @@ -0,0 +1,370 @@
|
| +// Copyright 2014 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "google_apis/gcm/engine/user_list.h"
|
| +
|
| +#include <string>
|
| +#include <vector>
|
| +
|
| +#include "base/bind.h"
|
| +#include "base/callback_forward.h"
|
| +#include "base/files/file_path.h"
|
| +#include "base/files/scoped_temp_dir.h"
|
| +#include "base/memory/scoped_ptr.h"
|
| +#include "base/message_loop/message_loop.h"
|
| +#include "base/run_loop.h"
|
| +#include "google_apis/gcm/engine/gcm_store_impl.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +namespace gcm {
|
| +
|
| +namespace {
|
| +
|
| +class GCMClientDelegate : public GCMClient::Delegate {
|
| + public:
|
| + explicit GCMClientDelegate(const std::string& username);
|
| + virtual ~GCMClientDelegate();
|
| +
|
| + const std::string& GetUsername() const { return username_; }
|
| +
|
| + // Overrides of GCMClientDelegate:
|
| + virtual void OnCheckInFinished(const GCMClient::CheckinInfo& checkin_info,
|
| + GCMClient::Result result) OVERRIDE {}
|
| + virtual void OnRegisterFinished(const std::string& app_id,
|
| + const std::string& registration_id,
|
| + GCMClient::Result result) OVERRIDE {}
|
| + virtual void OnSendFinished(const std::string& app_id,
|
| + const std::string& message_id,
|
| + GCMClient::Result result) OVERRIDE {}
|
| + virtual void OnMessageReceived(const std::string& app_id,
|
| + const GCMClient::IncomingMessage& message)
|
| + OVERRIDE {}
|
| + virtual void OnMessagesDeleted(const std::string& app_id) OVERRIDE {}
|
| + virtual void OnMessageSendError(const std::string& app_id,
|
| + const std::string& message_id,
|
| + GCMClient::Result result) OVERRIDE {}
|
| + virtual GCMClient::CheckinInfo GetCheckinInfo() const OVERRIDE {
|
| + return GCMClient::CheckinInfo();
|
| + }
|
| + virtual void OnLoadingCompleted() OVERRIDE {}
|
| + virtual base::TaskRunner* GetFileTaskRunner() OVERRIDE { return NULL; }
|
| +
|
| + private:
|
| + std::string username_;
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| +class UserListTest : public testing::Test {
|
| + public:
|
| + UserListTest();
|
| + virtual ~UserListTest();
|
| +
|
| + virtual void SetUp() OVERRIDE;
|
| +
|
| + static size_t GetListSize(const UserList* user_list);
|
| + void SetDelegateCallback(const std::string& username,
|
| + int64 user_serial_number);
|
| +
|
| + scoped_ptr<UserList> BuildUserList();
|
| +
|
| + void PumpLoop();
|
| +
|
| + void UpdateCallback(bool success);
|
| +
|
| + void Initialize(UserList* user_list, const GCMStore::LoadResult& result);
|
| +
|
| + void ResetLoop();
|
| +
|
| + protected:
|
| + int64 last_assigned_serial_number_;
|
| + std::string last_assigned_username_;
|
| + scoped_ptr<GCMStore> gcm_store_;
|
| +
|
| + private:
|
| + base::ScopedTempDir temp_directory_;
|
| + base::MessageLoop message_loop_;
|
| + scoped_ptr<base::RunLoop> run_loop_;
|
| +};
|
| +
|
| +UserListTest::UserListTest()
|
| + : last_assigned_serial_number_(gcm::kInvalidSerialNumber) {}
|
| +
|
| +UserListTest::~UserListTest() {}
|
| +
|
| +void UserListTest::SetUp() {
|
| + ASSERT_TRUE(temp_directory_.CreateUniqueTempDir());
|
| +}
|
| +
|
| +// static
|
| +size_t UserListTest::GetListSize(const UserList* user_list) {
|
| + return user_list->delegates_.size();
|
| +}
|
| +
|
| +void UserListTest::SetDelegateCallback(const std::string& username,
|
| + int64 user_serial_number) {
|
| + last_assigned_username_ = username;
|
| + last_assigned_serial_number_ = user_serial_number;
|
| + ResetLoop();
|
| +}
|
| +
|
| +scoped_ptr<UserList> UserListTest::BuildUserList() {
|
| + gcm_store_.reset(new GCMStoreImpl(temp_directory_.path(),
|
| + message_loop_.message_loop_proxy()));
|
| + return scoped_ptr<UserList>(new UserList(gcm_store_.get()));
|
| +}
|
| +
|
| +void UserListTest::Initialize(UserList* user_list,
|
| + const GCMStore::LoadResult& result) {
|
| + ASSERT_TRUE(result.success);
|
| + user_list->Initialize(result.serial_number_mappings);
|
| + ResetLoop();
|
| +}
|
| +
|
| +void UserListTest::ResetLoop() {
|
| + if (run_loop_ && run_loop_->running())
|
| + run_loop_->Quit();
|
| +}
|
| +
|
| +void UserListTest::PumpLoop() {
|
| + run_loop_.reset(new base::RunLoop);
|
| + run_loop_->Run();
|
| +}
|
| +
|
| +void UserListTest::UpdateCallback(bool success) { ASSERT_TRUE(success); }
|
| +
|
| +GCMClientDelegate::GCMClientDelegate(const std::string& username)
|
| + : username_(username) {}
|
| +
|
| +GCMClientDelegate::~GCMClientDelegate() {}
|
| +
|
| +// Make sure it is possible to add a delegate, and that it is assigned a serial
|
| +// number.
|
| +TEST_F(UserListTest, SetDelegateAndCheckSerialNumberAssignment) {
|
| + scoped_ptr<UserList> user_list(BuildUserList());
|
| + gcm_store_->Load(base::Bind(
|
| + &UserListTest::Initialize, base::Unretained(this), user_list.get()));
|
| + PumpLoop();
|
| +
|
| + // First adding a delegate.
|
| + scoped_ptr<GCMClientDelegate> delegate(new GCMClientDelegate("test_user_1"));
|
| + user_list->SetDelegate(
|
| + delegate->GetUsername(),
|
| + delegate.get(),
|
| + base::Bind(&UserListTest::SetDelegateCallback, base::Unretained(this)));
|
| + PumpLoop();
|
| +
|
| + // Verify the record was created.
|
| + EXPECT_EQ(1u, GetListSize(user_list.get()));
|
| + // Verify username and serial number were assigned.
|
| + EXPECT_EQ(delegate->GetUsername(), last_assigned_username_);
|
| + EXPECT_NE(gcm::kInvalidSerialNumber, last_assigned_serial_number_);
|
| + // Check that a serial number was assigned to delegate.
|
| + EXPECT_EQ(last_assigned_serial_number_,
|
| + user_list->GetSerialNumberForUsername(delegate->GetUsername()));
|
| +}
|
| +
|
| +// Get the delegate that was added to the list by both serial number and
|
| +// username.
|
| +TEST_F(UserListTest, GetDelegate) {
|
| + scoped_ptr<UserList> user_list(BuildUserList());
|
| + gcm_store_->Load(base::Bind(
|
| + &UserListTest::Initialize, base::Unretained(this), user_list.get()));
|
| + PumpLoop();
|
| +
|
| + // Start by adding a delegate and a serial number.
|
| + scoped_ptr<GCMClientDelegate> delegate(new GCMClientDelegate("test_user_1"));
|
| + user_list->SetDelegate(
|
| + delegate->GetUsername(),
|
| + delegate.get(),
|
| + base::Bind(&UserListTest::SetDelegateCallback, base::Unretained(this)));
|
| + PumpLoop();
|
| +
|
| + EXPECT_EQ(delegate.get(),
|
| + user_list->GetDelegateBySerialNumber(last_assigned_serial_number_));
|
| + EXPECT_EQ(delegate.get(),
|
| + user_list->GetDelegateByUsername(last_assigned_username_));
|
| +}
|
| +
|
| +// Make sure that correct mapping between username of the delegate and a serial
|
| +// number is preserved when loading the user list. Also verify that setting a
|
| +// delegate after load works correctly. (Finds the existing mapping entry.)
|
| +TEST_F(UserListTest, LoadUserEntrySetDelegate) {
|
| + scoped_ptr<UserList> user_list(BuildUserList());
|
| + gcm_store_->Load(base::Bind(
|
| + &UserListTest::Initialize, base::Unretained(this), user_list.get()));
|
| + PumpLoop();
|
| +
|
| + // Start by adding a delegate and a serial number.
|
| + scoped_ptr<GCMClientDelegate> delegate(new GCMClientDelegate("test_user_1"));
|
| + user_list->SetDelegate(
|
| + delegate->GetUsername(),
|
| + delegate.get(),
|
| + base::Bind(&UserListTest::SetDelegateCallback, base::Unretained(this)));
|
| + PumpLoop();
|
| +
|
| + // Reload the GCM User List.
|
| + user_list = BuildUserList().Pass();
|
| + gcm_store_->Load(base::Bind(
|
| + &UserListTest::Initialize, base::Unretained(this), user_list.get()));
|
| + PumpLoop();
|
| +
|
| + // Verify a single record was loaded, with matching username, but no delegate.
|
| + EXPECT_EQ(1u, GetListSize(user_list.get()));
|
| + int64 serial_number =
|
| + user_list->GetSerialNumberForUsername(delegate->GetUsername());
|
| + EXPECT_EQ(last_assigned_serial_number_, serial_number);
|
| + EXPECT_EQ(NULL, user_list->GetDelegateBySerialNumber(serial_number));
|
| + EXPECT_EQ(NULL, user_list->GetDelegateByUsername(delegate->GetUsername()));
|
| +
|
| + // After loading is complete, Delegates will start adding itself looking for
|
| + // their serial numbers. Check that correct matches are found and new records
|
| + // not created.
|
| + user_list->SetDelegate(
|
| + delegate->GetUsername(),
|
| + delegate.get(),
|
| + base::Bind(&UserListTest::SetDelegateCallback, base::Unretained(this)));
|
| + PumpLoop();
|
| +
|
| + EXPECT_EQ(1u, GetListSize(user_list.get()));
|
| + serial_number =
|
| + user_list->GetSerialNumberForUsername(delegate->GetUsername());
|
| + EXPECT_EQ(last_assigned_serial_number_, serial_number);
|
| + EXPECT_EQ(delegate.get(),
|
| + user_list->GetDelegateBySerialNumber(serial_number));
|
| + EXPECT_EQ(delegate.get(),
|
| + user_list->GetDelegateByUsername(delegate->GetUsername()));
|
| +}
|
| +
|
| +// Check that it is possible to add multiple delegates to the user list.
|
| +TEST_F(UserListTest, AddMultipleDelegates) {
|
| + scoped_ptr<UserList> user_list(BuildUserList());
|
| + gcm_store_->Load(base::Bind(
|
| + &UserListTest::Initialize, base::Unretained(this), user_list.get()));
|
| + PumpLoop();
|
| +
|
| + // Start by adding a delegate and a serial number.
|
| + scoped_ptr<GCMClientDelegate> delegate1(new GCMClientDelegate("test_user_1"));
|
| + user_list->SetDelegate(
|
| + delegate1->GetUsername(),
|
| + delegate1.get(),
|
| + base::Bind(&UserListTest::SetDelegateCallback, base::Unretained(this)));
|
| + PumpLoop();
|
| +
|
| + int64 serial_number1 = last_assigned_serial_number_;
|
| +
|
| + scoped_ptr<GCMClientDelegate> delegate2(new GCMClientDelegate("test_user_2"));
|
| + user_list->SetDelegate(
|
| + delegate2->GetUsername(),
|
| + delegate2.get(),
|
| + base::Bind(&UserListTest::SetDelegateCallback, base::Unretained(this)));
|
| + PumpLoop();
|
| +
|
| + int64 serial_number2 = last_assigned_serial_number_;
|
| +
|
| + // Ensuring that serial numbers are different.
|
| + EXPECT_EQ(2u, GetListSize(user_list.get()));
|
| +
|
| + // Reading the user entries.
|
| + user_list = BuildUserList().Pass();
|
| + gcm_store_->Load(base::Bind(
|
| + &UserListTest::Initialize, base::Unretained(this), user_list.get()));
|
| + PumpLoop();
|
| +
|
| + // Serial numbers stay the same, but there are no delegates assigned.
|
| + EXPECT_EQ(2u, GetListSize(user_list.get()));
|
| + EXPECT_EQ(NULL, user_list->GetDelegateByUsername(delegate1->GetUsername()));
|
| + EXPECT_EQ(NULL, user_list->GetDelegateBySerialNumber(serial_number1));
|
| + EXPECT_EQ(NULL, user_list->GetDelegateByUsername(delegate2->GetUsername()));
|
| + EXPECT_EQ(NULL, user_list->GetDelegateBySerialNumber(serial_number2));
|
| +
|
| + // Setting and checking a delegate on the second user.
|
| + user_list->SetDelegate(
|
| + delegate2->GetUsername(),
|
| + delegate2.get(),
|
| + base::Bind(&UserListTest::SetDelegateCallback, base::Unretained(this)));
|
| + PumpLoop();
|
| +
|
| + // First user still does not have a delegate.
|
| + EXPECT_EQ(NULL, user_list->GetDelegateByUsername(delegate1->GetUsername()));
|
| + EXPECT_EQ(NULL, user_list->GetDelegateBySerialNumber(serial_number1));
|
| + // Second user has a delegate set.
|
| + EXPECT_EQ(delegate2.get(),
|
| + user_list->GetDelegateByUsername(delegate2->GetUsername()));
|
| + EXPECT_EQ(delegate2.get(),
|
| + user_list->GetDelegateBySerialNumber(serial_number2));
|
| +}
|
| +
|
| +// Adding a delegate before the user list is initialized. Verifies that serial
|
| +// number assignment is postponed until after initialization.
|
| +TEST_F(UserListTest, AddDelegateThenInitializeWithoutSerialNumber) {
|
| + scoped_ptr<UserList> user_list(BuildUserList());
|
| +
|
| + // Add a delegate first.
|
| + scoped_ptr<GCMClientDelegate> delegate(new GCMClientDelegate("test_user_1"));
|
| + user_list->SetDelegate(
|
| + delegate->GetUsername(),
|
| + delegate.get(),
|
| + base::Bind(&UserListTest::SetDelegateCallback, base::Unretained(this)));
|
| +
|
| + EXPECT_EQ(gcm::kInvalidSerialNumber, last_assigned_serial_number_);
|
| + EXPECT_EQ("", last_assigned_username_);
|
| +
|
| + // Now run the initialization.
|
| + gcm_store_->Load(base::Bind(
|
| + &UserListTest::Initialize, base::Unretained(this), user_list.get()));
|
| + // Need to pump twice, due to initialization triggering additional set of
|
| + // callbacks to be run.
|
| + PumpLoop();
|
| + PumpLoop();
|
| +
|
| + EXPECT_EQ(last_assigned_serial_number_,
|
| + user_list->GetSerialNumberForUsername(delegate->GetUsername()));
|
| + EXPECT_EQ(delegate->GetUsername(), last_assigned_username_);
|
| +}
|
| +
|
| +// Adding a delegate that already has a serial number on a subsequent restart of
|
| +// the user list and prior to initialization. Expects to assing correct serial
|
| +// number based on existing mappings.
|
| +TEST_F(UserListTest, AddDelegateThenInitializeWithSerialNumber) {
|
| + scoped_ptr<UserList> user_list(BuildUserList());
|
| + gcm_store_->Load(base::Bind(
|
| + &UserListTest::Initialize, base::Unretained(this), user_list.get()));
|
| + PumpLoop();
|
| +
|
| + // First add a delegate to the list so that serial number is persisted.
|
| + scoped_ptr<GCMClientDelegate> delegate(new GCMClientDelegate("test_user_1"));
|
| + user_list->SetDelegate(
|
| + delegate->GetUsername(),
|
| + delegate.get(),
|
| + base::Bind(&UserListTest::SetDelegateCallback, base::Unretained(this)));
|
| + PumpLoop();
|
| +
|
| + last_assigned_serial_number_ = gcm::kInvalidSerialNumber;
|
| + last_assigned_username_ = "";
|
| +
|
| + // Resetting the user list to make sure it is not initialized.
|
| + user_list = BuildUserList().Pass();
|
| +
|
| + // Add a delegate again, this time no callback is expected until the list is
|
| + // initialized.
|
| + user_list->SetDelegate(
|
| + delegate->GetUsername(),
|
| + delegate.get(),
|
| + base::Bind(&UserListTest::SetDelegateCallback, base::Unretained(this)));
|
| +
|
| + // Now run the initialization.
|
| + gcm_store_->Load(base::Bind(
|
| + &UserListTest::Initialize, base::Unretained(this), user_list.get()));
|
| + // Need to pump twice, due to initialization triggering additional set of
|
| + // callbacks to be run.
|
| + PumpLoop();
|
| + PumpLoop();
|
| +
|
| + EXPECT_EQ(last_assigned_serial_number_,
|
| + user_list->GetSerialNumberForUsername(delegate->GetUsername()));
|
| + EXPECT_EQ(delegate->GetUsername(), last_assigned_username_);
|
| +}
|
| +
|
| +} // namespace gcm
|
|
|