// Copyright 2021 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 <gtest/gtest.h>

#include "dawn_native/Toggles.h"
#include "mocks/BindGroupLayoutMock.h"
#include "mocks/BindGroupMock.h"
#include "mocks/BufferMock.h"
#include "mocks/CommandBufferMock.h"
#include "mocks/ComputePipelineMock.h"
#include "mocks/DeviceMock.h"
#include "mocks/ExternalTextureMock.h"
#include "mocks/PipelineLayoutMock.h"
#include "mocks/QuerySetMock.h"
#include "mocks/RenderPipelineMock.h"
#include "mocks/SamplerMock.h"
#include "mocks/ShaderModuleMock.h"
#include "mocks/SwapChainMock.h"
#include "mocks/TextureMock.h"
#include "tests/DawnNativeTest.h"
#include "utils/ComboRenderPipelineDescriptor.h"

namespace dawn_native { namespace {

    using ::testing::_;
    using ::testing::ByMove;
    using ::testing::InSequence;
    using ::testing::Return;
    using ::testing::Test;

    class DestroyObjectTests : public Test {
      public:
        DestroyObjectTests() : Test() {
            // Skipping validation on descriptors as coverage for validation is already present.
            mDevice.SetToggle(Toggle::SkipValidation, true);
        }

        Ref<TextureMock> GetTexture() {
            if (mTexture != nullptr) {
                return mTexture;
            }
            mTexture =
                AcquireRef(new TextureMock(&mDevice, TextureBase::TextureState::OwnedInternal));
            EXPECT_CALL(*mTexture.Get(), DestroyImpl).Times(1);
            return mTexture;
        }

        Ref<PipelineLayoutMock> GetPipelineLayout() {
            if (mPipelineLayout != nullptr) {
                return mPipelineLayout;
            }
            mPipelineLayout = AcquireRef(new PipelineLayoutMock(&mDevice));
            EXPECT_CALL(*mPipelineLayout.Get(), DestroyImpl).Times(1);
            return mPipelineLayout;
        }

        Ref<ShaderModuleMock> GetVertexShaderModule() {
            if (mVsModule != nullptr) {
                return mVsModule;
            }
            DAWN_TRY_ASSIGN_WITH_CLEANUP(
                mVsModule, ShaderModuleMock::Create(&mDevice, R"(
            [[stage(vertex)]] fn main() -> [[builtin(position)]] vec4<f32> {
                return vec4<f32>(0.0, 0.0, 0.0, 1.0);
            })"),
                { ASSERT(false); }, mVsModule);
            EXPECT_CALL(*mVsModule.Get(), DestroyImpl).Times(1);
            return mVsModule;
        }

        Ref<ShaderModuleMock> GetComputeShaderModule() {
            if (mCsModule != nullptr) {
                return mCsModule;
            }
            DAWN_TRY_ASSIGN_WITH_CLEANUP(
                mCsModule, ShaderModuleMock::Create(&mDevice, R"(
            [[stage(compute), workgroup_size(1)]] fn main() {
            })"),
                { ASSERT(false); }, mCsModule);
            EXPECT_CALL(*mCsModule.Get(), DestroyImpl).Times(1);
            return mCsModule;
        }

      protected:
        DeviceMock mDevice;

        // The following lazy-initialized objects are used to facilitate creation of dependent
        // objects under test.
        Ref<TextureMock> mTexture;
        Ref<PipelineLayoutMock> mPipelineLayout;
        Ref<ShaderModuleMock> mVsModule;
        Ref<ShaderModuleMock> mCsModule;
    };

    TEST_F(DestroyObjectTests, BindGroupExplicit) {
        BindGroupMock bindGroupMock(&mDevice);
        EXPECT_CALL(bindGroupMock, DestroyImpl).Times(1);

        EXPECT_TRUE(bindGroupMock.IsAlive());
        bindGroupMock.Destroy();
        EXPECT_FALSE(bindGroupMock.IsAlive());
    }

    // If the reference count on API objects reach 0, they should delete themselves. Note that GTest
    // will also complain if there is a memory leak.
    TEST_F(DestroyObjectTests, BindGroupImplicit) {
        BindGroupMock* bindGroupMock = new BindGroupMock(&mDevice);
        EXPECT_CALL(*bindGroupMock, DestroyImpl).Times(1);
        {
            BindGroupDescriptor desc = {};
            Ref<BindGroupBase> bindGroup;
            EXPECT_CALL(mDevice, CreateBindGroupImpl)
                .WillOnce(Return(ByMove(AcquireRef(bindGroupMock))));
            DAWN_ASSERT_AND_ASSIGN(bindGroup, mDevice.CreateBindGroup(&desc));

            EXPECT_TRUE(bindGroup->IsAlive());
        }
    }

