]>
Commit | Line | Data |
---|---|---|
33d599f0 MV |
1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* | |
3 | * KUnit test for the linear_ranges helper. | |
4 | * | |
5 | * Copyright (C) 2020, ROHM Semiconductors. | |
6 | * Author: Matti Vaittinen <[email protected]> | |
7 | */ | |
8 | #include <kunit/test.h> | |
9 | ||
10 | #include <linux/linear_range.h> | |
11 | ||
12 | /* First things first. I deeply dislike unit-tests. I have seen all the hell | |
13 | * breaking loose when people who think the unit tests are "the silver bullet" | |
14 | * to kill bugs get to decide how a company should implement testing strategy... | |
15 | * | |
16 | * Believe me, it may get _really_ ridiculous. It is tempting to think that | |
17 | * walking through all the possible execution branches will nail down 100% of | |
18 | * bugs. This may lead to ideas about demands to get certain % of "test | |
19 | * coverage" - measured as line coverage. And that is one of the worst things | |
20 | * you can do. | |
21 | * | |
22 | * Ask people to provide line coverage and they do. I've seen clever tools | |
23 | * which generate test cases to test the existing functions - and by default | |
24 | * these tools expect code to be correct and just generate checks which are | |
25 | * passing when ran against current code-base. Run this generator and you'll get | |
26 | * tests that do not test code is correct but just verify nothing changes. | |
27 | * Problem is that testing working code is pointless. And if it is not | |
28 | * working, your test must not assume it is working. You won't catch any bugs | |
29 | * by such tests. What you can do is to generate a huge amount of tests. | |
30 | * Especially if you were are asked to proivde 100% line-coverage x_x. So what | |
31 | * does these tests - which are not finding any bugs now - do? | |
32 | * | |
33 | * They add inertia to every future development. I think it was Terry Pratchet | |
34 | * who wrote someone having same impact as thick syrup has to chronometre. | |
35 | * Excessive amount of unit-tests have this effect to development. If you do | |
36 | * actually find _any_ bug from code in such environment and try fixing it... | |
37 | * ...chances are you also need to fix the test cases. In sunny day you fix one | |
38 | * test. But I've done refactoring which resulted 500+ broken tests (which had | |
39 | * really zero value other than proving to managers that we do do "quality")... | |
40 | * | |
41 | * After this being said - there are situations where UTs can be handy. If you | |
42 | * have algorithms which take some input and should produce output - then you | |
43 | * can implement few, carefully selected simple UT-cases which test this. I've | |
44 | * previously used this for example for netlink and device-tree data parsing | |
45 | * functions. Feed some data examples to functions and verify the output is as | |
46 | * expected. I am not covering all the cases but I will see the logic should be | |
47 | * working. | |
48 | * | |
49 | * Here we also do some minor testing. I don't want to go through all branches | |
50 | * or test more or less obvious things - but I want to see the main logic is | |
51 | * working. And I definitely don't want to add 500+ test cases that break when | |
52 | * some simple fix is done x_x. So - let's only add few, well selected tests | |
53 | * which ensure as much logic is good as possible. | |
54 | */ | |
55 | ||
56 | /* | |
57 | * Test Range 1: | |
58 | * selectors: 2 3 4 5 6 | |
59 | * values (5): 10 20 30 40 50 | |
60 | * | |
61 | * Test Range 2: | |
62 | * selectors: 7 8 9 10 | |
63 | * values (4): 100 150 200 250 | |
64 | */ | |
65 | ||
66 | #define RANGE1_MIN 10 | |
67 | #define RANGE1_MIN_SEL 2 | |
68 | #define RANGE1_STEP 10 | |
69 | ||
70 | /* 2, 3, 4, 5, 6 */ | |
71 | static const unsigned int range1_sels[] = { RANGE1_MIN_SEL, RANGE1_MIN_SEL + 1, | |
72 | RANGE1_MIN_SEL + 2, | |
73 | RANGE1_MIN_SEL + 3, | |
74 | RANGE1_MIN_SEL + 4 }; | |
75 | /* 10, 20, 30, 40, 50 */ | |
76 | static const unsigned int range1_vals[] = { RANGE1_MIN, RANGE1_MIN + | |
77 | RANGE1_STEP, | |
78 | RANGE1_MIN + RANGE1_STEP * 2, | |
79 | RANGE1_MIN + RANGE1_STEP * 3, | |
80 | RANGE1_MIN + RANGE1_STEP * 4 }; | |
81 | ||
82 | #define RANGE2_MIN 100 | |
83 | #define RANGE2_MIN_SEL 7 | |
84 | #define RANGE2_STEP 50 | |
85 | ||
86 | /* 7, 8, 9, 10 */ | |
87 | static const unsigned int range2_sels[] = { RANGE2_MIN_SEL, RANGE2_MIN_SEL + 1, | |
88 | RANGE2_MIN_SEL + 2, | |
89 | RANGE2_MIN_SEL + 3 }; | |
90 | /* 100, 150, 200, 250 */ | |
91 | static const unsigned int range2_vals[] = { RANGE2_MIN, RANGE2_MIN + | |
92 | RANGE2_STEP, | |
93 | RANGE2_MIN + RANGE2_STEP * 2, | |
94 | RANGE2_MIN + RANGE2_STEP * 3 }; | |
95 | ||
96 | #define RANGE1_NUM_VALS (ARRAY_SIZE(range1_vals)) | |
97 | #define RANGE2_NUM_VALS (ARRAY_SIZE(range2_vals)) | |
98 | #define RANGE_NUM_VALS (RANGE1_NUM_VALS + RANGE2_NUM_VALS) | |
99 | ||
100 | #define RANGE1_MAX_SEL (RANGE1_MIN_SEL + RANGE1_NUM_VALS - 1) | |
101 | #define RANGE1_MAX_VAL (range1_vals[RANGE1_NUM_VALS - 1]) | |
102 | ||
103 | #define RANGE2_MAX_SEL (RANGE2_MIN_SEL + RANGE2_NUM_VALS - 1) | |
104 | #define RANGE2_MAX_VAL (range2_vals[RANGE2_NUM_VALS - 1]) | |
105 | ||
106 | #define SMALLEST_SEL RANGE1_MIN_SEL | |
107 | #define SMALLEST_VAL RANGE1_MIN | |
108 | ||
109 | static struct linear_range testr[] = { | |
bc64f30e MV |
110 | LINEAR_RANGE(RANGE1_MIN, RANGE1_MIN_SEL, RANGE1_MAX_SEL, RANGE1_STEP), |
111 | LINEAR_RANGE(RANGE2_MIN, RANGE2_MIN_SEL, RANGE2_MAX_SEL, RANGE2_STEP), | |
33d599f0 MV |
112 | }; |
113 | ||
114 | static void range_test_get_value(struct kunit *test) | |
115 | { | |
116 | int ret, i; | |
117 | unsigned int sel, val; | |
118 | ||
119 | for (i = 0; i < RANGE1_NUM_VALS; i++) { | |
120 | sel = range1_sels[i]; | |
121 | ret = linear_range_get_value_array(&testr[0], 2, sel, &val); | |
122 | KUNIT_EXPECT_EQ(test, 0, ret); | |
123 | KUNIT_EXPECT_EQ(test, val, range1_vals[i]); | |
124 | } | |
125 | for (i = 0; i < RANGE2_NUM_VALS; i++) { | |
126 | sel = range2_sels[i]; | |
127 | ret = linear_range_get_value_array(&testr[0], 2, sel, &val); | |
128 | KUNIT_EXPECT_EQ(test, 0, ret); | |
129 | KUNIT_EXPECT_EQ(test, val, range2_vals[i]); | |
130 | } | |
131 | ret = linear_range_get_value_array(&testr[0], 2, sel + 1, &val); | |
132 | KUNIT_EXPECT_NE(test, 0, ret); | |
133 | } | |
134 | ||
135 | static void range_test_get_selector_high(struct kunit *test) | |
136 | { | |
137 | int ret, i; | |
138 | unsigned int sel; | |
139 | bool found; | |
140 | ||
141 | for (i = 0; i < RANGE1_NUM_VALS; i++) { | |
142 | ret = linear_range_get_selector_high(&testr[0], range1_vals[i], | |
143 | &sel, &found); | |
144 | KUNIT_EXPECT_EQ(test, 0, ret); | |
145 | KUNIT_EXPECT_EQ(test, sel, range1_sels[i]); | |
146 | KUNIT_EXPECT_TRUE(test, found); | |
147 | } | |
148 | ||
149 | ret = linear_range_get_selector_high(&testr[0], RANGE1_MAX_VAL + 1, | |
150 | &sel, &found); | |
151 | KUNIT_EXPECT_LE(test, ret, 0); | |
152 | ||
153 | ret = linear_range_get_selector_high(&testr[0], RANGE1_MIN - 1, | |
154 | &sel, &found); | |
155 | KUNIT_EXPECT_EQ(test, 0, ret); | |
156 | KUNIT_EXPECT_FALSE(test, found); | |
157 | KUNIT_EXPECT_EQ(test, sel, range1_sels[0]); | |
158 | } | |
159 | ||
160 | static void range_test_get_value_amount(struct kunit *test) | |
161 | { | |
162 | int ret; | |
163 | ||
164 | ret = linear_range_values_in_range_array(&testr[0], 2); | |
165 | KUNIT_EXPECT_EQ(test, (int)RANGE_NUM_VALS, ret); | |
166 | } | |
167 | ||
168 | static void range_test_get_selector_low(struct kunit *test) | |
169 | { | |
170 | int i, ret; | |
171 | unsigned int sel; | |
172 | bool found; | |
173 | ||
174 | for (i = 0; i < RANGE1_NUM_VALS; i++) { | |
175 | ret = linear_range_get_selector_low_array(&testr[0], 2, | |
176 | range1_vals[i], &sel, | |
177 | &found); | |
178 | KUNIT_EXPECT_EQ(test, 0, ret); | |
179 | KUNIT_EXPECT_EQ(test, sel, range1_sels[i]); | |
180 | KUNIT_EXPECT_TRUE(test, found); | |
181 | } | |
182 | for (i = 0; i < RANGE2_NUM_VALS; i++) { | |
183 | ret = linear_range_get_selector_low_array(&testr[0], 2, | |
184 | range2_vals[i], &sel, | |
185 | &found); | |
186 | KUNIT_EXPECT_EQ(test, 0, ret); | |
187 | KUNIT_EXPECT_EQ(test, sel, range2_sels[i]); | |
188 | KUNIT_EXPECT_TRUE(test, found); | |
189 | } | |
190 | ||
191 | /* | |
192 | * Seek value greater than range max => get_selector_*_low should | |
193 | * return Ok - but set found to false as value is not in range | |
194 | */ | |
195 | ret = linear_range_get_selector_low_array(&testr[0], 2, | |
196 | range2_vals[RANGE2_NUM_VALS - 1] + 1, | |
197 | &sel, &found); | |
198 | ||
199 | KUNIT_EXPECT_EQ(test, 0, ret); | |
200 | KUNIT_EXPECT_EQ(test, sel, range2_sels[RANGE2_NUM_VALS - 1]); | |
201 | KUNIT_EXPECT_FALSE(test, found); | |
202 | } | |
203 | ||
204 | static struct kunit_case range_test_cases[] = { | |
205 | KUNIT_CASE(range_test_get_value_amount), | |
206 | KUNIT_CASE(range_test_get_selector_high), | |
207 | KUNIT_CASE(range_test_get_selector_low), | |
208 | KUNIT_CASE(range_test_get_value), | |
209 | {}, | |
210 | }; | |
211 | ||
212 | static struct kunit_suite range_test_module = { | |
213 | .name = "linear-ranges-test", | |
214 | .test_cases = range_test_cases, | |
215 | }; | |
216 | ||
217 | kunit_test_suites(&range_test_module); | |
218 | ||
219 | MODULE_LICENSE("GPL"); |