X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=tests%2Ftest-ovsdb.c;h=ede792262e443c8fe5ee108c799e9511065650fa;hb=ff8decf1a318b4a611cb08bb3f12833044e8a872;hp=fb13df9c3dcf890021dad237683539b0207ab6e5;hpb=e9011ac83235d37c8c05efee1a200f0879080187;p=openvswitch diff --git a/tests/test-ovsdb.c b/tests/test-ovsdb.c index fb13df9c..ede79226 100644 --- a/tests/test-ovsdb.c +++ b/tests/test-ovsdb.c @@ -34,6 +34,7 @@ #include "ovsdb/condition.h" #include "ovsdb/file.h" #include "ovsdb/log.h" +#include "ovsdb/mutation.h" #include "ovsdb/ovsdb.h" #include "ovsdb/query.h" #include "ovsdb/row.h" @@ -141,6 +142,10 @@ usage(void) " parse each CONDITION on TABLE, and re-serialize\n" " evaluate-conditions TABLE [CONDITION,...] [ROW,...]\n" " test CONDITIONS on TABLE against each ROW, print results\n" + " parse-mutations TABLE MUTATION...\n" + " parse each MUTATION on TABLE, and re-serialize\n" + " execute-mutations TABLE [MUTATION,...] [ROW,...]\n" + " execute MUTATIONS on TABLE on each ROW, print results\n" " query TABLE [ROW,...] [CONDITION,...]\n" " add each ROW to TABLE, then query and print the rows that\n" " satisfy each CONDITION.\n" @@ -210,6 +215,15 @@ print_and_free_json(struct json *json) free(string); } +static void +print_and_free_ovsdb_error(struct ovsdb_error *error) +{ + char *string = ovsdb_error_to_string(error); + ovsdb_error_destroy(error); + puts(string); + free(string); +} + static void check_ovsdb_error(struct ovsdb_error *error) { @@ -657,6 +671,135 @@ do_evaluate_conditions(int argc UNUSED, char *argv[]) ovsdb_table_destroy(table); /* Also destroys 'ts'. */ } +static void +do_parse_mutations(int argc, char *argv[]) +{ + struct ovsdb_table_schema *ts; + struct json *json; + int exit_code = 0; + int i; + + json = unbox_json(parse_json(argv[1])); + check_ovsdb_error(ovsdb_table_schema_from_json(json, "mytable", &ts)); + json_destroy(json); + + for (i = 2; i < argc; i++) { + struct ovsdb_mutation_set set; + struct ovsdb_error *error; + + json = parse_json(argv[i]); + error = ovsdb_mutation_set_from_json(ts, json, NULL, &set); + if (!error) { + print_and_free_json(ovsdb_mutation_set_to_json(&set)); + } else { + char *s = ovsdb_error_to_string(error); + ovs_error(0, "%s", s); + free(s); + ovsdb_error_destroy(error); + exit_code = 1; + } + json_destroy(json); + + ovsdb_mutation_set_destroy(&set); + } + ovsdb_table_schema_destroy(ts); + + exit(exit_code); +} + +static void +do_execute_mutations(int argc UNUSED, char *argv[]) +{ + struct ovsdb_table_schema *ts; + struct ovsdb_table *table; + struct ovsdb_mutation_set *sets; + size_t n_sets; + struct ovsdb_row **rows; + size_t n_rows; + struct json *json; + size_t i, j; + + /* Parse table schema, create table. */ + json = unbox_json(parse_json(argv[1])); + check_ovsdb_error(ovsdb_table_schema_from_json(json, "mytable", &ts)); + json_destroy(json); + + table = ovsdb_table_create(ts); + + /* Parse mutations. */ + json = parse_json(argv[2]); + if (json->type != JSON_ARRAY) { + ovs_fatal(0, "MUTATION argument is not JSON array"); + } + n_sets = json->u.array.n; + sets = xmalloc(n_sets * sizeof *sets); + for (i = 0; i < n_sets; i++) { + check_ovsdb_error(ovsdb_mutation_set_from_json(ts, + json->u.array.elems[i], + NULL, &sets[i])); + } + json_destroy(json); + + /* Parse rows. */ + json = parse_json(argv[3]); + if (json->type != JSON_ARRAY) { + ovs_fatal(0, "ROW argument is not JSON array"); + } + n_rows = json->u.array.n; + rows = xmalloc(n_rows * sizeof *rows); + for (i = 0; i < n_rows; i++) { + rows[i] = ovsdb_row_create(table); + check_ovsdb_error(ovsdb_row_from_json(rows[i], json->u.array.elems[i], + NULL, NULL)); + } + json_destroy(json); + + for (i = 0; i < n_sets; i++) { + printf("mutation %2d:\n", i); + for (j = 0; j < n_rows; j++) { + struct ovsdb_error *error; + struct ovsdb_row *row; + + row = ovsdb_row_clone(rows[j]); + error = ovsdb_mutation_set_execute(row, &sets[i]); + + printf("row %zu: ", j); + if (error) { + print_and_free_ovsdb_error(error); + } else { + struct ovsdb_column_set columns; + struct shash_node *node; + + ovsdb_column_set_init(&columns); + SHASH_FOR_EACH (node, &ts->columns) { + struct ovsdb_column *c = node->data; + if (!ovsdb_datum_equals(&row->fields[c->index], + &rows[j]->fields[c->index], + &c->type)) { + ovsdb_column_set_add(&columns, c); + } + } + if (columns.n_columns) { + print_and_free_json(ovsdb_row_to_json(row, &columns)); + } else { + printf("no change\n"); + } + ovsdb_column_set_destroy(&columns); + } + ovsdb_row_destroy(row); + } + printf("\n"); + } + + for (i = 0; i < n_sets; i++) { + ovsdb_mutation_set_destroy(&sets[i]); + } + for (i = 0; i < n_rows; i++) { + ovsdb_row_destroy(rows[i]); + } + ovsdb_table_destroy(table); /* Also destroys 'ts'. */ +} + struct do_query_cbdata { struct uuid *row_uuids; int *counts; @@ -791,7 +934,7 @@ do_query_distinct(int argc UNUSED, char *argv[]) /* Parse column set. */ json = parse_json(argv[4]); - ovsdb_column_set_from_json(json, table, &columns); + check_ovsdb_error(ovsdb_column_set_from_json(json, table, &columns)); json_destroy(json); /* Parse rows, add to table. */ @@ -1346,7 +1489,8 @@ parse_uuids(const struct json *json, struct ovsdb_symbol_table *symtab, if (json->type == JSON_STRING && uuid_from_string(&uuid, json->u.string)) { char *name = xasprintf("#%d#", *n); - ovsdb_symbol_table_put(symtab, name, &uuid); + fprintf(stderr, "%s = "UUID_FMT"\n", name, UUID_ARGS(&uuid)); + ovsdb_symbol_table_put(symtab, name, &uuid, false); free(name); *n += 1; } else if (json->type == JSON_ARRAY) { @@ -1368,12 +1512,12 @@ static void substitute_uuids(struct json *json, const struct ovsdb_symbol_table *symtab) { if (json->type == JSON_STRING) { - const struct uuid *uuid; + const struct ovsdb_symbol *symbol; - uuid = ovsdb_symbol_table_get(symtab, json->u.string); - if (uuid) { + symbol = ovsdb_symbol_table_get(symtab, json->u.string); + if (symbol) { free(json->u.string); - json->u.string = xasprintf(UUID_FMT, UUID_ARGS(uuid)); + json->u.string = xasprintf(UUID_FMT, UUID_ARGS(&symbol->uuid)); } } else if (json->type == JSON_ARRAY) { size_t i; @@ -1390,6 +1534,114 @@ substitute_uuids(struct json *json, const struct ovsdb_symbol_table *symtab) } } +static const struct idltest_simple * +idltest_find_simple(struct ovsdb_idl *idl, int i) +{ + const struct idltest_simple *s; + + IDLTEST_SIMPLE_FOR_EACH (s, idl) { + if (s->i == i) { + return s; + } + } + return NULL; +} + +static void +idl_set(struct ovsdb_idl *idl, char *commands, int step) +{ + char *cmd, *save_ptr1 = NULL; + struct ovsdb_idl_txn *txn; + enum ovsdb_idl_txn_status status; + bool increment = false; + + txn = ovsdb_idl_txn_create(idl); + for (cmd = strtok_r(commands, ",", &save_ptr1); cmd; + cmd = strtok_r(NULL, ",", &save_ptr1)) { + char *save_ptr2 = NULL; + char *name, *arg1, *arg2, *arg3; + + name = strtok_r(cmd, " ", &save_ptr2); + arg1 = strtok_r(NULL, " ", &save_ptr2); + arg2 = strtok_r(NULL, " ", &save_ptr2); + arg3 = strtok_r(NULL, " ", &save_ptr2); + + if (!strcmp(name, "set")) { + const struct idltest_simple *s; + + if (!arg3) { + ovs_fatal(0, "\"set\" command requires 3 arguments"); + } + + s = idltest_find_simple(idl, atoi(arg1)); + if (!s) { + ovs_fatal(0, "\"set\" command asks for nonexistent " + "i=%d", atoi(arg1)); + } + + if (!strcmp(arg2, "b")) { + idltest_simple_set_b(s, atoi(arg3)); + } else if (!strcmp(arg2, "s")) { + idltest_simple_set_s(s, arg3); + } else if (!strcmp(arg2, "u")) { + struct uuid uuid; + uuid_from_string(&uuid, arg3); + idltest_simple_set_u(s, uuid); + } else if (!strcmp(arg2, "r")) { + idltest_simple_set_r(s, atof(arg3)); + } else { + ovs_fatal(0, "\"set\" command asks for unknown column %s", + arg2); + } + } else if (!strcmp(name, "insert")) { + struct idltest_simple *s; + + if (!arg1 || arg2) { + ovs_fatal(0, "\"set\" command requires 1 argument"); + } + + s = idltest_simple_insert(txn); + idltest_simple_set_i(s, atoi(arg1)); + } else if (!strcmp(name, "delete")) { + const struct idltest_simple *s; + + if (!arg1 || arg2) { + ovs_fatal(0, "\"set\" command requires 1 argument"); + } + + s = idltest_find_simple(idl, atoi(arg1)); + if (!s) { + ovs_fatal(0, "\"set\" command asks for nonexistent " + "i=%d", atoi(arg1)); + } + idltest_simple_delete(s); + } else if (!strcmp(name, "increment")) { + if (!arg2 || arg3) { + ovs_fatal(0, "\"set\" command requires 2 arguments"); + } + ovsdb_idl_txn_increment(txn, arg1, arg2, NULL); + increment = true; + } else { + ovs_fatal(0, "unknown command %s", name); + } + } + + while ((status = ovsdb_idl_txn_commit(txn)) == TXN_INCOMPLETE) { + ovsdb_idl_run(idl); + ovsdb_idl_wait(idl); + ovsdb_idl_txn_wait(txn); + poll_block(); + } + printf("%03d: commit, status=%s", + step, ovsdb_idl_txn_status_to_string(status)); + if (increment) { + printf(", increment=%"PRId64, + ovsdb_idl_txn_get_increment_new_value(txn)); + } + putchar('\n'); + ovsdb_idl_txn_destroy(txn); +} + static void do_idl(int argc, char *argv[]) { @@ -1425,6 +1677,8 @@ do_idl(int argc, char *argv[]) if (!strcmp(argv[i], "reconnect")) { printf("%03d: reconnect\n", step++); ovsdb_idl_force_reconnect(idl); + } else if (argv[i][0] != '[') { + idl_set(idl, argv[i], step++); } else { struct json *json = parse_json(argv[i]); substitute_uuids(json, symtab); @@ -1465,6 +1719,8 @@ static struct command all_commands[] = { { "compare-rows", 2, INT_MAX, do_compare_rows }, { "parse-conditions", 2, INT_MAX, do_parse_conditions }, { "evaluate-conditions", 3, 3, do_evaluate_conditions }, + { "parse-mutations", 2, INT_MAX, do_parse_mutations }, + { "execute-mutations", 3, 3, do_execute_mutations }, { "query", 3, 3, do_query }, { "query-distinct", 4, 4, do_query_distinct }, { "transact", 1, INT_MAX, do_transact },