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 "base/bind.h" 6 #include "base/memory/scoped_ptr.h" 7 #include "base/test/sequenced_worker_pool_owner.h" 8 #include "content/browser/media/webrtc_identity_store.h" 9 #include "content/public/test/test_browser_thread_bundle.h" 10 #include "content/public/test/test_utils.h" 11 #include "net/base/net_errors.h" 12 #include "testing/gtest/include/gtest/gtest.h" 13 #include "url/gurl.h" 14 15 namespace content { 16 17 // TODO(jiayl): the tests fail on Android since the openssl version of 18 // CreateSelfSignedCert is not implemented. We should mock out this dependency 19 // and remove the if-defined. 20 #if !defined(OS_ANDROID) 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 virtual ~WebRTCIdentityStoreTest() { 55 pool_owner_->pool()->Shutdown(); 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), 73 identity_name, 74 common_name, 75 base::Bind(&OnRequestCompleted, completed, certificate, private_key)); 76 EXPECT_FALSE(cancel_callback.is_null()); 77 RunUntilIdle(); 78 return cancel_callback; 79 } 80 81 protected: 82 TestBrowserThreadBundle browser_thread_bundle_; 83 scoped_ptr<base::SequencedWorkerPoolOwner> pool_owner_; 84 scoped_refptr<WebRTCIdentityStore> webrtc_identity_store_; 85 }; 86 87 TEST_F(WebRTCIdentityStoreTest, RequestIdentity) { 88 bool completed = false; 89 std::string dummy; 90 base::Closure cancel_callback = 91 RequestIdentityAndRunUtilIdle(kFakeOrigin, 92 kFakeIdentityName1, 93 kFakeCommonName1, 94 &completed, 95 &dummy, 96 &dummy); 97 EXPECT_TRUE(completed); 98 } 99 100 TEST_F(WebRTCIdentityStoreTest, CancelRequest) { 101 bool completed = false; 102 std::string dummy; 103 base::Closure cancel_callback = webrtc_identity_store_->RequestIdentity( 104 GURL(kFakeOrigin), 105 kFakeIdentityName1, 106 kFakeCommonName1, 107 base::Bind(&OnRequestCompleted, &completed, &dummy, &dummy)); 108 ASSERT_FALSE(cancel_callback.is_null()); 109 cancel_callback.Run(); 110 111 RunUntilIdle(); 112 EXPECT_FALSE(completed); 113 } 114 115 TEST_F(WebRTCIdentityStoreTest, ConcurrentUniqueRequests) { 116 bool completed_1 = false; 117 bool completed_2 = false; 118 std::string dummy; 119 base::Closure cancel_callback_1 = webrtc_identity_store_->RequestIdentity( 120 GURL(kFakeOrigin), 121 kFakeIdentityName1, 122 kFakeCommonName1, 123 base::Bind(&OnRequestCompleted, &completed_1, &dummy, &dummy)); 124 ASSERT_FALSE(cancel_callback_1.is_null()); 125 126 base::Closure cancel_callback_2 = webrtc_identity_store_->RequestIdentity( 127 GURL(kFakeOrigin), 128 kFakeIdentityName2, 129 kFakeCommonName1, 130 base::Bind(&OnRequestCompleted, &completed_2, &dummy, &dummy)); 131 ASSERT_FALSE(cancel_callback_2.is_null()); 132 133 RunUntilIdle(); 134 EXPECT_TRUE(completed_1); 135 EXPECT_TRUE(completed_2); 136 } 137 138 TEST_F(WebRTCIdentityStoreTest, DifferentCommonNameReturnNewIdentity) { 139 bool completed_1 = false; 140 bool completed_2 = false; 141 std::string cert_1, cert_2, key_1, key_2; 142 143 base::Closure cancel_callback_1 = 144 RequestIdentityAndRunUtilIdle(kFakeOrigin, 145 kFakeIdentityName1, 146 kFakeCommonName1, 147 &completed_1, 148 &cert_1, 149 &key_1); 150 151 base::Closure cancel_callback_2 = 152 RequestIdentityAndRunUtilIdle(kFakeOrigin, 153 kFakeIdentityName1, 154 kFakeCommonName2, 155 &completed_2, 156 &cert_2, 157 &key_2); 158 159 EXPECT_TRUE(completed_1); 160 EXPECT_TRUE(completed_2); 161 EXPECT_NE(cert_1, cert_2); 162 EXPECT_NE(key_1, key_2); 163 } 164 165 TEST_F(WebRTCIdentityStoreTest, SerialIdenticalRequests) { 166 bool completed_1 = false; 167 bool completed_2 = false; 168 std::string cert_1, cert_2, key_1, key_2; 169 170 base::Closure cancel_callback_1 = 171 RequestIdentityAndRunUtilIdle(kFakeOrigin, 172 kFakeIdentityName1, 173 kFakeCommonName1, 174 &completed_1, 175 &cert_1, 176 &key_1); 177 178 base::Closure cancel_callback_2 = 179 RequestIdentityAndRunUtilIdle(kFakeOrigin, 180 kFakeIdentityName1, 181 kFakeCommonName1, 182 &completed_2, 183 &cert_2, 184 &key_2); 185 186 EXPECT_TRUE(completed_1); 187 EXPECT_TRUE(completed_2); 188 EXPECT_EQ(cert_1, cert_2); 189 EXPECT_EQ(key_1, key_2); 190 } 191 192 TEST_F(WebRTCIdentityStoreTest, ConcurrentIdenticalRequestsJoined) { 193 bool completed_1 = false; 194 bool completed_2 = false; 195 std::string cert_1, cert_2, key_1, key_2; 196 197 base::Closure cancel_callback_1 = webrtc_identity_store_->RequestIdentity( 198 GURL(kFakeOrigin), 199 kFakeIdentityName1, 200 kFakeCommonName1, 201 base::Bind(&OnRequestCompleted, &completed_1, &cert_1, &key_1)); 202 ASSERT_FALSE(cancel_callback_1.is_null()); 203 204 base::Closure cancel_callback_2 = webrtc_identity_store_->RequestIdentity( 205 GURL(kFakeOrigin), 206 kFakeIdentityName1, 207 kFakeCommonName1, 208 base::Bind(&OnRequestCompleted, &completed_2, &cert_2, &key_2)); 209 ASSERT_FALSE(cancel_callback_2.is_null()); 210 211 RunUntilIdle(); 212 EXPECT_TRUE(completed_1); 213 EXPECT_TRUE(completed_2); 214 EXPECT_EQ(cert_1, cert_2); 215 EXPECT_EQ(key_1, key_2); 216 } 217 218 TEST_F(WebRTCIdentityStoreTest, CancelOneOfIdenticalRequests) { 219 bool completed_1 = false; 220 bool completed_2 = false; 221 std::string cert_1, cert_2, key_1, key_2; 222 223 base::Closure cancel_callback_1 = webrtc_identity_store_->RequestIdentity( 224 GURL(kFakeOrigin), 225 kFakeIdentityName1, 226 kFakeCommonName1, 227 base::Bind(&OnRequestCompleted, &completed_1, &cert_1, &key_1)); 228 ASSERT_FALSE(cancel_callback_1.is_null()); 229 230 base::Closure cancel_callback_2 = webrtc_identity_store_->RequestIdentity( 231 GURL(kFakeOrigin), 232 kFakeIdentityName1, 233 kFakeCommonName1, 234 base::Bind(&OnRequestCompleted, &completed_2, &cert_2, &key_2)); 235 ASSERT_FALSE(cancel_callback_2.is_null()); 236 237 cancel_callback_1.Run(); 238 239 RunUntilIdle(); 240 EXPECT_FALSE(completed_1); 241 EXPECT_TRUE(completed_2); 242 } 243 244 TEST_F(WebRTCIdentityStoreTest, DeleteDataAndGenerateNewIdentity) { 245 bool completed_1 = false; 246 bool completed_2 = false; 247 std::string cert_1, cert_2, key_1, key_2; 248 249 // Generate the first identity. 250 base::Closure cancel_callback_1 = 251 RequestIdentityAndRunUtilIdle(kFakeOrigin, 252 kFakeIdentityName1, 253 kFakeCommonName1, 254 &completed_1, 255 &cert_1, 256 &key_1); 257 258 // Clear the data and the second request should return a new identity. 259 webrtc_identity_store_->DeleteBetween( 260 base::Time(), base::Time::Now(), base::Bind(&base::DoNothing)); 261 RunUntilIdle(); 262 263 base::Closure cancel_callback_2 = 264 RequestIdentityAndRunUtilIdle(kFakeOrigin, 265 kFakeIdentityName1, 266 kFakeCommonName1, 267 &completed_2, 268 &cert_2, 269 &key_2); 270 271 EXPECT_TRUE(completed_1); 272 EXPECT_TRUE(completed_2); 273 EXPECT_NE(cert_1, cert_2); 274 EXPECT_NE(key_1, key_2); 275 } 276 277 #endif 278 } // namespace content 279