ovsdb: Add unixctl commands for OVSDB replication
[cascardo/ovs.git] / tests / ovsdb-server.at
index eacca35..2f2ef99 100644 (file)
@@ -1,9 +1,12 @@
 AT_BANNER([OVSDB -- ovsdb-server transactions (Unix sockets)])
 
 m4_define([OVSDB_SERVER_SHUTDOWN], 
-  [cp pid savepid
-   AT_CHECK([ovs-appctl -t "`pwd`"/unixctl -e exit], [0], [ignore], [ignore])
-   OVS_WAIT_WHILE([kill -0 `cat savepid`], [kill `cat savepid`])])
+  [OVS_APP_EXIT_AND_WAIT_BY_TARGET([`pwd`/unixctl], [`pwd`/pid])])
+
+m4_define([OVSDB_SERVER_SHUTDOWN2],
+  [cp pid2 savepid2
+   AT_CHECK([ovs-appctl -t "`pwd`"/unixctl2 -e exit], [0], [ignore], [ignore])
+   OVS_WAIT_WHILE([kill -0 `cat savepid2`], [kill `cat savepid2`])])
 
 # OVSDB_CHECK_EXECUTION(TITLE, SCHEMA, TRANSACTIONS, OUTPUT, [KEYWORDS])
 #
@@ -21,7 +24,6 @@ m4_define([OVSDB_SERVER_SHUTDOWN],
 # TITLE is provided to AT_SETUP and KEYWORDS to AT_KEYWORDS.
 m4_define([OVSDB_CHECK_EXECUTION], 
   [AT_SETUP([$1])
-  OVS_RUNDIR=`pwd`; export OVS_RUNDIR
    AT_KEYWORDS([ovsdb server positive unix $5])
    $2 > schema
    AT_CHECK([ovsdb-tool create db schema], [0], [stdout], [ignore])
@@ -43,7 +45,6 @@ AT_BANNER([ovsdb-server miscellaneous features])
 AT_SETUP([truncating corrupted database log])
 AT_KEYWORDS([ovsdb server positive unix])
 AT_SKIP_IF([test "$IS_WIN32" = "yes"])
-OVS_RUNDIR=`pwd`; export OVS_RUNDIR
 ordinal_schema > schema
 AT_CHECK([ovsdb-tool create db schema], [0], [stdout], [ignore])
 dnl Do one transaction and save the output.
@@ -91,7 +92,6 @@ AT_CLEANUP
 AT_SETUP([truncating database log with bad transaction])
 AT_KEYWORDS([ovsdb server positive unix])
 AT_SKIP_IF([test "$IS_WIN32" = "yes"])
-OVS_RUNDIR=`pwd`; export OVS_RUNDIR
 ordinal_schema > schema
 AT_CHECK([ovsdb-tool create db schema], [0], [stdout], [ignore])
 dnl Do one transaction and save the output.
@@ -139,7 +139,6 @@ AT_CLEANUP
 
 AT_SETUP([ovsdb-client get-schema-version])
 AT_KEYWORDS([ovsdb server positive])
-OVS_RUNDIR=`pwd`; export OVS_RUNDIR
 ordinal_schema > schema
 AT_CHECK([ovsdb-tool create db schema], [0], [ignore], [ignore])
 AT_CHECK([ovsdb-server --detach --no-chdir --pidfile="`pwd`"/pid --unixctl="`pwd`"/unixctl --remote=punix:socket db], [0], [ignore], [ignore])
@@ -150,7 +149,6 @@ AT_CLEANUP
 
 AT_SETUP([database multiplexing implementation])
 AT_KEYWORDS([ovsdb server positive])
-OVS_RUNDIR=`pwd`; export OVS_RUNDIR
 ordinal_schema > schema1
 constraint_schema > schema2
 AT_CHECK([ovsdb-tool create db1 schema1], [0], [ignore], [ignore])
@@ -170,9 +168,7 @@ AT_CLEANUP
 
 AT_SETUP([ovsdb-server/add-db and remove-db])
 AT_KEYWORDS([ovsdb server positive])
-ON_EXIT([kill `cat ovsdb-server.pid`])
-OVS_RUNDIR=`pwd`; export OVS_RUNDIR
-OVS_LOGDIR=`pwd`; export OVS_LOGDIR
+on_exit 'kill `cat ovsdb-server.pid`'
 ordinal_schema > schema1
 constraint_schema > schema2
 AT_CHECK([ovsdb-tool create db1 schema1], [0], [ignore], [ignore])
@@ -211,7 +207,7 @@ fi
 # Add a non-existing database.
 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/add-db db3], 2, [], [stderr])
 AT_CHECK([sed 's/(.*)/(...)/' stderr], [0],
-  [I/O error: open: db3 failed (...)
+  [I/O error: db3: open failed (...)
 ovs-appctl: ovsdb-server: server returned an error
 ])
 
@@ -251,17 +247,16 @@ AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-dbs],
   [0], [constraints
 ])
 AT_CHECK([ovsdb-client list-tables unix:socket constraints], [0], [ignore], [ignore])
+OVS_APP_EXIT_AND_WAIT([ovsdb-server])
 AT_CLEANUP
 
 AT_SETUP([ovsdb-server/add-db with --monitor])
 AT_KEYWORDS([ovsdb server positive])
 AT_SKIP_IF([test "$IS_WIN32" = "yes"])
 # Start ovsdb-server, initially with one db.
