/* *------------------------------------------------------------------ * test.c -- VPP API/Stats tests * * Copyright (c) 2016 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *------------------------------------------------------------------ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "vppapiclient.h" #include "stat_client.h" #include #include #include #include #include #include volatile int sigterm_received = 0; volatile u32 result_ready; volatile u16 result_msg_id; /* M_NOALLOC: construct, but don't yet send a message */ #define M_NOALLOC(T,t) \ do { \ result_ready = 0; \ clib_memset (mp, 0, sizeof (*mp)); \ mp->_vl_msg_id = ntohs (VL_API_##T); \ mp->client_index = am->my_client_index; \ } while(0); void wrap_vac_callback (unsigned char *data, int len) { result_ready = 1; result_msg_id = ntohs(*((u16 *)data)); } static void test_connect () { int rv = vac_connect("vac_client", NULL, wrap_vac_callback, 32 /* rx queue-length*/); if (rv != 0) { printf("Connect failed: %d\n", rv); exit(rv); } printf("."); vac_disconnect(); } static void test_messages (void) { api_main_t * am = vlibapi_get_main(); vl_api_show_version_t message; vl_api_show_version_t *mp; int async = 1; int rv = vac_connect("vac_client", NULL, wrap_vac_callback, 32 /* rx queue-length*/); if (rv != 0) { printf("Connect failed: %d\n", rv); exit(rv); } double timestamp_start = unix_time_now_nsec() * 1e-6; /* * Test vpe_api_write and vpe_api_read to send and recv message for an * API */ int i; long int no_msgs = 10000; mp = &message; for (i = 0; i < no_msgs; i++) { /* Construct the API message */ M_NOALLOC(SHOW_VERSION, show_version); vac_write((char *)mp, sizeof(*mp)); #ifndef __COVERITY__ /* As given, async is always 1. Shut up Coverity about it */ if (!async) while (result_ready == 0); #endif } if (async) { vl_api_control_ping_t control; vl_api_control_ping_t *mp; mp = &control; M_NOALLOC(CONTROL_PING, control_ping); vac_write((char *)mp, sizeof(*mp)); while (result_msg_id != VL_API_CONTROL_PING_REPLY); } double timestamp_end = unix_time_now_nsec() * 1e-6; printf("\nTook %.2f msec, %.0f msgs/msec \n", (timestamp_end - timestamp_start), no_msgs/(timestamp_end - timestamp_start)); printf("Exiting...\n"); vac_disconnect(); } static void test_stats (void) { clib_mem_trace_enable_disable(1); clib_mem_trace (1); int rv = stat_segment_connect (STAT_SEGMENT_SOCKET_FILE); assert(rv == 0); u32 *dir; int i, k; stat_segment_data_t *res; u8 **pattern = 0; vec_add1(pattern, (u8 *)"/if/names"); vec_add1(pattern, (u8 *)"/err"); dir = stat_segment_ls ((u8 **)pattern); res = stat_segment_dump (dir); for (i = 0; i < vec_len (res); i++) { switch (res[i].type) { case STAT_DIR_TYPE_NAME_VECTOR: if (res[i].name_vector == 0) continue; for (k = 0; k < vec_len (res[i].name_vector); k++) if (res[i].name_vector[k]) fformat (stdout, "[%d]: %s %s\n", k, res[i].name_vector[k], res[i].name); break; default: assert(0); } } stat_segment_data_free (res); stat_segment_disconnect(); vec_free(pattern); vec_free(dir); (void) clib_mem_trace_enable_disable (0); u8 *leak_report = format (0, "%U", format_clib_mem_heap, 0, 1 /* verbose, i.e. print leaks */ ); printf("%s", leak_report); vec_free (leak_report); clib_mem_trace (0); } int main (int argc, char ** argv) { clib_mem_init (0, 3ULL << 30); test_stats(); int i; for (i = 0; i < 1000; i++) { test_connect(); } test_messages(); exit (0); }