Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(56)

Side by Side Diff: tests/skia_test.cpp

Issue 830513004: Simplify skiatest framework. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Another Patch Set Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« tests/Test.cpp ('K') | « tests/Test.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2011 Google Inc. 2 * Copyright 2011 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "CrashHandler.h" 8 #include "CrashHandler.h"
9 #include "OverwriteLine.h" 9 #include "OverwriteLine.h"
10 #include "Resources.h" 10 #include "Resources.h"
(...skipping 12 matching lines...) Expand all
23 #include "GrContextFactory.h" 23 #include "GrContextFactory.h"
24 #endif 24 #endif
25 25
26 using namespace skiatest; 26 using namespace skiatest;
27 27
28 DEFINE_bool2(extendedTest, x, false, "run extended tests for pathOps."); 28 DEFINE_bool2(extendedTest, x, false, "run extended tests for pathOps.");
29 29
30 // need to explicitly declare this, or we get some weird infinite loop llist 30 // need to explicitly declare this, or we get some weird infinite loop llist
31 template TestRegistry* TestRegistry::gHead; 31 template TestRegistry* TestRegistry::gHead;
32 32
33 class Iter { 33 // The threads report back to this object when they are done.
34 class Status {
34 public: 35 public:
35 Iter() { this->reset(); } 36 explicit Status(int total)
36 void reset() { fReg = TestRegistry::Head(); } 37 : fDone(0), fTestCount(0), fFailCount(0), fTotal(total) {}
37 38 // Threadsafe.
38 Test* next(Reporter* r) { 39 void endTest(const char* testName,
39 if (fReg) { 40 bool success,
40 TestRegistry::Factory fact = fReg->factory(); 41 SkMSec elapsed,
41 fReg = fReg->next(); 42 int testCount) {
42 Test* test = fact(NULL); 43 const int done = 1 + sk_atomic_inc(&fDone);
43 test->setReporter(r); 44 for (int i = 0; i < testCount; ++i) {
44 return test; 45 sk_atomic_inc(&fTestCount);
45 } 46 }
46 return NULL; 47 if (!success) {
47 } 48 SkDebugf("\n---- %s FAILED", testName);
48
49 private:
50 const TestRegistry* fReg;
51 };
52
53 class DebugfReporter : public Reporter {
54 public:
55 explicit DebugfReporter(int total) : fDone(0), fTotal(total) {}
56
57 bool allowExtendedTest() const SK_OVERRIDE { return FLAGS_extendedTest; }
58 bool verbose() const SK_OVERRIDE { return FLAGS_veryVerbose; }
59
60 protected:
61 void onReportFailed(const skiatest::Failure& failure) SK_OVERRIDE {
62 SkString desc;
63 failure.getFailureString(&desc);
64 SkDebugf("\nFAILED: %s", desc.c_str());
65 }
66
67 void onEnd(Test* test) SK_OVERRIDE {
68 const int done = 1 + sk_atomic_inc(&fDone);
69
70 if (!test->passed()) {
71 SkDebugf("\n---- %s FAILED", test->getName());
72 } 49 }
73 50
74 SkString prefix(kSkOverwriteLine); 51 SkString prefix(kSkOverwriteLine);
75 SkString time; 52 SkString time;
76 if (FLAGS_verbose) { 53 if (FLAGS_verbose) {
77 prefix.printf("\n"); 54 prefix.printf("\n");
78 time.printf("%5dms ", test->elapsedMs()); 55 time.printf("%5dms ", elapsed);
79 } 56 }
80 SkDebugf("%s[%3d/%3d] %s%s", prefix.c_str(), done, fTotal, time.c_str(), test->getName()); 57 SkDebugf("%s[%3d/%3d] %s%s", prefix.c_str(), done, fTotal, time.c_str(),
58 testName);
81 } 59 }
82 60
61 void reportFailure() { sk_atomic_inc(&fFailCount); }
62
63 int32_t testCount() { return fTestCount; }
64 int32_t failCount() { return fFailCount; }
65
83 private: 66 private:
84 int32_t fDone; // atomic 67 int32_t fDone; // atomic
68 int32_t fTestCount; // atomic
69 int32_t fFailCount; // atomic
85 const int fTotal; 70 const int fTotal;
86 }; 71 };
87 72
88 // Deletes self when run. 73 // Deletes self when run.
89 class SkTestRunnable : public SkRunnable { 74 class SkTestRunnable : public SkRunnable {
90 public: 75 public:
91 // Takes ownership of test. 76 SkTestRunnable(const Test& test,
92 SkTestRunnable(Test* test, int32_t* failCount) : fTest(test), fFailCount(failC ount) {} 77 Status* status,
78 GrContextFactory* grContextFactory = NULL)
79 : fTest(test), fStatus(status), fGrContextFactory(grContextFactory) {}
93 80
94 virtual void run() { 81 virtual void run() {
95 fTest->run(); 82 struct TestReporter : public skiatest::Reporter {
96 if(!fTest->passed()) { 83 public:
97 sk_atomic_inc(fFailCount); 84 TestReporter() : fError(false), fTestCount(0) {}
85 void bumpTestCount() SK_OVERRIDE { ++fTestCount; }
86 bool allowExtendedTest() const SK_OVERRIDE {
87 return FLAGS_extendedTest;
88 }
89 bool verbose() const SK_OVERRIDE { return FLAGS_veryVerbose; }
90 void reportFailed(const skiatest::Failure& failure) SK_OVERRIDE {
91 SkDebugf("\nFAILED: %s", failure.toString().c_str());
92 fError = true;
93 }
94 bool fError;
95 int fTestCount;
96 } reporter;
97
98 const SkMSec start = SkTime::GetMSecs();
99 fTest.proc(&reporter, fGrContextFactory);
100 SkMSec elapsed = SkTime::GetMSecs() - start;
101 if (reporter.fError) {
102 fStatus->reportFailure();
98 } 103 }
104 fStatus->endTest(fTest.name, !reporter.fError, elapsed,
105 reporter.fTestCount);
99 SkDELETE(this); 106 SkDELETE(this);
100 } 107 }
101 108
102 private: 109 private:
103 SkAutoTDelete<Test> fTest; 110 Test fTest;
104 int32_t* fFailCount; 111 Status* fStatus;
112 GrContextFactory* fGrContextFactory;
105 }; 113 };
106 114
107 static bool should_run(const char* testName, bool isGPUTest) { 115 static bool should_run(const char* testName, bool isGPUTest) {
108 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, testName)) { 116 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, testName)) {
109 return false; 117 return false;
110 } 118 }
111 if (!FLAGS_cpu && !isGPUTest) { 119 if (!FLAGS_cpu && !isGPUTest) {
112 return false; 120 return false;
113 } 121 }
114 if (!FLAGS_gpu && isGPUTest) { 122 if (!FLAGS_gpu && isGPUTest) {
(...skipping 15 matching lines...) Expand all
130 SkAutoGraphics ag; 138 SkAutoGraphics ag;
131 139
132 { 140 {
133 SkString header("Skia UnitTests:"); 141 SkString header("Skia UnitTests:");
134 if (!FLAGS_match.isEmpty()) { 142 if (!FLAGS_match.isEmpty()) {
135 header.appendf(" --match"); 143 header.appendf(" --match");
136 for (int index = 0; index < FLAGS_match.count(); ++index) { 144 for (int index = 0; index < FLAGS_match.count(); ++index) {
137 header.appendf(" %s", FLAGS_match[index]); 145 header.appendf(" %s", FLAGS_match[index]);
138 } 146 }
139 } 147 }
140 SkString tmpDir = Test::GetTmpDir(); 148 SkString tmpDir = skiatest::GetTmpDir();
141 if (!tmpDir.isEmpty()) { 149 if (!tmpDir.isEmpty()) {
142 header.appendf(" --tmpDir %s", tmpDir.c_str()); 150 header.appendf(" --tmpDir %s", tmpDir.c_str());
143 } 151 }
144 SkString resourcePath = GetResourcePath(); 152 SkString resourcePath = GetResourcePath();
145 if (!resourcePath.isEmpty()) { 153 if (!resourcePath.isEmpty()) {
146 header.appendf(" --resourcePath %s", resourcePath.c_str()); 154 header.appendf(" --resourcePath %s", resourcePath.c_str());
147 } 155 }
148 #ifdef SK_DEBUG 156 #ifdef SK_DEBUG
149 header.append(" SK_DEBUG"); 157 header.append(" SK_DEBUG");
150 #else 158 #else
151 header.append(" SK_RELEASE"); 159 header.append(" SK_RELEASE");
152 #endif 160 #endif
153 header.appendf(" skia_arch_width=%d", (int)sizeof(void*) * 8); 161 header.appendf(" skia_arch_width=%d", (int)sizeof(void*) * 8);
154 if (FLAGS_veryVerbose) { 162 if (FLAGS_veryVerbose) {
155 header.appendf("\n"); 163 header.appendf("\n");
156 } 164 }
157 SkDebugf(header.c_str()); 165 SkDebugf(header.c_str());
158 } 166 }
159 167
160 168
161 // Count tests first. 169 // Count tests first.
162 int total = 0; 170 int total = 0;
163 int toRun = 0; 171 int toRun = 0;
164 Test* test;
165 172
166 Iter iter; 173 for (const TestRegistry* iter = TestRegistry::Head(); iter;
167 while ((test = iter.next(NULL/*reporter not needed*/)) != NULL) { 174 iter = iter->next()) {
168 SkAutoTDelete<Test> owned(test); 175 const Test& test = iter->factory();
169 if (should_run(test->getName(), test->isGPUTest())) { 176 if (should_run(test.name, test.needsGpu)) {
170 toRun++; 177 toRun++;
171 } 178 }
172 total++; 179 total++;
173 } 180 }
174 181
175 // Now run them. 182 // Now run them.
176 iter.reset();
177 int32_t failCount = 0;
178 int skipCount = 0; 183 int skipCount = 0;
179 184
180 SkTaskGroup::Enabler enabled(FLAGS_threads); 185 SkTaskGroup::Enabler enabled(FLAGS_threads);
181 SkTaskGroup cpuTests; 186 SkTaskGroup cpuTests;
182 SkTArray<Test*> gpuTests; // Always passes ownership to an SkTestRunnable 187 SkTArray<const Test*> gpuTests;
183 188
184 DebugfReporter reporter(toRun); 189 Status status(toRun);
185 for (int i = 0; i < total; i++) { 190 for (const TestRegistry* iter = TestRegistry::Head(); iter;
186 SkAutoTDelete<Test> test(iter.next(&reporter)); 191 iter = iter->next()) {
187 if (!should_run(test->getName(), test->isGPUTest())) { 192 const Test& test = iter->factory();
193 if (!should_run(test.name, test.needsGpu)) {
188 ++skipCount; 194 ++skipCount;
189 } else if (test->isGPUTest()) { 195 } else if (test.needsGpu) {
190 gpuTests.push_back() = test.detach(); 196 gpuTests.push_back(&test);
191 } else { 197 } else {
192 cpuTests.add(SkNEW_ARGS(SkTestRunnable, (test.detach(), &failCount)) ); 198 cpuTests.add(SkNEW_ARGS(SkTestRunnable, (test, &status)));
193 } 199 }
194 } 200 }
195 201
202 GrContextFactory* grContextFactoryPtr = NULL;
196 #if SK_SUPPORT_GPU 203 #if SK_SUPPORT_GPU
197 // Give GPU tests a context factory if that makes sense on this machine. 204 // Give GPU tests a context factory if that makes sense on this machine.
198 GrContextFactory grContextFactory; 205 GrContextFactory grContextFactory;
199 for (int i = 0; i < gpuTests.count(); i++) { 206 grContextFactoryPtr = &grContextFactory;
200 gpuTests[i]->setGrContextFactory(&grContextFactory); 207
201 }
202 #endif 208 #endif
203 209
204 // Run GPU tests on this thread. 210 // Run GPU tests on this thread.
205 for (int i = 0; i < gpuTests.count(); i++) { 211 for (int i = 0; i < gpuTests.count(); i++) {
206 SkNEW_ARGS(SkTestRunnable, (gpuTests[i], &failCount))->run(); 212 SkNEW_ARGS(SkTestRunnable, (*gpuTests[i], &status, grContextFactoryPtr))
213 ->run();
207 } 214 }
208 215
209 // Block until threaded tests finish. 216 // Block until threaded tests finish.
210 cpuTests.wait(); 217 cpuTests.wait();
211 218
212 if (FLAGS_verbose) { 219 if (FLAGS_verbose) {
213 SkDebugf("\nFinished %d tests, %d failures, %d skipped. (%d internal tes ts)", 220 SkDebugf(
214 toRun, failCount, skipCount, reporter.countTests()); 221 "\nFinished %d tests, %d failures, %d skipped. "
222 "(%d internal tests)",
223 toRun, status.failCount(), skipCount, status.testCount());
215 } 224 }
216 225
217 SkDebugf("\n"); 226 SkDebugf("\n");
218 return (failCount == 0) ? 0 : 1; 227 return (status.failCount() == 0) ? 0 : 1;
219 } 228 }
220 229
221 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) 230 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL)
222 int main(int argc, char** argv) { 231 int main(int argc, char** argv) {
223 SkCommandLineFlags::Parse(argc, argv); 232 SkCommandLineFlags::Parse(argc, argv);
224 return test_main(); 233 return test_main();
225 } 234 }
226 #endif 235 #endif
OLDNEW
« tests/Test.cpp ('K') | « tests/Test.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698