Add monitor_cond method to ovsdb-client. Add unit tests. See ovsdb-client(1) man page for details. Replace monitor2 with monitor_cond.
Signed-off-by: Liran Schour <lir...@il.ibm.com> --- v2->v3: * Change API of ovsdb-client monitor-cond to minimize code change * Add test for conditions with non-monitored columns --- NEWS | 3 +- lib/ovsdb-idl.c | 28 +++---- ovsdb/jsonrpc-server.c | 14 ++-- ovsdb/jsonrpc-server.h | 2 +- ovsdb/ovsdb-client.1.in | 37 +++++---- ovsdb/ovsdb-client.c | 70 +++++++++++----- ovsdb/ovsdb-server.c | 20 ++--- tests/ovs-vswitchd.at | 8 +- tests/ovsdb-idl.at | 10 +-- tests/ovsdb-monitor.at | 207 ++++++++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 319 insertions(+), 80 deletions(-) diff --git a/NEWS b/NEWS index e683dae..d974802 100644 --- a/NEWS +++ b/NEWS @@ -1,7 +1,8 @@ Post-v2.5.0 --------------------- - ovsdb-server: - * New "monitor2" and "update2" extensions to RFC 7047. + * New "monitor_cond" "monitor_cond_update" and "update2" extensions to + RFC 7047. - OpenFlow: * OpenFlow 1.1+ OFPT_QUEUE_GET_CONFIG_REQUEST now supports OFPP_ANY. * OpenFlow 1.4+ OFPMP_QUEUE_DESC is now supported. diff --git a/lib/ovsdb-idl.c b/lib/ovsdb-idl.c index 7e84138..18d4b8b 100644 --- a/lib/ovsdb-idl.c +++ b/lib/ovsdb-idl.c @@ -79,8 +79,8 @@ enum ovsdb_idl_state { IDL_S_SCHEMA_REQUESTED, IDL_S_MONITOR_REQUESTED, IDL_S_MONITORING, - IDL_S_MONITOR2_REQUESTED, - IDL_S_MONITORING2 + IDL_S_MONITOR_COND_REQUESTED, + IDL_S_MONITORING_COND }; struct ovsdb_idl { @@ -153,7 +153,7 @@ static struct vlog_rate_limit semantic_rl = VLOG_RATE_LIMIT_INIT(1, 5); static void ovsdb_idl_clear(struct ovsdb_idl *); static void ovsdb_idl_send_schema_request(struct ovsdb_idl *); static void ovsdb_idl_send_monitor_request(struct ovsdb_idl *); -static void ovsdb_idl_send_monitor2_request(struct ovsdb_idl *); +static void ovsdb_idl_send_monitor_cond_request(struct ovsdb_idl *); static void ovsdb_idl_parse_update(struct ovsdb_idl *, const struct json *, enum ovsdb_update_version); static struct ovsdb_error *ovsdb_idl_parse_update__(struct ovsdb_idl *, @@ -392,20 +392,20 @@ ovsdb_idl_run(struct ovsdb_idl *idl) case IDL_S_SCHEMA_REQUESTED: /* Reply to our "get_schema" request. */ idl->schema = json_clone(msg->result); - ovsdb_idl_send_monitor2_request(idl); - idl->state = IDL_S_MONITOR2_REQUESTED; + ovsdb_idl_send_monitor_cond_request(idl); + idl->state = IDL_S_MONITOR_COND_REQUESTED; break; case IDL_S_MONITOR_REQUESTED: - case IDL_S_MONITOR2_REQUESTED: - /* Reply to our "monitor" or "monitor2" request. */ + case IDL_S_MONITOR_COND_REQUESTED: + /* Reply to our "monitor" or "monitor_cond" request. */ idl->change_seqno++; ovsdb_idl_clear(idl); if (idl->state == IDL_S_MONITOR_REQUESTED) { idl->state = IDL_S_MONITORING; ovsdb_idl_parse_update(idl, msg->result, OVSDB_UPDATE); - } else { /* IDL_S_MONITOR2_REQUESTED. */ - idl->state = IDL_S_MONITORING2; + } else { /* IDL_S_MONITOR_COND_REQUESTED. */ + idl->state = IDL_S_MONITORING_COND; ovsdb_idl_parse_update(idl, msg->result, OVSDB_UPDATE2); } @@ -416,7 +416,7 @@ ovsdb_idl_run(struct ovsdb_idl *idl) break; case IDL_S_MONITORING: - case IDL_S_MONITORING2: + case IDL_S_MONITORING_COND: default: OVS_NOT_REACHED(); } @@ -442,7 +442,7 @@ ovsdb_idl_run(struct ovsdb_idl *idl) /* Someone else stole our lock. */ ovsdb_idl_parse_lock_notify(idl, msg->params, false); } else if (msg->type == JSONRPC_ERROR - && idl->state == IDL_S_MONITOR2_REQUESTED + && idl->state == IDL_S_MONITOR_COND_REQUESTED && idl->request_id && json_equal(idl->request_id, msg->id)) { if (msg->error && !strcmp(json_string(msg->error), @@ -1012,9 +1012,9 @@ log_parse_update_error(struct ovsdb_error *error) } static void -ovsdb_idl_send_monitor2_request(struct ovsdb_idl *idl) +ovsdb_idl_send_monitor_cond_request(struct ovsdb_idl *idl) { - ovsdb_idl_send_monitor_request__(idl, "monitor2"); + ovsdb_idl_send_monitor_request__(idl, "monitor_cond"); } static void @@ -3033,7 +3033,7 @@ ovsdb_idl_update_has_lock(struct ovsdb_idl *idl, bool new_has_lock) { if (new_has_lock && !idl->has_lock) { if (idl->state == IDL_S_MONITORING || - idl->state == IDL_S_MONITORING2) { + idl->state == IDL_S_MONITORING_COND) { idl->change_seqno++; } else { /* We're setting up a session, so don't signal that the database diff --git a/ovsdb/jsonrpc-server.c b/ovsdb/jsonrpc-server.c index fa5d5c4..cd6a70a 100644 --- a/ovsdb/jsonrpc-server.c +++ b/ovsdb/jsonrpc-server.c @@ -46,9 +46,9 @@ VLOG_DEFINE_THIS_MODULE(ovsdb_jsonrpc_server); struct ovsdb_jsonrpc_remote; struct ovsdb_jsonrpc_session; -/* Set false to defeature monitor2, causing jsonrpc to respond to monitor2 - * method with an error. */ -static bool monitor2_enable__ = true; +/* Set false to defeature monitor_cond, causing jsonrpc to respond to + * monitor_cond method with an error. */ +static bool monitor_cond_enable__ = true; /* Message rate-limiting. */ static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); @@ -850,8 +850,8 @@ ovsdb_jsonrpc_session_got_request(struct ovsdb_jsonrpc_session *s, reply = execute_transaction(s, db, request); } } else if (!strcmp(request->method, "monitor") || - (monitor2_enable__ && !strcmp(request->method, "monitor2")) || - !strcmp(request->method, "monitor_cond")) { + (monitor_cond_enable__ && !strcmp(request->method, + "monitor_cond"))) { struct ovsdb *db = ovsdb_jsonrpc_lookup_db(s, request, &reply); if (!reply) { int l = strlen(request->method) - strlen("monitor"); @@ -1402,8 +1402,8 @@ ovsdb_jsonrpc_monitor_flush_all(struct ovsdb_jsonrpc_session *s) } void -ovsdb_jsonrpc_disable_monitor2(void) +ovsdb_jsonrpc_disable_monitor_cond(void) { /* Once disabled, it is not possible to re-enable it. */ - monitor2_enable__ = false; + monitor_cond_enable__ = false; } diff --git a/ovsdb/jsonrpc-server.h b/ovsdb/jsonrpc-server.h index 7a0bd31..ea50ff6 100644 --- a/ovsdb/jsonrpc-server.h +++ b/ovsdb/jsonrpc-server.h @@ -71,6 +71,6 @@ void ovsdb_jsonrpc_server_get_memory_usage(const struct ovsdb_jsonrpc_server *, struct ovsdb_jsonrpc_monitor; void ovsdb_jsonrpc_monitor_destroy(struct ovsdb_jsonrpc_monitor *); -void ovsdb_jsonrpc_disable_monitor2(void); +void ovsdb_jsonrpc_disable_monitor_cond(void); #endif /* ovsdb/jsonrpc-server.h */ diff --git a/ovsdb/ovsdb-client.1.in b/ovsdb/ovsdb-client.1.in index 5d99f59..8607c6f 100644 --- a/ovsdb/ovsdb-client.1.in +++ b/ovsdb/ovsdb-client.1.in @@ -33,10 +33,8 @@ ovsdb\-client \- command-line interface to \fBovsdb-server\fR(1) .br \fBovsdb\-client \fR[\fIoptions\fR] \fBmonitor\fI \fR[\fIserver\fR] \fR[\fIdatabase\fR] \fBALL\fR .br -\fBovsdb\-client \fR[\fIoptions\fR] \fBmonitor2\fI \fR[\fIserver\fR] \fR[\fIdatabase\fR] \fItable\fR -[\fIcolumn\fR[\fB,\fIcolumn\fR]...]... -.br -\fBovsdb\-client \fR[\fIoptions\fR] \fBmonitor2\fI \fR[\fIserver\fR] \fR[\fIdatabase\fR] \fBALL\fR +\fBovsdb\-client \fR[\fIoptions\fR] \fBmonitor-cond\fI \fR[\fIserver\fR] \fR[\fIdatabase\fR] \fIconditions +\fItable\fR [\fIcolumn\fR[\fB,\fIcolumn\fR]...]... .br \fBovsdb\-client help\fR .IP "Output formatting options:" @@ -113,12 +111,12 @@ specified, only that table is retrieved. If at least one \fIcolumn\fR is specified, only those columns are retrieved. . .IP "\fBmonitor\fI \fR[\fIserver\fR] \fR[\fIdatabase\fR] \fItable\fR [\fIcolumn\fR[\fB,\fIcolumn\fR]...]..." -.IQ "\fBmonitor2\fI \fR[\fIserver\fR] \fR[\fIdatabase\fR] \fItable\fR [\fIcolumn\fR[\fB,\fIcolumn\fR]...]..." -Connects to \fIserver\fR and monitors the contents of \fItable\fR in -\fIdatabase\fR. By default, the initial contents of \fItable\fR are -printed, followed by each change as it occurs. If at least one -\fIcolumn\fR is specified, only those columns are monitored. The -following \fIcolumn\fR names have special meanings: +.IQ "\fBmonitor-cond\fI \fR[\fIserver\fR] \fR[\fIdatabase\fR] \fIconditions\fR \fItable\fR [\fIcolumn\fR[\fB,\fIcolumn\fR]...]..." +Connects to \fIserver\fR and monitors the contents of rows that match conditions in +\fItable\fR in \fIdatabase\fR. By default, the initial contents of \fItable\fR are +printed, followed by each change as it occurs. If conditions emtpy, +all rows will be monitored. If at least one \fIcolumn\fR is specified, only those +columns are monitored. The following \fIcolumn\fR names have special meanings: .RS .IP "\fB!initial\fR" Do not print the initial contents of the specified columns. @@ -136,16 +134,18 @@ each group. Whether multiple groups or only a single group is specified, any given column may only be mentioned once on the command line. .IP -If \fB\-\-detach\fR is used with \fBmonitor\fR or \fBmointor2\fR, then +\fBconditions\fR is a JSON array of <condition> as defined in RFC 7047 5.1 +with the following change: A condition can be either a 3-element JSON array +as deescribed in the RFC or a boolean value.. +.IP +If \fB\-\-detach\fR is used with \fBmonitor\fR or \fBmointor-cond\fR, then \fBovsdb\-client\fR detaches after it has successfully received and printed the initial contents of \fItable\fR. .IP The \fBmonitor\fR command uses RFC 7047 "monitor" method to open a monitor -session with the server. The \fBmonitor2\fR command uses RFC 7047 -extension "monitor2" method. See \fBovsdb\-server\fR(1) for details. -. +session with the server. The \fBmonitor-cond\fR command uses RFC 7047 +extension "monitor_cond" method. See \fBovsdb\-server\fR(1) for details. .IP "\fBmonitor\fI \fR[\fIserver\fR] \fR[\fIdatabase\fR] \fBALL\fR" -.IQ "\fBmonitor2\fI \fR[\fIserver\fR] \fR[\fIdatabase\fR] \fBALL\fR" Connects to \fIserver\fR and monitors the contents of all tables in \fIdatabase\fR. Prints initial values and all kinds of changes to all columns in the database. The \fB\-\-detach\fR option causes @@ -153,8 +153,7 @@ columns in the database. The \fB\-\-detach\fR option causes prints the initial database contents. .IP The \fBmonitor\fR command uses RFC 7047 "monitor" method to open a monitor -session with the server. The \fBmonitor2\fR command uses RFC 7047 -extension "monitor2" method. See \fBovsdb\-server\fR(1) for details. +session with the server. . .SH OPTIONS .SS "Output Formatting Options" @@ -165,13 +164,13 @@ The following options controlling output formatting: .so lib/table.man . .IP "\fB\-\-timestamp\fR" -For the \fBmonitor\fR and \fBmonitor2\fR commands, add a timestamp to each +For the \fBmonitor\fR and \fBmonitor-cond\fR commands, add a timestamp to each table update. Most output formats add the timestamp on a line of its own just above the table. The JSON output format puts the timestamp in a member of the top-level JSON object named \fBtime\fR. . .SS "Daemon Options" -The daemon options apply only to the \fBmonitor\fR and \fBmonitor2\fR commands. +The daemon options apply only to the \fBmonitor\fR and \fBmonitor-cond\fR commands. With any other command, they have no effect. .ds DD .so lib/daemon.man diff --git a/ovsdb/ovsdb-client.c b/ovsdb/ovsdb-client.c index 06155ec..ba2c1c8 100644 --- a/ovsdb/ovsdb-client.c +++ b/ovsdb/ovsdb-client.c @@ -45,6 +45,7 @@ #include "stream-ssl.h" #include "table.h" #include "monitor.h" +#include "condition.h" #include "timeval.h" #include "unixctl.h" #include "util.h" @@ -256,12 +257,14 @@ usage(void) " monitor contents of COLUMNs in TABLE in DATABASE on SERVER.\n" " COLUMNs may include !initial, !insert, !delete, !modify\n" " to avoid seeing the specified kinds of changes.\n" + "\n monitor-cond [SERVER] [DATABASE] CONDITION TABLE [COLUMN,...]...\n" + " monitor contents that match CONDITION of COLUMNs in TABLE in\n" + " DATABASE on SERVER.\n" + " COLUMNs may include !initial, !insert, !delete, !modify\n" + " to avoid seeing the specified kinds of changes.\n" "\n monitor [SERVER] [DATABASE] ALL\n" " monitor all changes to all columns in all tables\n" " in DATBASE on SERVER.\n" - "\n monitor2 [SERVER] [DATABASE] ALL\n" - " same usage as monitor, but uses \"monitor2\" method over" - " the wire." "\n dump [SERVER] [DATABASE]\n" " dump contents of DATABASE on SERVER to stdout\n" "\nThe default SERVER is unix:%s/db.sock.\n" @@ -840,12 +843,13 @@ ovsdb_client_unblock(struct unixctl_conn *conn, int argc OVS_UNUSED, static void add_monitored_table(int argc, char *argv[], const char *server, const char *database, + struct json *condition, struct ovsdb_table_schema *table, struct json *monitor_requests, struct monitored_table **mts, size_t *n_mts, size_t *allocated_mts) { - struct json *monitor_request_array; + struct json *monitor_request_array, *mr; struct monitored_table *mt; if (*n_mts >= *allocated_mts) { @@ -860,19 +864,24 @@ add_monitored_table(int argc, char *argv[], int i; for (i = 1; i < argc; i++) { - json_array_add( - monitor_request_array, - parse_monitor_columns(argv[i], server, database, table, - &mt->columns)); + mr = parse_monitor_columns(argv[i], server, database, table, + &mt->columns); + if (i == 1 && condition) { + json_object_put(mr, "where", condition); + } + json_array_add(monitor_request_array, mr); } } else { /* Allocate a writable empty string since parse_monitor_columns() * is going to strtok() it and that's risky with literal "". */ char empty[] = ""; - json_array_add( - monitor_request_array, - parse_monitor_columns(empty, server, database, - table, &mt->columns)); + + mr = parse_monitor_columns(empty, server, database, + table, &mt->columns); + if (condition) { + json_object_put(mr, "where", condition); + } + json_array_add(monitor_request_array, mr); } json_object_put(monitor_requests, table->name, monitor_request_array); @@ -894,7 +903,7 @@ destroy_monitored_table(struct monitored_table *mts, size_t n) static void do_monitor__(struct jsonrpc *rpc, const char *database, enum ovsdb_monitor_version version, - int argc, char *argv[]) + int argc, char *argv[], struct json *condition) { const char *server = jsonrpc_get_name(rpc); const char *table_name = argv[0]; @@ -945,17 +954,21 @@ do_monitor__(struct jsonrpc *rpc, const char *database, server, database, table_name); } - add_monitored_table(argc, argv, server, database, table, + add_monitored_table(argc, argv, server, database, condition, table, monitor_requests, &mts, &n_mts, &allocated_mts); } else { size_t n = shash_count(&schema->tables); const struct shash_node **nodes = shash_sort(&schema->tables); size_t i; + if (condition) { + ovs_fatal(0, "ALL tables are not allowed with condition"); + } + for (i = 0; i < n; i++) { struct ovsdb_table_schema *table = nodes[i]->data; - add_monitored_table(argc, argv, server, database, table, + add_monitored_table(argc, argv, server, database, NULL, table, monitor_requests, &mts, &n_mts, &allocated_mts); } @@ -964,7 +977,7 @@ do_monitor__(struct jsonrpc *rpc, const char *database, monitor = json_array_create_3(json_string_create(database), json_null_create(), monitor_requests); - const char *method = version == OVSDB_MONITOR_V2 ? "monitor2" + const char *method = version == OVSDB_MONITOR_V2 ? "monitor_cond" : "monitor"; request = jsonrpc_create_request(method, monitor, NULL); @@ -1048,14 +1061,31 @@ static void do_monitor(struct jsonrpc *rpc, const char *database, int argc, char *argv[]) { - do_monitor__(rpc, database, OVSDB_MONITOR_V1, argc, argv); + do_monitor__(rpc, database, OVSDB_MONITOR_V1, argc, argv, NULL); } static void -do_monitor2(struct jsonrpc *rpc, const char *database, +do_monitor_cond(struct jsonrpc *rpc, const char *database, int argc, char *argv[]) { - do_monitor__(rpc, database, OVSDB_MONITOR_V2, argc, argv); + struct ovsdb_condition cnd; + struct json *condition = NULL; + struct ovsdb_schema *schema; + struct ovsdb_table_schema *table; + const char *table_name = argv[1]; + + ovs_assert(argc > 1); + schema = fetch_schema(rpc, database); + table = shash_find_data(&schema->tables, table_name); + if (!table) { + ovs_fatal(0, "%s does not have a table named \"%s\"", + database, table_name); + } + condition = parse_json(argv[0]); + check_ovsdb_error(ovsdb_condition_from_json(table, condition, + NULL, &cnd)); + ovsdb_condition_destroy(&cnd); + do_monitor__(rpc, database, OVSDB_MONITOR_V2, --argc, ++argv, condition); } struct dump_table_aux { @@ -1328,7 +1358,7 @@ static const struct ovsdb_client_command all_commands[] = { { "list-columns", NEED_DATABASE, 0, 1, do_list_columns }, { "transact", NEED_RPC, 1, 1, do_transact }, { "monitor", NEED_DATABASE, 1, INT_MAX, do_monitor }, - { "monitor2", NEED_DATABASE, 1, INT_MAX, do_monitor2 }, + { "monitor-cond", NEED_DATABASE, 2, 3, do_monitor_cond }, { "dump", NEED_DATABASE, 0, INT_MAX, do_dump }, { "help", NEED_NONE, 0, INT_MAX, do_help }, diff --git a/ovsdb/ovsdb-server.c b/ovsdb/ovsdb-server.c index 231ba2f..343fd59 100644 --- a/ovsdb/ovsdb-server.c +++ b/ovsdb/ovsdb-server.c @@ -79,7 +79,7 @@ static unixctl_cb_func ovsdb_server_compact; static unixctl_cb_func ovsdb_server_reconnect; static unixctl_cb_func ovsdb_server_perf_counters_clear; static unixctl_cb_func ovsdb_server_perf_counters_show; -static unixctl_cb_func ovsdb_server_disable_monitor2; +static unixctl_cb_func ovsdb_server_disable_monitor_cond; struct server_config { struct sset *remotes; @@ -332,9 +332,9 @@ main(int argc, char *argv[]) ovsdb_server_perf_counters_clear, NULL); /* Simulate the behavior of OVS release prior to version 2.5 that - * does not support the monitor2 method. */ - unixctl_command_register("ovsdb-server/disable-monitor2", "", 0, 0, - ovsdb_server_disable_monitor2, jsonrpc); + * does not support the monitor_cond method. */ + unixctl_command_register("ovsdb-server/disable-monitor-cond", "", 0, 0, + ovsdb_server_disable_monitor_cond, jsonrpc); main_loop(jsonrpc, &all_dbs, unixctl, &remotes, run_process, &exiting); @@ -1059,16 +1059,18 @@ ovsdb_server_perf_counters_clear(struct unixctl_conn *conn, int argc OVS_UNUSED, unixctl_command_reply(conn, NULL); } -/* "ovsdb-server/disable-monitor2": makes ovsdb-server drop all of its +/* "ovsdb-server/disable-monitor-cond": makes ovsdb-server drop all of its * JSON-RPC connections and reconnect. New sessions will not recognize - * the 'monitor2' method. */ + * the 'monitor_cond' method. */ static void -ovsdb_server_disable_monitor2(struct unixctl_conn *conn, int argc OVS_UNUSED, - const char *argv[] OVS_UNUSED, void *jsonrpc_) +ovsdb_server_disable_monitor_cond(struct unixctl_conn *conn, + int argc OVS_UNUSED, + const char *argv[] OVS_UNUSED, + void *jsonrpc_) { struct ovsdb_jsonrpc_server *jsonrpc = jsonrpc_; - ovsdb_jsonrpc_disable_monitor2(); + ovsdb_jsonrpc_disable_monitor_cond(); ovsdb_jsonrpc_server_reconnect(jsonrpc); unixctl_command_reply(conn, NULL); } diff --git a/tests/ovs-vswitchd.at b/tests/ovs-vswitchd.at index 4245fc4..4d7ecc2 100644 --- a/tests/ovs-vswitchd.at +++ b/tests/ovs-vswitchd.at @@ -165,14 +165,14 @@ OVS_VSWITCHD_STOP(["/Not adding Unix domain socket controller/d"]) AT_CLEANUP dnl ---------------------------------------------------------------------- -dnl OVSDB server before release version 2.5 does not support the monitor2 +dnl OVSDB server before release version 2.5 does not support the monitor_cond dnl method. This test defeatures the OVSDB server to simulate an older dnl OVSDB server and make sure ovs-vswitchd can still work with it -AT_SETUP([ovs-vswitchd -- Compatible with OVSDB server - w/o monitor2]) +AT_SETUP([ovs-vswitchd -- Compatible with OVSDB server - w/o monitor_cond]) OVS_VSWITCHD_START -dnl defeature OVSDB server -- no monitor2 -AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/disable-monitor2]) +dnl defeature OVSDB server -- no monitor_cond +AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/disable-monitor-cond]) sleep 1 diff --git a/tests/ovsdb-idl.at b/tests/ovsdb-idl.at index ebf82a5..4baac46 100644 --- a/tests/ovsdb-idl.at +++ b/tests/ovsdb-idl.at @@ -588,13 +588,13 @@ test-ovsdb|ovsdb_idl|link1 table in idltest database lacks l2 column (database n # Check that ovsdb-idl sent on "monitor" request and that it didn't # mention that table or column, and (for paranoia) that it did mention another # table and column. -AT_CHECK([grep -c '"monitor\|monitor2"' stderr], [0], [1 +AT_CHECK([grep -c '"monitor\|monitor_cond"' stderr], [0], [1 ]) -AT_CHECK([grep '"monitor\|monitor2"' stderr | grep link2], [1]) -AT_CHECK([grep '"monitor\|monitor2"' stderr | grep l2], [1]) -AT_CHECK([grep '"monitor\|monitor2"' stderr | grep -c '"link1"'], [0], [1 +AT_CHECK([grep '"monitor\|monitor_cond"' stderr | grep link2], [1]) +AT_CHECK([grep '"monitor\|monitor_cond"' stderr | grep l2], [1]) +AT_CHECK([grep '"monitor\|monitor_cond"' stderr | grep -c '"link1"'], [0], [1 ]) -AT_CHECK([grep '"monitor\|monitor2"' stderr | grep -c '"ua"'], [0], [1 +AT_CHECK([grep '"monitor\|monitor_cond"' stderr | grep -c '"ua"'], [0], [1 ]) OVSDB_SERVER_SHUTDOWN AT_CLEANUP diff --git a/tests/ovsdb-monitor.at b/tests/ovsdb-monitor.at index 0dbf5b0..ea57dfa 100644 --- a/tests/ovsdb-monitor.at +++ b/tests/ovsdb-monitor.at @@ -44,6 +44,50 @@ m4_define([OVSDB_CHECK_MONITOR], AT_CHECK([${PERL} $srcdir/ovsdb-monitor-sort.pl < output | ${PERL} $srcdir/uuidfilt.pl], [0], [$7], [ignore]) AT_CLEANUP]) +# OVSDB_CHECK_MONITOR_COND(TITLE, SCHEMA, [PRE-MONITOR-TXN], DB, TABLE, +# TRANSACTIONS, OUTPUT, CONDITIONS, [COLUMNS], [KEYWORDS]) +# +# Creates a database with the given SCHEMA, starts an ovsdb-server on +# that database, and runs each of the TRANSACTIONS (which should be a +# quoted list of quoted strings) against it with ovsdb-client one at a +# time. COLUMNS, if specified, is passed to ovsdb-client as the set +# of columns and operations to select. +# +# Checks that the overall output is OUTPUT, but UUIDs in the output +# are replaced by markers of the form <N> where N is a number. The +# first unique UUID is replaced by <0>, the next by <1>, and so on. +# If a given UUID appears more than once it is always replaced by the +# same marker. +# +# TITLE is provided to AT_SETUP and KEYWORDS to AT_KEYWORDS. +m4_define([OVSDB_CHECK_MONITOR_COND], + [AT_SETUP([$1]) + AT_KEYWORDS([ovsdb server monitor monitor-cond positive $10]) + $2 > schema + AT_CHECK([ovsdb-tool create db schema], [0], [stdout], [ignore]) + m4_foreach([txn], [$3], + [AT_CHECK([ovsdb-tool transact db 'txn'], [0], [ignore], [ignore])]) + AT_CAPTURE_FILE([ovsdb-server-log]) + AT_CHECK([ovsdb-server --detach --no-chdir --pidfile="`pwd`"/server-pid --remote=punix:socket --unixctl="`pwd`"/unixctl --log-file="`pwd`"/ovsdb-server-log db >/dev/null 2>&1], + [0], [], []) + if test "$IS_WIN32" = "yes"; then + AT_CHECK([ovsdb-client -vjsonrpc --pidfile="`pwd`"/client-pid -d json monitor-cond --format=csv unix:socket $4 '[$8]' $5 $9 > output &], + [0], [ignore], [ignore], [kill `cat server-pid`]) + sleep 1 + else + AT_CHECK([ ovsdb-client -vjsonrpc --detach --no-chdir --pidfile="`pwd`"/client-pid -d json monitor-cond --format=csv unix:socket $4 '[$8]' $5 $9 > output], + [0], [ignore], [ignore], [kill `cat server-pid`]) + fi + m4_foreach([txn], [$6], + [AT_CHECK([ovsdb-client transact unix:socket 'txn'], [0], + [ignore], [ignore], [kill `cat server-pid client-pid`])]) + AT_CHECK([ovsdb-client transact unix:socket '[["$4"]]'], [0], + [ignore], [ignore], [kill `cat server-pid client-pid`]) + AT_CHECK([ovs-appctl -t "`pwd`"/unixctl -e exit], [0], [ignore], [ignore]) + OVS_WAIT_UNTIL([test ! -e server-pid && test ! -e client-pid]) + AT_CHECK([${PERL} $srcdir/ovsdb-monitor-sort.pl < output | ${PERL} $srcdir/uuidfilt.pl], [0], [$7], [ignore]) + AT_CLEANUP]) + OVSDB_CHECK_MONITOR([monitor insert into empty table], [ordinal_schema], [], @@ -322,3 +366,166 @@ OVSDB_CHECK_MONITOR([monitor modify only], <0>,old,"""five""",,"[""uuid"",""<1>""]" ,new,"""FIVE""",5,"[""uuid"",""<2>""]" ]], [!initial,!insert,!delete]) + +AT_BANNER([ovsdb -- ovsdb-monitor-cond conditional monitor only some operations]) + +OVSDB_CHECK_MONITOR_COND([monitor-cond empty condition], + [ordinal_schema], + [[[["ordinals", + {"op": "insert", + "table": "ordinals", + "row": {"number": 0, "name": "zero"}}, + {"op": "insert", + "table": "ordinals", + "row": {"number": 1, "name": "one"}}, + {"op": "insert", + "table": "ordinals", + "row": {"number": 2, "name": "two"}}]]]], + [ordinals], [ordinals], + [[[["ordinals", + {"op": "insert", + "table": "ordinals", + "row": {"number": 10, "name": "ten"}}, + {"op": "insert", + "table": "ordinals", + "row": {"number": 11, "name": "eleven"}}]]]], + [[row,action,name,number,_version +<0>,initial,"""one""",1,"[""uuid"",""<1>""]" +<2>,initial,"""two""",2,"[""uuid"",""<3>""]" +<4>,initial,"""zero""",,"[""uuid"",""<5>""]" + +row,action,name,number,_version +<6>,insert,"""eleven""",11,"[""uuid"",""<7>""]" +<8>,insert,"""ten""",10,"[""uuid"",""<9>""]" +]], + [[]]) + +OVSDB_CHECK_MONITOR_COND([monitor-cond multiple conditions], + [ordinal_schema], + [[[["ordinals", + {"op": "insert", + "table": "ordinals", + "row": {"number": 0, "name": "zero"}}, + {"op": "insert", + "table": "ordinals", + "row": {"number": 1, "name": "one"}}, + {"op": "insert", + "table": "ordinals", + "row": {"number": 2, "name": "two"}}]]]], + [ordinals], [ordinals], + [[[["ordinals", + {"op": "insert", + "table": "ordinals", + "row": {"number": 10, "name": "ten"}}, + {"op": "insert", + "table": "ordinals", + "row": {"number": 11, "name": "eleven"}}]]]], + [[row,action,name,number,_version +<0>,initial,"""one""",1,"[""uuid"",""<1>""]" + +row,action,name,number,_version +<2>,insert,"""ten""",10,"[""uuid"",""<3>""]" +]], + [[["name","==","one"],["name","==","ten"]]]) + +OVSDB_CHECK_MONITOR_COND([monitor-cond delete from populated table], + [ordinal_schema], + [[[["ordinals", + {"op": "insert", + "table": "ordinals", + "row": {"number": 0, "name": "zero"}}, + {"op": "insert", + "table": "ordinals", + "row": {"number": 1, "name": "one"}}, + {"op": "insert", + "table": "ordinals", + "row": {"number": 2, "name": "two"}}]]]], + [ordinals], [ordinals], + [[[["ordinals", + {"op": "delete", + "table": "ordinals", + "where": []}]]]], + [[row,action,name,number,_version +<0>,initial,"""one""",1,"[""uuid"",""<1>""]" + +row,action,name,number,_version +<0>,delete,,, +]], + [[["name","==","one"],["name","==","ten"]]]) + +OVSDB_CHECK_MONITOR_COND([monitor-cond insert due to modify], + [ordinal_schema], + [[[["ordinals", + {"op": "insert", + "table": "ordinals", + "row": {"number": 0, "name": "zero"}}, + {"op": "insert", + "table": "ordinals", + "row": {"number": 1, "name": "one"}}, + {"op": "insert", + "table": "ordinals", + "row": {"number": 2, "name": "two"}}]]]], + [ordinals], [ordinals], + [[[["ordinals", + {"op": "update", + "table": "ordinals", + "where": [["name", "==", "one"]], + "row": {"name": "ONE"}}]]]], + [[row,action,name,number,_version +<0>,insert,"""ONE""",1,"[""uuid"",""<1>""]" +]], + [[["name","==","ONE"]]], + [!initial,!delete,!modify]) + +OVSDB_CHECK_MONITOR_COND([monitor-cond delete due to modify], + [ordinal_schema], + [[[["ordinals", + {"op": "insert", + "table": "ordinals", + "row": {"number": 0, "name": "zero"}}, + {"op": "insert", + "table": "ordinals", + "row": {"number": 1, "name": "one"}}, + {"op": "insert", + "table": "ordinals", + "row": {"number": 2, "name": "two"}}]]]], + [ordinals], [ordinals], + [[[["ordinals", + {"op": "update", + "table": "ordinals", + "where": [["name", "==", "one"]], + "row": {"name": "ONE"}}]]]], + [[row,action,name,number,_version +<0>,delete,,, +]], + [[["name","==","one"]]], + [!initial,!insert,!modify]) + +OVSDB_CHECK_MONITOR_COND([monitor-cond condition non-monitored columns], + [ordinal_schema], + [[[["ordinals", + {"op": "insert", + "table": "ordinals", + "row": {"number": 0, "name": "zero"}}, + {"op": "insert", + "table": "ordinals", + "row": {"number": 1, "name": "one"}}, + {"op": "insert", + "table": "ordinals", + "row": {"number": 2, "name": "two"}}]]]], + [ordinals], [ordinals], + [[[["ordinals", + {"op": "insert", + "table": "ordinals", + "row": {"number": 10, "name": "ten"}}, + {"op": "insert", + "table": "ordinals", + "row": {"number": 11, "name": "eleven"}}]]]], + [[row,action,number +<0>,initial,1 + +row,action,number +<1>,insert,10 +]], + [[["name","==","one"],["name","==","ten"]]], + ["number"]) -- 2.1.4 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev