|  | /* | 
|  | *  Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. | 
|  | * | 
|  | *  Use of this source code is governed by a BSD-style license | 
|  | *  that can be found in the LICENSE file in the root of the source | 
|  | *  tree. An additional intellectual property rights grant can be found | 
|  | *  in the file PATENTS.  All contributing project authors may | 
|  | *  be found in the AUTHORS file in the root of the source tree. | 
|  | */ | 
|  |  | 
|  | #include "audio/test/audio_end_to_end_test.h" | 
|  | #include "rtc_base/numerics/safe_compare.h" | 
|  | #include "system_wrappers/include/sleep.h" | 
|  | #include "test/gtest.h" | 
|  |  | 
|  | namespace webrtc { | 
|  | namespace test { | 
|  | namespace { | 
|  |  | 
|  | bool IsNear(int reference, int v) { | 
|  | // Margin is 10%. | 
|  | const int error = reference / 10 + 1; | 
|  | return std::abs(reference - v) <= error; | 
|  | } | 
|  |  | 
|  | class NoLossTest : public AudioEndToEndTest { | 
|  | public: | 
|  | const int kTestDurationMs = 8000; | 
|  | const int kBytesSent = 69351; | 
|  | const int32_t kPacketsSent = 400; | 
|  | const int64_t kRttMs = 100; | 
|  |  | 
|  | NoLossTest() = default; | 
|  |  | 
|  | BuiltInNetworkBehaviorConfig GetNetworkPipeConfig() const override { | 
|  | BuiltInNetworkBehaviorConfig pipe_config; | 
|  | pipe_config.queue_delay_ms = kRttMs / 2; | 
|  | return pipe_config; | 
|  | } | 
|  |  | 
|  | void PerformTest() override { | 
|  | SleepMs(kTestDurationMs); | 
|  | send_audio_device()->StopRecording(); | 
|  | AudioEndToEndTest::PerformTest(); | 
|  | } | 
|  |  | 
|  | void OnStreamsStopped() override { | 
|  | AudioSendStream::Stats send_stats = send_stream()->GetStats(); | 
|  | EXPECT_PRED2(IsNear, kBytesSent, send_stats.payload_bytes_sent); | 
|  | EXPECT_PRED2(IsNear, kPacketsSent, send_stats.packets_sent); | 
|  | EXPECT_EQ(0, send_stats.packets_lost); | 
|  | EXPECT_EQ(0.0f, send_stats.fraction_lost); | 
|  | EXPECT_EQ("opus", send_stats.codec_name); | 
|  | // send_stats.jitter_ms | 
|  | EXPECT_PRED2(IsNear, kRttMs, send_stats.rtt_ms); | 
|  | // Send level is 0 because it is cleared in TransmitMixer::StopSend(). | 
|  | EXPECT_EQ(0, send_stats.audio_level); | 
|  | // send_stats.total_input_energy | 
|  | // send_stats.total_input_duration | 
|  | EXPECT_FALSE(send_stats.apm_statistics.delay_median_ms); | 
|  | EXPECT_FALSE(send_stats.apm_statistics.delay_standard_deviation_ms); | 
|  | EXPECT_FALSE(send_stats.apm_statistics.echo_return_loss); | 
|  | EXPECT_FALSE(send_stats.apm_statistics.echo_return_loss_enhancement); | 
|  | EXPECT_FALSE(send_stats.apm_statistics.residual_echo_likelihood); | 
|  | EXPECT_FALSE(send_stats.apm_statistics.residual_echo_likelihood_recent_max); | 
|  | EXPECT_EQ(false, send_stats.typing_noise_detected); | 
|  |  | 
|  | AudioReceiveStream::Stats recv_stats = | 
|  | receive_stream()->GetStats(/*get_and_clear_legacy_stats=*/true); | 
|  | EXPECT_PRED2(IsNear, kBytesSent, recv_stats.payload_bytes_rcvd); | 
|  | EXPECT_PRED2(IsNear, kPacketsSent, recv_stats.packets_rcvd); | 
|  | EXPECT_EQ(0u, recv_stats.packets_lost); | 
|  | EXPECT_EQ("opus", send_stats.codec_name); | 
|  | // recv_stats.jitter_ms | 
|  | // recv_stats.jitter_buffer_ms | 
|  | EXPECT_EQ(20u, recv_stats.jitter_buffer_preferred_ms); | 
|  | // recv_stats.delay_estimate_ms | 
|  | // Receive level is 0 because it is cleared in Channel::StopPlayout(). | 
|  | EXPECT_EQ(0, recv_stats.audio_level); | 
|  | // recv_stats.total_output_energy | 
|  | // recv_stats.total_samples_received | 
|  | // recv_stats.total_output_duration | 
|  | // recv_stats.concealed_samples | 
|  | // recv_stats.expand_rate | 
|  | // recv_stats.speech_expand_rate | 
|  | EXPECT_EQ(0.0, recv_stats.secondary_decoded_rate); | 
|  | EXPECT_EQ(0.0, recv_stats.secondary_discarded_rate); | 
|  | EXPECT_EQ(0.0, recv_stats.accelerate_rate); | 
|  | EXPECT_EQ(0.0, recv_stats.preemptive_expand_rate); | 
|  | EXPECT_EQ(0, recv_stats.decoding_calls_to_silence_generator); | 
|  | // recv_stats.decoding_calls_to_neteq | 
|  | // recv_stats.decoding_normal | 
|  | // recv_stats.decoding_plc | 
|  | EXPECT_EQ(0, recv_stats.decoding_cng); | 
|  | // recv_stats.decoding_plc_cng | 
|  | // recv_stats.decoding_muted_output | 
|  | // Capture start time is -1 because we do not have an associated send stream | 
|  | // on the receiver side. | 
|  | EXPECT_EQ(-1, recv_stats.capture_start_ntp_time_ms); | 
|  |  | 
|  | // Match these stats between caller and receiver. | 
|  | EXPECT_EQ(send_stats.local_ssrc, recv_stats.remote_ssrc); | 
|  | EXPECT_EQ(*send_stats.codec_payload_type, *recv_stats.codec_payload_type); | 
|  | } | 
|  | }; | 
|  | }  // namespace | 
|  |  | 
|  | using AudioStatsTest = CallTest; | 
|  |  | 
|  | TEST_F(AudioStatsTest, DISABLED_NoLoss) { | 
|  | NoLossTest test; | 
|  | RunBaseTest(&test); | 
|  | } | 
|  |  | 
|  | }  // namespace test | 
|  | }  // namespace webrtc |