Skip to content

monitor_dbus_signals: check variant_level equality#328

Merged
mulkieran merged 1 commit into
stratis-storage:masterfrom
mulkieran:issue_stratisd_3895
Aug 19, 2025
Merged

monitor_dbus_signals: check variant_level equality#328
mulkieran merged 1 commit into
stratis-storage:masterfrom
mulkieran:issue_stratisd_3895

Conversation

@mulkieran

@mulkieran mulkieran commented Aug 18, 2025

Copy link
Copy Markdown
Member

Related stratis-storage/stratisd#3895

Summary by CodeRabbit

  • New Features
    • The D-Bus signal monitor now detects and reports variant-level mismatches in property values, adding a distinct diff entry for clearer diagnostics.
    • Diff/log outputs include a new, more granular discrepancy type for cases where a property's variant level changes, improving troubleshooting and visibility.
    • No changes to usage or configuration; existing workflows gain richer reporting automatically.

@mulkieran mulkieran self-assigned this Aug 18, 2025
@coderabbitai

coderabbitai Bot commented Aug 18, 2025

Copy link
Copy Markdown

Walkthrough

Adds a new Diff subtype DifferentVariantLevel and updates per-property diffing in scripts/monitor_dbus_signals.py to detect and report mismatches in variant_level between old and new D-Bus property values.

Changes

Cohort / File(s) Summary of Changes
D-Bus property diffing
scripts/monitor_dbus_signals.py
Added DifferentVariantLevel (subclass of Diff) with __init__ and __repr__. Extended _check_props to append DifferentVariantLevel when old_value is valid and new_value.variant_level != old_value.variant_level. Integrated within existing per-property comparison flow; no other public signatures changed.

Sequence Diagram(s)

sequenceDiagram
  participant Monitor as monitor_dbus_signals.py
  participant Checker as _check_props
  participant DiffList as Diffs

  Monitor->>Checker: Provide old and new property maps
  Checker->>Checker: Compare per-property values and states
  alt Property value changed (emits TRUE)
    Checker->>DiffList: Append DifferentProperty / ChangedProperty
  else Emits CONST
    Checker->>DiffList: Append ChangedProperty
  else Variant_level differs (old valid)
    Checker->>DiffList: Append DifferentVariantLevel
  end
  Checker-->>Monitor: Return diffs
  Monitor->>Monitor: Report diffs
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

I nibble logs at break of dawn,
A variant mismatch brightly drawn—
I mark the change with twitching nose,
A tiny diff where variant goes,
Then hop along where tidy reports flow. 🐇✨

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@mulkieran mulkieran added this to the v3.9.0 milestone Aug 18, 2025
@mulkieran mulkieran moved this to In Progress in 2025August Aug 18, 2025
@mulkieran mulkieran force-pushed the issue_stratisd_3895 branch from a501cfb to c414e93 Compare August 18, 2025 18:00
@mulkieran mulkieran changed the title monitor_dbus_signals: check variant-level equality monitor_dbus_signals: check variant_level equality Aug 18, 2025
@mulkieran mulkieran force-pushed the issue_stratisd_3895 branch 2 times, most recently from e718938 to c9a24ee Compare August 18, 2025 19:23
@mulkieran mulkieran marked this pull request as ready for review August 18, 2025 19:26

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
scripts/monitor_dbus_signals.py (2)

113-138: LGTM on new Diff type; minor docstring terminology fix

The addition of DifferentVariantLevel is clear and consistent with the existing Diff types. Minor nit: the D-Bus signal is named "PropertiesChanged", not "PropertiesChangedSignal". Consider correcting the terminology in the docstring for accuracy.

Apply this minimal docstring fix:

-    level does not match. The variant levels among the GetManagedObjects
-    result, the Properties.GetAll result and the PropertiesChangedSignal
+    level does not match. The variant levels among the GetManagedObjects
+    result, the Properties.GetAll result and the PropertiesChanged
     result should always be the same, because both are encoded using dicts,

