@@ -46,6 +46,7 @@ ovs_pytests = \
python/ovs/tests/test_decoders.py \
python/ovs/tests/test_dns_resolve.py \
python/ovs/tests/test_filter.py \
+ python/ovs/tests/test_idl.py \
python/ovs/tests/test_kv.py \
python/ovs/tests/test_list.py \
python/ovs/tests/test_odp.py \
@@ -1047,11 +1047,9 @@ class Idl(object):
else:
row_update = row_update['initial']
self.__add_default(table, row_update)
- changed = self.__row_update(table, row, row_update)
+ self.__row_update(table, row, row_update)
table.rows[uuid] = row
- if changed:
- return OVSDB_IDL_UPDATE_DB_CHANGED, Notice(ROW_CREATE, row)
- return OVSDB_IDL_UPDATE_NO_CHANGES, None
+ return OVSDB_IDL_UPDATE_DB_CHANGED, Notice(ROW_CREATE, row)
elif "modify" in row_update:
if not row:
# XXX rate-limit
new file mode 100644
@@ -0,0 +1,42 @@
+import uuid
+
+import pytest
+
+import ovs.db.idl
+
+
+# Every column is optional (n_min == 0), so a row at its defaults arrives
+# with no columns at all and __add_default() has nothing to inject.
+SCHEMA = {
+ "name": "idltest",
+ "version": "1.0.0",
+ "tables": {
+ "optional": {
+ "columns": {
+ "s": {"type": {"key": "string", "min": 0, "max": 1}},
+ },
+ },
+ },
+}
+
+
+@pytest.fixture
+def idl():
+ helper = ovs.db.idl.SchemaHelper(schema_json=SCHEMA)
+ helper.register_all()
+ return ovs.db.idl.Idl("unix:/nonexistent.sock", helper)
+
+
+@pytest.mark.parametrize("row_update", [{}, {"s": "x"}])
+@pytest.mark.parametrize("alert", [True, False])
+def test_update2_insert_always_notifies(idl, row_update, alert):
+ table = idl.tables["optional"]
+ table.columns["s"].alert = alert
+ row_uuid = uuid.uuid4()
+
+ result, notice = idl._process_update2(table, row_uuid,
+ {"insert": row_update})
+
+ assert result == ovs.db.idl.OVSDB_IDL_UPDATE_DB_CHANGED
+ assert notice == ovs.db.idl.Notice(ovs.db.idl.ROW_CREATE,
+ table.rows[row_uuid])
The row_update2 "insert"/"initial" handling only generated a ROW_CREATE notification, and bumped change_seqno, when __row_update() reported that an alerted column differed from its default. The C IDL treats an insert as a change by definition: ovsdb_idl_insert_row() discards ovsdb_idl_row_change()'s return value, and the insert case in ovsdb_idl_process_update() falls through to an unconditional OVSDB_IDL_UPDATE_DB_CHANGED. Only the modify case is gated. A client that registers only columns with n_min == 0, or columns with alert cleared, therefore never learns that a row was inserted: the row silently appears in the replica, notify() is not called and Idl.run() returns False. An equivalent C client gets a change_seqno bump and finds the row on its next scan. Drop the gate so that an insert always reports OVSDB_IDL_UPDATE_DB_CHANGED with a ROW_CREATE notice, matching C. Fixes: 897c8064f55c ("python: move Python idl to work with monitor_cond") Assisted-by: Claude Opus 5 Signed-off-by: Terry Wilson <twilson@redhat.com> --- python/automake.mk | 1 + python/ovs/db/idl.py | 6 ++---- python/ovs/tests/test_idl.py | 42 ++++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 python/ovs/tests/test_idl.py