Commit c5a63124 by Jamie Madill

Add unit tests for proper TLS initialization.

The test creates a worker thread which initializes EGL, then calls EGL methods which check for thread local storage values. This can cause a crash of the values are uninialized. BUG=angle:488 Change-Id: Ibaffede0605c720ba9ca47910690a1334ee9e20e Reviewed-on: https://chromium-review.googlesource.com/179130Reviewed-by: 's avatarShannon Woods <shannonwoods@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Geoff Lang <geofflang@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 3b866b6c
#include "gtest/gtest.h"
#define GL_GLEXT_PROTOTYPES
#include <EGL/egl.h>
#include <EGL/eglext.h>
typedef EGLAPI EGLDisplay EGLAPIENTRY EGLGetDisplay(EGLNativeDisplayType display_id);
typedef EGLAPI EGLBoolean EGLAPIENTRY EGLInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor);
typedef EGLAPI EGLContext EGLAPIENTRY EGLGetCurrentContext(void);
typedef EGLAPI EGLSurface EGLAPIENTRY EGLGetCurrentSurface(EGLint readdraw);
class EGLThreadTest : public testing::Test
{
public:
virtual void SetUp() {}
virtual void TearDown() {}
EGLGetDisplay *mGetDisplay;
EGLInitialize *mInitialize;
EGLGetCurrentContext *mGetCurrentContext;
EGLGetCurrentSurface *mGetCurrentSurface;
EGLDisplay mDisplay;
HMODULE mEGL;
HMODULE mGLESv2;
static DWORD WINAPI ThreadingTestEntryPoint(LPVOID thisPointer);
private:
void ThreadingTest();
};
DWORD WINAPI EGLThreadTest::ThreadingTestEntryPoint(LPVOID lpParameter)
{
EGLThreadTest *test = (EGLThreadTest *)lpParameter;
test->ThreadingTest();
return 0;
}
void EGLThreadTest::ThreadingTest()
{
mEGL = LoadLibrary(L"libEGL.dll");
mGLESv2 = LoadLibrary(L"libGLESv2.dll");
EXPECT_TRUE(mEGL != NULL);
EXPECT_TRUE(mGLESv2 != NULL);
mGetDisplay = (EGLGetDisplay *)GetProcAddress(mEGL, "eglGetDisplay");
mInitialize = (EGLInitialize *)GetProcAddress(mEGL, "eglInitialize");
mGetCurrentContext = (EGLGetCurrentContext *)GetProcAddress(mEGL, "eglGetCurrentContext");
mGetCurrentSurface = (EGLGetCurrentSurface *)GetProcAddress(mEGL, "eglGetCurrentSurface");
EXPECT_TRUE(mGetDisplay != NULL);
EXPECT_TRUE(mInitialize != NULL);
EXPECT_TRUE(mGetCurrentContext != NULL);
EXPECT_TRUE(mGetCurrentSurface != NULL);
mDisplay = mGetDisplay(EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE);
EXPECT_TRUE(mDisplay!= EGL_NO_DISPLAY);
mInitialize(mDisplay, NULL, NULL);
mGetCurrentContext();
}
TEST_F(EGLThreadTest, thread_init_crash)
{
DWORD threadId;
HANDLE threadHandle = CreateThread(NULL, 0, EGLThreadTest::ThreadingTestEntryPoint, this, 0, &threadId);
EXPECT_TRUE(threadHandle != NULL);
// wait for signal from thread
DWORD waitResult = WaitForSingleObject(threadHandle, 1000);
EXPECT_EQ(waitResult, WAIT_OBJECT_0);
// crash, because the TLS value is NULL on main thread
mGetCurrentSurface(EGL_DRAW);
mGetCurrentContext();
}
\ No newline at end of file
//
// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#include "gmock/gmock.h"
#include "gtest/gtest.h"
int main(int argc, char** argv)
{
testing::InitGoogleMock(&argc, argv);
int rt = RUN_ALL_TESTS();
return rt;
}
...@@ -128,6 +128,26 @@ ...@@ -128,6 +128,26 @@
'<!@(python enumerate_files.py angle_tests -types *.cpp *.h)' '<!@(python enumerate_files.py angle_tests -types *.cpp *.h)'
], ],
}, },
{
'target_name': 'standalone_tests',
'type': 'executable',
'dependencies':
[
'gtest',
'gmock',
],
'include_dirs':
[
'../include',
'angle_tests',
'third_party/googletest/include',
'third_party/googlemock/include',
],
'sources':
[
'<!@(python enumerate_files.py standalone_tests -types *.cpp *.h)'
],
},
], ],
}], }],
], ],
......
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