1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
|
/*
* Copyright 2011 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef skiatest_Test_DEFINED
#define skiatest_Test_DEFINED
#include "SkString.h"
#include "../tools/Registry.h"
#include "SkTypes.h"
#include "SkClipOpPriv.h"
#if SK_SUPPORT_GPU
#include "GrContextFactory.h"
#else
namespace sk_gpu_test {
class GrContextFactory;
class ContextInfo;
class GLTestContext;
} // namespace sk_gpu_test
class GrContext;
#endif
namespace skiatest {
SkString GetTmpDir();
struct Failure {
Failure(const char* f, int l, const char* c, const SkString& m)
: fileName(f), lineNo(l), condition(c), message(m) {}
const char* fileName;
int lineNo;
const char* condition;
SkString message;
SkString toString() const;
};
class Reporter : SkNoncopyable {
public:
virtual ~Reporter() {}
virtual void bumpTestCount();
virtual void reportFailed(const skiatest::Failure&) = 0;
virtual bool allowExtendedTest() const;
virtual bool verbose() const;
virtual void* stats() const { return nullptr; }
void reportFailedWithContext(const skiatest::Failure& f) {
SkString fullMessage = f.message;
if (!fContextStack.empty()) {
fullMessage.append(" [");
for (int i = 0; i < fContextStack.count(); ++i) {
if (i > 0) {
fullMessage.append(", ");
}
fullMessage.append(fContextStack[i]);
}
fullMessage.append("]");
}
this->reportFailed(skiatest::Failure(f.fileName, f.lineNo, f.condition, fullMessage));
}
void push(const SkString& message) {
fContextStack.push_back(message);
}
void pop() {
fContextStack.pop_back();
}
private:
SkTArray<SkString> fContextStack;
};
#define REPORT_FAILURE(reporter, cond, message) \
reporter->reportFailedWithContext(skiatest::Failure(__FILE__, __LINE__, cond, message))
class ReporterContext : SkNoncopyable {
public:
ReporterContext(Reporter* reporter, const SkString& message) : fReporter(reporter) {
fReporter->push(message);
}
~ReporterContext() {
fReporter->pop();
}
private:
Reporter* fReporter;
};
typedef void (*TestProc)(skiatest::Reporter*, sk_gpu_test::GrContextFactory*);
struct Test {
Test(const char* n, bool g, TestProc p) : name(n), needsGpu(g), proc(p) {}
const char* name;
bool needsGpu;
TestProc proc;
};
typedef sk_tools::Registry<Test> TestRegistry;
/*
Use the following macros to make use of the skiatest classes, e.g.
#include "Test.h"
DEF_TEST(TestName, reporter) {
...
REPORTER_ASSERT(reporter, x == 15);
...
REPORTER_ASSERT_MESSAGE(reporter, x == 15, "x should be 15");
...
if (x != 15) {
ERRORF(reporter, "x should be 15, but is %d", x);
return;
}
...
}
*/
#if SK_SUPPORT_GPU
using GrContextFactoryContextType = sk_gpu_test::GrContextFactory::ContextType;
#else
using GrContextFactoryContextType = int;
#endif
typedef void GrContextTestFn(Reporter*, const sk_gpu_test::ContextInfo&);
typedef bool GrContextTypeFilterFn(GrContextFactoryContextType);
extern bool IsGLContextType(GrContextFactoryContextType);
extern bool IsVulkanContextType(GrContextFactoryContextType);
extern bool IsRenderingGLContextType(GrContextFactoryContextType);
extern bool IsNullGLContextType(GrContextFactoryContextType);
void RunWithGPUTestContexts(GrContextTestFn*, GrContextTypeFilterFn*,
Reporter*, sk_gpu_test::GrContextFactory*);
/** Timer provides wall-clock duration since its creation. */
class Timer {
public:
/** Starts the timer. */
Timer();
/** Nanoseconds since creation. */
double elapsedNs() const;
/** Milliseconds since creation. */
double elapsedMs() const;
/** Milliseconds since creation as an integer.
Behavior is undefined for durations longer than SK_MSecMax.
*/
SkMSec elapsedMsInt() const;
private:
double fStartNanos;
};
} // namespace skiatest
#define REPORTER_ASSERT(r, cond) \
do { \
if (!(cond)) { \
REPORT_FAILURE(r, #cond, SkString()); \
} \
} while (0)
#define REPORTER_ASSERT_MESSAGE(r, cond, message) \
do { \
if (!(cond)) { \
REPORT_FAILURE(r, #cond, SkString(message)); \
} \
} while (0)
#define ERRORF(r, ...) \
do { \
REPORT_FAILURE(r, "", SkStringPrintf(__VA_ARGS__)); \
} while (0)
#define INFOF(REPORTER, ...) \
do { \
if ((REPORTER)->verbose()) { \
SkDebugf(__VA_ARGS__); \
} \
} while (0)
#define DEF_TEST(name, reporter) \
static void test_##name(skiatest::Reporter*, sk_gpu_test::GrContextFactory*); \
skiatest::TestRegistry name##TestRegistry( \
skiatest::Test(#name, false, test_##name)); \
void test_##name(skiatest::Reporter* reporter, sk_gpu_test::GrContextFactory*)
#define DEF_GPUTEST(name, reporter, factory) \
static void test_##name(skiatest::Reporter*, sk_gpu_test::GrContextFactory*); \
skiatest::TestRegistry name##TestRegistry( \
skiatest::Test(#name, true, test_##name)); \
void test_##name(skiatest::Reporter* reporter, sk_gpu_test::GrContextFactory* factory)
#define DEF_GPUTEST_FOR_CONTEXTS(name, context_filter, reporter, context_info) \
static void test_##name(skiatest::Reporter*, \
const sk_gpu_test::ContextInfo& context_info); \
static void test_gpu_contexts_##name(skiatest::Reporter* reporter, \
sk_gpu_test::GrContextFactory* factory) { \
skiatest::RunWithGPUTestContexts(test_##name, context_filter, reporter, factory); \
} \
skiatest::TestRegistry name##TestRegistry( \
skiatest::Test(#name, true, test_gpu_contexts_##name)); \
void test_##name(skiatest::Reporter* reporter, \
const sk_gpu_test::ContextInfo& context_info)
#define DEF_GPUTEST_FOR_ALL_CONTEXTS(name, reporter, context_info) \
DEF_GPUTEST_FOR_CONTEXTS(name, nullptr, reporter, context_info)
#define DEF_GPUTEST_FOR_RENDERING_CONTEXTS(name, reporter, context_info) \
DEF_GPUTEST_FOR_CONTEXTS(name, sk_gpu_test::GrContextFactory::IsRenderingContext, \
reporter, context_info)
#define DEF_GPUTEST_FOR_ALL_GL_CONTEXTS(name, reporter, context_info) \
DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsGLContextType, reporter, context_info)
#define DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(name, reporter, context_info) \
DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsRenderingGLContextType, reporter, context_info)
#define DEF_GPUTEST_FOR_NULLGL_CONTEXT(name, reporter, context_info) \
DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsNullGLContextType, reporter, context_info)
#define DEF_GPUTEST_FOR_VULKAN_CONTEXT(name, reporter, context_info) \
DEF_GPUTEST_FOR_CONTEXTS(name, &skiatest::IsVulkanContextType, reporter, context_info)
#define REQUIRE_PDF_DOCUMENT(TEST_NAME, REPORTER) \
do { \
SkDynamicMemoryWStream testStream; \
sk_sp<SkDocument> testDoc(SkDocument::MakePDF(&testStream)); \
if (!testDoc) { \
INFOF(REPORTER, "PDF disabled; %s test skipped.", #TEST_NAME); \
return; \
} \
} while (false)
#endif
|