Home | History | Annotate | Download | only in login
      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 <string>
      6 #include <vector>
      7 
      8 #include "base/command_line.h"
      9 #include "base/memory/ref_counted.h"
     10 #include "base/run_loop.h"
     11 #include "chrome/browser/chromeos/login/users/user.h"
     12 #include "chrome/browser/chromeos/login/users/user_manager.h"
     13 #include "chrome/test/base/in_process_browser_test.h"
     14 #include "chromeos/chromeos_switches.h"
     15 #include "chromeos/dbus/cryptohome_client.h"
     16 #include "chromeos/dbus/fake_dbus_thread_manager.h"
     17 #include "chromeos/dbus/fake_session_manager_client.h"
     18 #include "chromeos/dbus/session_manager_client.h"
     19 #include "content/public/test/test_utils.h"
     20 #include "testing/gmock/include/gmock/gmock.h"
     21 #include "third_party/cros_system_api/dbus/service_constants.h"
     22 
     23 namespace chromeos {
     24 
     25 namespace {
     26 
     27 const char kUserId1[] = "user1 (at) example.com";
     28 const char kUserId2[] = "user2 (at) example.com";
     29 const char kUserId3[] = "user3 (at) example.com";
     30 
     31 }  // namespace
     32 
     33 class CrashRestoreSimpleTest : public InProcessBrowserTest {
     34  protected:
     35   CrashRestoreSimpleTest() {}
     36 
     37   virtual ~CrashRestoreSimpleTest() {}
     38 
     39   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
     40     command_line->AppendSwitchASCII(switches::kLoginUser, kUserId1);
     41     command_line->AppendSwitchASCII(
     42         switches::kLoginProfile,
     43         CryptohomeClient::GetStubSanitizedUsername(kUserId1));
     44   }
     45 
     46   virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
     47     // Redirect session_manager DBus calls to FakeSessionManagerClient.
     48     FakeDBusThreadManager* dbus_thread_manager = new FakeDBusThreadManager;
     49     dbus_thread_manager->SetFakeClients();
     50     session_manager_client_ = new FakeSessionManagerClient;
     51     dbus_thread_manager->SetSessionManagerClient(
     52         scoped_ptr<SessionManagerClient>(session_manager_client_));
     53     DBusThreadManager::SetInstanceForTesting(dbus_thread_manager);
     54     session_manager_client_->StartSession(kUserId1);
     55   }
     56 
     57   FakeSessionManagerClient* session_manager_client_;
     58 };
     59 
     60 IN_PROC_BROWSER_TEST_F(CrashRestoreSimpleTest, RestoreSessionForOneUser) {
     61   UserManager* user_manager = UserManager::Get();
     62   User* user = user_manager->GetActiveUser();
     63   ASSERT_TRUE(user);
     64   EXPECT_EQ(kUserId1, user->email());
     65   EXPECT_EQ(CryptohomeClient::GetStubSanitizedUsername(kUserId1),
     66             user->username_hash());
     67   EXPECT_EQ(1UL, user_manager->GetLoggedInUsers().size());
     68 }
     69 
     70 // Observer that keeps track of user sessions restore event.
     71 class UserSessionRestoreObserver :
     72     public UserManager::UserSessionStateObserver {
     73  public:
     74   UserSessionRestoreObserver()
     75       : running_loop_(false),
     76         user_sessions_restored_(UserManager::Get()->UserSessionsRestored()) {
     77     if (!user_sessions_restored_)
     78       UserManager::Get()->AddSessionStateObserver(this);
     79   }
     80   virtual ~UserSessionRestoreObserver() {}
     81 
     82   virtual void PendingUserSessionsRestoreFinished() OVERRIDE {
     83     user_sessions_restored_ = true;
     84     UserManager::Get()->RemoveSessionStateObserver(this);
     85     if (!running_loop_)
     86       return;
     87 
     88     message_loop_runner_->Quit();
     89     running_loop_ = false;
     90   }
     91 
     92   // Wait until the user sessions are restored. If that happened between the
     93   // construction of this object and this call or even before it was created
     94   // then it returns immediately.
     95   void Wait() {
     96     if (user_sessions_restored_)
     97       return;
     98 
     99     running_loop_ = true;
    100     message_loop_runner_ = new content::MessageLoopRunner();
    101     message_loop_runner_->Run();
    102   }
    103 
    104  private:
    105   bool running_loop_;
    106   bool user_sessions_restored_;
    107   scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
    108 
    109   DISALLOW_COPY_AND_ASSIGN(UserSessionRestoreObserver);
    110 };
    111 
    112 class CrashRestoreComplexTest : public CrashRestoreSimpleTest {
    113  protected:
    114   CrashRestoreComplexTest() {}
    115   virtual ~CrashRestoreComplexTest() {}
    116 
    117   virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
    118     CrashRestoreSimpleTest::SetUpInProcessBrowserTestFixture();
    119     session_manager_client_->StartSession(kUserId2);
    120     session_manager_client_->StartSession(kUserId3);
    121   }
    122 };
    123 
    124 IN_PROC_BROWSER_TEST_F(CrashRestoreComplexTest, RestoreSessionForThreeUsers) {
    125   {
    126     UserSessionRestoreObserver restore_observer;
    127     restore_observer.Wait();
    128   }
    129 
    130   UserManager* user_manager = UserManager::Get();
    131   DCHECK(user_manager->UserSessionsRestored());
    132 
    133   // User that is last in the user sessions map becomes active. This behavior
    134   // will become better defined once each user gets a separate user desktop.
    135   User* user = user_manager->GetActiveUser();
    136   ASSERT_TRUE(user);
    137   EXPECT_EQ(kUserId3, user->email());
    138   EXPECT_EQ(CryptohomeClient::GetStubSanitizedUsername(kUserId3),
    139             user->username_hash());
    140   const UserList& users = user_manager->GetLoggedInUsers();
    141   ASSERT_EQ(3UL, users.size());
    142 
    143   // User that becomes active moves to the beginning of the list.
    144   EXPECT_EQ(kUserId3, users[0]->email());
    145   EXPECT_EQ(CryptohomeClient::GetStubSanitizedUsername(kUserId3),
    146             users[0]->username_hash());
    147   EXPECT_EQ(kUserId2, users[1]->email());
    148   EXPECT_EQ(CryptohomeClient::GetStubSanitizedUsername(kUserId2),
    149             users[1]->username_hash());
    150   EXPECT_EQ(kUserId1, users[2]->email());
    151   EXPECT_EQ(CryptohomeClient::GetStubSanitizedUsername(kUserId1),
    152             users[2]->username_hash());
    153 }
    154 
    155 }  // namespace chromeos
    156