1cf5ba1f75cff0dbd46b9f0b402fdce1a8c419b0
[vpp.git] / src / vppinfra / test_elog.c
1 /*
2  * Copyright (c) 2015 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 /*
16   Copyright (c) 2005 Eliot Dresselhaus
17
18   Permission is hereby granted, free of charge, to any person obtaining
19   a copy of this software and associated documentation files (the
20   "Software"), to deal in the Software without restriction, including
21   without limitation the rights to use, copy, modify, merge, publish,
22   distribute, sublicense, and/or sell copies of the Software, and to
23   permit persons to whom the Software is furnished to do so, subject to
24   the following conditions:
25
26   The above copyright notice and this permission notice shall be
27   included in all copies or substantial portions of the Software.
28
29   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
30   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
31   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
32   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
33   LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
34   OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
35   WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 */
37
38 #include <vppinfra/elog.h>
39 #include <vppinfra/error.h>
40 #include <vppinfra/format.h>
41 #include <vppinfra/random.h>
42 #include <vppinfra/serialize.h>
43 #include <vppinfra/unix.h>
44
45 int
46 test_elog_main (unformat_input_t * input)
47 {
48   clib_error_t *error = 0;
49   u32 i, n_iter, seed, max_events;
50   elog_main_t _em, *em = &_em;
51   u32 verbose;
52   f64 min_sample_time;
53   char *dump_file, *load_file, *merge_file, **merge_files;
54   u8 *tag, **tags;
55   f64 align_tweak;
56   f64 *align_tweaks;
57
58   n_iter = 100;
59   max_events = 100000;
60   seed = 1;
61   verbose = 0;
62   dump_file = 0;
63   load_file = 0;
64   merge_files = 0;
65   tags = 0;
66   align_tweaks = 0;
67   min_sample_time = 2;
68   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
69     {
70       if (unformat (input, "iter %d", &n_iter))
71         ;
72       else if (unformat (input, "seed %d", &seed))
73         ;
74       else if (unformat (input, "dump %s", &dump_file))
75         ;
76       else if (unformat (input, "load %s", &load_file))
77         ;
78       else if (unformat (input, "tag %s", &tag))
79         vec_add1 (tags, tag);
80       else if (unformat (input, "merge %s", &merge_file))
81         vec_add1 (merge_files, merge_file);
82
83       else if (unformat (input, "verbose %=", &verbose, 1))
84         ;
85       else if (unformat (input, "max-events %d", &max_events))
86         ;
87       else if (unformat (input, "sample-time %f", &min_sample_time))
88         ;
89       else if (unformat (input, "align-tweak %f", &align_tweak))
90         vec_add1 (align_tweaks, align_tweak);
91       else
92         {
93           error = clib_error_create ("unknown input `%U'\n",
94                                      format_unformat_error, input);
95           goto done;
96         }
97     }
98
99 #ifdef CLIB_UNIX
100   if (load_file)
101     {
102       if ((error = elog_read_file (em, load_file)))
103         goto done;
104     }
105
106   else if (merge_files)
107     {
108       uword i;
109       elog_main_t *ems;
110       vec_clone (ems, merge_files);
111
112       /* Supply default tags as needed */
113       if (vec_len (tags) < vec_len (ems))
114         {
115           for (i = vec_len (tags); i < vec_len (ems); i++)
116             vec_add1 (tags, format (0, "F%d%c", i, 0));
117         }
118
119       elog_init (em, max_events);
120       for (i = 0; i < vec_len (ems); i++)
121         {
122           if ((error =
123                elog_read_file (i == 0 ? em : &ems[i], merge_files[i])))
124             goto done;
125           if (i > 0)
126             {
127               align_tweak = 0.0;
128               if (i <= vec_len (align_tweaks))
129                 align_tweak = align_tweaks[i - 1];
130               elog_merge (em, tags[0], &ems[i], tags[i], align_tweak);
131               tags[0] = 0;
132             }
133         }
134     }
135
136   else
137 #endif /* CLIB_UNIX */
138     {
139       f64 t[2];
140
141       elog_init (em, max_events);
142       elog_enable_disable (em, 1);
143       t[0] = unix_time_now ();
144
145       for (i = 0; i < n_iter; i++)
146         {
147           u32 j, n, sum;
148
149           n = 1 + (random_u32 (&seed) % 128);
150           sum = 0;
151           for (j = 0; j < n; j++)
152             sum += random_u32 (&seed);
153
154           {
155             ELOG_TYPE_XF (e);
156             ELOG (em, e, sum);
157           }
158
159           {
160             ELOG_TYPE_XF (e);
161             ELOG (em, e, sum + 1);
162           }
163
164           {
165             struct
166             {
167               u32 string_index;
168               f32 f;
169             } *d;
170             ELOG_TYPE_DECLARE (e) =
171             {
172               .format = "fumble %s %.9f",.format_args =
173                 "t4f4",.n_enum_strings = 4,.enum_strings =
174               {
175             "string0", "string1", "string2", "string3",},};
176
177             d = ELOG_DATA (em, e);
178
179             d->string_index = sum & 3;
180             d->f = (sum & 0xff) / 128.;
181           }
182
183           {
184             ELOG_TYPE_DECLARE (e) =
185             {
186             .format = "bar %d.%d.%d.%d",.format_args = "i1i1i1i1",};
187             ELOG_TRACK (my_track);
188             u8 *d = ELOG_TRACK_DATA (em, e, my_track);
189             d[0] = i + 0;
190             d[1] = i + 1;
191             d[2] = i + 2;
192             d[3] = i + 3;
193           }
194
195           {
196             ELOG_TYPE_DECLARE (e) =
197             {
198             .format = "bar `%s'",.format_args = "s20",};
199             struct
200             {
201               char s[20];
202             } *d;
203             u8 *v;
204
205             d = ELOG_DATA (em, e);
206             v = format (0, "foo %d%c", i, 0);
207             clib_memcpy (d->s, v, clib_min (vec_len (v), sizeof (d->s)));
208           }
209
210           {
211             ELOG_TYPE_DECLARE (e) =
212             {
213             .format = "bar `%s'",.format_args = "T4",};
214             struct
215             {
216               u32 offset;
217             } *d;
218
219             d = ELOG_DATA (em, e);
220             d->offset = elog_string (em, "string table %d", i);
221           }
222         }
223
224       do
225         {
226           t[1] = unix_time_now ();
227         }
228       while (t[1] - t[0] < min_sample_time);
229     }
230
231 #ifdef CLIB_UNIX
232   if (dump_file)
233     {
234       if ((error =
235            elog_write_file (em, dump_file, 0 /* do not flush ring */ )))
236         goto done;
237     }
238 #endif
239
240   if (verbose)
241     {
242       elog_event_t *e, *es;
243       es = elog_get_events (em);
244       vec_foreach (e, es)
245       {
246         clib_warning ("%18.9f: %12U %U\n", e->time,
247                       format_elog_track, em, e, format_elog_event, em, e);
248       }
249     }
250
251 done:
252   if (error)
253     clib_error_report (error);
254   return 0;
255 }
256
257 #ifdef CLIB_UNIX
258 int
259 main (int argc, char *argv[])
260 {
261   unformat_input_t i;
262   int r;
263
264   clib_mem_init (0, 3ULL << 30);
265
266   unformat_init_command_line (&i, argv);
267   r = test_elog_main (&i);
268   unformat_free (&i);
269   return r;
270 }
271 #endif
272
273 /**
274  * @brief GDB callable function: vl - Return vector length of vector
275  *
276  * @param *p - void - address of vector
277  *
278  * @return length - u32
279  *
280  */
281 u32
282 vl (void *p)
283 {
284   return vec_len (p);
285 }
286
287 /**
288  * @brief GDB callable function: pe - call pool_elts - number of elements in a pool
289  *
290  * @param *v - void - address of pool
291  *
292  * @return number - uword
293  *
294  */
295 #include <vppinfra/pool.h>
296 uword
297 pe (void *v)
298 {
299   return (pool_elts (v));
300 }
301
302 #include <vppinfra/hash.h>
303 uword
304 he (void *v)
305 {
306   return (hash_elts (v));
307 }
308
309 /*
310  * fd.io coding-style-patch-verification: ON
311  *
312  * Local Variables:
313  * eval: (c-set-style "gnu")
314  * End:
315  */