LCOV - code coverage report
Current view: top level - tests - test-ovsdb.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1266 1396 90.7 %
Date: 2016-09-14 01:02:56 Functions: 82 84 97.6 %
Branches: 472 610 77.4 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2015, 2016 Nicira, Inc.
       3                 :            :  *
       4                 :            :  * Licensed under the Apache License, Version 2.0 (the "License");
       5                 :            :  * you may not use this file except in compliance with the License.
       6                 :            :  * You may obtain a copy of the License at:
       7                 :            :  *
       8                 :            :  *     http://www.apache.org/licenses/LICENSE-2.0
       9                 :            :  *
      10                 :            :  * Unless required by applicable law or agreed to in writing, software
      11                 :            :  * distributed under the License is distributed on an "AS IS" BASIS,
      12                 :            :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      13                 :            :  * See the License for the specific language governing permissions and
      14                 :            :  * limitations under the License.
      15                 :            :  */
      16                 :            : 
      17                 :            : #include <config.h>
      18                 :            : 
      19                 :            : #include <assert.h>
      20                 :            : #include <fcntl.h>
      21                 :            : #include <getopt.h>
      22                 :            : #include <inttypes.h>
      23                 :            : #include <stdio.h>
      24                 :            : #include <stdlib.h>
      25                 :            : 
      26                 :            : #include "byte-order.h"
      27                 :            : #include "command-line.h"
      28                 :            : #include "openvswitch/dynamic-string.h"
      29                 :            : #include "openvswitch/json.h"
      30                 :            : #include "jsonrpc.h"
      31                 :            : #include "ovsdb-data.h"
      32                 :            : #include "ovsdb-error.h"
      33                 :            : #include "ovsdb-idl.h"
      34                 :            : #include "ovsdb-types.h"
      35                 :            : #include "ovsdb/column.h"
      36                 :            : #include "ovsdb/condition.h"
      37                 :            : #include "ovsdb/file.h"
      38                 :            : #include "ovsdb/log.h"
      39                 :            : #include "ovsdb/mutation.h"
      40                 :            : #include "ovsdb/ovsdb.h"
      41                 :            : #include "ovsdb/query.h"
      42                 :            : #include "ovsdb/row.h"
      43                 :            : #include "ovsdb/server.h"
      44                 :            : #include "ovsdb/table.h"
      45                 :            : #include "ovsdb/transaction.h"
      46                 :            : #include "ovsdb/trigger.h"
      47                 :            : #include "poll-loop.h"
      48                 :            : #include "stream.h"
      49                 :            : #include "svec.h"
      50                 :            : #include "tests/idltest.h"
      51                 :            : #include "timeval.h"
      52                 :            : #include "util.h"
      53                 :            : #include "openvswitch/vlog.h"
      54                 :            : 
      55                 :            : struct test_ovsdb_pvt_context {
      56                 :            :     bool track;
      57                 :            : };
      58                 :            : 
      59                 :            : OVS_NO_RETURN static void usage(void);
      60                 :            : static void parse_options(int argc, char *argv[],
      61                 :            :     struct test_ovsdb_pvt_context *pvt);
      62                 :            : static struct ovs_cmdl_command *get_all_commands(void);
      63                 :            : 
      64                 :            : int
      65                 :        326 : main(int argc, char *argv[])
      66                 :            : {
      67                 :        326 :     struct test_ovsdb_pvt_context pvt = {.track = false};
      68                 :        326 :     struct ovs_cmdl_context ctx = { .argc = 0, .pvt = &pvt};
      69                 :        326 :     set_program_name(argv[0]);
      70                 :        326 :     parse_options(argc, argv, &pvt);
      71                 :        326 :     ctx.argc = argc - optind;
      72                 :        326 :     ctx.argv = argv + optind;
      73                 :        326 :     ovs_cmdl_run_command(&ctx, get_all_commands());
      74                 :        261 :     return 0;
      75                 :            : }
      76                 :            : 
      77                 :            : static void
      78                 :        326 : parse_options(int argc, char *argv[], struct test_ovsdb_pvt_context *pvt)
      79                 :            : {
      80                 :            :     static const struct option long_options[] = {
      81                 :            :         {"timeout", required_argument, NULL, 't'},
      82                 :            :         {"verbose", optional_argument, NULL, 'v'},
      83                 :            :         {"change-track", optional_argument, NULL, 'c'},
      84                 :            :         {"help", no_argument, NULL, 'h'},
      85                 :            :         {NULL, 0, NULL, 0},
      86                 :            :     };
      87                 :        326 :     char *short_options = ovs_cmdl_long_options_to_short_options(long_options);
      88                 :            : 
      89                 :            :     for (;;) {
      90                 :            :         unsigned long int timeout;
      91                 :            :         int c;
      92                 :            : 
      93                 :        399 :         c = getopt_long(argc, argv, short_options, long_options, NULL);
      94         [ +  + ]:        399 :         if (c == -1) {
      95                 :        326 :             break;
      96                 :            :         }
      97                 :            : 
      98   [ +  -  +  +  :         73 :         switch (c) {
                   -  - ]
      99                 :            :         case 't':
     100                 :         23 :             timeout = strtoul(optarg, NULL, 10);
     101         [ -  + ]:         23 :             if (timeout <= 0) {
     102                 :          0 :                 ovs_fatal(0, "value %s on -t or --timeout is not at least 1",
     103                 :            :                           optarg);
     104                 :            :             } else {
     105                 :         23 :                 time_alarm(timeout);
     106                 :            :             }
     107                 :         23 :             break;
     108                 :            : 
     109                 :            :         case 'h':
     110                 :          0 :             usage();
     111                 :            : 
     112                 :            :         case 'v':
     113                 :         46 :             vlog_set_verbosity(optarg);
     114                 :         46 :             break;
     115                 :            : 
     116                 :            :         case 'c':
     117                 :          4 :             pvt->track = true;
     118                 :          4 :             break;
     119                 :            : 
     120                 :            :         case '?':
     121                 :          0 :             exit(EXIT_FAILURE);
     122                 :            : 
     123                 :            :         default:
     124                 :          0 :             abort();
     125                 :            :         }
     126                 :         73 :     }
     127                 :        326 :     free(short_options);
     128                 :        326 : }
     129                 :            : 
     130                 :            : static void
     131                 :          0 : usage(void)
     132                 :            : {
     133                 :          0 :     printf("%s: Open vSwitch database test utility\n"
     134                 :            :            "usage: %s [OPTIONS] COMMAND [ARG...]\n\n"
     135                 :            :            "  log-io FILE FLAGS COMMAND...\n"
     136                 :            :            "    open FILE with FLAGS, run COMMANDs\n"
     137                 :            :            "  default-atoms\n"
     138                 :            :            "    test ovsdb_atom_default()\n"
     139                 :            :            "  default-data\n"
     140                 :            :            "    test ovsdb_datum_default()\n"
     141                 :            :            "  parse-atomic-type TYPE\n"
     142                 :            :            "    parse TYPE as OVSDB atomic type, and re-serialize\n"
     143                 :            :            "  parse-base-type TYPE\n"
     144                 :            :            "    parse TYPE as OVSDB base type, and re-serialize\n"
     145                 :            :            "  parse-type JSON\n"
     146                 :            :            "    parse JSON as OVSDB type, and re-serialize\n"
     147                 :            :            "  parse-atoms TYPE ATOM...\n"
     148                 :            :            "    parse JSON ATOMs as atoms of TYPE, and re-serialize\n"
     149                 :            :            "  parse-atom-strings TYPE ATOM...\n"
     150                 :            :            "    parse string ATOMs as atoms of given TYPE, and re-serialize\n"
     151                 :            :            "  sort-atoms TYPE ATOM...\n"
     152                 :            :            "    print JSON ATOMs in sorted order\n"
     153                 :            :            "  parse-data TYPE DATUM...\n"
     154                 :            :            "    parse JSON DATUMs as data of given TYPE, and re-serialize\n"
     155                 :            :            "  parse-data-strings TYPE DATUM...\n"
     156                 :            :            "    parse string DATUMs as data of given TYPE, and re-serialize\n"
     157                 :            :            "  parse-column NAME OBJECT\n"
     158                 :            :            "    parse column NAME with info OBJECT, and re-serialize\n"
     159                 :            :            "  parse-table NAME OBJECT [DEFAULT-IS-ROOT]\n"
     160                 :            :            "    parse table NAME with info OBJECT\n"
     161                 :            :            "  parse-row TABLE ROW..., and re-serialize\n"
     162                 :            :            "    parse each ROW of defined TABLE\n"
     163                 :            :            "  compare-row TABLE ROW...\n"
     164                 :            :            "    mutually compare all of the ROWs, print those that are equal\n"
     165                 :            :            "  parse-conditions TABLE CONDITION...\n"
     166                 :            :            "    parse each CONDITION on TABLE, and re-serialize\n"
     167                 :            :            "  evaluate-conditions TABLE [CONDITION,...] [ROW,...]\n"
     168                 :            :            "    test CONDITIONS on TABLE against each ROW, print results\n"
     169                 :            :            "  evaluate-conditions-any TABLE [CONDITION,...] [ROW,...]\n"
     170                 :            :            "    test CONDITIONS to match any of the CONDITONS on TABLE\n"
     171                 :            :            "    against each ROW, print results\n"
     172                 :            :            "  compare-conditions TABLE [CONDITION,...]\n"
     173                 :            :            "    mutually compare all of the CONDITION, print results for\n"
     174                 :            :            "    each pair\n"
     175                 :            :            "  parse-mutations TABLE MUTATION...\n"
     176                 :            :            "    parse each MUTATION on TABLE, and re-serialize\n"
     177                 :            :            "  execute-mutations TABLE [MUTATION,...] [ROW,...]\n"
     178                 :            :            "    execute MUTATIONS on TABLE on each ROW, print results\n"
     179                 :            :            "  query TABLE [ROW,...] [CONDITION,...]\n"
     180                 :            :            "    add each ROW to TABLE, then query and print the rows that\n"
     181                 :            :            "    satisfy each CONDITION.\n"
     182                 :            :            "  query-distinct TABLE [ROW,...] [CONDITION,...] COLUMNS\n"
     183                 :            :            "    add each ROW to TABLE, then query and print the rows that\n"
     184                 :            :            "    satisfy each CONDITION and have distinct COLUMNS.\n"
     185                 :            :            "  parse-schema JSON\n"
     186                 :            :            "    parse JSON as an OVSDB schema, and re-serialize\n"
     187                 :            :            "  transact COMMAND\n"
     188                 :            :            "    execute each specified transactional COMMAND:\n"
     189                 :            :            "      commit\n"
     190                 :            :            "      abort\n"
     191                 :            :            "      insert UUID I J\n"
     192                 :            :            "      delete UUID\n"
     193                 :            :            "      modify UUID I J\n"
     194                 :            :            "      print\n"
     195                 :            :            "  execute SCHEMA TRANSACTION...\n"
     196                 :            :            "    executes each TRANSACTION on an initially empty database\n"
     197                 :            :            "    the specified SCHEMA\n"
     198                 :            :            "  execute-readonly SCHEMA TRANSACTION...\n"
     199                 :            :            "    same as execute, except the TRANSACTION will be executed\n"
     200                 :            :            "    against the database server that is in read only mode\n"
     201                 :            :            "  trigger SCHEMA TRANSACTION...\n"
     202                 :            :            "    executes each TRANSACTION on an initially empty database\n"
     203                 :            :            "    the specified SCHEMA.   A TRANSACTION of the form\n"
     204                 :            :            "    [\"advance\", NUMBER] advances NUMBER milliseconds in\n"
     205                 :            :            "    simulated time, for causing triggers to time out.\n"
     206                 :            :            "  idl SERVER [TRANSACTION...]\n"
     207                 :            :            "    connect to SERVER and dump the contents of the database\n"
     208                 :            :            "    as seen initially by the IDL implementation and after\n"
     209                 :            :            "    executing each TRANSACTION.  (Each TRANSACTION must modify\n"
     210                 :            :            "    the database or this command will hang.)\n"
     211                 :            :            "  idl-partial-update-map-column SERVER \n"
     212                 :            :            "    connect to SERVER and executes different operations to\n"
     213                 :            :            "    test the capacity of updating elements inside a map column\n"
     214                 :            :            "    displaying the table information after each operation.\n"
     215                 :            :            "  idl-partial-update-set-column SERVER \n"
     216                 :            :            "    connect to SERVER and executes different operations to\n"
     217                 :            :            "    test the capacity of updating elements inside a set column\n"
     218                 :            :            "    displaying the table information after each operation.\n",
     219                 :            :            program_name, program_name);
     220                 :          0 :     vlog_usage();
     221                 :          0 :     printf("\nOther options:\n"
     222                 :            :            "  -t, --timeout=SECS          give up after SECS seconds\n"
     223                 :            :            "  -h, --help                  display this help message\n"
     224                 :            :            "  -c, --change-track          used with the 'idl' command to\n"
     225                 :            :            "                              enable tracking of IDL changes\n");
     226                 :          0 :     exit(EXIT_SUCCESS);
     227                 :            : }
     228                 :            : 
     229                 :            : /* Command helper functions. */
     230                 :            : 
     231                 :            : static struct json *
     232                 :       1097 : parse_json(const char *s)
     233                 :            : {
     234                 :       1097 :     struct json *json = json_from_string(s);
     235         [ -  + ]:       1097 :     if (json->type == JSON_STRING) {
     236                 :          0 :         ovs_fatal(0, "\"%s\": %s", s, json->u.string);
     237                 :            :     }
     238                 :       1097 :     return json;
     239                 :            : }
     240                 :            : 
     241                 :            : static struct json *
     242                 :        395 : unbox_json(struct json *json)
     243                 :            : {
     244 [ +  + ][ +  + ]:        395 :     if (json->type == JSON_ARRAY && json->u.array.n == 1) {
     245                 :        174 :         struct json *inner = json->u.array.elems[0];
     246                 :        174 :         json->u.array.elems[0] = NULL;
     247                 :        174 :         json_destroy(json);
     248                 :        174 :         return inner;
     249                 :            :     } else {
     250                 :        221 :         return json;
     251                 :            :     }
     252                 :            : }
     253                 :            : 
     254                 :            : static void
     255                 :        512 : print_and_free_json(struct json *json)
     256                 :            : {
     257                 :        512 :     char *string = json_to_string(json, JSSF_SORT);
     258                 :        512 :     json_destroy(json);
     259                 :        512 :     puts(string);
     260                 :        512 :     free(string);
     261                 :        512 : }
     262                 :            : 
     263                 :            : static void
     264                 :         94 : print_and_free_ovsdb_error(struct ovsdb_error *error)
     265                 :            : {
     266                 :         94 :     char *string = ovsdb_error_to_string(error);
     267                 :         94 :     ovsdb_error_destroy(error);
     268                 :         94 :     puts(string);
     269                 :         94 :     free(string);
     270                 :         94 : }
     271                 :            : 
     272                 :            : static void
     273                 :       1145 : check_ovsdb_error(struct ovsdb_error *error)
     274                 :            : {
     275         [ +  + ]:       1145 :     if (error) {
     276                 :         32 :         char *s = ovsdb_error_to_string(error);
     277                 :         32 :         ovsdb_error_destroy(error);
     278                 :         32 :         ovs_fatal(0, "%s", s);
     279                 :            :     }
     280                 :       1113 : }
     281                 :            : 
     282                 :            : static void
     283                 :         69 : die_if_error(char *error)
     284                 :            : {
     285         [ +  + ]:         69 :     if (error) {
     286                 :         13 :         ovs_fatal(0, "%s", error);
     287                 :            :     }
     288                 :         56 : }
     289                 :            : 
     290                 :            : /* Command implementations. */
     291                 :            : 
     292                 :            : static void
     293                 :         29 : do_log_io(struct ovs_cmdl_context *ctx)
     294                 :            : {
     295                 :         29 :     const char *name = ctx->argv[1];
     296                 :         29 :     char *mode_string = ctx->argv[2];
     297                 :            : 
     298                 :            :     struct ovsdb_error *error;
     299                 :            :     enum ovsdb_log_open_mode mode;
     300                 :            :     struct ovsdb_log *log;
     301                 :            :     int i;
     302                 :            : 
     303         [ +  + ]:         29 :     if (!strcmp(mode_string, "read-only")) {
     304                 :         11 :         mode = OVSDB_LOG_READ_ONLY;
     305         [ +  + ]:         18 :     } else if (!strcmp(mode_string, "read/write")) {
     306                 :          6 :         mode = OVSDB_LOG_READ_WRITE;
     307         [ +  - ]:         12 :     } else if (!strcmp(mode_string, "create")) {
     308                 :         12 :         mode = OVSDB_LOG_CREATE;
     309                 :            :     } else {
     310                 :          0 :         ovs_fatal(0, "unknown log-io open mode \"%s\"", mode_string);
     311                 :            :     }
     312                 :            : 
     313                 :         29 :     check_ovsdb_error(ovsdb_log_open(name, mode, -1, &log));
     314                 :         28 :     printf("%s: open successful\n", name);
     315                 :            : 
     316         [ +  + ]:        116 :     for (i = 3; i < ctx->argc; i++) {
     317                 :         88 :         const char *command = ctx->argv[i];
     318         [ +  + ]:         88 :         if (!strcmp(command, "read")) {
     319                 :            :             struct json *json;
     320                 :            : 
     321                 :         56 :             error = ovsdb_log_read(log, &json);
     322         [ +  + ]:         56 :             if (!error) {
     323                 :         51 :                 printf("%s: read: ", name);
     324         [ +  + ]:         51 :                 if (json) {
     325                 :         42 :                     print_and_free_json(json);
     326                 :            :                 } else {
     327                 :          9 :                     printf("end of log\n");
     328                 :            :                 }
     329                 :         56 :                 continue;
     330                 :            :             }
     331         [ +  - ]:         32 :         } else if (!strncmp(command, "write:", 6)) {
     332                 :         32 :             struct json *json = parse_json(command + 6);
     333                 :         32 :             error = ovsdb_log_write(log, json);
     334                 :         32 :             json_destroy(json);
     335         [ #  # ]:          0 :         } else if (!strcmp(command, "commit")) {
     336                 :          0 :             error = ovsdb_log_commit(log);
     337                 :            :         } else {
     338                 :          0 :             ovs_fatal(0, "unknown log-io command \"%s\"", command);
     339                 :            :         }
     340         [ +  + ]:         37 :         if (error) {
     341                 :          5 :             char *s = ovsdb_error_to_string(error);
     342                 :          5 :             printf("%s: %s failed: %s\n", name, command, s);
     343                 :          5 :             free(s);
     344                 :          5 :             ovsdb_error_destroy(error);
     345                 :            :         } else {
     346                 :         32 :             printf("%s: %s successful\n", name, command);
     347                 :            :         }
     348                 :            :     }
     349                 :            : 
     350                 :         28 :     ovsdb_log_close(log);
     351                 :         28 : }
     352                 :            : 
     353                 :            : static void
     354                 :          1 : do_default_atoms(struct ovs_cmdl_context *ctx OVS_UNUSED)
     355                 :            : {
     356                 :            :     int type;
     357                 :            : 
     358         [ +  + ]:          7 :     for (type = 0; type < OVSDB_N_TYPES; type++) {
     359                 :            :         union ovsdb_atom atom;
     360                 :            : 
     361         [ +  + ]:          6 :         if (type == OVSDB_TYPE_VOID) {
     362                 :          1 :             continue;
     363                 :            :         }
     364                 :            : 
     365                 :          5 :         printf("%s: ", ovsdb_atomic_type_to_string(type));
     366                 :            : 
     367                 :          5 :         ovsdb_atom_init_default(&atom, type);
     368         [ -  + ]:          5 :         if (!ovsdb_atom_equals(&atom, ovsdb_atom_default(type), type)) {
     369                 :          0 :             printf("wrong\n");
     370                 :          0 :             exit(1);
     371                 :            :         }
     372                 :          5 :         ovsdb_atom_destroy(&atom, type);
     373                 :            : 
     374                 :          5 :         printf("OK\n");
     375                 :            :     }
     376                 :          1 : }
     377                 :            : 
     378                 :            : static void
     379                 :          1 : do_default_data(struct ovs_cmdl_context *ctx OVS_UNUSED)
     380                 :            : {
     381                 :            :     unsigned int n_min;
     382                 :            :     int key, value;
     383                 :            : 
     384         [ +  + ]:          3 :     for (n_min = 0; n_min <= 1; n_min++) {
     385         [ +  + ]:         14 :         for (key = 0; key < OVSDB_N_TYPES; key++) {
     386         [ +  + ]:         12 :             if (key == OVSDB_TYPE_VOID) {
     387                 :          2 :                 continue;
     388                 :            :             }
     389         [ +  + ]:         70 :             for (value = 0; value < OVSDB_N_TYPES; value++) {
     390                 :            :                 struct ovsdb_datum datum;
     391                 :            :                 struct ovsdb_type type;
     392                 :            : 
     393                 :         60 :                 ovsdb_base_type_init(&type.key, key);
     394                 :         60 :                 ovsdb_base_type_init(&type.value, value);
     395                 :         60 :                 type.n_min = n_min;
     396                 :         60 :                 type.n_max = 1;
     397         [ -  + ]:         60 :                 assert(ovsdb_type_is_valid(&type));
     398                 :            : 
     399                 :         60 :                 printf("key %s, value %s, n_min %u: ",
     400                 :            :                        ovsdb_atomic_type_to_string(key),
     401                 :            :                        ovsdb_atomic_type_to_string(value), n_min);
     402                 :            : 
     403                 :         60 :                 ovsdb_datum_init_default(&datum, &type);
     404         [ -  + ]:         60 :                 if (!ovsdb_datum_equals(&datum, ovsdb_datum_default(&type),
     405                 :            :                                         &type)) {
     406                 :          0 :                     printf("wrong\n");
     407                 :          0 :                     exit(1);
     408                 :            :                 }
     409                 :         60 :                 ovsdb_datum_destroy(&datum, &type);
     410                 :         60 :                 ovsdb_type_destroy(&type);
     411                 :            : 
     412                 :         60 :                 printf("OK\n");
     413                 :            :             }
     414                 :            :         }
     415                 :            :     }
     416                 :          1 : }
     417                 :            : 
     418                 :            : static void
     419                 :          7 : do_diff_data(struct ovs_cmdl_context *ctx)
     420                 :            : {
     421                 :            :     struct ovsdb_type type;
     422                 :            :     struct json *json;
     423                 :            :     struct ovsdb_datum new, old, diff, reincarnation;
     424                 :            : 
     425                 :          7 :     json = unbox_json(parse_json(ctx->argv[1]));
     426                 :          7 :     check_ovsdb_error(ovsdb_type_from_json(&type, json));
     427                 :          7 :     json_destroy(json);
     428                 :            : 
     429                 :            :     /* Arguments in pairs of 'old' and 'new'. */
     430         [ +  + ]:         19 :     for (int i = 2; i < ctx->argc - 1; i+=2) {
     431                 :            :         struct ovsdb_error *error;
     432                 :            : 
     433                 :         14 :         json = unbox_json(parse_json(ctx->argv[i]));
     434                 :         14 :         check_ovsdb_error(ovsdb_datum_from_json(&old, &type, json, NULL));
     435                 :         14 :         json_destroy(json);
     436                 :            : 
     437                 :         14 :         json = unbox_json(parse_json(ctx->argv[i+1]));
     438                 :         14 :         check_ovsdb_error(ovsdb_transient_datum_from_json(&new, &type, json));
     439                 :         14 :         json_destroy(json);
     440                 :            : 
     441                 :            :         /* Generate the diff.  */
     442                 :         14 :         ovsdb_datum_diff(&diff, &old, &new, &type);
     443                 :            : 
     444                 :            :         /* Apply diff to 'old' to create'reincarnation'. */
     445                 :         14 :         error = ovsdb_datum_apply_diff(&reincarnation, &old, &diff, &type);
     446         [ +  + ]:         14 :         if (error) {
     447                 :          2 :             char *string = ovsdb_error_to_string(error);
     448                 :          2 :             ovsdb_error_destroy(error);
     449                 :          2 :             ovs_fatal(0, "%s", string);
     450                 :            :         }
     451                 :            : 
     452                 :            :         /* Test to make sure 'new' equals 'reincarnation'.  */
     453         [ -  + ]:         12 :         if (!ovsdb_datum_equals(&new, &reincarnation, &type)) {
     454                 :          0 :             ovs_fatal(0, "failed to apply diff");
     455                 :            :         }
     456                 :            : 
     457                 :            :         /* Print diff */
     458                 :         12 :         json = ovsdb_datum_to_json(&diff, &type);
     459                 :         12 :         printf ("diff: ");
     460                 :         12 :         print_and_free_json(json);
     461                 :            : 
     462                 :            :         /* Print reincarnation */
     463                 :         12 :         json = ovsdb_datum_to_json(&reincarnation, &type);
     464                 :         12 :         printf ("apply diff: ");
     465                 :         12 :         print_and_free_json(json);
     466                 :            : 
     467                 :         12 :         ovsdb_datum_destroy(&new, &type);
     468                 :         12 :         ovsdb_datum_destroy(&old, &type);
     469                 :         12 :         ovsdb_datum_destroy(&diff, &type);
     470                 :         12 :         ovsdb_datum_destroy(&reincarnation, &type);
     471                 :            : 
     472                 :         12 :         printf("OK\n");
     473                 :            :     }
     474                 :            : 
     475                 :          5 :     ovsdb_type_destroy(&type);
     476                 :          5 : }
     477                 :            : 
     478                 :            : static void
     479                 :          6 : do_parse_atomic_type(struct ovs_cmdl_context *ctx)
     480                 :            : {
     481                 :            :     enum ovsdb_atomic_type type;
     482                 :            :     struct json *json;
     483                 :            : 
     484                 :          6 :     json = unbox_json(parse_json(ctx->argv[1]));
     485                 :          6 :     check_ovsdb_error(ovsdb_atomic_type_from_json(&type, json));
     486                 :          5 :     json_destroy(json);
     487                 :          5 :     print_and_free_json(ovsdb_atomic_type_to_json(type));
     488                 :          5 : }
     489                 :            : 
     490                 :            : static void
     491                 :         23 : do_parse_base_type(struct ovs_cmdl_context *ctx)
     492                 :            : {
     493                 :            :     struct ovsdb_base_type base;
     494                 :            :     struct json *json;
     495                 :            : 
     496                 :         23 :     json = unbox_json(parse_json(ctx->argv[1]));
     497                 :         23 :     check_ovsdb_error(ovsdb_base_type_from_json(&base, json));
     498                 :         16 :     json_destroy(json);
     499                 :         16 :     print_and_free_json(ovsdb_base_type_to_json(&base));
     500                 :         16 :     ovsdb_base_type_destroy(&base);
     501                 :         16 : }
     502                 :            : 
     503                 :            : static void
     504                 :         25 : do_parse_type(struct ovs_cmdl_context *ctx)
     505                 :            : {
     506                 :            :     struct ovsdb_type type;
     507                 :            :     struct json *json;
     508                 :            : 
     509                 :         25 :     json = unbox_json(parse_json(ctx->argv[1]));
     510                 :         25 :     check_ovsdb_error(ovsdb_type_from_json(&type, json));
     511                 :         18 :     json_destroy(json);
     512                 :         18 :     print_and_free_json(ovsdb_type_to_json(&type));
     513                 :         18 :     ovsdb_type_destroy(&type);
     514                 :         18 : }
     515                 :            : 
     516                 :            : static void
     517                 :         24 : do_parse_atoms(struct ovs_cmdl_context *ctx)
     518                 :            : {
     519                 :            :     struct ovsdb_base_type base;
     520                 :            :     struct json *json;
     521                 :            :     int i;
     522                 :            : 
     523                 :         24 :     json = unbox_json(parse_json(ctx->argv[1]));
     524                 :         24 :     check_ovsdb_error(ovsdb_base_type_from_json(&base, json));
     525                 :         24 :     json_destroy(json);
     526                 :            : 
     527         [ +  + ]:        123 :     for (i = 2; i < ctx->argc; i++) {
     528                 :            :         struct ovsdb_error *error;
     529                 :            :         union ovsdb_atom atom;
     530                 :            : 
     531                 :         99 :         json = unbox_json(parse_json(ctx->argv[i]));
     532                 :         99 :         error = ovsdb_atom_from_json(&atom, &base, json, NULL);
     533                 :         99 :         json_destroy(json);
     534                 :            : 
     535         [ +  + ]:         99 :         if (error) {
     536                 :         42 :             print_and_free_ovsdb_error(error);
     537                 :            :         } else {
     538                 :         57 :             print_and_free_json(ovsdb_atom_to_json(&atom, base.type));
     539                 :         57 :             ovsdb_atom_destroy(&atom, base.type);
     540                 :            :         }
     541                 :            :     }
     542                 :         24 :     ovsdb_base_type_destroy(&base);
     543                 :         24 : }
     544                 :            : 
     545                 :            : static void
     546                 :         12 : do_parse_atom_strings(struct ovs_cmdl_context *ctx)
     547                 :            : {
     548                 :            :     struct ovsdb_base_type base;
     549                 :            :     struct json *json;
     550                 :            :     int i;
     551                 :            : 
     552                 :         12 :     json = unbox_json(parse_json(ctx->argv[1]));
     553                 :         12 :     check_ovsdb_error(ovsdb_base_type_from_json(&base, json));
     554                 :         12 :     json_destroy(json);
     555                 :            : 
     556         [ +  + ]:         33 :     for (i = 2; i < ctx->argc; i++) {
     557                 :            :         union ovsdb_atom atom;
     558                 :            :         struct ds out;
     559                 :            : 
     560                 :         28 :         die_if_error(ovsdb_atom_from_string(&atom, &base, ctx->argv[i], NULL));
     561                 :            : 
     562                 :         21 :         ds_init(&out);
     563                 :         21 :         ovsdb_atom_to_string(&atom, base.type, &out);
     564                 :         21 :         puts(ds_cstr(&out));
     565                 :         21 :         ds_destroy(&out);
     566                 :            : 
     567                 :         21 :         ovsdb_atom_destroy(&atom, base.type);
     568                 :            :     }
     569                 :          5 :     ovsdb_base_type_destroy(&base);
     570                 :          5 : }
     571                 :            : 
     572                 :            : static void
     573                 :         19 : do_parse_data__(int argc, char *argv[],
     574                 :            :                 struct ovsdb_error *
     575                 :            :                 (*parse)(struct ovsdb_datum *datum,
     576                 :            :                          const struct ovsdb_type *type,
     577                 :            :                          const struct json *json,
     578                 :            :                          struct ovsdb_symbol_table *symtab))
     579                 :            : {
     580                 :            :     struct ovsdb_type type;
     581                 :            :     struct json *json;
     582                 :            :     int i;
     583                 :            : 
     584                 :         19 :     json = unbox_json(parse_json(argv[1]));
     585                 :         19 :     check_ovsdb_error(ovsdb_type_from_json(&type, json));
     586                 :         19 :     json_destroy(json);
     587                 :            : 
     588         [ +  + ]:         55 :     for (i = 2; i < argc; i++) {
     589                 :            :         struct ovsdb_datum datum;
     590                 :            : 
     591                 :         42 :         json = unbox_json(parse_json(argv[i]));
     592                 :         42 :         check_ovsdb_error(parse(&datum, &type, json, NULL));
     593                 :         36 :         json_destroy(json);
     594                 :            : 
     595                 :         36 :         print_and_free_json(ovsdb_datum_to_json(&datum, &type));
     596                 :            : 
     597                 :         36 :         ovsdb_datum_destroy(&datum, &type);
     598                 :            :     }
     599                 :         13 :     ovsdb_type_destroy(&type);
     600                 :         13 : }
     601                 :            : 
     602                 :            : static void
     603                 :         19 : do_parse_data(struct ovs_cmdl_context *ctx)
     604                 :            : {
     605                 :         19 :     do_parse_data__(ctx->argc, ctx->argv, ovsdb_datum_from_json);
     606                 :         13 : }
     607                 :            : 
     608                 :            : static void
     609                 :         19 : do_parse_data_strings(struct ovs_cmdl_context *ctx)
     610                 :            : {
     611                 :            :     struct ovsdb_type type;
     612                 :            :     struct json *json;
     613                 :            :     int i;
     614                 :            : 
     615                 :         19 :     json = unbox_json(parse_json(ctx->argv[1]));
     616                 :         19 :     check_ovsdb_error(ovsdb_type_from_json(&type, json));
     617                 :         19 :     json_destroy(json);
     618                 :            : 
     619         [ +  + ]:         54 :     for (i = 2; i < ctx->argc; i++) {
     620                 :            :         struct ovsdb_datum datum;
     621                 :            :         struct ds out;
     622                 :            : 
     623                 :         41 :         die_if_error(ovsdb_datum_from_string(&datum, &type, ctx->argv[i], NULL));
     624                 :            : 
     625                 :         35 :         ds_init(&out);
     626                 :         35 :         ovsdb_datum_to_string(&datum, &type, &out);
     627                 :         35 :         puts(ds_cstr(&out));
     628                 :         35 :         ds_destroy(&out);
     629                 :            : 
     630                 :         35 :         ovsdb_datum_destroy(&datum, &type);
     631                 :            :     }
     632                 :         13 :     ovsdb_type_destroy(&type);
     633                 :         13 : }
     634                 :            : 
     635                 :            : static enum ovsdb_atomic_type compare_atoms_atomic_type;
     636                 :            : 
     637                 :            : static int
     638                 :        151 : compare_atoms(const void *a_, const void *b_)
     639                 :            : {
     640                 :        151 :     const union ovsdb_atom *a = a_;
     641                 :        151 :     const union ovsdb_atom *b = b_;
     642                 :            : 
     643                 :        151 :     return ovsdb_atom_compare_3way(a, b, compare_atoms_atomic_type);
     644                 :            : }
     645                 :            : 
     646                 :            : static void
     647                 :          5 : do_sort_atoms(struct ovs_cmdl_context *ctx)
     648                 :            : {
     649                 :            :     struct ovsdb_base_type base;
     650                 :            :     union ovsdb_atom *atoms;
     651                 :            :     struct json *json, **json_atoms;
     652                 :            :     size_t n_atoms;
     653                 :            :     int i;
     654                 :            : 
     655                 :          5 :     json = unbox_json(parse_json(ctx->argv[1]));
     656                 :          5 :     check_ovsdb_error(ovsdb_base_type_from_json(&base, json));
     657                 :          5 :     json_destroy(json);
     658                 :            : 
     659                 :          5 :     json = unbox_json(parse_json(ctx->argv[2]));
     660         [ -  + ]:          5 :     if (json->type != JSON_ARRAY) {
     661                 :          0 :         ovs_fatal(0, "second argument must be array");
     662                 :            :     }
     663                 :            : 
     664                 :            :     /* Convert JSON atoms to internal representation. */
     665                 :          5 :     n_atoms = json->u.array.n;
     666                 :          5 :     atoms = xmalloc(n_atoms * sizeof *atoms);
     667         [ +  + ]:         57 :     for (i = 0; i < n_atoms; i++) {
     668                 :         52 :         check_ovsdb_error(ovsdb_atom_from_json(&atoms[i], &base,
     669                 :         52 :                                                json->u.array.elems[i], NULL));
     670                 :            :     }
     671                 :          5 :     json_destroy(json);
     672                 :            : 
     673                 :            :     /* Sort atoms. */
     674                 :          5 :     compare_atoms_atomic_type = base.type;
     675                 :          5 :     qsort(atoms, n_atoms, sizeof *atoms, compare_atoms);
     676                 :            : 
     677                 :            :     /* Convert internal representation back to JSON. */
     678                 :          5 :     json_atoms = xmalloc(n_atoms * sizeof *json_atoms);
     679         [ +  + ]:         57 :     for (i = 0; i < n_atoms; i++) {
     680                 :         52 :         json_atoms[i] = ovsdb_atom_to_json(&atoms[i], base.type);
     681                 :         52 :         ovsdb_atom_destroy(&atoms[i], base.type);
     682                 :            :     }
     683                 :          5 :     print_and_free_json(json_array_create(json_atoms, n_atoms));
     684                 :          5 :     free(atoms);
     685                 :          5 :     ovsdb_base_type_destroy(&base);
     686                 :          5 : }
     687                 :            : 
     688                 :            : static void
     689                 :          3 : do_parse_column(struct ovs_cmdl_context *ctx)
     690                 :            : {
     691                 :            :     struct ovsdb_column *column;
     692                 :            :     struct json *json;
     693                 :            : 
     694                 :          3 :     json = parse_json(ctx->argv[2]);
     695                 :          3 :     check_ovsdb_error(ovsdb_column_from_json(json, ctx->argv[1], &column));
     696                 :          3 :     json_destroy(json);
     697                 :          3 :     print_and_free_json(ovsdb_column_to_json(column));
     698                 :          3 :     ovsdb_column_destroy(column);
     699                 :          3 : }
     700                 :            : 
     701                 :            : static void
     702                 :         14 : do_parse_table(struct ovs_cmdl_context *ctx)
     703                 :            : {
     704                 :            :     struct ovsdb_table_schema *ts;
     705                 :            :     bool default_is_root;
     706                 :            :     struct json *json;
     707                 :            : 
     708 [ +  + ][ +  - ]:         14 :     default_is_root = ctx->argc > 3 && !strcmp(ctx->argv[3], "true");
     709                 :            : 
     710                 :         14 :     json = parse_json(ctx->argv[2]);
     711                 :         14 :     check_ovsdb_error(ovsdb_table_schema_from_json(json, ctx->argv[1], &ts));
     712                 :          7 :     json_destroy(json);
     713                 :          7 :     print_and_free_json(ovsdb_table_schema_to_json(ts, default_is_root));
     714                 :          7 :     ovsdb_table_schema_destroy(ts);
     715                 :          7 : }
     716                 :            : 
     717                 :            : static void
     718                 :          8 : do_parse_rows(struct ovs_cmdl_context *ctx)
     719                 :            : {
     720                 :            :     struct ovsdb_column_set all_columns;
     721                 :            :     struct ovsdb_table_schema *ts;
     722                 :            :     struct ovsdb_table *table;
     723                 :            :     struct json *json;
     724                 :            :     int i;
     725                 :            : 
     726                 :          8 :     json = unbox_json(parse_json(ctx->argv[1]));
     727                 :          8 :     check_ovsdb_error(ovsdb_table_schema_from_json(json, "mytable", &ts));
     728                 :          8 :     json_destroy(json);
     729                 :            : 
     730                 :          8 :     table = ovsdb_table_create(ts);
     731                 :          8 :     ovsdb_column_set_init(&all_columns);
     732                 :          8 :     ovsdb_column_set_add_all(&all_columns, table);
     733                 :            : 
     734         [ +  + ]:         30 :     for (i = 2; i < ctx->argc; i++) {
     735                 :            :         struct ovsdb_column_set columns;
     736                 :            :         struct ovsdb_row *row;
     737                 :            : 
     738                 :         22 :         ovsdb_column_set_init(&columns);
     739                 :         22 :         row = ovsdb_row_create(table);
     740                 :            : 
     741                 :         22 :         json = unbox_json(parse_json(ctx->argv[i]));
     742                 :         22 :         check_ovsdb_error(ovsdb_row_from_json(row, json, NULL, &columns));
     743                 :         22 :         json_destroy(json);
     744                 :            : 
     745                 :         22 :         print_and_free_json(ovsdb_row_to_json(row, &all_columns));
     746                 :            : 
     747         [ +  + ]:         22 :         if (columns.n_columns) {
     748                 :            :             struct svec names;
     749                 :            :             size_t j;
     750                 :            :             char *s;
     751                 :            : 
     752                 :         14 :             svec_init(&names);
     753         [ +  + ]:         31 :             for (j = 0; j < columns.n_columns; j++) {
     754                 :         17 :                 svec_add(&names, columns.columns[j]->name);
     755                 :            :             }
     756                 :         14 :             svec_sort(&names);
     757                 :         14 :             s = svec_join(&names, ", ", "");
     758                 :         14 :             puts(s);
     759                 :         14 :             free(s);
     760                 :         14 :             svec_destroy(&names);
     761                 :            :         } else {
     762                 :          8 :             printf("<none>\n");
     763                 :            :         }
     764                 :            : 
     765                 :         22 :         ovsdb_column_set_destroy(&columns);
     766                 :         22 :         ovsdb_row_destroy(row);
     767                 :            :     }
     768                 :            : 
     769                 :          8 :     ovsdb_column_set_destroy(&all_columns);
     770                 :          8 :     ovsdb_table_destroy(table); /* Also destroys 'ts'. */
     771                 :          8 : }
     772                 :            : 
     773                 :            : static void
     774                 :          3 : do_compare_rows(struct ovs_cmdl_context *ctx)
     775                 :            : {
     776                 :            :     struct ovsdb_column_set all_columns;
     777                 :            :     struct ovsdb_table_schema *ts;
     778                 :            :     struct ovsdb_table *table;
     779                 :            :     struct ovsdb_row **rows;
     780                 :            :     struct json *json;
     781                 :            :     char **names;
     782                 :            :     int n_rows;
     783                 :            :     int i, j;
     784                 :            : 
     785                 :          3 :     json = unbox_json(parse_json(ctx->argv[1]));
     786                 :          3 :     check_ovsdb_error(ovsdb_table_schema_from_json(json, "mytable", &ts));
     787                 :          3 :     json_destroy(json);
     788                 :            : 
     789                 :          3 :     table = ovsdb_table_create(ts);
     790                 :          3 :     ovsdb_column_set_init(&all_columns);
     791                 :          3 :     ovsdb_column_set_add_all(&all_columns, table);
     792                 :            : 
     793                 :          3 :     n_rows = ctx->argc - 2;
     794                 :          3 :     rows = xmalloc(sizeof *rows * n_rows);
     795                 :          3 :     names = xmalloc(sizeof *names * n_rows);
     796         [ +  + ]:         96 :     for (i = 0; i < n_rows; i++) {
     797                 :         93 :         rows[i] = ovsdb_row_create(table);
     798                 :            : 
     799                 :         93 :         json = parse_json(ctx->argv[i + 2]);
     800 [ +  - ][ +  - ]:         93 :         if (json->type != JSON_ARRAY || json->u.array.n != 2
     801         [ -  + ]:         93 :             || json->u.array.elems[0]->type != JSON_STRING) {
     802                 :          0 :             ovs_fatal(0, "\"%s\" does not have expected form "
     803                 :          0 :                       "[\"name\", {data}]", ctx->argv[i]);
     804                 :            :         }
     805                 :         93 :         names[i] = xstrdup(json->u.array.elems[0]->u.string);
     806                 :         93 :         check_ovsdb_error(ovsdb_row_from_json(rows[i], json->u.array.elems[1],
     807                 :            :                                               NULL, NULL));
     808                 :         93 :         json_destroy(json);
     809                 :            :     }
     810         [ +  + ]:         96 :     for (i = 0; i < n_rows; i++) {
     811                 :         93 :         uint32_t i_hash = ovsdb_row_hash_columns(rows[i], &all_columns, 0);
     812         [ +  + ]:       1636 :         for (j = i + 1; j < n_rows; j++) {
     813                 :       1543 :             uint32_t j_hash = ovsdb_row_hash_columns(rows[j], &all_columns, 0);
     814         [ +  + ]:       1543 :             if (ovsdb_row_equal_columns(rows[i], rows[j], &all_columns)) {
     815                 :         31 :                 printf("%s == %s\n", names[i], names[j]);
     816         [ -  + ]:         31 :                 if (i_hash != j_hash) {
     817                 :          0 :                     printf("but hash(%s) != hash(%s)\n", names[i], names[j]);
     818                 :          0 :                     abort();
     819                 :            :                 }
     820         [ +  + ]:       1512 :             } else if (i_hash == j_hash) {
     821                 :          5 :                 printf("hash(%s) == hash(%s)\n", names[i], names[j]);
     822                 :            :             }
     823                 :            :         }
     824                 :            :     }
     825         [ +  + ]:         96 :     for (i = 0; i < n_rows; i++) {
     826                 :         93 :         ovsdb_row_destroy(rows[i]);
     827                 :         93 :         free(names[i]);
     828                 :            :     }
     829                 :          3 :     free(rows);
     830                 :          3 :     free(names);
     831                 :            : 
     832                 :          3 :     ovsdb_column_set_destroy(&all_columns);
     833                 :          3 :     ovsdb_table_destroy(table); /* Also destroys 'ts'. */
     834                 :          3 : }
     835                 :            : 
     836                 :            : static void
     837                 :          7 : do_parse_conditions(struct ovs_cmdl_context *ctx)
     838                 :            : {
     839                 :            :     struct ovsdb_table_schema *ts;
     840                 :            :     struct json *json;
     841                 :          7 :     int exit_code = 0;
     842                 :            :     int i;
     843                 :            : 
     844                 :          7 :     json = unbox_json(parse_json(ctx->argv[1]));
     845                 :          7 :     check_ovsdb_error(ovsdb_table_schema_from_json(json, "mytable", &ts));
     846                 :          7 :     json_destroy(json);
     847                 :            : 
     848         [ +  + ]:         71 :     for (i = 2; i < ctx->argc; i++) {
     849                 :            :         struct ovsdb_condition cnd;
     850                 :            :         struct ovsdb_error *error;
     851                 :            : 
     852                 :         64 :         json = parse_json(ctx->argv[i]);
     853                 :         64 :         error = ovsdb_condition_from_json(ts, json, NULL, &cnd);
     854         [ +  + ]:         64 :         if (!error) {
     855                 :         52 :             print_and_free_json(ovsdb_condition_to_json(&cnd));
     856                 :            :         } else {
     857                 :         12 :             char *s = ovsdb_error_to_string(error);
     858                 :         12 :             ovs_error(0, "%s", s);
     859                 :         12 :             free(s);
     860                 :         12 :             ovsdb_error_destroy(error);
     861                 :         12 :             exit_code = 1;
     862                 :            :         }
     863                 :         64 :         json_destroy(json);
     864                 :            : 
     865                 :         64 :         ovsdb_condition_destroy(&cnd);
     866                 :            :     }
     867                 :          7 :     ovsdb_table_schema_destroy(ts);
     868                 :            : 
     869                 :          7 :     exit(exit_code);
     870                 :            : }
     871                 :            : 
     872                 :            : #define OVSDB_CONDITION_EVERY 0
     873                 :            : #define OVSDB_CONDITION_ANY 1
     874                 :            : 
     875                 :            : static void
     876                 :         14 : do_evaluate_condition__(struct ovs_cmdl_context *ctx, int mode)
     877                 :            : {
     878                 :            :     struct ovsdb_table_schema *ts;
     879                 :            :     struct ovsdb_table *table;
     880                 :            :     struct ovsdb_condition *conditions;
     881                 :            :     size_t n_conditions;
     882                 :            :     struct ovsdb_row **rows;
     883                 :            :     size_t n_rows;
     884                 :            :     struct json *json;
     885                 :            :     size_t i, j;
     886                 :            : 
     887                 :            :     /* Parse table schema, create table. */
     888                 :         14 :     json = unbox_json(parse_json(ctx->argv[1]));
     889                 :         14 :     check_ovsdb_error(ovsdb_table_schema_from_json(json, "mytable", &ts));
     890                 :         14 :     json_destroy(json);
     891                 :            : 
     892                 :         14 :     table = ovsdb_table_create(ts);
     893                 :            : 
     894                 :            :     /* Parse conditions. */
     895                 :         14 :     json = parse_json(ctx->argv[2]);
     896         [ -  + ]:         14 :     if (json->type != JSON_ARRAY) {
     897                 :          0 :         ovs_fatal(0, "CONDITION argument is not JSON array");
     898                 :            :     }
     899                 :         14 :     n_conditions = json->u.array.n;
     900                 :         14 :     conditions = xmalloc(n_conditions * sizeof *conditions);
     901         [ +  + ]:        188 :     for (i = 0; i < n_conditions; i++) {
     902                 :        174 :         check_ovsdb_error(ovsdb_condition_from_json(ts, json->u.array.elems[i],
     903                 :        174 :                                                     NULL, &conditions[i]));
     904                 :            :     }
     905                 :         14 :     json_destroy(json);
     906                 :            : 
     907                 :            :     /* Parse rows. */
     908                 :         14 :     json = parse_json(ctx->argv[3]);
     909         [ -  + ]:         14 :     if (json->type != JSON_ARRAY) {
     910                 :          0 :         ovs_fatal(0, "ROW argument is not JSON array");
     911                 :            :     }
     912                 :         14 :     n_rows = json->u.array.n;
     913                 :         14 :     rows = xmalloc(n_rows * sizeof *rows);
     914         [ +  + ]:         80 :     for (i = 0; i < n_rows; i++) {
     915                 :         66 :         rows[i] = ovsdb_row_create(table);
     916                 :         66 :         check_ovsdb_error(ovsdb_row_from_json(rows[i], json->u.array.elems[i],
     917                 :            :                                               NULL, NULL));
     918                 :            :     }
     919                 :         14 :     json_destroy(json);
     920                 :            : 
     921         [ +  + ]:        188 :     for (i = 0; i < n_conditions; i++) {
     922                 :        174 :         printf("condition %2"PRIuSIZE":", i);
     923         [ +  + ]:       1440 :         for (j = 0; j < n_rows; j++) {
     924                 :            :             bool result;
     925         [ +  + ]:       1266 :             if (mode == OVSDB_CONDITION_EVERY) {
     926                 :       1260 :                 result = ovsdb_condition_match_every_clause(rows[j],
     927                 :       1260 :                                                   &conditions[i]);
     928                 :            :             } else {
     929                 :          6 :                 result = ovsdb_condition_match_any_clause(rows[j]->fields,
     930                 :          6 :                                                           &conditions[i],
     931                 :            :                                                           NULL);
     932                 :            :             }
     933         [ +  + ]:       1266 :             if (j % 5 == 0) {
     934                 :        306 :                 putchar(' ');
     935                 :            :             }
     936         [ +  + ]:       1266 :             putchar(result ? 'T' : '-');
     937                 :            :         }
     938                 :        174 :         printf("\n");
     939                 :            :     }
     940                 :            : 
     941         [ +  + ]:        188 :     for (i = 0; i < n_conditions; i++) {
     942                 :        174 :         ovsdb_condition_destroy(&conditions[i]);
     943                 :            :     }
     944                 :         14 :     free(conditions);
     945         [ +  + ]:         80 :     for (i = 0; i < n_rows; i++) {
     946                 :         66 :         ovsdb_row_destroy(rows[i]);
     947                 :            :     }
     948                 :         14 :     free(rows);
     949                 :         14 :     ovsdb_table_destroy(table); /* Also destroys 'ts'. */
     950                 :         14 : }
     951                 :            : 
     952                 :            : static void
     953                 :         12 : do_evaluate_conditions(struct ovs_cmdl_context *ctx)
     954                 :            : {
     955                 :         12 :     do_evaluate_condition__(ctx, OVSDB_CONDITION_EVERY);
     956                 :         12 : }
     957                 :            : 
     958                 :            : static void
     959                 :          2 : do_evaluate_conditions_any(struct ovs_cmdl_context *ctx)
     960                 :            : {
     961                 :          2 :     do_evaluate_condition__(ctx, OVSDB_CONDITION_ANY);
     962                 :          2 : }
     963                 :            : 
     964                 :            : static void
     965                 :          1 : do_compare_conditions(struct ovs_cmdl_context *ctx)
     966                 :            : {
     967                 :            :     struct ovsdb_table_schema *ts;
     968                 :            :     struct ovsdb_table *table;
     969                 :            :     struct ovsdb_condition *conditions;
     970                 :            :     size_t n_conditions;
     971                 :            :     struct json *json;
     972                 :            :     size_t i;
     973                 :            : 
     974                 :            :     /* Parse table schema, create table. */
     975                 :          1 :     json = unbox_json(parse_json(ctx->argv[1]));
     976                 :          1 :     check_ovsdb_error(ovsdb_table_schema_from_json(json, "mytable", &ts));
     977                 :          1 :     json_destroy(json);
     978                 :            : 
     979                 :          1 :     table = ovsdb_table_create(ts);
     980                 :            : 
     981                 :            :     /* Parse conditions. */
     982                 :          1 :     json = parse_json(ctx->argv[2]);
     983         [ -  + ]:          1 :     if (json->type != JSON_ARRAY) {
     984                 :          0 :         ovs_fatal(0, "CONDITION argument is not JSON array");
     985                 :            :     }
     986                 :          1 :     n_conditions = json->u.array.n;
     987                 :          1 :     conditions = xmalloc(n_conditions * sizeof *conditions);
     988                 :            : 
     989         [ +  + ]:          5 :     for (i = 0; i < n_conditions; i++) {
     990                 :          4 :         check_ovsdb_error(ovsdb_condition_from_json(ts, json->u.array.elems[i],
     991                 :          4 :                                                     NULL, &conditions[i]));
     992                 :            :     }
     993                 :          1 :     json_destroy(json);
     994                 :            : 
     995         [ +  + ]:          4 :     for (i = 0; i < n_conditions - 1; i++) {
     996                 :          3 :         int res = ovsdb_condition_cmp_3way(&conditions[i], &conditions[i + 1]);
     997                 :          3 :         printf("condition %"PRIuSIZE"-%"PRIuSIZE": %d\n", i, i + 1, res);
     998                 :            :     }
     999                 :            : 
    1000         [ +  + ]:          5 :     for (i = 0; i < n_conditions; i++) {
    1001                 :          4 :         ovsdb_condition_destroy(&conditions[i]);
    1002                 :            :     }
    1003                 :          1 :     free(conditions);
    1004                 :          1 :     ovsdb_table_destroy(table); /* Also destroys 'ts'. */
    1005                 :          1 : }
    1006                 :            : 
    1007                 :            : static void
    1008                 :          5 : do_parse_mutations(struct ovs_cmdl_context *ctx)
    1009                 :            : {
    1010                 :            :     struct ovsdb_table_schema *ts;
    1011                 :            :     struct json *json;
    1012                 :          5 :     int exit_code = 0;
    1013                 :            :     int i;
    1014                 :            : 
    1015                 :          5 :     json = unbox_json(parse_json(ctx->argv[1]));
    1016                 :          5 :     check_ovsdb_error(ovsdb_table_schema_from_json(json, "mytable", &ts));
    1017                 :          5 :     json_destroy(json);
    1018                 :            : 
    1019         [ +  + ]:         61 :     for (i = 2; i < ctx->argc; i++) {
    1020                 :            :         struct ovsdb_mutation_set set;
    1021                 :            :         struct ovsdb_error *error;
    1022                 :            : 
    1023                 :         56 :         json = parse_json(ctx->argv[i]);
    1024                 :         56 :         error = ovsdb_mutation_set_from_json(ts, json, NULL, &set);
    1025         [ +  + ]:         56 :         if (!error) {
    1026                 :         29 :             print_and_free_json(ovsdb_mutation_set_to_json(&set));
    1027                 :            :         } else {
    1028                 :         27 :             char *s = ovsdb_error_to_string(error);
    1029                 :         27 :             ovs_error(0, "%s", s);
    1030                 :         27 :             free(s);
    1031                 :         27 :             ovsdb_error_destroy(error);
    1032                 :         27 :             exit_code = 1;
    1033                 :            :         }
    1034                 :         56 :         json_destroy(json);
    1035                 :            : 
    1036                 :         56 :         ovsdb_mutation_set_destroy(&set);
    1037                 :            :     }
    1038                 :          5 :     ovsdb_table_schema_destroy(ts);
    1039                 :            : 
    1040                 :          5 :     exit(exit_code);
    1041                 :            : }
    1042                 :            : 
    1043                 :            : static void
    1044                 :         14 : do_execute_mutations(struct ovs_cmdl_context *ctx)
    1045                 :            : {
    1046                 :            :     struct ovsdb_table_schema *ts;
    1047                 :            :     struct ovsdb_table *table;
    1048                 :            :     struct ovsdb_mutation_set *sets;
    1049                 :            :     size_t n_sets;
    1050                 :            :     struct ovsdb_row **rows;
    1051                 :            :     size_t n_rows;
    1052                 :            :     struct json *json;
    1053                 :            :     size_t i, j;
    1054                 :            : 
    1055                 :            :     /* Parse table schema, create table. */
    1056                 :         14 :     json = unbox_json(parse_json(ctx->argv[1]));
    1057                 :         14 :     check_ovsdb_error(ovsdb_table_schema_from_json(json, "mytable", &ts));
    1058                 :         14 :     json_destroy(json);
    1059                 :            : 
    1060                 :         14 :     table = ovsdb_table_create(ts);
    1061                 :            : 
    1062                 :            :     /* Parse mutations. */
    1063                 :         14 :     json = parse_json(ctx->argv[2]);
    1064         [ -  + ]:         14 :     if (json->type != JSON_ARRAY) {
    1065                 :          0 :         ovs_fatal(0, "MUTATION argument is not JSON array");
    1066                 :            :     }
    1067                 :         14 :     n_sets = json->u.array.n;
    1068                 :         14 :     sets = xmalloc(n_sets * sizeof *sets);
    1069         [ +  + ]:         93 :     for (i = 0; i < n_sets; i++) {
    1070                 :         79 :         check_ovsdb_error(ovsdb_mutation_set_from_json(ts,
    1071                 :         79 :                                                        json->u.array.elems[i],
    1072                 :         79 :                                                        NULL, &sets[i]));
    1073                 :            :     }
    1074                 :         14 :     json_destroy(json);
    1075                 :            : 
    1076                 :            :     /* Parse rows. */
    1077                 :         14 :     json = parse_json(ctx->argv[3]);
    1078         [ -  + ]:         14 :     if (json->type != JSON_ARRAY) {
    1079                 :          0 :         ovs_fatal(0, "ROW argument is not JSON array");
    1080                 :            :     }
    1081                 :         14 :     n_rows = json->u.array.n;
    1082                 :         14 :     rows = xmalloc(n_rows * sizeof *rows);
    1083         [ +  + ]:         66 :     for (i = 0; i < n_rows; i++) {
    1084                 :         52 :         rows[i] = ovsdb_row_create(table);
    1085                 :         52 :         check_ovsdb_error(ovsdb_row_from_json(rows[i], json->u.array.elems[i],
    1086                 :            :                                               NULL, NULL));
    1087                 :            :     }
    1088                 :         14 :     json_destroy(json);
    1089                 :            : 
    1090         [ +  + ]:         93 :     for (i = 0; i < n_sets; i++) {
    1091                 :         79 :         printf("mutation %2"PRIuSIZE":\n", i);
    1092         [ +  + ]:        386 :         for (j = 0; j < n_rows; j++) {
    1093                 :            :             struct ovsdb_error *error;
    1094                 :            :             struct ovsdb_row *row;
    1095                 :            : 
    1096                 :        307 :             row = ovsdb_row_clone(rows[j]);
    1097                 :        307 :             error = ovsdb_mutation_set_execute(row, &sets[i]);
    1098                 :            : 
    1099                 :        307 :             printf("row %"PRIuSIZE": ", j);
    1100         [ +  + ]:        307 :             if (error) {
    1101                 :         52 :                 print_and_free_ovsdb_error(error);
    1102                 :            :             } else {
    1103                 :            :                 struct ovsdb_column_set columns;
    1104                 :            :                 struct shash_node *node;
    1105                 :            : 
    1106                 :        255 :                 ovsdb_column_set_init(&columns);
    1107 [ +  + ][ -  + ]:       1020 :                 SHASH_FOR_EACH (node, &ts->columns) {
    1108                 :        765 :                     struct ovsdb_column *c = node->data;
    1109         [ +  + ]:        765 :                     if (!ovsdb_datum_equals(&row->fields[c->index],
    1110                 :        765 :                                             &rows[j]->fields[c->index],
    1111                 :        765 :                                             &c->type)) {
    1112                 :        156 :                         ovsdb_column_set_add(&columns, c);
    1113                 :            :                     }
    1114                 :            :                 }
    1115         [ +  + ]:        255 :                 if (columns.n_columns) {
    1116                 :        156 :                     print_and_free_json(ovsdb_row_to_json(row, &columns));
    1117                 :            :                 } else {
    1118                 :         99 :                     printf("no change\n");
    1119                 :            :                 }
    1120                 :        255 :                 ovsdb_column_set_destroy(&columns);
    1121                 :            :             }
    1122                 :        307 :             ovsdb_row_destroy(row);
    1123                 :            :         }
    1124                 :         79 :         printf("\n");
    1125                 :            :     }
    1126                 :            : 
    1127         [ +  + ]:         93 :     for (i = 0; i < n_sets; i++) {
    1128                 :         79 :         ovsdb_mutation_set_destroy(&sets[i]);
    1129                 :            :     }
    1130                 :         14 :     free(sets);
    1131         [ +  + ]:         66 :     for (i = 0; i < n_rows; i++) {
    1132                 :         52 :         ovsdb_row_destroy(rows[i]);
    1133                 :            :     }
    1134                 :         14 :     free(rows);
    1135                 :         14 :     ovsdb_table_destroy(table); /* Also destroys 'ts'. */
    1136                 :         14 : }
    1137                 :            : 
    1138                 :            : /* Inserts a row, without bothering to update metadata such as refcounts. */
    1139                 :            : static void
    1140                 :         46 : put_row(struct ovsdb_table *table, struct ovsdb_row *row)
    1141                 :            : {
    1142                 :         46 :     const struct uuid *uuid = ovsdb_row_get_uuid(row);
    1143         [ +  - ]:         46 :     if (!ovsdb_table_get_row(table, uuid)) {
    1144                 :         46 :         hmap_insert(&table->rows, &row->hmap_node, uuid_hash(uuid));
    1145                 :            :     }
    1146                 :         46 : }
    1147                 :            : 
    1148                 :            : struct do_query_cbdata {
    1149                 :            :     struct uuid *row_uuids;
    1150                 :            :     int *counts;
    1151                 :            :     size_t n_rows;
    1152                 :            : };
    1153                 :            : 
    1154                 :            : static bool
    1155                 :        557 : do_query_cb(const struct ovsdb_row *row, void *cbdata_)
    1156                 :            : {
    1157                 :        557 :     struct do_query_cbdata *cbdata = cbdata_;
    1158                 :            :     size_t i;
    1159                 :            : 
    1160         [ +  + ]:       6498 :     for (i = 0; i < cbdata->n_rows; i++) {
    1161         [ +  + ]:       5941 :         if (uuid_equals(ovsdb_row_get_uuid(row), &cbdata->row_uuids[i])) {
    1162                 :        557 :             cbdata->counts[i]++;
    1163                 :            :         }
    1164                 :            :     }
    1165                 :            : 
    1166                 :        557 :     return true;
    1167                 :            : }
    1168                 :            : 
    1169                 :            : static void
    1170                 :          4 : do_query(struct ovs_cmdl_context *ctx)
    1171                 :            : {
    1172                 :            :     struct do_query_cbdata cbdata;
    1173                 :            :     struct ovsdb_table_schema *ts;
    1174                 :            :     struct ovsdb_table *table;
    1175                 :            :     struct json *json;
    1176                 :          4 :     int exit_code = 0;
    1177                 :            :     size_t i;
    1178                 :            : 
    1179                 :            :     /* Parse table schema, create table. */
    1180                 :          4 :     json = unbox_json(parse_json(ctx->argv[1]));
    1181                 :          4 :     check_ovsdb_error(ovsdb_table_schema_from_json(json, "mytable", &ts));
    1182                 :          4 :     json_destroy(json);
    1183                 :            : 
    1184                 :          4 :     table = ovsdb_table_create(ts);
    1185                 :            : 
    1186                 :            :     /* Parse rows, add to table. */
    1187                 :          4 :     json = parse_json(ctx->argv[2]);
    1188         [ -  + ]:          4 :     if (json->type != JSON_ARRAY) {
    1189                 :          0 :         ovs_fatal(0, "ROW argument is not JSON array");
    1190                 :            :     }
    1191                 :          4 :     cbdata.n_rows = json->u.array.n;
    1192                 :          4 :     cbdata.row_uuids = xmalloc(cbdata.n_rows * sizeof *cbdata.row_uuids);
    1193                 :          4 :     cbdata.counts = xmalloc(cbdata.n_rows * sizeof *cbdata.counts);
    1194         [ +  + ]:         40 :     for (i = 0; i < cbdata.n_rows; i++) {
    1195                 :         36 :         struct ovsdb_row *row = ovsdb_row_create(table);
    1196                 :         36 :         uuid_generate(ovsdb_row_get_uuid_rw(row));
    1197                 :         36 :         check_ovsdb_error(ovsdb_row_from_json(row, json->u.array.elems[i],
    1198                 :            :                                               NULL, NULL));
    1199         [ -  + ]:         36 :         if (ovsdb_table_get_row(table, ovsdb_row_get_uuid(row))) {
    1200                 :          0 :             ovs_fatal(0, "duplicate UUID "UUID_FMT" in table",
    1201                 :          0 :                       UUID_ARGS(ovsdb_row_get_uuid(row)));
    1202                 :            :         }
    1203                 :         36 :         cbdata.row_uuids[i] = *ovsdb_row_get_uuid(row);
    1204                 :         36 :         put_row(table, row);
    1205                 :            :     }
    1206                 :          4 :     json_destroy(json);
    1207                 :            : 
    1208                 :            :     /* Parse conditions and execute queries. */
    1209                 :          4 :     json = parse_json(ctx->argv[3]);
    1210         [ -  + ]:          4 :     if (json->type != JSON_ARRAY) {
    1211                 :          0 :         ovs_fatal(0, "CONDITION argument is not JSON array");
    1212                 :            :     }
    1213         [ +  + ]:        131 :     for (i = 0; i < json->u.array.n; i++) {
    1214                 :            :         struct ovsdb_condition cnd;
    1215                 :            :         size_t j;
    1216                 :            : 
    1217                 :        127 :         check_ovsdb_error(ovsdb_condition_from_json(ts, json->u.array.elems[i],
    1218                 :            :                                                     NULL, &cnd));
    1219                 :            : 
    1220                 :        127 :         memset(cbdata.counts, 0, cbdata.n_rows * sizeof *cbdata.counts);
    1221                 :        127 :         ovsdb_query(table, &cnd, do_query_cb, &cbdata);
    1222                 :            : 
    1223                 :        127 :         printf("query %2"PRIuSIZE":", i);
    1224         [ +  + ]:       1290 :         for (j = 0; j < cbdata.n_rows; j++) {
    1225         [ +  + ]:       1163 :             if (j % 5 == 0) {
    1226                 :        259 :                 putchar(' ');
    1227                 :            :             }
    1228         [ +  + ]:       1163 :             if (cbdata.counts[j]) {
    1229                 :        557 :                 printf("%d", cbdata.counts[j]);
    1230         [ -  + ]:        557 :                 if (cbdata.counts[j] > 1) {
    1231                 :            :                     /* Dup! */
    1232                 :        557 :                     exit_code = 1;
    1233                 :            :                 }
    1234                 :            :             } else {
    1235                 :        606 :                 putchar('-');
    1236                 :            :             }
    1237                 :            :         }
    1238                 :        127 :         putchar('\n');
    1239                 :            : 
    1240                 :        127 :         ovsdb_condition_destroy(&cnd);
    1241                 :            :     }
    1242                 :          4 :     json_destroy(json);
    1243                 :            : 
    1244                 :          4 :     ovsdb_table_destroy(table); /* Also destroys 'ts'. */
    1245                 :            : 
    1246                 :          4 :     exit(exit_code);
    1247                 :            : }
    1248                 :            : 
    1249                 :            : struct do_query_distinct_class {
    1250                 :            :     struct ovsdb_row *example;
    1251                 :            :     int count;
    1252                 :            : };
    1253                 :            : 
    1254                 :            : struct do_query_distinct_row {
    1255                 :            :     struct uuid uuid;
    1256                 :            :     struct do_query_distinct_class *class;
    1257                 :            : };
    1258                 :            : 
    1259                 :            : static void
    1260                 :          3 : do_query_distinct(struct ovs_cmdl_context *ctx)
    1261                 :            : {
    1262                 :            :     struct ovsdb_column_set columns;
    1263                 :            :     struct ovsdb_table_schema *ts;
    1264                 :            :     struct ovsdb_table *table;
    1265                 :            :     struct do_query_distinct_row *rows;
    1266                 :            :     size_t n_rows;
    1267                 :            :     struct do_query_distinct_class *classes;
    1268                 :            :     size_t n_classes;
    1269                 :            :     struct json *json;
    1270                 :          3 :     int exit_code = 0;
    1271                 :            :     size_t i;
    1272                 :            : 
    1273                 :            :     /* Parse table schema, create table. */
    1274                 :          3 :     json = unbox_json(parse_json(ctx->argv[1]));
    1275                 :          3 :     check_ovsdb_error(ovsdb_table_schema_from_json(json, "mytable", &ts));
    1276                 :          3 :     json_destroy(json);
    1277                 :            : 
    1278                 :          3 :     table = ovsdb_table_create(ts);
    1279                 :            : 
    1280                 :            :     /* Parse column set. */
    1281                 :          3 :     json = parse_json(ctx->argv[4]);
    1282                 :          3 :     check_ovsdb_error(ovsdb_column_set_from_json(json, table->schema,
    1283                 :            :                                                  &columns));
    1284                 :          2 :     json_destroy(json);
    1285                 :            : 
    1286                 :            :     /* Parse rows, add to table. */
    1287                 :          2 :     json = parse_json(ctx->argv[2]);
    1288         [ -  + ]:          2 :     if (json->type != JSON_ARRAY) {
    1289                 :          0 :         ovs_fatal(0, "ROW argument is not JSON array");
    1290                 :            :     }
    1291                 :          2 :     n_rows = json->u.array.n;
    1292                 :          2 :     rows = xmalloc(n_rows * sizeof *rows);
    1293                 :          2 :     classes = xmalloc(n_rows * sizeof *classes);
    1294                 :          2 :     n_classes = 0;
    1295         [ +  + ]:         12 :     for (i = 0; i < n_rows; i++) {
    1296                 :            :         struct ovsdb_row *row;
    1297                 :            :         size_t j;
    1298                 :            : 
    1299                 :            :         /* Parse row. */
    1300                 :         10 :         row = ovsdb_row_create(table);
    1301                 :         10 :         uuid_generate(ovsdb_row_get_uuid_rw(row));
    1302                 :         10 :         check_ovsdb_error(ovsdb_row_from_json(row, json->u.array.elems[i],
    1303                 :            :                                               NULL, NULL));
    1304                 :            : 
    1305                 :            :         /* Initialize row and find equivalence class. */
    1306                 :         10 :         rows[i].uuid = *ovsdb_row_get_uuid(row);
    1307                 :         10 :         rows[i].class = NULL;
    1308         [ +  + ]:         22 :         for (j = 0; j < n_classes; j++) {
    1309         [ +  + ]:         15 :             if (ovsdb_row_equal_columns(row, classes[j].example, &columns)) {
    1310                 :          3 :                 rows[i].class = &classes[j];
    1311                 :          3 :                 break;
    1312                 :            :             }
    1313                 :            :         }
    1314         [ +  + ]:         10 :         if (!rows[i].class) {
    1315                 :          7 :             rows[i].class = &classes[n_classes];
    1316                 :          7 :             classes[n_classes].example = ovsdb_row_clone(row);
    1317                 :          7 :             n_classes++;
    1318                 :            :         }
    1319                 :            : 
    1320                 :            :         /* Add row to table. */
    1321         [ -  + ]:         10 :         if (ovsdb_table_get_row(table, ovsdb_row_get_uuid(row))) {
    1322                 :          0 :             ovs_fatal(0, "duplicate UUID "UUID_FMT" in table",
    1323                 :          0 :                       UUID_ARGS(ovsdb_row_get_uuid(row)));
    1324                 :            :         }
    1325                 :         10 :         put_row(table, row);
    1326                 :            : 
    1327                 :            :     }
    1328                 :          2 :     json_destroy(json);
    1329                 :            : 
    1330                 :            :     /* Parse conditions and execute queries. */
    1331                 :          2 :     json = parse_json(ctx->argv[3]);
    1332         [ -  + ]:          2 :     if (json->type != JSON_ARRAY) {
    1333                 :          0 :         ovs_fatal(0, "CONDITION argument is not JSON array");
    1334                 :            :     }
    1335         [ +  + ]:         58 :     for (i = 0; i < json->u.array.n; i++) {
    1336                 :            :         struct ovsdb_row_set results;
    1337                 :            :         struct ovsdb_condition cnd;
    1338                 :            :         size_t j;
    1339                 :            : 
    1340                 :         56 :         check_ovsdb_error(ovsdb_condition_from_json(ts, json->u.array.elems[i],
    1341                 :            :                                                     NULL, &cnd));
    1342                 :            : 
    1343         [ +  + ]:        252 :         for (j = 0; j < n_classes; j++) {
    1344                 :        196 :             classes[j].count = 0;
    1345                 :            :         }
    1346                 :         56 :         ovsdb_row_set_init(&results);
    1347                 :         56 :         ovsdb_query_distinct(table, &cnd, &columns, &results);
    1348         [ +  + ]:        159 :         for (j = 0; j < results.n_rows; j++) {
    1349                 :            :             size_t k;
    1350                 :            : 
    1351         [ +  + ]:        618 :             for (k = 0; k < n_rows; k++) {
    1352         [ +  + ]:        515 :                 if (uuid_equals(ovsdb_row_get_uuid(results.rows[j]),
    1353                 :        515 :                                 &rows[k].uuid)) {
    1354                 :        103 :                     rows[k].class->count++;
    1355                 :            :                 }
    1356                 :            :             }
    1357                 :            :         }
    1358                 :         56 :         ovsdb_row_set_destroy(&results);
    1359                 :            : 
    1360                 :         56 :         printf("query %2"PRIuSIZE":", i);
    1361         [ +  + ]:        336 :         for (j = 0; j < n_rows; j++) {
    1362                 :        280 :             int count = rows[j].class->count;
    1363                 :            : 
    1364         [ +  + ]:        280 :             if (j % 5 == 0) {
    1365                 :         56 :                 putchar(' ');
    1366                 :            :             }
    1367         [ -  + ]:        280 :             if (count > 1) {
    1368                 :            :                 /* Dup! */
    1369                 :          0 :                 printf("%d", count);
    1370                 :          0 :                 exit_code = 1;
    1371         [ +  + ]:        280 :             } else if (count == 1) {
    1372                 :        162 :                 putchar("abcdefghijklmnopqrstuvwxyz"[rows[j].class - classes]);
    1373                 :            :             } else {
    1374                 :        118 :                 putchar('-');
    1375                 :            :             }
    1376                 :            :         }
    1377                 :         56 :         putchar('\n');
    1378                 :            : 
    1379                 :         56 :         ovsdb_condition_destroy(&cnd);
    1380                 :            :     }
    1381                 :          2 :     json_destroy(json);
    1382                 :            : 
    1383         [ +  + ]:          9 :     for (i = 0; i < n_classes; i++) {
    1384                 :          7 :         ovsdb_row_destroy(classes[i].example);
    1385                 :            :     }
    1386                 :            : 
    1387                 :          2 :     ovsdb_table_destroy(table); /* Also destroys 'ts'. */
    1388                 :            : 
    1389                 :          2 :     free(rows);
    1390                 :          2 :     free(classes);
    1391                 :          2 :     exit(exit_code);
    1392                 :            : }
    1393                 :            : 
    1394                 :            : static void
    1395                 :          6 : do_parse_schema(struct ovs_cmdl_context *ctx)
    1396                 :            : {
    1397                 :            :     struct ovsdb_schema *schema;
    1398                 :            :     struct json *json;
    1399                 :            : 
    1400                 :          6 :     json = parse_json(ctx->argv[1]);
    1401                 :          6 :     check_ovsdb_error(ovsdb_schema_from_json(json, &schema));
    1402                 :          4 :     json_destroy(json);
    1403                 :          4 :     print_and_free_json(ovsdb_schema_to_json(schema));
    1404                 :          4 :     ovsdb_schema_destroy(schema);
    1405                 :          4 : }
    1406                 :            : 
    1407                 :            : static void
    1408                 :         30 : do_execute__(struct ovs_cmdl_context *ctx, bool ro)
    1409                 :            : {
    1410                 :            :     struct ovsdb_schema *schema;
    1411                 :            :     struct json *json;
    1412                 :            :     struct ovsdb *db;
    1413                 :            :     int i;
    1414                 :            : 
    1415                 :            :     /* Create database. */
    1416                 :         30 :     json = parse_json(ctx->argv[1]);
    1417                 :         30 :     check_ovsdb_error(ovsdb_schema_from_json(json, &schema));
    1418                 :         30 :     json_destroy(json);
    1419                 :         30 :     db = ovsdb_create(schema);
    1420                 :            : 
    1421         [ +  + ]:        135 :     for (i = 2; i < ctx->argc; i++) {
    1422                 :            :         struct json *params, *result;
    1423                 :            :         char *s;
    1424                 :            : 
    1425                 :        105 :         params = parse_json(ctx->argv[i]);
    1426                 :        105 :         result = ovsdb_execute(db, NULL, params, ro,  0, NULL);
    1427                 :        105 :         s = json_to_string(result, JSSF_SORT);
    1428                 :        105 :         printf("%s\n", s);
    1429                 :        105 :         free(s);
    1430                 :        105 :         json_destroy(params);
    1431                 :        105 :         json_destroy(result);
    1432                 :            :     }
    1433                 :            : 
    1434                 :         30 :     ovsdb_destroy(db);
    1435                 :         30 : }
    1436                 :            : 
    1437                 :            : static void
    1438                 :          2 : do_execute_ro(struct ovs_cmdl_context *ctx)
    1439                 :            : {
    1440                 :          2 :     do_execute__(ctx, true);
    1441                 :          2 : }
    1442                 :            : 
    1443                 :            : static void
    1444                 :         28 : do_execute(struct ovs_cmdl_context *ctx)
    1445                 :            : {
    1446                 :         28 :     do_execute__(ctx, false);
    1447                 :         28 : }
    1448                 :            : 
    1449                 :            : struct test_trigger {
    1450                 :            :     struct ovsdb_trigger trigger;
    1451                 :            :     int number;
    1452                 :            : };
    1453                 :            : 
    1454                 :            : static void
    1455                 :         14 : do_trigger_dump(struct test_trigger *t, long long int now, const char *title)
    1456                 :            : {
    1457                 :            :     struct json *result;
    1458                 :            :     char *s;
    1459                 :            : 
    1460                 :         14 :     result = ovsdb_trigger_steal_result(&t->trigger);
    1461                 :         14 :     s = json_to_string(result, JSSF_SORT);
    1462                 :         14 :     printf("t=%lld: trigger %d (%s): %s\n", now, t->number, title, s);
    1463                 :         14 :     free(s);
    1464                 :         14 :     json_destroy(result);
    1465                 :         14 :     ovsdb_trigger_destroy(&t->trigger);
    1466                 :         14 :     free(t);
    1467                 :         14 : }
    1468                 :            : 
    1469                 :            : static void
    1470                 :          5 : do_trigger(struct ovs_cmdl_context *ctx)
    1471                 :            : {
    1472                 :            :     struct ovsdb_schema *schema;
    1473                 :            :     struct ovsdb_session session;
    1474                 :            :     struct ovsdb_server server;
    1475                 :            :     struct json *json;
    1476                 :            :     struct ovsdb *db;
    1477                 :            :     long long int now;
    1478                 :            :     int number;
    1479                 :            :     int i;
    1480                 :            : 
    1481                 :            :     /* Create database. */
    1482                 :          5 :     json = parse_json(ctx->argv[1]);
    1483                 :          5 :     check_ovsdb_error(ovsdb_schema_from_json(json, &schema));
    1484                 :          5 :     json_destroy(json);
    1485                 :          5 :     db = ovsdb_create(schema);
    1486                 :            : 
    1487                 :          5 :     ovsdb_server_init(&server);
    1488                 :          5 :     ovsdb_server_add_db(&server, db);
    1489                 :          5 :     ovsdb_session_init(&session, &server);
    1490                 :            : 
    1491                 :          5 :     now = 0;
    1492                 :          5 :     number = 0;
    1493         [ +  + ]:         28 :     for (i = 2; i < ctx->argc; i++) {
    1494                 :         23 :         struct json *params = parse_json(ctx->argv[i]);
    1495         [ +  - ]:         23 :         if (params->type == JSON_ARRAY
    1496         [ +  + ]:         23 :             && json_array(params)->n == 2
    1497         [ +  - ]:         15 :             && json_array(params)->elems[0]->type == JSON_STRING
    1498         [ +  + ]:         15 :             && !strcmp(json_string(json_array(params)->elems[0]), "advance")
    1499         [ +  - ]:          9 :             && json_array(params)->elems[1]->type == JSON_INTEGER) {
    1500                 :          9 :             now += json_integer(json_array(params)->elems[1]);
    1501                 :          9 :             json_destroy(params);
    1502                 :            :         } else {
    1503                 :         14 :             struct test_trigger *t = xmalloc(sizeof *t);
    1504                 :         14 :             ovsdb_trigger_init(&session, db, &t->trigger, params, now, false);
    1505                 :         14 :             t->number = number++;
    1506         [ +  + ]:         14 :             if (ovsdb_trigger_is_complete(&t->trigger)) {
    1507                 :          9 :                 do_trigger_dump(t, now, "immediate");
    1508                 :            :             } else {
    1509                 :          5 :                 printf("t=%lld: new trigger %d\n", now, t->number);
    1510                 :            :             }
    1511                 :            :         }
    1512                 :            : 
    1513                 :         23 :         ovsdb_trigger_run(db, now);
    1514         [ +  + ]:         28 :         while (!ovs_list_is_empty(&session.completions)) {
    1515                 :          5 :             do_trigger_dump(CONTAINER_OF(ovs_list_pop_front(&session.completions),
    1516                 :            :                                          struct test_trigger, trigger.node),
    1517                 :            :                             now, "delayed");
    1518                 :            :         }
    1519                 :            : 
    1520                 :         23 :         ovsdb_trigger_wait(db, now);
    1521                 :         23 :         poll_immediate_wake();
    1522                 :         23 :         poll_block();
    1523                 :            :     }
    1524                 :            : 
    1525                 :          5 :     ovsdb_server_destroy(&server);
    1526                 :          5 :     ovsdb_destroy(db);
    1527                 :          5 : }
    1528                 :            : 
    1529                 :            : static void
    1530                 :          0 : do_help(struct ovs_cmdl_context *ctx OVS_UNUSED)
    1531                 :            : {
    1532                 :          0 :     usage();
    1533                 :            : }
    1534                 :            : 
    1535                 :            : /* "transact" command. */
    1536                 :            : 
    1537                 :            : static struct ovsdb *do_transact_db;
    1538                 :            : static struct ovsdb_txn *do_transact_txn;
    1539                 :            : static struct ovsdb_table *do_transact_table;
    1540                 :            : 
    1541                 :            : static void
    1542                 :         21 : do_transact_commit(struct ovs_cmdl_context *ctx OVS_UNUSED)
    1543                 :            : {
    1544                 :         21 :     ovsdb_error_destroy(ovsdb_txn_commit(do_transact_txn, false));
    1545                 :         21 :     do_transact_txn = NULL;
    1546                 :         21 : }
    1547                 :            : 
    1548                 :            : static void
    1549                 :         10 : do_transact_abort(struct ovs_cmdl_context *ctx OVS_UNUSED)
    1550                 :            : {
    1551                 :         10 :     ovsdb_txn_abort(do_transact_txn);
    1552                 :         10 :     do_transact_txn = NULL;
    1553                 :         10 : }
    1554                 :            : 
    1555                 :            : static void
    1556                 :         55 : uuid_from_integer(int integer, struct uuid *uuid)
    1557                 :            : {
    1558                 :         55 :     uuid_zero(uuid);
    1559                 :         55 :     uuid->parts[3] = integer;
    1560                 :         55 : }
    1561                 :            : 
    1562                 :            : static const struct ovsdb_row *
    1563                 :         22 : do_transact_find_row(const char *uuid_string)
    1564                 :            : {
    1565                 :            :     const struct ovsdb_row *row;
    1566                 :            :     struct uuid uuid;
    1567                 :            : 
    1568                 :         22 :     uuid_from_integer(atoi(uuid_string), &uuid);
    1569                 :         22 :     row = ovsdb_table_get_row(do_transact_table, &uuid);
    1570         [ -  + ]:         22 :     if (!row) {
    1571                 :          0 :         ovs_fatal(0, "table does not contain row with UUID "UUID_FMT,
    1572                 :          0 :                   UUID_ARGS(&uuid));
    1573                 :            :     }
    1574                 :         22 :     return row;
    1575                 :            : }
    1576                 :            : 
    1577                 :            : static void
    1578                 :         82 : do_transact_set_integer(struct ovsdb_row *row, const char *column_name,
    1579                 :            :                         int integer)
    1580                 :            : {
    1581         [ +  + ]:         82 :     if (integer != -1) {
    1582                 :            :         const struct ovsdb_column *column;
    1583                 :            : 
    1584                 :         78 :         column = ovsdb_table_schema_get_column(do_transact_table->schema,
    1585                 :            :                                                column_name);
    1586                 :         78 :         row->fields[column->index].keys[0].integer = integer;
    1587                 :            :     }
    1588                 :         82 : }
    1589                 :            : 
    1590                 :            : static int
    1591                 :        144 : do_transact_get_integer(const struct ovsdb_row *row, const char *column_name)
    1592                 :            : {
    1593                 :            :     const struct ovsdb_column *column;
    1594                 :            : 
    1595                 :        144 :     column = ovsdb_table_schema_get_column(do_transact_table->schema,
    1596                 :            :                                            column_name);
    1597                 :        144 :     return row->fields[column->index].keys[0].integer;
    1598                 :            : }
    1599                 :            : 
    1600                 :            : static void
    1601                 :         41 : do_transact_set_i_j(struct ovsdb_row *row,
    1602                 :            :                     const char *i_string, const char *j_string)
    1603                 :            : {
    1604                 :         41 :     do_transact_set_integer(row, "i", atoi(i_string));
    1605                 :         41 :     do_transact_set_integer(row, "j", atoi(j_string));
    1606                 :         41 : }
    1607                 :            : 
    1608                 :            : static void
    1609                 :         33 : do_transact_insert(struct ovs_cmdl_context *ctx)
    1610                 :            : {
    1611                 :            :     struct ovsdb_row *row;
    1612                 :            :     struct uuid *uuid;
    1613                 :            : 
    1614                 :         33 :     row = ovsdb_row_create(do_transact_table);
    1615                 :            : 
    1616                 :            :     /* Set UUID. */
    1617                 :         33 :     uuid = ovsdb_row_get_uuid_rw(row);
    1618                 :         33 :     uuid_from_integer(atoi(ctx->argv[1]), uuid);
    1619         [ -  + ]:         33 :     if (ovsdb_table_get_row(do_transact_table, uuid)) {
    1620                 :          0 :         ovs_fatal(0, "table already contains row with UUID "UUID_FMT,
    1621                 :          0 :                   UUID_ARGS(uuid));
    1622                 :            :     }
    1623                 :            : 
    1624                 :         33 :     do_transact_set_i_j(row, ctx->argv[2], ctx->argv[3]);
    1625                 :            : 
    1626                 :            :     /* Insert row. */
    1627                 :         33 :     ovsdb_txn_row_insert(do_transact_txn, row);
    1628                 :         33 : }
    1629                 :            : 
    1630                 :            : static void
    1631                 :         14 : do_transact_delete(struct ovs_cmdl_context *ctx)
    1632                 :            : {
    1633                 :         14 :     const struct ovsdb_row *row = do_transact_find_row(ctx->argv[1]);
    1634                 :         14 :     ovsdb_txn_row_delete(do_transact_txn, row);
    1635                 :         14 : }
    1636                 :            : 
    1637                 :            : static void
    1638                 :          8 : do_transact_modify(struct ovs_cmdl_context *ctx)
    1639                 :            : {
    1640                 :            :     const struct ovsdb_row *row_ro;
    1641                 :            :     struct ovsdb_row *row_rw;
    1642                 :            : 
    1643                 :          8 :     row_ro = do_transact_find_row(ctx->argv[1]);
    1644                 :          8 :     row_rw = ovsdb_txn_row_modify(do_transact_txn, row_ro);
    1645                 :          8 :     do_transact_set_i_j(row_rw, ctx->argv[2], ctx->argv[3]);
    1646                 :          8 : }
    1647                 :            : 
    1648                 :            : static int
    1649                 :         33 : compare_rows_by_uuid(const void *a_, const void *b_)
    1650                 :            : {
    1651                 :         33 :     struct ovsdb_row *const *ap = a_;
    1652                 :         33 :     struct ovsdb_row *const *bp = b_;
    1653                 :            : 
    1654                 :         33 :     return uuid_compare_3way(ovsdb_row_get_uuid(*ap), ovsdb_row_get_uuid(*bp));
    1655                 :            : }
    1656                 :            : 
    1657                 :            : static void
    1658                 :         45 : do_transact_print(struct ovs_cmdl_context *ctx OVS_UNUSED)
    1659                 :            : {
    1660                 :            :     const struct ovsdb_row **rows;
    1661                 :            :     const struct ovsdb_row *row;
    1662                 :            :     size_t n_rows;
    1663                 :            :     size_t i;
    1664                 :            : 
    1665                 :         45 :     n_rows = hmap_count(&do_transact_table->rows);
    1666                 :         45 :     rows = xmalloc(n_rows * sizeof *rows);
    1667                 :         45 :     i = 0;
    1668 [ +  + ][ -  + ]:        117 :     HMAP_FOR_EACH (row, hmap_node, &do_transact_table->rows) {
    1669                 :         72 :         rows[i++] = row;
    1670                 :            :     }
    1671         [ -  + ]:         45 :     assert(i == n_rows);
    1672                 :            : 
    1673                 :         45 :     qsort(rows, n_rows, sizeof *rows, compare_rows_by_uuid);
    1674                 :            : 
    1675         [ +  + ]:        117 :     for (i = 0; i < n_rows; i++) {
    1676                 :        144 :         printf("\n%"PRId32": i=%d, j=%d",
    1677                 :         72 :                ovsdb_row_get_uuid(rows[i])->parts[3],
    1678                 :         72 :                do_transact_get_integer(rows[i], "i"),
    1679                 :         72 :                do_transact_get_integer(rows[i], "j"));
    1680                 :            :     }
    1681                 :            : 
    1682                 :         45 :     free(rows);
    1683                 :         45 : }
    1684                 :            : 
    1685                 :            : static void
    1686                 :         15 : do_transact(struct ovs_cmdl_context *ctx)
    1687                 :            : {
    1688                 :            :     static const struct ovs_cmdl_command do_transact_commands[] = {
    1689                 :            :         { "commit", NULL, 0, 0, do_transact_commit, OVS_RO },
    1690                 :            :         { "abort", NULL, 0, 0, do_transact_abort, OVS_RO },
    1691                 :            :         { "insert", NULL, 2, 3, do_transact_insert, OVS_RO },
    1692                 :            :         { "delete", NULL, 1, 1, do_transact_delete, OVS_RO },
    1693                 :            :         { "modify", NULL, 2, 3, do_transact_modify, OVS_RO },
    1694                 :            :         { "print", NULL, 0, 0, do_transact_print, OVS_RO },
    1695                 :            :         { NULL, NULL, 0, 0, NULL, OVS_RO },
    1696                 :            :     };
    1697                 :            : 
    1698                 :            :     struct ovsdb_schema *schema;
    1699                 :            :     struct json *json;
    1700                 :            :     int i;
    1701                 :            : 
    1702                 :            :     /* Create table. */
    1703                 :         15 :     json = parse_json("{\"name\": \"testdb\", "
    1704                 :            :                       " \"tables\": "
    1705                 :            :                       "  {\"mytable\": "
    1706                 :            :                       "    {\"columns\": "
    1707                 :            :                       "      {\"i\": {\"type\": \"integer\"}, "
    1708                 :            :                       "       \"j\": {\"type\": \"integer\"}}}}}");
    1709                 :         15 :     check_ovsdb_error(ovsdb_schema_from_json(json, &schema));
    1710                 :         15 :     json_destroy(json);
    1711                 :         15 :     do_transact_db = ovsdb_create(schema);
    1712                 :         15 :     do_transact_table = ovsdb_get_table(do_transact_db, "mytable");
    1713         [ -  + ]:         15 :     assert(do_transact_table != NULL);
    1714                 :            : 
    1715         [ +  + ]:        146 :     for (i = 1; i < ctx->argc; i++) {
    1716                 :            :         struct json *command;
    1717                 :            :         size_t n_args;
    1718                 :            :         char **args;
    1719                 :            :         int j;
    1720                 :        131 :         struct ovs_cmdl_context transact_ctx = { .argc = 0, };
    1721                 :            : 
    1722                 :        131 :         command = parse_json(ctx->argv[i]);
    1723         [ -  + ]:        131 :         if (command->type != JSON_ARRAY) {
    1724                 :          0 :             ovs_fatal(0, "transaction %d must be JSON array "
    1725                 :            :                       "with at least 1 element", i);
    1726                 :            :         }
    1727                 :            : 
    1728                 :        131 :         n_args = command->u.array.n;
    1729                 :        131 :         args = xmalloc((n_args + 1) * sizeof *args);
    1730         [ +  + ]:        399 :         for (j = 0; j < n_args; j++) {
    1731                 :        268 :             struct json *s = command->u.array.elems[j];
    1732         [ -  + ]:        268 :             if (s->type != JSON_STRING) {
    1733                 :          0 :                 ovs_fatal(0, "transaction %d argument %d must be JSON string",
    1734                 :            :                           i, j);
    1735                 :            :             }
    1736                 :        268 :             args[j] = xstrdup(json_string(s));
    1737                 :            :         }
    1738                 :        131 :         args[n_args] = NULL;
    1739                 :            : 
    1740         [ +  + ]:        131 :         if (!do_transact_txn) {
    1741                 :         46 :             do_transact_txn = ovsdb_txn_create(do_transact_db);
    1742                 :            :         }
    1743                 :            : 
    1744         [ +  + ]:        399 :         for (j = 0; j < n_args; j++) {
    1745         [ +  + ]:        268 :             if (j) {
    1746                 :        137 :                 putchar(' ');
    1747                 :            :             }
    1748                 :        268 :             fputs(args[j], stdout);
    1749                 :            :         }
    1750                 :        131 :         fputs(":", stdout);
    1751                 :        131 :         transact_ctx.argc = n_args;
    1752                 :        131 :         transact_ctx.argv = args;
    1753                 :        131 :         ovs_cmdl_run_command(&transact_ctx, do_transact_commands);
    1754                 :        131 :         putchar('\n');
    1755                 :            : 
    1756         [ +  + ]:        399 :         for (j = 0; j < n_args; j++) {
    1757                 :        268 :             free(args[j]);
    1758                 :            :         }
    1759                 :        131 :         free(args);
    1760                 :        131 :         json_destroy(command);
    1761                 :            :     }
    1762                 :         15 :     ovsdb_txn_abort(do_transact_txn);
    1763                 :         15 :     ovsdb_destroy(do_transact_db); /* Also destroys 'schema'. */
    1764                 :         15 : }
    1765                 :            : 
    1766                 :            : static int
    1767                 :         20 : compare_link1(const void *a_, const void *b_)
    1768                 :            : {
    1769                 :         20 :     const struct idltest_link1 *const *ap = a_;
    1770                 :         20 :     const struct idltest_link1 *const *bp = b_;
    1771                 :         20 :     const struct idltest_link1 *a = *ap;
    1772                 :         20 :     const struct idltest_link1 *b = *bp;
    1773                 :            : 
    1774         [ +  + ]:         20 :     return a->i < b->i ? -1 : a->i > b->i;
    1775                 :            : }
    1776                 :            : 
    1777                 :            : static void
    1778                 :         60 : print_idl_row_updated_simple(const struct idltest_simple *s, int step)
    1779                 :            : {
    1780                 :            :     size_t i;
    1781                 :         60 :     bool updated = false;
    1782                 :            : 
    1783         [ +  + ]:        660 :     for (i = 0; i < IDLTEST_SIMPLE_N_COLUMNS; i++) {
    1784         [ +  + ]:        600 :         if (idltest_simple_is_updated(s, i)) {
    1785         [ +  + ]:         47 :             if (!updated) {
    1786                 :         11 :                 printf("%03d: updated columns:", step);
    1787                 :         11 :                 updated = true;
    1788                 :            :             }
    1789                 :         47 :             printf(" %s", idltest_simple_columns[i].name);
    1790                 :            :         }
    1791                 :            :     }
    1792         [ +  + ]:         60 :     if (updated) {
    1793                 :         11 :         printf("\n");
    1794                 :            :     }
    1795                 :         60 : }
    1796                 :            : 
    1797                 :            : static void
    1798                 :         34 : print_idl_row_updated_link1(const struct idltest_link1 *l1, int step)
    1799                 :            : {
    1800                 :            :     size_t i;
    1801                 :         34 :     bool updated = false;
    1802                 :            : 
    1803         [ +  + ]:        170 :     for (i = 0; i < IDLTEST_LINK1_N_COLUMNS; i++) {
    1804         [ -  + ]:        136 :         if (idltest_link1_is_updated(l1, i)) {
    1805         [ #  # ]:          0 :             if (!updated) {
    1806                 :          0 :                 printf("%03d: updated columns:", step);
    1807                 :          0 :                 updated = true;
    1808                 :            :             }
    1809                 :          0 :             printf(" %s", idltest_link1_columns[i].name);
    1810                 :            :         }
    1811                 :            :     }
    1812         [ -  + ]:         34 :     if (updated) {
    1813                 :          0 :         printf("\n");
    1814                 :            :     }
    1815                 :         34 : }
    1816                 :            : 
    1817                 :            : static void
    1818                 :          2 : print_idl_row_updated_link2(const struct idltest_link2 *l2, int step)
    1819                 :            : {
    1820                 :            :     size_t i;
    1821                 :          2 :     bool updated = false;
    1822                 :            : 
    1823         [ +  + ]:          6 :     for (i = 0; i < IDLTEST_LINK2_N_COLUMNS; i++) {
    1824         [ -  + ]:          4 :         if (idltest_link2_is_updated(l2, i)) {
    1825         [ #  # ]:          0 :             if (!updated) {
    1826                 :          0 :                 printf("%03d: updated columns:", step);
    1827                 :          0 :                 updated = true;
    1828                 :            :             }
    1829                 :          0 :             printf(" %s", idltest_link2_columns[i].name);
    1830                 :            :         }
    1831                 :            :     }
    1832         [ -  + ]:          2 :     if (updated) {
    1833                 :          0 :         printf("\n");
    1834                 :            :     }
    1835                 :          2 : }
    1836                 :            : 
    1837                 :            : static void
    1838                 :         60 : print_idl_row_simple(const struct idltest_simple *s, int step)
    1839                 :            : {
    1840                 :            :     size_t i;
    1841                 :            : 
    1842         [ +  + ]:         60 :     printf("%03d: i=%"PRId64" r=%g b=%s s=%s u="UUID_FMT" ia=[",
    1843                 :         60 :            step, s->i, s->r, s->b ? "true" : "false",
    1844                 :        180 :            s->s, UUID_ARGS(&s->u));
    1845         [ +  + ]:        115 :     for (i = 0; i < s->n_ia; i++) {
    1846         [ +  + ]:         55 :         printf("%s%"PRId64, i ? " " : "", s->ia[i]);
    1847                 :            :     }
    1848                 :         60 :     printf("] ra=[");
    1849         [ +  + ]:         83 :     for (i = 0; i < s->n_ra; i++) {
    1850         [ -  + ]:         23 :         printf("%s%g", i ? " " : "", s->ra[i]);
    1851                 :            :     }
    1852                 :         60 :     printf("] ba=[");
    1853         [ +  + ]:         83 :     for (i = 0; i < s->n_ba; i++) {
    1854 [ +  + ][ -  + ]:         23 :         printf("%s%s", i ? " " : "", s->ba[i] ? "true" : "false");
    1855                 :            :     }
    1856                 :         60 :     printf("] sa=[");
    1857         [ +  + ]:         92 :     for (i = 0; i < s->n_sa; i++) {
    1858         [ +  + ]:         32 :         printf("%s%s", i ? " " : "", s->sa[i]);
    1859                 :            :     }
    1860                 :         60 :     printf("] ua=[");
    1861         [ +  + ]:         92 :     for (i = 0; i < s->n_ua; i++) {
    1862         [ +  + ]:         32 :         printf("%s"UUID_FMT, i ? " " : "", UUID_ARGS(&s->ua[i]));
    1863                 :            :     }
    1864                 :         60 :     printf("] uuid="UUID_FMT"\n", UUID_ARGS(&s->header_.uuid));
    1865                 :         60 :     print_idl_row_updated_simple(s, step);
    1866                 :         60 : }
    1867                 :            : 
    1868                 :            : static void
    1869                 :         34 : print_idl_row_link1(const struct idltest_link1 *l1, int step)
    1870                 :            : {
    1871                 :            :     struct idltest_link1 **links;
    1872                 :            :     size_t i;
    1873                 :            : 
    1874                 :         34 :     printf("%03d: i=%"PRId64" k=", step, l1->i);
    1875         [ +  - ]:         34 :     if (l1->k) {
    1876                 :         34 :         printf("%"PRId64, l1->k->i);
    1877                 :            :     }
    1878                 :         34 :     printf(" ka=[");
    1879                 :         34 :     links = xmemdup(l1->ka, l1->n_ka * sizeof *l1->ka);
    1880                 :         34 :     qsort(links, l1->n_ka, sizeof *links, compare_link1);
    1881         [ +  + ]:         54 :     for (i = 0; i < l1->n_ka; i++) {
    1882         [ +  + ]:         20 :         printf("%s%"PRId64, i ? " " : "", links[i]->i);
    1883                 :            :     }
    1884                 :         34 :     free(links);
    1885                 :         34 :     printf("] l2=");
    1886         [ +  + ]:         34 :     if (l1->l2) {
    1887                 :          1 :         printf("%"PRId64, l1->l2->i);
    1888                 :            :     }
    1889                 :         34 :     printf(" uuid="UUID_FMT"\n", UUID_ARGS(&l1->header_.uuid));
    1890                 :         34 :     print_idl_row_updated_link1(l1, step);
    1891                 :         34 : }
    1892                 :            : 
    1893                 :            : static void
    1894                 :          2 : print_idl_row_link2(const struct idltest_link2 *l2, int step)
    1895                 :            : {
    1896                 :          2 :     printf("%03d: i=%"PRId64" l1=", step, l2->i);
    1897         [ -  + ]:          2 :     if (l2->l1) {
    1898                 :          0 :         printf("%"PRId64, l2->l1->i);
    1899                 :            :     }
    1900                 :          2 :     printf(" uuid="UUID_FMT"\n", UUID_ARGS(&l2->header_.uuid));
    1901                 :          2 :     print_idl_row_updated_link2(l2, step);
    1902                 :          2 : }
    1903                 :            : 
    1904                 :            : static void
    1905                 :         61 : print_idl(struct ovsdb_idl *idl, int step)
    1906                 :            : {
    1907                 :            :     const struct idltest_simple *s;
    1908                 :            :     const struct idltest_link1 *l1;
    1909                 :            :     const struct idltest_link2 *l2;
    1910                 :         61 :     int n = 0;
    1911                 :            : 
    1912         [ +  + ]:        113 :     IDLTEST_SIMPLE_FOR_EACH (s, idl) {
    1913                 :         52 :         print_idl_row_simple(s, step);
    1914                 :         52 :         n++;
    1915                 :            :     }
    1916         [ +  + ]:         95 :     IDLTEST_LINK1_FOR_EACH (l1, idl) {
    1917                 :         34 :         print_idl_row_link1(l1, step);
    1918                 :         34 :         n++;
    1919                 :            :     }
    1920         [ +  + ]:         63 :     IDLTEST_LINK2_FOR_EACH (l2, idl) {
    1921                 :          2 :         print_idl_row_link2(l2, step);
    1922                 :          2 :         n++;
    1923                 :            :     }
    1924         [ +  + ]:         61 :     if (!n) {
    1925                 :         16 :         printf("%03d: empty\n", step);
    1926                 :            :     }
    1927                 :         61 : }
    1928                 :            : 
    1929                 :            : static void
    1930                 :          8 : print_idl_track(struct ovsdb_idl *idl, int step, unsigned int seqno)
    1931                 :            : {
    1932                 :            :     const struct idltest_simple *s;
    1933                 :            :     const struct idltest_link1 *l1;
    1934                 :            :     const struct idltest_link2 *l2;
    1935                 :          8 :     int n = 0;
    1936                 :            : 
    1937         [ +  + ]:         17 :     IDLTEST_SIMPLE_FOR_EACH_TRACKED (s, idl) {
    1938         [ +  + ]:          9 :         if (idltest_simple_row_get_seqno(s, OVSDB_IDL_CHANGE_DELETE) >= seqno) {
    1939                 :          1 :             printf("%03d: ##deleted## uuid="UUID_FMT"\n", step, UUID_ARGS(&s->header_.uuid));
    1940                 :            :         } else {
    1941                 :          8 :             print_idl_row_simple(s, step);
    1942                 :            :         }
    1943                 :          9 :         n++;
    1944                 :            :     }
    1945         [ -  + ]:          8 :     IDLTEST_LINK1_FOR_EACH_TRACKED (l1, idl) {
    1946         [ #  # ]:          0 :         if (idltest_simple_row_get_seqno(s, OVSDB_IDL_CHANGE_DELETE) >= seqno) {
    1947                 :          0 :             printf("%03d: ##deleted## uuid="UUID_FMT"\n", step, UUID_ARGS(&s->header_.uuid));
    1948                 :            :         } else {
    1949                 :          0 :             print_idl_row_link1(l1, step);
    1950                 :            :         }
    1951                 :          0 :         n++;
    1952                 :            :     }
    1953         [ -  + ]:          8 :     IDLTEST_LINK2_FOR_EACH_TRACKED (l2, idl) {
    1954         [ #  # ]:          0 :         if (idltest_simple_row_get_seqno(s, OVSDB_IDL_CHANGE_DELETE) >= seqno) {
    1955                 :          0 :             printf("%03d: ##deleted## uuid="UUID_FMT"\n", step, UUID_ARGS(&s->header_.uuid));
    1956                 :            :         } else {
    1957                 :          0 :             print_idl_row_link2(l2, step);
    1958                 :            :         }
    1959                 :          0 :         n++;
    1960                 :            :     }
    1961         [ +  + ]:          8 :     if (!n) {
    1962                 :          1 :         printf("%03d: empty\n", step);
    1963                 :            :     }
    1964                 :          8 : }
    1965                 :            : 
    1966                 :            : static void
    1967                 :        184 : parse_uuids(const struct json *json, struct ovsdb_symbol_table *symtab,
    1968                 :            :             size_t *n)
    1969                 :            : {
    1970                 :            :     struct uuid uuid;
    1971                 :            : 
    1972 [ +  + ][ +  + ]:        207 :     if (json->type == JSON_STRING && uuid_from_string(&uuid, json->u.string)) {
    1973                 :         23 :         char *name = xasprintf("#%"PRIuSIZE"#", *n);
    1974                 :         23 :         fprintf(stderr, "%s = "UUID_FMT"\n", name, UUID_ARGS(&uuid));
    1975                 :         23 :         ovsdb_symbol_table_put(symtab, name, &uuid, false);
    1976                 :         23 :         free(name);
    1977                 :         23 :         *n += 1;
    1978         [ +  + ]:        161 :     } else if (json->type == JSON_ARRAY) {
    1979                 :            :         size_t i;
    1980                 :            : 
    1981         [ +  + ]:        154 :         for (i = 0; i < json->u.array.n; i++) {
    1982                 :         95 :             parse_uuids(json->u.array.elems[i], symtab, n);
    1983                 :            :         }
    1984         [ +  + ]:        102 :     } else if (json->type == JSON_OBJECT) {
    1985                 :            :         const struct shash_node *node;
    1986                 :            : 
    1987 [ +  + ][ -  + ]:        102 :         SHASH_FOR_EACH (node, json_object(json)) {
    1988                 :         53 :             parse_uuids(node->data, symtab, n);
    1989                 :            :         }
    1990                 :            :     }
    1991                 :        184 : }
    1992                 :            : 
    1993                 :            : static void
    1994                 :        582 : substitute_uuids(struct json *json, const struct ovsdb_symbol_table *symtab)
    1995                 :            : {
    1996         [ +  + ]:        582 :     if (json->type == JSON_STRING) {
    1997                 :            :         const struct ovsdb_symbol *symbol;
    1998                 :            : 
    1999                 :        275 :         symbol = ovsdb_symbol_table_get(symtab, json->u.string);
    2000         [ +  + ]:        275 :         if (symbol) {
    2001                 :         12 :             free(json->u.string);
    2002                 :        275 :             json->u.string = xasprintf(UUID_FMT, UUID_ARGS(&symbol->uuid));
    2003                 :            :         }
    2004         [ +  + ]:        307 :     } else if (json->type == JSON_ARRAY) {
    2005                 :            :         size_t i;
    2006                 :            : 
    2007         [ +  + ]:        450 :         for (i = 0; i < json->u.array.n; i++) {
    2008                 :        289 :             substitute_uuids(json->u.array.elems[i], symtab);
    2009                 :            :         }
    2010         [ +  + ]:        146 :     } else if (json->type == JSON_OBJECT) {
    2011                 :            :         const struct shash_node *node;
    2012                 :            : 
    2013 [ +  + ][ -  + ]:        341 :         SHASH_FOR_EACH (node, json_object(json)) {
    2014                 :        257 :             substitute_uuids(node->data, symtab);
    2015                 :            :         }
    2016                 :            :     }
    2017                 :        582 : }
    2018                 :            : 
    2019                 :            : static const struct idltest_simple *
    2020                 :         18 : idltest_find_simple(struct ovsdb_idl *idl, int i)
    2021                 :            : {
    2022                 :            :     const struct idltest_simple *s;
    2023                 :            : 
    2024         [ +  - ]:         25 :     IDLTEST_SIMPLE_FOR_EACH (s, idl) {
    2025         [ +  + ]:         25 :         if (s->i == i) {
    2026                 :         18 :             return s;
    2027                 :            :         }
    2028                 :            :     }
    2029                 :          0 :     return NULL;
    2030                 :            : }
    2031                 :            : 
    2032                 :            : static void
    2033                 :         10 : idl_set(struct ovsdb_idl *idl, char *commands, int step)
    2034                 :            : {
    2035                 :         10 :     char *cmd, *save_ptr1 = NULL;
    2036                 :            :     struct ovsdb_idl_txn *txn;
    2037                 :            :     enum ovsdb_idl_txn_status status;
    2038                 :         10 :     bool increment = false;
    2039                 :            : 
    2040                 :         10 :     txn = ovsdb_idl_txn_create(idl);
    2041         [ +  + ]:         29 :     for (cmd = strtok_r(commands, ",", &save_ptr1); cmd;
    2042                 :         19 :          cmd = strtok_r(NULL, ",", &save_ptr1)) {
    2043                 :         21 :         char *save_ptr2 = NULL;
    2044                 :            :         char *name, *arg1, *arg2, *arg3;
    2045                 :            : 
    2046                 :         21 :         name = strtok_r(cmd, " ", &save_ptr2);
    2047                 :         21 :         arg1 = strtok_r(NULL, " ", &save_ptr2);
    2048                 :         21 :         arg2 = strtok_r(NULL, " ", &save_ptr2);
    2049                 :         21 :         arg3 = strtok_r(NULL, " ", &save_ptr2);
    2050                 :            : 
    2051         [ +  + ]:         21 :         if (!strcmp(name, "set")) {
    2052                 :            :             const struct idltest_simple *s;
    2053                 :            : 
    2054         [ -  + ]:         10 :             if (!arg3) {
    2055                 :          0 :                 ovs_fatal(0, "\"set\" command requires 3 arguments");
    2056                 :            :             }
    2057                 :            : 
    2058                 :         10 :             s = idltest_find_simple(idl, atoi(arg1));
    2059         [ -  + ]:         10 :             if (!s) {
    2060                 :          0 :                 ovs_fatal(0, "\"set\" command asks for nonexistent "
    2061                 :            :                           "i=%d", atoi(arg1));
    2062                 :            :             }
    2063                 :            : 
    2064         [ +  + ]:         10 :             if (!strcmp(arg2, "b")) {
    2065                 :          4 :                 idltest_simple_set_b(s, atoi(arg3));
    2066         [ -  + ]:          6 :             } else if (!strcmp(arg2, "s")) {
    2067                 :          0 :                 idltest_simple_set_s(s, arg3);
    2068         [ -  + ]:          6 :             } else if (!strcmp(arg2, "u")) {
    2069                 :            :                 struct uuid uuid;
    2070         [ #  # ]:          0 :                 if (!uuid_from_string(&uuid, arg3)) {
    2071                 :          0 :                     ovs_fatal(0, "\"%s\" is not a valid UUID", arg3);
    2072                 :            :                 }
    2073                 :          0 :                 idltest_simple_set_u(s, uuid);
    2074         [ +  - ]:          6 :             } else if (!strcmp(arg2, "r")) {
    2075                 :          6 :                 idltest_simple_set_r(s, atof(arg3));
    2076                 :            :             } else {
    2077                 :         10 :                 ovs_fatal(0, "\"set\" command asks for unknown column %s",
    2078                 :            :                           arg2);
    2079                 :            :             }
    2080         [ +  + ]:         11 :         } else if (!strcmp(name, "insert")) {
    2081                 :            :             struct idltest_simple *s;
    2082                 :            : 
    2083 [ +  - ][ -  + ]:          1 :             if (!arg1 || arg2) {
    2084                 :          0 :                 ovs_fatal(0, "\"insert\" command requires 1 argument");
    2085                 :            :             }
    2086                 :            : 
    2087                 :          1 :             s = idltest_simple_insert(txn);
    2088                 :          1 :             idltest_simple_set_i(s, atoi(arg1));
    2089         [ +  + ]:         10 :         } else if (!strcmp(name, "delete")) {
    2090                 :            :             const struct idltest_simple *s;
    2091                 :            : 
    2092 [ +  - ][ -  + ]:          1 :             if (!arg1 || arg2) {
    2093                 :          0 :                 ovs_fatal(0, "\"delete\" command requires 1 argument");
    2094                 :            :             }
    2095                 :            : 
    2096                 :          1 :             s = idltest_find_simple(idl, atoi(arg1));
    2097         [ -  + ]:          1 :             if (!s) {
    2098                 :          0 :                 ovs_fatal(0, "\"delete\" command asks for nonexistent "
    2099                 :            :                           "i=%d", atoi(arg1));
    2100                 :            :             }
    2101                 :          1 :             idltest_simple_delete(s);
    2102         [ +  + ]:          9 :         } else if (!strcmp(name, "verify")) {
    2103                 :            :             const struct idltest_simple *s;
    2104                 :            : 
    2105 [ +  - ][ -  + ]:          6 :             if (!arg2 || arg3) {
    2106                 :          0 :                 ovs_fatal(0, "\"verify\" command requires 2 arguments");
    2107                 :            :             }
    2108                 :            : 
    2109                 :          6 :             s = idltest_find_simple(idl, atoi(arg1));
    2110         [ -  + ]:          6 :             if (!s) {
    2111                 :          0 :                 ovs_fatal(0, "\"verify\" command asks for nonexistent "
    2112                 :            :                           "i=%d", atoi(arg1));
    2113                 :            :             }
    2114                 :            : 
    2115         [ +  + ]:          6 :             if (!strcmp(arg2, "i")) {
    2116                 :          1 :                 idltest_simple_verify_i(s);
    2117         [ +  + ]:          5 :             } else if (!strcmp(arg2, "b")) {
    2118                 :          2 :                 idltest_simple_verify_b(s);
    2119         [ -  + ]:          3 :             } else if (!strcmp(arg2, "s")) {
    2120                 :          0 :                 idltest_simple_verify_s(s);
    2121         [ -  + ]:          3 :             } else if (!strcmp(arg2, "u")) {
    2122                 :          0 :                 idltest_simple_verify_s(s);
    2123         [ +  - ]:          3 :             } else if (!strcmp(arg2, "r")) {
    2124                 :          3 :                 idltest_simple_verify_r(s);
    2125                 :            :             } else {
    2126                 :          6 :                 ovs_fatal(0, "\"verify\" command asks for unknown column %s",
    2127                 :            :                           arg2);
    2128                 :            :             }
    2129         [ +  + ]:          3 :         } else if (!strcmp(name, "increment")) {
    2130                 :            :             const struct idltest_simple *s;
    2131                 :            : 
    2132 [ +  - ][ -  + ]:          1 :             if (!arg1 || arg2) {
    2133                 :          0 :                 ovs_fatal(0, "\"increment\" command requires 1 argument");
    2134                 :            :             }
    2135                 :            : 
    2136                 :          1 :             s = idltest_find_simple(idl, atoi(arg1));
    2137         [ -  + ]:          1 :             if (!s) {
    2138                 :          0 :                 ovs_fatal(0, "\"set\" command asks for nonexistent "
    2139                 :            :                           "i=%d", atoi(arg1));
    2140                 :            :             }
    2141                 :            : 
    2142                 :          1 :             ovsdb_idl_txn_increment(txn, &s->header_, &idltest_simple_col_i,
    2143                 :            :                                     false);
    2144                 :          1 :             increment = true;
    2145         [ +  + ]:          2 :         } else if (!strcmp(name, "abort")) {
    2146                 :          1 :             ovsdb_idl_txn_abort(txn);
    2147                 :          1 :             break;
    2148         [ +  - ]:          1 :         } else if (!strcmp(name, "destroy")) {
    2149                 :          1 :             printf("%03d: destroy\n", step);
    2150                 :          1 :             ovsdb_idl_txn_destroy(txn);
    2151                 :          1 :             return;
    2152                 :            :         } else {
    2153                 :          0 :             ovs_fatal(0, "unknown command %s", name);
    2154                 :            :         }
    2155                 :            :     }
    2156                 :            : 
    2157                 :          9 :     status = ovsdb_idl_txn_commit_block(txn);
    2158                 :          9 :     printf("%03d: commit, status=%s",
    2159                 :            :            step, ovsdb_idl_txn_status_to_string(status));
    2160         [ +  + ]:          9 :     if (increment) {
    2161                 :          1 :         printf(", increment=%"PRId64,
    2162                 :            :                ovsdb_idl_txn_get_increment_new_value(txn));
    2163                 :            :     }
    2164                 :          9 :     putchar('\n');
    2165                 :          9 :     ovsdb_idl_txn_destroy(txn);
    2166                 :            : }
    2167                 :            : 
    2168                 :            : static const struct ovsdb_idl_table_class *
    2169                 :         17 : find_table_class(const char *name)
    2170                 :            : {
    2171         [ +  + ]:         17 :     if (!strcmp(name, "simple")) {
    2172                 :         13 :         return &idltest_table_simple;
    2173         [ +  + ]:          4 :     } else if (!strcmp(name, "link1")) {
    2174                 :          2 :         return &idltest_table_link1;
    2175         [ +  - ]:          2 :     } else if (!strcmp(name, "link2")) {
    2176                 :          2 :         return &idltest_table_link2;
    2177                 :            :     }
    2178                 :          0 :     return NULL;
    2179                 :            : }
    2180                 :            : 
    2181                 :            : static void
    2182                 :         15 : parse_simple_json_clause(struct ovsdb_idl *idl, bool add_cmd,
    2183                 :            :                          struct json *json)
    2184                 :            : {
    2185                 :            :     const char *c;
    2186                 :            :     struct ovsdb_error *error;
    2187                 :            :     enum ovsdb_function function;
    2188                 :            : 
    2189         [ +  + ]:         15 :     if (json->type == JSON_TRUE) {
    2190         [ +  - ]:          1 :         add_cmd ? idltest_simple_add_clause_true(idl) :
    2191                 :          0 :             idltest_simple_remove_clause_true(idl);
    2192                 :          8 :         return;
    2193         [ +  + ]:         14 :     } else if (json->type == JSON_FALSE) {
    2194         [ +  + ]:          7 :         add_cmd ? idltest_simple_add_clause_false(idl) :
    2195                 :          1 :             idltest_simple_remove_clause_false(idl);
    2196                 :          7 :         return;
    2197                 :            :     }
    2198 [ +  - ][ -  + ]:          7 :     if (json->type != JSON_ARRAY || json->u.array.n != 3) {
    2199                 :          0 :         ovs_fatal(0, "Error parsing condition");
    2200                 :            :     }
    2201                 :            : 
    2202                 :          7 :     c = json_string(json->u.array.elems[0]);
    2203                 :          7 :     error = ovsdb_function_from_string(json_string(json->u.array.elems[1]),
    2204                 :            :                                        &function);
    2205         [ -  + ]:          7 :     if (error) {
    2206                 :          0 :         ovs_fatal(0, "Error parsing clause function %s",
    2207                 :          0 :                   json_string(json->u.array.elems[1]));
    2208                 :            :     }
    2209                 :            : 
    2210                 :            :     /* add clause according to column */
    2211         [ -  + ]:          7 :     if (!strcmp(c, "b")) {
    2212                 :          0 :         add_cmd ? idltest_simple_add_clause_b(idl, function,
    2213         [ #  # ]:          0 :                                      json_boolean(json->u.array.elems[2])) :
    2214                 :          0 :             idltest_simple_remove_clause_b(idl, function,
    2215                 :          0 :                                      json_boolean(json->u.array.elems[2]));
    2216         [ +  - ]:          7 :     } else if (!strcmp(c, "i")) {
    2217                 :          6 :         add_cmd ? idltest_simple_add_clause_i(idl, function,
    2218         [ +  + ]:          7 :                                     json_integer(json->u.array.elems[2])) :
    2219                 :          7 :             idltest_simple_remove_clause_i(idl, function,
    2220                 :          1 :                                     json_integer(json->u.array.elems[2]));
    2221         [ #  # ]:          0 :     } else if (!strcmp(c, "s")) {
    2222                 :          0 :         add_cmd ? idltest_simple_add_clause_s(idl, function,
    2223         [ #  # ]:          0 :                                     json_string(json->u.array.elems[2])) :
    2224                 :          0 :             idltest_simple_remove_clause_s(idl, function,
    2225                 :          0 :                                     json_string(json->u.array.elems[2]));
    2226         [ #  # ]:          0 :     } else if (!strcmp(c, "u")) {
    2227                 :            :         struct uuid uuid;
    2228         [ #  # ]:          0 :         if (!uuid_from_string(&uuid,
    2229                 :          0 :                               json_string(json->u.array.elems[2]))) {
    2230                 :          0 :             ovs_fatal(0, "\"%s\" is not a valid UUID",
    2231                 :          0 :                       json_string(json->u.array.elems[2]));
    2232                 :            :         }
    2233         [ #  # ]:          0 :         add_cmd ? idltest_simple_add_clause_u(idl, function, uuid) :
    2234                 :          0 :             idltest_simple_remove_clause_u(idl, function, uuid);
    2235         [ #  # ]:          0 :     } else if (!strcmp(c, "r")) {
    2236                 :          0 :         add_cmd ? idltest_simple_add_clause_r(idl, function,
    2237         [ #  # ]:          0 :                                     json_real(json->u.array.elems[2])) :
    2238                 :          0 :             idltest_simple_remove_clause_r(idl, function,
    2239                 :          0 :                                     json_real(json->u.array.elems[2]));
    2240                 :            :     } else {
    2241                 :          7 :         ovs_fatal(0, "Unsupported columns name %s", c);
    2242                 :            :     }
    2243                 :            : }
    2244                 :            : 
    2245                 :            : static void
    2246                 :          2 : parse_link1_json_clause(struct ovsdb_idl *idl, bool add_cmd,
    2247                 :            :                         struct json *json)
    2248                 :            : {
    2249                 :            :     const char *c;
    2250                 :            :     struct ovsdb_error *error;
    2251                 :            :     enum ovsdb_function function;
    2252                 :            : 
    2253         [ -  + ]:          2 :     if (json->type == JSON_TRUE) {
    2254         [ #  # ]:          0 :         add_cmd ? idltest_link1_add_clause_true(idl) :
    2255                 :          0 :             idltest_link1_remove_clause_true(idl);
    2256                 :          1 :         return;
    2257         [ +  + ]:          2 :     } else if (json->type == JSON_FALSE) {
    2258         [ +  - ]:          1 :         add_cmd ? idltest_link1_add_clause_false(idl) :
    2259                 :          0 :             idltest_link1_remove_clause_false(idl);
    2260                 :          1 :         return;
    2261                 :            :     }
    2262 [ +  - ][ -  + ]:          1 :     if (json->type != JSON_ARRAY || json->u.array.n != 3) {
    2263                 :          0 :         ovs_fatal(0, "Error parsing condition");
    2264                 :            :     }
    2265                 :            : 
    2266                 :          1 :     c = json_string(json->u.array.elems[0]);
    2267                 :          1 :     error = ovsdb_function_from_string(json_string(json->u.array.elems[1]),
    2268                 :            :                                        &function);
    2269         [ -  + ]:          1 :     if (error) {
    2270                 :          0 :         ovs_fatal(0, "Error parsing clause function %s",
    2271                 :          0 :                   json_string(json->u.array.elems[1]));
    2272                 :            :     }
    2273                 :            : 
    2274                 :            :     /* add clause according to column */
    2275         [ +  - ]:          1 :     if (!strcmp(c, "i")) {
    2276                 :          1 :         add_cmd ? idltest_link1_add_clause_i(idl, function,
    2277         [ +  - ]:          1 :                                     json_integer(json->u.array.elems[2])) :
    2278                 :          1 :             idltest_link1_remove_clause_i(idl, function,
    2279                 :          0 :                                     json_integer(json->u.array.elems[2]));
    2280                 :            :     } else {
    2281                 :          0 :         ovs_fatal(0, "Unsupported columns name %s", c);
    2282                 :            :     }
    2283                 :            : }
    2284                 :            : 
    2285                 :            : static void
    2286                 :          2 : parse_link2_json_clause(struct ovsdb_idl *idl, bool add_cmd, struct json *json)
    2287                 :            : {
    2288                 :            :     const char *c;
    2289                 :            :     struct ovsdb_error *error;
    2290                 :            :     enum ovsdb_function function;
    2291                 :            : 
    2292         [ -  + ]:          2 :     if (json->type == JSON_TRUE) {
    2293         [ #  # ]:          0 :         add_cmd ? idltest_link2_add_clause_true(idl) :
    2294                 :          0 :             idltest_link2_remove_clause_true(idl);
    2295                 :          1 :         return;
    2296         [ +  + ]:          2 :     } else if (json->type == JSON_FALSE) {
    2297         [ +  - ]:          1 :         add_cmd ? idltest_link2_add_clause_false(idl) :
    2298                 :          0 :             idltest_link2_remove_clause_false(idl);
    2299                 :          1 :         return;
    2300                 :            :     }
    2301 [ +  - ][ -  + ]:          1 :     if (json->type != JSON_ARRAY || json->u.array.n != 3) {
    2302                 :          0 :         ovs_fatal(0, "Error parsing condition");
    2303                 :            :     }
    2304                 :            : 
    2305                 :          1 :     c = json_string(json->u.array.elems[0]);
    2306                 :          1 :     error = ovsdb_function_from_string(json_string(json->u.array.elems[1]),
    2307                 :            :                                        &function);
    2308         [ -  + ]:          1 :     if (error) {
    2309                 :          0 :         ovs_fatal(0, "Error parsing clause function %s",
    2310                 :          0 :                   json_string(json->u.array.elems[1]));
    2311                 :            :     }
    2312                 :            : 
    2313                 :            :     /* add clause according to column */
    2314         [ +  - ]:          1 :     if (!strcmp(c, "i")) {
    2315                 :          1 :         add_cmd ? idltest_link2_add_clause_i(idl, function,
    2316         [ +  - ]:          1 :                                     json_integer(json->u.array.elems[2])) :
    2317                 :          1 :             idltest_link2_remove_clause_i(idl, function,
    2318                 :          0 :                                     json_integer(json->u.array.elems[2]));
    2319                 :            :     } else {
    2320                 :          0 :         ovs_fatal(0, "Unsupported columns name %s", c);
    2321                 :            :     }
    2322                 :            : }
    2323                 :            : 
    2324                 :            : static void
    2325                 :         15 : update_conditions(struct ovsdb_idl *idl, char *commands)
    2326                 :            : {
    2327                 :         15 :     char *cmd, *save_ptr1 = NULL;
    2328                 :            :     const struct ovsdb_idl_table_class *tc;
    2329                 :         15 :     bool add_cmd = false;
    2330                 :            : 
    2331         [ +  + ]:         32 :     for (cmd = strtok_r(commands, ";", &save_ptr1); cmd;
    2332                 :         17 :          cmd = strtok_r(NULL, ";", &save_ptr1)) {
    2333         [ +  + ]:         17 :         if (strstr(cmd, "condition add")) {
    2334                 :         15 :             cmd += strlen("condition add ");
    2335                 :         15 :             add_cmd = true;
    2336         [ +  - ]:          2 :         } else if (strstr(cmd, "condition remove")) {
    2337                 :          2 :             cmd += strlen("condition remove ");
    2338                 :            :         } else {
    2339                 :          0 :             ovs_fatal(0, "condition command should be add or remove");
    2340                 :            :         }
    2341                 :            : 
    2342                 :         17 :         char *save_ptr2 = NULL;
    2343                 :         17 :         char *table_name = strtok_r(cmd, " ", &save_ptr2);
    2344                 :         17 :         struct json *json = parse_json(save_ptr2);
    2345                 :            :         int i;
    2346                 :            : 
    2347         [ -  + ]:         17 :         if (json->type != JSON_ARRAY) {
    2348                 :          0 :             ovs_fatal(0, "condition should be an array");
    2349                 :            :         }
    2350                 :            : 
    2351                 :         17 :         tc = find_table_class(table_name);
    2352         [ -  + ]:         17 :         if (!tc) {
    2353                 :          0 :             ovs_fatal(0, "Table %s does not exist", table_name);
    2354                 :            :         }
    2355                 :            : 
    2356                 :            :         //ovsdb_idl_condition_reset(idl, tc);
    2357                 :            : 
    2358         [ +  + ]:         36 :         for (i = 0; i < json->u.array.n; i++) {
    2359         [ +  + ]:         19 :             if (!strcmp(table_name, "simple")) {
    2360                 :         15 :                 parse_simple_json_clause(idl, add_cmd, json->u.array.elems[i]);
    2361         [ +  + ]:          4 :             } else if (!strcmp(table_name, "link1")) {
    2362                 :          2 :                 parse_link1_json_clause(idl, add_cmd, json->u.array.elems[i]);
    2363         [ +  - ]:          2 :             } else if (!strcmp(table_name, "link2")) {
    2364                 :          2 :                 parse_link2_json_clause(idl, add_cmd, json->u.array.elems[i]);
    2365                 :            :             }
    2366                 :            :         }
    2367                 :         17 :         json_destroy(json);
    2368                 :            :     }
    2369                 :         15 : }
    2370                 :            : 
    2371                 :            : static void
    2372                 :         21 : do_idl(struct ovs_cmdl_context *ctx)
    2373                 :            : {
    2374                 :            :     struct jsonrpc *rpc;
    2375                 :            :     struct ovsdb_idl *idl;
    2376                 :         21 :     unsigned int seqno = 0;
    2377                 :            :     struct ovsdb_symbol_table *symtab;
    2378                 :         21 :     size_t n_uuids = 0;
    2379                 :         21 :     int step = 0;
    2380                 :            :     int error;
    2381                 :            :     int i;
    2382                 :            :     bool track;
    2383                 :            : 
    2384                 :         21 :     idltest_init();
    2385                 :            : 
    2386                 :         21 :     track = ((struct test_ovsdb_pvt_context *)(ctx->pvt))->track;
    2387                 :            : 
    2388                 :         21 :     idl = ovsdb_idl_create(ctx->argv[1], &idltest_idl_class, true, true);
    2389         [ +  + ]:         21 :     if (ctx->argc > 2) {
    2390                 :            :         struct stream *stream;
    2391                 :            : 
    2392                 :         20 :         error = stream_open_block(jsonrpc_stream_open(ctx->argv[1], &stream,
    2393                 :            :                                   DSCP_DEFAULT), &stream);
    2394         [ -  + ]:         20 :         if (error) {
    2395                 :          0 :             ovs_fatal(error, "failed to connect to \"%s\"", ctx->argv[1]);
    2396                 :            :         }
    2397                 :         20 :         rpc = jsonrpc_open(stream);
    2398                 :            :     } else {
    2399                 :          1 :         rpc = NULL;
    2400                 :            :     }
    2401                 :            : 
    2402         [ +  + ]:         21 :     if (track) {
    2403                 :          2 :         ovsdb_idl_track_add_all(idl);
    2404                 :            :     }
    2405                 :            : 
    2406                 :         21 :     setvbuf(stdout, NULL, _IONBF, 0);
    2407                 :            : 
    2408                 :         21 :     symtab = ovsdb_symbol_table_create();
    2409 [ +  + ][ +  + ]:         21 :     if (ctx->argc > 2 && strstr(ctx->argv[2], "condition ")) {
    2410                 :          6 :         update_conditions(idl, ctx->argv[2]);
    2411                 :          6 :         printf("%03d: change conditions\n", step++);
    2412                 :          6 :         i = 3;
    2413                 :            :     } else {
    2414                 :         15 :         i = 2;
    2415                 :            :     }
    2416         [ +  + ]:         78 :     for (; i < ctx->argc; i++) {
    2417                 :         57 :         char *arg = ctx->argv[i];
    2418                 :            :         struct jsonrpc_msg *request, *reply;
    2419                 :            : 
    2420         [ +  + ]:         57 :         if (*arg == '+') {
    2421                 :            :             /* The previous transaction didn't change anything. */
    2422                 :          9 :             arg++;
    2423                 :            :         } else {
    2424                 :            :             /* Wait for update. */
    2425                 :            :             for (;;) {
    2426                 :         76 :                 ovsdb_idl_run(idl);
    2427         [ +  + ]:         76 :                 if (ovsdb_idl_get_seqno(idl) != seqno) {
    2428                 :         48 :                     break;
    2429                 :            :                 }
    2430                 :         28 :                 jsonrpc_run(rpc);
    2431                 :            : 
    2432                 :         28 :                 ovsdb_idl_wait(idl);
    2433                 :         28 :                 jsonrpc_wait(rpc);
    2434                 :         28 :                 poll_block();
    2435                 :         28 :             }
    2436                 :            : 
    2437                 :            :             /* Print update. */
    2438         [ +  + ]:         48 :             if (track) {
    2439                 :          8 :                 print_idl_track(idl, step++, ovsdb_idl_get_seqno(idl));
    2440                 :          8 :                 ovsdb_idl_track_clear(idl);
    2441                 :            :             } else {
    2442                 :         40 :                 print_idl(idl, step++);
    2443                 :            :             }
    2444                 :            :         }
    2445                 :         57 :         seqno = ovsdb_idl_get_seqno(idl);
    2446                 :            : 
    2447         [ +  + ]:         57 :         if (!strcmp(arg, "reconnect")) {
    2448                 :          2 :             printf("%03d: reconnect\n", step++);
    2449                 :          2 :             ovsdb_idl_force_reconnect(idl);
    2450         [ +  + ]:         55 :         }  else if (strstr(arg, "condition ")) {
    2451                 :          9 :             update_conditions(idl, arg);
    2452                 :          9 :             printf("%03d: change conditions\n", step++);
    2453         [ +  + ]:         46 :         } else if (arg[0] != '[') {
    2454                 :         10 :             idl_set(idl, arg, step++);
    2455                 :            :         } else {
    2456                 :         36 :             struct json *json = parse_json(arg);
    2457                 :         36 :             substitute_uuids(json, symtab);
    2458                 :         36 :             request = jsonrpc_create_request("transact", json, NULL);
    2459                 :         36 :             error = jsonrpc_transact_block(rpc, request, &reply);
    2460 [ +  - ][ -  + ]:         36 :             if (error || reply->error) {
    2461                 :          0 :                 ovs_fatal(error, "jsonrpc transaction failed");
    2462                 :            :             }
    2463                 :         36 :             printf("%03d: ", step++);
    2464         [ +  - ]:         36 :             if (reply->result) {
    2465                 :         36 :                 parse_uuids(reply->result, symtab, &n_uuids);
    2466                 :            :             }
    2467                 :         36 :             json_destroy(reply->id);
    2468                 :         36 :             reply->id = NULL;
    2469                 :         36 :             print_and_free_json(jsonrpc_msg_to_json(reply));
    2470                 :            :         }
    2471                 :            :     }
    2472                 :         21 :     ovsdb_symbol_table_destroy(symtab);
    2473                 :            : 
    2474         [ +  + ]:         21 :     if (rpc) {
    2475                 :         20 :         jsonrpc_close(rpc);
    2476                 :            :     }
    2477                 :            :     for (;;) {
    2478                 :         27 :         ovsdb_idl_run(idl);
    2479         [ +  + ]:         27 :         if (ovsdb_idl_get_seqno(idl) != seqno) {
    2480                 :         21 :             break;
    2481                 :            :         }
    2482                 :          6 :         ovsdb_idl_wait(idl);
    2483                 :          6 :         poll_block();
    2484                 :          6 :     }
    2485                 :         21 :     print_idl(idl, step++);
    2486                 :         21 :     ovsdb_idl_track_clear(idl);
    2487                 :         21 :     ovsdb_idl_destroy(idl);
    2488                 :         21 :     printf("%03d: done\n", step);
    2489                 :         21 : }
    2490                 :            : 
    2491                 :            : static void
    2492                 :          5 : print_idl_row_simple2(const struct idltest_simple2 *s, int step)
    2493                 :            : {
    2494                 :            :     size_t i;
    2495                 :            :     const struct ovsdb_datum *smap, *imap;
    2496                 :            : 
    2497                 :          5 :     smap = idltest_simple2_get_smap(s, OVSDB_TYPE_STRING, OVSDB_TYPE_STRING);
    2498                 :          5 :     imap = idltest_simple2_get_imap(s, OVSDB_TYPE_INTEGER, OVSDB_TYPE_STRING);
    2499                 :          5 :     printf("%03d: name=%s smap=[",
    2500                 :            :            step, s->name);
    2501         [ +  + ]:         13 :     for (i = 0; i < smap->n; i++) {
    2502         [ +  + ]:          8 :         printf("[%s : %s]%s", smap->keys[i].string, smap->values[i].string,
    2503                 :          8 :                 i < smap->n-1? ",": "");
    2504                 :            :     }
    2505                 :          5 :     printf("] imap=[");
    2506         [ +  + ]:          9 :     for (i = 0; i < imap->n; i++) {
    2507         [ -  + ]:          4 :         printf("[%"PRId64" : %s]%s", imap->keys[i].integer, imap->values[i].string,
    2508                 :          4 :                 i < imap->n-1? ",":"");
    2509                 :            :     }
    2510                 :          5 :     printf("]\n");
    2511                 :          5 : }
    2512                 :            : 
    2513                 :            : static void
    2514                 :          5 : dump_simple2(struct ovsdb_idl *idl,
    2515                 :            :              const struct idltest_simple2 *myRow,
    2516                 :            :              int step)
    2517                 :            : {
    2518         [ +  + ]:         10 :     IDLTEST_SIMPLE2_FOR_EACH(myRow, idl) {
    2519                 :          5 :         print_idl_row_simple2(myRow, step);
    2520                 :            :     }
    2521                 :          5 : }
    2522                 :            : 
    2523                 :            : static void
    2524                 :          1 : do_idl_partial_update_map_column(struct ovs_cmdl_context *ctx)
    2525                 :            : {
    2526                 :            :     struct ovsdb_idl *idl;
    2527                 :            :     struct ovsdb_idl_txn *myTxn;
    2528                 :            :     const struct idltest_simple2 *myRow;
    2529                 :            :     const struct ovsdb_datum *smap, *imap OVS_UNUSED;
    2530                 :          1 :     int step = 0;
    2531                 :            :     char key_to_delete[100];
    2532                 :            : 
    2533                 :          1 :     idltest_init();
    2534                 :          1 :     idl = ovsdb_idl_create(ctx->argv[1], &idltest_idl_class, false, true);
    2535                 :          1 :     ovsdb_idl_add_table(idl, &idltest_table_simple2);
    2536                 :          1 :     ovsdb_idl_add_column(idl, &idltest_simple2_col_name);
    2537                 :          1 :     ovsdb_idl_add_column(idl, &idltest_simple2_col_smap);
    2538                 :          1 :     ovsdb_idl_add_column(idl, &idltest_simple2_col_imap);
    2539                 :          1 :     ovsdb_idl_get_initial_snapshot(idl);
    2540                 :          1 :     setvbuf(stdout, NULL, _IONBF, 0);
    2541                 :          1 :     ovsdb_idl_run(idl);
    2542                 :            : 
    2543                 :            :     /* Display original data in table. */
    2544                 :          1 :     myRow = NULL;
    2545                 :          1 :     printf("%03d: Getting records\n", step++);
    2546                 :          1 :     dump_simple2(idl, myRow, step++);
    2547                 :            : 
    2548                 :            :     /* Insert new elements in different map columns. */
    2549                 :          1 :     myRow = idltest_simple2_first(idl);
    2550                 :          1 :     myTxn = ovsdb_idl_txn_create(idl);
    2551                 :          1 :     idltest_simple2_get_smap(myRow, OVSDB_TYPE_STRING,
    2552                 :            :                                     OVSDB_TYPE_STRING);
    2553                 :          1 :     idltest_simple2_update_smap_setkey(myRow, "key1", "myList1");
    2554                 :          1 :     imap = idltest_simple2_get_imap(myRow, OVSDB_TYPE_INTEGER,
    2555                 :            :                                     OVSDB_TYPE_STRING);
    2556                 :          1 :     idltest_simple2_update_imap_setkey(myRow, 3, "myids2");
    2557                 :          1 :     idltest_simple2_set_name(myRow, "String2");
    2558                 :          1 :     ovsdb_idl_txn_commit_block(myTxn);
    2559                 :          1 :     ovsdb_idl_txn_destroy(myTxn);
    2560                 :          1 :     ovsdb_idl_get_initial_snapshot(idl);
    2561                 :          1 :     printf("%03d: After insert element\n", step++);
    2562                 :          1 :     dump_simple2(idl, myRow, step++);
    2563                 :            : 
    2564                 :            :     /* Insert duplicate element. */
    2565                 :          1 :     myTxn = ovsdb_idl_txn_create(idl);
    2566                 :          1 :     idltest_simple2_update_smap_setkey(myRow, "key1", "myList1");
    2567                 :          1 :     ovsdb_idl_txn_commit_block(myTxn);
    2568                 :          1 :     ovsdb_idl_txn_destroy(myTxn);
    2569                 :          1 :     ovsdb_idl_get_initial_snapshot(idl);
    2570                 :          1 :     printf("%03d: After insert duplicated element\n", step++);
    2571                 :          1 :     dump_simple2(idl, myRow, step++);
    2572                 :            : 
    2573                 :            :     /* Deletes an element of a map column. */
    2574                 :          1 :     myRow = idltest_simple2_first(idl);
    2575                 :          1 :     myTxn = ovsdb_idl_txn_create(idl);
    2576                 :          1 :     smap = idltest_simple2_get_smap(myRow, OVSDB_TYPE_STRING,
    2577                 :            :                                     OVSDB_TYPE_STRING);
    2578                 :          1 :     strcpy(key_to_delete, smap->keys[0].string);
    2579                 :          1 :     idltest_simple2_update_smap_delkey(myRow, smap->keys[0].string);
    2580                 :          1 :     ovsdb_idl_txn_commit_block(myTxn);
    2581                 :          1 :     ovsdb_idl_txn_destroy(myTxn);
    2582                 :          1 :     ovsdb_idl_get_initial_snapshot(idl);
    2583                 :          1 :     printf("%03d: After delete element\n", step++);
    2584                 :          1 :     dump_simple2(idl, myRow, step++);
    2585                 :            : 
    2586                 :            :     /* Try to delete a deleted element of a map column. */
    2587                 :          1 :     myTxn = ovsdb_idl_txn_create(idl);
    2588                 :          1 :     idltest_simple2_update_smap_delkey(myRow, key_to_delete);
    2589                 :          1 :     ovsdb_idl_txn_commit_block(myTxn);
    2590                 :          1 :     ovsdb_idl_txn_destroy(myTxn);
    2591                 :          1 :     ovsdb_idl_get_initial_snapshot(idl);
    2592                 :          1 :     printf("%03d: After trying to delete a deleted element\n", step++);
    2593                 :          1 :     dump_simple2(idl, myRow, step++);
    2594                 :            : 
    2595                 :          1 :     printf("%03d: End test\n", step);
    2596                 :          1 :     return;
    2597                 :            : }
    2598                 :            : 
    2599                 :            : static void
    2600                 :          6 : print_idl_row_simple3(const struct idltest_simple3 *s, int step)
    2601                 :            : {
    2602                 :            :     size_t i;
    2603                 :            :     const struct ovsdb_datum *uset;
    2604                 :            :     const struct ovsdb_datum *uref;
    2605                 :            : 
    2606                 :          6 :     uset = idltest_simple3_get_uset(s, OVSDB_TYPE_UUID);
    2607                 :          6 :     printf("%03d: name=%s uset=[",
    2608                 :            :            step, s->name);
    2609         [ +  + ]:         24 :     for (i = 0; i < uset->n; i++) {
    2610         [ +  + ]:         18 :         printf("["UUID_FMT"]%s", UUID_ARGS(&(uset->keys[i].uuid)), i < uset->n-1? ",": "");
    2611                 :            :     }
    2612                 :          6 :     uref = idltest_simple3_get_uref(s, OVSDB_TYPE_UUID);
    2613                 :          6 :     printf("] uref=[");
    2614         [ +  + ]:          7 :     for (i = 0; i < uref->n; i++) {
    2615         [ -  + ]:          1 :         printf("["UUID_FMT"]%s", UUID_ARGS(&(uref->keys[i].uuid)), i < uref->n-1? ",": "");
    2616                 :            :     }
    2617                 :          6 :     printf("]\n");
    2618                 :          6 : }
    2619                 :            : 
    2620                 :            : static void
    2621                 :          6 : dump_simple3(struct ovsdb_idl *idl,
    2622                 :            :              const struct idltest_simple3 *myRow,
    2623                 :            :              int step)
    2624                 :            : {
    2625         [ +  + ]:         12 :     IDLTEST_SIMPLE3_FOR_EACH(myRow, idl) {
    2626                 :          6 :         print_idl_row_simple3(myRow, step);
    2627                 :            :     }
    2628                 :          6 : }
    2629                 :            : 
    2630                 :            : static void
    2631                 :          1 : do_idl_partial_update_set_column(struct ovs_cmdl_context *ctx)
    2632                 :            : {
    2633                 :            :     struct ovsdb_idl *idl;
    2634                 :            :     struct ovsdb_idl_txn *myTxn;
    2635                 :            :     const struct idltest_simple3 *myRow;
    2636                 :            :     struct idltest_simple4 *myRow2;
    2637                 :            :     const struct ovsdb_datum *uset OVS_UNUSED;
    2638                 :            :     const struct ovsdb_datum *uref OVS_UNUSED;
    2639                 :          1 :     int step = 0;
    2640                 :            : 
    2641                 :          1 :     idltest_init();
    2642                 :          1 :     idl = ovsdb_idl_create(ctx->argv[1], &idltest_idl_class, false, true);
    2643                 :          1 :     ovsdb_idl_add_table(idl, &idltest_table_simple3);
    2644                 :          1 :     ovsdb_idl_add_column(idl, &idltest_simple3_col_name);
    2645                 :          1 :     ovsdb_idl_add_column(idl, &idltest_simple3_col_uset);
    2646                 :          1 :     ovsdb_idl_add_column(idl, &idltest_simple3_col_uref);
    2647                 :          1 :     ovsdb_idl_add_table(idl, &idltest_table_simple4);
    2648                 :          1 :     ovsdb_idl_add_column(idl, &idltest_simple4_col_name);
    2649                 :          1 :     ovsdb_idl_get_initial_snapshot(idl);
    2650                 :          1 :     setvbuf(stdout, NULL, _IONBF, 0);
    2651                 :          1 :     ovsdb_idl_run(idl);
    2652                 :            : 
    2653                 :            :     /* Display original data in table. */
    2654                 :          1 :     myRow = NULL;
    2655                 :          1 :     printf("%03d: Getting records\n", step++);
    2656                 :          1 :     dump_simple3(idl, myRow, step++);
    2657                 :            : 
    2658                 :            :     /* Insert new elements in different map columns. */
    2659                 :          1 :     myRow = idltest_simple3_first(idl);
    2660                 :          1 :     myTxn = ovsdb_idl_txn_create(idl);
    2661                 :          1 :     idltest_simple3_get_uset(myRow, OVSDB_TYPE_UUID);
    2662                 :            :     struct uuid uuid_to_add;
    2663                 :          1 :     uuid_from_string(&uuid_to_add, "001e43d2-dd3f-4616-ab6a-83a490bb0991");
    2664                 :          1 :     idltest_simple3_update_uset_addvalue(myRow, uuid_to_add);
    2665                 :          1 :     idltest_simple3_set_name(myRow, "String2");
    2666                 :          1 :     ovsdb_idl_txn_commit_block(myTxn);
    2667                 :          1 :     ovsdb_idl_txn_destroy(myTxn);
    2668                 :          1 :     ovsdb_idl_get_initial_snapshot(idl);
    2669                 :          1 :     printf("%03d: After rename+add new value\n", step++);
    2670                 :          1 :     dump_simple3(idl, myRow, step++);
    2671                 :            : 
    2672                 :            :     /* Insert duplicate element. */
    2673                 :          1 :     myTxn = ovsdb_idl_txn_create(idl);
    2674                 :            :     struct uuid uuid_to_add2;
    2675                 :          1 :     uuid_from_string(&uuid_to_add2, "0026b3ba-571b-4729-8227-d860a5210ab8");
    2676                 :          1 :     idltest_simple3_update_uset_addvalue(myRow, uuid_to_add2);
    2677                 :          1 :     ovsdb_idl_txn_commit_block(myTxn);
    2678                 :          1 :     ovsdb_idl_txn_destroy(myTxn);
    2679                 :          1 :     ovsdb_idl_get_initial_snapshot(idl);
    2680                 :          1 :     printf("%03d: After add new value\n", step++);
    2681                 :          1 :     dump_simple3(idl, myRow, step++);
    2682                 :            : 
    2683                 :            :     /* Deletes an element of a set column. */
    2684                 :          1 :     myRow = idltest_simple3_first(idl);
    2685                 :          1 :     myTxn = ovsdb_idl_txn_create(idl);
    2686                 :          1 :     uset = idltest_simple3_get_uset(myRow, OVSDB_TYPE_UUID);
    2687                 :          1 :     idltest_simple3_update_uset_delvalue(myRow, uuid_to_add);
    2688                 :          1 :     ovsdb_idl_txn_commit_block(myTxn);
    2689                 :          1 :     ovsdb_idl_txn_destroy(myTxn);
    2690                 :          1 :     ovsdb_idl_get_initial_snapshot(idl);
    2691                 :          1 :     printf("%03d: After delete value\n", step++);
    2692                 :          1 :     dump_simple3(idl, myRow, step++);
    2693                 :            : 
    2694                 :            :     /* Try to delete a deleted element of a map column.  */
    2695                 :          1 :     myRow = idltest_simple3_first(idl);
    2696                 :          1 :     myTxn = ovsdb_idl_txn_create(idl);
    2697                 :          1 :     idltest_simple3_update_uset_delvalue(myRow, uuid_to_add);
    2698                 :          1 :     ovsdb_idl_txn_commit_block(myTxn);
    2699                 :          1 :     ovsdb_idl_txn_destroy(myTxn);
    2700                 :          1 :     ovsdb_idl_get_initial_snapshot(idl);
    2701                 :          1 :     printf("%03d: After trying to delete a deleted value\n", step++);
    2702                 :          1 :     dump_simple3(idl, myRow, step++);
    2703                 :            : 
    2704                 :            :     /* Adds to a table and update a strong reference in another table. */
    2705                 :          1 :     myRow = idltest_simple3_first(idl);
    2706                 :          1 :     myTxn = ovsdb_idl_txn_create(idl);
    2707                 :          1 :     myRow2 = idltest_simple4_insert(myTxn);
    2708                 :          1 :     idltest_simple4_set_name(myRow2, "test");
    2709                 :          1 :     idltest_simple3_update_uref_addvalue(myRow, myRow2);
    2710                 :          1 :     ovsdb_idl_txn_commit_block(myTxn);
    2711                 :          1 :     ovsdb_idl_txn_destroy(myTxn);
    2712                 :          1 :     ovsdb_idl_get_initial_snapshot(idl);
    2713                 :          1 :     printf("%03d: After add to other table + set of strong ref\n", step++);
    2714                 :          1 :     dump_simple3(idl, myRow, step++);
    2715                 :          1 :     printf("%03d: End test\n", step);
    2716                 :          1 :     return;
    2717                 :            : }
    2718                 :            : 
    2719                 :            : static struct ovs_cmdl_command all_commands[] = {
    2720                 :            :     { "log-io", NULL, 2, INT_MAX, do_log_io, OVS_RO },
    2721                 :            :     { "default-atoms", NULL, 0, 0, do_default_atoms, OVS_RO },
    2722                 :            :     { "default-data", NULL, 0, 0, do_default_data, OVS_RO },
    2723                 :            :     { "diff-data", NULL, 3, INT_MAX, do_diff_data, OVS_RO },
    2724                 :            :     { "parse-atomic-type", NULL, 1, 1, do_parse_atomic_type, OVS_RO },
    2725                 :            :     { "parse-base-type", NULL, 1, 1, do_parse_base_type, OVS_RO },
    2726                 :            :     { "parse-type", NULL, 1, 1, do_parse_type, OVS_RO },
    2727                 :            :     { "parse-atoms", NULL, 2, INT_MAX, do_parse_atoms, OVS_RO },
    2728                 :            :     { "parse-atom-strings", NULL, 2, INT_MAX, do_parse_atom_strings, OVS_RO },
    2729                 :            :     { "parse-data", NULL, 2, INT_MAX, do_parse_data, OVS_RO },
    2730                 :            :     { "parse-data-strings", NULL, 2, INT_MAX, do_parse_data_strings, OVS_RO },
    2731                 :            :     { "sort-atoms", NULL, 2, 2, do_sort_atoms, OVS_RO },
    2732                 :            :     { "parse-column", NULL, 2, 2, do_parse_column, OVS_RO },
    2733                 :            :     { "parse-table", NULL, 2, 3, do_parse_table, OVS_RO },
    2734                 :            :     { "parse-rows", NULL, 2, INT_MAX, do_parse_rows, OVS_RO },
    2735                 :            :     { "compare-rows", NULL, 2, INT_MAX, do_compare_rows, OVS_RO },
    2736                 :            :     { "parse-conditions", NULL, 2, INT_MAX, do_parse_conditions, OVS_RO },
    2737                 :            :     { "evaluate-conditions", NULL, 3, 3, do_evaluate_conditions, OVS_RO },
    2738                 :            :     { "evaluate-conditions-any", NULL, 3, 3, do_evaluate_conditions_any, OVS_RO },
    2739                 :            :     { "compare-conditions", NULL, 2, 2, do_compare_conditions, OVS_RO },
    2740                 :            :     { "parse-mutations", NULL, 2, INT_MAX, do_parse_mutations, OVS_RO },
    2741                 :            :     { "execute-mutations", NULL, 3, 3, do_execute_mutations, OVS_RO },
    2742                 :            :     { "query", NULL, 3, 3, do_query, OVS_RO },
    2743                 :            :     { "query-distinct", NULL, 4, 4, do_query_distinct, OVS_RO },
    2744                 :            :     { "transact", NULL, 1, INT_MAX, do_transact, OVS_RO },
    2745                 :            :     { "parse-schema", NULL, 1, 1, do_parse_schema, OVS_RO },
    2746                 :            :     { "execute", NULL, 2, INT_MAX, do_execute, OVS_RO },
    2747                 :            :     { "execute-readonly", NULL, 2, INT_MAX, do_execute_ro, OVS_RO },
    2748                 :            :     { "trigger", NULL, 2, INT_MAX, do_trigger, OVS_RO },
    2749                 :            :     { "idl", NULL, 1, INT_MAX, do_idl, OVS_RO },
    2750                 :            :     { "idl-partial-update-map-column", NULL, 1, INT_MAX,
    2751                 :            :         do_idl_partial_update_map_column, OVS_RO },
    2752                 :            :     { "idl-partial-update-set-column", NULL, 1, INT_MAX,
    2753                 :            :         do_idl_partial_update_set_column, OVS_RO },
    2754                 :            :     { "help", NULL, 0, INT_MAX, do_help, OVS_RO },
    2755                 :            :     { NULL, NULL, 0, 0, NULL, OVS_RO },
    2756                 :            : };
    2757                 :            : 
    2758                 :            : static struct ovs_cmdl_command *
    2759                 :        326 : get_all_commands(void)
    2760                 :            : {
    2761                 :        326 :     return all_commands;
    2762                 :            : }

Generated by: LCOV version 1.12