722-729: Guard variant_level access and clarify intent w.r.t. value inequality

Directly accessing .variant_level may raise AttributeError if either side is a plain Python type (e.g., unit tests or alternate proxy layers). Also, the class docstring says “value is correct but the variant level does not match,” yet this check runs regardless of equality. If that’s intentional (to report both a DifferentProperty and a DifferentVariantLevel), fine—otherwise add the equality guard.

Safer attribute access (treat missing variant_level as 0):

-            if (
-                old_value is not INVALIDATED
-                and new_value.variant_level != old_value.variant_level
-            ):
-                diffs.append(
-                    DifferentVariantLevel(object_path, ifn, key, old_value, new_value)
-                )
+            if old_value is not INVALIDATED:
+                old_vl = getattr(old_value, "variant_level", 0)
+                new_vl = getattr(new_value, "variant_level", 0)
+                if new_vl != old_vl:
+                    diffs.append(
+                        DifferentVariantLevel(object_path, ifn, key, old_value, new_value)
+                    )

If the intent is to only flag variant-level mismatches when the value itself matches, add the equality guard too:

-                if new_vl != old_vl:
+                if new_value == old_value and new_vl != old_vl:
                     diffs.append(
                         DifferentVariantLevel(object_path, ifn, key, old_value, new_value)
                     )

Please confirm which behavior you want (always report variant-level mismatches, or only when values otherwise match). If helpful, I can follow up with a small test harness to exercise both paths.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between c18bfbe and c9a24ee.

📒 Files selected for processing (1)
  • scripts/monitor_dbus_signals.py (2 hunks)

@mulkieran mulkieran force-pushed the issue_stratisd_3895 branch from c9a24ee to ae41a85 Compare August 18, 2025 21:09
@mulkieran mulkieran moved this from In Progress to In Review in 2025August Aug 18, 2025
@mulkieran

mulkieran commented Aug 18, 2025

Copy link
Copy Markdown
Member Author

I fixed a comment...but rejected the other suggestion. Actually, I decided it had a point and simplified things a bit.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
scripts/monitor_dbus_signals.py (2)

113-139: New diff type looks good; consider exposing variant levels in repr and aligning docstring with behavior

The class is consistent with existing Diff types. Two small improvements:

  • Make it easier to see the actual variant-level mismatch in logs by including the levels in repr (using getattr to stay robust).
  • Docstring says “value is correct but … variant level does not match,” while the check (Line 722 onward) runs regardless of value equality. Either clarify the docstring or gate the check to only when values are equal.

Apply this diff to enhance the repr:

@@
     def __repr__(self):
-        return (
-            f"DifferentVariantLevel({self.object_path!r}, "
-            f"{self.interface_name!r}, {self.key!r}, {self.old_value!r}, "
-            f"{self.new_value!r})"
-        )
+        old_vl = getattr(self.old_value, "variant_level", None)
+        new_vl = getattr(self.new_value, "variant_level", None)
+        return (
+            f"DifferentVariantLevel({self.object_path!r}, "
+            f"{self.interface_name!r}, {self.key!r}, {self.old_value!r}, "
+            f"{self.new_value!r}, old_vl={old_vl!r}, new_vl={new_vl!r})"
+        )

Optionally tweak the opening sentence of the docstring to avoid implying value equality if that’s not required by design.


722-729: Guard variant_level attribute access to avoid AttributeError; optionally restrict to equal values

new_value/old_value are often dbus.* instances with variant_level, but defensive guards will prevent crashes if plain Python values slip through. Also, if the intent is “value is correct but levels differ,” you may want to run this only when new_value == old_value.

Apply this diff to harden the check:

-            if (
-                old_value is not INVALIDATED
-                and new_value.variant_level != old_value.variant_level
-            ):
+            if (
+                old_value is not INVALIDATED
+                and hasattr(new_value, "variant_level")
+                and hasattr(old_value, "variant_level")
+                and new_value.variant_level != old_value.variant_level
+            ):
                 diffs.append(
                     DifferentVariantLevel(object_path, ifn, key, old_value, new_value)
                 )

