Initial commit of vpp code.
[vpp.git] / vppinfra / 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 test_elog_main (unformat_input_t * input)
46 {
47   clib_error_t * error = 0;
48   u32 i, n_iter, seed, max_events;
49   elog_main_t _em, * em = &_em;
50   u32 verbose;
51   f64 min_sample_time;
52   char * dump_file, * load_file, * merge_file, ** merge_files;
53   u8 * tag, ** tags;
54
55   n_iter = 100;
56   max_events = 100000;
57   seed = 1;
58   verbose = 0;
59   dump_file = 0;
60   load_file = 0;
61   merge_files = 0;
62   tags = 0;
63   min_sample_time = 2;
64   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
65     {
66       if (unformat (input, "iter %d", &n_iter))
67         ;
68       else if (unformat (input, "seed %d", &seed))
69         ;
70       else if (unformat (input, "dump %s", &dump_file))
71         ;
72       else if (unformat (input, "load %s", &load_file))
73         ;
74       else if (unformat (input, "tag %s", &tag))
75         vec_add1 (tags, tag);
76       else if (unformat (input, "merge %s", &merge_file))
77         vec_add1 (merge_files, merge_file);
78
79       else if (unformat (input, "verbose %=", &verbose, 1))
80         ;
81       else if (unformat (input, "max-events %d", &max_events))
82         ;
83       else if (unformat (input, "sample-time %f", &min_sample_time))
84         ;
85       else
86         {
87           error = clib_error_create ("unknown input `%U'\n",
88                                      format_unformat_error, input);
89           goto done;
90         }
91     }
92
93 #ifdef CLIB_UNIX
94   if (load_file)
95     {
96       if ((error = elog_read_file (em, load_file)))
97         goto done;
98     }
99
100   else if (merge_files)
101     {
102       uword i;
103       elog_main_t * ems;
104
105       vec_clone (ems, merge_files);
106
107       elog_init (em, max_events);
108       for (i = 0; i < vec_len (ems); i++)
109         {
110           if ((error = elog_read_file (i == 0 ? em : &ems[i], merge_files[i])))
111             goto done;
112           if (i > 0)
113             {
114               elog_merge (em, tags[0], &ems[i], tags[i]);
115               tags[0] = 0;
116             }
117         }
118     }
119
120   else
121 #endif /* CLIB_UNIX */
122     {
123       f64 t[2];
124
125       elog_init (em, max_events);
126       elog_enable_disable (em, 1);
127       t[0] = unix_time_now ();
128
129       for (i = 0; i < n_iter; i++)
130         {
131           u32 j, n, sum;
132
133           n = 1 + (random_u32 (&seed) % 128);
134           sum = 0;
135           for (j = 0; j < n; j++)
136             sum += random_u32 (&seed);
137
138           {
139             ELOG_TYPE_XF (e);
140             ELOG (em, e, sum);
141           }
142
143           {
144             ELOG_TYPE_XF (e);
145             ELOG (em, e, sum + 1);
146           }
147
148           {
149             struct { u32 string_index; f32 f; } * d;
150             ELOG_TYPE_DECLARE (e) = {
151               .format = "fumble %s %.9f",
152               .format_args = "t4f4",
153               .n_enum_strings = 4,
154               .enum_strings = {
155                 "string0",
156                 "string1",
157                 "string2",
158                 "string3",
159               },
160             };
161
162             d = ELOG_DATA (em, e);
163
164             d->string_index = sum & 3;
165             d->f = (sum & 0xff) / 128.;
166           }
167           
168           {
169             ELOG_TYPE_DECLARE (e) = {
170               .format = "bar %d.%d.%d.%d",
171               .format_args = "i1i1i1i1",
172             };
173             ELOG_TRACK (my_track);
174             u8 * d = ELOG_TRACK_DATA (em, e, my_track);
175             d[0] = i + 0;
176             d[1] = i + 1;
177             d[2] = i + 2;
178             d[3] = i + 3;
179           }
180
181           {
182             ELOG_TYPE_DECLARE (e) = {
183               .format = "bar `%s'",
184               .format_args = "s20",
185             };
186             struct { char s[20]; } * d;
187             u8 * v;
188
189             d = ELOG_DATA (em, e);
190             v = format (0, "foo %d%c", i, 0);
191             memcpy (d->s, v, clib_min (vec_len (v), sizeof (d->s)));
192           }
193
194           {
195             ELOG_TYPE_DECLARE (e) = {
196               .format = "bar `%s'",
197               .format_args = "T4",
198             };
199             struct { u32 offset; } * d;
200
201             d = ELOG_DATA (em, e);
202             d->offset = elog_string (em, "string table %d", i);
203           }
204         }
205
206       do {
207         t[1] = unix_time_now ();
208       } while (t[1] - t[0] < min_sample_time);
209     }
210
211 #ifdef CLIB_UNIX
212   if (dump_file)
213     {
214       if ((error = elog_write_file (em, dump_file)))
215         goto done;
216     }
217 #endif
218
219   if (verbose)
220     {
221       elog_event_t * e, * es;
222       es = elog_get_events (em);
223       vec_foreach (e, es)
224         {
225           clib_warning ("%18.9f: %12U %U\n", e->time,
226                         format_elog_track, em, e,
227                         format_elog_event, em, e);
228         }
229     }
230
231  done:
232   if (error)
233     clib_error_report (error);
234   return 0;
235 }
236
237 #ifdef CLIB_UNIX
238 int main (int argc, char * argv [])
239 {
240   unformat_input_t i;
241   int r;
242
243   unformat_init_command_line (&i, argv);
244   r = test_elog_main (&i);
245   unformat_free (&i);
246   return r;
247 }
248 #endif