Commit 776a75b4 by Jamie Madill Committed by Commit Bot

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/342050Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent be815a4f
......@@ -80,6 +80,9 @@ class EGLX11VisualHintTest : public ::testing::TestWithParam<angle::PlatformPara
// Test that display creation fails if the visual ID passed in invalid.
TEST_P(EGLX11VisualHintTest, InvalidVisualID)
{
// The test platform will log an error in this negative test.
IgnoreANGLEPlatformMessages();
static const int gInvalidVisualId = -1;
auto attributes = getDisplayAttributes(gInvalidVisualId);
......
......@@ -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 @@ float ColorNorm(GLubyte channelValue)
{
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 @@ ANGLETest::~ANGLETest()
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 @@ OSWindow *ANGLETest::mOSWindow = NULL;
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::SetUp()
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();
}
......@@ -18,6 +18,7 @@
#include "angle_test_configs.h"
#include "common/angleutils.h"
#include "shader_utils.h"
#include "system_utils.h"
#include "Vector.h"
#define EXPECT_GL_ERROR(err) EXPECT_EQ(static_cast<GLenum>(err), glGetError())
......@@ -186,8 +187,12 @@ class ANGLETest : public ::testing::TestWithParam<angle::PlatformParameters>
class ANGLETestEnvironment : public testing::Environment
{
public:
virtual void SetUp();
virtual void TearDown();
void SetUp() override;
void TearDown() override;
private:
// For loading and freeing platform
std::unique_ptr<angle::Library> mGLESLibrary;
};
bool IsIntel();
......@@ -203,4 +208,7 @@ bool IsD3DSM3();
bool IsLinux();
bool IsOSX();
// Negative tests may trigger expected errors/warnings in the ANGLE Platform.
void IgnoreANGLEPlatformMessages();
#endif // ANGLE_TESTS_ANGLE_TEST_H_
......@@ -39,4 +39,9 @@ std::string GetExecutableDirectory()
return (lastPathSepLoc != std::string::npos) ? executablePath.substr(0, lastPathSepLoc) : "";
}
std::string GetSharedLibraryExtension()
{
return "so";
}
} // namespace angle
......@@ -42,4 +42,9 @@ std::string GetExecutableDirectory()
return (lastPathSepLoc != std::string::npos) ? executablePath.substr(0, lastPathSepLoc) : "";
}
std::string GetSharedLibraryExtension()
{
return "dylib";
}
} // namespace angle
......@@ -9,6 +9,7 @@
#include "system_utils.h"
#include <sys/resource.h>
#include <dlfcn.h>
#include <sched.h>
#include <time.h>
#include <unistd.h>
......@@ -46,4 +47,45 @@ void WriteDebugMessage(const char *format, ...)
// TODO(jmadill): Implement this
}
class PosixLibrary : public Library
{
public:
PosixLibrary(const std::string &libraryName);
~PosixLibrary() override;
void *getSymbol(const std::string &symbolName) override;
private:
void *mModule;
};
PosixLibrary::PosixLibrary(const std::string &libraryName) : mModule(nullptr)
{
const auto &fullName = libraryName + "." + GetSharedLibraryExtension();
mModule = dlopen(fullName.c_str(), RTLD_NOW);
}
PosixLibrary::~PosixLibrary()
{
if (mModule)
{
dlclose(mModule);
}
}
void *PosixLibrary::getSymbol(const std::string &symbolName)
{
if (!mModule)
{
return nullptr;
}
return dlsym(mModule, symbolName.c_str());
}
Library *loadLibrary(const std::string &libraryName)
{
return new PosixLibrary(libraryName);
}
} // namespace angle
......@@ -6,16 +6,19 @@
// system_utils.h: declaration of OS-specific utility functions
#ifndef SAMPLE_UTIL_PATH_UTILS_H
#define SAMPLE_UTIL_PATH_UTILS_H
#ifndef UTIL_SYSTEM_UTILS_H_
#define UTIL_SYSTEM_UTILS_H_
#include <string>
#include "common/angleutils.h"
namespace angle
{
std::string GetExecutablePath();
std::string GetExecutableDirectory();
std::string GetSharedLibraryExtension();
// Cross platform equivalent of the Windows Sleep function
void Sleep(unsigned int milliseconds);
......@@ -25,6 +28,15 @@ void SetLowPriorityProcess();
// Write a debug message, either to a standard output or Debug window.
void WriteDebugMessage(const char *format, ...);
class Library : angle::NonCopyable
{
public:
virtual ~Library() {}
virtual void *getSymbol(const std::string &symbolName) = 0;
};
Library *loadLibrary(const std::string &libraryName);
} // namespace angle
#endif // SAMPLE_UTIL_PATH_UTILS_H
#endif // UTIL_SYSTEM_UTILS_H_
......@@ -31,6 +31,11 @@ std::string GetExecutableDirectory()
return (lastPathSepLoc != std::string::npos) ? executablePath.substr(0, lastPathSepLoc) : "";
}
std::string GetSharedLibraryExtension()
{
return "dll";
}
void Sleep(unsigned int milliseconds)
{
::Sleep(static_cast<DWORD>(milliseconds));
......
......@@ -19,4 +19,45 @@ void SetLowPriorityProcess()
SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS);
}
class Win32Library : public Library
{
public:
Win32Library(const std::string &libraryName);
~Win32Library() override;
void *getSymbol(const std::string &symbolName) override;
private:
HMODULE mModule;
};
Win32Library::Win32Library(const std::string &libraryName) : mModule(nullptr)
{
const auto &fullName = libraryName + "." + GetSharedLibraryExtension();
mModule = LoadLibraryA(fullName.c_str());
}
Win32Library::~Win32Library()
{
if (mModule)
{
FreeLibrary(mModule);
}
}
void *Win32Library::getSymbol(const std::string &symbolName)
{
if (!mModule)
{
return nullptr;
}
return GetProcAddress(mModule, symbolName.c_str());
}
Library *loadLibrary(const std::string &libraryName)
{
return new Win32Library(libraryName);
}
} // namespace angle
......@@ -19,4 +19,10 @@ void SetLowPriorityProcess()
// No equivalent to this in WinRT
}
Library *loadLibrary(const std::string &libraryName)
{
// WinRT cannot load code dynamically.
return nullptr;
}
} // namespace angle
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment