| // 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 "dawn/tests/unittests/wire/WireTest.h" |
| |
| #include "dawn/dawn_proc.h" |
| #include "dawn/utils/TerribleCommandBuffer.h" |
| #include "dawn/wire/WireClient.h" |
| #include "dawn/wire/WireServer.h" |
| |
| using testing::_; |
| using testing::AnyNumber; |
| using testing::Exactly; |
| using testing::Mock; |
| using testing::Return; |
| |
| WireTest::WireTest() {} |
| |
| WireTest::~WireTest() {} |
| |
| dawn::wire::client::MemoryTransferService* WireTest::GetClientMemoryTransferService() { |
| return nullptr; |
| } |
| |
| dawn::wire::server::MemoryTransferService* WireTest::GetServerMemoryTransferService() { |
| return nullptr; |
| } |
| |
| void WireTest::SetUp() { |
| DawnProcTable mockProcs; |
| api.GetProcTable(&mockProcs); |
| WGPUDevice mockDevice = api.GetNewDevice(); |
| |
| // This SetCallback call cannot be ignored because it is done as soon as we start the server |
| EXPECT_CALL(api, OnDeviceSetUncapturedErrorCallback(_, _, _)).Times(Exactly(1)); |
| EXPECT_CALL(api, OnDeviceSetLoggingCallback(_, _, _)).Times(Exactly(1)); |
| EXPECT_CALL(api, OnDeviceSetDeviceLostCallback(_, _, _)).Times(Exactly(1)); |
| SetupIgnoredCallExpectations(); |
| |
| mS2cBuf = std::make_unique<dawn::utils::TerribleCommandBuffer>(); |
| mC2sBuf = std::make_unique<dawn::utils::TerribleCommandBuffer>(mWireServer.get()); |
| |
| dawn::wire::WireServerDescriptor serverDesc = {}; |
| serverDesc.procs = &mockProcs; |
| serverDesc.serializer = mS2cBuf.get(); |
| serverDesc.memoryTransferService = GetServerMemoryTransferService(); |
| |
| mWireServer.reset(new dawn::wire::WireServer(serverDesc)); |
| mC2sBuf->SetHandler(mWireServer.get()); |
| |
| dawn::wire::WireClientDescriptor clientDesc = {}; |
| clientDesc.serializer = mC2sBuf.get(); |
| clientDesc.memoryTransferService = GetClientMemoryTransferService(); |
| |
| mWireClient.reset(new dawn::wire::WireClient(clientDesc)); |
| mS2cBuf->SetHandler(mWireClient.get()); |
| |
| dawnProcSetProcs(&dawn::wire::client::GetProcs()); |
| |
| auto deviceReservation = mWireClient->ReserveDevice(); |
| EXPECT_CALL(api, DeviceReference(mockDevice)); |
| mWireServer->InjectDevice(mockDevice, deviceReservation.id, deviceReservation.generation); |
| |
| device = deviceReservation.device; |
| apiDevice = mockDevice; |
| |
| // The GetQueue is done on WireClient startup so we expect it now. |
| queue = wgpuDeviceGetQueue(device); |
| apiQueue = api.GetNewQueue(); |
| EXPECT_CALL(api, DeviceGetQueue(apiDevice)).WillOnce(Return(apiQueue)); |
| FlushClient(); |
| } |
| |
| void WireTest::TearDown() { |
| dawnProcSetProcs(nullptr); |
| |
| // Derived classes should call the base TearDown() first. The client must |
| // be reset before any mocks are deleted. |
| // Incomplete client callbacks will be called on deletion, so the mocks |
| // cannot be null. |
| api.IgnoreAllReleaseCalls(); |
| mWireClient = nullptr; |
| |
| if (mWireServer && apiDevice) { |
| // These are called on server destruction to clear the callbacks. They must not be |
| // called after the server is destroyed. |
| EXPECT_CALL(api, OnDeviceSetUncapturedErrorCallback(apiDevice, nullptr, nullptr)) |
| .Times(Exactly(1)); |
| EXPECT_CALL(api, OnDeviceSetLoggingCallback(apiDevice, nullptr, nullptr)).Times(Exactly(1)); |
| EXPECT_CALL(api, OnDeviceSetDeviceLostCallback(apiDevice, nullptr, nullptr)) |
| .Times(Exactly(1)); |
| } |
| mWireServer = nullptr; |
| } |
| |
| // This should be called if |apiDevice| is no longer exists on the wire. |
| // This signals that expectations in |TearDowb| shouldn't be added. |
| void WireTest::DefaultApiDeviceWasReleased() { |
| apiDevice = nullptr; |
| } |
| |
| void WireTest::FlushClient(bool success) { |
| ASSERT_EQ(mC2sBuf->Flush(), success); |
| |
| Mock::VerifyAndClearExpectations(&api); |
| SetupIgnoredCallExpectations(); |
| } |
| |
| void WireTest::FlushServer(bool success) { |
| ASSERT_EQ(mS2cBuf->Flush(), success); |
| } |
| |
| dawn::wire::WireServer* WireTest::GetWireServer() { |
| return mWireServer.get(); |
| } |
| |
| dawn::wire::WireClient* WireTest::GetWireClient() { |
| return mWireClient.get(); |
| } |
| |
| void WireTest::DeleteServer() { |
| EXPECT_CALL(api, QueueRelease(apiQueue)).Times(1); |
| EXPECT_CALL(api, DeviceRelease(apiDevice)).Times(1); |
| |
| if (mWireServer) { |
| // These are called on server destruction to clear the callbacks. They must not be |
| // called after the server is destroyed. |
| EXPECT_CALL(api, OnDeviceSetUncapturedErrorCallback(apiDevice, nullptr, nullptr)) |
| .Times(Exactly(1)); |
| EXPECT_CALL(api, OnDeviceSetLoggingCallback(apiDevice, nullptr, nullptr)).Times(Exactly(1)); |
| EXPECT_CALL(api, OnDeviceSetDeviceLostCallback(apiDevice, nullptr, nullptr)) |
| .Times(Exactly(1)); |
| } |
| mWireServer = nullptr; |
| } |
| |
| void WireTest::DeleteClient() { |
| mWireClient = nullptr; |
| } |
| |
| void WireTest::SetupIgnoredCallExpectations() { |
| EXPECT_CALL(api, InstanceProcessEvents(_)).Times(AnyNumber()); |
| EXPECT_CALL(api, DeviceTick(_)).Times(AnyNumber()); |
| } |