#define CL_HPP_UNIT_TEST_ENABLE
#define CL_HPP_USE_CL_SUB_GROUPS_KHR

// We want to support all versions
#define CL_HPP_MINIMUM_OPENCL_VERSION 100
# include <CL/opencl.hpp>
# define TEST_RVALUE_REFERENCES
# define VECTOR_CLASS cl::vector
# define STRING_CLASS cl::string

extern "C"
{
#include <unity.h>
#include <cmock.h>
#include "Mockcl.h"
#include <string.h>

/// Creates fake IDs that are easy to identify

static inline cl_platform_id make_platform_id(int index)
{
    return (cl_platform_id) (size_t) (0x1a1a1a1a + index);
}

static inline cl_context make_context(int index)
{
    return (cl_context) (size_t) (0xcccccccc + index);
}

static inline cl_device_id make_device_id(int index)
{
    return (cl_device_id) (size_t) (0xdededede + index);
}

static inline cl_mem make_mem(int index)
{
    return (cl_mem) (size_t) (0x33333333 + index);
}

static inline cl_command_queue make_command_queue(int index)
{
    return (cl_command_queue) (size_t) (0xc0c0c0c0 + index);
}

static inline cl_kernel make_kernel(int index)
{
    return (cl_kernel) (size_t) (0xcececece + index);
}

static inline cl_program make_program(int index)
{
    return (cl_program)(size_t)(0xcfcfcfcf + index);
}

/* Pools of pre-allocated wrapped objects for tests. There is no device pool,
 * because there is no way to know whether the test wants the device to be
 * reference countable or not.
 */
static const int POOL_MAX = 5;
static cl::Platform platformPool[POOL_MAX];
static cl::Context contextPool[POOL_MAX];
static cl::CommandQueue commandQueuePool[POOL_MAX];
static cl::Buffer bufferPool[POOL_MAX];
static cl::Image2D image2DPool[POOL_MAX];
static cl::Image3D image3DPool[POOL_MAX];
static cl::Kernel kernelPool[POOL_MAX];

/****************************************************************************
 * Stub functions shared by multiple tests
 ****************************************************************************/

/**
 * Stub implementation of clGetCommandQueueInfo that returns the first context.
 */
static cl_int clGetCommandQueueInfo_context(
    cl_command_queue id,
    cl_command_queue_info param_name,
    size_t param_value_size,
    void *param_value,
    size_t *param_value_size_ret,
    int num_calls)
{
    (void)num_calls;


    TEST_ASSERT_EQUAL_HEX(CL_QUEUE_CONTEXT, param_name);
    TEST_ASSERT(param_value == NULL || param_value_size >= sizeof(cl_context));
    if (param_value_size_ret != NULL)
        *param_value_size_ret = sizeof(cl_context);
    if (param_value != NULL)
        *(cl_context *)param_value = make_context(0);

    return CL_SUCCESS;
}

/**
 * Stub implementation of clGetDeviceInfo that just returns the first platform.
 */
static cl_int clGetDeviceInfo_platform(
    cl_device_id id,
    cl_device_info param_name,
    size_t param_value_size,
    void *param_value,
    size_t *param_value_size_ret,
    int num_calls)
{
    (void) num_calls;

    TEST_ASSERT_EQUAL_HEX(CL_DEVICE_PLATFORM, param_name);
    TEST_ASSERT(param_value == NULL || param_value_size >= sizeof(cl_platform_id));
    if (param_value_size_ret != NULL)
        *param_value_size_ret = sizeof(cl_platform_id);
    if (param_value != NULL)
        *(cl_platform_id *) param_value = make_platform_id(0);
    return CL_SUCCESS;
}

/**
 * Stub implementation of clGetContextInfo that just returns the first device.
 */
static cl_int clGetContextInfo_device(
    cl_context id,
    cl_context_info param_name,
    size_t param_value_size,
    void *param_value,
    size_t *param_value_size_ret,
    int num_calls)
{
    (void) num_calls;

    TEST_ASSERT_EQUAL_HEX(CL_CONTEXT_DEVICES, param_name);
    TEST_ASSERT(param_value == NULL || param_value_size >= sizeof(cl_device_id));
    if (param_value_size_ret != NULL)
        *param_value_size_ret = sizeof(cl_device_id);
    if (param_value != NULL)
        *(cl_device_id *) param_value = make_device_id(0);
    return CL_SUCCESS;
}


/**
 * Stub implementation of clGetPlatformInfo that returns a specific version.
 * It also checks that the id is the zeroth platform.
 */
static cl_int clGetPlatformInfo_version(
    cl_platform_id id,
    cl_platform_info param_name,
    size_t param_value_size,
    void *param_value,
    size_t *param_value_size_ret,
    const char *version)
{
    size_t bytes = strlen(version) + 1;

    TEST_ASSERT_NOT_NULL(id);
    TEST_ASSERT_EQUAL_PTR(make_platform_id(0), id);
    TEST_ASSERT_EQUAL_HEX(CL_PLATFORM_VERSION, param_name);
    TEST_ASSERT(param_value == NULL || param_value_size >= bytes);
    if (param_value_size_ret != NULL)
        *param_value_size_ret = bytes;
    if (param_value != NULL)
        strcpy((char *) param_value, version);
    return CL_SUCCESS;
}

/**
 * A stub for clGetPlatformInfo that will only support querying
 * CL_PLATFORM_VERSION, and will return version 1.1.
 */
static cl_int clGetPlatformInfo_version_1_1(
    cl_platform_id id,
    cl_platform_info param_name,
    size_t param_value_size,
    void *param_value,
    size_t *param_value_size_ret,
    int num_calls)
{
    (void) num_calls;
    return clGetPlatformInfo_version(
        id, param_name, param_value_size, param_value,
        param_value_size_ret, "OpenCL 1.1 Mock");
}

/**
 * A stub for clGetPlatformInfo that will only support querying
 * CL_PLATFORM_VERSION, and will return version 1.2.
 */
static cl_int clGetPlatformInfo_version_1_2(
    cl_platform_id id,
    cl_platform_info param_name,
    size_t param_value_size,
    void *param_value,
    size_t *param_value_size_ret,
    int num_calls)
{
    (void) num_calls;
    return clGetPlatformInfo_version(
        id, param_name, param_value_size, param_value,
        param_value_size_ret, "OpenCL 1.2 Mock");
}

/**
 * A stub for clGetPlatformInfo that will only support querying
 * CL_PLATFORM_VERSION, and will return version 2.0.
 */
static cl_int clGetPlatformInfo_version_2_0(
    cl_platform_id id,
    cl_platform_info param_name,
    size_t param_value_size,
    void *param_value,
    size_t *param_value_size_ret,
    int num_calls)
{
    (void) num_calls;
    return clGetPlatformInfo_version(
        id, param_name, param_value_size, param_value,
        param_value_size_ret, "OpenCL 2.0 Mock");
}

/* Simulated reference counts. The table points to memory held by the caller.
 * This makes things simpler in the common case of only one object to be
 * reference counted.
 */
class RefcountTable
{
private:
    int n; // number of objects
    void * const *objects; // object IDs
    int *refcounts;        // current refcounts

    int find(void *object)
    {
        int idx = 0;
        while (idx < n && objects[idx] != object)
            idx++;
        TEST_ASSERT(idx < n);
        TEST_ASSERT(refcounts[idx] > 0); // otherwise object has been destroyed
        return idx;
    }

public:
    RefcountTable() : n(0), objects(NULL), refcounts(NULL) {}

    void init(int n, void * const *objects, int *refcounts)
    {
        this->n = n;
        this->objects = objects;
        this->refcounts = refcounts;
    }

    void reset()
    {
        init(0, NULL, NULL);
    }

    cl_int retain(void *object)
    {
        int idx = find(object);
        ++refcounts[idx];
        return CL_SUCCESS;
    }

    cl_int release(void *object)
    {
        int idx = find(object);
        --refcounts[idx];
        return CL_SUCCESS;
    }
};

/* Stubs for retain/release calls that track reference counts. The stubs
 * check that the reference count never becomes negative and that a zero
 * reference count is never incremented.
 *
 * Use the prepareRefcount* calls to set up the global variables first.
 */

#define MAKE_REFCOUNT_STUBS(cl_type, retainfunc, releasefunc, table) \
    static RefcountTable table; \
    static cl_int retainfunc ## _refcount(cl_type object, int num_calls) \
    { \
        (void) num_calls; \
        return table.retain(object); \
    } \
    static cl_int releasefunc ## _refcount(cl_type object, int num_calls) \
    { \
        (void) num_calls; \
        return table.release(object); \
    } \
    static void prepare_ ## table(int n, cl_type const *objects, int *refcounts) \
    { \
        table.init(n, (void * const *) objects, refcounts); \
        retainfunc ## _StubWithCallback(retainfunc ## _refcount); \
        releasefunc ## _StubWithCallback(releasefunc ## _refcount); \
    }

MAKE_REFCOUNT_STUBS(cl_device_id, clRetainDevice, clReleaseDevice, deviceRefcounts)
MAKE_REFCOUNT_STUBS(cl_context, clRetainContext, clReleaseContext, contextRefcounts)
MAKE_REFCOUNT_STUBS(cl_mem, clRetainMemObject, clReleaseMemObject, memRefcounts)

/* The indirection through MAKE_MOVE_TESTS2 with a prefix parameter is to
 * prevent the simple-minded parser from Unity from identifying tests from the
 * macro value.
 */
#ifdef TEST_RVALUE_REFERENCES
#define MAKE_MOVE_TESTS2(prefix, type, makeFunc, releaseFunc, pool) \
    void prefix ## MoveAssign ## type ## NonNull() \
    { \
        releaseFunc ## _ExpectAndReturn(makeFunc(0), CL_SUCCESS); \
        pool[0] = std::move(pool[1]); \
        TEST_ASSERT_EQUAL_PTR(makeFunc(1), pool[0]()); \
        TEST_ASSERT_NULL(pool[1]()); \
    } \
    \
    void prefix ## MoveAssign ## type ## Null() \
    { \
        pool[0]() = NULL; \
        pool[0] = std::move(pool[1]); \
        TEST_ASSERT_EQUAL_PTR(makeFunc(1), pool[0]()); \
        TEST_ASSERT_NULL(pool[1]()); \
    } \
    \
    void prefix ## MoveConstruct ## type ## NonNull() \
    { \
        cl::type tmp(std::move(pool[0])); \
        TEST_ASSERT_EQUAL_PTR(makeFunc(0), tmp()); \
        TEST_ASSERT_NULL(pool[0]()); \
        tmp() = NULL; \
    } \
    \
    void prefix ## MoveConstruct ## type ## Null() \
    { \
        cl::type empty; \
        cl::type tmp(std::move(empty)); \
        TEST_ASSERT_NULL(tmp()); \
        TEST_ASSERT_NULL(empty()); \
    }
#else
#define MAKE_MOVE_TESTS2(prefix, type, makeFunc, releaseFunc, pool) \
    void prefix ## MoveAssign ## type ## NonNull() {} \
    void prefix ## MoveAssign ## type ## Null() {} \
    void prefix ## MoveConstruct ## type ## NonNull() {} \
    void prefix ## MoveConstruct ## type ## Null() {}
#endif // !TEST_RVALUE_REFERENCES
#define MAKE_MOVE_TESTS(type, makeFunc, releaseFunc, pool) \
    MAKE_MOVE_TESTS2(test, type, makeFunc, releaseFunc, pool)

void setUp()
{
    /* We reach directly into the objects rather than using assignment to
     * avoid the reference counting functions from being called.
     */
    for (int i = 0; i < POOL_MAX; i++)
    {
        platformPool[i]() = make_platform_id(i);
        contextPool[i]() = make_context(i);
        commandQueuePool[i]() = make_command_queue(i);
        bufferPool[i]() = make_mem(i);
        image2DPool[i]() = make_mem(i);
        image3DPool[i]() = make_mem(i);
        kernelPool[i]() = make_kernel(i);
    }

    deviceRefcounts.reset();
    contextRefcounts.reset();
    memRefcounts.reset();
}

void tearDown()
{
    /* Wipe out the internal state to avoid a release call being made */
    for (int i = 0; i < POOL_MAX; i++)
    {
        platformPool[i]() = NULL;
        contextPool[i]() = NULL;
        commandQueuePool[i]() = NULL;
        bufferPool[i]() = NULL;
        image2DPool[i]() = NULL;
        image3DPool[i]() = NULL;
        kernelPool[i]() = NULL;
    }
}

/****************************************************************************
 * Tests for cl::Context
 ****************************************************************************/

void testCopyContextNonNull()
{
    clReleaseContext_ExpectAndReturn(make_context(0), CL_SUCCESS);
    clRetainContext_ExpectAndReturn(make_context(1), CL_SUCCESS);

    contextPool[0] = contextPool[1];
    TEST_ASSERT_EQUAL_PTR(make_context(1), contextPool[0]());
}

void testMoveAssignContextNonNull();
void testMoveAssignContextNull();
void testMoveConstructContextNonNull();
void testMoveConstructContextNull();
MAKE_MOVE_TESTS(Context, make_context, clReleaseContext, contextPool)

/// Stub for querying CL_CONTEXT_DEVICES that returns two devices
static cl_int clGetContextInfo_testContextGetDevices(
    cl_context context,
    cl_context_info param_name,
    size_t param_value_size,
    void *param_value,
    size_t *param_value_size_ret,
    int num_calls)
{
    (void) num_calls;
    TEST_ASSERT_EQUAL_PTR(make_context(0), context);
    TEST_ASSERT_EQUAL_HEX(CL_CONTEXT_DEVICES, param_name);
    TEST_ASSERT(param_value == NULL || param_value_size >= 2 * sizeof(cl_device_id));
    if (param_value_size_ret != NULL)
        *param_value_size_ret = 2 * sizeof(cl_device_id);
    if (param_value != NULL)
    {
        cl_device_id *devices = (cl_device_id *) param_value;
        devices[0] = make_device_id(0);
        devices[1] = make_device_id(1);
    }
    return CL_SUCCESS;
}

/// Test that queried devices are not refcounted
void testContextGetDevices1_1()
{
    clGetContextInfo_StubWithCallback(clGetContextInfo_testContextGetDevices);
    clGetDeviceInfo_StubWithCallback(clGetDeviceInfo_platform);
    clGetPlatformInfo_StubWithCallback(clGetPlatformInfo_version_1_1);

    VECTOR_CLASS<cl::Device> devices = contextPool[0].getInfo<CL_CONTEXT_DEVICES>();
    TEST_ASSERT_EQUAL(2, devices.size());
    TEST_ASSERT_EQUAL_PTR(make_device_id(0), devices[0]());
    TEST_ASSERT_EQUAL_PTR(make_device_id(1), devices[1]());
}

/// Test that queried devices are correctly refcounted
void testContextGetDevices1_2()
{
    clGetContextInfo_StubWithCallback(clGetContextInfo_testContextGetDevices);
    clGetDeviceInfo_StubWithCallback(clGetDeviceInfo_platform);
    clGetPlatformInfo_StubWithCallback(clGetPlatformInfo_version_1_2);

    clRetainDevice_ExpectAndReturn(make_device_id(0), CL_SUCCESS);
    clRetainDevice_ExpectAndReturn(make_device_id(1), CL_SUCCESS);

    VECTOR_CLASS<cl::Device> devices = contextPool[0].getInfo<CL_CONTEXT_DEVICES>();
    TEST_ASSERT_EQUAL(2, devices.size());
    TEST_ASSERT_EQUAL_PTR(make_device_id(0), devices[0]());
    TEST_ASSERT_EQUAL_PTR(make_device_id(1), devices[1]());

    // Prevent release in the destructor
    devices[0]() = NULL;
    devices[1]() = NULL;
}

// This is used to get a list of all platforms, so expect two calls
// First, return to say we have two platforms
// Then return the two platform id_s
static cl_int clGetPlatformIDs_testContextFromType(
    cl_uint num_entries,
    cl_platform_id *platforms,
    cl_uint *num_platforms,
    int num_calls)
{
    if (num_calls == 0)
    {
        TEST_ASSERT_NULL(platforms);
        TEST_ASSERT_NOT_NULL(num_platforms);
        *num_platforms = 2;
        return CL_SUCCESS;
    }
    else if (num_calls == 1)
    {
        TEST_ASSERT_NOT_NULL(platforms);
        TEST_ASSERT_EQUAL(2, num_entries);
        platforms[0] = make_platform_id(0);
        platforms[1] = make_platform_id(1);
        return CL_SUCCESS;
    }
    else
    {
        TEST_FAIL_MESSAGE("clGetPlatformIDs called too many times");
        return CL_INVALID_VALUE;
    }
}

// Expect three calls to this
// 1. Platform 1, we have no GPUs
// 2. Platform 2, we have two GPUs
// 3. Here are the two cl_device_id's
static cl_int clGetDeviceIDs_testContextFromType(
    cl_platform_id  platform,
    cl_device_type  device_type,
    cl_uint  num_entries,
    cl_device_id  *devices,
    cl_uint  *num_devices,
    int num_calls)
{
    if (num_calls == 0)
    {
        TEST_ASSERT_EQUAL_PTR(make_platform_id(0), platform);
        TEST_ASSERT_EQUAL(CL_DEVICE_TYPE_GPU, device_type);
        TEST_ASSERT_NOT_NULL(num_devices);
        return CL_DEVICE_NOT_FOUND;
    }
    else if (num_calls == 1)
    {
        TEST_ASSERT_EQUAL_PTR(make_platform_id(1), platform);
        TEST_ASSERT_EQUAL(CL_DEVICE_TYPE_GPU, device_type);
        TEST_ASSERT_NOT_NULL(num_devices);
        *num_devices = 2;
        return CL_SUCCESS;
    }
    else if (num_calls == 2)
    {
        TEST_ASSERT_EQUAL_PTR(make_platform_id(1), platform);
        TEST_ASSERT_EQUAL(CL_DEVICE_TYPE_GPU, device_type);
        TEST_ASSERT_EQUAL(2, num_entries);
        TEST_ASSERT_NOT_NULL(devices);
        devices[0] = make_device_id(0);
        devices[1] = make_device_id(1);
        return CL_SUCCESS;
    }
    else
    {
        TEST_FAIL_MESSAGE("clGetDeviceIDs called too many times");
        return CL_INVALID_VALUE;
    }
}

// Stub for clCreateContextFromType
// - expect platform 1 with GPUs and non-null properties
static cl_context clCreateContextFromType_testContextFromType(
    const cl_context_properties  *properties,
    cl_device_type  device_type,
    void  (CL_CALLBACK *pfn_notify) (const char *errinfo,
    const void  *private_info,
    size_t  cb,
    void  *user_data),
    void  *user_data,
    cl_int  *errcode_ret,
    int num_calls)
{
    TEST_ASSERT_EQUAL(CL_DEVICE_TYPE_GPU, device_type);
#if !defined(__APPLE__) && !defined(__MACOS)
    TEST_ASSERT_NOT_NULL(properties);
    TEST_ASSERT_EQUAL(CL_CONTEXT_PLATFORM, properties[0]);
    TEST_ASSERT_EQUAL(make_platform_id(1), properties[1]);
#endif
    return make_context(0);
}

void testContextFromType()
{
#if !defined(__APPLE__) && !defined(__MACOS)
    clGetPlatformIDs_StubWithCallback(clGetPlatformIDs_testContextFromType);
    clGetDeviceIDs_StubWithCallback(clGetDeviceIDs_testContextFromType);

    // The opencl.hpp header will perform an extra retain here to be consistent
    // with other APIs retaining runtime-owned objects before releasing them
    clRetainDevice_ExpectAndReturn(make_device_id(0), CL_SUCCESS);
    clRetainDevice_ExpectAndReturn(make_device_id(1), CL_SUCCESS);

    clGetDeviceInfo_StubWithCallback(clGetDeviceInfo_platform);
    clGetPlatformInfo_StubWithCallback(clGetPlatformInfo_version_1_2);

    // End of scope of vector of devices within constructor
    clReleaseDevice_ExpectAndReturn(make_device_id(0), CL_SUCCESS);
    clReleaseDevice_ExpectAndReturn(make_device_id(1), CL_SUCCESS);
#endif

    clCreateContextFromType_StubWithCallback(clCreateContextFromType_testContextFromType);

    cl::Context context(CL_DEVICE_TYPE_GPU);
    TEST_ASSERT_EQUAL_PTR(make_context(0), context());

    clReleaseContext_ExpectAndReturn(make_context(0), CL_SUCCESS);
}

/****************************************************************************
 * Tests for cl::CommandQueue
 ****************************************************************************/

void testMoveAssignCommandQueueNonNull();
void testMoveAssignCommandQueueNull();
void testMoveConstructCommandQueueNonNull();
void testMoveConstructCommandQueueNull();
MAKE_MOVE_TESTS(CommandQueue, make_command_queue, clReleaseCommandQueue, commandQueuePool);

// Stub for clGetCommandQueueInfo that returns context 0
static cl_int clGetCommandQueueInfo_testCommandQueueGetContext(
    cl_command_queue command_queue,
    cl_command_queue_info param_name,
    size_t param_value_size,
    void *param_value,
    size_t *param_value_size_ret,
    int num_calls)
{
    (void) num_calls;
    TEST_ASSERT_EQUAL_PTR(make_command_queue(0), command_queue);
    TEST_ASSERT_EQUAL_HEX(CL_QUEUE_CONTEXT, param_name);
    TEST_ASSERT(param_value == NULL || param_value_size >= sizeof(cl_context));
    if (param_value_size_ret != NULL)
        *param_value_size_ret = sizeof(cl_context);
    if (param_value != NULL)
        *(cl_context *) param_value = make_context(0);
    return CL_SUCCESS;
}

void testCommandQueueGetContext()
{
    cl_context expected = make_context(0);
    int refcount = 1;

    clGetCommandQueueInfo_StubWithCallback(clGetCommandQueueInfo_testCommandQueueGetContext);
    prepare_contextRefcounts(1, &expected, &refcount);

    cl::Context ctx = commandQueuePool[0].getInfo<CL_QUEUE_CONTEXT>();
    TEST_ASSERT_EQUAL_PTR(expected, ctx());
    TEST_ASSERT_EQUAL(2, refcount);

    ctx() = NULL;
}

// Stub for clGetCommandQueueInfo that returns device 0
static cl_int clGetCommandQueueInfo_testCommandQueueGetDevice(
    cl_command_queue command_queue,
    cl_command_queue_info param_name,
    size_t param_value_size,
    void *param_value,
    size_t *param_value_size_ret,
    int num_calls)
{
    (void) num_calls;
    TEST_ASSERT_EQUAL_PTR(make_command_queue(0), command_queue);
    TEST_ASSERT_EQUAL_HEX(CL_QUEUE_DEVICE, param_name);
    TEST_ASSERT(param_value == NULL || param_value_size >= sizeof(cl_device_id));
    if (param_value_size_ret != NULL)
        *param_value_size_ret = sizeof(cl_device_id);
    if (param_value != NULL)
        *(cl_device_id *) param_value = make_device_id(0);
    return CL_SUCCESS;
}

void testCommandQueueGetDevice1_1()
{
    cl_device_id expected = make_device_id(0);

    clGetDeviceInfo_StubWithCallback(clGetDeviceInfo_platform);
    clGetPlatformInfo_StubWithCallback(clGetPlatformInfo_version_1_1);
    clGetCommandQueueInfo_StubWithCallback(clGetCommandQueueInfo_testCommandQueueGetDevice);

    cl::Device device = commandQueuePool[0].getInfo<CL_QUEUE_DEVICE>();
    TEST_ASSERT_EQUAL_PTR(expected, device());

    device() = NULL;
}

void testCommandQueueGetDevice1_2()
{
    cl_device_id expected = make_device_id(0);
    int refcount = 1;

    clGetDeviceInfo_StubWithCallback(clGetDeviceInfo_platform);
    clGetPlatformInfo_StubWithCallback(clGetPlatformInfo_version_1_2);
    clGetCommandQueueInfo_StubWithCallback(clGetCommandQueueInfo_testCommandQueueGetDevice);
    prepare_deviceRefcounts(1, &expected, &refcount);

    cl::Device device = commandQueuePool[0].getInfo<CL_QUEUE_DEVICE>();
    TEST_ASSERT_EQUAL_PTR(expected, device());
    TEST_ASSERT_EQUAL(2, refcount);

    device() = NULL;
}

// stub for clCreateCommandQueue - returns queue zero
static cl_command_queue clCreateCommandQueue_testCommandQueueFromSpecifiedContext(
    cl_context context,
    cl_device_id device,
    cl_command_queue_properties properties,
    cl_int *errcode_ret,
    int num_calls)
{
    (void) num_calls;
    TEST_ASSERT_EQUAL_PTR(make_context(0), context);
    TEST_ASSERT_EQUAL_PTR(make_device_id(0), device);
    TEST_ASSERT(properties == 0);
    return make_command_queue(0);
}

#if CL_HPP_TARGET_OPENCL_VERSION >= 200
// stub for clCreateCommandQueueWithProperties - returns queue zero
static cl_command_queue clCreateCommandQueueWithProperties_testCommandQueueFromSpecifiedContext(
    cl_context context,
    cl_device_id device,
    const cl_queue_properties *properties,
    cl_int *errcode_ret,
    int num_calls)
{
    (void)num_calls;
    TEST_ASSERT_EQUAL_PTR(make_context(0), context);
    TEST_ASSERT_EQUAL_PTR(make_device_id(0), device);
    TEST_ASSERT(properties[0] == CL_QUEUE_PROPERTIES);
    TEST_ASSERT(properties[1] == 0);
    return make_command_queue(0);
}
#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200

void testCommandQueueFromSpecifiedContext()
{
    cl_command_queue expected = make_command_queue(0);
    cl_context expected_context =  make_context(0);
    cl_device_id expected_device = make_device_id(0);

    int context_refcount = 1;
    int device_refcount = 1;
    prepare_contextRefcounts(1, &expected_context, &context_refcount);
    prepare_deviceRefcounts(1, &expected_device, &device_refcount);

    // This is the context we will pass in to test
    cl::Context context = contextPool[0];

    // Assumes the context contains the fi rst device
    clGetContextInfo_StubWithCallback(clGetContextInfo_device);

#if CL_HPP_TARGET_OPENCL_VERSION >= 200
    clCreateCommandQueueWithProperties_StubWithCallback(clCreateCommandQueueWithProperties_testCommandQueueFromSpecifiedContext);
#else // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
    clCreateCommandQueue_StubWithCallback(clCreateCommandQueue_testCommandQueueFromSpecifiedContext);
#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
    clGetDeviceInfo_StubWithCallback(clGetDeviceInfo_platform);

#if CL_HPP_TARGET_OPENCL_VERSION >= 200
    clGetPlatformInfo_StubWithCallback(clGetPlatformInfo_version_2_0);
#else // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
    clGetPlatformInfo_StubWithCallback(clGetPlatformInfo_version_1_2);
#endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
    clReleaseCommandQueue_ExpectAndReturn(expected, CL_SUCCESS);

    cl::CommandQueue queue(context);
    TEST_ASSERT_EQUAL_PTR(expected, queue());

    // Context not destroyed yet
    TEST_ASSERT_EQUAL(2, context_refcount);
    // Device object destroyed at end of scope
    TEST_ASSERT_EQUAL(1, device_refcount);

}

/****************************************************************************
 * Tests for cl::Device
 ****************************************************************************/

void testCopyDeviceNonNull1_1()
{
    clGetDeviceInfo_StubWithCallback(clGetDeviceInfo_platform);
    clGetPlatformInfo_StubWithCallback(clGetPlatformInfo_version_1_1);

    cl::Device d0(make_device_id(0));
    cl::Device d1(make_device_id(1));
    d0 = d1;
}

void testCopyDeviceNonNull1_2()
{
    clGetDeviceInfo_StubWithCallback(clGetDeviceInfo_platform);
    clGetPlatformInfo_StubWithCallback(clGetPlatformInfo_version_1_2);
    clReleaseDevice_ExpectAndReturn(make_device_id(0), CL_SUCCESS);
    clRetainDevice_ExpectAndReturn(make_device_id(1), CL_SUCCESS);

    cl::Device d0(make_device_id(0));
    cl::Device d1(make_device_id(1));
    d0 = d1;

    // Prevent destructor from interfering with the test
    d0() = NULL;
    d1() = NULL;
}

void testCopyDeviceFromNull1_1()
{
    clGetDeviceInfo_StubWithCallback(clGetDeviceInfo_platform);
    clGetPlatformInfo_StubWithCallback(clGetPlatformInfo_version_1_1);
    // No other calls expected

    cl::Device d(make_device_id(0));
    d = cl::Device();
}

void testCopyDeviceFromNull1_2()
{
    clGetDeviceInfo_StubWithCallback(clGetDeviceInfo_platform);
    clGetPlatformInfo_StubWithCallback(clGetPlatformInfo_version_1_2);
    clReleaseDevice_ExpectAndReturn(make_device_id(0), CL_SUCCESS);

    cl::Device d(make_device_id(0));
    d = cl::Device();
}

void testCopyDeviceToNull1_1()
{
    clGetDeviceInfo_StubWithCallback(clGetDeviceInfo_platform);
    clGetPlatformInfo_StubWithCallback(clGetPlatformInfo_version_1_1);
    // No other calls expected

    cl::Device d0;
    cl::Device d1(make_device_id(0));
    d0 = d1;
}

void testCopyDeviceToNull1_2()
{
    clGetDeviceInfo_StubWithCallback(clGetDeviceInfo_platform);
    clGetPlatformInfo_StubWithCallback(clGetPlatformInfo_version_1_2);
    clRetainDevice_ExpectAndReturn(make_device_id(0), CL_SUCCESS);

    cl::Device d0;
    cl::Device d1(make_device_id(0));
    d0 = d1;

    // Prevent destructor from interfering with the test
    d0() = NULL;
    d1() = NULL;
}

void testCopyDeviceSelf()
{
    // Use 1.2 to check the retain/release calls
    clGetDeviceInfo_StubWithCallback(clGetDeviceInfo_platform);
    clGetPlatformInfo_StubWithCallback(clGetPlatformInfo_version_1_2);
    clReleaseDevice_ExpectAndReturn(make_device_id(0), CL_SUCCESS);
    clRetainDevice_ExpectAndReturn(make_device_id(1), CL_SUCCESS);

    cl::Device d0(make_device_id(0));
    cl::Device d1(make_device_id(1));
    d0 = d1;

    // Prevent destructor from interfering with the test
    d0() = NULL;
    d1() = NULL;
}

void testAssignDeviceNull()
{
    // Any version will do here
    clGetDeviceInfo_StubWithCallback(clGetDeviceInfo_platform);
    clGetPlatformInfo_StubWithCallback(clGetPlatformInfo_version_1_2);
    clReleaseDevice_ExpectAndReturn(make_device_id(0), CL_SUCCESS);

    cl::Device d(make_device_id(0));
    d = (cl_device_id) NULL;
}

// These tests do not use the MAKE_MOVE_TESTS helper because they need to
// check whether the device is reference-countable, and to check that
// the reference-countable flag is correctly moved.
void testMoveAssignDeviceNonNull()
{
#ifdef TEST_RVALUE_REFERENCES
    clGetDeviceInfo_StubWithCallback(clGetDeviceInfo_platform);
    clGetPlatformInfo_StubWithCallback(clGetPlatformInfo_version_1_2);

    // Release called when trg overwritten
    clReleaseDevice_ExpectAndReturn(make_device_id(1), CL_SUCCESS);

    cl::Device src(make_device_id(0));
    cl::Device trg(make_device_id(1));
    trg = std::move(src);
    TEST_ASSERT_EQUAL_PTR(make_device_id(0), trg());
    TEST_ASSERT_NULL(src());

    // Prevent destructor from interfering with the test
    trg() = NULL;
#endif
}

void testMoveAssignDeviceNull()
{
#ifdef TEST_RVALUE_REFERENCES
    clGetDeviceInfo_StubWithCallback(clGetDeviceInfo_platform);
    clGetPlatformInfo_StubWithCallback(clGetPlatformInfo_version_1_2);

    cl::Device trg;
    cl::Device src(make_device_id(1));
    trg = std::move(src);
    TEST_ASSERT_EQUAL_PTR(make_device_id(1), trg());
    TEST_ASSERT_NULL(src());

    // Prevent destructor from interfering with the test
    trg() = NULL;
#endif
}

void testMoveConstructDeviceNonNull()
{
#ifdef TEST_RVALUE_REFERENCES
    clGetDeviceInfo_StubWithCallback(clGetDeviceInfo_platform);
    clGetPlatformInfo_StubWithCallback(clGetPlatformInfo_version_1_2);

    cl::Device src(make_device_id(0));
    cl::Device trg(std::move(src));
    TEST_ASSERT_EQUAL_PTR(make_device_id(0), trg());
    TEST_ASSERT_NULL(src());

    // Prevent destructor from interfering with the test
    trg() = NULL;
#endif
}

void testMoveConstructDeviceNull()
{
#ifdef TEST_RVALUE_REFERENCES
    cl::Device empty;
    cl::Device trg(std::move(empty));
    TEST_ASSERT_NULL(trg());
    TEST_ASSERT_NULL(empty());
#endif
}

void testDestroyDevice1_1()
{
    clGetDeviceInfo_StubWithCallback(clGetDeviceInfo_platform);
    clGetPlatformInfo_StubWithCallback(clGetPlatformInfo_version_1_1);
    // No other calls expected

    cl::Device d(make_device_id(0));
}

void testDestroyDevice1_2()
{
    clGetDeviceInfo_StubWithCallback(clGetDeviceInfo_platform);
    clGetPlatformInfo_StubWithCallback(clGetPlatformInfo_version_1_2);
    clReleaseDevice_ExpectAndReturn(make_device_id(0), CL_SUCCESS);

    cl::Device d(make_device_id(0));
}

static cl_int clGetDeviceIDs_PlatformWithZeroDevices(
    cl_platform_id  platform,
    cl_device_type  device_type,
    cl_uint  num_entries,
    cl_device_id  *devices,
    cl_uint  *num_devices,
    int num_calls)
{
    if (num_calls == 0)
    {
        TEST_ASSERT_EQUAL_PTR(make_platform_id(0), platform);
        TEST_ASSERT_EQUAL(CL_DEVICE_TYPE_ALL, device_type);
        TEST_ASSERT_NOT_NULL(num_devices);
        return CL_DEVICE_NOT_FOUND;
    }
    else
    {
        TEST_FAIL_MESSAGE("clGetDeviceIDs called too many times");
        return CL_INVALID_VALUE;
    }
}

void testPlatformWithZeroDevices()
{
    clGetDeviceIDs_StubWithCallback(clGetDeviceIDs_PlatformWithZeroDevices);

    cl::Platform p(make_platform_id(0));
    std::vector<cl::Device> devices;

    cl_int errCode = p.getDevices(CL_DEVICE_TYPE_ALL, &devices);
    TEST_ASSERT_EQUAL(CL_SUCCESS, errCode);
    TEST_ASSERT_EQUAL(0, devices.size());
}

/****************************************************************************
 * Tests for cl::Buffer
 ****************************************************************************/

void testMoveAssignBufferNonNull();
void testMoveAssignBufferNull();
void testMoveConstructBufferNonNull();
void testMoveConstructBufferNull();
MAKE_MOVE_TESTS(Buffer, make_mem, clReleaseMemObject, bufferPool);

// Stub of clCreateBuffer for testBufferConstructorContextInterator
// - return the first memory location

static cl_mem clCreateBuffer_testBufferConstructorContextIterator(
    cl_context context,
    cl_mem_flags flags,
    size_t size,
    void *host_ptr,
    cl_int *errcode_ret,
    int num_calls)
{
    TEST_ASSERT_EQUAL_PTR(make_context(0), context);
    TEST_ASSERT_BITS(CL_MEM_COPY_HOST_PTR, flags, !CL_MEM_COPY_HOST_PTR);
    TEST_ASSERT_BITS(CL_MEM_READ_ONLY, flags, CL_MEM_READ_ONLY);
    TEST_ASSERT_EQUAL(sizeof(int)*1024, size);
    TEST_ASSERT_NULL(host_ptr);
    if (errcode_ret)
        errcode_ret = CL_SUCCESS;
    return make_mem(0);
}

// Declare forward these functions
static void * clEnqueueMapBuffer_testCopyHostToBuffer(
    cl_command_queue command_queue,
    cl_mem buffer,
    cl_bool blocking_map,
    cl_map_flags map_flags,
    size_t offset,
    size_t size,
    cl_uint num_events_in_wait_list,
    const cl_event *event_wait_list,
    cl_event *event,
    cl_int *errcode_ret,
    int num_calls);

static cl_int clEnqueueUnmapMemObject_testCopyHostToBuffer(
    cl_command_queue  command_queue ,
    cl_mem  memobj,
    void  *mapped_ptr,
    cl_uint  num_events_in_wait_list ,
    const cl_event  *event_wait_list ,
    cl_event  *event,
    int num_calls);

static cl_int clWaitForEvents_testCopyHostToBuffer(
    cl_uint num_events,
    const cl_event *event_list,
    int num_calls);

static cl_int clReleaseEvent_testCopyHostToBuffer(
    cl_event event,
    int num_calls);

void testBufferConstructorContextIterator()
{
    cl_mem expected = make_mem(0);

    // Assume this context includes make_device_id(0) for stub clGetContextInfo_device
    cl::Context context(make_context(0));

    clCreateBuffer_StubWithCallback(clCreateBuffer_testBufferConstructorContextIterator);
    clGetContextInfo_StubWithCallback(clGetContextInfo_device);
    clGetDeviceInfo_StubWithCallback(clGetDeviceInfo_platform);
#if CL_HPP_TARGET_OPENCL_VERSION >= 200
    clGetPlatformInfo_StubWithCallback(clGetPlatformInfo_version_2_0);
#else // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
    clGetPlatformInfo_StubWithCallback(clGetPlatformInfo_version_1_2);
#endif //#if CL_HPP_TARGET_OPENCL_VERSION >= 200
    clRetainDevice_ExpectAndReturn(make_device_id(0), CL_SUCCESS);

#if CL_HPP_TARGET_OPENCL_VERSION >= 200
    clCreateCommandQueueWithProperties_StubWithCallback(clCreateCommandQueueWithProperties_testCommandQueueFromSpecifiedContext);
#else // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
    clCreateCommandQueue_StubWithCallback(clCreateCommandQueue_testCommandQueueFromSpecifiedContext);
#endif //#if CL_HPP_TARGET_OPENCL_VERSION >= 200
    clReleaseDevice_ExpectAndReturn(make_device_id(0), CL_SUCCESS);
    clEnqueueMapBuffer_StubWithCallback(clEnqueueMapBuffer_testCopyHostToBuffer);
    clEnqueueUnmapMemObject_StubWithCallback(clEnqueueUnmapMemObject_testCopyHostToBuffer);
    clWaitForEvents_StubWithCallback(clWaitForEvents_testCopyHostToBuffer);
    clReleaseEvent_StubWithCallback(clReleaseEvent_testCopyHostToBuffer);
    clReleaseCommandQueue_ExpectAndReturn(make_command_queue(0), CL_SUCCESS);

    std::vector<int> host(1024);

    cl::Buffer buffer(context, host.begin(), host.end(), true);

    TEST_ASSERT_EQUAL_PTR(expected, buffer());

    // Tidy up at end of test
    clReleaseMemObject_ExpectAndReturn(expected, CL_SUCCESS);
    clReleaseContext_ExpectAndReturn(make_context(0), CL_SUCCESS);
}

void testBufferConstructorQueueIterator()
{
    cl_context expected_context = make_context(0);
    int context_refcount = 1;
    cl_mem expected = make_mem(0);

    cl::CommandQueue queue(make_command_queue(0));

    prepare_contextRefcounts(1, &expected_context, &context_refcount);
    clGetCommandQueueInfo_StubWithCallback(clGetCommandQueueInfo_context);
    clCreateBuffer_StubWithCallback(clCreateBuffer_testBufferConstructorContextIterator);

    clEnqueueMapBuffer_StubWithCallback(clEnqueueMapBuffer_testCopyHostToBuffer);
    clEnqueueUnmapMemObject_StubWithCallback(clEnqueueUnmapMemObject_testCopyHostToBuffer);
    clWaitForEvents_StubWithCallback(clWaitForEvents_testCopyHostToBuffer);
    clReleaseEvent_StubWithCallback(clReleaseEvent_testCopyHostToBuffer);

    std::vector<int> host(1024);

    cl::Buffer buffer(queue, host.begin(), host.end(), true);

    TEST_ASSERT_EQUAL_PTR(expected, buffer());
    TEST_ASSERT_EQUAL(1, context_refcount);

    // Tidy up at end of test
    clReleaseMemObject_ExpectAndReturn(expected, CL_SUCCESS);
    clReleaseCommandQueue_ExpectAndReturn(make_command_queue(0), CL_SUCCESS);
}

/****************************************************************************
 * Tests for cl::Image1DBuffer
 ****************************************************************************/

/**
 * Stub for querying CL_IMAGE_BUFFER and returning make_mem(1).
 */
cl_int clGetImageInfo_testGetImageInfoBuffer(
    cl_mem image, cl_image_info param_name,
    size_t param_value_size, void *param_value,
    size_t *param_value_size_ret,
    int num_calls)
{
    TEST_ASSERT_EQUAL(0, num_calls);
    TEST_ASSERT_EQUAL_PTR(make_mem(0), image);
    TEST_ASSERT_EQUAL_HEX(CL_IMAGE_BUFFER, param_name);
    TEST_ASSERT_EQUAL(sizeof(cl_mem), param_value_size);

    if (param_value != NULL)
    {
        *(cl_mem *) param_value = make_mem(1);
    }
    if (param_value_size_ret != NULL)
        *param_value_size_ret = sizeof(cl_mem);
    return CL_SUCCESS;
}

void testGetImageInfoBuffer()
{
#if CL_HPP_TARGET_OPENCL_VERSION >= 200
    cl_mem expected = make_mem(1);
    int refcount = 1;

    clGetImageInfo_StubWithCallback(clGetImageInfo_testGetImageInfoBuffer);
    prepare_memRefcounts(1, &expected, &refcount);

    cl::Image1DBuffer image(make_mem(0));
    const cl::Buffer &buffer = image.getImageInfo<CL_IMAGE_BUFFER>();
    TEST_ASSERT_EQUAL_PTR(make_mem(1), buffer());
    // Ref count should be 2 here because buffer has not been destroyed yet
    TEST_ASSERT_EQUAL(2, refcount);

    // prevent destructor from interfering with the test
    image() = NULL;
#endif
}

/**
 * Stub for querying CL_IMAGE_BUFFER and returning NULL.
 */
cl_int clGetImageInfo_testGetImageInfoBufferNull(
    cl_mem image, cl_image_info param_name,
    size_t param_value_size, void *param_value,
    size_t *param_value_size_ret,
    int num_calls)
{
    TEST_ASSERT_EQUAL(0, num_calls);
    TEST_ASSERT_EQUAL_PTR(make_mem(0), image);
    TEST_ASSERT_EQUAL_HEX(CL_IMAGE_BUFFER, param_name);
    TEST_ASSERT_EQUAL(sizeof(cl_mem), param_value_size);

    if (param_value != NULL)
    {
        *(cl_mem *) param_value = NULL;
    }
    if (param_value_size_ret != NULL)
        *param_value_size_ret = sizeof(cl_mem);
    return CL_SUCCESS;
}

void testGetImageInfoBufferNull()
{
#if CL_HPP_TARGET_OPENCL_VERSION >= 200
    clGetImageInfo_StubWithCallback(clGetImageInfo_testGetImageInfoBufferNull);

    cl::Image2D image(make_mem(0));
    cl::Buffer buffer = image.getImageInfo<CL_IMAGE_BUFFER>();
    TEST_ASSERT_NULL(buffer());

    // prevent destructor from interfering with the test
    image() = NULL;
#endif
}

void testGetImageInfoBufferOverwrite()
{
    clGetImageInfo_StubWithCallback(clGetImageInfo_testGetImageInfoBuffer);
    clReleaseMemObject_ExpectAndReturn(make_mem(2), CL_SUCCESS);
    clRetainMemObject_ExpectAndReturn(make_mem(1), CL_SUCCESS);

    cl::Image2D image(make_mem(0));
    cl::Buffer buffer(make_mem(2));
    cl_int status = image.getImageInfo(CL_IMAGE_BUFFER, &buffer);
    TEST_ASSERT_EQUAL(CL_SUCCESS, status);
    TEST_ASSERT_EQUAL_PTR(make_mem(1), buffer());

    // prevent destructor from interfering with the test
    image() = NULL;
    buffer() = NULL;
}

/**
 * A stub for clCreateImage that creates an image from a buffer
 * passing the buffer's cl_mem straight through.
 */
cl_mem clCreateImage_image1dbuffer(
    cl_context context,
    cl_mem_flags flags,
    const cl_image_format *image_format,
    const cl_image_desc *image_desc,
    void *host_ptr,
    cl_int *errcode_ret,
    int num_calls)
{
    TEST_ASSERT_NOT_NULL(image_format);
    TEST_ASSERT_NOT_NULL(image_desc);
    TEST_ASSERT_EQUAL_HEX(CL_MEM_OBJECT_IMAGE1D_BUFFER, image_desc->image_type);

    // Return the passed buffer as the cl_mem
    return image_desc->buffer;
}

void testConstructImageFromBuffer()
{
#if CL_HPP_TARGET_OPENCL_VERSION >= 120
    const size_t width = 64;
    clGetDeviceInfo_StubWithCallback(clGetDeviceInfo_platform);
    clGetPlatformInfo_StubWithCallback(clGetPlatformInfo_version_1_2);
    clCreateImage_StubWithCallback(clCreateImage_image1dbuffer);
    clReleaseMemObject_ExpectAndReturn(make_mem(0), CL_SUCCESS);
    clReleaseContext_ExpectAndReturn(make_context(0), CL_SUCCESS);

    cl::Context context(make_context(0));
    cl::Buffer buffer(make_mem(0));
    cl::Image1DBuffer image(
        context,
        CL_MEM_READ_ONLY,
        cl::ImageFormat(CL_R, CL_SIGNED_INT32),
        width,
        buffer);

    // Check that returned buffer matches the original
    TEST_ASSERT_EQUAL_PTR(buffer(), image());

    buffer() = NULL;
#endif
}

/****************************************************************************
 * Tests for cl::Image2D
 ****************************************************************************/

void testMoveAssignImage2DNonNull();
void testMoveAssignImage2DNull();
void testMoveConstructImage2DNonNull();
void testMoveConstructImage2DNull();
MAKE_MOVE_TESTS(Image2D, make_mem, clReleaseMemObject, image2DPool);

#ifdef CL_USE_DEPRECATED_OPENCL_1_1_APIS
static cl_mem clCreateImage2D_testCreateImage2D_1_1(
    cl_context context,
    cl_mem_flags flags,
    const cl_image_format *image_format,
    size_t image_width,
    size_t image_height,
    size_t image_row_pitch,
    void *host_ptr,
    cl_int *errcode_ret,
    int num_calls)
{
    TEST_ASSERT_EQUAL(0, num_calls);
    TEST_ASSERT_EQUAL_PTR(make_context(0), context);
    TEST_ASSERT_EQUAL_HEX(CL_MEM_READ_WRITE, flags);

    TEST_ASSERT_NOT_NULL(image_format);
    TEST_ASSERT_EQUAL_HEX(CL_R, image_format->image_channel_order);
    TEST_ASSERT_EQUAL_HEX(CL_FLOAT, image_format->image_channel_data_type);

    TEST_ASSERT_EQUAL(64, image_width);
    TEST_ASSERT_EQUAL(32, image_height);
    TEST_ASSERT_EQUAL(256, image_row_pitch);
    TEST_ASSERT_NULL(host_ptr);

    if (errcode_ret != NULL)
        *errcode_ret = CL_SUCCESS;
    return make_mem(0);
}
#endif

void testCreateImage2D_1_1()
{
#ifdef CL_USE_DEPRECATED_OPENCL_1_1_APIS
    clGetContextInfo_StubWithCallback(clGetContextInfo_device);
    clGetDeviceInfo_StubWithCallback(clGetDeviceInfo_platform);
    clGetPlatformInfo_StubWithCallback(clGetPlatformInfo_version_1_1);
    clCreateImage2D_StubWithCallback(clCreateImage2D_testCreateImage2D_1_1);

    cl_int err;
    cl::Context context;
    context() = make_context(0);
    cl::Image2D image(
        context, CL_MEM_READ_WRITE,
        cl::ImageFormat(CL_R, CL_FLOAT), 64, 32, 256, NULL, &err);

    TEST_ASSERT_EQUAL(CL_SUCCESS, err);
    TEST_ASSERT_EQUAL_PTR(make_mem(0), image());

    context() = NULL;
    image() = NULL;
#endif
}

static cl_mem clCreateImage_testCreateImage2D_1_2(
    cl_context context,
    cl_mem_flags flags,
    const cl_image_format *image_format,
    const cl_image_desc *image_desc,
    void *host_ptr,
    cl_int *errcode_ret,
    int num_calls)
{
    TEST_ASSERT_EQUAL(0, num_calls);
    TEST_ASSERT_EQUAL_PTR(make_context(0), context);
    TEST_ASSERT_EQUAL_HEX(CL_MEM_READ_WRITE, flags);

    TEST_ASSERT_NOT_NULL(image_format);
    TEST_ASSERT_EQUAL_HEX(CL_R, image_format->image_channel_order);
    TEST_ASSERT_EQUAL_HEX(CL_FLOAT, image_format->image_channel_data_type);

    TEST_ASSERT_NOT_NULL(image_desc);
    TEST_ASSERT_EQUAL_HEX(CL_MEM_OBJECT_IMAGE2D, image_desc->image_type);
    TEST_ASSERT_EQUAL(64, image_desc->image_width);
    TEST_ASSERT_EQUAL(32, image_desc->image_height);
    TEST_ASSERT_EQUAL(256, image_desc->image_row_pitch);
    TEST_ASSERT_EQUAL(0, image_desc->num_mip_levels);
    TEST_ASSERT_EQUAL(0, image_desc->num_samples);
    TEST_ASSERT_NULL(image_desc->buffer);

    TEST_ASSERT_NULL(host_ptr);

    if (errcode_ret != NULL)
        *errcode_ret = CL_SUCCESS;
    return make_mem(0);
}

void testCreateImage2D_1_2()
{
    clGetContextInfo_StubWithCallback(clGetContextInfo_device);
    clGetDeviceInfo_StubWithCallback(clGetDeviceInfo_platform);
    clGetPlatformInfo_StubWithCallback(clGetPlatformInfo_version_1_2);
    clCreateImage_StubWithCallback(clCreateImage_testCreateImage2D_1_2);

    cl_int err;
    cl::Context context;
    context() = make_context(0);
    cl::Image2D image(
        context, CL_MEM_READ_WRITE,
        cl::ImageFormat(CL_R, CL_FLOAT), 64, 32, 256, NULL, &err);

    TEST_ASSERT_EQUAL(CL_SUCCESS, err);
    TEST_ASSERT_EQUAL_PTR(make_mem(0), image());

    context() = NULL;
    image() = NULL;
}

/****************************************************************************
 * Tests for cl::Image3D
 ****************************************************************************/

void testMoveAssignImage3DNonNull();
void testMoveAssignImage3DNull();
void testMoveConstructImage3DNonNull();
void testMoveConstructImage3DNull();
MAKE_MOVE_TESTS(Image3D, make_mem, clReleaseMemObject, image3DPool);

#ifdef CL_USE_DEPRECATED_OPENCL_1_1_APIS
static cl_mem clCreateImage3D_testCreateImage3D_1_1(
    cl_context context,
    cl_mem_flags flags,
    const cl_image_format *image_format,
    size_t image_width,
    size_t image_height,
    size_t image_depth,
    size_t image_row_pitch,
    size_t image_slice_pitch,
    void *host_ptr,
    cl_int *errcode_ret,
    int num_calls)
{
    TEST_ASSERT_EQUAL(0, num_calls);
    TEST_ASSERT_EQUAL_PTR(make_context(0), context);
    TEST_ASSERT_EQUAL_HEX(CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, flags);

    TEST_ASSERT_NOT_NULL(image_format);
    TEST_ASSERT_EQUAL_HEX(CL_R, image_format->image_channel_order);
    TEST_ASSERT_EQUAL_HEX(CL_FLOAT, image_format->image_channel_data_type);

    TEST_ASSERT_EQUAL(64, image_width);
    TEST_ASSERT_EQUAL(32, image_height);
    TEST_ASSERT_EQUAL(16, image_depth);
    TEST_ASSERT_EQUAL(256, image_row_pitch);
    TEST_ASSERT_EQUAL(65536, image_slice_pitch);
    TEST_ASSERT_EQUAL_PTR((void *) 0xdeadbeef, host_ptr);

    if (errcode_ret != NULL)
        *errcode_ret = CL_SUCCESS;
    return make_mem(0);
}
#endif

void testCreateImage3D_1_1()
{
#ifdef CL_USE_DEPRECATED_OPENCL_1_1_APIS
    clGetContextInfo_StubWithCallback(clGetContextInfo_device);
    clGetDeviceInfo_StubWithCallback(clGetDeviceInfo_platform);
    clGetPlatformInfo_StubWithCallback(clGetPlatformInfo_version_1_1);
    clCreateImage3D_StubWithCallback(clCreateImage3D_testCreateImage3D_1_1);

    cl_int err;
    cl::Context context;
    context() = make_context(0);
    cl::Image3D image(
        context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
        cl::ImageFormat(CL_R, CL_FLOAT), 64, 32, 16, 256, 65536, (void *) 0xdeadbeef, &err);

    TEST_ASSERT_EQUAL(CL_SUCCESS, err);
    TEST_ASSERT_EQUAL_PTR(make_mem(0), image());

    context() = NULL;
    image() = NULL;
#endif
}

static cl_mem clCreateImage_testCreateImage3D_1_2(
    cl_context context,
    cl_mem_flags flags,
    const cl_image_format *image_format,
    const cl_image_desc *image_desc,
    void *host_ptr,
    cl_int *errcode_ret,
    int num_calls)
{
    TEST_ASSERT_EQUAL(0, num_calls);
    TEST_ASSERT_EQUAL_PTR(make_context(0), context);
    TEST_ASSERT_EQUAL_HEX(CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, flags);

    TEST_ASSERT_NOT_NULL(image_format);
    TEST_ASSERT_EQUAL_HEX(CL_R, image_format->image_channel_order);
    TEST_ASSERT_EQUAL_HEX(CL_FLOAT, image_format->image_channel_data_type);

    TEST_ASSERT_NOT_NULL(image_desc);
    TEST_ASSERT_EQUAL_HEX(CL_MEM_OBJECT_IMAGE3D, image_desc->image_type);
    TEST_ASSERT_EQUAL(64, image_desc->image_width);
    TEST_ASSERT_EQUAL(32, image_desc->image_height);
    TEST_ASSERT_EQUAL(16, image_desc->image_depth);
    TEST_ASSERT_EQUAL(256, image_desc->image_row_pitch);
    TEST_ASSERT_EQUAL(65536, image_desc->image_slice_pitch);
    TEST_ASSERT_EQUAL(0, image_desc->num_mip_levels);
    TEST_ASSERT_EQUAL(0, image_desc->num_samples);
    TEST_ASSERT_NULL(image_desc->buffer);

    TEST_ASSERT_EQUAL_PTR((void *) 0xdeadbeef, host_ptr);

    if (errcode_ret != NULL)
        *errcode_ret = CL_SUCCESS;
    return make_mem(0);
}

void testCreateImage3D_1_2()
{
    clGetContextInfo_StubWithCallback(clGetContextInfo_device);
    clGetDeviceInfo_StubWithCallback(clGetDeviceInfo_platform);
    clGetPlatformInfo_StubWithCallback(clGetPlatformInfo_version_1_2);
    clCreateImage_StubWithCallback(clCreateImage_testCreateImage3D_1_2);

    cl_int err;
    cl::Context context;
    context() = make_context(0);
    cl::Image3D image(
        context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
        cl::ImageFormat(CL_R, CL_FLOAT), 64, 32, 16, 256, 65536, (void *) 0xdeadbeef, &err);

    TEST_ASSERT_EQUAL(CL_SUCCESS, err);
    TEST_ASSERT_EQUAL_PTR(make_mem(0), image());

    context() = NULL;
    image() = NULL;
}

/****************************************************************************
 * Tests for cl::Kernel
 ****************************************************************************/
void testMoveAssignKernelNonNull();
void testMoveAssignKernelNull();
void testMoveConstructKernelNonNull();
void testMoveConstructKernelNull();
MAKE_MOVE_TESTS(Kernel, make_kernel, clReleaseKernel, kernelPool);

static cl_int scalarArg;
static cl_int3 vectorArg;

void testKernelSetArgScalar()
{
    scalarArg = 0xcafebabe;
    clSetKernelArg_ExpectAndReturn(make_kernel(0), 3, 4, &scalarArg, CL_SUCCESS);
    kernelPool[0].setArg(3, scalarArg);
}

void testKernelSetArgVector()
{
    vectorArg.s[0] = 0x12345678;
    vectorArg.s[1] = 0x23456789;
    vectorArg.s[2] = 0x87654321;
    clSetKernelArg_ExpectAndReturn(make_kernel(0), 2, 16, &vectorArg, CL_SUCCESS);
    kernelPool[0].setArg(2, vectorArg);
}

void testKernelSetArgMem()
{
    clSetKernelArg_ExpectAndReturn(make_kernel(0), 1, sizeof(cl_mem), &bufferPool[1](), CL_SUCCESS);
    kernelPool[0].setArg(1, bufferPool[1]);
}

void testKernelSetArgLocal()
{
    clSetKernelArg_ExpectAndReturn(make_kernel(0), 2, 123, NULL, CL_SUCCESS);
    kernelPool[0].setArg(2, cl::Local(123));
}

/****************************************************************************
 * Tests for cl::copy
 ****************************************************************************/

// This method should allocate some host accesible memory
// so we must do this ourselves
void *some_host_memory;

static void * clEnqueueMapBuffer_testCopyHostToBuffer(
    cl_command_queue command_queue,
    cl_mem buffer,
    cl_bool blocking_map,
    cl_map_flags map_flags,
    size_t offset,
    size_t size,
    cl_uint num_events_in_wait_list,
    const cl_event *event_wait_list,
    cl_event *event,
    cl_int *errcode_ret,
    int num_calls)
{
    TEST_ASSERT_EQUAL_PTR(make_command_queue(0), command_queue);
    TEST_ASSERT_EQUAL_PTR(make_mem(0), buffer);
    TEST_ASSERT_EQUAL(CL_TRUE, blocking_map);
    TEST_ASSERT_EQUAL(CL_MAP_WRITE, map_flags);
    TEST_ASSERT_EQUAL(sizeof(int)*1024, size);

    some_host_memory = malloc(sizeof(int) * 1024);

    // Set the return event
    if (event)
        *event = NULL;

    // Set the return error code
    if (errcode_ret)
        *errcode_ret = CL_SUCCESS;

    return some_host_memory;
}

static cl_int clEnqueueUnmapMemObject_testCopyHostToBuffer(
    cl_command_queue  command_queue ,
    cl_mem  memobj,
    void  *mapped_ptr,
    cl_uint  num_events_in_wait_list ,
    const cl_event  *event_wait_list ,
    cl_event  *event,
    int num_calls)
{
    TEST_ASSERT_EQUAL_PTR(make_command_queue(0), command_queue);
    TEST_ASSERT_EQUAL_PTR(make_mem(0), memobj);
    TEST_ASSERT_EQUAL_PTR(some_host_memory, mapped_ptr);
    TEST_ASSERT_NOT_NULL(event);
    return CL_SUCCESS;
}

static cl_int clWaitForEvents_testCopyHostToBuffer(
    cl_uint num_events,
    const cl_event *event_list,
    int num_calls)
{
    TEST_ASSERT_NOT_NULL(event_list);
    TEST_ASSERT_EQUAL(1, num_events);
    return CL_SUCCESS;
}

static cl_int clReleaseEvent_testCopyHostToBuffer(
    cl_event event,
    int num_calls)
{
    TEST_ASSERT_NOT_NULL(event);
    return CL_SUCCESS;
}

void testCopyHostToBuffer()
{
    cl_context context_expect = make_context(0);
    int context_refcount = 1;
    prepare_contextRefcounts(1, &context_expect, &context_refcount);
    cl::Context context = contextPool[0];

    cl_mem mem_expect = make_mem(0);
    int mem_refcount = 1;
    prepare_memRefcounts(1, &mem_expect, &mem_refcount);
    cl::Buffer buffer(make_mem(0));

    cl_command_queue queue_expect = make_command_queue(0);
    cl::CommandQueue queue(queue_expect);
    clReleaseCommandQueue_ExpectAndReturn(queue_expect, CL_SUCCESS);

    // Returns the pointer to host memory
    clEnqueueMapBuffer_StubWithCallback(clEnqueueMapBuffer_testCopyHostToBuffer);
    clEnqueueUnmapMemObject_StubWithCallback(clEnqueueUnmapMemObject_testCopyHostToBuffer);

    clWaitForEvents_StubWithCallback(clWaitForEvents_testCopyHostToBuffer);
    clReleaseEvent_StubWithCallback(clReleaseEvent_testCopyHostToBuffer);

    std::vector<int> host(1024);
    for (int i = 0; i < 1024; i++)
        host[i] = i;

    cl::copy(queue, host.begin(), host.end(), buffer);

    // Check that the memory was copied to some_host_memory
    TEST_ASSERT_EQUAL_MEMORY(&host[0], some_host_memory, sizeof(int) * 1024);

    free(some_host_memory);

}

/****************************************************************************
* Tests for building Programs
****************************************************************************/

static cl_int clGetDeviceInfo_testGetBuildInfo(
    cl_device_id device,
    cl_device_info param_name,
    size_t param_value_size,
    void *param_value,
    size_t *param_value_size_ret,
    int num_calls)
{
    TEST_ASSERT_EQUAL(param_name, CL_DEVICE_PLATFORM);
    TEST_ASSERT_EQUAL(param_value_size, sizeof(cl_platform_id));
    TEST_ASSERT_NOT_EQUAL(param_value, NULL);
    TEST_ASSERT_EQUAL(param_value_size_ret, NULL);
    cl_platform_id temp = make_platform_id(0);
    memcpy(param_value, &temp, sizeof(cl_platform_id));
    return CL_SUCCESS;
}


static  cl_int clGetProgramBuildInfo_testGetBuildInfo(
    cl_program program,
    cl_device_id device,
    cl_program_build_info param_name,
    size_t param_value_size,
    void *param_value,
    size_t *param_value_size_ret,
    int num_calls)
{
    TEST_ASSERT_EQUAL(param_name, CL_PROGRAM_BUILD_LOG);

    const char returnString[] = 
        "This is the string returned by the build info function.";
    if (param_value) {
        ::size_t returnSize = param_value_size;
        if (sizeof(returnString) < returnSize) {
            returnSize = sizeof(returnString);
        }
        memcpy(param_value, returnString, returnSize);
    }
    else {
        if (param_value_size_ret) {
            *param_value_size_ret = sizeof(returnString);
        }
    }

    return CL_SUCCESS;
}

void testGetBuildInfo()
{
    cl_device_id fakeDevice = make_device_id(0);
    clGetDeviceInfo_ExpectAndReturn(fakeDevice, CL_DEVICE_PLATFORM, sizeof(cl_platform_id), NULL, NULL, CL_SUCCESS);
    clGetDeviceInfo_StubWithCallback(clGetDeviceInfo_testGetBuildInfo);
    clGetPlatformInfo_StubWithCallback(clGetPlatformInfo_version_1_2);
    clGetPlatformInfo_StubWithCallback(clGetPlatformInfo_version_1_2);
    clGetProgramBuildInfo_StubWithCallback(clGetProgramBuildInfo_testGetBuildInfo);
    clGetProgramBuildInfo_StubWithCallback(clGetProgramBuildInfo_testGetBuildInfo);

    cl::Program prog(make_program(0));
    cl::Device dev(fakeDevice);
    
    cl_int err;
    std::string log = prog.getBuildInfo<CL_PROGRAM_BUILD_LOG>(dev, &err);

    prog() = NULL;
    dev() = NULL;
}

static cl_int clBuildProgram_testBuildProgram(
    cl_program           program,
    cl_uint              num_devices,
    const cl_device_id * device_list,
    const char *         options,
    void (CL_CALLBACK *  pfn_notify)(cl_program program, void * user_data),
    void *               user_data,
    int num_calls)
{
    TEST_ASSERT_EQUAL(program, make_program(0));
    TEST_ASSERT_NOT_EQUAL(num_devices, 0);
    TEST_ASSERT_NOT_EQUAL(device_list, NULL);
    TEST_ASSERT_EQUAL(options, NULL);
    TEST_ASSERT_EQUAL(pfn_notify, NULL);
    TEST_ASSERT_EQUAL(user_data, NULL);

    for (cl_uint i = 0; i < num_devices; i++) {
        TEST_ASSERT_EQUAL(device_list[i], make_device_id(i));
    }

    return CL_SUCCESS;
}

void testBuildProgramSingleDevice()
{
    cl_program program = make_program(0);
    cl_device_id device_id = make_device_id(0);
    int sc = 0;

    // Creating a device queries the platform version:
    clGetDeviceInfo_StubWithCallback(clGetDeviceInfo_platform);
    clGetPlatformInfo_StubWithCallback(clGetPlatformInfo_version_1_2);

    clBuildProgram_StubWithCallback(clBuildProgram_testBuildProgram);

    // Building the program queries the program build log:
    clRetainDevice_ExpectAndReturn(make_device_id(0), CL_SUCCESS);
    clGetProgramBuildInfo_StubWithCallback(clGetProgramBuildInfo_testGetBuildInfo);
    clGetProgramBuildInfo_StubWithCallback(clGetProgramBuildInfo_testGetBuildInfo);
    clReleaseDevice_ExpectAndReturn(make_device_id(0), CL_SUCCESS);
    clReleaseDevice_ExpectAndReturn(make_device_id(0), CL_SUCCESS);

    clReleaseProgram_ExpectAndReturn(program, CL_SUCCESS);

    cl::Program prog(program);
    cl::Device dev(device_id);

    cl_int errcode = prog.build(dev);

    TEST_ASSERT_EQUAL(errcode, CL_SUCCESS);
}

/**
* Stub implementation of clGetCommandQueueInfo that returns first one image then none
*/
static cl_int clGetSupportedImageFormats_testGetSupportedImageFormats(
    cl_context context,
    cl_mem_flags flags,
    cl_mem_object_type image_type,
    cl_uint num_entries,
    cl_image_format *image_formats,
    cl_uint *num_image_formats,
    int num_calls)
{        
    // Catch failure case that causes error in bugzilla 13355:
    // returns CL_INVALID_VALUE if flags or image_type are not valid, 
    // or if num_entries is 0 and image_formats is not NULL.
    if (num_entries == 0 && image_formats != NULL) {
        return CL_INVALID_VALUE;
    }
    if (num_entries == 0)  {
        // If num_entries was 0 this is the query for number
        if (num_image_formats) {
            if (num_calls == 0) {
                *num_image_formats = 1;
            }
            else {
                *num_image_formats = 0;
            }
        }
    }
    else {
        // Should return something
        TEST_ASSERT_NOT_NULL(image_formats);
        
        // For first call we should return one format here
        if (num_calls == 1) {
            TEST_ASSERT_EQUAL(num_entries, 1);
            image_formats[0] = cl::ImageFormat(CL_RGB, CL_FLOAT);
        }
    }

    return CL_SUCCESS;
}

void testGetSupportedImageFormats()
{
    cl_context ctx_cl = make_context(0);

    clGetSupportedImageFormats_StubWithCallback(clGetSupportedImageFormats_testGetSupportedImageFormats);
    clGetSupportedImageFormats_StubWithCallback(clGetSupportedImageFormats_testGetSupportedImageFormats);
    clReleaseContext_ExpectAndReturn(make_context(0), CL_SUCCESS);

    cl::Context ctx(ctx_cl);
    std::vector<cl::ImageFormat> formats;
    cl_int ret = CL_SUCCESS;

    ret = ctx.getSupportedImageFormats(
        CL_MEM_READ_WRITE,
        CL_MEM_OBJECT_IMAGE2D,
        &formats);
    TEST_ASSERT_EQUAL(ret, CL_SUCCESS);
    TEST_ASSERT_EQUAL(formats.size(), 1);
    ret = ctx.getSupportedImageFormats(
        CL_MEM_READ_WRITE,
        CL_MEM_OBJECT_IMAGE2D,
        &formats);
    TEST_ASSERT_EQUAL(formats.size(), 0);
    TEST_ASSERT_EQUAL(ret, CL_SUCCESS);
}

void testCreateSubDevice()
{
    // TODO

}

void testGetContextInfoDevices()
{
    // TODO
}

static cl_mem clCreateImage_testCreateImage2DFromBuffer_2_0(
    cl_context context,
    cl_mem_flags flags,
    const cl_image_format *image_format,
    const cl_image_desc *image_desc,
    void *host_ptr,
    cl_int *errcode_ret,
    int num_calls)
{
    TEST_ASSERT_NOT_NULL(image_format);
    TEST_ASSERT_NOT_NULL(image_desc);
    TEST_ASSERT_NULL(host_ptr);
    TEST_ASSERT_EQUAL_HEX(CL_MEM_OBJECT_IMAGE2D, image_desc->image_type);

    // Return the passed buffer as the cl_mem and success for the error code
    if (errcode_ret) {
        *errcode_ret = CL_SUCCESS;
    }
    return image_desc->buffer;
}

void testCreateImage2DFromBuffer_2_0()
{
#if CL_HPP_TARGET_OPENCL_VERSION >= 200
    clGetContextInfo_StubWithCallback(clGetContextInfo_device);
    clGetDeviceInfo_StubWithCallback(clGetDeviceInfo_platform);
    clGetPlatformInfo_StubWithCallback(clGetPlatformInfo_version_2_0);
    clCreateImage_StubWithCallback(clCreateImage_testCreateImage2DFromBuffer_2_0);
    clReleaseMemObject_ExpectAndReturn(make_mem(0), CL_SUCCESS);
    clReleaseContext_ExpectAndReturn(make_context(0), CL_SUCCESS);

    cl_int err;
    cl::Context context(make_context(0));

    // Create buffer
    // Create image from buffer
    cl::Buffer buffer(make_mem(0));
    cl::Image2D imageFromBuffer(
        context,
        cl::ImageFormat(CL_R, CL_FLOAT), buffer, 64, 32, 256, &err);

    TEST_ASSERT_EQUAL_PTR(buffer(), imageFromBuffer());
    TEST_ASSERT_EQUAL(CL_SUCCESS, err);

    buffer() = NULL;
#endif
}

static cl_mem clCreateImage_testCreateImage2D_2_0(
    cl_context context,
    cl_mem_flags flags,
    const cl_image_format *image_format,
    const cl_image_desc *image_desc,
    void *host_ptr,
    cl_int *errcode_ret,
    int num_calls)
{
    TEST_ASSERT_EQUAL(0, num_calls);
    TEST_ASSERT_EQUAL_PTR(make_context(0), context);
    TEST_ASSERT_EQUAL_HEX(CL_MEM_READ_WRITE, flags);

    TEST_ASSERT_NOT_NULL(image_format);
    TEST_ASSERT_EQUAL_HEX(CL_RGBA, image_format->image_channel_order);
    TEST_ASSERT_EQUAL_HEX(CL_FLOAT, image_format->image_channel_data_type);

    TEST_ASSERT_NOT_NULL(image_desc);
    TEST_ASSERT_EQUAL_HEX(CL_MEM_OBJECT_IMAGE2D, image_desc->image_type);
    TEST_ASSERT_EQUAL(64, image_desc->image_width);
    TEST_ASSERT_EQUAL(32, image_desc->image_height);
    TEST_ASSERT_EQUAL(256, image_desc->image_row_pitch);
    TEST_ASSERT_EQUAL(0, image_desc->num_mip_levels);
    TEST_ASSERT_EQUAL(0, image_desc->num_samples);
    TEST_ASSERT_NULL(image_desc->buffer);

    TEST_ASSERT_NULL(host_ptr);

    if (errcode_ret != NULL)
        *errcode_ret = CL_SUCCESS;
    return make_mem(0);
}

static cl_mem clCreateImage_testCreateImage2DFromImage_2_0(
    cl_context context,
    cl_mem_flags flags,
    const cl_image_format *image_format,
    const cl_image_desc *image_desc,
    void *host_ptr,
    cl_int *errcode_ret,
    int num_calls)
{
    TEST_ASSERT_NOT_NULL(image_format);
    TEST_ASSERT_NOT_NULL(image_desc);
    TEST_ASSERT_NULL(host_ptr);
    TEST_ASSERT_EQUAL_HEX(CL_MEM_OBJECT_IMAGE2D, image_desc->image_type);

    // Return the passed buffer as the cl_mem and success for the error code
    if (errcode_ret) {
        *errcode_ret = CL_SUCCESS;
    }
    return image_desc->buffer;
}

static cl_int clGetImageInfo_testCreateImage2DFromImage_2_0(
    cl_mem image,
    cl_image_info param_name,
    size_t param_value_size,
    void *param_value,
    size_t *param_value_size_ret,
    int num_calls)
{
    TEST_ASSERT_INT_WITHIN(6, 0, num_calls);
    return CL_SUCCESS;
}

void testCreateImage2DFromImage_2_0()
{
#if CL_HPP_TARGET_OPENCL_VERSION >= 200
    clGetContextInfo_StubWithCallback(clGetContextInfo_device);
    clGetDeviceInfo_StubWithCallback(clGetDeviceInfo_platform);
    clGetPlatformInfo_StubWithCallback(clGetPlatformInfo_version_2_0);
    clCreateImage_StubWithCallback(clCreateImage_testCreateImage2D_2_0);


    cl_int err;
    cl::Context context(make_context(0));

    // As in 1.2 2D image test, needed as source for image-from-image
    cl::Image2D image(
        context, CL_MEM_READ_WRITE,
        cl::ImageFormat(CL_RGBA, CL_FLOAT), 64, 32, 256, NULL, &err);

    TEST_ASSERT_EQUAL(CL_SUCCESS, err);
    TEST_ASSERT_EQUAL_PTR(make_mem(0), image());

    // Continue state for next phase
    clGetImageInfo_StubWithCallback(clGetImageInfo_testCreateImage2DFromImage_2_0);
    clCreateImage_StubWithCallback(clCreateImage_testCreateImage2DFromImage_2_0);
    clReleaseMemObject_ExpectAndReturn(make_mem(0), CL_SUCCESS);
    clReleaseMemObject_ExpectAndReturn(make_mem(0), CL_SUCCESS);
    clReleaseContext_ExpectAndReturn(make_context(0), CL_SUCCESS);

    // Create 2D image from 2D Image with a new channel order
    cl::Image2D imageFromImage(
        context,
        CL_sRGB,
        image,
        &err
        );

    TEST_ASSERT_EQUAL(CL_SUCCESS, err);
    TEST_ASSERT_EQUAL_PTR(image(), imageFromImage());

    //imageFromImage() = NULL;
    //image() = NULL;
    //context() = NULL;
#endif
}

// Note that default tests maintain state when run from the same
// unit process.
// One default setting test will maintain the defaults until the end.
void testSetDefaultPlatform()
{
    cl::Platform p(make_platform_id(1));
    cl::Platform p2 = cl::Platform::setDefault(p);
    cl::Platform p3 = cl::Platform::getDefault();
    TEST_ASSERT_EQUAL(p(), p2());
    TEST_ASSERT_EQUAL(p(), p3());
}

// Note that default tests maintain state when run from the same
// unit process.
// One default setting test will maintain the defaults until the end.
void testSetDefaultPlatformTwice()
{
    cl::Platform p(make_platform_id(2));
    cl::Platform p2 = cl::Platform::getDefault();
    cl::Platform p3 = cl::Platform::setDefault(p);
    // Set default should have failed
    TEST_ASSERT_EQUAL(p2(), p3());
    TEST_ASSERT_NOT_EQUAL(p(), p3());
}

// Note that default tests maintain state when run from the same
// unit process.
// One default setting test will maintain the defaults until the end.
void testSetDefaultContext()
{   

    clRetainContext_ExpectAndReturn(make_context(1), CL_SUCCESS);
    clRetainContext_ExpectAndReturn(make_context(1), CL_SUCCESS);
    clRetainContext_ExpectAndReturn(make_context(1), CL_SUCCESS);
    clReleaseContext_ExpectAndReturn(make_context(1), CL_SUCCESS);
    clReleaseContext_ExpectAndReturn(make_context(1), CL_SUCCESS);
    clReleaseContext_ExpectAndReturn(make_context(1), CL_SUCCESS);

    cl::Context c(make_context(1));
    cl::Context c2 = cl::Context::setDefault(c);
    cl::Context c3 = cl::Context::getDefault();
    TEST_ASSERT_EQUAL(c(), c2());
    TEST_ASSERT_EQUAL(c(), c3());
}

// Note that default tests maintain state when run from the same
// unit process.
// One default setting test will maintain the defaults until the end.
void testSetDefaultCommandQueue()
{
    clRetainCommandQueue_ExpectAndReturn(make_command_queue(1), CL_SUCCESS);
    clRetainCommandQueue_ExpectAndReturn(make_command_queue(1), CL_SUCCESS);
    clRetainCommandQueue_ExpectAndReturn(make_command_queue(1), CL_SUCCESS);
    clReleaseCommandQueue_ExpectAndReturn(make_command_queue(1), CL_SUCCESS);
    clReleaseCommandQueue_ExpectAndReturn(make_command_queue(1), CL_SUCCESS);
    clReleaseCommandQueue_ExpectAndReturn(make_command_queue(1), CL_SUCCESS);

    cl::CommandQueue c(make_command_queue(1));
    cl::CommandQueue c2 = cl::CommandQueue::setDefault(c);
    cl::CommandQueue c3 = cl::CommandQueue::getDefault();
    TEST_ASSERT_EQUAL(c(), c2());
    TEST_ASSERT_EQUAL(c(), c3());
}

// Note that default tests maintain state when run from the same
// unit process.
// One default setting test will maintain the defaults until the end.
void testSetDefaultDevice()
{
    clGetDeviceInfo_StubWithCallback(clGetDeviceInfo_platform);
    clGetPlatformInfo_StubWithCallback(clGetPlatformInfo_version_2_0);

    clRetainDevice_ExpectAndReturn(make_device_id(1), CL_SUCCESS);
    clRetainDevice_ExpectAndReturn(make_device_id(1), CL_SUCCESS);
    clRetainDevice_ExpectAndReturn(make_device_id(1), CL_SUCCESS);
    clReleaseDevice_ExpectAndReturn(make_device_id(1), CL_SUCCESS);
    clReleaseDevice_ExpectAndReturn(make_device_id(1), CL_SUCCESS);
    clReleaseDevice_ExpectAndReturn(make_device_id(1), CL_SUCCESS);

    cl::Device d(make_device_id(1));
    cl::Device  d2 = cl::Device::setDefault(d);
    cl::Device  d3 = cl::Device::getDefault();
    TEST_ASSERT_EQUAL(d(), d2());
    TEST_ASSERT_EQUAL(d(), d3());
}

static cl_command_queue clCreateCommandQueueWithProperties_testCommandQueueDevice(
    cl_context context,
    cl_device_id device,
    const cl_queue_properties *properties,
    cl_int *errcode_ret,
    int num_calls)
{
    (void)num_calls;
    TEST_ASSERT_EQUAL_PTR(make_context(1), context);
    TEST_ASSERT_EQUAL_PTR(make_device_id(1), device);
    TEST_ASSERT_EQUAL(properties[0], CL_QUEUE_PROPERTIES);
    static cl_command_queue default_ = 0;

    if ((properties[1] & CL_QUEUE_ON_DEVICE_DEFAULT) == 0) {
        TEST_ASSERT_EQUAL(properties[1], (CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE | CL_QUEUE_ON_DEVICE));
        if (properties[2] == CL_QUEUE_SIZE) {
            TEST_ASSERT_EQUAL(properties[3], 256);
            TEST_ASSERT_EQUAL(properties[4], 0);
            return make_command_queue(2);
        }
        else {
            TEST_ASSERT_EQUAL(properties[2], 0);
            return make_command_queue(3);
        }
    }
    else {
        TEST_ASSERT_EQUAL(properties[1], (CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE | CL_QUEUE_ON_DEVICE | CL_QUEUE_ON_DEVICE_DEFAULT));
        if (default_ == 0) {
            default_ = make_command_queue(4);
        }
        return default_;
    }
}

void testCreateDeviceCommandQueue()
{
#if CL_HPP_TARGET_OPENCL_VERSION >= 200
    clRetainContext_ExpectAndReturn(make_context(1), CL_SUCCESS);
    clGetDeviceInfo_StubWithCallback(clGetDeviceInfo_platform);
    clGetPlatformInfo_StubWithCallback(clGetPlatformInfo_version_2_0);
    clCreateCommandQueueWithProperties_StubWithCallback(clCreateCommandQueueWithProperties_testCommandQueueDevice);       
    clReleaseCommandQueue_ExpectAndReturn(make_command_queue(4), CL_SUCCESS);
    clReleaseCommandQueue_ExpectAndReturn(make_command_queue(4), CL_SUCCESS);
    clReleaseCommandQueue_ExpectAndReturn(make_command_queue(2), CL_SUCCESS);
    clReleaseCommandQueue_ExpectAndReturn(make_command_queue(3), CL_SUCCESS);
    clReleaseDevice_ExpectAndReturn(make_device_id(1), CL_SUCCESS);
    clReleaseContext_ExpectAndReturn(make_context(1), CL_SUCCESS);
    clReleaseContext_ExpectAndReturn(make_context(1), CL_SUCCESS);

    cl::Context c(make_context(1));
    cl::Context c2 = cl::Context::setDefault(c);
    cl::Device d(make_device_id(1));

    cl::DeviceCommandQueue dq(c, d);
    cl::DeviceCommandQueue dq2(c, d, 256);    

    cl::DeviceCommandQueue dqd = cl::DeviceCommandQueue::makeDefault(c, d);
    cl::DeviceCommandQueue dqd2 = cl::DeviceCommandQueue::makeDefault(c, d);

    TEST_ASSERT_EQUAL(dqd(), dqd2());
#endif
}

static cl_mem clCreatePipe_testCreatePipe(
    cl_context context,
    cl_mem_flags flags,
    cl_uint packet_size,
    cl_uint num_packets,
    const cl_pipe_properties *props,
    cl_int *errcode_ret,
    int num_calls)
{
    if (flags == 0) {
        flags = CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS;
    }
    TEST_ASSERT_EQUAL(flags, CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS);
    TEST_ASSERT_NULL(props);

    if (errcode_ret)
        *errcode_ret = CL_SUCCESS;
    return make_mem(0);
}

static cl_int clGetPipeInfo_testCreatePipe(
    cl_mem pipe,
    cl_pipe_info param_name,
    size_t param_value_size,
    void *param_value,
    size_t *param_value_size_ret,
    int num_calls)
{
    TEST_ASSERT_NOT_NULL(param_value);
    if (param_name == CL_PIPE_PACKET_SIZE) {
        *static_cast<cl_uint*>(param_value) = 16;
        if (param_value_size_ret) {
            *param_value_size_ret = param_value_size;
        }
        return CL_SUCCESS;
    }
    else if (param_name == CL_PIPE_MAX_PACKETS) {
        *static_cast<cl_uint*>(param_value) = 32;
        if (param_value_size_ret) {
            *param_value_size_ret = param_value_size;
        }
        return CL_SUCCESS;
    }
    else {
        TEST_FAIL();
        return CL_INVALID_VALUE;
    }
}

void testCreatePipe()
{    
#if CL_HPP_TARGET_OPENCL_VERSION >= 200
    clCreatePipe_StubWithCallback(clCreatePipe_testCreatePipe);
    clGetPipeInfo_StubWithCallback(clGetPipeInfo_testCreatePipe);
    clRetainContext_ExpectAndReturn(make_context(1), CL_SUCCESS);
    clReleaseContext_ExpectAndReturn(make_context(1), CL_SUCCESS);
    clReleaseMemObject_ExpectAndReturn(make_mem(0), CL_SUCCESS);
    clReleaseMemObject_ExpectAndReturn(make_mem(0), CL_SUCCESS);
    clReleaseContext_ExpectAndReturn(make_context(1), CL_SUCCESS);

    cl::Context c(make_context(1));
    cl::Pipe p(c, 16, 32);
    cl::Pipe p2(16, 32);

    cl_uint size = p2.getInfo<CL_PIPE_PACKET_SIZE>();
    cl_uint packets;
    p2.getInfo(CL_PIPE_MAX_PACKETS, &packets);

    TEST_ASSERT_EQUAL(size, 16);
    TEST_ASSERT_EQUAL(packets, 32);
#endif
}

static cl_int clGetKernelSubGroupInfo_testSubGroups(cl_kernel kernel,
    cl_device_id device,
    cl_kernel_sub_group_info param_name,
    size_t input_value_size,
    const void *input_value,
    size_t param_value_size,
    void *param_value,
    size_t *param_value_size_ret,
    int num_calls)
{    
    TEST_ASSERT_NOT_NULL(input_value);
    TEST_ASSERT_NOT_NULL(param_value);

    if (param_name == CL_KERNEL_MAX_SUB_GROUP_SIZE_FOR_NDRANGE_KHR) {
        *static_cast<size_t*>(param_value) = 32;
        if (param_value_size_ret) {
            *param_value_size_ret = sizeof(size_t);
        }
        return CL_SUCCESS;
    }
    else if (param_name == CL_KERNEL_SUB_GROUP_COUNT_FOR_NDRANGE_KHR) {
        *static_cast<size_t*>(param_value) = 2;
        if (param_value_size_ret) {
            *param_value_size_ret = sizeof(size_t);
        }
        return CL_SUCCESS;
    }
    else {
        TEST_ABORT();
        return CL_INVALID_OPERATION;
    }
}

void testSubGroups()
{
// TODO support testing cl_khr_subgroups on 2.0
#if CL_HPP_TARGET_OPENCL_VERSION >= 210
    clGetDeviceInfo_StubWithCallback(clGetDeviceInfo_platform);
    clGetPlatformInfo_StubWithCallback(clGetPlatformInfo_version_2_0);
    clGetKernelSubGroupInfo_StubWithCallback(clGetKernelSubGroupInfo_testSubGroups);
    clReleaseDevice_ExpectAndReturn(make_device_id(0), CL_SUCCESS);
    clReleaseKernel_ExpectAndReturn(make_kernel(0), CL_SUCCESS);

    cl::Kernel k(make_kernel(0));
    cl::Device d(make_device_id(0));
    cl_int err;
    cl::NDRange ndrange(8, 8);
    size_t res1 = k.getSubGroupInfo<CL_KERNEL_MAX_SUB_GROUP_SIZE_FOR_NDRANGE_KHR>(
        d, ndrange, &err);
    size_t res2 = 0;
    err = k.getSubGroupInfo(
        d, CL_KERNEL_SUB_GROUP_COUNT_FOR_NDRANGE_KHR, ndrange, &res2);

    TEST_ASSERT_EQUAL(res1, 32);
    TEST_ASSERT_EQUAL(res2, 2);
#endif
}

/**
* Stub implementation of clGetDeviceInfo that returns an absense of builtin kernels
*/
static cl_int clGetDeviceInfo_builtin(
    cl_device_id id,
    cl_device_info param_name,
    size_t param_value_size,
    void *param_value,
    size_t *param_value_size_ret,
    int num_calls)
{
    // Test to verify case where empty string is returned - so size is 0
    (void)num_calls;
    TEST_ASSERT_EQUAL_HEX(CL_DEVICE_BUILT_IN_KERNELS, param_name);
    if (param_value == NULL) {
        if (param_value_size_ret != NULL) {
            *param_value_size_ret = 0;
        }
    }
    return CL_SUCCESS;
}

void testBuiltInKernels()
{
#if CL_HPP_TARGET_OPENCL_VERSION >= 120
    clGetDeviceInfo_StubWithCallback(clGetDeviceInfo_platform);
    clGetPlatformInfo_StubWithCallback(clGetPlatformInfo_version_2_0);
    clReleaseDevice_ExpectAndReturn(make_device_id(0), CL_SUCCESS);

    cl::Device d0(make_device_id(0));

    clGetDeviceInfo_StubWithCallback(clGetDeviceInfo_builtin);
    cl::string s = d0.getInfo<CL_DEVICE_BUILT_IN_KERNELS>();
#endif
}

/**
 * Stub implementation of clCloneKernel that returns a new kernel object
 */
static cl_kernel clCloneKernel_simplecopy(
    cl_kernel k,
    cl_int *err,
    int num_calls)
{
    // Test to verify case where empty string is returned - so size is 0
    (void)num_calls;
    return make_kernel(POOL_MAX);
    return CL_SUCCESS;
}

void testCloneKernel()
{
#if CL_HPP_TARGET_OPENCL_VERSION >= 210
    clCloneKernel_StubWithCallback(clCloneKernel_simplecopy);
    clReleaseKernel_ExpectAndReturn(make_kernel(POOL_MAX), CL_SUCCESS);
    cl::Kernel clone = kernelPool[0].clone();
    TEST_ASSERT_EQUAL(clone(), make_kernel(POOL_MAX));
#endif
}


// Run after other tests to clear the default state in the header
// using special unit test bypasses.
// We cannot remove the once_flag, so this is a hard fix
// but it means we won't hit cmock release callbacks at the end.
// This is a lot like tearDown but for the header default
// so we do not want to run it for every test.
// The alternative would be to manually modify the test runner
// but we avoid that for now.
void testCleanupHeaderState()
{
    clReleaseCommandQueue_ExpectAndReturn(make_command_queue(1), CL_SUCCESS);
    clReleaseContext_ExpectAndReturn(make_context(1), CL_SUCCESS);
    clReleaseDevice_ExpectAndReturn(make_device_id(1), CL_SUCCESS);

    cl::CommandQueue::unitTestClearDefault();
    cl::Context::unitTestClearDefault();
    cl::Device::unitTestClearDefault();
    cl::Platform::unitTestClearDefault();
}

// OpenCL 2.2 APIs:

static void CL_CALLBACK test_program_release_callback(
    cl_program,
    void*)
{
}

static cl_int clSetProgramReleaseCallback_set(
    cl_program program,
    void (CL_CALLBACK * pfn_notify)(cl_program program, void * user_data),
    void *user_data,
    int num_calls)
{
    (void) num_calls;

    TEST_ASSERT_EQUAL_PTR(make_program(0), program);
    TEST_ASSERT_EQUAL_PTR(pfn_notify, test_program_release_callback);

    return CL_SUCCESS;
}

void testSetProgramReleaseCallback()
{
#if CL_HPP_TARGET_OPENCL_VERSION >= 220
    cl_program program = make_program(0);
    int user_data = 0;

    clSetProgramReleaseCallback_StubWithCallback(clSetProgramReleaseCallback_set);
    clReleaseProgram_ExpectAndReturn(program, CL_SUCCESS);

    cl::Program prog(program);

    prog.setReleaseCallback(test_program_release_callback, &user_data);
#endif
}

void testSetProgramSpecializationConstantScalar()
{
#if CL_HPP_TARGET_OPENCL_VERSION >= 220
    cl_program program = make_program(0);
    int sc = 0;

    clSetProgramSpecializationConstant_ExpectAndReturn(program, 0, sizeof(sc), &sc, CL_SUCCESS);
    clReleaseProgram_ExpectAndReturn(program, CL_SUCCESS);

    cl::Program prog(program);

    prog.setSpecializationConstant(0, sc);
#endif
}

/// Stub for testing boolean specialization constants
static cl_int clSetProgramSpecializationConstant_testBool(
    cl_program program,
    cl_uint spec_id,
    size_t spec_size,
    const void* spec_value,
    int num_calls)
{
    (void) num_calls;

    TEST_ASSERT_EQUAL_PTR(make_program(0), program);
    TEST_ASSERT(spec_id == 0 || spec_id == 1);
    TEST_ASSERT_EQUAL(spec_size, 1);
    if (spec_id == 0)
    {
        const cl_uchar *uc_value = (const cl_uchar*)spec_value;
        TEST_ASSERT_EQUAL_HEX(uc_value[0], 0);
    }
    if (spec_id == 1)
    {
        const cl_uchar *uc_value = (const cl_uchar*)spec_value;
        TEST_ASSERT_EQUAL_HEX(uc_value[0], CL_UCHAR_MAX);
    }
    return CL_SUCCESS;
}

void testSetProgramSpecializationConstantBool()
{
#if CL_HPP_TARGET_OPENCL_VERSION >= 220
    // Spec constant "false" should turn into a call with size one and no bits set.
    // Spec constant "true" should turn into a call with size one and all bits set.
    cl_program program = make_program(0);
    bool scFalse = false;
    bool scTrue = true;

    clSetProgramSpecializationConstant_StubWithCallback(clSetProgramSpecializationConstant_testBool);

    clReleaseProgram_ExpectAndReturn(program, CL_SUCCESS);

    cl::Program prog(program);

    prog.setSpecializationConstant(0, scFalse);
    prog.setSpecializationConstant(1, scTrue);
#endif
}

void testSetProgramSpecializationConstantPointer()
{
#if CL_HPP_TARGET_OPENCL_VERSION >= 220
    cl_program program = make_program(0);
    int scArray[5];

    clSetProgramSpecializationConstant_ExpectAndReturn(program, 0, sizeof(scArray), &scArray, CL_SUCCESS);
    clReleaseProgram_ExpectAndReturn(program, CL_SUCCESS);

    cl::Program prog(program);

    prog.setSpecializationConstant(0, sizeof(scArray), scArray);
#endif
}

// cl_khr_extended_versioning

static cl_int clGetPlatformInfo_extended_versioning(
    cl_platform_id id,
    cl_platform_info param_name,
    size_t param_value_size,
    void *param_value,
    size_t *param_value_size_ret,
    int num_calls)
{
    (void)num_calls;
    switch (param_name) {
    case CL_PLATFORM_NUMERIC_VERSION_KHR:
    {
        if (param_value_size == sizeof(cl_version_khr) && param_value) {
            *static_cast<cl_version_khr*>(param_value) = CL_MAKE_VERSION_KHR(1, 2, 3);
        }
        if (param_value_size_ret) {
            *param_value_size_ret = sizeof(cl_version_khr);
        }
        return CL_SUCCESS;
    }
    case CL_PLATFORM_EXTENSIONS_WITH_VERSION_KHR:
    {
        static cl_name_version_khr extension = {
            CL_MAKE_VERSION_KHR(10, 11, 12),
            "cl_dummy_extension",
        };
        if (param_value_size == sizeof(cl_name_version_khr) && param_value) {
            *static_cast<cl_name_version_khr*>(param_value) = extension;
        }
        if (param_value_size_ret) {
            *param_value_size_ret = sizeof(extension);
        }
        return CL_SUCCESS;
    }
    default: break;
    }
    TEST_FAIL();
    return CL_INVALID_OPERATION;
}

void testPlatformExtendedVersioning()
{
    cl::Platform p(make_platform_id(1));

    clGetPlatformInfo_StubWithCallback(clGetPlatformInfo_extended_versioning);

    cl_version_khr platformVersion = p.getInfo<CL_PLATFORM_NUMERIC_VERSION_KHR>();
    TEST_ASSERT_EQUAL_HEX(platformVersion, CL_MAKE_VERSION_KHR(1, 2, 3));

    std::vector<cl_name_version_khr> extensions = p.getInfo<CL_PLATFORM_EXTENSIONS_WITH_VERSION_KHR>();
    TEST_ASSERT_EQUAL(extensions.size(), 1);
    TEST_ASSERT_EQUAL_HEX(extensions[0].version, CL_MAKE_VERSION_KHR(10, 11, 12));
    TEST_ASSERT_EQUAL_STRING(extensions[0].name, "cl_dummy_extension");
}

static cl_int clGetDeviceInfo_extended_versioning(
    cl_device_id id,
    cl_device_info param_name,
    size_t param_value_size,
    void *param_value,
    size_t *param_value_size_ret,
    int num_calls)
{
    (void)num_calls;
    switch (param_name) {
    case CL_DEVICE_NUMERIC_VERSION_KHR:
    {
        if (param_value_size == sizeof(cl_version_khr) && param_value) {
            *static_cast<cl_version_khr*>(param_value) = CL_MAKE_VERSION_KHR(1, 2, 3);
        }
        if (param_value_size_ret) {
            *param_value_size_ret = sizeof(cl_version_khr);
        }
        return CL_SUCCESS;
    }
    case CL_DEVICE_OPENCL_C_NUMERIC_VERSION_KHR:
    {
        if (param_value_size == sizeof(cl_version_khr) && param_value) {
            *static_cast<cl_version_khr*>(param_value) = CL_MAKE_VERSION_KHR(4, 5, 6);
        }
        if (param_value_size_ret) {
            *param_value_size_ret = sizeof(cl_version_khr);
        }
        return CL_SUCCESS;
    }
    case CL_DEVICE_EXTENSIONS_WITH_VERSION_KHR:
    {
        static cl_name_version_khr extension = {
            CL_MAKE_VERSION_KHR(10, 11, 12),
            "cl_dummy_extension",
        };
        if (param_value_size == sizeof(cl_name_version_khr) && param_value) {
            *static_cast<cl_name_version_khr*>(param_value) = extension;
        }
        if (param_value_size_ret) {
            *param_value_size_ret = sizeof(extension);
        }
        return CL_SUCCESS;
    }
    case CL_DEVICE_ILS_WITH_VERSION_KHR:
    {
        static cl_name_version_khr il = {
            CL_MAKE_VERSION_KHR(20, 21, 22),
            "DUMMY_IR",
        };
        if (param_value_size == sizeof(cl_name_version_khr) && param_value) {
            *static_cast<cl_name_version_khr*>(param_value) = il;
        }
        if (param_value_size_ret) {
            *param_value_size_ret = sizeof(il);
        }
        return CL_SUCCESS;
    }
    case CL_DEVICE_BUILT_IN_KERNELS_WITH_VERSION_KHR:
    {
        // Test no built-in kernels:
        if (param_value_size_ret) {
            *param_value_size_ret = 0;
        }
        return CL_SUCCESS;
    }
    default: break;
    }
    TEST_FAIL();
    return CL_INVALID_OPERATION;
}

void testDeviceExtendedVersioning()
{
    clGetDeviceInfo_StubWithCallback(clGetDeviceInfo_platform);
    clGetPlatformInfo_StubWithCallback(clGetPlatformInfo_version_2_0);
    clReleaseDevice_ExpectAndReturn(make_device_id(0), CL_SUCCESS);

    cl::Device d0(make_device_id(0));

    clGetDeviceInfo_StubWithCallback(clGetDeviceInfo_extended_versioning);

    cl_version_khr deviceVersion = d0.getInfo<CL_DEVICE_NUMERIC_VERSION_KHR>();
    TEST_ASSERT_EQUAL_HEX(deviceVersion, CL_MAKE_VERSION_KHR(1, 2, 3));

    cl_version_khr cVersion = d0.getInfo<CL_DEVICE_OPENCL_C_NUMERIC_VERSION_KHR>();
    TEST_ASSERT_EQUAL_HEX(cVersion, CL_MAKE_VERSION_KHR(4, 5, 6));

    std::vector<cl_name_version_khr> extensions = d0.getInfo<CL_DEVICE_EXTENSIONS_WITH_VERSION_KHR>();
    TEST_ASSERT_EQUAL(extensions.size(), 1);
    TEST_ASSERT_EQUAL_HEX(extensions[0].version, CL_MAKE_VERSION_KHR(10, 11, 12));
    TEST_ASSERT_EQUAL_STRING(extensions[0].name, "cl_dummy_extension");

    std::vector<cl_name_version_khr> ils = d0.getInfo<CL_DEVICE_ILS_WITH_VERSION_KHR>();
    TEST_ASSERT_EQUAL(ils.size(), 1);
    TEST_ASSERT_EQUAL_HEX(ils[0].version, CL_MAKE_VERSION_KHR(20, 21, 22));
    TEST_ASSERT_EQUAL_STRING(ils[0].name, "DUMMY_IR");

    std::vector<cl_name_version_khr> builtInKernels = d0.getInfo<CL_DEVICE_BUILT_IN_KERNELS_WITH_VERSION_KHR>();
    TEST_ASSERT_EQUAL(builtInKernels.size(), 0);
}

} // extern "C"
