mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-18 16:17:50 +01:00
Add a unit testing framework.
Populate it with the beginnings of a resampler unit test to have it do someting. Also fix a bug in resampler caught with the test ;) Review URL: http://webrtc-codereview.appspot.com/135019 git-svn-id: http://webrtc.googlecode.com/svn/trunk@595 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
b524f441d0
commit
19eefdc9f0
9 changed files with 278 additions and 19 deletions
|
@ -8,9 +8,28 @@
|
||||||
|
|
||||||
{
|
{
|
||||||
'includes': [
|
'includes': [
|
||||||
'../common_settings.gypi', # Common settings
|
'../build/common.gypi',
|
||||||
'signal_processing_library/main/source/spl.gypi',
|
'signal_processing_library/main/source/spl.gypi',
|
||||||
'resampler/main/source/resampler.gypi',
|
'resampler/main/source/resampler.gypi',
|
||||||
'vad/main/source/vad.gypi',
|
'vad/main/source/vad.gypi',
|
||||||
],
|
],
|
||||||
|
'conditions': [
|
||||||
|
['build_with_chromium==0', {
|
||||||
|
'targets' : [
|
||||||
|
{
|
||||||
|
'target_name': 'common_audio_unittests',
|
||||||
|
'type': 'executable',
|
||||||
|
'dependencies': [
|
||||||
|
'<(webrtc_root)/../test/test.gyp:test_support',
|
||||||
|
'<(webrtc_root)/../testing/gtest.gyp:gtest',
|
||||||
|
'resampler',
|
||||||
|
],
|
||||||
|
'sources': [
|
||||||
|
'<(webrtc_root)/../test/run_all_unittests.cc',
|
||||||
|
'resampler/main/source/resampler_unittest.cc',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}],
|
||||||
|
],
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ enum ResamplerType
|
||||||
kResamplerInvalid = 0xff
|
kResamplerInvalid = 0xff
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO(andrew): doesn't need to be part of the interface.
|
||||||
enum ResamplerMode
|
enum ResamplerMode
|
||||||
{
|
{
|
||||||
kResamplerMode1To1,
|
kResamplerMode1To1,
|
||||||
|
@ -63,6 +64,7 @@ class Resampler
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Resampler();
|
Resampler();
|
||||||
|
// TODO(andrew): use an init function instead.
|
||||||
Resampler(int inFreq, int outFreq, ResamplerType type);
|
Resampler(int inFreq, int outFreq, ResamplerType type);
|
||||||
~Resampler();
|
~Resampler();
|
||||||
|
|
||||||
|
|
|
@ -62,8 +62,6 @@ Resampler::Resampler(int inFreq, int outFreq, ResamplerType type)
|
||||||
slave_left_ = NULL;
|
slave_left_ = NULL;
|
||||||
slave_right_ = NULL;
|
slave_right_ = NULL;
|
||||||
|
|
||||||
// TODO(andrew): looks like this class should use an init method
|
|
||||||
// (and possibly a static create).
|
|
||||||
Reset(inFreq, outFreq, type);
|
Reset(inFreq, outFreq, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,7 +211,7 @@ int Resampler::Reset(int inFreq, int outFreq, ResamplerType type)
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
my_type_ = kResamplerInvalid;
|
my_type_ = kResamplerInvalid;
|
||||||
break;
|
return -1;
|
||||||
}
|
}
|
||||||
} else if (outFreq == 1)
|
} else if (outFreq == 1)
|
||||||
{
|
{
|
||||||
|
@ -233,7 +231,7 @@ int Resampler::Reset(int inFreq, int outFreq, ResamplerType type)
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
my_type_ = kResamplerInvalid;
|
my_type_ = kResamplerInvalid;
|
||||||
break;
|
return -1;
|
||||||
}
|
}
|
||||||
} else if ((inFreq == 2) && (outFreq == 3))
|
} else if ((inFreq == 2) && (outFreq == 3))
|
||||||
{
|
{
|
||||||
|
|
119
src/common_audio/resampler/main/source/resampler_unittest.cc
Normal file
119
src/common_audio/resampler/main/source/resampler_unittest.cc
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2011 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 "gtest/gtest.h"
|
||||||
|
|
||||||
|
#include "common_audio/resampler/main/interface/resampler.h"
|
||||||
|
|
||||||
|
// TODO(andrew): this is a work-in-progress. Many more tests are needed.
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
namespace {
|
||||||
|
const ResamplerType kTypes[] = {
|
||||||
|
kResamplerSynchronous,
|
||||||
|
kResamplerAsynchronous,
|
||||||
|
kResamplerSynchronousStereo,
|
||||||
|
kResamplerAsynchronousStereo
|
||||||
|
// kResamplerInvalid excluded
|
||||||
|
};
|
||||||
|
const size_t kTypesSize = sizeof(kTypes) / sizeof(*kTypes);
|
||||||
|
|
||||||
|
// Rates we must support.
|
||||||
|
const int kMaxRate = 96000;
|
||||||
|
const int kRates[] = {
|
||||||
|
8000,
|
||||||
|
16000,
|
||||||
|
32000,
|
||||||
|
44000,
|
||||||
|
48000,
|
||||||
|
kMaxRate
|
||||||
|
};
|
||||||
|
const size_t kRatesSize = sizeof(kRates) / sizeof(*kRates);
|
||||||
|
const size_t kDataSize = kMaxRate / 100;
|
||||||
|
|
||||||
|
// TODO(andrew): should we be supporting these combinations?
|
||||||
|
bool ValidRates(int in_rate, int out_rate) {
|
||||||
|
// Not the most compact notation, for clarity.
|
||||||
|
if ((in_rate == 44000 && (out_rate == 48000 || out_rate == 96000)) ||
|
||||||
|
(out_rate == 44000 && (in_rate == 48000 || in_rate == 96000)) ||
|
||||||
|
(in_rate == 8000 && out_rate == 96000) ||
|
||||||
|
(in_rate == 96000 && out_rate == 8000)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ResamplerTest : public testing::Test {
|
||||||
|
protected:
|
||||||
|
ResamplerTest();
|
||||||
|
virtual void SetUp();
|
||||||
|
virtual void TearDown();
|
||||||
|
|
||||||
|
Resampler rs_;
|
||||||
|
int16_t data_in_[kDataSize];
|
||||||
|
int16_t data_out_[kDataSize];
|
||||||
|
};
|
||||||
|
|
||||||
|
ResamplerTest::ResamplerTest() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResamplerTest::SetUp() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResamplerTest::TearDown() {
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ResamplerTest, Reset) {
|
||||||
|
// The only failure mode for the constructor is if Reset() fails. For the
|
||||||
|
// time being then (until an Init function is added), we rely on Reset()
|
||||||
|
// to test the constructor.
|
||||||
|
|
||||||
|
// Check that all required combinations are supported.
|
||||||
|
for (size_t i = 0; i < kRatesSize; ++i) {
|
||||||
|
for (size_t j = 0; j < kRatesSize; ++j) {
|
||||||
|
for (size_t k = 0; k < kTypesSize; ++k) {
|
||||||
|
std::ostringstream ss;
|
||||||
|
ss << "Input rate: " << kRates[i] << ", output rate: " << kRates[j]
|
||||||
|
<< ", type: " << kTypes[k];
|
||||||
|
SCOPED_TRACE(ss.str());
|
||||||
|
if (ValidRates(kRates[i], kRates[j]))
|
||||||
|
EXPECT_EQ(0, rs_.Reset(kRates[i], kRates[j], kTypes[k]));
|
||||||
|
else
|
||||||
|
EXPECT_EQ(-1, rs_.Reset(kRates[i], kRates[j], kTypes[k]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ResamplerTest, Synchronous) {
|
||||||
|
for (size_t i = 0; i < kRatesSize; ++i) {
|
||||||
|
for (size_t j = 0; j < kRatesSize; ++j) {
|
||||||
|
std::ostringstream ss;
|
||||||
|
ss << "Input rate: " << kRates[i] << ", output rate: " << kRates[j];
|
||||||
|
SCOPED_TRACE(ss.str());
|
||||||
|
|
||||||
|
if (ValidRates(kRates[i], kRates[j])) {
|
||||||
|
int in_length = kRates[i] / 100;
|
||||||
|
int out_length = 0;
|
||||||
|
EXPECT_EQ(0, rs_.Reset(kRates[i], kRates[j], kResamplerSynchronous));
|
||||||
|
EXPECT_EQ(0, rs_.Push(data_in_, in_length, data_out_, kDataSize,
|
||||||
|
out_length));
|
||||||
|
EXPECT_EQ(kRates[j] / 100, out_length);
|
||||||
|
} else {
|
||||||
|
EXPECT_EQ(-1, rs_.Reset(kRates[i], kRates[j], kResamplerSynchronous));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(andrew): test stereo.
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
} // namespace webrtc
|
16
test/run_all_unittests.cc
Normal file
16
test/run_all_unittests.cc
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2011 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 "test/test_suite.h"
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
webrtc::TestSuite test_suite(argc, argv);
|
||||||
|
return test_suite.Run();
|
||||||
|
}
|
27
test/test.gyp
Normal file
27
test/test.gyp
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
# Copyright (c) 2011 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.
|
||||||
|
|
||||||
|
# TODO(andrew): consider moving test_support to src/base/test.
|
||||||
|
{
|
||||||
|
'includes': [
|
||||||
|
'../src/build/common.gypi',
|
||||||
|
],
|
||||||
|
'targets': [
|
||||||
|
{
|
||||||
|
'target_name': 'test_support',
|
||||||
|
'type': 'static_library',
|
||||||
|
'dependencies': [
|
||||||
|
'../testing/gtest.gyp:gtest',
|
||||||
|
],
|
||||||
|
'sources': [
|
||||||
|
'test_suite.cc',
|
||||||
|
'test_suite.h',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
36
test/test_suite.cc
Normal file
36
test/test_suite.cc
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2011 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 "test/test_suite.h"
|
||||||
|
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
TestSuite::TestSuite(int argc, char** argv) {
|
||||||
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
TestSuite::~TestSuite() {
|
||||||
|
}
|
||||||
|
|
||||||
|
int TestSuite::Run() {
|
||||||
|
Initialize();
|
||||||
|
int result = RUN_ALL_TESTS();
|
||||||
|
Shutdown();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestSuite::Initialize() {
|
||||||
|
// TODO(andrew): initialize singletons here (e.g. Trace).
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestSuite::Shutdown() {
|
||||||
|
}
|
||||||
|
} // namespace webrtc
|
40
test/test_suite.h
Normal file
40
test/test_suite.h
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2011 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TEST_TEST_SUITE_H_
|
||||||
|
#define TEST_TEST_SUITE_H_
|
||||||
|
|
||||||
|
// Derived from Chromium's src/base/test/test_suite.h.
|
||||||
|
|
||||||
|
// Defines a basic test suite framework for running gtest based tests. You can
|
||||||
|
// instantiate this class in your main function and call its Run method to run
|
||||||
|
// any gtest based tests that are linked into your executable.
|
||||||
|
|
||||||
|
#include "src/system_wrappers/interface/constructor_magic.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
class TestSuite {
|
||||||
|
public:
|
||||||
|
TestSuite(int argc, char** argv);
|
||||||
|
virtual ~TestSuite();
|
||||||
|
|
||||||
|
int Run();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Override these for custom initialization and shutdown handling. Use these
|
||||||
|
// instead of putting complex code in your constructor/destructor.
|
||||||
|
virtual void Initialize();
|
||||||
|
virtual void Shutdown();
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(TestSuite);
|
||||||
|
};
|
||||||
|
} // namespace webrtc
|
||||||
|
|
||||||
|
#endif // TEST_TEST_SUITE_H_
|
20
webrtc.gyp
20
webrtc.gyp
|
@ -8,24 +8,26 @@
|
||||||
|
|
||||||
{
|
{
|
||||||
'includes': [
|
'includes': [
|
||||||
'src/common_settings.gypi', # Common settings
|
'src/build/common.gypi',
|
||||||
],
|
],
|
||||||
'targets': [
|
'targets': [
|
||||||
{
|
{
|
||||||
'target_name': 'auto_tests',
|
'target_name': 'All',
|
||||||
'type': 'none',
|
'type': 'none',
|
||||||
'dependencies': [
|
'dependencies': [
|
||||||
'src/voice_engine/voice_engine.gyp:voe_auto_test',
|
'src/common_audio/common_audio.gyp:*',
|
||||||
|
# TODO(andrew): enable these when all tests build.
|
||||||
|
#'src/common_video/common_video.gyp:*',
|
||||||
|
#'src/modules/modules.gyp:*',
|
||||||
|
#'src/system_wrappers/source/system_wrappers.gyp:*',
|
||||||
|
# TODO(andrew): move the merge_lib targets to a private gyp so we can
|
||||||
|
# target "*" in these.
|
||||||
'src/video_engine/video_engine.gyp:vie_auto_test',
|
'src/video_engine/video_engine.gyp:vie_auto_test',
|
||||||
],
|
'src/voice_engine/voice_engine.gyp:voe_auto_test',
|
||||||
},
|
|
||||||
{
|
|
||||||
'target_name': 'cmd_test',
|
|
||||||
'type': 'none',
|
|
||||||
'dependencies': [
|
|
||||||
'src/voice_engine/voice_engine.gyp:voe_cmd_test',
|
'src/voice_engine/voice_engine.gyp:voe_cmd_test',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
# TODO(andrew): move peerconnection to its own gyp.
|
||||||
{
|
{
|
||||||
'target_name': 'peerconnection_server',
|
'target_name': 'peerconnection_server',
|
||||||
'type': 'executable',
|
'type': 'executable',
|
||||||
|
|
Loading…
Reference in a new issue