Skip to content

test: failing test for #3 -- cardinality one not enforced with generic peer #5

@github-actions

Description

@github-actions

Analyst's findings (summary)

Root cause: RelationshipCountConstraint.check returns early without validating when the relationship's peer is a generic schema, because get_relationships_by_identifier() on the generic returns an empty list. A secondary bug also silently skips cardinality: one relationships that do not set an explicit max_count (defaults to 0, which is falsy).
Affected files:

  • backend/infrahub/core/relationship/constraints/count.py — lines 43–63: both root defects live here

Replication test

Test file: backend/tests/component/core/constraint_validators/test_relationship_manager.py
Test name: test_cardinality_one_enforced_when_peer_is_generic

What it tests: Creating a second TestL3Interface node pointing to the same TestUnicastAddress (cardinality:one, inbound) raises ValidationError when the outbound relationship uses a generic peer type.

Verification: Test confirmed FAILING on current code (static analysis — Docker/TestContainers unavailable in CI environment).
Failure reason: RelationshipCountConstraint.check calls get_relationships_by_identifier on the generic TestIpAddress schema, which has no relationships defined (they live on the concrete subtypes). This returns [], triggering the early-return guard at count.py:45–46. No ValidationError is raised, so pytest.raises(ValidationError) fails with Failed: DID NOT RAISE.

Expected failure output (based on static code trace)
FAILED backend/tests/component/core/constraint_validators/test_relationship_manager.py::test_cardinality_one_enforced_when_peer_is_generic
- Failed: DID NOT RAISE <class 'infrahub.exceptions.ValidationError'>

Code trace:
  count.py:43  peer_schema = registry.schema.get(name="TestIpAddress", ...)  # GenericSchema
  count.py:44  peer_rels = peer_schema.get_relationships_by_identifier(id="addr__l3iface")  # returns []
  count.py:45  if not peer_rels:
  count.py:46      return  # ← early exit, no ValidationError raised

Test expectations

The test asserts that RelationshipCountConstraint.check raises ValidationError when:

  • The connector relationship (ip_addresses) has peer: TestIpAddress (a generic)
  • The concrete type of the peer node is TestUnicastAddress which has cardinality: one, direction: inbound for that identifier
  • A second connector already exists in the database pointing to the same peer

The test schema mirrors the real-world schema from the bug report: a generic TestIpAddress, a TestUnicastAddress concrete subtype with cardinality: one inbound, and a TestL3Interface connector with cardinality: many outbound to the generic. The schema fixture (generic_peer_cardinality_schema) is added to the constraint_validators conftest.py.

AGENT_TEST_COMPLETE

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • sensomatic.prefect.io

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "sensomatic.prefect.io"

See Network Configuration for more information.

Generated by Bug test-writer agent for issue #3 · ● 543.3K ·


Note

This was originally intended as a pull request, but GitHub Actions is not permitted to create or approve pull requests in this repository.
The changes have been pushed to branch ai-bug-pipeline-3-cardinality-generic-fbcc3a315eccf419.

Click here to create the pull request

To fix the permissions issue, go to SettingsActionsGeneral and enable Allow GitHub Actions to create and approve pull requests. See also: gh-aw FAQ

Show patch preview (134 of 134 lines)
From 0e5f314cba2d82fa88351b2c8de075e0926b8587 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com>
Date: Tue, 5 May 2026 14:24:13 +0000
Subject: [PATCH] test: add failing test for #3

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---
 .../core/constraint_validators/conftest.py    | 71 +++++++++++++++++++
 .../test_relationship_manager.py              | 22 ++++++
 2 files changed, 93 insertions(+)

diff --git a/backend/tests/component/core/constraint_validators/conftest.py b/backend/tests/component/core/constraint_validators/conftest.py
index 80fbd14c1..3caab30ca 100644
--- a/backend/tests/component/core/constraint_validators/conftest.py
+++ b/backend/tests/component/core/constraint_validators/conftest.py
@@ -120,6 +120,77 @@ async def car_person_generics_data_simple(
     return nodes
 
 
+@pytest.fixture
+async def generic_peer_cardinality_schema(db: InfrahubDatabase, default_branch: Branch) -> SchemaRoot:
+    SCHEMA = {
+        "generics": [
+            {
+                "name": "IpAddress",
+                "namespace": "Test",
+                "attributes": [
+                    {"name": "address", "kind": "Text", "unique": True},
+                ],
+            }
+        ],
+        "nodes": [
+            {
+                "name": "UnicastAddress",
+                "namespace": "Test",
+                "inherit_from": ["TestIpAddress"],
+                "relationships": [
+                    {
+                        "name": "layer3",
+                        "peer": "TestL3Interface",
+                        "identifier": "addr__l3iface",
+                        "kind": "Generic",
+                        "optional": True,
+                        "cardinality": "one",
+                        "direction": "inbound",
+                    }
+                ],
+            },
+            {
+                "name": "AnycastAddress",
+                "namespace": "Test",
+                "in
... (truncated)

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions