diff options
author | Liran Schour <lirans@il.ibm.com> | 2016-07-18 11:45:58 +0300 |
---|---|---|
committer | Ben Pfaff <blp@ovn.org> | 2016-07-18 22:58:45 -0700 |
commit | 16ebb90e05cad5a3013cadd5b4249fac93935447 (patch) | |
tree | 51a4b956d8f75bcf2cfecd81d951edaa76ece82c /tests | |
parent | 897c8064f55c180a7cbaec75cc2ba7fb48031d17 (diff) | |
download | openvswitch-16ebb90e05cad5a3013cadd5b4249fac93935447.tar.gz |
lib: add monitor_cond_change API to C IDL lib
Add to IDL API that allows the user to add and remove clauses on a table's condition
iteratively. IDL maintain tables condition and send monitor_cond_change to the server
upon condition change.
Add tests for conditional monitoring to IDL.
Signed-off-by: Liran Schour <lirans@il.ibm.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/ovsdb-idl.at | 136 | ||||
-rw-r--r-- | tests/test-ovsdb.c | 214 | ||||
-rw-r--r-- | tests/test-ovsdb.py | 35 |
3 files changed, 384 insertions, 1 deletions
diff --git a/tests/ovsdb-idl.at b/tests/ovsdb-idl.at index 63008b3df..5d9bb81c1 100644 --- a/tests/ovsdb-idl.at +++ b/tests/ovsdb-idl.at @@ -389,6 +389,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 add simple [false]' \ + 'condition remove simple [false]']], + [[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 add simple [false]' \ + 'condition add 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 add simple [false]' \ + 'condition add 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 add simple [false]' \ + 'condition add 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 add simple [false]' \ + 'condition add simple [["i","==",1],["i","==",2]]' \ + 'condition remove simple [["i","==",1]]' \ + '["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 add simple [false];condition add link1 [false];condition add link2 [false]' \ + 'condition add simple [["i","==",1]]' \ + 'condition add link1 [["i","==",0]]' \ + 'condition add 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 74b76afc2..6357c9cd4 100644 --- a/tests/test-ovsdb.c +++ b/tests/test-ovsdb.c @@ -2145,6 +2145,208 @@ 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 *idl, bool add_cmd, + struct json *json) +{ + const char *c; + struct ovsdb_error *error; + enum ovsdb_function function; + + if (json->type == JSON_TRUE) { + add_cmd ? idltest_simple_add_clause_true(idl) : + idltest_simple_remove_clause_true(idl); + return; + } else if (json->type == JSON_FALSE) { + add_cmd ? idltest_simple_add_clause_false(idl) : + idltest_simple_remove_clause_false(idl); + 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_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")) { + add_cmd ? idltest_simple_add_clause_b(idl, function, + json_boolean(json->u.array.elems[2])) : + idltest_simple_remove_clause_b(idl, function, + json_boolean(json->u.array.elems[2])); + } else if (!strcmp(c, "i")) { + add_cmd ? idltest_simple_add_clause_i(idl, function, + json_integer(json->u.array.elems[2])) : + idltest_simple_remove_clause_i(idl, function, + json_integer(json->u.array.elems[2])); + } else if (!strcmp(c, "s")) { + add_cmd ? idltest_simple_add_clause_s(idl, function, + json_string(json->u.array.elems[2])) : + idltest_simple_remove_clause_s(idl, 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])); + } + add_cmd ? idltest_simple_add_clause_u(idl, function, uuid) : + idltest_simple_remove_clause_u(idl, function, uuid); + } else if (!strcmp(c, "r")) { + add_cmd ? idltest_simple_add_clause_r(idl, function, + json_real(json->u.array.elems[2])) : + idltest_simple_remove_clause_r(idl, 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 *idl, bool add_cmd, + struct json *json) +{ + const char *c; + struct ovsdb_error *error; + enum ovsdb_function function; + + if (json->type == JSON_TRUE) { + add_cmd ? idltest_link1_add_clause_true(idl) : + idltest_link1_remove_clause_true(idl); + return; + } else if (json->type == JSON_FALSE) { + add_cmd ? idltest_link1_add_clause_false(idl) : + idltest_link1_remove_clause_false(idl); + 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_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")) { + add_cmd ? idltest_link1_add_clause_i(idl, function, + json_integer(json->u.array.elems[2])) : + idltest_link1_remove_clause_i(idl, 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 *idl, bool add_cmd, struct json *json) +{ + const char *c; + struct ovsdb_error *error; + enum ovsdb_function function; + + if (json->type == JSON_TRUE) { + add_cmd ? idltest_link2_add_clause_true(idl) : + idltest_link2_remove_clause_true(idl); + return; + } else if (json->type == JSON_FALSE) { + add_cmd ? idltest_link2_add_clause_false(idl) : + idltest_link2_remove_clause_false(idl); + 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_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")) { + add_cmd ? idltest_link2_add_clause_i(idl, function, + json_integer(json->u.array.elems[2])) : + idltest_link2_remove_clause_i(idl, 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; + bool add_cmd = false; + + for (cmd = strtok_r(commands, ";", &save_ptr1); cmd; + cmd = strtok_r(NULL, ";", &save_ptr1)) { + if (strstr(cmd, "condition add")) { + cmd += strlen("condition add "); + add_cmd = true; + } else if (strstr(cmd, "condition remove")) { + cmd += strlen("condition remove "); + } else { + ovs_fatal(0, "condition command should be add or remove"); + } + + char *save_ptr2 = NULL; + char *table_name = strtok_r(cmd, " ", &save_ptr2); + struct json *json = parse_json(save_ptr2); + 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_reset(idl, tc); + + for (i = 0; i < json->u.array.n; i++) { + if (!strcmp(table_name, "simple")) { + parse_simple_json_clause(idl, add_cmd, json->u.array.elems[i]); + } else if (!strcmp(table_name, "link1")) { + parse_link1_json_clause(idl, add_cmd, json->u.array.elems[i]); + } else if (!strcmp(table_name, "link2")) { + parse_link2_json_clause(idl, add_cmd, json->u.array.elems[i]); + } + } + } +} + static void do_idl(struct ovs_cmdl_context *ctx) { @@ -2183,7 +2385,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; @@ -2217,6 +2426,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 42d36d4b9..83fe4af36 100644 --- a/tests/test-ovsdb.py +++ b/tests/test-ovsdb.py @@ -391,6 +391,28 @@ 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 "):] + if "add" in command: + add_cmd = True + command = command[len("add "):] + else: + add_cmd = False + command = command[len("remove "):] + + 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_change(table, add_cmd, cond) + + def do_idl(schema_file, remote, *commands): schema_helper = ovs.db.idl.SchemaHelper(schema_file) if commands and commands[0].startswith("?"): @@ -422,6 +444,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 +476,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 |