OLD | NEW |
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 "SkInstCnt.h" |
13 #include "SkOSFile.h" | 14 #include "SkOSFile.h" |
14 #include "SkRunnable.h" | 15 #include "SkRunnable.h" |
15 #include "SkTArray.h" | 16 #include "SkTArray.h" |
16 #include "SkTaskGroup.h" | 17 #include "SkTaskGroup.h" |
17 #include "SkTemplates.h" | 18 #include "SkTemplates.h" |
| 19 #include "SkThread.h" |
18 #include "SkTime.h" | 20 #include "SkTime.h" |
19 #include "Test.h" | 21 #include "Test.h" |
20 | 22 |
21 #if SK_SUPPORT_GPU | 23 #if SK_SUPPORT_GPU |
22 #include "GrContext.h" | 24 #include "GrContext.h" |
23 #include "GrContextFactory.h" | 25 #include "GrContextFactory.h" |
24 #endif | 26 #endif |
25 | 27 |
26 using namespace skiatest; | 28 using namespace skiatest; |
27 | 29 |
28 DEFINE_bool2(extendedTest, x, false, "run extended tests for pathOps."); | 30 DEFINE_bool2(extendedTest, x, false, "run extended tests for pathOps."); |
29 | 31 |
30 // need to explicitly declare this, or we get some weird infinite loop llist | 32 // need to explicitly declare this, or we get some weird infinite loop llist |
31 template TestRegistry* TestRegistry::gHead; | 33 template TestRegistry* TestRegistry::gHead; |
32 | 34 |
33 class Iter { | 35 // The threads report back to this object when they are done. |
| 36 class Status { |
34 public: | 37 public: |
35 Iter() { this->reset(); } | 38 explicit Status(int total) |
36 void reset() { fReg = TestRegistry::Head(); } | 39 : fDone(0), fTestCount(0), fFailCount(0), fTotal(total) {} |
37 | 40 // Threadsafe. |
38 Test* next(Reporter* r) { | 41 void endTest(const char* testName, |
39 if (fReg) { | 42 bool success, |
40 TestRegistry::Factory fact = fReg->factory(); | 43 SkMSec elapsed, |
41 fReg = fReg->next(); | 44 int testCount) { |
42 Test* test = fact(NULL); | 45 const int done = 1 + sk_atomic_inc(&fDone); |
43 test->setReporter(r); | 46 for (int i = 0; i < testCount; ++i) { |
44 return test; | 47 sk_atomic_inc(&fTestCount); |
45 } | 48 } |
46 return NULL; | 49 if (!success) { |
47 } | 50 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 } | 51 } |
73 | 52 |
74 SkString prefix(kSkOverwriteLine); | 53 SkString prefix(kSkOverwriteLine); |
75 SkString time; | 54 SkString time; |
76 if (FLAGS_verbose) { | 55 if (FLAGS_verbose) { |
77 prefix.printf("\n"); | 56 prefix.printf("\n"); |
78 time.printf("%5dms ", test->elapsedMs()); | 57 time.printf("%5dms ", elapsed); |
79 } | 58 } |
80 SkDebugf("%s[%3d/%3d] %s%s", prefix.c_str(), done, fTotal, time.c_str(),
test->getName()); | 59 SkDebugf("%s[%3d/%3d] %s%s", prefix.c_str(), done, fTotal, time.c_str(), |
| 60 testName); |
81 } | 61 } |
82 | 62 |
| 63 void reportFailure() { sk_atomic_inc(&fFailCount); } |
| 64 |
| 65 int32_t testCount() { return fTestCount; } |
| 66 int32_t failCount() { return fFailCount; } |
| 67 |
83 private: | 68 private: |
84 int32_t fDone; // atomic | 69 int32_t fDone; // atomic |
| 70 int32_t fTestCount; // atomic |
| 71 int32_t fFailCount; // atomic |
85 const int fTotal; | 72 const int fTotal; |
86 }; | 73 }; |
87 | 74 |
88 // Deletes self when run. | 75 // Deletes self when run. |
89 class SkTestRunnable : public SkRunnable { | 76 class SkTestRunnable : public SkRunnable { |
90 public: | 77 public: |
91 // Takes ownership of test. | 78 SkTestRunnable(const Test& test, |
92 SkTestRunnable(Test* test, int32_t* failCount) : fTest(test), fFailCount(failC
ount) {} | 79 Status* status, |
| 80 GrContextFactory* grContextFactory = NULL) |
| 81 : fTest(test), fStatus(status), fGrContextFactory(grContextFactory) {} |
93 | 82 |
94 virtual void run() { | 83 virtual void run() { |
95 fTest->run(); | 84 struct TestReporter : public skiatest::Reporter { |
96 if(!fTest->passed()) { | 85 public: |
97 sk_atomic_inc(fFailCount); | 86 TestReporter() : fError(false), fTestCount(0) {} |
| 87 void bumpTestCount() SK_OVERRIDE { ++fTestCount; } |
| 88 bool allowExtendedTest() const SK_OVERRIDE { |
| 89 return FLAGS_extendedTest; |
| 90 } |
| 91 bool verbose() const SK_OVERRIDE { return FLAGS_veryVerbose; } |
| 92 void reportFailed(const skiatest::Failure& failure) SK_OVERRIDE { |
| 93 SkDebugf("\nFAILED: %s", failure.toString().c_str()); |
| 94 fError = true; |
| 95 } |
| 96 bool fError; |
| 97 int fTestCount; |
| 98 } reporter; |
| 99 |
| 100 const SkMSec start = SkTime::GetMSecs(); |
| 101 fTest.proc(&reporter, fGrContextFactory); |
| 102 SkMSec elapsed = SkTime::GetMSecs() - start; |
| 103 if (reporter.fError) { |
| 104 fStatus->reportFailure(); |
98 } | 105 } |
| 106 fStatus->endTest(fTest.name, !reporter.fError, elapsed, |
| 107 reporter.fTestCount); |
99 SkDELETE(this); | 108 SkDELETE(this); |
100 } | 109 } |
101 | 110 |
102 private: | 111 private: |
103 SkAutoTDelete<Test> fTest; | 112 Test fTest; |
104 int32_t* fFailCount; | 113 Status* fStatus; |
| 114 GrContextFactory* fGrContextFactory; |
105 }; | 115 }; |
106 | 116 |
107 static bool should_run(const char* testName, bool isGPUTest) { | 117 static bool should_run(const char* testName, bool isGPUTest) { |
108 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, testName)) { | 118 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, testName)) { |
109 return false; | 119 return false; |
110 } | 120 } |
111 if (!FLAGS_cpu && !isGPUTest) { | 121 if (!FLAGS_cpu && !isGPUTest) { |
112 return false; | 122 return false; |
113 } | 123 } |
114 if (!FLAGS_gpu && isGPUTest) { | 124 if (!FLAGS_gpu && isGPUTest) { |
(...skipping 15 matching lines...) Expand all Loading... |
130 SkAutoGraphics ag; | 140 SkAutoGraphics ag; |
131 | 141 |
132 { | 142 { |
133 SkString header("Skia UnitTests:"); | 143 SkString header("Skia UnitTests:"); |
134 if (!FLAGS_match.isEmpty()) { | 144 if (!FLAGS_match.isEmpty()) { |
135 header.appendf(" --match"); | 145 header.appendf(" --match"); |
136 for (int index = 0; index < FLAGS_match.count(); ++index) { | 146 for (int index = 0; index < FLAGS_match.count(); ++index) { |
137 header.appendf(" %s", FLAGS_match[index]); | 147 header.appendf(" %s", FLAGS_match[index]); |
138 } | 148 } |
139 } | 149 } |
140 SkString tmpDir = Test::GetTmpDir(); | 150 SkString tmpDir = skiatest::GetTmpDir(); |
141 if (!tmpDir.isEmpty()) { | 151 if (!tmpDir.isEmpty()) { |
142 header.appendf(" --tmpDir %s", tmpDir.c_str()); | 152 header.appendf(" --tmpDir %s", tmpDir.c_str()); |
143 } | 153 } |
144 SkString resourcePath = GetResourcePath(); | 154 SkString resourcePath = GetResourcePath(); |
145 if (!resourcePath.isEmpty()) { | 155 if (!resourcePath.isEmpty()) { |
146 header.appendf(" --resourcePath %s", resourcePath.c_str()); | 156 header.appendf(" --resourcePath %s", resourcePath.c_str()); |
147 } | 157 } |
148 #ifdef SK_DEBUG | 158 #ifdef SK_DEBUG |
149 header.append(" SK_DEBUG"); | 159 header.append(" SK_DEBUG"); |
150 #else | 160 #else |
151 header.append(" SK_RELEASE"); | 161 header.append(" SK_RELEASE"); |
152 #endif | 162 #endif |
153 header.appendf(" skia_arch_width=%d", (int)sizeof(void*) * 8); | 163 header.appendf(" skia_arch_width=%d", (int)sizeof(void*) * 8); |
154 if (FLAGS_veryVerbose) { | 164 if (FLAGS_veryVerbose) { |
155 header.appendf("\n"); | 165 header.appendf("\n"); |
156 } | 166 } |
157 SkDebugf(header.c_str()); | 167 SkDebugf(header.c_str()); |
158 } | 168 } |
159 | 169 |
160 | 170 |
161 // Count tests first. | 171 // Count tests first. |
162 int total = 0; | 172 int total = 0; |
163 int toRun = 0; | 173 int toRun = 0; |
164 Test* test; | |
165 | 174 |
166 Iter iter; | 175 for (const TestRegistry* iter = TestRegistry::Head(); iter; |
167 while ((test = iter.next(NULL/*reporter not needed*/)) != NULL) { | 176 iter = iter->next()) { |
168 SkAutoTDelete<Test> owned(test); | 177 const Test& test = iter->factory(); |
169 if (should_run(test->getName(), test->isGPUTest())) { | 178 if (should_run(test.name, test.needsGpu)) { |
170 toRun++; | 179 toRun++; |
171 } | 180 } |
172 total++; | 181 total++; |
173 } | 182 } |
174 | 183 |
175 // Now run them. | 184 // Now run them. |
176 iter.reset(); | |
177 int32_t failCount = 0; | |
178 int skipCount = 0; | 185 int skipCount = 0; |
179 | 186 |
180 SkTaskGroup::Enabler enabled(FLAGS_threads); | 187 SkTaskGroup::Enabler enabled(FLAGS_threads); |
181 SkTaskGroup cpuTests; | 188 SkTaskGroup cpuTests; |
182 SkTArray<Test*> gpuTests; // Always passes ownership to an SkTestRunnable | 189 SkTArray<const Test*> gpuTests; |
183 | 190 |
184 DebugfReporter reporter(toRun); | 191 Status status(toRun); |
185 for (int i = 0; i < total; i++) { | 192 for (const TestRegistry* iter = TestRegistry::Head(); iter; |
186 SkAutoTDelete<Test> test(iter.next(&reporter)); | 193 iter = iter->next()) { |
187 if (!should_run(test->getName(), test->isGPUTest())) { | 194 const Test& test = iter->factory(); |
| 195 if (!should_run(test.name, test.needsGpu)) { |
188 ++skipCount; | 196 ++skipCount; |
189 } else if (test->isGPUTest()) { | 197 } else if (test.needsGpu) { |
190 gpuTests.push_back() = test.detach(); | 198 gpuTests.push_back(&test); |
191 } else { | 199 } else { |
192 cpuTests.add(SkNEW_ARGS(SkTestRunnable, (test.detach(), &failCount))
); | 200 cpuTests.add(SkNEW_ARGS(SkTestRunnable, (test, &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], &status, grContextFactoryPtr)) |
| 215 ->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, status.failCount(), skipCount, status.testCount()); |
215 } | 226 } |
216 | 227 |
217 SkDebugf("\n"); | 228 SkDebugf("\n"); |
218 return (failCount == 0) ? 0 : 1; | 229 return (status.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 |
OLD | NEW |