Index: webrtc/p2p/base/p2ptransportchannel_unittest.cc |
diff --git a/webrtc/p2p/base/p2ptransportchannel_unittest.cc b/webrtc/p2p/base/p2ptransportchannel_unittest.cc |
index f6beee07bfa8b5e6edd616350fa6cb9526fce8b5..13f19ae0a54272cb39fb7786162dc761e7277e9a 100644 |
--- a/webrtc/p2p/base/p2ptransportchannel_unittest.cc |
+++ b/webrtc/p2p/base/p2ptransportchannel_unittest.cc |
@@ -1700,19 +1700,20 @@ TEST_F(P2PTransportChannelMultihomedTest, TestDrain) { |
DestroyChannels(); |
} |
-class P2PTransportChannelPingOrderTest : public testing::Test, |
- public sigslot::has_slots<> { |
+// A collection of tests which tests a single P2PTransportChannel by sending |
+// pings. |
+class P2PTransportChannelPingTest : public testing::Test, |
+ public sigslot::has_slots<> { |
public: |
- P2PTransportChannelPingOrderTest() : |
- pss_(new rtc::PhysicalSocketServer), |
- vss_(new rtc::VirtualSocketServer(pss_.get())), |
- ss_scope_(vss_.get()) { |
- } |
+ P2PTransportChannelPingTest() |
+ : pss_(new rtc::PhysicalSocketServer), |
+ vss_(new rtc::VirtualSocketServer(pss_.get())), |
+ ss_scope_(vss_.get()) {} |
protected: |
void PrepareChannel(cricket::P2PTransportChannel* ch) { |
ch->SignalRequestSignaling.connect( |
- this, &P2PTransportChannelPingOrderTest::OnChannelRequestSignaling); |
+ this, &P2PTransportChannelPingTest::OnChannelRequestSignaling); |
ch->SetIceProtocolType(cricket::ICEPROTO_RFC5245); |
ch->SetIceRole(cricket::ICEROLE_CONTROLLING); |
ch->SetIceCredentials(kIceUfrag[0], kIcePwd[0]); |
@@ -1741,13 +1742,17 @@ class P2PTransportChannelPingOrderTest : public testing::Test, |
return GetConnectionTo(ch, ip, port_num); |
} |
- cricket::Connection* GetConnectionTo(cricket::P2PTransportChannel* ch, |
- const std::string& ip, |
- int port_num) { |
+ cricket::Port* GetPort(cricket::P2PTransportChannel* ch) { |
if (ch->ports().empty()) { |
return nullptr; |
} |
- cricket::Port* port = static_cast<cricket::Port*>(ch->ports()[0]); |
+ return static_cast<cricket::Port*>(ch->ports()[0]); |
+ } |
+ |
+ cricket::Connection* GetConnectionTo(cricket::P2PTransportChannel* ch, |
+ const std::string& ip, |
+ int port_num) { |
+ cricket::Port* port = GetPort(ch); |
if (!port) { |
return nullptr; |
} |
@@ -1760,7 +1765,7 @@ class P2PTransportChannelPingOrderTest : public testing::Test, |
rtc::SocketServerScope ss_scope_; |
}; |
-TEST_F(P2PTransportChannelPingOrderTest, TestTriggeredChecks) { |
+TEST_F(P2PTransportChannelPingTest, TestTriggeredChecks) { |
cricket::FakePortAllocator pa(rtc::Thread::Current(), nullptr); |
cricket::P2PTransportChannel ch("trigger checks", 1, nullptr, &pa); |
PrepareChannel(&ch); |
@@ -1784,7 +1789,7 @@ TEST_F(P2PTransportChannelPingOrderTest, TestTriggeredChecks) { |
EXPECT_EQ(conn1, ch.FindNextPingableConnection()); |
} |
-TEST_F(P2PTransportChannelPingOrderTest, TestNoTriggeredChecksWhenWritable) { |
+TEST_F(P2PTransportChannelPingTest, TestNoTriggeredChecksWhenWritable) { |
cricket::FakePortAllocator pa(rtc::Thread::Current(), nullptr); |
cricket::P2PTransportChannel ch("trigger checks", 1, nullptr, &pa); |
PrepareChannel(&ch); |
@@ -1807,3 +1812,52 @@ TEST_F(P2PTransportChannelPingOrderTest, TestNoTriggeredChecksWhenWritable) { |
// a higher priority. |
EXPECT_EQ(conn2, ch.FindNextPingableConnection()); |
} |
+ |
+TEST_F(P2PTransportChannelPingTest, ConnectionResurrection) { |
+ cricket::FakePortAllocator pa(rtc::Thread::Current(), nullptr); |
+ cricket::P2PTransportChannel ch("connection resurrection", 1, nullptr, &pa); |
+ PrepareChannel(&ch); |
+ ch.Connect(); |
+ |
+ // Create conn1 and keep track of original candidate priority. |
+ ch.OnCandidate(CreateCandidate("1.1.1.1", 1, 1)); |
+ cricket::Connection* conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1); |
+ ASSERT_TRUE(conn1 != nullptr); |
+ uint32 remote_priority = conn1->remote_candidate().priority(); |
+ |
+ // Create a higher priority candidate and make the connection |
+ // readable/writable. This will prune conn1. |
+ ch.OnCandidate(CreateCandidate("2.2.2.2", 2, 2)); |
+ cricket::Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2); |
+ ASSERT_TRUE(conn2 != nullptr); |
+ conn2->ReceivedPing(); |
+ conn2->ReceivedPingResponse(); |
+ |
+ // Wait for conn1 being destroyed. |
+ EXPECT_TRUE_WAIT(GetConnectionTo(&ch, "1.1.1.1", 1) == nullptr, 3000); |
+ cricket::Port* port = GetPort(&ch); |
+ |
+ // Create a minimal STUN message with prflx priority. |
+ cricket::IceMessage request; |
+ request.SetType(cricket::STUN_BINDING_REQUEST); |
+ request.AddAttribute(new cricket::StunByteStringAttribute( |
+ cricket::STUN_ATTR_USERNAME, kIceUfrag[1])); |
+ uint32 prflx_priority = cricket::ICE_TYPE_PREFERENCE_PRFLX << 24; |
+ request.AddAttribute(new cricket::StunUInt32Attribute( |
+ cricket::STUN_ATTR_PRIORITY, prflx_priority)); |
+ EXPECT_NE(prflx_priority, remote_priority); |
+ |
+ // conn1 should be resurrected with original priority. |
+ port->SignalUnknownAddress(port, rtc::SocketAddress("1.1.1.1", 1), |
+ cricket::PROTO_UDP, &request, kIceUfrag[1], false); |
+ conn1 = WaitForConnectionTo(&ch, "1.1.1.1", 1); |
+ ASSERT_TRUE(conn1 != nullptr); |
+ EXPECT_EQ(conn1->remote_candidate().priority(), remote_priority); |
+ |
+ // conn3, a real prflx connection, should have prflx priority. |
+ port->SignalUnknownAddress(port, rtc::SocketAddress("3.3.3.3", 1), |
+ cricket::PROTO_UDP, &request, kIceUfrag[1], false); |
+ cricket::Connection* conn3 = WaitForConnectionTo(&ch, "3.3.3.3", 1); |
+ ASSERT_TRUE(conn3 != nullptr); |
+ EXPECT_EQ(conn3->remote_candidate().priority(), prflx_priority); |
+} |