-OVS_RUNDIR=`pwd`; export OVS_RUNDIR
-OVS_LOGDIR=`pwd`; export OVS_LOGDIR
 ordinal_schema > schema
 AT_CHECK([ovsdb-tool create db1 schema], [0], [ignore], [ignore])
-ON_EXIT([kill `cat *.pid`])
+on_exit 'kill `cat *.pid`'
 AT_CHECK([ovsdb-server -v -vvlog:off --monitor --detach --no-chdir --pidfile --log-file db1])
 
 # Add the second database.
@@ -280,23 +275,23 @@ AT_CHECK([kill -SEGV `cat ovsdb-server.pid`])
 OVS_WAIT_WHILE([kill -0 `cat old.pid`])
 OVS_WAIT_UNTIL(
   [test -s ovsdb-server.pid && test `cat ovsdb-server.pid` != `cat old.pid`])
+OVS_WAIT_UNTIL([ovs-appctl -t ovsdb-server version])
 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-dbs],
   [0], [constraints
 ordinals
 ])
+OVS_APP_EXIT_AND_WAIT([ovsdb-server])
 AT_CLEANUP
 
 AT_SETUP([ovsdb-server/add-db and remove-db with --monitor])
 AT_KEYWORDS([ovsdb server positive])
 AT_SKIP_IF([test "$IS_WIN32" = "yes"])
 # Start ovsdb-server, initially with one db.
-OVS_RUNDIR=`pwd`; export OVS_RUNDIR
-OVS_LOGDIR=`pwd`; export OVS_LOGDIR
 ordinal_schema > schema
 AT_CHECK([ovsdb-tool create db1 schema], [0], [ignore], [ignore])
 constraint_schema > schema2
 AT_CHECK([ovsdb-tool create db2 schema2], [0], [ignore], [ignore])
-ON_EXIT([kill `cat *.pid`])
+on_exit 'kill `cat *.pid`'
 AT_CHECK([ovsdb-server -v -vvlog:off --monitor --detach --no-chdir --pidfile --log-file db1 db2])
 
 # Remove the second database.
@@ -312,15 +307,15 @@ AT_CHECK([kill -SEGV `cat ovsdb-server.pid`])
 OVS_WAIT_WHILE([kill -0 `cat old.pid`])
 OVS_WAIT_UNTIL(
   [test -s ovsdb-server.pid && test `cat ovsdb-server.pid` != `cat old.pid`])
+OVS_WAIT_UNTIL([ovs-appctl -t ovsdb-server version])
 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-dbs],
   [0], [ordinals
 ])
+OVS_APP_EXIT_AND_WAIT([ovsdb-server])
 AT_CLEANUP
 
 AT_SETUP([--remote=db: implementation])
 AT_KEYWORDS([ovsdb server positive])
-OVS_RUNDIR=`pwd`; export OVS_RUNDIR
-OVS_LOGDIR=`pwd`; export OVS_LOGDIR
 AT_DATA([schema],
   [[{"name": "mydb",
      "tables": {
@@ -359,7 +354,7 @@ AT_CHECK(
         "table": "Manager",
         "uuid-name": "x",
         "row": {"target": "punix:socket2"}}]']], [0], [ignore], [ignore])
-ON_EXIT([kill `cat ovsdb-server.pid`])
+on_exit 'kill `cat ovsdb-server.pid`'
 AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --remote=db:mydb,Root,managers --remote=db:mydb,Root,manager_options --log-file db], [0], [ignore], [ignore])
 ovs-appctl -t ovsdb-server time/warp 6000 1000
 AT_CHECK(
@@ -380,15 +375,14 @@ AT_CHECK(
   [[[{"rows":[{"managers":"punix:socket1"}]},{"rows":[{"is_connected":false,"target":"punix:socket2"}]}]
 ]], 
   [ignore])
+OVS_APP_EXIT_AND_WAIT([ovsdb-server])
 AT_CLEANUP
 
 AT_SETUP([ovsdb-server/add-remote and remove-remote])
 AT_KEYWORDS([ovsdb server positive])
-OVS_RUNDIR=`pwd`; export OVS_RUNDIR
-OVS_LOGDIR=`pwd`; export OVS_LOGDIR
 ordinal_schema > schema
 AT_CHECK([ovsdb-tool create db schema], [0], [ignore], [ignore])
-ON_EXIT([kill `cat *.pid`])
+on_exit 'kill `cat *.pid`'
 AT_CHECK([ovsdb-server --detach --no-chdir --pidfile db])
 
 AT_CHECK([test ! -e socket1])
@@ -434,17 +428,16 @@ AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/remove-remote punix:socket2])
 OVS_WAIT_UNTIL([test ! -e socket2])
 AT_CHECK([test ! -e socket1])
 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-remotes])
+OVS_APP_EXIT_AND_WAIT([ovsdb-server])
 AT_CLEANUP
 
 AT_SETUP([ovsdb-server/add-remote with --monitor])
 AT_KEYWORDS([ovsdb server positive])
 AT_SKIP_IF([test "$IS_WIN32" = "yes"])
 # Start ovsdb-server, initially with no remotes.