    TEST_F(DestroyObjectTests, BindGroupLayoutExplicit) {
        BindGroupLayoutMock bindGroupLayoutMock(&mDevice);
        EXPECT_CALL(bindGroupLayoutMock, DestroyImpl).Times(1);

        EXPECT_TRUE(bindGroupLayoutMock.IsAlive());
        bindGroupLayoutMock.Destroy();
        EXPECT_FALSE(bindGroupLayoutMock.IsAlive());
    }

    // If the reference count on API objects reach 0, they should delete themselves. Note that GTest
    // will also complain if there is a memory leak.
    TEST_F(DestroyObjectTests, BindGroupLayoutImplicit) {
        BindGroupLayoutMock* bindGroupLayoutMock = new BindGroupLayoutMock(&mDevice);
        EXPECT_CALL(*bindGroupLayoutMock, DestroyImpl).Times(1);
        {
            BindGroupLayoutDescriptor desc = {};
            Ref<BindGroupLayoutBase> bindGroupLayout;
            EXPECT_CALL(mDevice, CreateBindGroupLayoutImpl)
                .WillOnce(Return(ByMove(AcquireRef(bindGroupLayoutMock))));
            DAWN_ASSERT_AND_ASSIGN(bindGroupLayout, mDevice.CreateBindGroupLayout(&desc));

            EXPECT_TRUE(bindGroupLayout->IsAlive());
            EXPECT_TRUE(bindGroupLayout->IsCachedReference());
        }
    }

    TEST_F(DestroyObjectTests, BufferExplicit) {
        {
            BufferMock bufferMock(&mDevice, BufferBase::BufferState::Unmapped);
            EXPECT_CALL(bufferMock, DestroyImpl).Times(1);

            EXPECT_TRUE(bufferMock.IsAlive());
            bufferMock.Destroy();
            EXPECT_FALSE(bufferMock.IsAlive());
        }
        {
            BufferMock bufferMock(&mDevice, BufferBase::BufferState::Mapped);
            {
                InSequence seq;
                EXPECT_CALL(bufferMock, DestroyImpl).Times(1);
                EXPECT_CALL(bufferMock, UnmapImpl).Times(1);
            }

            EXPECT_TRUE(bufferMock.IsAlive());
            bufferMock.Destroy();
            EXPECT_FALSE(bufferMock.IsAlive());
        }
    }

    // If the reference count on API objects reach 0, they should delete themselves. Note that GTest
    // will also complain if there is a memory leak.
    TEST_F(DestroyObjectTests, BufferImplicit) {
        {
            BufferMock* bufferMock = new BufferMock(&mDevice, BufferBase::BufferState::Unmapped);
            EXPECT_CALL(*bufferMock, DestroyImpl).Times(1);
            {
                BufferDescriptor desc = {};
                Ref<BufferBase> buffer;
                EXPECT_CALL(mDevice, CreateBufferImpl)
                    .WillOnce(Return(ByMove(AcquireRef(bufferMock))));
                DAWN_ASSERT_AND_ASSIGN(buffer, mDevice.CreateBuffer(&desc));

                EXPECT_TRUE(buffer->IsAlive());
            }
        }
        {
            BufferMock* bufferMock = new BufferMock(&mDevice, BufferBase::BufferState::Mapped);
            {
                InSequence seq;
                EXPECT_CALL(*bufferMock, DestroyImpl).Times(1);
                EXPECT_CALL(*bufferMock, UnmapImpl).Times(1);
            }
            {
                BufferDescriptor desc = {};
                Ref<BufferBase> buffer;
                EXPECT_CALL(mDevice, CreateBufferImpl)
                    .WillOnce(Return(ByMove(AcquireRef(bufferMock))));
                DAWN_ASSERT_AND_ASSIGN(buffer, mDevice.CreateBuffer(&desc));

                EXPECT_TRUE(buffer->IsAlive());
            }
        }
    }

    TEST_F(DestroyObjectTests, CommandBufferExplicit) {
        CommandBufferMock commandBufferMock(&mDevice);
        EXPECT_CALL(commandBufferMock, DestroyImpl).Times(1);

        EXPECT_TRUE(commandBufferMock.IsAlive());
        commandBufferMock.Destroy();
        EXPECT_FALSE(commandBufferMock.IsAlive());
    }

