blob: 81c25d7f63f76281b3e4181c89f18e47fd2e065a [file] [log] [blame]
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/bind.h"
#include "base/memory/scoped_ptr.h"
#include "base/test/sequenced_worker_pool_owner.h"
#include "content/browser/media/webrtc_identity_store.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/test_utils.h"
#include "net/base/net_errors.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
namespace content {
// TODO(jiayl): the tests fail on Android since the openssl version of
// CreateSelfSignedCert is not implemented. We should mock out this dependency
// and remove the if-defined.
#if !defined(OS_ANDROID)
static const char* kFakeOrigin = "http://foo.com";
static const char* kFakeIdentityName1 = "name1";
static const char* kFakeIdentityName2 = "name2";
static const char* kFakeCommonName1 = "cname1";
static const char* kFakeCommonName2 = "cname2";
static void OnRequestCompleted(bool* completed,
std::string* out_cert,
std::string* out_key,
int error,
const std::string& certificate,
const std::string& private_key) {
ASSERT_EQ(net::OK, error);
ASSERT_NE("", certificate);
ASSERT_NE("", private_key);
*completed = true;
*out_cert = certificate;
*out_key = private_key;
}
class WebRTCIdentityStoreTest : public testing::Test {
public:
WebRTCIdentityStoreTest()
: browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP |
TestBrowserThreadBundle::REAL_DB_THREAD),
pool_owner_(
new base::SequencedWorkerPoolOwner(3, "WebRTCIdentityStoreTest")),
webrtc_identity_store_(
new WebRTCIdentityStore(base::FilePath(), NULL)) {
webrtc_identity_store_->SetTaskRunnerForTesting(pool_owner_->pool());
}
virtual ~WebRTCIdentityStoreTest() {
pool_owner_->pool()->Shutdown();
}
void RunUntilIdle() {
RunAllPendingInMessageLoop(BrowserThread::DB);
RunAllPendingInMessageLoop(BrowserThread::IO);
pool_owner_->pool()->FlushForTesting();
base::RunLoop().RunUntilIdle();
}
base::Closure RequestIdentityAndRunUtilIdle(const std::string& origin,
const std::string& identity_name,
const std::string& common_name,
bool* completed,
std::string* certificate,
std::string* private_key) {
base::Closure cancel_callback = webrtc_identity_store_->RequestIdentity(
GURL(origin),
identity_name,
common_name,
base::Bind(&OnRequestCompleted, completed, certificate, private_key));
EXPECT_FALSE(cancel_callback.is_null());
RunUntilIdle();
return cancel_callback;
}
protected:
TestBrowserThreadBundle browser_thread_bundle_;
scoped_ptr<base::SequencedWorkerPoolOwner> pool_owner_;
scoped_refptr<WebRTCIdentityStore> webrtc_identity_store_;
};
TEST_F(WebRTCIdentityStoreTest, RequestIdentity) {
bool completed = false;
std::string dummy;
base::Closure cancel_callback =
RequestIdentityAndRunUtilIdle(kFakeOrigin,
kFakeIdentityName1,
kFakeCommonName1,
&completed,
&dummy,
&dummy);
EXPECT_TRUE(completed);
}
TEST_F(WebRTCIdentityStoreTest, CancelRequest) {
bool completed = false;
std::string dummy;
base::Closure cancel_callback = webrtc_identity_store_->RequestIdentity(
GURL(kFakeOrigin),
kFakeIdentityName1,
kFakeCommonName1,
base::Bind(&OnRequestCompleted, &completed, &dummy, &dummy));
ASSERT_FALSE(cancel_callback.is_null());
cancel_callback.Run();
RunUntilIdle();
EXPECT_FALSE(completed);
}
TEST_F(WebRTCIdentityStoreTest, ConcurrentUniqueRequests) {
bool completed_1 = false;
bool completed_2 = false;
std::string dummy;
base::Closure cancel_callback_1 = webrtc_identity_store_->RequestIdentity(
GURL(kFakeOrigin),
kFakeIdentityName1,
kFakeCommonName1,
base::Bind(&OnRequestCompleted, &completed_1, &dummy, &dummy));
ASSERT_FALSE(cancel_callback_1.is_null());
base::Closure cancel_callback_2 = webrtc_identity_store_->RequestIdentity(
GURL(kFakeOrigin),
kFakeIdentityName2,
kFakeCommonName1,
base::Bind(&OnRequestCompleted, &completed_2, &dummy, &dummy));
ASSERT_FALSE(cancel_callback_2.is_null());
RunUntilIdle();
EXPECT_TRUE(completed_1);
EXPECT_TRUE(completed_2);
}
TEST_F(WebRTCIdentityStoreTest, DifferentCommonNameReturnNewIdentity) {
bool completed_1 = false;
bool completed_2 = false;
std::string cert_1, cert_2, key_1, key_2;
base::Closure cancel_callback_1 =
RequestIdentityAndRunUtilIdle(kFakeOrigin,
kFakeIdentityName1,
kFakeCommonName1,
&completed_1,
&cert_1,
&key_1);
base::Closure cancel_callback_2 =
RequestIdentityAndRunUtilIdle(kFakeOrigin,
kFakeIdentityName1,
kFakeCommonName2,
&completed_2,
&cert_2,
&key_2);
EXPECT_TRUE(completed_1);
EXPECT_TRUE(completed_2);
EXPECT_NE(cert_1, cert_2);
EXPECT_NE(key_1, key_2);
}
TEST_F(WebRTCIdentityStoreTest, SerialIdenticalRequests) {
bool completed_1 = false;
bool completed_2 = false;
std::string cert_1, cert_2, key_1, key_2;
base::Closure cancel_callback_1 =
RequestIdentityAndRunUtilIdle(kFakeOrigin,
kFakeIdentityName1,
kFakeCommonName1,
&completed_1,
&cert_1,
&key_1);
base::Closure cancel_callback_2 =
RequestIdentityAndRunUtilIdle(kFakeOrigin,
kFakeIdentityName1,
kFakeCommonName1,
&completed_2,
&cert_2,
&key_2);
EXPECT_TRUE(completed_1);
EXPECT_TRUE(completed_2);
EXPECT_EQ(cert_1, cert_2);
EXPECT_EQ(key_1, key_2);
}
TEST_F(WebRTCIdentityStoreTest, ConcurrentIdenticalRequestsJoined) {
bool completed_1 = false;
bool completed_2 = false;
std::string cert_1, cert_2, key_1, key_2;
base::Closure cancel_callback_1 = webrtc_identity_store_->RequestIdentity(
GURL(kFakeOrigin),
kFakeIdentityName1,
kFakeCommonName1,
base::Bind(&OnRequestCompleted, &completed_1, &cert_1, &key_1));
ASSERT_FALSE(cancel_callback_1.is_null());
base::Closure cancel_callback_2 = webrtc_identity_store_->RequestIdentity(
GURL(kFakeOrigin),
kFakeIdentityName1,
kFakeCommonName1,
base::Bind(&OnRequestCompleted, &completed_2, &cert_2, &key_2));
ASSERT_FALSE(cancel_callback_2.is_null());
RunUntilIdle();
EXPECT_TRUE(completed_1);
EXPECT_TRUE(completed_2);
EXPECT_EQ(cert_1, cert_2);
EXPECT_EQ(key_1, key_2);
}
TEST_F(WebRTCIdentityStoreTest, CancelOneOfIdenticalRequests) {
bool completed_1 = false;
bool completed_2 = false;
std::string cert_1, cert_2, key_1, key_2;
base::Closure cancel_callback_1 = webrtc_identity_store_->RequestIdentity(
GURL(kFakeOrigin),
kFakeIdentityName1,
kFakeCommonName1,
base::Bind(&OnRequestCompleted, &completed_1, &cert_1, &key_1));
ASSERT_FALSE(cancel_callback_1.is_null());
base::Closure cancel_callback_2 = webrtc_identity_store_->RequestIdentity(
GURL(kFakeOrigin),
kFakeIdentityName1,
kFakeCommonName1,
base::Bind(&OnRequestCompleted, &completed_2, &cert_2, &key_2));
ASSERT_FALSE(cancel_callback_2.is_null());
cancel_callback_1.Run();
RunUntilIdle();
EXPECT_FALSE(completed_1);
EXPECT_TRUE(completed_2);
}
TEST_F(WebRTCIdentityStoreTest, DeleteDataAndGenerateNewIdentity) {
bool completed_1 = false;
bool completed_2 = false;
std::string cert_1, cert_2, key_1, key_2;
// Generate the first identity.
base::Closure cancel_callback_1 =
RequestIdentityAndRunUtilIdle(kFakeOrigin,
kFakeIdentityName1,
kFakeCommonName1,
&completed_1,
&cert_1,
&key_1);
// Clear the data and the second request should return a new identity.
webrtc_identity_store_->DeleteBetween(
base::Time(), base::Time::Now(), base::Bind(&base::DoNothing));
RunUntilIdle();
base::Closure cancel_callback_2 =
RequestIdentityAndRunUtilIdle(kFakeOrigin,
kFakeIdentityName1,
kFakeCommonName1,
&completed_2,
&cert_2,
&key_2);
EXPECT_TRUE(completed_1);
EXPECT_TRUE(completed_2);
EXPECT_NE(cert_1, cert_2);
EXPECT_NE(key_1, key_2);
}
#endif
} // namespace content