Ole Troan | 793be46 | 2020-12-04 13:15:30 +0100 | [diff] [blame] | 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); |
Ole Troan | cf0102b | 2021-02-12 11:48:12 +0100 | [diff] [blame] | 87 | printf ("Message name: %s\n", name); |
Ole Troan | 793be46 | 2020-12-04 13:15:30 +0100 | [diff] [blame] | 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[] = { |
Ole Troan | fb0afab | 2021-02-11 11:13:46 +0100 | [diff] [blame] | 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 | }, |
Ole Troan | cf0102b | 2021-02-12 11:48:12 +0100 | [diff] [blame] | 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 | }, |
Ole Troan | 316967c | 2021-02-16 00:31:52 +0100 | [diff] [blame] | 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 | }, |
Ole Troan | 93c4b1b | 2021-02-16 18:09:51 +0100 | [diff] [blame] | 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 | }, |
Ole Troan | 71134f2 | 2021-02-17 14:10:04 +0100 | [diff] [blame] | 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 | }, |
Ole Troan | 793be46 | 2020-12-04 13:15:30 +0100 | [diff] [blame] | 170 | }; |
| 171 | |
| 172 | struct tests tests[] = { |
Ole Troan | fb0afab | 2021-02-11 11:13:46 +0100 | [diff] [blame] | 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\"}" }, |
Ole Troan | cf0102b | 2021-02-12 11:48:12 +0100 | [diff] [blame] | 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\" }}" }, |
Ole Troan | 316967c | 2021-02-16 00:31:52 +0100 | [diff] [blame] | 191 | { .s = "{\"_msgname\": \"test_addresses\", \"a\": \"1.2.3.4\" }" }, |
| 192 | { .s = "{\"_msgname\": \"test_addresses\", \"a\": \"2001:db8::23\" }" }, |
Ole Troan | 93c4b1b | 2021-02-16 18:09:51 +0100 | [diff] [blame] | 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\"}" }, |
Ole Troan | 71134f2 | 2021-02-17 14:10:04 +0100 | [diff] [blame] | 198 | { .s = "{\"_msgname\": \"test_interface\", \"sw_if_index\": 100 }" }, |
Filip Tehlar | 36217e3 | 2021-07-23 08:51:10 +0000 | [diff] [blame] | 199 | { .s = "{\"_msgname\": \"test_interface\", \"sw_if_index\": 4294967295 }" }, |
Ole Troan | 793be46 | 2020-12-04 13:15:30 +0100 | [diff] [blame] | 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 | } |