/*-------------------------------------------------------------------------
 * OpenGL Conformance Test Suite
 * -----------------------------
 *
 * Copyright (c) 2015-2018 The Khronos Group Inc.
 *
 * 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.
 *
 */ /*!
 * \file
 * \brief
 */ /*-------------------------------------------------------------------*/

/**
 * \file  glcKHRDebugTests.cpp
 * \brief Implements conformance tests for "KHR Debug" functionality.
 */ /*-------------------------------------------------------------------*/

#include "glcKHRDebugTests.hpp"

#include "gluPlatform.hpp"
#include "gluRenderConfig.hpp"
#include "gluRenderContext.hpp"
#include "gluStrUtil.hpp"
#include "glwEnums.hpp"
#include "glwFunctions.hpp"
#include "tcuCommandLine.hpp"
#include "tcuTestLog.hpp"
//
//#include <string>

#define DEBUG_ENBALE_MESSAGE_CALLBACK 0

#if DEBUG_ENBALE_MESSAGE_CALLBACK
//#include <iomanip>
#endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */

using namespace glw;

namespace glcts
{
namespace KHRDebug
{
/** Macro, verifies generated error, logs error message and throws failure
 *
 * @param expected_error Expected error value
 * @param error_message  Message logged if generated error is not the expected one
 **/
#define CHECK_ERROR(expected_error, error_message)                                                      \
	do {                                                                                                \
		GLenum generated_error = m_gl->getError();                                                      \
                                                                                                        \
		if (expected_error != generated_error)                                                          \
		{                                                                                               \
			m_testCtx.getLog()                                                                          \
				<< tcu::TestLog::Message << "File: " << __FILE__ << ", line: " << __LINE__              \
				<< ". Got wrong error: " << glu::getErrorStr(generated_error)                           \
				<< ", expected: " << glu::getErrorStr(expected_error) << ", message: " << error_message \
				<< tcu::TestLog::EndMessage;                                                            \
			TestBase::done();                                                                           \
			TCU_FAIL("Invalid error generated");                                                        \
		}                                                                                               \
	} while (0)

/** Pop all groups from stack
 *
 * @param gl GL functions
 **/
void cleanGroupStack(const Functions* gl)
{
	while (1)
	{
		gl->popDebugGroup();

		const GLenum err = gl->getError();

		if (GL_STACK_UNDERFLOW == err)
		{
			break;
		}

		GLU_EXPECT_NO_ERROR(err, "PopDebugGroup");
	}
}

/** Extracts all messages from log
 *
 * @param gl GL functions
 **/
void cleanMessageLog(const Functions* gl)
{
	static const GLuint count = 16;

	while (1)
	{
		GLuint ret = gl->getDebugMessageLog(count /* count */, 0 /* bufSize */, 0 /* sources */, 0 /* types */,
											0 /* ids */, 0 /* severities */, 0 /* lengths */, 0 /* messageLog */);

		GLU_EXPECT_NO_ERROR(gl->getError(), "GetDebugMessageLog");

		if (0 == ret)
		{
			break;
		}
	}
}

/** Fill stack of groups
 *
 * @param gl GL functions
 **/
void fillGroupStack(const Functions* gl)
{
	static const GLchar  message[] = "Foo";
	static const GLsizei length	= (GLsizei)(sizeof(message) / sizeof(message[0]));

	while (1)
	{
		gl->pushDebugGroup(GL_DEBUG_SOURCE_APPLICATION /* source */, 1 /* id */, length /* length */,
						   message /* message */);

		const GLenum err = gl->getError();

		if (GL_STACK_OVERFLOW == err)
		{
			break;
		}

		GLU_EXPECT_NO_ERROR(err, "PopDebugGroup");
	}
}

/** Constructor
 * Creates and set as current new context that should be used by test.
 *
 * @param testCtx  Test context
 * @param is_debug Selects if debug or non-debug context should be created
 **/
TestBase::TestBase(tcu::TestContext& testContext, glu::ApiType apiType, bool is_debug)
	: m_gl(0), m_is_debug(is_debug), m_rc(0), m_testContext(testContext), m_apiType(apiType)
{
	/* Nothing to be done here */
}

/** Destructor
 * Destroys context used by test and set original context as current
 **/
TestBase::~TestBase()
{
	if (0 != m_rc)
	{
		done();
	}
}

/** Initialize rendering context
 **/
void TestBase::init()
{
	if (true == m_is_debug)
	{
		initDebug();
	}
	else
	{
		initNonDebug();
	}

	/* Get functions */
	m_gl = &m_rc->getFunctions();
}

/** Prepares debug context
 **/
void TestBase::initDebug()
{
	tcu::Platform&	platform = m_testContext.getPlatform();
	glu::RenderConfig renderCfg(glu::ContextType(m_apiType, glu::CONTEXT_DEBUG));

	const tcu::CommandLine& commandLine = m_testContext.getCommandLine();
	parseRenderConfig(&renderCfg, commandLine);

	if (commandLine.getSurfaceType() != tcu::SURFACETYPE_WINDOW)
		throw tcu::NotSupportedError("Test not supported in non-windowed context");

	m_rc = createRenderContext(platform, commandLine, renderCfg);
	m_rc->makeCurrent();
}

/** Prepares non-debug context
 **/
void TestBase::initNonDebug()
{
	tcu::Platform&	platform = m_testContext.getPlatform();
	glu::RenderConfig renderCfg(glu::ContextType(m_apiType, glu::ContextFlags(0)));

	const tcu::CommandLine& commandLine = m_testContext.getCommandLine();
	parseRenderConfig(&renderCfg, commandLine);

	if (commandLine.getSurfaceType() != tcu::SURFACETYPE_WINDOW)
		throw tcu::NotSupportedError("Test not supported in non-windowed context");

	m_rc = createRenderContext(platform, commandLine, renderCfg);
	m_rc->makeCurrent();
}

/** Finalize rendering context
 **/
void TestBase::done()
{
	/* Delete context used by test and make no context current */
	delete m_rc;

	m_rc = 0;
	m_gl = 0;
}

/** Constructor
 *
 * @param testCtx  Test context
 * @param is_debug Selects if debug or non-debug context should be used
 * @param name     Name of test
 **/
APIErrorsTest::APIErrorsTest(tcu::TestContext& testCtx, glu::ApiType apiType, bool is_debug, const GLchar* name)
	: TestBase(testCtx, apiType, is_debug), TestCase(testCtx, name, "Verifies that errors are generated as expected")
{
	/* Nothing to be done */
}

/** Execute test
 *
 * @return tcu::TestNode::STOP
 **/
tcu::TestNode::IterateResult APIErrorsTest::iterate()
{
	/* Initialize rendering context */
	TestBase::init();

	/* Get maximum label length */
	GLint max_label = 0;

	m_gl->getIntegerv(GL_MAX_LABEL_LENGTH, &max_label);
	GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetIntegerv");

	/* Prepare too long label */
	std::vector<GLchar> too_long_label;

	too_long_label.resize(max_label + 2);

	for (GLint i = 0; i <= max_label; ++i)
	{
		too_long_label[i] = 'f';
	}

	too_long_label[max_label + 1] = 0;

	/* Get maximum message length */
	GLint max_length = 0;

	m_gl->getIntegerv(GL_MAX_DEBUG_MESSAGE_LENGTH, &max_length);
	GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetIntegerv");

	/* Prepare too long message */
	std::vector<GLchar> too_long_message;

	too_long_message.resize(max_length + 2);

	for (GLint i = 0; i <= max_length; ++i)
	{
		too_long_message[i] = 'f';
	}

	too_long_message[max_length + 1] = 0;

	/* Get maximum number of groups on stack */
	GLint max_groups = 0;

	m_gl->getIntegerv(GL_MAX_DEBUG_GROUP_STACK_DEPTH, &max_groups);
	GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetIntegerv");

	/*
	 * DebugMessageControl function should generate:
	 * - INVALID_ENUM when <source> is invalid;
	 * - INVALID_ENUM when <type> is invalid;
	 * - INVALID_ENUM when <severity> is invalid;
	 * - INVALID_VALUE when <count> is negative;
	 * - INVALID_OPERATION when <count> is not zero and <source> is DONT_CARE;
	 * - INVALID_OPERATION when <count> is not zero and <type> is DONT_CARE;
	 * - INVALID_OPERATION when <count> is not zero and <severity> is not
	 * DONT_CARE.
	 */
	{
		static const GLuint  ids[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
		static const GLsizei n_ids = (GLsizei)(sizeof(ids) / sizeof(ids[0]));

		m_gl->debugMessageControl(GL_ARRAY_BUFFER /* source */, GL_DEBUG_TYPE_ERROR /* type */,
								  GL_DEBUG_SEVERITY_LOW /* severity */, 0 /* count */, 0 /* ids */,
								  GL_TRUE /* enabled */);
		CHECK_ERROR(GL_INVALID_ENUM, "DebugMessageControl with <source> set to GL_ARRAY_BUFFER");

		m_gl->debugMessageControl(GL_DEBUG_SOURCE_API /* source */, GL_ARRAY_BUFFER /* type */,
								  GL_DEBUG_SEVERITY_LOW /* severity */, 0 /* count */, 0 /* ids */,
								  GL_TRUE /* enabled */);
		CHECK_ERROR(GL_INVALID_ENUM, "DebugMessageControl with <type> set to GL_ARRAY_BUFFER");

		m_gl->debugMessageControl(GL_DEBUG_SOURCE_API /* source */, GL_DEBUG_TYPE_ERROR /* type */,
								  GL_ARRAY_BUFFER /* severity */, 0 /* count */, 0 /* ids */, GL_TRUE /* enabled */);
		CHECK_ERROR(GL_INVALID_ENUM, "DebugMessageControl with <severity> set to GL_ARRAY_BUFFER");

		m_gl->debugMessageControl(GL_DEBUG_SOURCE_API /* source */, GL_DEBUG_TYPE_ERROR /* type */,
								  GL_DEBUG_SEVERITY_LOW /* severity */, -1 /* count */, ids /* ids */,
								  GL_TRUE /* enabled */);
		CHECK_ERROR(GL_INVALID_VALUE, "DebugMessageControl with <count> set to -1");

		m_gl->debugMessageControl(GL_DONT_CARE /* source */, GL_DEBUG_TYPE_ERROR /* type */,
								  GL_DONT_CARE /* severity */, n_ids /* count */, ids /* ids */, GL_TRUE /* enabled */);
		CHECK_ERROR(GL_INVALID_OPERATION, "DebugMessageControl with <source> set to GL_DONT_CARE and non zero <count>");

		m_gl->debugMessageControl(GL_DEBUG_SOURCE_API /* source */, GL_DONT_CARE /* type */,
								  GL_DONT_CARE /* severity */, n_ids /* count */, ids /* ids */, GL_TRUE /* enabled */);
		CHECK_ERROR(GL_INVALID_OPERATION, "DebugMessageControl with <type> set to GL_DONT_CARE and non zero <count>");

		m_gl->debugMessageControl(GL_DEBUG_SOURCE_API /* source */, GL_DEBUG_TYPE_ERROR /* type */,
								  GL_DEBUG_SEVERITY_LOW /* severity */, n_ids /* count */, ids /* ids */,
								  GL_TRUE /* enabled */);
		CHECK_ERROR(GL_INVALID_OPERATION,
					"DebugMessageControl with <severity> set to GL_DEBUG_SEVERITY_LOW and non zero <count>");
	}

	/*
	 * GetDebugMessageLog function should generate:
	 * - INVALID_VALUE when <bufSize> is negative and messageLog is not NULL.
	 */
	{
		static const GLsizei bufSize = 32;
		static const GLuint  count   = 4;

		GLenum  ids[count];
		GLsizei lengths[count];
		GLchar  messageLog[bufSize];
		GLenum  types[count];
		GLenum  severities[count];
		GLenum  sources[count];

		m_gl->getDebugMessageLog(count /* count */, -1 /* bufSize */, sources, types, ids, severities, lengths,
								 messageLog);
		CHECK_ERROR(GL_INVALID_VALUE, "GetDebugMessageLog with <bufSize> set to -1");
	}

	/*
	 * DebugMessageInsert function should generate:
	 * - INVALID_ENUM when <source> is not DEBUG_SOURCE_APPLICATION or
	 * DEBUG_SOURCE_THIRD_PARTY;
	 * - INVALID_ENUM when <type> is invalid;
	 * - INVALID_ENUM when <severity> is invalid;
	 * - INVALID_VALUE when length of string <buf> is not less than
	 * MAX_DEBUG_MESSAGE_LENGTH.
	 */
	{
		static const GLchar  message[] = "Foo";
		static const GLsizei length	= (GLsizei)(sizeof(message) / sizeof(message[0]));

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_API /* source */, GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR /* type */,
								 0 /* id */, GL_DEBUG_SEVERITY_LOW /* severity */, length /* length */,
								 message /* message */);
		CHECK_ERROR(GL_INVALID_ENUM, "DebugMessageInsert with <source> set to GL_DEBUG_SOURCE_API");

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_ARRAY_BUFFER /* type */, 0 /* id */,
								 GL_DEBUG_SEVERITY_LOW /* severity */, length /* length */, message /* message */);
		CHECK_ERROR(GL_INVALID_ENUM, "DebugMessageInsert with <type> set to GL_ARRAY_BUFFER");

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR /* type */,
								 0 /* id */, GL_ARRAY_BUFFER /* severity */, length /* length */,
								 message /* message */);
		CHECK_ERROR(GL_INVALID_ENUM, "DebugMessageInsert with <severity> set to GL_ARRAY_BUFFER");

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR /* type */,
								 0 /* id */, GL_DEBUG_SEVERITY_LOW /* severity */, max_length + 1 /* length */,
								 message /* message */);
		CHECK_ERROR(GL_INVALID_VALUE, "DebugMessageInsert with <length> set to GL_MAX_DEBUG_MESSAGE_LENGTH + 1");

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR /* type */,
								 0 /* id */, GL_DEBUG_SEVERITY_LOW /* severity */, -1 /* length */,
								 &too_long_message[0] /* message */);
		CHECK_ERROR(GL_INVALID_VALUE, "DebugMessageInsert with too long message");
	}

	/*
	 * PushDebugGroup function should generate:
	 * - INVALID_ENUM when <source> is not DEBUG_SOURCE_APPLICATION or
	 * DEBUG_SOURCE_THIRD_PARTY;
	 * - INVALID_VALUE when length of string <message> is not less than
	 * MAX_DEBUG_MESSAGE_LENGTH;
	 * - STACK_OVERFLOW when stack contains MAX_DEBUG_GROUP_STACK_DEPTH entries.
	 */
	{
		static const GLchar  message[] = "Foo";
		static const GLsizei length	= (GLsizei)(sizeof(message) / sizeof(message[0]));

		m_gl->pushDebugGroup(GL_DEBUG_SOURCE_API /* source */, 1 /* id */, length /* length */, message /* message */);
		CHECK_ERROR(GL_INVALID_ENUM, "PushDebugGroup with <source> set to GL_DEBUG_SOURCE_API");

		m_gl->pushDebugGroup(GL_DEBUG_SOURCE_APPLICATION /* source */, 1 /* id */, max_length + 1 /* length */,
							 message /* message */);
		CHECK_ERROR(GL_INVALID_VALUE, "PushDebugGroup with <length> set to GL_MAX_DEBUG_MESSAGE_LENGTH + 1");

		m_gl->pushDebugGroup(GL_DEBUG_SOURCE_APPLICATION /* source */, 1 /* id */, -1 /* length */,
							 &too_long_message[0] /* message */);
		CHECK_ERROR(GL_INVALID_VALUE, "PushDebugGroup with too long message");

		/* Clean stack */
		cleanGroupStack(m_gl);

		/* Fill stack */
		for (GLint i = 0; i < max_groups - 1; ++i)
		{
			m_gl->pushDebugGroup(GL_DEBUG_SOURCE_APPLICATION /* source */, 1 /* id */, length /* length */,
								 message /* message */);
			GLU_EXPECT_NO_ERROR(m_gl->getError(), "PushDebugGroup");
		}

		/* Overflow stack */
		m_gl->pushDebugGroup(GL_DEBUG_SOURCE_APPLICATION /* source */, 1 /* id */, length /* length */,
							 message /* message */);
		CHECK_ERROR(GL_STACK_OVERFLOW, "PushDebugGroup called GL_MAX_DEBUG_GROUP_STACK_DEPTH times");

		/* Clean stack */
		cleanGroupStack(m_gl);
	}

	/*
	 * PopDebugGroup function should generate:
	 * - STACK_UNDERFLOW when stack contains no entries.
	 */
	{
		fillGroupStack(m_gl);

		for (GLint i = 0; i < max_groups - 1; ++i)
		{
			m_gl->popDebugGroup();

			GLU_EXPECT_NO_ERROR(m_gl->getError(), "PopDebugGroup");
		}

		m_gl->popDebugGroup();
		CHECK_ERROR(GL_STACK_UNDERFLOW, "PopDebugGroup called GL_MAX_DEBUG_GROUP_STACK_DEPTH times");
	}

	/*
	 * ObjectLabel function should generate:
	 * - INVALID_ENUM when <identifier> is invalid;
	 * - INVALID_VALUE when if <name> is not valid object name of type specified by
	 * <identifier>;
	 * - INVALID_VALUE when length of string <label> is not less than
	 * MAX_LABEL_LENGTH.
	 */
	{
		static const GLchar  label[] = "Foo";
		static const GLsizei length  = (GLsizei)(sizeof(label) / sizeof(label[0]));

		GLuint texture_id = 0;
		GLuint invalid_id = 1;
		m_gl->genTextures(1, &texture_id);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "GenTextures");
		m_gl->bindTexture(GL_TEXTURE_BUFFER, texture_id);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "BindTexture");

		try
		{
			m_gl->objectLabel(GL_TEXTURE_BUFFER /* identifier */, texture_id /* name */, length /* length */,
							  label /* label */);
			CHECK_ERROR(GL_INVALID_ENUM, "ObjectLabel with <identifier> set to GL_TEXTURE_BUFFER");

			while (GL_TRUE == m_gl->isTexture(invalid_id))
			{
				invalid_id += 1;
			}

			m_gl->objectLabel(GL_TEXTURE /* identifier */, invalid_id /* name */, length /* length */,
							  label /* label */);
			CHECK_ERROR(GL_INVALID_VALUE, "ObjectLabel with <name> set to not generated value");

			m_gl->objectLabel(GL_TEXTURE /* identifier */, texture_id /* name */, max_label + 1 /* length */,
							  label /* label */);
			CHECK_ERROR(GL_INVALID_VALUE, "ObjectLabel with <label> set to MAX_LABEL_LENGTH + 1");

			m_gl->objectLabel(GL_TEXTURE /* identifier */, texture_id /* name */, -1 /* length */,
							  &too_long_label[0] /* label */);
			CHECK_ERROR(GL_INVALID_VALUE, "ObjectLabel with too long label");
		}
		catch (const std::exception& exc)
		{
			m_gl->deleteTextures(1, &texture_id);
			TCU_FAIL(exc.what());
		}

		m_gl->deleteTextures(1, &texture_id);
	}

	/*
	 * GetObjectLabel function should generate:
	 * - INVALID_ENUM when <identifier> is invalid;
	 * - INVALID_VALUE when if <name> is not valid object name of type specified by
	 * <identifier>;
	 * - INVALID_VALUE when <bufSize> is negative.
	 */
	{
		static const GLsizei bufSize = 32;

		GLchar  label[bufSize];
		GLsizei length = 0;

		GLuint texture_id = 0;
		GLuint invalid_id = 1;
		m_gl->genTextures(1, &texture_id);
		m_gl->bindTexture(GL_TEXTURE_2D, texture_id);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "GenTextures");

		try
		{
			m_gl->getObjectLabel(GL_TEXTURE_BUFFER /* identifier */, texture_id /* name */, bufSize /* bufSize */,
								 &length /* length */, label /* label */);
			CHECK_ERROR(GL_INVALID_ENUM, "GetObjectLabel with <identifier> set to GL_TEXTURE_BUFFER");

			while (GL_TRUE == m_gl->isTexture(invalid_id))
			{
				invalid_id += 1;
			}

			m_gl->getObjectLabel(GL_TEXTURE /* identifier */, invalid_id /* name */, bufSize /* bufSize */,
								 &length /* length */, label /* label */);
			CHECK_ERROR(GL_INVALID_VALUE, "GetObjectLabel with <name> set to not generated value");

			m_gl->getObjectLabel(GL_TEXTURE /* identifier */, invalid_id /* name */, -1 /* bufSize */,
								 &length /* length */, label /* label */);
			CHECK_ERROR(GL_INVALID_VALUE, "GetObjectLabel with <bufSize> set to -1");
		}
		catch (const std::exception& exc)
		{
			m_gl->deleteTextures(1, &texture_id);
			TCU_FAIL(exc.what());
		}

		m_gl->deleteTextures(1, &texture_id);
	}

	/*
	 * ObjectPtrLabel function should generate:
	 * - INVALID_VALUE when <ptr> is not the name of sync object;
	 * - INVALID_VALUE when length of string <label> is not less than
	 * MAX_LABEL_LENGTH.
	 */
	{
		static const GLchar  label[] = "Foo";
		static const GLsizei length  = (GLsizei)(sizeof(label) / sizeof(label[0]));

		GLsync sync_id	= 0;
		GLsync invalid_id = 0;
		sync_id			  = m_gl->fenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "FenceSync");

		try
		{
			while (GL_TRUE == m_gl->isSync(invalid_id))
			{
				invalid_id = (GLsync)(((unsigned long long)invalid_id) + 1);
			}

			m_gl->objectPtrLabel(invalid_id /* name */, length /* length */, label /* label */);
			CHECK_ERROR(GL_INVALID_VALUE, "ObjectPtrLabel with <ptr> set to not generated value");

			m_gl->objectPtrLabel(sync_id /* name */, max_label + 1 /* length */, label /* label */);
			CHECK_ERROR(GL_INVALID_VALUE, "ObjectPtrLabel with <length> set to MAX_LABEL_LENGTH + 1");

			m_gl->objectPtrLabel(sync_id /* name */, -1 /* length */, &too_long_label[0] /* label */);
			CHECK_ERROR(GL_INVALID_VALUE, "ObjectPtrLabel with too long label");
		}
		catch (const std::exception& exc)
		{
			m_gl->deleteSync(sync_id);
			TCU_FAIL(exc.what());
		}

		m_gl->deleteSync(sync_id);
	}

	/*
	 * GetObjectPtrLabel function should generate:
	 * - INVALID_VALUE when <ptr> is not the name of sync object;
	 * - INVALID_VALUE when <bufSize> is negative.
	 */
	{
		static const GLsizei bufSize = 32;

		GLchar  label[bufSize];
		GLsizei length = 0;

		GLsync sync_id	= 0;
		GLsync invalid_id = 0;
		sync_id			  = m_gl->fenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "FenceSync");

		try
		{
			while (GL_TRUE == m_gl->isSync(invalid_id))
			{
				invalid_id = (GLsync)(((unsigned long long)invalid_id) + 1);
			}

			m_gl->getObjectPtrLabel(invalid_id /* name */, bufSize /* bufSize */, &length /* length */,
									label /* label */);
			CHECK_ERROR(GL_INVALID_VALUE, "GetObjectPtrLabel with <ptr> set to not generated value");

			m_gl->getObjectPtrLabel(sync_id /* name */, -1 /* bufSize */, &length /* length */, label /* label */);
			CHECK_ERROR(GL_INVALID_VALUE, "GetObjectPtrLabel with <bufSize> set to -1");
		}
		catch (const std::exception& exc)
		{
			m_gl->deleteSync(sync_id);
			TCU_FAIL(exc.what());
		}

		m_gl->deleteSync(sync_id);
	}

	/*
	 * GetPointerv function should generate:
	 * - INVALID_ENUM when <pname> is invalid.
	 **/
	{
		GLuint  uint;
		GLuint* uint_ptr = &uint;

		m_gl->getPointerv(GL_ARRAY_BUFFER, (GLvoid**)&uint_ptr);
		CHECK_ERROR(GL_INVALID_ENUM, "GetPointerv with <pname> set to GL_ARRAY_BUFFER");
	}

	/* Set result */
	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");

	/* Done */
	TestBase::done();

	return tcu::TestNode::STOP;
}

