On Thu, Feb 4, 2021 at 6:56 PM Dumitru Ceara <dce...@redhat.com> wrote: > > Signed-off-by: Dumitru Ceara <dce...@redhat.com>
Acked-by: Numan Siddique <num...@ovn.org> Numan > --- > controller/test-lflow-cache.c | 224 +++++++++++++++++++++++++++++++++++ > controller/test-ofctrl-seqno.c | 18 --- > tests/automake.mk | 8 + > tests/ovn-lflow-cache.at | 257 > ++++++++++++++++++++++++++++++++++++++++ > tests/ovn.at | 68 +++++++++++ > tests/test-utils.c | 49 ++++++++ > tests/test-utils.h | 26 ++++ > tests/testsuite.at | 1 > 8 files changed, 633 insertions(+), 18 deletions(-) > create mode 100644 controller/test-lflow-cache.c > create mode 100644 tests/ovn-lflow-cache.at > create mode 100644 tests/test-utils.c > create mode 100644 tests/test-utils.h > > diff --git a/controller/test-lflow-cache.c b/controller/test-lflow-cache.c > new file mode 100644 > index 0000000..d6e962e > --- /dev/null > +++ b/controller/test-lflow-cache.c > @@ -0,0 +1,224 @@ > +/* Copyright (c) 2021, Red Hat, 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 <config.h> > + > +#include "ovn/expr.h" > +#include "ovn-sb-idl.h" > +#include "tests/ovstest.h" > +#include "tests/test-utils.h" > +#include "util.h" > + > +#include "lflow-cache.h" > + > +static void > +test_lflow_cache_add__(struct lflow_cache *lc, const char *op_type, > + const struct sbrec_logical_flow *lflow, > + unsigned int conj_id_ofs, > + struct expr *e) > +{ > + printf("ADD %s:\n", op_type); > + printf(" conj-id-ofs: %u\n", conj_id_ofs); > + > + if (!strcmp(op_type, "conj-id")) { > + lflow_cache_add_conj_id(lc, lflow, conj_id_ofs); > + } else if (!strcmp(op_type, "expr")) { > + lflow_cache_add_expr(lc, lflow, conj_id_ofs, expr_clone(e)); > + } else if (!strcmp(op_type, "matches")) { > + struct hmap *matches = xmalloc(sizeof *matches); > + ovs_assert(expr_to_matches(e, NULL, NULL, matches) == 0); > + ovs_assert(hmap_count(matches) == 1); > + lflow_cache_add_matches(lc, lflow, matches); > + } else { > + OVS_NOT_REACHED(); > + } > +} > + > +static void > +test_lflow_cache_lookup__(struct lflow_cache *lc, > + const struct sbrec_logical_flow *lflow) > +{ > + struct lflow_cache_value *lcv = lflow_cache_get(lc, lflow); > + > + printf("LOOKUP:\n"); > + if (!lcv) { > + printf(" not found\n"); > + return; > + } > + > + printf(" conj_id_ofs: %"PRIu32"\n", lcv->conj_id_ofs); > + switch (lcv->type) { > + case LCACHE_T_CONJ_ID: > + printf(" type: conj-id\n"); > + break; > + case LCACHE_T_EXPR: > + printf(" type: expr\n"); > + break; > + case LCACHE_T_MATCHES: > + printf(" type: matches\n"); > + break; > + case LCACHE_T_NONE: > + OVS_NOT_REACHED(); > + break; > + } > +} > + > +static void > +test_lflow_cache_delete__(struct lflow_cache *lc, > + const struct sbrec_logical_flow *lflow) > +{ > + printf("DELETE\n"); > + lflow_cache_delete(lc, lflow); > +} > + > +static void > +test_lflow_cache_stats__(struct lflow_cache *lc) > +{ > + struct lflow_cache_stats *lcs = lflow_cache_get_stats(lc); > + > + if (!lcs) { > + return; > + } > + printf("Enabled: %s\n", lflow_cache_is_enabled(lc) ? "true" : "false"); > + for (size_t i = 0; i < LCACHE_T_MAX; i++) { > + printf(" %s: %"PRIuSIZE"\n", lflow_cache_type_names[i], > + lcs->n_entries[i]); > + } > + free(lcs); > +} > + > +static void > +test_lflow_cache_operations(struct ovs_cmdl_context *ctx) > +{ > + struct lflow_cache *lc = lflow_cache_create(); > + struct expr *e = expr_create_boolean(true); > + bool enabled = !strcmp(ctx->argv[1], "true"); > + unsigned int shift = 2; > + unsigned int n_ops; > + > + lflow_cache_enable(lc, enabled); > + test_lflow_cache_stats__(lc); > + > + if (!test_read_uint_value(ctx, shift++, "n_ops", &n_ops)) { > + goto done; > + } > + > + for (unsigned int i = 0; i < n_ops; i++) { > + const char *op = test_read_value(ctx, shift++, "op"); > + > + if (!op) { > + goto done; > + } > + > + struct sbrec_logical_flow lflow; > + uuid_generate(&lflow.header_.uuid); > + > + if (!strcmp(op, "add")) { > + const char *op_type = test_read_value(ctx, shift++, "op_type"); > + if (!op_type) { > + goto done; > + } > + > + unsigned int conj_id_ofs; > + if (!test_read_uint_value(ctx, shift++, "conj-id-ofs", > + &conj_id_ofs)) { > + goto done; > + } > + > + test_lflow_cache_add__(lc, op_type, &lflow, conj_id_ofs, e); > + test_lflow_cache_lookup__(lc, &lflow); > + } else if (!strcmp(op, "add-del")) { > + const char *op_type = test_read_value(ctx, shift++, "op_type"); > + if (!op_type) { > + goto done; > + } > + > + unsigned int conj_id_ofs; > + if (!test_read_uint_value(ctx, shift++, "conj-id-ofs", > + &conj_id_ofs)) { > + goto done; > + } > + > + test_lflow_cache_add__(lc, op_type, &lflow, conj_id_ofs, e); > + test_lflow_cache_lookup__(lc, &lflow); > + test_lflow_cache_delete__(lc, &lflow); > + test_lflow_cache_lookup__(lc, &lflow); > + } else if (!strcmp(op, "enable")) { > + printf("ENABLE\n"); > + lflow_cache_enable(lc, true); > + } else if (!strcmp(op, "disable")) { > + printf("DISABLE\n"); > + lflow_cache_enable(lc, false); > + } else if (!strcmp(op, "flush")) { > + printf("FLUSH\n"); > + lflow_cache_flush(lc); > + } else { > + OVS_NOT_REACHED(); > + } > + test_lflow_cache_stats__(lc); > + } > +done: > + lflow_cache_destroy(lc); > + expr_destroy(e); > +} > + > +static void > +test_lflow_cache_negative(struct ovs_cmdl_context *ctx OVS_UNUSED) > +{ > + lflow_cache_flush(NULL); > + lflow_cache_destroy(NULL); > + lflow_cache_enable(NULL, true); > + ovs_assert(!lflow_cache_is_enabled(NULL)); > + ovs_assert(!lflow_cache_get_stats(NULL)); > + > + struct lflow_cache *lcs[] = { > + NULL, > + lflow_cache_create(), > + }; > + > + for (size_t i = 0; i < ARRAY_SIZE(lcs); i++) { > + struct expr *e = expr_create_boolean(true); > + struct hmap *matches = xmalloc(sizeof *matches); > + > + ovs_assert(expr_to_matches(e, NULL, NULL, matches) == 0); > + ovs_assert(hmap_count(matches) == 1); > + > + lflow_cache_add_conj_id(lcs[i], NULL, 0); > + lflow_cache_add_expr(lcs[i], NULL, 0, NULL); > + lflow_cache_add_expr(lcs[i], NULL, 0, e); > + lflow_cache_add_matches(lcs[i], NULL, NULL); > + lflow_cache_add_matches(lcs[i], NULL, matches); > + lflow_cache_destroy(lcs[i]); > + } > +} > + > +static void > +test_lflow_cache_main(int argc, char *argv[]) > +{ > + set_program_name(argv[0]); > + static const struct ovs_cmdl_command commands[] = { > + {"lflow_cache_operations", NULL, 3, INT_MAX, > + test_lflow_cache_operations, OVS_RO}, > + {"lflow_cache_negative", NULL, 0, 0, > + test_lflow_cache_negative, OVS_RO}, > + {NULL, NULL, 0, 0, NULL, OVS_RO}, > + }; > + struct ovs_cmdl_context ctx; > + ctx.argc = argc - 1; > + ctx.argv = argv + 1; > + ovs_cmdl_run_command(&ctx, commands); > +} > + > +OVSTEST_REGISTER("test-lflow-cache", test_lflow_cache_main); > diff --git a/controller/test-ofctrl-seqno.c b/controller/test-ofctrl-seqno.c > index fce88d4..b96da9d 100644 > --- a/controller/test-ofctrl-seqno.c > +++ b/controller/test-ofctrl-seqno.c > @@ -16,6 +16,7 @@ > #include <config.h> > > #include "tests/ovstest.h" > +#include "tests/test-utils.h" > #include "sort.h" > #include "util.h" > > @@ -27,23 +28,6 @@ test_init(void) > ofctrl_seqno_init(); > } > > -static bool > -test_read_uint_value(struct ovs_cmdl_context *ctx, unsigned int index, > - const char *descr, unsigned int *result) > -{ > - if (index >= ctx->argc) { > - fprintf(stderr, "Missing %s argument\n", descr); > - return false; > - } > - > - const char *arg = ctx->argv[index]; > - if (!str_to_uint(arg, 10, result)) { > - fprintf(stderr, "Invalid %s: %s\n", descr, arg); > - return false; > - } > - return true; > -} > - > static int > test_seqno_compare(size_t a, size_t b, void *values_) > { > diff --git a/tests/automake.mk b/tests/automake.mk > index 282d1b1..df6d0a2 100644 > --- a/tests/automake.mk > +++ b/tests/automake.mk > @@ -33,7 +33,8 @@ TESTSUITE_AT = \ > tests/ovn-macros.at \ > tests/ovn-performance.at \ > tests/ovn-ofctrl-seqno.at \ > - tests/ovn-ipam.at > + tests/ovn-ipam.at \ > + tests/ovn-lflow-cache.at > > SYSTEM_KMOD_TESTSUITE_AT = \ > tests/system-common-macros.at \ > @@ -207,8 +208,13 @@ noinst_PROGRAMS += tests/ovstest > tests_ovstest_SOURCES = \ > tests/ovstest.c \ > tests/ovstest.h \ > + tests/test-utils.c \ > + tests/test-utils.h \ > tests/test-ovn.c \ > + controller/test-lflow-cache.c \ > controller/test-ofctrl-seqno.c \ > + controller/lflow-cache.c \ > + controller/lflow-cache.h \ > controller/ofctrl-seqno.c \ > controller/ofctrl-seqno.h \ > northd/test-ipam.c \ > diff --git a/tests/ovn-lflow-cache.at b/tests/ovn-lflow-cache.at > new file mode 100644 > index 0000000..f7e8959 > --- /dev/null > +++ b/tests/ovn-lflow-cache.at > @@ -0,0 +1,257 @@ > +# > +# Unit tests for the controller/lflow-cache.c module. > +# > +AT_BANNER([OVN unit tests - lflow-cache]) > + > +AT_SETUP([ovn -- unit test -- lflow-cache single add/lookup]) > +AT_CHECK( > + [ovstest test-lflow-cache lflow_cache_operations \ > + true 3 \ > + add conj-id 1 \ > + add expr 2 \ > + add matches 3], > + [0], [dnl > +Enabled: true > + cache-conj-id: 0 > + cache-expr: 0 > + cache-matches: 0 > +ADD conj-id: > + conj-id-ofs: 1 > +LOOKUP: > + conj_id_ofs: 1 > + type: conj-id > +Enabled: true > + cache-conj-id: 1 > + cache-expr: 0 > + cache-matches: 0 > +ADD expr: > + conj-id-ofs: 2 > +LOOKUP: > + conj_id_ofs: 2 > + type: expr > +Enabled: true > + cache-conj-id: 1 > + cache-expr: 1 > + cache-matches: 0 > +ADD matches: > + conj-id-ofs: 3 > +LOOKUP: > + conj_id_ofs: 0 > + type: matches > +Enabled: true > + cache-conj-id: 1 > + cache-expr: 1 > + cache-matches: 1 > +]) > +AT_CLEANUP > + > +AT_SETUP([ovn -- unit test -- lflow-cache single add/lookup/del]) > +AT_CHECK( > + [ovstest test-lflow-cache lflow_cache_operations \ > + true 3 \ > + add-del conj-id 1 \ > + add-del expr 2 \ > + add-del matches 3], > + [0], [dnl > +Enabled: true > + cache-conj-id: 0 > + cache-expr: 0 > + cache-matches: 0 > +ADD conj-id: > + conj-id-ofs: 1 > +LOOKUP: > + conj_id_ofs: 1 > + type: conj-id > +DELETE > +LOOKUP: > + not found > +Enabled: true > + cache-conj-id: 0 > + cache-expr: 0 > + cache-matches: 0 > +ADD expr: > + conj-id-ofs: 2 > +LOOKUP: > + conj_id_ofs: 2 > + type: expr > +DELETE > +LOOKUP: > + not found > +Enabled: true > + cache-conj-id: 0 > + cache-expr: 0 > + cache-matches: 0 > +ADD matches: > + conj-id-ofs: 3 > +LOOKUP: > + conj_id_ofs: 0 > + type: matches > +DELETE > +LOOKUP: > + not found > +Enabled: true > + cache-conj-id: 0 > + cache-expr: 0 > + cache-matches: 0 > +]) > +AT_CLEANUP > + > +AT_SETUP([ovn -- unit test -- lflow-cache disabled single add/lookup/del]) > +AT_CHECK( > + [ovstest test-lflow-cache lflow_cache_operations \ > + false 3 \ > + add conj-id 1 \ > + add expr 2 \ > + add matches 3], > + [0], [dnl > +Enabled: false > + cache-conj-id: 0 > + cache-expr: 0 > + cache-matches: 0 > +ADD conj-id: > + conj-id-ofs: 1 > +LOOKUP: > + not found > +Enabled: false > + cache-conj-id: 0 > + cache-expr: 0 > + cache-matches: 0 > +ADD expr: > + conj-id-ofs: 2 > +LOOKUP: > + not found > +Enabled: false > + cache-conj-id: 0 > + cache-expr: 0 > + cache-matches: 0 > +ADD matches: > + conj-id-ofs: 3 > +LOOKUP: > + not found > +Enabled: false > + cache-conj-id: 0 > + cache-expr: 0 > + cache-matches: 0 > +]) > +AT_CLEANUP > + > +AT_SETUP([ovn -- unit test -- lflow-cache disable/enable/flush]) > +AT_CHECK( > + [ovstest test-lflow-cache lflow_cache_operations \ > + true 12 \ > + add conj-id 1 \ > + add expr 2 \ > + add matches 3 \ > + disable \ > + add conj-id 4 \ > + add expr 5 \ > + add matches 6 \ > + enable \ > + add conj-id 7 \ > + add expr 8 \ > + add matches 9 \ > + flush], > + [0], [dnl > +Enabled: true > + cache-conj-id: 0 > + cache-expr: 0 > + cache-matches: 0 > +ADD conj-id: > + conj-id-ofs: 1 > +LOOKUP: > + conj_id_ofs: 1 > + type: conj-id > +Enabled: true > + cache-conj-id: 1 > + cache-expr: 0 > + cache-matches: 0 > +ADD expr: > + conj-id-ofs: 2 > +LOOKUP: > + conj_id_ofs: 2 > + type: expr > +Enabled: true > + cache-conj-id: 1 > + cache-expr: 1 > + cache-matches: 0 > +ADD matches: > + conj-id-ofs: 3 > +LOOKUP: > + conj_id_ofs: 0 > + type: matches > +Enabled: true > + cache-conj-id: 1 > + cache-expr: 1 > + cache-matches: 1 > +DISABLE > +Enabled: false > + cache-conj-id: 0 > + cache-expr: 0 > + cache-matches: 0 > +ADD conj-id: > + conj-id-ofs: 4 > +LOOKUP: > + not found > +Enabled: false > + cache-conj-id: 0 > + cache-expr: 0 > + cache-matches: 0 > +ADD expr: > + conj-id-ofs: 5 > +LOOKUP: > + not found > +Enabled: false > + cache-conj-id: 0 > + cache-expr: 0 > + cache-matches: 0 > +ADD matches: > + conj-id-ofs: 6 > +LOOKUP: > + not found > +Enabled: false > + cache-conj-id: 0 > + cache-expr: 0 > + cache-matches: 0 > +ENABLE > +Enabled: true > + cache-conj-id: 0 > + cache-expr: 0 > + cache-matches: 0 > +ADD conj-id: > + conj-id-ofs: 7 > +LOOKUP: > + conj_id_ofs: 7 > + type: conj-id > +Enabled: true > + cache-conj-id: 1 > + cache-expr: 0 > + cache-matches: 0 > +ADD expr: > + conj-id-ofs: 8 > +LOOKUP: > + conj_id_ofs: 8 > + type: expr > +Enabled: true > + cache-conj-id: 1 > + cache-expr: 1 > + cache-matches: 0 > +ADD matches: > + conj-id-ofs: 9 > +LOOKUP: > + conj_id_ofs: 0 > + type: matches > +Enabled: true > + cache-conj-id: 1 > + cache-expr: 1 > + cache-matches: 1 > +FLUSH > +Enabled: true > + cache-conj-id: 0 > + cache-expr: 0 > + cache-matches: 0 > +]) > +AT_CLEANUP > + > +AT_SETUP([ovn -- unit test -- lflow-cache negative tests]) > +AT_CHECK([ovstest test-lflow-cache lflow_cache_negative], [0], []) > +AT_CLEANUP > diff --git a/tests/ovn.at b/tests/ovn.at > index 4a75acc..0e114cf 100644 > --- a/tests/ovn.at > +++ b/tests/ovn.at > @@ -22235,6 +22235,74 @@ OVN_CLEANUP([hv1]) > > AT_CLEANUP > > +AT_SETUP([ovn -- lflow cache operations]) > +ovn_start > +net_add n1 > +sim_add hv1 > + > +as hv1 > +ovs-vsctl add-br br-phys > +ovn_attach n1 br-phys 192.168.0.1 > + > +as hv1 > +ovs-vsctl -- add-port br-int hv1-vif1 \ > + -- set interface hv1-vif1 external-ids:iface-id=lsp1 \ > + -- add-port br-int hv1-vif2 \ > + -- set interface hv1-vif2 external-ids:iface-id=lsp2 > + > +ovn-nbctl ls-add ls1 \ > + -- lsp-add ls1 lsp1 \ > + -- lsp-add ls1 lsp2 \ > + -- pg-add pg1 lsp1 lsp2 \ > + -- create Address_Set name=as1 addresses=\"10.0.0.1\",\"10.0.0.2\" > +check ovn-nbctl --wait=hv sync > +wait_for_ports_up lsp1 lsp2 > + > +get_cache_count () { > + local cache_name=$1 > + as hv1 ovn-appctl -t ovn-controller lflow-cache/show-stats | grep > ${cache_name} | awk '{ print $3 }' > +} > + > +AS_BOX([Check matches caching]) > +conj_id_cnt=$(get_cache_count cache-conj-id) > +expr_cnt=$(get_cache_count cache-expr) > +matches_cnt=$(get_cache_count cache-matches) > + > +check ovn-nbctl acl-add ls1 from-lport 1 '1' drop > +check ovn-nbctl --wait=hv sync > + > +AT_CHECK([test "$conj_id_cnt" = "$(get_cache_count cache-conj-id)"], [0], []) > +AT_CHECK([test "$expr_cnt" = "$(get_cache_count cache-expr)"], [0], []) > +AT_CHECK([test "$(($matches_cnt + 1))" = "$(get_cache_count > cache-matches)"], [0], []) > + > +AS_BOX([Check expr caching for is_chassis_resident() matches]) > +conj_id_cnt=$(get_cache_count cache-conj-id) > +expr_cnt=$(get_cache_count cache-expr) > +matches_cnt=$(get_cache_count cache-matches) > + > +check ovn-nbctl acl-add ls1 from-lport 1 'is_chassis_resident("lsp1")' drop > +check ovn-nbctl --wait=hv sync > + > +AT_CHECK([test "$conj_id_cnt" = "$(get_cache_count cache-conj-id)"], [0], []) > +AT_CHECK([test "$(($expr_cnt + 1))" = "$(get_cache_count cache-expr)"], [0], > []) > +AT_CHECK([test "$matches_cnt" = "$(get_cache_count cache-matches)"], [0], []) > + > +AS_BOX([Check conj-id caching for conjunctive port group/address set > matches]) > +conj_id_cnt=$(get_cache_count cache-conj-id) > +expr_cnt=$(get_cache_count cache-expr) > +matches_cnt=$(get_cache_count cache-matches) > + > +check ovn-nbctl acl-add ls1 from-lport 1 'inport == @pg1 && outport == @pg1 > && is_chassis_resident("lsp1")' drop > +check ovn-nbctl acl-add ls1 from-lport 1 'ip4.src == $as1 && ip4.dst == $as1 > && is_chassis_resident("lsp1")' drop > +check ovn-nbctl --wait=hv sync > + > +AT_CHECK([test "$(($conj_id_cnt + 2))" = "$(get_cache_count > cache-conj-id)"], [0], []) > +AT_CHECK([test "$expr_cnt" = "$(get_cache_count cache-expr)"], [0], []) > +AT_CHECK([test "$matches_cnt" = "$(get_cache_count cache-matches)"], [0], []) > + > +OVN_CLEANUP([hv1]) > +AT_CLEANUP > + > AT_SETUP([ovn -- Delete Port_Binding and OVS port Incremental Processing]) > ovn_start > > diff --git a/tests/test-utils.c b/tests/test-utils.c > new file mode 100644 > index 0000000..6a3b198 > --- /dev/null > +++ b/tests/test-utils.c > @@ -0,0 +1,49 @@ > +/* Copyright (c) 2021, Red Hat, 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 <config.h> > + > +#include "test-utils.h" > + > +#include "util.h" > + > +bool > +test_read_uint_value(struct ovs_cmdl_context *ctx, unsigned int index, > + const char *descr, unsigned int *result) > +{ > + if (index >= ctx->argc) { > + fprintf(stderr, "Missing %s argument\n", descr); > + return false; > + } > + > + const char *arg = ctx->argv[index]; > + if (!str_to_uint(arg, 10, result)) { > + fprintf(stderr, "Invalid %s: %s\n", descr, arg); > + return false; > + } > + return true; > +} > + > +const char * > +test_read_value(struct ovs_cmdl_context *ctx, unsigned int index, > + const char *descr) > +{ > + if (index >= ctx->argc) { > + fprintf(stderr, "Missing %s argument\n", descr); > + return NULL; > + } > + > + return ctx->argv[index]; > +} > diff --git a/tests/test-utils.h b/tests/test-utils.h > new file mode 100644 > index 0000000..721032f > --- /dev/null > +++ b/tests/test-utils.h > @@ -0,0 +1,26 @@ > +/* Copyright (c) 2021, Red Hat, 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. > + */ > + > +#ifndef TEST_UTILS_H > +#define TEST_UTILS_H 1 > + > +#include "ovstest.h" > + > +bool test_read_uint_value(struct ovs_cmdl_context *ctx, unsigned int index, > + const char *descr, unsigned int *result); > +const char *test_read_value(struct ovs_cmdl_context *ctx, unsigned int index, > + const char *descr); > + > +#endif /* tests/test-utils.h */ > diff --git a/tests/testsuite.at b/tests/testsuite.at > index 6253d11..35908ad 100644 > --- a/tests/testsuite.at > +++ b/tests/testsuite.at > @@ -27,6 +27,7 @@ m4_include([tests/ovn.at]) > m4_include([tests/ovn-performance.at]) > m4_include([tests/ovn-northd.at]) > m4_include([tests/ovn-nbctl.at]) > +m4_include([tests/ovn-lflow-cache.at]) > m4_include([tests/ovn-ofctrl-seqno.at]) > m4_include([tests/ovn-sbctl.at]) > m4_include([tests/ovn-ic-nbctl.at]) > > _______________________________________________ > dev mailing list > d...@openvswitch.org > https://mail.openvswitch.org/mailman/listinfo/ovs-dev > _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev