--- a/media/mtransport/test/gtest_utils.h
+++ b/media/mtransport/test/gtest_utils.h
@@ -95,56 +95,63 @@ extern "C" {
#define ASSERT_EQ_WAIT(expected, actual, timeout) \
do { \
WAIT(expected == actual, timeout); \
ASSERT_EQ(expected, actual); \
} while(0)
using test::RingbufferDumper;
+const std::string kDefaultStunServerHostname(
+ (char *)"localhost");
+const std::string kDefaultStunServerAddress(
+ (char *)"10.252.26.185");
+const uint16_t kDefaultStunServerPort=3478;
+const uint16_t kDefaultStunServerReflexivePort=3479;
+const std::string kBogusStunServerHostname(
+ (char *)"stun-server-nonexistent.invalid");
+
+const std::string kDefaultTurnServerHostname(
+ (char *)"localhost");
+const std::string kDefaultTurnServerAddress(
+ (char *)"10.252.26.185");
+const uint16_t kDefaultTurnServerPort=3478;
+const std::string kDefaultTurnUsername(
+ (char *)"foo");
+const std::string kDefaultTurnPassword(
+ (char *)"bar");
+
class MtransportTest : public ::testing::Test {
public:
MtransportTest()
: test_utils_(nullptr)
, dumper_(nullptr)
{
+ stun_server_hostname_ = kDefaultStunServerHostname;
+ stun_server_address_ = kDefaultStunServerAddress;
+ turn_server_address_ = kDefaultTurnServerAddress;
+ turn_user_ = kDefaultTurnUsername;
+ turn_password_ = kDefaultTurnPassword;
}
void SetUp() override {
test_utils_ = new MtransportTestUtils();
NSS_NoDB_Init(nullptr);
NSS_SetDomesticPolicy();
NR_reg_init(NR_REG_MODE_LOCAL);
// Attempt to load env vars used by tests.
- GetEnvironment("TURN_SERVER_ADDRESS", turn_server_);
+ GetEnvironment("TURN_SERVER_ADDRESS", turn_server_address_);
+ GetEnvironment("TURN_SERVER_HOSTNAME", turn_server_hostname_);
GetEnvironment("TURN_SERVER_USER", turn_user_);
GetEnvironment("TURN_SERVER_PASSWORD", turn_password_);
GetEnvironment("STUN_SERVER_ADDRESS", stun_server_address_);
GetEnvironment("STUN_SERVER_HOSTNAME", stun_server_hostname_);
- std::string disable_non_local;
- GetEnvironment("MOZ_DISABLE_NONLOCAL_CONNECTIONS", disable_non_local);
- std::string upload_dir;
- GetEnvironment("MOZ_UPLOAD_DIR", upload_dir);
-
- if ((!disable_non_local.empty() && disable_non_local != "0") ||
- !upload_dir.empty()) {
- // We're assuming that MOZ_UPLOAD_DIR is only set on tbpl;
- // MOZ_DISABLE_NONLOCAL_CONNECTIONS probably should be set when running the
- // cpp unit-tests, but is not presently.
- stun_server_address_ = "";
- stun_server_hostname_ = "";
- turn_server_ = "";
- }
-
- // Some tests are flaky and need to check if they're supposed to run.
- webrtc_enabled_ = CheckEnvironmentFlag("MOZ_WEBRTC_TESTS");
-
::testing::TestEventListeners& listeners =
::testing::UnitTest::GetInstance()->listeners();
dumper_ = new RingbufferDumper(test_utils_);
listeners.Append(dumper_);
}
void TearDown() override {
@@ -155,49 +162,19 @@ public:
void GetEnvironment(const char* aVar, std::string& out) {
char* value = getenv(aVar);
if (value) {
out = value;
}
}
- bool CheckEnvironmentFlag(const char* aVar) {
- std::string value;
- GetEnvironment(aVar, value);
- return value == "1";
- }
-
- bool WarnIfTurnNotConfigured() const {
- bool configured =
- !turn_server_.empty() &&
- !turn_user_.empty() &&
- !turn_password_.empty();
-
- if (configured) {
- nr_transport_addr addr;
- if (nr_str_port_to_transport_addr(turn_server_.c_str(), 3478,
- IPPROTO_UDP, &addr)) {
- printf("Invalid TURN_SERVER_ADDRESS \"%s\". Only IP numbers supported.\n",
- turn_server_.c_str());
- configured = false;
- }
- } else {
- printf(
- "Set TURN_SERVER_ADDRESS, TURN_SERVER_USER, and TURN_SERVER_PASSWORD\n"
- "environment variables to run this test\n");
- }
-
- return !configured;
- }
-
MtransportTestUtils* test_utils_;
RingbufferDumper* dumper_;
- std::string turn_server_;
+ std::string turn_server_address_;
+ std::string turn_server_hostname_;
std::string turn_user_;
std::string turn_password_;
std::string stun_server_address_;
std::string stun_server_hostname_;
-
- bool webrtc_enabled_;
};
#endif
--- a/media/mtransport/test/ice_unittest.cpp
+++ b/media/mtransport/test/ice_unittest.cpp
@@ -55,23 +55,16 @@ extern "C" {
#include "gtest/gtest.h"
#include "gtest_utils.h"
using namespace mozilla;
static unsigned int kDefaultTimeout = 7000;
-//TODO(nils@mozilla.com): This should get replaced with some non-external
-//solution like discussed in bug 860775.
-const std::string kDefaultStunServerHostname(
- (char *)"global.stun.twilio.com");
-const std::string kBogusStunServerHostname(
- (char *)"stun-server-nonexistent.invalid");
-const uint16_t kDefaultStunServerPort=3478;
const std::string kBogusIceCandidate(
(char *)"candidate:0 2 UDP 2113601790 192.168.178.20 50769 typ");
const std::string kUnreachableHostIceCandidate(
(char *)"candidate:0 1 UDP 2113601790 192.168.178.20 50769 typ host");
namespace {
@@ -119,27 +112,28 @@ Resolve(const std::string& fqdn, int add
freeaddrinfo(res);
return str_addr;
}
class StunTest : public MtransportTest {
public:
StunTest() : MtransportTest() {
- stun_server_hostname_ = kDefaultStunServerHostname;
}
void SetUp() override {
MtransportTest::SetUp();
// If only a STUN server FQDN was provided, look up its IP address for the
// address-only tests.
+ /*
if (stun_server_address_.empty() && !stun_server_hostname_.empty()) {
stun_server_address_ = Resolve(stun_server_hostname_, AF_INET);
}
+ */
// Make sure NrIceCtx is in a testable state.
test_utils_->sts_target()->Dispatch(
WrapRunnableNM(&NrIceCtx::internal_DeinitializeGlobal),
NS_DISPATCH_SYNC);
// NB: NrIceCtx::internal_DeinitializeGlobal destroys the RLogRingBuffer
// singleton.
@@ -1654,25 +1648,28 @@ class WebRtcIceConnectTest : public Stun
}
void InitPeer(IceTestPeer* peer, bool setup_stun_servers = true) {
if (use_nat_) {
// If we enable nat simulation, but still use a real STUN server somewhere
// on the internet, we will see failures if there is a real NAT in
// addition to our simulated one, particularly if it disallows
// hairpinning.
+ /*
if (setup_stun_servers) {
InitTestStunServer();
peer->UseTestStunServer();
}
+ */
peer->UseNat();
peer->SetFilteringType(filtering_type_);
peer->SetMappingType(mapping_type_);
peer->SetBlockUdp(block_udp_);
- } else if (setup_stun_servers) {
+ }
+ if (setup_stun_servers) {
std::vector<NrIceStunServer> stun_servers;
stun_servers.push_back(*NrIceStunServer::Create(stun_server_address_,
kDefaultStunServerPort, kNrIceTransportUdp));
stun_servers.push_back(*NrIceStunServer::Create(stun_server_address_,
kDefaultStunServerPort, kNrIceTransportTcp));
peer->SetStunServers(stun_servers);
@@ -2176,17 +2173,17 @@ TEST_F(WebRtcIceGatherTest, TestGatherFa
}
TEST_F(WebRtcIceGatherTest, TestGatherDNSStunServerIpAddress) {
if (stun_server_address_.empty()) {
return;
}
EnsurePeer();
- peer_->SetStunServer(stun_server_address_, kDefaultStunServerPort);
+ peer_->SetStunServer(stun_server_address_, kDefaultStunServerReflexivePort);
peer_->SetDNSResolver();
Gather();
ASSERT_TRUE(StreamHasMatchingCandidate(0, " UDP "));
ASSERT_TRUE(StreamHasMatchingCandidate(0, "typ srflx raddr"));
}
TEST_F(WebRtcIceGatherTest, TestGatherDNSStunServerIpAddressTcp) {
if (stun_server_address_.empty()) {
@@ -2206,24 +2203,28 @@ TEST_F(WebRtcIceGatherTest, TestGatherDN
}
TEST_F(WebRtcIceGatherTest, TestGatherDNSStunServerHostname) {
if (stun_server_hostname_.empty()) {
return;
}
EnsurePeer();
- peer_->SetStunServer(stun_server_hostname_, kDefaultStunServerPort);
+ peer_->SetStunServer(stun_server_hostname_, kDefaultStunServerReflexivePort);
peer_->SetDNSResolver();
Gather();
ASSERT_TRUE(StreamHasMatchingCandidate(0, " UDP "));
ASSERT_TRUE(StreamHasMatchingCandidate(0, "typ srflx raddr"));
}
TEST_F(WebRtcIceGatherTest, TestGatherDNSStunServerHostnameTcp) {
+ if (stun_server_hostname_.empty()) {
+ return;
+ }
+
EnsurePeer(ICE_TEST_PEER_OFFERER | ICE_TEST_PEER_ENABLED_TCP);
peer_->SetStunServer(stun_server_hostname_, kDefaultStunServerPort,
kNrIceTransportTcp);
peer_->SetDNSResolver();
Gather();
ASSERT_TRUE(StreamHasMatchingCandidate(0, "tcptype passive"));
ASSERT_FALSE(StreamHasMatchingCandidate(0, "tcptype passive", " 9 "));
ASSERT_TRUE(StreamHasMatchingCandidate(0, "tcptype so"));
@@ -2283,47 +2284,39 @@ TEST_F(WebRtcIceGatherTest, TestGatherDN
kNrIceTransportTcp);
peer_->SetDNSResolver();
Gather();
ASSERT_TRUE(StreamHasMatchingCandidate(0, " TCP "));
}
TEST_F(WebRtcIceGatherTest, TestDefaultCandidate) {
EnsurePeer();
- peer_->SetStunServer(stun_server_hostname_, kDefaultStunServerPort);
+ peer_->SetStunServer(stun_server_address_, kDefaultStunServerPort);
Gather();
NrIceCandidate default_candidate;
ASSERT_TRUE(NS_SUCCEEDED(peer_->GetDefaultCandidate(0, &default_candidate)));
}
TEST_F(WebRtcIceGatherTest, TestGatherTurn) {
EnsurePeer();
- if (turn_server_.empty())
- return;
- peer_->SetTurnServer(turn_server_, kDefaultStunServerPort,
+ peer_->SetTurnServer(turn_server_address_, kDefaultTurnServerPort,
turn_user_, turn_password_, kNrIceTransportUdp);
Gather();
}
TEST_F(WebRtcIceGatherTest, TestGatherTurnTcp) {
EnsurePeer();
- if (turn_server_.empty())
- return;
- peer_->SetTurnServer(turn_server_, kDefaultStunServerPort,
+ peer_->SetTurnServer(turn_server_address_, kDefaultTurnServerPort,
turn_user_, turn_password_, kNrIceTransportTcp);
Gather();
}
TEST_F(WebRtcIceGatherTest, TestGatherDisableComponent) {
- if (stun_server_hostname_.empty()) {
- return;
- }
-
EnsurePeer();
- peer_->SetStunServer(stun_server_hostname_, kDefaultStunServerPort);
+ peer_->SetStunServer(stun_server_address_, kDefaultStunServerPort);
peer_->AddStream(2);
peer_->DisableComponent(1, 2);
Gather();
std::vector<std::string> candidates =
peer_->GetCandidates(1);
for (size_t i=0; i<candidates.size(); ++i) {
size_t sp1 = candidates[i].find(' ');
@@ -2854,69 +2847,60 @@ TEST_F(WebRtcIceConnectTest, TestGatherS
UseNat();
SetFilteringType(TestNat::PORT_DEPENDENT);
SetMappingType(TestNat::PORT_DEPENDENT);
AddStream(1);
ASSERT_TRUE(Gather());
}
TEST_F(WebRtcIceConnectTest, TestConnectSymmetricNat) {
- if (turn_server_.empty())
- return;
-
UseNat();
SetFilteringType(TestNat::PORT_DEPENDENT);
SetMappingType(TestNat::PORT_DEPENDENT);
AddStream(1);
p1_->SetExpectedTypes(NrIceCandidate::Type::ICE_RELAYED,
NrIceCandidate::Type::ICE_RELAYED);
p2_->SetExpectedTypes(NrIceCandidate::Type::ICE_RELAYED,
NrIceCandidate::Type::ICE_RELAYED);
- SetTurnServer(turn_server_, kDefaultStunServerPort,
+ SetTurnServer(turn_server_address_, kDefaultTurnServerPort,
turn_user_, turn_password_);
ASSERT_TRUE(Gather());
Connect();
}
TEST_F(WebRtcIceConnectTest, TestGatherNatBlocksUDP) {
- if (turn_server_.empty())
- return;
-
UseNat();
BlockUdp();
AddStream(1);
std::vector<NrIceTurnServer> turn_servers;
std::vector<unsigned char> password_vec(turn_password_.begin(),
turn_password_.end());
turn_servers.push_back(
- *NrIceTurnServer::Create(turn_server_, kDefaultStunServerPort,
+ *NrIceTurnServer::Create(turn_server_address_, kDefaultTurnServerPort,
turn_user_, password_vec, kNrIceTransportTcp));
turn_servers.push_back(
- *NrIceTurnServer::Create(turn_server_, kDefaultStunServerPort,
+ *NrIceTurnServer::Create(turn_server_address_, kDefaultTurnServerPort,
turn_user_, password_vec, kNrIceTransportUdp));
SetTurnServers(turn_servers);
// We have to wait for the UDP-based stuff to time out.
ASSERT_TRUE(Gather(kDefaultTimeout * 3));
}
TEST_F(WebRtcIceConnectTest, TestConnectNatBlocksUDP) {
- if (turn_server_.empty())
- return;
-
UseNat();
BlockUdp();
AddStream(1);
std::vector<NrIceTurnServer> turn_servers;
std::vector<unsigned char> password_vec(turn_password_.begin(),
turn_password_.end());
turn_servers.push_back(
- *NrIceTurnServer::Create(turn_server_, kDefaultStunServerPort,
+ *NrIceTurnServer::Create(turn_server_address_, kDefaultTurnServerPort,
turn_user_, password_vec, kNrIceTransportTcp));
turn_servers.push_back(
- *NrIceTurnServer::Create(turn_server_, kDefaultStunServerPort,
+ *NrIceTurnServer::Create(turn_server_address_, kDefaultTurnServerPort,
turn_user_, password_vec, kNrIceTransportUdp));
SetTurnServers(turn_servers);
p1_->SetExpectedTypes(NrIceCandidate::Type::ICE_RELAYED,
NrIceCandidate::Type::ICE_RELAYED,
kNrIceTransportTcp);
p2_->SetExpectedTypes(NrIceCandidate::Type::ICE_RELAYED,
NrIceCandidate::Type::ICE_RELAYED,
kNrIceTransportTcp);
@@ -3300,179 +3284,146 @@ TEST_F(WebRtcIceConnectTest, TestConsent
p1_->SetStunResponseDelay(300);
p2_->SetStunResponseDelay(300);
PR_Sleep(1000);
AssertConsentRefresh();
SendReceive();
}
TEST_F(WebRtcIceConnectTest, TestConnectTurn) {
- if (turn_server_.empty())
- return;
-
AddStream(1);
- SetTurnServer(turn_server_, kDefaultStunServerPort,
+ SetTurnServer(turn_server_address_, kDefaultTurnServerPort,
turn_user_, turn_password_);
ASSERT_TRUE(Gather());
Connect();
}
TEST_F(WebRtcIceConnectTest, TestConnectTurnWithDelay) {
- if (turn_server_.empty())
- return;
-
AddStream(1);
- SetTurnServer(turn_server_, kDefaultStunServerPort,
+ SetTurnServer(turn_server_address_, kDefaultTurnServerPort,
turn_user_, turn_password_);
SetCandidateFilter(SabotageHostCandidateAndDropReflexive);
p1_->Gather();
PR_Sleep(500);
p2_->Gather();
ConnectTrickle(TRICKLE_REAL);
WaitForGather();
WaitForComplete();
}
TEST_F(WebRtcIceConnectTest, TestConnectTurnWithNormalTrickleDelay) {
- if (turn_server_.empty())
- return;
-
AddStream(1);
- SetTurnServer(turn_server_, kDefaultStunServerPort,
+ SetTurnServer(turn_server_address_, kDefaultTurnServerPort,
turn_user_, turn_password_);
ASSERT_TRUE(Gather());
ConnectTrickle();
RealisticTrickleDelay(p1_->ControlTrickle(0));
RealisticTrickleDelay(p2_->ControlTrickle(0));
ASSERT_TRUE_WAIT(p1_->ice_complete(), kDefaultTimeout);
ASSERT_TRUE_WAIT(p2_->ice_complete(), kDefaultTimeout);
AssertCheckingReached();
}
TEST_F(WebRtcIceConnectTest, TestConnectTurnWithNormalTrickleDelayOneSided) {
- if (turn_server_.empty())
- return;
-
AddStream(1);
- SetTurnServer(turn_server_, kDefaultStunServerPort,
+ SetTurnServer(turn_server_address_, kDefaultTurnServerPort,
turn_user_, turn_password_);
ASSERT_TRUE(Gather());
ConnectTrickle();
RealisticTrickleDelay(p1_->ControlTrickle(0));
p2_->SimulateTrickle(0);
ASSERT_TRUE_WAIT(p1_->ice_complete(), kDefaultTimeout);
ASSERT_TRUE_WAIT(p2_->ice_complete(), kDefaultTimeout);
AssertCheckingReached();
}
TEST_F(WebRtcIceConnectTest, TestConnectTurnWithLargeTrickleDelay) {
- if (turn_server_.empty())
- return;
-
AddStream(1);
- SetTurnServer(turn_server_, kDefaultStunServerPort,
+ SetTurnServer(turn_server_address_, kDefaultTurnServerPort,
turn_user_, turn_password_);
SetCandidateFilter(SabotageHostCandidateAndDropReflexive);
ASSERT_TRUE(Gather());
ConnectTrickle();
// Trickle host candidates immediately, but delay relay candidates
DelayRelayCandidates(p1_->ControlTrickle(0), 3700);
DelayRelayCandidates(p2_->ControlTrickle(0), 3700);
ASSERT_TRUE_WAIT(p1_->ice_complete(), kDefaultTimeout);
ASSERT_TRUE_WAIT(p2_->ice_complete(), kDefaultTimeout);
AssertCheckingReached();
}
TEST_F(WebRtcIceConnectTest, TestConnectTurnTcp) {
- if (turn_server_.empty())
- return;
-
AddStream(1);
- SetTurnServer(turn_server_, kDefaultStunServerPort,
+ SetTurnServer(turn_server_address_, kDefaultTurnServerPort,
turn_user_, turn_password_, kNrIceTransportTcp);
ASSERT_TRUE(Gather());
Connect();
}
TEST_F(WebRtcIceConnectTest, TestConnectTurnOnly) {
- if (turn_server_.empty())
- return;
-
AddStream(1);
- SetTurnServer(turn_server_, kDefaultStunServerPort,
+ SetTurnServer(turn_server_address_, kDefaultTurnServerPort,
turn_user_, turn_password_);
ASSERT_TRUE(Gather());
SetCandidateFilter(IsRelayCandidate);
SetExpectedTypes(NrIceCandidate::Type::ICE_RELAYED,
NrIceCandidate::Type::ICE_RELAYED);
Connect();
}
TEST_F(WebRtcIceConnectTest, TestConnectTurnTcpOnly) {
- if (turn_server_.empty())
- return;
-
AddStream(1);
- SetTurnServer(turn_server_, kDefaultStunServerPort,
+ SetTurnServer(turn_server_address_, kDefaultTurnServerPort,
turn_user_, turn_password_, kNrIceTransportTcp);
ASSERT_TRUE(Gather());
SetCandidateFilter(IsRelayCandidate);
SetExpectedTypes(NrIceCandidate::Type::ICE_RELAYED,
NrIceCandidate::Type::ICE_RELAYED,
kNrIceTransportTcp);
Connect();
}
TEST_F(WebRtcIceConnectTest, TestSendReceiveTurnOnly) {
- if (turn_server_.empty())
- return;
-
AddStream(1);
- SetTurnServer(turn_server_, kDefaultStunServerPort,
+ SetTurnServer(turn_server_address_, kDefaultTurnServerPort,
turn_user_, turn_password_);
ASSERT_TRUE(Gather());
SetCandidateFilter(IsRelayCandidate);
SetExpectedTypes(NrIceCandidate::Type::ICE_RELAYED,
NrIceCandidate::Type::ICE_RELAYED);
Connect();
SendReceive();
}
TEST_F(WebRtcIceConnectTest, TestSendReceiveTurnTcpOnly) {
- if (turn_server_.empty())
- return;
-
AddStream(1);
- SetTurnServer(turn_server_, kDefaultStunServerPort,
+ SetTurnServer(turn_server_address_, kDefaultTurnServerPort,
turn_user_, turn_password_, kNrIceTransportTcp);
ASSERT_TRUE(Gather());
SetCandidateFilter(IsRelayCandidate);
SetExpectedTypes(NrIceCandidate::Type::ICE_RELAYED,
NrIceCandidate::Type::ICE_RELAYED,
kNrIceTransportTcp);
Connect();
SendReceive();
}
TEST_F(WebRtcIceConnectTest, TestSendReceiveTurnBothOnly) {
- if (turn_server_.empty())
- return;
-
AddStream(1);
std::vector<NrIceTurnServer> turn_servers;
std::vector<unsigned char> password_vec(turn_password_.begin(),
turn_password_.end());
turn_servers.push_back(*NrIceTurnServer::Create(
- turn_server_, kDefaultStunServerPort,
+ turn_server_address_, kDefaultTurnServerPort,
turn_user_, password_vec, kNrIceTransportTcp));
turn_servers.push_back(*NrIceTurnServer::Create(
- turn_server_, kDefaultStunServerPort,
+ turn_server_address_, kDefaultTurnServerPort,
turn_user_, password_vec, kNrIceTransportUdp));
SetTurnServers(turn_servers);
ASSERT_TRUE(Gather());
SetCandidateFilter(IsRelayCandidate);
// UDP is preferred.
SetExpectedTypes(NrIceCandidate::Type::ICE_RELAYED,
NrIceCandidate::Type::ICE_RELAYED,
kNrIceTransportUdp);
--- a/media/mtransport/test/turn_unittest.cpp
+++ b/media/mtransport/test/turn_unittest.cpp
@@ -79,35 +79,37 @@ extern "C" {
#include "nricemediastream.h"
#include "nricectxhandler.h"
using namespace mozilla;
static std::string kDummyTurnServer("192.0.2.1"); // From RFC 5737
-class TurnClient : public MtransportTest {
+class WebRtcTurn: public MtransportTest {
public:
- TurnClient()
+ WebRtcTurn()
: MtransportTest(),
real_socket_(nullptr),
net_socket_(nullptr),
buffered_socket_(nullptr),
net_fd_(nullptr),
turn_ctx_(nullptr),
allocated_(false),
received_(0),
protocol_(IPPROTO_UDP) {
}
- ~TurnClient() {
+ ~WebRtcTurn() {
}
static void SetUpTestCase() {
- NrIceCtx::InitializeGlobals(false, false, false);
+ NrIceCtx::InitializeGlobals(true, // loopback
+ false, // tcp
+ false); // link local
}
void SetTcp() {
protocol_ = IPPROTO_TCP;
}
void Init_s() {
int r;
@@ -123,18 +125,18 @@ class TurnClient : public MtransportTest
nr_socket_buffered_stun_create(real_socket_, 100000, TURN_TCP_FRAMING,
&buffered_socket_);
ASSERT_EQ(0, r);
net_socket_ = buffered_socket_;
} else {
net_socket_ = real_socket_;
}
- r = nr_str_port_to_transport_addr(turn_server_.c_str(), 3478,
- protocol_, &addr);
+ r = nr_str_port_to_transport_addr(turn_server_address_.c_str(),
+ kDefaultTurnServerPort, protocol_, &addr);
ASSERT_EQ(0, r);
std::vector<unsigned char> password_vec(
turn_password_.begin(), turn_password_.end());
Data password;
INIT_DATA(password, &password_vec[0], password_vec.size());
r = nr_turn_client_ctx_create("test", net_socket_,
turn_user_.c_str(),
@@ -155,33 +157,33 @@ class TurnClient : public MtransportTest
NR_ASYNC_CANCEL(net_fd_, NR_ASYNC_WAIT_READ);
}
nr_socket_destroy(&buffered_socket_);
}
void TearDown() {
RUN_ON_THREAD(test_utils_->sts_target(),
- WrapRunnable(this, &TurnClient::TearDown_s),
+ WrapRunnable(this, &WebRtcTurn::TearDown_s),
NS_DISPATCH_SYNC);
}
void Allocate_s() {
Init_s();
ASSERT_TRUE(turn_ctx_);
int r = nr_turn_client_allocate(turn_ctx_,
allocate_success_cb,
this);
ASSERT_EQ(0, r);
}
void Allocate(bool expect_success=true) {
RUN_ON_THREAD(test_utils_->sts_target(),
- WrapRunnable(this, &TurnClient::Allocate_s),
+ WrapRunnable(this, &WebRtcTurn::Allocate_s),
NS_DISPATCH_SYNC);
if (expect_success) {
ASSERT_TRUE_WAIT(allocated_, 5000);
}
else {
PR_Sleep(10000);
ASSERT_FALSE(allocated_);
@@ -211,17 +213,17 @@ class TurnClient : public MtransportTest
std::cerr << "De-Allocating..." << std::endl;
int r = nr_turn_client_deallocate(turn_ctx_);
ASSERT_EQ(0, r);
}
void Deallocate() {
RUN_ON_THREAD(test_utils_->sts_target(),
- WrapRunnable(this, &TurnClient::Deallocate_s),
+ WrapRunnable(this, &WebRtcTurn::Deallocate_s),
NS_DISPATCH_SYNC);
}
void RequestPermission_s(const std::string& target) {
nr_transport_addr addr;
int r;
// Expected pattern here is "IP4:127.0.0.1:3487"
@@ -240,17 +242,17 @@ class TurnClient : public MtransportTest
ASSERT_EQ(0, r);
r = nr_turn_client_ensure_perm(turn_ctx_, &addr);
ASSERT_EQ(0, r);
}
void RequestPermission(const std::string& target) {
RUN_ON_THREAD(test_utils_->sts_target(),
- WrapRunnable(this, &TurnClient::RequestPermission_s, target),
+ WrapRunnable(this, &WebRtcTurn::RequestPermission_s, target),
NS_DISPATCH_SYNC);
}
void Readable(NR_SOCKET s, int how, void *arg) {
// Re-arm
std::cerr << "Socket is readable" << std::endl;
NR_ASYNC_WAIT(s, how, socket_readable_cb, arg);
@@ -338,96 +340,77 @@ class TurnClient : public MtransportTest
&addr);
if (expect_return >= 0) {
ASSERT_EQ(expect_return, r);
}
}
void SendTo(const std::string& target, int expect_return=0) {
RUN_ON_THREAD(test_utils_->sts_target(),
- WrapRunnable(this, &TurnClient::SendTo_s, target,
+ WrapRunnable(this, &WebRtcTurn::SendTo_s, target,
expect_return),
NS_DISPATCH_SYNC);
}
int received() const { return received_; }
static void socket_readable_cb(NR_SOCKET s, int how, void *arg) {
- static_cast<TurnClient *>(arg)->Readable(s, how, arg);
+ static_cast<WebRtcTurn*>(arg)->Readable(s, how, arg);
}
static void allocate_success_cb(NR_SOCKET s, int how, void *arg){
- static_cast<TurnClient *>(arg)->Allocated();
+ static_cast<WebRtcTurn*>(arg)->Allocated();
}
protected:
- std::string turn_server_;
nr_socket *real_socket_;
nr_socket *net_socket_;
nr_socket *buffered_socket_;
NR_SOCKET net_fd_;
nr_turn_client_ctx *turn_ctx_;
std::string relay_addr_;
bool allocated_;
int received_;
int protocol_;
};
-TEST_F(TurnClient, Allocate) {
- if (WarnIfTurnNotConfigured())
- return;
-
+TEST_F(WebRtcTurn, Allocate) {
Allocate();
}
-TEST_F(TurnClient, AllocateTcp) {
- if (WarnIfTurnNotConfigured())
- return;
-
+TEST_F(WebRtcTurn, AllocateTcp) {
SetTcp();
Allocate();
}
-TEST_F(TurnClient, AllocateAndHold) {
- if (WarnIfTurnNotConfigured())
- return;
-
+TEST_F(WebRtcTurn, AllocateAndHold) {
Allocate();
PR_Sleep(20000);
ASSERT_TRUE(turn_ctx_->state == NR_TURN_CLIENT_STATE_ALLOCATED);
}
-TEST_F(TurnClient, SendToSelf) {
- if (WarnIfTurnNotConfigured())
- return;
-
+TEST_F(WebRtcTurn, SendToSelf) {
Allocate();
SendTo(relay_addr_);
ASSERT_TRUE_WAIT(received() == 100, 5000);
SendTo(relay_addr_);
ASSERT_TRUE_WAIT(received() == 200, 1000);
}
-TEST_F(TurnClient, SendToSelfTcp) {
- if (WarnIfTurnNotConfigured())
- return;
-
+TEST_F(WebRtcTurn, SendToSelfTcp) {
SetTcp();
Allocate();
SendTo(relay_addr_);
ASSERT_TRUE_WAIT(received() == 100, 5000);
SendTo(relay_addr_);
ASSERT_TRUE_WAIT(received() == 200, 1000);
}
-TEST_F(TurnClient, PermissionDenied) {
- if (WarnIfTurnNotConfigured())
- return;
-
+TEST_F(WebRtcTurn, PermissionDenied) {
Allocate();
RequestPermission(relay_addr_);
PR_Sleep(1000);
/* Fake a 403 response */
nr_turn_permission *perm;
perm = STAILQ_FIRST(&turn_ctx_->permissions);
ASSERT_TRUE(perm);
@@ -440,48 +423,39 @@ TEST_F(TurnClient, PermissionDenied) {
SendTo(relay_addr_, R_NOT_PERMITTED);
ASSERT_TRUE(received() == 0);
//TODO: We should check if we can still send to a second destination, but
// we would need a second TURN client as one client can only handle one
// allocation (maybe as part of bug 1128128 ?).
}
-TEST_F(TurnClient, DeallocateReceiveFailure) {
- if (WarnIfTurnNotConfigured())
- return;
-
+TEST_F(WebRtcTurn, DeallocateReceiveFailure) {
Allocate();
SendTo(relay_addr_);
ASSERT_TRUE_WAIT(received() == 100, 5000);
Deallocate();
turn_ctx_->state = NR_TURN_CLIENT_STATE_ALLOCATED;
SendTo(relay_addr_);
PR_Sleep(1000);
ASSERT_TRUE(received() == 100);
}
-TEST_F(TurnClient, DeallocateReceiveFailureTcp) {
- if (WarnIfTurnNotConfigured())
- return;
-
+TEST_F(WebRtcTurn, DeallocateReceiveFailureTcp) {
SetTcp();
Allocate();
SendTo(relay_addr_);
ASSERT_TRUE_WAIT(received() == 100, 5000);
Deallocate();
turn_ctx_->state = NR_TURN_CLIENT_STATE_ALLOCATED;
/* Either the connection got closed by the TURN server already, then the send
* is going to fail, which we simply ignore. Or the connection is still alive
* and we cand send the data, but it should not get forwarded to us. In either
* case we should not receive more data. */
SendTo(relay_addr_, -1);
PR_Sleep(1000);
ASSERT_TRUE(received() == 100);
}
-TEST_F(TurnClient, AllocateDummyServer) {
- if (WarnIfTurnNotConfigured())
- return;
-
- turn_server_ = kDummyTurnServer;
+TEST_F(WebRtcTurn, AllocateDummyServer) {
+ turn_server_address_ = kDummyTurnServer;
Allocate(false);
}
--- a/python/mozbuild/mozbuild/mach_commands.py
+++ b/python/mozbuild/mozbuild/mach_commands.py
@@ -990,16 +990,161 @@ class GTestCommands(MachCommandBase):
print("(We can't handle the %r character.)" % e.char)
return 1
# Prepend the debugger args.
args = [debuggerInfo.path] + debuggerInfo.args + args
return args
@CommandProvider
+class GTestWebRtcCommands(MachCommandBase):
+ @Command('gtest-webrtc', category='testing',
+ description='Run WebRTC GTest unit tests (C++ tests).')
+ @CommandArgument('gtest_filter', default=b"*", nargs='?', metavar='gtest_filter',
+ help="test_filter is a ':'-separated list of wildcard patterns (called the positive patterns),"
+ "optionally followed by a '-' and another ':'-separated pattern list (called the negative patterns).")
+ @CommandArgument('--jobs', '-j', default='1', nargs='?', metavar='jobs', type=int,
+ help='Run the tests in parallel using multiple processes.')
+ @CommandArgument('--tbpl-parser', '-t', action='store_true',
+ help='Output test results in a format that can be parsed by TBPL.')
+ @CommandArgument('--shuffle', '-s', action='store_true',
+ help='Randomize the execution order of tests.')
+
+ @CommandArgumentGroup('debugging')
+ @CommandArgument('--debug', action='store_true', group='debugging',
+ help='Enable the debugger. Not specifying a --debugger option will result in the default debugger being used.')
+ @CommandArgument('--debugger', default=None, type=str, group='debugging',
+ help='Name of debugger to use.')
+ @CommandArgument('--debugger-args', default=None, metavar='params', type=str,
+ group='debugging',
+ help='Command-line arguments to pass to the debugger itself; split as the Bourne shell would.')
+
+
+ def gtest_webrtc(self, shuffle, jobs, gtest_filter, tbpl_parser, debug, debugger,
+ debugger_args):
+
+ # We lazy build gtest because it's slow to link
+ self._run_make(directory="testing/gtest", target='gtest',
+ print_directory=False, ensure_exit_code=True)
+
+ app_path = self.get_binary_path('app')
+ args = [app_path, '-unittest'];
+
+ if debug or debugger or debugger_args:
+ args = self.prepend_debugger_args(args, debugger, debugger_args)
+
+ cwd = os.path.join(self.topobjdir, '_tests', 'gtest')
+
+ if not os.path.isdir(cwd):
+ os.makedirs(cwd)
+
+ # Use GTest environment variable to control test execution
+ # For details see:
+ # https://code.google.com/p/googletest/wiki/AdvancedGuide#Running_Test_Programs:_Advanced_Options
+ if (gtest_filter == '*'):
+ gtest_env = {b'GTEST_FILTER': 'WebRtcIce*:WebRtcTurn.*'}
+ else:
+ gtest_env = {b'GTEST_FILTER': gtest_filter}
+
+ # Note: we must normalize the path here so that gtest on Windows sees
+ # a MOZ_GMP_PATH which has only Windows dir seperators, because
+ # nsILocalFile cannot open the paths with non-Windows dir seperators.
+ xre_path = os.path.join(os.path.normpath(self.topobjdir), "dist", "bin")
+ gtest_env["MOZ_XRE_DIR"] = xre_path
+ gtest_env["MOZ_GMP_PATH"] = os.pathsep.join(
+ os.path.join(xre_path, p, "1.0")
+ for p in ('gmp-fake', 'gmp-fakeopenh264')
+ )
+
+ gtest_env[b"MOZ_RUN_GTEST"] = b"True"
+
+ if shuffle:
+ gtest_env[b"GTEST_SHUFFLE"] = b"True"
+
+ if tbpl_parser:
+ gtest_env[b"MOZ_TBPL_PARSER"] = b"True"
+
+ if jobs == 1:
+ return self.run_process(args=args,
+ append_env=gtest_env,
+ cwd=cwd,
+ ensure_exit_code=False,
+ pass_thru=True)
+
+ from mozprocess import ProcessHandlerMixin
+ import functools
+ def handle_line(job_id, line):
+ # Prepend the jobId
+ line = '[%d] %s' % (job_id + 1, line.strip())
+ self.log(logging.INFO, "GTest", {'line': line}, '{line}')
+
+ gtest_env["GTEST_TOTAL_SHARDS"] = str(jobs)
+ processes = {}
+ for i in range(0, jobs):
+ gtest_env["GTEST_SHARD_INDEX"] = str(i)
+ processes[i] = ProcessHandlerMixin([app_path, "-unittest"],
+ cwd=cwd,
+ env=gtest_env,
+ processOutputLine=[functools.partial(handle_line, i)],
+ universal_newlines=True)
+ processes[i].run()
+
+ exit_code = 0
+ for process in processes.values():
+ status = process.wait()
+ if status:
+ exit_code = status
+
+ # Clamp error code to 255 to prevent overflowing multiple of
+ # 256 into 0
+ if exit_code > 255:
+ exit_code = 255
+
+ return exit_code
+
+ def prepend_debugger_args(self, args, debugger, debugger_args):
+ '''
+ Given an array with program arguments, prepend arguments to run it under a
+ debugger.
+
+ :param args: The executable and arguments used to run the process normally.
+ :param debugger: The debugger to use, or empty to use the default debugger.
+ :param debugger_args: Any additional parameters to pass to the debugger.
+ '''
+
+ import mozdebug
+
+ if not debugger:
+ # No debugger name was provided. Look for the default ones on
+ # current OS.
+ debugger = mozdebug.get_default_debugger_name(mozdebug.DebuggerSearch.KeepLooking)
+
+ if debugger:
+ debuggerInfo = mozdebug.get_debugger_info(debugger, debugger_args)
+ if not debuggerInfo:
+ print("Could not find a suitable debugger in your PATH.")
+ return 1
+
+ # Parameters come from the CLI. We need to convert them before
+ # their use.
+ if debugger_args:
+ from mozbuild import shellutil
+ try:
+ debugger_args = shellutil.split(debugger_args)
+ except shellutil.MetaCharacterException as e:
+ print("The --debugger_args you passed require a real shell to parse them.")
+ print("(We can't handle the %r character.)" % e.char)
+ return 1
+
+ # Prepend the debugger args.
+ args = [debuggerInfo.path] + debuggerInfo.args + args
+ return args
+
+
+@CommandProvider
class ClangCommands(MachCommandBase):
@Command('clang-complete', category='devenv',
description='Generate a .clang_complete file.')
def clang_complete(self):
import shlex
build_vars = {}
--- a/testing/tools/iceserver/iceserver.py
+++ b/testing/tools/iceserver/iceserver.py
@@ -396,28 +396,28 @@ class StunHandler(object):
server, along with Allocation.
"""
def __init__(self, transport_handler):
self.client_address = None
self.data = str()
self.transport_handler = transport_handler
- def data_received(self, data, address):
+ def data_received(self, data, reply_address, address):
self.data += bytearray(data)
while True:
stun_message = StunMessage()
parsed_len = stun_message.parse(self.data)
if parsed_len > len(self.data):
break
self.data = self.data[parsed_len:]
response = self.handle_stun(stun_message, address)
if response:
- self.transport_handler.write(response, address)
+ self.transport_handler.write(response, reply_address)
def handle_stun(self, stun_message, address):
self.client_address = address
if stun_message.msg_class == INDICATION:
if stun_message.method == SEND:
self.handle_send_indication(stun_message)
else:
print("Dropping unknown indication method: {}"
@@ -557,16 +557,24 @@ class StunHandler(object):
def handle_send_indication(self, indication):
try:
allocation = allocations[self.get_allocation_tuple()]
except KeyError:
print("Dropping send indication; no allocation for tuple {}"
.format(self.get_allocation_tuple()))
return
+ if allocation.expiry <= time.time():
+ print("Rejecting send indication, binding expired")
+ return self.make_error_response(
+ indication,
+ 437,
+ ("Refresh request for non-existing allocation, tuple {}"
+ .format(self.get_allocation_tuple())))
+
peer_address = indication.get_xor_address(XOR_PEER_ADDRESS)
if not peer_address:
print("Dropping send indication, missing XOR-PEER-ADDRESS")
return
data_attr = indication.find(DATA_ATTR)
if not data_attr:
print("Dropping send indication, missing DATA")
@@ -636,48 +644,61 @@ class StunHandler(object):
return self.make_success_response(request)
class UdpStunHandler(protocol.DatagramProtocol):
"""
Represents a UDP listen port for TURN.
"""
+ def __init__(self, fakePort=False):
+ self.fakePort = fakePort
+
def datagramReceived(self, data, address):
stun_handler = StunHandler(self)
- stun_handler.data_received(data,
- IPv4Address('UDP', address[0], address[1]))
+ addr = IPv4Address('UDP', address[0], address[1])
+ stun_addr = addr
+ if (self.fakePort):
+ stun_addr = IPv4Address('UDP', address[0], address[1] + 5)
+ stun_handler.data_received(data, addr, stun_addr)
def write(self, data, address):
self.transport.write(str(data), (address.host, address.port))
class TcpStunHandlerFactory(protocol.Factory):
"""
Represents a TCP listen port for TURN.
"""
+ def __init__(self, fakePort=False):
+ self.fakePort = fakePort
+
def buildProtocol(self, addr):
- return TcpStunHandler(addr)
+ return TcpStunHandler(addr, self.fakePort)
class TcpStunHandler(protocol.Protocol):
"""
Represents a connected TCP port for TURN.
"""
- def __init__(self, addr):
+ def __init__(self, addr, fakePort):
self.address = addr
+ self.fakePort = fakePort
self.stun_handler = None
def dataReceived(self, data):
# This needs to persist, since it handles framing
if not self.stun_handler:
self.stun_handler = StunHandler(self)
- self.stun_handler.data_received(data, self.address)
+ stun_addr = self.address
+ if (self.fakePort):
+ stun_addr = IPv4Address('TCP', self.address[0], self.address[1] + 5)
+ self.stun_handler.data_received(data, self.address, stun_addr)
def connectionLost(self, reason):
print("Lost connection from {}".format(self.address))
# Destroy allocations that this connection made
for key, allocation in allocations.items():
if allocation.other_transport_handler == self:
print("Closing allocation due to dropped connection: {}"
.format(key))
@@ -702,58 +723,66 @@ turn_user="foo"
turn_pass="bar"
turn_realm="mozilla.invalid"
allocations = {}
v4_address = get_default_route(socket.AF_INET)
try:
v6_address = get_default_route(socket.AF_INET6)
except:
v6_address = ""
+v4_address_loopback = "127.0.0.1"
+v6_address_loopback = "::1"
+hostname = socket.gethostname()
def prune_allocations():
now = time.time()
for key, allocation in allocations.items():
if allocation.expiry < now:
print("Allocation expired: {}".format(key))
del allocations[key]
allocation.close()
if __name__ == "__main__":
random.seed()
- if platform.system() is "Windows":
- # Windows is finicky about allowing real interfaces to talk to loopback.
- interface_4 = v4_address
- interface_6 = v6_address
- hostname = socket.gethostname()
- else:
- # Our linux builders do not have a hostname that resolves to the real
- # interface.
- interface_4 = "127.0.0.1"
- interface_6 = "::1"
- hostname = "localhost"
-
- reactor.listenUDP(3478, UdpStunHandler(), interface=interface_4)
- reactor.listenTCP(3478, TcpStunHandlerFactory(), interface=interface_4)
+ reactor.listenUDP(3478, UdpStunHandler(), interface=v4_address)
+ reactor.listenUDP(3478, UdpStunHandler(), interface=v4_address_loopback)
+ reactor.listenTCP(3478, TcpStunHandlerFactory(), interface=v4_address)
+ reactor.listenTCP(3478, TcpStunHandlerFactory(), interface=v4_address_loopback)
try:
- reactor.listenUDP(3478, UdpStunHandler(), interface=interface_6)
- reactor.listenTCP(3478, TcpStunHandlerFactory(), interface=interface_6)
+ reactor.listenUDP(3478, UdpStunHandler(), interface=v6_address)
+ reactor.listenUDP(3478, UdpStunHandler(), interface=v6_address_loopback)
+ reactor.listenTCP(3478, TcpStunHandlerFactory(), interface=v6_address)
+ reactor.listenTCP(3478, TcpStunHandlerFactory(), interface=v6_address_loopback)
+
except:
pass
+ try:
+ reactor.listenUDP(3479, UdpStunHandler(fakePort=True), interface=v4_address)
+ reactor.listenUDP(3479, UdpStunHandler(fakePort=True), interface=v4_address_loopback)
+ reactor.listenTCP(3479, TcpStunHandlerFactory(fakePort=True), interface=v4_address)
+ reactor.listenTCP(3479, TcpStunHandlerFactory(fakePort=True), interface=v4_address_loopback)
+ reactor.listenUDP(3479, UdpStunHandler(fakePort=True), interface=v6_address)
+ reactor.listenUDP(3479, UdpStunHandler(fakePort=True), interface=v6_address_loopback)
+ reactor.listenTCP(3479, TcpStunHandlerFactory(fakePort=True), interface=v6_address)
+ reactor.listenTCP(3479, TcpStunHandlerFactory(fakePort=True), interface=v6_address_loopback)
+ except:
+ print('failed')
+
allocation_pruner = LoopingCall(prune_allocations)
allocation_pruner.start(1)
template = Template(
'[\
{"url":"stun:$hostname"}, \
{"url":"stun:$hostname?transport=tcp"}, \
{"username":"$user","credential":"$pwd","url":"turn:$hostname"}, \
-{"username":"$user","credential":"$pwd","url":"turn:$hostname?transport=tcp"}]'
-)
+{"username":"$user","credential":"$pwd","url":"turn:$hostname?transport=tcp"}\
+]')
print(template.substitute(user=turn_user,
pwd=turn_pass,
hostname=hostname))
reactor.run()