diff mbox

[ovs-dev,monitor_cond,V6,10/11] tests: add testing for idl conditional monitoring

Message ID 1463495229-26258-11-git-send-email-lirans@il.ibm.com
State Changes Requested
Headers show

Commit Message

Liran Schour May 17, 2016, 2:27 p.m. UTC
Add tests for conditional monitoring to IDL.

Signed-off-by: Liran Schour <lirans@il.ibm.com>
---
 tests/ovsdb-idl.at  | 136 ++++++++++++++++++++++++++++++++++++
 tests/test-ovsdb.c  | 193 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 tests/test-ovsdb.py |  27 ++++++++
 3 files changed, 355 insertions(+), 1 deletion(-)

Comments

Ben Pfaff June 2, 2016, 5:08 p.m. UTC | #1
On Tue, May 17, 2016 at 05:27:08PM +0300, Liran Schour wrote:
> Add tests for conditional monitoring to IDL.
> 
> Signed-off-by: Liran Schour <lirans@il.ibm.com>

Thanks for adding tests.

Usually we squash tests for new features with the patches that implement
those new features.  Can you do that?

Thanks,

Ben.
Liran Schour June 6, 2016, 11:02 a.m. UTC | #2
Ben Pfaff <blp@ovn.org> wrote on 02/06/2016 08:08:14 PM:

> On Tue, May 17, 2016 at 05:27:08PM +0300, Liran Schour wrote:
> > Add tests for conditional monitoring to IDL.
> > 
> > Signed-off-by: Liran Schour <lirans@il.ibm.com>
> 
> Thanks for adding tests.
> 
> Usually we squash tests for new features with the patches that implement
> those new features.  Can you do that?
> 

Sure. Will squash this into the previous patch.

Thanks,
- Liran
diff mbox

Patch

diff --git a/tests/ovsdb-idl.at b/tests/ovsdb-idl.at
index 7f2fe1d..068d859 100644
--- a/tests/ovsdb-idl.at
+++ b/tests/ovsdb-idl.at
@@ -353,6 +353,142 @@  OVSDB_CHECK_IDL([simple idl, destroy without commit or abort],
 004: done
 ]])
 
