• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 The Dawn Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef TESTS_UNITTESTS_VALIDATIONTEST_H_
16 #define TESTS_UNITTESTS_VALIDATIONTEST_H_
17 
18 #include "common/Log.h"
19 #include "dawn/webgpu_cpp.h"
20 #include "dawn_native/DawnNative.h"
21 
22 #include <gmock/gmock.h>
23 #include <gtest/gtest.h>
24 
25 // Argument helpers to allow macro overriding.
26 #define UNIMPLEMENTED_MACRO(...) UNREACHABLE()
27 #define GET_3RD_ARG_HELPER_(_1, _2, NAME, ...) NAME
28 #define GET_3RD_ARG_(args) GET_3RD_ARG_HELPER_ args
29 
30 // Overloaded to allow further validation of the error messages given an error is expected.
31 // Especially useful to verify that the expected errors are occuring, not just any error.
32 //
33 // Example usages:
34 //   1 Argument Case:
35 //     ASSERT_DEVICE_ERROR(FunctionThatExpectsError());
36 //
37 //   2 Argument Case:
38 //     ASSERT_DEVICE_ERROR(FunctionThatHasLongError(), HasSubstr("partial match"))
39 //     ASSERT_DEVICE_ERROR(FunctionThatHasShortError(), Eq("exact match"));
40 #define ASSERT_DEVICE_ERROR(...)                                                         \
41     GET_3RD_ARG_((__VA_ARGS__, ASSERT_DEVICE_ERROR_IMPL_2_, ASSERT_DEVICE_ERROR_IMPL_1_, \
42                   UNIMPLEMENTED_MACRO))                                                  \
43     (__VA_ARGS__)
44 
45 #define ASSERT_DEVICE_ERROR_IMPL_1_(statement)                  \
46     StartExpectDeviceError();                                   \
47     statement;                                                  \
48     FlushWire();                                                \
49     if (!EndExpectDeviceError()) {                              \
50         FAIL() << "Expected device error in:\n " << #statement; \
51     }                                                           \
52     do {                                                        \
53     } while (0)
54 
55 #define ASSERT_DEVICE_ERROR_IMPL_2_(statement, matcher)         \
56     StartExpectDeviceError(matcher);                            \
57     statement;                                                  \
58     FlushWire();                                                \
59     if (!EndExpectDeviceError()) {                              \
60         FAIL() << "Expected device error in:\n " << #statement; \
61     }                                                           \
62     do {                                                        \
63     } while (0)
64 
65 // Skip a test when the given condition is satisfied.
66 #define DAWN_SKIP_TEST_IF(condition)                            \
67     do {                                                        \
68         if (condition) {                                        \
69             dawn::InfoLog() << "Test skipped: " #condition "."; \
70             GTEST_SKIP();                                       \
71             return;                                             \
72         }                                                       \
73     } while (0)
74 
75 #define EXPECT_DEPRECATION_WARNINGS(statement, n)                                                 \
76     do {                                                                                          \
77         FlushWire();                                                                              \
78         size_t warningsBefore = dawn_native::GetDeprecationWarningCountForTesting(backendDevice); \
79         EXPECT_EQ(mLastWarningCount, warningsBefore);                                             \
80         statement;                                                                                \
81         FlushWire();                                                                              \
82         size_t warningsAfter = dawn_native::GetDeprecationWarningCountForTesting(backendDevice);  \
83         EXPECT_EQ(warningsAfter, warningsBefore + n);                                             \
84         mLastWarningCount = warningsAfter;                                                        \
85     } while (0)
86 #define EXPECT_DEPRECATION_WARNING(statement) EXPECT_DEPRECATION_WARNINGS(statement, 1)
87 
88 namespace utils {
89     class WireHelper;
90 }  // namespace utils
91 
92 void InitDawnValidationTestEnvironment(int argc, char** argv);
93 
94 class ValidationTest : public testing::Test {
95   public:
96     ValidationTest();
97     ~ValidationTest() override;
98 
99     void SetUp() override;
100     void TearDown() override;
101 
102     void StartExpectDeviceError(testing::Matcher<std::string> errorMatcher);
103     void StartExpectDeviceError();
104     bool EndExpectDeviceError();
105     std::string GetLastDeviceErrorMessage() const;
106 
107     wgpu::Device RegisterDevice(WGPUDevice backendDevice);
108 
109     bool UsesWire() const;
110 
111     void FlushWire();
112     void WaitForAllOperations(const wgpu::Device& device);
113 
114     // Helper functions to create objects to test validation.
115 
116     struct DummyRenderPass : public wgpu::RenderPassDescriptor {
117       public:
118         DummyRenderPass(const wgpu::Device& device);
119         wgpu::Texture attachment;
120         wgpu::TextureFormat attachmentFormat;
121         uint32_t width;
122         uint32_t height;
123 
124       private:
125         wgpu::RenderPassColorAttachment mColorAttachment;
126     };
127 
128     bool HasToggleEnabled(const char* toggle) const;
129 
130     // TODO(crbug.com/dawn/689): Use limits returned from the wire
131     // This is implemented here because tests need to always query
132     // the |backendDevice| since limits are not implemented in the wire.
133     wgpu::SupportedLimits GetSupportedLimits();
134 
135   protected:
136     virtual WGPUDevice CreateTestDevice();
137 
138     std::unique_ptr<dawn_native::Instance> instance;
139     dawn_native::Adapter adapter;
140     wgpu::Device device;
141     WGPUDevice backendDevice;
142 
143     size_t mLastWarningCount = 0;
144 
145   private:
146     std::unique_ptr<utils::WireHelper> mWireHelper;
147 
148     static void OnDeviceError(WGPUErrorType type, const char* message, void* userdata);
149     std::string mDeviceErrorMessage;
150     bool mExpectError = false;
151     bool mError = false;
152     testing::Matcher<std::string> mErrorMatcher;
153 };
154 
155 #endif  // TESTS_UNITTESTS_VALIDATIONTEST_H_
156