/** Constructor
 *
 * @param testCtx  Test context
 * @param is_debug Selects if debug or non-debug context should be used
 * @param name     Name of test
 **/
LabelsTest::LabelsTest(tcu::TestContext& testCtx, glu::ApiType apiType, bool is_debug, const GLchar* name)
	: TestCase(testCtx, name, "Verifies that labels can be assigned and queried"), TestBase(testCtx, apiType, is_debug)
{
	/* Nothing to be done */
}

/** Represnets case for LabelsTest **/
struct labelsTestCase
{
	GLenum m_identifier;
	GLuint (*m_create)(const glw::Functions* gl, const glu::RenderContext*);
	GLvoid (*m_destroy)(const glw::Functions* gl, GLuint id);
	const GLchar* m_name;
};

/** Execute test
 *
 * @return tcu::TestNode::STOP
 **/
tcu::TestNode::IterateResult LabelsTest::iterate()
{
	static const labelsTestCase test_cases[] = {
		{ GL_BUFFER, createBuffer, deleteBuffer, "Buffer" },
		{ GL_FRAMEBUFFER, createFramebuffer, deleteFramebuffer, "Framebuffer" },
		{ GL_PROGRAM, createProgram, deleteProgram, "Program" },
		{ GL_PROGRAM_PIPELINE, createProgramPipeline, deleteProgramPipeline, "ProgramPipeline" },
		{ GL_QUERY, createQuery, deleteQuery, "Query" },
		{ GL_RENDERBUFFER, createRenderbuffer, deleteRenderbuffer, "Renderbuffer" },
		{ GL_SAMPLER, createSampler, deleteSampler, "Sampler" },
		{ GL_SHADER, createShader, deleteShader, "Shader" },
		{ GL_TEXTURE, createTexture, deleteTexture, "Texture" },
		{ GL_TRANSFORM_FEEDBACK, createTransformFeedback, deleteTransformFeedback, "TransformFeedback" },
		{ GL_VERTEX_ARRAY, createVertexArray, deleteVertexArray, "VertexArray" },
	};

	static const size_t n_test_cases = sizeof(test_cases) / sizeof(test_cases[0]);

	static const GLsizei bufSize	  = 32;
	static const GLchar  label[]	  = "foo";
	static const GLsizei label_length = (GLsizei)(sizeof(label) / sizeof(label[0]) - 1);

	/* Initialize render context */
	TestBase::init();

	/* For each test case */
	for (size_t test_case_index = 0; test_case_index < n_test_cases; ++test_case_index)
	{
		const labelsTestCase& test_case = test_cases[test_case_index];

		const GLenum identifier = test_case.m_identifier;
		const GLuint id			= test_case.m_create(m_gl, m_rc);

		try
		{
			GLchar  buffer[bufSize] = "HelloWorld";
			GLsizei length;

			/*
			 * - query label; It is expected that result will be an empty string and length
			 * will be zero;
			 */
			m_gl->getObjectLabel(identifier, id, bufSize, &length, buffer);
			GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetObjectLabel");

			if (0 != length)
			{
				TCU_FAIL("Just created object has label of length != 0");
			}

			if (0 != buffer[0])
			{
				TCU_FAIL("Just created object has not empty label");
			}

			/*
			 * - assign label to object;
			 * - query label; It is expected that result will be equal to the provided
			 * label and length will be correct;
			 */
			m_gl->objectLabel(identifier, id, -1 /* length */, label);
			GLU_EXPECT_NO_ERROR(m_gl->getError(), "ObjectLabel");

			m_gl->getObjectLabel(identifier, id, bufSize, &length, buffer);
			GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetObjectLabel");

			if (label_length != length)
			{
				TCU_FAIL("Length is different than length of set label");
			}

			if (0 != strcmp(buffer, label))
			{
				TCU_FAIL("Different label returned");
			}

			/*
			 * - query length only; Correct value is expected;
			 */
			length = 0;

			m_gl->getObjectLabel(identifier, id, 0 /* bufSize */, &length, 0 /* label */);
			GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetObjectLabel");

			if (label_length != length)
			{
				TCU_FAIL("Invalid length returned when label and bufSize are set to 0");
			}

			/*
			 * - query label with <bufSize> less than actual length of label; It is
			 * expected that only <bufSize> characters will be stored in buffer (including
			 * NULL);
			 */
			length = 0;
			strcpy(buffer, "HelloWorld");

			m_gl->getObjectLabel(identifier, id, 2 /* bufSize */, &length, buffer);
			GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetObjectLabel");

			if (buffer[0] != label[0])
			{
				TCU_FAIL("Different label returned");
			}

			if (buffer[1] != 0)
			{
				TCU_FAIL("GetObjectLabel did not stored NULL at the end of string");
			}

			if (buffer[2] != 'l')
			{
				TCU_FAIL("GetObjectLabel overflowed buffer");
			}

			/*
			 * - query label with <bufSize> equal zero; It is expected that buffer contents
			 * will not be modified;
			 */
			length = 0;
			strcpy(buffer, "HelloWorld");

			m_gl->getObjectLabel(identifier, id, 0 /* bufSize */, &length, buffer);
			GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetObjectLabel");

			if (0 != strcmp(buffer, "HelloWorld"))
			{
				TCU_FAIL("GetObjectLabel modified buffer, bufSize set to 0");
			}

			/*
			 * - assign empty string as label to object;
			 * - query label, it is expected that result will be an empty string and length
			 * will be zero;
			 */
			m_gl->objectLabel(identifier, id, -1 /* length */, "");
			GLU_EXPECT_NO_ERROR(m_gl->getError(), "ObjectLabel");

			m_gl->getObjectLabel(identifier, id, bufSize, &length, buffer);
			GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetObjectLabel");

			if (0 != length)
			{
				TCU_FAIL("Label length is != 0, empty string was set");
			}

			if (0 != buffer[0])
			{
				TCU_FAIL("Non empty label returned, empty string was set");
			}

			/*
			 * - assign NULL as label to object;
			 * - query label, it is expected that result will be an empty string and length
			 * will be zero;
			 */
			m_gl->objectLabel(identifier, id, 2, 0 /* label */);
			GLU_EXPECT_NO_ERROR(m_gl->getError(), "ObjectLabel");

			m_gl->getObjectLabel(identifier, id, bufSize, &length, buffer);
			GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetObjectLabel");

			if (0 != length)
			{
				TCU_FAIL("Label length is != 0, label was removed");
			}

			if (0 != buffer[0])
			{
				TCU_FAIL("Different label returned, label was removed");
			}
		}
		catch (const std::exception& exc)
		{
			test_case.m_destroy(m_gl, id);

			m_testCtx.getLog()
				<< tcu::TestLog::Message << "Error during test case: " << test_case.m_name << tcu::TestLog::EndMessage;

			TCU_FAIL(exc.what());
		}

		test_case.m_destroy(m_gl, id);
	}

	/* Set result */
	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");

	/* Done */
	TestBase::done();

	return tcu::TestNode::STOP;
}

