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.
5 #include "chrome/browser/net/nss_context.h"
8 #include "base/run_loop.h"
9 #include "chrome/browser/chromeos/login/login_manager_test.h"
10 #include "chrome/browser/chromeos/login/startup_utils.h"
11 #include "chrome/browser/chromeos/login/user.h"
12 #include "chrome/browser/chromeos/login/user_adding_screen.h"
13 #include "chrome/browser/chromeos/login/user_manager.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "net/cert/nss_cert_database.h"
19 const char kTestUser1
[] = "test-user1@gmail.com";
20 const char kTestUser2
[] = "test-user2@gmail.com";
22 void NotCalledDbCallback(net::NSSCertDatabase
* db
) { ASSERT_TRUE(false); }
24 // DBTester handles retrieving the NSSCertDatabase for a given profile, and
25 // doing some simple sanity checks.
26 // Browser test cases run on the UI thread, while the nss_context access needs
27 // to happen on the IO thread. The DBTester class encapsulates the thread
28 // posting and waiting on the UI thread so that the test case body can be
32 explicit DBTester(Profile
* profile
) : profile_(profile
), db_(NULL
) {}
34 // Initial retrieval of cert database. It may be asynchronous or synchronous.
35 // Returns true if the database was retrieved successfully.
37 base::RunLoop run_loop
;
38 content::BrowserThread::PostTask(
39 content::BrowserThread::IO
,
41 base::Bind(&DBTester::GetDBAndDoTestsOnIOThread
,
42 base::Unretained(this),
43 profile_
->GetResourceContext(),
44 run_loop
.QuitClosure()));
49 // Test retrieving the database again, should be called after DoGetDBTests.
50 void DoGetDBAgainTests() {
51 base::RunLoop run_loop
;
52 content::BrowserThread::PostTask(
53 content::BrowserThread::IO
,
55 base::Bind(&DBTester::DoGetDBAgainTestsOnIOThread
,
56 base::Unretained(this),
57 profile_
->GetResourceContext(),
58 run_loop
.QuitClosure()));
62 void DoNotEqualsTests(DBTester
* other_tester
) {
63 // The DB and its NSS slots should be different for each profile.
64 EXPECT_NE(db_
, other_tester
->db_
);
65 EXPECT_NE(db_
->GetPublicSlot().get(),
66 other_tester
->db_
->GetPublicSlot().get());
70 void GetDBAndDoTestsOnIOThread(content::ResourceContext
* context
,
71 const base::Closure
& done_callback
) {
72 net::NSSCertDatabase
* db
= GetNSSCertDatabaseForResourceContext(
74 base::Bind(&DBTester::DoTestsOnIOThread
,
75 base::Unretained(this),
78 DVLOG(1) << "got db synchronously";
79 DoTestsOnIOThread(done_callback
, db
);
81 DVLOG(1) << "getting db asynchronously...";
85 void DoTestsOnIOThread(const base::Closure
& done_callback
,
86 net::NSSCertDatabase
* db
) {
90 EXPECT_TRUE(db
->GetPublicSlot().get());
91 // Public and private slot are the same in tests.
92 EXPECT_EQ(db
->GetPublicSlot().get(), db
->GetPrivateSlot().get());
95 content::BrowserThread::PostTask(
96 content::BrowserThread::UI
, FROM_HERE
, done_callback
);
99 void DoGetDBAgainTestsOnIOThread(content::ResourceContext
* context
,
100 const base::Closure
& done_callback
) {
101 net::NSSCertDatabase
* db
= GetNSSCertDatabaseForResourceContext(
102 context
, base::Bind(&NotCalledDbCallback
));
103 // Should always be synchronous now.
105 // Should return the same db as before.
108 content::BrowserThread::PostTask(
109 content::BrowserThread::UI
, FROM_HERE
, done_callback
);
113 net::NSSCertDatabase
* db_
;
118 class NSSContextChromeOSBrowserTest
: public chromeos::LoginManagerTest
{
120 NSSContextChromeOSBrowserTest()
121 : LoginManagerTest(true /* should_launch_browser */) {}
122 virtual ~NSSContextChromeOSBrowserTest() {}
125 IN_PROC_BROWSER_TEST_F(NSSContextChromeOSBrowserTest
, PRE_TwoUsers
) {
126 // Initialization for ChromeOS multi-profile test infrastructure.
127 RegisterUser(kTestUser1
);
128 RegisterUser(kTestUser2
);
129 chromeos::StartupUtils::MarkOobeCompleted();
132 IN_PROC_BROWSER_TEST_F(NSSContextChromeOSBrowserTest
, TwoUsers
) {
133 chromeos::UserManager
* user_manager
= chromeos::UserManager::Get();
135 // Log in first user and get their DB.
136 LoginUser(kTestUser1
);
138 user_manager
->GetProfileByUser(user_manager
->FindUser(kTestUser1
));
139 ASSERT_TRUE(profile1
);
141 DBTester
tester1(profile1
);
142 ASSERT_TRUE(tester1
.DoGetDBTests());
144 // Log in second user and get their DB.
145 chromeos::UserAddingScreen::Get()->Start();
146 base::RunLoop().RunUntilIdle();
150 user_manager
->GetProfileByUser(user_manager
->FindUser(kTestUser2
));
151 ASSERT_TRUE(profile2
);
153 DBTester
tester2(profile2
);
154 ASSERT_TRUE(tester2
.DoGetDBTests());
156 // Get both DBs again to check that the same object is returned.
157 tester1
.DoGetDBAgainTests();
158 tester2
.DoGetDBAgainTests();
160 // Check that each user has a separate DB and NSS slots.
161 tester1
.DoNotEqualsTests(&tester2
);