Add CompilationInfo wire test, check offset/length

Change-Id: Ifc457d6b58f20c294531444836693cb31e036ca1
Bug: dawn:746
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/57941
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Brandon Jones <bajones@chromium.org>
diff --git a/src/tests/BUILD.gn b/src/tests/BUILD.gn
index 54cc12b..2310591 100644
--- a/src/tests/BUILD.gn
+++ b/src/tests/BUILD.gn
@@ -239,6 +239,7 @@
     "unittests/wire/WireMemoryTransferServiceTests.cpp",
     "unittests/wire/WireOptionalTests.cpp",
     "unittests/wire/WireQueueTests.cpp",
+    "unittests/wire/WireShaderModuleTests.cpp",
     "unittests/wire/WireTest.cpp",
     "unittests/wire/WireTest.h",
     "unittests/wire/WireWGPUDevicePropertiesTests.cpp",
diff --git a/src/tests/unittests/validation/ShaderModuleValidationTests.cpp b/src/tests/unittests/validation/ShaderModuleValidationTests.cpp
index 69d4e0a..16b943a 100644
--- a/src/tests/unittests/validation/ShaderModuleValidationTests.cpp
+++ b/src/tests/unittests/validation/ShaderModuleValidationTests.cpp
@@ -174,12 +174,14 @@
     messages->AddMessageForTesting("Info Message");
     messages->AddMessageForTesting("Warning Message", wgpu::CompilationMessageType::Warning);
     messages->AddMessageForTesting("Error Message", wgpu::CompilationMessageType::Error, 3, 4);
+    messages->AddMessageForTesting("Complete Message", wgpu::CompilationMessageType::Info, 3, 4, 5,
+                                   6);
 
     auto callback = [](WGPUCompilationInfoRequestStatus status, const WGPUCompilationInfo* info,
                        void* userdata) {
         ASSERT_EQ(WGPUCompilationInfoRequestStatus_Success, status);
         ASSERT_NE(nullptr, info);
-        ASSERT_EQ(3u, info->messageCount);
+        ASSERT_EQ(4u, info->messageCount);
 
         const WGPUCompilationMessage* message = &info->messages[0];
         ASSERT_STREQ("Info Message", message->message);
@@ -198,6 +200,14 @@
         ASSERT_EQ(WGPUCompilationMessageType_Error, message->type);
         ASSERT_EQ(3u, message->lineNum);
         ASSERT_EQ(4u, message->linePos);
+
+        message = &info->messages[3];
+        ASSERT_STREQ("Complete Message", message->message);
+        ASSERT_EQ(WGPUCompilationMessageType_Info, message->type);
+        ASSERT_EQ(3u, message->lineNum);
+        ASSERT_EQ(4u, message->linePos);
+        ASSERT_EQ(5u, message->offset);
+        ASSERT_EQ(6u, message->length);
     };
 
     shaderModule.GetCompilationInfo(callback, nullptr);
diff --git a/src/tests/unittests/wire/WireShaderModuleTests.cpp b/src/tests/unittests/wire/WireShaderModuleTests.cpp
new file mode 100644
index 0000000..f4a0425
--- /dev/null
+++ b/src/tests/unittests/wire/WireShaderModuleTests.cpp
@@ -0,0 +1,120 @@
+// 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 "tests/unittests/wire/WireTest.h"
+
+#include "dawn_wire/WireClient.h"
+
+using namespace testing;
+using namespace dawn_wire;
+
+namespace {
+
+    // Mock class to add expectations on the wire calling callbacks
+    class MockCompilationInfoCallback {
+      public:
+        MOCK_METHOD(void,
+                    Call,
+                    (WGPUCompilationInfoRequestStatus status,
+                     const WGPUCompilationInfo* info,
+                     void* userdata));
+    };
+
+    std::unique_ptr<StrictMock<MockCompilationInfoCallback>> mockCompilationInfoCallback;
+    void ToMockGetCompilationInfoCallback(WGPUCompilationInfoRequestStatus status,
+                                          const WGPUCompilationInfo* info,
+                                          void* userdata) {
+        mockCompilationInfoCallback->Call(status, info, userdata);
+    }
+
+}  // anonymous namespace
+
+class WireShaderModuleTests : public WireTest {
+  public:
+    WireShaderModuleTests() {
+    }
+    ~WireShaderModuleTests() override = default;
+
+    void SetUp() override {
+        WireTest::SetUp();
+
+        mockCompilationInfoCallback = std::make_unique<StrictMock<MockCompilationInfoCallback>>();
+        apiShaderModule = api.GetNewShaderModule();
+
+        WGPUShaderModuleDescriptor descriptor = {};
+        shaderModule = wgpuDeviceCreateShaderModule(device, &descriptor);
+
+        EXPECT_CALL(api, DeviceCreateShaderModule(apiDevice, _))
+            .WillOnce(Return(apiShaderModule))
+            .RetiresOnSaturation();
+        FlushClient();
+    }
+
+    void TearDown() override {
+        WireTest::TearDown();
+
+        // Delete mock so that expectations are checked
+        mockCompilationInfoCallback = nullptr;
+    }
+
+    void FlushClient() {
+        WireTest::FlushClient();
+        Mock::VerifyAndClearExpectations(&mockCompilationInfoCallback);
+    }
+
+    void FlushServer() {
+        WireTest::FlushServer();
+        Mock::VerifyAndClearExpectations(&mockCompilationInfoCallback);
+    }
+
+  protected:
+    WGPUShaderModule shaderModule;
+    WGPUShaderModule apiShaderModule;
+};
+
+// Check getting CompilationInfo for a successfully created shader module
+TEST_F(WireShaderModuleTests, GetCompilationInfo) {
+    wgpuShaderModuleGetCompilationInfo(shaderModule, ToMockGetCompilationInfoCallback, nullptr);
+
+    WGPUCompilationMessage message = {"Test Message", WGPUCompilationMessageType_Info, 2, 4, 6, 8};
+    WGPUCompilationInfo compilationInfo;
+    compilationInfo.messageCount = 1;
+    compilationInfo.messages = &message;
+
+    EXPECT_CALL(api, OnShaderModuleGetCompilationInfo(apiShaderModule, _, _))
+        .WillOnce(InvokeWithoutArgs([&]() {
+            api.CallShaderModuleGetCompilationInfoCallback(
+                apiShaderModule, WGPUCompilationInfoRequestStatus_Success, &compilationInfo);
+        }));
+
+    FlushClient();
+
+    EXPECT_CALL(*mockCompilationInfoCallback,
+                Call(WGPUCompilationInfoRequestStatus_Success,
+                     MatchesLambda([&](const WGPUCompilationInfo* info) -> bool {
+                         if (info->messageCount != compilationInfo.messageCount) {
+                             return false;
+                         }
+                         const WGPUCompilationMessage* infoMessage = &info->messages[0];
+                         return strcmp(infoMessage->message, message.message) == 0 &&
+                                infoMessage->type == message.type &&
+                                infoMessage->lineNum == message.lineNum &&
+                                infoMessage->linePos == message.linePos &&
+                                infoMessage->offset == message.offset &&
+                                infoMessage->length == message.length;
+                     }),
+                     _))
+        .Times(1);
+    FlushServer();
+}
\ No newline at end of file