/** Create buffer
 *
 * @param gl GL functions
 *
 * @return ID of created resource
 **/
GLuint LabelsTest::createBuffer(const Functions* gl, const glu::RenderContext* rc)
{
	GLuint id = 0;

	if (glu::contextSupports(rc->getType(), glu::ApiType::core(4, 5)))
	{
		gl->createBuffers(1, &id);
		GLU_EXPECT_NO_ERROR(gl->getError(), "CreateBuffers");
	}
	else
	{
		gl->genBuffers(1, &id);
		gl->bindBuffer(GL_ARRAY_BUFFER, id);
		GLU_EXPECT_NO_ERROR(gl->getError(), "GenBuffers");
	}

	return id;
}

/** Create FBO
 *
 * @param gl GL functions
 *
 * @return ID of created resource
 **/
GLuint LabelsTest::createFramebuffer(const Functions* gl, const glu::RenderContext* rc)
{
	GLuint id = 0;
	if (glu::contextSupports(rc->getType(), glu::ApiType::core(4, 5)))
	{
		gl->createFramebuffers(1, &id);
		GLU_EXPECT_NO_ERROR(gl->getError(), "CreateFramebuffers");
	}
	else
	{
		GLint currentFbo;
		gl->getIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &currentFbo);
		gl->genFramebuffers(1, &id);
		gl->bindFramebuffer(GL_DRAW_FRAMEBUFFER, id);
		gl->bindFramebuffer(GL_DRAW_FRAMEBUFFER, currentFbo);
		GLU_EXPECT_NO_ERROR(gl->getError(), "GenFramebuffers / BindFramebuffer");
	}

	return id;
}

