Chromium Code Reviews| Index: talk/app/webrtc/peerconnection_unittest.cc | 
| diff --git a/talk/app/webrtc/peerconnection_unittest.cc b/talk/app/webrtc/peerconnection_unittest.cc | 
| index 6dc83a575132d889462568b9f5abd6b8b6e4fab8..9f387b37e9c6ef04f361e7e3461f4b773f15a802 100644 | 
| --- a/talk/app/webrtc/peerconnection_unittest.cc | 
| +++ b/talk/app/webrtc/peerconnection_unittest.cc | 
| @@ -144,18 +144,26 @@ class PeerConnectionTestClient : public webrtc::PeerConnectionObserver, | 
| public SignalingMessageReceiver, | 
| public ObserverInterface { | 
| public: | 
| - static PeerConnectionTestClient* CreateClient( | 
| + static PeerConnectionTestClient* CreateClientWithKeySpecified( | 
| const std::string& id, | 
| const MediaConstraintsInterface* constraints, | 
| - const PeerConnectionFactory::Options* options) { | 
| + const PeerConnectionFactory::Options* options, | 
| + bool use_alternate_key) { | 
| 
 
pthatcher1
2015/11/30 20:23:10
Why not just CreateClientWithAlternateKey and then
 
guoweis_webrtc
2015/12/01 22:05:12
I think this will duplicate the code in this funct
 
 | 
| PeerConnectionTestClient* client(new PeerConnectionTestClient(id)); | 
| - if (!client->Init(constraints, options)) { | 
| + if (!client->Init(constraints, options, use_alternate_key)) { | 
| delete client; | 
| return nullptr; | 
| } | 
| return client; | 
| } | 
| + static PeerConnectionTestClient* CreateClient( | 
| + const std::string& id, | 
| + const MediaConstraintsInterface* constraints, | 
| + const PeerConnectionFactory::Options* options) { | 
| + return CreateClientWithKeySpecified(id, constraints, options, false); | 
| + } | 
| + | 
| ~PeerConnectionTestClient() { | 
| while (!fake_video_renderers_.empty()) { | 
| RenderMap::iterator it = fake_video_renderers_.begin(); | 
| @@ -686,7 +694,8 @@ class PeerConnectionTestClient : public webrtc::PeerConnectionObserver, | 
| explicit PeerConnectionTestClient(const std::string& id) : id_(id) {} | 
| bool Init(const MediaConstraintsInterface* constraints, | 
| - const PeerConnectionFactory::Options* options) { | 
| + const PeerConnectionFactory::Options* options, | 
| + bool use_alternate_key) { | 
| EXPECT_TRUE(!peer_connection_); | 
| EXPECT_TRUE(!peer_connection_factory_); | 
| allocator_factory_ = webrtc::FakePortAllocatorFactory::Create(); | 
| @@ -711,7 +720,7 @@ class PeerConnectionTestClient : public webrtc::PeerConnectionObserver, | 
| peer_connection_factory_->SetOptions(*options); | 
| } | 
| peer_connection_ = CreatePeerConnection(allocator_factory_.get(), | 
| - constraints); | 
| + constraints, use_alternate_key); | 
| return peer_connection_.get() != nullptr; | 
| } | 
| @@ -733,16 +742,23 @@ class PeerConnectionTestClient : public webrtc::PeerConnectionObserver, | 
| rtc::scoped_refptr<webrtc::PeerConnectionInterface> CreatePeerConnection( | 
| webrtc::PortAllocatorFactoryInterface* factory, | 
| - const MediaConstraintsInterface* constraints) { | 
| + const MediaConstraintsInterface* constraints, | 
| + bool use_alternate_key) { | 
| // CreatePeerConnection with IceServers. | 
| webrtc::PeerConnectionInterface::IceServers ice_servers; | 
| webrtc::PeerConnectionInterface::IceServer ice_server; | 
| ice_server.uri = "stun:stun.l.google.com:19302"; | 
| ice_servers.push_back(ice_server); | 
| - rtc::scoped_ptr<webrtc::DtlsIdentityStoreInterface> dtls_identity_store( | 
| + rtc::scoped_ptr<FakeDtlsIdentityStore> dtls_identity_store( | 
| rtc::SSLStreamAdapter::HaveDtlsSrtp() ? new FakeDtlsIdentityStore() | 
| : nullptr); | 
| + | 
| + if (use_alternate_key) { | 
| + dtls_identity_store->use_alternate_key(); | 
| + } else { | 
| + dtls_identity_store->use_original_key(); | 
| + } | 
| return peer_connection_factory_->CreatePeerConnection( | 
| ice_servers, constraints, factory, dtls_identity_store.Pass(), this); | 
| } | 
| @@ -966,6 +982,11 @@ class MAYBE_JsepPeerConnectionP2PTestClient : public testing::Test { | 
| if (receiving_client_) { | 
| receiving_client_->set_signaling_message_receiver(nullptr); | 
| } | 
| + // The clients have to be explicitly closed. Otherwise, they will be | 
| + // disposed after VirtualSocketServer which they still have dependency | 
| + // during the destructing time. | 
| 
 
pthatcher1
2015/11/30 20:23:11
which => on which
dependency => a dependency
durin
 
guoweis_webrtc
2015/12/01 22:05:12
Done.
 
 | 
| + initiating_client_->pc()->Close(); | 
| + receiving_client_->pc()->Close(); | 
| } | 
| bool CreateTestClients() { return CreateTestClients(nullptr, nullptr); } | 
| @@ -976,6 +997,11 @@ class MAYBE_JsepPeerConnectionP2PTestClient : public testing::Test { | 
| nullptr); | 
| } | 
| + void SetSignalingReceivers() { | 
| + initiating_client_->set_signaling_message_receiver(receiving_client_.get()); | 
| + receiving_client_->set_signaling_message_receiver(initiating_client_.get()); | 
| + } | 
| + | 
| bool CreateTestClients(MediaConstraintsInterface* init_constraints, | 
| PeerConnectionFactory::Options* init_options, | 
| MediaConstraintsInterface* recv_constraints, | 
| @@ -987,8 +1013,7 @@ class MAYBE_JsepPeerConnectionP2PTestClient : public testing::Test { | 
| if (!initiating_client_ || !receiving_client_) { | 
| return false; | 
| } | 
| - initiating_client_->set_signaling_message_receiver(receiving_client_.get()); | 
| - receiving_client_->set_signaling_message_receiver(initiating_client_.get()); | 
| + SetSignalingReceivers(); | 
| return true; | 
| } | 
| @@ -1066,6 +1091,26 @@ class MAYBE_JsepPeerConnectionP2PTestClient : public testing::Test { | 
| kMaxWaitForFramesMs); | 
| } | 
| + void SetupAndVerifyDtlsCall() { | 
| + MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp); | 
| + FakeConstraints setup_constraints; | 
| + setup_constraints.AddMandatory(MediaConstraintsInterface::kEnableDtlsSrtp, | 
| + true); | 
| + ASSERT_TRUE(CreateTestClients(&setup_constraints, &setup_constraints)); | 
| + LocalP2PTest(); | 
| + VerifyRenderedSize(640, 480); | 
| + } | 
| + | 
| + PeerConnectionTestClient* CreateDtlsClientWithAlternateKey() { | 
| + FakeConstraints setup_constraints; | 
| + setup_constraints.AddMandatory(MediaConstraintsInterface::kEnableDtlsSrtp, | 
| + true); | 
| + | 
| + // Make sure the new client is using a different certificate. | 
| + return PeerConnectionTestClient::CreateClientWithKeySpecified( | 
| + "New Peer: ", &setup_constraints, nullptr, true); | 
| + } | 
| + | 
| void SendRtpData(webrtc::DataChannelInterface* dc, const std::string& data) { | 
| // Messages may get lost on the unreliable DataChannel, so we send multiple | 
| // times to avoid test flakiness. | 
| @@ -1079,16 +1124,37 @@ class MAYBE_JsepPeerConnectionP2PTestClient : public testing::Test { | 
| PeerConnectionTestClient* initializing_client() { | 
| return initiating_client_.get(); | 
| } | 
| + | 
| + // Reset the |initiating_client_| to the |client| passed in and return the | 
| + // original |initiating_client_|. | 
| + PeerConnectionTestClient* swap_initializing_client( | 
| + PeerConnectionTestClient* client) { | 
| + PeerConnectionTestClient* old = initiating_client_.release(); | 
| + initiating_client_.reset(client); | 
| + return old; | 
| + } | 
| 
 
pthatcher1
2015/11/30 20:23:11
These two methods aren't used any more.
 
guoweis_webrtc
2015/12/01 22:05:12
Done.
 
 | 
| + | 
| PeerConnectionTestClient* receiving_client() { | 
| return receiving_client_.get(); | 
| } | 
| + // Reset the |receiving_client_| to the |client| passed in and return the | 
| + // original |receiving_client_|. | 
| + PeerConnectionTestClient* swap_receiving_client( | 
| + PeerConnectionTestClient* client) { | 
| + PeerConnectionTestClient* old = receiving_client_.release(); | 
| + receiving_client_.reset(client); | 
| + return old; | 
| + } | 
| + | 
| + protected: | 
| + rtc::scoped_ptr<PeerConnectionTestClient> initiating_client_; | 
| + rtc::scoped_ptr<PeerConnectionTestClient> receiving_client_; | 
| 
 
pthatcher1
2015/11/30 20:23:10
Usually, we leave "foo_" members private and then
 
guoweis_webrtc
2015/12/01 22:05:12
but we'll be doing this
foo() = new client():
Un
 
pthatcher1
2015/12/01 23:29:34
Then add set_foo and use it: set_foo(new_client())
 
 | 
| + | 
| private: | 
| rtc::scoped_ptr<rtc::PhysicalSocketServer> pss_; | 
| rtc::scoped_ptr<rtc::VirtualSocketServer> ss_; | 
| rtc::SocketServerScope ss_scope_; | 
| - rtc::scoped_ptr<PeerConnectionTestClient> initiating_client_; | 
| - rtc::scoped_ptr<PeerConnectionTestClient> receiving_client_; | 
| }; | 
| // Disable for TSan v2, see | 
| @@ -1144,13 +1210,7 @@ TEST_F(MAYBE_JsepPeerConnectionP2PTestClient, DISABLED_LocalP2PTest1280By720) { | 
| // This test sets up a call between two endpoints that are configured to use | 
| // DTLS key agreement. As a result, DTLS is negotiated and used for transport. | 
| TEST_F(MAYBE_JsepPeerConnectionP2PTestClient, LocalP2PTestDtls) { | 
| - MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp); | 
| - FakeConstraints setup_constraints; | 
| - setup_constraints.AddMandatory(MediaConstraintsInterface::kEnableDtlsSrtp, | 
| - true); | 
| - ASSERT_TRUE(CreateTestClients(&setup_constraints, &setup_constraints)); | 
| - LocalP2PTest(); | 
| - VerifyRenderedSize(640, 480); | 
| + SetupAndVerifyDtlsCall(); | 
| } | 
| // This test sets up a audio call initially and then upgrades to audio/video, | 
| @@ -1167,6 +1227,42 @@ TEST_F(MAYBE_JsepPeerConnectionP2PTestClient, LocalP2PTestDtlsRenegotiate) { | 
| receiving_client()->Negotiate(); | 
| } | 
| +// This test sets up a call transfer to a new caller with a different DTLS | 
| +// fingerprint. | 
| +TEST_F(MAYBE_JsepPeerConnectionP2PTestClient, LocalP2PTestDtlsTransferCallee) { | 
| + MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp); | 
| + SetupAndVerifyDtlsCall(); | 
| + | 
| + // Keeping the original peer around which will still send packets to the | 
| + // receiving client. These SRTP packets will be dropped. | 
| + rtc::scoped_ptr<PeerConnectionTestClient> original_peer( | 
| + initiating_client_.release()); | 
| + initiating_client_.reset(CreateDtlsClientWithAlternateKey()); | 
| + | 
| + SetSignalingReceivers(); | 
| + receiving_client()->SetExpectIceRestart(true); | 
| + LocalP2PTest(); | 
| + VerifyRenderedSize(640, 480); | 
| +} | 
| + | 
| +// This test sets up a call transfer to a new callee with a different DTLS | 
| +// fingerprint. | 
| +TEST_F(MAYBE_JsepPeerConnectionP2PTestClient, LocalP2PTestDtlsTransferCaller) { | 
| + MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp); | 
| + SetupAndVerifyDtlsCall(); | 
| + | 
| + // Keeping the original peer around which will still send packets to the | 
| + // receiving client. These SRTP packets will be dropped. | 
| + rtc::scoped_ptr<PeerConnectionTestClient> original_peer( | 
| + receiving_client_.release()); | 
| + receiving_client_.reset(CreateDtlsClientWithAlternateKey()); | 
| + | 
| + SetSignalingReceivers(); | 
| + initializing_client()->IceRestart(); | 
| 
 
pthatcher1
2015/11/30 20:23:10
It looks like we are testing the scenario where IC
 
guoweis_webrtc
2015/12/01 22:05:12
Can we do that? Since we don't do DTLS rekeying, I
 
pthatcher1
2015/12/01 23:29:34
Yeah, good point.  In ORTC land, we disallow there
 
 | 
| + LocalP2PTest(); | 
| + VerifyRenderedSize(640, 480); | 
| +} | 
| + | 
| // This test sets up a call between two endpoints that are configured to use | 
| // DTLS key agreement. The offerer don't support SDES. As a result, DTLS is | 
| // negotiated and used for transport. |