vppinfra: clib_bitmap fix
[vpp.git] / src / plugins / unittest / bitmap_test.c
1 /*
2  * Copyright (c) 2020 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include <vlib/vlib.h>
16 #include <vppinfra/bitmap.h>
17
18 static clib_error_t *
19 check_bitmap (const char *test_name, const uword *bm, u32 expected_len, ...)
20 {
21   clib_error_t *error = 0;
22   u32 i;
23   uword expected_value;
24
25   va_list va;
26   va_start (va, expected_len);
27
28   if (vec_len (bm) != expected_len)
29     {
30       error = clib_error_create ("%s failed, wrong "
31                                  "bitmap's size (%u != %u expected)",
32                                  test_name, vec_len (bm), expected_len);
33       goto done;
34     }
35
36   for (i = 0; i < expected_len; ++i)
37     {
38       expected_value = va_arg (va, uword);
39       if (bm[i] != expected_value)
40         {
41           error = clib_error_create (
42             "%s failed, wrong "
43             "bitmap's value at index %u (%u != %u expected)",
44             test_name, i, bm[i], expected_value);
45           break;
46         }
47     }
48
49 done:
50   va_end (va);
51   return error;
52 }
53
54 static clib_error_t *
55 test_bitmap_command_fn (vlib_main_t * vm,
56                         unformat_input_t * input, vlib_cli_command_t * cmd)
57 {
58   clib_error_t *error = 0;
59   uword *bm = 0;
60   uword *bm2 = 0;
61   uword *dup = 0;
62
63   /*  bm should look like:
64    *          bm[0]     bm[1]
65    *  LSB |0011...11|1100...00| MSB
66    */
67   bm = clib_bitmap_set_multiple (0, 2, ~0ULL, BITS (uword));
68   error = check_bitmap ("clib_bitmap_set_multiple 1", bm, 2, ~0ULL << 2, 3);
69   if (error != 0)
70     goto done;
71
72   /*  bm2 should look like:
73    *        bm2[0]
74    *  LSB |11...11| MSB
75    */
76   bm2 = clib_bitmap_set_multiple (0, 0, ~0ULL, BITS (uword));
77   error = check_bitmap ("clib_bitmap_set_multiple 2", bm2, 1, ~0ULL);
78   if (error != 0)
79     goto done;
80
81   /*  bm should look like:
82    *          bm[0]      bm[1]
83    *  LSB |0011...1100|000...000| MSB
84    */
85   bm = clib_bitmap_set_multiple (bm, 2, pow2_mask (BITS (uword) - 3),
86                                  BITS (uword));
87   error = check_bitmap ("clib_bitmap_set_multiple 3", bm, 2,
88                         pow2_mask (BITS (uword) - 3) << 2, 0);
89   if (error != 0)
90     goto done;
91
92   /*  bm2 should look like:
93    *         bm2[0]
94    *  LSB |101...111| MSB
95    */
96   bm2 = clib_bitmap_xori (bm2, 1);
97   error = check_bitmap ("clib_bitmap_xori 1", bm2, 1, ~0ULL ^ 2);
98   if (error != 0)
99     goto done;
100
101   /*  bm should look like:
102    *           bm[0]      bm[1]
103    *  LSB |0011...1100|000...001| MSB
104    */
105   bm = clib_bitmap_xori (bm, 2 * BITS (uword) - 1);
106   error = check_bitmap ("clib_bitmap_xori 2", bm, 2,
107                         pow2_mask (BITS (uword) - 3) << 2,
108                         1ULL << (BITS (uword) - 1));
109   if (error != 0)
110     goto done;
111
112   /*  bm should look like:
113    *         bm[0]      bm[1]
114    *  LSB |00100...00|000...001| MSB
115    */
116   bm = clib_bitmap_andi (bm, 2);
117   error =
118     check_bitmap ("clib_bitmap_andi", bm, 2, 4, 1ULL << (BITS (uword) - 1));
119   if (error != 0)
120     goto done;
121
122   /*  bm should look like:
123    *         bm[0]
124    *  LSB |00100...00| MSB
125    */
126   bm = clib_bitmap_xori (bm, 2 * BITS (uword) - 1);
127   error = check_bitmap ("clib_bitmap_xori 3", bm, 1, 4);
128   if (error != 0)
129     goto done;
130
131   /*  bm and bm2 should look like:
132    *         bm[0]     bm[1]
133    *  LSB |0011...11|1100...00| MSB
134    *         bm2[0]    bm2[1]
135    *  LSB |101...111|0011...11| MSB
136    */
137   bm = clib_bitmap_set_multiple (bm, 2, ~0ULL, BITS (uword));
138   bm2 =
139     clib_bitmap_set_multiple (bm2, BITS (uword) + 2, ~0ULL, BITS (uword) - 3);
140   dup = clib_bitmap_dup_and (bm, bm2);
141   error = check_bitmap ("clib_bitmap_dup_and", dup, 1, bm[0] & bm2[0]);
142   if (error != 0)
143     goto done;
144
145   /*  bm should look like:
146    *         bm[0]    bm[1]   ...   bm[3]
147    *  LSB |0011...11|11...11| ... |11...11| MSB
148    */
149   bm = clib_bitmap_set_region (bm, 5, 1, 4 * BITS (uword) - 5);
150   error = check_bitmap ("clib_bitmap_set_region 1", bm, 4, ~0ULL << 2, ~0ULL,
151                         ~0ULL, ~0ULL);
152   if (error != 0)
153     goto done;
154
155   /*  bm should look like:
156    *         bm[0]    bm[1]   ...      bm[3]
157    *  LSB |0011...11|11...11| ... |11...1100000| MSB
158    */
159   bm = clib_bitmap_set_region (bm, 4 * BITS (uword) - 5, 0, 5);
160   error = check_bitmap ("clib_bitmap_set_region 2", bm, 4, ~0ULL << 2, ~0ULL,
161                         ~0ULL, pow2_mask (BITS (uword) - 5));
162   if (error != 0)
163     goto done;
164
165 done:
166   vec_free (bm);
167   vec_free (bm2);
168   vec_free (dup);
169
170   return error;
171 }
172
173 /* *INDENT-OFF* */
174 VLIB_CLI_COMMAND (test_bitmap_command, static) = {
175   .path = "test bitmap",
176   .short_help = "Coverage test for bitmap.h",
177   .function = test_bitmap_command_fn,
178 };
179 /* *INDENT-ON* */
180
181 /*
182  * fd.io coding-style-patch-verification: ON
183  *
184  * Local Variables:
185  * eval: (c-set-style "gnu")
186  * End:
187  */