Loading...
1// SPDX-License-Identifier: GPL-2.0-only
2#define pr_fmt(fmt) "min_heap_test: " fmt
3
4/*
5 * Test cases for the min max heap.
6 */
7
8#include <linux/log2.h>
9#include <linux/min_heap.h>
10#include <linux/module.h>
11#include <linux/printk.h>
12#include <linux/random.h>
13
14static __init bool less_than(const void *lhs, const void *rhs)
15{
16 return *(int *)lhs < *(int *)rhs;
17}
18
19static __init bool greater_than(const void *lhs, const void *rhs)
20{
21 return *(int *)lhs > *(int *)rhs;
22}
23
24static __init void swap_ints(void *lhs, void *rhs)
25{
26 int temp = *(int *)lhs;
27
28 *(int *)lhs = *(int *)rhs;
29 *(int *)rhs = temp;
30}
31
32static __init int pop_verify_heap(bool min_heap,
33 struct min_heap *heap,
34 const struct min_heap_callbacks *funcs)
35{
36 int *values = heap->data;
37 int err = 0;
38 int last;
39
40 last = values[0];
41 min_heap_pop(heap, funcs);
42 while (heap->nr > 0) {
43 if (min_heap) {
44 if (last > values[0]) {
45 pr_err("error: expected %d <= %d\n", last,
46 values[0]);
47 err++;
48 }
49 } else {
50 if (last < values[0]) {
51 pr_err("error: expected %d >= %d\n", last,
52 values[0]);
53 err++;
54 }
55 }
56 last = values[0];
57 min_heap_pop(heap, funcs);
58 }
59 return err;
60}
61
62static __init int test_heapify_all(bool min_heap)
63{
64 int values[] = { 3, 1, 2, 4, 0x8000000, 0x7FFFFFF, 0,
65 -3, -1, -2, -4, 0x8000000, 0x7FFFFFF };
66 struct min_heap heap = {
67 .data = values,
68 .nr = ARRAY_SIZE(values),
69 .size = ARRAY_SIZE(values),
70 };
71 struct min_heap_callbacks funcs = {
72 .elem_size = sizeof(int),
73 .less = min_heap ? less_than : greater_than,
74 .swp = swap_ints,
75 };
76 int i, err;
77
78 /* Test with known set of values. */
79 min_heapify_all(&heap, &funcs);
80 err = pop_verify_heap(min_heap, &heap, &funcs);
81
82
83 /* Test with randomly generated values. */
84 heap.nr = ARRAY_SIZE(values);
85 for (i = 0; i < heap.nr; i++)
86 values[i] = get_random_int();
87
88 min_heapify_all(&heap, &funcs);
89 err += pop_verify_heap(min_heap, &heap, &funcs);
90
91 return err;
92}
93
94static __init int test_heap_push(bool min_heap)
95{
96 const int data[] = { 3, 1, 2, 4, 0x80000000, 0x7FFFFFFF, 0,
97 -3, -1, -2, -4, 0x80000000, 0x7FFFFFFF };
98 int values[ARRAY_SIZE(data)];
99 struct min_heap heap = {
100 .data = values,
101 .nr = 0,
102 .size = ARRAY_SIZE(values),
103 };
104 struct min_heap_callbacks funcs = {
105 .elem_size = sizeof(int),
106 .less = min_heap ? less_than : greater_than,
107 .swp = swap_ints,
108 };
109 int i, temp, err;
110
111 /* Test with known set of values copied from data. */
112 for (i = 0; i < ARRAY_SIZE(data); i++)
113 min_heap_push(&heap, &data[i], &funcs);
114
115 err = pop_verify_heap(min_heap, &heap, &funcs);
116
117 /* Test with randomly generated values. */
118 while (heap.nr < heap.size) {
119 temp = get_random_int();
120 min_heap_push(&heap, &temp, &funcs);
121 }
122 err += pop_verify_heap(min_heap, &heap, &funcs);
123
124 return err;
125}
126
127static __init int test_heap_pop_push(bool min_heap)
128{
129 const int data[] = { 3, 1, 2, 4, 0x80000000, 0x7FFFFFFF, 0,
130 -3, -1, -2, -4, 0x80000000, 0x7FFFFFFF };
131 int values[ARRAY_SIZE(data)];
132 struct min_heap heap = {
133 .data = values,
134 .nr = 0,
135 .size = ARRAY_SIZE(values),
136 };
137 struct min_heap_callbacks funcs = {
138 .elem_size = sizeof(int),
139 .less = min_heap ? less_than : greater_than,
140 .swp = swap_ints,
141 };
142 int i, temp, err;
143
144 /* Fill values with data to pop and replace. */
145 temp = min_heap ? 0x80000000 : 0x7FFFFFFF;
146 for (i = 0; i < ARRAY_SIZE(data); i++)
147 min_heap_push(&heap, &temp, &funcs);
148
149 /* Test with known set of values copied from data. */
150 for (i = 0; i < ARRAY_SIZE(data); i++)
151 min_heap_pop_push(&heap, &data[i], &funcs);
152
153 err = pop_verify_heap(min_heap, &heap, &funcs);
154
155 heap.nr = 0;
156 for (i = 0; i < ARRAY_SIZE(data); i++)
157 min_heap_push(&heap, &temp, &funcs);
158
159 /* Test with randomly generated values. */
160 for (i = 0; i < ARRAY_SIZE(data); i++) {
161 temp = get_random_int();
162 min_heap_pop_push(&heap, &temp, &funcs);
163 }
164 err += pop_verify_heap(min_heap, &heap, &funcs);
165
166 return err;
167}
168
169static int __init test_min_heap_init(void)
170{
171 int err = 0;
172
173 err += test_heapify_all(true);
174 err += test_heapify_all(false);
175 err += test_heap_push(true);
176 err += test_heap_push(false);
177 err += test_heap_pop_push(true);
178 err += test_heap_pop_push(false);
179 if (err) {
180 pr_err("test failed with %d errors\n", err);
181 return -EINVAL;
182 }
183 pr_info("test passed\n");
184 return 0;
185}
186module_init(test_min_heap_init);
187
188static void __exit test_min_heap_exit(void)
189{
190 /* do nothing */
191}
192module_exit(test_min_heap_exit);
193
194MODULE_LICENSE("GPL");
1// SPDX-License-Identifier: GPL-2.0-only
2#define pr_fmt(fmt) "min_heap_test: " fmt
3
4/*
5 * Test cases for the min max heap.
6 */
7
8#include <linux/log2.h>
9#include <linux/min_heap.h>
10#include <linux/module.h>
11#include <linux/printk.h>
12#include <linux/random.h>
13
14DEFINE_MIN_HEAP(int, min_heap_test);
15
16static __init bool less_than(const void *lhs, const void *rhs, void __always_unused *args)
17{
18 return *(int *)lhs < *(int *)rhs;
19}
20
21static __init bool greater_than(const void *lhs, const void *rhs, void __always_unused *args)
22{
23 return *(int *)lhs > *(int *)rhs;
24}
25
26static __init int pop_verify_heap(bool min_heap,
27 struct min_heap_test *heap,
28 const struct min_heap_callbacks *funcs)
29{
30 int *values = heap->data;
31 int err = 0;
32 int last;
33
34 last = values[0];
35 min_heap_pop(heap, funcs, NULL);
36 while (heap->nr > 0) {
37 if (min_heap) {
38 if (last > values[0]) {
39 pr_err("error: expected %d <= %d\n", last,
40 values[0]);
41 err++;
42 }
43 } else {
44 if (last < values[0]) {
45 pr_err("error: expected %d >= %d\n", last,
46 values[0]);
47 err++;
48 }
49 }
50 last = values[0];
51 min_heap_pop(heap, funcs, NULL);
52 }
53 return err;
54}
55
56static __init int test_heapify_all(bool min_heap)
57{
58 int values[] = { 3, 1, 2, 4, 0x8000000, 0x7FFFFFF, 0,
59 -3, -1, -2, -4, 0x8000000, 0x7FFFFFF };
60 struct min_heap_test heap = {
61 .data = values,
62 .nr = ARRAY_SIZE(values),
63 .size = ARRAY_SIZE(values),
64 };
65 struct min_heap_callbacks funcs = {
66 .less = min_heap ? less_than : greater_than,
67 .swp = NULL,
68 };
69 int i, err;
70
71 /* Test with known set of values. */
72 min_heapify_all(&heap, &funcs, NULL);
73 err = pop_verify_heap(min_heap, &heap, &funcs);
74
75
76 /* Test with randomly generated values. */
77 heap.nr = ARRAY_SIZE(values);
78 for (i = 0; i < heap.nr; i++)
79 values[i] = get_random_u32();
80
81 min_heapify_all(&heap, &funcs, NULL);
82 err += pop_verify_heap(min_heap, &heap, &funcs);
83
84 return err;
85}
86
87static __init int test_heap_push(bool min_heap)
88{
89 const int data[] = { 3, 1, 2, 4, 0x80000000, 0x7FFFFFFF, 0,
90 -3, -1, -2, -4, 0x80000000, 0x7FFFFFFF };
91 int values[ARRAY_SIZE(data)];
92 struct min_heap_test heap = {
93 .data = values,
94 .nr = 0,
95 .size = ARRAY_SIZE(values),
96 };
97 struct min_heap_callbacks funcs = {
98 .less = min_heap ? less_than : greater_than,
99 .swp = NULL,
100 };
101 int i, temp, err;
102
103 /* Test with known set of values copied from data. */
104 for (i = 0; i < ARRAY_SIZE(data); i++)
105 min_heap_push(&heap, &data[i], &funcs, NULL);
106
107 err = pop_verify_heap(min_heap, &heap, &funcs);
108
109 /* Test with randomly generated values. */
110 while (heap.nr < heap.size) {
111 temp = get_random_u32();
112 min_heap_push(&heap, &temp, &funcs, NULL);
113 }
114 err += pop_verify_heap(min_heap, &heap, &funcs);
115
116 return err;
117}
118
119static __init int test_heap_pop_push(bool min_heap)
120{
121 const int data[] = { 3, 1, 2, 4, 0x80000000, 0x7FFFFFFF, 0,
122 -3, -1, -2, -4, 0x80000000, 0x7FFFFFFF };
123 int values[ARRAY_SIZE(data)];
124 struct min_heap_test heap = {
125 .data = values,
126 .nr = 0,
127 .size = ARRAY_SIZE(values),
128 };
129 struct min_heap_callbacks funcs = {
130 .less = min_heap ? less_than : greater_than,
131 .swp = NULL,
132 };
133 int i, temp, err;
134
135 /* Fill values with data to pop and replace. */
136 temp = min_heap ? 0x80000000 : 0x7FFFFFFF;
137 for (i = 0; i < ARRAY_SIZE(data); i++)
138 min_heap_push(&heap, &temp, &funcs, NULL);
139
140 /* Test with known set of values copied from data. */
141 for (i = 0; i < ARRAY_SIZE(data); i++)
142 min_heap_pop_push(&heap, &data[i], &funcs, NULL);
143
144 err = pop_verify_heap(min_heap, &heap, &funcs);
145
146 heap.nr = 0;
147 for (i = 0; i < ARRAY_SIZE(data); i++)
148 min_heap_push(&heap, &temp, &funcs, NULL);
149
150 /* Test with randomly generated values. */
151 for (i = 0; i < ARRAY_SIZE(data); i++) {
152 temp = get_random_u32();
153 min_heap_pop_push(&heap, &temp, &funcs, NULL);
154 }
155 err += pop_verify_heap(min_heap, &heap, &funcs);
156
157 return err;
158}
159
160static __init int test_heap_del(bool min_heap)
161{
162 int values[] = { 3, 1, 2, 4, 0x8000000, 0x7FFFFFF, 0,
163 -3, -1, -2, -4, 0x8000000, 0x7FFFFFF };
164 struct min_heap_test heap;
165
166 min_heap_init(&heap, values, ARRAY_SIZE(values));
167 heap.nr = ARRAY_SIZE(values);
168 struct min_heap_callbacks funcs = {
169 .less = min_heap ? less_than : greater_than,
170 .swp = NULL,
171 };
172 int i, err;
173
174 /* Test with known set of values. */
175 min_heapify_all(&heap, &funcs, NULL);
176 for (i = 0; i < ARRAY_SIZE(values) / 2; i++)
177 min_heap_del(&heap, get_random_u32() % heap.nr, &funcs, NULL);
178 err = pop_verify_heap(min_heap, &heap, &funcs);
179
180
181 /* Test with randomly generated values. */
182 heap.nr = ARRAY_SIZE(values);
183 for (i = 0; i < heap.nr; i++)
184 values[i] = get_random_u32();
185 min_heapify_all(&heap, &funcs, NULL);
186
187 for (i = 0; i < ARRAY_SIZE(values) / 2; i++)
188 min_heap_del(&heap, get_random_u32() % heap.nr, &funcs, NULL);
189 err += pop_verify_heap(min_heap, &heap, &funcs);
190
191 return err;
192}
193
194static int __init test_min_heap_init(void)
195{
196 int err = 0;
197
198 err += test_heapify_all(true);
199 err += test_heapify_all(false);
200 err += test_heap_push(true);
201 err += test_heap_push(false);
202 err += test_heap_pop_push(true);
203 err += test_heap_pop_push(false);
204 err += test_heap_del(true);
205 err += test_heap_del(false);
206 if (err) {
207 pr_err("test failed with %d errors\n", err);
208 return -EINVAL;
209 }
210 pr_info("test passed\n");
211 return 0;
212}
213module_init(test_min_heap_init);
214
215static void __exit test_min_heap_exit(void)
216{
217 /* do nothing */
218}
219module_exit(test_min_heap_exit);
220
221MODULE_DESCRIPTION("Test cases for the min max heap");
222MODULE_LICENSE("GPL");