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/memclnt.api.vapi.h>
28 #include <vapi/vlib.api.vapi.h>
29 #include <vapi/vpe.api.vapi.h>
30 #include <vapi/interface.api.vapi.h>
31 #include <vapi/mss_clamp.api.vapi.h>
32 #include <vapi/l2.api.vapi.h>
33 #include <fake.api.vapi.h>
35 #include <vppinfra/vec.h>
36 #include <vppinfra/mem.h>
38 DEFINE_VAPI_MSG_IDS_VPE_API_JSON;
39 DEFINE_VAPI_MSG_IDS_INTERFACE_API_JSON;
40 DEFINE_VAPI_MSG_IDS_MSS_CLAMP_API_JSON;
41 DEFINE_VAPI_MSG_IDS_L2_API_JSON;
42 DEFINE_VAPI_MSG_IDS_FAKE_API_JSON;
44 static char *app_name = NULL;
45 static char *api_prefix = NULL;
46 static const int max_outstanding_requests = 64;
47 static const int response_queue_size = 32;
49 /* centos has ancient check so we hack our way around here
50 * to make it work somehow */
51 #ifndef ck_assert_ptr_eq
52 #define ck_assert_ptr_eq(X,Y) ck_assert_int_eq((long)X, (long)Y)
55 #ifndef ck_assert_ptr_ne
56 #define ck_assert_ptr_ne(X,Y) ck_assert_int_ne((long)X, (long)Y)
59 START_TEST (test_invalid_values)
62 vapi_error_e rv = vapi_ctx_alloc (&ctx);
63 ck_assert_int_eq (VAPI_OK, rv);
64 vapi_msg_show_version *sv = vapi_alloc_show_version (ctx);
65 ck_assert_ptr_eq (NULL, sv);
66 rv = vapi_send (ctx, sv);
67 ck_assert_int_eq (VAPI_EINVAL, rv);
68 rv = vapi_connect (ctx, app_name, api_prefix, max_outstanding_requests,
69 response_queue_size, VAPI_MODE_BLOCKING, true);
70 ck_assert_int_eq (VAPI_OK, rv);
71 rv = vapi_send (ctx, NULL);
72 ck_assert_int_eq (VAPI_EINVAL, rv);
73 rv = vapi_send (NULL, NULL);
74 ck_assert_int_eq (VAPI_EINVAL, rv);
75 rv = vapi_recv (NULL, NULL, NULL, 0, 0);
76 ck_assert_int_eq (VAPI_EINVAL, rv);
77 rv = vapi_recv (ctx, NULL, NULL, 0, 0);
78 ck_assert_int_eq (VAPI_EINVAL, rv);
79 vapi_msg_show_version_reply *reply;
80 rv = vapi_recv (ctx, (void **) &reply, NULL, 0, 0);
81 ck_assert_int_eq (VAPI_EINVAL, rv);
82 rv = vapi_disconnect (ctx);
83 ck_assert_int_eq (VAPI_OK, rv);
89 START_TEST (test_hton_1)
91 const u16 _vl_msg_id = 1;
92 vapi_type_msg_header1_t h;
93 h._vl_msg_id = _vl_msg_id;
94 vapi_type_msg_header1_t_hton (&h);
95 ck_assert_int_eq (be16toh (h._vl_msg_id), _vl_msg_id);
100 START_TEST (test_hton_2)
102 const u16 _vl_msg_id = 1;
103 const u32 client_index = 3;
104 vapi_type_msg_header2_t h;
105 h._vl_msg_id = _vl_msg_id;
106 h.client_index = client_index;
107 vapi_type_msg_header2_t_hton (&h);
108 ck_assert_int_eq (be16toh (h._vl_msg_id), _vl_msg_id);
109 ck_assert_int_eq (h.client_index, client_index);
114 #define verify_hton_swap(expr, value) \
115 if (4 == sizeof (expr)) \
117 ck_assert_int_eq (expr, htobe32 (value)); \
119 else if (2 == sizeof (expr)) \
121 ck_assert_int_eq (expr, htobe16 (value)); \
125 ck_assert_int_eq (expr, value); \
128 START_TEST (test_hton_4)
130 const int vla_count = 3;
131 char x[sizeof (vapi_msg_bridge_domain_details) +
132 vla_count * sizeof (vapi_type_bridge_domain_sw_if)];
133 vapi_msg_bridge_domain_details *d = (void *) x;
135 d->header._vl_msg_id = cnt++;
136 d->header.context = cnt++;
137 d->payload.bd_id = cnt++;
138 d->payload.mac_age = cnt++;
139 d->payload.bvi_sw_if_index = cnt++;
140 d->payload.n_sw_ifs = vla_count;
142 for (i = 0; i < vla_count; ++i)
144 vapi_type_bridge_domain_sw_if *det = &d->payload.sw_if_details[i];
145 det->context = cnt++;
146 det->sw_if_index = cnt++;
149 ck_assert_int_eq (sizeof (x), vapi_calc_bridge_domain_details_msg_size (d));
150 vapi_msg_bridge_domain_details_hton (d);
152 verify_hton_swap (d->header._vl_msg_id, tmp);
154 ck_assert_int_eq (d->header.context, tmp);
156 verify_hton_swap (d->payload.bd_id, tmp);
158 verify_hton_swap (d->payload.mac_age, tmp);
160 verify_hton_swap (d->payload.bvi_sw_if_index, tmp);
162 ck_assert_int_eq (d->payload.n_sw_ifs, htobe32 (vla_count));
163 for (i = 0; i < vla_count; ++i)
165 vapi_type_bridge_domain_sw_if *det = &d->payload.sw_if_details[i];
166 verify_hton_swap (det->context, tmp);
168 verify_hton_swap (det->sw_if_index, tmp);
170 verify_hton_swap (det->shg, tmp);
173 vapi_msg_bridge_domain_details_ntoh (d);
175 ck_assert_int_eq (d->header._vl_msg_id, tmp);
177 ck_assert_int_eq (d->header.context, tmp);
179 ck_assert_int_eq (d->payload.bd_id, tmp);
181 ck_assert_int_eq (d->payload.mac_age, tmp);
183 ck_assert_int_eq (d->payload.bvi_sw_if_index, tmp);
185 ck_assert_int_eq (d->payload.n_sw_ifs, vla_count);
186 for (i = 0; i < vla_count; ++i)
188 vapi_type_bridge_domain_sw_if *det = &d->payload.sw_if_details[i];
189 ck_assert_int_eq (det->context, tmp);
191 ck_assert_int_eq (det->sw_if_index, tmp);
193 ck_assert_int_eq (det->shg, tmp);
196 ck_assert_int_eq (sizeof (x), vapi_calc_bridge_domain_details_msg_size (d));
201 START_TEST (test_ntoh_1)
203 const u16 _vl_msg_id = 1;
204 vapi_type_msg_header1_t h;
205 h._vl_msg_id = _vl_msg_id;
206 vapi_type_msg_header1_t_ntoh (&h);
207 ck_assert_int_eq (htobe16 (h._vl_msg_id), _vl_msg_id);
212 START_TEST (test_ntoh_2)
214 const u16 _vl_msg_id = 1;
215 const u32 client_index = 3;
216 vapi_type_msg_header2_t h;
217 h._vl_msg_id = _vl_msg_id;
218 h.client_index = client_index;
219 vapi_type_msg_header2_t_ntoh (&h);
220 ck_assert_int_eq (htobe16 (h._vl_msg_id), _vl_msg_id);
221 ck_assert_int_eq (h.client_index, client_index);
226 #define verify_ntoh_swap(expr, value) \
227 if (4 == sizeof (expr)) \
229 ck_assert_int_eq (expr, be32toh (value)); \
231 else if (2 == sizeof (expr)) \
233 ck_assert_int_eq (expr, be16toh (value)); \
237 ck_assert_int_eq (expr, value); \
240 START_TEST (test_ntoh_4)
242 const int vla_count = 3;
243 char x[sizeof (vapi_msg_bridge_domain_details) +
244 vla_count * sizeof (vapi_type_bridge_domain_sw_if)];
245 vapi_msg_bridge_domain_details *d = (void *) x;
247 d->header._vl_msg_id = cnt++;
248 d->header.context = cnt++;
249 d->payload.bd_id = cnt++;
250 d->payload.mac_age = cnt++;
251 d->payload.bvi_sw_if_index = cnt++;
252 d->payload.n_sw_ifs = htobe32 (vla_count);
254 for (i = 0; i < vla_count; ++i)
256 vapi_type_bridge_domain_sw_if *det = &d->payload.sw_if_details[i];
257 det->context = cnt++;
258 det->sw_if_index = cnt++;
261 vapi_msg_bridge_domain_details_ntoh (d);
262 ck_assert_int_eq (sizeof (x), vapi_calc_bridge_domain_details_msg_size (d));
264 verify_ntoh_swap (d->header._vl_msg_id, tmp);
266 ck_assert_int_eq (d->header.context, tmp);
268 verify_ntoh_swap (d->payload.bd_id, tmp);
270 verify_ntoh_swap (d->payload.mac_age, tmp);
272 verify_ntoh_swap (d->payload.bvi_sw_if_index, tmp);
274 ck_assert_int_eq (d->payload.n_sw_ifs, vla_count);
275 for (i = 0; i < vla_count; ++i)
277 vapi_type_bridge_domain_sw_if *det = &d->payload.sw_if_details[i];
278 verify_ntoh_swap (det->context, tmp);
280 verify_ntoh_swap (det->sw_if_index, tmp);
282 verify_ntoh_swap (det->shg, tmp);
285 vapi_msg_bridge_domain_details_hton (d);
287 ck_assert_int_eq (d->header._vl_msg_id, tmp);
289 ck_assert_int_eq (d->header.context, tmp);
291 ck_assert_int_eq (d->payload.bd_id, tmp);
293 ck_assert_int_eq (d->payload.mac_age, tmp);
295 ck_assert_int_eq (d->payload.bvi_sw_if_index, tmp);
297 ck_assert_int_eq (d->payload.n_sw_ifs, htobe32 (vla_count));
298 for (i = 0; i < vla_count; ++i)
300 vapi_type_bridge_domain_sw_if *det = &d->payload.sw_if_details[i];
301 ck_assert_int_eq (det->context, tmp);
303 ck_assert_int_eq (det->sw_if_index, tmp);
305 ck_assert_int_eq (det->shg, tmp);
313 show_version_cb (vapi_ctx_t ctx, void *caller_ctx,
314 vapi_error_e rv, bool is_last,
315 vapi_payload_show_version_reply * p)
317 ck_assert_int_eq (VAPI_OK, rv);
318 ck_assert_int_eq (true, is_last);
319 ck_assert_str_eq ("vpe", (char *) p->program);
321 ("show_version_reply: program: `%s', version: `%s', build directory: "
322 "`%s', build date: `%s'\n", p->program, p->version, p->build_directory,
324 ++*(int *) caller_ctx;
332 u32 *sw_if_index_storage;
333 } test_create_loopback_ctx_t;
336 loopback_create_cb (vapi_ctx_t ctx, void *caller_ctx,
337 vapi_error_e rv, bool is_last,
338 vapi_payload_create_loopback_reply * p)
340 test_create_loopback_ctx_t *clc = caller_ctx;
341 ck_assert_int_eq (clc->expected_retval, p->retval);
342 *clc->sw_if_index_storage = p->sw_if_index;
351 u32 *sw_if_index_storage;
352 } test_delete_loopback_ctx_t;
355 loopback_delete_cb (vapi_ctx_t ctx, void *caller_ctx,
356 vapi_error_e rv, bool is_last,
357 vapi_payload_delete_loopback_reply * p)
359 test_delete_loopback_ctx_t *dlc = caller_ctx;
360 ck_assert_int_eq (dlc->expected_retval, p->retval);
365 START_TEST (test_connect)
368 vapi_error_e rv = vapi_ctx_alloc (&ctx);
369 ck_assert_int_eq (VAPI_OK, rv);
370 rv = vapi_connect (ctx, app_name, api_prefix, max_outstanding_requests,
371 response_queue_size, VAPI_MODE_BLOCKING, true);
372 ck_assert_int_eq (VAPI_OK, rv);
373 rv = vapi_disconnect (ctx);
374 ck_assert_int_eq (VAPI_OK, rv);
383 setup_blocking (void)
385 vapi_error_e rv = vapi_ctx_alloc (&ctx);
386 ck_assert_int_eq (VAPI_OK, rv);
387 rv = vapi_connect (ctx, app_name, api_prefix, max_outstanding_requests,
388 response_queue_size, VAPI_MODE_BLOCKING, true);
389 ck_assert_int_eq (VAPI_OK, rv);
393 setup_nonblocking (void)
395 vapi_error_e rv = vapi_ctx_alloc (&ctx);
396 ck_assert_int_eq (VAPI_OK, rv);
397 rv = vapi_connect (ctx, app_name, api_prefix, max_outstanding_requests,
398 response_queue_size, VAPI_MODE_NONBLOCKING, true);
399 ck_assert_int_eq (VAPI_OK, rv);
405 vapi_disconnect (ctx);
409 START_TEST (test_show_version_1)
411 printf ("--- Basic show version message - reply test ---\n");
412 vapi_msg_show_version *sv = vapi_alloc_show_version (ctx);
413 ck_assert_ptr_ne (NULL, sv);
414 vapi_msg_show_version_hton (sv);
415 vapi_error_e rv = vapi_send (ctx, sv);
416 ck_assert_int_eq (VAPI_OK, rv);
417 vapi_msg_show_version_reply *resp;
419 rv = vapi_recv (ctx, (void *) &resp, &size, 0, 0);
420 ck_assert_int_eq (VAPI_OK, rv);
422 show_version_cb (NULL, &placeholder, VAPI_OK, true, &resp->payload);
423 vapi_msg_free (ctx, resp);
428 START_TEST (test_show_version_2)
431 printf ("--- Show version via blocking callback API ---\n");
432 const int attempts = response_queue_size * 4;
434 for (i = 0; i < attempts; ++i)
436 vapi_msg_show_version *sv = vapi_alloc_show_version (ctx);
437 ck_assert_ptr_ne (NULL, sv);
438 vapi_error_e rv = vapi_show_version (ctx, sv, show_version_cb, &called);
439 ck_assert_int_eq (VAPI_OK, rv);
441 ck_assert_int_eq (attempts, called);
453 } sw_interface_dump_ctx;
456 sw_interface_dump_cb (struct vapi_ctx_s *ctx, void *callback_ctx,
457 vapi_error_e rv, bool is_last,
458 vapi_payload_sw_interface_details * reply)
460 sw_interface_dump_ctx *dctx = callback_ctx;
461 ck_assert_int_eq (false, dctx->last_called);
464 ck_assert (NULL == reply);
465 dctx->last_called = true;
469 ck_assert (NULL != reply);
470 printf ("Interface dump entry: [%u]: %s\n", reply->sw_if_index,
471 reply->interface_name);
473 for (i = 0; i < dctx->num_ifs; ++i)
475 if (dctx->sw_if_indexes[i] == reply->sw_if_index)
477 ck_assert_int_eq (false, dctx->seen[i]);
478 dctx->seen[i] = true;
487 vapi_mss_clamp_enable_disable_reply_cb (
488 struct vapi_ctx_s *ctx, void *callback_ctx, vapi_error_e rv, bool is_last,
489 vapi_payload_mss_clamp_enable_disable_reply *reply)
491 bool *x = callback_ctx;
497 vapi_mss_clamp_get_reply_cb (struct vapi_ctx_s *ctx, void *callback_ctx,
498 vapi_error_e rv, bool is_last,
499 vapi_payload_mss_clamp_get_reply *reply)
501 int *counter = callback_ctx;
502 ck_assert_int_gt (*counter, 0); // make sure details were called first
504 ck_assert_int_eq (is_last, true);
505 printf ("Got mss clamp reply error %d\n", rv);
506 ck_assert_int_eq (rv, VAPI_OK);
507 printf ("counter is %d", *counter);
512 vapi_mss_clamp_get_details_cb (struct vapi_ctx_s *ctx, void *callback_ctx,
513 vapi_error_e rv, bool is_last,
514 vapi_payload_mss_clamp_details *details)
516 int *counter = callback_ctx;
520 printf ("Got ipv4 mss clamp to %u for sw_if_index %u\n",
521 details->ipv4_mss, details->sw_if_index);
522 ck_assert_int_eq (details->ipv4_mss, 1000 + details->sw_if_index);
524 printf ("counter is %d", *counter);
528 START_TEST (test_loopbacks_1)
530 printf ("--- Create/delete loopbacks using blocking API ---\n");
531 const size_t num_ifs = 5;
532 u8 mac_addresses[num_ifs][6];
533 clib_memset (&mac_addresses, 0, sizeof (mac_addresses));
534 u32 sw_if_indexes[num_ifs];
535 clib_memset (&sw_if_indexes, 0xff, sizeof (sw_if_indexes));
536 test_create_loopback_ctx_t clcs[num_ifs];
537 clib_memset (&clcs, 0, sizeof (clcs));
538 test_delete_loopback_ctx_t dlcs[num_ifs];
539 clib_memset (&dlcs, 0, sizeof (dlcs));
541 for (i = 0; i < num_ifs; ++i)
543 memcpy (&mac_addresses[i], "\1\2\3\4\5\6", 6);
544 mac_addresses[i][5] = i;
545 clcs[i].sw_if_index_storage = &sw_if_indexes[i];
547 for (i = 0; i < num_ifs; ++i)
549 vapi_msg_create_loopback *cl = vapi_alloc_create_loopback (ctx);
551 for (j = 0; j < 6; ++j)
553 cl->payload.mac_address[j] = mac_addresses[i][j];
556 vapi_create_loopback (ctx, cl, loopback_create_cb, &clcs[i]);
557 ck_assert_int_eq (VAPI_OK, rv);
559 for (i = 0; i < num_ifs; ++i)
561 ck_assert_int_eq (1, clcs[i].called);
562 printf ("Created loopback with MAC %02x:%02x:%02x:%02x:%02x:%02x --> "
564 mac_addresses[i][0], mac_addresses[i][1], mac_addresses[i][2],
565 mac_addresses[i][3], mac_addresses[i][4], mac_addresses[i][5],
570 for (int i = 0; i < num_ifs; ++i)
572 vapi_msg_mss_clamp_enable_disable *mc =
573 vapi_alloc_mss_clamp_enable_disable (ctx);
574 mc->payload.sw_if_index = sw_if_indexes[i];
575 mc->payload.ipv4_mss = 1000 + sw_if_indexes[i];
576 mc->payload.ipv4_direction = MSS_CLAMP_DIR_RX;
577 bool reply_ctx = false;
578 printf ("Set ipv4 mss clamp to %u for sw_if_index %u\n",
579 mc->payload.ipv4_mss, mc->payload.sw_if_index);
580 vapi_error_e rv = vapi_mss_clamp_enable_disable (
581 ctx, mc, vapi_mss_clamp_enable_disable_reply_cb, &reply_ctx);
582 ck_assert_int_eq (VAPI_OK, rv);
583 ck_assert_int_eq (reply_ctx, true);
589 vapi_msg_mss_clamp_get *msg = vapi_alloc_mss_clamp_get (ctx);
590 msg->payload.sw_if_index = ~0;
592 vapi_mss_clamp_get (ctx, msg, vapi_mss_clamp_get_reply_cb, &counter,
593 vapi_mss_clamp_get_details_cb, &counter);
594 printf ("counter is %d", counter);
595 ck_assert_int_eq (VAPI_OK, rv);
596 ck_assert_int_eq (counter, num_ifs + 1);
600 sw_interface_dump_ctx dctx = { false, num_ifs, sw_if_indexes, seen, 0 };
601 vapi_msg_sw_interface_dump *dump;
603 const int attempts = response_queue_size * 4;
604 for (i = 0; i < attempts; ++i)
606 dctx.last_called = false;
607 clib_memset (&seen, 0, sizeof (seen));
608 dump = vapi_alloc_sw_interface_dump (ctx, 0);
609 while (VAPI_EAGAIN ==
611 vapi_sw_interface_dump (ctx, dump, sw_interface_dump_cb,
614 ck_assert_int_eq (true, dctx.last_called);
616 for (j = 0; j < num_ifs; ++j)
618 ck_assert_int_eq (true, seen[j]);
621 clib_memset (&seen, 0, sizeof (seen));
622 for (i = 0; i < num_ifs; ++i)
624 vapi_msg_delete_loopback *dl = vapi_alloc_delete_loopback (ctx);
625 dl->payload.sw_if_index = sw_if_indexes[i];
627 vapi_delete_loopback (ctx, dl, loopback_delete_cb, &dlcs[i]);
628 ck_assert_int_eq (VAPI_OK, rv);
630 for (i = 0; i < num_ifs; ++i)
632 ck_assert_int_eq (1, dlcs[i].called);
633 printf ("Deleted loopback with sw_if_index %u\n", sw_if_indexes[i]);
635 dctx.last_called = false;
636 clib_memset (&seen, 0, sizeof (seen));
637 dump = vapi_alloc_sw_interface_dump (ctx, 0);
638 while (VAPI_EAGAIN ==
640 vapi_sw_interface_dump (ctx, dump, sw_interface_dump_cb, &dctx)))
642 ck_assert_int_eq (true, dctx.last_called);
643 for (i = 0; i < num_ifs; ++i)
645 ck_assert_int_eq (false, seen[i]);
651 START_TEST (test_show_version_3)
653 printf ("--- Show version via async callback ---\n");
656 vapi_msg_show_version *sv = vapi_alloc_show_version (ctx);
657 ck_assert_ptr_ne (NULL, sv);
658 while (VAPI_EAGAIN ==
659 (rv = vapi_show_version (ctx, sv, show_version_cb, &called)))
661 ck_assert_int_eq (VAPI_OK, rv);
662 ck_assert_int_eq (0, called);
663 while (VAPI_EAGAIN == (rv = vapi_dispatch (ctx)))
665 ck_assert_int_eq (VAPI_OK, rv);
666 ck_assert_int_eq (1, called);
668 rv = vapi_dispatch (ctx);
669 ck_assert_int_eq (VAPI_OK, rv);
670 ck_assert_int_eq (0, called);
675 START_TEST (test_show_version_4)
677 printf ("--- Show version via async callback - multiple messages ---\n");
679 const size_t num_req = 5;
680 int contexts[num_req];
681 clib_memset (contexts, 0, sizeof (contexts));
683 for (i = 0; i < num_req; ++i)
685 vapi_msg_show_version *sv = vapi_alloc_show_version (ctx);
686 ck_assert_ptr_ne (NULL, sv);
687 while (VAPI_EAGAIN ==
689 vapi_show_version (ctx, sv, show_version_cb, &contexts[i])))
691 ck_assert_int_eq (VAPI_OK, rv);
693 for (j = 0; j < num_req; ++j)
695 ck_assert_int_eq (0, contexts[j]);
698 while (VAPI_EAGAIN == (rv = vapi_dispatch (ctx)))
700 ck_assert_int_eq (VAPI_OK, rv);
701 for (i = 0; i < num_req; ++i)
703 ck_assert_int_eq (1, contexts[i]);
705 clib_memset (contexts, 0, sizeof (contexts));
706 while (VAPI_EAGAIN == (rv = vapi_dispatch (ctx)))
708 ck_assert_int_eq (VAPI_OK, rv);
709 for (i = 0; i < num_req; ++i)
711 ck_assert_int_eq (0, contexts[i]);
717 START_TEST (test_loopbacks_2)
719 printf ("--- Create/delete loopbacks using non-blocking API ---\n");
721 const size_t num_ifs = 5;
722 u8 mac_addresses[num_ifs][6];
723 clib_memset (&mac_addresses, 0, sizeof (mac_addresses));
724 u32 sw_if_indexes[num_ifs];
725 clib_memset (&sw_if_indexes, 0xff, sizeof (sw_if_indexes));
726 test_create_loopback_ctx_t clcs[num_ifs];
727 clib_memset (&clcs, 0, sizeof (clcs));
728 test_delete_loopback_ctx_t dlcs[num_ifs];
729 clib_memset (&dlcs, 0, sizeof (dlcs));
731 for (i = 0; i < num_ifs; ++i)
733 memcpy (&mac_addresses[i], "\1\2\3\4\5\6", 6);
734 mac_addresses[i][5] = i;
735 clcs[i].sw_if_index_storage = &sw_if_indexes[i];
737 for (i = 0; i < num_ifs; ++i)
739 vapi_msg_create_loopback *cl = vapi_alloc_create_loopback (ctx);
741 for (j = 0; j < 6; ++j)
743 cl->payload.mac_address[j] = mac_addresses[i][j];
745 while (VAPI_EAGAIN ==
747 vapi_create_loopback (ctx, cl, loopback_create_cb, &clcs[i])))
749 ck_assert_int_eq (VAPI_OK, rv);
751 while (VAPI_EAGAIN == (rv = vapi_dispatch (ctx)))
753 ck_assert_int_eq (VAPI_OK, rv);
754 for (i = 0; i < num_ifs; ++i)
756 ck_assert_int_eq (1, clcs[i].called);
757 printf ("Loopback with MAC %02x:%02x:%02x:%02x:%02x:%02x --> "
759 mac_addresses[i][0], mac_addresses[i][1], mac_addresses[i][2],
760 mac_addresses[i][3], mac_addresses[i][4], mac_addresses[i][5],
764 clib_memset (&seen, 0, sizeof (seen));
765 sw_interface_dump_ctx dctx = { false, num_ifs, sw_if_indexes, seen, 0 };
766 vapi_msg_sw_interface_dump *dump = vapi_alloc_sw_interface_dump (ctx, 0);
767 while (VAPI_EAGAIN ==
769 vapi_sw_interface_dump (ctx, dump, sw_interface_dump_cb, &dctx)))
771 for (i = 0; i < num_ifs; ++i)
773 ck_assert_int_eq (false, seen[i]);
775 clib_memset (&seen, 0, sizeof (seen));
776 ck_assert_int_eq (false, dctx.last_called);
777 while (VAPI_EAGAIN == (rv = vapi_dispatch (ctx)))
779 ck_assert_int_eq (VAPI_OK, rv);
780 for (i = 0; i < num_ifs; ++i)
782 ck_assert_int_eq (true, seen[i]);
784 clib_memset (&seen, 0, sizeof (seen));
785 ck_assert_int_eq (true, dctx.last_called);
786 for (i = 0; i < num_ifs; ++i)
788 vapi_msg_delete_loopback *dl = vapi_alloc_delete_loopback (ctx);
789 dl->payload.sw_if_index = sw_if_indexes[i];
790 while (VAPI_EAGAIN ==
792 vapi_delete_loopback (ctx, dl, loopback_delete_cb, &dlcs[i])))
794 ck_assert_int_eq (VAPI_OK, rv);
796 while (VAPI_EAGAIN == (rv = vapi_dispatch (ctx)))
798 ck_assert_int_eq (VAPI_OK, rv);
799 for (i = 0; i < num_ifs; ++i)
801 ck_assert_int_eq (1, dlcs[i].called);
802 printf ("Deleted loopback with sw_if_index %u\n", sw_if_indexes[i]);
804 clib_memset (&seen, 0, sizeof (seen));
805 dctx.last_called = false;
806 dump = vapi_alloc_sw_interface_dump (ctx, 0);
807 while (VAPI_EAGAIN ==
809 vapi_sw_interface_dump (ctx, dump, sw_interface_dump_cb, &dctx)))
811 while (VAPI_EAGAIN == (rv = vapi_dispatch (ctx)))
813 ck_assert_int_eq (VAPI_OK, rv);
814 for (i = 0; i < num_ifs; ++i)
816 ck_assert_int_eq (false, seen[i]);
818 clib_memset (&seen, 0, sizeof (seen));
819 ck_assert_int_eq (true, dctx.last_called);
825 generic_cb (vapi_ctx_t ctx, void *callback_ctx, vapi_msg_id_t id, void *msg)
827 int *called = callback_ctx;
828 ck_assert_int_eq (0, *called);
830 ck_assert_int_eq (id, vapi_msg_id_show_version_reply);
831 ck_assert_ptr_ne (NULL, msg);
832 vapi_msg_show_version_reply *reply = msg;
833 ck_assert_str_eq ("vpe", (char *) reply->payload.program);
837 START_TEST (test_show_version_5)
839 printf ("--- Receive show version using generic callback - nonblocking "
842 vapi_msg_show_version *sv = vapi_alloc_show_version (ctx);
843 ck_assert_ptr_ne (NULL, sv);
844 vapi_msg_show_version_hton (sv);
845 while (VAPI_EAGAIN == (rv = vapi_send (ctx, sv)))
847 ck_assert_int_eq (VAPI_OK, rv);
849 vapi_set_generic_event_cb (ctx, generic_cb, &called);
850 ck_assert_int_eq (VAPI_OK, rv);
851 while (VAPI_EAGAIN == (rv = vapi_dispatch_one (ctx)))
853 ck_assert_int_eq (VAPI_OK, rv);
854 ck_assert_int_eq (1, called);
855 sv = vapi_alloc_show_version (ctx);
856 ck_assert_ptr_ne (NULL, sv);
857 vapi_msg_show_version_hton (sv);
858 while (VAPI_EAGAIN == (rv = vapi_send (ctx, sv)))
860 ck_assert_int_eq (VAPI_OK, rv);
861 vapi_clear_generic_event_cb (ctx);
862 while (VAPI_EAGAIN == (rv = vapi_dispatch_one (ctx)))
864 ck_assert_int_eq (VAPI_OK, rv);
865 ck_assert_int_eq (1, called); /* needs to remain unchanged */
871 show_version_no_cb (vapi_ctx_t ctx, void *caller_ctx,
872 vapi_error_e rv, bool is_last,
873 vapi_payload_show_version_reply * p)
875 ck_assert_int_eq (VAPI_ENORESP, rv);
876 ck_assert_int_eq (true, is_last);
877 ck_assert_ptr_eq (NULL, p);
878 ++*(int *) caller_ctx;
882 START_TEST (test_no_response_1)
884 printf ("--- Simulate no response to regular message ---\n");
886 vapi_msg_show_version *sv = vapi_alloc_show_version (ctx);
887 ck_assert_ptr_ne (NULL, sv);
888 sv->header._vl_msg_id = ~0; /* malformed ID causes vpp to drop the msg */
890 while (VAPI_EAGAIN ==
891 (rv = vapi_show_version (ctx, sv, show_version_no_cb, &called)))
893 ck_assert_int_eq (VAPI_OK, rv);
894 sv = vapi_alloc_show_version (ctx);
895 ck_assert_ptr_ne (NULL, sv);
896 while (VAPI_EAGAIN ==
897 (rv = vapi_show_version (ctx, sv, show_version_cb, &called)))
899 ck_assert_int_eq (VAPI_OK, rv);
900 while (VAPI_EAGAIN == (rv = vapi_dispatch (ctx)))
902 ck_assert_int_eq (VAPI_OK, rv);
903 ck_assert_int_eq (2, called);
909 no_msg_cb (struct vapi_ctx_s *ctx, void *callback_ctx,
910 vapi_error_e rv, bool is_last,
911 vapi_payload_sw_interface_details * reply)
913 int *called = callback_ctx;
915 ck_assert_int_eq (VAPI_OK, rv);
916 ck_assert_int_eq (true, is_last);
917 ck_assert_ptr_eq (NULL, reply);
921 START_TEST (test_no_response_2)
923 printf ("--- Simulate no response to dump message ---\n");
925 vapi_msg_sw_interface_dump *dump = vapi_alloc_sw_interface_dump (ctx, 0);
926 dump->header._vl_msg_id = ~0; /* malformed ID causes vpp to drop the msg */
928 while (VAPI_EAGAIN ==
929 (rv = vapi_sw_interface_dump (ctx, dump, no_msg_cb, &no_called)))
931 ck_assert_int_eq (VAPI_OK, rv);
932 while (VAPI_EAGAIN == (rv = vapi_dispatch (ctx)))
934 ck_assert_int_eq (VAPI_OK, rv);
935 ck_assert_int_eq (1, no_called);
940 START_TEST (test_unsupported)
942 printf ("--- Unsupported messages ---\n");
943 bool available = vapi_is_msg_available (ctx, vapi_msg_id_test_fake_msg);
944 ck_assert_int_eq (false, available);
949 START_TEST (test_api_strings)
951 printf ("--- Invalid api strings ---\n");
953 /* test string 'TEST'
957 const char str[] = "TEST";
958 u8 *vec_str = 0, *vstr = 0;
961 vapi_msg_sw_interface_dump *dump =
962 malloc (sizeof (vapi_msg_sw_interface_dump) + strlen (str));
963 clib_mem_init (0, 1 << 20);
965 vl_api_c_string_to_api_string (str, &dump->payload.name_filter);
966 /* Assert nul terminator NOT present */
967 ck_assert_int_eq (vl_api_string_len (&dump->payload.name_filter),
970 cstr = vl_api_from_api_to_new_c_string (&dump->payload.name_filter);
971 ck_assert_ptr_ne (cstr, NULL);
972 /* Assert nul terminator present */
973 ck_assert_int_eq (vec_len (cstr), sizeof (str));
974 ck_assert_int_eq (strlen (str), strlen (cstr));
977 vstr = vl_api_from_api_to_new_vec (0 /* not really an API message */ ,
978 &dump->payload.name_filter);
979 ck_assert_ptr_ne (vstr, NULL);
980 /* Assert nul terminator NOT present */
981 ck_assert_int_eq (vec_len (vstr), strlen (str));
984 /* vector conaining NON nul terminated string 'TEST' */
985 vec_add (vec_str, str, strlen (str));
986 clib_memset (dump->payload.name_filter.buf, 0, strlen (str));
987 dump->payload.name_filter.length = 0;
989 vl_api_vec_to_api_string (vec_str, &dump->payload.name_filter);
990 /* Assert nul terminator NOT present */
991 ck_assert_int_eq (vl_api_string_len (&dump->payload.name_filter),
994 cstr = vl_api_from_api_to_new_c_string (&dump->payload.name_filter);
995 ck_assert_ptr_ne (cstr, NULL);
996 /* Assert nul terminator present */
997 ck_assert_int_eq (vec_len (cstr), sizeof (str));
998 ck_assert_int_eq (strlen (str), strlen (cstr));
1001 vstr = vl_api_from_api_to_new_vec (0 /* not a real api msg */ ,
1002 &dump->payload.name_filter);
1003 ck_assert_ptr_ne (vstr, NULL);
1004 /* Assert nul terminator NOT present */
1005 ck_assert_int_eq (vec_len (vstr), strlen (str));
1015 Suite *s = suite_create ("VAPI test");
1017 TCase *tc_negative = tcase_create ("Negative tests");
1018 tcase_add_test (tc_negative, test_invalid_values);
1019 suite_add_tcase (s, tc_negative);
1021 TCase *tc_swap = tcase_create ("Byteswap tests");
1022 tcase_add_test (tc_swap, test_hton_1);
1023 tcase_add_test (tc_swap, test_hton_2);
1024 tcase_add_test (tc_swap, test_hton_4);
1025 tcase_add_test (tc_swap, test_ntoh_1);
1026 tcase_add_test (tc_swap, test_ntoh_2);
1027 tcase_add_test (tc_swap, test_ntoh_4);
1028 suite_add_tcase (s, tc_swap);
1030 TCase *tc_connect = tcase_create ("Connect");
1031 tcase_add_test (tc_connect, test_connect);
1032 suite_add_tcase (s, tc_connect);
1034 TCase *tc_block = tcase_create ("Blocking API");
1035 tcase_set_timeout (tc_block, 25);
1036 tcase_add_checked_fixture (tc_block, setup_blocking, teardown);
1037 tcase_add_test (tc_block, test_show_version_1);
1038 tcase_add_test (tc_block, test_show_version_2);
1039 tcase_add_test (tc_block, test_loopbacks_1);
1040 suite_add_tcase (s, tc_block);
1042 TCase *tc_nonblock = tcase_create ("Nonblocking API");
1043 tcase_set_timeout (tc_nonblock, 25);
1044 tcase_add_checked_fixture (tc_nonblock, setup_nonblocking, teardown);
1045 tcase_add_test (tc_nonblock, test_show_version_3);
1046 tcase_add_test (tc_nonblock, test_show_version_4);
1047 tcase_add_test (tc_nonblock, test_show_version_5);
1048 tcase_add_test (tc_nonblock, test_loopbacks_2);
1049 tcase_add_test (tc_nonblock, test_no_response_1);
1050 tcase_add_test (tc_nonblock, test_no_response_2);
1051 suite_add_tcase (s, tc_nonblock);
1053 TCase *tc_unsupported = tcase_create ("Unsupported message");
1054 tcase_add_checked_fixture (tc_unsupported, setup_blocking, teardown);
1055 tcase_add_test (tc_unsupported, test_unsupported);
1056 suite_add_tcase (s, tc_unsupported);
1058 TCase *tc_dynamic = tcase_create ("Dynamic message size");
1059 tcase_add_test (tc_dynamic, test_api_strings);
1060 suite_add_tcase (s, tc_dynamic);
1066 main (int argc, char *argv[])
1070 printf ("Invalid argc==`%d'\n", argc);
1071 return EXIT_FAILURE;
1074 api_prefix = argv[2];
1075 printf ("App name: `%s', API prefix: `%s'\n", app_name, api_prefix);
1082 sr = srunner_create (s);
1084 srunner_run_all (sr, CK_NORMAL);
1085 number_failed = srunner_ntests_failed (sr);
1087 return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
1091 * fd.io coding-style-patch-verification: ON
1094 * eval: (c-set-style "gnu")