    // If the reference count on API objects reach 0, they should delete themselves. Note that GTest
    // will also complain if there is a memory leak.
    TEST_F(DestroyObjectTests, CommandBufferImplicit) {
        CommandBufferMock* commandBufferMock = new CommandBufferMock(&mDevice);
        EXPECT_CALL(*commandBufferMock, DestroyImpl).Times(1);
        {
            CommandBufferDescriptor desc = {};
            Ref<CommandBufferBase> commandBuffer;
            EXPECT_CALL(mDevice, CreateCommandBuffer)
                .WillOnce(Return(ByMove(AcquireRef(commandBufferMock))));
            DAWN_ASSERT_AND_ASSIGN(commandBuffer, mDevice.CreateCommandBuffer(nullptr, &desc));

            EXPECT_TRUE(commandBuffer->IsAlive());
        }
    }

    TEST_F(DestroyObjectTests, ComputePipelineExplicit) {
        ComputePipelineMock computePipelineMock(&mDevice);
        EXPECT_CALL(computePipelineMock, DestroyImpl).Times(1);

        EXPECT_TRUE(computePipelineMock.IsAlive());
        computePipelineMock.Destroy();
        EXPECT_FALSE(computePipelineMock.IsAlive());
    }

    // If the reference count on API objects reach 0, they should delete themselves. Note that GTest
    // will also complain if there is a memory leak.
    TEST_F(DestroyObjectTests, ComputePipelineImplicit) {
        // ComputePipelines usually set their hash values at construction, but the mock does not, so
        // we set it here.
        constexpr size_t hash = 0x12345;
        ComputePipelineMock* computePipelineMock = new ComputePipelineMock(&mDevice);
        computePipelineMock->SetContentHash(hash);
        ON_CALL(*computePipelineMock, ComputeContentHash).WillByDefault(Return(hash));

        // Compute pipelines are initialized during their creation via the device.
        EXPECT_CALL(*computePipelineMock, Initialize).Times(1);
        EXPECT_CALL(*computePipelineMock, DestroyImpl).Times(1);

        {
            ComputePipelineDescriptor desc = {};
            desc.layout = GetPipelineLayout().Get();
            desc.compute.module = GetComputeShaderModule().Get();

            Ref<ComputePipelineBase> computePipeline;
            EXPECT_CALL(mDevice, CreateUninitializedComputePipelineImpl)
                .WillOnce(Return(ByMove(AcquireRef(computePipelineMock))));
            DAWN_ASSERT_AND_ASSIGN(computePipeline, mDevice.CreateComputePipeline(&desc));

            EXPECT_TRUE(computePipeline->IsAlive());
            EXPECT_TRUE(computePipeline->IsCachedReference());
        }
    }

    TEST_F(DestroyObjectTests, ExternalTextureExplicit) {
        ExternalTextureMock externalTextureMock(&mDevice);
        EXPECT_CALL(externalTextureMock, DestroyImpl).Times(1);

        EXPECT_TRUE(externalTextureMock.IsAlive());
        externalTextureMock.Destroy();
        EXPECT_FALSE(externalTextureMock.IsAlive());
    }

    // We can use an actual ExternalTexture object to test the implicit case.
    TEST_F(DestroyObjectTests, ExternalTextureImplicit) {
        ExternalTextureDescriptor desc = {};
        Ref<ExternalTextureBase> externalTexture;
        DAWN_ASSERT_AND_ASSIGN(externalTexture, mDevice.CreateExternalTexture(&desc));

        EXPECT_TRUE(externalTexture->IsAlive());
    }

    TEST_F(DestroyObjectTests, PipelineLayoutExplicit) {
        PipelineLayoutMock pipelineLayoutMock(&mDevice);
        EXPECT_CALL(pipelineLayoutMock, DestroyImpl).Times(1);

        EXPECT_TRUE(pipelineLayoutMock.IsAlive());
        pipelineLayoutMock.Destroy();
        EXPECT_FALSE(pipelineLayoutMock.IsAlive());
    }

