skia2/tests/Test.cpp
scroggo 0ee2627026 When running DM, write test failures to json.
Add skiatest::Failure to keep track of data about a test failure.

Reporter::reportFailed and ::onReportFailed now take Failure as a
parameter. This allows the implementation to treat the failure as it
wishes. Provide a helper to format the failure the same as prior to
the change.

Update the macros for calling reportFailed (REPORTER_ASSERT etc) to
create a Failure object.

Convert a direct call to reportFailed to the macro ERRORF.

Write Failures to Json.
Sample output when running dm on the dummy test crrev.com/705723004:
{
   "test_results" : {
      "failures" : [
         {
            "condition" : "0 > 3",
            "file_name" : "../../tests/DummyTest.cpp",
            "line_no" : 10,
            "message" : ""
         },
         {
            "condition" : "false",
            "file_name" : "../../tests/DummyTest.cpp",
            "line_no" : 4,
            "message" : ""
         },
         {
            "condition" : "1 == 3",
            "file_name" : "../../tests/DummyTest.cpp",
            "line_no" : 5,
            "message" : "I can too count!"
         },
         {
            "condition" : "",
            "file_name" : "../../tests/DummyTest.cpp",
            "line_no" : 6,
            "message" : "seven is 7"
         },
         {
            "condition" : "1 == 3",
            "file_name" : "../../tests/DummyTest.cpp",
            "line_no" : 14,
            "message" : "I can too count!"
         }
      ]
   }
}

Report all of the failures from one test.
Previously, if one test had multiple failures, only one was reportered.
e.g:

Failures:
  test Dummy: ../../tests/DummyTest.cpp:6   seven is 7
  test Dummy2: ../../tests/DummyTest.cpp:10 0 > 3
  test Dummy3: ../../tests/DummyTest.cpp:14 I can too count!: 1 == 3
3 failures.

Now, we get all the messages:

Failures:
  test Dummy: ../../tests/DummyTest.cpp:4   false
        ../../tests/DummyTest.cpp:5 I can too count!: 1 == 3
        ../../tests/DummyTest.cpp:6 seven is 7
  test Dummy2: ../../tests/DummyTest.cpp:10 0 > 3
  test Dummy3: ../../tests/DummyTest.cpp:14 I can too count!: 1 == 3
3 failures.

(Note that we still state "3 failures" because 3 DM::Tasks failed.)

BUG=skia:3082
BUG=skia:2454

Review URL: https://codereview.chromium.org/694703005
2014-11-07 06:07:32 -08:00

119 lines
2.9 KiB
C++

/*
* Copyright 2011 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "Test.h"
#include "SkCommandLineFlags.h"
#include "SkError.h"
#include "SkString.h"
#include "SkTArray.h"
#include "SkTime.h"
#if SK_SUPPORT_GPU
#include "GrContext.h"
#include "gl/SkGLContext.h"
#else
class GrContext;
#endif
DEFINE_string2(tmpDir, t, NULL, "tmp directory for tests to use.");
using namespace skiatest;
Reporter::Reporter() : fTestCount(0) {
}
void Reporter::startTest(Test* test) {
this->onStart(test);
}
void Reporter::reportFailed(const skiatest::Failure& failure) {
this->onReportFailed(failure);
}
void Reporter::endTest(Test* test) {
this->onEnd(test);
}
///////////////////////////////////////////////////////////////////////////////
Test::Test() : fReporter(NULL), fPassed(true) {}
Test::~Test() {
SkSafeUnref(fReporter);
}
void Test::setReporter(Reporter* r) {
SkRefCnt_SafeAssign(fReporter, r);
}
const char* Test::getName() {
if (fName.size() == 0) {
this->onGetName(&fName);
}
return fName.c_str();
}
class LocalReporter : public Reporter {
public:
explicit LocalReporter(Reporter* reporterToMimic) : fReporter(reporterToMimic) {}
int numFailures() const { return fFailures.count(); }
const skiatest::Failure& failure(int i) const { return fFailures[i]; }
protected:
virtual void onReportFailed(const Failure& failure) SK_OVERRIDE {
fFailures.push_back(failure);
}
// Proxy down to fReporter. We assume these calls are threadsafe.
virtual bool allowExtendedTest() const SK_OVERRIDE {
return fReporter->allowExtendedTest();
}
virtual void bumpTestCount() SK_OVERRIDE {
fReporter->bumpTestCount();
}
virtual bool verbose() const SK_OVERRIDE {
return fReporter->verbose();
}
private:
Reporter* fReporter; // Unowned.
SkTArray<skiatest::Failure> fFailures;
};
void Test::run() {
// Clear the Skia error callback before running any test, to ensure that tests
// don't have unintended side effects when running more than one.
SkSetErrorCallback( NULL, NULL );
// Tell (likely shared) fReporter that this test has started.
fReporter->startTest(this);
const SkMSec start = SkTime::GetMSecs();
// Run the test into a LocalReporter so we know if it's passed or failed without interference
// from other tests that might share fReporter.
LocalReporter local(fReporter);
this->onRun(&local);
fPassed = local.numFailures() == 0;
fElapsed = SkTime::GetMSecs() - start;
// Now tell fReporter about any failures and wrap up.
for (int i = 0; i < local.numFailures(); i++) {
fReporter->reportFailed(local.failure(i));
}
fReporter->endTest(this);
}
SkString Test::GetTmpDir() {
const char* tmpDir = FLAGS_tmpDir.isEmpty() ? NULL : FLAGS_tmpDir[0];
return SkString(tmpDir);
}