vlib: clean up r2 plugin registration relocator
[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 void
46 g2_test_pattern (elog_main_t * em, int g2_test, char *dump_file)
47 {
48   int i, j;
49   clib_error_t *error;
50   elog_track_t *tracks = 0;
51
52   elog_init (em, 100000);
53   elog_enable_disable (em, 1 /* enable */ );
54
55   for (i = 0; i < 100; i++)
56     {
57       elog_track_t *t;
58       vec_validate (tracks, i);
59       t = tracks + i;
60       t->name = (char *) format (0, "Track %3d", i + 1);
61       elog_track_register (em, t);
62     }
63
64   for (i = 0; i < 100; i++)
65     {
66       for (j = 0; j < 100; j++)
67         {
68           ELOG_TYPE_DECLARE (e) =
69           {
70           .format = "0: t%d event %d",.format_args = "i4i4",};
71           ELOG_TYPE_DECLARE (e2) =
72           {
73           .format = "1: t%d event %d",.format_args = "i4i4",};
74
75           struct
76           {
77             int track, event;
78           } *ed;
79
80           ed = ELOG_TRACK_DATA (em, e, tracks[j]);
81           ed->track = j + 1;
82           ed->event = i;
83           ed = ELOG_TRACK_DATA (em, e2, tracks[j]);
84           ed->track = j + 1;
85           ed->event = i;
86         }
87     }
88
89   if (dump_file == 0)
90     dump_file = "/tmp/g2_test.elog";
91
92   error = elog_write_file (em, dump_file, 1 /* flush ring */ );
93
94   if (error)
95     clib_error_report (error);
96 }
97
98
99 int
100 test_elog_main (unformat_input_t * input)
101 {
102   clib_error_t *error = 0;
103   u32 i, n_iter, seed, max_events;
104   elog_main_t _em, *em = &_em;
105   u32 verbose;
106   f64 min_sample_time;
107   char *dump_file, *load_file, *merge_file, **merge_files;
108   u8 *tag, **tags;
109   f64 align_tweak;
110   f64 *align_tweaks;
111   int g2_test;
112
113   n_iter = 100;
114   max_events = 100000;
115   seed = 1;
116   verbose = 0;
117   dump_file = 0;
118   load_file = 0;
119   merge_files = 0;
120   tags = 0;
121   align_tweaks = 0;
122   min_sample_time = 2;
123   g2_test = 0;
124   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
125     {
126       if (unformat (input, "iter %d", &n_iter))
127         ;
128       else if (unformat (input, "seed %d", &seed))
129         ;
130       else if (unformat (input, "dump %s", &dump_file))
131         ;
132       else if (unformat (input, "load %s", &load_file))
133         ;
134       else if (unformat (input, "tag %s", &tag))
135         vec_add1 (tags, tag);
136       else if (unformat (input, "merge %s", &merge_file))
137         vec_add1 (merge_files, merge_file);
138
139       else if (unformat (input, "verbose %=", &verbose, 1))
140         ;
141       else if (unformat (input, "max-events %d", &max_events))
142         ;
143       else if (unformat (input, "sample-time %f", &min_sample_time))
144         ;
145       else if (unformat (input, "align-tweak %f", &align_tweak))
146         vec_add1 (align_tweaks, align_tweak);
147       else if (unformat (input, "g2-test %=", &g2_test, 1))
148         ;
149       else
150         {
151           error = clib_error_create ("unknown input `%U'\n",
152                                      format_unformat_error, input);
153           goto done;
154         }
155     }
156
157   if (g2_test)
158     {
159       g2_test_pattern (em, g2_test, dump_file);
160       return (0);
161     }
162
163 #ifdef CLIB_UNIX
164   if (load_file)
165     {
166       if ((error = elog_read_file (em, load_file)))
167         goto done;
168     }
169
170   else if (merge_files)
171     {
172       uword i;
173       elog_main_t *ems;
174       vec_clone (ems, merge_files);
175
176       /* Supply default tags as needed */
177       if (vec_len (tags) < vec_len (ems))
178         {
179           for (i = vec_len (tags); i < vec_len (ems); i++)
180             vec_add1 (tags, format (0, "F%d%c", i, 0));
181         }
182
183       elog_init (em, max_events);
184       for (i = 0; i < vec_len (ems); i++)
185         {
186           if ((error =
187                elog_read_file (i == 0 ? em : &ems[i], merge_files[i])))
188             goto done;
189           if (i > 0)
190             {
191               align_tweak = 0.0;
192               if (i <= vec_len (align_tweaks))
193                 align_tweak = align_tweaks[i - 1];
194               elog_merge (em, tags[0], &ems[i], tags[i], align_tweak);
195               tags[0] = 0;
196             }
197         }
198     }
199
200   else
201 #endif /* CLIB_UNIX */
202     {
203       f64 t[2];
204
205       elog_init (em, max_events);
206       elog_enable_disable (em, 1);
207       t[0] = unix_time_now ();
208
209       for (i = 0; i < n_iter; i++)
210         {
211           u32 j, n, sum;
212
213           n = 1 + (random_u32 (&seed) % 128);
214           sum = 0;
215           for (j = 0; j < n; j++)
216             sum += random_u32 (&seed);
217
218           {
219             ELOG_TYPE_XF (e);
220             ELOG (em, e, sum);
221           }
222
223           {
224             ELOG_TYPE_XF (e);
225             ELOG (em, e, sum + 1);
226           }
227
228           {
229             struct
230             {
231               u32 string_index;
232               f32 f;
233             } *d;
234             ELOG_TYPE_DECLARE (e) =
235             {
236               .format = "fumble %s %.9f",.format_args =
237                 "t4f4",.n_enum_strings = 4,.enum_strings =
238               {
239             "string0", "string1", "string2", "string3",},};
240
241             d = ELOG_DATA (em, e);
242
243             d->string_index = sum & 3;
244             d->f = (sum & 0xff) / 128.;
245           }
246
247           {
248             ELOG_TYPE_DECLARE (e) =
249             {
250             .format = "bar %d.%d.%d.%d",.format_args = "i1i1i1i1",};
251             ELOG_TRACK (my_track);
252             u8 *d = ELOG_TRACK_DATA (em, e, my_track);
253             d[0] = i + 0;
254             d[1] = i + 1;
255             d[2] = i + 2;
256             d[3] = i + 3;
257           }
258
259           {
260             ELOG_TYPE_DECLARE (e) =
261             {
262             .format = "bar `%s'",.format_args = "s20",};
263             struct
264             {
265               char s[20];
266             } *d;
267             u8 *v;
268
269             d = ELOG_DATA (em, e);
270             v = format (0, "foo %d%c", i, 0);
271             clib_memcpy (d->s, v, clib_min (vec_len (v), sizeof (d->s)));
272           }
273
274           {
275             ELOG_TYPE_DECLARE (e) =
276             {
277             .format = "bar `%s'",.format_args = "T4",};
278             struct
279             {
280               u32 offset;
281             } *d;
282
283             d = ELOG_DATA (em, e);
284             d->offset = elog_string (em, "string table %d", i);
285           }
286         }
287
288       do
289         {
290           t[1] = unix_time_now ();
291         }
292       while (t[1] - t[0] < min_sample_time);
293     }
294
295 #ifdef CLIB_UNIX
296   if (dump_file)
297     {
298       if ((error =
299            elog_write_file (em, dump_file, 0 /* do not flush ring */ )))
300         goto done;
301     }
302 #endif
303
304   if (verbose)
305     {
306       elog_event_t *e, *es;
307       es = elog_get_events (em);
308       vec_foreach (e, es)
309       {
310         clib_warning ("%18.9f: %12U %U\n", e->time,
311                       format_elog_track_name, em, e, format_elog_event, em,
312                       e);
313       }
314     }
315
316 done:
317   if (error)
318     clib_error_report (error);
319   return 0;
320 }
321
322 #ifdef CLIB_UNIX
323 int
324 main (int argc, char *argv[])
325 {
326   unformat_input_t i;
327   int r;
328
329   clib_mem_init (0, 3ULL << 30);
330
331   unformat_init_command_line (&i, argv);
332   r = test_elog_main (&i);
333   unformat_free (&i);
334   return r;
335 }
336 #endif
337
338 /**
339  * @brief GDB callable function: vl - Return vector length of vector
340  *
341  * @param *p - void - address of vector
342  *
343  * @return length - u32
344  *
345  */
346 u32
347 vl (void *p)
348 {
349   return vec_len (p);
350 }
351
352 /**
353  * @brief GDB callable function: pe - call pool_elts - number of elements in a pool
354  *
355  * @param *v - void - address of pool
356  *
357  * @return number - uword
358  *
359  */
360 #include <vppinfra/pool.h>
361 uword
362 pe (void *v)
363 {
364   return (pool_elts (v));
365 }
366
367 #include <vppinfra/hash.h>
368 uword
369 he (void *v)
370 {
371   return (hash_elts (v));
372 }
373
374 /*
375  * fd.io coding-style-patch-verification: ON
376  *
377  * Local Variables:
378  * eval: (c-set-style "gnu")
379  * End:
380  */