Skip to content

Commit

Permalink
Merge "vRouter test framework"
Browse files Browse the repository at this point in the history
  • Loading branch information
Zuul authored and opencontrail-ci-admin committed May 15, 2015
2 parents dd7bcbf + d74aa41 commit bf12491
Show file tree
Hide file tree
Showing 10 changed files with 1,590 additions and 1 deletion.
2 changes: 1 addition & 1 deletion utils/SConscript
Expand Up @@ -18,7 +18,7 @@ env.Append(CCFLAGS = '-g')
if 'install' in COMMAND_LINE_TARGETS:
VRutilsEnv.Append(SRC_INSTALL_TARGET = '/utils/')

subdirs = ['dkms']
subdirs = ['dkms', 'vtest']
for sdir in subdirs:
env.SConscript(sdir + '/SConscript',
exports='VRutilsEnv',
Expand Down
225 changes: 225 additions & 0 deletions utils/vtest/README.txt
@@ -0,0 +1,225 @@
The xml file specification
-------------------------

<?xml version="1.0"?>
<test>
<test_name>Interface test</test_name>
<message>
<vif>
<m_op>Add</m_op>
<vif_type>Virtual</vif_type>
<vif_index>4</vif_index>
<vif_vrf>0</vif_vrf>
<vif_mac>00:01:02:03:04:05</vif_mac>
<vif_mtu>1514</vif_mtu>
</vif>
<message_return>0</message_return>
</message>

<test_result>
<message>
<vif>
<m_op>Get</m_op>
<vif_index>4</vif_index>
</vif>
</message>
<message_return>0</message_return>
<message_expect>
<vif>
<vif_type>Virtual</vif_type>
<vif_index>4</vif_index>
<vif_vrf>0</vif_vrf>
<vif_mac>00:01:02:03:04:05</vif_mac>
<vif_mtu>1514</vif_mtu>
</vif>
</message_expect>
</test_result>

</test>

The generated code from sandesh file processing
-----------------------------------------------

There is a sandesh compiler that parses the sandesh file and autogenerates
code to read values from specification file and assign it to corresponding
variables of the sandesh structure. It takes care of all known data types
of sandesh message (including list<type> and string). As of now, the compiler
generates 'vt_gen_sandesh.c' (that contains the above described functionality)
, 'vt_gen_message_modules.c' (that contains the list of nodes under the message
module of vtest), 'vt_gen_message_modules.h' (a header file that contains all
the required declarations) and 'vt_gen_expect.c' that sanitizes the received
message with expected values from the specification file.

The generator is still evolving. More functionality will be added to generator
on need basis.


Snap of code generated in 'vt_gen_sandesh.c'
-------------------------------------------

....

void *
vr_nexthop_req_node(xmlNodePtr node, struct vtest *test)
{
unsigned int list_size;
vr_nexthop_req *req;

req = calloc(sizeof(*req), 1);
if (!req)
return NULL;

node = node->xmlChildrenNode;
while (node) {
if (!node->content || !strlen(node->content)) {
return NULL;
}

if (!strncmp(node->name, "h_op", strlen(node->content))) {
req->h_op = vt_gen_op(node->content);
} else if (!strncmp(node->name, "nhr_type", strlen(node->content))) {
req->nhr_type = strtoul(node->content, NULL, 0);
} else if (!strncmp(node->name, "nhr_family", strlen(node->content))) {

....

} else if (!strncmp(node->name, "nhr_label_list", strlen(node->content))) {
req->nhr_label_list = vt_gen_list(node->content, GEN_TYPE_U32, &list_size);
req->nhr_label_list_size = list_size;
}
node = node->next;
}

return (void *)req;
}

Snap of code generated in 'vt_gen_message_modules.c'
----------------------------------------------------

/*
* Auto generated file
*/
#include <string.h>

#include <stdbool.h>

#include <libxml/xmlmemory.h>
#include <libxml/parser.h>

#include <vr_types.h>
#include <vt_gen_lib.h>
#include <vtest.h>

#include <vt_gen_message_modules.h>

struct vt_message_module vt_message_modules[] = {
{
.vmm_name = "vr_nexthop_req",
.vmm_node = vr_nexthop_req_node,
.vmm_expect = vr_nexthop_req_expect,
.vmm_size = sizeof(vr_nexthop_req),
},
{
.vmm_name = "vr_interface_req",
.vmm_node = vr_interface_req_node,

....
....

{
.vmm_name = "expect",
.vmm_node = vt_expect_node,
.vmm_size = 0,
},
};

unsigned int vt_message_modules_num =
sizeof(vt_message_modules) / sizeof(vt_message_modules[0]);


Snap of code generated in 'vt_gen_message_modules.h'
---------------------------------------------------

/*
* Auto generated file
*/
#ifndef __VT_GEN_MESSAGE_MODULES_H__
#define __VT_GEN_MESSAGE_MODULES_H__

#include <string.h>

#include <stdbool.h>

#include <libxml/xmlmemory.h>
#include <libxml/parser.h>

#include <vr_types.h>
#include <vt_gen_lib.h>
#include <vtest.h>

struct vt_message_module {
char *vmm_name;
void *(*vmm_node)(xmlNodePtr, struct vtest *);
bool (*vmm_expect)(xmlNodePtr, struct vtest *, void *);
unsigned int vmm_size;
};

extern void *vr_nexthop_req_node(xmlNodePtr, struct vtest *);
extern bool vr_nexthop_req_expect(xmlNodePtr, struct vtest *, void *);

....
....

extern void *vt_return_node(xmlNodePtr, struct vtest *);
extern void *vt_expect_node(xmlNodePtr, struct vtest *);

#endif

Snap of code generated in 'vt_gen_sandesh_expect.c'
--------------------------------------------------

/*
* Auto generated file
*/
#include <string.h>

#include <stdbool.h>

#include <libxml/xmlmemory.h>
#include <libxml/parser.h>

#include <vr_types.h>
#include <vt_gen_lib.h>
#include <vtest.h>

bool
vr_nexthop_req_expect(xmlNodePtr node, struct vtest *test, void *buf)
{
bool result = true;
unsigned int list_size;
vr_nexthop_req *req = (vr_nexthop_req *)buf;

node = node->xmlChildrenNode;
while (node) {
if (!node->content || !strlen(node->content)) {
return NULL;
}

....
....

} else if (!strncmp(node->name, "nhr_label_list", strlen(node->content))) {
result = vt_gen_list_compare(req->nhr_label_list,
req->nhr_label_list_size, node->content, GEN_TYPE_U32);
}

if (!result)
return result;

node = node->next;
}

return result;
}


50 changes: 50 additions & 0 deletions utils/vtest/SConscript
@@ -0,0 +1,50 @@
#
# Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
#
import os
Import('VRutilsEnv')
env = VRutilsEnv.Clone()
VTestEnv = env;

src_root = Dir('#').srcnode().abspath
build_root = Dir(env['TOP']).abspath
sandesh_file = src_root + '/vrouter/sandesh/vr.sandesh'
build_dir = build_root + '/vrouter/utils/vtest/'

system_header_path = GetOption('system-header-path')
if system_header_path:
env.Append(CPPPATH = system_header_path + '/include/')

env.Append(CPPPATH = ['./include', build_dir, '/usr/include/libxml2'])
xml_cpppath = os.popen('xml2-config --cflags | sed \'s/\-I//g\'').read()
#env.Append(CPPPATH = xml_cpppath)

# CFLAGS
env.Append(CCFLAGS = '-g')

env.Replace(LIBPATH = env['TOP_LIB'])
env.Append(LIBPATH = ['.', '../../sandesh'])
env.Replace(LIBS = ['sandesh-c', 'dp_sandesh_c', 'xml2'])

sandesh_gen = env.Program('sandesh_gen.c')

sandesh_gen_cmd = build_root + '/vrouter/utils/vtest/sandesh_gen' + ' ' + sandesh_file
sandesh_gen_output = env.Command('sandesh_gen_output', None,
sandesh_gen_cmd, chdir=build_dir)

vtest_src = [
'vt_main.c',
'vt_message.c',
'vt_gen_lib.c',
'vt_gen_message_modules.c',
'vt_gen_sandesh.c',
'vt_gen_sandesh_expect.c',
]


vtest = env.Program('vtest', vtest_src)
env.Requires(vtest, sandesh_gen_output)

# Local Variables:
# mode: python
# End:
36 changes: 36 additions & 0 deletions utils/vtest/example.xml
@@ -0,0 +1,36 @@
<?xml version="1.0"?>
<test>
<test_name>Interface test</test_name>
<message>
<vif>
<m_op>Add</m_op>
<vif_type>Virtual</vif_type>
<vif_index>4</vif_index>
<vif_vrf>0</vif_vrf>
<vif_mac>00:01:02:03:04:05</vif_mac>
<vif_mtu>1514</vif_mtu>
</vif>
<message_return>0</message_return>
</message>

<test_result>
<message>
<vif>
<m_op>Get</m_op>
<vif_index>4</vif_index>
</vif>
</message>
<message_return>0</message_return>
<message_expect>
<vif>
<vif_type>Virtual</vif_type>
<vif_index>4</vif_index>
<vif_vrf>0</vif_vrf>
<vif_mac>00:01:02:03:04:05</vif_mac>
<vif_mtu>1514</vif_mtu>
</vif>
</message_expect>
</test_result>

</test>

33 changes: 33 additions & 0 deletions utils/vtest/include/vt_gen_lib.h
@@ -0,0 +1,33 @@
/*
* gen_lib.h --
*
* Copyright (c) 2015, Juniper Networks, Inc.
* All rights reserved
*/

#ifndef __GEN_LIB_H__
#define __GEN_LIB_H__

enum gen_types {
GEN_TYPE_U8,
GEN_TYPE_U16,
GEN_TYPE_U32,
GEN_TYPE_U64,
};

unsigned char *vt_gen_skip_space(unsigned char *);
unsigned char *vt_gen_reach_char(unsigned char *, unsigned char);
unsigned char *vt_gen_reach_space(unsigned char *);
bool vt_gen_byte_compare(uint8_t, uint8_t);
bool vt_gen_short_compare(uint16_t, uint16_t);
bool vt_gen_int_compare(unsigned int, unsigned int);
bool vt_gen_int64_compare(uint64_t, uint64_t);
bool vt_gen_flow_op_compare(int, unsigned char *);
int vt_gen_flow_op(unsigned char *);
bool vt_gen_op_compare(int, unsigned char *);
int vt_gen_op(unsigned char *);
void *vt_gen_list(unsigned char *, unsigned int, unsigned int *);
bool vt_gen_list_compare(void *, unsigned int, unsigned char *, unsigned int);
void *vt_gen_string(char *);

#endif /* __GEN_LIB_H__ */
30 changes: 30 additions & 0 deletions utils/vtest/include/vtest.h
@@ -0,0 +1,30 @@
/*
* vtest.h --
*
* Copyright (c) 2015, Juniper Networks, Inc.
* All rights reserved
*/
#ifndef __VTEST_H__
#define __VTEST_H__

#define VT_PROG_NAME "vtest"
#define VT_MAX_TEST_NAME_LEN 128
#define VT_MAX_TEST_MODULE_NAME_LEN 128

struct vtest {
int vtest_return;
int vtest_iteration;
bool vtest_break;
unsigned char *vtest_name;
unsigned char *vtest_error_module;
};

struct vtest_module {
unsigned char *vt_name;
int (*vt_node)(xmlNodePtr, struct vtest *);
int (*vt_init)(void);
};

extern int vt_message(xmlNodePtr, struct vtest *);

#endif /* __VTEST_H__ */

0 comments on commit bf12491

Please sign in to comment.