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 <[email protected]>
---
 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

diff --git a/python/automake.mk b/python/automake.mk
index c3e960c82..3de655227 100644
--- a/python/automake.mk
+++ b/python/automake.mk
@@ -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 \
diff --git a/python/ovs/db/idl.py b/python/ovs/db/idl.py
index 4d0b7ac38..3107987c1 100644
--- a/python/ovs/db/idl.py
+++ b/python/ovs/db/idl.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
diff --git a/python/ovs/tests/test_idl.py b/python/ovs/tests/test_idl.py
new file mode 100644
index 000000000..4b254187f
--- /dev/null
+++ b/python/ovs/tests/test_idl.py
@@ -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}},
+            },
+        },
+    },
+}
+
+
[email protected]
+def idl():
+    helper = ovs.db.idl.SchemaHelper(schema_json=SCHEMA)
+    helper.register_all()
+    return ovs.db.idl.Idl("unix:/nonexistent.sock", helper)
+
+
[email protected]("row_update", [{}, {"s": "x"}])
[email protected]("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])
-- 
2.55.0

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to