Flutter Engine
The Flutter Engine
Functions
SkSLErrorTest.cpp File Reference
#include "include/core/SkData.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkString.h"
#include "src/base/SkNoDestructor.h"
#include "src/core/SkOSFile.h"
#include "src/core/SkTHash.h"
#include "src/sksl/SkSLCompiler.h"
#include "src/sksl/SkSLProgramKind.h"
#include "src/sksl/SkSLProgramSettings.h"
#include "src/sksl/SkSLUtil.h"
#include "src/sksl/ir/SkSLProgram.h"
#include "src/utils/SkOSPath.h"
#include "tests/Test.h"
#include "tools/Resources.h"
#include <cstring>
#include <functional>
#include <memory>
#include <sstream>
#include <string>
#include <string_view>
#include <utility>
#include <vector>

Go to the source code of this file.

Functions

static std::vector< std::string > get_expected_errors (const char *shaderString)
 
static void check_expected_errors (skiatest::Reporter *r, const char *testFile, const std::vector< std::string > &expectedErrors, std::string reportedErrors)
 
static void test_expect_fail (skiatest::Reporter *r, const char *testFile, SkSL::ProgramKind kind)
 
static void iterate_dir (const char *directory, const char *extension, const std::function< void(const char *)> &run)
 
 DEF_TEST (SkSLErrorTest, r)
 
 DEF_TEST (SkSLComputeErrorTest, r)
 
 DEF_TEST (SkSLMeshVertexErrorTest, r)
 
 DEF_TEST (SkSLMeshFragmentErrorTest, r)
 
 DEF_TEST (SkSLRuntimeShaderErrorTest, r)
 
 DEF_TEST (SkSLPrivateRuntimeShaderErrorTest, r)
 
 DEF_TEST (SkSLRuntimeColorFilterErrorTest, r)
 
 DEF_TEST (SkSLRuntimeBlenderErrorTest, r)
 

Function Documentation

◆ check_expected_errors()

static void check_expected_errors ( skiatest::Reporter r,
const char *  testFile,
const std::vector< std::string > &  expectedErrors,
std::string  reportedErrors 
)
static

Definition at line 64 of file SkSLErrorTest.cpp.

67 {
68 // Verify that the SkSL compiler actually emitted the expected error messages.
69 // The list of expectations isn't necessarily exhaustive, though.
70 std::string originalErrors = reportedErrors;
71 bool reportOriginalErrors = false;
72 for (const std::string& expectedError : expectedErrors) {
73 // If this error wasn't reported, trigger an error.
74 size_t pos = reportedErrors.find(expectedError.c_str());
75 if (pos == std::string::npos) {
76 ERRORF(r, "%s: Expected an error that wasn't reported:\n%s\n",
77 SkOSPath::Basename(testFile).c_str(), expectedError.c_str());
78 reportOriginalErrors = true;
79 } else {
80 // We found the error that we expected to have. Remove that error from our report, and
81 // everything preceding it as well. This ensures that we don't match the same error
82 // twice, and that errors are reported in the order we expect.
83 reportedErrors.erase(0, pos + expectedError.size());
84 }
85 }
86
87 if (reportOriginalErrors) {
88 ERRORF(r, "%s: The following errors were reported:\n%s\n",
89 SkOSPath::Basename(testFile).c_str(), originalErrors.c_str());
90 }
91}
SkPoint pos
#define ERRORF(r,...)
Definition: Test.h:293
static SkString Basename(const char *fullPath)
Definition: SkOSPath.cpp:23
const char * c_str() const
Definition: SkString.h:133

◆ DEF_TEST() [1/8]

DEF_TEST ( SkSLComputeErrorTest  ,
 
)

Definition at line 177 of file SkSLErrorTest.cpp.

177 {
178 iterate_dir("sksl/errors/", ".compute", [&](const char* path) {
180 });
181}
static void iterate_dir(const char *directory, const char *extension, const std::function< void(const char *)> &run)
static void test_expect_fail(skiatest::Reporter *r, const char *testFile, SkSL::ProgramKind kind)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57

◆ DEF_TEST() [2/8]

