2
0
mirror of https://github.com/openvswitch/ovs synced 2025-10-29 15:28:56 +00:00

python: Send old values of the updated cols in notify for update2

When python IDL calls the "notify" function after processing the "update2"
message from ovsdb-server, it is suppose to send the old values of the
updated columns as the last parameter. But the recent commit "897c8064"
sends the updated values. This breaks the behaviour.
This patch fixes this issue. It also updates the description of
the 'updates' param of the notify function to make it more clear.

Fixes: 897c8064 ("python: move Python idl to work with monitor_cond")
Signed-off-by: Numan Siddique <nusiddiq@redhat.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
This commit is contained in:
Numan Siddique
2016-07-26 23:28:14 +05:30
committed by Ben Pfaff
parent d2fa6c676a
commit a7261bf7ac
3 changed files with 162 additions and 18 deletions

View File

@@ -333,7 +333,8 @@ class Idl(object):
:type event: ROW_CREATE, ROW_UPDATE, or ROW_DELETE :type event: ROW_CREATE, ROW_UPDATE, or ROW_DELETE
:param row: The row as it is after the operation has occured :param row: The row as it is after the operation has occured
:type row: Row :type row: Row
:param updates: For updates, row with only updated columns :param updates: For updates, row with only old values of the changed
columns
:type updates: Row :type updates: Row
""" """
@@ -511,9 +512,10 @@ class Idl(object):
if not row: if not row:
raise error.Error('Modify non-existing row') raise error.Error('Modify non-existing row')
self.__apply_diff(table, row, row_update['modify']) old_row_diff_json = self.__apply_diff(table, row,
row_update['modify'])
self.notify(ROW_UPDATE, row, self.notify(ROW_UPDATE, row,
Row.from_json(self, table, uuid, row_update['modify'])) Row.from_json(self, table, uuid, old_row_diff_json))
changed = True changed = True
else: else:
raise error.Error('<row-update> unknown operation', raise error.Error('<row-update> unknown operation',
@@ -576,7 +578,8 @@ class Idl(object):
row_update[column.name] = self.__column_name(column) row_update[column.name] = self.__column_name(column)
def __apply_diff(self, table, row, row_diff): def __apply_diff(self, table, row, row_diff):
for column_name, datum_json in six.iteritems(row_diff): old_row_diff_json = {}
for column_name, datum_diff_json in six.iteritems(row_diff):
column = table.columns.get(column_name) column = table.columns.get(column_name)
if not column: if not column:
# XXX rate-limit # XXX rate-limit
@@ -585,17 +588,21 @@ class Idl(object):
continue continue
try: try:
datum = ovs.db.data.Datum.from_json(column.type, datum_json) datum_diff = ovs.db.data.Datum.from_json(column.type,
datum_diff_json)
except error.Error as e: except error.Error as e:
# XXX rate-limit # XXX rate-limit
vlog.warn("error parsing column %s in table %s: %s" vlog.warn("error parsing column %s in table %s: %s"
% (column_name, table.name, e)) % (column_name, table.name, e))
continue continue
datum = row._data[column_name].diff(datum) old_row_diff_json[column_name] = row._data[column_name].to_json()
datum = row._data[column_name].diff(datum_diff)
if datum != row._data[column_name]: if datum != row._data[column_name]:
row._data[column_name] = datum row._data[column_name] = datum
return old_row_diff_json
def __row_update(self, table, row, row_json): def __row_update(self, table, row, row_json):
changed = False changed = False
for column_name, datum_json in six.iteritems(row_json): for column_name, datum_json in six.iteritems(row_json):

View File

@@ -1106,3 +1106,111 @@ OVSDB_CHECK_IDL_PARTIAL_UPDATE_MAP_COLUMN([map, simple2 idl-partial-update-map-c
009: name=String2 smap=[[key2 : value2]] imap=[[3 : myids2]] 009: name=String2 smap=[[key2 : value2]] imap=[[3 : myids2]]
010: End test 010: End test
]]) ]])
m4_define([OVSDB_CHECK_IDL_NOTIFY_PY],
[AT_SETUP([$1 - Python])
AT_SKIP_IF([test $HAVE_PYTHON = no])
AT_KEYWORDS([ovsdb server idl Python notify $4])
AT_CHECK([ovsdb-tool create db $abs_srcdir/idltest.ovsschema],
[0], [stdout], [ignore])
AT_CHECK([ovsdb-server '-vPATTERN:console:ovsdb-server|%c|%m' --detach --no-chdir --pidfile="`pwd`"/pid --remote=punix:socket --unixctl="`pwd`"/unixctl db], [0], [ignore], [ignore])
AT_CHECK([$PYTHON $srcdir/test-ovsdb.py -t10 idl $srcdir/idltest.ovsschema unix:socket $2],
[0], [stdout], [ignore], [kill `cat pid`])
AT_CHECK([sort stdout | ${PERL} $srcdir/uuidfilt.pl]m4_if([$5],,, [[| $5]]),
[0], [$3], [], [kill `cat pid`])
OVSDB_SERVER_SHUTDOWN
AT_CLEANUP])
m4_define([OVSDB_CHECK_IDL_NOTIFY],
[OVSDB_CHECK_IDL_NOTIFY_PY($@)])
OVSDB_CHECK_IDL_NOTIFY([simple idl verify notify],
[['track-notify' \
'["idltest",
{"op": "insert",
"table": "simple",
"row": {"i": 1,
"r": 2.0,
"b": true,
"s": "mystring",
"u": ["uuid", "84f5c8f5-ac76-4dbc-a24f-8860eb407fc1"],
"ia": ["set", [1, 2, 3]],
"ra": ["set", [-0.5]],
"ba": ["set", [true]],
"sa": ["set", ["abc", "def"]],
"ua": ["set", [["uuid", "69443985-7806-45e2-b35f-574a04e720f9"],
["uuid", "aad11ef0-816a-4b01-93e6-03b8b4256b98"]]]}},
{"op": "insert",
"table": "simple",
"row": {}}]' \
'["idltest",
{"op": "update",
"table": "simple",
"where": [],
"row": {"b": false}}]' \
'["idltest",
{"op": "update",
"table": "simple",
"where": [],
"row": {"r": 123.5}}]' \
'["idltest",
{"op": "insert",
"table": "simple",
"row": {"i": -1,
"r": 125,
"b": false,
"s": "",
"ia": ["set", [1]],
"ra": ["set", [1.5]],
"ba": ["set", [false]],
"sa": ["set", []],
"ua": ["set", []]}}]' \
'["idltest",
{"op": "update",
"table": "simple",
"where": [["i", "<", 1]],
"row": {"s": "newstring"}}]' \
'["idltest",
{"op": "delete",
"table": "simple",
"where": [["i", "==", 0]]}]' \
'reconnect']],
[[000: empty
001: {"error":null,"result":[{"uuid":["uuid","<0>"]},{"uuid":["uuid","<1>"]}]}
002: event:create, row={i=0 r=0 b=false s= u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>}, updates=None
002: event:create, row={i=1 r=2 b=true s=mystring u=<3> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<4> <5>] uuid=<0>}, updates=None
002: i=0 r=0 b=false s= u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
002: i=1 r=2 b=true s=mystring u=<3> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<4> <5>] uuid=<0>
003: {"error":null,"result":[{"count":2}]}
004: event:update, row={i=1 r=2 b=false s=mystring u=<3> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<4> <5>] uuid=<0>}, updates={b=true uuid=<0>}
004: i=0 r=0 b=false s= u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
004: i=1 r=2 b=false s=mystring u=<3> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<4> <5>] uuid=<0>
005: {"error":null,"result":[{"count":2}]}
006: event:update, row={i=0 r=123.5 b=false s= u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>}, updates={r=0 uuid=<1>}
006: event:update, row={i=1 r=123.5 b=false s=mystring u=<3> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<4> <5>] uuid=<0>}, updates={r=2 uuid=<0>}
006: i=0 r=123.5 b=false s= u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
006: i=1 r=123.5 b=false s=mystring u=<3> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<4> <5>] uuid=<0>
007: {"error":null,"result":[{"uuid":["uuid","<6>"]}]}
008: event:create, row={i=-1 r=125 b=false s= u=<2> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<6>}, updates=None
008: i=-1 r=125 b=false s= u=<2> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<6>
008: i=0 r=123.5 b=false s= u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
008: i=1 r=123.5 b=false s=mystring u=<3> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<4> <5>] uuid=<0>
009: {"error":null,"result":[{"count":2}]}
010: event:update, row={i=-1 r=125 b=false s=newstring u=<2> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<6>}, updates={s= uuid=<6>}
010: event:update, row={i=0 r=123.5 b=false s=newstring u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>}, updates={s= uuid=<1>}
010: i=-1 r=125 b=false s=newstring u=<2> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<6>
010: i=0 r=123.5 b=false s=newstring u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
010: i=1 r=123.5 b=false s=mystring u=<3> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<4> <5>] uuid=<0>
011: {"error":null,"result":[{"count":1}]}
012: event:delete, row={i=0 r=123.5 b=false s=newstring u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>}, updates=None
012: i=-1 r=125 b=false s=newstring u=<2> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<6>
012: i=1 r=123.5 b=false s=mystring u=<3> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<4> <5>] uuid=<0>
013: reconnect
014: event:create, row={i=-1 r=125 b=false s=newstring u=<2> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<6>}, updates=None
014: event:create, row={i=1 r=123.5 b=false s=mystring u=<3> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<4> <5>] uuid=<0>}, updates=None
014: i=-1 r=125 b=false s=newstring u=<2> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<6>
014: i=1 r=123.5 b=false s=mystring u=<3> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<4> <5>] uuid=<0>
015: done
]])

