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 |