Note: this patch is rebased on top of : [PATCH] move ovn/lib/<lex|actions|expr>.h to include/ovn
On Mon, Jul 25, 2016 at 3:07 PM, Aaron Rosen <aaronoro...@gmail.com> wrote: > This patch exposes the c function expr_parse_string() to be called via > python. The motivation for this is so that clients interfacing with > ovn can call this method in order to validate the data they are writting > to ovn. > > Previously, there were several bugs in the neutron/ovn integration > that went unnoticed due to the client writing invalid data. This should > hopefully help catch errors like this earlier as it can now be detected on > the client side and an error can be raised. > > Signed-off-by: Aaron Rosen <aaronoro...@gmail.com> > --- > include/ovn/expr.h | 1 + > ovn/lib/expr.c | 107 > +++++++++++++++++++++++++++++++++++++++++++++ > python/automake.mk | 4 +- > python/ovs/_ovn-utils.c | 104 ++++++++++++++++++++++++++++++++++++++++++++ > python/setup.py | 31 +++++++++++++- > tests/automake.mk | 4 +- > tests/test-ovn-utils.at | 15 +++++++ > tests/test-ovn-utils.py | 33 ++++++++++++++ > tests/test-ovn.c | 112 > +----------------------------------------------- > tests/testsuite.at | 1 + > 10 files changed, 299 insertions(+), 113 deletions(-) > create mode 100644 python/ovs/_ovn-utils.c > create mode 100644 tests/test-ovn-utils.at > create mode 100644 tests/test-ovn-utils.py > > diff --git a/include/ovn/expr.h b/include/ovn/expr.h > index d790c49..381e32f 100644 > --- a/include/ovn/expr.h > +++ b/include/ovn/expr.h > @@ -470,5 +470,6 @@ void expr_macros_add(struct shash *macros, const char > *name, > const char * const *values, size_t n_values); > void expr_macros_remove(struct shash *macros, const char *name); > void expr_macros_destroy(struct shash *macros); > +void create_symtab_helper(struct shash *symtab); > > #endif /* ovn/expr.h */ > diff --git a/ovn/lib/expr.c b/ovn/lib/expr.c > index 288aae2..94b93c5 100644 > --- a/ovn/lib/expr.c > +++ b/ovn/lib/expr.c > @@ -3008,3 +3008,110 @@ expr_parse_constant_set(struct lexer *lexer, const > struct shash *symtab, > parse_constant_set(&ctx, cs); > return ctx.error; > } > + > +/* create_symtab_helper() is used for testing purposes and in the > ovn_utils > + * python package. */ > +void > +create_symtab_helper(struct shash *symtab) > +{ > + shash_init(symtab); > + > + /* Reserve a pair of registers for the logical inport and outport. A > full > + * 32-bit register each is bigger than we need, but the expression > code > + * doesn't yet support string fields that occupy less than a full > OXM. */ > + expr_symtab_add_string(symtab, "inport", MFF_REG6, NULL); > + expr_symtab_add_string(symtab, "outport", MFF_REG7, NULL); > + > + expr_symtab_add_field(symtab, "xreg0", MFF_XREG0, NULL, false); > + expr_symtab_add_field(symtab, "xreg1", MFF_XREG1, NULL, false); > + expr_symtab_add_field(symtab, "xreg2", MFF_XREG2, NULL, false); > + > + expr_symtab_add_subfield(symtab, "reg0", NULL, "xreg0[32..63]"); > + expr_symtab_add_subfield(symtab, "reg1", NULL, "xreg0[0..31]"); > + expr_symtab_add_subfield(symtab, "reg2", NULL, "xreg1[32..63]"); > + expr_symtab_add_subfield(symtab, "reg3", NULL, "xreg1[0..31]"); > + expr_symtab_add_subfield(symtab, "reg4", NULL, "xreg2[32..63]"); > + expr_symtab_add_subfield(symtab, "reg5", NULL, "xreg2[0..31]"); > + > + expr_symtab_add_field(symtab, "eth.src", MFF_ETH_SRC, NULL, false); > + expr_symtab_add_field(symtab, "eth.dst", MFF_ETH_DST, NULL, false); > + expr_symtab_add_field(symtab, "eth.type", MFF_ETH_TYPE, NULL, true); > + > + expr_symtab_add_field(symtab, "vlan.tci", MFF_VLAN_TCI, NULL, false); > + expr_symtab_add_predicate(symtab, "vlan.present", "vlan.tci[12]"); > + expr_symtab_add_subfield(symtab, "vlan.pcp", "vlan.present", > + "vlan.tci[13..15]"); > + expr_symtab_add_subfield(symtab, "vlan.vid", "vlan.present", > + "vlan.tci[0..11]"); > + > + expr_symtab_add_predicate(symtab, "ip4", "eth.type == 0x800"); > + expr_symtab_add_predicate(symtab, "ip6", "eth.type == 0x86dd"); > + expr_symtab_add_predicate(symtab, "ip", "ip4 || ip6"); > + expr_symtab_add_field(symtab, "ip.proto", MFF_IP_PROTO, "ip", true); > + expr_symtab_add_field(symtab, "ip.dscp", MFF_IP_DSCP, "ip", false); > + expr_symtab_add_field(symtab, "ip.ecn", MFF_IP_ECN, "ip", false); > + expr_symtab_add_field(symtab, "ip.ttl", MFF_IP_TTL, "ip", false); > + > + expr_symtab_add_field(symtab, "ip4.src", MFF_IPV4_SRC, "ip4", false); > + expr_symtab_add_field(symtab, "ip4.dst", MFF_IPV4_DST, "ip4", false); > + > + expr_symtab_add_predicate(symtab, "icmp4", "ip4 && ip.proto == 1"); > + expr_symtab_add_field(symtab, "icmp4.type", MFF_ICMPV4_TYPE, "icmp4", > + false); > + expr_symtab_add_field(symtab, "icmp4.code", MFF_ICMPV4_CODE, "icmp4", > + false); > + > + expr_symtab_add_field(symtab, "ip6.src", MFF_IPV6_SRC, "ip6", false); > + expr_symtab_add_field(symtab, "ip6.dst", MFF_IPV6_DST, "ip6", false); > + expr_symtab_add_field(symtab, "ip6.label", MFF_IPV6_LABEL, "ip6", > false); > + > + expr_symtab_add_predicate(symtab, "icmp6", "ip6 && ip.proto == 58"); > + expr_symtab_add_field(symtab, "icmp6.type", MFF_ICMPV6_TYPE, "icmp6", > + true); > + expr_symtab_add_field(symtab, "icmp6.code", MFF_ICMPV6_CODE, "icmp6", > + true); > + > + expr_symtab_add_predicate(symtab, "icmp", "icmp4 || icmp6"); > + > + expr_symtab_add_field(symtab, "ip.frag", MFF_IP_FRAG, "ip", false); > + expr_symtab_add_predicate(symtab, "ip.is_frag", "ip.frag[0]"); > + expr_symtab_add_predicate(symtab, "ip.later_frag", "ip.frag[1]"); > + expr_symtab_add_predicate(symtab, "ip.first_frag", "ip.is_frag && > !ip.later_frag"); > + > + expr_symtab_add_predicate(symtab, "arp", "eth.type == 0x806"); > + expr_symtab_add_field(symtab, "arp.op", MFF_ARP_OP, "arp", false); > + expr_symtab_add_field(symtab, "arp.spa", MFF_ARP_SPA, "arp", false); > + expr_symtab_add_field(symtab, "arp.sha", MFF_ARP_SHA, "arp", false); > + expr_symtab_add_field(symtab, "arp.tpa", MFF_ARP_TPA, "arp", false); > + expr_symtab_add_field(symtab, "arp.tha", MFF_ARP_THA, "arp", false); > + > + expr_symtab_add_predicate(symtab, "nd", "icmp6.type == {135, 136} && > icmp6.code == 0"); > + expr_symtab_add_field(symtab, "nd.target", MFF_ND_TARGET, "nd", > false); > + expr_symtab_add_field(symtab, "nd.sll", MFF_ND_SLL, > + "nd && icmp6.type == 135", false); > + expr_symtab_add_field(symtab, "nd.tll", MFF_ND_TLL, > + "nd && icmp6.type == 136", false); > + > + expr_symtab_add_predicate(symtab, "tcp", "ip.proto == 6"); > + expr_symtab_add_field(symtab, "tcp.src", MFF_TCP_SRC, "tcp", false); > + expr_symtab_add_field(symtab, "tcp.dst", MFF_TCP_DST, "tcp", false); > + expr_symtab_add_field(symtab, "tcp.flags", MFF_TCP_FLAGS, "tcp", > false); > + > + expr_symtab_add_predicate(symtab, "udp", "ip.proto == 17"); > + expr_symtab_add_field(symtab, "udp.src", MFF_UDP_SRC, "udp", false); > + expr_symtab_add_field(symtab, "udp.dst", MFF_UDP_DST, "udp", false); > + > + expr_symtab_add_predicate(symtab, "sctp", "ip.proto == 132"); > + expr_symtab_add_field(symtab, "sctp.src", MFF_SCTP_SRC, "sctp", > false); > + expr_symtab_add_field(symtab, "sctp.dst", MFF_SCTP_DST, "sctp", > false); > + > + /* For negative testing. */ > + expr_symtab_add_field(symtab, "bad_prereq", MFF_XREG0, "xyzzy", > false); > + expr_symtab_add_field(symtab, "self_recurse", MFF_XREG0, > + "self_recurse != 0", false); > + expr_symtab_add_field(symtab, "mutual_recurse_1", MFF_XREG0, > + "mutual_recurse_2 != 0", false); > + expr_symtab_add_field(symtab, "mutual_recurse_2", MFF_XREG0, > + "mutual_recurse_1 != 0", false); > + expr_symtab_add_string(symtab, "big_string", MFF_XREG0, NULL); > +} > diff --git a/python/automake.mk b/python/automake.mk > index 874a178..b4f4ef3 100644 > --- a/python/automake.mk > +++ b/python/automake.mk > @@ -47,7 +47,9 @@ EXTRA_DIST += \ > python/setup.py > > # C extension support. > -EXTRA_DIST += python/ovs/_json.c > +EXTRA_DIST += \ > + python/ovs/_json.c \ > + python/ovs/_ovn-utils.c > > PYFILES = $(ovs_pyfiles) python/ovs/dirs.py $(ovstest_pyfiles) > EXTRA_DIST += $(PYFILES) > diff --git a/python/ovs/_ovn-utils.c b/python/ovs/_ovn-utils.c > new file mode 100644 > index 0000000..e2395ec > --- /dev/null > +++ b/python/ovs/_ovn-utils.c > @@ -0,0 +1,104 @@ > +/* > + * Copyright (c) 2016 Nicira, Inc. > + * > + * 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 <Python.h> > +#include "ovn/actions.h" > +#include "ovn/expr.h" > +#include "ovn/lex.h" > +#include "openvswitch/shash.h" > + > +#if PY_MAJOR_VERSION >= 3 > +#define IS_PY3K > +#endif > + > +#ifdef IS_PY3K > +PyMODINIT_FUNC PyInit_ovn_utils(void); > +#else > +void initovn_utils(void); > +#endif > + > +static char parse_match_docs[] = > + "Specify match string to validate\n"; > + > +static PyObject* parse_match(PyObject* self OVS_UNUSED, PyObject *args) > +{ > + char *match_string; > + PyObject *error_string; > + > + if (!PyArg_ParseTuple(args, "s", &match_string)) { > + return Py_BuildValue("s", "Unable to parse input"); > + } > + > + struct shash symtab; > + create_symtab_helper(&symtab); > + struct expr *expr; > + char *error; > + expr = expr_parse_string(match_string, &symtab, NULL, &error); > + > + expr_destroy(expr); > + expr_symtab_destroy(&symtab); > + shash_destroy(&symtab); > + if(error) { > +#ifdef IS_PY3K > + error_string = PyUnicode_FromString(error); > +#else > + error_string = PyString_FromString(error); > +#endif > + free(error); > + return error_string; > + } > + Py_RETURN_NONE; > +} > + > + > +static PyMethodDef ovn_utils_funcs[] = { > + {"parse_match", parse_match, METH_VARARGS, parse_match_docs}, > + {NULL} > +}; > + > +#ifdef IS_PY3K > +static struct PyModuleDef moduledef = { > + PyModuleDef_HEAD_INIT, > + "ovs.ovn_utils", /* m_name */ > + "OVN helper utilities", /* m_doc */ > + 0, /* m_size */ > + ovn_utils_funcs, /* m_methods */ > + 0, /* m_slots */ > + 0, /* m_traverse */ > + 0, /* m_clear */ > + 0, /* m_free */ > +}; > +#define INITERROR return NULL > +#else /* !IS_PY3K */ > +#define INITERROR return > +#endif > + > +PyMODINIT_FUNC > +#ifdef IS_PY3K > +PyInit_ovn_utils(void) > +#else > +initovn_utils(void) > +#endif > +{ > +#ifdef IS_PY3K > + PyObject *m; > + m = PyModule_Create(&moduledef); > + return m; > +#else > + Py_InitModule3("ovs.ovn_utils", ovn_utils_funcs, > + "OVN helper utilities"); > +#endif > +} > diff --git a/python/setup.py b/python/setup.py > index 19c1f18..5269151 100644 > --- a/python/setup.py > +++ b/python/setup.py > @@ -77,7 +77,36 @@ setup_args = dict( > 'Programming Language :: Python :: 3.4', > ], > ext_modules=[setuptools.Extension("ovs._json", > sources=["ovs/_json.c"], > - libraries=['openvswitch'])], > + libraries=['openvswitch']), > + setuptools.Extension("ovs.ovn_utils", > + # XXX there must be a better way > + # to do this? > + libraries=['openvswitch'], > + extra_compile_args=([ > + '-Wstrict-prototypes', > + '-Wall', > + '-Wextra', > + '-shared', > + '-Wno-sign-compare', > + '-Wpointer-arith', > + '-Wformat-security', > + '-Wswitch-enum', > + '-Wunused-parameter', > + '-Wbad-function-cast', > + '-Wcast-align', > + '-Wmissing-prototypes', > + '-Wmissing-field-initializers', > + '-fno-strict-aliasing', > + '-std=gnu99', > + '-DHAVE_CONFIG_H']), > + include_dirs=['../include/', > + '../lib/', > + '../ovn/lib', > + '../'], > + sources=["ovs/_ovn-utils.c", > + "../ovn/lib/lex.c", > + "../ovn/lib/expr.c", > + "../ovn/lib/actions.c"])], > cmdclass={'build_ext': try_build_ext}, > ) > > diff --git a/tests/automake.mk b/tests/automake.mk > index 575ffeb..c45a5b5 100644 > --- a/tests/automake.mk > +++ b/tests/automake.mk > @@ -94,7 +94,8 @@ TESTSUITE_AT = \ > tests/ovn-nbctl.at \ > tests/ovn-sbctl.at \ > tests/ovn-controller.at \ > - tests/ovn-controller-vtep.at > + tests/ovn-controller-vtep.at \ > + tests/test-ovn-utils.at > > SYSTEM_KMOD_TESTSUITE_AT = \ > tests/system-common-macros.at \ > @@ -385,6 +386,7 @@ CHECK_PYFILES = \ > tests/test-jsonrpc.py \ > tests/test-l7.py \ > tests/test-ovsdb.py \ > + tests/test-ovn-utils.py \ > tests/test-reconnect.py \ > tests/MockXenAPI.py \ > tests/test-unix-socket.py \ > diff --git a/tests/test-ovn-utils.at b/tests/test-ovn-utils.at > new file mode 100644 > index 0000000..66e5c36 > --- /dev/null > +++ b/tests/test-ovn-utils.at > @@ -0,0 +1,15 @@ > +AT_BANNER([Test OVN Utils]) > + > +m4_define([TEST_OVN_UTILS], > + [AT_SETUP([test-ovn-utils - $1]) > + AT_SKIP_IF([test $2 = no]) > + # Skip test if user doesn't have ovs.ovn_utils module > + AT_SKIP_IF([! $3 -c 'import ovs.ovn_utils' 2> /dev/null]) > + AT_KEYWORDS([ovnutils]) > + AT_CHECK([$3 $srcdir/test-ovn-utils.py], > + [0],[ignore], [ignore]) > + AT_CLEANUP]) > + > + > +TEST_OVN_UTILS([Python2], [$HAVE_PYTHON], [$PYTHON]) > +TEST_OVN_UTILS([Python3], [$HAVE_PYTHON3], [$PYTHON3]) > diff --git a/tests/test-ovn-utils.py b/tests/test-ovn-utils.py > new file mode 100644 > index 0000000..fecf2c0 > --- /dev/null > +++ b/tests/test-ovn-utils.py > @@ -0,0 +1,33 @@ > +# Copyright (c) 2016 Nicira, Inc. > +# > +# 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. > + > +import unittest > + > +from ovs import ovn_utils > + > + > +class TestOvnUtils(unittest.TestCase): > + > + def test_parse_match_fail(self): > + expected = "Syntax error at `a' expecting field name." > + result = ovn_utils.parse_match("a") > + self.assertEqual(result, expected) > + > + def test_parse_match_success(self): > + result = ovn_utils.parse_match( > + 'outport == "25560992-3f36-4a8b-bc19-e3f84188ef33" && ip4 && > udp') > + self.assertEqual(result, None) > + > +if __name__ == '__main__': > + unittest.main() > diff --git a/tests/test-ovn.c b/tests/test-ovn.c > index ffb4e50..ba3fcc6 100644 > --- a/tests/test-ovn.c > +++ b/tests/test-ovn.c > @@ -136,114 +136,6 @@ test_lex(struct ovs_cmdl_context *ctx OVS_UNUSED) > } > > static void > -create_symtab(struct shash *symtab) > -{ > - shash_init(symtab); > - > - /* Reserve a pair of registers for the logical inport and outport. A > full > - * 32-bit register each is bigger than we need, but the expression > code > - * doesn't yet support string fields that occupy less than a full > OXM. */ > - expr_symtab_add_string(symtab, "inport", MFF_REG14, NULL); > - expr_symtab_add_string(symtab, "outport", MFF_REG15, NULL); > - > - expr_symtab_add_field(symtab, "xxreg0", MFF_XXREG0, NULL, false); > - expr_symtab_add_field(symtab, "xxreg1", MFF_XXREG1, NULL, false); > - > - expr_symtab_add_field(symtab, "xreg0", MFF_XREG0, NULL, false); > - expr_symtab_add_field(symtab, "xreg1", MFF_XREG1, NULL, false); > - expr_symtab_add_field(symtab, "xreg2", MFF_XREG2, NULL, false); > - > - expr_symtab_add_subfield(symtab, "reg0", NULL, "xreg0[32..63]"); > - expr_symtab_add_subfield(symtab, "reg1", NULL, "xreg0[0..31]"); > - expr_symtab_add_subfield(symtab, "reg2", NULL, "xreg1[32..63]"); > - expr_symtab_add_subfield(symtab, "reg3", NULL, "xreg1[0..31]"); > - expr_symtab_add_subfield(symtab, "reg4", NULL, "xreg2[32..63]"); > - expr_symtab_add_subfield(symtab, "reg5", NULL, "xreg2[0..31]"); > - > - expr_symtab_add_field(symtab, "eth.src", MFF_ETH_SRC, NULL, false); > - expr_symtab_add_field(symtab, "eth.dst", MFF_ETH_DST, NULL, false); > - expr_symtab_add_field(symtab, "eth.type", MFF_ETH_TYPE, NULL, true); > - > - expr_symtab_add_field(symtab, "vlan.tci", MFF_VLAN_TCI, NULL, false); > - expr_symtab_add_predicate(symtab, "vlan.present", "vlan.tci[12]"); > - expr_symtab_add_subfield(symtab, "vlan.pcp", "vlan.present", > - "vlan.tci[13..15]"); > - expr_symtab_add_subfield(symtab, "vlan.vid", "vlan.present", > - "vlan.tci[0..11]"); > - > - expr_symtab_add_predicate(symtab, "ip4", "eth.type == 0x800"); > - expr_symtab_add_predicate(symtab, "ip6", "eth.type == 0x86dd"); > - expr_symtab_add_predicate(symtab, "ip", "ip4 || ip6"); > - expr_symtab_add_field(symtab, "ip.proto", MFF_IP_PROTO, "ip", true); > - expr_symtab_add_field(symtab, "ip.dscp", MFF_IP_DSCP, "ip", false); > - expr_symtab_add_field(symtab, "ip.ecn", MFF_IP_ECN, "ip", false); > - expr_symtab_add_field(symtab, "ip.ttl", MFF_IP_TTL, "ip", false); > - > - expr_symtab_add_field(symtab, "ip4.src", MFF_IPV4_SRC, "ip4", false); > - expr_symtab_add_field(symtab, "ip4.dst", MFF_IPV4_DST, "ip4", false); > - > - expr_symtab_add_predicate(symtab, "icmp4", "ip4 && ip.proto == 1"); > - expr_symtab_add_field(symtab, "icmp4.type", MFF_ICMPV4_TYPE, "icmp4", > - false); > - expr_symtab_add_field(symtab, "icmp4.code", MFF_ICMPV4_CODE, "icmp4", > - false); > - > - expr_symtab_add_field(symtab, "ip6.src", MFF_IPV6_SRC, "ip6", false); > - expr_symtab_add_field(symtab, "ip6.dst", MFF_IPV6_DST, "ip6", false); > - expr_symtab_add_field(symtab, "ip6.label", MFF_IPV6_LABEL, "ip6", > false); > - > - expr_symtab_add_predicate(symtab, "icmp6", "ip6 && ip.proto == 58"); > - expr_symtab_add_field(symtab, "icmp6.type", MFF_ICMPV6_TYPE, "icmp6", > - true); > - expr_symtab_add_field(symtab, "icmp6.code", MFF_ICMPV6_CODE, "icmp6", > - true); > - > - expr_symtab_add_predicate(symtab, "icmp", "icmp4 || icmp6"); > - > - expr_symtab_add_field(symtab, "ip.frag", MFF_IP_FRAG, "ip", false); > - expr_symtab_add_predicate(symtab, "ip.is_frag", "ip.frag[0]"); > - expr_symtab_add_predicate(symtab, "ip.later_frag", "ip.frag[1]"); > - expr_symtab_add_predicate(symtab, "ip.first_frag", "ip.is_frag && > !ip.later_frag"); > - > - expr_symtab_add_predicate(symtab, "arp", "eth.type == 0x806"); > - expr_symtab_add_field(symtab, "arp.op", MFF_ARP_OP, "arp", false); > - expr_symtab_add_field(symtab, "arp.spa", MFF_ARP_SPA, "arp", false); > - expr_symtab_add_field(symtab, "arp.sha", MFF_ARP_SHA, "arp", false); > - expr_symtab_add_field(symtab, "arp.tpa", MFF_ARP_TPA, "arp", false); > - expr_symtab_add_field(symtab, "arp.tha", MFF_ARP_THA, "arp", false); > - > - expr_symtab_add_predicate(symtab, "nd", "icmp6.type == {135, 136} && > icmp6.code == 0"); > - expr_symtab_add_field(symtab, "nd.target", MFF_ND_TARGET, "nd", > false); > - expr_symtab_add_field(symtab, "nd.sll", MFF_ND_SLL, > - "nd && icmp6.type == 135", false); > - expr_symtab_add_field(symtab, "nd.tll", MFF_ND_TLL, > - "nd && icmp6.type == 136", false); > - > - expr_symtab_add_predicate(symtab, "tcp", "ip.proto == 6"); > - expr_symtab_add_field(symtab, "tcp.src", MFF_TCP_SRC, "tcp", false); > - expr_symtab_add_field(symtab, "tcp.dst", MFF_TCP_DST, "tcp", false); > - expr_symtab_add_field(symtab, "tcp.flags", MFF_TCP_FLAGS, "tcp", > false); > - > - expr_symtab_add_predicate(symtab, "udp", "ip.proto == 17"); > - expr_symtab_add_field(symtab, "udp.src", MFF_UDP_SRC, "udp", false); > - expr_symtab_add_field(symtab, "udp.dst", MFF_UDP_DST, "udp", false); > - > - expr_symtab_add_predicate(symtab, "sctp", "ip.proto == 132"); > - expr_symtab_add_field(symtab, "sctp.src", MFF_SCTP_SRC, "sctp", > false); > - expr_symtab_add_field(symtab, "sctp.dst", MFF_SCTP_DST, "sctp", > false); > - > - /* For negative testing. */ > - expr_symtab_add_field(symtab, "bad_prereq", MFF_XREG0, "xyzzy", > false); > - expr_symtab_add_field(symtab, "self_recurse", MFF_XREG0, > - "self_recurse != 0", false); > - expr_symtab_add_field(symtab, "mutual_recurse_1", MFF_XREG0, > - "mutual_recurse_2 != 0", false); > - expr_symtab_add_field(symtab, "mutual_recurse_2", MFF_XREG0, > - "mutual_recurse_1 != 0", false); > - expr_symtab_add_string(symtab, "big_string", MFF_XREG0, NULL); > -} > - > -static void > create_dhcp_opts(struct hmap *dhcp_opts) > { > hmap_init(dhcp_opts); > @@ -311,7 +203,7 @@ test_parse_expr__(int steps) > struct simap ports; > struct ds input; > > - create_symtab(&symtab); > + create_symtab_helper(&symtab); > create_macros(¯os); > > simap_init(&ports); > @@ -1281,7 +1173,7 @@ test_parse_actions(struct ovs_cmdl_context *ctx > OVS_UNUSED) > struct simap ports, ct_zones; > struct ds input; > > - create_symtab(&symtab); > + create_symtab_helper(&symtab); > create_dhcp_opts(&dhcp_opts); > > /* Initialize group ids. */ > diff --git a/tests/testsuite.at b/tests/testsuite.at > index f5f1253..1721ba8 100644 > --- a/tests/testsuite.at > +++ b/tests/testsuite.at > @@ -76,3 +76,4 @@ m4_include([tests/ovn-nbctl.at]) > m4_include([tests/ovn-sbctl.at]) > m4_include([tests/ovn-controller.at]) > m4_include([tests/ovn-controller-vtep.at]) > +m4_include([tests/test-ovn-utils.at]) > -- > 1.9.1 > > _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev