1 // SPDX-License-Identifier: GPL-2.0 1 // SPDX-License-Identifier: GPL-2.0 2 /* 2 /* 3 * KUnit test for core test infrastructure. 3 * KUnit test for core test infrastructure. 4 * 4 * 5 * Copyright (C) 2019, Google LLC. 5 * Copyright (C) 2019, Google LLC. 6 * Author: Brendan Higgins <brendanhiggins@goo 6 * Author: Brendan Higgins <brendanhiggins@google.com> 7 */ 7 */ 8 #include "linux/gfp_types.h" << 9 #include <kunit/test.h> 8 #include <kunit/test.h> 10 #include <kunit/test-bug.h> << 11 9 12 #include <linux/device.h> << 13 #include <kunit/device.h> << 14 << 15 #include "string-stream.h" << 16 #include "try-catch-impl.h" 10 #include "try-catch-impl.h" 17 11 18 struct kunit_try_catch_test_context { 12 struct kunit_try_catch_test_context { 19 struct kunit_try_catch *try_catch; 13 struct kunit_try_catch *try_catch; 20 bool function_called; 14 bool function_called; 21 }; 15 }; 22 16 23 static void kunit_test_successful_try(void *da 17 static void kunit_test_successful_try(void *data) 24 { 18 { 25 struct kunit *test = data; 19 struct kunit *test = data; 26 struct kunit_try_catch_test_context *c 20 struct kunit_try_catch_test_context *ctx = test->priv; 27 21 28 ctx->function_called = true; 22 ctx->function_called = true; 29 } 23 } 30 24 31 static void kunit_test_no_catch(void *data) 25 static void kunit_test_no_catch(void *data) 32 { 26 { 33 struct kunit *test = data; 27 struct kunit *test = data; 34 28 35 KUNIT_FAIL(test, "Catch should not be 29 KUNIT_FAIL(test, "Catch should not be called\n"); 36 } 30 } 37 31 38 static void kunit_test_try_catch_successful_tr 32 static void kunit_test_try_catch_successful_try_no_catch(struct kunit *test) 39 { 33 { 40 struct kunit_try_catch_test_context *c 34 struct kunit_try_catch_test_context *ctx = test->priv; 41 struct kunit_try_catch *try_catch = ct 35 struct kunit_try_catch *try_catch = ctx->try_catch; 42 36 43 kunit_try_catch_init(try_catch, 37 kunit_try_catch_init(try_catch, 44 test, 38 test, 45 kunit_test_succes 39 kunit_test_successful_try, 46 kunit_test_no_cat 40 kunit_test_no_catch); 47 kunit_try_catch_run(try_catch, test); 41 kunit_try_catch_run(try_catch, test); 48 42 49 KUNIT_EXPECT_TRUE(test, ctx->function_ 43 KUNIT_EXPECT_TRUE(test, ctx->function_called); 50 } 44 } 51 45 52 static void kunit_test_unsuccessful_try(void * 46 static void kunit_test_unsuccessful_try(void *data) 53 { 47 { 54 struct kunit *test = data; 48 struct kunit *test = data; 55 struct kunit_try_catch_test_context *c 49 struct kunit_try_catch_test_context *ctx = test->priv; 56 struct kunit_try_catch *try_catch = ct 50 struct kunit_try_catch *try_catch = ctx->try_catch; 57 51 58 kunit_try_catch_throw(try_catch); 52 kunit_try_catch_throw(try_catch); 59 KUNIT_FAIL(test, "This line should nev 53 KUNIT_FAIL(test, "This line should never be reached\n"); 60 } 54 } 61 55 62 static void kunit_test_catch(void *data) 56 static void kunit_test_catch(void *data) 63 { 57 { 64 struct kunit *test = data; 58 struct kunit *test = data; 65 struct kunit_try_catch_test_context *c 59 struct kunit_try_catch_test_context *ctx = test->priv; 66 60 67 ctx->function_called = true; 61 ctx->function_called = true; 68 } 62 } 69 63 70 static void kunit_test_try_catch_unsuccessful_ 64 static void kunit_test_try_catch_unsuccessful_try_does_catch(struct kunit *test) 71 { 65 { 72 struct kunit_try_catch_test_context *c 66 struct kunit_try_catch_test_context *ctx = test->priv; 73 struct kunit_try_catch *try_catch = ct 67 struct kunit_try_catch *try_catch = ctx->try_catch; 74 68 75 kunit_try_catch_init(try_catch, 69 kunit_try_catch_init(try_catch, 76 test, 70 test, 77 kunit_test_unsucc 71 kunit_test_unsuccessful_try, 78 kunit_test_catch) 72 kunit_test_catch); 79 kunit_try_catch_run(try_catch, test); 73 kunit_try_catch_run(try_catch, test); 80 74 81 KUNIT_EXPECT_TRUE(test, ctx->function_ 75 KUNIT_EXPECT_TRUE(test, ctx->function_called); 82 } 76 } 83 77 84 static int kunit_try_catch_test_init(struct ku 78 static int kunit_try_catch_test_init(struct kunit *test) 85 { 79 { 86 struct kunit_try_catch_test_context *c 80 struct kunit_try_catch_test_context *ctx; 87 81 88 ctx = kunit_kzalloc(test, sizeof(*ctx) 82 ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL); 89 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx 83 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); 90 test->priv = ctx; 84 test->priv = ctx; 91 85 92 ctx->try_catch = kunit_kmalloc(test, 86 ctx->try_catch = kunit_kmalloc(test, 93 sizeof( 87 sizeof(*ctx->try_catch), 94 GFP_KER 88 GFP_KERNEL); 95 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx 89 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx->try_catch); 96 90 97 return 0; 91 return 0; 98 } 92 } 99 93 100 static struct kunit_case kunit_try_catch_test_ 94 static struct kunit_case kunit_try_catch_test_cases[] = { 101 KUNIT_CASE(kunit_test_try_catch_succes 95 KUNIT_CASE(kunit_test_try_catch_successful_try_no_catch), 102 KUNIT_CASE(kunit_test_try_catch_unsucc 96 KUNIT_CASE(kunit_test_try_catch_unsuccessful_try_does_catch), 103 {} 97 {} 104 }; 98 }; 105 99 106 static struct kunit_suite kunit_try_catch_test 100 static struct kunit_suite kunit_try_catch_test_suite = { 107 .name = "kunit-try-catch-test", 101 .name = "kunit-try-catch-test", 108 .init = kunit_try_catch_test_init, 102 .init = kunit_try_catch_test_init, 109 .test_cases = kunit_try_catch_test_cas 103 .test_cases = kunit_try_catch_test_cases, 110 }; 104 }; 111 105 112 #if IS_ENABLED(CONFIG_KUNIT_FAULT_TEST) << 113 << 114 static void kunit_test_null_dereference(void * << 115 { << 116 struct kunit *test = data; << 117 int *null = NULL; << 118 << 119 *null = 0; << 120 << 121 KUNIT_FAIL(test, "This line should nev << 122 } << 123 << 124 static void kunit_test_fault_null_dereference( << 125 { << 126 struct kunit_try_catch_test_context *c << 127 struct kunit_try_catch *try_catch = ct << 128 << 129 kunit_try_catch_init(try_catch, << 130 test, << 131 kunit_test_null_d << 132 kunit_test_catch) << 133 kunit_try_catch_run(try_catch, test); << 134 << 135 KUNIT_EXPECT_EQ(test, try_catch->try_r << 136 KUNIT_EXPECT_TRUE(test, ctx->function_ << 137 } << 138 << 139 #endif /* CONFIG_KUNIT_FAULT_TEST */ << 140 << 141 static struct kunit_case kunit_fault_test_case << 142 #if IS_ENABLED(CONFIG_KUNIT_FAULT_TEST) << 143 KUNIT_CASE(kunit_test_fault_null_deref << 144 #endif /* CONFIG_KUNIT_FAULT_TEST */ << 145 {} << 146 }; << 147 << 148 static struct kunit_suite kunit_fault_test_sui << 149 .name = "kunit_fault", << 150 .init = kunit_try_catch_test_init, << 151 .test_cases = kunit_fault_test_cases, << 152 }; << 153 << 154 /* 106 /* 155 * Context for testing test managed resources 107 * Context for testing test managed resources 156 * is_resource_initialized is used to test arb 108 * is_resource_initialized is used to test arbitrary resources 157 */ 109 */ 158 struct kunit_test_resource_context { 110 struct kunit_test_resource_context { 159 struct kunit test; 111 struct kunit test; 160 bool is_resource_initialized; 112 bool is_resource_initialized; 161 int allocate_order[2]; 113 int allocate_order[2]; 162 int free_order[4]; !! 114 int free_order[2]; 163 }; 115 }; 164 116 165 static int fake_resource_init(struct kunit_res 117 static int fake_resource_init(struct kunit_resource *res, void *context) 166 { 118 { 167 struct kunit_test_resource_context *ct 119 struct kunit_test_resource_context *ctx = context; 168 120 169 res->data = &ctx->is_resource_initiali 121 res->data = &ctx->is_resource_initialized; 170 ctx->is_resource_initialized = true; 122 ctx->is_resource_initialized = true; 171 return 0; 123 return 0; 172 } 124 } 173 125 174 static void fake_resource_free(struct kunit_re 126 static void fake_resource_free(struct kunit_resource *res) 175 { 127 { 176 bool *is_resource_initialized = res->d 128 bool *is_resource_initialized = res->data; 177 129 178 *is_resource_initialized = false; 130 *is_resource_initialized = false; 179 } 131 } 180 132 181 static void kunit_resource_test_init_resources 133 static void kunit_resource_test_init_resources(struct kunit *test) 182 { 134 { 183 struct kunit_test_resource_context *ct 135 struct kunit_test_resource_context *ctx = test->priv; 184 136 185 kunit_init_test(&ctx->test, "testing_t 137 kunit_init_test(&ctx->test, "testing_test_init_test", NULL); 186 138 187 KUNIT_EXPECT_TRUE(test, list_empty(&ct 139 KUNIT_EXPECT_TRUE(test, list_empty(&ctx->test.resources)); 188 } 140 } 189 141 190 static void kunit_resource_test_alloc_resource 142 static void kunit_resource_test_alloc_resource(struct kunit *test) 191 { 143 { 192 struct kunit_test_resource_context *ct 144 struct kunit_test_resource_context *ctx = test->priv; 193 struct kunit_resource *res; 145 struct kunit_resource *res; 194 kunit_resource_free_t free = fake_reso 146 kunit_resource_free_t free = fake_resource_free; 195 147 196 res = kunit_alloc_and_get_resource(&ct 148 res = kunit_alloc_and_get_resource(&ctx->test, 197 fak 149 fake_resource_init, 198 fak 150 fake_resource_free, 199 GFP 151 GFP_KERNEL, 200 ctx 152 ctx); 201 153 202 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, res 154 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, res); 203 KUNIT_EXPECT_PTR_EQ(test, 155 KUNIT_EXPECT_PTR_EQ(test, 204 &ctx->is_resource_ 156 &ctx->is_resource_initialized, 205 (bool *)res->data) 157 (bool *)res->data); 206 KUNIT_EXPECT_TRUE(test, list_is_last(& 158 KUNIT_EXPECT_TRUE(test, list_is_last(&res->node, &ctx->test.resources)); 207 KUNIT_EXPECT_PTR_EQ(test, free, res->f 159 KUNIT_EXPECT_PTR_EQ(test, free, res->free); 208 160 209 kunit_put_resource(res); 161 kunit_put_resource(res); 210 } 162 } 211 163 212 static inline bool kunit_resource_instance_mat << 213 << 214 << 215 { << 216 return res->data == match_data; << 217 } << 218 << 219 /* 164 /* 220 * Note: tests below use kunit_alloc_and_get_r 165 * Note: tests below use kunit_alloc_and_get_resource(), so as a consequence 221 * they have a reference to the associated res 166 * they have a reference to the associated resource that they must release 222 * via kunit_put_resource(). In normal operat 167 * via kunit_put_resource(). In normal operation, users will only 223 * have to do this for cases where they use ku 168 * have to do this for cases where they use kunit_find_resource(), and the 224 * kunit_alloc_resource() function will be use 169 * kunit_alloc_resource() function will be used (which does not take a 225 * resource reference). 170 * resource reference). 226 */ 171 */ 227 static void kunit_resource_test_destroy_resour 172 static void kunit_resource_test_destroy_resource(struct kunit *test) 228 { 173 { 229 struct kunit_test_resource_context *ct 174 struct kunit_test_resource_context *ctx = test->priv; 230 struct kunit_resource *res = kunit_all 175 struct kunit_resource *res = kunit_alloc_and_get_resource( 231 &ctx->test, 176 &ctx->test, 232 fake_resource_init, 177 fake_resource_init, 233 fake_resource_free, 178 fake_resource_free, 234 GFP_KERNEL, 179 GFP_KERNEL, 235 ctx); 180 ctx); 236 181 237 kunit_put_resource(res); 182 kunit_put_resource(res); 238 183 239 KUNIT_ASSERT_FALSE(test, 184 KUNIT_ASSERT_FALSE(test, 240 kunit_destroy_resou 185 kunit_destroy_resource(&ctx->test, 241 186 kunit_resource_instance_match, 242 187 res->data)); 243 188 244 KUNIT_EXPECT_FALSE(test, ctx->is_resou 189 KUNIT_EXPECT_FALSE(test, ctx->is_resource_initialized); 245 KUNIT_EXPECT_TRUE(test, list_empty(&ct 190 KUNIT_EXPECT_TRUE(test, list_empty(&ctx->test.resources)); 246 } 191 } 247 192 248 static void kunit_resource_test_remove_resourc << 249 { << 250 struct kunit_test_resource_context *ct << 251 struct kunit_resource *res = kunit_all << 252 &ctx->test, << 253 fake_resource_init, << 254 fake_resource_free, << 255 GFP_KERNEL, << 256 ctx); << 257 << 258 /* The resource is in the list */ << 259 KUNIT_EXPECT_FALSE(test, list_empty(&c << 260 << 261 /* Remove the resource. The pointer is << 262 * found. << 263 */ << 264 kunit_remove_resource(test, res); << 265 KUNIT_EXPECT_TRUE(test, list_empty(&ct << 266 /* We haven't been freed yet. */ << 267 KUNIT_EXPECT_TRUE(test, ctx->is_resour << 268 << 269 /* Removing the resource multiple time << 270 kunit_remove_resource(test, res); << 271 KUNIT_EXPECT_TRUE(test, list_empty(&ct << 272 /* Despite having been removed twice ( << 273 * resource still has not been freed. << 274 */ << 275 KUNIT_EXPECT_TRUE(test, ctx->is_resour << 276 << 277 /* Free the resource. */ << 278 kunit_put_resource(res); << 279 KUNIT_EXPECT_FALSE(test, ctx->is_resou << 280 } << 281 << 282 static void kunit_resource_test_cleanup_resour 193 static void kunit_resource_test_cleanup_resources(struct kunit *test) 283 { 194 { 284 int i; 195 int i; 285 struct kunit_test_resource_context *ct 196 struct kunit_test_resource_context *ctx = test->priv; 286 struct kunit_resource *resources[5]; 197 struct kunit_resource *resources[5]; 287 198 288 for (i = 0; i < ARRAY_SIZE(resources); 199 for (i = 0; i < ARRAY_SIZE(resources); i++) { 289 resources[i] = kunit_alloc_and 200 resources[i] = kunit_alloc_and_get_resource(&ctx->test, 290 201 fake_resource_init, 291 202 fake_resource_free, 292 203 GFP_KERNEL, 293 204 ctx); 294 kunit_put_resource(resources[i 205 kunit_put_resource(resources[i]); 295 } 206 } 296 207 297 kunit_cleanup(&ctx->test); 208 kunit_cleanup(&ctx->test); 298 209 299 KUNIT_EXPECT_TRUE(test, list_empty(&ct 210 KUNIT_EXPECT_TRUE(test, list_empty(&ctx->test.resources)); 300 } 211 } 301 212 302 static void kunit_resource_test_mark_order(int 213 static void kunit_resource_test_mark_order(int order_array[], 303 siz 214 size_t order_size, 304 int 215 int key) 305 { 216 { 306 int i; 217 int i; 307 218 308 for (i = 0; i < order_size && order_ar 219 for (i = 0; i < order_size && order_array[i]; i++) 309 ; 220 ; 310 221 311 order_array[i] = key; 222 order_array[i] = key; 312 } 223 } 313 224 314 #define KUNIT_RESOURCE_TEST_MARK_ORDER(ctx, or 225 #define KUNIT_RESOURCE_TEST_MARK_ORDER(ctx, order_field, key) \ 315 kunit_resource_test_mark_order 226 kunit_resource_test_mark_order(ctx->order_field, \ 316 227 ARRAY_SIZE(ctx->order_field), \ 317 228 key) 318 229 319 static int fake_resource_2_init(struct kunit_r 230 static int fake_resource_2_init(struct kunit_resource *res, void *context) 320 { 231 { 321 struct kunit_test_resource_context *ct 232 struct kunit_test_resource_context *ctx = context; 322 233 323 KUNIT_RESOURCE_TEST_MARK_ORDER(ctx, al 234 KUNIT_RESOURCE_TEST_MARK_ORDER(ctx, allocate_order, 2); 324 235 325 res->data = ctx; 236 res->data = ctx; 326 237 327 return 0; 238 return 0; 328 } 239 } 329 240 330 static void fake_resource_2_free(struct kunit_ 241 static void fake_resource_2_free(struct kunit_resource *res) 331 { 242 { 332 struct kunit_test_resource_context *ct 243 struct kunit_test_resource_context *ctx = res->data; 333 244 334 KUNIT_RESOURCE_TEST_MARK_ORDER(ctx, fr 245 KUNIT_RESOURCE_TEST_MARK_ORDER(ctx, free_order, 2); 335 } 246 } 336 247 337 static int fake_resource_1_init(struct kunit_r 248 static int fake_resource_1_init(struct kunit_resource *res, void *context) 338 { 249 { 339 struct kunit_test_resource_context *ct 250 struct kunit_test_resource_context *ctx = context; 340 struct kunit_resource *res2; 251 struct kunit_resource *res2; 341 252 342 res2 = kunit_alloc_and_get_resource(&c 253 res2 = kunit_alloc_and_get_resource(&ctx->test, 343 fa 254 fake_resource_2_init, 344 fa 255 fake_resource_2_free, 345 GF 256 GFP_KERNEL, 346 ct 257 ctx); 347 258 348 KUNIT_RESOURCE_TEST_MARK_ORDER(ctx, al 259 KUNIT_RESOURCE_TEST_MARK_ORDER(ctx, allocate_order, 1); 349 260 350 res->data = ctx; 261 res->data = ctx; 351 262 352 kunit_put_resource(res2); 263 kunit_put_resource(res2); 353 264 354 return 0; 265 return 0; 355 } 266 } 356 267 357 static void fake_resource_1_free(struct kunit_ 268 static void fake_resource_1_free(struct kunit_resource *res) 358 { 269 { 359 struct kunit_test_resource_context *ct 270 struct kunit_test_resource_context *ctx = res->data; 360 271 361 KUNIT_RESOURCE_TEST_MARK_ORDER(ctx, fr 272 KUNIT_RESOURCE_TEST_MARK_ORDER(ctx, free_order, 1); 362 } 273 } 363 274 364 /* 275 /* 365 * TODO(brendanhiggins@google.com): replace th 276 * TODO(brendanhiggins@google.com): replace the arrays that keep track of the 366 * order of allocation and freeing with strict 277 * order of allocation and freeing with strict mocks using the IN_SEQUENCE macro 367 * to assert allocation and freeing order when 278 * to assert allocation and freeing order when the feature becomes available. 368 */ 279 */ 369 static void kunit_resource_test_proper_free_or 280 static void kunit_resource_test_proper_free_ordering(struct kunit *test) 370 { 281 { 371 struct kunit_test_resource_context *ct 282 struct kunit_test_resource_context *ctx = test->priv; 372 struct kunit_resource *res; 283 struct kunit_resource *res; 373 284 374 /* fake_resource_1 allocates a fake_re 285 /* fake_resource_1 allocates a fake_resource_2 in its init. */ 375 res = kunit_alloc_and_get_resource(&ct 286 res = kunit_alloc_and_get_resource(&ctx->test, 376 fak 287 fake_resource_1_init, 377 fak 288 fake_resource_1_free, 378 GFP 289 GFP_KERNEL, 379 ctx 290 ctx); 380 291 381 /* 292 /* 382 * Since fake_resource_2_init calls KU 293 * Since fake_resource_2_init calls KUNIT_RESOURCE_TEST_MARK_ORDER 383 * before returning to fake_resource_1 294 * before returning to fake_resource_1_init, it should be the first to 384 * put its key in the allocate_order a 295 * put its key in the allocate_order array. 385 */ 296 */ 386 KUNIT_EXPECT_EQ(test, ctx->allocate_or 297 KUNIT_EXPECT_EQ(test, ctx->allocate_order[0], 2); 387 KUNIT_EXPECT_EQ(test, ctx->allocate_or 298 KUNIT_EXPECT_EQ(test, ctx->allocate_order[1], 1); 388 299 389 kunit_put_resource(res); 300 kunit_put_resource(res); 390 301 391 kunit_cleanup(&ctx->test); 302 kunit_cleanup(&ctx->test); 392 303 393 /* 304 /* 394 * Because fake_resource_2 finishes al 305 * Because fake_resource_2 finishes allocation before fake_resource_1, 395 * fake_resource_1 should be freed fir 306 * fake_resource_1 should be freed first since it could depend on 396 * fake_resource_2. 307 * fake_resource_2. 397 */ 308 */ 398 KUNIT_EXPECT_EQ(test, ctx->free_order[ 309 KUNIT_EXPECT_EQ(test, ctx->free_order[0], 1); 399 KUNIT_EXPECT_EQ(test, ctx->free_order[ 310 KUNIT_EXPECT_EQ(test, ctx->free_order[1], 2); 400 } 311 } 401 312 402 static void kunit_resource_test_static(struct 313 static void kunit_resource_test_static(struct kunit *test) 403 { 314 { 404 struct kunit_test_resource_context ctx 315 struct kunit_test_resource_context ctx; 405 struct kunit_resource res; 316 struct kunit_resource res; 406 317 407 KUNIT_EXPECT_EQ(test, kunit_add_resour 318 KUNIT_EXPECT_EQ(test, kunit_add_resource(test, NULL, NULL, &res, &ctx), 408 0); 319 0); 409 320 410 KUNIT_EXPECT_PTR_EQ(test, res.data, (v 321 KUNIT_EXPECT_PTR_EQ(test, res.data, (void *)&ctx); 411 322 412 kunit_cleanup(test); 323 kunit_cleanup(test); 413 324 414 KUNIT_EXPECT_TRUE(test, list_empty(&te 325 KUNIT_EXPECT_TRUE(test, list_empty(&test->resources)); 415 } 326 } 416 327 417 static void kunit_resource_test_named(struct k 328 static void kunit_resource_test_named(struct kunit *test) 418 { 329 { 419 struct kunit_resource res1, res2, *fou 330 struct kunit_resource res1, res2, *found = NULL; 420 struct kunit_test_resource_context ctx 331 struct kunit_test_resource_context ctx; 421 332 422 KUNIT_EXPECT_EQ(test, 333 KUNIT_EXPECT_EQ(test, 423 kunit_add_named_resour 334 kunit_add_named_resource(test, NULL, NULL, &res1, 424 335 "resource_1", &ctx), 425 0); 336 0); 426 KUNIT_EXPECT_PTR_EQ(test, res1.data, ( 337 KUNIT_EXPECT_PTR_EQ(test, res1.data, (void *)&ctx); 427 338 428 KUNIT_EXPECT_EQ(test, 339 KUNIT_EXPECT_EQ(test, 429 kunit_add_named_resour 340 kunit_add_named_resource(test, NULL, NULL, &res1, 430 341 "resource_1", &ctx), 431 -EEXIST); 342 -EEXIST); 432 343 433 KUNIT_EXPECT_EQ(test, 344 KUNIT_EXPECT_EQ(test, 434 kunit_add_named_resour 345 kunit_add_named_resource(test, NULL, NULL, &res2, 435 346 "resource_2", &ctx), 436 0); 347 0); 437 348 438 found = kunit_find_named_resource(test 349 found = kunit_find_named_resource(test, "resource_1"); 439 350 440 KUNIT_EXPECT_PTR_EQ(test, found, &res1 351 KUNIT_EXPECT_PTR_EQ(test, found, &res1); 441 352 442 if (found) 353 if (found) 443 kunit_put_resource(&res1); 354 kunit_put_resource(&res1); 444 355 445 KUNIT_EXPECT_EQ(test, kunit_destroy_na 356 KUNIT_EXPECT_EQ(test, kunit_destroy_named_resource(test, "resource_2"), 446 0); 357 0); 447 358 448 kunit_cleanup(test); 359 kunit_cleanup(test); 449 360 450 KUNIT_EXPECT_TRUE(test, list_empty(&te 361 KUNIT_EXPECT_TRUE(test, list_empty(&test->resources)); 451 } 362 } 452 363 453 static void increment_int(void *ctx) << 454 { << 455 int *i = (int *)ctx; << 456 (*i)++; << 457 } << 458 << 459 static void kunit_resource_test_action(struct << 460 { << 461 int num_actions = 0; << 462 << 463 kunit_add_action(test, increment_int, << 464 KUNIT_EXPECT_EQ(test, num_actions, 0); << 465 kunit_cleanup(test); << 466 KUNIT_EXPECT_EQ(test, num_actions, 1); << 467 << 468 /* Once we've cleaned up, the action q << 469 kunit_cleanup(test); << 470 KUNIT_EXPECT_EQ(test, num_actions, 1); << 471 << 472 /* Check the same function can be defe << 473 kunit_add_action(test, increment_int, << 474 kunit_add_action(test, increment_int, << 475 kunit_cleanup(test); << 476 KUNIT_EXPECT_EQ(test, num_actions, 3); << 477 } << 478 static void kunit_resource_test_remove_action( << 479 { << 480 int num_actions = 0; << 481 << 482 kunit_add_action(test, increment_int, << 483 KUNIT_EXPECT_EQ(test, num_actions, 0); << 484 << 485 kunit_remove_action(test, increment_in << 486 kunit_cleanup(test); << 487 KUNIT_EXPECT_EQ(test, num_actions, 0); << 488 } << 489 static void kunit_resource_test_release_action << 490 { << 491 int num_actions = 0; << 492 << 493 kunit_add_action(test, increment_int, << 494 KUNIT_EXPECT_EQ(test, num_actions, 0); << 495 /* Runs immediately on trigger. */ << 496 kunit_release_action(test, increment_i << 497 KUNIT_EXPECT_EQ(test, num_actions, 1); << 498 << 499 /* Doesn't run again on test exit. */ << 500 kunit_cleanup(test); << 501 KUNIT_EXPECT_EQ(test, num_actions, 1); << 502 } << 503 static void action_order_1(void *ctx) << 504 { << 505 struct kunit_test_resource_context *re << 506 << 507 KUNIT_RESOURCE_TEST_MARK_ORDER(res_ctx << 508 kunit_log(KERN_INFO, current->kunit_te << 509 } << 510 static void action_order_2(void *ctx) << 511 { << 512 struct kunit_test_resource_context *re << 513 << 514 KUNIT_RESOURCE_TEST_MARK_ORDER(res_ctx << 515 kunit_log(KERN_INFO, current->kunit_te << 516 } << 517 static void kunit_resource_test_action_orderin << 518 { << 519 struct kunit_test_resource_context *ct << 520 << 521 kunit_add_action(test, action_order_1, << 522 kunit_add_action(test, action_order_2, << 523 kunit_add_action(test, action_order_1, << 524 kunit_add_action(test, action_order_2, << 525 kunit_remove_action(test, action_order << 526 kunit_release_action(test, action_orde << 527 kunit_cleanup(test); << 528 << 529 /* [2 is triggered] [2], [(1 is cancel << 530 KUNIT_EXPECT_EQ(test, ctx->free_order[ << 531 KUNIT_EXPECT_EQ(test, ctx->free_order[ << 532 KUNIT_EXPECT_EQ(test, ctx->free_order[ << 533 } << 534 << 535 static int kunit_resource_test_init(struct kun 364 static int kunit_resource_test_init(struct kunit *test) 536 { 365 { 537 struct kunit_test_resource_context *ct 366 struct kunit_test_resource_context *ctx = 538 kzalloc(sizeof(*ctx), 367 kzalloc(sizeof(*ctx), GFP_KERNEL); 539 368 540 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx 369 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); 541 370 542 test->priv = ctx; 371 test->priv = ctx; 543 372 544 kunit_init_test(&ctx->test, "test_test 373 kunit_init_test(&ctx->test, "test_test_context", NULL); 545 374 546 return 0; 375 return 0; 547 } 376 } 548 377 549 static void kunit_resource_test_exit(struct ku 378 static void kunit_resource_test_exit(struct kunit *test) 550 { 379 { 551 struct kunit_test_resource_context *ct 380 struct kunit_test_resource_context *ctx = test->priv; 552 381 553 kunit_cleanup(&ctx->test); 382 kunit_cleanup(&ctx->test); 554 kfree(ctx); 383 kfree(ctx); 555 } 384 } 556 385 557 static struct kunit_case kunit_resource_test_c 386 static struct kunit_case kunit_resource_test_cases[] = { 558 KUNIT_CASE(kunit_resource_test_init_re 387 KUNIT_CASE(kunit_resource_test_init_resources), 559 KUNIT_CASE(kunit_resource_test_alloc_r 388 KUNIT_CASE(kunit_resource_test_alloc_resource), 560 KUNIT_CASE(kunit_resource_test_destroy 389 KUNIT_CASE(kunit_resource_test_destroy_resource), 561 KUNIT_CASE(kunit_resource_test_remove_ << 562 KUNIT_CASE(kunit_resource_test_cleanup 390 KUNIT_CASE(kunit_resource_test_cleanup_resources), 563 KUNIT_CASE(kunit_resource_test_proper_ 391 KUNIT_CASE(kunit_resource_test_proper_free_ordering), 564 KUNIT_CASE(kunit_resource_test_static) 392 KUNIT_CASE(kunit_resource_test_static), 565 KUNIT_CASE(kunit_resource_test_named), 393 KUNIT_CASE(kunit_resource_test_named), 566 KUNIT_CASE(kunit_resource_test_action) << 567 KUNIT_CASE(kunit_resource_test_remove_ << 568 KUNIT_CASE(kunit_resource_test_release << 569 KUNIT_CASE(kunit_resource_test_action_ << 570 {} 394 {} 571 }; 395 }; 572 396 573 static struct kunit_suite kunit_resource_test_ 397 static struct kunit_suite kunit_resource_test_suite = { 574 .name = "kunit-resource-test", 398 .name = "kunit-resource-test", 575 .init = kunit_resource_test_init, 399 .init = kunit_resource_test_init, 576 .exit = kunit_resource_test_exit, 400 .exit = kunit_resource_test_exit, 577 .test_cases = kunit_resource_test_case 401 .test_cases = kunit_resource_test_cases, 578 }; 402 }; 579 403 580 /* !! 404 static void kunit_log_test(struct kunit *test); 581 * Log tests call string_stream functions, whi !! 405 582 * build this code if this test is built-in. !! 406 static struct kunit_case kunit_log_test_cases[] = { 583 */ !! 407 KUNIT_CASE(kunit_log_test), 584 #if IS_BUILTIN(CONFIG_KUNIT_TEST) !! 408 {} >> 409 }; 585 410 586 /* This avoids a cast warning if kfree() is pa !! 411 static struct kunit_suite kunit_log_test_suite = { 587 KUNIT_DEFINE_ACTION_WRAPPER(kfree_wrapper, kfr !! 412 .name = "kunit-log-test", >> 413 .test_cases = kunit_log_test_cases, >> 414 }; 588 415 589 static void kunit_log_test(struct kunit *test) 416 static void kunit_log_test(struct kunit *test) 590 { 417 { 591 struct kunit_suite suite; !! 418 struct kunit_suite *suite = &kunit_log_test_suite; 592 #ifdef CONFIG_KUNIT_DEBUGFS << 593 char *full_log; << 594 #endif << 595 suite.log = kunit_alloc_string_stream( << 596 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, sui << 597 string_stream_set_append_newlines(suit << 598 419 599 kunit_log(KERN_INFO, test, "put this i 420 kunit_log(KERN_INFO, test, "put this in log."); 600 kunit_log(KERN_INFO, test, "this too." 421 kunit_log(KERN_INFO, test, "this too."); 601 kunit_log(KERN_INFO, &suite, "add to s !! 422 kunit_log(KERN_INFO, suite, "add to suite log."); 602 kunit_log(KERN_INFO, &suite, "along wi !! 423 kunit_log(KERN_INFO, suite, "along with this."); 603 424 604 #ifdef CONFIG_KUNIT_DEBUGFS 425 #ifdef CONFIG_KUNIT_DEBUGFS 605 KUNIT_EXPECT_TRUE(test, test->log->app << 606 << 607 full_log = string_stream_get_string(te << 608 kunit_add_action(test, kfree_wrapper, << 609 KUNIT_EXPECT_NOT_ERR_OR_NULL(test, 426 KUNIT_EXPECT_NOT_ERR_OR_NULL(test, 610 strstr(fu !! 427 strstr(test->log, "put this in log.")); 611 KUNIT_EXPECT_NOT_ERR_OR_NULL(test, 428 KUNIT_EXPECT_NOT_ERR_OR_NULL(test, 612 strstr(fu !! 429 strstr(test->log, "this too.")); 613 << 614 full_log = string_stream_get_string(su << 615 kunit_add_action(test, kfree_wrapper, << 616 KUNIT_EXPECT_NOT_ERR_OR_NULL(test, 430 KUNIT_EXPECT_NOT_ERR_OR_NULL(test, 617 strstr(fu !! 431 strstr(suite->log, "add to suite log.")); 618 KUNIT_EXPECT_NOT_ERR_OR_NULL(test, 432 KUNIT_EXPECT_NOT_ERR_OR_NULL(test, 619 strstr(fu !! 433 strstr(suite->log, "along with this.")); 620 #else 434 #else 621 KUNIT_EXPECT_NULL(test, test->log); !! 435 KUNIT_EXPECT_PTR_EQ(test, test->log, (char *)NULL); >> 436 KUNIT_EXPECT_PTR_EQ(test, suite->log, (char *)NULL); 622 #endif 437 #endif 623 } 438 } 624 439 625 static void kunit_log_newline_test(struct kuni << 626 { << 627 char *full_log; << 628 << 629 kunit_info(test, "Add newline\n"); << 630 if (test->log) { << 631 full_log = string_stream_get_s << 632 kunit_add_action(test, kfree_w << 633 KUNIT_ASSERT_NOT_NULL_MSG(test << 634 "Missing log line, ful << 635 KUNIT_EXPECT_NULL(test, strstr << 636 } else { << 637 kunit_skip(test, "only useful << 638 } << 639 } << 640 #else << 641 static void kunit_log_test(struct kunit *test) << 642 { << 643 kunit_skip(test, "Log tests only run w << 644 } << 645 << 646 static void kunit_log_newline_test(struct kuni << 647 { << 648 kunit_skip(test, "Log tests only run w << 649 } << 650 #endif /* IS_BUILTIN(CONFIG_KUNIT_TEST) */ << 651 << 652 static struct kunit_case kunit_log_test_cases[ << 653 KUNIT_CASE(kunit_log_test), << 654 KUNIT_CASE(kunit_log_newline_test), << 655 {} << 656 }; << 657 << 658 static struct kunit_suite kunit_log_test_suite << 659 .name = "kunit-log-test", << 660 .test_cases = kunit_log_test_cases, << 661 }; << 662 << 663 static void kunit_status_set_failure_test(stru << 664 { << 665 struct kunit fake; << 666 << 667 kunit_init_test(&fake, "fake test", NU << 668 << 669 KUNIT_EXPECT_EQ(test, fake.status, (en << 670 kunit_set_failure(&fake); << 671 KUNIT_EXPECT_EQ(test, fake.status, (en << 672 } << 673 << 674 static void kunit_status_mark_skipped_test(str << 675 { << 676 struct kunit fake; << 677 << 678 kunit_init_test(&fake, "fake test", NU << 679 << 680 /* Before: Should be SUCCESS with no c << 681 KUNIT_EXPECT_EQ(test, fake.status, KUN << 682 KUNIT_EXPECT_STREQ(test, fake.status_c << 683 << 684 /* Mark the test as skipped. */ << 685 kunit_mark_skipped(&fake, "Accepts for << 686 << 687 /* After: Should be SKIPPED with our c << 688 KUNIT_EXPECT_EQ(test, fake.status, (en << 689 KUNIT_EXPECT_STREQ(test, fake.status_c << 690 } << 691 << 692 static struct kunit_case kunit_status_test_cas << 693 KUNIT_CASE(kunit_status_set_failure_te << 694 KUNIT_CASE(kunit_status_mark_skipped_t << 695 {} << 696 }; << 697 << 698 static struct kunit_suite kunit_status_test_su << 699 .name = "kunit_status", << 700 .test_cases = kunit_status_test_cases, << 701 }; << 702 << 703 static void kunit_current_test(struct kunit *t << 704 { << 705 /* Check results of both current->kuni << 706 * kunit_get_current_test() are equiva << 707 */ << 708 KUNIT_EXPECT_PTR_EQ(test, test, curren << 709 KUNIT_EXPECT_PTR_EQ(test, test, kunit_ << 710 } << 711 << 712 static void kunit_current_fail_test(struct kun << 713 { << 714 struct kunit fake; << 715 << 716 kunit_init_test(&fake, "fake test", NU << 717 KUNIT_EXPECT_EQ(test, fake.status, KUN << 718 << 719 /* Set current->kunit_test to fake tes << 720 current->kunit_test = &fake; << 721 << 722 kunit_fail_current_test("This should m << 723 KUNIT_EXPECT_EQ(test, fake.status, (en << 724 kunit_cleanup(&fake); << 725 << 726 /* Reset current->kunit_test to curren << 727 current->kunit_test = test; << 728 } << 729 << 730 static struct kunit_case kunit_current_test_ca << 731 KUNIT_CASE(kunit_current_test), << 732 KUNIT_CASE(kunit_current_fail_test), << 733 {} << 734 }; << 735 << 736 static void test_dev_action(void *priv) << 737 { << 738 *(void **)priv = (void *)1; << 739 } << 740 << 741 static void kunit_device_test(struct kunit *te << 742 { << 743 struct device *test_device; << 744 long action_was_run = 0; << 745 << 746 test_device = kunit_device_register(te << 747 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, tes << 748 << 749 // Add an action to verify cleanup. << 750 devm_add_action(test_device, test_dev_ << 751 << 752 KUNIT_EXPECT_EQ(test, action_was_run, << 753 << 754 kunit_device_unregister(test, test_dev << 755 << 756 KUNIT_EXPECT_EQ(test, action_was_run, << 757 } << 758 << 759 static void kunit_device_cleanup_test(struct k << 760 { << 761 struct device *test_device; << 762 long action_was_run = 0; << 763 << 764 test_device = kunit_device_register(te << 765 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, tes << 766 << 767 /* Add an action to verify cleanup. */ << 768 devm_add_action(test_device, test_dev_ << 769 << 770 KUNIT_EXPECT_EQ(test, action_was_run, << 771 << 772 /* Force KUnit to run cleanup early. * << 773 kunit_cleanup(test); << 774 << 775 KUNIT_EXPECT_EQ(test, action_was_run, << 776 } << 777 << 778 struct driver_test_state { << 779 bool driver_device_probed; << 780 bool driver_device_removed; << 781 long action_was_run; << 782 }; << 783 << 784 static int driver_probe_hook(struct device *de << 785 { << 786 struct kunit *test = kunit_get_current << 787 struct driver_test_state *state = (str << 788 << 789 state->driver_device_probed = true; << 790 return 0; << 791 } << 792 << 793 static int driver_remove_hook(struct device *d << 794 { << 795 struct kunit *test = kunit_get_current << 796 struct driver_test_state *state = (str << 797 << 798 state->driver_device_removed = true; << 799 return 0; << 800 } << 801 << 802 static void kunit_device_driver_test(struct ku << 803 { << 804 struct device_driver *test_driver; << 805 struct device *test_device; << 806 struct driver_test_state *test_state = << 807 << 808 test->priv = test_state; << 809 test_driver = kunit_driver_create(test << 810 << 811 // This can fail with an error pointer << 812 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, tes << 813 << 814 test_driver->probe = driver_probe_hook << 815 test_driver->remove = driver_remove_ho << 816 << 817 test_device = kunit_device_register_wi << 818 << 819 // This can fail with an error pointer << 820 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, tes << 821 << 822 // Make sure the probe function was ca << 823 KUNIT_ASSERT_TRUE(test, test_state->dr << 824 << 825 // Add an action to verify cleanup. << 826 devm_add_action(test_device, test_dev_ << 827 << 828 KUNIT_EXPECT_EQ(test, test_state->acti << 829 << 830 kunit_device_unregister(test, test_dev << 831 test_device = NULL; << 832 << 833 // Make sure the remove hook was calle << 834 KUNIT_ASSERT_TRUE(test, test_state->dr << 835 << 836 // We're going to test this again. << 837 test_state->driver_device_probed = fal << 838 << 839 // The driver should not automatically << 840 // kunit_device_unregister, so we can << 841 test_device = kunit_device_register_wi << 842 << 843 // This can fail with an error pointer << 844 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, tes << 845 << 846 // Probe was called again. << 847 KUNIT_ASSERT_TRUE(test, test_state->dr << 848 << 849 // Everything is automatically freed h << 850 } << 851 << 852 static struct kunit_case kunit_device_test_cas << 853 KUNIT_CASE(kunit_device_test), << 854 KUNIT_CASE(kunit_device_cleanup_test), << 855 KUNIT_CASE(kunit_device_driver_test), << 856 {} << 857 }; << 858 << 859 static struct kunit_suite kunit_device_test_su << 860 .name = "kunit_device", << 861 .test_cases = kunit_device_test_cases, << 862 }; << 863 << 864 static struct kunit_suite kunit_current_test_s << 865 .name = "kunit_current", << 866 .test_cases = kunit_current_test_cases << 867 }; << 868 << 869 kunit_test_suites(&kunit_try_catch_test_suite, 440 kunit_test_suites(&kunit_try_catch_test_suite, &kunit_resource_test_suite, 870 &kunit_log_test_suite, &kuni !! 441 &kunit_log_test_suite); 871 &kunit_current_test_suite, & << 872 &kunit_fault_test_suite); << 873 442 874 MODULE_DESCRIPTION("KUnit test for core test i << 875 MODULE_LICENSE("GPL v2"); 443 MODULE_LICENSE("GPL v2"); 876 444
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.