blob: fd56cc71fbfb064917583c35441bf9fcd44f2284 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001/*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
commit-bot@chromium.orgba59d642013-04-11 16:54:09 +00007
scroggo@google.com5a6324e2013-04-11 20:11:40 +00008#include "SkCommandLineFlags.h"
reed@android.com5e5adfd2009-03-07 03:39:23 +00009#include "SkGraphics.h"
reed@android.comed673312009-02-27 16:24:51 +000010#include "Test.h"
reed@google.com789c6f22013-02-25 20:24:24 +000011#include "SkOSFile.h"
reed@android.comed673312009-02-27 16:24:51 +000012
robertphillips@google.combdb1be52012-09-07 18:24:43 +000013#if SK_SUPPORT_GPU
14#include "GrContext.h"
15#endif
16
reed@android.comed673312009-02-27 16:24:51 +000017using namespace skiatest;
18
reed@android.comd252db02009-04-01 18:31:44 +000019// need to explicitly declare this, or we get some weird infinite loop llist
20template TestRegistry* TestRegistry::gHead;
21
reed@android.comed673312009-02-27 16:24:51 +000022class Iter {
23public:
24 Iter(Reporter* r) : fReporter(r) {
25 r->ref();
26 fReg = TestRegistry::Head();
27 }
reed@android.com80e39a72009-04-02 16:59:40 +000028
reed@android.comed673312009-02-27 16:24:51 +000029 ~Iter() {
30 fReporter->unref();
31 }
reed@android.com80e39a72009-04-02 16:59:40 +000032
reed@android.comed673312009-02-27 16:24:51 +000033 Test* next() {
34 if (fReg) {
35 TestRegistry::Factory fact = fReg->factory();
36 fReg = fReg->next();
37 Test* test = fact(NULL);
38 test->setReporter(fReporter);
39 return test;
40 }
41 return NULL;
42 }
reed@android.com80e39a72009-04-02 16:59:40 +000043
reed@android.com57b799e2009-04-01 20:26:42 +000044 static int Count() {
45 const TestRegistry* reg = TestRegistry::Head();
46 int count = 0;
47 while (reg) {
48 count += 1;
49 reg = reg->next();
50 }
51 return count;
52 }
reed@android.com80e39a72009-04-02 16:59:40 +000053
reed@android.comed673312009-02-27 16:24:51 +000054private:
55 Reporter* fReporter;
56 const TestRegistry* fReg;
57};
58
59static const char* result2string(Reporter::Result result) {
60 return result == Reporter::kPassed ? "passed" : "FAILED";
61}
62
reed@android.comd252db02009-04-01 18:31:44 +000063class DebugfReporter : public Reporter {
reed@android.com57b799e2009-04-01 20:26:42 +000064public:
caryclark@google.com16cfe402013-04-18 18:47:37 +000065 DebugfReporter(bool allowExtendedTest, bool allowThreaded)
caryclark@google.comd54e1e92013-04-10 15:57:31 +000066 : fIndex(0)
67 , fTotal(0)
caryclark@google.com16cfe402013-04-18 18:47:37 +000068 , fAllowExtendedTest(allowExtendedTest)
69 , fAllowThreaded(allowThreaded) {
caryclark@google.comd54e1e92013-04-10 15:57:31 +000070 }
reed@android.comeeb3b7f2009-04-09 04:06:54 +000071
reed@android.com57b799e2009-04-01 20:26:42 +000072 void setIndexOfTotal(int index, int total) {
73 fIndex = index;
74 fTotal = total;
75 }
caryclark@google.comd54e1e92013-04-10 15:57:31 +000076
77 virtual bool allowExtendedTest() const {
skia.committer@gmail.com391ca662013-04-11 07:01:45 +000078 return fAllowExtendedTest;
caryclark@google.comd54e1e92013-04-10 15:57:31 +000079 }
80
caryclark@google.com16cfe402013-04-18 18:47:37 +000081 virtual bool allowThreaded() const {
82 return fAllowThreaded;
83 }
84
reed@android.comed673312009-02-27 16:24:51 +000085protected:
86 virtual void onStart(Test* test) {
djsollen@google.comf4d1b392012-11-29 16:29:58 +000087 SkDebugf("[%d/%d] %s...\n", fIndex+1, fTotal, test->getName());
reed@android.comed673312009-02-27 16:24:51 +000088 }
89 virtual void onReport(const char desc[], Reporter::Result result) {
djsollen@google.comf4d1b392012-11-29 16:29:58 +000090 SkDebugf("\t%s: %s\n", result2string(result), desc);
reed@android.comed673312009-02-27 16:24:51 +000091 }
sugoi@google.com54f0d1b2013-02-27 19:17:41 +000092 virtual void onEnd(Test*) {
djsollen@google.comf4d1b392012-11-29 16:29:58 +000093 if (!this->getCurrSuccess()) {
94 SkDebugf("---- FAILED\n");
reed@android.comeeb3b7f2009-04-09 04:06:54 +000095 }
96 }
djsollen@google.comf4d1b392012-11-29 16:29:58 +000097private:
reed@android.com57b799e2009-04-01 20:26:42 +000098 int fIndex, fTotal;
caryclark@google.comd54e1e92013-04-10 15:57:31 +000099 bool fAllowExtendedTest;
caryclark@google.com16cfe402013-04-18 18:47:37 +0000100 bool fAllowThreaded;
reed@android.comed673312009-02-27 16:24:51 +0000101};
102
reed@google.com789c6f22013-02-25 20:24:24 +0000103static const char* make_canonical_dir_path(const char* path, SkString* storage) {
104 if (path) {
105 // clean it up so it always has a trailing searator
106 size_t len = strlen(path);
107 if (0 == len) {
108 path = NULL;
109 } else if (SkPATH_SEPARATOR != path[len - 1]) {
110 // resize to len + 1, to make room for searator
111 storage->set(path, len + 1);
112 storage->writable_str()[len] = SkPATH_SEPARATOR;
113 path = storage->c_str();
114 }
115 }
116 return path;
117}
118
djsollen@google.comcb626502013-03-20 13:48:20 +0000119static SkString gTmpDir;
reed@google.com789c6f22013-02-25 20:24:24 +0000120
djsollen@google.comcb626502013-03-20 13:48:20 +0000121const SkString& Test::GetTmpDir() {
reed@google.com789c6f22013-02-25 20:24:24 +0000122 return gTmpDir;
123}
124
djsollen@google.comcb626502013-03-20 13:48:20 +0000125static SkString gResourcePath;
126
127const SkString& Test::GetResourcePath() {
128 return gResourcePath;
129}
130
reed@google.com9aff1482013-04-11 18:27:52 +0000131DEFINE_string2(match, m, NULL, "substring of test name to run.");
commit-bot@chromium.orgba59d642013-04-11 16:54:09 +0000132DEFINE_string2(tmpDir, t, NULL, "tmp directory for tests to use.");
133DEFINE_string2(resourcePath, i, NULL, "directory for test resources.");
134DEFINE_bool2(extendedTest, x, false, "run extended tests for pathOps.");
caryclark@google.com16cfe402013-04-18 18:47:37 +0000135DEFINE_bool2(threaded, z, false, "allow tests to use multiple threads.");
commit-bot@chromium.orgba59d642013-04-11 16:54:09 +0000136DEFINE_bool2(verbose, v, false, "enable verbose output.");
137
caryclark@google.com5987f582012-10-02 18:33:14 +0000138int tool_main(int argc, char** argv);
139int tool_main(int argc, char** argv) {
commit-bot@chromium.orgba59d642013-04-11 16:54:09 +0000140 SkCommandLineFlags::SetUsage("");
141 SkCommandLineFlags::Parse(argc, argv);
142
143 if (!FLAGS_tmpDir.isEmpty()) {
144 make_canonical_dir_path(FLAGS_tmpDir[0], &gTmpDir);
145 }
146 if (!FLAGS_resourcePath.isEmpty()) {
147 make_canonical_dir_path(FLAGS_resourcePath[0], &gResourcePath);
148 }
149
bsalomon@google.com4e230682013-01-15 20:37:04 +0000150#if SK_ENABLE_INST_COUNT
reed@google.coma2769752012-07-22 22:33:05 +0000151 gPrintInstCount = true;
152#endif
caryclark@google.comd54e1e92013-04-10 15:57:31 +0000153
reed@google.coma2769752012-07-22 22:33:05 +0000154 SkGraphics::Init();
bungeman@google.com5af16f82011-09-02 15:06:44 +0000155
reed@google.com91d449e2011-10-26 15:25:18 +0000156 {
157 SkString header("Skia UnitTests:");
reed@google.com9aff1482013-04-11 18:27:52 +0000158 if (!FLAGS_match.isEmpty()) {
159 header.appendf(" --match %s", FLAGS_match[0]);
reed@google.com91d449e2011-10-26 15:25:18 +0000160 }
djsollen@google.comcb626502013-03-20 13:48:20 +0000161 if (!gTmpDir.isEmpty()) {
162 header.appendf(" --tmpDir %s", gTmpDir.c_str());
163 }
164 if (!gResourcePath.isEmpty()) {
165 header.appendf(" --resourcePath %s", gResourcePath.c_str());
reed@google.com789c6f22013-02-25 20:24:24 +0000166 }
reed@google.com91d449e2011-10-26 15:25:18 +0000167#ifdef SK_DEBUG
168 header.append(" SK_DEBUG");
169#else
170 header.append(" SK_RELEASE");
171#endif
172#ifdef SK_SCALAR_IS_FIXED
173 header.append(" SK_SCALAR_IS_FIXED");
174#else
175 header.append(" SK_SCALAR_IS_FLOAT");
176#endif
djsollen@google.comf4d1b392012-11-29 16:29:58 +0000177 SkDebugf("%s\n", header.c_str());
reed@google.com91d449e2011-10-26 15:25:18 +0000178 }
179
caryclark@google.com16cfe402013-04-18 18:47:37 +0000180 DebugfReporter reporter(FLAGS_extendedTest, FLAGS_threaded);
reed@android.comed673312009-02-27 16:24:51 +0000181 Iter iter(&reporter);
182 Test* test;
reed@android.com80e39a72009-04-02 16:59:40 +0000183
reed@android.com57b799e2009-04-01 20:26:42 +0000184 const int count = Iter::Count();
185 int index = 0;
bungeman@google.com5af16f82011-09-02 15:06:44 +0000186 int failCount = 0;
187 int skipCount = 0;
reed@android.comed673312009-02-27 16:24:51 +0000188 while ((test = iter.next()) != NULL) {
reed@android.com57b799e2009-04-01 20:26:42 +0000189 reporter.setIndexOfTotal(index, count);
reed@google.com9aff1482013-04-11 18:27:52 +0000190 if (!FLAGS_match.isEmpty() && !strstr(test->getName(), FLAGS_match[0])) {
bungeman@google.com5af16f82011-09-02 15:06:44 +0000191 ++skipCount;
192 } else {
193 if (!test->run()) {
194 ++failCount;
195 }
196 }
reed@android.comed673312009-02-27 16:24:51 +0000197 SkDELETE(test);
reed@android.com57b799e2009-04-01 20:26:42 +0000198 index += 1;
reed@android.comed673312009-02-27 16:24:51 +0000199 }
reed@android.com57b799e2009-04-01 20:26:42 +0000200
djsollen@google.comf4d1b392012-11-29 16:29:58 +0000201 SkDebugf("Finished %d tests, %d failures, %d skipped.\n",
202 count, failCount, skipCount);
caryclark@google.comd54e1e92013-04-10 15:57:31 +0000203 int testCount = reporter.countTests();
commit-bot@chromium.orgba59d642013-04-11 16:54:09 +0000204 if (FLAGS_verbose && testCount > 0) {
caryclark@google.comd54e1e92013-04-10 15:57:31 +0000205 SkDebugf("Ran %d Internal tests.\n", testCount);
206 }
robertphillips@google.combdb1be52012-09-07 18:24:43 +0000207#if SK_SUPPORT_GPU
208
209#if GR_CACHE_STATS
210 GrContext *gr = GpuTest::GetContext();
211
212 gr->printCacheStats();
213#endif
214
215#endif
216
reed@google.coma2769752012-07-22 22:33:05 +0000217 SkGraphics::Term();
bsalomon@google.com67b915d2013-02-04 16:13:32 +0000218 GpuTest::DestroyContexts();
reed@google.coma2769752012-07-22 22:33:05 +0000219
bungeman@google.com5af16f82011-09-02 15:06:44 +0000220 return (failCount == 0) ? 0 : 1;
reed@android.comed673312009-02-27 16:24:51 +0000221}
caryclark@google.com5987f582012-10-02 18:33:14 +0000222
borenet@google.com7158e6a2012-11-01 17:43:44 +0000223#if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL)
caryclark@google.com5987f582012-10-02 18:33:14 +0000224int main(int argc, char * const argv[]) {
225 return tool_main(argc, (char**) argv);
226}
227#endif