Wire up --force_fieldtrials for vie_auto_test and for test targets linking with test/test.gyp:{test_main|test_support_main}

This allows use of webrtc field trials  and opens up the possibility to try the different code paths when running the unit tests by wiring them up to a --force_fieldtrials.

Tested: running a test target that links with the above with a flag --force_fieldtrials=invalid leads the test to crash.

BUG=crbug/367114
R=mflodman@webrtc.org, phoglund@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/19439004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@6181 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
andresp@webrtc.org 2014-05-16 09:39:51 +00:00
parent 1b21a57902
commit 60015d27ae
8 changed files with 173 additions and 9 deletions

View File

@ -53,7 +53,6 @@
// needs to push a config with start_active:true or run a local finch
// server.
//
// TODO(andresp): support --force_fieldtirals from webrtc tests.
// TODO(andresp): find out how to get bots to run tests with trials enabled.
namespace webrtc {

View File

@ -0,0 +1,86 @@
/*
* Copyright (c) 2014 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/test/field_trial.h"
#include <algorithm>
#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <map>
#include <string>
#include "webrtc/system_wrappers/interface/field_trial.h"
namespace webrtc {
namespace {
// Clients of this library have show a clear intent to setup field trials by
// linking with it. As so try to crash if they forget to call
// InitFieldTrialsFromString before webrtc tries to access a field trial.
bool field_trials_initiated_ = false;
std::map<std::string, std::string> field_trials_;
} // namespace
namespace field_trial {
std::string FindFullName(const std::string& trial_name) {
assert(field_trials_initiated_);
std::map<std::string, std::string>::const_iterator it =
field_trials_.find(trial_name);
if (it == field_trials_.end())
return std::string();
return it->second;
}
} // namespace field_trial
namespace test {
// Note: this code is copied from src/base/metrics/field_trial.cc since the aim
// is to mimic chromium --force-fieldtrials.
void InitFieldTrialsFromString(const std::string& trials_string) {
static const char kPersistentStringSeparator = '/';
// Catch an error if this is called more than once.
assert(field_trials_initiated_ == false);
field_trials_initiated_ = true;
if (trials_string.empty()) return;
size_t next_item = 0;
while (next_item < trials_string.length()) {
size_t name_end = trials_string.find(kPersistentStringSeparator, next_item);
if (name_end == trials_string.npos || next_item == name_end)
break;
size_t group_name_end = trials_string.find(kPersistentStringSeparator,
name_end + 1);
if (group_name_end == trials_string.npos || name_end + 1 == group_name_end)
break;
std::string name(trials_string, next_item, name_end - next_item);
std::string group_name(trials_string, name_end + 1,
group_name_end - name_end - 1);
next_item = group_name_end + 1;
// Fail if duplicate with different group name.
if (field_trials_.find(name) != field_trials_.end() &&
field_trials_.find(name)->second != group_name)
break;
field_trials_[name] = group_name;
// Successfully parsed all field trials from the string.
if (next_item == trials_string.length())
return;
}
// LOG does not prints when this is called early on main.
fprintf(stderr, "Invalid field trials string.\n");
// Using abort so it crashs both in debug and release mode.
abort();
}
} // namespace test
} // namespace webrtc

37
webrtc/test/field_trial.h Normal file
View File

@ -0,0 +1,37 @@
/*
* Copyright (c) 2014 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 WEBRTC_TEST_FIELD_TRIAL_H_
#define WEBRTC_TEST_FIELD_TRIAL_H_
#include <string>
namespace webrtc {
namespace test {
// Parses enabled field trials from a string config, such as the one passed
// to chrome's argument --force-fieldtrials and initializes webrtc::field_trial
// with such a config.
// E.g.:
// "WebRTC-experimentFoo/Enabled/WebRTC-experimentBar/Enabled100kbps/"
// Assigns the process to group "Enabled" on WebRTCExperimentFoo trial
// and to group "Enabled100kbps" on WebRTCExperimentBar.
//
// E.g. invalid config:
// "WebRTC-experiment1/Enabled" (note missing / separator at the end).
//
// Note: This method crashes with an error message if an invalid config is
// passed to it. That can be used to find out if a binary is parsing the flags.
void InitFieldTrialsFromString(const std::string& config);
} // namespace test
} // namespace webrtc
#endif // WEBRTC_TEST_FIELD_TRIAL_H_

View File

@ -63,6 +63,17 @@
'<(webrtc_root)/modules/modules.gyp:rtp_rtcp',
],
},
{
'target_name': 'field_trial',
'type': 'static_library',
'sources': [
'field_trial.cc',
'field_trial.h',
],
'dependencies': [
'<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers',
],
},
{
'target_name': 'test_main',
'type': 'static_library',
@ -70,8 +81,9 @@
'test_main.cc',
],
'dependencies': [
'<(DEPTH)/testing/gtest.gyp:gtest',
'<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:field_trial_default',
'field_trial',
'<(DEPTH)/testing/gtest.gyp:gtest',
'<(DEPTH)/third_party/gflags/gflags.gyp:gflags',
],
},
{
@ -80,12 +92,9 @@
'dependencies': [
'<(DEPTH)/testing/gtest.gyp:gtest',
'<(DEPTH)/testing/gmock.gyp:gmock',
'<(DEPTH)/third_party/gflags/gflags.gyp:gflags',
'<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers',
],
'sources': [
'test_suite.cc',
'test_suite.h',
'testsupport/android/root_path_android.cc',
'testsupport/android/root_path_android_chromium.cc',
'testsupport/fileutils.cc',
@ -128,11 +137,16 @@
'target_name': 'test_support_main',
'type': 'static_library',
'dependencies': [
'field_trial',
'test_support',
'<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:field_trial_default',
'<(DEPTH)/testing/gmock.gyp:gmock',
'<(DEPTH)/testing/gtest.gyp:gtest',
'<(DEPTH)/third_party/gflags/gflags.gyp:gflags',
],
'sources': [
'run_all_unittests.cc',
'test_suite.cc',
'test_suite.h',
],
},
{

View File

@ -8,14 +8,26 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#include "gflags/gflags.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/test/field_trial.h"
#include "webrtc/test/run_tests.h"
#include "webrtc/test/testsupport/fileutils.h"
DEFINE_string(force_fieldtrials, "",
"Field trials control experimental feature code which can be forced. "
"E.g. running with --force_fieldtrials=WebRTC-FooFeature/Enable/"
" will assign the group Enable to field trial WebRTC-FooFeature.");
int main(int argc, char* argv[]) {
::testing::InitGoogleTest(&argc, argv);
webrtc::test::SetExecutablePath(argv[0]);
// AllowCommandLineParsing allows us to ignore flags passed on to us by
// Chromium build bots without having to explicitly disable them.
google::AllowCommandLineReparsing();
google::ParseCommandLineFlags(&argc, &argv, false);
webrtc::test::SetExecutablePath(argv[0]);
webrtc::test::InitFieldTrialsFromString(FLAGS_force_fieldtrials);
return webrtc::test::RunAllTests();
}

View File

@ -15,9 +15,15 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/test/testsupport/fileutils.h"
#include "webrtc/test/testsupport/trace_to_stderr.h"
#include "webrtc/test/field_trial.h"
DEFINE_bool(logs, false, "print logs to stderr");
DEFINE_string(force_fieldtrials, "",
"Field trials control experimental feature code which can be forced. "
"E.g. running with --force_fieldtrials=WebRTC-FooFeature/Enable/"
" will assign the group Enable to field trial WebRTC-FooFeature.");
namespace webrtc {
namespace test {
@ -28,6 +34,8 @@ TestSuite::TestSuite(int argc, char** argv) {
// Chromium build bots without having to explicitly disable them.
google::AllowCommandLineReparsing();
google::ParseCommandLineFlags(&argc, &argv, true);
webrtc::test::InitFieldTrialsFromString(FLAGS_force_fieldtrials);
}
TestSuite::~TestSuite() {

View File

@ -13,6 +13,7 @@
#include "gflags/gflags.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/test/field_trial.h"
#include "webrtc/test/testsupport/fileutils.h"
#include "webrtc/video_engine/test/auto_test/interface/vie_autotest.h"
#include "webrtc/video_engine/test/auto_test/interface/vie_autotest_window_manager_interface.h"
@ -20,6 +21,10 @@
DEFINE_bool(automated, false, "Run Video engine tests in noninteractive mode.");
DEFINE_bool(auto_custom_call, false, "Run custom call directly.");
DEFINE_string(force_fieldtrials, "",
"Field trials control experimental feature code which can be forced. "
"E.g. running with --force_fieldtrials=WebRTC-FooFeature/Enable/"
" will assign the group Enable to field trial WebRTC-FooFeature.");
static const std::string kStandardTest = "ViEStandardIntegrationTest";
static const std::string kExtendedTest = "ViEExtendedIntegrationTest";
@ -48,6 +53,8 @@ int ViEAutoTestMain::RunTests(int argc, char** argv) {
google::AllowCommandLineReparsing();
// Parse remaining flags:
google::ParseCommandLineFlags(&argc, &argv, true);
// Initialize field trial
webrtc::test::InitFieldTrialsFromString(FLAGS_force_fieldtrials);
int result;
if (FLAGS_automated) {

View File

@ -22,6 +22,7 @@
'<(webrtc_root)/test/metrics.gyp:metrics',
'<(webrtc_root)/test/test.gyp:channel_transport',
'<(webrtc_root)/test/test.gyp:test_support',
'<(webrtc_root)/test/test.gyp:field_trial',
'video_engine_core',
'libvietest',
],