/** Create program
 *
 * @param gl GL functions
 *
 * @return ID of created resource
 **/
GLuint LabelsTest::createProgram(const Functions* gl, const glu::RenderContext*)
{
	GLuint id = gl->createProgram();
	GLU_EXPECT_NO_ERROR(gl->getError(), "CreateProgram");

	return id;
}

/** Create pipeline
 *
 * @param gl GL functions
 *
 * @return ID of created resource
 **/
GLuint LabelsTest::createProgramPipeline(const Functions* gl, const glu::RenderContext* rc)
{
	GLuint id = 0;
	if (glu::contextSupports(rc->getType(), glu::ApiType::core(4, 5)))
	{
		gl->createProgramPipelines(1, &id);
		GLU_EXPECT_NO_ERROR(gl->getError(), "CreateProgramPipelines");
	}
	else
	{
		gl->genProgramPipelines(1, &id);
		gl->bindProgramPipeline(id);
		GLU_EXPECT_NO_ERROR(gl->getError(), "GenProgramPipelines / BindProgramPipeline");
	}

	return id;
}

/** Create query
 *
 * @param gl GL functions
 *
 * @return ID of created resource
 **/
GLuint LabelsTest::createQuery(const Functions* gl, const glu::RenderContext* rc)
{
	GLuint id = 0;
	if (glu::contextSupports(rc->getType(), glu::ApiType::core(4, 5)))
	{
		gl->createQueries(GL_TIMESTAMP, 1, &id);
		GLU_EXPECT_NO_ERROR(gl->getError(), "CreateQueries");
	}
	else
	{
		gl->genQueries(1, &id);
		gl->beginQuery(GL_SAMPLES_PASSED, id);
		gl->endQuery(GL_SAMPLES_PASSED);
		GLU_EXPECT_NO_ERROR(gl->getError(), "GenQueries / BeginQuery / EndQuery");
	}

	return id;
}

/** Create render buffer
 *
 * @param gl GL functions
 *
 * @return ID of created resource
 **/
GLuint LabelsTest::createRenderbuffer(const Functions* gl, const glu::RenderContext* rc)
{
	GLuint id = 0;

	if (glu::contextSupports(rc->getType(), glu::ApiType::core(4, 5)))
	{
		gl->createRenderbuffers(1, &id);
		GLU_EXPECT_NO_ERROR(gl->getError(), "CreateRenderbuffers");
	}
	else
	{
		gl->genRenderbuffers(1, &id);
		gl->bindRenderbuffer(GL_RENDERBUFFER, id);
		gl->bindRenderbuffer(GL_RENDERBUFFER, 0);
		GLU_EXPECT_NO_ERROR(gl->getError(), "GenRenderbuffers / BindRenderbuffer");
	}

	return id;
}

/** Create sampler
 *
 * @param gl GL functions
 *
 * @return ID of created resource
 **/
GLuint LabelsTest::createSampler(const Functions* gl, const glu::RenderContext* rc)
{
	GLuint id = 0;
	if (glu::contextSupports(rc->getType(), glu::ApiType::core(4, 5)))
	{
		gl->createSamplers(1, &id);
		GLU_EXPECT_NO_ERROR(gl->getError(), "CreateSamplers");
	}
	else
	{
		gl->genSamplers(1, &id);
		gl->bindSampler(0, id);
		gl->bindSampler(0, 0);
		GLU_EXPECT_NO_ERROR(gl->getError(), "GenSamplers / BindSampler");
	}

	return id;
}

/** Create shader
 *
 * @param gl GL functions
 *
 * @return ID of created resource
 **/
GLuint LabelsTest::createShader(const Functions* gl, const glu::RenderContext*)
{
	GLuint id = gl->createShader(GL_VERTEX_SHADER);
	GLU_EXPECT_NO_ERROR(gl->getError(), "CreateShader");

	return id;
}

/** Create texture
 *
 * @param gl GL functions
 *
 * @return ID of created resource
 **/
GLuint LabelsTest::createTexture(const Functions* gl, const glu::RenderContext* rc)
{
	GLuint id = 0;
	if (glu::contextSupports(rc->getType(), glu::ApiType::core(4, 5)))
	{
		gl->createTextures(GL_TEXTURE_2D, 1, &id);
		GLU_EXPECT_NO_ERROR(gl->getError(), "CreateTextures");
	}
	else
	{
		gl->genTextures(1, &id);
		gl->bindTexture(GL_TEXTURE_2D, id);
		gl->bindTexture(GL_TEXTURE_2D, 0);
		GLU_EXPECT_NO_ERROR(gl->getError(), "GenTextures / BindTexture");
	}

	return id;
}

/** Create XFB
 *
 * @param gl GL functions
 *
 * @return ID of created resource
 **/
GLuint LabelsTest::createTransformFeedback(const Functions* gl, const glu::RenderContext* rc)
{
	GLuint id = 0;
	if (glu::contextSupports(rc->getType(), glu::ApiType::core(4, 5)))
	{
		gl->createTransformFeedbacks(1, &id);
		GLU_EXPECT_NO_ERROR(gl->getError(), "CreateTransformFeedbacks");
	}
	else
	{
		gl->genTransformFeedbacks(1, &id);
		gl->bindTransformFeedback(GL_TRANSFORM_FEEDBACK, id);
		gl->bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
		GLU_EXPECT_NO_ERROR(gl->getError(), "GenTransformFeedbacks / BindTransformFeedback");
	}

	return id;
}

/** Create VAO
 *
 * @param gl GL functions
 *
 * @return ID of created resource
 **/
GLuint LabelsTest::createVertexArray(const Functions* gl, const glu::RenderContext* rc)
{
	GLuint id = 0;

	if (glu::contextSupports(rc->getType(), glu::ApiType::core(4, 5)))
	{
		gl->createVertexArrays(1, &id);
		GLU_EXPECT_NO_ERROR(gl->getError(), "CreateVertexArrays");
	}
	else
	{
		gl->genVertexArrays(1, &id);
		gl->bindVertexArray(id);
		gl->bindVertexArray(0);
		GLU_EXPECT_NO_ERROR(gl->getError(), "GenVertexArrays / BindVertexArrays");
	}

	return id;
}

/** Destroy buffer
 *
 * @param gl GL functions
 * @param id ID of resource
 **/
GLvoid LabelsTest::deleteBuffer(const Functions* gl, GLuint id)
{
	gl->deleteBuffers(1, &id);
	GLU_EXPECT_NO_ERROR(gl->getError(), "DeleteBuffers");
}

/** Destroy FBO
 *
 * @param gl GL functions
 * @param id ID of resource
 **/
GLvoid LabelsTest::deleteFramebuffer(const Functions* gl, GLuint id)
{
	gl->deleteFramebuffers(1, &id);
	GLU_EXPECT_NO_ERROR(gl->getError(), "DeleteFramebuffers");
}

/** Destroy program
 *
 * @param gl GL functions
 * @param id ID of resource
 **/
GLvoid LabelsTest::deleteProgram(const Functions* gl, GLuint id)
{
	gl->deleteProgram(id);
	GLU_EXPECT_NO_ERROR(gl->getError(), "DeleteProgram");
}

/** Destroy pipeline
 *
 * @param gl GL functions
 * @param id ID of resource
 **/
GLvoid LabelsTest::deleteProgramPipeline(const Functions* gl, GLuint id)
{
	gl->deleteProgramPipelines(1, &id);
	GLU_EXPECT_NO_ERROR(gl->getError(), "DeleteProgramPipelines");
}

/** Destroy query
 *
 * @param gl GL functions
 * @param id ID of resource
 **/
GLvoid LabelsTest::deleteQuery(const Functions* gl, GLuint id)
{
	gl->deleteQueries(1, &id);
	GLU_EXPECT_NO_ERROR(gl->getError(), "DeleteQueries");
}

/** Destroy render buffer
 *
 * @param gl GL functions
 * @param id ID of resource
 **/
