api: API trace improvements
[vpp.git] / src / vat2 / test / vat2_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
16 #include <stdio.h>
17 #include <assert.h>
18 #include <vlibapi/api.h>
19 #include "vat2/test/vat2_test.api_types.h"
20 #include "vat2/test/vat2_test.api_tojson.h"
21 #include "vat2/test/vat2_test.api_fromjson.h"
22
23 typedef cJSON *(* tojson_fn_t)(void *);
24 typedef void *(* fromjson_fn_t)(cJSON *o, int *len);
25
26 static void
27 test (tojson_fn_t tojson, fromjson_fn_t fromjson, cJSON *o, bool should_fail)
28 {
29   // convert JSON object to API
30   int len = 0;
31   void *mp = (fromjson)(o, &len);
32   assert(mp);
33
34   // convert API to JSON
35   cJSON *o2 = (tojson)(mp);
36   assert(o2);
37
38   if (should_fail)
39     assert(!cJSON_Compare(o, o2, 1));
40   else
41     assert(cJSON_Compare(o, o2, 1));
42   char *s2 = cJSON_Print(o2);
43   assert(s2);
44
45   char *in = cJSON_Print(o);
46   printf("%s\n%s\n", in, s2);
47
48   free(in);
49   free(mp);
50   cJSON_Delete(o2);
51   free(s2);
52 }
53
54 struct msgs {
55   char *name;
56   tojson_fn_t tojson;
57   fromjson_fn_t fromjson;
58 };
59 struct tests {
60   char *s;
61   bool should_fail;
62 };
63
64 uword *function_by_name_tojson;
65 uword *function_by_name_fromjson;
66 static void
67 register_functions(struct msgs msgs[], int n)
68 {
69   int i;
70   function_by_name_tojson = hash_create_string (0, sizeof (uword));
71   function_by_name_fromjson = hash_create_string (0, sizeof (uword));
72   for (i = 0; i < n; i++) {
73     hash_set_mem(function_by_name_tojson, msgs[i].name, msgs[i].tojson);
74     hash_set_mem(function_by_name_fromjson, msgs[i].name, msgs[i].fromjson);
75   }
76 }
77
78 static void
79 runtest (char *s, bool should_fail)
80 {
81   cJSON *o = cJSON_Parse(s);
82   assert(o);
83   char *name = cJSON_GetStringValue(cJSON_GetObjectItem(o, "_msgname"));
84   assert(name);
85
86   uword *p = hash_get_mem(function_by_name_tojson, name);
87   printf ("Message name: %s\n", name);
88   assert(p);
89   tojson_fn_t tojson = (tojson_fn_t)p[0];
90
91   p = hash_get_mem(function_by_name_fromjson, name);
92   assert(p);
93   fromjson_fn_t fromjson = (fromjson_fn_t)p[0];
94
95   test(tojson, fromjson, o, should_fail);
96   cJSON_Delete(o);
97 }
98
99 struct msgs msgs[] = {
100   {
101     .name = "test_prefix",
102     .tojson = (tojson_fn_t) vl_api_test_prefix_t_tojson,
103     .fromjson = (fromjson_fn_t) vl_api_test_prefix_t_fromjson,
104   },
105   {
106     .name = "test_enum",
107     .tojson = (tojson_fn_t) vl_api_test_enum_t_tojson,
108     .fromjson = (fromjson_fn_t) vl_api_test_enum_t_fromjson,
109   },
110   {
111     .name = "test_string",
112     .tojson = (tojson_fn_t) vl_api_test_string_t_tojson,
113     .fromjson = (fromjson_fn_t) vl_api_test_string_t_fromjson,
114   },
115   {
116     .name = "test_string2",
117     .tojson = (tojson_fn_t) vl_api_test_string2_t_tojson,
118     .fromjson = (fromjson_fn_t) vl_api_test_string2_t_fromjson,
119   },
120   {
121     .name = "test_vla",
122     .tojson = (tojson_fn_t) vl_api_test_vla_t_tojson,
123     .fromjson = (fromjson_fn_t) vl_api_test_vla_t_fromjson,
124   },
125   {
126     .name = "test_vla2",
127     .tojson = (tojson_fn_t) vl_api_test_vla2_t_tojson,
128     .fromjson = (fromjson_fn_t) vl_api_test_vla2_t_fromjson,
129   },
130   {
131     .name = "test_vla3",
132     .tojson = (tojson_fn_t) vl_api_test_vla3_t_tojson,
133     .fromjson = (fromjson_fn_t) vl_api_test_vla3_t_fromjson,
134   },
135   {
136     .name = "test_vla4",
137     .tojson = (tojson_fn_t) vl_api_test_vla4_t_tojson,
138     .fromjson = (fromjson_fn_t) vl_api_test_vla4_t_fromjson,
139   },
140   {
141     .name = "test_vla5",
142     .tojson = (tojson_fn_t) vl_api_test_vla5_t_tojson,
143     .fromjson = (fromjson_fn_t) vl_api_test_vla5_t_fromjson,
144   },
145   {
146     .name = "test_addresses",
147     .tojson = (tojson_fn_t) vl_api_test_addresses_t_tojson,
148     .fromjson = (fromjson_fn_t) vl_api_test_addresses_t_fromjson,
149   },
150   {
151     .name = "test_addresses2",
152     .tojson = (tojson_fn_t) vl_api_test_addresses2_t_tojson,
153     .fromjson = (fromjson_fn_t) vl_api_test_addresses2_t_fromjson,
154   },
155   {
156     .name = "test_addresses3",
157     .tojson = (tojson_fn_t) vl_api_test_addresses3_t_tojson,
158     .fromjson = (fromjson_fn_t) vl_api_test_addresses3_t_fromjson,
159   },
160   {
161     .name = "test_empty",
162     .tojson = (tojson_fn_t) vl_api_test_empty_t_tojson,
163     .fromjson = (fromjson_fn_t) vl_api_test_empty_t_fromjson,
164   },
165   {
166     .name = "test_interface",
167     .tojson = (tojson_fn_t) vl_api_test_interface_t_tojson,
168     .fromjson = (fromjson_fn_t) vl_api_test_interface_t_fromjson,
169   },
170 };
171
172 struct tests tests[] = {
173   { .s = "{\"_msgname\": \"test_prefix\", \"pref\": \"2001:db8::/64\"}" },
174   { .s = "{\"_msgname\": \"test_prefix\", \"pref\": \"192.168.10.0/24\"}" },
175   { .s = "{\"_msgname\": \"test_enum\", \"flags\": [\"RED\", \"BLUE\"]}" },
176   { .s = "{\"_msgname\": \"test_enum\", \"flags\": [\"BLACK\", \"BLUE\"]}",
177     .should_fail = 1 },
178   { .s = "{\"_msgname\": \"test_string\", \"str\": {\"str\": \"Test string "
179          "type\"}}" },
180   { .s =
181       "{\"_msgname\": \"test_string2\", \"str\": \"Test string toplevel\"}" },
182   { .s = "{\"_msgname\": \"test_vla\", \"count\": 5, \"vla\": [1,2,3,4,5]}" },
183   { .s = "{\"_msgname\": \"test_vla2\", \"count\": 5, \"vla\": "
184          "\"0xaabbccddee\"}" },
185   { .s = "{\"_msgname\": \"test_vla3\", \"count\": 2, \"vla\": [{\"data\": 1} "
186          ", {\"data\": 2} ] }" },
187   { .s = "{\"_msgname\": \"test_vla4\", \"data\": { \"count\": 5, \"vla\": "
188          "[1,2,3,4,5] }}" },
189   { .s = "{\"_msgname\": \"test_vla5\", \"data\": { \"count\": 5, \"vla\": "
190          "\"0xaabbccddee\" }}" },
191   { .s = "{\"_msgname\": \"test_addresses\", \"a\": \"1.2.3.4\" }" },
192   { .s = "{\"_msgname\": \"test_addresses\", \"a\": \"2001:db8::23\" }" },
193   { .s = "{\"_msgname\": \"test_addresses2\", \"a\": [\"2001:db8::23\", "
194          "\"2001:db8::23\"] }" },
195   { .s = "{\"_msgname\": \"test_addresses3\", \"n\": 2, \"a\": "
196          "[\"2001:db8::23\", \"2001:db8::23\"] }" },
197   { .s = "{\"_msgname\": \"test_empty\"}" },
198   { .s = "{\"_msgname\": \"test_interface\", \"sw_if_index\": 100 }" },
199   { .s = "{\"_msgname\": \"test_interface\", \"sw_if_index\": 4294967295 }" },
200 };
201
202 int main (int argc, char **argv)
203 {
204   clib_mem_init (0, 64 << 20);
205   int n = sizeof(msgs)/sizeof(msgs[0]);
206   register_functions(msgs, n);
207
208   int i;
209   n = sizeof(tests)/sizeof(tests[0]);
210   for (i = 0; i < n; i++) {
211     runtest(tests[i].s, tests[i].should_fail);
212   }
213 }