    // If the reference count on API objects reach 0, they should delete themselves. Note that GTest
    // will also complain if there is a memory leak.
    TEST_F(DestroyObjectTests, PipelineLayoutImplicit) {
        PipelineLayoutMock* pipelineLayoutMock = new PipelineLayoutMock(&mDevice);
        EXPECT_CALL(*pipelineLayoutMock, DestroyImpl).Times(1);
        {
            PipelineLayoutDescriptor desc = {};
            Ref<PipelineLayoutBase> pipelineLayout;
            EXPECT_CALL(mDevice, CreatePipelineLayoutImpl)
                .WillOnce(Return(ByMove(AcquireRef(pipelineLayoutMock))));
            DAWN_ASSERT_AND_ASSIGN(pipelineLayout, mDevice.CreatePipelineLayout(&desc));

            EXPECT_TRUE(pipelineLayout->IsAlive());
            EXPECT_TRUE(pipelineLayout->IsCachedReference());
        }
    }

    TEST_F(DestroyObjectTests, QuerySetExplicit) {
        QuerySetMock querySetMock(&mDevice);
        EXPECT_CALL(querySetMock, DestroyImpl).Times(1);

        EXPECT_TRUE(querySetMock.IsAlive());
        querySetMock.Destroy();
        EXPECT_FALSE(querySetMock.IsAlive());
    }

    // If the reference count on API objects reach 0, they should delete themselves. Note that GTest
    // will also complain if there is a memory leak.
    TEST_F(DestroyObjectTests, QuerySetImplicit) {
        QuerySetMock* querySetMock = new QuerySetMock(&mDevice);
        EXPECT_CALL(*querySetMock, DestroyImpl).Times(1);
        {
            QuerySetDescriptor desc = {};
            Ref<QuerySetBase> querySet;
            EXPECT_CALL(mDevice, CreateQuerySetImpl)
                .WillOnce(Return(ByMove(AcquireRef(querySetMock))));
            DAWN_ASSERT_AND_ASSIGN(querySet, mDevice.CreateQuerySet(&desc));

            EXPECT_TRUE(querySet->IsAlive());
        }
    }

    TEST_F(DestroyObjectTests, RenderPipelineExplicit) {
        RenderPipelineMock renderPipelineMock(&mDevice);
        EXPECT_CALL(renderPipelineMock, DestroyImpl).Times(1);

        EXPECT_TRUE(renderPipelineMock.IsAlive());
        renderPipelineMock.Destroy();
        EXPECT_FALSE(renderPipelineMock.IsAlive());
    }

    // If the reference count on API objects reach 0, they should delete themselves. Note that GTest
    // will also complain if there is a memory leak.
    TEST_F(DestroyObjectTests, RenderPipelineImplicit) {
        // RenderPipelines usually set their hash values at construction, but the mock does not, so
        // we set it here.
        constexpr size_t hash = 0x12345;
        RenderPipelineMock* renderPipelineMock = new RenderPipelineMock(&mDevice);
        renderPipelineMock->SetContentHash(hash);
        ON_CALL(*renderPipelineMock, ComputeContentHash).WillByDefault(Return(hash));

        // Render pipelines are initialized during their creation via the device.
        EXPECT_CALL(*renderPipelineMock, Initialize).Times(1);
        EXPECT_CALL(*renderPipelineMock, DestroyImpl).Times(1);

        {
            RenderPipelineDescriptor desc = {};
            desc.layout = GetPipelineLayout().Get();
            desc.vertex.module = GetVertexShaderModule().Get();

            Ref<RenderPipelineBase> renderPipeline;
            EXPECT_CALL(mDevice, CreateUninitializedRenderPipelineImpl)
                .WillOnce(Return(ByMove(AcquireRef(renderPipelineMock))));
            DAWN_ASSERT_AND_ASSIGN(renderPipeline, mDevice.CreateRenderPipeline(&desc));

            EXPECT_TRUE(renderPipeline->IsAlive());
            EXPECT_TRUE(renderPipeline->IsCachedReference());
        }
    }

    TEST_F(DestroyObjectTests, SamplerExplicit) {
        SamplerMock samplerMock(&mDevice);
        EXPECT_CALL(samplerMock, DestroyImpl).Times(1);

        EXPECT_TRUE(samplerMock.IsAlive());
        samplerMock.Destroy();
        EXPECT_FALSE(samplerMock.IsAlive());
    }

    // If the reference count on API objects reach 0, they should delete themselves. Note that GTest
    // will also complain if there is a memory leak.
    TEST_F(DestroyObjectTests, SamplerImplicit) {
        SamplerMock* samplerMock = new SamplerMock(&mDevice);
        EXPECT_CALL(*samplerMock, DestroyImpl).Times(1);
        {
            SamplerDescriptor desc = {};
            Ref<SamplerBase> sampler;
            EXPECT_CALL(mDevice, CreateSamplerImpl)
                .WillOnce(Return(ByMove(AcquireRef(samplerMock))));
            DAWN_ASSERT_AND_ASSIGN(sampler, mDevice.CreateSampler(&desc));

            EXPECT_TRUE(sampler->IsAlive());
            EXPECT_TRUE(sampler->IsCachedReference());
        }
    }