GLvoid LabelsTest::deleteRenderbuffer(const Functions* gl, GLuint id)
{
	gl->deleteRenderbuffers(1, &id);
	GLU_EXPECT_NO_ERROR(gl->getError(), "DeleteRenderbuffers");
}

/** Destroy sampler
 *
 * @param gl GL functions
 * @param id ID of resource
 **/
GLvoid LabelsTest::deleteSampler(const Functions* gl, GLuint id)
{
	gl->deleteSamplers(1, &id);
	GLU_EXPECT_NO_ERROR(gl->getError(), "DeleteSamplers");
}

/** Destroy shader
 *
 * @param gl GL functions
 * @param id ID of resource
 **/
GLvoid LabelsTest::deleteShader(const Functions* gl, GLuint id)
{
	gl->deleteShader(id);
	GLU_EXPECT_NO_ERROR(gl->getError(), "DeleteShader");
}

/** Destroy texture
 *
 * @param gl GL functions
 * @param id ID of resource
 **/
GLvoid LabelsTest::deleteTexture(const Functions* gl, GLuint id)
{
	gl->deleteTextures(1, &id);
	GLU_EXPECT_NO_ERROR(gl->getError(), "DeleteTextures");
}

/** Destroy XFB
 *
 * @param gl GL functions
 * @param id ID of resource
 **/
GLvoid LabelsTest::deleteTransformFeedback(const Functions* gl, GLuint id)
{
	gl->deleteTransformFeedbacks(1, &id);
	GLU_EXPECT_NO_ERROR(gl->getError(), "DeleteTransformFeedbacks");
}

/** Destroy VAO
 *
 * @param gl GL functions
 * @param id ID of resource
 **/
GLvoid LabelsTest::deleteVertexArray(const Functions* gl, GLuint id)
{
	gl->deleteVertexArrays(1, &id);
	GLU_EXPECT_NO_ERROR(gl->getError(), "DeleteVertexArrays");
}

/** Constructor
 *
 * @param testCtx  Test context
 * @param is_debug Selects if debug or non-debug context should be used
 * @param name     Name of test
 **/
ReceivingMessagesTest::ReceivingMessagesTest(tcu::TestContext& testCtx, glu::ApiType apiType)
	: TestCase(testCtx, "receiving_messages", "Verifies that messages can be received")
	, TestBase(testCtx, apiType, true /* is_debug */)
{
	/* Nothing to be done */
}

/** Execute test
 *
 * @return tcu::TestNode::STOP
 **/
