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 memset (&mac_addresses, 0, sizeof (mac_addresses));
607 u32 sw_if_indexes[num_ifs];
608 memset (&sw_if_indexes, 0xff, sizeof (sw_if_indexes));
609 test_create_loopback_ctx_t clcs[num_ifs];
610 memset (&clcs, 0, sizeof (clcs));
611 test_delete_loopback_ctx_t dlcs[num_ifs];
612 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 memset (&seen, 0, sizeof (seen));
647 dump = vapi_alloc_sw_interface_dump (ctx);
648 dump->payload.name_filter_valid = 0;
649 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 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 memset (&seen, 0, sizeof (seen));
679 dump = vapi_alloc_sw_interface_dump (ctx);
680 dump->payload.name_filter_valid = 0;
681 memset (dump->payload.name_filter, 0, sizeof (dump->payload.name_filter));
682 while (VAPI_EAGAIN ==
684 vapi_sw_interface_dump (ctx, dump, sw_interface_dump_cb, &dctx)))
686 ck_assert_int_eq (true, dctx.last_called);
687 for (i = 0; i < num_ifs; ++i)
689 ck_assert_int_eq (false, seen[i]);
695 START_TEST (test_show_version_3)
697 printf ("--- Show version via async callback ---\n");
700 vapi_msg_show_version *sv = vapi_alloc_show_version (ctx);
701 ck_assert_ptr_ne (NULL, sv);
702 while (VAPI_EAGAIN ==
703 (rv = vapi_show_version (ctx, sv, show_version_cb, &called)))
705 ck_assert_int_eq (VAPI_OK, rv);
706 ck_assert_int_eq (0, called);
707 rv = vapi_dispatch (ctx);
708 ck_assert_int_eq (VAPI_OK, rv);
709 ck_assert_int_eq (1, called);
711 rv = vapi_dispatch (ctx);
712 ck_assert_int_eq (VAPI_OK, rv);
713 ck_assert_int_eq (0, called);
718 START_TEST (test_show_version_4)
720 printf ("--- Show version via async callback - multiple messages ---\n");
722 const size_t num_req = 5;
723 int contexts[num_req];
724 memset (contexts, 0, sizeof (contexts));
726 for (i = 0; i < num_req; ++i)
728 vapi_msg_show_version *sv = vapi_alloc_show_version (ctx);
729 ck_assert_ptr_ne (NULL, sv);
730 while (VAPI_EAGAIN ==
732 vapi_show_version (ctx, sv, show_version_cb, &contexts[i])))
734 ck_assert_int_eq (VAPI_OK, rv);
736 for (j = 0; j < num_req; ++j)
738 ck_assert_int_eq (0, contexts[j]);
741 rv = vapi_dispatch (ctx);
742 ck_assert_int_eq (VAPI_OK, rv);
743 for (i = 0; i < num_req; ++i)
745 ck_assert_int_eq (1, contexts[i]);
747 memset (contexts, 0, sizeof (contexts));
748 rv = vapi_dispatch (ctx);
749 ck_assert_int_eq (VAPI_OK, rv);
750 for (i = 0; i < num_req; ++i)
752 ck_assert_int_eq (0, contexts[i]);
758 START_TEST (test_loopbacks_2)
760 printf ("--- Create/delete loopbacks using non-blocking API ---\n");
762 const size_t num_ifs = 5;
763 u8 mac_addresses[num_ifs][6];
764 memset (&mac_addresses, 0, sizeof (mac_addresses));
765 u32 sw_if_indexes[num_ifs];
766 memset (&sw_if_indexes, 0xff, sizeof (sw_if_indexes));
767 test_create_loopback_ctx_t clcs[num_ifs];
768 memset (&clcs, 0, sizeof (clcs));
769 test_delete_loopback_ctx_t dlcs[num_ifs];
770 memset (&dlcs, 0, sizeof (dlcs));
772 for (i = 0; i < num_ifs; ++i)
774 memcpy (&mac_addresses[i], "\1\2\3\4\5\6", 6);
775 mac_addresses[i][5] = i;
776 clcs[i].sw_if_index_storage = &sw_if_indexes[i];
778 for (i = 0; i < num_ifs; ++i)
780 vapi_msg_create_loopback *cl = vapi_alloc_create_loopback (ctx);
781 memcpy (cl->payload.mac_address, mac_addresses[i],
782 sizeof (cl->payload.mac_address));
783 while (VAPI_EAGAIN ==
785 vapi_create_loopback (ctx, cl, loopback_create_cb, &clcs[i])))
787 ck_assert_int_eq (VAPI_OK, rv);
789 rv = vapi_dispatch (ctx);
790 ck_assert_int_eq (VAPI_OK, rv);
791 for (i = 0; i < num_ifs; ++i)
793 ck_assert_int_eq (1, clcs[i].called);
794 printf ("Loopback with MAC %02x:%02x:%02x:%02x:%02x:%02x --> "
796 mac_addresses[i][0], mac_addresses[i][1], mac_addresses[i][2],
797 mac_addresses[i][3], mac_addresses[i][4], mac_addresses[i][5],
801 memset (&seen, 0, sizeof (seen));
802 sw_interface_dump_ctx dctx = { false, num_ifs, sw_if_indexes, seen, 0 };
803 vapi_msg_sw_interface_dump *dump = vapi_alloc_sw_interface_dump (ctx);
804 dump->payload.name_filter_valid = 0;
805 memset (dump->payload.name_filter, 0, sizeof (dump->payload.name_filter));
806 while (VAPI_EAGAIN ==
808 vapi_sw_interface_dump (ctx, dump, sw_interface_dump_cb, &dctx)))
810 for (i = 0; i < num_ifs; ++i)
812 ck_assert_int_eq (false, seen[i]);
814 memset (&seen, 0, sizeof (seen));
815 ck_assert_int_eq (false, dctx.last_called);
816 rv = vapi_dispatch (ctx);
817 ck_assert_int_eq (VAPI_OK, rv);
818 for (i = 0; i < num_ifs; ++i)
820 ck_assert_int_eq (true, seen[i]);
822 memset (&seen, 0, sizeof (seen));
823 ck_assert_int_eq (true, dctx.last_called);
824 for (i = 0; i < num_ifs; ++i)
826 vapi_msg_delete_loopback *dl = vapi_alloc_delete_loopback (ctx);
827 dl->payload.sw_if_index = sw_if_indexes[i];
828 while (VAPI_EAGAIN ==
830 vapi_delete_loopback (ctx, dl, loopback_delete_cb, &dlcs[i])))
832 ck_assert_int_eq (VAPI_OK, rv);
834 rv = vapi_dispatch (ctx);
835 ck_assert_int_eq (VAPI_OK, rv);
836 for (i = 0; i < num_ifs; ++i)
838 ck_assert_int_eq (1, dlcs[i].called);
839 printf ("Deleted loopback with sw_if_index %u\n", sw_if_indexes[i]);
841 memset (&seen, 0, sizeof (seen));
842 dctx.last_called = false;
843 dump = vapi_alloc_sw_interface_dump (ctx);
844 dump->payload.name_filter_valid = 0;
845 memset (dump->payload.name_filter, 0, sizeof (dump->payload.name_filter));
846 while (VAPI_EAGAIN ==
848 vapi_sw_interface_dump (ctx, dump, sw_interface_dump_cb, &dctx)))
850 rv = vapi_dispatch (ctx);
851 ck_assert_int_eq (VAPI_OK, rv);
852 for (i = 0; i < num_ifs; ++i)
854 ck_assert_int_eq (false, seen[i]);
856 memset (&seen, 0, sizeof (seen));
857 ck_assert_int_eq (true, dctx.last_called);
863 interface_simple_stats_cb (vapi_ctx_t ctx, void *callback_ctx,
864 vapi_error_e rv, bool is_last,
865 vapi_payload_want_interface_simple_stats_reply *
872 simple_counters_cb (vapi_ctx_t ctx, void *callback_ctx,
873 vapi_payload_vnet_interface_simple_counters * payload)
875 int *called = callback_ctx;
877 printf ("simple counters: first_sw_if_index=%u\n",
878 payload->first_sw_if_index);
882 START_TEST (test_stats_1)
884 printf ("--- Receive stats using generic blocking API ---\n");
885 vapi_msg_want_interface_simple_stats *ws =
886 vapi_alloc_want_interface_simple_stats (ctx);
887 ws->payload.enable_disable = 1;
888 ws->payload.pid = getpid ();
890 rv = vapi_want_interface_simple_stats (ctx, ws, interface_simple_stats_cb,
892 ck_assert_int_eq (VAPI_OK, rv);
894 vapi_set_event_cb (ctx, vapi_msg_id_vnet_interface_simple_counters,
895 (vapi_event_cb) simple_counters_cb, &called);
896 rv = vapi_dispatch_one (ctx);
897 ck_assert_int_eq (VAPI_OK, rv);
898 ck_assert_int_eq (1, called);
903 START_TEST (test_stats_2)
905 printf ("--- Receive stats using stat-specific blocking API ---\n");
906 vapi_msg_want_interface_simple_stats *ws =
907 vapi_alloc_want_interface_simple_stats (ctx);
908 ws->payload.enable_disable = 1;
909 ws->payload.pid = getpid ();
911 rv = vapi_want_interface_simple_stats (ctx, ws, interface_simple_stats_cb,
913 ck_assert_int_eq (VAPI_OK, rv);
915 vapi_set_vapi_msg_vnet_interface_simple_counters_event_cb (ctx,
918 rv = vapi_dispatch_one (ctx);
919 ck_assert_int_eq (VAPI_OK, rv);
920 ck_assert_int_eq (1, called);
926 generic_cb (vapi_ctx_t ctx, void *callback_ctx, vapi_msg_id_t id, void *msg)
928 int *called = callback_ctx;
929 ck_assert_int_eq (0, *called);
931 ck_assert_int_eq (id, vapi_msg_id_show_version_reply);
932 ck_assert_ptr_ne (NULL, msg);
933 vapi_msg_show_version_reply *reply = msg;
934 ck_assert_str_eq ("vpe", (char *) reply->payload.program);
938 START_TEST (test_show_version_5)
940 printf ("--- Receive show version using generic callback - nonblocking "
943 vapi_msg_show_version *sv = vapi_alloc_show_version (ctx);
944 ck_assert_ptr_ne (NULL, sv);
945 vapi_msg_show_version_hton (sv);
946 while (VAPI_EAGAIN == (rv = vapi_send (ctx, sv)))
948 ck_assert_int_eq (VAPI_OK, rv);
950 vapi_set_generic_event_cb (ctx, generic_cb, &called);
951 ck_assert_int_eq (VAPI_OK, rv);
952 rv = vapi_dispatch_one (ctx);
953 ck_assert_int_eq (VAPI_OK, rv);
954 ck_assert_int_eq (1, called);
955 sv = vapi_alloc_show_version (ctx);
956 ck_assert_ptr_ne (NULL, sv);
957 vapi_msg_show_version_hton (sv);
958 while (VAPI_EAGAIN == (rv = vapi_send (ctx, sv)))
960 ck_assert_int_eq (VAPI_OK, rv);
961 vapi_clear_generic_event_cb (ctx);
962 rv = vapi_dispatch_one (ctx);
963 ck_assert_int_eq (VAPI_OK, rv);
964 ck_assert_int_eq (1, called); /* needs to remain unchanged */
970 combined_counters_cb (struct vapi_ctx_s *ctx, void *callback_ctx,
971 vapi_payload_vnet_interface_combined_counters * payload)
973 int *called = callback_ctx;
975 printf ("combined counters: first_sw_if_index=%u\n",
976 payload->first_sw_if_index);
981 stats_cb (vapi_ctx_t ctx, void *callback_ctx, vapi_error_e rv,
982 bool is_last, vapi_payload_want_stats_reply * payload)
987 START_TEST (test_stats_3)
989 printf ("--- Receive multiple stats using stat-specific non-blocking API "
991 vapi_msg_want_stats *ws = vapi_alloc_want_stats (ctx);
992 ws->payload.enable_disable = 1;
993 ws->payload.pid = getpid ();
995 rv = vapi_want_stats (ctx, ws, stats_cb, NULL);
996 ck_assert_int_eq (VAPI_OK, rv);
999 vapi_set_vapi_msg_vnet_interface_simple_counters_event_cb (ctx,
1002 vapi_set_vapi_msg_vnet_interface_combined_counters_event_cb (ctx,
1003 combined_counters_cb,
1005 while (!called || !called2)
1007 if (VAPI_EAGAIN != (rv = vapi_dispatch_one (ctx)))
1009 ck_assert_int_eq (VAPI_OK, rv);
1017 show_version_no_cb (vapi_ctx_t ctx, void *caller_ctx,
1018 vapi_error_e rv, bool is_last,
1019 vapi_payload_show_version_reply * p)
1021 ck_assert_int_eq (VAPI_ENORESP, rv);
1022 ck_assert_int_eq (true, is_last);
1023 ck_assert_ptr_eq (NULL, p);
1024 ++*(int *) caller_ctx;
1028 START_TEST (test_no_response_1)
1030 printf ("--- Simulate no response to regular message ---\n");
1032 vapi_msg_show_version *sv = vapi_alloc_show_version (ctx);
1033 ck_assert_ptr_ne (NULL, sv);
1034 sv->header._vl_msg_id = ~0; /* malformed ID causes vpp to drop the msg */
1036 while (VAPI_EAGAIN ==
1037 (rv = vapi_show_version (ctx, sv, show_version_no_cb, &called)))
1039 ck_assert_int_eq (VAPI_OK, rv);
1040 sv = vapi_alloc_show_version (ctx);
1041 ck_assert_ptr_ne (NULL, sv);
1042 while (VAPI_EAGAIN ==
1043 (rv = vapi_show_version (ctx, sv, show_version_cb, &called)))
1045 ck_assert_int_eq (VAPI_OK, rv);
1046 rv = vapi_dispatch (ctx);
1047 ck_assert_int_eq (VAPI_OK, rv);
1048 ck_assert_int_eq (2, called);
1054 no_msg_cb (struct vapi_ctx_s *ctx, void *callback_ctx,
1055 vapi_error_e rv, bool is_last,
1056 vapi_payload_sw_interface_details * reply)
1058 int *called = callback_ctx;
1060 ck_assert_int_eq (VAPI_OK, rv);
1061 ck_assert_int_eq (true, is_last);
1062 ck_assert_ptr_eq (NULL, reply);
1066 START_TEST (test_no_response_2)
1068 printf ("--- Simulate no response to dump message ---\n");
1070 vapi_msg_sw_interface_dump *dump = vapi_alloc_sw_interface_dump (ctx);
1071 dump->header._vl_msg_id = ~0; /* malformed ID causes vpp to drop the msg */
1073 while (VAPI_EAGAIN ==
1074 (rv = vapi_sw_interface_dump (ctx, dump, no_msg_cb, &no_called)))
1076 ck_assert_int_eq (VAPI_OK, rv);
1077 rv = vapi_dispatch (ctx);
1078 ck_assert_int_eq (VAPI_OK, rv);
1079 ck_assert_int_eq (1, no_called);
1084 START_TEST (test_unsupported)
1086 printf ("--- Unsupported messages ---\n");
1087 bool available = vapi_is_msg_available (ctx, vapi_msg_id_test_fake_msg);
1088 ck_assert_int_eq (false, available);
1096 Suite *s = suite_create ("VAPI test");
1098 TCase *tc_negative = tcase_create ("Negative tests");
1099 tcase_add_test (tc_negative, test_invalid_values);
1100 suite_add_tcase (s, tc_negative);
1102 TCase *tc_swap = tcase_create ("Byteswap tests");
1103 tcase_add_test (tc_swap, test_hton_1);
1104 tcase_add_test (tc_swap, test_hton_2);
1105 tcase_add_test (tc_swap, test_hton_3);
1106 tcase_add_test (tc_swap, test_hton_4);
1107 tcase_add_test (tc_swap, test_ntoh_1);
1108 tcase_add_test (tc_swap, test_ntoh_2);
1109 tcase_add_test (tc_swap, test_ntoh_3);
1110 tcase_add_test (tc_swap, test_ntoh_4);
1111 suite_add_tcase (s, tc_swap);
1113 TCase *tc_connect = tcase_create ("Connect");
1114 tcase_add_test (tc_connect, test_connect);
1115 suite_add_tcase (s, tc_connect);
1117 TCase *tc_block = tcase_create ("Blocking API");
1118 tcase_set_timeout (tc_block, 25);
1119 tcase_add_checked_fixture (tc_block, setup_blocking, teardown);
1120 tcase_add_test (tc_block, test_show_version_1);
1121 tcase_add_test (tc_block, test_show_version_2);
1122 tcase_add_test (tc_block, test_loopbacks_1);
1123 tcase_add_test (tc_block, test_stats_1);
1124 tcase_add_test (tc_block, test_stats_2);
1125 suite_add_tcase (s, tc_block);
1127 TCase *tc_nonblock = tcase_create ("Nonblocking API");
1128 tcase_set_timeout (tc_nonblock, 25);
1129 tcase_add_checked_fixture (tc_nonblock, setup_nonblocking, teardown);
1130 tcase_add_test (tc_nonblock, test_show_version_3);
1131 tcase_add_test (tc_nonblock, test_show_version_4);
1132 tcase_add_test (tc_nonblock, test_show_version_5);
1133 tcase_add_test (tc_nonblock, test_loopbacks_2);
1134 tcase_add_test (tc_nonblock, test_stats_3);
1135 tcase_add_test (tc_nonblock, test_no_response_1);
1136 tcase_add_test (tc_nonblock, test_no_response_2);
1137 suite_add_tcase (s, tc_nonblock);
1139 TCase *tc_unsupported = tcase_create ("Unsupported message");
1140 tcase_add_checked_fixture (tc_unsupported, setup_blocking, teardown);
1141 tcase_add_test (tc_unsupported, test_unsupported);
1142 suite_add_tcase (s, tc_unsupported);
1148 main (int argc, char *argv[])
1152 printf ("Invalid argc==`%d'\n", argc);
1153 return EXIT_FAILURE;
1156 api_prefix = argv[2];
1157 printf ("App name: `%s', API prefix: `%s'\n", app_name, api_prefix);
1164 sr = srunner_create (s);
1166 srunner_run_all (sr, CK_NORMAL);
1167 number_failed = srunner_ntests_failed (sr);
1169 return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
1173 * fd.io coding-style-patch-verification: ON
1176 * eval: (c-set-style "gnu")