summaryrefslogtreecommitdiffstats
path: root/content/public/test
diff options
context:
space:
mode:
authorphajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-24 01:05:24 +0000
committerphajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-24 01:05:24 +0000
commita849fe38ede485987714d71ea32738586eafd30e (patch)
tree620f6aa89239ebe30bbd57be9b1cf52d3139acce /content/public/test
parentc974d5d74d83ca4a1d5a5624878f0b3b9be2d8be (diff)
downloadchromium_src-a849fe38ede485987714d71ea32738586eafd30e.zip
chromium_src-a849fe38ede485987714d71ea32738586eafd30e.tar.gz
chromium_src-a849fe38ede485987714d71ea32738586eafd30e.tar.bz2
Revert "Revert "GTTF: refactor interface..." and Revert "GTTF: Implement test retries.""
This reverts commit ad079af85f8d5a6545ead008db256657b9770096. TBR=kouhei BUG=236893 Review URL: https://codereview.chromium.org/38973002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@230580 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/public/test')
-rw-r--r--content/public/test/test_launcher.cc230
1 files changed, 135 insertions, 95 deletions
diff --git a/content/public/test/test_launcher.cc b/content/public/test/test_launcher.cc
index 0e75b52..31dbef2 100644
--- a/content/public/test/test_launcher.cc
+++ b/content/public/test/test_launcher.cc
@@ -103,33 +103,26 @@ class WrapperTestLauncherDelegate : public base::TestLauncherDelegate {
const testing::TestInfo* test_info) OVERRIDE;
virtual bool ShouldRunTest(const testing::TestCase* test_case,
const testing::TestInfo* test_info) OVERRIDE;
- virtual void RunTest(
- const testing::TestCase* test_case,
- const testing::TestInfo* test_info,
- const base::TestLauncherDelegate::TestResultCallback& callback) OVERRIDE;
- virtual void RunRemainingTests() OVERRIDE;
+ virtual void RunTests(base::TestLauncher* test_launcher,
+ const std::vector<std::string>& test_names) OVERRIDE;
+ virtual size_t RetryTests(
+ base::TestLauncher* test_launcher,
+ const std::vector<std::string>& test_names) OVERRIDE;
private:
- struct TestInfo {
- std::string GetFullName() const { return test_case_name + "." + test_name; }
-
- std::string test_case_name;
- std::string test_name;
- std::vector<base::TestLauncherDelegate::TestResultCallback> callbacks;
- };
-
- // Launches test from |test_info| using |command_line| and parallel launcher.
- void DoRunTest(const TestInfo& test_info, const CommandLine& command_line);
+ void DoRunTest(base::TestLauncher* test_launcher,
+ const std::string& test_name);
- // Launches test named |test_name| using |command_line| and parallel launcher,
+ // Launches test named |test_name| using parallel launcher,
// given result of PRE_ test |pre_test_result|.
- void RunDependentTest(const std::string test_name,
- const CommandLine& command_line,
+ void RunDependentTest(base::TestLauncher* test_launcher,
+ const std::string test_name,
const base::TestResult& pre_test_result);
// Callback to receive result of a test.
void GTestCallback(
- const TestInfo& test_info,
+ base::TestLauncher* test_launcher,
+ const std::string& test_name,
int exit_code,
const base::TimeDelta& elapsed_time,
bool was_timeout,
@@ -146,10 +139,19 @@ class WrapperTestLauncherDelegate : public base::TestLauncherDelegate {
base::ParallelTestLauncher parallel_launcher_;
- // Store all tests to run before running any of them to properly
- // handle PRE_ tests. The map is indexed by test full name (e.g. "A.B").
- typedef std::map<std::string, TestInfo> TestInfoMap;
- TestInfoMap tests_to_run_;
+ // Store dependent test name (map is indexed by full test name).
+ typedef std::map<std::string, std::string> DependentTestMap;
+ DependentTestMap dependent_test_map_;
+ DependentTestMap reverse_dependent_test_map_;
+
+ // Store unique data directory prefix for test names (without PRE_ prefixes).
+ // PRE_ tests and tests that depend on them must share the same
+ // data directory. Using test name as directory name leads to too long
+ // names (exceeding UNIX_PATH_MAX, which creates a problem with
+ // process_singleton_linux). Create a randomly-named temporary directory
+ // and keep track of the names so that PRE_ tests can still re-use them.
+ typedef std::map<std::string, base::FilePath> UserDataDirMap;
+ UserDataDirMap user_data_dir_map_;
// Temporary directory for user data directories.
base::ScopedTempDir temp_dir_;
@@ -158,7 +160,8 @@ class WrapperTestLauncherDelegate : public base::TestLauncherDelegate {
};
void WrapperTestLauncherDelegate::OnTestIterationStarting() {
- tests_to_run_.clear();
+ dependent_test_map_.clear();
+ user_data_dir_map_.clear();
}
std::string WrapperTestLauncherDelegate::GetTestNameForFiltering(
@@ -188,74 +191,112 @@ bool WrapperTestLauncherDelegate::ShouldRunTest(
return true;
}
-void WrapperTestLauncherDelegate::RunTest(
- const testing::TestCase* test_case,
- const testing::TestInfo* test_info,
- const base::TestLauncherDelegate::TestResultCallback& callback) {
- TestInfo run_test_info;
- run_test_info.test_case_name = test_case->name();
- run_test_info.test_name = test_info->name();
- run_test_info.callbacks.push_back(callback);
-
- DCHECK(!ContainsKey(tests_to_run_, run_test_info.GetFullName()));
- tests_to_run_[run_test_info.GetFullName()] = run_test_info;
-}
-
-void WrapperTestLauncherDelegate::RunRemainingTests() {
- // PRE_ tests and tests that depend on them must share the same
- // data directory. Using test name as directory name leads to too long
- // names (exceeding UNIX_PATH_MAX, which creates a problem with
- // process_singleton_linux). Create a randomly-named temporary directory
- // and keep track of the names so that PRE_ tests can still re-use them.
- std::map<std::string, base::FilePath> temp_directories;
-
+void WrapperTestLauncherDelegate::RunTests(
+ base::TestLauncher* test_launcher,
+ const std::vector<std::string>& test_names) {
// List of tests we can kick off right now, depending on no other tests.
- std::vector<std::pair<std::string, CommandLine> > tests_to_run_now;
+ std::vector<std::string> tests_to_run_now;
- for (TestInfoMap::iterator i = tests_to_run_.begin();
- i != tests_to_run_.end();
- ++i) {
- const TestInfo& test_info = i->second;
+ std::set<std::string> test_names_set(test_names.begin(), test_names.end());
+
+ for (size_t i = 0; i < test_names.size(); i++) {
+ std::string full_name(test_names[i]);
// Make sure PRE_ tests and tests that depend on them share the same
// data directory - based it on the test name without prefixes.
- std::string test_name_no_pre(RemoveAnyPrePrefixes(test_info.GetFullName()));
- if (!ContainsKey(temp_directories, test_name_no_pre)) {
+ std::string test_name_no_pre(RemoveAnyPrePrefixes(full_name));
+ if (!ContainsKey(user_data_dir_map_, test_name_no_pre)) {
base::FilePath temp_dir;
CHECK(file_util::CreateTemporaryDirInDir(
temp_dir_.path(), FILE_PATH_LITERAL("d"), &temp_dir));
- temp_directories[test_name_no_pre] = temp_dir;
+ user_data_dir_map_[test_name_no_pre] = temp_dir;
}
- CommandLine new_cmd_line(*CommandLine::ForCurrentProcess());
- CHECK(launcher_delegate_->AdjustChildProcessCommandLine(
- &new_cmd_line, temp_directories[test_name_no_pre]));
-
+ size_t dot_pos = full_name.find('.');
+ CHECK_NE(dot_pos, std::string::npos);
+ std::string test_case_name = full_name.substr(0, dot_pos);
+ std::string test_name = full_name.substr(dot_pos + 1);
std::string pre_test_name(
- test_info.test_case_name + "." + kPreTestPrefix + test_info.test_name);
- if (ContainsKey(tests_to_run_, pre_test_name)) {
- tests_to_run_[pre_test_name].callbacks.push_back(
- base::Bind(&WrapperTestLauncherDelegate::RunDependentTest,
- base::Unretained(this),
- test_info.GetFullName(),
- new_cmd_line));
+ test_case_name + "." + kPreTestPrefix + test_name);
+ if (ContainsKey(test_names_set, pre_test_name)) {
+ DCHECK(!ContainsKey(dependent_test_map_, pre_test_name));
+ dependent_test_map_[pre_test_name] = full_name;
+
+ DCHECK(!ContainsKey(reverse_dependent_test_map_, full_name));
+ reverse_dependent_test_map_[full_name] = pre_test_name;
} else {
- tests_to_run_now.push_back(
- std::make_pair(test_info.GetFullName(), new_cmd_line));
+ tests_to_run_now.push_back(full_name);
}
}
- for (size_t i = 0; i < tests_to_run_now.size(); i++) {
- const TestInfo& test_info = tests_to_run_[tests_to_run_now[i].first];
- const CommandLine& cmd_line = tests_to_run_now[i].second;
- DoRunTest(test_info, cmd_line);
+ for (size_t i = 0; i < tests_to_run_now.size(); i++)
+ DoRunTest(test_launcher, tests_to_run_now[i]);
+}
+
+size_t WrapperTestLauncherDelegate::RetryTests(
+ base::TestLauncher* test_launcher,
+ const std::vector<std::string>& test_names) {
+ // List of tests we can kick off right now, depending on no other tests.
+ std::vector<std::string> tests_to_run_now;
+
+ // We retry at least the tests requested to retry.
+ std::set<std::string> test_names_set(test_names.begin(), test_names.end());
+
+ // In the face of PRE_ tests, we need to retry the entire chain of tests,
+ // from the very first one.
+ for (size_t i = 0; i < test_names.size(); i++) {
+ std::string test_name(test_names[i]);
+ while (ContainsKey(reverse_dependent_test_map_, test_name)) {
+ test_name = reverse_dependent_test_map_[test_name];
+ test_names_set.insert(test_name);
+ }
}
+
+ // Discard user data directories from any previous runs. Start with
+ // fresh state.
+ user_data_dir_map_.clear();
+
+ for (std::set<std::string>::const_iterator i = test_names_set.begin();
+ i != test_names_set.end();
+ ++i) {
+ std::string full_name(*i);
+
+ // Make sure PRE_ tests and tests that depend on them share the same
+ // data directory - based it on the test name without prefixes.
+ std::string test_name_no_pre(RemoveAnyPrePrefixes(full_name));
+ if (!ContainsKey(user_data_dir_map_, test_name_no_pre)) {
+ base::FilePath temp_dir;
+ CHECK(file_util::CreateTemporaryDirInDir(
+ temp_dir_.path(), FILE_PATH_LITERAL("d"), &temp_dir));
+ user_data_dir_map_[test_name_no_pre] = temp_dir;
+ }
+
+ size_t dot_pos = full_name.find('.');
+ CHECK_NE(dot_pos, std::string::npos);
+ std::string test_case_name = full_name.substr(0, dot_pos);
+ std::string test_name = full_name.substr(dot_pos + 1);
+ std::string pre_test_name(
+ test_case_name + "." + kPreTestPrefix + test_name);
+ if (!ContainsKey(test_names_set, pre_test_name))
+ tests_to_run_now.push_back(full_name);
+ }
+
+ for (size_t i = 0; i < tests_to_run_now.size(); i++)
+ DoRunTest(test_launcher, tests_to_run_now[i]);
+
+ return test_names_set.size();
}
-void WrapperTestLauncherDelegate::DoRunTest(const TestInfo& test_info,
- const CommandLine& command_line) {
- CommandLine new_cmd_line(command_line.GetProgram());
- CommandLine::SwitchMap switches = command_line.GetSwitches();
+void WrapperTestLauncherDelegate::DoRunTest(base::TestLauncher* test_launcher,
+ const std::string& test_name) {
+ std::string test_name_no_pre(RemoveAnyPrePrefixes(test_name));
+
+ CommandLine cmd_line(*CommandLine::ForCurrentProcess());
+ CHECK(launcher_delegate_->AdjustChildProcessCommandLine(
+ &cmd_line, user_data_dir_map_[test_name_no_pre]));
+
+ CommandLine new_cmd_line(cmd_line.GetProgram());
+ CommandLine::SwitchMap switches = cmd_line.GetSwitches();
// Strip out gtest_output flag because otherwise we would overwrite results
// of the other tests.
@@ -269,55 +310,52 @@ void WrapperTestLauncherDelegate::DoRunTest(const TestInfo& test_info,
// Always enable disabled tests. This method is not called with disabled
// tests unless this flag was specified to the browser test executable.
new_cmd_line.AppendSwitch("gtest_also_run_disabled_tests");
- new_cmd_line.AppendSwitchASCII(
- "gtest_filter",
- test_info.test_case_name + "." + test_info.test_name);
+ new_cmd_line.AppendSwitchASCII("gtest_filter", test_name);
new_cmd_line.AppendSwitch(kSingleProcessTestsFlag);
char* browser_wrapper = getenv("BROWSER_WRAPPER");
- // PRE_ tests and tests that depend on them should share the sequence token
- // name, so that they are run serially.
- std::string test_name_no_pre = RemoveAnyPrePrefixes(
- test_info.test_case_name + "." + test_info.test_name);
-
parallel_launcher_.LaunchChildGTestProcess(
new_cmd_line,
browser_wrapper ? browser_wrapper : std::string(),
TestTimeouts::action_max_timeout(),
base::Bind(&WrapperTestLauncherDelegate::GTestCallback,
base::Unretained(this),
- test_info));
+ test_launcher,
+ test_name));
}
void WrapperTestLauncherDelegate::RunDependentTest(
+ base::TestLauncher* test_launcher,
const std::string test_name,
- const CommandLine& command_line,
const base::TestResult& pre_test_result) {
- const TestInfo& test_info = tests_to_run_[test_name];
if (pre_test_result.status == base::TestResult::TEST_SUCCESS) {
// Only run the dependent test if PRE_ test succeeded.
- DoRunTest(test_info, command_line);
+ DoRunTest(test_launcher, test_name);
} else {
// Otherwise skip the test.
base::TestResult test_result;
- test_result.test_case_name = test_info.test_case_name;
- test_result.test_name = test_info.test_name;
+ test_result.full_name = test_name;
test_result.status = base::TestResult::TEST_SKIPPED;
- for (size_t i = 0; i < test_info.callbacks.size(); i++)
- test_info.callbacks[i].Run(test_result);
+ test_launcher->OnTestFinished(test_result);
+
+ if (ContainsKey(dependent_test_map_, test_name)) {
+ RunDependentTest(test_launcher,
+ dependent_test_map_[test_name],
+ test_result);
+ }
}
}
void WrapperTestLauncherDelegate::GTestCallback(
- const TestInfo& test_info,
+ base::TestLauncher* test_launcher,
+ const std::string& test_name,
int exit_code,
const base::TimeDelta& elapsed_time,
bool was_timeout,
const std::string& output) {
base::TestResult result;
- result.test_case_name = test_info.test_case_name;
- result.test_name = test_info.test_name;
+ result.full_name = test_name;
// TODO(phajdan.jr): Recognize crashes.
if (exit_code == 0)
@@ -334,8 +372,10 @@ void WrapperTestLauncherDelegate::GTestCallback(
fprintf(stdout, "%s", output.c_str());
fflush(stdout);
- for (size_t i = 0; i < test_info.callbacks.size(); i++)
- test_info.callbacks[i].Run(result);
+ if (ContainsKey(dependent_test_map_, test_name))
+ RunDependentTest(test_launcher, dependent_test_map_[test_name], result);
+
+ test_launcher->OnTestFinished(result);
parallel_launcher_.ResetOutputWatchdog();
}