-OVS_RUNDIR=`pwd`; export OVS_RUNDIR
-OVS_LOGDIR=`pwd`; export OVS_LOGDIR
 ordinal_schema > schema
 AT_CHECK([ovsdb-tool create db schema], [0], [ignore], [ignore])
-ON_EXIT([kill `cat *.pid`])
+on_exit 'kill `cat *.pid`'
 AT_CHECK([ovsdb-server -v -vvlog:off --monitor --detach --no-chdir --pidfile --log-file db])
 
 # Add a remote.
@@ -464,18 +457,18 @@ AT_CHECK([kill -SEGV `cat ovsdb-server.pid`])
 OVS_WAIT_WHILE([kill -0 `cat old.pid`])
 OVS_WAIT_UNTIL(
   [test -s ovsdb-server.pid && test `cat ovsdb-server.pid` != `cat old.pid`])
+OVS_WAIT_UNTIL([ovs-appctl -t ovsdb-server version])
 OVS_WAIT_UNTIL([test -S socket1])
+OVS_APP_EXIT_AND_WAIT([ovsdb-server])
 AT_CLEANUP
 
 AT_SETUP([ovsdb-server/add-remote and remove-remote with --monitor])
 AT_KEYWORDS([ovsdb server positive])
 AT_SKIP_IF([test "$IS_WIN32" = "yes"])
 # Start ovsdb-server, initially with no remotes.
-OVS_RUNDIR=`pwd`; export OVS_RUNDIR
-OVS_LOGDIR=`pwd`; export OVS_LOGDIR
 ordinal_schema > schema
 AT_CHECK([ovsdb-tool create db schema], [0], [ignore], [ignore])
-ON_EXIT([kill `cat *.pid`])
+on_exit 'kill `cat *.pid`'
 AT_CHECK([ovsdb-server -v -vvlog:off --monitor --detach --no-chdir --pidfile --log-file db])
 
 # Add a remote.
@@ -499,7 +492,9 @@ AT_CHECK([kill -SEGV `cat ovsdb-server.pid`])
 OVS_WAIT_WHILE([kill -0 `cat old.pid`])
 OVS_WAIT_UNTIL(
   [test -s ovsdb-server.pid && test `cat ovsdb-server.pid` != `cat old.pid`])
+OVS_WAIT_UNTIL([ovs-appctl -t ovsdb-server version])
 AT_CHECK([test ! -e socket1])
+OVS_APP_EXIT_AND_WAIT([ovsdb-server])
 AT_CLEANUP
 
 AT_SETUP([SSL db: implementation])
@@ -530,7 +525,6 @@ AT_CHECK(
                 "certificate": "'"$PKIDIR/testpki-cert2.pem"'",
                 "ca_cert": "'"$PKIDIR/testpki-cacert.pem"'"}}]']],
   [0], [ignore], [ignore])
