2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-22 01:51:26 +00:00
ovs/tests/ovsdb-monitor.at
Xavier Simonart 4fc02650ae ovsdb: Fix potential leak when making diff of conditions.
OVN unit tests highlight this:

ERROR: LeakSanitizer: detected memory leaks
Direct leak of 1344 byte(s) in 1 object(s) allocated from:
    0 0x4db0b7 in calloc (ovsdb/ovsdb-server+0x4db0b7)
    1 0x5c2162 in xcalloc__ lib/util.c:124:31
    2 0x5c221c in xcalloc lib/util.c:161:12
    3 0x54afbc in ovsdb_condition_diff ovsdb/condition.c:527:21
    4 0x529da6 in ovsdb_monitor_table_condition_update ovsdb/monitor.c:824:5
    5 0x524fa4 in ovsdb_jsonrpc_parse_monitor_cond_change_request ovsdb/jsonrpc-server.c:1557:13
    6 0x5235c3 in ovsdb_jsonrpc_monitor_cond_change ovsdb/jsonrpc-server.c:1624:25
    7 0x5217f2 in ovsdb_jsonrpc_session_got_request ovsdb/jsonrpc-server.c:1034:17
    8 0x520ee6 in ovsdb_jsonrpc_session_run ovsdb/jsonrpc-server.c:572:17
    9 0x51ffbe in ovsdb_jsonrpc_session_run_all ovsdb/jsonrpc-server.c:602:21
    10 0x51fbcf in ovsdb_jsonrpc_server_run ovsdb/jsonrpc-server.c:417:9
    11 0x517550 in main_loop ovsdb/ovsdb-server.c:224:9
    12 0x512e80 in main ovsdb/ovsdb-server.c:507:5
    13 0x7f9ecf675b74 in __libc_start_main (/lib64/libc.so.6+0x27b74)

Fixes: ef1da757f016 ("ovsdb: condition: Process condition changes incrementally.")
Signed-off-by: Xavier Simonart <xsimonar@redhat.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
2023-09-25 12:53:06 +02:00

1081 lines
39 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

