Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
playground_test.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
6
7#ifndef FML_OS_WIN
8#include <wordexp.h>
9#endif
10
11#include "flutter/fml/file.h"
17
18namespace impeller {
19
21 : Playground(GetParam(),
22 PlaygroundSwitches{flutter::testing::GetArgsForProcess()}) {
24 [](const char* message, const char* file, int line) -> bool {
25 // GTEST_MESSAGE_AT_ can only be used in a function that returns void.
26 // Hence the goofy lambda. The failure message and location will still
27 // be correct however.
28 //
29 // https://google.github.io/googletest/advanced.html#assertion-placement
30 [message, file, line]() -> void {
31 GTEST_MESSAGE_AT_(file, line, "Impeller Validation Error",
32 ::testing::TestPartResult::kFatalFailure)
33 << message;
34 }();
35 return true;
36 });
37}
38
42
44 if (!Playground::SupportsBackend(GetParam())) {
45 GTEST_SKIP() << "Playground doesn't support this backend type.";
46 return;
47 }
48
50 GTEST_SKIP() << "Skipping due to user action.";
51 return;
52 }
53
55}
56
60
61namespace {
62
63class PlaygroundTestEnvironment : public ::testing::Environment {
64 public:
65 static std::optional<std::string> ValidateGoldenDirectory(
66 const std::string& dir) {
67#ifdef FML_OS_WIN
68 return dir;
69#else // FML_OS_WIN
70 wordexp_t wordexp_result;
71 int code = wordexp(dir.c_str(), &wordexp_result, 0);
72 FML_CHECK(code == 0) << "Could not parse golden output directory: " << dir;
73 FML_CHECK(wordexp_result.we_wordc == 1u)
74 << "Exactly one directory must be specified for Golden image output: "
75 << dir;
76 std::optional<std::string> working_dir = wordexp_result.we_wordv[0];
77 wordfree(&wordexp_result);
78
79 FML_CHECK(working_dir) << "Unrecognized golden output directory: " << dir;
81 working_dir->c_str(), false, fml::FilePermission::kReadWrite);
82 FML_CHECK(fml::IsDirectory(directory))
83 << "Golden output directory must be a directory with read/write"
84 << " permissions: " << dir;
85 return working_dir;
86#endif // FML_OS_WIN
87 }
88
89 void SetUp() override {
91 std::string golden_output_dir;
92 if (args.GetOptionValue("golden_output_dir", &golden_output_dir)) {
93 const std::optional<std::string> validated_dir =
94 ValidateGoldenDirectory(golden_output_dir);
95 if (validated_dir) {
96 golden_manager_.emplace(*validated_dir);
97 } else {
98 FML_CHECK(validated_dir)
99 << "Did not recognize golden output directory: "
100 << golden_output_dir;
101 }
102 }
103 }
104
105 void TearDown() override {
106 if (golden_manager_) {
107 if (::testing::UnitTest::GetInstance()->Passed()) {
108 golden_manager_->Write();
109 } else {
110 FML_LOG(ERROR)
111 << ::testing::UnitTest::GetInstance()->failed_test_count()
112 << " tests failed, golden digest will not be written";
113 golden_manager_->ClearDigestData();
114 }
115 golden_manager_.reset();
116 }
119 }
120
121 static testing::GoldenDigestManager* GetGoldenDigestManager() {
122 return golden_manager_ ? &golden_manager_.value() : nullptr;
123 }
124
125 private:
126 static std::optional<testing::GoldenDigestManager> golden_manager_;
127};
128
129std::optional<testing::GoldenDigestManager>
130 PlaygroundTestEnvironment::golden_manager_;
131
132} // namespace
133
134// Change these declarations to #defines to enable swiftshader or metal
135// validation.
136#undef APPLY_METAL_VALIDATION
137#undef ENABLE_VK_SWIFTSHADER
138
140#ifdef ENABLE_VK_SWIFTSHADER
141 // Make sure environment is set up for VK swiftshader
142 std::filesystem::path testing_assets_path =
144 std::filesystem::path target_path = testing_assets_path.parent_path()
145 .parent_path()
146 .parent_path()
147 .parent_path();
148 std::filesystem::path icd_path = target_path / "vk_swiftshader_icd.json";
149 setenv("VK_ICD_FILENAMES", icd_path.c_str(), 1);
150#endif
151
152#ifdef APPLY_METAL_VALIDATION
153 // https://developer.apple.com/documentation/metal/diagnosing_metal_programming_issues_early?language=objc
154 // Enables all shader validation tests.
155 setenv("MTL_SHADER_VALIDATION", "1", true);
156 // Validates accesses to device and constant memory.
157 setenv("MTL_SHADER_VALIDATION_GLOBAL_MEMORY", "1", true);
158 // Validates accesses to threadgroup memory.
159 setenv("MTL_SHADER_VALIDATION_THREADGROUP_MEMORY", "1", true);
160 // Validates that texture references are not nil.
161 setenv("MTL_SHADER_VALIDATION_TEXTURE_USAGE", "1", true);
162 // Enables metal validation.
163 setenv("METAL_DEBUG_ERROR_MODE", "0", true);
164 // Enables metal validation.
165 setenv("METAL_DEVICE_WRAPPER_TYPE", "1", true);
166#endif
167
168 ::testing::AddGlobalTestEnvironment(new PlaygroundTestEnvironment());
169}
170
172 const {
173 return PlaygroundTestEnvironment::GetGoldenDigestManager();
174}
175
177 return false;
178}
179
181 return GetParam();
182}
183
184// |Playground|
185std::unique_ptr<fml::Mapping> PlaygroundTest::OpenAssetAsMapping(
186 std::string asset_name) const {
188}
189
190absl::StatusOr<RuntimeStage::Map> PlaygroundTest::OpenAssetAsRuntimeStage(
191 const char* asset_name) const {
192 const std::shared_ptr<fml::Mapping> fixture =
194 if (!fixture || fixture->GetSize() == 0) {
195 return absl::NotFoundError("Asset not found or empty.");
196 }
197 return RuntimeStage::DecodeRuntimeStages(fixture);
198}
199
200// |Playground|
202 std::stringstream stream;
203 stream << "Impeller Playground for '"
205 switch (GetBackend()) {
208 break;
211 if (GetSwitches().use_angle) {
212 stream << " (Angle) ";
213 }
214 break;
216 if (GetSwitches().use_swiftshader) {
217 stream << " (SwiftShader) ";
218 }
219 break;
220 }
221 stream << " (Press ESC to quit)";
222 return stream.str();
223}
224
225// |Playground|
226bool PlaygroundTest::ShouldKeepRendering() const {
227 if (!GetSwitches().timeout.has_value()) {
228 return true;
229 }
230
231 if (SecondsF{GetSecondsElapsed()} > GetSwitches().timeout.value()) {
232 return false;
233 }
234
235 return true;
236}
237
238} // namespace impeller
static void OnTearDownTestEnvironment()
static bool ShouldOpenNewPlaygrounds()
static bool SupportsBackend(PlaygroundBackend backend)
const PlaygroundSwitches & GetSwitches() const
Return an unmodifiable reference to the current switches. The switches might change at the start of a...
Definition playground.h:183
void SetEnableWriteGolden(bool write_golden)
Sets a particular test to either write a golden or not, false by default.
Scalar GetSecondsElapsed() const
Get the amount of time elapsed from the start of the playground's execution.
static void OnTearDownTestEnvironment()
std::unique_ptr< fml::Mapping > OpenAssetAsMapping(std::string asset_name) const override
std::string GetWindowTitle() const override
absl::StatusOr< RuntimeStage::Map > OpenAssetAsRuntimeStage(const char *asset_name) const
PlaygroundBackend GetBackend() const
testing::GoldenDigestManager * GetGoldenDigestManager() const override
virtual bool IsGoldenTestSuite() const
This method is overridden on a test suite basis and establishes whether a given set of tests is inten...
static absl::StatusOr< Map > DecodeRuntimeStages(const std::shared_ptr< fml::Mapping > &payload)
const char * message
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
#define FML_LOG(severity)
Definition logging.h:101
#define FML_CHECK(condition)
Definition logging.h:104
std::string GetCurrentTestName()
Gets the name of the currently running test. This is useful in generating logs or assets based on tes...
Definition testing.cc:14
const char * GetTestingAssetsPath()
Returns the directory containing assets shared across all tests.
std::unique_ptr< fml::Mapping > OpenFixtureAsMapping(const std::string &fixture_name)
Opens a fixture of the given file name and returns a mapping to its contents.
Definition testing.cc:58
const fml::CommandLine & GetArgsForProcess()
Definition test_args.cc:11
fml::UniqueFD OpenDirectory(const char *path, bool create_if_necessary, FilePermission permission)
Definition file_posix.cc:97
bool IsDirectory(const fml::UniqueFD &directory)
void ImpellerValidationErrorsSetCallback(ValidationFailureCallback callback)
Sets a callback that callers (usually tests) can set to intercept validation failures.
Definition validation.cc:21
PlaygroundBackend
Definition playground.h:32
std::chrono::duration< float > SecondsF
Definition timing.h:13
std::optional< std::chrono::milliseconds > timeout
Definition switches.h:21