Index: webrtc/p2p/base/p2ptransportchannel_unittest.cc |
diff --git a/webrtc/p2p/base/p2ptransportchannel_unittest.cc b/webrtc/p2p/base/p2ptransportchannel_unittest.cc |
index d7ee87300d9ed5f9d886bb7a0c8190d2a2e9c080..c39bda2a3a61a5c0d9d5d6a6e3b7229d7f6315de 100644 |
--- a/webrtc/p2p/base/p2ptransportchannel_unittest.cc |
+++ b/webrtc/p2p/base/p2ptransportchannel_unittest.cc |
@@ -51,11 +51,13 @@ static const SocketAddress kPublicAddrs[2] = |
// IPv6 Addresses on the public internet. |
static const SocketAddress kIPv6PublicAddrs[2] = { |
SocketAddress("2400:4030:1:2c00:be30:abcd:efab:cdef", 0), |
- SocketAddress("2620:0:1000:1b03:2e41:38ff:fea6:f2a4", 0) |
-}; |
+ SocketAddress("2600:0:1000:1b03:2e41:38ff:fea6:f2a4", 0)}; |
// For configuring multihomed clients. |
static const SocketAddress kAlternateAddrs[2] = { |
SocketAddress("101.101.101.101", 0), SocketAddress("202.202.202.202", 0)}; |
+static const SocketAddress kIPv6AlternateAddrs[2] = { |
+ SocketAddress("2401:4030:1:2c00:be30:abcd:efab:cdef", 0), |
+ SocketAddress("2601:0:1000:1b03:2e41:38ff:fea6:f2a4", 0)}; |
// Addresses for HTTP proxy servers. |
static const SocketAddress kHttpsProxyAddrs[2] = |
{ SocketAddress("11.11.11.1", 443), SocketAddress("22.22.22.1", 443) }; |
@@ -413,7 +415,7 @@ class P2PTransportChannelTestBase : public testing::Test, |
return NULL; |
} |
} |
- PortAllocator* GetAllocator(int endpoint) { |
+ BasicPortAllocator* GetAllocator(int endpoint) { |
return GetEndpoint(endpoint)->allocator_.get(); |
} |
void AddAddress(int endpoint, const SocketAddress& addr) { |
@@ -1984,6 +1986,81 @@ TEST_F(P2PTransportChannelMultihomedTest, TestFailoverControllingSide) { |
DestroyChannels(); |
} |
+// Test that we can quickly switch links if an interface goes down when |
+// there are many connections. |
+TEST_F(P2PTransportChannelMultihomedTest, TestFailoverWithManyConnections) { |
+ test_turn_server()->AddInternalSocket(kTurnTcpIntAddr, PROTO_TCP); |
+ cricket::RelayServerConfig turn_server(cricket::RELAY_TURN); |
+ turn_server.credentials = kRelayCredentials; |
+ turn_server.ports.push_back( |
+ cricket::ProtocolAddress(kTurnTcpIntAddr, cricket::PROTO_TCP, false)); |
+ GetAllocator(0)->AddTurnServer(turn_server); |
+ GetAllocator(1)->AddTurnServer(turn_server); |
+ // Enable IPv6 |
+ SetAllocatorFlags(0, PORTALLOCATOR_ENABLE_IPV6); |
+ SetAllocatorFlags(1, PORTALLOCATOR_ENABLE_IPV6); |
+ int delay = kMinimumStepDelay; |
Taylor Brandstetter
2016/10/04 02:08:10
nit: Why is this variable needed?
honghaiz3
2016/10/20 23:47:58
Removed
|
+ SetAllocationStepDelay(0, delay); |
+ SetAllocationStepDelay(1, delay); |
+ |
+ auto& wifi = kPublicAddrs; |
+ auto& cellular = kAlternateAddrs; |
+ auto& wifiIpv6 = kIPv6PublicAddrs; |
+ auto& cellularIpv6 = kIPv6AlternateAddrs; |
+ AddAddress(0, wifi[0], "wifi0", rtc::ADAPTER_TYPE_WIFI); |
+ AddAddress(0, wifiIpv6[0], "wifi0", rtc::ADAPTER_TYPE_WIFI); |
+ AddAddress(0, cellular[0], "cellular0", rtc::ADAPTER_TYPE_CELLULAR); |
+ AddAddress(0, cellularIpv6[0], "cellular0", rtc::ADAPTER_TYPE_CELLULAR); |
+ AddAddress(1, wifi[1], "wifi1", rtc::ADAPTER_TYPE_WIFI); |
+ AddAddress(1, wifiIpv6[1], "wifi1", rtc::ADAPTER_TYPE_WIFI); |
+ AddAddress(1, cellular[1], "cellular1", rtc::ADAPTER_TYPE_CELLULAR); |
+ AddAddress(1, cellularIpv6[1], "cellular1", rtc::ADAPTER_TYPE_CELLULAR); |
+ |
+ // Set smaller delay on the TCP TURN server so that TCP TURN candidates |
+ // will be created in time. |
+ virtual_socket_server()->SetDelayOnAddress(kTurnTcpIntAddr, 1); |
+ virtual_socket_server()->SetDelayOnAddress(kTurnUdpExtAddr, 1); |
+ virtual_socket_server()->set_delay_mean(100); |
+ virtual_socket_server()->set_delay_stddev(100); |
honghaiz3
2016/10/03 21:28:33
The random delay is needed so that the test may fa
Taylor Brandstetter
2016/10/04 02:08:10
If the test will only fail randomly, then if a reg
honghaiz3
2016/10/20 23:47:58
I Find a way to remove the randomness by using lon
|
+ virtual_socket_server()->UpdateDelayDistribution(); |
+ |
+ // Make the receiving timeout shorter for testing. |
+ IceConfig config = CreateIceConfig(1000, GATHER_CONTINUALLY); |
+ // Create channels and let them go writable, as usual. |
+ CreateChannels(config, config, true /* ice_renomination */); |
+ EXPECT_TRUE_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() && |
+ ep2_ch1()->receiving() && ep2_ch1()->writable(), |
+ 3000); |
Taylor Brandstetter
2016/10/04 02:08:10
Can you use a constant instead of 3000?
honghaiz3
2016/10/20 23:47:58
Done.
|
+ EXPECT_TRUE_WAIT( |
+ ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection() && |
+ LocalCandidate(ep1_ch1())->address().EqualIPs(wifiIpv6[0]) && |
+ RemoteCandidate(ep1_ch1())->address().EqualIPs(wifiIpv6[1]), |
+ 3000); |
+ |
+ // Blackhole any traffic to or from the wifi on endpoint 1. |
+ LOG(LS_INFO) << "Failing over..."; |
Taylor Brandstetter
2016/10/04 02:08:10
Is this log still necessary?
honghaiz3
2016/10/20 23:47:58
This log is informational. The similar log is also
|
+ fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, wifi[0]); |
+ fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, wifiIpv6[0]); |
+ |
+ // The selected connections may switch, so keep references to them. |
+ const Connection* selected_connection1 = ep1_ch1()->selected_connection(); |
+ const Connection* selected_connection2 = ep2_ch1()->selected_connection(); |
+ EXPECT_TRUE_WAIT( |
+ !selected_connection1->receiving() && !selected_connection2->receiving(), |
+ 3000); |
+ |
+ // It should switch over to use the cellular IPv6 addr on endpoint 1 before |
+ // it timed out on writing. |
+ EXPECT_TRUE_WAIT( |
+ ep1_ch1()->selected_connection()->receiving() && |
+ ep2_ch1()->selected_connection()->receiving() && |
+ RemoteCandidate(ep2_ch1())->address().EqualIPs(cellularIpv6[0]) && |
+ LocalCandidate(ep1_ch1())->address().EqualIPs(cellularIpv6[0]), |
+ 3000); |
+ |
+ DestroyChannels(); |
+} |
+ |
// Test that when the controlling side switches the selected connection, |
// the nomination of the selected connection on the controlled side will |
// increase. |