+OVSDB_CHECK_IDL([simple idl, conditional, false condition],
+  [['["idltest",
+       {"op": "insert",
+       "table": "simple",
+       "row": {"i": 1,
+               "r": 2.0,
+               "b": true}}]']],
+  [['condition simple [false]' \
+    'condition simple []']],
+  [[000: change conditions
+001: empty
+002: change conditions
+003: i=1 r=2 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
+004: done
+]])
+
+OVSDB_CHECK_IDL([simple idl, conditional, true condition],
+  [['["idltest",
+       {"op": "insert",
+       "table": "simple",
+       "row": {"i": 1,
+               "r": 2.0,
+               "b": true}}]']],
+  [['condition simple [false]' \
+    'condition simple [true]']],
+  [[000: change conditions
+001: empty
+002: change conditions
+003: i=1 r=2 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
+004: done
+]])
+
+OVSDB_CHECK_IDL([simple idl, conditional, multiple clauses in condition],
+  [['["idltest",
+       {"op": "insert",
+       "table": "simple",
+       "row": {"i": 1,
+               "r": 2.0,
+               "b": true}},
+       {"op": "insert",
+       "table": "simple",
+       "row": {"i": 2,
+               "r": 3.0,
+               "b": true}}]']],
+  [['condition simple [false]' \
+    'condition simple [["i","==",1],["i","==",2]]']],
+  [[000: change conditions
+001: empty
+002: change conditions
+003: i=1 r=2 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
+003: i=2 r=3 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<2>
+004: done
+]])
+
+OVSDB_CHECK_IDL([simple idl, conditional, modify as insert due to condition],
+  [['["idltest",
+       {"op": "insert",
+       "table": "simple",
+       "row": {"i": 1,
+               "r": 2.0,
+               "b": true}}]']],
+  [['condition simple [false]' \
+    'condition simple [["i","==",1]]']],
+  [[000: change conditions
+001: empty
+002: change conditions
+003: i=1 r=2 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
+004: done
+]])
+
+OVSDB_CHECK_IDL([simple idl, conditional, modify as delete due to condition],
+  [['["idltest",
+       {"op": "insert",
+       "table": "simple",
+       "row": {"i": 1,
+               "r": 2.0,
+               "b": true}}]']],
+  [['condition simple [false]' \
+    'condition simple [["i","==",1]]' \
+    'condition simple [["i","==",2]]' \
+    '["idltest",
+       {"op": "insert",
+       "table": "simple",
+       "row": {"i": 2,
+               "r": 3.0,
+               "b": true}}]']],
+  [[000: change conditions
+001: empty
+002: change conditions
+003: i=1 r=2 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
+004: change conditions
+005: empty
+006: {"error":null,"result":[{"uuid":["uuid","<2>"]}]}
+007: i=2 r=3 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<2>
+008: done
+]])
+
+OVSDB_CHECK_IDL([simple idl, conditional, multiple tables],
+  [['["idltest",
+       {"op": "insert",
+       "table": "simple",
+       "row": {"i": 1,
+               "r": 2.0,
+               "b": true}},
+       {"op": "insert",
+       "table": "link1",
+       "row": {"i": 0, "k": ["named-uuid", "self"]},
+       "uuid-name": "self"},
+        {"op": "insert",
+       "table": "link2",
+       "row": {"i": 2},
+       "uuid-name": "row0"}]']],
+  [['condition simple [false];condition link1 [false];condition link2 [false]' \
+    'condition simple [["i","==",1]]' \
+    'condition link1 [["i","==",0]]' \
+    'condition link2 [["i","==",3]]' \
+    '+["idltest",
+       {"op": "insert",
+       "table": "link2",
+       "row": {"i": 3},
+        "uuid-name": "row0"}]']],
+  [[000: change conditions
+001: empty
+002: change conditions
+003: i=1 r=2 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
+004: change conditions
+005: i=0 k=0 ka=[] l2= uuid=<2>
+005: i=1 r=2 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
+006: change conditions
+007: {"error":null,"result":[{"uuid":["uuid","<3>"]}]}
+008: i=0 k=0 ka=[] l2= uuid=<2>
+008: i=1 r=2 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
+008: i=3 l1= uuid=<3>
+009: done
+]])
+
 OVSDB_CHECK_IDL([self-linking idl, consistent ops],
   [],
   [['["idltest",
diff --git a/tests/test-ovsdb.c b/tests/test-ovsdb.c
index 11d332b..7a62a78 100644
--- a/tests/test-ovsdb.c
+++ b/tests/test-ovsdb.c
@@ -2141,6 +2141,187 @@  idl_set(struct ovsdb_idl *idl, char *commands, int step)
     ovsdb_idl_txn_destroy(txn);
 }
 
+static const struct ovsdb_idl_table_class *
+find_table_class(const char *name)
+{
+    if (!strcmp(name, "simple")) {
+        return &idltest_table_simple;
+    } else if (!strcmp(name, "link1")) {
+        return &idltest_table_link1;
+    } else if (!strcmp(name, "link2")) {
+        return &idltest_table_link2;
+    }
+    return NULL;
+}
+
+static void
+parse_simple_json_clause(struct ovsdb_idl_condition *cnd, struct json *json)
+{
+    const char *c;
+    struct ovsdb_error *error;
+    enum ovsdb_idl_function function;
+
+    if (json->type == JSON_TRUE) {
+        idltest_simple_add_clause_true(cnd);
+        return;
+    } else if (json->type == JSON_FALSE) {
+        idltest_simple_add_clause_false(cnd);
+        return;
+    }
+    if (json->type != JSON_ARRAY || json->u.array.n != 3) {
+        ovs_fatal(0, "Error parsing condition");
+    }
+
+    c = json_string(json->u.array.elems[0]);
+    error = ovsdb_idl_function_from_string(
+                                           json_string(json->u.array.elems[1]),
+                                           &function);
+    if (error) {
+        ovs_fatal(0, "Error parsing clause function %s",
+                  json_string(json->u.array.elems[1]));
+    }
+
+    /* add clause according to column */
+    if (!strcmp(c, "b")) {
+        idltest_simple_add_clause_b(cnd, function,
+                                    json_boolean(json->u.array.elems[2]));
+    } else if (!strcmp(c, "i")) {
+        idltest_simple_add_clause_i(cnd, function,
+                                    json_integer(json->u.array.elems[2]));
+    } else if (!strcmp(c, "s")) {
+        idltest_simple_add_clause_s(cnd, function,
+                                    json_string(json->u.array.elems[2]));
+    } else if (!strcmp(c, "u")) {
+        struct uuid uuid;
+        if (!uuid_from_string(&uuid,
+                              json_string(json->u.array.elems[2]))) {
+            ovs_fatal(0, "\"%s\" is not a valid UUID",
+                      json_string(json->u.array.elems[2]));
+        }
+        idltest_simple_add_clause_u(cnd, function, uuid);
+    } else if (!strcmp(c, "r")) {
+        idltest_simple_add_clause_r(cnd, function,
+                                    json_real(json->u.array.elems[2]));
+    } else {
+        ovs_fatal(0, "Unsupported columns name %s", c);
+    }
+}
+
+static void
+parse_link1_json_clause(struct ovsdb_idl_condition *cnd, struct json *json)
+{
+    const char *c;
+    struct ovsdb_error *error;
+    enum ovsdb_idl_function function;
+
+    if (json->type == JSON_TRUE) {
+        idltest_link1_add_clause_true(cnd);
+        return;
+    } else if (json->type == JSON_FALSE) {
+        idltest_link1_add_clause_false(cnd);
+        return;
+    }
+    if (json->type != JSON_ARRAY || json->u.array.n != 3) {
+        ovs_fatal(0, "Error parsing condition");
+    }
+
+    c = json_string(json->u.array.elems[0]);
+    error = ovsdb_idl_function_from_string(
+                                           json_string(json->u.array.elems[1]),
+                                           &function);
+    if (error) {
+        ovs_fatal(0, "Error parsing clause function %s",
+                  json_string(json->u.array.elems[1]));
+    }
+
+    /* add clause according to column */
+    if (!strcmp(c, "i")) {
+        idltest_link1_add_clause_i(cnd, function,
+                                    json_integer(json->u.array.elems[2]));
+    } else {
+        ovs_fatal(0, "Unsupported columns name %s", c);
+    }
+}
+
+static void
+parse_link2_json_clause(struct ovsdb_idl_condition *cnd, struct json *json)
+{
+    const char *c;
+    struct ovsdb_error *error;
+    enum ovsdb_idl_function function;
+
+    if (json->type == JSON_TRUE) {
+        idltest_link2_add_clause_true(cnd);
+        return;
+    } else if (json->type == JSON_FALSE) {
+        idltest_link2_add_clause_false(cnd);
+        return;
+    }
+    if (json->type != JSON_ARRAY || json->u.array.n != 3) {
+        ovs_fatal(0, "Error parsing condition");
+    }
+
+    c = json_string(json->u.array.elems[0]);
+    error = ovsdb_idl_function_from_string(
+                                           json_string(json->u.array.elems[1]),
+                                           &function);
+    if (error) {
+        ovs_fatal(0, "Error parsing clause function %s",
+                  json_string(json->u.array.elems[1]));
+    }
+
+    /* add clause according to column */
+    if (!strcmp(c, "i")) {
+        idltest_link2_add_clause_i(cnd, function,
+                                    json_integer(json->u.array.elems[2]));
+    } else {
+        ovs_fatal(0, "Unsupported columns name %s", c);
+    }
+}
+
+static void
+update_conditions(struct ovsdb_idl *idl, char *commands)
+{
+    char *cmd, *save_ptr1 = NULL;
+    const struct ovsdb_idl_table_class *tc;
+
+    for (cmd = strtok_r(commands, ";", &save_ptr1); cmd;
+         cmd = strtok_r(NULL, ";", &save_ptr1)) {
+        cmd += strlen("condition ");
+        char *save_ptr2 = NULL;
+        char *table_name = strtok_r(cmd, " ", &save_ptr2);
+        struct json *json = parse_json(save_ptr2);
+        struct ovsdb_idl_condition cnd;
+        int i;
+
+        if (json->type != JSON_ARRAY) {
+            ovs_fatal(0, "condition should be an array");
+        }
+
+        tc = find_table_class(table_name);
+        if (!tc) {
+            ovs_fatal(0, "Table %s does not exist", table_name);
+        }
+
+        ovsdb_idl_condition_init(&cnd, tc);
+
+        for (i = 0; i < json->u.array.n; i++) {
+            if (!strcmp(table_name, "simple")) {
+                parse_simple_json_clause(&cnd, json->u.array.elems[i]);
+            } else if (!strcmp(table_name, "link1")) {
+                parse_link1_json_clause(&cnd, json->u.array.elems[i]);
+            } else if (!strcmp(table_name, "link2")) {
+                parse_link2_json_clause(&cnd, json->u.array.elems[i]);
+            }
+        }
+
+        if (!ovsdb_idl_cond_update(idl, &cnd)) {
+            ovs_fatal(0, "Error update conditions");
+        }
+        ovsdb_idl_condition_destroy(&cnd);
+    }
+}
+
 static void
 do_idl(struct ovs_cmdl_context *ctx)
 {
@@ -2179,7 +2360,14 @@  do_idl(struct ovs_cmdl_context *ctx)
     setvbuf(stdout, NULL, _IONBF, 0);
 
     symtab = ovsdb_symbol_table_create();
-    for (i = 2; i < ctx->argc; i++) {
+    if (ctx->argc > 2 && strstr(ctx->argv[2], "condition ")) {
+        update_conditions(idl, ctx->argv[2]);
+        printf("%03d: change conditions\n", step++);
+        i = 3;
+    } else {
+        i = 2;
+    }
+    for (; i < ctx->argc; i++) {
         char *arg = ctx->argv[i];
         struct jsonrpc_msg *request, *reply;
 
@@ -2213,6 +2401,9 @@  do_idl(struct ovs_cmdl_context *ctx)
         if (!strcmp(arg, "reconnect")) {
             printf("%03d: reconnect\n", step++);
             ovsdb_idl_force_reconnect(idl);
+        }  else if (strstr(arg, "condition ")) {
+            update_conditions(idl, arg);
+            printf("%03d: change conditions\n", step++);
         } else if (arg[0] != '[') {
             idl_set(idl, arg, step++);
         } else {
diff --git a/tests/test-ovsdb.py b/tests/test-ovsdb.py
index 4e87dbb..31bf1c2 100644
--- a/tests/test-ovsdb.py
+++ b/tests/test-ovsdb.py
@@ -391,6 +391,20 @@  def idl_set(idl, commands, step):
     sys.stdout.flush()
 
 
+def update_condition(idl, commands):
+    commands = commands.split(";")
+    for command in commands:
+        command = command[len("condition "):]
+        command = command.split(" ")
+        if(len(command) != 2):
+            sys.stderr.write("Error parsong condition %s\n" % command)
+            sys.exit(1)
+
+        table = command[0]
+        cond = ovs.json.from_string(command[1])
+        idl.cond_update(table, cond)
+
+
 def do_idl(schema_file, remote, *commands):
     schema_helper = ovs.db.idl.SchemaHelper(schema_file)
     if commands and commands[0].startswith("?"):
@@ -422,6 +436,14 @@  def do_idl(schema_file, remote, *commands):
     symtab = {}
     seqno = 0
     step = 0
+
+    commands = list(commands)
+    if len(commands) >= 1 and "condition" in commands[0]:
+        update_condition(idl, commands.pop(0))
+        sys.stdout.write("%03d: change conditions\n" % step)
+        sys.stdout.flush()
+        step += 1
+
     for command in commands:
         if command.startswith("+"):
             # The previous transaction didn't change anything.
@@ -446,6 +468,11 @@  def do_idl(schema_file, remote, *commands):
             sys.stdout.flush()
             step += 1
             idl.force_reconnect()
+        elif "condition" in command:
+            update_condition(idl, command)
+            sys.stdout.write("%03d: change conditions\n" % step)
+            sys.stdout.flush()
+            step += 1
         elif not command.startswith("["):
             idl_set(idl, command, step)
             step += 1