tcu::TestNode::IterateResult ReceivingMessagesTest::iterate()
{
	static const size_t bufSize		  = 32;
	static const GLchar label[]		  = "foo";
	static const size_t label_length  = sizeof(label) / sizeof(label[0]) - 1;
	static const size_t read_messages = 4;

	GLuint callback_counter   = 0;
	GLint  max_debug_messages = 0;

	/* Initialize render context */
	TestBase::init();

	/* Get max number of debug messages */
	m_gl->getIntegerv(GL_MAX_DEBUG_LOGGED_MESSAGES, &max_debug_messages);
	GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetIntegerv");

	/*
	 * - verify that the state of DEBUG_OUTPUT is enabled as it should be by
	 * default;
	 * - verify that state of DEBUG_CALLBACK_FUNCTION and
	 * DEBUG_CALLBACK_USER_PARAM are NULL;
	 */
	{
		inspectDebugState(GL_TRUE, 0 /* cb */, 0 /* info */);
	}

	/*
	 * Ignore spurious performance messages
	 */
	m_gl->debugMessageControl(GL_DONT_CARE /* source */, GL_DEBUG_TYPE_PERFORMANCE /* type */,
							  GL_DONT_CARE /* severity */, 0 /* counts */, 0 /* ids */, GL_FALSE /* enabled */);

	/*
	 * - insert a message with DebugMessageInsert;
	 * - inspect message log to check if the message is reported;
	 * - inspect message log again, there should be no messages;
	 */
	{
		GLchar  messageLog[bufSize];
		GLenum  sources[read_messages];
		GLenum  types[read_messages];
		GLuint  ids[read_messages];
		GLenum  severities[read_messages];
		GLsizei lengths[read_messages];

		cleanMessageLog(m_gl);

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		GLuint ret = m_gl->getDebugMessageLog(read_messages /* count */, bufSize /* bufSize */, sources /* sources */,
											  types /* types */, ids /* ids */, severities /* severities */,
											  lengths /* lengths */, messageLog /* messageLog */);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetDebugMessageLog");

		if (1 != ret)
		{
			m_testCtx.getLog() << tcu::TestLog::Message
												<< "GetDebugMessageLog returned invalid number of messages: " << ret
												<< ", expected 1" << tcu::TestLog::EndMessage;

			TCU_FAIL("Invalid value returned by GetDebugMessageLog");
		}

		if (GL_DEBUG_SOURCE_APPLICATION != sources[0])
		{
			TCU_FAIL("Invalid source value returned by GetDebugMessageLog");
		}

		if (GL_DEBUG_TYPE_ERROR != types[0])
		{
			TCU_FAIL("Invalid type value returned by GetDebugMessageLog");
		}

		if (11 != ids[0])
		{
			TCU_FAIL("Invalid id value returned by GetDebugMessageLog");
		}

		if (GL_DEBUG_SEVERITY_HIGH != severities[0])
		{
			TCU_FAIL("Invalid severity value returned by GetDebugMessageLog");
		}

		// DebugMessageInsert's length does not include null-terminated character (if length is positive)
		// But GetDebugMessageLog's length include null-terminated character
		// OpenGL 4.5 Core Spec, Page 530 and Page 535
		if (label_length + 1 != lengths[0])
		{
			TCU_FAIL("Invalid length value returned by GetDebugMessageLog");
		}

		if (0 != strcmp(label, messageLog))
		{
			TCU_FAIL("Invalid message returned by GetDebugMessageLog");
		}
	}

	/*
	 * - disable DEBUG_OUTPUT;
	 * - insert a message with DebugMessageInsert;
	 * - inspect message log again, there should be no messages;
	 */
	{
		m_gl->disable(GL_DEBUG_OUTPUT);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "Disable");

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		inspectMessageLog(0);
	}

	/*
	 * - enable DEBUG_OUTPUT;
	 * - register debug message callback with DebugMessageCallback;
	 * - verify that the state of DEBUG_CALLBACK_FUNCTION and
	 * DEBUG_CALLBACK_USER_PARAM are correct;
	 * - insert a message with DebugMessageInsert;
	 * - it is expected that debug message callback will be executed for
	 * the message;
	 * - inspect message log to check there are no messages;
	 */
	{
		m_gl->enable(GL_DEBUG_OUTPUT);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "Enable");

		m_gl->debugMessageCallback(debug_proc, &callback_counter);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageCallback");

		inspectDebugState(GL_TRUE, debug_proc, &callback_counter);

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		inspectCallbackCounter(callback_counter, 1);

		inspectMessageLog(0);
	}

	/*
	 * - disable DEBUG_OUTPUT;
	 * - insert a message with DebugMessageInsert;
	 * - debug message callback should not be called;
	 * - inspect message log to check there are no messages;
	 */
	{
		m_gl->disable(GL_DEBUG_OUTPUT);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "Disable");

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		inspectCallbackCounter(callback_counter, 1);

		inspectMessageLog(0);
	}

	/*
	 * - enable DEBUG_OUTPUT;
	 * - execute DebugMessageControl with <type> DEBUG_TYPE_ERROR, <severity>
	 * DEBUG_SEVERITY_HIGH and <enabled> FALSE;
	 * - insert a message with DebugMessageInsert, set <type> to DEBUG_TYPE_ERROR
	 * and <severity> DEBUG_SEVERITY_MEDIUM;
	 * - insert a message with DebugMessageInsert, set <type> to DEBUG_TYPE_OTHER
	 * and <severity> DEBUG_SEVERITY_HIGH;
	 * - insert a message with DebugMessageInsert, set <type> to DEBUG_TYPE_OTHER
	 * and <severity> DEBUG_SEVERITY_LOW;
	 * - debug message callback should not be called;
	 * - inspect message log to check there are no messages;
	 */
	{
		m_gl->enable(GL_DEBUG_OUTPUT);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "Enable");

		m_gl->debugMessageControl(GL_DONT_CARE /* source */, GL_DEBUG_TYPE_ERROR /* type */,
								  GL_DONT_CARE /* severity */, 0 /* counts */, 0 /* ids */, GL_FALSE /* enabled */);

		m_gl->debugMessageControl(GL_DONT_CARE /* source */, GL_DONT_CARE /* type */,
								  GL_DEBUG_SEVERITY_HIGH /* severity */, 0 /* counts */, 0 /* ids */,
								  GL_FALSE /* enabled */);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageControl");

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_MEDIUM /* severity */, label_length /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_OTHER /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_OTHER /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_LOW /* severity */, label_length /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		inspectCallbackCounter(callback_counter, 1);

		inspectMessageLog(0);
	}

	/*
	 * - set NULL as debug message callback;
	 * - verify that state of DEBUG_CALLBACK_FUNCTION and
	 * DEBUG_CALLBACK_USER_PARAM are NULL;
	 * - insert a message with DebugMessageInsert, set <type> to DEBUG_TYPE_ERROR
	 * and <severity> DEBUG_SEVERITY_MEDIUM;
	 * - insert a message with DebugMessageInsert, set <type> to DEBUG_TYPE_OTHER
	 * and <severity> DEBUG_SEVERITY_HIGH;
	 * - insert a message with DebugMessageInsert, set <type> to DEBUG_TYPE_OTHER
	 * and <severity> DEBUG_SEVERITY_LOW;
	 * - inspect message log to check there are no messages;
	 */
	{
		m_gl->debugMessageCallback(0, 0);

		inspectDebugState(GL_TRUE, 0, 0);

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_MEDIUM /* severity */, label_length /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_OTHER /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_OTHER /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_LOW /* severity */, label_length /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		inspectMessageLog(0);
	}

	/*
	 * - execute DebugMessageControl to enable messages of <type> DEBUG_TYPE_ERROR
	 * and <severity> DEBUG_SEVERITY_HIGH.
	 */
	{
		m_gl->debugMessageControl(GL_DONT_CARE /* source */, GL_DEBUG_TYPE_ERROR /* type */,
								  GL_DONT_CARE /* severity */, 0 /* counts */, 0 /* ids */, GL_TRUE /* enabled */);

		m_gl->debugMessageControl(GL_DONT_CARE /* source */, GL_DONT_CARE /* type */,
								  GL_DEBUG_SEVERITY_HIGH /* severity */, 0 /* counts */, 0 /* ids */,
								  GL_TRUE /* enabled */);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageControl");
	}

	/*
	 * - insert MAX_DEBUG_LOGGED_MESSAGES + 1 unique messages with
	 * DebugMessageInsert;
	 * - check state of DEBUG_LOGGED_MESSAGES; It is expected that
	 * MAX_DEBUG_LOGGED_MESSAGES will be reported;
	 */
	{
		for (GLint i = 0; i < max_debug_messages + 1; ++i)
		{
			m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */,
									 i /* id */, GL_DEBUG_SEVERITY_MEDIUM /* severity */, label_length /* length */,
									 label);
			GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");
		}

		GLint n_debug_messages = 0;

		m_gl->getIntegerv(GL_DEBUG_LOGGED_MESSAGES, &n_debug_messages);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetIntegerv");

		if (n_debug_messages != max_debug_messages)
		{
			m_testCtx.getLog()
				<< tcu::TestLog::Message << "State of DEBUG_LOGGED_MESSAGES: " << n_debug_messages << ", expected "
				<< max_debug_messages << tcu::TestLog::EndMessage;

			TCU_FAIL("Invalid state of DEBUG_LOGGED_MESSAGES");
		}
	}

	/*
	 * If MAX_DEBUG_LOGGED_MESSAGES is greater than 1:
	 * - inspect first half of the message log by specifying proper <count>; Verify
	 * that messages are reported in order from the oldest to the newest; Check
	 * that <count> messages were stored into provided buffers;
	 * - check state of DEBUG_LOGGED_MESSAGES; It is expected that <count> messages
	 * were removed from log;
	 * - inspect rest of the message log with <bufSize> too small to held last
	 * message; Verify that messages are reported in order from the oldest to the
	 * newest; Verify that maximum <bufSize> characters were written to
	 * <messageLog>;
	 * - check state of DEBUG_LOGGED_MESSAGES; It is expected that one message is
	 * available;
	 * - fetch the message and verify it is the newest one;
	 */
	if (1 != max_debug_messages)
	{
		GLint half_count	   = max_debug_messages / 2;
		GLint n_debug_messages = 0;
		GLint rest_count	   = max_debug_messages - half_count;

		GLsizei buf_size = (GLsizei)((half_count + 1) * (label_length + 1));

		std::vector<GLchar>  messageLog;
		std::vector<GLenum>  sources;
		std::vector<GLenum>  types;
		std::vector<GLuint>  ids;
		std::vector<GLenum>  severities;
		std::vector<GLsizei> lengths;

		messageLog.resize(buf_size);
		sources.resize(half_count + 1);
		types.resize(half_count + 1);
		ids.resize(half_count + 1);
		severities.resize(half_count + 1);
		lengths.resize(half_count + 1);

		GLuint ret = m_gl->getDebugMessageLog(half_count /* count */, buf_size /* bufSize */, &sources[0] /* sources */,
											  &types[0] /* types */, &ids[0] /* ids */, &severities[0] /* severities */,
											  &lengths[0] /* lengths */, &messageLog[0] /* messageLog */);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetDebugMessageLog");

		if (ret != (GLuint)half_count)
		{
			m_testCtx.getLog() << tcu::TestLog::Message
												<< "GetDebugMessageLog returned unexpected number of messages: " << ret
												<< ", expected " << half_count << tcu::TestLog::EndMessage;

			TCU_FAIL("Invalid number of meessages");
		}

		m_gl->getIntegerv(GL_DEBUG_LOGGED_MESSAGES, &n_debug_messages);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetIntegerv");

		if (n_debug_messages != rest_count)
		{
			m_testCtx.getLog()
				<< tcu::TestLog::Message << "State of DEBUG_LOGGED_MESSAGES: " << n_debug_messages << ", expected "
				<< rest_count << tcu::TestLog::EndMessage;

			TCU_FAIL("Invalid state of DEBUG_LOGGED_MESSAGES");
		}

		for (GLint i = 0; i < half_count; ++i)
		{
			if (GL_DEBUG_SOURCE_APPLICATION != sources[i])
			{
				TCU_FAIL("Invalid source value returned by GetDebugMessageLog");
			}

			if (GL_DEBUG_TYPE_ERROR != types[i])
			{
				TCU_FAIL("Invalid type value returned by GetDebugMessageLog");
			}

			if ((GLuint)i != ids[i])
			{
				TCU_FAIL("Invalid id value returned by GetDebugMessageLog");
			}

			if (GL_DEBUG_SEVERITY_MEDIUM != severities[i])
			{
				TCU_FAIL("Invalid severity value returned by GetDebugMessageLog");
			}

			// DebugMessageInsert's length does not include null-terminated character (if length is positive)
			// But GetDebugMessageLog's length include null-terminated character
			// OpenGL 4.5 Core Spec, Page 530 and Page 535
			if (label_length + 1 != lengths[i])
			{
				TCU_FAIL("Invalid length value returned by GetDebugMessageLog");
			}

			if (0 != strcmp(label, &messageLog[i * (label_length + 1)]))
			{
				TCU_FAIL("Invalid message returned by GetDebugMessageLog");
			}
		}

		/* */
		buf_size = (GLsizei)((rest_count - 1) * (label_length + 1) + label_length);
		memset(&messageLog[0], 0, messageLog.size());

		ret = m_gl->getDebugMessageLog(rest_count /* count */, buf_size /* bufSize */, &sources[0] /* sources */,
									   &types[0] /* types */, &ids[0] /* ids */, &severities[0] /* severities */,
									   &lengths[0] /* lengths */, &messageLog[0] /* messageLog */);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetDebugMessageLog");

		if (ret != (GLuint)(rest_count - 1))
		{
			m_testCtx.getLog() << tcu::TestLog::Message
												<< "GetDebugMessageLog returned unexpected number of messages: " << ret
												<< ", expected " << (rest_count - 1) << tcu::TestLog::EndMessage;

			TCU_FAIL("Invalid number of meessages");
		}

		m_gl->getIntegerv(GL_DEBUG_LOGGED_MESSAGES, &n_debug_messages);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetIntegerv");

		if (n_debug_messages != 1)
		{
			m_testCtx.getLog()
				<< tcu::TestLog::Message << "State of DEBUG_LOGGED_MESSAGES: " << n_debug_messages << ", expected "
				<< (rest_count - 1) << tcu::TestLog::EndMessage;

			TCU_FAIL("Invalid state of DEBUG_LOGGED_MESSAGES");
		}

		for (GLint i = 0; i < (rest_count - 1); ++i)
		{
			if (GL_DEBUG_SOURCE_APPLICATION != sources[i])
			{
				TCU_FAIL("Invalid source value returned by GetDebugMessageLog");
			}

			if (GL_DEBUG_TYPE_ERROR != types[i])
			{
				TCU_FAIL("Invalid type value returned by GetDebugMessageLog");
			}

			if ((GLuint)(i + half_count) != ids[i])
			{
				TCU_FAIL("Invalid id value returned by GetDebugMessageLog");
			}

			if (GL_DEBUG_SEVERITY_MEDIUM != severities[i])
			{
				TCU_FAIL("Invalid severity value returned by GetDebugMessageLog");
			}

			// DebugMessageInsert's length does not include null-terminated character (if length is positive)
			// But GetDebugMessageLog's length include null-terminated character
			// OpenGL 4.5 Core Spec, Page 530 and Page 535
			if (label_length + 1 != lengths[i])
			{
				TCU_FAIL("Invalid length value returned by GetDebugMessageLog");
			}

			if (0 != strcmp(label, &messageLog[i * (label_length + 1)]))
			{
				TCU_FAIL("Invalid message returned by GetDebugMessageLog");
			}
		}

		/* */
		memset(&messageLog[0], 0, messageLog.size());

		ret = m_gl->getDebugMessageLog(rest_count /* count */, buf_size /* bufSize */, &sources[0] /* sources */,
									   &types[0] /* types */, &ids[0] /* ids */, &severities[0] /* severities */,
									   &lengths[0] /* lengths */, &messageLog[0] /* messageLog */);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetDebugMessageLog");

		if (ret != 1)
		{
			m_testCtx.getLog() << tcu::TestLog::Message
												<< "GetDebugMessageLog returned unexpected number of messages: " << ret
												<< ", expected 1" << tcu::TestLog::EndMessage;

			TCU_FAIL("Invalid number of meessages");
		}

		m_gl->getIntegerv(GL_DEBUG_LOGGED_MESSAGES, &n_debug_messages);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetIntegerv");

		if (n_debug_messages != 0)
		{
			m_testCtx.getLog()
				<< tcu::TestLog::Message << "State of DEBUG_LOGGED_MESSAGES: " << n_debug_messages << ", expected 1"
				<< tcu::TestLog::EndMessage;

			TCU_FAIL("Invalid state of DEBUG_LOGGED_MESSAGES");
		}

		if (GL_DEBUG_SOURCE_APPLICATION != sources[0])
		{
			TCU_FAIL("Invalid source value returned by GetDebugMessageLog");
		}

		if (GL_DEBUG_TYPE_ERROR != types[0])
		{
			TCU_FAIL("Invalid type value returned by GetDebugMessageLog");
		}

		if ((GLuint)(max_debug_messages - 1) != ids[0])
		{
			TCU_FAIL("Invalid id value returned by GetDebugMessageLog");
		}

		if (GL_DEBUG_SEVERITY_MEDIUM != severities[0])
		{
			TCU_FAIL("Invalid severity value returned by GetDebugMessageLog");
		}

		// DebugMessageInsert's length does not include null-terminated character (if length is positive)
		// But GetDebugMessageLog's length include null-terminated character
		// OpenGL 4.5 Core Spec, Page 530 and Page 535
		if (label_length + 1 != lengths[0])
		{
			TCU_FAIL("Invalid length value returned by GetDebugMessageLog");
		}

		if (0 != strcmp(label, &messageLog[0]))
		{
			TCU_FAIL("Invalid message returned by GetDebugMessageLog");
		}
	}

	/* Set result */
	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");

	/* Done */
	TestBase::done();

	return tcu::TestNode::STOP;
}

