OLD | NEW |
| (Empty) |
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 "content/browser/media/webrtc/webrtc_identity_store.h" | |
6 | |
7 #include <memory> | |
8 | |
9 #include "base/bind.h" | |
10 #include "base/files/scoped_temp_dir.h" | |
11 #include "base/test/sequenced_worker_pool_owner.h" | |
12 #include "content/public/test/test_browser_thread_bundle.h" | |
13 #include "content/public/test/test_utils.h" | |
14 #include "net/base/net_errors.h" | |
15 #include "sql/connection.h" | |
16 #include "sql/test/test_helpers.h" | |
17 #include "testing/gtest/include/gtest/gtest.h" | |
18 #include "url/gurl.h" | |
19 | |
20 namespace content { | |
21 | |
22 static const char kFakeOrigin[] = "http://foo.com"; | |
23 static const char kFakeIdentityName1[] = "name1"; | |
24 static const char kFakeIdentityName2[] = "name2"; | |
25 static const char kFakeCommonName1[] = "cname1"; | |
26 static const char kFakeCommonName2[] = "cname2"; | |
27 | |
28 static void OnRequestCompleted(bool* completed, | |
29 std::string* out_cert, | |
30 std::string* out_key, | |
31 int error, | |
32 const std::string& certificate, | |
33 const std::string& private_key) { | |
34 ASSERT_EQ(net::OK, error); | |
35 ASSERT_NE("", certificate); | |
36 ASSERT_NE("", private_key); | |
37 *completed = true; | |
38 *out_cert = certificate; | |
39 *out_key = private_key; | |
40 } | |
41 | |
42 class WebRtcIdentityStoreTest : public testing::Test { | |
43 public: | |
44 WebRtcIdentityStoreTest() | |
45 : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP | | |
46 TestBrowserThreadBundle::REAL_DB_THREAD), | |
47 pool_owner_( | |
48 new base::SequencedWorkerPoolOwner(3, "WebRtcIdentityStoreTest")), | |
49 webrtc_identity_store_( | |
50 new WebRTCIdentityStore(base::FilePath(), NULL)) { | |
51 webrtc_identity_store_->SetTaskRunnerForTesting(pool_owner_->pool()); | |
52 } | |
53 | |
54 void SetValidityPeriod(base::TimeDelta validity_period) { | |
55 webrtc_identity_store_->SetValidityPeriodForTesting(validity_period); | |
56 } | |
57 | |
58 void RunUntilIdle() { | |
59 RunAllPendingInMessageLoop(BrowserThread::DB); | |
60 RunAllPendingInMessageLoop(BrowserThread::IO); | |
61 pool_owner_->pool()->FlushForTesting(); | |
62 base::RunLoop().RunUntilIdle(); | |
63 } | |
64 | |
65 base::Closure RequestIdentityAndRunUtilIdle(const std::string& origin, | |
66 const std::string& identity_name, | |
67 const std::string& common_name, | |
68 bool* completed, | |
69 std::string* certificate, | |
70 std::string* private_key) { | |
71 base::Closure cancel_callback = webrtc_identity_store_->RequestIdentity( | |
72 GURL(origin), identity_name, common_name, | |
73 base::Bind(&OnRequestCompleted, completed, certificate, private_key), | |
74 true /* enable_cache */); | |
75 EXPECT_FALSE(cancel_callback.is_null()); | |
76 RunUntilIdle(); | |
77 return cancel_callback; | |
78 } | |
79 | |
80 void Restart(const base::FilePath& path) { | |
81 webrtc_identity_store_ = new WebRTCIdentityStore(path, NULL); | |
82 webrtc_identity_store_->SetTaskRunnerForTesting(pool_owner_->pool()); | |
83 } | |
84 | |
85 void Stop() { webrtc_identity_store_ = nullptr; } | |
86 | |
87 protected: | |
88 TestBrowserThreadBundle browser_thread_bundle_; | |
89 std::unique_ptr<base::SequencedWorkerPoolOwner> pool_owner_; | |
90 scoped_refptr<WebRTCIdentityStore> webrtc_identity_store_; | |
91 }; | |
92 | |
93 TEST_F(WebRtcIdentityStoreTest, RequestIdentity) { | |
94 bool completed = false; | |
95 std::string dummy; | |
96 base::Closure cancel_callback = | |
97 RequestIdentityAndRunUtilIdle(kFakeOrigin, | |
98 kFakeIdentityName1, | |
99 kFakeCommonName1, | |
100 &completed, | |
101 &dummy, | |
102 &dummy); | |
103 EXPECT_TRUE(completed); | |
104 } | |
105 | |
106 TEST_F(WebRtcIdentityStoreTest, CancelRequest) { | |
107 bool completed = false; | |
108 std::string dummy; | |
109 base::Closure cancel_callback = webrtc_identity_store_->RequestIdentity( | |
110 GURL(kFakeOrigin), kFakeIdentityName1, kFakeCommonName1, | |
111 base::Bind(&OnRequestCompleted, &completed, &dummy, &dummy), | |
112 true /* enable_cache */); | |
113 ASSERT_FALSE(cancel_callback.is_null()); | |
114 cancel_callback.Run(); | |
115 | |
116 RunUntilIdle(); | |
117 EXPECT_FALSE(completed); | |
118 } | |
119 | |
120 TEST_F(WebRtcIdentityStoreTest, ConcurrentUniqueRequests) { | |
121 bool completed_1 = false; | |
122 bool completed_2 = false; | |
123 std::string dummy; | |
124 base::Closure cancel_callback_1 = webrtc_identity_store_->RequestIdentity( | |
125 GURL(kFakeOrigin), kFakeIdentityName1, kFakeCommonName1, | |
126 base::Bind(&OnRequestCompleted, &completed_1, &dummy, &dummy), | |
127 true /* enable_cache */); | |
128 ASSERT_FALSE(cancel_callback_1.is_null()); | |
129 | |
130 base::Closure cancel_callback_2 = webrtc_identity_store_->RequestIdentity( | |
131 GURL(kFakeOrigin), kFakeIdentityName2, kFakeCommonName1, | |
132 base::Bind(&OnRequestCompleted, &completed_2, &dummy, &dummy), | |
133 true /* enable_cache */); | |
134 ASSERT_FALSE(cancel_callback_2.is_null()); | |
135 | |
136 RunUntilIdle(); | |
137 EXPECT_TRUE(completed_1); | |
138 EXPECT_TRUE(completed_2); | |
139 } | |
140 | |
141 TEST_F(WebRtcIdentityStoreTest, DifferentCommonNameReturnNewIdentity) { | |
142 bool completed_1 = false; | |
143 bool completed_2 = false; | |
144 std::string cert_1, cert_2, key_1, key_2; | |
145 | |
146 base::Closure cancel_callback_1 = | |
147 RequestIdentityAndRunUtilIdle(kFakeOrigin, | |
148 kFakeIdentityName1, | |
149 kFakeCommonName1, | |
150 &completed_1, | |
151 &cert_1, | |
152 &key_1); | |
153 | |
154 base::Closure cancel_callback_2 = | |
155 RequestIdentityAndRunUtilIdle(kFakeOrigin, | |
156 kFakeIdentityName1, | |
157 kFakeCommonName2, | |
158 &completed_2, | |
159 &cert_2, | |
160 &key_2); | |
161 | |
162 EXPECT_TRUE(completed_1); | |
163 EXPECT_TRUE(completed_2); | |
164 EXPECT_NE(cert_1, cert_2); | |
165 EXPECT_NE(key_1, key_2); | |
166 } | |
167 | |
168 TEST_F(WebRtcIdentityStoreTest, DisableCacheReturnNewIdentity) { | |
169 bool completed_1 = false; | |
170 bool completed_2 = false; | |
171 std::string cert_1, cert_2, key_1, key_2; | |
172 | |
173 base::Closure cancel_callback_1 = RequestIdentityAndRunUtilIdle( | |
174 kFakeOrigin, kFakeIdentityName1, kFakeCommonName1, &completed_1, &cert_1, | |
175 &key_1); | |
176 | |
177 base::Closure cancel_callback_2 = webrtc_identity_store_->RequestIdentity( | |
178 GURL(kFakeOrigin), kFakeIdentityName1, kFakeCommonName1, | |
179 base::Bind(&OnRequestCompleted, &completed_2, &cert_2, &key_2), | |
180 false /* enable_cache */); | |
181 EXPECT_FALSE(cancel_callback_2.is_null()); | |
182 RunUntilIdle(); | |
183 | |
184 EXPECT_TRUE(completed_1); | |
185 EXPECT_TRUE(completed_2); | |
186 EXPECT_NE(cert_1, cert_2); | |
187 EXPECT_NE(key_1, key_2); | |
188 } | |
189 | |
190 TEST_F(WebRtcIdentityStoreTest, SerialIdenticalRequests) { | |
191 bool completed_1 = false; | |
192 bool completed_2 = false; | |
193 std::string cert_1, cert_2, key_1, key_2; | |
194 | |
195 base::Closure cancel_callback_1 = | |
196 RequestIdentityAndRunUtilIdle(kFakeOrigin, | |
197 kFakeIdentityName1, | |
198 kFakeCommonName1, | |
199 &completed_1, | |
200 &cert_1, | |
201 &key_1); | |
202 | |
203 base::Closure cancel_callback_2 = | |
204 RequestIdentityAndRunUtilIdle(kFakeOrigin, | |
205 kFakeIdentityName1, | |
206 kFakeCommonName1, | |
207 &completed_2, | |
208 &cert_2, | |
209 &key_2); | |
210 | |
211 EXPECT_TRUE(completed_1); | |
212 EXPECT_TRUE(completed_2); | |
213 EXPECT_EQ(cert_1, cert_2); | |
214 EXPECT_EQ(key_1, key_2); | |
215 } | |
216 | |
217 TEST_F(WebRtcIdentityStoreTest, ConcurrentIdenticalRequestsJoined) { | |
218 bool completed_1 = false; | |
219 bool completed_2 = false; | |
220 std::string cert_1, cert_2, key_1, key_2; | |
221 | |
222 base::Closure cancel_callback_1 = webrtc_identity_store_->RequestIdentity( | |
223 GURL(kFakeOrigin), kFakeIdentityName1, kFakeCommonName1, | |
224 base::Bind(&OnRequestCompleted, &completed_1, &cert_1, &key_1), | |
225 true /* enable_cache */); | |
226 ASSERT_FALSE(cancel_callback_1.is_null()); | |
227 | |
228 base::Closure cancel_callback_2 = webrtc_identity_store_->RequestIdentity( | |
229 GURL(kFakeOrigin), kFakeIdentityName1, kFakeCommonName1, | |
230 base::Bind(&OnRequestCompleted, &completed_2, &cert_2, &key_2), | |
231 true /* enable_cache */); | |
232 ASSERT_FALSE(cancel_callback_2.is_null()); | |
233 | |
234 RunUntilIdle(); | |
235 EXPECT_TRUE(completed_1); | |
236 EXPECT_TRUE(completed_2); | |
237 EXPECT_EQ(cert_1, cert_2); | |
238 EXPECT_EQ(key_1, key_2); | |
239 } | |
240 | |
241 TEST_F(WebRtcIdentityStoreTest, CancelOneOfIdenticalRequests) { | |
242 bool completed_1 = false; | |
243 bool completed_2 = false; | |
244 std::string cert_1, cert_2, key_1, key_2; | |
245 | |
246 base::Closure cancel_callback_1 = webrtc_identity_store_->RequestIdentity( | |
247 GURL(kFakeOrigin), kFakeIdentityName1, kFakeCommonName1, | |
248 base::Bind(&OnRequestCompleted, &completed_1, &cert_1, &key_1), | |
249 true /* enable_cache */); | |
250 ASSERT_FALSE(cancel_callback_1.is_null()); | |
251 | |
252 base::Closure cancel_callback_2 = webrtc_identity_store_->RequestIdentity( | |
253 GURL(kFakeOrigin), kFakeIdentityName1, kFakeCommonName1, | |
254 base::Bind(&OnRequestCompleted, &completed_2, &cert_2, &key_2), | |
255 true /* enable_cache */); | |
256 ASSERT_FALSE(cancel_callback_2.is_null()); | |
257 | |
258 cancel_callback_1.Run(); | |
259 | |
260 RunUntilIdle(); | |
261 EXPECT_FALSE(completed_1); | |
262 EXPECT_TRUE(completed_2); | |
263 } | |
264 | |
265 TEST_F(WebRtcIdentityStoreTest, DeleteDataAndGenerateNewIdentity) { | |
266 bool completed_1 = false; | |
267 bool completed_2 = false; | |
268 std::string cert_1, cert_2, key_1, key_2; | |
269 | |
270 // Generate the first identity. | |
271 base::Closure cancel_callback_1 = | |
272 RequestIdentityAndRunUtilIdle(kFakeOrigin, | |
273 kFakeIdentityName1, | |
274 kFakeCommonName1, | |
275 &completed_1, | |
276 &cert_1, | |
277 &key_1); | |
278 | |
279 // Clear the data and the second request should return a new identity. | |
280 webrtc_identity_store_->DeleteBetween( | |
281 base::Time(), base::Time::Now(), base::Bind(&base::DoNothing)); | |
282 RunUntilIdle(); | |
283 | |
284 base::Closure cancel_callback_2 = | |
285 RequestIdentityAndRunUtilIdle(kFakeOrigin, | |
286 kFakeIdentityName1, | |
287 kFakeCommonName1, | |
288 &completed_2, | |
289 &cert_2, | |
290 &key_2); | |
291 | |
292 EXPECT_TRUE(completed_1); | |
293 EXPECT_TRUE(completed_2); | |
294 EXPECT_NE(cert_1, cert_2); | |
295 EXPECT_NE(key_1, key_2); | |
296 } | |
297 | |
298 TEST_F(WebRtcIdentityStoreTest, ExpiredIdentityDeleted) { | |
299 // The identities will expire immediately after creation. | |
300 SetValidityPeriod(base::TimeDelta::FromMilliseconds(0)); | |
301 | |
302 bool completed_1 = false; | |
303 bool completed_2 = false; | |
304 std::string cert_1, cert_2, key_1, key_2; | |
305 | |
306 base::Closure cancel_callback_1 = | |
307 RequestIdentityAndRunUtilIdle(kFakeOrigin, | |
308 kFakeIdentityName1, | |
309 kFakeCommonName1, | |
310 &completed_1, | |
311 &cert_1, | |
312 &key_1); | |
313 EXPECT_TRUE(completed_1); | |
314 | |
315 // Check that the old identity is not returned. | |
316 base::Closure cancel_callback_2 = | |
317 RequestIdentityAndRunUtilIdle(kFakeOrigin, | |
318 kFakeIdentityName1, | |
319 kFakeCommonName1, | |
320 &completed_2, | |
321 &cert_2, | |
322 &key_2); | |
323 EXPECT_TRUE(completed_2); | |
324 EXPECT_NE(cert_1, cert_2); | |
325 EXPECT_NE(key_1, key_2); | |
326 } | |
327 | |
328 TEST_F(WebRtcIdentityStoreTest, IdentityPersistentAcrossRestart) { | |
329 base::ScopedTempDir temp_dir; | |
330 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); | |
331 Restart(temp_dir.path()); | |
332 | |
333 bool completed_1 = false; | |
334 bool completed_2 = false; | |
335 std::string cert_1, cert_2, key_1, key_2; | |
336 | |
337 // Creates an identity. | |
338 base::Closure cancel_callback_1 = | |
339 RequestIdentityAndRunUtilIdle(kFakeOrigin, | |
340 kFakeIdentityName1, | |
341 kFakeCommonName1, | |
342 &completed_1, | |
343 &cert_1, | |
344 &key_1); | |
345 EXPECT_TRUE(completed_1); | |
346 | |
347 Restart(temp_dir.path()); | |
348 | |
349 // Check that the same identity is returned after the restart. | |
350 base::Closure cancel_callback_2 = | |
351 RequestIdentityAndRunUtilIdle(kFakeOrigin, | |
352 kFakeIdentityName1, | |
353 kFakeCommonName1, | |
354 &completed_2, | |
355 &cert_2, | |
356 &key_2); | |
357 EXPECT_TRUE(completed_2); | |
358 EXPECT_EQ(cert_1, cert_2); | |
359 EXPECT_EQ(key_1, key_2); | |
360 Stop(); | |
361 } | |
362 | |
363 TEST_F(WebRtcIdentityStoreTest, HandleDBErrors) { | |
364 base::ScopedTempDir temp_dir; | |
365 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); | |
366 Restart(temp_dir.path()); | |
367 | |
368 bool completed_1 = false; | |
369 std::string cert_1, key_1; | |
370 | |
371 // Creates an identity. | |
372 RequestIdentityAndRunUtilIdle(kFakeOrigin, | |
373 kFakeIdentityName1, | |
374 kFakeCommonName1, | |
375 &completed_1, | |
376 &cert_1, | |
377 &key_1); | |
378 | |
379 // Make the table corrupted. | |
380 base::FilePath db_path = | |
381 temp_dir.path().Append(FILE_PATH_LITERAL("WebRTCIdentityStore")); | |
382 EXPECT_TRUE(sql::test::CorruptSizeInHeader(db_path)); | |
383 | |
384 // Reset to commit the DB changes, which should fail and not crash. | |
385 webrtc_identity_store_ = NULL; | |
386 RunUntilIdle(); | |
387 | |
388 // Verifies the corrupted table was razed. | |
389 std::unique_ptr<sql::Connection> db(new sql::Connection()); | |
390 EXPECT_TRUE(db->Open(db_path)); | |
391 EXPECT_EQ(0U, sql::test::CountSQLTables(db.get())); | |
392 | |
393 Stop(); | |
394 } | |
395 | |
396 } // namespace content | |
OLD | NEW |