blob: f99ae8c0a565ed697fad7d3f60ecc03955d20e1b [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
reed@android.com5e5adfd2009-03-07 03:39:23 +00008#include "SkGraphics.h"
reed@android.comed673312009-02-27 16:24:51 +00009#include "Test.h"
reed@google.com789c6f22013-02-25 20:24:24 +000010#include "SkOSFile.h"
reed@android.comed673312009-02-27 16:24:51 +000011
robertphillips@google.combdb1be52012-09-07 18:24:43 +000012#if SK_SUPPORT_GPU
13#include "GrContext.h"
14#endif
15
reed@android.comed673312009-02-27 16:24:51 +000016using namespace skiatest;
17
reed@android.comd252db02009-04-01 18:31:44 +000018// need to explicitly declare this, or we get some weird infinite loop llist
19template TestRegistry* TestRegistry::gHead;
20
reed@android.comed673312009-02-27 16:24:51 +000021class Iter {
22public:
23 Iter(Reporter* r) : fReporter(r) {
24 r->ref();
25 fReg = TestRegistry::Head();
26 }
reed@android.com80e39a72009-04-02 16:59:40 +000027
reed@android.comed673312009-02-27 16:24:51 +000028 ~Iter() {
29 fReporter->unref();
30 }
reed@android.com80e39a72009-04-02 16:59:40 +000031
reed@android.comed673312009-02-27 16:24:51 +000032 Test* next() {
33 if (fReg) {
34 TestRegistry::Factory fact = fReg->factory();
35 fReg = fReg->next();
36 Test* test = fact(NULL);
37 test->setReporter(fReporter);
38 return test;
39 }
40 return NULL;
41 }
reed@android.com80e39a72009-04-02 16:59:40 +000042
reed@android.com57b799e2009-04-01 20:26:42 +000043 static int Count() {
44 const TestRegistry* reg = TestRegistry::Head();
45 int count = 0;
46 while (reg) {
47 count += 1;
48 reg = reg->next();
49 }
50 return count;
51 }
reed@android.com80e39a72009-04-02 16:59:40 +000052
reed@android.comed673312009-02-27 16:24:51 +000053private:
54 Reporter* fReporter;
55 const TestRegistry* fReg;
56};
57
58static const char* result2string(Reporter::Result result) {
59 return result == Reporter::kPassed ? "passed" : "FAILED";
60}
61
reed@android.comd252db02009-04-01 18:31:44 +000062class DebugfReporter : public Reporter {
reed@android.com57b799e2009-04-01 20:26:42 +000063public:
caryclark@google.comd54e1e92013-04-10 15:57:31 +000064 DebugfReporter(bool allowExtendedTest)
65 : fIndex(0)
66 , fTotal(0)
67 , fAllowExtendedTest(allowExtendedTest) {
68 }
reed@android.comeeb3b7f2009-04-09 04:06:54 +000069
reed@android.com57b799e2009-04-01 20:26:42 +000070 void setIndexOfTotal(int index, int total) {
71 fIndex = index;
72 fTotal = total;
73 }
caryclark@google.comd54e1e92013-04-10 15:57:31 +000074
75 virtual bool allowExtendedTest() const {
76 return fAllowExtendedTest;
77 }
78
reed@android.comed673312009-02-27 16:24:51 +000079protected:
80 virtual void onStart(Test* test) {
djsollen@google.comf4d1b392012-11-29 16:29:58 +000081 SkDebugf("[%d/%d] %s...\n", fIndex+1, fTotal, test->getName());
reed@android.comed673312009-02-27 16:24:51 +000082 }
83 virtual void onReport(const char desc[], Reporter::Result result) {
djsollen@google.comf4d1b392012-11-29 16:29:58 +000084 SkDebugf("\t%s: %s\n", result2string(result), desc);
reed@android.comed673312009-02-27 16:24:51 +000085 }
sugoi@google.com54f0d1b2013-02-27 19:17:41 +000086 virtual void onEnd(Test*) {
djsollen@google.comf4d1b392012-11-29 16:29:58 +000087 if (!this->getCurrSuccess()) {
88 SkDebugf("---- FAILED\n");
reed@android.comeeb3b7f2009-04-09 04:06:54 +000089 }
90 }
djsollen@google.comf4d1b392012-11-29 16:29:58 +000091private:
reed@android.com57b799e2009-04-01 20:26:42 +000092 int fIndex, fTotal;
caryclark@google.comd54e1e92013-04-10 15:57:31 +000093 bool fAllowExtendedTest;
reed@android.comed673312009-02-27 16:24:51 +000094};
95
reed@google.com789c6f22013-02-25 20:24:24 +000096static const char* make_canonical_dir_path(const char* path, SkString* storage) {
97 if (path) {
98 // clean it up so it always has a trailing searator
99 size_t len = strlen(path);
100 if (0 == len) {
101 path = NULL;
102 } else if (SkPATH_SEPARATOR != path[len - 1]) {
103 // resize to len + 1, to make room for searator
104 storage->set(path, len + 1);
105 storage->writable_str()[len] = SkPATH_SEPARATOR;
106 path = storage->c_str();
107 }
108 }
109 return path;
110}
111
djsollen@google.comcb626502013-03-20 13:48:20 +0000112static SkString gTmpDir;
reed@google.com789c6f22013-02-25 20:24:24 +0000113
djsollen@google.comcb626502013-03-20 13:48:20 +0000114const SkString& Test::GetTmpDir() {
reed@google.com789c6f22013-02-25 20:24:24 +0000115 return gTmpDir;
116}
117
djsollen@google.comcb626502013-03-20 13:48:20 +0000118static SkString gResourcePath;
119
120const SkString& Test::GetResourcePath() {
121 return gResourcePath;
122}
123
caryclark@google.com5987f582012-10-02 18:33:14 +0000124int tool_main(int argc, char** argv);
125int tool_main(int argc, char** argv) {
bsalomon@google.com4e230682013-01-15 20:37:04 +0000126#if SK_ENABLE_INST_COUNT
reed@google.coma2769752012-07-22 22:33:05 +0000127 gPrintInstCount = true;
128#endif
caryclark@google.comd54e1e92013-04-10 15:57:31 +0000129 bool allowExtendedTest = false;
130 bool verboseOutput = false;
131
reed@google.coma2769752012-07-22 22:33:05 +0000132 SkGraphics::Init();
bungeman@google.com5af16f82011-09-02 15:06:44 +0000133
bungeman@google.com5af16f82011-09-02 15:06:44 +0000134 const char* matchStr = NULL;
135
136 char* const* stop = argv + argc;
137 for (++argv; argv < stop; ++argv) {
caryclark@google.comd54e1e92013-04-10 15:57:31 +0000138 if (0 == strcmp(*argv, "--match") || 0 == strcmp(*argv, "-m")) {
bungeman@google.com5af16f82011-09-02 15:06:44 +0000139 ++argv;
140 if (argv < stop && **argv) {
141 matchStr = *argv;
reed@google.com789c6f22013-02-25 20:24:24 +0000142 } else {
143 SkDebugf("no following argument to --match\n");
144 return -1;
145 }
caryclark@google.comd54e1e92013-04-10 15:57:31 +0000146 } else if (0 == strcmp(*argv, "--tmpDir") || 0 == strcmp(*argv, "-t")) {
reed@google.com789c6f22013-02-25 20:24:24 +0000147 ++argv;
148 if (argv < stop && **argv) {
djsollen@google.comcb626502013-03-20 13:48:20 +0000149 make_canonical_dir_path(*argv, &gTmpDir);
reed@google.com789c6f22013-02-25 20:24:24 +0000150 } else {
151 SkDebugf("no following argument to --tmpDir\n");
152 return -1;
bungeman@google.com5af16f82011-09-02 15:06:44 +0000153 }
caryclark@google.comd54e1e92013-04-10 15:57:31 +0000154 } else if (0 == strcmp(*argv, "--resourcePath") || 0 == strcmp(*argv, "-i")) {
djsollen@google.comcb626502013-03-20 13:48:20 +0000155 argv++;
156 if (argv < stop && **argv) {
157 make_canonical_dir_path(*argv, &gResourcePath);
158 }
caryclark@google.comd54e1e92013-04-10 15:57:31 +0000159 } else if (0 == strcmp(*argv, "--extendedTest") || 0 == strcmp(*argv, "-x")) {
160 allowExtendedTest = true;
161 } else if (0 == strcmp(*argv, "--verbose") || 0 == strcmp(*argv, "-v")) {
162 verboseOutput = true;
163 } else {
164 if (0 != strcmp(*argv, "--help") && 0 != strcmp(*argv, "-h")
165 && 0 != strcmp(*argv, "-?")) {
166 SkDebugf("Unknown option %s. ", *argv);
167 }
168 SkDebugf("Skia UnitTests options are:\n");
169 SkDebugf(" -m --match [test-name-substring]\n");
170 SkDebugf(" -t --tmpDir [dir]\n");
171 SkDebugf(" -i --resourcePath [dir]\n");
172 SkDebugf(" -x --extendedTest\n");
173 SkDebugf(" -v --verbose\n");
174 return 1;
reed@android.comeeb3b7f2009-04-09 04:06:54 +0000175 }
176 }
reed@android.com5e5adfd2009-03-07 03:39:23 +0000177
reed@google.com91d449e2011-10-26 15:25:18 +0000178 {
179 SkString header("Skia UnitTests:");
180 if (matchStr) {
181 header.appendf(" --match %s", matchStr);
182 }
djsollen@google.comcb626502013-03-20 13:48:20 +0000183 if (!gTmpDir.isEmpty()) {
184 header.appendf(" --tmpDir %s", gTmpDir.c_str());
185 }
186 if (!gResourcePath.isEmpty()) {
187 header.appendf(" --resourcePath %s", gResourcePath.c_str());
reed@google.com789c6f22013-02-25 20:24:24 +0000188 }
reed@google.com91d449e2011-10-26 15:25:18 +0000189#ifdef SK_DEBUG
190 header.append(" SK_DEBUG");
191#else
192 header.append(" SK_RELEASE");
193#endif
194#ifdef SK_SCALAR_IS_FIXED
195 header.append(" SK_SCALAR_IS_FIXED");
196#else
197 header.append(" SK_SCALAR_IS_FLOAT");
198#endif
djsollen@google.comf4d1b392012-11-29 16:29:58 +0000199 SkDebugf("%s\n", header.c_str());
reed@google.com91d449e2011-10-26 15:25:18 +0000200 }
201
caryclark@google.comd54e1e92013-04-10 15:57:31 +0000202 DebugfReporter reporter(allowExtendedTest);
reed@android.comed673312009-02-27 16:24:51 +0000203 Iter iter(&reporter);
204 Test* test;
reed@android.com80e39a72009-04-02 16:59:40 +0000205
reed@android.com57b799e2009-04-01 20:26:42 +0000206 const int count = Iter::Count();
207 int index = 0;
bungeman@google.com5af16f82011-09-02 15:06:44 +0000208 int failCount = 0;
209 int skipCount = 0;
reed@android.comed673312009-02-27 16:24:51 +0000210 while ((test = iter.next()) != NULL) {
reed@android.com57b799e2009-04-01 20:26:42 +0000211 reporter.setIndexOfTotal(index, count);
bungeman@google.com5af16f82011-09-02 15:06:44 +0000212 if (NULL != matchStr && !strstr(test->getName(), matchStr)) {
213 ++skipCount;
214 } else {
215 if (!test->run()) {
216 ++failCount;
217 }
218 }
reed@android.comed673312009-02-27 16:24:51 +0000219 SkDELETE(test);
reed@android.com57b799e2009-04-01 20:26:42 +0000220 index += 1;
reed@android.comed673312009-02-27 16:24:51 +0000221 }
reed@android.com57b799e2009-04-01 20:26:42 +0000222
djsollen@google.comf4d1b392012-11-29 16:29:58 +0000223 SkDebugf("Finished %d tests, %d failures, %d skipped.\n",
224 count, failCount, skipCount);
caryclark@google.comd54e1e92013-04-10 15:57:31 +0000225 int testCount = reporter.countTests();
226 if (verboseOutput && testCount > 0) {
227 SkDebugf("Ran %d Internal tests.\n", testCount);
228 }
robertphillips@google.combdb1be52012-09-07 18:24:43 +0000229#if SK_SUPPORT_GPU
230
231#if GR_CACHE_STATS
232 GrContext *gr = GpuTest::GetContext();
233
234 gr->printCacheStats();
235#endif
236
237#endif
238
reed@google.coma2769752012-07-22 22:33:05 +0000239 SkGraphics::Term();
bsalomon@google.com67b915d2013-02-04 16:13:32 +0000240 GpuTest::DestroyContexts();
reed@google.coma2769752012-07-22 22:33:05 +0000241
bungeman@google.com5af16f82011-09-02 15:06:44 +0000242 return (failCount == 0) ? 0 : 1;
reed@android.comed673312009-02-27 16:24:51 +0000243}
caryclark@google.com5987f582012-10-02 18:33:14 +0000244
borenet@google.com7158e6a2012-11-01 17:43:44 +0000245#if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL)
caryclark@google.com5987f582012-10-02 18:33:14 +0000246int main(int argc, char * const argv[]) {
247 return tool_main(argc, (char**) argv);
248}
249#endif