Chromium Code Reviews| Index: webrtc/audio/test/audio_stats_test.cc | 
| diff --git a/webrtc/audio/test/audio_stats_test.cc b/webrtc/audio/test/audio_stats_test.cc | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..6993d3396efbd77568c58ccc7dfbba824f1f1725 | 
| --- /dev/null | 
| +++ b/webrtc/audio/test/audio_stats_test.cc | 
| @@ -0,0 +1,118 @@ | 
| +/* | 
| + * 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 "webrtc/audio/test/audio_end_to_end_test.h" | 
| +#include "webrtc/system_wrappers/include/sleep.h" | 
| +#include "webrtc/test/gtest.h" | 
| + | 
| +namespace webrtc { | 
| +namespace test { | 
| +namespace { | 
| + | 
| +bool IsNear(int reference, int v) { | 
| + // Margin is 10%. | 
| + int error = reference / 10 + 1; | 
| 
 
kwiberg-webrtc
2017/09/13 14:20:26
const?
 
the sun
2017/09/13 14:53:33
Done.
 
 | 
| + 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; | 
| 
 
kwiberg-webrtc
2017/09/13 14:20:26
static constexpr? Or maybe just constexpr, if you
 
the sun
2017/09/13 14:53:32
constexpr on its own yields compiler errors:
../.
 
kwiberg-webrtc
2017/09/14 01:26:40
Yeah, that. You could use the enum hack (which got
 
 | 
| + | 
| + NoLossTest() = default; | 
| + | 
| + FakeNetworkPipe::Config GetNetworkPipeConfig() const override { | 
| + FakeNetworkPipe::Config 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.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); | 
| 
 
kwiberg-webrtc
2017/09/13 14:20:26
Should this comparison be case-insensitive? SDP co
 
the sun
2017/09/13 14:53:33
Changing it to lower case, here and in call_test.c
 
 | 
| + // 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_EQ(-1.0f, send_stats.aec_quality_min); | 
| + EXPECT_EQ(-1, send_stats.echo_delay_median_ms); | 
| + EXPECT_EQ(-1, send_stats.echo_delay_std_ms); | 
| + EXPECT_EQ(-100, send_stats.echo_return_loss); | 
| + EXPECT_EQ(-100, send_stats.echo_return_loss_enhancement); | 
| + EXPECT_EQ(0.0f, send_stats.residual_echo_likelihood); | 
| + EXPECT_EQ(0.0f, send_stats.residual_echo_likelihood_recent_max); | 
| + EXPECT_EQ(false, send_stats.typing_noise_detected); | 
| + | 
| + AudioReceiveStream::Stats recv_stats = receive_stream()->GetStats(); | 
| + EXPECT_PRED2(IsNear, kBytesSent, recv_stats.bytes_rcvd); | 
| + EXPECT_PRED2(IsNear, kPacketsSent, recv_stats.packets_rcvd); | 
| + EXPECT_EQ(0u, recv_stats.packets_lost); | 
| + EXPECT_EQ(0.0f, recv_stats.fraction_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); | 
| + EXPECT_EQ(send_stats.ext_seqnum, | 
| + static_cast<int32_t>(recv_stats.ext_seqnum)); | 
| 
 
kwiberg-webrtc
2017/09/13 14:20:26
static_cast is dangerous. Can you convert both of
 
the sun
2017/09/13 14:53:33
Done.
 
 | 
| + } | 
| +}; | 
| +} // namespace | 
| + | 
| +using AudioStatsTest = CallTest; | 
| + | 
| +TEST_F(AudioStatsTest, NoLoss) { | 
| + NoLossTest test; | 
| + RunBaseTest(&test); | 
| +} | 
| + | 
| +} // namespace test | 
| +} // namespace webrtc |