Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ppapi/tests/test_case.h" | 5 #include "ppapi/tests/test_case.h" |
| 6 | 6 |
| 7 #include <string.h> | |
| 8 | |
| 7 #include <sstream> | 9 #include <sstream> |
| 8 | 10 |
| 11 #include "ppapi/cpp/core.h" | |
| 12 #include "ppapi/cpp/module.h" | |
| 9 #include "ppapi/tests/pp_thread.h" | 13 #include "ppapi/tests/pp_thread.h" |
| 10 #include "ppapi/tests/test_utils.h" | 14 #include "ppapi/tests/test_utils.h" |
| 11 #include "ppapi/tests/testing_instance.h" | 15 #include "ppapi/tests/testing_instance.h" |
| 12 | 16 |
| 17 namespace { | |
| 18 | |
| 19 std::string StripPrefixes(const std::string& test_name) { | |
|
bbudge
2013/02/06 14:51:26
s/StripPrefixes/StripPrefix
| |
| 20 const char* const prefixes[] = { | |
| 21 "FAILS_", "FLAKY_", "DISABLED_" }; | |
| 22 for (size_t i = 0; i < sizeof(prefixes)/sizeof(prefixes[0]); ++i) | |
| 23 if (test_name.find(prefixes[i]) == 0) | |
| 24 return test_name.substr(strlen(prefixes[i])); | |
| 25 return test_name; | |
| 26 } | |
| 27 | |
| 28 // Strip the TestCase name off and return the remainder (i.e., everything after | |
| 29 // '_'). If there is no '_', assume only the TestCase was provided, and return | |
| 30 // an empty string. | |
| 31 // For example: | |
| 32 // StripTestCase("Foo_TestName"); | |
| 33 // returns | |
| 34 // "TestName" | |
| 35 // while | |
| 36 // StripTestCase("Foo); | |
| 37 // returns | |
| 38 // "Foo" | |
|
bbudge
2013/02/06 14:51:26
I had trouble understanding this documentation. Ma
| |
| 39 std::string StripTestCase(const std::string& full_test_name) { | |
| 40 size_t delim = full_test_name.find_first_of('_'); | |
| 41 if (delim != std::string::npos) | |
| 42 return full_test_name.substr(delim+1); | |
| 43 // In this case, our "filter" is the empty string; the full test name is the | |
| 44 // same as the TestCase name with which we were constructed. | |
| 45 // TODO(dmichael): It might be nice to be able to PP_DCHECK against the | |
| 46 // TestCase class name, but we'd have to plumb that name to TestCase somehow. | |
| 47 return std::string(); | |
| 48 } | |
| 49 | |
| 50 // Parse |test_filter|, which is a comma-delimited list of (possibly prefixed) | |
| 51 // test names and insert the un-prefixed names in to |remaining_tests|, with | |
| 52 // the bool indicating whether the test should be run. | |
| 53 void ParseTestFilter(std::string test_filter, | |
| 54 std::map<std::string, bool>* remaining_tests) { | |
| 55 // We can't use base/string_util.h::Tokenize in ppapi. Instead, we'll | |
|
bbudge
2013/02/06 14:51:26
Did this comment get cut off?
| |
| 56 while (!test_filter.empty()) { | |
| 57 size_t end_of_first_test_name = test_filter.find_first_of(","); | |
| 58 // Note |end_of_first_test_name| could be npos, which means "take all | |
| 59 // characters" to substr, so this is good for lists of 1 also. | |
| 60 | |
| 61 // |current_test| includes prefixes, if any, like DISABLED_Foo_TestBar | |
| 62 std::string current_test(test_filter.substr(0, end_of_first_test_name)); | |
| 63 | |
| 64 // Advance past the first item to the next. | |
| 65 test_filter.erase(0, end_of_first_test_name + 1); | |
| 66 | |
| 67 std::string stripped_test_name(StripPrefixes(current_test)); | |
| 68 // We'll strip the case for use as a key, because the test name | |
|
bbudge
2013/02/06 14:51:26
This is a little confusing to me. Maybe say "Strip
| |
| 69 // MatchesFilter wants to use to look up the test doesn't have the TestCase | |
| 70 // name. | |
| 71 std::string test_name_without_case(StripTestCase(stripped_test_name)); | |
| 72 | |
| 73 // If the test wasn't prefixed, it should be run. | |
| 74 bool should_run_test = (current_test == stripped_test_name); | |
| 75 PP_DCHECK(remaining_tests->count(test_name_without_case) == 0); | |
| 76 remaining_tests->insert( | |
| 77 std::make_pair(test_name_without_case, should_run_test)); | |
| 78 } | |
| 79 // There may be a trailing comma; ignore empty strings. | |
| 80 remaining_tests->erase(std::string()); | |
| 81 } | |
| 82 | |
| 83 } // namespace | |
| 84 | |
| 13 TestCase::TestCase(TestingInstance* instance) | 85 TestCase::TestCase(TestingInstance* instance) |
| 14 : instance_(instance), | 86 : instance_(instance), |
| 15 testing_interface_(NULL), | 87 testing_interface_(NULL), |
| 16 callback_type_(PP_REQUIRED) { | 88 callback_type_(PP_REQUIRED), |
| 89 have_populated_remaining_tests_(false) { | |
| 17 // Get the testing_interface_ if it is available, so that we can do Resource | 90 // Get the testing_interface_ if it is available, so that we can do Resource |
| 18 // and Var checks on shutdown (see CheckResourcesAndVars). If it is not | 91 // and Var checks on shutdown (see CheckResourcesAndVars). If it is not |
| 19 // available, testing_interface_ will be NULL. Some tests do not require it. | 92 // available, testing_interface_ will be NULL. Some tests do not require it. |
| 20 testing_interface_ = GetTestingInterface(); | 93 testing_interface_ = GetTestingInterface(); |
| 21 } | 94 } |
| 22 | 95 |
| 23 TestCase::~TestCase() { | 96 TestCase::~TestCase() { |
| 24 } | 97 } |
| 25 | 98 |
| 26 bool TestCase::Init() { | 99 bool TestCase::Init() { |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 96 | 169 |
| 97 bool TestCase::EnsureRunningOverHTTP() { | 170 bool TestCase::EnsureRunningOverHTTP() { |
| 98 if (instance_->protocol() != "http:") { | 171 if (instance_->protocol() != "http:") { |
| 99 instance_->AppendError("This test needs to be run over HTTP."); | 172 instance_->AppendError("This test needs to be run over HTTP."); |
| 100 return false; | 173 return false; |
| 101 } | 174 } |
| 102 | 175 |
| 103 return true; | 176 return true; |
| 104 } | 177 } |
| 105 | 178 |
| 106 bool TestCase::MatchesFilter(const std::string& test_name, | 179 bool TestCase::MatchesFilter(const std::string& test_name, |
|
bbudge
2013/02/06 14:51:26
nit: Maybe this method should be named "ShouldRunT
| |
| 107 const std::string& filter) { | 180 const std::string& filter) { |
| 108 return filter.empty() || (test_name == filter); | 181 // If only the TestCase is listed, we're running all the tests in RunTests. |
| 182 if (StripTestCase(filter) == std::string()) | |
| 183 return true; | |
| 184 | |
| 185 // Lazily initialize our "remaining_tests_" map. | |
| 186 if (!have_populated_remaining_tests_) { | |
| 187 ParseTestFilter(filter, &remaining_tests_); | |
| 188 have_populated_remaining_tests_ = true; | |
| 189 } | |
| 190 std::map<std::string, bool>::iterator iter = remaining_tests_.find(test_name); | |
| 191 if (iter == remaining_tests_.end()) { | |
| 192 // The test name wasn't listed in the filter. Don't run it, but store it | |
| 193 // so TestingInstance::ExecuteTests can report an error later. | |
| 194 skipped_tests_.insert(test_name); | |
| 195 return false; | |
| 196 } | |
| 197 bool should_run_test = iter->second; | |
| 198 remaining_tests_.erase(iter); | |
| 199 return should_run_test; | |
| 200 } | |
| 201 | |
| 202 PP_TimeTicks TestCase::NowInTimeTicks() { | |
| 203 return pp::Module::Get()->core()->GetTimeTicks(); | |
| 109 } | 204 } |
| 110 | 205 |
| 111 std::string TestCase::CheckResourcesAndVars(std::string errors) { | 206 std::string TestCase::CheckResourcesAndVars(std::string errors) { |
| 112 if (!errors.empty()) | 207 if (!errors.empty()) |
| 113 return errors; | 208 return errors; |
| 114 | 209 |
| 115 if (testing_interface_) { | 210 if (testing_interface_) { |
| 116 // TODO(dmichael): Fix tests that leak resources and enable the following: | 211 // TODO(dmichael): Fix tests that leak resources and enable the following: |
| 117 /* | 212 /* |
| 118 uint32_t leaked_resources = | 213 uint32_t leaked_resources = |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 163 void TestCase::RunOnThreadInternal(void (*thread_func)(void*), | 258 void TestCase::RunOnThreadInternal(void (*thread_func)(void*), |
| 164 void* thread_param, | 259 void* thread_param, |
| 165 const PPB_Testing_Dev* testing_interface) { | 260 const PPB_Testing_Dev* testing_interface) { |
| 166 PP_ThreadType thread; | 261 PP_ThreadType thread; |
| 167 PP_CreateThread(&thread, thread_func, thread_param); | 262 PP_CreateThread(&thread, thread_func, thread_param); |
| 168 // Run a message loop so pepper calls can be dispatched. The background | 263 // Run a message loop so pepper calls can be dispatched. The background |
| 169 // thread will set result_ and make us Quit when it's done. | 264 // thread will set result_ and make us Quit when it's done. |
| 170 testing_interface->RunMessageLoop(instance_->pp_instance()); | 265 testing_interface->RunMessageLoop(instance_->pp_instance()); |
| 171 PP_JoinThread(thread); | 266 PP_JoinThread(thread); |
| 172 } | 267 } |
| OLD | NEW |