Adding an end-to-end connection time test.
The test uses a fake clock and simulates network and signaling delays in order to get a repeatable measurement of the time to establish a connection (including DTLS). This will help ensure that various optimizations continue to work as expected, and no new delays are introduced. This CL depends on: https://codereview.webrtc.org/2140283002/ R=honghaiz@webrtc.org, pthatcher@webrtc.org, skvlad@webrtc.org Review URL: https://codereview.webrtc.org/2141863003 . Cr-Commit-Position: refs/heads/master@{#14270}
This commit is contained in:
parent
de65ddc212
commit
e5835f5d84
@ -30,6 +30,7 @@
|
||||
#include "webrtc/api/test/fakertccertificategenerator.h"
|
||||
#include "webrtc/api/test/fakevideotrackrenderer.h"
|
||||
#include "webrtc/api/test/mockpeerconnectionobservers.h"
|
||||
#include "webrtc/base/fakenetwork.h"
|
||||
#include "webrtc/base/gunit.h"
|
||||
#include "webrtc/base/helpers.h"
|
||||
#include "webrtc/base/physicalsocketserver.h"
|
||||
@ -38,9 +39,10 @@
|
||||
#include "webrtc/base/thread.h"
|
||||
#include "webrtc/base/virtualsocketserver.h"
|
||||
#include "webrtc/media/engine/fakewebrtcvideoengine.h"
|
||||
#include "webrtc/p2p/base/fakeportallocator.h"
|
||||
#include "webrtc/p2p/base/p2pconstants.h"
|
||||
#include "webrtc/p2p/base/sessiondescription.h"
|
||||
#include "webrtc/p2p/base/testturnserver.h"
|
||||
#include "webrtc/p2p/client/basicportallocator.h"
|
||||
#include "webrtc/pc/mediasession.h"
|
||||
|
||||
#define MAYBE_SKIP_TEST(feature) \
|
||||
@ -104,6 +106,20 @@ static const int kDefaultSrtpCryptoSuite = rtc::SRTP_AES128_CM_SHA1_32;
|
||||
static const int kDefaultSrtpCryptoSuiteGcm = rtc::SRTP_AEAD_AES_256_GCM;
|
||||
#endif
|
||||
|
||||
// Used to simulate signaling ICE/SDP between two PeerConnections.
|
||||
enum Message { MSG_SDP_MESSAGE, MSG_ICE_MESSAGE };
|
||||
|
||||
struct SdpMessage {
|
||||
std::string type;
|
||||
std::string msg;
|
||||
};
|
||||
|
||||
struct IceMessage {
|
||||
std::string sdp_mid;
|
||||
int sdp_mline_index;
|
||||
std::string msg;
|
||||
};
|
||||
|
||||
static void RemoveLinesFromSdp(const std::string& line_start,
|
||||
std::string* sdp) {
|
||||
const char kSdpLineEnd[] = "\r\n";
|
||||
@ -169,13 +185,15 @@ class MockRtpReceiverObserver : public webrtc::RtpReceiverObserverInterface {
|
||||
|
||||
class PeerConnectionTestClient : public webrtc::PeerConnectionObserver,
|
||||
public SignalingMessageReceiver,
|
||||
public ObserverInterface {
|
||||
public ObserverInterface,
|
||||
public rtc::MessageHandler {
|
||||
public:
|
||||
// If |config| is not provided, uses a default constructed RTCConfiguration.
|
||||
static PeerConnectionTestClient* CreateClientWithDtlsIdentityStore(
|
||||
const std::string& id,
|
||||
const MediaConstraintsInterface* constraints,
|
||||
const PeerConnectionFactory::Options* options,
|
||||
const PeerConnectionInterface::RTCConfiguration& config,
|
||||
const PeerConnectionInterface::RTCConfiguration* config,
|
||||
std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator,
|
||||
bool prefer_constraint_apis,
|
||||
rtc::Thread* network_thread,
|
||||
@ -193,7 +211,7 @@ class PeerConnectionTestClient : public webrtc::PeerConnectionObserver,
|
||||
const std::string& id,
|
||||
const MediaConstraintsInterface* constraints,
|
||||
const PeerConnectionFactory::Options* options,
|
||||
const PeerConnectionInterface::RTCConfiguration& config,
|
||||
const PeerConnectionInterface::RTCConfiguration* config,
|
||||
rtc::Thread* network_thread,
|
||||
rtc::Thread* worker_thread) {
|
||||
std::unique_ptr<FakeRTCCertificateGenerator> cert_generator(
|
||||
@ -208,14 +226,13 @@ class PeerConnectionTestClient : public webrtc::PeerConnectionObserver,
|
||||
static PeerConnectionTestClient* CreateClientPreferNoConstraints(
|
||||
const std::string& id,
|
||||
const PeerConnectionFactory::Options* options,
|
||||
const PeerConnectionInterface::RTCConfiguration& config,
|
||||
rtc::Thread* network_thread,
|
||||
rtc::Thread* worker_thread) {
|
||||
std::unique_ptr<FakeRTCCertificateGenerator> cert_generator(
|
||||
rtc::SSLStreamAdapter::HaveDtlsSrtp() ?
|
||||
new FakeRTCCertificateGenerator() : nullptr);
|
||||
|
||||
return CreateClientWithDtlsIdentityStore(id, nullptr, options, config,
|
||||
return CreateClientWithDtlsIdentityStore(id, nullptr, options, nullptr,
|
||||
std::move(cert_generator), false,
|
||||
network_thread, worker_thread);
|
||||
}
|
||||
@ -239,8 +256,64 @@ class PeerConnectionTestClient : public webrtc::PeerConnectionObserver,
|
||||
std::string sdp;
|
||||
EXPECT_TRUE(offer->ToString(&sdp));
|
||||
EXPECT_TRUE(DoSetLocalDescription(offer.release()));
|
||||
signaling_message_receiver_->ReceiveSdpMessage(
|
||||
webrtc::SessionDescriptionInterface::kOffer, sdp);
|
||||
SendSdpMessage(webrtc::SessionDescriptionInterface::kOffer, sdp);
|
||||
}
|
||||
|
||||
void SendSdpMessage(const std::string& type, std::string& msg) {
|
||||
if (signaling_delay_ms_ == 0) {
|
||||
if (signaling_message_receiver_) {
|
||||
signaling_message_receiver_->ReceiveSdpMessage(type, msg);
|
||||
}
|
||||
} else {
|
||||
rtc::Thread::Current()->PostDelayed(
|
||||
RTC_FROM_HERE, signaling_delay_ms_, this, MSG_SDP_MESSAGE,
|
||||
new rtc::TypedMessageData<SdpMessage>({type, msg}));
|
||||
}
|
||||
}
|
||||
|
||||
void SendIceMessage(const std::string& sdp_mid,
|
||||
int sdp_mline_index,
|
||||
const std::string& msg) {
|
||||
if (signaling_delay_ms_ == 0) {
|
||||
if (signaling_message_receiver_) {
|
||||
signaling_message_receiver_->ReceiveIceMessage(sdp_mid, sdp_mline_index,
|
||||
msg);
|
||||
}
|
||||
} else {
|
||||
rtc::Thread::Current()->PostDelayed(RTC_FROM_HERE, signaling_delay_ms_,
|
||||
this, MSG_ICE_MESSAGE,
|
||||
new rtc::TypedMessageData<IceMessage>(
|
||||
{sdp_mid, sdp_mline_index, msg}));
|
||||
}
|
||||
}
|
||||
|
||||
// MessageHandler callback.
|
||||
void OnMessage(rtc::Message* msg) override {
|
||||
switch (msg->message_id) {
|
||||
case MSG_SDP_MESSAGE: {
|
||||
auto sdp_message =
|
||||
static_cast<rtc::TypedMessageData<SdpMessage>*>(msg->pdata);
|
||||
if (signaling_message_receiver_) {
|
||||
signaling_message_receiver_->ReceiveSdpMessage(
|
||||
sdp_message->data().type, sdp_message->data().msg);
|
||||
}
|
||||
delete sdp_message;
|
||||
break;
|
||||
}
|
||||
case MSG_ICE_MESSAGE: {
|
||||
auto ice_message =
|
||||
static_cast<rtc::TypedMessageData<IceMessage>*>(msg->pdata);
|
||||
if (signaling_message_receiver_) {
|
||||
signaling_message_receiver_->ReceiveIceMessage(
|
||||
ice_message->data().sdp_mid, ice_message->data().sdp_mline_index,
|
||||
ice_message->data().msg);
|
||||
}
|
||||
delete ice_message;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
RTC_CHECK(false);
|
||||
}
|
||||
}
|
||||
|
||||
// SignalingMessageReceiver callback.
|
||||
@ -299,8 +372,7 @@ class PeerConnectionTestClient : public webrtc::PeerConnectionObserver,
|
||||
// Remote party may be deleted.
|
||||
return;
|
||||
}
|
||||
signaling_message_receiver_->ReceiveIceMessage(
|
||||
candidate->sdp_mid(), candidate->sdp_mline_index(), ice_sdp);
|
||||
SendIceMessage(candidate->sdp_mid(), candidate->sdp_mline_index(), ice_sdp);
|
||||
}
|
||||
|
||||
// MediaStreamInterface callback
|
||||
@ -375,6 +447,8 @@ class PeerConnectionTestClient : public webrtc::PeerConnectionObserver,
|
||||
signaling_message_receiver_ = signaling_message_receiver;
|
||||
}
|
||||
|
||||
void set_signaling_delay_ms(int delay_ms) { signaling_delay_ms_ = delay_ms; }
|
||||
|
||||
void EnableVideoDecoderFactory() {
|
||||
video_decoder_factory_enabled_ = true;
|
||||
fake_video_decoder_factory_->AddSupportedVideoCodecType(
|
||||
@ -402,6 +476,9 @@ class PeerConnectionTestClient : public webrtc::PeerConnectionObserver,
|
||||
bool ExpectIceRenomination() { return expect_ice_renomination_; }
|
||||
bool ExpectRemoteIceRenomination() { return expect_remote_ice_renomination_; }
|
||||
|
||||
// The below 3 methods assume streams will be offered.
|
||||
// Thus they'll only set the "offer to receive" flag to true if it's
|
||||
// currently false, not if it's just unset.
|
||||
void SetReceiveAudioVideo(bool audio, bool video) {
|
||||
SetReceiveAudio(audio);
|
||||
SetReceiveVideo(video);
|
||||
@ -410,15 +487,24 @@ class PeerConnectionTestClient : public webrtc::PeerConnectionObserver,
|
||||
}
|
||||
|
||||
void SetReceiveAudio(bool audio) {
|
||||
if (audio && can_receive_audio())
|
||||
if (audio && can_receive_audio()) {
|
||||
return;
|
||||
}
|
||||
offer_answer_constraints_.SetMandatoryReceiveAudio(audio);
|
||||
offer_answer_options_.offer_to_receive_audio = audio ? 1 : 0;
|
||||
}
|
||||
|
||||
void SetReceiveVideo(bool video) {
|
||||
if (video && can_receive_video())
|
||||
if (video && can_receive_video()) {
|
||||
return;
|
||||
}
|
||||
offer_answer_constraints_.SetMandatoryReceiveVideo(video);
|
||||
offer_answer_options_.offer_to_receive_video = video ? 1 : 0;
|
||||
}
|
||||
|
||||
void SetOfferToReceiveAudioVideo(bool audio, bool video) {
|
||||
offer_answer_constraints_.SetMandatoryReceiveAudio(audio);
|
||||
offer_answer_options_.offer_to_receive_audio = audio ? 1 : 0;
|
||||
offer_answer_constraints_.SetMandatoryReceiveVideo(video);
|
||||
offer_answer_options_.offer_to_receive_video = video ? 1 : 0;
|
||||
}
|
||||
@ -896,7 +982,7 @@ class PeerConnectionTestClient : public webrtc::PeerConnectionObserver,
|
||||
bool Init(
|
||||
const MediaConstraintsInterface* constraints,
|
||||
const PeerConnectionFactory::Options* options,
|
||||
const PeerConnectionInterface::RTCConfiguration& config,
|
||||
const PeerConnectionInterface::RTCConfiguration* config,
|
||||
std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator,
|
||||
bool prefer_constraint_apis,
|
||||
rtc::Thread* network_thread,
|
||||
@ -908,8 +994,11 @@ class PeerConnectionTestClient : public webrtc::PeerConnectionObserver,
|
||||
}
|
||||
prefer_constraint_apis_ = prefer_constraint_apis;
|
||||
|
||||
fake_network_manager_.reset(new rtc::FakeNetworkManager());
|
||||
fake_network_manager_->AddInterface(rtc::SocketAddress("192.168.1.1", 0));
|
||||
|
||||
std::unique_ptr<cricket::PortAllocator> port_allocator(
|
||||
new cricket::FakePortAllocator(network_thread, nullptr));
|
||||
new cricket::BasicPortAllocator(fake_network_manager_.get()));
|
||||
fake_audio_capture_module_ = FakeAudioCaptureModule::Create();
|
||||
|
||||
if (fake_audio_capture_module_ == nullptr) {
|
||||
@ -931,17 +1020,23 @@ class PeerConnectionTestClient : public webrtc::PeerConnectionObserver,
|
||||
peer_connection_ =
|
||||
CreatePeerConnection(std::move(port_allocator), constraints, config,
|
||||
std::move(cert_generator));
|
||||
|
||||
return peer_connection_.get() != nullptr;
|
||||
}
|
||||
|
||||
rtc::scoped_refptr<webrtc::PeerConnectionInterface> CreatePeerConnection(
|
||||
std::unique_ptr<cricket::PortAllocator> port_allocator,
|
||||
const MediaConstraintsInterface* constraints,
|
||||
const PeerConnectionInterface::RTCConfiguration& config,
|
||||
const PeerConnectionInterface::RTCConfiguration* config,
|
||||
std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator) {
|
||||
// CreatePeerConnection with RTCConfiguration.
|
||||
PeerConnectionInterface::RTCConfiguration default_config;
|
||||
|
||||
if (!config) {
|
||||
config = &default_config;
|
||||
}
|
||||
|
||||
return peer_connection_factory_->CreatePeerConnection(
|
||||
config, constraints, std::move(port_allocator),
|
||||
*config, constraints, std::move(port_allocator),
|
||||
std::move(cert_generator), this);
|
||||
}
|
||||
|
||||
@ -961,10 +1056,7 @@ class PeerConnectionTestClient : public webrtc::PeerConnectionObserver,
|
||||
std::string sdp;
|
||||
EXPECT_TRUE(answer->ToString(&sdp));
|
||||
EXPECT_TRUE(DoSetLocalDescription(answer.release()));
|
||||
if (signaling_message_receiver_) {
|
||||
signaling_message_receiver_->ReceiveSdpMessage(
|
||||
webrtc::SessionDescriptionInterface::kAnswer, sdp);
|
||||
}
|
||||
SendSdpMessage(webrtc::SessionDescriptionInterface::kAnswer, sdp);
|
||||
}
|
||||
|
||||
void HandleIncomingAnswer(const std::string& msg) {
|
||||
@ -1065,6 +1157,8 @@ class PeerConnectionTestClient : public webrtc::PeerConnectionObserver,
|
||||
|
||||
std::string id_;
|
||||
|
||||
std::unique_ptr<rtc::FakeNetworkManager> fake_network_manager_;
|
||||
|
||||
rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection_;
|
||||
rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface>
|
||||
peer_connection_factory_;
|
||||
@ -1095,6 +1189,7 @@ class PeerConnectionTestClient : public webrtc::PeerConnectionObserver,
|
||||
|
||||
// For remote peer communication.
|
||||
SignalingMessageReceiver* signaling_message_receiver_ = nullptr;
|
||||
int signaling_delay_ms_ = 0;
|
||||
|
||||
// Store references to the video capturers we've created, so that we can stop
|
||||
// them, if required.
|
||||
@ -1129,9 +1224,6 @@ class P2PTestConductor : public testing::Test {
|
||||
worker_thread_(rtc::Thread::Create()) {
|
||||
RTC_CHECK(network_thread_->Start());
|
||||
RTC_CHECK(worker_thread_->Start());
|
||||
webrtc::PeerConnectionInterface::IceServer ice_server;
|
||||
ice_server.uri = "stun:stun.l.google.com:19302";
|
||||
config_.servers.push_back(ice_server);
|
||||
}
|
||||
|
||||
bool SessionActive() {
|
||||
@ -1234,19 +1326,24 @@ class P2PTestConductor : public testing::Test {
|
||||
|
||||
bool CreateTestClients(MediaConstraintsInterface* init_constraints,
|
||||
MediaConstraintsInterface* recv_constraints) {
|
||||
return CreateTestClients(init_constraints, nullptr, recv_constraints,
|
||||
nullptr);
|
||||
return CreateTestClients(init_constraints, nullptr, nullptr,
|
||||
recv_constraints, nullptr, nullptr);
|
||||
}
|
||||
|
||||
bool CreateTestClients(
|
||||
const PeerConnectionInterface::RTCConfiguration& init_config,
|
||||
const PeerConnectionInterface::RTCConfiguration& recv_config) {
|
||||
return CreateTestClients(nullptr, nullptr, &init_config, nullptr, nullptr,
|
||||
&recv_config);
|
||||
}
|
||||
|
||||
bool CreateTestClientsThatPreferNoConstraints() {
|
||||
initiating_client_.reset(
|
||||
PeerConnectionTestClient::CreateClientPreferNoConstraints(
|
||||
"Caller: ", nullptr, config_, network_thread_.get(),
|
||||
worker_thread_.get()));
|
||||
"Caller: ", nullptr, network_thread_.get(), worker_thread_.get()));
|
||||
receiving_client_.reset(
|
||||
PeerConnectionTestClient::CreateClientPreferNoConstraints(
|
||||
"Callee: ", nullptr, config_, network_thread_.get(),
|
||||
worker_thread_.get()));
|
||||
"Callee: ", nullptr, network_thread_.get(), worker_thread_.get()));
|
||||
if (!initiating_client_ || !receiving_client_) {
|
||||
return false;
|
||||
}
|
||||
@ -1256,20 +1353,18 @@ class P2PTestConductor : public testing::Test {
|
||||
return true;
|
||||
}
|
||||
|
||||
void SetSignalingReceivers() {
|
||||
initiating_client_->set_signaling_message_receiver(receiving_client_.get());
|
||||
receiving_client_->set_signaling_message_receiver(initiating_client_.get());
|
||||
}
|
||||
|
||||
bool CreateTestClients(MediaConstraintsInterface* init_constraints,
|
||||
PeerConnectionFactory::Options* init_options,
|
||||
MediaConstraintsInterface* recv_constraints,
|
||||
PeerConnectionFactory::Options* recv_options) {
|
||||
bool CreateTestClients(
|
||||
MediaConstraintsInterface* init_constraints,
|
||||
PeerConnectionFactory::Options* init_options,
|
||||
const PeerConnectionInterface::RTCConfiguration* init_config,
|
||||
MediaConstraintsInterface* recv_constraints,
|
||||
PeerConnectionFactory::Options* recv_options,
|
||||
const PeerConnectionInterface::RTCConfiguration* recv_config) {
|
||||
initiating_client_.reset(PeerConnectionTestClient::CreateClient(
|
||||
"Caller: ", init_constraints, init_options, config_,
|
||||
"Caller: ", init_constraints, init_options, init_config,
|
||||
network_thread_.get(), worker_thread_.get()));
|
||||
receiving_client_.reset(PeerConnectionTestClient::CreateClient(
|
||||
"Callee: ", recv_constraints, recv_options, config_,
|
||||
"Callee: ", recv_constraints, recv_options, recv_config,
|
||||
network_thread_.get(), worker_thread_.get()));
|
||||
if (!initiating_client_ || !receiving_client_) {
|
||||
return false;
|
||||
@ -1278,6 +1373,16 @@ class P2PTestConductor : public testing::Test {
|
||||
return true;
|
||||
}
|
||||
|
||||
void SetSignalingReceivers() {
|
||||
initiating_client_->set_signaling_message_receiver(receiving_client_.get());
|
||||
receiving_client_->set_signaling_message_receiver(initiating_client_.get());
|
||||
}
|
||||
|
||||
void SetSignalingDelayMs(int delay_ms) {
|
||||
initiating_client_->set_signaling_delay_ms(delay_ms);
|
||||
receiving_client_->set_signaling_delay_ms(delay_ms);
|
||||
}
|
||||
|
||||
void SetVideoConstraints(const webrtc::FakeConstraints& init_constraints,
|
||||
const webrtc::FakeConstraints& recv_constraints) {
|
||||
initiating_client_->SetVideoConstraints(init_constraints);
|
||||
@ -1370,7 +1475,7 @@ class P2PTestConductor : public testing::Test {
|
||||
|
||||
// Make sure the new client is using a different certificate.
|
||||
return PeerConnectionTestClient::CreateClientWithDtlsIdentityStore(
|
||||
"New Peer: ", &setup_constraints, nullptr, config_,
|
||||
"New Peer: ", &setup_constraints, nullptr, nullptr,
|
||||
std::move(cert_generator), prefer_constraint_apis_,
|
||||
network_thread_.get(), worker_thread_.get());
|
||||
}
|
||||
@ -1385,6 +1490,8 @@ class P2PTestConductor : public testing::Test {
|
||||
}
|
||||
}
|
||||
|
||||
rtc::Thread* network_thread() { return network_thread_.get(); }
|
||||
|
||||
rtc::VirtualSocketServer* virtual_socket_server() { return ss_.get(); }
|
||||
|
||||
PeerConnectionTestClient* initializing_client() {
|
||||
@ -1412,9 +1519,6 @@ class P2PTestConductor : public testing::Test {
|
||||
receiving_client_.reset(client);
|
||||
return old;
|
||||
}
|
||||
webrtc::PeerConnectionInterface::RTCConfiguration* config() {
|
||||
return &config_;
|
||||
}
|
||||
|
||||
bool AllObserversReceived(
|
||||
const std::vector<std::unique_ptr<MockRtpReceiverObserver>>& observers) {
|
||||
@ -1432,8 +1536,8 @@ class P2PTestConductor : public testing::Test {
|
||||
init_options.crypto_options.enable_gcm_crypto_suites = local_gcm_enabled;
|
||||
PeerConnectionFactory::Options recv_options;
|
||||
recv_options.crypto_options.enable_gcm_crypto_suites = remote_gcm_enabled;
|
||||
ASSERT_TRUE(
|
||||
CreateTestClients(nullptr, &init_options, nullptr, &recv_options));
|
||||
ASSERT_TRUE(CreateTestClients(nullptr, &init_options, nullptr, nullptr,
|
||||
&recv_options, nullptr));
|
||||
rtc::scoped_refptr<webrtc::FakeMetricsObserver>
|
||||
init_observer =
|
||||
new rtc::RefCountedObject<webrtc::FakeMetricsObserver>();
|
||||
@ -1460,7 +1564,6 @@ class P2PTestConductor : public testing::Test {
|
||||
std::unique_ptr<PeerConnectionTestClient> initiating_client_;
|
||||
std::unique_ptr<PeerConnectionTestClient> receiving_client_;
|
||||
bool prefer_constraint_apis_ = true;
|
||||
webrtc::PeerConnectionInterface::RTCConfiguration config_;
|
||||
};
|
||||
|
||||
// Disable for TSan v2, see
|
||||
@ -1803,8 +1906,8 @@ TEST_F(P2PTestConductor, GetDtls12None) {
|
||||
init_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
|
||||
PeerConnectionFactory::Options recv_options;
|
||||
recv_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
|
||||
ASSERT_TRUE(
|
||||
CreateTestClients(nullptr, &init_options, nullptr, &recv_options));
|
||||
ASSERT_TRUE(CreateTestClients(nullptr, &init_options, nullptr, nullptr,
|
||||
&recv_options, nullptr));
|
||||
rtc::scoped_refptr<webrtc::FakeMetricsObserver>
|
||||
init_observer = new rtc::RefCountedObject<webrtc::FakeMetricsObserver>();
|
||||
initializing_client()->pc()->RegisterUMAObserver(init_observer);
|
||||
@ -1828,8 +1931,8 @@ TEST_F(P2PTestConductor, GetDtls12Both) {
|
||||
init_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
|
||||
PeerConnectionFactory::Options recv_options;
|
||||
recv_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
|
||||
ASSERT_TRUE(
|
||||
CreateTestClients(nullptr, &init_options, nullptr, &recv_options));
|
||||
ASSERT_TRUE(CreateTestClients(nullptr, &init_options, nullptr, nullptr,
|
||||
&recv_options, nullptr));
|
||||
rtc::scoped_refptr<webrtc::FakeMetricsObserver>
|
||||
init_observer = new rtc::RefCountedObject<webrtc::FakeMetricsObserver>();
|
||||
initializing_client()->pc()->RegisterUMAObserver(init_observer);
|
||||
@ -1854,8 +1957,8 @@ TEST_F(P2PTestConductor, GetDtls12Init) {
|
||||
init_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
|
||||
PeerConnectionFactory::Options recv_options;
|
||||
recv_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
|
||||
ASSERT_TRUE(
|
||||
CreateTestClients(nullptr, &init_options, nullptr, &recv_options));
|
||||
ASSERT_TRUE(CreateTestClients(nullptr, &init_options, nullptr, nullptr,
|
||||
&recv_options, nullptr));
|
||||
rtc::scoped_refptr<webrtc::FakeMetricsObserver>
|
||||
init_observer = new rtc::RefCountedObject<webrtc::FakeMetricsObserver>();
|
||||
initializing_client()->pc()->RegisterUMAObserver(init_observer);
|
||||
@ -1880,8 +1983,8 @@ TEST_F(P2PTestConductor, GetDtls12Recv) {
|
||||
init_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_10;
|
||||
PeerConnectionFactory::Options recv_options;
|
||||
recv_options.ssl_max_version = rtc::SSL_PROTOCOL_DTLS_12;
|
||||
ASSERT_TRUE(
|
||||
CreateTestClients(nullptr, &init_options, nullptr, &recv_options));
|
||||
ASSERT_TRUE(CreateTestClients(nullptr, &init_options, nullptr, nullptr,
|
||||
&recv_options, nullptr));
|
||||
rtc::scoped_refptr<webrtc::FakeMetricsObserver>
|
||||
init_observer = new rtc::RefCountedObject<webrtc::FakeMetricsObserver>();
|
||||
initializing_client()->pc()->RegisterUMAObserver(init_observer);
|
||||
@ -2176,8 +2279,9 @@ TEST_F(P2PTestConductor, IceRestart) {
|
||||
}
|
||||
|
||||
TEST_F(P2PTestConductor, IceRenominationDisabled) {
|
||||
config()->enable_ice_renomination = false;
|
||||
ASSERT_TRUE(CreateTestClients());
|
||||
PeerConnectionInterface::RTCConfiguration config;
|
||||
config.enable_ice_renomination = false;
|
||||
ASSERT_TRUE(CreateTestClients(config, config));
|
||||
LocalP2PTest();
|
||||
|
||||
initializing_client()->VerifyLocalIceRenomination();
|
||||
@ -2187,8 +2291,9 @@ TEST_F(P2PTestConductor, IceRenominationDisabled) {
|
||||
}
|
||||
|
||||
TEST_F(P2PTestConductor, IceRenominationEnabled) {
|
||||
config()->enable_ice_renomination = true;
|
||||
ASSERT_TRUE(CreateTestClients());
|
||||
PeerConnectionInterface::RTCConfiguration config;
|
||||
config.enable_ice_renomination = true;
|
||||
ASSERT_TRUE(CreateTestClients(config, config));
|
||||
initializing_client()->SetExpectIceRenomination(true);
|
||||
initializing_client()->SetExpectRemoteIceRenomination(true);
|
||||
receiving_client()->SetExpectIceRenomination(true);
|
||||
@ -2268,8 +2373,9 @@ TEST_F(P2PTestConductor, EarlyWarmupTest) {
|
||||
// This test sets up a call between two parties using QUIC instead of DTLS for
|
||||
// audio and video, and a QUIC data channel.
|
||||
TEST_F(P2PTestConductor, LocalP2PTestQuicDataChannel) {
|
||||
config()->enable_quic = true;
|
||||
ASSERT_TRUE(CreateTestClients());
|
||||
PeerConnectionInterface::RTCConfiguration quic_config;
|
||||
quic_config.enable_quic = true;
|
||||
ASSERT_TRUE(CreateTestClients(quic_config, quic_config));
|
||||
webrtc::DataChannelInit init;
|
||||
init.ordered = false;
|
||||
init.reliable = true;
|
||||
@ -2296,7 +2402,9 @@ TEST_F(P2PTestConductor, LocalP2PTestQuicDataChannel) {
|
||||
|
||||
// Tests that negotiation of QUIC data channels is completed without error.
|
||||
TEST_F(P2PTestConductor, NegotiateQuicDataChannel) {
|
||||
config()->enable_quic = true;
|
||||
PeerConnectionInterface::RTCConfiguration quic_config;
|
||||
quic_config.enable_quic = true;
|
||||
ASSERT_TRUE(CreateTestClients(quic_config, quic_config));
|
||||
FakeConstraints constraints;
|
||||
constraints.SetMandatory(MediaConstraintsInterface::kEnableDtlsSrtp, true);
|
||||
ASSERT_TRUE(CreateTestClients(&constraints, &constraints));
|
||||
@ -2310,16 +2418,18 @@ TEST_F(P2PTestConductor, NegotiateQuicDataChannel) {
|
||||
|
||||
// This test sets up a JSEP call using QUIC. The callee only receives video.
|
||||
TEST_F(P2PTestConductor, LocalP2PTestVideoOnlyWithQuic) {
|
||||
config()->enable_quic = true;
|
||||
ASSERT_TRUE(CreateTestClients());
|
||||
PeerConnectionInterface::RTCConfiguration quic_config;
|
||||
quic_config.enable_quic = true;
|
||||
ASSERT_TRUE(CreateTestClients(quic_config, quic_config));
|
||||
receiving_client()->SetReceiveAudioVideo(false, true);
|
||||
LocalP2PTest();
|
||||
}
|
||||
|
||||
// This test sets up a JSEP call using QUIC. The callee only receives audio.
|
||||
TEST_F(P2PTestConductor, LocalP2PTestAudioOnlyWithQuic) {
|
||||
config()->enable_quic = true;
|
||||
ASSERT_TRUE(CreateTestClients());
|
||||
PeerConnectionInterface::RTCConfiguration quic_config;
|
||||
quic_config.enable_quic = true;
|
||||
ASSERT_TRUE(CreateTestClients(quic_config, quic_config));
|
||||
receiving_client()->SetReceiveAudioVideo(true, false);
|
||||
LocalP2PTest();
|
||||
}
|
||||
@ -2327,8 +2437,9 @@ TEST_F(P2PTestConductor, LocalP2PTestAudioOnlyWithQuic) {
|
||||
// This test sets up a JSEP call using QUIC. The callee rejects both audio and
|
||||
// video.
|
||||
TEST_F(P2PTestConductor, LocalP2PTestNoVideoAudioWithQuic) {
|
||||
config()->enable_quic = true;
|
||||
ASSERT_TRUE(CreateTestClients());
|
||||
PeerConnectionInterface::RTCConfiguration quic_config;
|
||||
quic_config.enable_quic = true;
|
||||
ASSERT_TRUE(CreateTestClients(quic_config, quic_config));
|
||||
receiving_client()->SetReceiveAudioVideo(false, false);
|
||||
LocalP2PTest();
|
||||
}
|
||||
@ -2368,6 +2479,102 @@ TEST_F(P2PTestConductor, ForwardVideoOnlyStream) {
|
||||
kMaxWaitForFramesMs);
|
||||
}
|
||||
|
||||
// Test that we achieve the expected end-to-end connection time, using a
|
||||
// fake clock and simulated latency on the media and signaling paths.
|
||||
// We use a TURN<->TURN connection because this is usually the quickest to
|
||||
// set up initially, especially when we're confident the connection will work
|
||||
// and can start sending media before we get a STUN response.
|
||||
//
|
||||
// With various optimizations enabled, here are the network delays we expect to
|
||||
// be on the critical path:
|
||||
// 1. 2 signaling trips: Signaling offer and offerer's TURN candidate, then
|
||||
// signaling answer (with DTLS fingerprint).
|
||||
// 2. 9 media hops: Rest of the DTLS handshake. 3 hops in each direction when
|
||||
// using TURN<->TURN pair, and DTLS exchange is 4 packets,
|
||||
// the first of which should have arrived before the answer.
|
||||
TEST_F(P2PTestConductor, EndToEndConnectionTimeWithTurnTurnPair) {
|
||||
rtc::ScopedFakeClock fake_clock;
|
||||
// Some things use a time of "0" as a special value, so we need to start out
|
||||
// the fake clock at a nonzero time.
|
||||
// TODO(deadbeef): Fix this.
|
||||
fake_clock.AdvanceTime(rtc::TimeDelta::FromSeconds(1));
|
||||
|
||||
static constexpr int media_hop_delay_ms = 50;
|
||||
static constexpr int signaling_trip_delay_ms = 500;
|
||||
// For explanation of these values, see comment above.
|
||||
static constexpr int required_media_hops = 9;
|
||||
static constexpr int required_signaling_trips = 2;
|
||||
// For internal delays (such as posting an event asychronously).
|
||||
static constexpr int allowed_internal_delay_ms = 20;
|
||||
static constexpr int total_connection_time_ms =
|
||||
media_hop_delay_ms * required_media_hops +
|
||||
signaling_trip_delay_ms * required_signaling_trips +
|
||||
allowed_internal_delay_ms;
|
||||
|
||||
static const rtc::SocketAddress turn_server_1_internal_address{"88.88.88.0",
|
||||
3478};
|
||||
static const rtc::SocketAddress turn_server_1_external_address{"88.88.88.1",
|
||||
0};
|
||||
static const rtc::SocketAddress turn_server_2_internal_address{"99.99.99.0",
|
||||
3478};
|
||||
static const rtc::SocketAddress turn_server_2_external_address{"99.99.99.1",
|
||||
0};
|
||||
cricket::TestTurnServer turn_server_1(network_thread(),
|
||||
turn_server_1_internal_address,
|
||||
turn_server_1_external_address);
|
||||
cricket::TestTurnServer turn_server_2(network_thread(),
|
||||
turn_server_2_internal_address,
|
||||
turn_server_2_external_address);
|
||||
// Bypass permission check on received packets so media can be sent before
|
||||
// the candidate is signaled.
|
||||
turn_server_1.set_enable_permission_checks(false);
|
||||
turn_server_2.set_enable_permission_checks(false);
|
||||
|
||||
PeerConnectionInterface::RTCConfiguration client_1_config;
|
||||
webrtc::PeerConnectionInterface::IceServer ice_server_1;
|
||||
ice_server_1.urls.push_back("turn:88.88.88.0:3478");
|
||||
ice_server_1.username = "test";
|
||||
ice_server_1.password = "test";
|
||||
client_1_config.servers.push_back(ice_server_1);
|
||||
client_1_config.type = webrtc::PeerConnectionInterface::kRelay;
|
||||
client_1_config.presume_writable_when_fully_relayed = true;
|
||||
|
||||
PeerConnectionInterface::RTCConfiguration client_2_config;
|
||||
webrtc::PeerConnectionInterface::IceServer ice_server_2;
|
||||
ice_server_2.urls.push_back("turn:99.99.99.0:3478");
|
||||
ice_server_2.username = "test";
|
||||
ice_server_2.password = "test";
|
||||
client_2_config.servers.push_back(ice_server_2);
|
||||
client_2_config.type = webrtc::PeerConnectionInterface::kRelay;
|
||||
client_2_config.presume_writable_when_fully_relayed = true;
|
||||
|
||||
ASSERT_TRUE(CreateTestClients(client_1_config, client_2_config));
|
||||
// Set up the simulated delays.
|
||||
SetSignalingDelayMs(signaling_trip_delay_ms);
|
||||
virtual_socket_server()->set_delay_mean(media_hop_delay_ms);
|
||||
virtual_socket_server()->UpdateDelayDistribution();
|
||||
|
||||
initializing_client()->SetOfferToReceiveAudioVideo(true, true);
|
||||
initializing_client()->Negotiate();
|
||||
// TODO(deadbeef): kIceConnectionConnected currently means both ICE and DTLS
|
||||
// are connected. This is an important distinction. Once we have separate ICE
|
||||
// and DTLS state, this check needs to use the DTLS state.
|
||||
EXPECT_TRUE_SIMULATED_WAIT(
|
||||
(receiving_client()->ice_connection_state() ==
|
||||
webrtc::PeerConnectionInterface::kIceConnectionConnected ||
|
||||
receiving_client()->ice_connection_state() ==
|
||||
webrtc::PeerConnectionInterface::kIceConnectionCompleted) &&
|
||||
(initializing_client()->ice_connection_state() ==
|
||||
webrtc::PeerConnectionInterface::kIceConnectionConnected ||
|
||||
initializing_client()->ice_connection_state() ==
|
||||
webrtc::PeerConnectionInterface::kIceConnectionCompleted),
|
||||
total_connection_time_ms, fake_clock);
|
||||
// Need to free the clients here since they're using things we created on
|
||||
// the stack.
|
||||
delete set_initializing_client(nullptr);
|
||||
delete set_receiving_client(nullptr);
|
||||
}
|
||||
|
||||
class IceServerParsingTest : public testing::Test {
|
||||
public:
|
||||
// Convenience for parsing a single URL.
|
||||
|
||||
@ -31,7 +31,7 @@ const int kFakeIPv6NetworkPrefixLength = 64;
|
||||
class FakeNetworkManager : public NetworkManagerBase,
|
||||
public MessageHandler {
|
||||
public:
|
||||
FakeNetworkManager() : thread_(Thread::Current()) {}
|
||||
FakeNetworkManager() {}
|
||||
|
||||
typedef std::vector<std::pair<SocketAddress, AdapterType>> IfaceList;
|
||||
|
||||
@ -68,7 +68,7 @@ class FakeNetworkManager : public NetworkManagerBase,
|
||||
++start_count_;
|
||||
if (start_count_ == 1) {
|
||||
sent_first_update_ = false;
|
||||
thread_->Post(RTC_FROM_HERE, this);
|
||||
rtc::Thread::Current()->Post(RTC_FROM_HERE, this);
|
||||
} else {
|
||||
if (sent_first_update_) {
|
||||
SignalNetworksChanged();
|
||||
@ -115,7 +115,6 @@ class FakeNetworkManager : public NetworkManagerBase,
|
||||
}
|
||||
}
|
||||
|
||||
Thread* thread_;
|
||||
IfaceList ifaces_;
|
||||
int next_index_ = 0;
|
||||
int start_count_ = 0;
|
||||
|
||||
@ -52,10 +52,10 @@ class TestTurnServer : public TurnAuthInterface {
|
||||
const rtc::SocketAddress& int_addr,
|
||||
const rtc::SocketAddress& udp_ext_addr,
|
||||
ProtocolType int_protocol = PROTO_UDP)
|
||||
: server_(thread) {
|
||||
: server_(thread), thread_(thread) {
|
||||
AddInternalSocket(int_addr, int_protocol);
|
||||
server_.SetExternalSocketFactory(new rtc::BasicPacketSocketFactory(),
|
||||
udp_ext_addr);
|
||||
server_.SetExternalSocketFactory(new rtc::BasicPacketSocketFactory(thread),
|
||||
udp_ext_addr);
|
||||
server_.set_realm(kTestRealm);
|
||||
server_.set_software(kTestSoftware);
|
||||
server_.set_auth_hook(this);
|
||||
@ -77,15 +77,15 @@ class TestTurnServer : public TurnAuthInterface {
|
||||
|
||||
void AddInternalSocket(const rtc::SocketAddress& int_addr,
|
||||
ProtocolType proto) {
|
||||
rtc::Thread* thread = rtc::Thread::Current();
|
||||
if (proto == cricket::PROTO_UDP) {
|
||||
server_.AddInternalSocket(rtc::AsyncUDPSocket::Create(
|
||||
thread->socketserver(), int_addr), proto);
|
||||
server_.AddInternalSocket(
|
||||
rtc::AsyncUDPSocket::Create(thread_->socketserver(), int_addr),
|
||||
proto);
|
||||
} else if (proto == cricket::PROTO_TCP) {
|
||||
// For TCP we need to create a server socket which can listen for incoming
|
||||
// new connections.
|
||||
rtc::AsyncSocket* socket =
|
||||
thread->socketserver()->CreateAsyncSocket(SOCK_STREAM);
|
||||
thread_->socketserver()->CreateAsyncSocket(SOCK_STREAM);
|
||||
socket->Bind(int_addr);
|
||||
socket->Listen(5);
|
||||
server_.AddInternalServerSocket(socket, proto);
|
||||
@ -114,6 +114,7 @@ class TestTurnServer : public TurnAuthInterface {
|
||||
}
|
||||
|
||||
TurnServer server_;
|
||||
rtc::Thread* thread_;
|
||||
};
|
||||
|
||||
} // namespace cricket
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user