    TEST_F(DestroyObjectTests, ShaderModuleExplicit) {
        ShaderModuleMock shaderModuleMock(&mDevice);
        EXPECT_CALL(shaderModuleMock, DestroyImpl).Times(1);

        EXPECT_TRUE(shaderModuleMock.IsAlive());
        shaderModuleMock.Destroy();
        EXPECT_FALSE(shaderModuleMock.IsAlive());
    }

    // If the reference count on API objects reach 0, they should delete themselves. Note that GTest
    // will also complain if there is a memory leak.
    TEST_F(DestroyObjectTests, ShaderModuleImplicit) {
        ShaderModuleMock* shaderModuleMock = new ShaderModuleMock(&mDevice);
        EXPECT_CALL(*shaderModuleMock, DestroyImpl).Times(1);
        {
            ShaderModuleWGSLDescriptor wgslDesc;
            wgslDesc.source = R"(
                [[stage(compute), workgroup_size(1)]] fn main() {
                }
            )";
            ShaderModuleDescriptor desc = {};
            desc.nextInChain = &wgslDesc;
            Ref<ShaderModuleBase> shaderModule;
            EXPECT_CALL(mDevice, CreateShaderModuleImpl)
                .WillOnce(Return(ByMove(AcquireRef(shaderModuleMock))));
            DAWN_ASSERT_AND_ASSIGN(shaderModule, mDevice.CreateShaderModule(&desc));

            EXPECT_TRUE(shaderModule->IsAlive());
            EXPECT_TRUE(shaderModule->IsCachedReference());
        }
    }

    TEST_F(DestroyObjectTests, SwapChainExplicit) {
        SwapChainMock swapChainMock(&mDevice);
        EXPECT_CALL(swapChainMock, DestroyImpl).Times(1);

        EXPECT_TRUE(swapChainMock.IsAlive());
        swapChainMock.Destroy();
        EXPECT_FALSE(swapChainMock.IsAlive());
    }

    // If the reference count on API objects reach 0, they should delete themselves. Note that GTest
    // will also complain if there is a memory leak.
    TEST_F(DestroyObjectTests, SwapChainImplicit) {
        SwapChainMock* swapChainMock = new SwapChainMock(&mDevice);
        EXPECT_CALL(*swapChainMock, DestroyImpl).Times(1);
        {
            SwapChainDescriptor desc = {};
            Ref<SwapChainBase> swapChain;
            EXPECT_CALL(mDevice, CreateSwapChainImpl(_))
                .WillOnce(Return(ByMove(AcquireRef(swapChainMock))));
            DAWN_ASSERT_AND_ASSIGN(swapChain, mDevice.CreateSwapChain(nullptr, &desc));

            EXPECT_TRUE(swapChain->IsAlive());
        }
    }

    TEST_F(DestroyObjectTests, TextureExplicit) {
        {
            TextureMock textureMock(&mDevice, TextureBase::TextureState::OwnedInternal);
            EXPECT_CALL(textureMock, DestroyImpl).Times(1);

            EXPECT_TRUE(textureMock.IsAlive());
            textureMock.Destroy();
            EXPECT_FALSE(textureMock.IsAlive());
        }
        {
            TextureMock textureMock(&mDevice, TextureBase::TextureState::OwnedExternal);
            EXPECT_CALL(textureMock, DestroyImpl).Times(1);

            EXPECT_TRUE(textureMock.IsAlive());
            textureMock.Destroy();
            EXPECT_FALSE(textureMock.IsAlive());
        }
    }

