Index: webrtc/modules/audio_coding/neteq/neteq_unittest.cc |
diff --git a/webrtc/modules/audio_coding/neteq/neteq_unittest.cc b/webrtc/modules/audio_coding/neteq/neteq_unittest.cc |
index 8be077a322bcfb1b514e84504020494f57267955..956309f2e7fb38f7e045a9a4498562b2193cf871 100644 |
--- a/webrtc/modules/audio_coding/neteq/neteq_unittest.cc |
+++ b/webrtc/modules/audio_coding/neteq/neteq_unittest.cc |
@@ -22,6 +22,8 @@ |
#include "gflags/gflags.h" |
#include "testing/gtest/include/gtest/gtest.h" |
+#include "webrtc/base/sha1digest.h" |
+#include "webrtc/base/stringencode.h" |
#include "webrtc/modules/audio_coding/neteq/tools/audio_loop.h" |
#include "webrtc/modules/audio_coding/neteq/tools/rtp_file_source.h" |
#include "webrtc/modules/audio_coding/codecs/pcm16b/pcm16b.h" |
@@ -41,6 +43,28 @@ DEFINE_bool(gen_ref, false, "Generate reference files."); |
namespace { |
+const std::string& PlatformChecksum(const std::string& checksum_general, |
+ const std::string& checksum_android, |
+ const std::string& checksum_win_32, |
+ const std::string& checksum_win_64) { |
+#ifdef WEBRTC_ANDROID |
+ if (!checksum_android.empty()) |
hlundin-webrtc
2016/04/29 12:26:28
I think I would rather have the strings always pop
minyue-webrtc
2016/04/29 13:11:27
Sounds good to me. I was thinking that 1) the refe
|
+ return checksum_android; |
+#endif // WEBRTC_ANDROID |
+ |
+#ifdef WEBRTC_WIN |
+#ifdef WEBRTC_ARCH_64_BITS |
+ if (!checksum_win_64.empty()) |
+ return checksum_win_64; |
+#else |
+ if (!checksum_win_32.empty()) |
+ return checksum_win_32; |
+#endif // WEBRTC_ARCH_64_BITS |
+#endif // WEBRTC_WIN |
+ |
+ return checksum_general; |
+} |
+ |
bool IsAllZero(const int16_t* buf, size_t buf_length) { |
bool all_zero = true; |
for (size_t n = 0; n < buf_length && all_zero; ++n) |
@@ -85,186 +109,100 @@ void Convert(const webrtc::RtcpStatistics& stats_raw, |
stats->set_jitter(stats_raw.jitter); |
} |
-void WriteMessage(FILE* file, const std::string& message) { |
+void WriteMessage(FILE* file, rtc::MessageDigest* digest, |
minyue-webrtc
2016/04/29 13:11:27
I also like to rename this guy
hlundin-webrtc
2016/04/29 13:19:09
Acknowledged.
|
+ const std::string& message) { |
int32_t size = message.length(); |
- ASSERT_EQ(1u, fwrite(&size, sizeof(size), 1, file)); |
- if (size <= 0) |
- return; |
- ASSERT_EQ(static_cast<size_t>(size), |
- fwrite(message.data(), sizeof(char), size, file)); |
-} |
+ if (file) |
+ ASSERT_EQ(1u, fwrite(&size, sizeof(size), 1, file)); |
+ digest->Update(&size, sizeof(size)); |
-void ReadMessage(FILE* file, std::string* message) { |
- int32_t size; |
- ASSERT_EQ(1u, fread(&size, sizeof(size), 1, file)); |
if (size <= 0) |
hlundin-webrtc
2016/04/29 12:26:28
Can you omit this early return? I mean, the length
minyue-webrtc
2016/04/29 13:11:27
Yes. When I read this part, I did not like it myse
|
return; |
- std::unique_ptr<char[]> buffer(new char[size]); |
- ASSERT_EQ(static_cast<size_t>(size), |
- fread(buffer.get(), sizeof(char), size, file)); |
- message->assign(buffer.get(), size); |
+ if (file) |
+ ASSERT_EQ(static_cast<size_t>(size), |
+ fwrite(message.data(), sizeof(char), size, file)); |
+ digest->Update(message.data(), sizeof(char) * size); |
} |
+ |
#endif // WEBRTC_NETEQ_UNITTEST_BITEXACT |
} // namespace |
namespace webrtc { |
-class RefFiles { |
+class ResultSink { |
public: |
- RefFiles(const std::string& input_file, const std::string& output_file); |
- ~RefFiles(); |
- template<class T> void ProcessReference(const T& test_results); |
- template<typename T, size_t n> void ProcessReference( |
- const T (&test_results)[n], |
- size_t length); |
- template<typename T, size_t n> void WriteToFile( |
- const T (&test_results)[n], |
- size_t length); |
- template<typename T, size_t n> void ReadFromFileAndCompare( |
+ explicit ResultSink(const std::string& output_file); |
+ ~ResultSink(); |
+ |
+ template<typename T, size_t n> void AddResult( |
const T (&test_results)[n], |
size_t length); |
- void WriteToFile(const NetEqNetworkStatistics& stats); |
- void ReadFromFileAndCompare(const NetEqNetworkStatistics& stats); |
- void WriteToFile(const RtcpStatistics& stats); |
- void ReadFromFileAndCompare(const RtcpStatistics& stats); |
- FILE* input_fp_; |
+ void AddResult(const NetEqNetworkStatistics& stats); |
+ void AddResult(const RtcpStatistics& stats); |
+ |
+ void VerifyChecksum(const std::string& ref_check_sum); |
+ |
+ private: |
FILE* output_fp_; |
+ std::unique_ptr<rtc::MessageDigest> digest_; |
}; |
-RefFiles::RefFiles(const std::string &input_file, |
- const std::string &output_file) |
- : input_fp_(NULL), |
- output_fp_(NULL) { |
- if (!input_file.empty()) { |
- input_fp_ = fopen(input_file.c_str(), "rb"); |
- EXPECT_TRUE(input_fp_ != NULL); |
- } |
+ResultSink::ResultSink(const std::string &output_file) |
+ : output_fp_(NULL), |
hlundin-webrtc
2016/04/29 12:26:28
nullptr
minyue-webrtc
2016/04/29 13:11:27
Done.
|
+ digest_(new rtc::Sha1Digest()) { |
if (!output_file.empty()) { |
output_fp_ = fopen(output_file.c_str(), "wb"); |
EXPECT_TRUE(output_fp_ != NULL); |
} |
} |
-RefFiles::~RefFiles() { |
- if (input_fp_) { |
- EXPECT_EQ(EOF, fgetc(input_fp_)); // Make sure that we reached the end. |
- fclose(input_fp_); |
- } |
- if (output_fp_) fclose(output_fp_); |
-} |
- |
-template<class T> |
-void RefFiles::ProcessReference(const T& test_results) { |
- WriteToFile(test_results); |
- ReadFromFileAndCompare(test_results); |
+ResultSink::~ResultSink() { |
+ if (output_fp_) |
+ fclose(output_fp_); |
} |
template<typename T, size_t n> |
-void RefFiles::ProcessReference(const T (&test_results)[n], size_t length) { |
- WriteToFile(test_results, length); |
- ReadFromFileAndCompare(test_results, length); |
-} |
- |
-template<typename T, size_t n> |
-void RefFiles::WriteToFile(const T (&test_results)[n], size_t length) { |
+void ResultSink::AddResult(const T (&test_results)[n], size_t length) { |
if (output_fp_) { |
ASSERT_EQ(length, fwrite(&test_results, sizeof(T), length, output_fp_)); |
} |
+ digest_->Update(&test_results, sizeof(T) * length); |
} |
-template<typename T, size_t n> |
-void RefFiles::ReadFromFileAndCompare(const T (&test_results)[n], |
- size_t length) { |
- if (input_fp_) { |
- // Read from ref file. |
- T* ref = new T[length]; |
- ASSERT_EQ(length, fread(ref, sizeof(T), length, input_fp_)); |
- // Compare |
- ASSERT_EQ(0, memcmp(&test_results, ref, sizeof(T) * length)); |
- delete [] ref; |
- } |
-} |
- |
-void RefFiles::WriteToFile(const NetEqNetworkStatistics& stats_raw) { |
+void ResultSink::AddResult(const NetEqNetworkStatistics& stats_raw) { |
#ifdef WEBRTC_NETEQ_UNITTEST_BITEXACT |
- if (!output_fp_) |
- return; |
neteq_unittest::NetEqNetworkStatistics stats; |
Convert(stats_raw, &stats); |
std::string stats_string; |
ASSERT_TRUE(stats.SerializeToString(&stats_string)); |
- WriteMessage(output_fp_, stats_string); |
+ WriteMessage(output_fp_, digest_.get(), stats_string); |
#else |
FAIL() << "Writing to reference file requires Proto Buffer."; |
#endif // WEBRTC_NETEQ_UNITTEST_BITEXACT |
} |
-void RefFiles::ReadFromFileAndCompare( |
- const NetEqNetworkStatistics& stats) { |
+void ResultSink::AddResult(const RtcpStatistics& stats_raw) { |
#ifdef WEBRTC_NETEQ_UNITTEST_BITEXACT |
- if (!input_fp_) |
- return; |
- |
- std::string stats_string; |
- ReadMessage(input_fp_, &stats_string); |
- neteq_unittest::NetEqNetworkStatistics ref_stats; |
- ASSERT_TRUE(ref_stats.ParseFromString(stats_string)); |
- |
- // Compare |
- ASSERT_EQ(stats.current_buffer_size_ms, ref_stats.current_buffer_size_ms()); |
- ASSERT_EQ(stats.preferred_buffer_size_ms, |
- ref_stats.preferred_buffer_size_ms()); |
- ASSERT_EQ(stats.jitter_peaks_found, ref_stats.jitter_peaks_found()); |
- ASSERT_EQ(stats.packet_loss_rate, ref_stats.packet_loss_rate()); |
- ASSERT_EQ(stats.packet_discard_rate, ref_stats.packet_discard_rate()); |
- ASSERT_EQ(stats.expand_rate, ref_stats.expand_rate()); |
- ASSERT_EQ(stats.preemptive_rate, ref_stats.preemptive_rate()); |
- ASSERT_EQ(stats.accelerate_rate, ref_stats.accelerate_rate()); |
- ASSERT_EQ(stats.clockdrift_ppm, ref_stats.clockdrift_ppm()); |
- ASSERT_EQ(stats.added_zero_samples, ref_stats.added_zero_samples()); |
- ASSERT_EQ(stats.secondary_decoded_rate, ref_stats.secondary_decoded_rate()); |
- ASSERT_LE(stats.speech_expand_rate, ref_stats.expand_rate()); |
-#else |
- FAIL() << "Reading from reference file requires Proto Buffer."; |
-#endif // WEBRTC_NETEQ_UNITTEST_BITEXACT |
-} |
- |
-void RefFiles::WriteToFile(const RtcpStatistics& stats_raw) { |
-#ifdef WEBRTC_NETEQ_UNITTEST_BITEXACT |
- if (!output_fp_) |
- return; |
neteq_unittest::RtcpStatistics stats; |
Convert(stats_raw, &stats); |
std::string stats_string; |
ASSERT_TRUE(stats.SerializeToString(&stats_string)); |
- WriteMessage(output_fp_, stats_string); |
+ WriteMessage(output_fp_, digest_.get(), stats_string); |
#else |
FAIL() << "Writing to reference file requires Proto Buffer."; |
#endif // WEBRTC_NETEQ_UNITTEST_BITEXACT |
} |
-void RefFiles::ReadFromFileAndCompare(const RtcpStatistics& stats) { |
-#ifdef WEBRTC_NETEQ_UNITTEST_BITEXACT |
- if (!input_fp_) |
- return; |
- std::string stats_string; |
- ReadMessage(input_fp_, &stats_string); |
- neteq_unittest::RtcpStatistics ref_stats; |
- ASSERT_TRUE(ref_stats.ParseFromString(stats_string)); |
- |
- // Compare |
- ASSERT_EQ(stats.fraction_lost, ref_stats.fraction_lost()); |
- ASSERT_EQ(stats.cumulative_lost, ref_stats.cumulative_lost()); |
- ASSERT_EQ(stats.extended_max_sequence_number, |
- ref_stats.extended_max_sequence_number()); |
- ASSERT_EQ(stats.jitter, ref_stats.jitter()); |
-#else |
- FAIL() << "Reading from reference file requires Proto Buffer."; |
-#endif // WEBRTC_NETEQ_UNITTEST_BITEXACT |
+void ResultSink::VerifyChecksum(const std::string& checksum) { |
+ std::vector<char> buffer; |
+ buffer.resize(digest_->Size()); |
+ digest_->Finish(&buffer[0], buffer.size()); |
+ const std::string result = rtc::hex_encode(&buffer[0], digest_->Size()); |
+ EXPECT_EQ(checksum, result); |
} |
class NetEqDecodingTest : public ::testing::Test { |
@@ -287,9 +225,10 @@ class NetEqDecodingTest : public ::testing::Test { |
void Process(); |
void DecodeAndCompare(const std::string& rtp_file, |
- const std::string& ref_file, |
- const std::string& stat_ref_file, |
- const std::string& rtcp_ref_file); |
+ const std::string& output_checksum, |
+ const std::string& network_stats_checksum, |
+ const std::string& rtcp_stats_checksum, |
+ bool gen_ref); |
static void PopulateRtpInfo(int frame_index, |
int timestamp, |
@@ -434,29 +373,25 @@ void NetEqDecodingTest::Process() { |
sim_clock_ += kTimeStepMs; |
} |
-void NetEqDecodingTest::DecodeAndCompare(const std::string& rtp_file, |
- const std::string& ref_file, |
- const std::string& stat_ref_file, |
- const std::string& rtcp_ref_file) { |
+void NetEqDecodingTest::DecodeAndCompare( |
+ const std::string& rtp_file, |
+ const std::string& output_checksum, |
+ const std::string& network_stats_checksum, |
+ const std::string& rtcp_stats_checksum, |
+ bool gen_ref) { |
OpenInputFile(rtp_file); |
- std::string ref_out_file = ""; |
- if (ref_file.empty()) { |
- ref_out_file = webrtc::test::OutputPath() + "neteq_universal_ref.pcm"; |
- } |
- RefFiles ref_files(ref_file, ref_out_file); |
+ std::string ref_out_file = |
+ gen_ref ? webrtc::test::OutputPath() + "neteq_universal_ref.pcm" : ""; |
+ ResultSink ref_files(ref_out_file); |
minyue-webrtc
2016/04/29 13:11:27
I'd rename ref_files as well.
hlundin-webrtc
2016/04/29 13:19:09
Acknowledged.
|
- std::string stat_out_file = ""; |
- if (stat_ref_file.empty()) { |
- stat_out_file = webrtc::test::OutputPath() + "neteq_network_stats.dat"; |
- } |
- RefFiles network_stat_files(stat_ref_file, stat_out_file); |
+ std::string stat_out_file = |
+ gen_ref ? webrtc::test::OutputPath() + "neteq_network_stats.dat" : ""; |
+ ResultSink network_stat_files(stat_out_file); |
- std::string rtcp_out_file = ""; |
- if (rtcp_ref_file.empty()) { |
- rtcp_out_file = webrtc::test::OutputPath() + "neteq_rtcp_stats.dat"; |
- } |
- RefFiles rtcp_stat_files(rtcp_ref_file, rtcp_out_file); |
+ std::string rtcp_out_file = |
+ gen_ref ? webrtc::test::OutputPath() + "neteq_rtcp_stats.dat" : ""; |
+ ResultSink rtcp_stat_files(rtcp_out_file); |
packet_.reset(rtp_source_->NextPacket()); |
int i = 0; |
@@ -465,7 +400,7 @@ void NetEqDecodingTest::DecodeAndCompare(const std::string& rtp_file, |
ss << "Lap number " << i++ << " in DecodeAndCompare while loop"; |
SCOPED_TRACE(ss.str()); // Print out the parameter values on failure. |
ASSERT_NO_FATAL_FAILURE(Process()); |
- ASSERT_NO_FATAL_FAILURE(ref_files.ProcessReference( |
+ ASSERT_NO_FATAL_FAILURE(ref_files.AddResult( |
out_frame_.data_, out_frame_.samples_per_channel_)); |
// Query the network statistics API once per second |
@@ -474,16 +409,20 @@ void NetEqDecodingTest::DecodeAndCompare(const std::string& rtp_file, |
NetEqNetworkStatistics network_stats; |
ASSERT_EQ(0, neteq_->NetworkStatistics(&network_stats)); |
ASSERT_NO_FATAL_FAILURE( |
- network_stat_files.ProcessReference(network_stats)); |
+ network_stat_files.AddResult(network_stats)); |
// Compare with CurrentDelay, which should be identical. |
EXPECT_EQ(network_stats.current_buffer_size_ms, neteq_->CurrentDelayMs()); |
// Process RTCPstat. |
RtcpStatistics rtcp_stats; |
neteq_->GetRtcpStatistics(&rtcp_stats); |
- ASSERT_NO_FATAL_FAILURE(rtcp_stat_files.ProcessReference(rtcp_stats)); |
+ ASSERT_NO_FATAL_FAILURE(rtcp_stat_files.AddResult(rtcp_stats)); |
} |
} |
+ |
+ ref_files.VerifyChecksum(output_checksum); |
hlundin-webrtc
2016/04/29 12:26:28
I think you should add SCOPED_TRACE("ref_files") o
minyue-webrtc
2016/04/29 13:11:27
Done.
|
+ network_stat_files.VerifyChecksum(network_stats_checksum); |
+ rtcp_stat_files.VerifyChecksum(rtcp_stats_checksum); |
} |
void NetEqDecodingTest::PopulateRtpInfo(int frame_index, |
@@ -522,31 +461,30 @@ void NetEqDecodingTest::PopulateCng(int frame_index, |
TEST_F(NetEqDecodingTest, MAYBE_TestBitExactness) { |
const std::string input_rtp_file = |
webrtc::test::ResourcePath("audio_coding/neteq_universal_new", "rtp"); |
- // Note that neteq4_universal_ref.pcm and neteq4_universal_ref_win_32.pcm |
- // are identical. The latter could have been removed, but if clients still |
- // have a copy of the file, the test will fail. |
- const std::string input_ref_file = |
- webrtc::test::ResourcePath("audio_coding/neteq4_universal_ref", "pcm"); |
-#if defined(_MSC_VER) && (_MSC_VER >= 1700) |
- // For Visual Studio 2012 and later, we will have to use the generic reference |
- // file, rather than the windows-specific one. |
- const std::string network_stat_ref_file = webrtc::test::ProjectRootPath() + |
- "resources/audio_coding/neteq4_network_stats.dat"; |
-#else |
- const std::string network_stat_ref_file = |
- webrtc::test::ResourcePath("audio_coding/neteq4_network_stats", "dat"); |
-#endif |
- const std::string rtcp_stat_ref_file = |
- webrtc::test::ResourcePath("audio_coding/neteq4_rtcp_stats", "dat"); |
- |
- if (FLAGS_gen_ref) { |
- DecodeAndCompare(input_rtp_file, "", "", ""); |
- } else { |
- DecodeAndCompare(input_rtp_file, |
- input_ref_file, |
- network_stat_ref_file, |
- rtcp_stat_ref_file); |
- } |
+ |
+ const std::string output_checksum = PlatformChecksum( |
+ "f587883b7c371ee8d87dbf1b0f07525af7d959b8", |
+ "a349bd71dba548029b05d1d2a6dc7caafab9a856", |
+ "", |
hlundin-webrtc
2016/04/29 12:26:28
Follow my suggestion in PlatformChecksum, and expl
minyue-webrtc
2016/04/29 13:11:27
Done.
|
+ "08266b198e7686b3cd9330813e0d2cd72fc8fdc2"); |
+ |
+ const std::string network_stats_checksum = PlatformChecksum( |
+ "2cf380a05ee07080bd72471e8ec7777a39644ec9", |
+ "2853ab577fe571adfc7b18f77bbe58f1253d2019", |
+ "", |
+ ""); |
+ |
+ const std::string rtcp_stats_checksum = PlatformChecksum( |
+ "b8880bf9fed2487efbddcb8d94b9937a29ae521d", |
+ "f3f7b3d3e71d7e635240b5373b57df6a7e4ce9d4", |
+ "", |
+ ""); |
+ |
+ DecodeAndCompare(input_rtp_file, |
+ output_checksum, |
+ network_stats_checksum, |
+ rtcp_stats_checksum, |
+ FLAGS_gen_ref); |
} |
// Disabled for UBSan: https://bugs.chromium.org/p/webrtc/issues/detail?id=5820 |
@@ -560,26 +498,24 @@ TEST_F(NetEqDecodingTest, MAYBE_TestBitExactness) { |
TEST_F(NetEqDecodingTest, MAYBE_TestOpusBitExactness) { |
const std::string input_rtp_file = |
webrtc::test::ResourcePath("audio_coding/neteq_opus", "rtp"); |
- const std::string input_ref_file = |
- // The pcm files were generated by using Opus v1.1.2 to decode the RTC |
- // file generated by Opus v1.1 |
- webrtc::test::ResourcePath("audio_coding/neteq4_opus_ref", "pcm"); |
- const std::string network_stat_ref_file = |
- // The network stats file was generated when using Opus v1.1.2 to decode |
- // the RTC file generated by Opus v1.1 |
- webrtc::test::ResourcePath("audio_coding/neteq4_opus_network_stats", |
- "dat"); |
- const std::string rtcp_stat_ref_file = |
- webrtc::test::ResourcePath("audio_coding/neteq4_opus_rtcp_stats", "dat"); |
- |
- if (FLAGS_gen_ref) { |
- DecodeAndCompare(input_rtp_file, "", "", ""); |
- } else { |
- DecodeAndCompare(input_rtp_file, |
- input_ref_file, |
- network_stat_ref_file, |
- rtcp_stat_ref_file); |
- } |
+ |
+ const std::string output_checksum = PlatformChecksum( |
+ "c23004d91ffbe5e7a1f24620fc89b58c0426040f", |
+ "", "", ""); |
+ |
+ const std::string network_stats_checksum = PlatformChecksum( |
+ "dc2d9f584efb0111ebcd71a2c86f1fb09cd8c2bb", |
+ "", "", ""); |
+ |
+ const std::string rtcp_stats_checksum = PlatformChecksum( |
+ "e37c797e3de6a64dda88c9ade7a013d022a2e1e0", |
+ "", "", ""); |
+ |
+ DecodeAndCompare(input_rtp_file, |
+ output_checksum, |
+ network_stats_checksum, |
+ rtcp_stats_checksum, |
+ FLAGS_gen_ref); |
} |
// Use fax mode to avoid time-scaling. This is to simplify the testing of |