| // Copyright 2019 The Dawn & Tint Authors | |
| // | |
| // Redistribution and use in source and binary forms, with or without | |
| // modification, are permitted provided that the following conditions are met: | |
| // | |
| // 1. Redistributions of source code must retain the above copyright notice, this | |
| // list of conditions and the following disclaimer. | |
| // | |
| // 2. Redistributions in binary form must reproduce the above copyright notice, | |
| // this list of conditions and the following disclaimer in the documentation | |
| // and/or other materials provided with the distribution. | |
| // | |
| // 3. Neither the name of the copyright holder nor the names of its | |
| // contributors may be used to endorse or promote products derived from | |
| // this software without specific prior written permission. | |
| // | |
| // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
| // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | |
| // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
| // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
| // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |
| // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |
| // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
| // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| #include "src/dawn/common/vulkan_platform.h" | |
| // Must come after vulkan_platform | |
| #include "dawn/native/VulkanBackend.h" | |
| #include "partition_alloc/pointers/raw_ptr.h" | |
| #include "src/dawn/common/Math.h" | |
| #include "src/dawn/native/ErrorData.h" | |
| #include "src/dawn/native/vulkan/DeviceVk.h" | |
| #include "src/dawn/native/vulkan/VulkanError.h" | |
| #include "src/dawn/tests/DawnTest.h" | |
| namespace dawn::native::vulkan { | |
| namespace { | |
| class VulkanErrorInjectorTests : public DawnTest { | |
| public: | |
| void SetUp() override { | |
| DawnTest::SetUp(); | |
| DAWN_TEST_UNSUPPORTED_IF(UsesWire()); | |
| mDeviceVk = native::vulkan::ToBackend(native::FromAPI(device.Get())); | |
| } | |
| protected: | |
| raw_ptr<native::vulkan::Device> mDeviceVk; | |
| }; | |
| TEST_P(VulkanErrorInjectorTests, InjectErrorOnCreateBuffer) { | |
| VkBufferCreateInfo createInfo = {}; | |
| createInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; | |
| createInfo.pNext = nullptr; | |
| createInfo.size = 16; | |
| createInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; | |
| // Check that making a buffer works. | |
| { | |
| VkBuffer buffer = VK_NULL_HANDLE; | |
| EXPECT_EQ( | |
| mDeviceVk->fn.CreateBuffer(mDeviceVk->GetVkDevice(), &createInfo, nullptr, &*buffer), | |
| VK_SUCCESS); | |
| mDeviceVk->fn.DestroyBuffer(mDeviceVk->GetVkDevice(), buffer, nullptr); | |
| } | |
| auto CreateTestBuffer = [&]() -> bool { | |
| VkBuffer buffer = VK_NULL_HANDLE; | |
| MaybeError err = CheckVkSuccess( | |
| mDeviceVk->fn.CreateBuffer(mDeviceVk->GetVkDevice(), &createInfo, nullptr, &*buffer), | |
| "vkCreateBuffer"); | |
| if (err.IsError()) { | |
| // The handle should never be written to, even for mock failures. | |
| EXPECT_EQ(buffer, VK_NULL_HANDLE); | |
| err.AcquireError(); | |
| return false; | |
| } | |
| EXPECT_NE(buffer, VK_NULL_HANDLE); | |
| // We never use the buffer, only test mocking errors on creation. Cleanup now. | |
| mDeviceVk->fn.DestroyBuffer(mDeviceVk->GetVkDevice(), buffer, nullptr); | |
| return true; | |
| }; | |
| // Check that making a buffer inside CheckVkSuccess works. | |
| { | |
| EXPECT_TRUE(CreateTestBuffer()); | |
| // The error injector call count should be empty | |
| EXPECT_EQ(AcquireErrorInjectorCallCount(), 0u); | |
| } | |
| // Test error injection works. | |
| EnableErrorInjector(); | |
| { | |
| EXPECT_TRUE(CreateTestBuffer()); | |
| EXPECT_TRUE(CreateTestBuffer()); | |
| // The error injector call count should be two. | |
| EXPECT_EQ(AcquireErrorInjectorCallCount(), 2u); | |
| // Inject an error at index 0. The first should fail, the second succeed. | |
| { | |
| InjectErrorAt(0u); | |
| EXPECT_FALSE(CreateTestBuffer()); | |
| EXPECT_TRUE(CreateTestBuffer()); | |
| ClearErrorInjector(); | |
| } | |
| // Inject an error at index 1. The second should fail, the first succeed. | |
| { | |
| InjectErrorAt(1u); | |
| EXPECT_TRUE(CreateTestBuffer()); | |
| EXPECT_FALSE(CreateTestBuffer()); | |
| ClearErrorInjector(); | |
| } | |
| // Inject an error and then clear the injector. Calls should be successful. | |
| { | |
| InjectErrorAt(0u); | |
| DisableErrorInjector(); | |
| EXPECT_TRUE(CreateTestBuffer()); | |
| EXPECT_TRUE(CreateTestBuffer()); | |
| ClearErrorInjector(); | |
| } | |
| } | |
| } | |
| DAWN_INSTANTIATE_TEST(VulkanErrorInjectorTests, VulkanBackend()); | |
| } // anonymous namespace | |
| } // namespace dawn::native::vulkan |