|
| 1 | +// |
| 2 | +// Copyright (c) 2025 The Khronos Group Inc. |
| 3 | +// |
| 4 | +// Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | +// you may not use this file except in compliance with the License. |
| 6 | +// You may obtain a copy of the License at |
| 7 | +// |
| 8 | +// http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | +// |
| 10 | +// Unless required by applicable law or agreed to in writing, software |
| 11 | +// distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | +// See the License for the specific language governing permissions and |
| 14 | +// limitations under the License. |
| 15 | +// |
| 16 | +#include "testBase.h" |
| 17 | + |
| 18 | +/* Negative Tests for clCreateContext */ |
| 19 | +REGISTER_TEST(negative_create_context) |
| 20 | +{ |
| 21 | + cl_context_properties props[3] = { |
| 22 | + CL_CONTEXT_PLATFORM, reinterpret_cast<cl_context_properties>(nullptr), 0 |
| 23 | + }; |
| 24 | + cl_int err = 0; |
| 25 | + cl_context ctx = clCreateContext(props, 1, &device, nullptr, nullptr, &err); |
| 26 | + test_object_failure_ret( |
| 27 | + ctx, err, CL_INVALID_PLATFORM, |
| 28 | + "clCreateContext should return CL_INVALID_PLATFORM when:\"an invalid " |
| 29 | + "platform object is used with the CL_CONTEXT_PLATFORM property\" using " |
| 30 | + "a nullptr", |
| 31 | + TEST_FAIL); |
| 32 | + |
| 33 | + if (get_device_cl_version(device) >= Version(1, 1)) |
| 34 | + { |
| 35 | + props[0] = reinterpret_cast<cl_context_properties>("INVALID_PROPERTY"); |
| 36 | + |
| 37 | + props[1] = reinterpret_cast<cl_context_properties>(nullptr); |
| 38 | + ctx = clCreateContext(props, 1, &device, nullptr, nullptr, &err); |
| 39 | + test_object_failure_ret( |
| 40 | + ctx, err, CL_INVALID_PROPERTY, |
| 41 | + "clCreateContext should return CL_INVALID_PROPERTY when: \"context " |
| 42 | + "property name in properties is not a supported property name\"", |
| 43 | + TEST_FAIL); |
| 44 | + |
| 45 | + cl_context_properties invalid_value{ -1 }; |
| 46 | + props[0] = CL_CONTEXT_INTEROP_USER_SYNC; |
| 47 | + props[1] = invalid_value; |
| 48 | + ctx = clCreateContext(props, 1, &device, nullptr, nullptr, &err); |
| 49 | + test_object_failure_ret( |
| 50 | + ctx, err, CL_INVALID_PROPERTY, |
| 51 | + "clCreateContext should return CL_INVALID_PROPERTY when: \"the " |
| 52 | + "value specified for a supported property name is not valid\"", |
| 53 | + TEST_FAIL); |
| 54 | + |
| 55 | + props[0] = CL_DEVICE_TYPE; |
| 56 | + props[1] = 0; |
| 57 | + ctx = clCreateContext(props, 1, &device, nullptr, nullptr, &err); |
| 58 | + test_object_failure_ret( |
| 59 | + ctx, err, CL_INVALID_PROPERTY, |
| 60 | + "clCreateContext should return CL_INVALID_PROPERTY when: \"the " |
| 61 | + "context property name in properties is not a supported property " |
| 62 | + "name\"", |
| 63 | + TEST_FAIL); |
| 64 | + |
| 65 | + cl_bool property_value = CL_FALSE; |
| 66 | + cl_context_properties duplicated_property[5] = { |
| 67 | + CL_CONTEXT_INTEROP_USER_SYNC, |
| 68 | + static_cast<cl_context_properties>(property_value), |
| 69 | + CL_CONTEXT_INTEROP_USER_SYNC, |
| 70 | + static_cast<cl_context_properties>(property_value), 0 |
| 71 | + }; |
| 72 | + ctx = clCreateContext(duplicated_property, 1, &device, nullptr, nullptr, |
| 73 | + &err); |
| 74 | + test_object_failure_ret( |
| 75 | + ctx, err, CL_INVALID_PROPERTY, |
| 76 | + "clCreateContext should return CL_INVALID_PROPERTY when: \"the " |
| 77 | + "same property name is specified more than once\"", |
| 78 | + TEST_FAIL); |
| 79 | + } |
| 80 | + |
| 81 | + ctx = clCreateContext(nullptr, 1, nullptr, nullptr, nullptr, &err); |
| 82 | + test_object_failure_ret(ctx, err, CL_INVALID_VALUE, |
| 83 | + "clCreateContext should return CL_INVALID_VALUE " |
| 84 | + "when: \"devices is NULL\"", |
| 85 | + TEST_FAIL); |
| 86 | + |
| 87 | + ctx = clCreateContext(nullptr, 0, &device, nullptr, nullptr, &err); |
| 88 | + test_object_failure_ret(ctx, err, CL_INVALID_VALUE, |
| 89 | + "clCreateContext should return CL_INVALID_VALUE " |
| 90 | + "when: \"num_devices is equal to zero\"", |
| 91 | + TEST_FAIL); |
| 92 | + |
| 93 | + int user_data = 1; // Arbitrary non-NULL value |
| 94 | + ctx = clCreateContext(nullptr, 1, &device, nullptr, &user_data, &err); |
| 95 | + test_object_failure_ret( |
| 96 | + ctx, err, CL_INVALID_VALUE, |
| 97 | + "clCreateContext should return CL_INVALID_VALUE when: \"pfn_notify is " |
| 98 | + "NULL but user_data is not NULL\"", |
| 99 | + TEST_FAIL); |
| 100 | + |
| 101 | + cl_device_id invalid_device = nullptr; |
| 102 | + ctx = clCreateContext(nullptr, 1, &invalid_device, nullptr, nullptr, &err); |
| 103 | + test_object_failure_ret( |
| 104 | + ctx, err, CL_INVALID_DEVICE, |
| 105 | + "clCreateContext should return CL_INVALID_DEVICE when: \"any device in " |
| 106 | + "devices is not a valid device\" using a device set to nullptr", |
| 107 | + TEST_FAIL); |
| 108 | + |
| 109 | + return TEST_PASS; |
| 110 | +} |
| 111 | + |
| 112 | +/* Negative Tests for clCreateContextFromType */ |
| 113 | +REGISTER_TEST(negative_create_context_from_type) |
| 114 | +{ |
| 115 | + cl_platform_id platform = getPlatformFromDevice(device); |
| 116 | + |
| 117 | + cl_context_properties props[5] = { |
| 118 | + CL_CONTEXT_PLATFORM, reinterpret_cast<cl_context_properties>(nullptr), |
| 119 | + 0, 0, 0 |
| 120 | + }; |
| 121 | + cl_int err = 0; |
| 122 | + cl_context ctx = clCreateContextFromType(props, CL_DEVICE_TYPE_DEFAULT, |
| 123 | + nullptr, nullptr, &err); |
| 124 | + test_object_failure_ret( |
| 125 | + ctx, err, CL_INVALID_PLATFORM, |
| 126 | + "clCreateContextFromType should return CL_INVALID_PLATFORM when: \"an " |
| 127 | + "invalid platform object is used with the CL_CONTEXT_PLATFORM " |
| 128 | + "property\" using a nullptr", |
| 129 | + TEST_FAIL); |
| 130 | + |
| 131 | + ctx = clCreateContextFromType(props, CL_DEVICE_TYPE_DEFAULT, nullptr, |
| 132 | + nullptr, &err); |
| 133 | + test_object_failure_ret( |
| 134 | + ctx, err, CL_INVALID_PLATFORM, |
| 135 | + "clCreateContextFromType should return CL_INVALID_PLATFORM when: \"an " |
| 136 | + "invalid platform object is used with the CL_CONTEXT_PLATFORM " |
| 137 | + "property\" using a valid object that is NOT a platform", |
| 138 | + TEST_FAIL); |
| 139 | + |
| 140 | + if (get_device_cl_version(device) >= Version(1, 1)) |
| 141 | + { |
| 142 | + props[1] = reinterpret_cast<cl_context_properties>(platform); |
| 143 | + props[2] = reinterpret_cast<cl_context_properties>("INVALID_PROPERTY"); |
| 144 | + props[3] = reinterpret_cast<cl_context_properties>(nullptr); |
| 145 | + |
| 146 | + ctx = clCreateContextFromType(props, CL_DEVICE_TYPE_DEFAULT, nullptr, |
| 147 | + nullptr, &err); |
| 148 | + test_object_failure_ret( |
| 149 | + ctx, err, CL_INVALID_PROPERTY, |
| 150 | + "clCreateContextFromType should return CL_INVALID_PROPERTY when: " |
| 151 | + "\"context property name in properties is not a supported property " |
| 152 | + "name\"", |
| 153 | + TEST_FAIL); |
| 154 | + |
| 155 | + cl_context_properties invalid_value{ -1 }; |
| 156 | + props[2] = CL_CONTEXT_INTEROP_USER_SYNC; |
| 157 | + props[3] = invalid_value; |
| 158 | + ctx = clCreateContextFromType(props, CL_DEVICE_TYPE_DEFAULT, nullptr, |
| 159 | + nullptr, &err); |
| 160 | + test_object_failure_ret( |
| 161 | + ctx, err, CL_INVALID_PROPERTY, |
| 162 | + "clCreateContextFromType should return CL_INVALID_PROPERTY when: " |
| 163 | + "\"the value specified for a supported property name is not " |
| 164 | + "valid\"", |
| 165 | + TEST_FAIL); |
| 166 | + |
| 167 | + props[2] = CL_CONTEXT_PLATFORM; |
| 168 | + props[3] = reinterpret_cast<cl_context_properties>(platform); |
| 169 | + ctx = clCreateContextFromType(props, CL_DEVICE_TYPE_DEFAULT, nullptr, |
| 170 | + nullptr, &err); |
| 171 | + test_object_failure_ret( |
| 172 | + ctx, err, CL_INVALID_PROPERTY, |
| 173 | + "clCreateContextFromType should return CL_INVALID_PROPERTY when: " |
| 174 | + "\"the same property name is specified more than once\"", |
| 175 | + TEST_FAIL); |
| 176 | + } |
| 177 | + |
| 178 | + int user_data = 1; // Arbitrary non-NULL value |
| 179 | + ctx = clCreateContextFromType(nullptr, CL_DEVICE_TYPE_DEFAULT, nullptr, |
| 180 | + &user_data, &err); |
| 181 | + test_object_failure_ret( |
| 182 | + ctx, err, CL_INVALID_VALUE, |
| 183 | + "clCreateContextFromType should return CL_INVALID_VALUE when: " |
| 184 | + "\"pfn_notify is NULL but user_data is not NULL\"", |
| 185 | + TEST_FAIL); |
| 186 | + |
| 187 | + cl_device_type INVALID_DEVICE_TYPE = 0; |
| 188 | + ctx = clCreateContextFromType(nullptr, INVALID_DEVICE_TYPE, nullptr, |
| 189 | + nullptr, &err); |
| 190 | + test_object_failure_ret( |
| 191 | + ctx, err, CL_INVALID_DEVICE_TYPE, |
| 192 | + "clCreateContextFromType should return CL_INVALID_DEVICE_TYPE when: " |
| 193 | + "\"device_type is not a valid value\"", |
| 194 | + TEST_FAIL); |
| 195 | + |
| 196 | + std::vector<cl_device_type> device_types = { CL_DEVICE_TYPE_CPU, |
| 197 | + CL_DEVICE_TYPE_GPU, |
| 198 | + CL_DEVICE_TYPE_ACCELERATOR }; |
| 199 | + if (get_device_cl_version(device) >= Version(1, 2)) |
| 200 | + { |
| 201 | + device_types.push_back(CL_DEVICE_TYPE_CUSTOM); |
| 202 | + } |
| 203 | + for (auto type : device_types) |
| 204 | + { |
| 205 | + clContextWrapper tmp_context = |
| 206 | + clCreateContextFromType(nullptr, type, nullptr, nullptr, &err); |
| 207 | + if (err != CL_SUCCESS) |
| 208 | + { |
| 209 | + test_object_failure_ret( |
| 210 | + tmp_context, err, CL_DEVICE_NOT_FOUND, |
| 211 | + "clCreateContextFromType should return CL_DEVICE_NOT_AVAILABLE " |
| 212 | + "when: \"no devices that match device_type and property values " |
| 213 | + "specified in properties are currently available\"", |
| 214 | + TEST_FAIL); |
| 215 | + break; |
| 216 | + } |
| 217 | + } |
| 218 | + |
| 219 | + return TEST_PASS; |
| 220 | +} |
| 221 | + |
| 222 | +/* Negative Tests for clRetainContext */ |
| 223 | +REGISTER_TEST(negative_retain_context) |
| 224 | +{ |
| 225 | + cl_int err = clRetainContext(nullptr); |
| 226 | + test_failure_error_ret( |
| 227 | + err, CL_INVALID_CONTEXT, |
| 228 | + "clRetainContext should return CL_INVALID_CONTEXT when: \"context is " |
| 229 | + "not a valid OpenCL context\" using a nullptr", |
| 230 | + TEST_FAIL); |
| 231 | + |
| 232 | + return TEST_PASS; |
| 233 | +} |
| 234 | + |
| 235 | +/* Negative Tests for clReleaseContext */ |
| 236 | +REGISTER_TEST(negative_release_context) |
| 237 | +{ |
| 238 | + cl_int err = clReleaseContext(nullptr); |
| 239 | + test_failure_error_ret( |
| 240 | + err, CL_INVALID_CONTEXT, |
| 241 | + "clReleaseContext should return CL_INVALID_CONTEXT when: \"context is " |
| 242 | + "not a valid OpenCL context\" using a nullptr", |
| 243 | + TEST_FAIL); |
| 244 | + |
| 245 | + return TEST_PASS; |
| 246 | +} |
| 247 | + |
| 248 | +/* Negative Tests for clGetContextInfo */ |
| 249 | +REGISTER_TEST(negative_get_context_info) |
| 250 | +{ |
| 251 | + |
| 252 | + cl_uint param_value = 0; |
| 253 | + cl_int err = clGetContextInfo(nullptr, CL_CONTEXT_REFERENCE_COUNT, |
| 254 | + sizeof(param_value), ¶m_value, nullptr); |
| 255 | + test_failure_error_ret( |
| 256 | + err, CL_INVALID_CONTEXT, |
| 257 | + "clGetContextInfo should return CL_INVALID_CONTEXT when: \"context is " |
| 258 | + "not a valid context\" using a nullptr", |
| 259 | + TEST_FAIL); |
| 260 | + |
| 261 | + cl_context_info INVALID_PARAM_VALUE = 0; |
| 262 | + err = clGetContextInfo(context, INVALID_PARAM_VALUE, 0, nullptr, nullptr); |
| 263 | + test_failure_error_ret( |
| 264 | + err, CL_INVALID_VALUE, |
| 265 | + "clGetContextInfo should return CL_INVALID_VALUE when: \"param_name is " |
| 266 | + "not one of the supported values\"", |
| 267 | + TEST_FAIL); |
| 268 | + |
| 269 | + err = clGetContextInfo(context, CL_CONTEXT_REFERENCE_COUNT, 0, ¶m_value, |
| 270 | + nullptr); |
| 271 | + test_failure_error_ret( |
| 272 | + err, CL_INVALID_VALUE, |
| 273 | + "clGetContextInfo should return CL_INVALID_VALUE when: \"size in bytes " |
| 274 | + "specified by param_value_size is < size of return type and " |
| 275 | + "param_value is not a NULL value\"", |
| 276 | + TEST_FAIL); |
| 277 | + |
| 278 | + return TEST_PASS; |
| 279 | +} |
| 280 | + |
| 281 | +/* Negative Tests for clSetContextDestructorCallback */ |
| 282 | +static void CL_CALLBACK callback(cl_context context, void* user_data) {} |
| 283 | + |
| 284 | +REGISTER_TEST_VERSION(negative_set_context_destructor_callback, Version(3, 0)) |
| 285 | +{ |
| 286 | + cl_int err = clSetContextDestructorCallback(nullptr, callback, nullptr); |
| 287 | + test_failure_error_ret( |
| 288 | + err, CL_INVALID_CONTEXT, |
| 289 | + "clSetContextDestructorCallback should return CL_INVALID_CONTEXT when: " |
| 290 | + "\"context is not a valid context\" using a nullptr", |
| 291 | + TEST_FAIL); |
| 292 | + |
| 293 | + err = clSetContextDestructorCallback(context, nullptr, nullptr); |
| 294 | + test_failure_error_ret(err, CL_INVALID_VALUE, |
| 295 | + "clSetContextDestructorCallback should return " |
| 296 | + "CL_INVALID_VALUE when: \"pfn_notify is NULL\"", |
| 297 | + TEST_FAIL); |
| 298 | + |
| 299 | + return TEST_PASS; |
| 300 | +} |
0 commit comments