Index: tests/skia_test.cpp |
diff --git a/tests/skia_test.cpp b/tests/skia_test.cpp |
index a1d4bf799bfcdeb31bcb0d305c3b31252a8a3038..26a7701a8def4c4e11ec81ff628bd858351cbf6a 100644 |
--- a/tests/skia_test.cpp |
+++ b/tests/skia_test.cpp |
@@ -13,6 +13,7 @@ |
#include "SkThreadPool.h" |
#include "SkTime.h" |
#include "Test.h" |
+#include "OverwriteLine.h" |
#if SK_SUPPORT_GPU |
#include "GrContext.h" |
@@ -20,121 +21,79 @@ |
using namespace skiatest; |
+DEFINE_string2(match, m, NULL, "[~][^]substring[$] [...] of test name to run.\n" \ |
+ "Multiple matches may be separated by spaces.\n" \ |
+ "~ causes a matching test to always be skipped\n" \ |
+ "^ requires the start of the test to match\n" \ |
+ "$ requires the end of the test to match\n" \ |
+ "^ and $ requires an exact match\n" \ |
+ "If a test does not match any list entry,\n" \ |
+ "it is skipped unless some list entry starts with ~"); |
+DEFINE_string2(tmpDir, t, NULL, "tmp directory for tests to use."); |
+DEFINE_string2(resourcePath, i, "resources", "directory for test resources."); |
+DEFINE_bool2(extendedTest, x, false, "run extended tests for pathOps."); |
+DEFINE_bool2(single, z, false, "run tests on a single thread internally."); |
+DEFINE_bool2(verbose, v, false, "enable verbose output."); |
+DEFINE_int32(threads, SkThreadPool::kThreadPerCore, |
+ "Run threadsafe tests on a threadpool with this many threads."); |
+ |
// need to explicitly declare this, or we get some weird infinite loop llist |
template TestRegistry* TestRegistry::gHead; |
class Iter { |
public: |
- Iter(Reporter* r) : fReporter(r) { |
- r->ref(); |
- this->reset(); |
- } |
- |
- void reset() { |
- fReg = TestRegistry::Head(); |
- } |
- |
- ~Iter() { |
- fReporter->unref(); |
- } |
+ Iter() { this->reset(); } |
+ void reset() { fReg = TestRegistry::Head(); } |
- Test* next() { |
+ Test* next(Reporter* r) { |
if (fReg) { |
TestRegistry::Factory fact = fReg->factory(); |
fReg = fReg->next(); |
Test* test = fact(NULL); |
- test->setReporter(fReporter); |
+ test->setReporter(r); |
return test; |
} |
return NULL; |
} |
private: |
- Reporter* fReporter; |
const TestRegistry* fReg; |
}; |
class DebugfReporter : public Reporter { |
public: |
- DebugfReporter(bool allowExtendedTest, bool allowThreaded, bool verbose) |
- : fNextIndex(0) |
- , fPending(0) |
- , fTotal(0) |
- , fAllowExtendedTest(allowExtendedTest) |
- , fAllowThreaded(allowThreaded) |
- , fVerbose(verbose) { |
- } |
+ explicit DebugfReporter(int total) : fDone(0), fTotal(total) {} |
- void setTotal(int total) { |
- fTotal = total; |
- } |
- |
- virtual bool allowExtendedTest() const SK_OVERRIDE { |
- return fAllowExtendedTest; |
- } |
- |
- virtual bool allowThreaded() const SK_OVERRIDE { |
- return fAllowThreaded; |
- } |
- |
- virtual bool verbose() const SK_OVERRIDE { |
- return fVerbose; |
- } |
+ virtual bool allowExtendedTest() const SK_OVERRIDE { return FLAGS_extendedTest; } |
+ virtual bool allowThreaded() const SK_OVERRIDE { return !FLAGS_single; } |
+ virtual bool verbose() const SK_OVERRIDE { return FLAGS_verbose; } |
protected: |
- virtual void onStart(Test* test) { |
- SkAutoMutexAcquire lock(fStartEndMutex); |
- fNextIndex++; |
- fPending++; |
- SkDebugf("[%3d/%3d] (%d) %s\n", fNextIndex, fTotal, fPending, test->getName()); |
+ virtual void onReportFailed(const SkString& desc) SK_OVERRIDE { |
+ SkDebugf("\nFAILED: %s", desc.c_str()); |
} |
- virtual void onReportFailed(const SkString& desc) { |
- SkDebugf("\tFAILED: %s\n", desc.c_str()); |
- } |
+ virtual void onEnd(Test* test) SK_OVERRIDE { |
+ const int done = 1 + sk_atomic_inc(&fDone); |
- virtual void onEnd(Test* test) { |
- SkAutoMutexAcquire lock(fStartEndMutex); |
if (!test->passed()) { |
- SkDebugf("---- %s FAILED\n", test->getName()); |
+ SkDebugf("\n---- %s FAILED", test->getName()); |
} |
- fPending--; |
- if (fNextIndex == fTotal) { |
- // Just waiting on straggler tests. Shame them by printing their name and runtime. |
- SkDebugf(" (%d) %5.1fs %s\n", |
- fPending, test->elapsedMs() / 1e3, test->getName()); |
+ SkString prefix(kSkOverwriteLine); |
+ SkString time; |
+ if (FLAGS_verbose) { |
+ prefix.printf("\n"); |
+ time.printf("%5dms ", test->elapsedMs()); |
} |
+ SkDebugf("%s[%3d/%3d] %s%s", prefix.c_str(), done, fTotal, time.c_str(), test->getName()); |
} |
private: |
- SkMutex fStartEndMutex; // Guards fNextIndex and fPending. |
- int32_t fNextIndex; |
- int32_t fPending; |
- |
- // Once the tests get going, these are logically const. |
- int fTotal; |
- bool fAllowExtendedTest; |
- bool fAllowThreaded; |
- bool fVerbose; |
+ int32_t fDone; // atomic |
+ const int fTotal; |
}; |
-DEFINE_string2(match, m, NULL, "[~][^]substring[$] [...] of test name to run.\n" \ |
- "Multiple matches may be separated by spaces.\n" \ |
- "~ causes a matching test to always be skipped\n" \ |
- "^ requires the start of the test to match\n" \ |
- "$ requires the end of the test to match\n" \ |
- "^ and $ requires an exact match\n" \ |
- "If a test does not match any list entry,\n" \ |
- "it is skipped unless some list entry starts with ~"); |
-DEFINE_string2(tmpDir, t, NULL, "tmp directory for tests to use."); |
-DEFINE_string2(resourcePath, i, "resources", "directory for test resources."); |
-DEFINE_bool2(extendedTest, x, false, "run extended tests for pathOps."); |
-DEFINE_bool2(single, z, false, "run tests on a single thread internally."); |
-DEFINE_bool2(verbose, v, false, "enable verbose output."); |
-DEFINE_int32(threads, SkThreadPool::kThreadPerCore, |
- "Run threadsafe tests on a threadpool with this many threads."); |
- |
SkString Test::GetTmpDir() { |
const char* tmpDir = FLAGS_tmpDir.isEmpty() ? NULL : FLAGS_tmpDir[0]; |
return SkString(tmpDir); |
@@ -197,18 +156,17 @@ int tool_main(int argc, char** argv) { |
header.append(" SK_RELEASE"); |
#endif |
header.appendf(" skia_arch_width=%d", (int)sizeof(void*) * 8); |
- SkDebugf("%s\n", header.c_str()); |
+ SkDebugf(header.c_str()); |
} |
- DebugfReporter reporter(FLAGS_extendedTest, !FLAGS_single, FLAGS_verbose); |
- Iter iter(&reporter); |
// Count tests first. |
int total = 0; |
int toRun = 0; |
Test* test; |
- while ((test = iter.next()) != NULL) { |
+ Iter iter; |
+ while ((test = iter.next(NULL/*reporter not needed*/)) != NULL) { |
SkAutoTDelete<Test> owned(test); |
if(!SkCommandLineFlags::ShouldSkip(FLAGS_match, test->getName())) { |
@@ -216,7 +174,6 @@ int tool_main(int argc, char** argv) { |
} |
total++; |
} |
- reporter.setTotal(toRun); |
// Now run them. |
iter.reset(); |
@@ -225,8 +182,10 @@ int tool_main(int argc, char** argv) { |
SkThreadPool threadpool(FLAGS_threads); |
SkTArray<Test*> unsafeTests; // Always passes ownership to an SkTestRunnable |
+ |
+ DebugfReporter reporter(toRun); |
for (int i = 0; i < total; i++) { |
- SkAutoTDelete<Test> test(iter.next()); |
+ SkAutoTDelete<Test> test(iter.next(&reporter)); |
if (SkCommandLineFlags::ShouldSkip(FLAGS_match, test->getName())) { |
++skipCount; |
} else if (!test->isThreadsafe()) { |
@@ -244,15 +203,14 @@ int tool_main(int argc, char** argv) { |
// Block until threaded tests finish. |
threadpool.wait(); |
- SkDebugf("Finished %d tests, %d failures, %d skipped.\n", |
- toRun, failCount, skipCount); |
- const int testCount = reporter.countTests(); |
- if (FLAGS_verbose && testCount > 0) { |
- SkDebugf("Ran %d Internal tests.\n", testCount); |
+ if (FLAGS_verbose) { |
+ SkDebugf("\nFinished %d tests, %d failures, %d skipped. (%d internal tests)", |
+ toRun, failCount, skipCount, reporter.countTests()); |
} |
SkGraphics::Term(); |
GpuTest::DestroyContexts(); |
+ SkDebugf("\n"); |
return (failCount == 0) ? 0 : 1; |
} |