summaryrefslogtreecommitdiffstats
path: root/tests/glx/create_context_unittest.cpp
diff options
context:
space:
mode:
authorIan Romanick <[email protected]>2011-12-15 18:45:27 -0800
committerIan Romanick <[email protected]>2012-01-02 12:41:45 -0800
commit3ef3ba4d2eee36f64062a21ce030c3f4d8c4cac4 (patch)
treecb7b3bc1f1946f49cf597abd5fae30035223e308 /tests/glx/create_context_unittest.cpp
parent8a4b36de05a133c1c9527836ca58bf8ebdf229bd (diff)
tests/glx: Add unit tests for GLX_ARB_create_context GLX protocol
This adds a new tests directory at the top-level and some extra build infrastructure. The tests use the Google C++ Testing Framework, and they will only be built if configure can detect its availability. The tests are automatically wired-in to run with 'make check'. Signed-off-by: Ian Romanick <[email protected]> Acked-by: Chad Versace <[email protected]>
Diffstat (limited to 'tests/glx/create_context_unittest.cpp')
-rw-r--r--tests/glx/create_context_unittest.cpp513
1 files changed, 513 insertions, 0 deletions
diff --git a/tests/glx/create_context_unittest.cpp b/tests/glx/create_context_unittest.cpp
new file mode 100644
index 00000000000..f97ec7ca5f2
--- /dev/null
+++ b/tests/glx/create_context_unittest.cpp
@@ -0,0 +1,513 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#include <gtest/gtest.h>
+#include <string.h>
+
+extern "C" {
+#include "glxclient.h"
+#include "glx_error.h"
+}
+
+#include <xcb/glx.h>
+#include "mock_xdisplay.h"
+#include "fake_glx_screen.h"
+
+static bool CreateContextAttribsARB_was_sent;
+static xcb_glx_create_context_attribs_arb_request_t req;
+static uint32_t sent_attribs[1024];
+static uint32_t next_id;
+
+
+struct glx_screen *psc;
+
+extern "C" Bool
+glx_context_init(struct glx_context *gc,
+ struct glx_screen *psc, struct glx_config *config)
+{
+ gc->majorOpcode = 123;
+ gc->screen = psc->scr;
+ gc->psc = psc;
+ gc->config = config;
+ gc->isDirect = GL_TRUE;
+ gc->currentContextTag = -1;
+
+ return GL_TRUE;
+}
+
+extern "C" struct glx_screen *
+GetGLXScreenConfigs(Display * dpy, int scrn)
+{
+ (void) dpy;
+ (void) scrn;
+ return psc;
+}
+
+extern "C" uint32_t
+xcb_generate_id(xcb_connection_t *c)
+{
+ (void) c;
+
+ return next_id++;
+}
+
+extern "C" xcb_void_cookie_t
+xcb_glx_create_context_attribs_arb_checked(xcb_connection_t *c,
+ xcb_glx_context_t context,
+ uint32_t fbconfig,
+ uint32_t screen,
+ uint32_t share_list,
+ uint8_t is_direct,
+ uint32_t num_attribs,
+ const uint32_t *attribs)
+{
+ (void) c;
+
+ CreateContextAttribsARB_was_sent = true;
+ req.context = context;
+ req.fbconfig = fbconfig;
+ req.screen = screen;
+ req.share_list = share_list;
+ req.is_direct = is_direct;
+ req.num_attribs = num_attribs;
+
+ if (num_attribs != 0 && attribs != NULL)
+ memcpy(sent_attribs, attribs, num_attribs * 2 * sizeof(uint32_t));
+
+ xcb_void_cookie_t cookie;
+ cookie.sequence = 0xbadc0de;
+
+ return cookie;
+}
+
+extern "C" xcb_generic_error_t *
+xcb_request_check(xcb_connection_t *c, xcb_void_cookie_t cookie)
+{
+ return NULL;
+}
+
+extern "C" void
+__glXSendErrorForXcb(Display * dpy, const xcb_generic_error_t *err)
+{
+}
+
+extern "C" void
+__glXSendError(Display * dpy, int_fast8_t errorCode, uint_fast32_t resourceID,
+ uint_fast16_t minorCode, bool coreX11error)
+{
+}
+
+class glXCreateContextAttribARB_test : public ::testing::Test {
+public:
+ virtual void SetUp();
+
+ /**
+ * Replace the existing screen with a direct-rendering screen
+ */
+ void use_direct_rendering_screen();
+
+ mock_XDisplay *dpy;
+ struct glx_config fbc;
+};
+
+void
+glXCreateContextAttribARB_test::SetUp()
+{
+ CreateContextAttribsARB_was_sent = false;
+ memset(&req, 0, sizeof(req));
+ next_id = 99;
+ fake_glx_context::contexts_allocated = 0;
+ psc = new fake_glx_screen(NULL, 0, "");
+
+ this->dpy = new mock_XDisplay(1);
+
+ memset(&this->fbc, 0, sizeof(this->fbc));
+ this->fbc.fbconfigID = 0xbeefcafe;
+}
+
+void
+glXCreateContextAttribARB_test::use_direct_rendering_screen()
+{
+ struct glx_screen *direct_psc =
+ new fake_glx_screen_direct(psc->display,
+ psc->scr,
+ psc->serverGLXexts);
+
+ delete psc;
+ psc = direct_psc;
+}
+
+/**
+ * \name Verify detection of client-side errors
+ */
+/*@{*/
+TEST_F(glXCreateContextAttribARB_test, NULL_display_returns_None)
+{
+ GLXContext ctx =
+ glXCreateContextAttribsARB(NULL, (GLXFBConfig) &this->fbc, 0,
+ False, NULL);
+
+ EXPECT_EQ(None, ctx);
+ EXPECT_EQ(0, fake_glx_context::contexts_allocated);
+}
+
+TEST_F(glXCreateContextAttribARB_test, NULL_fbconfig_returns_None)
+{
+ GLXContext ctx =
+ glXCreateContextAttribsARB(this->dpy, NULL, 0, False, NULL);
+
+ EXPECT_EQ(None, ctx);
+ EXPECT_EQ(0, fake_glx_context::contexts_allocated);
+}
+
+TEST_F(glXCreateContextAttribARB_test, NULL_screen_returns_None)
+{
+ delete psc;
+ psc = NULL;
+
+ GLXContext ctx =
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, NULL);
+
+ EXPECT_EQ(None, ctx);
+ EXPECT_EQ(0, fake_glx_context::contexts_allocated);
+}
+/*@}*/
+
+/**
+ * \name Verify that correct protocol bits are sent to the server.
+ */
+/*@{*/
+TEST_F(glXCreateContextAttribARB_test, does_send_protocol)
+{
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, NULL);
+
+ EXPECT_TRUE(CreateContextAttribsARB_was_sent);
+}
+
+TEST_F(glXCreateContextAttribARB_test, sent_correct_context)
+{
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, NULL);
+
+ EXPECT_EQ(99, req.context);
+}
+
+TEST_F(glXCreateContextAttribARB_test, sent_correct_fbconfig)
+{
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, NULL);
+
+ EXPECT_EQ(0xbeefcafe, req.fbconfig);
+}
+
+TEST_F(glXCreateContextAttribARB_test, sent_correct_share_list)
+{
+ GLXContext share =
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, NULL);
+
+ ASSERT_NE((GLXContext) 0, share);
+
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, share,
+ False, NULL);
+
+ struct glx_context *glx_ctx = (struct glx_context *) share;
+ EXPECT_EQ(glx_ctx->xid, req.share_list);
+}
+
+TEST_F(glXCreateContextAttribARB_test, sent_correct_is_direct_for_indirect_screen_and_direct_set_to_true)
+{
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ True, NULL);
+
+ EXPECT_FALSE(req.is_direct);
+}
+
+TEST_F(glXCreateContextAttribARB_test, sent_correct_is_direct_for_indirect_screen_and_direct_set_to_false)
+{
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, NULL);
+
+ EXPECT_FALSE(req.is_direct);
+}
+
+TEST_F(glXCreateContextAttribARB_test, sent_correct_is_direct_for_direct_screen_and_direct_set_to_true)
+{
+ this->use_direct_rendering_screen();
+
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ True, NULL);
+
+ EXPECT_TRUE(req.is_direct);
+}
+
+TEST_F(glXCreateContextAttribARB_test, sent_correct_is_direct_for_direct_screen_and_direct_set_to_false)
+{
+ this->use_direct_rendering_screen();
+
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, NULL);
+
+ EXPECT_FALSE(req.is_direct);
+}
+
+TEST_F(glXCreateContextAttribARB_test, sent_correct_screen)
+{
+ this->fbc.screen = 7;
+ psc->scr = 7;
+
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, NULL);
+
+ EXPECT_EQ(7, req.screen);
+}
+
+TEST_F(glXCreateContextAttribARB_test, sent_correct_num_attribs)
+{
+ /* Use zeros in the second half of each attribute pair to try and trick the
+ * implementation into termiating the list early.
+ *
+ * Use non-zero in the second half of the last attribute pair to try and
+ * trick the implementation into not terminating the list early enough.
+ */
+ static const int attribs[] = {
+ 1, 0,
+ 2, 0,
+ 3, 0,
+ 4, 0,
+ 0, 6,
+ 0, 0
+ };
+
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, attribs);
+
+ EXPECT_EQ(4, req.num_attribs);
+}
+
+TEST_F(glXCreateContextAttribARB_test, sent_correct_num_attribs_empty_list)
+{
+ static const int attribs[] = {
+ 0,
+ };
+
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, attribs);
+
+ EXPECT_EQ(0, req.num_attribs);
+}
+
+TEST_F(glXCreateContextAttribARB_test, sent_correct_num_attribs_NULL_list_pointer)
+{
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, NULL);
+
+ EXPECT_EQ(0, req.num_attribs);
+}
+
+TEST_F(glXCreateContextAttribARB_test, sent_correct_attrib_list)
+{
+ int attribs[] = {
+ GLX_RENDER_TYPE, GLX_RGBA_TYPE,
+ GLX_CONTEXT_MAJOR_VERSION_ARB, 1,
+ GLX_CONTEXT_MINOR_VERSION_ARB, 2,
+ 0
+ };
+
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, attribs);
+
+ for (unsigned i = 0; i < 6; i++) {
+ EXPECT_EQ(attribs[i], sent_attribs[i]);
+ }
+}
+/*@}*/
+
+/**
+ * \name Verify details of the returned GLXContext
+ */
+/*@{*/
+TEST_F(glXCreateContextAttribARB_test, correct_context)
+{
+ GLXContext ctx =
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, NULL);
+
+ /* Since the server did not return an error, the GLXContext should not be
+ * NULL.
+ */
+ EXPECT_NE((GLXContext)0, ctx);
+
+ /* It shouldn't be the XID of the context either.
+ */
+ EXPECT_NE((GLXContext)99, ctx);
+}
+
+TEST_F(glXCreateContextAttribARB_test, correct_context_xid)
+{
+ GLXContext ctx =
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, NULL);
+
+ /* Since the server did not return an error, the GLXContext should not be
+ * NULL.
+ */
+ ASSERT_NE((GLXContext)0, ctx);
+
+ struct glx_context *glx_ctx = (struct glx_context *) ctx;
+ EXPECT_EQ(99, glx_ctx->xid);
+}
+
+TEST_F(glXCreateContextAttribARB_test, correct_context_share_xid)
+{
+ GLXContext first =
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, NULL);
+
+ ASSERT_NE((GLXContext) 0, first);
+
+ GLXContext second =
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, first,
+ False, NULL);
+
+ ASSERT_NE((GLXContext) 0, second);
+
+ struct glx_context *share = (struct glx_context *) first;
+ struct glx_context *ctx = (struct glx_context *) second;
+ EXPECT_EQ(share->xid, ctx->share_xid);
+}
+
+TEST_F(glXCreateContextAttribARB_test, correct_context_isDirect_for_indirect_screen_and_direct_set_to_true)
+{
+ GLXContext ctx =
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ True, NULL);
+
+ ASSERT_NE((GLXContext) 0, ctx);
+
+ struct glx_context *gc = (struct glx_context *) ctx;
+
+ EXPECT_FALSE(gc->isDirect);
+}
+
+TEST_F(glXCreateContextAttribARB_test, correct_context_isDirect_for_indirect_screen_and_direct_set_to_false)
+{
+ GLXContext ctx =
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, NULL);
+
+ ASSERT_NE((GLXContext) 0, ctx);
+
+ struct glx_context *gc = (struct glx_context *) ctx;
+
+ EXPECT_FALSE(gc->isDirect);
+}
+
+TEST_F(glXCreateContextAttribARB_test, correct_context_isDirect_for_direct_screen_and_direct_set_to_true)
+{
+ this->use_direct_rendering_screen();
+
+ GLXContext ctx =
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ True, NULL);
+
+ ASSERT_NE((GLXContext) 0, ctx);
+
+ struct glx_context *gc = (struct glx_context *) ctx;
+
+ EXPECT_TRUE(gc->isDirect);
+}
+
+TEST_F(glXCreateContextAttribARB_test, correct_context_isDirect_for_direct_screen_and_direct_set_to_false)
+{
+ this->use_direct_rendering_screen();
+
+ GLXContext ctx =
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, NULL);
+
+ ASSERT_NE((GLXContext) 0, ctx);
+
+ struct glx_context *gc = (struct glx_context *) ctx;
+
+ EXPECT_FALSE(gc->isDirect);
+}
+
+TEST_F(glXCreateContextAttribARB_test, correct_indirect_context_client_state_private)
+{
+ GLXContext ctx =
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, NULL);
+
+ ASSERT_NE((GLXContext) 0, ctx);
+
+ struct glx_context *gc = (struct glx_context *) ctx;
+
+ ASSERT_FALSE(gc->isDirect);
+ EXPECT_EQ((struct __GLXattributeRec *) 0xcafebabe,
+ gc->client_state_private);
+}
+
+TEST_F(glXCreateContextAttribARB_test, correct_indirect_context_config)
+{
+ GLXContext ctx =
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, NULL);
+
+ ASSERT_NE((GLXContext) 0, ctx);
+
+ struct glx_context *gc = (struct glx_context *) ctx;
+
+ EXPECT_EQ(&this->fbc, gc->config);
+}
+
+TEST_F(glXCreateContextAttribARB_test, correct_context_screen_number)
+{
+ this->fbc.screen = 7;
+ psc->scr = 7;
+
+ GLXContext ctx =
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, NULL);
+
+ ASSERT_NE((GLXContext) 0, ctx);
+
+ struct glx_context *gc = (struct glx_context *) ctx;
+
+ EXPECT_EQ(7, gc->screen);
+}
+
+TEST_F(glXCreateContextAttribARB_test, correct_context_screen_pointer)
+{
+ GLXContext ctx =
+ glXCreateContextAttribsARB(this->dpy, (GLXFBConfig) &this->fbc, 0,
+ False, NULL);
+
+ ASSERT_NE((GLXContext) 0, ctx);
+
+ struct glx_context *gc = (struct glx_context *) ctx;
+
+ EXPECT_EQ(psc, gc->psc);
+}
+/*@}*/