Index: webrtc/p2p/base/port_unittest.cc |
diff --git a/webrtc/p2p/base/port_unittest.cc b/webrtc/p2p/base/port_unittest.cc |
index ab48ec9af52dfb4797945e17ece9ed289315a0b2..abda90dd96344a9e941912e433b6762c9c82fa16 100644 |
--- a/webrtc/p2p/base/port_unittest.cc |
+++ b/webrtc/p2p/base/port_unittest.cc |
@@ -46,6 +46,7 @@ using rtc::NAT_SYMMETRIC; |
using rtc::PacketSocketFactory; |
using rtc::Socket; |
using rtc::SocketAddress; |
+using rtc::kMaxNetworkCost; |
using namespace cricket; |
static const int kTimeout = 1000; |
@@ -64,6 +65,7 @@ static const SocketAddress kTurnUdpIntAddr("99.99.99.4", STUN_SERVER_PORT); |
static const SocketAddress kTurnTcpIntAddr("99.99.99.4", 5010); |
static const SocketAddress kTurnUdpExtAddr("99.99.99.5", 0); |
static const RelayCredentials kRelayCredentials("test", "test"); |
+static const uint16_t kCostForUnknownNetworkType = 10; |
// TODO: Update these when RFC5245 is completely supported. |
// Magic value of 30 is from RFC3484, for IPv4 addresses. |
@@ -384,6 +386,18 @@ class PortTest : public testing::Test, public sigslot::has_slots<> { |
network_.AddIP(rtc::IPAddress(INADDR_ANY)); |
} |
+ void ConnectSignalNeworkCostChangdForPort(PortInterface* port) { |
+ port->SignalNetworkCostChanged.connect(this, |
+ &PortTest::OnPortNetworkCostChanged); |
+ } |
+ |
+ void OnPortNetworkCostChanged(PortInterface* port) { |
+ port_network_cost_changed_ = true; |
+ ; |
+ } |
+ |
+ bool port_network_cost_changed() { return port_network_cost_changed_; } |
+ |
protected: |
void TestLocalToLocal() { |
Port* port1 = CreateUdpPort(kLocalAddr1); |
@@ -759,7 +773,6 @@ class PortTest : public testing::Test, public sigslot::has_slots<> { |
return &nat_socket_factory1_; |
} |
- protected: |
rtc::VirtualSocketServer* vss() { return ss_.get(); } |
private: |
@@ -782,6 +795,7 @@ class PortTest : public testing::Test, public sigslot::has_slots<> { |
std::string password_; |
bool role_conflict_; |
bool destroyed_; |
+ bool port_network_cost_changed_ = false; |
}; |
void PortTest::TestConnectivity(const char* name1, Port* port1, |
@@ -1762,11 +1776,75 @@ TEST_F(PortTest, TestUseCandidateAttribute) { |
ASSERT_TRUE(use_candidate_attr != NULL); |
} |
-TEST_F(PortTest, TestNetworkInfoAttribute) { |
+// Tests that when the network type changes, the network cost of the port will |
+// change, the network cost of the local candidates will change and a signal |
+// will be fire to notify the network cost change if there are connections in |
+// the port. Also tests that the remote network costs are updated with the stun |
+// binding requests. |
+TEST_F(PortTest, TestNetworkCostChange) { |
std::unique_ptr<TestPort> lport( |
CreateTestPort(kLocalAddr1, "lfrag", "lpass")); |
- // Set the network type for rport to be cellular so its cost will be 999. |
+ std::unique_ptr<TestPort> rport( |
+ CreateTestPort(kLocalAddr2, "rfrag", "rpass")); |
+ lport->SetIceRole(cricket::ICEROLE_CONTROLLING); |
+ lport->SetIceTiebreaker(kTiebreaker1); |
+ rport->SetIceRole(cricket::ICEROLE_CONTROLLED); |
+ rport->SetIceTiebreaker(kTiebreaker2); |
+ lport->PrepareAddress(); |
+ rport->PrepareAddress(); |
+ ConnectSignalNeworkCostChangdForPort(lport.get()); |
+ |
+ // Default local port cost is kCostForUnknownNetworkType. |
+ EXPECT_EQ(kCostForUnknownNetworkType, lport->network_cost()); |
+ ASSERT_TRUE(!lport->Candidates().empty()); |
+ for (const cricket::Candidate& candidate : lport->Candidates()) { |
+ EXPECT_EQ(kCostForUnknownNetworkType, candidate.network_cost()); |
+ } |
+ |
+ // Change the network type to wifi. |
+ SetNetworkType(rtc::ADAPTER_TYPE_WIFI); |
+ EXPECT_EQ(0, lport->network_cost()); |
+ for (const cricket::Candidate& candidate : lport->Candidates()) { |
+ EXPECT_EQ(0u, candidate.network_cost()); |
+ } |
+ // There is no connection yet, should not fire the NetworkCostChanged event. |
+ EXPECT_FALSE(port_network_cost_changed()); |
+ |
+ // Add a connection and then change the network type. |
+ Connection* lconn = |
+ lport->CreateConnection(rport->Candidates()[0], Port::ORIGIN_MESSAGE); |
+ // Change the network type to cellular. |
+ SetNetworkType(rtc::ADAPTER_TYPE_CELLULAR); |
+ EXPECT_EQ(kMaxNetworkCost, lport->network_cost()); |
+ for (const cricket::Candidate& candidate : lport->Candidates()) { |
+ EXPECT_EQ(kMaxNetworkCost, candidate.network_cost()); |
+ } |
+ // Should fire SignalNetworkCostChanged now. |
+ EXPECT_TRUE(port_network_cost_changed()); |
+ |
+ SetNetworkType(rtc::ADAPTER_TYPE_WIFI); |
+ Connection* rconn = |
+ rport->CreateConnection(lport->Candidates()[0], Port::ORIGIN_MESSAGE); |
SetNetworkType(rtc::ADAPTER_TYPE_CELLULAR); |
+ lconn->Ping(0); |
+ // The rconn's remote candidate cost is 0, but the ping contains an attribute |
+ // of network cost of kMaxNetworkCost. Once the message is handled in rconn, |
+ // The rconn's remote candidate will have cost kMaxNetworkCost; |
+ EXPECT_EQ(0u, rconn->remote_candidate().network_cost()); |
+ ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, 1000); |
+ IceMessage* msg = lport->last_stun_msg(); |
+ EXPECT_EQ(STUN_BINDING_REQUEST, msg->type()); |
+ // Pass the binding request to rport. |
+ rconn->OnReadPacket(lport->last_stun_buf()->data<char>(), |
+ lport->last_stun_buf()->size(), rtc::PacketTime()); |
+ // Wait until rport sends the response and then check the remote network cost. |
+ ASSERT_TRUE_WAIT(rport->last_stun_msg() != NULL, 1000); |
+ EXPECT_EQ(kMaxNetworkCost, rconn->remote_candidate().network_cost()); |
+} |
+ |
+TEST_F(PortTest, TestNetworkInfoAttribute) { |
+ std::unique_ptr<TestPort> lport( |
+ CreateTestPort(kLocalAddr1, "lfrag", "lpass")); |
std::unique_ptr<TestPort> rport( |
CreateTestPort(kLocalAddr2, "rfrag", "rpass")); |
lport->SetIceRole(cricket::ICEROLE_CONTROLLING); |
@@ -1789,10 +1867,12 @@ TEST_F(PortTest, TestNetworkInfoAttribute) { |
ASSERT_TRUE(network_info_attr != NULL); |
uint32_t network_info = network_info_attr->value(); |
EXPECT_EQ(lnetwork_id, network_info >> 16); |
- // Default network cost is 0. |
- EXPECT_EQ(0U, network_info & 0xFFFF); |
+ // Default network has unknown type and cost |kCostForUnknownNetworkType|. |
+ EXPECT_EQ(kCostForUnknownNetworkType, network_info & 0xFFFF); |
+ // Set the network type to be cellular so its cost will be 999. |
// Send a fake ping from rport to lport. |
+ SetNetworkType(rtc::ADAPTER_TYPE_CELLULAR); |
uint16_t rnetwork_id = 8; |
rport->Network()->set_id(rnetwork_id); |
Connection* rconn = |
@@ -1804,7 +1884,7 @@ TEST_F(PortTest, TestNetworkInfoAttribute) { |
ASSERT_TRUE(network_info_attr != NULL); |
network_info = network_info_attr->value(); |
EXPECT_EQ(rnetwork_id, network_info >> 16); |
- EXPECT_EQ(cricket::kMaxNetworkCost, network_info & 0xFFFF); |
+ EXPECT_EQ(kMaxNetworkCost, network_info & 0xFFFF); |
} |
// Test handling STUN messages. |