DEF_TEST ( SkSLErrorTest  ,
 
)

Definition at line 171 of file SkSLErrorTest.cpp.

171 {
172 iterate_dir("sksl/errors/", ".sksl", [&](const char* path) {
174 });
175}

◆ DEF_TEST() [3/8]

DEF_TEST ( SkSLMeshFragmentErrorTest  ,
 
)

Definition at line 189 of file SkSLErrorTest.cpp.

189 {
190 iterate_dir("sksl/errors/", ".mfrag", [&](const char* path) {
192 });
193}

◆ DEF_TEST() [4/8]

DEF_TEST ( SkSLMeshVertexErrorTest  ,
 
)

Definition at line 183 of file SkSLErrorTest.cpp.

183 {
184 iterate_dir("sksl/errors/", ".mvert", [&](const char* path) {
186 });
187}

◆ DEF_TEST() [5/8]

DEF_TEST ( SkSLPrivateRuntimeShaderErrorTest  ,
 
)

Definition at line 204 of file SkSLErrorTest.cpp.

204 {
205 iterate_dir("sksl/errors/", ".privrts", [&](const char* path) {
207 });
208 iterate_dir("sksl/runtime_errors/", ".privrts", [&](const char* path) {
210 });
211}

◆ DEF_TEST() [6/8]

DEF_TEST ( SkSLRuntimeBlenderErrorTest  ,
 
)

Definition at line 219 of file SkSLErrorTest.cpp.

219 {
220 iterate_dir("sksl/runtime_errors/", ".rtb", [&](const char* path) {
222 });
223}

◆ DEF_TEST() [7/8]

DEF_TEST ( SkSLRuntimeColorFilterErrorTest  ,
 
)

Definition at line 213 of file SkSLErrorTest.cpp.

213 {
214 iterate_dir("sksl/runtime_errors/", ".rtcf", [&](const char* path) {
216 });
217}

◆ DEF_TEST() [8/8]

DEF_TEST ( SkSLRuntimeShaderErrorTest  ,
 
)

Definition at line 195 of file SkSLErrorTest.cpp.

195 {
196 iterate_dir("sksl/errors/", ".rts", [&](const char* path) {
198 });
199 iterate_dir("sksl/runtime_errors/", ".rts", [&](const char* path) {
201 });
202}

◆ get_expected_errors()

static std::vector< std::string > get_expected_errors ( const char *  shaderString)
static

Definition at line 34 of file SkSLErrorTest.cpp.

34 {
35 // Error expectations are embedded in the source with a special *%%* marker, like so:
36 //
37 // /*%%*
38 // expected 'foo', but found 'bar'
39 // 'baz' is not a valid identifier
40 // *%%*/
41 //
42 // Extract them from the shader text.
43 std::vector<std::string> expectedErrors;
44 constexpr char kExpectedErrorsStart[] = "/*%%*";
45 constexpr char kExpectedErrorsEnd[] = "*%%*/";
46 if (const char* startPtr = strstr(shaderString, kExpectedErrorsStart)) {
47 startPtr += strlen(kExpectedErrorsStart);
48 if (const char* endPtr = strstr(startPtr, kExpectedErrorsEnd)) {
49 // Store the text between these delimiters in an array of expected errors.
50 std::stringstream stream{std::string{startPtr, endPtr}};
51 while (stream.good()) {
52 expectedErrors.push_back({});
53 std::getline(stream, expectedErrors.back(), '\n');
54 if (expectedErrors.back().empty()) {
55 expectedErrors.pop_back();
56 }
57 }
58 }
59 }
60
61 return expectedErrors;
62}

◆ iterate_dir()

static void iterate_dir ( const char *  directory,
const char *  extension,
const std::function< void(const char *)> &  run 
)
static

Definition at line 158 of file SkSLErrorTest.cpp.

160 {
161 SkString resourceDirectory = GetResourcePath(directory);
162 SkOSFile::Iter iter(resourceDirectory.c_str(), extension);
164
165 while (iter.next(&name, /*getDir=*/false)) {
166 SkString path(SkOSPath::Join(directory, name.c_str()));
167 run(path.c_str());
168 }
169}
SkString GetResourcePath(const char *resource)
Definition: Resources.cpp:23
static SkString Join(const char *rootPath, const char *relativePath)
Definition: SkOSPath.cpp:14
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32
def run(cmd)
Definition: run.py:14

