2 *------------------------------------------------------------------
3 * Copyright (c) 2017 Cisco and/or its affiliates.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *------------------------------------------------------------------
25 #include <vapi/vapi.h>
26 #include <vapi/vpe.api.vapi.h>
27 #include <vapi/interface.api.vapi.h>
28 #include <vapi/l2.api.vapi.h>
29 #include <vapi/stats.api.vapi.h>
30 #include <fake.api.vapi.h>
32 DEFINE_VAPI_MSG_IDS_VPE_API_JSON;
33 DEFINE_VAPI_MSG_IDS_INTERFACE_API_JSON;
34 DEFINE_VAPI_MSG_IDS_L2_API_JSON;
35 DEFINE_VAPI_MSG_IDS_STATS_API_JSON;
36 DEFINE_VAPI_MSG_IDS_FAKE_API_JSON;
38 static char *app_name = NULL;
39 static char *api_prefix = NULL;
40 static const int max_outstanding_requests = 64;
41 static const int response_queue_size = 32;
43 START_TEST (test_invalid_values)
46 vapi_error_e rv = vapi_ctx_alloc (&ctx);
47 ck_assert_int_eq (VAPI_OK, rv);
48 vapi_msg_show_version *sv = vapi_alloc_show_version (ctx);
49 ck_assert_ptr_eq (NULL, sv);
50 rv = vapi_send (ctx, sv);
51 ck_assert_int_eq (VAPI_EINVAL, rv);
52 rv = vapi_connect (ctx, app_name, api_prefix, max_outstanding_requests,
53 response_queue_size, VAPI_MODE_BLOCKING);
54 ck_assert_int_eq (VAPI_OK, rv);
55 rv = vapi_send (ctx, NULL);
56 ck_assert_int_eq (VAPI_EINVAL, rv);
57 rv = vapi_send (NULL, NULL);
58 ck_assert_int_eq (VAPI_EINVAL, rv);
59 rv = vapi_recv (NULL, NULL, NULL);
60 ck_assert_int_eq (VAPI_EINVAL, rv);
61 rv = vapi_recv (ctx, NULL, NULL);
62 ck_assert_int_eq (VAPI_EINVAL, rv);
63 vapi_msg_show_version_reply *reply;
64 rv = vapi_recv (ctx, (void **) &reply, NULL);
65 ck_assert_int_eq (VAPI_EINVAL, rv);
66 rv = vapi_disconnect (ctx);
67 ck_assert_int_eq (VAPI_OK, rv);
73 START_TEST (test_hton_1)
75 const u16 _vl_msg_id = 1;
76 vapi_type_msg_header1_t h;
77 h._vl_msg_id = _vl_msg_id;
78 vapi_type_msg_header1_t_hton (&h);
79 ck_assert_int_eq (be16toh (h._vl_msg_id), _vl_msg_id);
84 START_TEST (test_hton_2)
86 const u16 _vl_msg_id = 1;
87 const u32 client_index = 3;
88 vapi_type_msg_header2_t h;
89 h._vl_msg_id = _vl_msg_id;
90 h.client_index = client_index;
91 vapi_type_msg_header2_t_hton (&h);
92 ck_assert_int_eq (be16toh (h._vl_msg_id), _vl_msg_id);
93 ck_assert_int_eq (h.client_index, client_index);
98 START_TEST (test_hton_3)
100 const size_t data_size = 10;
101 vapi_msg_vnet_interface_combined_counters *m =
102 malloc (sizeof (vapi_msg_vnet_interface_combined_counters) +
103 data_size * sizeof (vapi_type_vlib_counter));
104 ck_assert_ptr_ne (NULL, m);
105 vapi_payload_vnet_interface_combined_counters *p = &m->payload;
106 const u16 _vl_msg_id = 1;
107 p->_vl_msg_id = _vl_msg_id;
108 const u32 first_sw_if_index = 2;
109 p->first_sw_if_index = first_sw_if_index;
110 p->count = data_size;
111 const u64 packets = 1234;
112 const u64 bytes = 2345;
114 for (i = 0; i < data_size; ++i)
116 p->data[i].packets = packets;
117 p->data[i].bytes = bytes;
119 vapi_msg_vnet_interface_combined_counters_hton (m);
120 ck_assert_int_eq (_vl_msg_id, be16toh (p->_vl_msg_id));
121 ck_assert_int_eq (first_sw_if_index, be32toh (p->first_sw_if_index));
122 ck_assert_int_eq (data_size, be32toh (p->count));
123 for (i = 0; i < data_size; ++i)
125 ck_assert_int_eq (packets, be64toh (p->data[i].packets));
126 ck_assert_int_eq (bytes, be64toh (p->data[i].bytes));
133 #define verify_hton_swap(expr, value) \
134 if (4 == sizeof (expr)) \
136 ck_assert_int_eq (expr, htobe32 (value)); \
138 else if (2 == sizeof (expr)) \
140 ck_assert_int_eq (expr, htobe16 (value)); \
144 ck_assert_int_eq (expr, value); \
147 START_TEST (test_hton_4)
149 const int vla_count = 3;
150 char x[sizeof (vapi_msg_bridge_domain_details) +
151 vla_count * sizeof (vapi_type_bridge_domain_sw_if)];
152 vapi_msg_bridge_domain_details *d = (void *) x;
154 d->header._vl_msg_id = cnt++;
155 d->header.context = cnt++;
156 d->payload.bd_id = cnt++;
157 d->payload.flood = cnt++;
158 d->payload.uu_flood = cnt++;
159 d->payload.forward = cnt++;
160 d->payload.learn = cnt++;
161 d->payload.arp_term = cnt++;
162 d->payload.mac_age = cnt++;
163 d->payload.bvi_sw_if_index = cnt++;
164 d->payload.n_sw_ifs = vla_count;
166 for (i = 0; i < vla_count; ++i)
168 vapi_type_bridge_domain_sw_if *det = &d->payload.sw_if_details[i];
169 det->context = cnt++;
170 det->sw_if_index = cnt++;
173 ck_assert_int_eq (sizeof (x), vapi_calc_bridge_domain_details_msg_size (d));
174 vapi_msg_bridge_domain_details_hton (d);
176 verify_hton_swap (d->header._vl_msg_id, tmp);
178 ck_assert_int_eq (d->header.context, tmp);
180 verify_hton_swap (d->payload.bd_id, tmp);
182 verify_hton_swap (d->payload.flood, tmp);
184 verify_hton_swap (d->payload.uu_flood, tmp);
186 verify_hton_swap (d->payload.forward, tmp);
188 verify_hton_swap (d->payload.learn, tmp);
190 verify_hton_swap (d->payload.arp_term, tmp);
192 verify_hton_swap (d->payload.mac_age, tmp);
194 verify_hton_swap (d->payload.bvi_sw_if_index, tmp);
196 ck_assert_int_eq (d->payload.n_sw_ifs, htobe32 (vla_count));
197 for (i = 0; i < vla_count; ++i)
199 vapi_type_bridge_domain_sw_if *det = &d->payload.sw_if_details[i];
200 verify_hton_swap (det->context, tmp);
202 verify_hton_swap (det->sw_if_index, tmp);
204 verify_hton_swap (det->shg, tmp);
207 vapi_msg_bridge_domain_details_ntoh (d);
209 ck_assert_int_eq (d->header._vl_msg_id, tmp);
211 ck_assert_int_eq (d->header.context, tmp);
213 ck_assert_int_eq (d->payload.bd_id, tmp);
215 ck_assert_int_eq (d->payload.flood, tmp);
217 ck_assert_int_eq (d->payload.uu_flood, tmp);
219 ck_assert_int_eq (d->payload.forward, tmp);
221 ck_assert_int_eq (d->payload.learn, tmp);
223 ck_assert_int_eq (d->payload.arp_term, tmp);
225 ck_assert_int_eq (d->payload.mac_age, tmp);
227 ck_assert_int_eq (d->payload.bvi_sw_if_index, tmp);
229 ck_assert_int_eq (d->payload.n_sw_ifs, vla_count);
230 for (i = 0; i < vla_count; ++i)
232 vapi_type_bridge_domain_sw_if *det = &d->payload.sw_if_details[i];
233 ck_assert_int_eq (det->context, tmp);
235 ck_assert_int_eq (det->sw_if_index, tmp);
237 ck_assert_int_eq (det->shg, tmp);
240 ck_assert_int_eq (sizeof (x), vapi_calc_bridge_domain_details_msg_size (d));
245 START_TEST (test_ntoh_1)
247 const u16 _vl_msg_id = 1;
248 vapi_type_msg_header1_t h;
249 h._vl_msg_id = _vl_msg_id;
250 vapi_type_msg_header1_t_ntoh (&h);
251 ck_assert_int_eq (htobe16 (h._vl_msg_id), _vl_msg_id);
256 START_TEST (test_ntoh_2)
258 const u16 _vl_msg_id = 1;
259 const u32 client_index = 3;
260 vapi_type_msg_header2_t h;
261 h._vl_msg_id = _vl_msg_id;
262 h.client_index = client_index;
263 vapi_type_msg_header2_t_ntoh (&h);
264 ck_assert_int_eq (htobe16 (h._vl_msg_id), _vl_msg_id);
265 ck_assert_int_eq (h.client_index, client_index);
270 START_TEST (test_ntoh_3)
272 const size_t data_size = 10;
273 vapi_msg_vnet_interface_combined_counters *m =
274 malloc (sizeof (vapi_msg_vnet_interface_combined_counters) +
275 data_size * sizeof (vapi_type_vlib_counter));
276 ck_assert_ptr_ne (NULL, m);
277 vapi_payload_vnet_interface_combined_counters *p = &m->payload;
278 const u16 _vl_msg_id = 1;
279 p->_vl_msg_id = _vl_msg_id;
280 const u32 first_sw_if_index = 2;
281 p->first_sw_if_index = first_sw_if_index;
282 const size_t be_data_size = htobe32 (data_size);
283 p->count = be_data_size;
284 const u64 packets = 1234;
285 const u64 bytes = 2345;
287 for (i = 0; i < data_size; ++i)
289 p->data[i].packets = packets;
290 p->data[i].bytes = bytes;
292 vapi_msg_vnet_interface_combined_counters_ntoh (m);
293 ck_assert_int_eq (_vl_msg_id, be16toh (p->_vl_msg_id));
294 ck_assert_int_eq (first_sw_if_index, be32toh (p->first_sw_if_index));
295 ck_assert_int_eq (be_data_size, be32toh (p->count));
296 for (i = 0; i < data_size; ++i)
298 ck_assert_int_eq (packets, htobe64 (p->data[i].packets));
299 ck_assert_int_eq (bytes, htobe64 (p->data[i].bytes));
306 #define verify_ntoh_swap(expr, value) \
307 if (4 == sizeof (expr)) \
309 ck_assert_int_eq (expr, be32toh (value)); \
311 else if (2 == sizeof (expr)) \
313 ck_assert_int_eq (expr, be16toh (value)); \
317 ck_assert_int_eq (expr, value); \
320 START_TEST (test_ntoh_4)
322 const int vla_count = 3;
323 char x[sizeof (vapi_msg_bridge_domain_details) +
324 vla_count * sizeof (vapi_type_bridge_domain_sw_if)];
325 vapi_msg_bridge_domain_details *d = (void *) x;
327 d->header._vl_msg_id = cnt++;
328 d->header.context = cnt++;
329 d->payload.bd_id = cnt++;
330 d->payload.flood = cnt++;
331 d->payload.uu_flood = cnt++;
332 d->payload.forward = cnt++;
333 d->payload.learn = cnt++;
334 d->payload.arp_term = cnt++;
335 d->payload.mac_age = cnt++;
336 d->payload.bvi_sw_if_index = cnt++;
337 d->payload.n_sw_ifs = htobe32 (vla_count);
339 for (i = 0; i < vla_count; ++i)
341 vapi_type_bridge_domain_sw_if *det = &d->payload.sw_if_details[i];
342 det->context = cnt++;
343 det->sw_if_index = cnt++;
346 vapi_msg_bridge_domain_details_ntoh (d);
347 ck_assert_int_eq (sizeof (x), vapi_calc_bridge_domain_details_msg_size (d));
349 verify_ntoh_swap (d->header._vl_msg_id, tmp);
351 ck_assert_int_eq (d->header.context, tmp);
353 verify_ntoh_swap (d->payload.bd_id, tmp);
355 verify_ntoh_swap (d->payload.flood, tmp);
357 verify_ntoh_swap (d->payload.uu_flood, tmp);
359 verify_ntoh_swap (d->payload.forward, tmp);
361 verify_ntoh_swap (d->payload.learn, tmp);
363 verify_ntoh_swap (d->payload.arp_term, tmp);
365 verify_ntoh_swap (d->payload.mac_age, tmp);
367 verify_ntoh_swap (d->payload.bvi_sw_if_index, tmp);
369 ck_assert_int_eq (d->payload.n_sw_ifs, vla_count);
370 for (i = 0; i < vla_count; ++i)
372 vapi_type_bridge_domain_sw_if *det = &d->payload.sw_if_details[i];
373 verify_ntoh_swap (det->context, tmp);
375 verify_ntoh_swap (det->sw_if_index, tmp);
377 verify_ntoh_swap (det->shg, tmp);
380 vapi_msg_bridge_domain_details_hton (d);
382 ck_assert_int_eq (d->header._vl_msg_id, tmp);
384 ck_assert_int_eq (d->header.context, tmp);
386 ck_assert_int_eq (d->payload.bd_id, tmp);
388 ck_assert_int_eq (d->payload.flood, tmp);
390 ck_assert_int_eq (d->payload.uu_flood, tmp);
392 ck_assert_int_eq (d->payload.forward, tmp);
394 ck_assert_int_eq (d->payload.learn, tmp);
396 ck_assert_int_eq (d->payload.arp_term, tmp);
398 ck_assert_int_eq (d->payload.mac_age, tmp);
400 ck_assert_int_eq (d->payload.bvi_sw_if_index, tmp);
402 ck_assert_int_eq (d->payload.n_sw_ifs, htobe32 (vla_count));
403 for (i = 0; i < vla_count; ++i)
405 vapi_type_bridge_domain_sw_if *det = &d->payload.sw_if_details[i];
406 ck_assert_int_eq (det->context, tmp);
408 ck_assert_int_eq (det->sw_if_index, tmp);
410 ck_assert_int_eq (det->shg, tmp);
418 show_version_cb (vapi_ctx_t ctx, void *caller_ctx,
419 vapi_error_e rv, bool is_last,
420 vapi_payload_show_version_reply * p)
422 ck_assert_int_eq (VAPI_OK, rv);
423 ck_assert_int_eq (true, is_last);
424 ck_assert_str_eq ("vpe", (char *) p->program);
426 ("show_version_reply: program: `%s', version: `%s', build directory: "
427 "`%s', build date: `%s'\n", p->program, p->version, p->build_directory,
429 ++*(int *) caller_ctx;
437 u32 *sw_if_index_storage;
438 } test_create_loopback_ctx_t;
441 loopback_create_cb (vapi_ctx_t ctx, void *caller_ctx,
442 vapi_error_e rv, bool is_last,
443 vapi_payload_create_loopback_reply * p)
445 test_create_loopback_ctx_t *clc = caller_ctx;
446 ck_assert_int_eq (clc->expected_retval, p->retval);
447 *clc->sw_if_index_storage = p->sw_if_index;
456 u32 *sw_if_index_storage;
457 } test_delete_loopback_ctx_t;
460 loopback_delete_cb (vapi_ctx_t ctx, void *caller_ctx,
461 vapi_error_e rv, bool is_last,
462 vapi_payload_delete_loopback_reply * p)
464 test_delete_loopback_ctx_t *dlc = caller_ctx;
465 ck_assert_int_eq (dlc->expected_retval, p->retval);
470 START_TEST (test_connect)
473 vapi_error_e rv = vapi_ctx_alloc (&ctx);
474 ck_assert_int_eq (VAPI_OK, rv);
475 rv = vapi_connect (ctx, app_name, api_prefix, max_outstanding_requests,
476 response_queue_size, VAPI_MODE_BLOCKING);
477 ck_assert_int_eq (VAPI_OK, rv);
478 rv = vapi_disconnect (ctx);
479 ck_assert_int_eq (VAPI_OK, rv);
488 setup_blocking (void)
490 vapi_error_e rv = vapi_ctx_alloc (&ctx);
491 ck_assert_int_eq (VAPI_OK, rv);
492 rv = vapi_connect (ctx, app_name, api_prefix, max_outstanding_requests,
493 response_queue_size, VAPI_MODE_BLOCKING);
494 ck_assert_int_eq (VAPI_OK, rv);
498 setup_nonblocking (void)
500 vapi_error_e rv = vapi_ctx_alloc (&ctx);
501 ck_assert_int_eq (VAPI_OK, rv);
502 rv = vapi_connect (ctx, app_name, api_prefix, max_outstanding_requests,
503 response_queue_size, VAPI_MODE_NONBLOCKING);
504 ck_assert_int_eq (VAPI_OK, rv);
510 vapi_disconnect (ctx);
514 START_TEST (test_show_version_1)
516 printf ("--- Basic show version message - reply test ---\n");
517 vapi_msg_show_version *sv = vapi_alloc_show_version (ctx);
518 ck_assert_ptr_ne (NULL, sv);
519 vapi_msg_show_version_hton (sv);
520 vapi_error_e rv = vapi_send (ctx, sv);
521 ck_assert_int_eq (VAPI_OK, rv);
522 vapi_msg_show_version_reply *resp;
524 rv = vapi_recv (ctx, (void *) &resp, &size);
525 ck_assert_int_eq (VAPI_OK, rv);
527 show_version_cb (NULL, &dummy, VAPI_OK, true, &resp->payload);
528 vapi_msg_free (ctx, resp);
533 START_TEST (test_show_version_2)
536 printf ("--- Show version via blocking callback API ---\n");
537 const int attempts = response_queue_size * 4;
539 for (i = 0; i < attempts; ++i)
541 vapi_msg_show_version *sv = vapi_alloc_show_version (ctx);
542 ck_assert_ptr_ne (NULL, sv);
543 vapi_error_e rv = vapi_show_version (ctx, sv, show_version_cb, &called);
544 ck_assert_int_eq (VAPI_OK, rv);
546 ck_assert_int_eq (attempts, called);
558 } sw_interface_dump_ctx;
561 sw_interface_dump_cb (struct vapi_ctx_s *ctx, void *callback_ctx,
562 vapi_error_e rv, bool is_last,
563 vapi_payload_sw_interface_details * reply)
565 sw_interface_dump_ctx *dctx = callback_ctx;
566 ck_assert_int_eq (false, dctx->last_called);
569 ck_assert (NULL == reply);
570 dctx->last_called = true;
575 printf ("Interface dump entry: [%u]: %s\n", reply->sw_if_index,
576 reply->interface_name);
578 for (i = 0; i < dctx->num_ifs; ++i)
580 if (dctx->sw_if_indexes[i] == reply->sw_if_index)
582 ck_assert_int_eq (false, dctx->seen[i]);
583 dctx->seen[i] = true;
591 START_TEST (test_loopbacks_1)
593 printf ("--- Create/delete loopbacks using blocking API ---\n");
594 const size_t num_ifs = 5;
595 u8 mac_addresses[num_ifs][6];
596 memset (&mac_addresses, 0, sizeof (mac_addresses));
597 u32 sw_if_indexes[num_ifs];
598 memset (&sw_if_indexes, 0xff, sizeof (sw_if_indexes));
599 test_create_loopback_ctx_t clcs[num_ifs];
600 memset (&clcs, 0, sizeof (clcs));
601 test_delete_loopback_ctx_t dlcs[num_ifs];
602 memset (&dlcs, 0, sizeof (dlcs));
604 for (i = 0; i < num_ifs; ++i)
606 memcpy (&mac_addresses[i], "\1\2\3\4\5\6", 6);
607 mac_addresses[i][5] = i;
608 clcs[i].sw_if_index_storage = &sw_if_indexes[i];
610 for (i = 0; i < num_ifs; ++i)
612 vapi_msg_create_loopback *cl = vapi_alloc_create_loopback (ctx);
613 memcpy (cl->payload.mac_address, mac_addresses[i],
614 sizeof (cl->payload.mac_address));
616 vapi_create_loopback (ctx, cl, loopback_create_cb, &clcs[i]);
617 ck_assert_int_eq (VAPI_OK, rv);
619 for (i = 0; i < num_ifs; ++i)
621 ck_assert_int_eq (1, clcs[i].called);
622 printf ("Created loopback with MAC %02x:%02x:%02x:%02x:%02x:%02x --> "
624 mac_addresses[i][0], mac_addresses[i][1], mac_addresses[i][2],
625 mac_addresses[i][3], mac_addresses[i][4], mac_addresses[i][5],
629 sw_interface_dump_ctx dctx = { false, num_ifs, sw_if_indexes, seen, 0 };
630 vapi_msg_sw_interface_dump *dump;
632 const int attempts = response_queue_size * 4;
633 for (i = 0; i < attempts; ++i)
635 dctx.last_called = false;
636 memset (&seen, 0, sizeof (seen));
637 dump = vapi_alloc_sw_interface_dump (ctx);
638 dump->payload.name_filter_valid = 0;
639 memset (dump->payload.name_filter, 0,
640 sizeof (dump->payload.name_filter));
641 while (VAPI_EAGAIN ==
643 vapi_sw_interface_dump (ctx, dump, sw_interface_dump_cb,
646 ck_assert_int_eq (true, dctx.last_called);
648 for (j = 0; j < num_ifs; ++j)
650 ck_assert_int_eq (true, seen[j]);
653 memset (&seen, 0, sizeof (seen));
654 for (i = 0; i < num_ifs; ++i)
656 vapi_msg_delete_loopback *dl = vapi_alloc_delete_loopback (ctx);
657 dl->payload.sw_if_index = sw_if_indexes[i];
659 vapi_delete_loopback (ctx, dl, loopback_delete_cb, &dlcs[i]);
660 ck_assert_int_eq (VAPI_OK, rv);
662 for (i = 0; i < num_ifs; ++i)
664 ck_assert_int_eq (1, dlcs[i].called);
665 printf ("Deleted loopback with sw_if_index %u\n", sw_if_indexes[i]);
667 dctx.last_called = false;
668 memset (&seen, 0, sizeof (seen));
669 dump = vapi_alloc_sw_interface_dump (ctx);
670 dump->payload.name_filter_valid = 0;
671 memset (dump->payload.name_filter, 0, sizeof (dump->payload.name_filter));
672 while (VAPI_EAGAIN ==
674 vapi_sw_interface_dump (ctx, dump, sw_interface_dump_cb, &dctx)))
676 ck_assert_int_eq (true, dctx.last_called);
677 for (i = 0; i < num_ifs; ++i)
679 ck_assert_int_eq (false, seen[i]);
685 START_TEST (test_show_version_3)
687 printf ("--- Show version via async callback ---\n");
690 vapi_msg_show_version *sv = vapi_alloc_show_version (ctx);
691 ck_assert_ptr_ne (NULL, sv);
692 while (VAPI_EAGAIN ==
693 (rv = vapi_show_version (ctx, sv, show_version_cb, &called)))
695 ck_assert_int_eq (VAPI_OK, rv);
696 ck_assert_int_eq (0, called);
697 rv = vapi_dispatch (ctx);
698 ck_assert_int_eq (VAPI_OK, rv);
699 ck_assert_int_eq (1, called);
701 rv = vapi_dispatch (ctx);
702 ck_assert_int_eq (VAPI_OK, rv);
703 ck_assert_int_eq (0, called);
708 START_TEST (test_show_version_4)
710 printf ("--- Show version via async callback - multiple messages ---\n");
712 const size_t num_req = 5;
713 int contexts[num_req];
714 memset (contexts, 0, sizeof (contexts));
716 for (i = 0; i < num_req; ++i)
718 vapi_msg_show_version *sv = vapi_alloc_show_version (ctx);
719 ck_assert_ptr_ne (NULL, sv);
720 while (VAPI_EAGAIN ==
722 vapi_show_version (ctx, sv, show_version_cb, &contexts[i])))
724 ck_assert_int_eq (VAPI_OK, rv);
726 for (j = 0; j < num_req; ++j)
728 ck_assert_int_eq (0, contexts[j]);
731 rv = vapi_dispatch (ctx);
732 ck_assert_int_eq (VAPI_OK, rv);
733 for (i = 0; i < num_req; ++i)
735 ck_assert_int_eq (1, contexts[i]);
737 memset (contexts, 0, sizeof (contexts));
738 rv = vapi_dispatch (ctx);
739 ck_assert_int_eq (VAPI_OK, rv);
740 for (i = 0; i < num_req; ++i)
742 ck_assert_int_eq (0, contexts[i]);
748 START_TEST (test_loopbacks_2)
750 printf ("--- Create/delete loopbacks using non-blocking API ---\n");
752 const size_t num_ifs = 5;
753 u8 mac_addresses[num_ifs][6];
754 memset (&mac_addresses, 0, sizeof (mac_addresses));
755 u32 sw_if_indexes[num_ifs];
756 memset (&sw_if_indexes, 0xff, sizeof (sw_if_indexes));
757 test_create_loopback_ctx_t clcs[num_ifs];
758 memset (&clcs, 0, sizeof (clcs));
759 test_delete_loopback_ctx_t dlcs[num_ifs];
760 memset (&dlcs, 0, sizeof (dlcs));
762 for (i = 0; i < num_ifs; ++i)
764 memcpy (&mac_addresses[i], "\1\2\3\4\5\6", 6);
765 mac_addresses[i][5] = i;
766 clcs[i].sw_if_index_storage = &sw_if_indexes[i];
768 for (i = 0; i < num_ifs; ++i)
770 vapi_msg_create_loopback *cl = vapi_alloc_create_loopback (ctx);
771 memcpy (cl->payload.mac_address, mac_addresses[i],
772 sizeof (cl->payload.mac_address));
773 while (VAPI_EAGAIN ==
775 vapi_create_loopback (ctx, cl, loopback_create_cb, &clcs[i])))
777 ck_assert_int_eq (VAPI_OK, rv);
779 rv = vapi_dispatch (ctx);
780 ck_assert_int_eq (VAPI_OK, rv);
781 for (i = 0; i < num_ifs; ++i)
783 ck_assert_int_eq (1, clcs[i].called);
784 printf ("Loopback with MAC %02x:%02x:%02x:%02x:%02x:%02x --> "
786 mac_addresses[i][0], mac_addresses[i][1], mac_addresses[i][2],
787 mac_addresses[i][3], mac_addresses[i][4], mac_addresses[i][5],
791 memset (&seen, 0, sizeof (seen));
792 sw_interface_dump_ctx dctx = { false, num_ifs, sw_if_indexes, seen, 0 };
793 vapi_msg_sw_interface_dump *dump = vapi_alloc_sw_interface_dump (ctx);
794 dump->payload.name_filter_valid = 0;
795 memset (dump->payload.name_filter, 0, sizeof (dump->payload.name_filter));
796 while (VAPI_EAGAIN ==
798 vapi_sw_interface_dump (ctx, dump, sw_interface_dump_cb, &dctx)))
800 for (i = 0; i < num_ifs; ++i)
802 ck_assert_int_eq (false, seen[i]);
804 memset (&seen, 0, sizeof (seen));
805 ck_assert_int_eq (false, dctx.last_called);
806 rv = vapi_dispatch (ctx);
807 ck_assert_int_eq (VAPI_OK, rv);
808 for (i = 0; i < num_ifs; ++i)
810 ck_assert_int_eq (true, seen[i]);
812 memset (&seen, 0, sizeof (seen));
813 ck_assert_int_eq (true, dctx.last_called);
814 for (i = 0; i < num_ifs; ++i)
816 vapi_msg_delete_loopback *dl = vapi_alloc_delete_loopback (ctx);
817 dl->payload.sw_if_index = sw_if_indexes[i];
818 while (VAPI_EAGAIN ==
820 vapi_delete_loopback (ctx, dl, loopback_delete_cb, &dlcs[i])))
822 ck_assert_int_eq (VAPI_OK, rv);
824 rv = vapi_dispatch (ctx);
825 ck_assert_int_eq (VAPI_OK, rv);
826 for (i = 0; i < num_ifs; ++i)
828 ck_assert_int_eq (1, dlcs[i].called);
829 printf ("Deleted loopback with sw_if_index %u\n", sw_if_indexes[i]);
831 memset (&seen, 0, sizeof (seen));
832 dctx.last_called = false;
833 dump = vapi_alloc_sw_interface_dump (ctx);
834 dump->payload.name_filter_valid = 0;
835 memset (dump->payload.name_filter, 0, sizeof (dump->payload.name_filter));
836 while (VAPI_EAGAIN ==
838 vapi_sw_interface_dump (ctx, dump, sw_interface_dump_cb, &dctx)))
840 rv = vapi_dispatch (ctx);
841 ck_assert_int_eq (VAPI_OK, rv);
842 for (i = 0; i < num_ifs; ++i)
844 ck_assert_int_eq (false, seen[i]);
846 memset (&seen, 0, sizeof (seen));
847 ck_assert_int_eq (true, dctx.last_called);
853 interface_simple_stats_cb (vapi_ctx_t ctx, void *callback_ctx,
854 vapi_error_e rv, bool is_last,
855 vapi_payload_want_interface_simple_stats_reply *
862 simple_counters_cb (vapi_ctx_t ctx, void *callback_ctx,
863 vapi_payload_vnet_interface_simple_counters * payload)
865 int *called = callback_ctx;
867 printf ("simple counters: first_sw_if_index=%u\n",
868 payload->first_sw_if_index);
872 START_TEST (test_stats_1)
874 printf ("--- Receive stats using generic blocking API ---\n");
875 vapi_msg_want_interface_simple_stats *ws =
876 vapi_alloc_want_interface_simple_stats (ctx);
877 ws->payload.enable_disable = 1;
878 ws->payload.pid = getpid ();
880 rv = vapi_want_interface_simple_stats (ctx, ws, interface_simple_stats_cb,
882 ck_assert_int_eq (VAPI_OK, rv);
884 vapi_set_event_cb (ctx, vapi_msg_id_vnet_interface_simple_counters,
885 (vapi_event_cb) simple_counters_cb, &called);
886 rv = vapi_dispatch_one (ctx);
887 ck_assert_int_eq (VAPI_OK, rv);
888 ck_assert_int_eq (1, called);
893 START_TEST (test_stats_2)
895 printf ("--- Receive stats using stat-specific blocking API ---\n");
896 vapi_msg_want_interface_simple_stats *ws =
897 vapi_alloc_want_interface_simple_stats (ctx);
898 ws->payload.enable_disable = 1;
899 ws->payload.pid = getpid ();
901 rv = vapi_want_interface_simple_stats (ctx, ws, interface_simple_stats_cb,
903 ck_assert_int_eq (VAPI_OK, rv);
905 vapi_set_vapi_msg_vnet_interface_simple_counters_event_cb (ctx,
908 rv = vapi_dispatch_one (ctx);
909 ck_assert_int_eq (VAPI_OK, rv);
910 ck_assert_int_eq (1, called);
916 generic_cb (vapi_ctx_t ctx, void *callback_ctx, vapi_msg_id_t id, void *msg)
918 int *called = callback_ctx;
919 ck_assert_int_eq (0, *called);
921 ck_assert_int_eq (id, vapi_msg_id_show_version_reply);
922 ck_assert_ptr_ne (NULL, msg);
923 vapi_msg_show_version_reply *reply = msg;
924 ck_assert_str_eq ("vpe", (char *) reply->payload.program);
928 START_TEST (test_show_version_5)
930 printf ("--- Receive show version using generic callback - nonblocking "
933 vapi_msg_show_version *sv = vapi_alloc_show_version (ctx);
934 ck_assert_ptr_ne (NULL, sv);
935 vapi_msg_show_version_hton (sv);
936 while (VAPI_EAGAIN == (rv = vapi_send (ctx, sv)))
938 ck_assert_int_eq (VAPI_OK, rv);
940 vapi_set_generic_event_cb (ctx, generic_cb, &called);
941 ck_assert_int_eq (VAPI_OK, rv);
942 rv = vapi_dispatch_one (ctx);
943 ck_assert_int_eq (VAPI_OK, rv);
944 ck_assert_int_eq (1, called);
945 sv = vapi_alloc_show_version (ctx);
946 ck_assert_ptr_ne (NULL, sv);
947 vapi_msg_show_version_hton (sv);
948 while (VAPI_EAGAIN == (rv = vapi_send (ctx, sv)))
950 ck_assert_int_eq (VAPI_OK, rv);
951 vapi_clear_generic_event_cb (ctx);
952 rv = vapi_dispatch_one (ctx);
953 ck_assert_int_eq (VAPI_OK, rv);
954 ck_assert_int_eq (1, called); /* needs to remain unchanged */
960 combined_counters_cb (struct vapi_ctx_s *ctx, void *callback_ctx,
961 vapi_payload_vnet_interface_combined_counters * payload)
963 int *called = callback_ctx;
965 printf ("combined counters: first_sw_if_index=%u\n",
966 payload->first_sw_if_index);
971 stats_cb (vapi_ctx_t ctx, void *callback_ctx, vapi_error_e rv,
972 bool is_last, vapi_payload_want_stats_reply * payload)
977 START_TEST (test_stats_3)
979 printf ("--- Receive multiple stats using stat-specific non-blocking API "
981 vapi_msg_want_stats *ws = vapi_alloc_want_stats (ctx);
982 ws->payload.enable_disable = 1;
983 ws->payload.pid = getpid ();
985 rv = vapi_want_stats (ctx, ws, stats_cb, NULL);
986 ck_assert_int_eq (VAPI_OK, rv);
989 vapi_set_vapi_msg_vnet_interface_simple_counters_event_cb (ctx,
992 vapi_set_vapi_msg_vnet_interface_combined_counters_event_cb (ctx,
993 combined_counters_cb,
995 while (!called || !called2)
997 if (VAPI_EAGAIN != (rv = vapi_dispatch_one (ctx)))
999 ck_assert_int_eq (VAPI_OK, rv);
1007 show_version_no_cb (vapi_ctx_t ctx, void *caller_ctx,
1008 vapi_error_e rv, bool is_last,
1009 vapi_payload_show_version_reply * p)
1011 ck_assert_int_eq (VAPI_ENORESP, rv);
1012 ck_assert_int_eq (true, is_last);
1013 ck_assert_ptr_eq (NULL, p);
1014 ++*(int *) caller_ctx;
1018 START_TEST (test_no_response_1)
1020 printf ("--- Simulate no response to regular message ---\n");
1022 vapi_msg_show_version *sv = vapi_alloc_show_version (ctx);
1023 ck_assert_ptr_ne (NULL, sv);
1024 sv->header._vl_msg_id = ~0; /* malformed ID causes vpp to drop the msg */
1026 while (VAPI_EAGAIN ==
1027 (rv = vapi_show_version (ctx, sv, show_version_no_cb, &called)))
1029 ck_assert_int_eq (VAPI_OK, rv);
1030 sv = vapi_alloc_show_version (ctx);
1031 ck_assert_ptr_ne (NULL, sv);
1032 while (VAPI_EAGAIN ==
1033 (rv = vapi_show_version (ctx, sv, show_version_cb, &called)))
1035 ck_assert_int_eq (VAPI_OK, rv);
1036 rv = vapi_dispatch (ctx);
1037 ck_assert_int_eq (VAPI_OK, rv);
1038 ck_assert_int_eq (2, called);
1044 no_msg_cb (struct vapi_ctx_s *ctx, void *callback_ctx,
1045 vapi_error_e rv, bool is_last,
1046 vapi_payload_sw_interface_details * reply)
1048 int *called = callback_ctx;
1050 ck_assert_int_eq (VAPI_OK, rv);
1051 ck_assert_int_eq (true, is_last);
1052 ck_assert_ptr_eq (NULL, reply);
1056 START_TEST (test_no_response_2)
1058 printf ("--- Simulate no response to dump message ---\n");
1060 vapi_msg_sw_interface_dump *dump = vapi_alloc_sw_interface_dump (ctx);
1061 dump->header._vl_msg_id = ~0; /* malformed ID causes vpp to drop the msg */
1063 while (VAPI_EAGAIN ==
1064 (rv = vapi_sw_interface_dump (ctx, dump, no_msg_cb, &no_called)))
1066 ck_assert_int_eq (VAPI_OK, rv);
1067 rv = vapi_dispatch (ctx);
1068 ck_assert_int_eq (VAPI_OK, rv);
1069 ck_assert_int_eq (1, no_called);
1074 START_TEST (test_unsupported)
1076 printf ("--- Unsupported messages ---\n");
1077 bool available = vapi_is_msg_available (ctx, vapi_msg_id_test_fake_msg);
1078 ck_assert_int_eq (false, available);
1086 Suite *s = suite_create ("VAPI test");
1088 TCase *tc_negative = tcase_create ("Negative tests");
1089 tcase_add_test (tc_negative, test_invalid_values);
1090 suite_add_tcase (s, tc_negative);
1092 TCase *tc_swap = tcase_create ("Byteswap tests");
1093 tcase_add_test (tc_swap, test_hton_1);
1094 tcase_add_test (tc_swap, test_hton_2);
1095 tcase_add_test (tc_swap, test_hton_3);
1096 tcase_add_test (tc_swap, test_hton_4);
1097 tcase_add_test (tc_swap, test_ntoh_1);
1098 tcase_add_test (tc_swap, test_ntoh_2);
1099 tcase_add_test (tc_swap, test_ntoh_3);
1100 tcase_add_test (tc_swap, test_ntoh_4);
1101 suite_add_tcase (s, tc_swap);
1103 TCase *tc_connect = tcase_create ("Connect");
1104 tcase_add_test (tc_connect, test_connect);
1105 suite_add_tcase (s, tc_connect);
1107 TCase *tc_block = tcase_create ("Blocking API");
1108 tcase_set_timeout (tc_block, 25);
1109 tcase_add_checked_fixture (tc_block, setup_blocking, teardown);
1110 tcase_add_test (tc_block, test_show_version_1);
1111 tcase_add_test (tc_block, test_show_version_2);
1112 tcase_add_test (tc_block, test_loopbacks_1);
1113 tcase_add_test (tc_block, test_stats_1);
1114 tcase_add_test (tc_block, test_stats_2);
1115 suite_add_tcase (s, tc_block);
1117 TCase *tc_nonblock = tcase_create ("Nonblocking API");
1118 tcase_set_timeout (tc_nonblock, 25);
1119 tcase_add_checked_fixture (tc_nonblock, setup_nonblocking, teardown);
1120 tcase_add_test (tc_nonblock, test_show_version_3);
1121 tcase_add_test (tc_nonblock, test_show_version_4);
1122 tcase_add_test (tc_nonblock, test_show_version_5);
1123 tcase_add_test (tc_nonblock, test_loopbacks_2);
1124 tcase_add_test (tc_nonblock, test_stats_3);
1125 tcase_add_test (tc_nonblock, test_no_response_1);
1126 tcase_add_test (tc_nonblock, test_no_response_2);
1127 suite_add_tcase (s, tc_nonblock);
1129 TCase *tc_unsupported = tcase_create ("Unsupported message");
1130 tcase_add_checked_fixture (tc_unsupported, setup_blocking, teardown);
1131 tcase_add_test (tc_unsupported, test_unsupported);
1132 suite_add_tcase (s, tc_unsupported);
1138 main (int argc, char *argv[])
1142 printf ("Invalid argc==`%d'\n", argc);
1143 return EXIT_FAILURE;
1146 api_prefix = argv[2];
1147 printf ("App name: `%s', API prefix: `%s'\n", app_name, api_prefix);
1154 sr = srunner_create (s);
1156 srunner_run_all (sr, CK_NORMAL);
1157 number_failed = srunner_ntests_failed (sr);
1159 return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
1163 * fd.io coding-style-patch-verification: ON
1166 * eval: (c-set-style "gnu")