    // If the reference count on API objects reach 0, they should delete themselves. Note that GTest
    // will also complain if there is a memory leak.
    TEST_F(DestroyObjectTests, TextureImplicit) {
        {
            TextureMock* textureMock =
                new TextureMock(&mDevice, TextureBase::TextureState::OwnedInternal);
            EXPECT_CALL(*textureMock, DestroyImpl).Times(1);
            {
                TextureDescriptor desc = {};
                Ref<TextureBase> texture;
                EXPECT_CALL(mDevice, CreateTextureImpl)
                    .WillOnce(Return(ByMove(AcquireRef(textureMock))));
                DAWN_ASSERT_AND_ASSIGN(texture, mDevice.CreateTexture(&desc));

                EXPECT_TRUE(texture->IsAlive());
            }
        }
        {
            TextureMock* textureMock =
                new TextureMock(&mDevice, TextureBase::TextureState::OwnedExternal);
            EXPECT_CALL(*textureMock, DestroyImpl).Times(1);
            {
                TextureDescriptor desc = {};
                Ref<TextureBase> texture;
                EXPECT_CALL(mDevice, CreateTextureImpl)
                    .WillOnce(Return(ByMove(AcquireRef(textureMock))));
                DAWN_ASSERT_AND_ASSIGN(texture, mDevice.CreateTexture(&desc));

                EXPECT_TRUE(texture->IsAlive());
            }
        }
    }

    TEST_F(DestroyObjectTests, TextureViewExplicit) {
        TextureViewMock textureViewMock(GetTexture().Get());
        EXPECT_CALL(textureViewMock, DestroyImpl).Times(1);

        EXPECT_TRUE(textureViewMock.IsAlive());
        textureViewMock.Destroy();
        EXPECT_FALSE(textureViewMock.IsAlive());
    }

    // If the reference count on API objects reach 0, they should delete themselves. Note that GTest
    // will also complain if there is a memory leak.
    TEST_F(DestroyObjectTests, TextureViewImplicit) {
        TextureViewMock* textureViewMock = new TextureViewMock(GetTexture().Get());
        EXPECT_CALL(*textureViewMock, DestroyImpl).Times(1);
        {
            TextureViewDescriptor desc = {};
            Ref<TextureViewBase> textureView;
            EXPECT_CALL(mDevice, CreateTextureViewImpl)
                .WillOnce(Return(ByMove(AcquireRef(textureViewMock))));
            DAWN_ASSERT_AND_ASSIGN(textureView,
                                   mDevice.CreateTextureView(GetTexture().Get(), &desc));

            EXPECT_TRUE(textureView->IsAlive());
        }
    }

