mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-17 17:05:31 +00:00
Implement ErrorScopes for synchronous errors
This patch implements Push/PopErrorScope except for asynchronous or GPU commands. These commands, such as Queue::Submit will need to hold onto the ErrorScope until GPU execution is complete. Bug: dawn:153 Change-Id: I2d340b8b391d117a59497f35690993a9cd7503e6 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/10700 Reviewed-by: Austin Eng <enga@chromium.org> Commit-Queue: Austin Eng <enga@chromium.org>
This commit is contained in:
committed by
Commit Bot service account
parent
619935f7f2
commit
f35dcfe60a
134
src/tests/unittests/validation/ErrorScopeValidationTests.cpp
Normal file
134
src/tests/unittests/validation/ErrorScopeValidationTests.cpp
Normal file
@@ -0,0 +1,134 @@
|
||||
// Copyright 2019 The Dawn Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "tests/unittests/validation/ValidationTest.h"
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
using namespace testing;
|
||||
|
||||
class MockDevicePopErrorScopeCallback {
|
||||
public:
|
||||
MOCK_METHOD3(Call, void(DawnErrorType type, const char* message, void* userdata));
|
||||
};
|
||||
|
||||
static std::unique_ptr<MockDevicePopErrorScopeCallback> mockDevicePopErrorScopeCallback;
|
||||
static void ToMockDevicePopErrorScopeCallback(DawnErrorType type,
|
||||
const char* message,
|
||||
void* userdata) {
|
||||
mockDevicePopErrorScopeCallback->Call(type, message, userdata);
|
||||
}
|
||||
|
||||
class ErrorScopeValidationTest : public ValidationTest {
|
||||
private:
|
||||
void SetUp() override {
|
||||
ValidationTest::SetUp();
|
||||
mockDevicePopErrorScopeCallback = std::make_unique<MockDevicePopErrorScopeCallback>();
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
// Delete mocks so that expectations are checked
|
||||
mockDevicePopErrorScopeCallback = nullptr;
|
||||
ValidationTest::TearDown();
|
||||
}
|
||||
};
|
||||
|
||||
// Test the simple success case.
|
||||
TEST_F(ErrorScopeValidationTest, Success) {
|
||||
device.PushErrorScope(dawn::ErrorFilter::Validation);
|
||||
|
||||
EXPECT_CALL(*mockDevicePopErrorScopeCallback, Call(DAWN_ERROR_TYPE_NO_ERROR, _, this)).Times(1);
|
||||
device.PopErrorScope(ToMockDevicePopErrorScopeCallback, this);
|
||||
}
|
||||
|
||||
// Test the simple case where the error scope catches an error.
|
||||
TEST_F(ErrorScopeValidationTest, CatchesError) {
|
||||
device.PushErrorScope(dawn::ErrorFilter::Validation);
|
||||
|
||||
dawn::BufferDescriptor desc = {};
|
||||
desc.usage = static_cast<dawn::BufferUsage>(DAWN_BUFFER_USAGE_FORCE32);
|
||||
device.CreateBuffer(&desc);
|
||||
|
||||
EXPECT_CALL(*mockDevicePopErrorScopeCallback, Call(DAWN_ERROR_TYPE_VALIDATION, _, this))
|
||||
.Times(1);
|
||||
device.PopErrorScope(ToMockDevicePopErrorScopeCallback, this);
|
||||
}
|
||||
|
||||
// Test that errors bubble to the parent scope if not handled by the current scope.
|
||||
TEST_F(ErrorScopeValidationTest, ErrorBubbles) {
|
||||
device.PushErrorScope(dawn::ErrorFilter::Validation);
|
||||
device.PushErrorScope(dawn::ErrorFilter::OutOfMemory);
|
||||
|
||||
dawn::BufferDescriptor desc = {};
|
||||
desc.usage = static_cast<dawn::BufferUsage>(DAWN_BUFFER_USAGE_FORCE32);
|
||||
device.CreateBuffer(&desc);
|
||||
|
||||
// OutOfMemory does not match Validation error.
|
||||
EXPECT_CALL(*mockDevicePopErrorScopeCallback, Call(DAWN_ERROR_TYPE_NO_ERROR, _, this)).Times(1);
|
||||
device.PopErrorScope(ToMockDevicePopErrorScopeCallback, this);
|
||||
|
||||
// Parent validation error scope captures the error.
|
||||
EXPECT_CALL(*mockDevicePopErrorScopeCallback, Call(DAWN_ERROR_TYPE_VALIDATION, _, this + 1))
|
||||
.Times(1);
|
||||
device.PopErrorScope(ToMockDevicePopErrorScopeCallback, this + 1);
|
||||
}
|
||||
|
||||
// Test that if an error scope matches an error, it does not bubble to the parent scope.
|
||||
TEST_F(ErrorScopeValidationTest, HandledErrorsStopBubbling) {
|
||||
device.PushErrorScope(dawn::ErrorFilter::OutOfMemory);
|
||||
device.PushErrorScope(dawn::ErrorFilter::Validation);
|
||||
|
||||
dawn::BufferDescriptor desc = {};
|
||||
desc.usage = static_cast<dawn::BufferUsage>(DAWN_BUFFER_USAGE_FORCE32);
|
||||
device.CreateBuffer(&desc);
|
||||
|
||||
// Inner scope catches the error.
|
||||
EXPECT_CALL(*mockDevicePopErrorScopeCallback, Call(DAWN_ERROR_TYPE_VALIDATION, _, this))
|
||||
.Times(1);
|
||||
device.PopErrorScope(ToMockDevicePopErrorScopeCallback, this);
|
||||
|
||||
// Parent scope does not see the error.
|
||||
EXPECT_CALL(*mockDevicePopErrorScopeCallback, Call(DAWN_ERROR_TYPE_NO_ERROR, _, this + 1))
|
||||
.Times(1);
|
||||
device.PopErrorScope(ToMockDevicePopErrorScopeCallback, this + 1);
|
||||
}
|
||||
|
||||
// Test that if no error scope handles an error, it goes to the device UncapturedError callback
|
||||
TEST_F(ErrorScopeValidationTest, UnhandledErrorsMatchUncapturedErrorCallback) {
|
||||
device.PushErrorScope(dawn::ErrorFilter::OutOfMemory);
|
||||
|
||||
dawn::BufferDescriptor desc = {};
|
||||
desc.usage = static_cast<dawn::BufferUsage>(DAWN_BUFFER_USAGE_FORCE32);
|
||||
ASSERT_DEVICE_ERROR(device.CreateBuffer(&desc));
|
||||
|
||||
EXPECT_CALL(*mockDevicePopErrorScopeCallback, Call(DAWN_ERROR_TYPE_NO_ERROR, _, this)).Times(1);
|
||||
device.PopErrorScope(ToMockDevicePopErrorScopeCallback, this);
|
||||
}
|
||||
|
||||
// Check that push/popping error scopes must be balanced.
|
||||
TEST_F(ErrorScopeValidationTest, PushPopBalanced) {
|
||||
// No error scopes to pop.
|
||||
{ EXPECT_FALSE(device.PopErrorScope(ToMockDevicePopErrorScopeCallback, this)); }
|
||||
|
||||
// Too many pops
|
||||
{
|
||||
device.PushErrorScope(dawn::ErrorFilter::Validation);
|
||||
|
||||
EXPECT_CALL(*mockDevicePopErrorScopeCallback, Call(DAWN_ERROR_TYPE_NO_ERROR, _, this + 1))
|
||||
.Times(1);
|
||||
device.PopErrorScope(ToMockDevicePopErrorScopeCallback, this + 1);
|
||||
|
||||
EXPECT_FALSE(device.PopErrorScope(ToMockDevicePopErrorScopeCallback, this + 2));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user