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

Side by Side Diff: tests/skia_test.cpp

Issue 109513002: make tests output spin on the same line by default (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: more refactoring Created 6 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 | Annotate | Revision Log
« no previous file with comments | « gyp/dm.gyp ('k') | tools/OverwriteLine.h » ('j') | 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 "SkCommandLineFlags.h" 8 #include "SkCommandLineFlags.h"
9 #include "SkGraphics.h" 9 #include "SkGraphics.h"
10 #include "SkOSFile.h" 10 #include "SkOSFile.h"
11 #include "SkTArray.h" 11 #include "SkTArray.h"
12 #include "SkTemplates.h" 12 #include "SkTemplates.h"
13 #include "SkThreadPool.h" 13 #include "SkThreadPool.h"
14 #include "SkTime.h" 14 #include "SkTime.h"
15 #include "Test.h" 15 #include "Test.h"
16 #include "OverwriteLine.h"
16 17
17 #if SK_SUPPORT_GPU 18 #if SK_SUPPORT_GPU
18 #include "GrContext.h" 19 #include "GrContext.h"
19 #endif 20 #endif
20 21
21 using namespace skiatest; 22 using namespace skiatest;
22 23
23 // need to explicitly declare this, or we get some weird infinite loop llist
24 template TestRegistry* TestRegistry::gHead;
25
26 class Iter {
27 public:
28 Iter(Reporter* r) : fReporter(r) {
29 r->ref();
30 this->reset();
31 }
32
33 void reset() {
34 fReg = TestRegistry::Head();
35 }
36
37 ~Iter() {
38 fReporter->unref();
39 }
40
41 Test* next() {
42 if (fReg) {
43 TestRegistry::Factory fact = fReg->factory();
44 fReg = fReg->next();
45 Test* test = fact(NULL);
46 test->setReporter(fReporter);
47 return test;
48 }
49 return NULL;
50 }
51
52 private:
53 Reporter* fReporter;
54 const TestRegistry* fReg;
55 };
56
57 class DebugfReporter : public Reporter {
58 public:
59 DebugfReporter(bool allowExtendedTest, bool allowThreaded, bool verbose)
60 : fNextIndex(0)
61 , fPending(0)
62 , fTotal(0)
63 , fAllowExtendedTest(allowExtendedTest)
64 , fAllowThreaded(allowThreaded)
65 , fVerbose(verbose) {
66 }
67
68 void setTotal(int total) {
69 fTotal = total;
70 }
71
72 virtual bool allowExtendedTest() const SK_OVERRIDE {
73 return fAllowExtendedTest;
74 }
75
76 virtual bool allowThreaded() const SK_OVERRIDE {
77 return fAllowThreaded;
78 }
79
80 virtual bool verbose() const SK_OVERRIDE {
81 return fVerbose;
82 }
83
84 protected:
85 virtual void onStart(Test* test) {
86 SkAutoMutexAcquire lock(fStartEndMutex);
87 fNextIndex++;
88 fPending++;
89 SkDebugf("[%3d/%3d] (%d) %s\n", fNextIndex, fTotal, fPending, test->getN ame());
90 }
91
92 virtual void onReportFailed(const SkString& desc) {
93 SkDebugf("\tFAILED: %s\n", desc.c_str());
94 }
95
96 virtual void onEnd(Test* test) {
97 SkAutoMutexAcquire lock(fStartEndMutex);
98 if (!test->passed()) {
99 SkDebugf("---- %s FAILED\n", test->getName());
100 }
101
102 fPending--;
103 if (fNextIndex == fTotal) {
104 // Just waiting on straggler tests. Shame them by printing their na me and runtime.
105 SkDebugf(" (%d) %5.1fs %s\n",
106 fPending, test->elapsedMs() / 1e3, test->getName());
107 }
108 }
109
110 private:
111 SkMutex fStartEndMutex; // Guards fNextIndex and fPending.
112 int32_t fNextIndex;
113 int32_t fPending;
114
115 // Once the tests get going, these are logically const.
116 int fTotal;
117 bool fAllowExtendedTest;
118 bool fAllowThreaded;
119 bool fVerbose;
120 };
121
122 DEFINE_string2(match, m, NULL, "[~][^]substring[$] [...] of test name to run.\n" \ 24 DEFINE_string2(match, m, NULL, "[~][^]substring[$] [...] of test name to run.\n" \
123 "Multiple matches may be separated by spaces.\n" \ 25 "Multiple matches may be separated by spaces.\n" \
124 "~ causes a matching test to always be skipped\n" \ 26 "~ causes a matching test to always be skipped\n" \
125 "^ requires the start of the test to match\n" \ 27 "^ requires the start of the test to match\n" \
126 "$ requires the end of the test to match\n" \ 28 "$ requires the end of the test to match\n" \
127 "^ and $ requires an exact match\n" \ 29 "^ and $ requires an exact match\n" \
128 "If a test does not match any list entry,\n" \ 30 "If a test does not match any list entry,\n" \
129 "it is skipped unless some list entry starts with ~"); 31 "it is skipped unless some list entry starts with ~");
130 DEFINE_string2(tmpDir, t, NULL, "tmp directory for tests to use."); 32 DEFINE_string2(tmpDir, t, NULL, "tmp directory for tests to use.");
131 DEFINE_string2(resourcePath, i, "resources", "directory for test resources."); 33 DEFINE_string2(resourcePath, i, "resources", "directory for test resources.");
132 DEFINE_bool2(extendedTest, x, false, "run extended tests for pathOps."); 34 DEFINE_bool2(extendedTest, x, false, "run extended tests for pathOps.");
133 DEFINE_bool2(single, z, false, "run tests on a single thread internally."); 35 DEFINE_bool2(single, z, false, "run tests on a single thread internally.");
134 DEFINE_bool2(verbose, v, false, "enable verbose output."); 36 DEFINE_bool2(verbose, v, false, "enable verbose output.");
135 DEFINE_int32(threads, SkThreadPool::kThreadPerCore, 37 DEFINE_int32(threads, SkThreadPool::kThreadPerCore,
136 "Run threadsafe tests on a threadpool with this many threads."); 38 "Run threadsafe tests on a threadpool with this many threads.");
137 39
40 // need to explicitly declare this, or we get some weird infinite loop llist
41 template TestRegistry* TestRegistry::gHead;
42
43 class Iter {
44 public:
45 Iter() { this->reset(); }
46 void reset() { fReg = TestRegistry::Head(); }
47
48 Test* next(Reporter* r) {
49 if (fReg) {
50 TestRegistry::Factory fact = fReg->factory();
51 fReg = fReg->next();
52 Test* test = fact(NULL);
53 test->setReporter(r);
54 return test;
55 }
56 return NULL;
57 }
58
59 private:
60 const TestRegistry* fReg;
61 };
62
63 class DebugfReporter : public Reporter {
64 public:
65 explicit DebugfReporter(int total) : fDone(0), fTotal(total) {}
66
67 virtual bool allowExtendedTest() const SK_OVERRIDE { return FLAGS_extendedTe st; }
68 virtual bool allowThreaded() const SK_OVERRIDE { return !FLAGS_single; }
69 virtual bool verbose() const SK_OVERRIDE { return FLAGS_verbose; }
70
71 protected:
72 virtual void onReportFailed(const SkString& desc) SK_OVERRIDE {
73 SkDebugf("\nFAILED: %s", desc.c_str());
74 }
75
76 virtual void onEnd(Test* test) SK_OVERRIDE {
77 const int done = 1 + sk_atomic_inc(&fDone);
78
79 if (!test->passed()) {
80 SkDebugf("\n---- %s FAILED", test->getName());
81 }
82
83 SkString prefix(kSkOverwriteLine);
84 SkString time;
85 if (FLAGS_verbose) {
86 prefix.printf("\n");
87 time.printf("%5dms ", test->elapsedMs());
88 }
89 SkDebugf("%s[%3d/%3d] %s%s", prefix.c_str(), done, fTotal, time.c_str(), test->getName());
90 }
91
92 private:
93 int32_t fDone; // atomic
94 const int fTotal;
95 };
96
138 SkString Test::GetTmpDir() { 97 SkString Test::GetTmpDir() {
139 const char* tmpDir = FLAGS_tmpDir.isEmpty() ? NULL : FLAGS_tmpDir[0]; 98 const char* tmpDir = FLAGS_tmpDir.isEmpty() ? NULL : FLAGS_tmpDir[0];
140 return SkString(tmpDir); 99 return SkString(tmpDir);
141 } 100 }
142 101
143 SkString Test::GetResourcePath() { 102 SkString Test::GetResourcePath() {
144 const char* resourcePath = FLAGS_resourcePath.isEmpty() ? NULL : FLAGS_resou rcePath[0]; 103 const char* resourcePath = FLAGS_resourcePath.isEmpty() ? NULL : FLAGS_resou rcePath[0];
145 return SkString(resourcePath); 104 return SkString(resourcePath);
146 } 105 }
147 106
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 SkString resourcePath = Test::GetResourcePath(); 149 SkString resourcePath = Test::GetResourcePath();
191 if (!resourcePath.isEmpty()) { 150 if (!resourcePath.isEmpty()) {
192 header.appendf(" --resourcePath %s", resourcePath.c_str()); 151 header.appendf(" --resourcePath %s", resourcePath.c_str());
193 } 152 }
194 #ifdef SK_DEBUG 153 #ifdef SK_DEBUG
195 header.append(" SK_DEBUG"); 154 header.append(" SK_DEBUG");
196 #else 155 #else
197 header.append(" SK_RELEASE"); 156 header.append(" SK_RELEASE");
198 #endif 157 #endif
199 header.appendf(" skia_arch_width=%d", (int)sizeof(void*) * 8); 158 header.appendf(" skia_arch_width=%d", (int)sizeof(void*) * 8);
200 SkDebugf("%s\n", header.c_str()); 159 SkDebugf(header.c_str());
201 } 160 }
202 161
203 DebugfReporter reporter(FLAGS_extendedTest, !FLAGS_single, FLAGS_verbose);
204 Iter iter(&reporter);
205 162
206 // Count tests first. 163 // Count tests first.
207 int total = 0; 164 int total = 0;
208 int toRun = 0; 165 int toRun = 0;
209 Test* test; 166 Test* test;
210 167
211 while ((test = iter.next()) != NULL) { 168 Iter iter;
169 while ((test = iter.next(NULL/*reporter not needed*/)) != NULL) {
212 SkAutoTDelete<Test> owned(test); 170 SkAutoTDelete<Test> owned(test);
213 171
214 if(!SkCommandLineFlags::ShouldSkip(FLAGS_match, test->getName())) { 172 if(!SkCommandLineFlags::ShouldSkip(FLAGS_match, test->getName())) {
215 toRun++; 173 toRun++;
216 } 174 }
217 total++; 175 total++;
218 } 176 }
219 reporter.setTotal(toRun);
220 177
221 // Now run them. 178 // Now run them.
222 iter.reset(); 179 iter.reset();
223 int32_t failCount = 0; 180 int32_t failCount = 0;
224 int skipCount = 0; 181 int skipCount = 0;
225 182
226 SkThreadPool threadpool(FLAGS_threads); 183 SkThreadPool threadpool(FLAGS_threads);
227 SkTArray<Test*> unsafeTests; // Always passes ownership to an SkTestRunnabl e 184 SkTArray<Test*> unsafeTests; // Always passes ownership to an SkTestRunnabl e
185
186 DebugfReporter reporter(toRun);
228 for (int i = 0; i < total; i++) { 187 for (int i = 0; i < total; i++) {
229 SkAutoTDelete<Test> test(iter.next()); 188 SkAutoTDelete<Test> test(iter.next(&reporter));
230 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, test->getName())) { 189 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, test->getName())) {
231 ++skipCount; 190 ++skipCount;
232 } else if (!test->isThreadsafe()) { 191 } else if (!test->isThreadsafe()) {
233 unsafeTests.push_back() = test.detach(); 192 unsafeTests.push_back() = test.detach();
234 } else { 193 } else {
235 threadpool.add(SkNEW_ARGS(SkTestRunnable, (test.detach(), &failCount ))); 194 threadpool.add(SkNEW_ARGS(SkTestRunnable, (test.detach(), &failCount )));
236 } 195 }
237 } 196 }
238 197
239 // Run the tests that aren't threadsafe. 198 // Run the tests that aren't threadsafe.
240 for (int i = 0; i < unsafeTests.count(); i++) { 199 for (int i = 0; i < unsafeTests.count(); i++) {
241 SkNEW_ARGS(SkTestRunnable, (unsafeTests[i], &failCount))->run(); 200 SkNEW_ARGS(SkTestRunnable, (unsafeTests[i], &failCount))->run();
242 } 201 }
243 202
244 // Block until threaded tests finish. 203 // Block until threaded tests finish.
245 threadpool.wait(); 204 threadpool.wait();
246 205
247 SkDebugf("Finished %d tests, %d failures, %d skipped.\n", 206 if (FLAGS_verbose) {
248 toRun, failCount, skipCount); 207 SkDebugf("\nFinished %d tests, %d failures, %d skipped. (%d internal tes ts)",
249 const int testCount = reporter.countTests(); 208 toRun, failCount, skipCount, reporter.countTests());
250 if (FLAGS_verbose && testCount > 0) {
251 SkDebugf("Ran %d Internal tests.\n", testCount);
252 } 209 }
253 SkGraphics::Term(); 210 SkGraphics::Term();
254 GpuTest::DestroyContexts(); 211 GpuTest::DestroyContexts();
255 212
213 SkDebugf("\n");
256 return (failCount == 0) ? 0 : 1; 214 return (failCount == 0) ? 0 : 1;
257 } 215 }
258 216
259 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) 217 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL)
260 int main(int argc, char * const argv[]) { 218 int main(int argc, char * const argv[]) {
261 return tool_main(argc, (char**) argv); 219 return tool_main(argc, (char**) argv);
262 } 220 }
263 #endif 221 #endif
OLDNEW
« no previous file with comments | « gyp/dm.gyp ('k') | tools/OverwriteLine.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698