Home | History | Annotate | Download | only in profiles
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/profiles/profile_loader.h"
      6 
      7 #include <map>
      8 
      9 #include "base/bind.h"
     10 #include "base/files/file_path.h"
     11 #include "base/memory/weak_ptr.h"
     12 #include "chrome/browser/lifetime/application_lifetime.h"
     13 #include "chrome/browser/profiles/profile.h"
     14 #include "chrome/browser/profiles/profile_loader.h"
     15 #include "chrome/test/base/testing_profile.h"
     16 #include "testing/gmock/include/gmock/gmock.h"
     17 #include "testing/gtest/include/gtest/gtest.h"
     18 
     19 namespace {
     20 
     21 using ::testing::_;
     22 using ::testing::Invoke;
     23 using ::testing::Return;
     24 using ::testing::StrictMock;
     25 using ::testing::WithArgs;
     26 
     27 class TestProfileLoader : public ProfileLoader {
     28  public:
     29   TestProfileLoader() : ProfileLoader(NULL) {}
     30   virtual ~TestProfileLoader() {}
     31 
     32   MOCK_METHOD1(GetProfileByPath, Profile*(const base::FilePath&));
     33   MOCK_METHOD5(CreateProfileAsync, void(const base::FilePath&,
     34                                         const ProfileManager::CreateCallback&,
     35                                         const string16&,
     36                                         const string16&,
     37                                         const std::string&));
     38 
     39   void SetCreateCallback(const base::FilePath& path,
     40                          const ProfileManager::CreateCallback& callback) {
     41     callbacks_[path] = callback;
     42   }
     43 
     44   void RunCreateCallback(const base::FilePath& path,
     45                          Profile* profile,
     46                          Profile::CreateStatus status) {
     47     callbacks_[path].Run(profile, status);
     48   }
     49 
     50  private:
     51   std::map<base::FilePath, ProfileManager::CreateCallback> callbacks_;
     52 
     53   DISALLOW_COPY_AND_ASSIGN(TestProfileLoader);
     54 };
     55 
     56 class MockCallback : public base::RefCountedThreadSafe<MockCallback> {
     57  public:
     58   MockCallback();
     59   MOCK_METHOD1(Run, void(Profile*));
     60 
     61  protected:
     62   friend class base::RefCountedThreadSafe<MockCallback>;
     63   virtual ~MockCallback();
     64 
     65  private:
     66   DISALLOW_COPY_AND_ASSIGN(MockCallback);
     67 };
     68 
     69 MockCallback::MockCallback() {}
     70 MockCallback::~MockCallback() {}
     71 
     72 TEST(ProfileLoaderTest, LoadProfileInvalidatingOtherLoads) {
     73   TestingProfile profile;
     74   base::FilePath fake_profile_path_1 =
     75       base::FilePath::FromUTF8Unsafe("fake/profile 1");
     76   base::FilePath fake_profile_path_2 =
     77       base::FilePath::FromUTF8Unsafe("fake/profile 2");
     78 
     79   TestProfileLoader loader;
     80   EXPECT_FALSE(loader.IsAnyProfileLoading());
     81 
     82   // path_1 never loads.
     83   EXPECT_CALL(loader, GetProfileByPath(fake_profile_path_1))
     84       .WillRepeatedly(Return(static_cast<Profile*>(NULL)));
     85   EXPECT_CALL(loader,
     86               CreateProfileAsync(fake_profile_path_1, _, _, _, std::string()))
     87       .WillRepeatedly(WithArgs<0, 1>(
     88           Invoke(&loader, &TestProfileLoader::SetCreateCallback)));
     89 
     90   // path_2 loads after the first request.
     91   EXPECT_CALL(loader, GetProfileByPath(fake_profile_path_2))
     92       .WillOnce(Return(static_cast<Profile*>(NULL)))
     93       .WillRepeatedly(Return(&profile));
     94   EXPECT_CALL(loader,
     95               CreateProfileAsync(fake_profile_path_2, _, _, _, std::string()))
     96       .WillRepeatedly(WithArgs<0, 1>(
     97           Invoke(&loader, &TestProfileLoader::SetCreateCallback)));
     98 
     99   // Try to load both paths twice.
    100   // path_1_load is never called because it is first invalidated by the load
    101   // request for (path_2), and then invalidated manually.
    102   // path_2_load is called both times.
    103   StrictMock<MockCallback>* path_1_load = new StrictMock<MockCallback>();
    104   StrictMock<MockCallback>* path_2_load = new StrictMock<MockCallback>();
    105   EXPECT_CALL(*path_2_load, Run(&profile))
    106       .Times(2);
    107 
    108   // Try to load path_1.
    109   loader.LoadProfileInvalidatingOtherLoads(
    110       fake_profile_path_1, base::Bind(&MockCallback::Run, path_1_load));
    111   EXPECT_TRUE(loader.IsAnyProfileLoading());
    112 
    113   // Try to load path_2, this invalidates the previous request.
    114   loader.LoadProfileInvalidatingOtherLoads(
    115       fake_profile_path_2, base::Bind(&MockCallback::Run, path_2_load));
    116 
    117   // Finish the load request for path_1, then for path_2.
    118   loader.RunCreateCallback(fake_profile_path_1, &profile,
    119                            Profile::CREATE_STATUS_INITIALIZED);
    120   loader.RunCreateCallback(fake_profile_path_2, &profile,
    121                            Profile::CREATE_STATUS_INITIALIZED);
    122   EXPECT_FALSE(loader.IsAnyProfileLoading());
    123 
    124   // The second request for path_2 should return immediately.
    125   loader.LoadProfileInvalidatingOtherLoads(
    126       fake_profile_path_2, base::Bind(&MockCallback::Run, path_2_load));
    127 
    128   // Make a second request for path_1, and invalidate it.
    129   loader.LoadProfileInvalidatingOtherLoads(
    130       fake_profile_path_1, base::Bind(&MockCallback::Run, path_1_load));
    131   loader.InvalidatePendingProfileLoads();
    132 }
    133 
    134 }  // namespace
    135