Let DM run unit tests.
- refactor GYPs and a few flags
- make GPU tests grab a thread-local GrContextFactory when needed as we do in DM for GMs
- add a few more UI features to make DM more like tests
I believe this makes the program 'tests' obsolete.
It should be somewhat faster to run the two sets together than running the old binaries serially:
- serial: tests 20s (3m18s CPU), dm 21s (3m01s CPU)
- together: 27s (6m21s CPU)
Next up is to incorporate benches. I'm only planning there on a single-pass sanity check, so that won't obsolete the program 'bench' just yet.
Tested: out/Debug/tests && out/Debug/dm && echo ok
BUG=skia:
Committed: http://code.google.com/p/skia/source/detail?r=13586
R=reed@google.com, bsalomon@google.com, mtklein@google.com, tfarina@chromium.org
Author: mtklein@chromium.org
Review URL: https://codereview.chromium.org/178273002
git-svn-id: http://skia.googlecode.com/svn/trunk@13592 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/dm/DM.cpp b/dm/DM.cpp
index 8a4a382..ee53e9d 100644
--- a/dm/DM.cpp
+++ b/dm/DM.cpp
@@ -7,26 +7,29 @@
#include "SkForceLinking.h"
#include "SkGraphics.h"
#include "SkString.h"
+#include "Test.h"
#include "gm.h"
+#include "DMCpuTask.h"
+#include "DMGpuTask.h"
#include "DMReporter.h"
#include "DMTask.h"
#include "DMTaskRunner.h"
-#include "DMCpuTask.h"
-#include "DMGpuTask.h"
+#include "DMTestTask.h"
#include "DMWriteTask.h"
#include <string.h>
using skiagm::GM;
using skiagm::GMRegistry;
+using skiatest::Test;
+using skiatest::TestRegistry;
-DEFINE_int32(cpuThreads, -1, "Threads for CPU work. Default NUM_CPUS.");
-DEFINE_int32(gpuThreads, 1, "Threads for GPU work.");
+DEFINE_int32(threads, -1, "Threads for CPU work. Default NUM_CPUS.");
DEFINE_string2(expectations, r, "",
"If a directory, compare generated images against images under this path. "
"If a file, compare generated images against JSON expectations at this path.");
-DEFINE_string(resources, "resources", "Path to resources directory.");
+DEFINE_string2(resources, i, "resources", "Path to resources directory.");
DEFINE_string(match, "", "[~][^]substring[$] [...] of GM name to run.\n"
"Multiple matches may be separated by spaces.\n"
"~ causes a matching GM to always be skipped\n"
@@ -37,6 +40,10 @@
"it is skipped unless some list entry starts with ~");
DEFINE_string(config, "565 8888 gpu",
"Options: 565 8888 gpu msaa4 msaa16 gpunull gpudebug angle mesa"); // TODO(mtklein): pdf
+DEFINE_bool(leaks, false, "Print leaked instance-counted objects at exit?");
+
+DEFINE_bool(gms, true, "Run GMs?");
+DEFINE_bool(tests, true, "Run tests?");
__SK_FORCE_IMAGE_DECODER_LINKING;
@@ -48,11 +55,11 @@
return s;
}
-static void kick_off_tasks(const SkTDArray<GMRegistry::Factory>& gms,
- const SkTArray<SkString>& configs,
- const DM::Expectations& expectations,
- DM::Reporter* reporter,
- DM::TaskRunner* tasks) {
+static void kick_off_gms(const SkTDArray<GMRegistry::Factory>& gms,
+ const SkTArray<SkString>& configs,
+ const DM::Expectations& expectations,
+ DM::Reporter* reporter,
+ DM::TaskRunner* tasks) {
const SkColorType _565 = kRGB_565_SkColorType;
const SkColorType _8888 = kPMColor_SkColorType;
const GrContextFactory::GLContextType native = GrContextFactory::kNative_GLContextType;
@@ -93,6 +100,14 @@
#undef START
}
+static void kick_off_tests(const SkTDArray<TestRegistry::Factory>& tests,
+ DM::Reporter* reporter,
+ DM::TaskRunner* tasks) {
+ for (int i = 0; i < tests.count(); i++) {
+ tasks->add(SkNEW_ARGS(DM::TestTask, (reporter, tasks, tests[i])));
+ }
+}
+
static void report_failures(const DM::Reporter& reporter) {
SkTArray<SkString> failures;
reporter.getFailures(&failures);
@@ -109,40 +124,57 @@
int tool_main(int argc, char** argv);
int tool_main(int argc, char** argv) {
+#if SK_ENABLE_INST_COUNT
+ gPrintInstCount = FLAGS_leaks;
+#endif
SkGraphics::Init();
-
SkCommandLineFlags::Parse(argc, argv);
GM::SetResourcePath(FLAGS_resources[0]);
+ Test::SetResourcePath(FLAGS_resources[0]);
+
SkTArray<SkString> configs;
- for (int i = 0; i < FLAGS_config.count(); i++) {
- SkStrSplit(FLAGS_config[i], ", ", &configs);
- }
-
SkTDArray<GMRegistry::Factory> gms;
- for (const GMRegistry* reg = GMRegistry::Head(); reg != NULL; reg = reg->next()) {
- SkAutoTDelete<GM> gmForName(reg->factory()(NULL));
- if (!SkCommandLineFlags::ShouldSkip(FLAGS_match, gmForName->shortName())) {
- *gms.append() = reg->factory();
- }
- }
- SkDebugf("%d GMs x %d configs\n", gms.count(), configs.count());
-
SkAutoTDelete<DM::Expectations> expectations(SkNEW(DM::NoExpectations));
- if (FLAGS_expectations.count() > 0) {
- const char* path = FLAGS_expectations[0];
- if (sk_isdir(path)) {
- expectations.reset(SkNEW_ARGS(DM::WriteTask::Expectations, (path)));
- } else {
- expectations.reset(SkNEW_ARGS(DM::JsonExpectations, (path)));
+
+ if (FLAGS_gms) {
+ for (int i = 0; i < FLAGS_config.count(); i++) {
+ SkStrSplit(FLAGS_config[i], ", ", &configs);
+ }
+
+ for (const GMRegistry* reg = GMRegistry::Head(); reg != NULL; reg = reg->next()) {
+ SkAutoTDelete<GM> gmForName(reg->factory()(NULL));
+ if (!SkCommandLineFlags::ShouldSkip(FLAGS_match, gmForName->shortName())) {
+ *gms.append() = reg->factory();
+ }
+ }
+
+ if (FLAGS_expectations.count() > 0) {
+ const char* path = FLAGS_expectations[0];
+ if (sk_isdir(path)) {
+ expectations.reset(SkNEW_ARGS(DM::WriteTask::Expectations, (path)));
+ } else {
+ expectations.reset(SkNEW_ARGS(DM::JsonExpectations, (path)));
+ }
}
}
+ SkTDArray<TestRegistry::Factory> tests;
+ if (FLAGS_tests) {
+ for (const TestRegistry* reg = TestRegistry::Head(); reg != NULL; reg = reg->next()) {
+ SkAutoTDelete<Test> testForName(reg->factory()(NULL));
+ if (!SkCommandLineFlags::ShouldSkip(FLAGS_match, testForName->getName())) {
+ *tests.append() = reg->factory();
+ }
+ }
+ }
+
+ SkDebugf("%d GMs x %d configs, %d tests\n", gms.count(), configs.count(), tests.count());
DM::Reporter reporter;
- DM::TaskRunner tasks(FLAGS_cpuThreads, FLAGS_gpuThreads);
- kick_off_tasks(gms, configs, *expectations, &reporter, &tasks);
+ DM::TaskRunner tasks(FLAGS_threads);
+ kick_off_gms(gms, configs, *expectations, &reporter, &tasks);
+ kick_off_tests(tests, &reporter, &tasks);
tasks.wait();
- reporter.updateStatusLine();
SkDebugf("\n");
report_failures(reporter);