AT_BANNER([OVSDB -- ovsdb-server monitors])
OVS_START_SHELL_HELPERS
# ovsdb_check_monitor SCHEMA_FUNC DB TABLE OUTPUT COLUMNS
# PRE-MONITOR-TXN... -- TRANSACTION...
ovsdb_check_monitor () {
local schema_func=$1 db=$2 table=$3 output=$4 columns=$5
shift; shift; shift; shift; shift
$schema_func > schema
AT_CHECK([ovsdb-tool create db schema], [0], [stdout], [ignore])
while test "$1" != "--"; do
AT_CHECK([ovsdb-tool transact db "$1"], [0], [ignore], [ignore])
shift
done
shift
AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --remote=punix:socket --log-file db > ovsdb-server.stdout 2> ovsdb-server.stderr],
[0], [], [])
on_exit 'kill `cat ovsdb-server.pid`'
if test "$IS_WIN32" = "yes"; then
AT_CHECK([ovsdb-client -vjsonrpc --pidfile --log-file -d json monitor --format=csv unix:socket $db $table $columns > output 2> ovsdb-client.stderr &],
[0], [ignore], [ignore])
sleep 1
else
AT_CHECK([ovsdb-client -vjsonrpc --detach --no-chdir --pidfile --log-file -d json monitor --format=csv unix:socket $db $table $columns > output 2> ovsdb-client.stderr],
[0], [ignore], [ignore])
fi
on_exit 'kill `cat ovsdb-client.pid`'
for txn in ${1+"$@"} '[["'$db'"]]'; do
AT_CHECK([ovsdb-client transact unix:socket "$txn"], [0], [ignore], [ignore])
done
OVSDB_SERVER_SHUTDOWN
OVS_WAIT_UNTIL([test ! -e ovsdb-client.pid])
AT_CHECK_UNQUOTED([$PYTHON3 $srcdir/ovsdb-monitor-sort.py < output | uuidfilt], [0], [$output], [ignore])
}
OVS_END_SHELL_HELPERS
# OVSDB_CHECK_MONITOR(TITLE, SCHEMA, [PRE-MONITOR-TXN], DB, TABLE,
# TRANSACTIONS, OUTPUT, [COLUMNS], [KEYWORDS])
#
# Creates a database with the given SCHEMA, starts an ovsdb-server on
# that database, and runs each of the TRANSACTIONS (which should be a
# quoted list of quoted strings) against it with ovsdb-client one at a
# time. COLUMNS, if specified, is passed to ovsdb-client as the set
# of columns and operations to select.
#
# Checks that the overall output is OUTPUT, but UUIDs in the output
# are replaced by markers of the form <N> where N is a number. The
# first unique UUID is replaced by <0>, the next by <1>, and so on.
# If a given UUID appears more than once it is always replaced by the
# same marker.
#
# TITLE is provided to AT_SETUP and KEYWORDS to AT_KEYWORDS.
m4_define([OVSDB_CHECK_MONITOR],
[AT_SETUP([$1])
AT_KEYWORDS([ovsdb server monitor positive $9])
AT_CAPTURE_FILE([ovsdb-server.log])
AT_CAPTURE_FILE([ovsdb-server.stdout])
AT_CAPTURE_FILE([ovsdb-server.stderr])
AT_CAPTURE_FILE([ovsdb-client.log])
AT_CAPTURE_FILE([ovsdb-client.stderr])
ovsdb_check_monitor '$2' '$4' '$5' '$7' '$8' \
m4_foreach([txn], [$3], ['txn' ]) -- \
m4_foreach([txn], [$6], ['txn' ])
AT_CLEANUP])
# OVSDB_CHECK_MONITOR_COND(TITLE, SCHEMA, [PRE-MONITOR-TXN], DB, TABLE,
# TRANSACTIONS, OUTPUT, CONDITIONS, [COLUMNS], [KEYWORDS],
# [CONDITIONS_CHANGE])
#
# Creates a database with the given SCHEMA, starts an ovsdb-server on
# that database, and runs each of the TRANSACTIONS (which should be a
# quoted list of quoted strings) against it with ovsdb-client one at a
# time. COLUMNS, if specified, is passed to ovsdb-client as the set
# of columns and operations to select.
#
# Checks that the overall output is OUTPUT, but UUIDs in the output
# are replaced by markers of the form <N> where N is a number. The
# first unique UUID is replaced by <0>, the next by <1>, and so on.
# If a given UUID appears more than once it is always replaced by the
# same marker.
#
# TITLE is provided to AT_SETUP and KEYWORDS to AT_KEYWORDS.
m4_define([OVSDB_CHECK_MONITOR_COND],
[AT_SETUP([$1])
AT_KEYWORDS([ovsdb server monitor monitor-cond positive $10])
$2 > schema
AT_CHECK([ovsdb-tool create db schema], [0], [stdout], [ignore])
for txn in m4_foreach([txn], [$3], ['txn' ]); do
AT_CHECK([ovsdb-tool transact db "$txn"], [0], [ignore], [ignore])
done
AT_CAPTURE_FILE([ovsdb-server.log])
AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --remote=punix:socket --log-file db], [0], [ignore], [ignore])
on_exit 'kill `cat ovsdb-server.pid`'
AT_CHECK([ovsdb-client -vjsonrpc --pidfile --detach --no-chdir -d json monitor-cond --format=csv unix:socket $4 '[$8]' $5 $9 > output 2> ovsdb-client.stderr],
[0], [ignore], [ignore])
on_exit 'kill `cat ovsdb-client.pid`'
for txn in m4_foreach([txn], [$6], ['txn' ]); do
AT_CHECK([ovsdb-client transact unix:socket "$txn"], [0],
[ignore], [ignore], [kill `cat server-pid client-pid`])
done
for cond in m4_foreach([cond], [$10], ['cond' ]); do
AT_CHECK([ovs-appctl -t ovsdb-client ovsdb-client/cond_change $5 "$cond"], [0], [ignore], [ignore])
done
AT_CHECK([ovsdb-client transact unix:socket '[["$4"]]'], [0],
[ignore], [ignore])
OVSDB_SERVER_SHUTDOWN
OVS_WAIT_UNTIL([test ! -e ovsdb-server.pid && test ! -e ovsdb-client.pid])
AT_CHECK([$PYTHON3 $srcdir/ovsdb-monitor-sort.py < output | uuidfilt], [0], [$7], [ignore])
AT_CLEANUP])
OVSDB_CHECK_MONITOR([monitor insert into empty table],
[ordinal_schema],
[],
[ordinals], [ordinals],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
"row": {"number": 0, "name": "zero"}}]]]],
[[row,action,name,number,_version
<0>,insert,"""zero""",0,"[""uuid"",""<1>""]"
]])
OVSDB_CHECK_MONITOR([monitor insert into populated table],
[ordinal_schema],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
"row": {"number": 10, "name": "ten"}}]]]],
[ordinals], [ordinals],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
"row": {"number": 0, "name": "zero"}}]]]],
[[row,action,name,number,_version
<0>,initial,"""ten""",10,"[""uuid"",""<1>""]"
row,action,name,number,_version
<2>,insert,"""zero""",0,"[""uuid"",""<3>""]"
]])
OVSDB_CHECK_MONITOR([monitor delete],
[ordinal_schema],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
"row": {"number": 10, "name": "ten"}}]]]],
[ordinals], [ordinals],
[[[["ordinals",
{"op": "delete",
"table": "ordinals",
"where": [["number", "==", 10]]}]]]],
[[row,action,name,number,_version
<0>,initial,"""ten""",10,"[""uuid"",""<1>""]"
row,action,name,number,_version
<0>,delete,"""ten""",10,"[""uuid"",""<1>""]"
]])
OVSDB_CHECK_MONITOR([monitor row update],
[ordinal_schema],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
"row": {"number": 10, "name": "ten"}}]]]],
[ordinals], [ordinals],
[[[["ordinals",
{"op": "update",
"table": "ordinals",
"where": [["number", "==", 10]],
"row": {"name": "five plus five"}}]]]],
[[row,action,name,number,_version
<0>,initial,"""ten""",10,"[""uuid"",""<1>""]"
row,action,name,number,_version
<0>,old,"""ten""",,"[""uuid"",""<1>""]"
,new,"""five plus five""",10,"[""uuid"",""<2>""]"
]])
OVSDB_CHECK_MONITOR([monitor no-op row updates],
[ordinal_schema],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
"row": {"number": 10, "name": "ten"}}]]]],
[ordinals], [ordinals],
[[[["ordinals",
{"op": "update",
"table": "ordinals",
"where": [["number", "==", 10]],
"row": {"number": 10, "name": "ten"}}]]],
[[["ordinals",
{"op": "insert",
"table": "ordinals",
"row": {"number": 9, "name": "nine"}}]]]],
[[row,action,name,number,_version
<0>,initial,"""ten""",10,"[""uuid"",""<1>""]"
row,action,name,number,_version
<2>,insert,"""nine""",9,"[""uuid"",""<3>""]"
]])
OVSDB_CHECK_MONITOR([monitor insert-and-update transaction],
[ordinal_schema],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
"row": {"number": 10, "name": "ten"}}]]]],
[ordinals], [ordinals],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
"row": {"number": 9, "name": "nine"},
"uuid-name": "nine"},
{"op": "update",
"table": "ordinals",
"where": [["_uuid", "==", ["named-uuid", "nine"]]],
"row": {"name": "three squared"}}]]]],
[[row,action,name,number,_version
<0>,initial,"""ten""",10,"[""uuid"",""<1>""]"
row,action,name,number,_version
<2>,insert,"""three squared""",9,"[""uuid"",""<3>""]"
]])
OVSDB_CHECK_MONITOR([monitor insert-update-and-delete transaction],
[ordinal_schema],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
"row": {"number": 10, "name": "ten"}}]]]],
[ordinals], [ordinals],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
"row": {"number": 9, "name": "nine"},
"uuid-name": "nine"},
{"op": "update",
"table": "ordinals",
"where": [["_uuid", "==", ["named-uuid", "nine"]]],
"row": {"name": "three squared"}},
{"op": "delete",
"table": "ordinals",
"where": [["_uuid", "==", ["named-uuid", "nine"]]]},
{"op": "insert",
"table": "ordinals",
"row": {"number": 7, "name": "seven"}}]]]],
[[row,action,name,number,_version
<0>,initial,"""ten""",10,"[""uuid"",""<1>""]"
row,action,name,number,_version
<2>,insert,"""seven""",7,"[""uuid"",""<3>""]"
]])
OVSDB_CHECK_MONITOR([monitor weak reference change],
[weak_schema],
[[[["weak",
{"op": "insert",
"table": "a",
"row": {"a": 0,
"a2a1": ["named-uuid", "a0"],
"a2b": ["named-uuid", "b2"]},
"uuid-name": "a0"},
{"op": "insert",
"table": "a",
"row": {"a": 1,
"a2a": ["named-uuid", "a0"],
"a2a1": ["named-uuid", "a1"],
"a2b": ["named-uuid", "b2"]},
"uuid-name": "a1"},
{"op": "insert",
"table": "b",
"row": {"b": 2},
"uuid-name": "b2"}]]]],
[weak], [a],
[[[["weak",
{"op": "delete",
"table": "a",
"where": [["a", "==", 0]]}]]]],
[[row,action,a,a2a,a2a1,a2b,_version
<0>,initial,0,"[""set"",[]]","[""uuid"",""<0>""]","[""uuid"",""<1>""]","[""uuid"",""<2>""]"
<3>,initial,1,"[""uuid"",""<0>""]","[""uuid"",""<3>""]","[""uuid"",""<1>""]","[""uuid"",""<4>""]"
row,action,a,a2a,a2a1,a2b,_version
<0>,delete,0,"[""set"",[]]","[""uuid"",""<0>""]","[""uuid"",""<1>""]","[""uuid"",""<2>""]"
<3>,old,,"[""uuid"",""<0>""]",,,"[""uuid"",""<4>""]"
,new,1,"[""set"",[]]","[""uuid"",""<3>""]","[""uuid"",""<1>""]","[""uuid"",""<5>""]"
]])
OVSDB_CHECK_MONITOR([monitor insert-update-and-delete transaction],
[ordinal_schema],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
"row": {"number": 10, "name": "ten"}}]]]],
[ordinals], [ordinals],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
"row": {"number": 9, "name": "nine"},
"uuid-name": "nine"},
{"op": "update",
"table": "ordinals",
"where": [["_uuid", "==", ["named-uuid", "nine"]]],
"row": {"name": "three squared"}},
{"op": "delete",
"table": "ordinals",
"where": [["_uuid", "==", ["named-uuid", "nine"]]]},
{"op": "insert",
"table": "ordinals",
"row": {"number": 7, "name": "seven"}}]]]],
[[row,action,name,number,_version
<0>,initial,"""ten""",10,"[""uuid"",""<1>""]"
row,action,name,number,_version
<2>,insert,"""seven""",7,"[""uuid"",""<3>""]"
]])
AT_BANNER([ovsdb -- ovsdb-monitor monitor only some operations])
m4_define([OVSDB_MONITOR_INITIAL],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
"row": {"number": 10, "name": "ten"}}]]]])
m4_define([OVSDB_MONITOR_TXNS],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
"row": {"number": 5, "name": "five"}}]]],
[[["ordinals",
{"op": "update",
"table": "ordinals",
"where": [["name", "==", "five"]],
"row": {"name": "FIVE"}}]]],
[[["ordinals",
{"op": "delete",
"table": "ordinals",
"where": []}]]]])
OVSDB_CHECK_MONITOR([monitor all operations],
[ordinal_schema], [OVSDB_MONITOR_INITIAL],
[ordinals], [ordinals], [OVSDB_MONITOR_TXNS],
[[row,action,name,number,_version
<0>,initial,"""ten""",10,"[""uuid"",""<1>""]"
row,action,name,number,_version
<2>,insert,"""five""",5,"[""uuid"",""<3>""]"
row,action,name,number,_version
<2>,old,"""five""",,"[""uuid"",""<3>""]"
,new,"""FIVE""",5,"[""uuid"",""<4>""]"
row,action,name,number,_version
<2>,delete,"""FIVE""",5,"[""uuid"",""<4>""]"
<0>,delete,"""ten""",10,"[""uuid"",""<1>""]"
]])
dnl A monitor with "initial" only doesn't really make sense,
dnl but it's still allowed and should work.
OVSDB_CHECK_MONITOR([monitor initial only],
[ordinal_schema], [OVSDB_MONITOR_INITIAL],
[ordinals], [ordinals], [OVSDB_MONITOR_TXNS],
[[row,action,name,number,_version
<0>,initial,"""ten""",10,"[""uuid"",""<1>""]"
]], [!insert,!delete,!modify])
OVSDB_CHECK_MONITOR([monitor insert only],
[ordinal_schema], [OVSDB_MONITOR_INITIAL],
[ordinals], [ordinals], [OVSDB_MONITOR_TXNS],
[[row,action,name,number,_version
<0>,insert,"""five""",5,"[""uuid"",""<1>""]"
]], [!initial,!delete,!modify])
OVSDB_CHECK_MONITOR([monitor delete only],
[ordinal_schema], [OVSDB_MONITOR_INITIAL],
[ordinals], [ordinals], [OVSDB_MONITOR_TXNS],
[[row,action,name,number,_version
<0>,delete,"""FIVE""",5,"[""uuid"",""<1>""]"
<2>,delete,"""ten""",10,"[""uuid"",""<3>""]"
]], [!initial,!insert,!modify])
OVSDB_CHECK_MONITOR([monitor modify only],
[ordinal_schema], [OVSDB_MONITOR_INITIAL],
[ordinals], [ordinals], [OVSDB_MONITOR_TXNS],
[[row,action,name,number,_version
<0>,old,"""five""",,"[""uuid"",""<1>""]"
,new,"""FIVE""",5,"[""uuid"",""<2>""]"
]], [!initial,!insert,!delete])
AT_BANNER([ovsdb -- ovsdb-monitor-cond conditional monitor only some operations])
OVSDB_CHECK_MONITOR_COND([monitor-cond empty condition],
[ordinal_schema],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
"row": {"number": 0, "name": "zero"}},
{"op": "insert",
"table": "ordinals",
"row": {"number": 1, "name": "one"}},
{"op": "insert",
"table": "ordinals",
"row": {"number": 2, "name": "two"}}]]]],
[ordinals], [ordinals],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
"row": {"number": 10, "name": "ten"}},
{"op": "insert",
"table": "ordinals",
"row": {"number": 11, "name": "eleven"}}]]]],
[[row,action,name,number,_version
<0>,initial,"""one""",1,"[""uuid"",""<1>""]"
<2>,initial,"""two""",2,"[""uuid"",""<3>""]"
<4>,initial,"""zero""",,"[""uuid"",""<5>""]"
row,action,name,number,_version
<6>,insert,"""eleven""",11,"[""uuid"",""<7>""]"
<8>,insert,"""ten""",10,"[""uuid"",""<9>""]"
]],
[[]])
OVSDB_CHECK_MONITOR_COND([monitor-cond multiple conditions],
[ordinal_schema],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
"row": {"number": 0, "name": "zero"}},
{"op": "insert",
"table": "ordinals",
"row": {"number": 1, "name": "one"}},
{"op": "insert",
"table": "ordinals",
"row": {"number": 2, "name": "two"}}]]]],
[ordinals], [ordinals],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
"row": {"number": 10, "name": "ten"}},
{"op": "insert",
"table": "ordinals",
"row": {"number": 11, "name": "eleven"}}]]]],
[[row,action,name,number,_version
<0>,initial,"""one""",1,"[""uuid"",""<1>""]"
row,action,name,number,_version
<2>,insert,"""ten""",10,"[""uuid"",""<3>""]"
]],
[[["name","==","one"],["name","==","ten"]]])
OVSDB_CHECK_MONITOR_COND([monitor-cond delete from populated table],
[ordinal_schema],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
"row": {"number": 0, "name": "zero"}},
{"op": "insert",
"table": "ordinals",
"row": {"number": 1, "name": "one"}},
{"op": "insert",
"table": "ordinals",
"row": {"number": 2, "name": "two"}}]]]],
[ordinals], [ordinals],
[[[["ordinals",
{"op": "delete",
"table": "ordinals",
"where": []}]]]],
[[row,action,name,number,_version
<0>,initial,"""one""",1,"[""uuid"",""<1>""]"
row,action,name,number,_version
<0>,delete,,,
]],
[[["name","==","one"],["name","==","ten"]]])
OVSDB_CHECK_MONITOR_COND([monitor-cond insert due to modify],
[ordinal_schema],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
"row": {"number": 0, "name": "zero"}},
{"op": "insert",
"table": "ordinals",
"row": {"number": 1, "name": "one"}},
{"op": "insert",
"table": "ordinals",
"row": {"number": 2, "name": "two"}}]]]],
[ordinals], [ordinals],
[[[["ordinals",
{"op": "update",
"table": "ordinals",
"where": [["name", "==", "one"]],
"row": {"name": "ONE"}}]]]],
[[row,action,name,number,_version
<0>,insert,"""ONE""",1,"[""uuid"",""<1>""]"
]],
[[["name","==","ONE"]]],
[!initial,!delete,!modify])
OVSDB_CHECK_MONITOR_COND([monitor-cond delete due to modify],
[ordinal_schema],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
"row": {"number": 0, "name": "zero"}},
{"op": "insert",
"table": "ordinals",
"row": {"number": 1, "name": "one"}},
{"op": "insert",
"table": "ordinals",
"row": {"number": 2, "name": "two"}}]]]],
[ordinals], [ordinals],
[[[["ordinals",
{"op": "update",
"table": "ordinals",
"where": [["name", "==", "one"]],
"row": {"name": "ONE"}}]]]],
[[row,action,name,number,_version
<0>,delete,,,
]],
[[["name","==","one"]]],
[!initial,!insert,!modify])
OVSDB_CHECK_MONITOR_COND([monitor-cond condition non-monitored columns],
[ordinal_schema],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
"row": {"number": 0, "name": "zero"}},
{"op": "insert",
"table": "ordinals",
"row": {"number": 1, "name": "one"}},
{"op": "insert",
"table": "ordinals",
"row": {"number": 2, "name": "two"}}]]]],
[ordinals], [ordinals],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
"row": {"number": 10, "name": "ten"}},
{"op": "insert",
"table": "ordinals",
"row": {"number": 11, "name": "eleven"}}]]]],
[[row,action,number
<0>,initial,1
row,action,number
<1>,insert,10
]],
[[["name","==","one"],["name","==","ten"]]],
["number"])
OVSDB_CHECK_MONITOR_COND([monitor-cond-change],
[ordinal_schema],
[[[["ordinals",
{"op": "insert",
"table": "ordinals",
"row": {"number": 0, "name": "zero"}},
{"op": "insert",
"table": "ordinals",
"row": {"number": 1, "name": "one"}},
{"op": "insert",
"table": "ordinals",
"row": {"number": 2, "name": "two"}}]]]],
[ordinals], [ordinals],
[],
[[row,action,name,number,_version
<0>,initial,"""one""",1,"[""uuid"",""<1>""]"
<2>,initial,"""two""",2,"[""uuid"",""<3>""]"
<4>,initial,"""zero""",,"[""uuid"",""<5>""]"
row,action,name,number,_version
<4>,delete,,,
row,action,name,number,_version
<2>,delete,,,
row,action,name,number,_version
<0>,delete,,,
row,action,name,number,_version
<0>,insert,"""one""",1,"[""uuid"",""<1>""]"
<2>,insert,"""two""",2,"[""uuid"",""<3>""]"
<4>,insert,"""zero""",,"[""uuid"",""<5>""]"
]],
[[]],
[],
[[[[["name","==","one"],["name","==","two"]]]],
[[[["name","==","two"],["name","==","one"]]]],
[[[["name","==","one"]]]],
[[[false]]],
[[[true]]]])
AT_SETUP(monitor-cond-change with many sessions pending)
AT_KEYWORDS([ovsdb server monitor monitor-cond negative])
ordinal_schema > schema
AT_CHECK([ovsdb-tool create db schema], [0], [stdout], [ignore])
AT_CAPTURE_FILE([ovsdb-server.log])
AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --remote=punix:socket --log-file db], [0], [ignore], [ignore])
on_exit 'kill `cat ovsdb-server.pid`'
for txn in m4_foreach([txn], [[[["ordinals",
{"op": "insert",
"table": "ordinals",
"row": {"number": 0, "name": "zero"}},
{"op": "insert",
"table": "ordinals",
"row": {"number": 1, "name": "one"}},
{"op": "insert",
"table": "ordinals",
"row": {"number": 2, "name": "two"}}]]]], ['txn' ]); do
AT_CHECK([ovsdb-client transact unix:socket "$txn"], [0], [ignore], [ignore])
done
# 1001 clients monitoring column "name" and with condition for "name" only.
# The clients are created in a way that the 991th client will request condition
# change, so that the chance is high that the condition change will be handled
# before some pending changes are freed.
cond='[[["name","==","ten"]]]'
for i in `seq 1 990`; do
AT_CHECK([ovsdb-client -vjsonrpc --pidfile=ovsdb-client$i.pid --detach --no-chdir -d json monitor-cond --format=csv unix:socket ordinals $cond ordinals ["name"] >ovsdb-client$i.out 2>&1], [0], [ignore], [ignore])
done
AT_CHECK([ovsdb-client -vjsonrpc --pidfile --detach --no-chdir -d json monitor-cond --format=csv unix:socket ordinals $cond ordinals ["name"] > output 2> ovsdb-client.stderr],
[0], [ignore], [ignore])
for i in `seq 991 1000`; do
AT_CHECK([ovsdb-client -vjsonrpc --pidfile=ovsdb-client$i.pid --detach --no-chdir -d json monitor-cond --format=csv unix:socket ordinals $cond ordinals ["name"] >ovsdb-client$i.out 2>&1 ], [0], [ignore], [ignore])
done
for txn in m4_foreach([txn], [[[["ordinals",
{"op": "insert",
"table": "ordinals",
"row": {"number": 10, "name": "ten"}}]]]], ['txn' ]); do
AT_CHECK([ovsdb-client transact unix:socket "$txn"], [0],
[ignore], [ignore], [kill `cat server-pid client-pid`])
done
# Change the condition so that a new column "number" is added to monitor table.
cond='[[["number","==",1]]]'
AT_CHECK([ovs-appctl -t ovsdb-client ovsdb-client/cond_change ordinals $cond], [0], [ignore], [ignore])
# Give some time for the server to flush and free pending changes
# (to crash, when n_columns is not handled properly)
sleep 1
AT_CHECK([ovsdb-client transact unix:socket '[["ordinals"]]'], [0],
[ignore], [ignore])
OVSDB_SERVER_SHUTDOWN("/Too many open files/d")
OVS_WAIT_UNTIL([test ! -e ovsdb-server.pid && test ! -e ovsdb-client.pid])
AT_CHECK([$PYTHON3 $srcdir/ovsdb-monitor-sort.py < output | uuidfilt], [0], [[row,action,name
<0>,insert,"""ten"""
row,action,name
<0>,delete,
<1>,insert,"""one"""
]], [ignore])
AT_CLEANUP
# Test monitor-cond-since with zero uuid, which shouldn't
# be found in server and server should send all rows
# as initial.
AT_SETUP([monitor-cond-since not found])
AT_KEYWORDS([ovsdb server monitor monitor-cond-since positive])
ordinal_schema > schema
AT_CHECK([ovsdb-tool create-cluster db schema unix:db.raft], [0], [stdout], [ignore])
AT_CAPTURE_FILE([ovsdb-server.log])
AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --remote=punix:socket --log-file db], [0], [ignore], [ignore])
on_exit 'kill `cat ovsdb-server.pid`'
for txn in m4_foreach([txn], [[[["ordinals",
{"op": "insert",
"table": "ordinals",
"row": {"number": 0, "name": "zero"}},
{"op": "insert",
"table": "ordinals",
"row": {"number": 1, "name": "one"}},
{"op": "insert",
"table": "ordinals",
"row": {"number": 2, "name": "two"}}]]]], ['txn' ]); do
AT_CHECK([ovsdb-client transact unix:socket "$txn"], [0], [ignore], [ignore])
done
# Omitting the last_id parameter in ovsdb-client monitor-cond-since command
# will by default using all zero uuid, which doesn't exist in any history txn.
AT_CHECK([ovsdb-client -vjsonrpc --pidfile --detach --no-chdir -d json monitor-cond-since --format=csv unix:socket ordinals '[[["name","==","one"],["name","==","ten"]]]' ordinals > output 2> ovsdb-client.stderr],
[0], [ignore], [ignore])
on_exit 'kill `cat ovsdb-client.pid`'
for txn in m4_foreach([txn], [[[["ordinals",
{"op": "insert",
"table": "ordinals",
"row": {"number": 10, "name": "ten"}},
{"op": "insert",
"table": "ordinals",
"row": {"number": 11, "name": "eleven"}}]]]], ['txn' ]); do
AT_CHECK([ovsdb-client transact unix:socket "$txn"], [0],
[ignore], [ignore], [kill `cat server-pid client-pid`])
done
AT_CHECK([ovsdb-client transact unix:socket '[["ordinals"]]'], [0],
[ignore], [ignore])
OVSDB_SERVER_SHUTDOWN
OVS_WAIT_UNTIL([test ! -e ovsdb-server.pid && test ! -e ovsdb-client.pid])
AT_CHECK([$PYTHON3 $srcdir/ovsdb-monitor-sort.py < output | uuidfilt], [0],
[[found: false, last_id: <0>
row,action,name,number,_version
<1>,initial,"""one""",1,"[""uuid"",""<2>""]"
last_id: <3>
row,action,name,number,_version
<4>,insert,"""ten""",10,"[""uuid"",""<5>""]"
]], [ignore])
AT_CLEANUP
# Test monitor-cond-since in ovsdb server restart scenario.
# ovsdb-client should receive only new changes after the
# specific transaction id.
AT_SETUP([monitor-cond-since db restart])
AT_KEYWORDS([ovsdb server monitor monitor-cond-since positive])
ordinal_schema > schema
AT_CHECK([ovsdb-tool create-cluster db schema unix:db.raft], [0], [stdout], [ignore])
AT_CAPTURE_FILE([ovsdb-server.log])
AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --remote=punix:socket --log-file db], [0], [ignore], [ignore])
on_exit 'kill `cat ovsdb-server.pid`'
for txn in m4_foreach([txn], [[[["ordinals",
{"op": "insert",
"table": "ordinals",
"row": {"number": 0, "name": "zero"}},
{"op": "insert",
"table": "ordinals",
"row": {"number": 1, "name": "one"}},
{"op": "insert",
"table": "ordinals",
"row": {"number": 2, "name": "two"}}]]]], ['txn' ]); do
AT_CHECK([ovsdb-client transact unix:socket "$txn"], [0], [ignore], [ignore])
done
AT_CHECK([ovsdb-client -vjsonrpc --pidfile --detach --no-chdir -d json monitor-cond-since --format=csv unix:socket ordinals '[[["name","==","one"],["name","==","ten"]]]' ordinals > output 2> ovsdb-client.stderr],
[0], [ignore], [ignore])
on_exit 'kill `cat ovsdb-client.pid`'
OVS_WAIT_UNTIL([grep last_id output])
OVSDB_SERVER_SHUTDOWN
OVS_WAIT_UNTIL([test ! -e ovsdb-server.pid && test ! -e ovsdb-client.pid])
# Remember the last_id, which will be used for monitor-cond-since later.
last_id=`grep last_id output | awk '{print $4}'`
AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --remote=punix:socket --log-file db], [0], [ignore], [ignore])
# Some new changes made to db after restarting the server.
for txn in m4_foreach([txn], [[[["ordinals",
{"op": "insert",
"table": "ordinals",
"row": {"number": 10, "name": "ten"}},
{"op": "insert",
"table": "ordinals",
"row": {"number": 11, "name": "eleven"}}]]]], ['txn' ]); do
AT_CHECK([ovsdb-client transact unix:socket "$txn"], [0],
[ignore], [ignore], [kill `cat server-pid client-pid`])
done
# Use last_id to monitor and get only the new changes.
AT_CHECK([ovsdb-client -vjsonrpc --pidfile --detach --no-chdir -d json monitor-cond-since --format=csv unix:socket ordinals $last_id '[[["name","==","one"],["name","==","ten"]]]' ordinals > output 2> ovsdb-client.stderr],
[0], [ignore], [ignore])
AT_CHECK([ovsdb-client transact unix:socket '[["ordinals"]]'], [0],
[ignore], [ignore])
OVSDB_SERVER_SHUTDOWN
OVS_WAIT_UNTIL([test ! -e ovsdb-server.pid && test ! -e ovsdb-client.pid])
AT_CHECK([$PYTHON3 $srcdir/ovsdb-monitor-sort.py < output | uuidfilt], [0],
[[found: true, last_id: <0>
row,action,name,number,_version
<1>,insert,"""ten""",10,"[""uuid"",""<2>""]"
]], [ignore])
AT_CLEANUP
# Test monitor-cond-since with last_id found in server
# but there is no new change after that transaction.
AT_SETUP([monitor-cond-since found but no new rows])
AT_KEYWORDS([ovsdb server monitor monitor-cond-since positive])
ordinal_schema > schema
AT_CHECK([ovsdb-tool create-cluster db schema unix:db.raft], [0], [stdout], [ignore])
AT_CAPTURE_FILE([ovsdb-server.log])
AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --remote=punix:socket --log-file db], [0], [ignore], [ignore])
on_exit 'kill `cat ovsdb-server.pid`'
for txn in m4_foreach([txn], [[[["ordinals",
{"op": "insert",
"table": "ordinals",
"row": {"number": 0, "name": "zero"}},
{"op": "insert",
"table": "ordinals",
"row": {"number": 1, "name": "one"}},
{"op": "insert",
"table": "ordinals",
"row": {"number": 2, "name": "two"}}]]]], ['txn' ]); do
AT_CHECK([ovsdb-client transact unix:socket "$txn"], [0], [ignore], [ignore])
done
AT_CHECK([ovsdb-client -vjsonrpc --pidfile --detach --no-chdir -d json monitor-cond-since --format=csv unix:socket ordinals '[[["name","==","one"],["name","==","ten"]]]' ordinals > output 2> ovsdb-client.stderr],
[0], [ignore], [ignore])
on_exit 'kill `cat ovsdb-client.pid`'
OVS_WAIT_UNTIL([grep last_id output])
kill `cat ovsdb-client.pid`
OVS_WAIT_UNTIL([test ! -e ovsdb-client.pid])
last_id=`grep last_id output | awk '{print $4}'`
AT_CHECK([ovsdb-client -vjsonrpc --pidfile --detach --no-chdir -d json monitor-cond-since --format=csv unix:socket ordinals $last_id '[[["name","==","one"],["name","==","ten"]]]' ordinals > output 2> ovsdb-client.stderr],
[0], [ignore], [ignore])
AT_CHECK([ovsdb-client transact unix:socket '[["ordinals"]]'], [0],
[ignore], [ignore])
OVSDB_SERVER_SHUTDOWN
OVS_WAIT_UNTIL([test ! -e ovsdb-server.pid && test ! -e ovsdb-client.pid])
AT_CHECK([$PYTHON3 $srcdir/ovsdb-monitor-sort.py < output | uuidfilt], [0],
[[found: true, last_id: <0>
]], [ignore])
AT_CLEANUP
# Test monitor-cond-since against empty DB
AT_SETUP([monitor-cond-since empty db])
AT_KEYWORDS([ovsdb server monitor monitor-cond-since positive])
ordinal_schema > schema
AT_CHECK([ovsdb-tool create-cluster db schema unix:db.raft], [0], [stdout], [ignore])
AT_CAPTURE_FILE([ovsdb-server.log])
AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --remote=punix:socket --log-file db], [0], [ignore], [ignore])
on_exit 'kill `cat ovsdb-server.pid`'
AT_CHECK([ovsdb-client -vjsonrpc --pidfile --detach --no-chdir -d json monitor-cond-since --format=csv unix:socket ordinals '[[["name","==","one"],["name","==","ten"]]]' ordinals > output 2> ovsdb-client.stderr],
[0], [ignore], [ignore])
on_exit 'kill `cat ovsdb-client.pid`'
OVS_WAIT_UNTIL([grep last_id output])
AT_CHECK([ovsdb-client transact unix:socket '[["ordinals"]]'], [0],
[ignore], [ignore])
OVSDB_SERVER_SHUTDOWN
OVS_WAIT_UNTIL([test ! -e ovsdb-server.pid && test ! -e ovsdb-client.pid])
AT_CHECK([$PYTHON3 $srcdir/ovsdb-monitor-sort.py < output | uuidfilt], [0],
[[found: false, last_id: <0>
]], [ignore])
AT_CLEANUP
# Test monitor-cond-since with cond-change followed.
AT_SETUP([monitor-cond-since condition change])
AT_KEYWORDS([ovsdb server monitor monitor-cond-since positive])
ordinal_schema > schema
AT_CHECK([ovsdb-tool create-cluster db schema unix:db.raft], [0], [stdout], [ignore])
AT_CAPTURE_FILE([ovsdb-server.log])
AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --remote=punix:socket --log-file -vjsonrpc:file:dbg db], [0], [ignore], [ignore])
on_exit 'kill `cat ovsdb-server.pid`'
for txn in m4_foreach([txn], [[[["ordinals",
{"op": "insert",
"table": "ordinals",
"row": {"number": 0, "name": "zero"}},
{"op": "insert",
"table": "ordinals",
"row": {"number": 1, "name": "one"}},
{"op": "insert",
"table": "ordinals",
"row": {"number": 2, "name": "two"}}]]]], ['txn' ]); do
AT_CHECK([ovsdb-client transact unix:socket "$txn"], [0], [ignore], [ignore])
done
AT_CAPTURE_FILE([ovsdb-client.log])
AT_CHECK([ovsdb-client -vjsonrpc --log-file --pidfile --detach --no-chdir -d json monitor-cond-since --format=csv unix:socket ordinals '[[]]' ordinals > output 2> ovsdb-client.stderr])
on_exit 'kill `cat ovsdb-client.pid`'
for cond in m4_foreach([cond],
[[[[["name","==","one"],["name","==","two"]]]],
[[[["name","==","one"]]]],
[[[false]]],
[[[true]]]], ['cond' ]); do
AT_CHECK([ovs-appctl -t ovsdb-client ovsdb-client/cond_change ordinals "$cond"], [0], [ignore], [ignore])
done
AT_CHECK([ovsdb-client transact unix:socket '[["ordinals"]]'], [0],
[ignore], [ignore])
OVSDB_SERVER_SHUTDOWN
OVS_WAIT_UNTIL([test ! -e ovsdb-server.pid && test ! -e ovsdb-client.pid])
AT_CHECK([$PYTHON3 $srcdir/ovsdb-monitor-sort.py < output | uuidfilt], [0],
[[found: false, last_id: <0>
row,action,name,number,_version
<1>,initial,"""one""",1,"[""uuid"",""<2>""]"
<3>,initial,"""two""",2,"[""uuid"",""<4>""]"
<5>,initial,"""zero""",,"[""uuid"",""<6>""]"
last_id: <0>
row,action,name,number,_version
<5>,delete,,,
last_id: <0>
row,action,name,number,_version
<3>,delete,,,
last_id: <0>
row,action,name,number,_version
<1>,delete,,,
last_id: <0>
row,action,name,number,_version
<1>,insert,"""one""",1,"[""uuid"",""<2>""]"
<3>,insert,"""two""",2,"[""uuid"",""<4>""]"
<5>,insert,"""zero""",,"[""uuid"",""<6>""]"
]], [ignore])
AT_CLEANUP
# Test monitor-cond-since with non-cluster mode server
AT_SETUP([monitor-cond-since non-cluster])
AT_KEYWORDS([ovsdb server monitor monitor-cond-since positive])
ordinal_schema > schema
AT_CHECK([ovsdb-tool create db schema], [0], [stdout], [ignore])
AT_CAPTURE_FILE([ovsdb-server.log])
AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --remote=punix:socket --log-file db], [0], [ignore], [ignore])
on_exit 'kill `cat ovsdb-server.pid`'
for txn in m4_foreach([txn], [[[["ordinals",
{"op": "insert",
"table": "ordinals",
"row": {"number": 0, "name": "zero"}},
{"op": "insert",
"table": "ordinals",
"row": {"number": 1, "name": "one"}},
{"op": "insert",
"table": "ordinals",
"row": {"number": 2, "name": "two"}}]]]], ['txn' ]); do
AT_CHECK([ovsdb-client transact unix:socket "$txn"], [0], [ignore], [ignore])
done
AT_CHECK([ovsdb-client -vjsonrpc --pidfile --detach --no-chdir -d json monitor-cond-since --format=csv unix:socket ordinals '[[["name","==","one"],["name","==","ten"]]]' ordinals > output 2> ovsdb-client.stderr],
[0], [ignore], [ignore])
on_exit 'kill `cat ovsdb-client.pid`'
for txn in m4_foreach([txn], [[[["ordinals",
{"op": "insert",
"table": "ordinals",
"row": {"number": 10, "name": "ten"}},
{"op": "insert",
"table": "ordinals",
"row": {"number": 11, "name": "eleven"}}]]]], ['txn' ]); do
AT_CHECK([ovsdb-client transact unix:socket "$txn"], [0],
[ignore], [ignore], [kill `cat server-pid client-pid`])
done
AT_CHECK([ovsdb-client transact unix:socket '[["ordinals"]]'], [0],
[ignore], [ignore])
OVSDB_SERVER_SHUTDOWN
OVS_WAIT_UNTIL([test ! -e ovsdb-server.pid && test ! -e ovsdb-client.pid])
# Transaction shouldn't be found, and last_id returned should always
# be the same (all zero uuid)
AT_CHECK([$PYTHON3 $srcdir/ovsdb-monitor-sort.py < output | uuidfilt], [0],
[[found: false, last_id: <0>
row,action,name,number,_version
<1>,initial,"""one""",1,"[""uuid"",""<2>""]"
last_id: <0>
row,action,name,number,_version
<3>,insert,"""ten""",10,"[""uuid"",""<4>""]"
]], [ignore])
AT_CLEANUP
# Test monitor-cond-since with non-cluster mode server with non-zero last_id
AT_SETUP([monitor-cond-since non-cluster non-zero last_id])
AT_KEYWORDS([ovsdb server monitor monitor-cond-since negative])
ordinal_schema > schema
AT_CHECK([ovsdb-tool create db schema], [0], [stdout], [ignore])
AT_CAPTURE_FILE([ovsdb-server.log])
AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --remote=punix:socket --log-file db], [0], [ignore], [ignore])
on_exit 'kill `cat ovsdb-server.pid`'
for txn in m4_foreach([txn], [[[["ordinals",
{"op": "insert",
"table": "ordinals",
"row": {"number": 0, "name": "zero"}},
{"op": "insert",
"table": "ordinals",
"row": {"number": 1, "name": "one"}},
{"op": "insert",
"table": "ordinals",
"row": {"number": 2, "name": "two"}}]]]], ['txn' ]); do
AT_CHECK([ovsdb-client transact unix:socket "$txn"], [0], [ignore], [ignore])
done
# A non-zero uuid
last_id=11111111-1111-1111-1111-111111111111
AT_CHECK([ovsdb-client -vjsonrpc --pidfile --detach --no-chdir -d json monitor-cond-since --format=csv unix:socket ordinals $last_id '[[["name","==","one"],["name","==","ten"]]]' ordinals > output 2> ovsdb-client.stderr],
[0], [ignore], [ignore])
on_exit 'kill `cat ovsdb-client.pid`'
for txn in m4_foreach([txn], [[[["ordinals",
{"op": "insert",
"table": "ordinals",
"row": {"number": 10, "name": "ten"}},
{"op": "insert",
"table": "ordinals",
"row": {"number": 11, "name": "eleven"}}]]]], ['txn' ]); do
AT_CHECK([ovsdb-client transact unix:socket "$txn"], [0],
[ignore], [ignore], [kill `cat server-pid client-pid`])
done
AT_CHECK([ovsdb-client transact unix:socket '[["ordinals"]]'], [0],
[ignore], [ignore])
OVSDB_SERVER_SHUTDOWN
OVS_WAIT_UNTIL([test ! -e ovsdb-server.pid && test ! -e ovsdb-client.pid])
# Transaction shouldn't be found, and last_id returned should always
# be the same (all zero uuid)
AT_CHECK([$PYTHON3 $srcdir/ovsdb-monitor-sort.py < output | uuidfilt], [0],
[[found: false, last_id: <0>
row,action,name,number,_version
<1>,initial,"""one""",1,"[""uuid"",""<2>""]"
last_id: <0>
row,action,name,number,_version
<3>,insert,"""ten""",10,"[""uuid"",""<4>""]"
]], [ignore])
AT_CLEANUP
AT_SETUP([monitor-cond initial reply with condition on non-monitored column])
AT_KEYWORDS([ovsdb server monitor monitor-cond positive initial non-monitored])
ordinal_schema > schema
AT_CHECK([ovsdb-tool create db schema], [0], [stdout], [ignore])
on_exit 'kill `cat ovsdb-server.pid`'
AT_CAPTURE_FILE([ovsdb-server.log])
AT_CHECK([ovsdb-server --detach --no-chdir --pidfile \
--remote=punix:socket --log-file db], [0], [ignore], [ignore])
dnl Initialize the database content.
for txn in m4_foreach([txn], [[[["ordinals",
{"op": "insert",
"table": "ordinals",
"row": {"number": 0, "name": "zero"}},
{"op": "insert",
"table": "ordinals",
"row": {"number": 1, "name": "one"}},
{"op": "insert",
"table": "ordinals",
"row": {"number": 2, "name": "two"}}]]]], ['txn' ]); do
AT_CHECK([ovsdb-client transact unix:socket "$txn"], [0], [ignore], [ignore])
done
dnl Start a first client that monitors only the column 'name'.
on_exit 'kill `cat client-1.pid`'
AT_CAPTURE_FILE([client-1.out])
AT_CHECK([ovsdb-client -vjsonrpc --pidfile=client-1.pid --detach --no-chdir \
-d json monitor-cond --format=csv unix:socket \
ordinals '[[true]]' ordinals ["name"] \
> client-1.out 2> client-1.err], [0], [ignore], [ignore])
dnl Wait for the initial monitor reply.
OVS_WAIT_UNTIL([grep -q 'initial' client-1.out])
dnl Start a second client that monitors the column 'name', but has a condition
dnl on column 'number'.
on_exit 'kill `cat client-2.pid`'
AT_CAPTURE_FILE([client-2.out])
AT_CHECK([ovsdb-client -vjsonrpc --pidfile=client-2.pid --detach --no-chdir \
-d json monitor-cond --format=csv unix:socket \
ordinals '[[["number", "!=", 1]]]' ordinals ["name"] \
> client-2.out 2> client-2.err], [0], [ignore], [ignore])
dnl Wait for the initial monitor reply.
OVS_WAIT_UNTIL([grep -q 'initial' client-2.out])
OVSDB_SERVER_SHUTDOWN
OVS_WAIT_UNTIL([test ! -e ovsdb-server.pid && \
test ! -e client-1.pid && test ! -e client-2.pid])
dnl The first client should have all the names.
AT_CHECK([$PYTHON3 $srcdir/ovsdb-monitor-sort.py < client-1.out | uuidfilt],
[0], [dnl
row,action,name
<0>,initial,"""one"""
<1>,initial,"""two"""
<2>,initial,"""zero"""
])
dnl The second client should not have the name 'one'.
AT_CHECK([$PYTHON3 $srcdir/ovsdb-monitor-sort.py < client-2.out | uuidfilt],
[0], [dnl
row,action,name
<0>,initial,"""two"""
<1>,initial,"""zero"""
])
AT_CLEANUP