View File

@@ -149,23 +149,30 @@ def do_parse_schema(schema_string):
print(ovs.json.to_string(schema.to_json(), sort_keys=True)) print(ovs.json.to_string(schema.to_json(), sort_keys=True))
def print_idl(idl, step): def get_simple_table_printable_row(row):
n = 0
if "simple" in idl.tables:
simple_columns = ["i", "r", "b", "s", "u", "ia", simple_columns = ["i", "r", "b", "s", "u", "ia",
"ra", "ba", "sa", "ua", "uuid"] "ra", "ba", "sa", "ua", "uuid"]
simple = idl.tables["simple"].rows s = ""
for row in six.itervalues(simple):
s = "%03d:" % step
for column in simple_columns: for column in simple_columns:
if hasattr(row, column) and not (type(getattr(row, column)) if hasattr(row, column) and not (type(getattr(row, column))
is ovs.db.data.Atom): is ovs.db.data.Atom):
s += "%s=%s " % (column, getattr(row, column)) s += "%s=%s " % (column, getattr(row, column))
s = s.strip()
s = re.sub('""|,|u?\'', "", s) s = re.sub('""|,|u?\'', "", s)
s = re.sub('UUID\(([^)]+)\)', r'\1', s) s = re.sub('UUID\(([^)]+)\)', r'\1', s)
s = re.sub('False', 'false', s) s = re.sub('False', 'false', s)
s = re.sub('True', 'true', s) s = re.sub('True', 'true', s)
s = re.sub(r'(ba)=([^[][^ ]*) ', r'\1=[\2] ', s) s = re.sub(r'(ba)=([^[][^ ]*) ', r'\1=[\2] ', s)
return s
def print_idl(idl, step):
n = 0
if "simple" in idl.tables:
simple = idl.tables["simple"].rows
for row in six.itervalues(simple):
s = "%03d: " % step
s += get_simple_table_printable_row(row)
print(s) print(s)
n += 1 n += 1
@@ -415,6 +422,12 @@ def update_condition(idl, commands):
def do_idl(schema_file, remote, *commands): def do_idl(schema_file, remote, *commands):
schema_helper = ovs.db.idl.SchemaHelper(schema_file) schema_helper = ovs.db.idl.SchemaHelper(schema_file)
track_notify = False
if commands and commands[0] == "track-notify":
commands = commands[1:]
track_notify = True
if commands and commands[0].startswith("?"): if commands and commands[0].startswith("?"):
readonly = {} readonly = {}
for x in commands[0][1:].split("?"): for x in commands[0][1:].split("?"):
@@ -445,6 +458,22 @@ def do_idl(schema_file, remote, *commands):
seqno = 0 seqno = 0
step = 0 step = 0
def mock_notify(event, row, updates=None):
output = "%03d: " % step
output += "event:" + str(event) + ", row={"
output += get_simple_table_printable_row(row) + "}, updates="
if updates is None:
output += "None"
else:
output += "{" + get_simple_table_printable_row(updates) + "}"
output += '\n'
sys.stdout.write(output)
sys.stdout.flush()
if track_notify and "simple" in idl.tables:
idl.notify = mock_notify
commands = list(commands) commands = list(commands)
if len(commands) >= 1 and "condition" in commands[0]: if len(commands) >= 1 and "condition" in commands[0]:
update_condition(idl, commands.pop(0)) update_condition(idl, commands.pop(0))