/** Debug callback used by the test, increase counter by one
 *
 * @param ignored
 * @param ignored
 * @param ignored
 * @param ignored
 * @param ignored
 * @param ignored
 * @param info    Pointer to uint counter
 **/
void ReceivingMessagesTest::debug_proc(glw::GLenum /* source */, glw::GLenum /* type */, glw::GLuint /* id */,
										glw::GLenum /* severity */, glw::GLsizei /* length */,
										const glw::GLchar* /* message */, const void* info)
{
	GLuint* counter = (GLuint*)info;

	*counter += 1;
}

/** Inspects state of DEBUG_OUTPUT and debug callback
 *
 * @param expected_state     Expected state of DEBUG_OUTPUT
 * @param expected_callback  Expected state of DEBUG_CALLBACK_FUNCTION
 * @param expected_user_info Expected state of DEBUG_CALLBACK_USER_PARAM
 **/
void ReceivingMessagesTest::inspectDebugState(GLboolean expected_state, GLDEBUGPROC expected_callback,
											   GLvoid* expected_user_info) const
{
	GLboolean debug_state = -1;
	m_gl->getBooleanv(GL_DEBUG_OUTPUT, &debug_state);
	GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetBooleanv");

	if (expected_state != debug_state)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "State of DEBUG_OUTPUT: " << debug_state
											<< ", expected " << expected_state << tcu::TestLog::EndMessage;

		TCU_FAIL("Invalid state of DEBUG_OUTPUT");
	}

	GLvoid* callback_procedure = 0;
	m_gl->getPointerv(GL_DEBUG_CALLBACK_FUNCTION, &callback_procedure);
	GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetPointerv");

	if (expected_callback != callback_procedure)
	{
		TCU_FAIL("Invalid state of DEBUG_CALLBACK_FUNCTION");
	}

	GLvoid* callback_user_info = 0;
	m_gl->getPointerv(GL_DEBUG_CALLBACK_USER_PARAM, &callback_user_info);
	GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetPointerv");

	if (expected_user_info != callback_user_info)
	{
		TCU_FAIL("Invalid state of DEBUG_CALLBACK_USER_PARAM");
	}
}

/** Inspects value of counter used by callback
 *
 * @param callback_counter            Reference to counter
 * @param expected_number_of_messages Expected value of counter
 **/
void ReceivingMessagesTest::inspectCallbackCounter(GLuint& callback_counter, GLuint expected_number_of_messages) const
{
	m_gl->finish();
	GLU_EXPECT_NO_ERROR(m_gl->getError(), "Finish");

	if (expected_number_of_messages != callback_counter)
	{
		m_testCtx.getLog()
			<< tcu::TestLog::Message << "Debug callback was executed invalid number of times: " << callback_counter
			<< ", expected " << expected_number_of_messages << tcu::TestLog::EndMessage;

		TCU_FAIL("Invalid execution of debug callback");
	}
}

/** Inspects amount of messages stored in log
 *
 * @param expected_number_of_messages Expected number of messages
 **/
void ReceivingMessagesTest::inspectMessageLog(GLuint expected_number_of_messages) const
{
	static const size_t bufSize		  = 32;
	static const size_t read_messages = 4;

	GLchar  messageLog[bufSize];
	GLenum  sources[read_messages];
	GLenum  types[read_messages];
	GLuint  ids[read_messages];
	GLenum  severities[read_messages];
	GLsizei lengths[read_messages];

	GLuint ret = m_gl->getDebugMessageLog(read_messages /* count */, bufSize /* bufSize */, sources /* sources */,
										  types /* types */, ids /* ids */, severities /* severities */,
										  lengths /* lengths */, messageLog /* messageLog */);
	GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetDebugMessageLog");

	if (expected_number_of_messages != ret)
	{
		m_testCtx.getLog() << tcu::TestLog::Message
											<< "GetDebugMessageLog returned invalid number of messages: " << ret
											<< ", expected " << expected_number_of_messages << tcu::TestLog::EndMessage;

		TCU_FAIL("Invalid value returned by GetDebugMessageLog");
	}
}

/** Constructor
 *
 * @param testCtx  Test context
 * @param is_debug Selects if debug or non-debug context should be used
 * @param name     Name of test
 **/
GroupsTest::GroupsTest(tcu::TestContext& testCtx, glu::ApiType apiType)
	: TestCase(testCtx, "groups", "Verifies that groups can be used to control generated messages")
	, TestBase(testCtx, apiType, true /* is_debug */)
{
	/* Nothing to be done */
}

/** Execute test
 *
 * @return tcu::TestNode::STOP
 **/
tcu::TestNode::IterateResult GroupsTest::iterate()
{
	static const GLchar label[]		 = "foo";
	static const size_t label_length = sizeof(label) / sizeof(label[0]) - 1;

	/* Initialize render context */
	TestBase::init();

	cleanMessageLog(m_gl);

	/*
	 * - check state of DEBUG_GROUP_STACK_DEPTH; It should be 1;
	 */
	inspectGroupStack(1);

	/*
	 * - insert message with <type> DEBUG_TYPE_ERROR;
	 * - inspect message log to check if the message is reported;
	 * - insert message with <type> DEBUG_TYPE_OTHER;
	 * - inspect message log to check if the message is reported;
	 */
	{
		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		inspectMessageLog(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */,
						  GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_OTHER /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		inspectMessageLog(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_OTHER /* type */, 11 /* id */,
						  GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);
	}

	/*
	 * - push debug group with unique <id> and <message>;
	 * - inspect message log to check if the message about push is reported;
	 * - disable messages with <type> DEBUG_TYPE_ERROR;
	 * - insert message with <type> DEBUG_TYPE_ERROR;
	 * - inspect message log to check there are no messages;
	 * - insert message with <type> DEBUG_TYPE_OTHER;
	 * - inspect message log to check if the message is reported;
	 */
	{
		m_gl->pushDebugGroup(GL_DEBUG_SOURCE_APPLICATION /* source */, 0xabcd0123 /* id */, -1 /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "PushDebugGroup");

		inspectMessageLog(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_PUSH_GROUP /* type */,
						  0xabcd0123 /* id */, GL_DEBUG_SEVERITY_NOTIFICATION /* severity */, label_length /* length */,
						  label);

		m_gl->debugMessageControl(GL_DONT_CARE /* source */, GL_DEBUG_TYPE_ERROR /* type */,
								  GL_DONT_CARE /* severity */, 0 /* counts */, 0 /* ids */, GL_FALSE /* enabled */);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageControl");

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		verifyEmptyLog();

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_OTHER /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		inspectMessageLog(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_OTHER /* type */, 11 /* id */,
						  GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);
	}

	/*
	 * - check state of DEBUG_GROUP_STACK_DEPTH; It should be 2;
	 */
	inspectGroupStack(2);

	/*
	 * - push debug group with unique <id> and <message>;
	 * - inspect message log to check if the message about push is reported;
	 * - disable messages with <type> DEBUG_TYPE_OTHER;
	 * - insert message with <type> DEBUG_TYPE_ERROR;
	 * - inspect message log to check there are no messages;
	 * - insert message with <type> DEBUG_TYPE_OTHER;
	 * - inspect message log to check there are no messages;
	 */
	{
		m_gl->pushDebugGroup(GL_DEBUG_SOURCE_APPLICATION /* source */, 0x0123abcd /* id */, -1 /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "PushDebugGroup");

		inspectMessageLog(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_PUSH_GROUP /* type */,
						  0x0123abcd /* id */, GL_DEBUG_SEVERITY_NOTIFICATION /* severity */, label_length /* length */,
						  label);

		m_gl->debugMessageControl(GL_DONT_CARE /* source */, GL_DEBUG_TYPE_OTHER /* type */,
								  GL_DONT_CARE /* severity */, 0 /* counts */, 0 /* ids */, GL_FALSE /* enabled */);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageControl");

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		verifyEmptyLog();

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_OTHER /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		verifyEmptyLog();
	}

	/*
	 * - check state of DEBUG_GROUP_STACK_DEPTH; It should be 3;
	 */
	inspectGroupStack(3);

	/*
	 * - pop debug group;
	 * - inspect message log to check if the message about pop is reported and
	 * corresponds with the second push;
	 * - insert message with <type> DEBUG_TYPE_ERROR;
	 * - inspect message log to check there are no messages;
	 * - insert message with <type> DEBUG_TYPE_OTHER;
	 * - inspect message log to check if the message is reported;
	 */
	{
		m_gl->popDebugGroup();
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "PopDebugGroup");

		inspectMessageLog(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_POP_GROUP /* type */,
						  0x0123abcd /* id */, GL_DEBUG_SEVERITY_NOTIFICATION /* severity */, label_length /* length */,
						  label);

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		verifyEmptyLog();

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_OTHER /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		inspectMessageLog(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_OTHER /* type */, 11 /* id */,
						  GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);
	}

	/*
	 * - check state of DEBUG_GROUP_STACK_DEPTH; It should be 2;
	 */
	inspectGroupStack(2);

	/*
	 * - pop debug group;
	 * - inspect message log to check if the message about pop is reported and
	 * corresponds with the first push;
	 * - insert message with <type> DEBUG_TYPE_ERROR;
	 * - inspect message log to check if the message is reported;
	 * - insert message with <type> DEBUG_TYPE_OTHER;
	 * - inspect message log to check if the message is reported;
	 */
	{
		m_gl->popDebugGroup();
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "PopDebugGroup");

		inspectMessageLog(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_POP_GROUP /* type */,
						  0xabcd0123 /* id */, GL_DEBUG_SEVERITY_NOTIFICATION /* severity */, label_length /* length */,
						  label);

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		inspectMessageLog(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */,
						  GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);

		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_OTHER /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		inspectMessageLog(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_OTHER /* type */, 11 /* id */,
						  GL_DEBUG_SEVERITY_HIGH /* severity */, label_length /* length */, label);
	}

	/*
	 * - check state of DEBUG_GROUP_STACK_DEPTH; It should be 1;
	 */
	inspectGroupStack(1);

	/* Set result */
	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");

	/* Done */
	TestBase::done();

	return tcu::TestNode::STOP;
}

