LCOV - code coverage report
Current view: top level - root/contrail/vrouter/utils/vtest - vt_process_xml.c (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 140 202 69.3 %
Date: 2026-08-03 02:19:58 Functions: 13 14 92.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : 
       2             : #include <stdio.h>
       3             : #include <string.h>
       4             : #include <stdlib.h>
       5             : #include <stdbool.h>
       6             : #include <errno.h>
       7             : #include <unistd.h>
       8             : 
       9             : #include <libxml/xmlmemory.h>
      10             : #include <libxml/parser.h>
      11             : 
      12             : #include <vtest.h>
      13             : #include <vt_main.h>
      14             : #include <vt_message.h>
      15             : #include <vt_process_xml.h>
      16             : 
      17             : #include <net/if.h>
      18             : #include <nl_util.h>
      19             : 
      20             : #include <vt_packet.h>
      21             : 
      22             : extern struct vtest_module vt_modules[];
      23             : #define SKIP_TEST_PFX "SKIP"
      24             : 
      25             : int
      26        2920 : vt_test_name(xmlNodePtr node, struct vtest *test)
      27             : {
      28             :     xmlNodePtr child;
      29        2920 :     if (!node ||!test) {
      30           0 :         return E_PROCESS_XML_ERR_FARG;
      31             :     }
      32             : 
      33        2920 :     child = node->xmlChildrenNode;
      34        2920 :     if (!child || !child->content || !strlen(child->content)) {
      35           0 :         return E_MAIN_ERR_FARG;
      36             :     }
      37             : 
      38        2920 :     if (strncmp(child->content, SKIP_TEST_PFX,
      39             :         sizeof(SKIP_TEST_PFX) - 1) == 0) {
      40           0 :         printf("Skipping %s...\n", (char *)child->content +
      41             :             sizeof(SKIP_TEST_PFX) + 1);
      42           0 :         return E_MAIN_SKIP;
      43             :     } else {
      44        2920 :         printf("Running %s...\n", (char *)child->content);
      45             :     }
      46             : 
      47        2920 :     return E_PROCESS_XML_OK;
      48             : }
      49             : 
      50             : static int
      51           0 : vt_search_vt_modules_by_name(char *vt_name) {
      52             : 
      53             :     // -1 = not found
      54           0 :     int ret = -1;
      55           0 :     size_t i = 0;
      56           0 :     if (!vt_name) {
      57           0 :         return -2;
      58             :     }
      59             : 
      60           0 :     for (i = 0; i < VTEST_NUM_MODULES; i++) {
      61           0 :         if (!strncmp(vt_name, vt_modules[i].vt_name,
      62           0 :                     strlen(vt_modules[i].vt_name) + 1)) {
      63           0 :             return i;
      64             :         }
      65             :     }
      66           0 :     return ret;
      67             : }
      68             : 
      69             : static int
      70        2794 : vt_check_return_val(struct vtest *test) {
      71             : 
      72             :     bool has_returned;
      73        2794 :     int xml_return_val = 0;
      74        2794 :     int returned_msg_val = 0;
      75             : 
      76        2794 :     if (!test || !test->messages.return_vrouter_msg) {
      77           0 :         return E_PROCESS_XML_ERR_FARG;
      78             :     }
      79             : 
      80        2794 :     has_returned = test->messages.return_vrouter_msg->has_returned;
      81        2794 :     xml_return_val = test->messages.data[test->message_ptr_num].xml_data.return_value;
      82        2794 :     returned_msg_val = test->messages.return_vrouter_msg->return_val[test->messages.return_vrouter_msg->ptr_num];
      83             : 
      84        2794 :     if (has_returned && xml_return_val == returned_msg_val) {
      85        2384 :         return E_PROCESS_XML_OK;
      86             :     }
      87             : 
      88         410 :     test->vtest_return = E_MAIN_TEST_FAIL;
      89             : 
      90         410 :     return E_PROCESS_XML_ERR;
      91             : }
      92             : 
      93             : static int
      94        2794 : vt_send_vRouter_msg(struct vtest *test) {
      95             : 
      96        5588 :     return (vr_sendmsg(test->vrouter_cl, test->messages.data[test->message_ptr_num].mem,
      97        2794 :                 test->messages.data[test->message_ptr_num].type));
      98             : }
      99             : 
     100             : static int
     101        2794 : vt_recv_vRouter_msg( struct vtest *test) {
     102             : 
     103        2794 :     int ret = 0;
     104        2794 :     if (!test) {
     105           0 :         return E_PROCESS_XML_ERR_FARG;
     106             :     }
     107        2794 :     test->messages.return_vrouter_msg->has_returned = false;
     108        2794 :     ret = vr_recvmsg(test->vrouter_cl, false);
     109        2794 :     test->messages.data[test->message_ptr_num].recv_ret_value = ret;
     110        2794 :     return ret;
     111             : }
     112             : 
     113             : static int inline
     114        2384 : vt_post_process_message_expect(struct vtest *test) {
     115             : 
     116        2384 :     if (test->messages.data[test->message_ptr_num].xml_data.is_element_expect) {
     117           0 :         vt_expect_node((xmlNodePtr)test->messages.data[test->message_ptr_num].xml_data.element_expect_ptr, test);
     118           0 :         if (test->messages.data[test->message_ptr_num].return_from_expected != true) {
     119           0 :             fprintf(stderr, "Message has different value then expected value.\n");
     120           0 :             test->vtest_return = E_MAIN_TEST_FAIL;
     121           0 :             return E_MAIN_ERR;
     122             :         }
     123             :     }
     124        2384 :     return E_PROCESS_XML_OK;
     125             : 
     126             : }
     127             : 
     128             : static void
     129        2384 : vt_post_process_write_response_xml(struct vtest *test)
     130             : {
     131        2384 :     sandesh_info_t *sinfo = NULL;
     132        2384 :     char* node_name = NULL;
     133        2384 :     int resp_index = test->messages.received_vrouter_msg->ptr_num;
     134        2384 :     int err = 0;
     135             :     ThriftXMLProtocol xml_proto;
     136             :     ThriftFileTransport file_transport;
     137             : 
     138        2384 :     if ((test->cli_opt.resp_file[0] == '\0') || (resp_index < 0)) {
     139        1698 :         return;
     140             :     }
     141             : 
     142         686 :     node_name = test->messages.data[test->message_ptr_num].type;
     143         686 :     if (!strncmp(node_name, "vr_flow_req", sizeof("vr_flow_req")))
     144         206 :         node_name = "vr_flow_response";
     145         686 :     sinfo = vr_find_sandesh_info(node_name);
     146         686 :     if (!sinfo) {
     147           0 :         fprintf(stderr, "Failed to find sandesh info for %s\n",
     148           0 :                 test->messages.data[test->message_ptr_num].type);
     149           0 :         return;
     150             :     }
     151             : 
     152         686 :     fprintf(stdout, "Found sandesh info for %s\n", 
     153         686 :             test->messages.data[test->message_ptr_num].type);
     154             : 
     155         686 :     fprintf(stdout, "Write response to xml file %s\n", test->cli_opt.resp_file);
     156         686 :     if (thrift_file_transport_init(&file_transport,
     157         686 :                                    test->cli_opt.resp_file) < 0) {
     158           0 :         fprintf(stderr, "Failed to open file %s\n", test->cli_opt.resp_file);
     159           0 :         return;
     160             :     }
     161         686 :     thrift_protocol_init((ThriftProtocol *)&xml_proto, T_PROTOCOL_XML,
     162             :                          (ThriftTransport *)&file_transport);
     163         686 :     sinfo->write((void *)test->messages.received_vrouter_msg->\
     164             :                  mem_handles[resp_index].mem, (ThriftProtocol *)&xml_proto, &err);
     165         686 :     if (err != 0) {
     166           0 :         fprintf(stderr, "Sandesh write returned error %d\n", err);
     167             :     }
     168         686 :     thrift_file_transport_close(&file_transport);
     169             : }
     170             : 
     171             : static int inline
     172        2794 : vt_post_process_message(struct vtest *test) {
     173             : 
     174        2794 :     int ret = 0;
     175        2794 :     int tot_cnt = 0;
     176             : 
     177        2794 :     test->vtest_return = E_MAIN_TEST_PASS;
     178        2794 :     tot_cnt = test->message_ptr_num - test->message_ptr_start;
     179             :     /* reset the current pointer */
     180        2794 :     test->message_ptr_num = test->message_ptr_start;
     181             :     /*advance the start pointer */
     182        2794 :     test->message_ptr_start += tot_cnt;
     183        2794 :     tot_cnt++;
     184             : 
     185        5178 :     while (tot_cnt != 0) {
     186        2794 :         if (test->messages.data[test->message_ptr_num].mem) {
     187        2794 :             ret = vt_send_vRouter_msg(test);
     188        2794 :             if (!(ret > 0)) {
     189           0 :                 fprintf(stderr, "Send message, failed\n");
     190           0 :                 return E_PROCESS_XML_ERR_MSG_SEND;
     191             :             }
     192             : 
     193        2794 :             ret = vt_recv_vRouter_msg(test);
     194        2794 :             if (!(ret > 0)) {
     195           0 :                 fprintf(stderr, "Receive message, failed\n");
     196           0 :                 return E_PROCESS_XML_ERR_MSG_RECV;
     197             :             }
     198             : 
     199        2794 :             ret =  vt_check_return_val(test);
     200        2794 :             if (ret != E_PROCESS_XML_OK) {
     201         410 :                 fprintf(stderr, "Message has different return value, failed\n");
     202         410 :                 return E_PROCESS_XML_ERR;
     203             :             }
     204             : 
     205             :             /* If expect element is in <message> file. */
     206        2384 :             ret = vt_post_process_message_expect(test);
     207        2384 :             if (ret != E_PROCESS_XML_OK) {
     208           0 :                 fprintf(stderr, "Expected message has different value then returned, failed\n");
     209             : 
     210           0 :                 return ret;
     211             :             }
     212             :             /* Write the response in XML file */
     213        2384 :             vt_post_process_write_response_xml(test);
     214             :         }
     215        2384 :         tot_cnt--;
     216        2384 :         test->message_ptr_num++;
     217             :     }
     218             : 
     219        2384 :     test->message_ptr_num = test->message_ptr_start;
     220        2384 :     return E_MAIN_OK;
     221             : }
     222             : 
     223             : static int inline
     224         126 : vt_post_process_packet(struct vtest *test) {
     225             : 
     226         126 :     int ret = 0;
     227             : 
     228         126 :     ret = run_pcap_test(test);
     229         126 :     if (ret == EXIT_FAILURE) {
     230           0 :         test->vtest_return = E_MAIN_TEST_FAIL;
     231           0 :         return E_PROCESS_XML_ERR;
     232         126 :     } else if (ret == EXIT_SUCCESS) {
     233         126 :         test->vtest_return = E_MAIN_TEST_PASS;
     234         126 :         return E_PROCESS_XML_OK;
     235             :     }
     236             : 
     237           0 :     return E_PROCESS_XML_OK;
     238             : }
     239             : 
     240             : static int
     241        5840 : vt_post_process_node(xmlNodePtr node, struct vtest *test) {
     242             : 
     243        5840 :     int ret = 0;
     244             : 
     245        5840 :     if (!test || !node) {
     246           0 :         return E_PROCESS_XML_ERR_FARG;
     247             :     }
     248             : 
     249        5840 :     if (!strncmp((char *) node->name, "message", sizeof("message"))) {
     250        2794 :         ret = vt_post_process_message(test);
     251             : 
     252             :     }
     253             : 
     254        5840 :     if(!strncmp((char *) node->name, "packet", sizeof("packet"))) {
     255         126 :         ret = vt_post_process_packet(test);
     256             :     }
     257             : 
     258        5840 :     return ret;
     259             : }
     260             : 
     261             : static int
     262        5840 : vt_process_node(xmlNodePtr node, struct vtest *test)
     263             : {
     264             :     unsigned int i;
     265        5840 :     int ret = 0;
     266             : 
     267        5840 :     if (!node || !test) {
     268           0 :         return E_PROCESS_XML_ERR_FARG;
     269             :     }
     270             : 
     271             :     /* control block is processed already */
     272        5840 :     if (!strncmp((char *) node->name, "control", sizeof("control"))) {
     273           0 :         return E_PROCESS_XML_OK;
     274             :     }
     275        8886 :     for (i = 0; i < VTEST_NUM_MODULES; i++) {
     276        8886 :         if (!strncmp((char *)node->name, vt_modules[i].vt_name,
     277        8886 :                     strlen(vt_modules[i].vt_name) + 1)) {
     278        5840 :             ret = vt_modules[i].vt_node(node, test);
     279             : 
     280        5840 :             if (ret == E_MAIN_SKIP)
     281           0 :                 return ret;
     282             : 
     283        5840 :             if (ret != E_MESSAGE_OK) {
     284           0 :                 fprintf(stderr, "%s(): Error processing node %s\n",
     285             :                     __func__, node->name);
     286           0 :                 return ret;
     287             :             }
     288             : 
     289        5840 :             ret = vt_post_process_node(node, test);
     290        5840 :             if (ret != E_PROCESS_XML_OK) {
     291         410 :                 fprintf(stderr, "%s(): Error post-processing node %s\n",
     292             :                     __func__, node->name);
     293         410 :                 return ret;
     294             :             }
     295             : 
     296        5430 :             return E_PROCESS_XML_OK;
     297             :         }
     298             :     }
     299             : 
     300           0 :     if (i == VTEST_NUM_MODULES) {
     301           0 :         fprintf(stderr, "Unrecognized node %s in XML\n", node->name);
     302           0 :         return E_PROCESS_XML_ERR;
     303             :     }
     304             : 
     305           0 :     return E_PROCESS_XML_ERR;
     306             : }
     307             : 
     308             : static int
     309        2920 : vt_tree_traverse(xmlNodePtr node, struct vtest *test)
     310             : {
     311        2920 :     int ret = 0;
     312             : 
     313        2920 :     if (!node || !test) {
     314           0 :         return E_PROCESS_XML_ERR_FARG;
     315             :     }
     316             : 
     317       16700 :     while (node) {
     318       14190 :         if (node->type == XML_ELEMENT_NODE) {
     319        5840 :             ret = vt_process_node(node, test);
     320        5840 :             if (ret == E_MAIN_SKIP) {
     321           0 :                 return ret;
     322             :             }
     323             : 
     324        5840 :             if (ret != E_PROCESS_XML_OK) {
     325         410 :                 fprintf(stderr ,"%s(): Tree traverse error %d\n",
     326             :                     __func__, ret);
     327             : 
     328         410 :                 return ret;
     329             :             }
     330             :             else {
     331        5430 :                 test->vtest_break = 0;
     332             :             }
     333             :         }
     334       13780 :         node = node->next;
     335             :     }
     336             : 
     337        2510 :     return E_PROCESS_XML_ERR;
     338             : }
     339             : 
     340             : static int
     341        2920 : vt_traverse_control_node(xmlNodePtr node, struct vtest *test)
     342             : {
     343        2920 :     int ret = E_MAIN_SKIP;
     344             : 
     345        2920 :     if (!node || !test) {
     346           0 :         return E_PROCESS_XML_ERR_FARG;
     347             :     }
     348             : 
     349       17520 :     while (node) {
     350       14600 :         if (node->type == XML_ELEMENT_NODE) {
     351        5840 :             if (!strncmp((char *) node->name, "control", sizeof("control"))) {
     352           0 :                 xmlNodePtr child_node = node->xmlChildrenNode;
     353           0 :                 while (child_node) {
     354           0 :                     if (!strncmp((char *) child_node->name, "flow_count",
     355             :                             sizeof("flow_count"))) {
     356           0 :                         if (child_node->children &&
     357           0 :                                     child_node->children->content) {
     358           0 :                             test->flow_count =
     359           0 :                                 strtoul(child_node->children->content, NULL, 0);
     360           0 :                             ret = E_MAIN_OK;
     361             :                         }
     362             :                     }
     363           0 :                     child_node = child_node->next;
     364             :                 }
     365             :             }
     366             : 
     367             : 
     368             :         }
     369       14600 :         node = node->next;
     370             :     }
     371        2920 :     return ret;
     372             : }
     373             : 
     374             : int
     375        2920 : vt_parse_file(char *file, struct vtest *test)
     376             : {
     377        2920 :     xmlDocPtr doc = NULL;
     378        2920 :     xmlNodePtr node = NULL;
     379             :     int ret;
     380             : 
     381             : 
     382        2920 :     doc = xmlParseFile(file);
     383        2920 :     if (!doc) {
     384           0 :         fprintf(stderr ,"%s(): Error parsing XML file %s\n", __func__, file);
     385           0 :         return E_PROCESS_XML_ERR;
     386             :     }
     387        2920 :     test->file_name = file;
     388             : 
     389        2920 :     node = xmlDocGetRootElement(doc);
     390        2920 :     if (!node) {
     391           0 :         fprintf(stderr ,"%s(): Error getting root element\n", __func__);
     392           0 :         return E_PROCESS_XML_ERR;
     393             :     }
     394             : 
     395        2920 :     ret = vt_traverse_control_node(node->xmlChildrenNode, test);
     396        2920 :     ret = vt_tree_traverse(node->xmlChildrenNode, test);
     397             : 
     398        2920 :     xmlFreeDoc(doc);
     399             : 
     400        2920 :     return ret;
     401             : }

Generated by: LCOV version 1.14