If you do want to enforce that only “value-equal but variant-level-different” cases are reported, consider making this block an elif to the preceding if new_value != old_value: or add and new_value == old_value to the condition.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between c9a24ee and ae41a85.

📒 Files selected for processing (1)
  • scripts/monitor_dbus_signals.py (2 hunks)

@mulkieran mulkieran force-pushed the issue_stratisd_3895 branch from ae41a85 to 0deba5b Compare August 18, 2025 21:22
Signed-off-by: mulhern <amulhern@redhat.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
scripts/monitor_dbus_signals.py (1)

708-724: Guard against missing variant_level and tighten mutually-exclusive branches.

Relying on assert hasattr(old_value, "variant_level") can still raise at runtime (asserts can be stripped with -O, and new_value.variant_level is accessed later without any guard). Using getattr defensively prevents crashes if a plain Python type slips through. Also, switch the second if to elif to reflect the exclusivity of enum cases.

Apply this diff:

@@
-            else:
-                assert hasattr(old_value, "variant_level")
-
-                if new_value != old_value:
-                    if emits_signal is EmitsChangedSignal.TRUE:
+            else:
+                # Be defensive: dbus-python values should carry `variant_level`,
+                # but guard in case a plain Python type slips through.
+                old_vl = getattr(old_value, "variant_level", None)
+                new_vl = getattr(new_value, "variant_level", None)
+
+                if new_value != old_value:
+                    if emits_signal is EmitsChangedSignal.TRUE:
                         diffs.append(
                             DifferentProperty(
                                 object_path, ifn, key, old_value, new_value
                             )
                         )
 
-                    if emits_signal is EmitsChangedSignal.CONST:
+                    elif emits_signal is EmitsChangedSignal.CONST:
                         diffs.append(
                             ChangedProperty(object_path, ifn, key, old_value, new_value)
                         )
-                elif new_value.variant_level != old_value.variant_level:
+                elif old_vl is not None and new_vl is not None and new_vl != old_vl:
                     diffs.append(
                         DifferentVariantLevel(
                             object_path, ifn, key, old_value, new_value
                         )
                     )

Would you confirm that in your environments all property values indeed carry variant_level via dbus-python? If not guaranteed, the above guard will avoid spurious AttributeErrors.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between ae41a85 and 0deba5b.

📒 Files selected for processing (1)
  • scripts/monitor_dbus_signals.py (2 hunks)
🔇 Additional comments (3)
scripts/monitor_dbus_signals.py (3)

113-138: Nice addition: explicit diff for variant-level mismatches.

The DifferentVariantLevel Diff type is clear, mirrors the existing Diff classes, and the docstring crisply explains why this matters for a{sv} values across GetManagedObjects/GetAll/PropertiesChanged. The __repr__ format also aligns with the rest.


701-708: INVALIDATED handling remains correct and readable.

Keeping the NotInvalidatedProperty check gated on old_value is INVALIDATED and emits_signal != INVALIDATES maintains the original behavior and makes the invariant explicit.


724-728: Right placement for variant-level comparison.

Checking variant_level only when values are equal is the correct semantics to isolate encoding mismatches without masking actual value changes.

@mulkieran

Copy link
Copy Markdown
Member Author

Now definitely ignoring CodeRabbit's advice...

@mulkieran mulkieran merged commit e1456e8 into stratis-storage:master Aug 19, 2025
5 checks passed
@github-project-automation github-project-automation Bot moved this from In Review to Done in 2025August Aug 19, 2025
@mulkieran mulkieran deleted the issue_stratisd_3895 branch August 19, 2025 01:40
@mulkieran mulkieran moved this from Done to Done(3) in 2025August Aug 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

No open projects
Status: Done(3)

Development

Successfully merging this pull request may close these issues.

1 participant