/** Inspects amount of groups on stack
 *
 * @param expected_depth Expected number of groups
 **/
void GroupsTest::inspectGroupStack(GLuint expected_depth) const
{
	GLint stack_depth = 0;

	m_gl->getIntegerv(GL_DEBUG_GROUP_STACK_DEPTH, &stack_depth);
	GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetIntegerv");

	if (expected_depth != (GLuint)stack_depth)
	{
		m_testCtx.getLog() << tcu::TestLog::Message
											<< "State of DEBUG_GROUP_STACK_DEPTH: " << stack_depth << ", expected "
											<< expected_depth << tcu::TestLog::EndMessage;

		TCU_FAIL("Invalid state of DEBUG_GROUP_STACK_DEPTH");
	}
}

/** Inspects first message stored in log
 *
 * @param expected_source   Expected source of messages
 * @param expected_type     Expected type of messages
 * @param expected_id       Expected id of messages
 * @param expected_severity Expected severity of messages
 * @param expected_length   Expected length of messages
 * @param expected_label    Expected label of messages
 **/
void GroupsTest::inspectMessageLog(glw::GLenum expected_source, glw::GLenum expected_type, glw::GLuint expected_id,
								   glw::GLenum expected_severity, glw::GLsizei expected_length,
								   const glw::GLchar* expected_label) const
{
	static const size_t bufSize		  = 32;
	static const size_t read_messages = 1;

	GLchar  messageLog[bufSize];
	GLenum  source;
	GLenum  type;
	GLuint  id;
	GLenum  severity;
	GLsizei length;

	GLuint ret = m_gl->getDebugMessageLog(read_messages /* count */, bufSize /* bufSize */, &source /* sources */,
										  &type /* types */, &id /* ids */, &severity /* severities */,
										  &length /* lengths */, messageLog /* messageLog */);
	GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetDebugMessageLog");

	if (0 == ret)
	{
		TCU_FAIL("GetDebugMessageLog returned 0 messages");
	}

	if (expected_source != source)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Got message with invalid source: " << source
											<< ", expected " << expected_source << tcu::TestLog::EndMessage;

		TCU_FAIL("Invalid source of message");
	}

	if (expected_type != type)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Got message with invalid type: " << type
											<< ", expected " << expected_type << tcu::TestLog::EndMessage;

		TCU_FAIL("Invalid type of message");
	}

	if (expected_id != id)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Got message with invalid id: " << id
											<< ", expected " << expected_id << tcu::TestLog::EndMessage;

		TCU_FAIL("Invalid id of message");
	}

	if (expected_severity != severity)
	{
		m_testCtx.getLog() << tcu::TestLog::Message
											<< "Got message with invalid severity: " << severity << ", expected "
											<< expected_severity << tcu::TestLog::EndMessage;

		TCU_FAIL("Invalid severity of message");
	}

	// DebugMessageInsert's length does not include null-terminated character (if length is positive)
	// But GetDebugMessageLog's length include null-terminated character
	// OpenGL 4.5 Core Spec, Page 530 and Page 535
	if (expected_length + 1 != length)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Got message with invalid length: " << length
											<< ", expected " << expected_length << tcu::TestLog::EndMessage;

		TCU_FAIL("Invalid length of message");
	}

	if (0 != strcmp(expected_label, messageLog))
	{
		m_testCtx.getLog() << tcu::TestLog::Message
											<< "Got message with invalid message: " << messageLog << ", expected "
											<< expected_label << tcu::TestLog::EndMessage;

		TCU_FAIL("Invalid message");
	}
}

/** Verifies that message log is empty
 *
 **/
void GroupsTest::verifyEmptyLog() const
{
	static const size_t bufSize		  = 32;
	static const size_t read_messages = 1;

	GLchar  messageLog[bufSize];
	GLenum  source;
	GLenum  type;
	GLuint  id;
	GLenum  severity;
	GLsizei length;

	GLuint ret = m_gl->getDebugMessageLog(read_messages /* count */, bufSize /* bufSize */, &source /* sources */,
										  &type /* types */, &id /* ids */, &severity /* severities */,
										  &length /* lengths */, messageLog /* messageLog */);
	GLU_EXPECT_NO_ERROR(m_gl->getError(), "GetDebugMessageLog");

	if (0 != ret)
	{
		TCU_FAIL("GetDebugMessageLog returned unexpected messages");
	}
}

/** Constructor
 *
 * @param testCtx  Test context
 * @param is_debug Selects if debug or non-debug context should be used
 * @param name     Name of test
 **/
SynchronousCallsTest::SynchronousCallsTest(tcu::TestContext& testCtx, glu::ApiType apiType)
	: TestCase(testCtx, "synchronous_calls", "Verifies that messages can be received")
	, TestBase(testCtx, apiType, true /* is_debug */)
{
	/* Create pthread_key_t visible to all threads
	 * The key has value NULL associated with it in all existing
	 * or about to be created threads
	 */
	m_uid = 0;
}

/** Execute test
 *
 * @return tcu::TestNode::STOP
 **/
tcu::TestNode::IterateResult SynchronousCallsTest::iterate()
{
	m_uid++;

	/* associate  some unique id with the current thread */
	m_tls.set((void*)(deUintptr)m_uid);

	static const GLchar label[] = "foo";

	GLuint buffer_id = 0;

	/* Initialize render context */
	TestBase::init();

	/* - set callback_executed to 0; */
	int callback_executed = 0;

	/*
	 *- enable DEBUG_OUTPUT_SYNCHRONOUS;
	 */
	m_gl->enable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
	GLU_EXPECT_NO_ERROR(m_gl->getError(), "Enable");

	/*
	 * - register debug message callback with DebugMessageCallback; Provide the
	 * instance of UserParam structure as <userParam>; Routine should do the
	 * following:
	 *   * set callback_executed to 1;
	 */
	m_gl->debugMessageCallback(debug_proc, &callback_executed);
	try
	{
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageCallback");

		/*
		 * - insert a message with DebugMessageInsert;
		 */
		m_gl->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION /* source */, GL_DEBUG_TYPE_ERROR /* type */, 11 /* id */,
								 GL_DEBUG_SEVERITY_HIGH /* severity */, -1 /* length */, label);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "DebugMessageInsert");

		/* Make sure execution finished before we check results */
		m_gl->finish();
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "Finish");

		/*
		 * - check if:
		 *   * callback_executed is set to 1;
		 */
		if (1 != callback_executed)
		{
			TCU_FAIL("callback_executed is not set to 1");
		}

		/* Check that the message was recorded by the current thread */
		if ((deUintptr)(m_tls.get()) != m_uid)
		{
			TCU_FAIL("thread id stored by callback is not the same as \"test\" thread");
		}

		/*
		 * - reset callback_executed;
		 */
		callback_executed = 0;

		/*
		 * - execute BindBufferBase with GL_ARRAY_BUFFER <target>, GL_INVALID_ENUM
		 * error should be generated;
		 */
		m_gl->genBuffers(1, &buffer_id);
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "GenBuffers");

		m_gl->bindBufferBase(GL_ARRAY_BUFFER, 0 /* index */, buffer_id);
		if (GL_INVALID_ENUM != m_gl->getError())
		{
			TCU_FAIL("Unexpected error generated");
		}

		/* Make sure execution finished before we check results */
		m_gl->finish();
		GLU_EXPECT_NO_ERROR(m_gl->getError(), "Finish");

		/*
		 * - test pass if:
		 *   * callback_executed is set to 0 - implementation does not send messages;
		 *   * callback_executed is set to 1 and thread_id is the same
		 *   as "test" thread - implementation sent message to proper thread;
		 */
		if (1 == callback_executed)
		{
			/* Check that the error was recorded by the current thread */
			if ((deUintptr)(m_tls.get()) != m_uid)
			{
				TCU_FAIL("thread id stored by callback is not the same as \"test\" thread");
			}
		}

		/* Clean */
		m_gl->deleteBuffers(1, &buffer_id);
		buffer_id = 0;
	}
	catch (const std::exception& exc)
	{
		if (0 != buffer_id)
		{
			m_gl->deleteBuffers(1, &buffer_id);
			buffer_id = 0;
		}

		TCU_FAIL(exc.what());
	}

	/* Set result */
	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");

	/* Done */
	TestBase::done();

	return tcu::TestNode::STOP;
}

/** Destructor */
SynchronousCallsTest::~SynchronousCallsTest(void)
{
}

/** Debug callback used by the test, sets callback_executed to 1 and stores 0 to tls
 *
 * @param ignored
 * @param ignored
 * @param ignored
 * @param ignored
 * @param ignored
 * @param ignored
 * @param info    Pointer to uint counter
 **/
void SynchronousCallsTest::debug_proc(glw::GLenum /* source */, glw::GLenum /* type */, glw::GLuint /* id */,
									  glw::GLenum /* severity */, glw::GLsizei /* length */,
									  const glw::GLchar* /* message */, const void* info)
{
	int* callback_executed = (int*)info;

	*callback_executed = 1;
}
} /* KHRDebug */

/** Constructor.
 *
 *  @param context Rendering context.
 **/
KHRDebugTests::KHRDebugTests(tcu::TestContext& testCtx, glu::ApiType apiType)
	: TestCaseGroup(testCtx, "khr_debug", "Verifies \"khr debug\" functionality")
	, m_apiType(apiType)

{
	/* Left blank on purpose */
}

/** Initializes a khr_debug test group.
 *
 **/
void KHRDebugTests::init(void)
{
	addChild(new KHRDebug::APIErrorsTest(m_testCtx, m_apiType, false, "api_errors_non_debug"));
	addChild(new KHRDebug::LabelsTest(m_testCtx, m_apiType, false, "labels_non_debug"));
	addChild(new KHRDebug::ReceivingMessagesTest(m_testCtx, m_apiType));
	addChild(new KHRDebug::GroupsTest(m_testCtx, m_apiType));
	addChild(new KHRDebug::APIErrorsTest(m_testCtx, m_apiType, true, "api_errors_debug"));
	addChild(new KHRDebug::LabelsTest(m_testCtx, m_apiType, true, "labels_debug"));
	addChild(new KHRDebug::SynchronousCallsTest(m_testCtx, m_apiType));
}

} /* glcts namespace */
