[ovs-dev] [PATCH ovn v3 05/10] lflow-cache: Add unit tests.

Dumitru Ceara dceara at redhat.com
Tue Feb 9 20:09:57 UTC 2021


Acked-by: Mark Michelson <mmichels at redhat.com>
Acked-by: Numan Siddique <numans at ovn.org>
Signed-off-by: Dumitru Ceara <dceara at redhat.com>
---
v3:
- change calls to lflow-cache API to use new conventions.
- update UT outputs to match new lflow-cache stats outputs.
---
 controller/test-lflow-cache.c  |  223 +++++++++++++++++++++++++++++++++++
 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, 632 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..79fe8c6
--- /dev/null
+++ b/controller/test-lflow-cache.c
@@ -0,0 +1,223 @@
+/* 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 "lib/uuid.h"
+#include "ovn/expr.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 uuid *lflow_uuid,
+                       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_uuid, conj_id_ofs);
+    } else if (!strcmp(op_type, "expr")) {
+        lflow_cache_add_expr(lc, lflow_uuid, 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_uuid, matches);
+    } else {
+        OVS_NOT_REACHED();
+    }
+}
+
+static void
+test_lflow_cache_lookup__(struct lflow_cache *lc,
+                          const struct uuid *lflow_uuid)
+{
+    struct lflow_cache_value *lcv = lflow_cache_get(lc, lflow_uuid);
+
+    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 uuid *lflow_uuid)
+{
+    printf("DELETE\n");
+    lflow_cache_delete(lc, lflow_uuid);
+}
+
+static void
+test_lflow_cache_stats__(struct lflow_cache *lc)
+{
+    struct ds ds = DS_EMPTY_INITIALIZER;
+
+    lflow_cache_get_stats(lc, &ds);
+    printf("%s", ds_cstr(&ds));
+    ds_destroy(&ds);
+}
+
+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 uuid lflow_uuid;
+        uuid_generate(&lflow_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_uuid, conj_id_ofs, e);
+            test_lflow_cache_lookup__(lc, &lflow_uuid);
+        } 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_uuid, conj_id_ofs, e);
+            test_lflow_cache_lookup__(lc, &lflow_uuid);
+            test_lflow_cache_delete__(lc, &lflow_uuid);
+            test_lflow_cache_lookup__(lc, &lflow_uuid);
+        } 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));
+
+    struct ds ds = DS_EMPTY_INITIALIZER;
+    lflow_cache_get_stats(NULL, &ds);
+    ovs_assert(!strcmp(ds_cstr_ro(&ds), "Invalid arguments."));
+    lflow_cache_get_stats(NULL, NULL);
+    ds_destroy(&ds);
+
+    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..5000165
--- /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 785514d..878230a 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -22345,6 +22345,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])



More information about the dev mailing list