    // Destroying the objects on the mDevice should result in all created objects being destroyed in
    // order.
    TEST_F(DestroyObjectTests, DestroyObjects) {
        BindGroupMock* bindGroupMock = new BindGroupMock(&mDevice);
        BindGroupLayoutMock* bindGroupLayoutMock = new BindGroupLayoutMock(&mDevice);
        BufferMock* bufferMock = new BufferMock(&mDevice, BufferBase::BufferState::Unmapped);
        CommandBufferMock* commandBufferMock = new CommandBufferMock(&mDevice);
        ComputePipelineMock* computePipelineMock = new ComputePipelineMock(&mDevice);
        PipelineLayoutMock* pipelineLayoutMock = new PipelineLayoutMock(&mDevice);
        QuerySetMock* querySetMock = new QuerySetMock(&mDevice);
        RenderPipelineMock* renderPipelineMock = new RenderPipelineMock(&mDevice);
        SamplerMock* samplerMock = new SamplerMock(&mDevice);
        ShaderModuleMock* shaderModuleMock = new ShaderModuleMock(&mDevice);
        SwapChainMock* swapChainMock = new SwapChainMock(&mDevice);
        TextureMock* textureMock =
            new TextureMock(&mDevice, TextureBase::TextureState::OwnedInternal);
        TextureViewMock* textureViewMock = new TextureViewMock(GetTexture().Get());
        {
            InSequence seq;
            EXPECT_CALL(*commandBufferMock, DestroyImpl).Times(1);
            EXPECT_CALL(*renderPipelineMock, DestroyImpl).Times(1);
            EXPECT_CALL(*computePipelineMock, DestroyImpl).Times(1);
            EXPECT_CALL(*pipelineLayoutMock, DestroyImpl).Times(1);
            EXPECT_CALL(*swapChainMock, DestroyImpl).Times(1);
            EXPECT_CALL(*bindGroupMock, DestroyImpl).Times(1);
            EXPECT_CALL(*bindGroupLayoutMock, DestroyImpl).Times(1);
            EXPECT_CALL(*shaderModuleMock, DestroyImpl).Times(1);
            EXPECT_CALL(*textureViewMock, DestroyImpl).Times(1);
            EXPECT_CALL(*textureMock, DestroyImpl).Times(1);
            EXPECT_CALL(*querySetMock, DestroyImpl).Times(1);
            EXPECT_CALL(*samplerMock, DestroyImpl).Times(1);
            EXPECT_CALL(*bufferMock, DestroyImpl).Times(1);
        }

        Ref<BindGroupBase> bindGroup;
        {
            BindGroupDescriptor desc = {};
            EXPECT_CALL(mDevice, CreateBindGroupImpl)
                .WillOnce(Return(ByMove(AcquireRef(bindGroupMock))));
            DAWN_ASSERT_AND_ASSIGN(bindGroup, mDevice.CreateBindGroup(&desc));
            EXPECT_TRUE(bindGroup->IsAlive());
        }

        Ref<BindGroupLayoutBase> bindGroupLayout;
        {
            BindGroupLayoutDescriptor desc = {};
            EXPECT_CALL(mDevice, CreateBindGroupLayoutImpl)
                .WillOnce(Return(ByMove(AcquireRef(bindGroupLayoutMock))));
            DAWN_ASSERT_AND_ASSIGN(bindGroupLayout, mDevice.CreateBindGroupLayout(&desc));
            EXPECT_TRUE(bindGroupLayout->IsAlive());
            EXPECT_TRUE(bindGroupLayout->IsCachedReference());
        }

        Ref<BufferBase> buffer;
        {
            BufferDescriptor desc = {};
            EXPECT_CALL(mDevice, CreateBufferImpl).WillOnce(Return(ByMove(AcquireRef(bufferMock))));
            DAWN_ASSERT_AND_ASSIGN(buffer, mDevice.CreateBuffer(&desc));
            EXPECT_TRUE(buffer->IsAlive());
        }

        Ref<CommandBufferBase> commandBuffer;
        {
            CommandBufferDescriptor desc = {};
            EXPECT_CALL(mDevice, CreateCommandBuffer)
                .WillOnce(Return(ByMove(AcquireRef(commandBufferMock))));
            DAWN_ASSERT_AND_ASSIGN(commandBuffer, mDevice.CreateCommandBuffer(nullptr, &desc));
            EXPECT_TRUE(commandBuffer->IsAlive());
        }

        Ref<ComputePipelineBase> computePipeline;
        {
            // Compute pipelines usually set their hash values at construction, but the mock does
            // not, so we set it here.
            constexpr size_t hash = 0x12345;
            computePipelineMock->SetContentHash(hash);
            ON_CALL(*computePipelineMock, ComputeContentHash).WillByDefault(Return(hash));

            // Compute pipelines are initialized during their creation via the device.
            EXPECT_CALL(*computePipelineMock, Initialize).Times(1);

            ComputePipelineDescriptor desc = {};
            desc.layout = GetPipelineLayout().Get();
            desc.compute.module = GetComputeShaderModule().Get();
            EXPECT_CALL(mDevice, CreateUninitializedComputePipelineImpl)
                .WillOnce(Return(ByMove(AcquireRef(computePipelineMock))));
            DAWN_ASSERT_AND_ASSIGN(computePipeline, mDevice.CreateComputePipeline(&desc));
            EXPECT_TRUE(computePipeline->IsAlive());
            EXPECT_TRUE(computePipeline->IsCachedReference());
        }

        Ref<ExternalTextureBase> externalTexture;
        {
            ExternalTextureDescriptor desc = {};
            DAWN_ASSERT_AND_ASSIGN(externalTexture, mDevice.CreateExternalTexture(&desc));
            EXPECT_TRUE(externalTexture->IsAlive());
        }

        Ref<PipelineLayoutBase> pipelineLayout;
        {
            PipelineLayoutDescriptor desc = {};
            EXPECT_CALL(mDevice, CreatePipelineLayoutImpl)
                .WillOnce(Return(ByMove(AcquireRef(pipelineLayoutMock))));
            DAWN_ASSERT_AND_ASSIGN(pipelineLayout, mDevice.CreatePipelineLayout(&desc));
            EXPECT_TRUE(pipelineLayout->IsAlive());
            EXPECT_TRUE(pipelineLayout->IsCachedReference());
        }

        Ref<QuerySetBase> querySet;
        {
            QuerySetDescriptor desc = {};
            EXPECT_CALL(mDevice, CreateQuerySetImpl)
                .WillOnce(Return(ByMove(AcquireRef(querySetMock))));
            DAWN_ASSERT_AND_ASSIGN(querySet, mDevice.CreateQuerySet(&desc));
            EXPECT_TRUE(querySet->IsAlive());
        }

        Ref<RenderPipelineBase> renderPipeline;
        {
            // Render pipelines usually set their hash values at construction, but the mock does
            // not, so we set it here.
            constexpr size_t hash = 0x12345;
            renderPipelineMock->SetContentHash(hash);
            ON_CALL(*renderPipelineMock, ComputeContentHash).WillByDefault(Return(hash));

            // Render pipelines are initialized during their creation via the device.
            EXPECT_CALL(*renderPipelineMock, Initialize).Times(1);

            RenderPipelineDescriptor desc = {};
            desc.layout = GetPipelineLayout().Get();
            desc.vertex.module = GetVertexShaderModule().Get();
            EXPECT_CALL(mDevice, CreateUninitializedRenderPipelineImpl)
                .WillOnce(Return(ByMove(AcquireRef(renderPipelineMock))));
            DAWN_ASSERT_AND_ASSIGN(renderPipeline, mDevice.CreateRenderPipeline(&desc));
            EXPECT_TRUE(renderPipeline->IsAlive());
            EXPECT_TRUE(renderPipeline->IsCachedReference());
        }

        Ref<SamplerBase> sampler;
        {
            SamplerDescriptor desc = {};
            EXPECT_CALL(mDevice, CreateSamplerImpl)
                .WillOnce(Return(ByMove(AcquireRef(samplerMock))));
            DAWN_ASSERT_AND_ASSIGN(sampler, mDevice.CreateSampler(&desc));
            EXPECT_TRUE(sampler->IsAlive());
            EXPECT_TRUE(sampler->IsCachedReference());
        }

        Ref<ShaderModuleBase> shaderModule;
        {
            ShaderModuleWGSLDescriptor wgslDesc;
            wgslDesc.source = R"(
                [[stage(compute), workgroup_size(1)]] fn main() {
                }
            )";
            ShaderModuleDescriptor desc = {};
            desc.nextInChain = &wgslDesc;

            EXPECT_CALL(mDevice, CreateShaderModuleImpl)
                .WillOnce(Return(ByMove(AcquireRef(shaderModuleMock))));
            DAWN_ASSERT_AND_ASSIGN(shaderModule, mDevice.CreateShaderModule(&desc));
            EXPECT_TRUE(shaderModule->IsAlive());
            EXPECT_TRUE(shaderModule->IsCachedReference());
        }

        Ref<SwapChainBase> swapChain;
        {
            SwapChainDescriptor desc = {};
            EXPECT_CALL(mDevice, CreateSwapChainImpl(_))
                .WillOnce(Return(ByMove(AcquireRef(swapChainMock))));
            DAWN_ASSERT_AND_ASSIGN(swapChain, mDevice.CreateSwapChain(nullptr, &desc));
            EXPECT_TRUE(swapChain->IsAlive());
        }

        Ref<TextureBase> texture;
        {
            TextureDescriptor desc = {};
            EXPECT_CALL(mDevice, CreateTextureImpl)
                .WillOnce(Return(ByMove(AcquireRef(textureMock))));
            DAWN_ASSERT_AND_ASSIGN(texture, mDevice.CreateTexture(&desc));
            EXPECT_TRUE(texture->IsAlive());
        }

        Ref<TextureViewBase> textureView;
        {
            TextureViewDescriptor desc = {};
            EXPECT_CALL(mDevice, CreateTextureViewImpl)
                .WillOnce(Return(ByMove(AcquireRef(textureViewMock))));
            DAWN_ASSERT_AND_ASSIGN(textureView,
                                   mDevice.CreateTextureView(GetTexture().Get(), &desc));
            EXPECT_TRUE(textureView->IsAlive());
        }

        mDevice.DestroyObjects();
        EXPECT_FALSE(bindGroup->IsAlive());
        EXPECT_FALSE(bindGroupLayout->IsAlive());
        EXPECT_FALSE(buffer->IsAlive());
        EXPECT_FALSE(commandBuffer->IsAlive());
        EXPECT_FALSE(computePipeline->IsAlive());
        EXPECT_FALSE(externalTexture->IsAlive());
        EXPECT_FALSE(pipelineLayout->IsAlive());
        EXPECT_FALSE(querySet->IsAlive());
        EXPECT_FALSE(renderPipeline->IsAlive());
        EXPECT_FALSE(sampler->IsAlive());
        EXPECT_FALSE(shaderModule->IsAlive());
        EXPECT_FALSE(swapChain->IsAlive());
        EXPECT_FALSE(texture->IsAlive());
        EXPECT_FALSE(textureView->IsAlive());
    }

}}  // namespace dawn_native::
