Chromium Code Reviews| 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 |
|
mtklein
2015/01/15 23:46:46
Just FYI, I'm going to ignore this file. If it co
hal.canary
2015/01/16 15:31:58
Acknowledged.
| |
| 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 "Test.h" | 19 #include "Test.h" |
| 20 | 20 |
| 21 #if SK_SUPPORT_GPU | 21 #if SK_SUPPORT_GPU |
| 22 #include "GrContext.h" | 22 #include "GrContext.h" |
| 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 DEFINE_string2(tmpDir, t, NULL, "tmp directory for tests to use."); | |
| 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 static SkString get_tmp_dir() { |
| 34 public: | 35 return SkString(FLAGS_tmpDir.isEmpty() ? NULL : FLAGS_tmpDir[0]); |
| 35 Iter() { this->reset(); } | 36 } |
| 36 void reset() { fReg = TestRegistry::Head(); } | |
| 37 | |
| 38 Test* next(Reporter* r) { | |
| 39 if (fReg) { | |
| 40 TestRegistry::Factory fact = fReg->factory(); | |
| 41 fReg = fReg->next(); | |
| 42 Test* test = fact(NULL); | |
| 43 test->setReporter(r); | |
| 44 return test; | |
| 45 } | |
| 46 return NULL; | |
| 47 } | |
| 48 | |
| 49 private: | |
| 50 const TestRegistry* fReg; | |
| 51 }; | |
| 52 | 37 |
| 53 class DebugfReporter : public Reporter { | 38 class DebugfReporter : public Reporter { |
| 54 public: | 39 public: |
| 55 explicit DebugfReporter(int total) : fDone(0), fTotal(total) {} | 40 DebugfReporter() : fErrorCount(0), fTestCount(0) { |
| 56 | 41 } |
| 57 bool allowExtendedTest() const SK_OVERRIDE { return FLAGS_extendedTest; } | 42 bool allowExtendedTest() const SK_OVERRIDE { return FLAGS_extendedTest; } |
| 58 bool verbose() const SK_OVERRIDE { return FLAGS_veryVerbose; } | 43 bool verbose() const SK_OVERRIDE { return FLAGS_veryVerbose; } |
| 59 | 44 |
| 60 protected: | 45 void reportFailed(const skiatest::Failure& failure) SK_OVERRIDE { |
| 61 void onReportFailed(const skiatest::Failure& failure) SK_OVERRIDE { | 46 SkString desc = FailureToString(failure); |
| 62 SkString desc; | |
| 63 failure.getFailureString(&desc); | |
| 64 SkDebugf("\nFAILED: %s", desc.c_str()); | 47 SkDebugf("\nFAILED: %s", desc.c_str()); |
| 48 ++fErrorCount; | |
| 65 } | 49 } |
| 50 SkString getTmpDir() SK_OVERRIDE { | |
| 51 return get_tmp_dir(); | |
| 52 } | |
| 53 void bumpTestCount() SK_OVERRIDE { | |
| 54 ++fTestCount; | |
| 55 } | |
| 56 int fErrorCount; | |
| 57 int fTestCount; | |
| 58 }; | |
| 66 | 59 |
| 67 void onEnd(Test* test) SK_OVERRIDE { | 60 class DebugfStatusKeeper { |
| 61 public: | |
| 62 explicit DebugfStatusKeeper(int total) : fDone(0), fTotal(total) { | |
| 63 } | |
| 64 void endTest(const char* testName, | |
| 65 bool success, | |
| 66 SkMSec elapsed, | |
| 67 int testCount) { | |
| 68 const int done = 1 + sk_atomic_inc(&fDone); | 68 const int done = 1 + sk_atomic_inc(&fDone); |
| 69 | 69 for (int i = 0; i < testCount; ++i) { |
| 70 if (!test->passed()) { | 70 sk_atomic_inc(&fTestCount); |
| 71 SkDebugf("\n---- %s FAILED", test->getName()); | 71 } |
| 72 if (!success) { | |
| 73 SkDebugf("\n---- %s FAILED", testName); | |
| 72 } | 74 } |
| 73 | 75 |
| 74 SkString prefix(kSkOverwriteLine); | 76 SkString prefix(kSkOverwriteLine); |
| 75 SkString time; | 77 SkString time; |
| 76 if (FLAGS_verbose) { | 78 if (FLAGS_verbose) { |
| 77 prefix.printf("\n"); | 79 prefix.printf("\n"); |
| 78 time.printf("%5dms ", test->elapsedMs()); | 80 time.printf("%5dms ", elapsed); |
| 79 } | 81 } |
| 80 SkDebugf("%s[%3d/%3d] %s%s", prefix.c_str(), done, fTotal, time.c_str(), test->getName()); | 82 SkDebugf("%s[%3d/%3d] %s%s", prefix.c_str(), done, fTotal, time.c_str(), |
| 83 testName); | |
| 84 } | |
| 85 | |
| 86 int32_t testCount() { | |
| 87 return fTestCount; | |
| 81 } | 88 } |
| 82 | 89 |
| 83 private: | 90 private: |
| 84 int32_t fDone; // atomic | 91 int32_t fDone; // atomic |
| 92 int32_t fTestCount; // atomic | |
| 85 const int fTotal; | 93 const int fTotal; |
| 86 }; | 94 }; |
| 87 | 95 |
| 88 // Deletes self when run. | 96 // Deletes self when run. |
| 89 class SkTestRunnable : public SkRunnable { | 97 class SkTestRunnable : public SkRunnable { |
| 90 public: | 98 public: |
| 91 // Takes ownership of test. | 99 // Takes ownership of test. |
| 92 SkTestRunnable(Test* test, int32_t* failCount) : fTest(test), fFailCount(failC ount) {} | 100 SkTestRunnable(const Test& test, |
| 101 int32_t* failCount, | |
| 102 DebugfStatusKeeper* status, | |
| 103 GrContextFactory* grContextFactory = NULL) | |
| 104 : fTest(test) | |
| 105 , fFailCount(failCount) | |
| 106 , fStatus(status) | |
| 107 , fGrContextFactory(grContextFactory) { | |
| 108 } | |
| 93 | 109 |
| 94 virtual void run() { | 110 virtual void run() { |
| 95 fTest->run(); | 111 DebugfReporter reporter; |
| 96 if(!fTest->passed()) { | 112 const SkMSec start = SkTime::GetMSecs(); |
| 113 fTest.proc(&reporter, fGrContextFactory); | |
| 114 SkMSec elapsed = SkTime::GetMSecs() - start; | |
| 115 bool success = 0 == reporter.fErrorCount; | |
| 116 if (!success) { | |
| 97 sk_atomic_inc(fFailCount); | 117 sk_atomic_inc(fFailCount); |
| 98 } | 118 } |
| 119 fStatus->endTest(fTest.name, success, elapsed, reporter.fTestCount); | |
| 99 SkDELETE(this); | 120 SkDELETE(this); |
| 100 } | 121 } |
| 101 | 122 |
| 102 private: | 123 private: |
| 103 SkAutoTDelete<Test> fTest; | 124 Test fTest; |
| 104 int32_t* fFailCount; | 125 int32_t* fFailCount; |
| 126 DebugfStatusKeeper* fStatus; | |
| 127 GrContextFactory* fGrContextFactory; | |
| 105 }; | 128 }; |
| 106 | 129 |
| 107 static bool should_run(const char* testName, bool isGPUTest) { | 130 static bool should_run(const char* testName, bool isGPUTest) { |
| 108 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, testName)) { | 131 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, testName)) { |
| 109 return false; | 132 return false; |
| 110 } | 133 } |
| 111 if (!FLAGS_cpu && !isGPUTest) { | 134 if (!FLAGS_cpu && !isGPUTest) { |
| 112 return false; | 135 return false; |
| 113 } | 136 } |
| 114 if (!FLAGS_gpu && isGPUTest) { | 137 if (!FLAGS_gpu && isGPUTest) { |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 130 SkAutoGraphics ag; | 153 SkAutoGraphics ag; |
| 131 | 154 |
| 132 { | 155 { |
| 133 SkString header("Skia UnitTests:"); | 156 SkString header("Skia UnitTests:"); |
| 134 if (!FLAGS_match.isEmpty()) { | 157 if (!FLAGS_match.isEmpty()) { |
| 135 header.appendf(" --match"); | 158 header.appendf(" --match"); |
| 136 for (int index = 0; index < FLAGS_match.count(); ++index) { | 159 for (int index = 0; index < FLAGS_match.count(); ++index) { |
| 137 header.appendf(" %s", FLAGS_match[index]); | 160 header.appendf(" %s", FLAGS_match[index]); |
| 138 } | 161 } |
| 139 } | 162 } |
| 140 SkString tmpDir = Test::GetTmpDir(); | 163 SkString tmpDir = get_tmp_dir(); |
| 141 if (!tmpDir.isEmpty()) { | 164 if (!tmpDir.isEmpty()) { |
| 142 header.appendf(" --tmpDir %s", tmpDir.c_str()); | 165 header.appendf(" --tmpDir %s", tmpDir.c_str()); |
| 143 } | 166 } |
| 144 SkString resourcePath = GetResourcePath(); | 167 SkString resourcePath = GetResourcePath(); |
| 145 if (!resourcePath.isEmpty()) { | 168 if (!resourcePath.isEmpty()) { |
| 146 header.appendf(" --resourcePath %s", resourcePath.c_str()); | 169 header.appendf(" --resourcePath %s", resourcePath.c_str()); |
| 147 } | 170 } |
| 148 #ifdef SK_DEBUG | 171 #ifdef SK_DEBUG |
| 149 header.append(" SK_DEBUG"); | 172 header.append(" SK_DEBUG"); |
| 150 #else | 173 #else |
| 151 header.append(" SK_RELEASE"); | 174 header.append(" SK_RELEASE"); |
| 152 #endif | 175 #endif |
| 153 header.appendf(" skia_arch_width=%d", (int)sizeof(void*) * 8); | 176 header.appendf(" skia_arch_width=%d", (int)sizeof(void*) * 8); |
| 154 if (FLAGS_veryVerbose) { | 177 if (FLAGS_veryVerbose) { |
| 155 header.appendf("\n"); | 178 header.appendf("\n"); |
| 156 } | 179 } |
| 157 SkDebugf(header.c_str()); | 180 SkDebugf(header.c_str()); |
| 158 } | 181 } |
| 159 | 182 |
| 160 | 183 |
| 161 // Count tests first. | 184 // Count tests first. |
| 162 int total = 0; | 185 int total = 0; |
| 163 int toRun = 0; | 186 int toRun = 0; |
| 164 Test* test; | |
| 165 | 187 |
| 166 Iter iter; | 188 for (const TestRegistry* iter = TestRegistry::Head(); iter; |
| 167 while ((test = iter.next(NULL/*reporter not needed*/)) != NULL) { | 189 iter = iter->next()) { |
| 168 SkAutoTDelete<Test> owned(test); | 190 const Test& test = iter->factory(); |
| 169 if (should_run(test->getName(), test->isGPUTest())) { | 191 if (should_run(test.name, test.needsGpu)) { |
| 170 toRun++; | 192 toRun++; |
| 171 } | 193 } |
| 172 total++; | 194 total++; |
| 173 } | 195 } |
| 174 | 196 |
| 175 // Now run them. | 197 // Now run them. |
| 176 iter.reset(); | |
| 177 int32_t failCount = 0; | 198 int32_t failCount = 0; |
| 178 int skipCount = 0; | 199 int skipCount = 0; |
| 179 | 200 |
| 180 SkTaskGroup::Enabler enabled(FLAGS_threads); | 201 SkTaskGroup::Enabler enabled(FLAGS_threads); |
| 181 SkTaskGroup cpuTests; | 202 SkTaskGroup cpuTests; |
| 182 SkTArray<Test*> gpuTests; // Always passes ownership to an SkTestRunnable | 203 SkTArray<const Test*> gpuTests; |
| 183 | 204 |
| 184 DebugfReporter reporter(toRun); | 205 DebugfStatusKeeper status(toRun); |
| 185 for (int i = 0; i < total; i++) { | 206 for (const TestRegistry* iter = TestRegistry::Head(); iter; |
| 186 SkAutoTDelete<Test> test(iter.next(&reporter)); | 207 iter = iter->next()) { |
| 187 if (!should_run(test->getName(), test->isGPUTest())) { | 208 const Test& test = iter->factory(); |
| 209 if (!should_run(test.name, test.needsGpu)) { | |
| 188 ++skipCount; | 210 ++skipCount; |
| 189 } else if (test->isGPUTest()) { | 211 } else if (test.needsGpu) { |
| 190 gpuTests.push_back() = test.detach(); | 212 gpuTests.push_back(&test); |
| 191 } else { | 213 } else { |
| 192 cpuTests.add(SkNEW_ARGS(SkTestRunnable, (test.detach(), &failCount)) ); | 214 cpuTests.add( |
| 215 SkNEW_ARGS(SkTestRunnable, (test, &failCount, &status))); | |
| 193 } | 216 } |
| 194 } | 217 } |
| 195 | 218 |
| 219 GrContextFactory* grContextFactoryPtr = NULL; | |
| 196 #if SK_SUPPORT_GPU | 220 #if SK_SUPPORT_GPU |
| 197 // Give GPU tests a context factory if that makes sense on this machine. | 221 // Give GPU tests a context factory if that makes sense on this machine. |
| 198 GrContextFactory grContextFactory; | 222 GrContextFactory grContextFactory; |
| 199 for (int i = 0; i < gpuTests.count(); i++) { | 223 grContextFactoryPtr = &grContextFactory; |
| 200 gpuTests[i]->setGrContextFactory(&grContextFactory); | 224 |
| 201 } | |
| 202 #endif | 225 #endif |
| 203 | 226 |
| 204 // Run GPU tests on this thread. | 227 // Run GPU tests on this thread. |
| 205 for (int i = 0; i < gpuTests.count(); i++) { | 228 for (int i = 0; i < gpuTests.count(); i++) { |
| 206 SkNEW_ARGS(SkTestRunnable, (gpuTests[i], &failCount))->run(); | 229 SkNEW_ARGS(SkTestRunnable, (*gpuTests[i], &failCount, &status, |
| 230 grContextFactoryPtr))->run(); | |
| 207 } | 231 } |
| 208 | 232 |
| 209 // Block until threaded tests finish. | 233 // Block until threaded tests finish. |
| 210 cpuTests.wait(); | 234 cpuTests.wait(); |
| 211 | 235 |
| 212 if (FLAGS_verbose) { | 236 if (FLAGS_verbose) { |
| 213 SkDebugf("\nFinished %d tests, %d failures, %d skipped. (%d internal tes ts)", | 237 SkDebugf( |
| 214 toRun, failCount, skipCount, reporter.countTests()); | 238 "\nFinished %d tests, %d failures, %d skipped. " |
| 239 "(%d internal tests)", | |
| 240 toRun, failCount, skipCount, status.testCount()); | |
| 215 } | 241 } |
| 216 | 242 |
| 217 SkDebugf("\n"); | 243 SkDebugf("\n"); |
| 218 return (failCount == 0) ? 0 : 1; | 244 return (failCount == 0) ? 0 : 1; |
| 219 } | 245 } |
| 220 | 246 |
| 221 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) | 247 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) |
| 222 int main(int argc, char** argv) { | 248 int main(int argc, char** argv) { |
| 223 SkCommandLineFlags::Parse(argc, argv); | 249 SkCommandLineFlags::Parse(argc, argv); |
| 224 return test_main(); | 250 return test_main(); |
| 225 } | 251 } |
| 226 #endif | 252 #endif |
| OLD | NEW |