◆ test_expect_fail()

static void test_expect_fail ( skiatest::Reporter r,
const char *  testFile,
SkSL::ProgramKind  kind 
)
static

Definition at line 93 of file SkSLErrorTest.cpp.

93 {
94 // In a size-optimized build, there are a handful of errors which report differently, or not at
95 // all. Skip over those tests.
96 static const SkNoDestructor<THashSet<std::string_view>> kTestsToSkip{{
97 // These are tests that have been deleted, but which may still show up (and fail) on tasks,
98 // because the resources directory isn't properly cleaned up. (b/40044088)
99 "sksl/errors/InvalidBackendBindingFlagsGL.sksl",
100 "sksl/errors/InvalidThreadgroupRTS.rts",
101 "sksl/errors/LastFragColorWithoutCaps.sksl",
102 "sksl/errors/MeshFragmentWithShader.mfrag",
103 "sksl/errors/MeshFragmentWithBlender.mfrag",
104 "sksl/errors/MeshFragmentWithColorFilter.mfrag",
105 "sksl/errors/StaticIfTest.sksl",
106 "sksl/errors/StaticSwitchConditionalBreak.sksl",
107 "sksl/errors/StaticSwitchTest.sksl",
108 "sksl/errors/StaticSwitchWithConditionalBreak.sksl",
109 "sksl/errors/StaticSwitchWithConditionalContinue.sksl",
110 "sksl/errors/StaticSwitchWithConditionalReturn.sksl",
111
112 "sksl/errors/ComputeUniform.compute",
113 "sksl/errors/DuplicateBinding.compute",
114 "sksl/errors/InvalidThreadgroupCompute.compute",
115 "sksl/errors/UnspecifiedBinding.compute",
116
117 "sksl/runtime_errors/ReservedNameISampler2D.rts",
118
119#ifdef SK_ENABLE_OPTIMIZE_SIZE
120 "sksl/errors/ArrayInlinedIndexOutOfRange.sksl",
121 "sksl/errors/MatrixInlinedIndexOutOfRange.sksl",
122 "sksl/errors/OverflowInlinedLiteral.sksl",
123 "sksl/errors/VectorInlinedIndexOutOfRange.sksl",
124#endif
125 }};
126 if (kTestsToSkip->contains(testFile)) {
127 INFOF(r, "%s: skipped in SK_ENABLE_OPTIMIZE_SIZE mode", testFile);
128 return;
129 }
130
131 sk_sp<SkData> shaderData = GetResourceAsData(testFile);
132 if (!shaderData) {
133 ERRORF(r, "%s: Unable to load file", SkOSPath::Basename(testFile).c_str());
134 return;
135 }
136
137 std::string shaderString{reinterpret_cast<const char*>(shaderData->bytes()),
138 shaderData->size()};
139
140 std::vector<std::string> expectedErrors = get_expected_errors(shaderString.c_str());
141
142 // Compile the code.
145 std::unique_ptr<SkSL::Program> program = compiler.convertProgram(kind, std::move(shaderString),
146 settings);
147
148 // If the code actually generated a working program, we've already failed.
149 if (program) {
150 ERRORF(r, "%s: Expected failure, but compiled successfully",
151 SkOSPath::Basename(testFile).c_str());
152 return;
153 }
154
155 check_expected_errors(r, testFile, expectedErrors, compiler.errorText());
156}
sk_sp< SkData > GetResourceAsData(const char *resource)
Definition: Resources.cpp:42
static void check_expected_errors(skiatest::Reporter *r, const char *testFile, const std::vector< std::string > &expectedErrors, std::string reportedErrors)
static std::vector< std::string > get_expected_errors(const char *shaderString)
#define INFOF(REPORTER,...)
Definition: Test.h:298
const uint8_t * bytes() const
Definition: SkData.h:43
size_t size() const
Definition: SkData.h:30
compiler
Definition: malisc.py:17