Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(279)

Unified Diff: webrtc/p2p/base/p2ptransportchannel_unittest.cc

Issue 2025573002: Use continual gathering to restore backup connections (Closed) Base URL: https://chromium.googlesource.com/external/webrtc@master
Patch Set: Address Taylor comments Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: webrtc/p2p/base/p2ptransportchannel_unittest.cc
diff --git a/webrtc/p2p/base/p2ptransportchannel_unittest.cc b/webrtc/p2p/base/p2ptransportchannel_unittest.cc
index 68543a5f39ed3af006541bfdcdd747c84a2d5df9..1b0ac6f40c55aa2df681e3d8212025d655d01aae 100644
--- a/webrtc/p2p/base/p2ptransportchannel_unittest.cc
+++ b/webrtc/p2p/base/p2ptransportchannel_unittest.cc
@@ -388,6 +388,7 @@ class P2PTransportChannelTestBase : public testing::Test,
}
void RemoveAddress(int endpoint, const SocketAddress& addr) {
GetEndpoint(endpoint)->network_manager_.RemoveInterface(addr);
+ fw()->AddRule(false, rtc::FP_ANY, rtc::FD_ANY, addr);
}
void SetProxy(int endpoint, rtc::ProxyType type) {
rtc::ProxyInfo info;
@@ -1583,6 +1584,37 @@ TEST_F(P2PTransportChannelSameNatTest, TestConesBehindSameCone) {
// In the future we will try different RTTs and configs for the different
// interfaces, so that we can simulate a user with Ethernet and VPN networks.
class P2PTransportChannelMultihomedTest : public P2PTransportChannelTestBase {
+ public:
+ const cricket::Connection* GetConnectionWithRemoteAddress(
+ cricket::P2PTransportChannel* channel,
+ const SocketAddress& address) {
+ for (cricket::Connection* conn : channel->connections()) {
+ if (conn->remote_candidate().address().EqualIPs(address)) {
+ return conn;
+ }
+ }
+ return nullptr;
+ }
+
+ const cricket::Connection* GetConnectionWithLocalAddress(
+ cricket::P2PTransportChannel* channel,
+ const SocketAddress& address) {
+ for (cricket::Connection* conn : channel->connections()) {
+ if (conn->local_candidate().address().EqualIPs(address)) {
+ return conn;
+ }
+ }
+ return nullptr;
+ }
+
+ void DestroyAllButBestConnection(cricket::P2PTransportChannel* channel) {
+ const cricket::Connection* best_connection = channel->best_connection();
+ for (cricket::Connection* conn : channel->connections()) {
+ if (conn != best_connection) {
+ conn->Destroy();
+ }
+ }
+ }
};
// Test that we can establish connectivity when both peers are multihomed.
@@ -1729,6 +1761,7 @@ TEST_F(P2PTransportChannelMultihomedTest, TestPreferWifiToWifiConnection) {
LocalCandidate(ep2_ch1())->address().EqualIPs(wifi[1]) &&
RemoteCandidate(ep2_ch1())->address().EqualIPs(wifi[0]),
1000);
+ DestroyChannels();
}
// Tests that a Wifi-Cellular connection has higher precedence than
@@ -1759,6 +1792,7 @@ TEST_F(P2PTransportChannelMultihomedTest, TestPreferWifiOverCellularNetwork) {
EXPECT_TRUE_WAIT(ep2_ch1()->best_connection() &&
LocalCandidate(ep2_ch1())->address().EqualIPs(wifi[1]),
1000);
+ DestroyChannels();
}
// Test that the backup connection is pinged at a rate no faster than
@@ -1796,6 +1830,8 @@ TEST_F(P2PTransportChannelMultihomedTest, TestPingBackupConnectionRate) {
backup_conn->last_ping_response_received() - last_ping_response_ms;
LOG(LS_INFO) << "Time elapsed: " << time_elapsed;
EXPECT_GE(time_elapsed, backup_ping_interval);
+
+ DestroyChannels();
}
TEST_F(P2PTransportChannelMultihomedTest, TestGetState) {
@@ -1810,6 +1846,8 @@ TEST_F(P2PTransportChannelMultihomedTest, TestGetState) {
ep1_ch1()->GetState(), 1000);
EXPECT_EQ_WAIT(cricket::TransportChannelState::STATE_COMPLETED,
ep2_ch1()->GetState(), 1000);
+
+ DestroyChannels();
}
// Tests that when a network interface becomes inactive, if and only if
@@ -1848,17 +1886,58 @@ TEST_F(P2PTransportChannelMultihomedTest, TestNetworkBecomesInactive) {
rtc::Thread::Current()->ProcessMessages(500);
EXPECT_EQ(num_ports, ep2_ch1()->ports().size());
EXPECT_EQ(num_remote_candidates, ep1_ch1()->remote_candidates().size());
+
+ DestroyChannels();
}
-/*
+// Tests that continual gathering will create new connections when a new
+// interface is added.
+TEST_F(P2PTransportChannelMultihomedTest,
+ TestContinualGatheringOnNewInterface) {
+ auto& wifi = kAlternateAddrs;
+ auto& cellular = kPublicAddrs;
+ AddAddress(0, wifi[0], "test_wifi0", rtc::ADAPTER_TYPE_WIFI);
+ AddAddress(1, cellular[1], "test_cell1", rtc::ADAPTER_TYPE_CELLULAR);
+ CreateChannels(1);
+ // Enable continual gathering.
+ ep1_ch1()->SetIceConfig(CreateIceConfig(1000, true));
+ ep2_ch1()->SetIceConfig(CreateIceConfig(1000, true));
+ SetAllocatorFlags(0, kOnlyLocalPorts);
+ SetAllocatorFlags(1, kOnlyLocalPorts);
+ EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
+ ep2_ch1()->receiving() && ep2_ch1()->writable(),
+ kDefaultTimeout, kDefaultTimeout);
+
+ // Add a new wifi interface on end point 2. We should expect a new connection
+ // to be created and the new one will be the best connection.
+ AddAddress(1, wifi[1], "test_wifi1", rtc::ADAPTER_TYPE_WIFI);
+ const cricket::Connection* conn;
+ EXPECT_TRUE_WAIT((conn = ep1_ch1()->best_connection()) != nullptr &&
+ conn->remote_candidate().address().EqualIPs(wifi[1]),
+ kDefaultTimeout);
+ EXPECT_TRUE_WAIT((conn = ep2_ch1()->best_connection()) != nullptr &&
+ conn->local_candidate().address().EqualIPs(wifi[1]),
+ kDefaultTimeout);
+
+ // Add a new cellular interface on end point 1, we should expect a new
+ // backup connection created using this new interface.
+ AddAddress(0, cellular[0], "test_cellular0", rtc::ADAPTER_TYPE_CELLULAR);
+ EXPECT_TRUE_WAIT(
+ ep1_ch1()->GetState() == cricket::STATE_COMPLETED &&
+ (conn = GetConnectionWithLocalAddress(ep1_ch1(), cellular[0])) &&
+ conn != ep1_ch1()->best_connection() && conn->writable(),
+ kDefaultTimeout);
+ EXPECT_TRUE_WAIT(
+ ep2_ch1()->GetState() == cricket::STATE_COMPLETED &&
+ (conn = GetConnectionWithRemoteAddress(ep2_ch1(), cellular[0])) &&
+ conn != ep2_ch1()->best_connection() && conn->receiving(),
+ kDefaultTimeout);
-TODO(pthatcher): Once have a way to handle network interfaces changes
-without signalling an ICE restart, put a test like this back. In the
-mean time, this test only worked for GICE. With ICE, it's currently
-not possible without an ICE restart.
+ DestroyChannels();
+}
-// Test that we can switch links in a coordinated fashion.
-TEST_F(P2PTransportChannelMultihomedTest, TestDrain) {
+// Tests that we can switch links via continual gathering.
+TEST_F(P2PTransportChannelMultihomedTest, TestContinualGatheringSwitchLinks) {
AddAddress(0, kPublicAddrs[0]);
AddAddress(1, kPublicAddrs[1]);
// Use only local ports for simplicity.
@@ -1867,35 +1946,119 @@ TEST_F(P2PTransportChannelMultihomedTest, TestDrain) {
// Create channels and let them go writable, as usual.
CreateChannels(1);
- EXPECT_TRUE_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
- ep2_ch1()->receiving() && ep2_ch1()->writable(),
- 1000);
+ // Enable continual gathering.
+ ep1_ch1()->SetIceConfig(CreateIceConfig(1000, true));
+ ep2_ch1()->SetIceConfig(CreateIceConfig(1000, true));
+ EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
+ ep2_ch1()->receiving() && ep2_ch1()->writable(),
+ kDefaultTimeout, kDefaultTimeout);
EXPECT_TRUE(
ep1_ch1()->best_connection() && ep2_ch1()->best_connection() &&
LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
RemoteCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[1]));
-
- // Remove the public interface, add the alternate interface, and allocate
- // a new generation of candidates for the new interface (via
- // MaybeStartGathering()).
+ // Add the new address first and then remove the other one.
LOG(LS_INFO) << "Draining...";
AddAddress(1, kAlternateAddrs[1]);
RemoveAddress(1, kPublicAddrs[1]);
- ep2_ch1()->MaybeStartGathering();
-
- // We should switch over to use the alternate address after
- // an exchange of pings.
+ // We should switch to use the alternate address after an exchange of pings.
EXPECT_TRUE_WAIT(
ep1_ch1()->best_connection() && ep2_ch1()->best_connection() &&
LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
RemoteCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[1]),
3000);
+ // Remove one address first and then add another address.
+ LOG(LS_INFO) << "Draining again...";
+ RemoveAddress(1, kAlternateAddrs[1]);
+ AddAddress(1, kAlternateAddrs[0]);
+ EXPECT_TRUE_WAIT(
+ ep1_ch1()->best_connection() && ep2_ch1()->best_connection() &&
+ LocalCandidate(ep1_ch1())->address().EqualIPs(kPublicAddrs[0]) &&
+ RemoteCandidate(ep1_ch1())->address().EqualIPs(kAlternateAddrs[0]),
+ 3000);
+
+ DestroyChannels();
+}
+
+// Tests that if the backup connections are lost and then the interface with the
+// selected connection is gone, continual gathering will restore the
+// connectivity.
+TEST_F(P2PTransportChannelMultihomedTest,
+ TestBackupConnectionLostThenContinualGathering) {
+ auto& wifi = kAlternateAddrs;
+ auto& cellular = kPublicAddrs;
+ AddAddress(0, wifi[0], "test_wifi0", rtc::ADAPTER_TYPE_WIFI);
+ AddAddress(0, cellular[0], "test_cell0", rtc::ADAPTER_TYPE_CELLULAR);
+ AddAddress(1, wifi[1], "test_wifi1", rtc::ADAPTER_TYPE_WIFI);
+ AddAddress(1, cellular[1], "test_cell1", rtc::ADAPTER_TYPE_CELLULAR);
+ // Use only local ports for simplicity.
+ SetAllocatorFlags(0, kOnlyLocalPorts);
+ SetAllocatorFlags(1, kOnlyLocalPorts);
+
+ // Create channels and let them go writable, as usual.
+ CreateChannels(1);
+ // Enable continual gathering.
+ ep1_ch1()->SetIceConfig(CreateIceConfig(1000, true));
+ ep2_ch1()->SetIceConfig(CreateIceConfig(1000, true));
+ EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
+ ep2_ch1()->receiving() && ep2_ch1()->writable(),
+ kDefaultTimeout, kDefaultTimeout);
+ EXPECT_TRUE(ep1_ch1()->best_connection() && ep2_ch1()->best_connection() &&
+ LocalCandidate(ep1_ch1())->address().EqualIPs(wifi[0]) &&
+ RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]));
+
+ // First destroy all backup connection.
+ DestroyAllButBestConnection(ep1_ch1());
+ // Then the interface of the best connection goes away.
+ RemoveAddress(0, wifi[0]);
+ EXPECT_TRUE_WAIT(
+ ep1_ch1()->best_connection() && ep2_ch1()->best_connection() &&
+ LocalCandidate(ep1_ch1())->address().EqualIPs(cellular[0]) &&
+ RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]),
+ kDefaultTimeout);
+
DestroyChannels();
}
-*/
+// Tests that the backup connection will be restored after it is destroyed.
+TEST_F(P2PTransportChannelMultihomedTest, TestRestoreBackupConnection) {
+ auto& wifi = kAlternateAddrs;
+ auto& cellular = kPublicAddrs;
+ AddAddress(0, wifi[0], "test_wifi0", rtc::ADAPTER_TYPE_WIFI);
+ AddAddress(0, cellular[0], "test_cell0", rtc::ADAPTER_TYPE_CELLULAR);
+ AddAddress(1, wifi[1], "test_wifi1", rtc::ADAPTER_TYPE_WIFI);
+ AddAddress(1, cellular[1], "test_cell1", rtc::ADAPTER_TYPE_CELLULAR);
+ // Use only local ports for simplicity.
+ SetAllocatorFlags(0, kOnlyLocalPorts);
+ SetAllocatorFlags(1, kOnlyLocalPorts);
+
+ // Create channels and let them go writable, as usual.
+ CreateChannels(1);
+ ep1_ch1()->SetIceConfig(CreateIceConfig(1000, true));
+ ep2_ch1()->SetIceConfig(CreateIceConfig(1000, true));
+ EXPECT_TRUE_WAIT_MARGIN(ep1_ch1()->receiving() && ep1_ch1()->writable() &&
+ ep2_ch1()->receiving() && ep2_ch1()->writable(),
+ kDefaultTimeout, kDefaultTimeout);
+ EXPECT_TRUE(ep1_ch1()->best_connection() && ep2_ch1()->best_connection() &&
+ LocalCandidate(ep1_ch1())->address().EqualIPs(wifi[0]) &&
+ RemoteCandidate(ep1_ch1())->address().EqualIPs(wifi[1]));
+
+ // Destroy all backup connections.
+ ep1_ch1()->set_check_restore_backup_connection_interval(2000);
+ DestroyAllButBestConnection(ep1_ch1());
+ // Ensure the backup connection is removed first.
+ EXPECT_TRUE_WAIT(
+ GetConnectionWithLocalAddress(ep1_ch1(), cellular[0]) == nullptr,
+ kDefaultTimeout);
+ const cricket::Connection* conn;
+ EXPECT_TRUE_WAIT(
+ (conn = GetConnectionWithLocalAddress(ep1_ch1(), cellular[0])) &&
+ conn != ep1_ch1()->best_connection() && conn->writable(),
+ 5000);
+
+ DestroyChannels();
+}
// A collection of tests which tests a single P2PTransportChannel by sending
// pings.

Powered by Google App Engine
This is Rietveld 408576698