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

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: mtklein comments 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
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"
11 #include "SkCommonFlags.h" 11 #include "SkCommonFlags.h"
12 #include "SkGraphics.h" 12 #include "SkGraphics.h"
13 #include "SkOSFile.h" 13 #include "SkOSFile.h"
14 #include "SkRunnable.h" 14 #include "SkRunnable.h"
15 #include "SkTArray.h" 15 #include "SkTArray.h"
16 #include "SkTaskGroup.h" 16 #include "SkTaskGroup.h"
17 #include "SkTemplates.h" 17 #include "SkTemplates.h"
18 #include "SkTime.h" 18 #include "SkTime.h"
19 #include "TempDir.h"
19 #include "Test.h" 20 #include "Test.h"
20 21
21 #if SK_SUPPORT_GPU 22 #if SK_SUPPORT_GPU
22 #include "GrContext.h" 23 #include "GrContext.h"
23 #include "GrContextFactory.h" 24 #include "GrContextFactory.h"
24 #endif 25 #endif
25 26
26 using namespace skiatest; 27 using namespace skiatest;
27 28
28 DEFINE_bool2(extendedTest, x, false, "run extended tests for pathOps."); 29 DEFINE_bool2(extendedTest, x, false, "run extended tests for pathOps.");
29 30
30 // need to explicitly declare this, or we get some weird infinite loop llist 31 // need to explicitly declare this, or we get some weird infinite loop llist
31 template TestRegistry* TestRegistry::gHead; 32 template TestRegistry* TestRegistry::gHead;
32 33
33 class Iter { 34 class DebugfReporter : public Reporter {
34 public: 35 public:
35 Iter() { this->reset(); } 36 DebugfReporter() : fErrorCount(0), fTestCount(0) {}
36 void reset() { fReg = TestRegistry::Head(); } 37 void bumpTestCount() SK_OVERRIDE { ++fTestCount; }
37 38 bool allowExtendedTest() const SK_OVERRIDE { return FLAGS_extendedTest; }
38 Test* next(Reporter* r) { 39 bool verbose() const SK_OVERRIDE { return FLAGS_veryVerbose; }
39 if (fReg) { 40 SkString getTmpDir() const SK_OVERRIDE { return sk_tools::GetTmpDir(); }
40 TestRegistry::Factory fact = fReg->factory(); 41 void reportFailed(const skiatest::Failure& failure) SK_OVERRIDE {
41 fReg = fReg->next(); 42 SkDebugf("\nFAILED: %s", failure.toString().c_str());
42 Test* test = fact(NULL); 43 ++fErrorCount;
43 test->setReporter(r);
44 return test;
45 }
46 return NULL;
47 } 44 }
48 45 int fErrorCount;
49 private: 46 int fTestCount;
50 const TestRegistry* fReg;
51 }; 47 };
52 48
53 class DebugfReporter : public Reporter { 49 class DebugfStatusKeeper {
54 public: 50 public:
55 explicit DebugfReporter(int total) : fDone(0), fTotal(total) {} 51 explicit DebugfStatusKeeper(int total) : fDone(0), fTotal(total) {}
56 52 void endTest(const char* testName,
57 bool allowExtendedTest() const SK_OVERRIDE { return FLAGS_extendedTest; } 53 bool success,
58 bool verbose() const SK_OVERRIDE { return FLAGS_veryVerbose; } 54 SkMSec elapsed,
59 55 int testCount) {
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); 56 const int done = 1 + sk_atomic_inc(&fDone);
69 57 for (int i = 0; i < testCount; ++i) {
70 if (!test->passed()) { 58 sk_atomic_inc(&fTestCount);
71 SkDebugf("\n---- %s FAILED", test->getName()); 59 }
60 if (!success) {
61 SkDebugf("\n---- %s FAILED", testName);
72 } 62 }
73 63
74 SkString prefix(kSkOverwriteLine); 64 SkString prefix(kSkOverwriteLine);
75 SkString time; 65 SkString time;
76 if (FLAGS_verbose) { 66 if (FLAGS_verbose) {
77 prefix.printf("\n"); 67 prefix.printf("\n");
78 time.printf("%5dms ", test->elapsedMs()); 68 time.printf("%5dms ", elapsed);
79 } 69 }
80 SkDebugf("%s[%3d/%3d] %s%s", prefix.c_str(), done, fTotal, time.c_str(), test->getName()); 70 SkDebugf("%s[%3d/%3d] %s%s", prefix.c_str(), done, fTotal, time.c_str(),
71 testName);
81 } 72 }
82 73
74 int32_t testCount() { return fTestCount; }
75
83 private: 76 private:
84 int32_t fDone; // atomic 77 int32_t fDone; // atomic
78 int32_t fTestCount; // atomic
85 const int fTotal; 79 const int fTotal;
86 }; 80 };
87 81
88 // Deletes self when run. 82 // Deletes self when run.
89 class SkTestRunnable : public SkRunnable { 83 class SkTestRunnable : public SkRunnable {
90 public: 84 public:
91 // Takes ownership of test. 85 // Takes ownership of test.
92 SkTestRunnable(Test* test, int32_t* failCount) : fTest(test), fFailCount(failC ount) {} 86 SkTestRunnable(const Test& test,
87 int32_t* failCount,
88 DebugfStatusKeeper* status,
89 GrContextFactory* grContextFactory = NULL)
90 : fTest(test)
91 , fFailCount(failCount)
92 , fStatus(status)
93 , fGrContextFactory(grContextFactory) {}
93 94
94 virtual void run() { 95 virtual void run() {
95 fTest->run(); 96 DebugfReporter reporter;
96 if(!fTest->passed()) { 97 const SkMSec start = SkTime::GetMSecs();
98 fTest.proc(&reporter, fGrContextFactory);
99 SkMSec elapsed = SkTime::GetMSecs() - start;
100 bool success = 0 == reporter.fErrorCount;
101 if (!success) {
97 sk_atomic_inc(fFailCount); 102 sk_atomic_inc(fFailCount);
98 } 103 }
104 fStatus->endTest(fTest.name, success, elapsed, reporter.fTestCount);
99 SkDELETE(this); 105 SkDELETE(this);
100 } 106 }
101 107
102 private: 108 private:
103 SkAutoTDelete<Test> fTest; 109 Test fTest;
104 int32_t* fFailCount; 110 int32_t* fFailCount;
111 DebugfStatusKeeper* 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 = sk_tools::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; 183 int32_t failCount = 0;
178 int skipCount = 0; 184 int skipCount = 0;
179 185
180 SkTaskGroup::Enabler enabled(FLAGS_threads); 186 SkTaskGroup::Enabler enabled(FLAGS_threads);
181 SkTaskGroup cpuTests; 187 SkTaskGroup cpuTests;
182 SkTArray<Test*> gpuTests; // Always passes ownership to an SkTestRunnable 188 SkTArray<const Test*> gpuTests;
183 189
184 DebugfReporter reporter(toRun); 190 DebugfStatusKeeper status(toRun);
185 for (int i = 0; i < total; i++) { 191 for (const TestRegistry* iter = TestRegistry::Head(); iter;
186 SkAutoTDelete<Test> test(iter.next(&reporter)); 192 iter = iter->next()) {
187 if (!should_run(test->getName(), test->isGPUTest())) { 193 const Test& test = iter->factory();
194 if (!should_run(test.name, test.needsGpu)) {
188 ++skipCount; 195 ++skipCount;
189 } else if (test->isGPUTest()) { 196 } else if (test.needsGpu) {
190 gpuTests.push_back() = test.detach(); 197 gpuTests.push_back(&test);
191 } else { 198 } else {
192 cpuTests.add(SkNEW_ARGS(SkTestRunnable, (test.detach(), &failCount)) ); 199 cpuTests.add(
200 SkNEW_ARGS(SkTestRunnable, (test, &failCount, &status)));
193 } 201 }
194 } 202 }
195 203
204 GrContextFactory* grContextFactoryPtr = NULL;
196 #if SK_SUPPORT_GPU 205 #if SK_SUPPORT_GPU
197 // Give GPU tests a context factory if that makes sense on this machine. 206 // Give GPU tests a context factory if that makes sense on this machine.
198 GrContextFactory grContextFactory; 207 GrContextFactory grContextFactory;
199 for (int i = 0; i < gpuTests.count(); i++) { 208 grContextFactoryPtr = &grContextFactory;
200 gpuTests[i]->setGrContextFactory(&grContextFactory); 209
201 }
202 #endif 210 #endif
203 211
204 // Run GPU tests on this thread. 212 // Run GPU tests on this thread.
205 for (int i = 0; i < gpuTests.count(); i++) { 213 for (int i = 0; i < gpuTests.count(); i++) {
206 SkNEW_ARGS(SkTestRunnable, (gpuTests[i], &failCount))->run(); 214 SkNEW_ARGS(SkTestRunnable, (*gpuTests[i], &failCount, &status,
215 grContextFactoryPtr))->run();
207 } 216 }
208 217
209 // Block until threaded tests finish. 218 // Block until threaded tests finish.
210 cpuTests.wait(); 219 cpuTests.wait();
211 220
212 if (FLAGS_verbose) { 221 if (FLAGS_verbose) {
213 SkDebugf("\nFinished %d tests, %d failures, %d skipped. (%d internal tes ts)", 222 SkDebugf(
214 toRun, failCount, skipCount, reporter.countTests()); 223 "\nFinished %d tests, %d failures, %d skipped. "
224 "(%d internal tests)",
225 toRun, failCount, skipCount, status.testCount());
215 } 226 }
216 227
217 SkDebugf("\n"); 228 SkDebugf("\n");
218 return (failCount == 0) ? 0 : 1; 229 return (failCount == 0) ? 0 : 1;
219 } 230 }
220 231
221 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) 232 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL)
222 int main(int argc, char** argv) { 233 int main(int argc, char** argv) {
223 SkCommandLineFlags::Parse(argc, argv); 234 SkCommandLineFlags::Parse(argc, argv);
224 return test_main(); 235 return test_main();
225 } 236 }
226 #endif 237 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698