Make Platform errors trigger test failures.

This can be useful in the Vulkan back-end to make validation layer
errors cause test cases to fail.

BUG=angleproject:1319

Change-Id: I523f3c874e892a2646600e4c5c554319ed8d770c
Reviewed-on: https://chromium-review.googlesource.com/342050
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
diff --git a/src/tests/test_utils/ANGLETest.cpp b/src/tests/test_utils/ANGLETest.cpp
index c91dd60..d7b43e7 100644
--- a/src/tests/test_utils/ANGLETest.cpp
+++ b/src/tests/test_utils/ANGLETest.cpp
@@ -10,7 +10,7 @@
 #include "ANGLETest.h"
 #include "EGLWindow.h"
 #include "OSWindow.h"
-#include "system_utils.h"
+#include "platform/Platform.h"
 
 namespace angle
 {
@@ -28,6 +28,59 @@
 {
     return static_cast<float>(channelValue) / 255.0f;
 }
+
+// Use a custom ANGLE platform class to capture and report internal errors.
+class TestPlatform : public angle::Platform
+{
+  public:
+    TestPlatform() : mIgnoreMessages(false) {}
+
+    void logError(const char *errorMessage) override;
+    void logWarning(const char *warningMessage) override;
+    void logInfo(const char *infoMessage) override;
+
+    void ignoreMessages();
+    void enableMessages();
+
+  private:
+    bool mIgnoreMessages;
+};
+
+void TestPlatform::logError(const char *errorMessage)
+{
+    if (mIgnoreMessages)
+        return;
+
+    FAIL() << errorMessage;
+}
+
+void TestPlatform::logWarning(const char *warningMessage)
+{
+    if (mIgnoreMessages)
+        return;
+
+    std::cerr << "Warning: " << warningMessage << std::endl;
+}
+
+void TestPlatform::logInfo(const char *infoMessage)
+{
+    if (mIgnoreMessages)
+        return;
+
+    angle::WriteDebugMessage("%s\n", infoMessage);
+}
+
+void TestPlatform::ignoreMessages()
+{
+    mIgnoreMessages = true;
+}
+
+void TestPlatform::enableMessages()
+{
+    mIgnoreMessages = false;
+}
+
+TestPlatform g_testPlatformInstance;
 }  // anonymous namespace
 
 GLColor::GLColor() : R(0), G(0), B(0), A(0)
@@ -93,6 +146,8 @@
 
 void ANGLETest::SetUp()
 {
+    angle::g_testPlatformInstance.enableMessages();
+
     // Resize the window before creating the context so that the first make current
     // sets the viewport and scissor box to the right size.
     bool needSwap = false;
@@ -637,6 +692,17 @@
 
 void ANGLETestEnvironment::SetUp()
 {
+    mGLESLibrary.reset(angle::loadLibrary("libGLESv2"));
+    if (mGLESLibrary)
+    {
+        auto initFunc = reinterpret_cast<ANGLEPlatformInitializeFunc>(
+            mGLESLibrary->getSymbol("ANGLEPlatformInitialize"));
+        if (initFunc)
+        {
+            initFunc(&angle::g_testPlatformInstance);
+        }
+    }
+
     if (!ANGLETest::InitTestWindow())
     {
         FAIL() << "Failed to create ANGLE test window.";
@@ -646,4 +712,20 @@
 void ANGLETestEnvironment::TearDown()
 {
     ANGLETest::DestroyTestWindow();
+
+    if (mGLESLibrary)
+    {
+        auto shutdownFunc = reinterpret_cast<ANGLEPlatformShutdownFunc>(
+            mGLESLibrary->getSymbol("ANGLEPlatformShutdown"));
+        if (shutdownFunc)
+        {
+            shutdownFunc();
+        }
+    }
+}
+
+void IgnoreANGLEPlatformMessages()
+{
+    // Negative tests may trigger expected errors/warnings in the ANGLE Platform.
+    angle::g_testPlatformInstance.ignoreMessages();
 }