crypto-native: fix CPU detection for SHA2 code
[vpp.git] / src / plugins / unittest / counter_test.c
1 /*
2  * Copyright (c) 2021 EMnify.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include <vlib/vlib.h>
17 #include <vppinfra/time.h>
18 #include <vppinfra/cache.h>
19 #include <vppinfra/error.h>
20
21 #include <vlib/counter.h>
22 #include <vlib/stats/stats.h>
23
24 enum
25 {
26   type_simple = 0,
27   type_combined,
28 };
29
30 enum
31 {
32   test_expand = 0,
33 };
34
35 /*
36  * Return the stats segment epoch value.
37  */
38 static uint64_t
39 get_stats_epoch ()
40 {
41   vlib_stats_segment_t *sm = vlib_stats_get_segment ();
42   return sm->shared_header->epoch;
43 }
44
45 /* number of times to repeat the counter expand tests */
46 #define EXPAND_TEST_ROUNDS 3
47
48 /*
49  * Let a simple counter vector grow and verify that
50  * the stats epoch is increased only when the vector
51  * is expanded.
52  */
53 static clib_error_t *
54 test_simple_counter_expand (vlib_main_t *vm)
55 {
56   vlib_simple_counter_main_t counter = {
57     .name = "test-simple-counter-expand",
58     .stat_segment_name = "/vlib/test-simple-counter-expand",
59   };
60   int i, index;
61   uint64_t epoch, new_epoch;
62
63   // Create one counter to allocate the vector.
64   vlib_validate_simple_counter (&counter, 0);
65   epoch = get_stats_epoch ();
66
67   for (i = 0; i < EXPAND_TEST_ROUNDS; i++)
68     {
69       // Check how many elements fit into the counter vector without expanding
70       // that. The next validate calls should not increase the stats segment
71       // epoch.
72       int mem_size = vec_max_len (counter.counters[0]);
73       for (index = 1; index <= mem_size - 1; index++)
74         {
75           vlib_validate_simple_counter (&counter, index);
76           new_epoch = get_stats_epoch ();
77           if (new_epoch != epoch)
78             return clib_error_return (
79               0, "Stats segment epoch should not increase");
80         }
81
82       // The next counter index does not fit and it will extend the vector.
83       // The stats segment epoch should increase.
84       vlib_validate_simple_counter (&counter, index + 1);
85       new_epoch = get_stats_epoch ();
86       if (new_epoch == epoch)
87         return clib_error_return (0,
88                                   "Stats segment epoch should have increased");
89       epoch = new_epoch;
90     }
91
92   vlib_free_simple_counter (&counter);
93   vlib_validate_simple_counter (&counter, 0);
94
95   return 0;
96 }
97
98 /*
99  * Let a combined counter vector grow and verify that
100  * the stats epoch is increased only when the vector
101  * is expanded.
102  */
103 static clib_error_t *
104 test_combined_counter_expand (vlib_main_t *vm)
105 {
106   vlib_combined_counter_main_t counter = {
107     .name = "test-combined-counter-expand",
108     .stat_segment_name = "/vlib/test-combined-counter-expand",
109   };
110   int i, index;
111   uint64_t epoch, new_epoch;
112
113   // Create one counter to allocate the vector.
114   vlib_validate_combined_counter (&counter, 0);
115   epoch = get_stats_epoch ();
116
117   for (i = 0; i < EXPAND_TEST_ROUNDS; i++)
118     {
119       // Check how many elements fit into the counter vector without expanding
120       // that. The next validate calls should not increase the stats segment
121       // epoch.
122       int mem_size = vec_max_len (counter.counters[0]);
123       for (index = 1; index <= mem_size - 1; index++)
124         {
125           vlib_validate_combined_counter (&counter, index);
126           new_epoch = get_stats_epoch ();
127           if (new_epoch != epoch)
128             return clib_error_return (
129               0, "Stats segment epoch should not increase");
130         }
131
132       // The next counter index does not fit and it will extend the vector.
133       // The stats segment epoch should increase.
134       vlib_validate_combined_counter (&counter, index + 1);
135       new_epoch = get_stats_epoch ();
136       if (new_epoch == epoch)
137         return clib_error_return (0,
138                                   "Stats segment epoch should have increased");
139       epoch = new_epoch;
140     }
141
142   vlib_free_combined_counter (&counter);
143   vlib_validate_combined_counter (&counter, 0);
144
145   return 0;
146 }
147
148 static clib_error_t *
149 test_simple_counter (vlib_main_t *vm, int test_case)
150 {
151   clib_error_t *error;
152
153   switch (test_case)
154     {
155     case test_expand:
156       error = test_simple_counter_expand (vm);
157       break;
158
159     default:
160       return clib_error_return (0, "no such test");
161     }
162
163   return error;
164 }
165
166 static clib_error_t *
167 test_combined_counter (vlib_main_t *vm, int test_case)
168 {
169   clib_error_t *error;
170
171   switch (test_case)
172     {
173     case test_expand:
174       error = test_combined_counter_expand (vm);
175       break;
176
177     default:
178       return clib_error_return (0, "no such test");
179     }
180
181   return error;
182 }
183
184 static clib_error_t *
185 test_counter_command_fn (vlib_main_t *vm, unformat_input_t *input,
186                          vlib_cli_command_t *cmd)
187 {
188   clib_error_t *error;
189   int counter_type = -1;
190   int test_case = -1;
191
192   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
193     {
194       if (unformat (input, "simple"))
195         counter_type = type_simple;
196       else if (unformat (input, "combined"))
197         counter_type = type_combined;
198       else if (unformat (input, "expand"))
199         test_case = test_expand;
200       else
201         return clib_error_return (0, "unknown input '%U'",
202                                   format_unformat_error, input);
203     }
204
205   if (test_case == -1)
206     return clib_error_return (0, "no such test");
207
208   switch (counter_type)
209     {
210     case type_simple:
211       error = test_simple_counter (vm, test_case);
212       break;
213
214     case type_combined:
215       error = test_combined_counter (vm, test_case);
216       break;
217
218     default:
219       return clib_error_return (0, "no such test");
220     }
221
222   return error;
223 }
224
225 VLIB_CLI_COMMAND (test_counter_command, static) = {
226   .path = "test counter",
227   .short_help = "test counter [simple | combined] expand",
228   .function = test_counter_command_fn,
229 };
230
231 static clib_error_t *
232 test_counter_init (vlib_main_t *vm)
233 {
234   return (0);
235 }
236
237 VLIB_INIT_FUNCTION (test_counter_init);
238
239 /*
240  * fd.io coding-style-patch-verification: ON
241  *
242  * Local Variables:
243  * eval: (c-set-style "gnu")
244  * End:
245  */