18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Test cases for memcat_p() in lib/memcat_p.c 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#include <linux/string.h> 88c2ecf20Sopenharmony_ci#include <linux/slab.h> 98c2ecf20Sopenharmony_ci#include <linux/module.h> 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_cistruct test_struct { 128c2ecf20Sopenharmony_ci int num; 138c2ecf20Sopenharmony_ci unsigned int magic; 148c2ecf20Sopenharmony_ci}; 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci#define MAGIC 0xf00ff00f 178c2ecf20Sopenharmony_ci/* Size of each of the NULL-terminated input arrays */ 188c2ecf20Sopenharmony_ci#define INPUT_MAX 128 198c2ecf20Sopenharmony_ci/* Expected number of non-NULL elements in the output array */ 208c2ecf20Sopenharmony_ci#define EXPECT (INPUT_MAX * 2 - 2) 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_cistatic int __init test_memcat_p_init(void) 238c2ecf20Sopenharmony_ci{ 248c2ecf20Sopenharmony_ci struct test_struct **in0, **in1, **out, **p; 258c2ecf20Sopenharmony_ci int err = -ENOMEM, i, r, total = 0; 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci in0 = kcalloc(INPUT_MAX, sizeof(*in0), GFP_KERNEL); 288c2ecf20Sopenharmony_ci if (!in0) 298c2ecf20Sopenharmony_ci return err; 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci in1 = kcalloc(INPUT_MAX, sizeof(*in1), GFP_KERNEL); 328c2ecf20Sopenharmony_ci if (!in1) 338c2ecf20Sopenharmony_ci goto err_free_in0; 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci for (i = 0, r = 1; i < INPUT_MAX - 1; i++) { 368c2ecf20Sopenharmony_ci in0[i] = kmalloc(sizeof(**in0), GFP_KERNEL); 378c2ecf20Sopenharmony_ci if (!in0[i]) 388c2ecf20Sopenharmony_ci goto err_free_elements; 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci in1[i] = kmalloc(sizeof(**in1), GFP_KERNEL); 418c2ecf20Sopenharmony_ci if (!in1[i]) { 428c2ecf20Sopenharmony_ci kfree(in0[i]); 438c2ecf20Sopenharmony_ci goto err_free_elements; 448c2ecf20Sopenharmony_ci } 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci /* lifted from test_sort.c */ 478c2ecf20Sopenharmony_ci r = (r * 725861) % 6599; 488c2ecf20Sopenharmony_ci in0[i]->num = r; 498c2ecf20Sopenharmony_ci in1[i]->num = -r; 508c2ecf20Sopenharmony_ci in0[i]->magic = MAGIC; 518c2ecf20Sopenharmony_ci in1[i]->magic = MAGIC; 528c2ecf20Sopenharmony_ci } 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci in0[i] = in1[i] = NULL; 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci out = memcat_p(in0, in1); 578c2ecf20Sopenharmony_ci if (!out) 588c2ecf20Sopenharmony_ci goto err_free_all_elements; 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci err = -EINVAL; 618c2ecf20Sopenharmony_ci for (i = 0, p = out; *p && (i < INPUT_MAX * 2 - 1); p++, i++) { 628c2ecf20Sopenharmony_ci total += (*p)->num; 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci if ((*p)->magic != MAGIC) { 658c2ecf20Sopenharmony_ci pr_err("test failed: wrong magic at %d: %u\n", i, 668c2ecf20Sopenharmony_ci (*p)->magic); 678c2ecf20Sopenharmony_ci goto err_free_out; 688c2ecf20Sopenharmony_ci } 698c2ecf20Sopenharmony_ci } 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci if (total) { 728c2ecf20Sopenharmony_ci pr_err("test failed: expected zero total, got %d\n", total); 738c2ecf20Sopenharmony_ci goto err_free_out; 748c2ecf20Sopenharmony_ci } 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci if (i != EXPECT) { 778c2ecf20Sopenharmony_ci pr_err("test failed: expected output size %d, got %d\n", 788c2ecf20Sopenharmony_ci EXPECT, i); 798c2ecf20Sopenharmony_ci goto err_free_out; 808c2ecf20Sopenharmony_ci } 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci for (i = 0; i < INPUT_MAX - 1; i++) 838c2ecf20Sopenharmony_ci if (out[i] != in0[i] || out[i + INPUT_MAX - 1] != in1[i]) { 848c2ecf20Sopenharmony_ci pr_err("test failed: wrong element order at %d\n", i); 858c2ecf20Sopenharmony_ci goto err_free_out; 868c2ecf20Sopenharmony_ci } 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci err = 0; 898c2ecf20Sopenharmony_ci pr_info("test passed\n"); 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_cierr_free_out: 928c2ecf20Sopenharmony_ci kfree(out); 938c2ecf20Sopenharmony_cierr_free_all_elements: 948c2ecf20Sopenharmony_ci i = INPUT_MAX; 958c2ecf20Sopenharmony_cierr_free_elements: 968c2ecf20Sopenharmony_ci for (i--; i >= 0; i--) { 978c2ecf20Sopenharmony_ci kfree(in1[i]); 988c2ecf20Sopenharmony_ci kfree(in0[i]); 998c2ecf20Sopenharmony_ci } 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci kfree(in1); 1028c2ecf20Sopenharmony_cierr_free_in0: 1038c2ecf20Sopenharmony_ci kfree(in0); 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci return err; 1068c2ecf20Sopenharmony_ci} 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_cistatic void __exit test_memcat_p_exit(void) 1098c2ecf20Sopenharmony_ci{ 1108c2ecf20Sopenharmony_ci} 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_cimodule_init(test_memcat_p_init); 1138c2ecf20Sopenharmony_cimodule_exit(test_memcat_p_exit); 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 116