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.
6 #include "base/files/scoped_temp_dir.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/test/sequenced_worker_pool_owner.h"
9 #include "content/browser/media/webrtc_identity_store.h"
10 #include "content/public/test/test_browser_thread_bundle.h"
11 #include "content/public/test/test_utils.h"
12 #include "net/base/net_errors.h"
13 #include "sql/connection.h"
14 #include "sql/test/test_helpers.h"
15 #include "testing/gtest/include/gtest/gtest.h"
20 static const char kFakeOrigin
[] = "http://foo.com";
21 static const char kFakeIdentityName1
[] = "name1";
22 static const char kFakeIdentityName2
[] = "name2";
23 static const char kFakeCommonName1
[] = "cname1";
24 static const char kFakeCommonName2
[] = "cname2";
26 static void OnRequestCompleted(bool* completed
,
27 std::string
* out_cert
,
30 const std::string
& certificate
,
31 const std::string
& private_key
) {
32 ASSERT_EQ(net::OK
, error
);
33 ASSERT_NE("", certificate
);
34 ASSERT_NE("", private_key
);
36 *out_cert
= certificate
;
37 *out_key
= private_key
;
40 class WebRTCIdentityStoreTest
: public testing::Test
{
42 WebRTCIdentityStoreTest()
43 : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP
|
44 TestBrowserThreadBundle::REAL_DB_THREAD
),
46 new base::SequencedWorkerPoolOwner(3, "WebRTCIdentityStoreTest")),
47 webrtc_identity_store_(
48 new WebRTCIdentityStore(base::FilePath(), NULL
)) {
49 webrtc_identity_store_
->SetTaskRunnerForTesting(pool_owner_
->pool());
52 virtual ~WebRTCIdentityStoreTest() {
53 pool_owner_
->pool()->Shutdown();
56 void SetValidityPeriod(base::TimeDelta validity_period
) {
57 webrtc_identity_store_
->SetValidityPeriodForTesting(validity_period
);
61 RunAllPendingInMessageLoop(BrowserThread::DB
);
62 RunAllPendingInMessageLoop(BrowserThread::IO
);
63 pool_owner_
->pool()->FlushForTesting();
64 base::RunLoop().RunUntilIdle();
67 base::Closure
RequestIdentityAndRunUtilIdle(const std::string
& origin
,
68 const std::string
& identity_name
,
69 const std::string
& common_name
,
71 std::string
* certificate
,
72 std::string
* private_key
) {
73 base::Closure cancel_callback
= webrtc_identity_store_
->RequestIdentity(
77 base::Bind(&OnRequestCompleted
, completed
, certificate
, private_key
));
78 EXPECT_FALSE(cancel_callback
.is_null());
80 return cancel_callback
;
83 void Restart(const base::FilePath
& path
) {
84 webrtc_identity_store_
= new WebRTCIdentityStore(path
, NULL
);
85 webrtc_identity_store_
->SetTaskRunnerForTesting(pool_owner_
->pool());
89 TestBrowserThreadBundle browser_thread_bundle_
;
90 scoped_ptr
<base::SequencedWorkerPoolOwner
> pool_owner_
;
91 scoped_refptr
<WebRTCIdentityStore
> webrtc_identity_store_
;
94 TEST_F(WebRTCIdentityStoreTest
, RequestIdentity
) {
95 bool completed
= false;
97 base::Closure cancel_callback
=
98 RequestIdentityAndRunUtilIdle(kFakeOrigin
,
104 EXPECT_TRUE(completed
);
107 TEST_F(WebRTCIdentityStoreTest
, CancelRequest
) {
108 bool completed
= false;
110 base::Closure cancel_callback
= webrtc_identity_store_
->RequestIdentity(
114 base::Bind(&OnRequestCompleted
, &completed
, &dummy
, &dummy
));
115 ASSERT_FALSE(cancel_callback
.is_null());
116 cancel_callback
.Run();
119 EXPECT_FALSE(completed
);
122 TEST_F(WebRTCIdentityStoreTest
, ConcurrentUniqueRequests
) {
123 bool completed_1
= false;
124 bool completed_2
= false;
126 base::Closure cancel_callback_1
= webrtc_identity_store_
->RequestIdentity(
130 base::Bind(&OnRequestCompleted
, &completed_1
, &dummy
, &dummy
));
131 ASSERT_FALSE(cancel_callback_1
.is_null());
133 base::Closure cancel_callback_2
= webrtc_identity_store_
->RequestIdentity(
137 base::Bind(&OnRequestCompleted
, &completed_2
, &dummy
, &dummy
));
138 ASSERT_FALSE(cancel_callback_2
.is_null());
141 EXPECT_TRUE(completed_1
);
142 EXPECT_TRUE(completed_2
);
145 TEST_F(WebRTCIdentityStoreTest
, DifferentCommonNameReturnNewIdentity
) {
146 bool completed_1
= false;
147 bool completed_2
= false;
148 std::string cert_1
, cert_2
, key_1
, key_2
;
150 base::Closure cancel_callback_1
=
151 RequestIdentityAndRunUtilIdle(kFakeOrigin
,
158 base::Closure cancel_callback_2
=
159 RequestIdentityAndRunUtilIdle(kFakeOrigin
,
166 EXPECT_TRUE(completed_1
);
167 EXPECT_TRUE(completed_2
);
168 EXPECT_NE(cert_1
, cert_2
);
169 EXPECT_NE(key_1
, key_2
);
172 TEST_F(WebRTCIdentityStoreTest
, SerialIdenticalRequests
) {
173 bool completed_1
= false;
174 bool completed_2
= false;
175 std::string cert_1
, cert_2
, key_1
, key_2
;
177 base::Closure cancel_callback_1
=
178 RequestIdentityAndRunUtilIdle(kFakeOrigin
,
185 base::Closure cancel_callback_2
=
186 RequestIdentityAndRunUtilIdle(kFakeOrigin
,
193 EXPECT_TRUE(completed_1
);
194 EXPECT_TRUE(completed_2
);
195 EXPECT_EQ(cert_1
, cert_2
);
196 EXPECT_EQ(key_1
, key_2
);
199 TEST_F(WebRTCIdentityStoreTest
, ConcurrentIdenticalRequestsJoined
) {
200 bool completed_1
= false;
201 bool completed_2
= false;
202 std::string cert_1
, cert_2
, key_1
, key_2
;
204 base::Closure cancel_callback_1
= webrtc_identity_store_
->RequestIdentity(
208 base::Bind(&OnRequestCompleted
, &completed_1
, &cert_1
, &key_1
));
209 ASSERT_FALSE(cancel_callback_1
.is_null());
211 base::Closure cancel_callback_2
= webrtc_identity_store_
->RequestIdentity(
215 base::Bind(&OnRequestCompleted
, &completed_2
, &cert_2
, &key_2
));
216 ASSERT_FALSE(cancel_callback_2
.is_null());
219 EXPECT_TRUE(completed_1
);
220 EXPECT_TRUE(completed_2
);
221 EXPECT_EQ(cert_1
, cert_2
);
222 EXPECT_EQ(key_1
, key_2
);
225 TEST_F(WebRTCIdentityStoreTest
, CancelOneOfIdenticalRequests
) {
226 bool completed_1
= false;
227 bool completed_2
= false;
228 std::string cert_1
, cert_2
, key_1
, key_2
;
230 base::Closure cancel_callback_1
= webrtc_identity_store_
->RequestIdentity(
234 base::Bind(&OnRequestCompleted
, &completed_1
, &cert_1
, &key_1
));
235 ASSERT_FALSE(cancel_callback_1
.is_null());
237 base::Closure cancel_callback_2
= webrtc_identity_store_
->RequestIdentity(
241 base::Bind(&OnRequestCompleted
, &completed_2
, &cert_2
, &key_2
));
242 ASSERT_FALSE(cancel_callback_2
.is_null());
244 cancel_callback_1
.Run();
247 EXPECT_FALSE(completed_1
);
248 EXPECT_TRUE(completed_2
);
251 TEST_F(WebRTCIdentityStoreTest
, DeleteDataAndGenerateNewIdentity
) {
252 bool completed_1
= false;
253 bool completed_2
= false;
254 std::string cert_1
, cert_2
, key_1
, key_2
;
256 // Generate the first identity.
257 base::Closure cancel_callback_1
=
258 RequestIdentityAndRunUtilIdle(kFakeOrigin
,
265 // Clear the data and the second request should return a new identity.
266 webrtc_identity_store_
->DeleteBetween(
267 base::Time(), base::Time::Now(), base::Bind(&base::DoNothing
));
270 base::Closure cancel_callback_2
=
271 RequestIdentityAndRunUtilIdle(kFakeOrigin
,
278 EXPECT_TRUE(completed_1
);
279 EXPECT_TRUE(completed_2
);
280 EXPECT_NE(cert_1
, cert_2
);
281 EXPECT_NE(key_1
, key_2
);
284 TEST_F(WebRTCIdentityStoreTest
, ExpiredIdentityDeleted
) {
285 // The identities will expire immediately after creation.
286 SetValidityPeriod(base::TimeDelta::FromMilliseconds(0));
288 bool completed_1
= false;
289 bool completed_2
= false;
290 std::string cert_1
, cert_2
, key_1
, key_2
;
292 base::Closure cancel_callback_1
=
293 RequestIdentityAndRunUtilIdle(kFakeOrigin
,
299 EXPECT_TRUE(completed_1
);
301 // Check that the old identity is not returned.
302 base::Closure cancel_callback_2
=
303 RequestIdentityAndRunUtilIdle(kFakeOrigin
,
309 EXPECT_TRUE(completed_2
);
310 EXPECT_NE(cert_1
, cert_2
);
311 EXPECT_NE(key_1
, key_2
);
314 TEST_F(WebRTCIdentityStoreTest
, IdentityPersistentAcrossRestart
) {
315 base::ScopedTempDir temp_dir
;
316 ASSERT_TRUE(temp_dir
.CreateUniqueTempDir());
317 Restart(temp_dir
.path());
319 bool completed_1
= false;
320 bool completed_2
= false;
321 std::string cert_1
, cert_2
, key_1
, key_2
;
323 // Creates an identity.
324 base::Closure cancel_callback_1
=
325 RequestIdentityAndRunUtilIdle(kFakeOrigin
,
331 EXPECT_TRUE(completed_1
);
333 Restart(temp_dir
.path());
335 // Check that the same identity is returned after the restart.
336 base::Closure cancel_callback_2
=
337 RequestIdentityAndRunUtilIdle(kFakeOrigin
,
343 EXPECT_TRUE(completed_2
);
344 EXPECT_EQ(cert_1
, cert_2
);
345 EXPECT_EQ(key_1
, key_2
);
348 TEST_F(WebRTCIdentityStoreTest
, HandleDBErrors
) {
349 base::ScopedTempDir temp_dir
;
350 ASSERT_TRUE(temp_dir
.CreateUniqueTempDir());
351 Restart(temp_dir
.path());
353 bool completed_1
= false;
354 std::string cert_1
, key_1
;
356 // Creates an identity.
357 RequestIdentityAndRunUtilIdle(kFakeOrigin
,
364 // Make the table corrupted.
365 base::FilePath db_path
=
366 temp_dir
.path().Append(FILE_PATH_LITERAL("WebRTCIdentityStore"));
367 EXPECT_TRUE(sql::test::CorruptSizeInHeader(db_path
));
369 // Reset to commit the DB changes, which should fail and not crash.
370 webrtc_identity_store_
= NULL
;
373 // Verifies the corrupted table was razed.
374 scoped_ptr
<sql::Connection
> db(new sql::Connection());
375 EXPECT_TRUE(db
->Open(db_path
));
376 EXPECT_EQ(0U, sql::test::CountSQLTables(db
.get()));
379 } // namespace content