| // 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/wire/WireTest.h" |
| |
| using namespace testing; |
| using namespace dawn_wire; |
| |
| namespace { |
| |
| // Mock classes to add expectations on the wire calling callbacks |
| class MockBufferMapReadCallback { |
| public: |
| MOCK_METHOD(void, |
| Call, |
| (WGPUBufferMapAsyncStatus status, |
| const uint32_t* ptr, |
| uint64_t dataLength, |
| void* userdata)); |
| }; |
| |
| std::unique_ptr<StrictMock<MockBufferMapReadCallback>> mockBufferMapReadCallback; |
| void ToMockBufferMapReadCallback(WGPUBufferMapAsyncStatus status, |
| const void* ptr, |
| uint64_t dataLength, |
| void* userdata) { |
| // Assume the data is uint32_t to make writing matchers easier |
| mockBufferMapReadCallback->Call(status, static_cast<const uint32_t*>(ptr), dataLength, |
| userdata); |
| } |
| |
| class MockBufferMapWriteCallback { |
| public: |
| MOCK_METHOD( |
| void, |
| Call, |
| (WGPUBufferMapAsyncStatus status, uint32_t* ptr, uint64_t dataLength, void* userdata)); |
| }; |
| |
| std::unique_ptr<StrictMock<MockBufferMapWriteCallback>> mockBufferMapWriteCallback; |
| uint32_t* lastMapWritePointer = nullptr; |
| void ToMockBufferMapWriteCallback(WGPUBufferMapAsyncStatus status, |
| void* ptr, |
| uint64_t dataLength, |
| void* userdata) { |
| // Assume the data is uint32_t to make writing matchers easier |
| lastMapWritePointer = static_cast<uint32_t*>(ptr); |
| mockBufferMapWriteCallback->Call(status, lastMapWritePointer, dataLength, userdata); |
| } |
| |
| class MockBufferCreateMappedCallback { |
| public: |
| MOCK_METHOD(void, |
| Call, |
| (WGPUBufferMapAsyncStatus status, |
| WGPUBuffer buffer, |
| uint32_t* ptr, |
| uint64_t dataLength, |
| void* userdata)); |
| }; |
| |
| } // anonymous namespace |
| |
| class WireBufferMappingTests : public WireTest { |
| public: |
| WireBufferMappingTests() { |
| } |
| ~WireBufferMappingTests() override = default; |
| |
| void SetUp() override { |
| WireTest::SetUp(); |
| |
| mockBufferMapReadCallback = std::make_unique<StrictMock<MockBufferMapReadCallback>>(); |
| mockBufferMapWriteCallback = std::make_unique<StrictMock<MockBufferMapWriteCallback>>(); |
| |
| WGPUBufferDescriptor descriptor = {}; |
| descriptor.size = kBufferSize; |
| |
| apiBuffer = api.GetNewBuffer(); |
| buffer = wgpuDeviceCreateBuffer(device, &descriptor); |
| |
| EXPECT_CALL(api, DeviceCreateBuffer(apiDevice, _)) |
| .WillOnce(Return(apiBuffer)) |
| .RetiresOnSaturation(); |
| FlushClient(); |
| } |
| |
| void TearDown() override { |
| WireTest::TearDown(); |
| |
| // Delete mocks so that expectations are checked |
| mockBufferMapReadCallback = nullptr; |
| mockBufferMapWriteCallback = nullptr; |
| } |
| |
| void FlushServer() { |
| WireTest::FlushServer(); |
| |
| Mock::VerifyAndClearExpectations(&mockBufferMapReadCallback); |
| Mock::VerifyAndClearExpectations(&mockBufferMapWriteCallback); |
| } |
| |
| protected: |
| static constexpr uint64_t kBufferSize = sizeof(uint32_t); |
| // A successfully created buffer |
| WGPUBuffer buffer; |
| WGPUBuffer apiBuffer; |
| }; |
| |
| // MapRead-specific tests |
| |
| // Check mapping for reading a succesfully created buffer |
| TEST_F(WireBufferMappingTests, MappingForReadSuccessBuffer) { |
| wgpuBufferMapReadAsync(buffer, ToMockBufferMapReadCallback, nullptr); |
| |
| uint32_t bufferContent = 31337; |
| EXPECT_CALL(api, OnBufferMapReadAsyncCallback(apiBuffer, _, _)) |
| .WillOnce(InvokeWithoutArgs([&]() { |
| api.CallMapReadCallback(apiBuffer, WGPUBufferMapAsyncStatus_Success, &bufferContent, |
| kBufferSize); |
| })); |
| |
| FlushClient(); |
| |
| EXPECT_CALL(*mockBufferMapReadCallback, |
| Call(WGPUBufferMapAsyncStatus_Success, Pointee(Eq(bufferContent)), kBufferSize, _)) |
| .Times(1); |
| |
| FlushServer(); |
| |
| wgpuBufferUnmap(buffer); |
| EXPECT_CALL(api, BufferUnmap(apiBuffer)).Times(1); |
| |
| FlushClient(); |
| } |
| |
| // Check that things work correctly when a validation error happens when mapping the buffer for |
| // reading |
| TEST_F(WireBufferMappingTests, ErrorWhileMappingForRead) { |
| wgpuBufferMapReadAsync(buffer, ToMockBufferMapReadCallback, nullptr); |
| |
| EXPECT_CALL(api, OnBufferMapReadAsyncCallback(apiBuffer, _, _)) |
| .WillOnce(InvokeWithoutArgs([&]() { |
| api.CallMapReadCallback(apiBuffer, WGPUBufferMapAsyncStatus_Error, nullptr, 0); |
| })); |
| |
| FlushClient(); |
| |
| EXPECT_CALL(*mockBufferMapReadCallback, Call(WGPUBufferMapAsyncStatus_Error, nullptr, 0, _)) |
| .Times(1); |
| |
| FlushServer(); |
| } |
| |
| // Check that the map read callback is called with UNKNOWN when the buffer is destroyed before the |
| // request is finished |
| TEST_F(WireBufferMappingTests, DestroyBeforeReadRequestEnd) { |
| wgpuBufferMapReadAsync(buffer, ToMockBufferMapReadCallback, nullptr); |
| |
| // Return success |
| EXPECT_CALL(api, OnBufferMapReadAsyncCallback(apiBuffer, _, _)) |
| .WillOnce(InvokeWithoutArgs([&]() { |
| api.CallMapReadCallback(apiBuffer, WGPUBufferMapAsyncStatus_Success, nullptr, 0); |
| })); |
| |
| // Destroy before the client gets the success, so the callback is called with unknown. |
| EXPECT_CALL(*mockBufferMapReadCallback, Call(WGPUBufferMapAsyncStatus_Unknown, nullptr, 0, _)) |
| .Times(1); |
| wgpuBufferRelease(buffer); |
| EXPECT_CALL(api, BufferRelease(apiBuffer)); |
| |
| FlushClient(); |
| FlushServer(); |
| } |
| |
| // Check the map read callback is called with UNKNOWN when the map request would have worked, but |
| // Unmap was called |
| TEST_F(WireBufferMappingTests, UnmapCalledTooEarlyForRead) { |
| wgpuBufferMapReadAsync(buffer, ToMockBufferMapReadCallback, nullptr); |
| |
| uint32_t bufferContent = 31337; |
| EXPECT_CALL(api, OnBufferMapReadAsyncCallback(apiBuffer, _, _)) |
| .WillOnce(InvokeWithoutArgs([&]() { |
| api.CallMapReadCallback(apiBuffer, WGPUBufferMapAsyncStatus_Success, &bufferContent, |
| kBufferSize); |
| })); |
| |
| FlushClient(); |
| |
| // Oh no! We are calling Unmap too early! |
| EXPECT_CALL(*mockBufferMapReadCallback, Call(WGPUBufferMapAsyncStatus_Unknown, nullptr, 0, _)) |
| .Times(1); |
| wgpuBufferUnmap(buffer); |
| |
| // The callback shouldn't get called, even when the request succeeded on the server side |
| FlushServer(); |
| } |
| |
| // Check that an error map read callback gets nullptr while a buffer is already mapped |
| TEST_F(WireBufferMappingTests, MappingForReadingErrorWhileAlreadyMappedGetsNullptr) { |
| // Successful map |
| wgpuBufferMapReadAsync(buffer, ToMockBufferMapReadCallback, nullptr); |
| |
| uint32_t bufferContent = 31337; |
| EXPECT_CALL(api, OnBufferMapReadAsyncCallback(apiBuffer, _, _)) |
| .WillOnce(InvokeWithoutArgs([&]() { |
| api.CallMapReadCallback(apiBuffer, WGPUBufferMapAsyncStatus_Success, &bufferContent, |
| kBufferSize); |
| })) |
| .RetiresOnSaturation(); |
| |
| FlushClient(); |
| |
| EXPECT_CALL(*mockBufferMapReadCallback, |
| Call(WGPUBufferMapAsyncStatus_Success, Pointee(Eq(bufferContent)), kBufferSize, _)) |
| .Times(1); |
| |
| FlushServer(); |
| |
| // Map failure while the buffer is already mapped |
| wgpuBufferMapReadAsync(buffer, ToMockBufferMapReadCallback, nullptr); |
| EXPECT_CALL(api, OnBufferMapReadAsyncCallback(apiBuffer, _, _)) |
| .WillOnce(InvokeWithoutArgs([&]() { |
| api.CallMapReadCallback(apiBuffer, WGPUBufferMapAsyncStatus_Error, nullptr, 0); |
| })); |
| |
| FlushClient(); |
| |
| EXPECT_CALL(*mockBufferMapReadCallback, Call(WGPUBufferMapAsyncStatus_Error, nullptr, 0, _)) |
| .Times(1); |
| |
| FlushServer(); |
| } |
| |
| // Test that the MapReadCallback isn't fired twice when unmap() is called inside the callback |
| TEST_F(WireBufferMappingTests, UnmapInsideMapReadCallback) { |
| wgpuBufferMapReadAsync(buffer, ToMockBufferMapReadCallback, nullptr); |
| |
| uint32_t bufferContent = 31337; |
| EXPECT_CALL(api, OnBufferMapReadAsyncCallback(apiBuffer, _, _)) |
| .WillOnce(InvokeWithoutArgs([&]() { |
| api.CallMapReadCallback(apiBuffer, WGPUBufferMapAsyncStatus_Success, &bufferContent, |
| kBufferSize); |
| })); |
| |
| FlushClient(); |
| |
| EXPECT_CALL(*mockBufferMapReadCallback, |
| Call(WGPUBufferMapAsyncStatus_Success, Pointee(Eq(bufferContent)), kBufferSize, _)) |
| .WillOnce(InvokeWithoutArgs([&]() { wgpuBufferUnmap(buffer); })); |
| |
| FlushServer(); |
| |
| EXPECT_CALL(api, BufferUnmap(apiBuffer)).Times(1); |
| |
| FlushClient(); |
| } |
| |
| // Test that the MapReadCallback isn't fired twice the buffer external refcount reaches 0 in the |
| // callback |
| TEST_F(WireBufferMappingTests, DestroyInsideMapReadCallback) { |
| wgpuBufferMapReadAsync(buffer, ToMockBufferMapReadCallback, nullptr); |
| |
| uint32_t bufferContent = 31337; |
| EXPECT_CALL(api, OnBufferMapReadAsyncCallback(apiBuffer, _, _)) |
| .WillOnce(InvokeWithoutArgs([&]() { |
| api.CallMapReadCallback(apiBuffer, WGPUBufferMapAsyncStatus_Success, &bufferContent, |
| kBufferSize); |
| })); |
| |
| FlushClient(); |
| |
| EXPECT_CALL(*mockBufferMapReadCallback, |
| Call(WGPUBufferMapAsyncStatus_Success, Pointee(Eq(bufferContent)), kBufferSize, _)) |
| .WillOnce(InvokeWithoutArgs([&]() { wgpuBufferRelease(buffer); })); |
| |
| FlushServer(); |
| |
| EXPECT_CALL(api, BufferRelease(apiBuffer)); |
| |
| FlushClient(); |
| } |
| |
| // MapWrite-specific tests |
| |
| // Check mapping for writing a succesfully created buffer |
| TEST_F(WireBufferMappingTests, MappingForWriteSuccessBuffer) { |
| wgpuBufferMapWriteAsync(buffer, ToMockBufferMapWriteCallback, nullptr); |
| |
| uint32_t serverBufferContent = 31337; |
| uint32_t updatedContent = 4242; |
| uint32_t zero = 0; |
| |
| EXPECT_CALL(api, OnBufferMapWriteAsyncCallback(apiBuffer, _, _)) |
| .WillOnce(InvokeWithoutArgs([&]() { |
| api.CallMapWriteCallback(apiBuffer, WGPUBufferMapAsyncStatus_Success, |
| &serverBufferContent, kBufferSize); |
| })); |
| |
| FlushClient(); |
| |
| // The map write callback always gets a buffer full of zeroes. |
| EXPECT_CALL(*mockBufferMapWriteCallback, |
| Call(WGPUBufferMapAsyncStatus_Success, Pointee(Eq(zero)), kBufferSize, _)) |
| .Times(1); |
| |
| FlushServer(); |
| |
| // Write something to the mapped pointer |
| *lastMapWritePointer = updatedContent; |
| |
| wgpuBufferUnmap(buffer); |
| EXPECT_CALL(api, BufferUnmap(apiBuffer)).Times(1); |
| |
| FlushClient(); |
| |
| // After the buffer is unmapped, the content of the buffer is updated on the server |
| ASSERT_EQ(serverBufferContent, updatedContent); |
| } |
| |
| // Check that things work correctly when a validation error happens when mapping the buffer for |
| // writing |
| TEST_F(WireBufferMappingTests, ErrorWhileMappingForWrite) { |
| wgpuBufferMapWriteAsync(buffer, ToMockBufferMapWriteCallback, nullptr); |
| |
| EXPECT_CALL(api, OnBufferMapWriteAsyncCallback(apiBuffer, _, _)) |
| .WillOnce(InvokeWithoutArgs([&]() { |
| api.CallMapWriteCallback(apiBuffer, WGPUBufferMapAsyncStatus_Error, nullptr, 0); |
| })); |
| |
| FlushClient(); |
| |
| EXPECT_CALL(*mockBufferMapWriteCallback, Call(WGPUBufferMapAsyncStatus_Error, nullptr, 0, _)) |
| .Times(1); |
| |
| FlushServer(); |
| } |
| |
| // Check that the map write callback is called with UNKNOWN when the buffer is destroyed before the |
| // request is finished |
| TEST_F(WireBufferMappingTests, DestroyBeforeWriteRequestEnd) { |
| wgpuBufferMapWriteAsync(buffer, ToMockBufferMapWriteCallback, nullptr); |
| |
| // Return success |
| EXPECT_CALL(api, OnBufferMapWriteAsyncCallback(apiBuffer, _, _)) |
| .WillOnce(InvokeWithoutArgs([&]() { |
| api.CallMapWriteCallback(apiBuffer, WGPUBufferMapAsyncStatus_Success, nullptr, 0); |
| })); |
| |
| // Destroy before the client gets the success, so the callback is called with unknown. |
| EXPECT_CALL(*mockBufferMapWriteCallback, Call(WGPUBufferMapAsyncStatus_Unknown, nullptr, 0, _)) |
| .Times(1); |
| wgpuBufferRelease(buffer); |
| EXPECT_CALL(api, BufferRelease(apiBuffer)); |
| |
| FlushClient(); |
| FlushServer(); |
| } |
| |
| // Check the map read callback is called with UNKNOWN when the map request would have worked, but |
| // Unmap was called |
| TEST_F(WireBufferMappingTests, UnmapCalledTooEarlyForWrite) { |
| wgpuBufferMapWriteAsync(buffer, ToMockBufferMapWriteCallback, nullptr); |
| |
| uint32_t bufferContent = 31337; |
| EXPECT_CALL(api, OnBufferMapWriteAsyncCallback(apiBuffer, _, _)) |
| .WillOnce(InvokeWithoutArgs([&]() { |
| api.CallMapWriteCallback(apiBuffer, WGPUBufferMapAsyncStatus_Success, &bufferContent, |
| kBufferSize); |
| })); |
| |
| FlushClient(); |
| |
| // Oh no! We are calling Unmap too early! |
| EXPECT_CALL(*mockBufferMapWriteCallback, Call(WGPUBufferMapAsyncStatus_Unknown, nullptr, 0, _)) |
| .Times(1); |
| wgpuBufferUnmap(buffer); |
| |
| // The callback shouldn't get called, even when the request succeeded on the server side |
| FlushServer(); |
| } |
| |
| // Check that an error map read callback gets nullptr while a buffer is already mapped |
| TEST_F(WireBufferMappingTests, MappingForWritingErrorWhileAlreadyMappedGetsNullptr) { |
| // Successful map |
| wgpuBufferMapWriteAsync(buffer, ToMockBufferMapWriteCallback, nullptr); |
| |
| uint32_t bufferContent = 31337; |
| uint32_t zero = 0; |
| EXPECT_CALL(api, OnBufferMapWriteAsyncCallback(apiBuffer, _, _)) |
| .WillOnce(InvokeWithoutArgs([&]() { |
| api.CallMapWriteCallback(apiBuffer, WGPUBufferMapAsyncStatus_Success, &bufferContent, |
| kBufferSize); |
| })) |
| .RetiresOnSaturation(); |
| |
| FlushClient(); |
| |
| EXPECT_CALL(*mockBufferMapWriteCallback, |
| Call(WGPUBufferMapAsyncStatus_Success, Pointee(Eq(zero)), kBufferSize, _)) |
| .Times(1); |
| |
| FlushServer(); |
| |
| // Map failure while the buffer is already mapped |
| wgpuBufferMapWriteAsync(buffer, ToMockBufferMapWriteCallback, nullptr); |
| EXPECT_CALL(api, OnBufferMapWriteAsyncCallback(apiBuffer, _, _)) |
| .WillOnce(InvokeWithoutArgs([&]() { |
| api.CallMapWriteCallback(apiBuffer, WGPUBufferMapAsyncStatus_Error, nullptr, 0); |
| })); |
| |
| FlushClient(); |
| |
| EXPECT_CALL(*mockBufferMapWriteCallback, Call(WGPUBufferMapAsyncStatus_Error, nullptr, 0, _)) |
| .Times(1); |
| |
| FlushServer(); |
| } |
| |
| // Test that the MapWriteCallback isn't fired twice when unmap() is called inside the callback |
| TEST_F(WireBufferMappingTests, UnmapInsideMapWriteCallback) { |
| wgpuBufferMapWriteAsync(buffer, ToMockBufferMapWriteCallback, nullptr); |
| |
| uint32_t bufferContent = 31337; |
| uint32_t zero = 0; |
| EXPECT_CALL(api, OnBufferMapWriteAsyncCallback(apiBuffer, _, _)) |
| .WillOnce(InvokeWithoutArgs([&]() { |
| api.CallMapWriteCallback(apiBuffer, WGPUBufferMapAsyncStatus_Success, &bufferContent, |
| kBufferSize); |
| })); |
| |
| FlushClient(); |
| |
| EXPECT_CALL(*mockBufferMapWriteCallback, |
| Call(WGPUBufferMapAsyncStatus_Success, Pointee(Eq(zero)), kBufferSize, _)) |
| .WillOnce(InvokeWithoutArgs([&]() { wgpuBufferUnmap(buffer); })); |
| |
| FlushServer(); |
| |
| EXPECT_CALL(api, BufferUnmap(apiBuffer)).Times(1); |
| |
| FlushClient(); |
| } |
| |
| // Test that the MapWriteCallback isn't fired twice the buffer external refcount reaches 0 in the |
| // callback |
| TEST_F(WireBufferMappingTests, DestroyInsideMapWriteCallback) { |
| wgpuBufferMapWriteAsync(buffer, ToMockBufferMapWriteCallback, nullptr); |
| |
| uint32_t bufferContent = 31337; |
| uint32_t zero = 0; |
| EXPECT_CALL(api, OnBufferMapWriteAsyncCallback(apiBuffer, _, _)) |
| .WillOnce(InvokeWithoutArgs([&]() { |
| api.CallMapWriteCallback(apiBuffer, WGPUBufferMapAsyncStatus_Success, &bufferContent, |
| kBufferSize); |
| })); |
| |
| FlushClient(); |
| |
| EXPECT_CALL(*mockBufferMapWriteCallback, |
| Call(WGPUBufferMapAsyncStatus_Success, Pointee(Eq(zero)), kBufferSize, _)) |
| .WillOnce(InvokeWithoutArgs([&]() { wgpuBufferRelease(buffer); })); |
| |
| FlushServer(); |
| |
| EXPECT_CALL(api, BufferRelease(apiBuffer)); |
| |
| FlushClient(); |
| } |
| |
| // Test successful CreateBufferMapped |
| TEST_F(WireBufferMappingTests, CreateBufferMappedSuccess) { |
| WGPUBufferDescriptor descriptor = {}; |
| descriptor.size = 4; |
| |
| WGPUBuffer apiBuffer = api.GetNewBuffer(); |
| WGPUCreateBufferMappedResult apiResult; |
| uint32_t apiBufferData = 1234; |
| apiResult.buffer = apiBuffer; |
| apiResult.data = reinterpret_cast<uint8_t*>(&apiBufferData); |
| apiResult.dataLength = 4; |
| |
| WGPUCreateBufferMappedResult result = wgpuDeviceCreateBufferMapped(device, &descriptor); |
| |
| EXPECT_CALL(api, DeviceCreateBufferMapped(apiDevice, _)) |
| .WillOnce(Return(apiResult)) |
| .RetiresOnSaturation(); |
| |
| FlushClient(); |
| |
| wgpuBufferUnmap(result.buffer); |
| EXPECT_CALL(api, BufferUnmap(apiBuffer)).Times(1); |
| |
| FlushClient(); |
| } |
| |
| // Test that releasing after CreateBufferMapped does not call Unmap |
| TEST_F(WireBufferMappingTests, ReleaseAfterCreateBufferMapped) { |
| WGPUBufferDescriptor descriptor = {}; |
| descriptor.size = 4; |
| |
| WGPUBuffer apiBuffer = api.GetNewBuffer(); |
| WGPUCreateBufferMappedResult apiResult; |
| uint32_t apiBufferData = 1234; |
| apiResult.buffer = apiBuffer; |
| apiResult.data = reinterpret_cast<uint8_t*>(&apiBufferData); |
| apiResult.dataLength = 4; |
| |
| WGPUCreateBufferMappedResult result = wgpuDeviceCreateBufferMapped(device, &descriptor); |
| |
| EXPECT_CALL(api, DeviceCreateBufferMapped(apiDevice, _)) |
| .WillOnce(Return(apiResult)) |
| .RetiresOnSaturation(); |
| |
| FlushClient(); |
| |
| wgpuBufferRelease(result.buffer); |
| EXPECT_CALL(api, BufferRelease(apiBuffer)).Times(1); |
| |
| FlushClient(); |
| } |
| |
| // Test that it is valid to map a buffer after CreateBufferMapped and Unmap |
| TEST_F(WireBufferMappingTests, CreateBufferMappedThenMapSuccess) { |
| WGPUBufferDescriptor descriptor = {}; |
| descriptor.size = 4; |
| |
| WGPUBuffer apiBuffer = api.GetNewBuffer(); |
| WGPUCreateBufferMappedResult apiResult; |
| uint32_t apiBufferData = 9863; |
| apiResult.buffer = apiBuffer; |
| apiResult.data = reinterpret_cast<uint8_t*>(&apiBufferData); |
| apiResult.dataLength = 4; |
| |
| WGPUCreateBufferMappedResult result = wgpuDeviceCreateBufferMapped(device, &descriptor); |
| |
| EXPECT_CALL(api, DeviceCreateBufferMapped(apiDevice, _)) |
| .WillOnce(Return(apiResult)) |
| .RetiresOnSaturation(); |
| |
| FlushClient(); |
| |
| wgpuBufferUnmap(result.buffer); |
| EXPECT_CALL(api, BufferUnmap(apiBuffer)).Times(1); |
| |
| FlushClient(); |
| |
| wgpuBufferMapWriteAsync(result.buffer, ToMockBufferMapWriteCallback, nullptr); |
| |
| uint32_t zero = 0; |
| EXPECT_CALL(api, OnBufferMapWriteAsyncCallback(apiBuffer, _, _)) |
| .WillOnce(InvokeWithoutArgs([&]() { |
| api.CallMapWriteCallback(apiBuffer, WGPUBufferMapAsyncStatus_Success, &apiBufferData, |
| kBufferSize); |
| })); |
| |
| FlushClient(); |
| |
| EXPECT_CALL(*mockBufferMapWriteCallback, |
| Call(WGPUBufferMapAsyncStatus_Success, Pointee(Eq(zero)), kBufferSize, _)) |
| .Times(1); |
| |
| FlushServer(); |
| } |
| |
| // Test that it is invalid to map a buffer after CreateBufferMapped before Unmap |
| TEST_F(WireBufferMappingTests, CreateBufferMappedThenMapFailure) { |
| WGPUBufferDescriptor descriptor = {}; |
| descriptor.size = 4; |
| |
| WGPUBuffer apiBuffer = api.GetNewBuffer(); |
| WGPUCreateBufferMappedResult apiResult; |
| uint32_t apiBufferData = 9863; |
| apiResult.buffer = apiBuffer; |
| apiResult.data = reinterpret_cast<uint8_t*>(&apiBufferData); |
| apiResult.dataLength = 4; |
| |
| WGPUCreateBufferMappedResult result = wgpuDeviceCreateBufferMapped(device, &descriptor); |
| |
| EXPECT_CALL(api, DeviceCreateBufferMapped(apiDevice, _)) |
| .WillOnce(Return(apiResult)) |
| .RetiresOnSaturation(); |
| |
| FlushClient(); |
| |
| wgpuBufferMapWriteAsync(result.buffer, ToMockBufferMapWriteCallback, nullptr); |
| |
| EXPECT_CALL(api, OnBufferMapWriteAsyncCallback(apiBuffer, _, _)) |
| .WillOnce(InvokeWithoutArgs([&]() { |
| api.CallMapWriteCallback(apiBuffer, WGPUBufferMapAsyncStatus_Error, nullptr, 0); |
| })); |
| |
| FlushClient(); |
| |
| EXPECT_CALL(*mockBufferMapWriteCallback, Call(WGPUBufferMapAsyncStatus_Error, nullptr, 0, _)) |
| .Times(1); |
| |
| FlushServer(); |
| |
| wgpuBufferUnmap(result.buffer); |
| EXPECT_CALL(api, BufferUnmap(apiBuffer)).Times(1); |
| |
| FlushClient(); |
| } |
| |