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 <vppinfra/string.h>
26 #include <vapi/vapi.h>
27 #include <vapi/vpe.api.vapi.h>
28 #include <vapi/interface.api.vapi.h>
29 #include <vapi/l2.api.vapi.h>
30 #include <vapi/stats.api.vapi.h>
31 #include <fake.api.vapi.h>
33 DEFINE_VAPI_MSG_IDS_VPE_API_JSON;
34 DEFINE_VAPI_MSG_IDS_INTERFACE_API_JSON;
35 DEFINE_VAPI_MSG_IDS_L2_API_JSON;
36 DEFINE_VAPI_MSG_IDS_STATS_API_JSON;
37 DEFINE_VAPI_MSG_IDS_FAKE_API_JSON;
39 static char *app_name = NULL;
40 static char *api_prefix = NULL;
41 static const int max_outstanding_requests = 64;
42 static const int response_queue_size = 32;
44 /* centos has ancient check so we hack our way around here
45 * to make it work somehow */
46 #ifndef ck_assert_ptr_eq
47 #define ck_assert_ptr_eq(X,Y) ck_assert_int_eq((long)X, (long)Y)
50 #ifndef ck_assert_ptr_ne
51 #define ck_assert_ptr_ne(X,Y) ck_assert_int_ne((long)X, (long)Y)
54 START_TEST (test_invalid_values)
57 vapi_error_e rv = vapi_ctx_alloc (&ctx);
58 ck_assert_int_eq (VAPI_OK, rv);
59 vapi_msg_show_version *sv = vapi_alloc_show_version (ctx);
60 ck_assert_ptr_eq (NULL, sv);
61 rv = vapi_send (ctx, sv);
62 ck_assert_int_eq (VAPI_EINVAL, rv);
63 rv = vapi_connect (ctx, app_name, api_prefix, max_outstanding_requests,
64 response_queue_size, VAPI_MODE_BLOCKING, true);
65 ck_assert_int_eq (VAPI_OK, rv);
66 rv = vapi_send (ctx, NULL);
67 ck_assert_int_eq (VAPI_EINVAL, rv);
68 rv = vapi_send (NULL, NULL);
69 ck_assert_int_eq (VAPI_EINVAL, rv);
70 rv = vapi_recv (NULL, NULL, NULL, 0, 0);
71 ck_assert_int_eq (VAPI_EINVAL, rv);
72 rv = vapi_recv (ctx, NULL, NULL, 0, 0);
73 ck_assert_int_eq (VAPI_EINVAL, rv);
74 vapi_msg_show_version_reply *reply;
75 rv = vapi_recv (ctx, (void **) &reply, NULL, 0, 0);
76 ck_assert_int_eq (VAPI_EINVAL, rv);
77 rv = vapi_disconnect (ctx);
78 ck_assert_int_eq (VAPI_OK, rv);
84 START_TEST (test_hton_1)
86 const u16 _vl_msg_id = 1;
87 vapi_type_msg_header1_t h;
88 h._vl_msg_id = _vl_msg_id;
89 vapi_type_msg_header1_t_hton (&h);
90 ck_assert_int_eq (be16toh (h._vl_msg_id), _vl_msg_id);
95 START_TEST (test_hton_2)
97 const u16 _vl_msg_id = 1;
98 const u32 client_index = 3;
99 vapi_type_msg_header2_t h;
100 h._vl_msg_id = _vl_msg_id;
101 h.client_index = client_index;
102 vapi_type_msg_header2_t_hton (&h);
103 ck_assert_int_eq (be16toh (h._vl_msg_id), _vl_msg_id);
104 ck_assert_int_eq (h.client_index, client_index);
109 START_TEST (test_hton_3)
111 const size_t data_size = 10;
112 vapi_msg_vnet_interface_combined_counters *m =
113 malloc (sizeof (vapi_msg_vnet_interface_combined_counters) +
114 data_size * sizeof (vapi_type_vlib_counter));
115 ck_assert_ptr_ne (NULL, m);
116 vapi_payload_vnet_interface_combined_counters *p = &m->payload;
117 const u16 _vl_msg_id = 1;
118 p->_vl_msg_id = _vl_msg_id;
119 const u32 first_sw_if_index = 2;
120 p->first_sw_if_index = first_sw_if_index;
121 p->count = data_size;
122 const u64 packets = 1234;
123 const u64 bytes = 2345;
125 for (i = 0; i < data_size; ++i)
127 p->data[i].packets = packets;
128 p->data[i].bytes = bytes;
130 vapi_msg_vnet_interface_combined_counters_hton (m);
131 ck_assert_int_eq (_vl_msg_id, be16toh (p->_vl_msg_id));
132 ck_assert_int_eq (first_sw_if_index, be32toh (p->first_sw_if_index));
133 ck_assert_int_eq (data_size, be32toh (p->count));
134 for (i = 0; i < data_size; ++i)
136 ck_assert_int_eq (packets, be64toh (p->data[i].packets));
137 ck_assert_int_eq (bytes, be64toh (p->data[i].bytes));
144 #define verify_hton_swap(expr, value) \
145 if (4 == sizeof (expr)) \
147 ck_assert_int_eq (expr, htobe32 (value)); \
149 else if (2 == sizeof (expr)) \
151 ck_assert_int_eq (expr, htobe16 (value)); \
155 ck_assert_int_eq (expr, value); \
158 START_TEST (test_hton_4)
160 const int vla_count = 3;
161 char x[sizeof (vapi_msg_bridge_domain_details) +
162 vla_count * sizeof (vapi_type_bridge_domain_sw_if)];
163 vapi_msg_bridge_domain_details *d = (void *) x;
165 d->header._vl_msg_id = cnt++;
166 d->header.context = cnt++;
167 d->payload.bd_id = cnt++;
168 d->payload.flood = cnt++;
169 d->payload.uu_flood = cnt++;
170 d->payload.forward = cnt++;
171 d->payload.learn = cnt++;
172 d->payload.arp_term = cnt++;
173 d->payload.mac_age = cnt++;
174 d->payload.bvi_sw_if_index = cnt++;
175 d->payload.n_sw_ifs = vla_count;
177 for (i = 0; i < vla_count; ++i)
179 vapi_type_bridge_domain_sw_if *det = &d->payload.sw_if_details[i];
180 det->context = cnt++;
181 det->sw_if_index = cnt++;
184 ck_assert_int_eq (sizeof (x), vapi_calc_bridge_domain_details_msg_size (d));
185 vapi_msg_bridge_domain_details_hton (d);
187 verify_hton_swap (d->header._vl_msg_id, tmp);
189 ck_assert_int_eq (d->header.context, tmp);
191 verify_hton_swap (d->payload.bd_id, tmp);
193 verify_hton_swap (d->payload.flood, tmp);
195 verify_hton_swap (d->payload.uu_flood, tmp);
197 verify_hton_swap (d->payload.forward, tmp);
199 verify_hton_swap (d->payload.learn, tmp);
201 verify_hton_swap (d->payload.arp_term, tmp);
203 verify_hton_swap (d->payload.mac_age, tmp);
205 verify_hton_swap (d->payload.bvi_sw_if_index, tmp);
207 ck_assert_int_eq (d->payload.n_sw_ifs, htobe32 (vla_count));
208 for (i = 0; i < vla_count; ++i)
210 vapi_type_bridge_domain_sw_if *det = &d->payload.sw_if_details[i];
211 verify_hton_swap (det->context, tmp);
213 verify_hton_swap (det->sw_if_index, tmp);
215 verify_hton_swap (det->shg, tmp);
218 vapi_msg_bridge_domain_details_ntoh (d);
220 ck_assert_int_eq (d->header._vl_msg_id, tmp);
222 ck_assert_int_eq (d->header.context, tmp);
224 ck_assert_int_eq (d->payload.bd_id, tmp);
226 ck_assert_int_eq (d->payload.flood, tmp);
228 ck_assert_int_eq (d->payload.uu_flood, tmp);
230 ck_assert_int_eq (d->payload.forward, tmp);
232 ck_assert_int_eq (d->payload.learn, tmp);
234 ck_assert_int_eq (d->payload.arp_term, tmp);
236 ck_assert_int_eq (d->payload.mac_age, tmp);
238 ck_assert_int_eq (d->payload.bvi_sw_if_index, tmp);
240 ck_assert_int_eq (d->payload.n_sw_ifs, vla_count);
241 for (i = 0; i < vla_count; ++i)
243 vapi_type_bridge_domain_sw_if *det = &d->payload.sw_if_details[i];
244 ck_assert_int_eq (det->context, tmp);
246 ck_assert_int_eq (det->sw_if_index, tmp);
248 ck_assert_int_eq (det->shg, tmp);
251 ck_assert_int_eq (sizeof (x), vapi_calc_bridge_domain_details_msg_size (d));
256 START_TEST (test_ntoh_1)
258 const u16 _vl_msg_id = 1;
259 vapi_type_msg_header1_t h;
260 h._vl_msg_id = _vl_msg_id;
261 vapi_type_msg_header1_t_ntoh (&h);
262 ck_assert_int_eq (htobe16 (h._vl_msg_id), _vl_msg_id);
267 START_TEST (test_ntoh_2)
269 const u16 _vl_msg_id = 1;
270 const u32 client_index = 3;
271 vapi_type_msg_header2_t h;
272 h._vl_msg_id = _vl_msg_id;
273 h.client_index = client_index;
274 vapi_type_msg_header2_t_ntoh (&h);
275 ck_assert_int_eq (htobe16 (h._vl_msg_id), _vl_msg_id);
276 ck_assert_int_eq (h.client_index, client_index);
281 START_TEST (test_ntoh_3)
283 const size_t data_size = 10;
284 vapi_msg_vnet_interface_combined_counters *m =
285 malloc (sizeof (vapi_msg_vnet_interface_combined_counters) +
286 data_size * sizeof (vapi_type_vlib_counter));
287 ck_assert_ptr_ne (NULL, m);
288 vapi_payload_vnet_interface_combined_counters *p = &m->payload;
289 const u16 _vl_msg_id = 1;
290 p->_vl_msg_id = _vl_msg_id;
291 const u32 first_sw_if_index = 2;
292 p->first_sw_if_index = first_sw_if_index;
293 const size_t be_data_size = htobe32 (data_size);
294 p->count = be_data_size;
295 const u64 packets = 1234;
296 const u64 bytes = 2345;
298 for (i = 0; i < data_size; ++i)
300 p->data[i].packets = packets;
301 p->data[i].bytes = bytes;
303 vapi_msg_vnet_interface_combined_counters_ntoh (m);
304 ck_assert_int_eq (_vl_msg_id, be16toh (p->_vl_msg_id));
305 ck_assert_int_eq (first_sw_if_index, be32toh (p->first_sw_if_index));
306 ck_assert_int_eq (be_data_size, be32toh (p->count));
307 for (i = 0; i < data_size; ++i)
309 ck_assert_int_eq (packets, htobe64 (p->data[i].packets));
310 ck_assert_int_eq (bytes, htobe64 (p->data[i].bytes));
317 #define verify_ntoh_swap(expr, value) \
318 if (4 == sizeof (expr)) \
320 ck_assert_int_eq (expr, be32toh (value)); \
322 else if (2 == sizeof (expr)) \
324 ck_assert_int_eq (expr, be16toh (value)); \
328 ck_assert_int_eq (expr, value); \
331 START_TEST (test_ntoh_4)
333 const int vla_count = 3;
334 char x[sizeof (vapi_msg_bridge_domain_details) +
335 vla_count * sizeof (vapi_type_bridge_domain_sw_if)];
336 vapi_msg_bridge_domain_details *d = (void *) x;
338 d->header._vl_msg_id = cnt++;
339 d->header.context = cnt++;
340 d->payload.bd_id = cnt++;
341 d->payload.flood = cnt++;
342 d->payload.uu_flood = cnt++;
343 d->payload.forward = cnt++;
344 d->payload.learn = cnt++;
345 d->payload.arp_term = cnt++;
346 d->payload.mac_age = cnt++;
347 d->payload.bvi_sw_if_index = cnt++;
348 d->payload.n_sw_ifs = htobe32 (vla_count);
350 for (i = 0; i < vla_count; ++i)
352 vapi_type_bridge_domain_sw_if *det = &d->payload.sw_if_details[i];
353 det->context = cnt++;
354 det->sw_if_index = cnt++;
357 vapi_msg_bridge_domain_details_ntoh (d);
358 ck_assert_int_eq (sizeof (x), vapi_calc_bridge_domain_details_msg_size (d));
360 verify_ntoh_swap (d->header._vl_msg_id, tmp);
362 ck_assert_int_eq (d->header.context, tmp);
364 verify_ntoh_swap (d->payload.bd_id, tmp);
366 verify_ntoh_swap (d->payload.flood, tmp);
368 verify_ntoh_swap (d->payload.uu_flood, tmp);
370 verify_ntoh_swap (d->payload.forward, tmp);
372 verify_ntoh_swap (d->payload.learn, tmp);
374 verify_ntoh_swap (d->payload.arp_term, tmp);
376 verify_ntoh_swap (d->payload.mac_age, tmp);
378 verify_ntoh_swap (d->payload.bvi_sw_if_index, tmp);
380 ck_assert_int_eq (d->payload.n_sw_ifs, vla_count);
381 for (i = 0; i < vla_count; ++i)
383 vapi_type_bridge_domain_sw_if *det = &d->payload.sw_if_details[i];
384 verify_ntoh_swap (det->context, tmp);
386 verify_ntoh_swap (det->sw_if_index, tmp);
388 verify_ntoh_swap (det->shg, tmp);
391 vapi_msg_bridge_domain_details_hton (d);
393 ck_assert_int_eq (d->header._vl_msg_id, tmp);
395 ck_assert_int_eq (d->header.context, tmp);
397 ck_assert_int_eq (d->payload.bd_id, tmp);
399 ck_assert_int_eq (d->payload.flood, tmp);
401 ck_assert_int_eq (d->payload.uu_flood, tmp);
403 ck_assert_int_eq (d->payload.forward, tmp);
405 ck_assert_int_eq (d->payload.learn, tmp);
407 ck_assert_int_eq (d->payload.arp_term, tmp);
409 ck_assert_int_eq (d->payload.mac_age, tmp);
411 ck_assert_int_eq (d->payload.bvi_sw_if_index, tmp);
413 ck_assert_int_eq (d->payload.n_sw_ifs, htobe32 (vla_count));
414 for (i = 0; i < vla_count; ++i)
416 vapi_type_bridge_domain_sw_if *det = &d->payload.sw_if_details[i];
417 ck_assert_int_eq (det->context, tmp);
419 ck_assert_int_eq (det->sw_if_index, tmp);
421 ck_assert_int_eq (det->shg, tmp);
429 show_version_cb (vapi_ctx_t ctx, void *caller_ctx,
430 vapi_error_e rv, bool is_last,
431 vapi_payload_show_version_reply * p)
433 ck_assert_int_eq (VAPI_OK, rv);
434 ck_assert_int_eq (true, is_last);
435 ck_assert_str_eq ("vpe", (char *) p->program);
437 ("show_version_reply: program: `%s', version: `%s', build directory: "
438 "`%s', build date: `%s'\n", p->program, p->version, p->build_directory,
440 ++*(int *) caller_ctx;
448 u32 *sw_if_index_storage;
449 } test_create_loopback_ctx_t;
452 loopback_create_cb (vapi_ctx_t ctx, void *caller_ctx,
453 vapi_error_e rv, bool is_last,
454 vapi_payload_create_loopback_reply * p)
456 test_create_loopback_ctx_t *clc = caller_ctx;
457 ck_assert_int_eq (clc->expected_retval, p->retval);
458 *clc->sw_if_index_storage = p->sw_if_index;
467 u32 *sw_if_index_storage;
468 } test_delete_loopback_ctx_t;
471 loopback_delete_cb (vapi_ctx_t ctx, void *caller_ctx,
472 vapi_error_e rv, bool is_last,
473 vapi_payload_delete_loopback_reply * p)
475 test_delete_loopback_ctx_t *dlc = caller_ctx;
476 ck_assert_int_eq (dlc->expected_retval, p->retval);
481 START_TEST (test_connect)
484 vapi_error_e rv = vapi_ctx_alloc (&ctx);
485 ck_assert_int_eq (VAPI_OK, rv);
486 rv = vapi_connect (ctx, app_name, api_prefix, max_outstanding_requests,
487 response_queue_size, VAPI_MODE_BLOCKING, true);
488 ck_assert_int_eq (VAPI_OK, rv);
489 rv = vapi_disconnect (ctx);
490 ck_assert_int_eq (VAPI_OK, rv);
499 setup_blocking (void)
501 vapi_error_e rv = vapi_ctx_alloc (&ctx);
502 ck_assert_int_eq (VAPI_OK, rv);
503 rv = vapi_connect (ctx, app_name, api_prefix, max_outstanding_requests,
504 response_queue_size, VAPI_MODE_BLOCKING, true);
505 ck_assert_int_eq (VAPI_OK, rv);
509 setup_nonblocking (void)
511 vapi_error_e rv = vapi_ctx_alloc (&ctx);
512 ck_assert_int_eq (VAPI_OK, rv);
513 rv = vapi_connect (ctx, app_name, api_prefix, max_outstanding_requests,
514 response_queue_size, VAPI_MODE_NONBLOCKING, true);
515 ck_assert_int_eq (VAPI_OK, rv);
521 vapi_disconnect (ctx);
525 START_TEST (test_show_version_1)
527 printf ("--- Basic show version message - reply test ---\n");
528 vapi_msg_show_version *sv = vapi_alloc_show_version (ctx);
529 ck_assert_ptr_ne (NULL, sv);
530 vapi_msg_show_version_hton (sv);
531 vapi_error_e rv = vapi_send (ctx, sv);
532 ck_assert_int_eq (VAPI_OK, rv);
533 vapi_msg_show_version_reply *resp;
535 rv = vapi_recv (ctx, (void *) &resp, &size, 0, 0);
536 ck_assert_int_eq (VAPI_OK, rv);
538 show_version_cb (NULL, &dummy, VAPI_OK, true, &resp->payload);
539 vapi_msg_free (ctx, resp);
544 START_TEST (test_show_version_2)
547 printf ("--- Show version via blocking callback API ---\n");
548 const int attempts = response_queue_size * 4;
550 for (i = 0; i < attempts; ++i)
552 vapi_msg_show_version *sv = vapi_alloc_show_version (ctx);
553 ck_assert_ptr_ne (NULL, sv);
554 vapi_error_e rv = vapi_show_version (ctx, sv, show_version_cb, &called);
555 ck_assert_int_eq (VAPI_OK, rv);
557 ck_assert_int_eq (attempts, called);
569 } sw_interface_dump_ctx;
572 sw_interface_dump_cb (struct vapi_ctx_s *ctx, void *callback_ctx,
573 vapi_error_e rv, bool is_last,
574 vapi_payload_sw_interface_details * reply)
576 sw_interface_dump_ctx *dctx = callback_ctx;
577 ck_assert_int_eq (false, dctx->last_called);
580 ck_assert (NULL == reply);
581 dctx->last_called = true;
585 ck_assert (NULL != reply);
586 printf ("Interface dump entry: [%u]: %s\n", reply->sw_if_index,
587 reply->interface_name);
589 for (i = 0; i < dctx->num_ifs; ++i)
591 if (dctx->sw_if_indexes[i] == reply->sw_if_index)
593 ck_assert_int_eq (false, dctx->seen[i]);
594 dctx->seen[i] = true;
602 START_TEST (test_loopbacks_1)
604 printf ("--- Create/delete loopbacks using blocking API ---\n");
605 const size_t num_ifs = 5;
606 u8 mac_addresses[num_ifs][6];
607 clib_memset (&mac_addresses, 0, sizeof (mac_addresses));
608 u32 sw_if_indexes[num_ifs];
609 clib_memset (&sw_if_indexes, 0xff, sizeof (sw_if_indexes));
610 test_create_loopback_ctx_t clcs[num_ifs];
611 clib_memset (&clcs, 0, sizeof (clcs));
612 test_delete_loopback_ctx_t dlcs[num_ifs];
613 clib_memset (&dlcs, 0, sizeof (dlcs));
615 for (i = 0; i < num_ifs; ++i)
617 memcpy (&mac_addresses[i], "\1\2\3\4\5\6", 6);
618 mac_addresses[i][5] = i;
619 clcs[i].sw_if_index_storage = &sw_if_indexes[i];
621 for (i = 0; i < num_ifs; ++i)
623 vapi_msg_create_loopback *cl = vapi_alloc_create_loopback (ctx);
624 memcpy (cl->payload.mac_address, mac_addresses[i],
625 sizeof (cl->payload.mac_address));
627 vapi_create_loopback (ctx, cl, loopback_create_cb, &clcs[i]);
628 ck_assert_int_eq (VAPI_OK, rv);
630 for (i = 0; i < num_ifs; ++i)
632 ck_assert_int_eq (1, clcs[i].called);
633 printf ("Created loopback with MAC %02x:%02x:%02x:%02x:%02x:%02x --> "
635 mac_addresses[i][0], mac_addresses[i][1], mac_addresses[i][2],
636 mac_addresses[i][3], mac_addresses[i][4], mac_addresses[i][5],
640 sw_interface_dump_ctx dctx = { false, num_ifs, sw_if_indexes, seen, 0 };
641 vapi_msg_sw_interface_dump *dump;
643 const int attempts = response_queue_size * 4;
644 for (i = 0; i < attempts; ++i)
646 dctx.last_called = false;
647 clib_memset (&seen, 0, sizeof (seen));
648 dump = vapi_alloc_sw_interface_dump (ctx);
649 dump->payload.name_filter_valid = 0;
650 clib_memset (dump->payload.name_filter, 0,
651 sizeof (dump->payload.name_filter));
652 while (VAPI_EAGAIN ==
654 vapi_sw_interface_dump (ctx, dump, sw_interface_dump_cb,
657 ck_assert_int_eq (true, dctx.last_called);
659 for (j = 0; j < num_ifs; ++j)
661 ck_assert_int_eq (true, seen[j]);
664 clib_memset (&seen, 0, sizeof (seen));
665 for (i = 0; i < num_ifs; ++i)
667 vapi_msg_delete_loopback *dl = vapi_alloc_delete_loopback (ctx);
668 dl->payload.sw_if_index = sw_if_indexes[i];
670 vapi_delete_loopback (ctx, dl, loopback_delete_cb, &dlcs[i]);
671 ck_assert_int_eq (VAPI_OK, rv);
673 for (i = 0; i < num_ifs; ++i)
675 ck_assert_int_eq (1, dlcs[i].called);
676 printf ("Deleted loopback with sw_if_index %u\n", sw_if_indexes[i]);
678 dctx.last_called = false;
679 clib_memset (&seen, 0, sizeof (seen));
680 dump = vapi_alloc_sw_interface_dump (ctx);
681 dump->payload.name_filter_valid = 0;
682 clib_memset (dump->payload.name_filter, 0,
683 sizeof (dump->payload.name_filter));
684 while (VAPI_EAGAIN ==
686 vapi_sw_interface_dump (ctx, dump, sw_interface_dump_cb, &dctx)))
688 ck_assert_int_eq (true, dctx.last_called);
689 for (i = 0; i < num_ifs; ++i)
691 ck_assert_int_eq (false, seen[i]);
697 START_TEST (test_show_version_3)
699 printf ("--- Show version via async callback ---\n");
702 vapi_msg_show_version *sv = vapi_alloc_show_version (ctx);
703 ck_assert_ptr_ne (NULL, sv);
704 while (VAPI_EAGAIN ==
705 (rv = vapi_show_version (ctx, sv, show_version_cb, &called)))
707 ck_assert_int_eq (VAPI_OK, rv);
708 ck_assert_int_eq (0, called);
709 rv = vapi_dispatch (ctx);
710 ck_assert_int_eq (VAPI_OK, rv);
711 ck_assert_int_eq (1, called);
713 rv = vapi_dispatch (ctx);
714 ck_assert_int_eq (VAPI_OK, rv);
715 ck_assert_int_eq (0, called);
720 START_TEST (test_show_version_4)
722 printf ("--- Show version via async callback - multiple messages ---\n");
724 const size_t num_req = 5;
725 int contexts[num_req];
726 clib_memset (contexts, 0, sizeof (contexts));
728 for (i = 0; i < num_req; ++i)
730 vapi_msg_show_version *sv = vapi_alloc_show_version (ctx);
731 ck_assert_ptr_ne (NULL, sv);
732 while (VAPI_EAGAIN ==
734 vapi_show_version (ctx, sv, show_version_cb, &contexts[i])))
736 ck_assert_int_eq (VAPI_OK, rv);
738 for (j = 0; j < num_req; ++j)
740 ck_assert_int_eq (0, contexts[j]);
743 rv = vapi_dispatch (ctx);
744 ck_assert_int_eq (VAPI_OK, rv);
745 for (i = 0; i < num_req; ++i)
747 ck_assert_int_eq (1, contexts[i]);
749 clib_memset (contexts, 0, sizeof (contexts));
750 rv = vapi_dispatch (ctx);
751 ck_assert_int_eq (VAPI_OK, rv);
752 for (i = 0; i < num_req; ++i)
754 ck_assert_int_eq (0, contexts[i]);
760 START_TEST (test_loopbacks_2)
762 printf ("--- Create/delete loopbacks using non-blocking API ---\n");
764 const size_t num_ifs = 5;
765 u8 mac_addresses[num_ifs][6];
766 clib_memset (&mac_addresses, 0, sizeof (mac_addresses));
767 u32 sw_if_indexes[num_ifs];
768 clib_memset (&sw_if_indexes, 0xff, sizeof (sw_if_indexes));
769 test_create_loopback_ctx_t clcs[num_ifs];
770 clib_memset (&clcs, 0, sizeof (clcs));
771 test_delete_loopback_ctx_t dlcs[num_ifs];
772 clib_memset (&dlcs, 0, sizeof (dlcs));
774 for (i = 0; i < num_ifs; ++i)
776 memcpy (&mac_addresses[i], "\1\2\3\4\5\6", 6);
777 mac_addresses[i][5] = i;
778 clcs[i].sw_if_index_storage = &sw_if_indexes[i];
780 for (i = 0; i < num_ifs; ++i)
782 vapi_msg_create_loopback *cl = vapi_alloc_create_loopback (ctx);
783 memcpy (cl->payload.mac_address, mac_addresses[i],
784 sizeof (cl->payload.mac_address));
785 while (VAPI_EAGAIN ==
787 vapi_create_loopback (ctx, cl, loopback_create_cb, &clcs[i])))
789 ck_assert_int_eq (VAPI_OK, rv);
791 rv = vapi_dispatch (ctx);
792 ck_assert_int_eq (VAPI_OK, rv);
793 for (i = 0; i < num_ifs; ++i)
795 ck_assert_int_eq (1, clcs[i].called);
796 printf ("Loopback with MAC %02x:%02x:%02x:%02x:%02x:%02x --> "
798 mac_addresses[i][0], mac_addresses[i][1], mac_addresses[i][2],
799 mac_addresses[i][3], mac_addresses[i][4], mac_addresses[i][5],
803 clib_memset (&seen, 0, sizeof (seen));
804 sw_interface_dump_ctx dctx = { false, num_ifs, sw_if_indexes, seen, 0 };
805 vapi_msg_sw_interface_dump *dump = vapi_alloc_sw_interface_dump (ctx);
806 dump->payload.name_filter_valid = 0;
807 clib_memset (dump->payload.name_filter, 0,
808 sizeof (dump->payload.name_filter));
809 while (VAPI_EAGAIN ==
811 vapi_sw_interface_dump (ctx, dump, sw_interface_dump_cb, &dctx)))
813 for (i = 0; i < num_ifs; ++i)
815 ck_assert_int_eq (false, seen[i]);
817 clib_memset (&seen, 0, sizeof (seen));
818 ck_assert_int_eq (false, dctx.last_called);
819 rv = vapi_dispatch (ctx);
820 ck_assert_int_eq (VAPI_OK, rv);
821 for (i = 0; i < num_ifs; ++i)
823 ck_assert_int_eq (true, seen[i]);
825 clib_memset (&seen, 0, sizeof (seen));
826 ck_assert_int_eq (true, dctx.last_called);
827 for (i = 0; i < num_ifs; ++i)
829 vapi_msg_delete_loopback *dl = vapi_alloc_delete_loopback (ctx);
830 dl->payload.sw_if_index = sw_if_indexes[i];
831 while (VAPI_EAGAIN ==
833 vapi_delete_loopback (ctx, dl, loopback_delete_cb, &dlcs[i])))
835 ck_assert_int_eq (VAPI_OK, rv);
837 rv = vapi_dispatch (ctx);
838 ck_assert_int_eq (VAPI_OK, rv);
839 for (i = 0; i < num_ifs; ++i)
841 ck_assert_int_eq (1, dlcs[i].called);
842 printf ("Deleted loopback with sw_if_index %u\n", sw_if_indexes[i]);
844 clib_memset (&seen, 0, sizeof (seen));
845 dctx.last_called = false;
846 dump = vapi_alloc_sw_interface_dump (ctx);
847 dump->payload.name_filter_valid = 0;
848 clib_memset (dump->payload.name_filter, 0,
849 sizeof (dump->payload.name_filter));
850 while (VAPI_EAGAIN ==
852 vapi_sw_interface_dump (ctx, dump, sw_interface_dump_cb, &dctx)))
854 rv = vapi_dispatch (ctx);
855 ck_assert_int_eq (VAPI_OK, rv);
856 for (i = 0; i < num_ifs; ++i)
858 ck_assert_int_eq (false, seen[i]);
860 clib_memset (&seen, 0, sizeof (seen));
861 ck_assert_int_eq (true, dctx.last_called);
867 interface_simple_stats_cb (vapi_ctx_t ctx, void *callback_ctx,
868 vapi_error_e rv, bool is_last,
869 vapi_payload_want_interface_simple_stats_reply *
876 simple_counters_cb (vapi_ctx_t ctx, void *callback_ctx,
877 vapi_payload_vnet_interface_simple_counters * payload)
879 int *called = callback_ctx;
881 printf ("simple counters: first_sw_if_index=%u\n",
882 payload->first_sw_if_index);
886 START_TEST (test_stats_1)
888 printf ("--- Receive stats using generic blocking API ---\n");
889 vapi_msg_want_interface_simple_stats *ws =
890 vapi_alloc_want_interface_simple_stats (ctx);
891 ws->payload.enable_disable = 1;
892 ws->payload.pid = getpid ();
894 rv = vapi_want_interface_simple_stats (ctx, ws, interface_simple_stats_cb,
896 ck_assert_int_eq (VAPI_OK, rv);
898 vapi_set_event_cb (ctx, vapi_msg_id_vnet_interface_simple_counters,
899 (vapi_event_cb) simple_counters_cb, &called);
900 rv = vapi_dispatch_one (ctx);
901 ck_assert_int_eq (VAPI_OK, rv);
902 ck_assert_int_eq (1, called);
907 START_TEST (test_stats_2)
909 printf ("--- Receive stats using stat-specific blocking API ---\n");
910 vapi_msg_want_interface_simple_stats *ws =
911 vapi_alloc_want_interface_simple_stats (ctx);
912 ws->payload.enable_disable = 1;
913 ws->payload.pid = getpid ();
915 rv = vapi_want_interface_simple_stats (ctx, ws, interface_simple_stats_cb,
917 ck_assert_int_eq (VAPI_OK, rv);
919 vapi_set_vapi_msg_vnet_interface_simple_counters_event_cb (ctx,
922 rv = vapi_dispatch_one (ctx);
923 ck_assert_int_eq (VAPI_OK, rv);
924 ck_assert_int_eq (1, called);
930 generic_cb (vapi_ctx_t ctx, void *callback_ctx, vapi_msg_id_t id, void *msg)
932 int *called = callback_ctx;
933 ck_assert_int_eq (0, *called);
935 ck_assert_int_eq (id, vapi_msg_id_show_version_reply);
936 ck_assert_ptr_ne (NULL, msg);
937 vapi_msg_show_version_reply *reply = msg;
938 ck_assert_str_eq ("vpe", (char *) reply->payload.program);
942 START_TEST (test_show_version_5)
944 printf ("--- Receive show version using generic callback - nonblocking "
947 vapi_msg_show_version *sv = vapi_alloc_show_version (ctx);
948 ck_assert_ptr_ne (NULL, sv);
949 vapi_msg_show_version_hton (sv);
950 while (VAPI_EAGAIN == (rv = vapi_send (ctx, sv)))
952 ck_assert_int_eq (VAPI_OK, rv);
954 vapi_set_generic_event_cb (ctx, generic_cb, &called);
955 ck_assert_int_eq (VAPI_OK, rv);
956 rv = vapi_dispatch_one (ctx);
957 ck_assert_int_eq (VAPI_OK, rv);
958 ck_assert_int_eq (1, called);
959 sv = vapi_alloc_show_version (ctx);
960 ck_assert_ptr_ne (NULL, sv);
961 vapi_msg_show_version_hton (sv);
962 while (VAPI_EAGAIN == (rv = vapi_send (ctx, sv)))
964 ck_assert_int_eq (VAPI_OK, rv);
965 vapi_clear_generic_event_cb (ctx);
966 rv = vapi_dispatch_one (ctx);
967 ck_assert_int_eq (VAPI_OK, rv);
968 ck_assert_int_eq (1, called); /* needs to remain unchanged */
974 combined_counters_cb (struct vapi_ctx_s *ctx, void *callback_ctx,
975 vapi_payload_vnet_interface_combined_counters * payload)
977 int *called = callback_ctx;
979 printf ("combined counters: first_sw_if_index=%u\n",
980 payload->first_sw_if_index);
985 stats_cb (vapi_ctx_t ctx, void *callback_ctx, vapi_error_e rv,
986 bool is_last, vapi_payload_want_stats_reply * payload)
991 START_TEST (test_stats_3)
993 printf ("--- Receive multiple stats using stat-specific non-blocking API "
995 vapi_msg_want_stats *ws = vapi_alloc_want_stats (ctx);
996 ws->payload.enable_disable = 1;
997 ws->payload.pid = getpid ();
999 rv = vapi_want_stats (ctx, ws, stats_cb, NULL);
1000 ck_assert_int_eq (VAPI_OK, rv);
1003 vapi_set_vapi_msg_vnet_interface_simple_counters_event_cb (ctx,
1006 vapi_set_vapi_msg_vnet_interface_combined_counters_event_cb (ctx,
1007 combined_counters_cb,
1009 while (!called || !called2)
1011 if (VAPI_EAGAIN != (rv = vapi_dispatch_one (ctx)))
1013 ck_assert_int_eq (VAPI_OK, rv);
1021 show_version_no_cb (vapi_ctx_t ctx, void *caller_ctx,
1022 vapi_error_e rv, bool is_last,
1023 vapi_payload_show_version_reply * p)
1025 ck_assert_int_eq (VAPI_ENORESP, rv);
1026 ck_assert_int_eq (true, is_last);
1027 ck_assert_ptr_eq (NULL, p);
1028 ++*(int *) caller_ctx;
1032 START_TEST (test_no_response_1)
1034 printf ("--- Simulate no response to regular message ---\n");
1036 vapi_msg_show_version *sv = vapi_alloc_show_version (ctx);
1037 ck_assert_ptr_ne (NULL, sv);
1038 sv->header._vl_msg_id = ~0; /* malformed ID causes vpp to drop the msg */
1040 while (VAPI_EAGAIN ==
1041 (rv = vapi_show_version (ctx, sv, show_version_no_cb, &called)))
1043 ck_assert_int_eq (VAPI_OK, rv);
1044 sv = vapi_alloc_show_version (ctx);
1045 ck_assert_ptr_ne (NULL, sv);
1046 while (VAPI_EAGAIN ==
1047 (rv = vapi_show_version (ctx, sv, show_version_cb, &called)))
1049 ck_assert_int_eq (VAPI_OK, rv);
1050 rv = vapi_dispatch (ctx);
1051 ck_assert_int_eq (VAPI_OK, rv);
1052 ck_assert_int_eq (2, called);
1058 no_msg_cb (struct vapi_ctx_s *ctx, void *callback_ctx,
1059 vapi_error_e rv, bool is_last,
1060 vapi_payload_sw_interface_details * reply)
1062 int *called = callback_ctx;
1064 ck_assert_int_eq (VAPI_OK, rv);
1065 ck_assert_int_eq (true, is_last);
1066 ck_assert_ptr_eq (NULL, reply);
1070 START_TEST (test_no_response_2)
1072 printf ("--- Simulate no response to dump message ---\n");
1074 vapi_msg_sw_interface_dump *dump = vapi_alloc_sw_interface_dump (ctx);
1075 dump->header._vl_msg_id = ~0; /* malformed ID causes vpp to drop the msg */
1077 while (VAPI_EAGAIN ==
1078 (rv = vapi_sw_interface_dump (ctx, dump, no_msg_cb, &no_called)))
1080 ck_assert_int_eq (VAPI_OK, rv);
1081 rv = vapi_dispatch (ctx);
1082 ck_assert_int_eq (VAPI_OK, rv);
1083 ck_assert_int_eq (1, no_called);
1088 START_TEST (test_unsupported)
1090 printf ("--- Unsupported messages ---\n");
1091 bool available = vapi_is_msg_available (ctx, vapi_msg_id_test_fake_msg);
1092 ck_assert_int_eq (false, available);
1100 Suite *s = suite_create ("VAPI test");
1102 TCase *tc_negative = tcase_create ("Negative tests");
1103 tcase_add_test (tc_negative, test_invalid_values);
1104 suite_add_tcase (s, tc_negative);
1106 TCase *tc_swap = tcase_create ("Byteswap tests");
1107 tcase_add_test (tc_swap, test_hton_1);
1108 tcase_add_test (tc_swap, test_hton_2);
1109 tcase_add_test (tc_swap, test_hton_3);
1110 tcase_add_test (tc_swap, test_hton_4);
1111 tcase_add_test (tc_swap, test_ntoh_1);
1112 tcase_add_test (tc_swap, test_ntoh_2);
1113 tcase_add_test (tc_swap, test_ntoh_3);
1114 tcase_add_test (tc_swap, test_ntoh_4);
1115 suite_add_tcase (s, tc_swap);
1117 TCase *tc_connect = tcase_create ("Connect");
1118 tcase_add_test (tc_connect, test_connect);
1119 suite_add_tcase (s, tc_connect);
1121 TCase *tc_block = tcase_create ("Blocking API");
1122 tcase_set_timeout (tc_block, 25);
1123 tcase_add_checked_fixture (tc_block, setup_blocking, teardown);
1124 tcase_add_test (tc_block, test_show_version_1);
1125 tcase_add_test (tc_block, test_show_version_2);
1126 tcase_add_test (tc_block, test_loopbacks_1);
1127 tcase_add_test (tc_block, test_stats_1);
1128 tcase_add_test (tc_block, test_stats_2);
1129 suite_add_tcase (s, tc_block);
1131 TCase *tc_nonblock = tcase_create ("Nonblocking API");
1132 tcase_set_timeout (tc_nonblock, 25);
1133 tcase_add_checked_fixture (tc_nonblock, setup_nonblocking, teardown);
1134 tcase_add_test (tc_nonblock, test_show_version_3);
1135 tcase_add_test (tc_nonblock, test_show_version_4);
1136 tcase_add_test (tc_nonblock, test_show_version_5);
1137 tcase_add_test (tc_nonblock, test_loopbacks_2);
1138 tcase_add_test (tc_nonblock, test_stats_3);
1139 tcase_add_test (tc_nonblock, test_no_response_1);
1140 tcase_add_test (tc_nonblock, test_no_response_2);
1141 suite_add_tcase (s, tc_nonblock);
1143 TCase *tc_unsupported = tcase_create ("Unsupported message");
1144 tcase_add_checked_fixture (tc_unsupported, setup_blocking, teardown);
1145 tcase_add_test (tc_unsupported, test_unsupported);
1146 suite_add_tcase (s, tc_unsupported);
1152 main (int argc, char *argv[])
1156 printf ("Invalid argc==`%d'\n", argc);
1157 return EXIT_FAILURE;
1160 api_prefix = argv[2];
1161 printf ("App name: `%s', API prefix: `%s'\n", app_name, api_prefix);
1168 sr = srunner_create (s);
1170 srunner_run_all (sr, CK_NORMAL);
1171 number_failed = srunner_ntests_failed (sr);
1173 return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
1177 * fd.io coding-style-patch-verification: ON
1180 * eval: (c-set-style "gnu")