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 /* centos has ancient check so we hack our way around here
44 * to make it work somehow */
45 #ifndef ck_assert_ptr_eq
46 #define ck_assert_ptr_eq(X,Y) ck_assert_int_eq((long)X, (long)Y)
49 #ifndef ck_assert_ptr_ne
50 #define ck_assert_ptr_ne(X,Y) ck_assert_int_ne((long)X, (long)Y)
53 START_TEST (test_invalid_values)
56 vapi_error_e rv = vapi_ctx_alloc (&ctx);
57 ck_assert_int_eq (VAPI_OK, rv);
58 vapi_msg_show_version *sv = vapi_alloc_show_version (ctx);
59 ck_assert_ptr_eq (NULL, sv);
60 rv = vapi_send (ctx, sv);
61 ck_assert_int_eq (VAPI_EINVAL, rv);
62 rv = vapi_connect (ctx, app_name, api_prefix, max_outstanding_requests,
63 response_queue_size, VAPI_MODE_BLOCKING, true);
64 ck_assert_int_eq (VAPI_OK, rv);
65 rv = vapi_send (ctx, NULL);
66 ck_assert_int_eq (VAPI_EINVAL, rv);
67 rv = vapi_send (NULL, NULL);
68 ck_assert_int_eq (VAPI_EINVAL, rv);
69 rv = vapi_recv (NULL, NULL, NULL, 0, 0);
70 ck_assert_int_eq (VAPI_EINVAL, rv);
71 rv = vapi_recv (ctx, NULL, NULL, 0, 0);
72 ck_assert_int_eq (VAPI_EINVAL, rv);
73 vapi_msg_show_version_reply *reply;
74 rv = vapi_recv (ctx, (void **) &reply, NULL, 0, 0);
75 ck_assert_int_eq (VAPI_EINVAL, rv);
76 rv = vapi_disconnect (ctx);
77 ck_assert_int_eq (VAPI_OK, rv);
83 START_TEST (test_hton_1)
85 const u16 _vl_msg_id = 1;
86 vapi_type_msg_header1_t h;
87 h._vl_msg_id = _vl_msg_id;
88 vapi_type_msg_header1_t_hton (&h);
89 ck_assert_int_eq (be16toh (h._vl_msg_id), _vl_msg_id);
94 START_TEST (test_hton_2)
96 const u16 _vl_msg_id = 1;
97 const u32 client_index = 3;
98 vapi_type_msg_header2_t h;
99 h._vl_msg_id = _vl_msg_id;
100 h.client_index = client_index;
101 vapi_type_msg_header2_t_hton (&h);
102 ck_assert_int_eq (be16toh (h._vl_msg_id), _vl_msg_id);
103 ck_assert_int_eq (h.client_index, client_index);
108 START_TEST (test_hton_3)
110 const size_t data_size = 10;
111 vapi_msg_vnet_interface_combined_counters *m =
112 malloc (sizeof (vapi_msg_vnet_interface_combined_counters) +
113 data_size * sizeof (vapi_type_vlib_counter));
114 ck_assert_ptr_ne (NULL, m);
115 vapi_payload_vnet_interface_combined_counters *p = &m->payload;
116 const u16 _vl_msg_id = 1;
117 p->_vl_msg_id = _vl_msg_id;
118 const u32 first_sw_if_index = 2;
119 p->first_sw_if_index = first_sw_if_index;
120 p->count = data_size;
121 const u64 packets = 1234;
122 const u64 bytes = 2345;
124 for (i = 0; i < data_size; ++i)
126 p->data[i].packets = packets;
127 p->data[i].bytes = bytes;
129 vapi_msg_vnet_interface_combined_counters_hton (m);
130 ck_assert_int_eq (_vl_msg_id, be16toh (p->_vl_msg_id));
131 ck_assert_int_eq (first_sw_if_index, be32toh (p->first_sw_if_index));
132 ck_assert_int_eq (data_size, be32toh (p->count));
133 for (i = 0; i < data_size; ++i)
135 ck_assert_int_eq (packets, be64toh (p->data[i].packets));
136 ck_assert_int_eq (bytes, be64toh (p->data[i].bytes));
143 #define verify_hton_swap(expr, value) \
144 if (4 == sizeof (expr)) \
146 ck_assert_int_eq (expr, htobe32 (value)); \
148 else if (2 == sizeof (expr)) \
150 ck_assert_int_eq (expr, htobe16 (value)); \
154 ck_assert_int_eq (expr, value); \
157 START_TEST (test_hton_4)
159 const int vla_count = 3;
160 char x[sizeof (vapi_msg_bridge_domain_details) +
161 vla_count * sizeof (vapi_type_bridge_domain_sw_if)];
162 vapi_msg_bridge_domain_details *d = (void *) x;
164 d->header._vl_msg_id = cnt++;
165 d->header.context = cnt++;
166 d->payload.bd_id = cnt++;
167 d->payload.flood = cnt++;
168 d->payload.uu_flood = cnt++;
169 d->payload.forward = cnt++;
170 d->payload.learn = cnt++;
171 d->payload.arp_term = cnt++;
172 d->payload.mac_age = cnt++;
173 d->payload.bvi_sw_if_index = cnt++;
174 d->payload.n_sw_ifs = vla_count;
176 for (i = 0; i < vla_count; ++i)
178 vapi_type_bridge_domain_sw_if *det = &d->payload.sw_if_details[i];
179 det->context = cnt++;
180 det->sw_if_index = cnt++;
183 ck_assert_int_eq (sizeof (x), vapi_calc_bridge_domain_details_msg_size (d));
184 vapi_msg_bridge_domain_details_hton (d);
186 verify_hton_swap (d->header._vl_msg_id, tmp);
188 ck_assert_int_eq (d->header.context, tmp);
190 verify_hton_swap (d->payload.bd_id, tmp);
192 verify_hton_swap (d->payload.flood, tmp);
194 verify_hton_swap (d->payload.uu_flood, tmp);
196 verify_hton_swap (d->payload.forward, tmp);
198 verify_hton_swap (d->payload.learn, tmp);
200 verify_hton_swap (d->payload.arp_term, tmp);
202 verify_hton_swap (d->payload.mac_age, tmp);
204 verify_hton_swap (d->payload.bvi_sw_if_index, tmp);
206 ck_assert_int_eq (d->payload.n_sw_ifs, htobe32 (vla_count));
207 for (i = 0; i < vla_count; ++i)
209 vapi_type_bridge_domain_sw_if *det = &d->payload.sw_if_details[i];
210 verify_hton_swap (det->context, tmp);
212 verify_hton_swap (det->sw_if_index, tmp);
214 verify_hton_swap (det->shg, tmp);
217 vapi_msg_bridge_domain_details_ntoh (d);
219 ck_assert_int_eq (d->header._vl_msg_id, tmp);
221 ck_assert_int_eq (d->header.context, tmp);
223 ck_assert_int_eq (d->payload.bd_id, tmp);
225 ck_assert_int_eq (d->payload.flood, tmp);
227 ck_assert_int_eq (d->payload.uu_flood, tmp);
229 ck_assert_int_eq (d->payload.forward, tmp);
231 ck_assert_int_eq (d->payload.learn, tmp);
233 ck_assert_int_eq (d->payload.arp_term, tmp);
235 ck_assert_int_eq (d->payload.mac_age, tmp);
237 ck_assert_int_eq (d->payload.bvi_sw_if_index, tmp);
239 ck_assert_int_eq (d->payload.n_sw_ifs, vla_count);
240 for (i = 0; i < vla_count; ++i)
242 vapi_type_bridge_domain_sw_if *det = &d->payload.sw_if_details[i];
243 ck_assert_int_eq (det->context, tmp);
245 ck_assert_int_eq (det->sw_if_index, tmp);
247 ck_assert_int_eq (det->shg, tmp);
250 ck_assert_int_eq (sizeof (x), vapi_calc_bridge_domain_details_msg_size (d));
255 START_TEST (test_ntoh_1)
257 const u16 _vl_msg_id = 1;
258 vapi_type_msg_header1_t h;
259 h._vl_msg_id = _vl_msg_id;
260 vapi_type_msg_header1_t_ntoh (&h);
261 ck_assert_int_eq (htobe16 (h._vl_msg_id), _vl_msg_id);
266 START_TEST (test_ntoh_2)
268 const u16 _vl_msg_id = 1;
269 const u32 client_index = 3;
270 vapi_type_msg_header2_t h;
271 h._vl_msg_id = _vl_msg_id;
272 h.client_index = client_index;
273 vapi_type_msg_header2_t_ntoh (&h);
274 ck_assert_int_eq (htobe16 (h._vl_msg_id), _vl_msg_id);
275 ck_assert_int_eq (h.client_index, client_index);
280 START_TEST (test_ntoh_3)
282 const size_t data_size = 10;
283 vapi_msg_vnet_interface_combined_counters *m =
284 malloc (sizeof (vapi_msg_vnet_interface_combined_counters) +
285 data_size * sizeof (vapi_type_vlib_counter));
286 ck_assert_ptr_ne (NULL, m);
287 vapi_payload_vnet_interface_combined_counters *p = &m->payload;
288 const u16 _vl_msg_id = 1;
289 p->_vl_msg_id = _vl_msg_id;
290 const u32 first_sw_if_index = 2;
291 p->first_sw_if_index = first_sw_if_index;
292 const size_t be_data_size = htobe32 (data_size);
293 p->count = be_data_size;
294 const u64 packets = 1234;
295 const u64 bytes = 2345;
297 for (i = 0; i < data_size; ++i)
299 p->data[i].packets = packets;
300 p->data[i].bytes = bytes;
302 vapi_msg_vnet_interface_combined_counters_ntoh (m);
303 ck_assert_int_eq (_vl_msg_id, be16toh (p->_vl_msg_id));
304 ck_assert_int_eq (first_sw_if_index, be32toh (p->first_sw_if_index));
305 ck_assert_int_eq (be_data_size, be32toh (p->count));
306 for (i = 0; i < data_size; ++i)
308 ck_assert_int_eq (packets, htobe64 (p->data[i].packets));
309 ck_assert_int_eq (bytes, htobe64 (p->data[i].bytes));
316 #define verify_ntoh_swap(expr, value) \
317 if (4 == sizeof (expr)) \
319 ck_assert_int_eq (expr, be32toh (value)); \
321 else if (2 == sizeof (expr)) \
323 ck_assert_int_eq (expr, be16toh (value)); \
327 ck_assert_int_eq (expr, value); \
330 START_TEST (test_ntoh_4)
332 const int vla_count = 3;
333 char x[sizeof (vapi_msg_bridge_domain_details) +
334 vla_count * sizeof (vapi_type_bridge_domain_sw_if)];
335 vapi_msg_bridge_domain_details *d = (void *) x;
337 d->header._vl_msg_id = cnt++;
338 d->header.context = cnt++;
339 d->payload.bd_id = cnt++;
340 d->payload.flood = cnt++;
341 d->payload.uu_flood = cnt++;
342 d->payload.forward = cnt++;
343 d->payload.learn = cnt++;
344 d->payload.arp_term = cnt++;
345 d->payload.mac_age = cnt++;
346 d->payload.bvi_sw_if_index = cnt++;
347 d->payload.n_sw_ifs = htobe32 (vla_count);
349 for (i = 0; i < vla_count; ++i)
351 vapi_type_bridge_domain_sw_if *det = &d->payload.sw_if_details[i];
352 det->context = cnt++;
353 det->sw_if_index = cnt++;
356 vapi_msg_bridge_domain_details_ntoh (d);
357 ck_assert_int_eq (sizeof (x), vapi_calc_bridge_domain_details_msg_size (d));
359 verify_ntoh_swap (d->header._vl_msg_id, tmp);
361 ck_assert_int_eq (d->header.context, tmp);
363 verify_ntoh_swap (d->payload.bd_id, tmp);
365 verify_ntoh_swap (d->payload.flood, tmp);
367 verify_ntoh_swap (d->payload.uu_flood, tmp);
369 verify_ntoh_swap (d->payload.forward, tmp);
371 verify_ntoh_swap (d->payload.learn, tmp);
373 verify_ntoh_swap (d->payload.arp_term, tmp);
375 verify_ntoh_swap (d->payload.mac_age, tmp);
377 verify_ntoh_swap (d->payload.bvi_sw_if_index, tmp);
379 ck_assert_int_eq (d->payload.n_sw_ifs, vla_count);
380 for (i = 0; i < vla_count; ++i)
382 vapi_type_bridge_domain_sw_if *det = &d->payload.sw_if_details[i];
383 verify_ntoh_swap (det->context, tmp);
385 verify_ntoh_swap (det->sw_if_index, tmp);
387 verify_ntoh_swap (det->shg, tmp);
390 vapi_msg_bridge_domain_details_hton (d);
392 ck_assert_int_eq (d->header._vl_msg_id, tmp);
394 ck_assert_int_eq (d->header.context, tmp);
396 ck_assert_int_eq (d->payload.bd_id, tmp);
398 ck_assert_int_eq (d->payload.flood, tmp);
400 ck_assert_int_eq (d->payload.uu_flood, tmp);
402 ck_assert_int_eq (d->payload.forward, tmp);
404 ck_assert_int_eq (d->payload.learn, tmp);
406 ck_assert_int_eq (d->payload.arp_term, tmp);
408 ck_assert_int_eq (d->payload.mac_age, tmp);
410 ck_assert_int_eq (d->payload.bvi_sw_if_index, tmp);
412 ck_assert_int_eq (d->payload.n_sw_ifs, htobe32 (vla_count));
413 for (i = 0; i < vla_count; ++i)
415 vapi_type_bridge_domain_sw_if *det = &d->payload.sw_if_details[i];
416 ck_assert_int_eq (det->context, tmp);
418 ck_assert_int_eq (det->sw_if_index, tmp);
420 ck_assert_int_eq (det->shg, tmp);
428 show_version_cb (vapi_ctx_t ctx, void *caller_ctx,
429 vapi_error_e rv, bool is_last,
430 vapi_payload_show_version_reply * p)
432 ck_assert_int_eq (VAPI_OK, rv);
433 ck_assert_int_eq (true, is_last);
434 ck_assert_str_eq ("vpe", (char *) p->program);
436 ("show_version_reply: program: `%s', version: `%s', build directory: "
437 "`%s', build date: `%s'\n", p->program, p->version, p->build_directory,
439 ++*(int *) caller_ctx;
447 u32 *sw_if_index_storage;
448 } test_create_loopback_ctx_t;
451 loopback_create_cb (vapi_ctx_t ctx, void *caller_ctx,
452 vapi_error_e rv, bool is_last,
453 vapi_payload_create_loopback_reply * p)
455 test_create_loopback_ctx_t *clc = caller_ctx;
456 ck_assert_int_eq (clc->expected_retval, p->retval);
457 *clc->sw_if_index_storage = p->sw_if_index;
466 u32 *sw_if_index_storage;
467 } test_delete_loopback_ctx_t;
470 loopback_delete_cb (vapi_ctx_t ctx, void *caller_ctx,
471 vapi_error_e rv, bool is_last,
472 vapi_payload_delete_loopback_reply * p)
474 test_delete_loopback_ctx_t *dlc = caller_ctx;
475 ck_assert_int_eq (dlc->expected_retval, p->retval);
480 START_TEST (test_connect)
483 vapi_error_e rv = vapi_ctx_alloc (&ctx);
484 ck_assert_int_eq (VAPI_OK, rv);
485 rv = vapi_connect (ctx, app_name, api_prefix, max_outstanding_requests,
486 response_queue_size, VAPI_MODE_BLOCKING, true);
487 ck_assert_int_eq (VAPI_OK, rv);
488 rv = vapi_disconnect (ctx);
489 ck_assert_int_eq (VAPI_OK, rv);
498 setup_blocking (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_BLOCKING, true);
504 ck_assert_int_eq (VAPI_OK, rv);
508 setup_nonblocking (void)
510 vapi_error_e rv = vapi_ctx_alloc (&ctx);
511 ck_assert_int_eq (VAPI_OK, rv);
512 rv = vapi_connect (ctx, app_name, api_prefix, max_outstanding_requests,
513 response_queue_size, VAPI_MODE_NONBLOCKING, true);
514 ck_assert_int_eq (VAPI_OK, rv);
520 vapi_disconnect (ctx);
524 START_TEST (test_show_version_1)
526 printf ("--- Basic show version message - reply test ---\n");
527 vapi_msg_show_version *sv = vapi_alloc_show_version (ctx);
528 ck_assert_ptr_ne (NULL, sv);
529 vapi_msg_show_version_hton (sv);
530 vapi_error_e rv = vapi_send (ctx, sv);
531 ck_assert_int_eq (VAPI_OK, rv);
532 vapi_msg_show_version_reply *resp;
534 rv = vapi_recv (ctx, (void *) &resp, &size, 0, 0);
535 ck_assert_int_eq (VAPI_OK, rv);
537 show_version_cb (NULL, &dummy, VAPI_OK, true, &resp->payload);
538 vapi_msg_free (ctx, resp);
543 START_TEST (test_show_version_2)
546 printf ("--- Show version via blocking callback API ---\n");
547 const int attempts = response_queue_size * 4;
549 for (i = 0; i < attempts; ++i)
551 vapi_msg_show_version *sv = vapi_alloc_show_version (ctx);
552 ck_assert_ptr_ne (NULL, sv);
553 vapi_error_e rv = vapi_show_version (ctx, sv, show_version_cb, &called);
554 ck_assert_int_eq (VAPI_OK, rv);
556 ck_assert_int_eq (attempts, called);
568 } sw_interface_dump_ctx;
571 sw_interface_dump_cb (struct vapi_ctx_s *ctx, void *callback_ctx,
572 vapi_error_e rv, bool is_last,
573 vapi_payload_sw_interface_details * reply)
575 sw_interface_dump_ctx *dctx = callback_ctx;
576 ck_assert_int_eq (false, dctx->last_called);
579 ck_assert (NULL == reply);
580 dctx->last_called = true;
584 ck_assert (NULL != reply);
585 printf ("Interface dump entry: [%u]: %s\n", reply->sw_if_index,
586 reply->interface_name);
588 for (i = 0; i < dctx->num_ifs; ++i)
590 if (dctx->sw_if_indexes[i] == reply->sw_if_index)
592 ck_assert_int_eq (false, dctx->seen[i]);
593 dctx->seen[i] = true;
601 START_TEST (test_loopbacks_1)
603 printf ("--- Create/delete loopbacks using blocking API ---\n");
604 const size_t num_ifs = 5;
605 u8 mac_addresses[num_ifs][6];
606 clib_memset (&mac_addresses, 0, sizeof (mac_addresses));
607 u32 sw_if_indexes[num_ifs];
608 clib_memset (&sw_if_indexes, 0xff, sizeof (sw_if_indexes));
609 test_create_loopback_ctx_t clcs[num_ifs];
610 clib_memset (&clcs, 0, sizeof (clcs));
611 test_delete_loopback_ctx_t dlcs[num_ifs];
612 clib_memset (&dlcs, 0, sizeof (dlcs));
614 for (i = 0; i < num_ifs; ++i)
616 memcpy (&mac_addresses[i], "\1\2\3\4\5\6", 6);
617 mac_addresses[i][5] = i;
618 clcs[i].sw_if_index_storage = &sw_if_indexes[i];
620 for (i = 0; i < num_ifs; ++i)
622 vapi_msg_create_loopback *cl = vapi_alloc_create_loopback (ctx);
623 memcpy (cl->payload.mac_address, mac_addresses[i],
624 sizeof (cl->payload.mac_address));
626 vapi_create_loopback (ctx, cl, loopback_create_cb, &clcs[i]);
627 ck_assert_int_eq (VAPI_OK, rv);
629 for (i = 0; i < num_ifs; ++i)
631 ck_assert_int_eq (1, clcs[i].called);
632 printf ("Created loopback with MAC %02x:%02x:%02x:%02x:%02x:%02x --> "
634 mac_addresses[i][0], mac_addresses[i][1], mac_addresses[i][2],
635 mac_addresses[i][3], mac_addresses[i][4], mac_addresses[i][5],
639 sw_interface_dump_ctx dctx = { false, num_ifs, sw_if_indexes, seen, 0 };
640 vapi_msg_sw_interface_dump *dump;
642 const int attempts = response_queue_size * 4;
643 for (i = 0; i < attempts; ++i)
645 dctx.last_called = false;
646 clib_memset (&seen, 0, sizeof (seen));
647 dump = vapi_alloc_sw_interface_dump (ctx);
648 dump->payload.name_filter_valid = 0;
649 clib_memset (dump->payload.name_filter, 0,
650 sizeof (dump->payload.name_filter));
651 while (VAPI_EAGAIN ==
653 vapi_sw_interface_dump (ctx, dump, sw_interface_dump_cb,
656 ck_assert_int_eq (true, dctx.last_called);
658 for (j = 0; j < num_ifs; ++j)
660 ck_assert_int_eq (true, seen[j]);
663 clib_memset (&seen, 0, sizeof (seen));
664 for (i = 0; i < num_ifs; ++i)
666 vapi_msg_delete_loopback *dl = vapi_alloc_delete_loopback (ctx);
667 dl->payload.sw_if_index = sw_if_indexes[i];
669 vapi_delete_loopback (ctx, dl, loopback_delete_cb, &dlcs[i]);
670 ck_assert_int_eq (VAPI_OK, rv);
672 for (i = 0; i < num_ifs; ++i)
674 ck_assert_int_eq (1, dlcs[i].called);
675 printf ("Deleted loopback with sw_if_index %u\n", sw_if_indexes[i]);
677 dctx.last_called = false;
678 clib_memset (&seen, 0, sizeof (seen));
679 dump = vapi_alloc_sw_interface_dump (ctx);
680 dump->payload.name_filter_valid = 0;
681 clib_memset (dump->payload.name_filter, 0,
682 sizeof (dump->payload.name_filter));
683 while (VAPI_EAGAIN ==
685 vapi_sw_interface_dump (ctx, dump, sw_interface_dump_cb, &dctx)))
687 ck_assert_int_eq (true, dctx.last_called);
688 for (i = 0; i < num_ifs; ++i)
690 ck_assert_int_eq (false, seen[i]);
696 START_TEST (test_show_version_3)
698 printf ("--- Show version via async callback ---\n");
701 vapi_msg_show_version *sv = vapi_alloc_show_version (ctx);
702 ck_assert_ptr_ne (NULL, sv);
703 while (VAPI_EAGAIN ==
704 (rv = vapi_show_version (ctx, sv, show_version_cb, &called)))
706 ck_assert_int_eq (VAPI_OK, rv);
707 ck_assert_int_eq (0, called);
708 rv = vapi_dispatch (ctx);
709 ck_assert_int_eq (VAPI_OK, rv);
710 ck_assert_int_eq (1, called);
712 rv = vapi_dispatch (ctx);
713 ck_assert_int_eq (VAPI_OK, rv);
714 ck_assert_int_eq (0, called);
719 START_TEST (test_show_version_4)
721 printf ("--- Show version via async callback - multiple messages ---\n");
723 const size_t num_req = 5;
724 int contexts[num_req];
725 clib_memset (contexts, 0, sizeof (contexts));
727 for (i = 0; i < num_req; ++i)
729 vapi_msg_show_version *sv = vapi_alloc_show_version (ctx);
730 ck_assert_ptr_ne (NULL, sv);
731 while (VAPI_EAGAIN ==
733 vapi_show_version (ctx, sv, show_version_cb, &contexts[i])))
735 ck_assert_int_eq (VAPI_OK, rv);
737 for (j = 0; j < num_req; ++j)
739 ck_assert_int_eq (0, contexts[j]);
742 rv = vapi_dispatch (ctx);
743 ck_assert_int_eq (VAPI_OK, rv);
744 for (i = 0; i < num_req; ++i)
746 ck_assert_int_eq (1, contexts[i]);
748 clib_memset (contexts, 0, sizeof (contexts));
749 rv = vapi_dispatch (ctx);
750 ck_assert_int_eq (VAPI_OK, rv);
751 for (i = 0; i < num_req; ++i)
753 ck_assert_int_eq (0, contexts[i]);
759 START_TEST (test_loopbacks_2)
761 printf ("--- Create/delete loopbacks using non-blocking API ---\n");
763 const size_t num_ifs = 5;
764 u8 mac_addresses[num_ifs][6];
765 clib_memset (&mac_addresses, 0, sizeof (mac_addresses));
766 u32 sw_if_indexes[num_ifs];
767 clib_memset (&sw_if_indexes, 0xff, sizeof (sw_if_indexes));
768 test_create_loopback_ctx_t clcs[num_ifs];
769 clib_memset (&clcs, 0, sizeof (clcs));
770 test_delete_loopback_ctx_t dlcs[num_ifs];
771 clib_memset (&dlcs, 0, sizeof (dlcs));
773 for (i = 0; i < num_ifs; ++i)
775 memcpy (&mac_addresses[i], "\1\2\3\4\5\6", 6);
776 mac_addresses[i][5] = i;
777 clcs[i].sw_if_index_storage = &sw_if_indexes[i];
779 for (i = 0; i < num_ifs; ++i)
781 vapi_msg_create_loopback *cl = vapi_alloc_create_loopback (ctx);
782 memcpy (cl->payload.mac_address, mac_addresses[i],
783 sizeof (cl->payload.mac_address));
784 while (VAPI_EAGAIN ==
786 vapi_create_loopback (ctx, cl, loopback_create_cb, &clcs[i])))
788 ck_assert_int_eq (VAPI_OK, rv);
790 rv = vapi_dispatch (ctx);
791 ck_assert_int_eq (VAPI_OK, rv);
792 for (i = 0; i < num_ifs; ++i)
794 ck_assert_int_eq (1, clcs[i].called);
795 printf ("Loopback with MAC %02x:%02x:%02x:%02x:%02x:%02x --> "
797 mac_addresses[i][0], mac_addresses[i][1], mac_addresses[i][2],
798 mac_addresses[i][3], mac_addresses[i][4], mac_addresses[i][5],
802 clib_memset (&seen, 0, sizeof (seen));
803 sw_interface_dump_ctx dctx = { false, num_ifs, sw_if_indexes, seen, 0 };
804 vapi_msg_sw_interface_dump *dump = vapi_alloc_sw_interface_dump (ctx);
805 dump->payload.name_filter_valid = 0;
806 clib_memset (dump->payload.name_filter, 0,
807 sizeof (dump->payload.name_filter));
808 while (VAPI_EAGAIN ==
810 vapi_sw_interface_dump (ctx, dump, sw_interface_dump_cb, &dctx)))
812 for (i = 0; i < num_ifs; ++i)
814 ck_assert_int_eq (false, seen[i]);
816 clib_memset (&seen, 0, sizeof (seen));
817 ck_assert_int_eq (false, dctx.last_called);
818 rv = vapi_dispatch (ctx);
819 ck_assert_int_eq (VAPI_OK, rv);
820 for (i = 0; i < num_ifs; ++i)
822 ck_assert_int_eq (true, seen[i]);
824 clib_memset (&seen, 0, sizeof (seen));
825 ck_assert_int_eq (true, dctx.last_called);
826 for (i = 0; i < num_ifs; ++i)
828 vapi_msg_delete_loopback *dl = vapi_alloc_delete_loopback (ctx);
829 dl->payload.sw_if_index = sw_if_indexes[i];
830 while (VAPI_EAGAIN ==
832 vapi_delete_loopback (ctx, dl, loopback_delete_cb, &dlcs[i])))
834 ck_assert_int_eq (VAPI_OK, rv);
836 rv = vapi_dispatch (ctx);
837 ck_assert_int_eq (VAPI_OK, rv);
838 for (i = 0; i < num_ifs; ++i)
840 ck_assert_int_eq (1, dlcs[i].called);
841 printf ("Deleted loopback with sw_if_index %u\n", sw_if_indexes[i]);
843 clib_memset (&seen, 0, sizeof (seen));
844 dctx.last_called = false;
845 dump = vapi_alloc_sw_interface_dump (ctx);
846 dump->payload.name_filter_valid = 0;
847 clib_memset (dump->payload.name_filter, 0,
848 sizeof (dump->payload.name_filter));
849 while (VAPI_EAGAIN ==
851 vapi_sw_interface_dump (ctx, dump, sw_interface_dump_cb, &dctx)))
853 rv = vapi_dispatch (ctx);
854 ck_assert_int_eq (VAPI_OK, rv);
855 for (i = 0; i < num_ifs; ++i)
857 ck_assert_int_eq (false, seen[i]);
859 clib_memset (&seen, 0, sizeof (seen));
860 ck_assert_int_eq (true, dctx.last_called);
866 interface_simple_stats_cb (vapi_ctx_t ctx, void *callback_ctx,
867 vapi_error_e rv, bool is_last,
868 vapi_payload_want_interface_simple_stats_reply *
875 simple_counters_cb (vapi_ctx_t ctx, void *callback_ctx,
876 vapi_payload_vnet_interface_simple_counters * payload)
878 int *called = callback_ctx;
880 printf ("simple counters: first_sw_if_index=%u\n",
881 payload->first_sw_if_index);
885 START_TEST (test_stats_1)
887 printf ("--- Receive stats using generic blocking API ---\n");
888 vapi_msg_want_interface_simple_stats *ws =
889 vapi_alloc_want_interface_simple_stats (ctx);
890 ws->payload.enable_disable = 1;
891 ws->payload.pid = getpid ();
893 rv = vapi_want_interface_simple_stats (ctx, ws, interface_simple_stats_cb,
895 ck_assert_int_eq (VAPI_OK, rv);
897 vapi_set_event_cb (ctx, vapi_msg_id_vnet_interface_simple_counters,
898 (vapi_event_cb) simple_counters_cb, &called);
899 rv = vapi_dispatch_one (ctx);
900 ck_assert_int_eq (VAPI_OK, rv);
901 ck_assert_int_eq (1, called);
906 START_TEST (test_stats_2)
908 printf ("--- Receive stats using stat-specific blocking API ---\n");
909 vapi_msg_want_interface_simple_stats *ws =
910 vapi_alloc_want_interface_simple_stats (ctx);
911 ws->payload.enable_disable = 1;
912 ws->payload.pid = getpid ();
914 rv = vapi_want_interface_simple_stats (ctx, ws, interface_simple_stats_cb,
916 ck_assert_int_eq (VAPI_OK, rv);
918 vapi_set_vapi_msg_vnet_interface_simple_counters_event_cb (ctx,
921 rv = vapi_dispatch_one (ctx);
922 ck_assert_int_eq (VAPI_OK, rv);
923 ck_assert_int_eq (1, called);
929 generic_cb (vapi_ctx_t ctx, void *callback_ctx, vapi_msg_id_t id, void *msg)
931 int *called = callback_ctx;
932 ck_assert_int_eq (0, *called);
934 ck_assert_int_eq (id, vapi_msg_id_show_version_reply);
935 ck_assert_ptr_ne (NULL, msg);
936 vapi_msg_show_version_reply *reply = msg;
937 ck_assert_str_eq ("vpe", (char *) reply->payload.program);
941 START_TEST (test_show_version_5)
943 printf ("--- Receive show version using generic callback - nonblocking "
946 vapi_msg_show_version *sv = vapi_alloc_show_version (ctx);
947 ck_assert_ptr_ne (NULL, sv);
948 vapi_msg_show_version_hton (sv);
949 while (VAPI_EAGAIN == (rv = vapi_send (ctx, sv)))
951 ck_assert_int_eq (VAPI_OK, rv);
953 vapi_set_generic_event_cb (ctx, generic_cb, &called);
954 ck_assert_int_eq (VAPI_OK, rv);
955 rv = vapi_dispatch_one (ctx);
956 ck_assert_int_eq (VAPI_OK, rv);
957 ck_assert_int_eq (1, called);
958 sv = vapi_alloc_show_version (ctx);
959 ck_assert_ptr_ne (NULL, sv);
960 vapi_msg_show_version_hton (sv);
961 while (VAPI_EAGAIN == (rv = vapi_send (ctx, sv)))
963 ck_assert_int_eq (VAPI_OK, rv);
964 vapi_clear_generic_event_cb (ctx);
965 rv = vapi_dispatch_one (ctx);
966 ck_assert_int_eq (VAPI_OK, rv);
967 ck_assert_int_eq (1, called); /* needs to remain unchanged */
973 combined_counters_cb (struct vapi_ctx_s *ctx, void *callback_ctx,
974 vapi_payload_vnet_interface_combined_counters * payload)
976 int *called = callback_ctx;
978 printf ("combined counters: first_sw_if_index=%u\n",
979 payload->first_sw_if_index);
984 stats_cb (vapi_ctx_t ctx, void *callback_ctx, vapi_error_e rv,
985 bool is_last, vapi_payload_want_stats_reply * payload)
990 START_TEST (test_stats_3)
992 printf ("--- Receive multiple stats using stat-specific non-blocking API "
994 vapi_msg_want_stats *ws = vapi_alloc_want_stats (ctx);
995 ws->payload.enable_disable = 1;
996 ws->payload.pid = getpid ();
998 rv = vapi_want_stats (ctx, ws, stats_cb, NULL);
999 ck_assert_int_eq (VAPI_OK, rv);
1002 vapi_set_vapi_msg_vnet_interface_simple_counters_event_cb (ctx,
1005 vapi_set_vapi_msg_vnet_interface_combined_counters_event_cb (ctx,
1006 combined_counters_cb,
1008 while (!called || !called2)
1010 if (VAPI_EAGAIN != (rv = vapi_dispatch_one (ctx)))
1012 ck_assert_int_eq (VAPI_OK, rv);
1020 show_version_no_cb (vapi_ctx_t ctx, void *caller_ctx,
1021 vapi_error_e rv, bool is_last,
1022 vapi_payload_show_version_reply * p)
1024 ck_assert_int_eq (VAPI_ENORESP, rv);
1025 ck_assert_int_eq (true, is_last);
1026 ck_assert_ptr_eq (NULL, p);
1027 ++*(int *) caller_ctx;
1031 START_TEST (test_no_response_1)
1033 printf ("--- Simulate no response to regular message ---\n");
1035 vapi_msg_show_version *sv = vapi_alloc_show_version (ctx);
1036 ck_assert_ptr_ne (NULL, sv);
1037 sv->header._vl_msg_id = ~0; /* malformed ID causes vpp to drop the msg */
1039 while (VAPI_EAGAIN ==
1040 (rv = vapi_show_version (ctx, sv, show_version_no_cb, &called)))
1042 ck_assert_int_eq (VAPI_OK, rv);
1043 sv = vapi_alloc_show_version (ctx);
1044 ck_assert_ptr_ne (NULL, sv);
1045 while (VAPI_EAGAIN ==
1046 (rv = vapi_show_version (ctx, sv, show_version_cb, &called)))
1048 ck_assert_int_eq (VAPI_OK, rv);
1049 rv = vapi_dispatch (ctx);
1050 ck_assert_int_eq (VAPI_OK, rv);
1051 ck_assert_int_eq (2, called);
1057 no_msg_cb (struct vapi_ctx_s *ctx, void *callback_ctx,
1058 vapi_error_e rv, bool is_last,
1059 vapi_payload_sw_interface_details * reply)
1061 int *called = callback_ctx;
1063 ck_assert_int_eq (VAPI_OK, rv);
1064 ck_assert_int_eq (true, is_last);
1065 ck_assert_ptr_eq (NULL, reply);
1069 START_TEST (test_no_response_2)
1071 printf ("--- Simulate no response to dump message ---\n");
1073 vapi_msg_sw_interface_dump *dump = vapi_alloc_sw_interface_dump (ctx);
1074 dump->header._vl_msg_id = ~0; /* malformed ID causes vpp to drop the msg */
1076 while (VAPI_EAGAIN ==
1077 (rv = vapi_sw_interface_dump (ctx, dump, no_msg_cb, &no_called)))
1079 ck_assert_int_eq (VAPI_OK, rv);
1080 rv = vapi_dispatch (ctx);
1081 ck_assert_int_eq (VAPI_OK, rv);
1082 ck_assert_int_eq (1, no_called);
1087 START_TEST (test_unsupported)
1089 printf ("--- Unsupported messages ---\n");
1090 bool available = vapi_is_msg_available (ctx, vapi_msg_id_test_fake_msg);
1091 ck_assert_int_eq (false, available);
1099 Suite *s = suite_create ("VAPI test");
1101 TCase *tc_negative = tcase_create ("Negative tests");
1102 tcase_add_test (tc_negative, test_invalid_values);
1103 suite_add_tcase (s, tc_negative);
1105 TCase *tc_swap = tcase_create ("Byteswap tests");
1106 tcase_add_test (tc_swap, test_hton_1);
1107 tcase_add_test (tc_swap, test_hton_2);
1108 tcase_add_test (tc_swap, test_hton_3);
1109 tcase_add_test (tc_swap, test_hton_4);
1110 tcase_add_test (tc_swap, test_ntoh_1);
1111 tcase_add_test (tc_swap, test_ntoh_2);
1112 tcase_add_test (tc_swap, test_ntoh_3);
1113 tcase_add_test (tc_swap, test_ntoh_4);
1114 suite_add_tcase (s, tc_swap);
1116 TCase *tc_connect = tcase_create ("Connect");
1117 tcase_add_test (tc_connect, test_connect);
1118 suite_add_tcase (s, tc_connect);
1120 TCase *tc_block = tcase_create ("Blocking API");
1121 tcase_set_timeout (tc_block, 25);
1122 tcase_add_checked_fixture (tc_block, setup_blocking, teardown);
1123 tcase_add_test (tc_block, test_show_version_1);
1124 tcase_add_test (tc_block, test_show_version_2);
1125 tcase_add_test (tc_block, test_loopbacks_1);
1126 tcase_add_test (tc_block, test_stats_1);
1127 tcase_add_test (tc_block, test_stats_2);
1128 suite_add_tcase (s, tc_block);
1130 TCase *tc_nonblock = tcase_create ("Nonblocking API");
1131 tcase_set_timeout (tc_nonblock, 25);
1132 tcase_add_checked_fixture (tc_nonblock, setup_nonblocking, teardown);
1133 tcase_add_test (tc_nonblock, test_show_version_3);
1134 tcase_add_test (tc_nonblock, test_show_version_4);
1135 tcase_add_test (tc_nonblock, test_show_version_5);
1136 tcase_add_test (tc_nonblock, test_loopbacks_2);
1137 tcase_add_test (tc_nonblock, test_stats_3);
1138 tcase_add_test (tc_nonblock, test_no_response_1);
1139 tcase_add_test (tc_nonblock, test_no_response_2);
1140 suite_add_tcase (s, tc_nonblock);
1142 TCase *tc_unsupported = tcase_create ("Unsupported message");
1143 tcase_add_checked_fixture (tc_unsupported, setup_blocking, teardown);
1144 tcase_add_test (tc_unsupported, test_unsupported);
1145 suite_add_tcase (s, tc_unsupported);
1151 main (int argc, char *argv[])
1155 printf ("Invalid argc==`%d'\n", argc);
1156 return EXIT_FAILURE;
1159 api_prefix = argv[2];
1160 printf ("App name: `%s', API prefix: `%s'\n", app_name, api_prefix);
1167 sr = srunner_create (s);
1169 srunner_run_all (sr, CK_NORMAL);
1170 number_failed = srunner_ntests_failed (sr);
1172 return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
1176 * fd.io coding-style-patch-verification: ON
1179 * eval: (c-set-style "gnu")