-OVS_LOGDIR=`pwd`; export OVS_LOGDIR
 AT_CHECK(
   [ovsdb-server --log-file --detach --no-chdir --pidfile="`pwd`"/pid \
         --private-key=db:mydb,SSL,private_key \
@@ -538,7 +532,7 @@ AT_CHECK(
         --ca-cert=db:mydb,SSL,ca_cert \
         --remote=pssl:0:127.0.0.1 --unixctl="`pwd`"/unixctl db],
   [0], [ignore], [ignore])
-SSL_PORT=`parse_listening_port < ovsdb-server.log`
+PARSE_LISTENING_PORT([ovsdb-server.log], [SSL_PORT])
 AT_CHECK(
   [[ovsdb-client \
         --private-key=$PKIDIR/testpki-privkey.pem \
@@ -561,7 +555,6 @@ AT_CLEANUP
 
 AT_SETUP([compacting online])
 AT_KEYWORDS([ovsdb server compact])
-OVS_RUNDIR=`pwd`; export OVS_RUNDIR
 ordinal_schema > schema
 dnl Make sure that "ovsdb-tool create" works with a dangling symlink for
 dnl the database and the lockfile, creating the target of each symlink rather
@@ -693,9 +686,7 @@ OVSDB_SERVER_SHUTDOWN
 AT_CLEANUP
 
 AT_SETUP([ovsdb-server combines updates on backlogged connections])
-OVS_LOGDIR=`pwd`; export OVS_LOGDIR
-OVS_RUNDIR=`pwd`; export OVS_RUNDIR
-ON_EXIT([kill `cat *.pid`])
+on_exit 'kill `cat *.pid`'
 
 # The maximum socket receive buffer size is important for this test, which
 # tests behavior when the receive buffer overflows.
@@ -771,8 +762,7 @@ done
 AT_CHECK([ovs-appctl -t ovsdb-client ovsdb-client/unblock])
 OVS_WAIT_UNTIL([grep "\"xyzzy$counter\"" ovsdb-client.out])
 OVS_WAIT_UNTIL([grep "\"xyzzy$counter\"" ovsdb-client-nonblock.out])
-AT_CHECK([ovs-appctl -t ovsdb-client exit])
-OVS_WAIT_WHILE([test -e ovsdb-client.pid])
+OVS_APP_EXIT_AND_WAIT([ovsdb-client])
 AT_CHECK([kill `cat nonblock.pid`])
 
 # Count the number of updates in the ovsdb-client output, by counting
@@ -790,6 +780,7 @@ AT_CHECK([test $logged_updates -lt $logged_nonblock_updates])
 AT_CHECK_UNQUOTED([ovs-vsctl get open_vswitch . system_version], [0],
   ["xyzzy$counter"
 ])
+OVS_APP_EXIT_AND_WAIT([ovsdb-server])
 AT_CLEANUP
 \f
 AT_BANNER([OVSDB -- ovsdb-server transactions (SSL IPv4 sockets)])
@@ -812,13 +803,11 @@ m4_define([OVSDB_CHECK_EXECUTION],
   [AT_SETUP([$1])
    AT_KEYWORDS([ovsdb server positive ssl $5])
    AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
-   OVS_RUNDIR=`pwd`; export OVS_RUNDIR
-   OVS_LOGDIR=`pwd`; export OVS_LOGDIR
    $2 > schema
    PKIDIR=$abs_top_builddir/tests
    AT_CHECK([ovsdb-tool create db schema], [0], [stdout], [ignore])
    AT_CHECK([ovsdb-server --log-file --detach --no-chdir --pidfile="`pwd`"/pid --private-key=$PKIDIR/testpki-privkey2.pem --certificate=$PKIDIR/testpki-cert2.pem --ca-cert=$PKIDIR/testpki-cacert.pem --remote=pssl:0:127.0.0.1 --unixctl="`pwd`"/unixctl db], [0], [ignore], [ignore])
-   SSL_PORT=`parse_listening_port < ovsdb-server.log`
+   PARSE_LISTENING_PORT([ovsdb-server.log], [SSL_PORT])
    m4_foreach([txn], [$3], 
      [AT_CHECK([ovsdb-client --private-key=$PKIDIR/testpki-privkey.pem --certificate=$PKIDIR/testpki-cert.pem --ca-cert=$PKIDIR/testpki-cacert.pem transact ssl:127.0.0.1:$SSL_PORT 'txn'], [0], [stdout], [ignore],
      [test ! -e pid || kill `cat pid`])
@@ -851,13 +840,12 @@ m4_define([OVSDB_CHECK_EXECUTION],
   [AT_SETUP([$1])
    AT_KEYWORDS([ovsdb server positive ssl6 $5])
    AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
-   OVS_RUNDIR=`pwd`; export OVS_RUNDIR
-   OVS_LOGDIR=`pwd`; export OVS_LOGDIR
+   AT_SKIP_IF([test $HAVE_IPV6 = no])
    $2 > schema
    PKIDIR=$abs_top_builddir/tests
    AT_CHECK([ovsdb-tool create db schema], [0], [stdout], [ignore])
    AT_CHECK([ovsdb-server --log-file --detach --no-chdir --pidfile="`pwd`"/pid --private-key=$PKIDIR/testpki-privkey2.pem --certificate=$PKIDIR/testpki-cert2.pem --ca-cert=$PKIDIR/testpki-cacert.pem --remote=pssl:0:[[::1]] --unixctl="`pwd`"/unixctl db], [0], [ignore], [ignore])
-   SSL_PORT=`parse_listening_port < ovsdb-server.log`
+   PARSE_LISTENING_PORT([ovsdb-server.log], [SSL_PORT])
    m4_foreach([txn], [$3],
      [AT_CHECK([ovsdb-client --private-key=$PKIDIR/testpki-privkey.pem --certificate=$PKIDIR/testpki-cert.pem --ca-cert=$PKIDIR/testpki-cacert.pem transact ssl:[[::1]]:$SSL_PORT 'txn'], [0], [stdout], [ignore],
      [test ! -e pid || kill `cat pid`])
@@ -876,9 +864,8 @@ AT_SETUP([ovsdb-client get-schema-version - tcp socket])
 AT_KEYWORDS([ovsdb server positive tcp])
 ordinal_schema > schema
 AT_CHECK([ovsdb-tool create db schema], [0], [ignore], [ignore])
-OVS_LOGDIR=`pwd`; export OVS_LOGDIR
 AT_CHECK([ovsdb-server --log-file --detach --no-chdir --pidfile="`pwd`"/pid --unixctl="`pwd`"/unixctl --remote=ptcp:0:127.0.0.1 db], [0], [ignore], [ignore])
-TCP_PORT=`parse_listening_port < ovsdb-server.log`
+PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
 AT_CHECK([ovsdb-client get-schema-version tcp:127.0.0.1:$TCP_PORT ordinals], [0], [5.1.3
 ])
 OVSDB_SERVER_SHUTDOWN
@@ -901,13 +888,11 @@ AT_CLEANUP])
 m4_define([OVSDB_CHECK_EXECUTION],
   [AT_SETUP([$1])
    AT_KEYWORDS([ovsdb server positive tcp $5])
-   OVS_RUNDIR=`pwd`; export OVS_RUNDIR
-   OVS_LOGDIR=`pwd`; export OVS_LOGDIR
    $2 > schema
    PKIDIR=$abs_top_builddir/tests
    AT_CHECK([ovsdb-tool create db schema], [0], [stdout], [ignore])
    AT_CHECK([ovsdb-server --log-file --detach --no-chdir --pidfile="`pwd`"/pid --remote=ptcp:0:127.0.0.1 --unixctl="`pwd`"/unixctl db], [0], [ignore], [ignore])
-   TCP_PORT=`parse_listening_port < ovsdb-server.log`
+   PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
    m4_foreach([txn], [$3],
      [AT_CHECK([ovsdb-client transact tcp:127.0.0.1:$TCP_PORT 'txn'], [0], [stdout], [ignore],
      [test ! -e pid || kill `cat pid`])
@@ -939,13 +924,12 @@ AT_BANNER([OVSDB -- ovsdb-server transactions (TCP IPv6 sockets)])
 m4_define([OVSDB_CHECK_EXECUTION],
   [AT_SETUP([$1])
    AT_KEYWORDS([ovsdb server positive tcp6 $5])
-   OVS_RUNDIR=`pwd`; export OVS_RUNDIR
-   OVS_LOGDIR=`pwd`; export OVS_LOGDIR
+   AT_SKIP_IF([test $HAVE_IPV6 = no])
    $2 > schema
    PKIDIR=$abs_top_builddir/tests
    AT_CHECK([ovsdb-tool create db schema], [0], [stdout], [ignore])
    AT_CHECK([ovsdb-server --log-file --detach --no-chdir --pidfile="`pwd`"/pid --remote=ptcp:0:[[::1]] --unixctl="`pwd`"/unixctl db], [0], [ignore], [ignore])
-   TCP_PORT=`parse_listening_port < ovsdb-server.log`
+   PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
    m4_foreach([txn], [$3],
      [AT_CHECK([ovsdb-client transact tcp:[[::1]]:$TCP_PORT 'txn'], [0], [stdout], [ignore],
      [test ! -e pid || kill `cat pid`])
@@ -981,7 +965,6 @@ m4_define([OVSDB_CHECK_EXECUTION],
   [AT_SETUP([$1])
    AT_SKIP_IF([test "$IS_WIN32" = "yes"])
    AT_KEYWORDS([ovsdb server positive transient $5])
-   OVS_RUNDIR=`pwd`; export OVS_RUNDIR
    $2 > schema
    AT_CHECK([ovsdb-tool create db schema], [0], [stdout], [ignore])
    m4_foreach([txn], [$3], 
@@ -994,3 +977,294 @@ m4_define([OVSDB_CHECK_EXECUTION],
    AT_CLEANUP])
 
 EXECUTION_EXAMPLES
+\f
+AT_BANNER([OVSDB -- ovsdb-server replication (TCP IPv4 sockets)])
+
+# OVSDB_CHECK_EXECUTION(TITLE, SCHEMA, TRANSACTIONS, OUTPUT, [KEYWORDS])
+#
+# Creates two databases with the given SCHEMA, and starts an ovsdb-server on
+# each database.
+# Runs each of the TRANSACTIONS (which should be a quoted list of
+# quoted strings) against one of the servers with ovsdb-client one at a
+# time. The server replicates its database to the other ovsdb-server.
+#
+# Checks that the dump of both databases are the same.
+#
+# TITLE is provided to AT_SETUP and KEYWORDS to AT_KEYWORDS.
+m4_define([OVSDB_CHECK_EXECUTION],
+  [AT_SETUP([$1])
+   AT_KEYWORDS([ovsdb server tcp replication $5])
+   $2 > schema
+   AT_CHECK([ovsdb-tool create db1 schema], [0], [stdout], [ignore])
+   AT_CHECK([ovsdb-tool create db2 schema], [0], [stdout], [ignore])
+
+   AT_CHECK([ovsdb-server --detach --no-chdir --log-file=ovsdb-server1.log --pidfile="`pwd`"/pid --remote=ptcp:0:127.0.0.1 --unixctl="`pwd`"/unixctl db1], [0], [ignore], [ignore])
+   PARSE_LISTENING_PORT([ovsdb-server1.log], [TCP_PORT1])
+
+   AT_CHECK([ovsdb-server --detach --no-chdir --log-file=ovsdb-server2.log --pidfile="`pwd`"/pid2 --remote=ptcp:0:127.0.0.1 --unixctl="`pwd`"/unixctl2 --sync-from=tcp:127.0.0.1:$TCP_PORT1 db2], [0], [ignore], [ignore])
+   PARSE_LISTENING_PORT([ovsdb-server2.log], [TCP_PORT2])
+
+   m4_foreach([txn], [$3],
+     [AT_CHECK([ovsdb-client transact tcp:127.0.0.1:$TCP_PORT1 'txn'; sleep 2], [0], [stdout], [ignore],
+     [test ! -e pid || kill `cat pid`; test ! -e pid2 || kill `cat pid2`])
+   ])
+
+   AT_CHECK([ovsdb-client dump tcp:127.0.0.1:$TCP_PORT1], [0], [stdout], [ignore],
+     [test ! -e pid || kill `cat pid`; test ! -e pid2 || kill `cat pid2`])
+   cat stdout >> dump1
+   AT_CHECK([ovsdb-client dump tcp:127.0.0.1:$TCP_PORT2], [0], [stdout], [ignore],
+     [test ! -e pid || kill `cat pid`; test ! -e pid2 || kill `cat pid2`])
+   cat stdout >> dump2
+
+   AT_CHECK([diff dump1 dump2], [0], [], [ignore],
+            [test ! -e pid || kill `cat pid`; test ! -e pid2 || kill `cat pid2`])
+   OVSDB_SERVER_SHUTDOWN
+   OVSDB_SERVER_SHUTDOWN2
+   AT_CLEANUP])
+
+EXECUTION_EXAMPLES
+
+AT_BANNER([OVSDB -- ovsdb-server replication table-exclusion (TCP IPv4 sockets)])
+
+# OVSDB_CHECK_REPLICATION(TITLE, SCHEMA, TRANSACTIONS, OUTPUT, [KEYWORDS])
+#
+# Creates two databases with the given SCHEMA, and starts an
+# ovsdb-server on each database.
+# Runs each of the TRANSACTIONS (which should be a quoted list of
+# quoted strings) against one of the servers with ovsdb-client one at a
+# time. The server replicates its database to the other ovsdb-server.
+#
+# Checks that the difference between the dump of the databases is
+# OUTPUT, but UUIDs in the output are replaced by markers of the form
+# <N> where N is a number.  The first unique UUID is replaced by <0>,
+# the next by <1>, and so on.
+# If a given UUID appears more than once it is always replaced by the
+# same marker.
+#
+# TITLE is provided to AT_SETUP and KEYWORDS to AT_KEYWORDS.
+m4_define([OVSDB_CHECK_REPLICATION],
+   [AT_SETUP([$1])
+   AT_KEYWORDS([ovsdb server tcp replication table-exclusion])
+   $2 > schema
+   AT_CHECK([ovsdb-tool create db1 schema], [0], [stdout], [ignore])
+   AT_CHECK([ovsdb-tool create db2 schema], [0], [stdout], [ignore])
+
+   AT_CHECK([ovsdb-server --detach --no-chdir --log-file=ovsdb-server1.log --pidfile="`pwd`"/pid --remote=ptcp:0:127.0.0.1 --unixctl="`pwd`"/unixctl db1], [0], [ignore], [ignore])
+   PARSE_LISTENING_PORT([ovsdb-server1.log], [TCP_PORT1])
+
+   AT_CHECK([ovsdb-server --detach --no-chdir --log-file=ovsdb-server2.log --pidfile="`pwd`"/pid2 --remote=ptcp:0:127.0.0.1 --unixctl="`pwd`"/unixctl2 --sync-from=tcp:127.0.0.1:$TCP_PORT1 --sync-exclude-tables=mydb:b db2], [0], [ignore], [ignore])
+   PARSE_LISTENING_PORT([ovsdb-server2.log], [TCP_PORT2])
+
+   m4_foreach([txn], [$3],
+     [AT_CHECK([ovsdb-client transact tcp:127.0.0.1:$TCP_PORT1 'txn'; sleep 2], [0], [stdout], [ignore],
+     [test ! -e pid || kill `cat pid`; test ! -e pid2 || kill `cat pid2`])
+   ])
+
+   AT_CHECK([ovsdb-client dump tcp:127.0.0.1:$TCP_PORT1], [0], [stdout], [ignore],
+     [test ! -e pid || kill `cat pid`; test ! -e pid2 || kill `cat pid2`])
+   cat stdout >> dump1
+   AT_CHECK([ovsdb-client dump tcp:127.0.0.1:$TCP_PORT2], [0], [stdout], [ignore],
+     [test ! -e pid || kill `cat pid`; test ! -e pid2 || kill `cat pid2`])
+   cat stdout >> dump2
+
+   AT_CHECK([diff dump1 dump2], [1], [stdout], [ignore],
+            [test ! -e pid || kill `cat pid`; test ! -e pid2 || kill `cat pid2`])
+   cat stdout >> output
+
+   AT_CHECK([${PERL} $srcdir/uuidfilt.pl output], [0], [$4], [ignore],
+            [test ! -e pid || kill `cat pid`; test ! -e pid2 || kill `cat pid2`])
+
+   OVSDB_SERVER_SHUTDOWN
+   OVSDB_SERVER_SHUTDOWN2
+   AT_CLEANUP])
+
+REPLICATION_EXAMPLES
+
+AT_BANNER([OVSDB -- ovsdb-server replication runtime management commands])
+
+#ovsdb-server/get-remote-ovsdb-server command
+AT_SETUP([ovsdb-server/get-remote-ovsdb-server])
+AT_KEYWORDS([ovsdb server replication get-remote])
+ordinal_schema > schema
+AT_CHECK([ovsdb-tool create db schema], [0], [ignore], [ignore])
+on_exit 'kill `cat *.pid`'
+AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --sync-from=tcp:127.0.0.1:9999 db])
+
+AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/get-remote-ovsdb-server],
+  [0], [tcp:127.0.0.1:9999
+])
+AT_CLEANUP
+
+#*ovsdb-server/set-remote-ovsdb-server command
+AT_SETUP([ovsdb-server/set-remote-ovsdb-server])
+AT_KEYWORDS([ovsdb server replication set-remote])
+ordinal_schema > schema
+AT_CHECK([ovsdb-tool create db schema], [0], [ignore], [ignore])
+on_exit 'kill `cat *.pid`'
+AT_CHECK([ovsdb-server --detach --no-chdir --pidfile db])
+
+AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/set-remote-ovsdb-server tcp:127.0.0.1:9999])
+AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/get-remote-ovsdb-server],
+  [0], [tcp:127.0.0.1:9999
+])
+AT_CLEANUP
+
+#ovsdb-server/get-sync-excluded-tables command
+AT_SETUP([ovsdb-server/get-sync-excluded-tables])
+AT_KEYWORDS([ovsdb server replication get-excluded-tables])
+ordinal_schema > schema
+AT_CHECK([ovsdb-tool create db schema], [0], [ignore], [ignore])
+on_exit 'kill `cat *.pid`'
+AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --sync-exclude-tables=mydb:db1,mydb:db2 db])
+
+AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/get-sync-excluded-tables],
+  [0], [mydb:db2
+mydb:db1
+])
+AT_CLEANUP
+
+#ovsdb-server/set-sync-excluded-tables command
+AT_SETUP([ovsdb-server/set-sync-excluded-tables])
+AT_KEYWORDS([ovsdb server replication set-excluded-tables])
+replication_schema > schema
+AT_CHECK([ovsdb-tool create db1 schema], [0], [stdout], [ignore])
+AT_CHECK([ovsdb-tool create db2 schema], [0], [stdout], [ignore])
+
+AT_CHECK([ovsdb-server --detach --no-chdir --log-file=ovsdb-server1.log --pidfile="`pwd`"/pid --remote=ptcp:0:127.0.0.1 --unixctl="`pwd`"/unixctl db1], [0], [ignore], [ignore])
+PARSE_LISTENING_PORT([ovsdb-server1.log], [TCP_PORT1])
+
+AT_CHECK([ovsdb-server --detach --no-chdir --log-file=ovsdb-server2.log --pidfile="`pwd`"/pid2 --remote=ptcp:0:127.0.0.1 --unixctl="`pwd`"/unixctl2 --sync-from=tcp:127.0.0.1:$TCP_PORT1        db2], [0], [ignore], [ignore])
+PARSE_LISTENING_PORT([ovsdb-server2.log], [TCP_PORT2])
+
+AT_CHECK([ovs-appctl -t "`pwd`"/unixctl2 ovsdb-server/set-sync-excluded-tables mydb:b], [0], [ignore], [ignore], [test ! -e pid || kill `cat pid`; test ! -e pid2 || kill `cat pid2`])
+
+AT_CHECK([ovsdb-client transact tcp:127.0.0.1:$TCP_PORT1 \
+ '[["mydb",
+    {"op": "insert",
+      "table": "a",
+      "row": {"number": 0, "name": "zero"}},
+    {"op": "insert",
+      "table": "b",
+      "row": {"number": 1, "name": "one"}}]]'], [0], [stdout], [ignore],
+ [test ! -e pid || kill `cat pid`; test ! -e pid2 || kill `cat pid2`])
+sleep 2
+
+AT_CHECK([ovsdb-client dump tcp:127.0.0.1:$TCP_PORT1], [0], [stdout], [ignore],
+ [test ! -e pid || kill `cat pid`; test ! -e pid2 || kill `cat pid2`])
+cat stdout >> dump1
+AT_CHECK([ovsdb-client dump tcp:127.0.0.1:$TCP_PORT2], [0], [stdout], [ignore],
+ [test ! -e pid || kill `cat pid`; test ! -e pid2 || kill `cat pid2`])
+cat stdout >> dump2
+
+AT_CHECK([diff dump1 dump2], [1], [stdout], [ignore],
+        [test ! -e pid || kill `cat pid`; test ! -e pid2 || kill `cat pid2`])
+cat stdout >> output
+
+AT_CHECK([${PERL} $srcdir/uuidfilt.pl output], [0], [7,9c7,8
+< _uuid                                name number
+< ------------------------------------ ---- ------
+< <0> one  1     @&t@
+---
+> _uuid name number
+> ----- ---- ------
+], [ignore], [test ! -e pid || kill `cat pid`; test ! -e pid2 || kill `cat pid2`])
+
+OVSDB_SERVER_SHUTDOWN
+OVSDB_SERVER_SHUTDOWN2
+AT_CLEANUP
+
+#ovsdb-server/connect-remote-ovsdb-server
+AT_SETUP([ovsdb-server/connect-remote-server])
+AT_KEYWORDS([ovsdb server replication connect-remote-server])
+replication_schema > schema
+AT_CHECK([ovsdb-tool create db1 schema], [0], [stdout], [ignore])
+AT_CHECK([ovsdb-tool create db2 schema], [0], [stdout], [ignore])
+
+AT_CHECK([ovsdb-server --detach --no-chdir --log-file=ovsdb-server1.log --pidfile="`pwd`"/pid --remote=ptcp:0:127.0.0.1 --unixctl="`pwd`"/unixctl db1], [0], [ignore], [ignore])
+PARSE_LISTENING_PORT([ovsdb-server1.log], [TCP_PORT1])
+
+AT_CHECK([ovsdb-server --detach --no-chdir --log-file=ovsdb-server2.log --pidfile="`pwd`"/pid2 --remote=ptcp:0:127.0.0.1 --unixctl="`pwd`"/unixctl2 db2], [0], [ignore], [ignore])
+PARSE_LISTENING_PORT([ovsdb-server2.log], [TCP_PORT2])
+
+AT_CHECK([ovs-appctl -t "`pwd`"/unixctl2 ovsdb-server/set-remote-ovsdb-server tcp:127.0.0.1:$TCP_PORT1], [0], [ignore], [ignore], [test ! -e pid || kill `cat pid`; test ! -e pid2 || kill `cat pid2`])
+
+AT_CHECK([ovs-appctl -t "`pwd`"/unixctl2 ovsdb-server/connect-remote-ovsdb-server], [0], [ignore], [ignore],
+        [test ! -e pid || kill `cat pid`; test ! -e pid2 || kill `cat pid2`])
+
+AT_CHECK([ovsdb-client transact tcp:127.0.0.1:$TCP_PORT1 \
+ '[["mydb",
+  {"op": "insert",
+   "table": "a",
+   "row": {},
+   "uuid-name": "0"}]]'], [0], [stdout], [ignore],
+ [test ! -e pid || kill `cat pid`; test ! -e pid2 || kill `cat pid2`])
+sleep 2
+
+AT_CHECK([ovsdb-client dump tcp:127.0.0.1:$TCP_PORT1], [0], [stdout], [ignore],
+ [test ! -e pid || kill `cat pid`; test ! -e pid2 || kill `cat pid2`])
+cat stdout >> dump1
+AT_CHECK([ovsdb-client dump tcp:127.0.0.1:$TCP_PORT2], [0], [stdout], [ignore],
+ [test ! -e pid || kill `cat pid`; test ! -e pid2 || kill `cat pid2`])
+cat stdout >> dump2
+
+AT_CHECK([diff dump1 dump2], [0], [], [ignore], [test ! -e pid || kill `cat pid`; test ! -e pid2 || kill `cat pid2`])
+OVSDB_SERVER_SHUTDOWN
+OVSDB_SERVER_SHUTDOWN2
+AT_CLEANUP
+
+#ovsdb-server/disconnect-remote-server command
+AT_SETUP([ovsbd-server/disconnect-remote-server])
+AT_KEYWORDS([ovsdb server replication disconnect-remote-server])
+replication_schema > schema
+AT_CHECK([ovsdb-tool create db1 schema], [0], [stdout], [ignore])
+AT_CHECK([ovsdb-tool create db2 schema], [0], [stdout], [ignore])
+
+AT_CHECK([ovsdb-server --detach --no-chdir --log-file=ovsdb-server1.log --pidfile="`pwd`"/pid --remote=ptcp:0:127.0.0.1 --unixctl="`pwd`"/unixctl db1], [0], [ignore], [ignore])
+PARSE_LISTENING_PORT([ovsdb-server1.log], [TCP_PORT1])
+
+AT_CHECK([ovsdb-server --detach --no-chdir --log-file=ovsdb-server2.log --pidfile="`pwd`"/pid2 --remote=ptcp:0:127.0.0.1 --unixctl="`pwd`"/unixctl2 --sync-from=tcp:127.0.0.1:$TCP_PORT1        db2], [0], [ignore], [ignore])
+PARSE_LISTENING_PORT([ovsdb-server2.log], [TCP_PORT2])
+
+AT_CHECK([ovsdb-client transact tcp:127.0.0.1:$TCP_PORT1 \
+'[["mydb",
+  {"op": "insert",
+   "table": "a",
+   "row": {"number": 0, "name": "zero"}}]]'], [0], [stdout], [ignore],
+[test ! -e pid || kill `cat pid`; test ! -e pid2 || kill `cat pid2`])
+sleep 2
+
+AT_CHECK([ovs-appctl -t "`pwd`"/unixctl2 ovsdb-server/disconnect-remote-ovsdb-server], [0], [ignore], [ignore],
+        [test ! -e pid || kill `cat pid`; test ! -e pid2 || kill `cat pid2`])
+
+AT_CHECK([ovsdb-client transact tcp:127.0.0.1:$TCP_PORT1 \
+'[["mydb",
+  {"op": "insert",
+   "table": "b",
+   "row": {"number": 1, "name": "one"}}]]'], [0], [stdout], [ignore],
+[test ! -e pid || kill `cat pid`; test ! -e pid2 || kill `cat pid2`])
+sleep 2
+
+AT_CHECK([ovsdb-client dump tcp:127.0.0.1:$TCP_PORT1], [0], [stdout], [ignore],
+ [test ! -e pid || kill `cat pid`; test ! -e pid2 || kill `cat pid2`])
+cat stdout >> dump1
+
+AT_CHECK([ovsdb-client dump tcp:127.0.0.1:$TCP_PORT2], [0], [stdout], [ignore],
+ [test ! -e pid || kill `cat pid`; test ! -e pid2 || kill `cat pid2`])
+cat stdout >> dump2
+
+AT_CHECK([diff dump1 dump2], [1], [stdout], [ignore],
+        [test ! -e pid || kill `cat pid`; test ! -e pid2 || kill `cat pid2`])
+cat stdout >> output
+
+AT_CHECK([${PERL} $srcdir/uuidfilt.pl output], [0], [7,9c7,8
+< _uuid                                name number
+< ------------------------------------ ---- ------
+< <0> one  1     @&t@
+---
+> _uuid name number
+> ----- ---- ------
+], [ignore], [test ! -e pid || kill `cat pid`; test ! -e pid2 || kill `cat pid2`])
+
+OVSDB_SERVER_SHUTDOWN
+OVSDB_SERVER_SHUTDOWN2
+AT_CLEANUP