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
@ -8,9 +8,28 @@
|
||||
|
||||
{
|
||||
'includes': [
|
||||
'../common_settings.gypi', # Common settings
|
||||
'../build/common.gypi',
|
||||
'signal_processing_library/main/source/spl.gypi',
|
||||
'resampler/main/source/resampler.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',
|
||||
],
|
||||
},
|
||||
],
|
||||
}],
|
||||
],
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ namespace webrtc
|
||||
{
|
||||
|
||||
// TODO(andrew): the implementation depends on the exact values of this enum.
|
||||
// It should be rewritten in a less fragile way.
|
||||
// It should be rewritten in a less fragile way.
|
||||
enum ResamplerType
|
||||
{
|
||||
// 4 MSB = Number of channels
|
||||
@ -35,6 +35,7 @@ enum ResamplerType
|
||||
kResamplerInvalid = 0xff
|
||||
};
|
||||
|
||||
// TODO(andrew): doesn't need to be part of the interface.
|
||||
enum ResamplerMode
|
||||
{
|
||||
kResamplerMode1To1,
|
||||
@ -63,6 +64,7 @@ class Resampler
|
||||
|
||||
public:
|
||||
Resampler();
|
||||
// TODO(andrew): use an init function instead.
|
||||
Resampler(int inFreq, int outFreq, ResamplerType type);
|
||||
~Resampler();
|
||||
|
||||
|
@ -62,8 +62,6 @@ Resampler::Resampler(int inFreq, int outFreq, ResamplerType type)
|
||||
slave_left_ = NULL;
|
||||
slave_right_ = NULL;
|
||||
|
||||
// TODO(andrew): looks like this class should use an init method
|
||||
// (and possibly a static create).
|
||||
Reset(inFreq, outFreq, type);
|
||||
}
|
||||
|
||||
@ -213,7 +211,7 @@ int Resampler::Reset(int inFreq, int outFreq, ResamplerType type)
|
||||
break;
|
||||
default:
|
||||
my_type_ = kResamplerInvalid;
|
||||
break;
|
||||
return -1;
|
||||
}
|
||||
} else if (outFreq == 1)
|
||||
{
|
||||
@ -233,7 +231,7 @@ int Resampler::Reset(int inFreq, int outFreq, ResamplerType type)
|
||||
break;
|
||||
default:
|
||||
my_type_ = kResamplerInvalid;
|
||||
break;
|
||||
return -1;
|
||||
}
|
||||
} 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_
|
28
webrtc.gyp
28
webrtc.gyp
@ -8,24 +8,26 @@
|
||||
|
||||
{
|
||||
'includes': [
|
||||
'src/common_settings.gypi', # Common settings
|
||||
'src/build/common.gypi',
|
||||
],
|
||||
'targets': [
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'auto_tests',
|
||||
'target_name': 'All',
|
||||
'type': 'none',
|
||||
'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',
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': 'cmd_test',
|
||||
'type': 'none',
|
||||
'dependencies': [
|
||||
'src/voice_engine/voice_engine.gyp:voe_auto_test',
|
||||
'src/voice_engine/voice_engine.gyp:voe_cmd_test',
|
||||
],
|
||||
},
|
||||
},
|
||||
# TODO(andrew): move peerconnection to its own gyp.
|
||||
{
|
||||
'target_name': 'peerconnection_server',
|
||||
'type': 'executable',
|
||||
@ -61,7 +63,7 @@
|
||||
],
|
||||
'msvs_settings': {
|
||||
'VCLinkerTool': {
|
||||
'SubSystem': '2', # Windows
|
||||
'SubSystem': '2', # Windows
|
||||
},
|
||||
},
|
||||
'dependencies': [
|
||||
@ -116,5 +118,5 @@
|
||||
},
|
||||
], # targets
|
||||
}, ], # OS="linux"
|
||||
], # conditions
|
||||
], # conditions
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user