Coverage Report

Created: 2021-08-22 09:07

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