Skip to content

test: Add tests for named HTTPRouteRule sectionName targeting#943

Open
Tiago-Vier-Preto wants to merge 4 commits into
Kuadrant:mainfrom
Tiago-Vier-Preto:feature/add-tests-for-named-httprouterule
Open

test: Add tests for named HTTPRouteRule sectionName targeting#943
Tiago-Vier-Preto wants to merge 4 commits into
Kuadrant:mainfrom
Tiago-Vier-Preto:feature/add-tests-for-named-httprouterule

Conversation

@Tiago-Vier-Preto
Copy link
Copy Markdown

@Tiago-Vier-Preto Tiago-Vier-Preto commented Apr 20, 2026

Description

This PR adds support for explicitly named HTTPRoute rules in the testsuite models and introduces test coverage to verify that Kuadrant policies can correctly target these named rules via the sectionName field. This aligns the testsuite with the Gateway API's introduction of explicit naming for HTTPRouteRule entries (kubernetes-sigs/gateway-api#995) and Kuadrant's policy-machinery support for it (Kuadrant/policy-machinery#63).

Issue #942

Changes

  • Updated HTTPRoute.add_backend`()` and HTTPRoute.add_rule() in testsuite/gateway/gateway_api/route.py to accept an optional name parameter, allowing rules to be explicitly named instead of relying solely on auto-generated names.
  • Added test_named_route_rule.py in the Limitador section tests to verify that a RateLimitPolicy correctly applies to a specific named rule (section_name="get-rule").
  • Added test_authpolicy_named_http_route_rule.py in the AuthPolicy section tests to verify that an AuthPolicy correctly protects traffic for a specific named rule without affecting untargeted rules.

Verification

  • Added new automated tests (test_limit_match_named_route_rule and test_authpolicy_section_name_targeting_named_http_route_rule) which create an HTTPRoute with explicitly named rules (e.g., get-rule and anything-rule).
  • The tests verify that when a policy targets the get-rule section name, the policy is enforced exclusively on that rule's route, while the other route remains unaffected.

Summary by CodeRabbit

  • New Features

    • HTTP route rules can be explicitly named, allowing AuthPolicy and RateLimitPolicy to target specific named rule sections.
  • Tests

    • Added tests validating AuthPolicy section-name targeting for named route rules.
    • Added tests validating RateLimitPolicy targeting for named route rules.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 20, 2026

Warning

Rate limit exceeded

@Tiago-Vier-Preto has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 48 minutes and 40 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0067058e-7f0f-4bf9-ac13-d6e6f21268d9

📥 Commits

Reviewing files that changed from the base of the PR and between f2a1de7 and 3bda78a.

📒 Files selected for processing (3)
  • testsuite/gateway/gateway_api/route.py
  • testsuite/tests/singlecluster/gateway/authpolicy/test_authpolicy_named_http_route_rule.py
  • testsuite/tests/singlecluster/limitador/section/test_named_route_rule.py
📝 Walkthrough

Walkthrough

Adds optional name parameters to HTTPRoute.add_rule() and HTTPRoute.add_backend() to include named rule sections. Adds tests validating AuthPolicy and RateLimitPolicy section-name targeting against named HTTPRoute backend rules.

Changes

Named HTTPRoute rule support and tests

Layer / File(s) Summary
Route API: add optional name to rules
testsuite/gateway/gateway_api/route.py
HTTPRoute.add_rule() and HTTPRoute.add_backend() signatures now accept an optional name: str = None. When provided and truthy, the name is added to the constructed rule dict before appending to self.model.spec.rules.
AuthPolicy: tests for named rule targeting
testsuite/tests/singlecluster/gateway/authpolicy/test_authpolicy_named_http_route_rule.py
New test module that replaces route rules with two named backend rules (get-rule, anything-rule), creates an AuthPolicy targeting section_name="get-rule", and asserts /get is protected while /anything remains public.
RateLimitPolicy: tests for named rule targeting
testsuite/tests/singlecluster/limitador/section/test_named_route_rule.py
New test module that replaces route rules with two named backend rules and creates a RateLimitPolicy targeting get-rule with Limit(2, "10s"); asserts rate limiting applies only to /get and not /anything.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant HTTPRoute
    participant Policy
    participant Backend

    Client->>HTTPRoute: HTTP request (e.g. /get)
    HTTPRoute->>HTTPRoute: Match rule and identify section name (e.g. get-rule)
    HTTPRoute->>Policy: Evaluate section_name targeting
    alt Section matches
        Policy->>Policy: Apply policy (auth or rate-limit)
        alt Policy permits
            HTTPRoute->>Backend: Forward request
            Backend->>Client: HTTP 200
        else Policy denies
            Policy->>Client: HTTP 401 or 429
        end
    else Section doesn't match
        HTTPRoute->>Backend: Forward to other rule (e.g. anything-rule)
        Backend->>Client: HTTP 200
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A rabbit hops where rules are named,

Sections tagged so policies are aimed,
Auth checks only the chosen gate,
Limits land where counts dictate,
Tests confirm the routing frame.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The pull request title clearly describes the main change: adding tests for named HTTPRouteRule sectionName targeting, which directly aligns with the changeset.
Description check ✅ Passed The pull request description covers all required template sections with comprehensive details about changes, verification, and related issues.
Docstring Coverage ✅ Passed Docstring coverage is 81.82% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (5)
testsuite/tests/singlecluster/limitador/section/test_named_route_rule.py (2)

27-34: Minor: test leaves the limit counter in a 429 state.

After the third /get request the counter is exhausted for the remaining window (10s). If any follow-up assertion or retry is added later within the same module, it will hit unexpected 429s. Not a bug in the current test, but worth keeping in mind — you could either reorder to check /anything first, or size the limit/window to tolerate a small buffer.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@testsuite/tests/singlecluster/limitador/section/test_named_route_rule.py`
around lines 27 - 34, The test_limit_match_named_route_rule test exhausts the
/get rate limit and leaves the counter in a 429 state for the remainder of the
window; to avoid impacting later assertions, either move the `/anything` check
to run before the get_many()/additional get() calls (i.e., call
client.get("/anything") first) or increase the limit/window used by the test so
a single extra request won't hit 429; update the test function
test_limit_match_named_route_rule to perform the non-limited assertion before
exhausting the /get counter or adjust the rate-limit parameters accordingly.

22-22: Prefer keyword argument for section_name.

Passing "get-rule" as a positional argument works today but is fragile: RateLimitPolicy.create_instance signature is (cluster, name, target, section_name=None, labels=None), so any future reordering of kwargs would silently break this. Using a keyword argument matches the style used in test_authpolicy_named_http_route_rule.py.

Proposed change
-    rlp = RateLimitPolicy.create_instance(cluster, blame("limit"), route, "get-rule", labels={"testRun": module_label})
+    rlp = RateLimitPolicy.create_instance(
+        cluster, blame("limit"), route, section_name="get-rule", labels={"testRun": module_label}
+    )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@testsuite/tests/singlecluster/limitador/section/test_named_route_rule.py` at
line 22, The test passes the section name "get-rule" positionally to
RateLimitPolicy.create_instance which has signature (cluster, name, target,
section_name=None, labels=None) and is fragile; change the call to pass
section_name="get-rule" as a keyword argument to match the existing style (see
RateLimitPolicy.create_instance and the call site rlp =
RateLimitPolicy.create_instance(...)) so future argument reordering won't break
the test.
testsuite/tests/singlecluster/gateway/authpolicy/test_authpolicy_named_http_route_rule.py (2)

9-9: Consider linking the related issue.

Per the PR description, this test covers issue #942. Adding pytest.mark.issue("https://github.com/Kuadrant/testsuite/issues/942") to pytestmark (here and in the limitador test) improves traceability in Report Portal.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@testsuite/tests/singlecluster/gateway/authpolicy/test_authpolicy_named_http_route_rule.py`
at line 9, Update the pytest marks to include the issue link by adding
pytest.mark.issue("https://github.com/Kuadrant/testsuite/issues/942") into the
pytestmark list used in this test (the pytestmark variable at top of
test_authpolicy_named_http_route_rule.py) and mirror the same addition in the
corresponding limitador test file; ensure the new pytest.mark.issue entry is
included alongside pytest.mark.authorino and pytest.mark.kuadrant_only so Report
Portal can trace the test to issue `#942`.

42-57: Consider asserting policy enforcement status before sending traffic.

Relying solely on HTTP responses can produce flaky failures if the policy hasn't been fully enforced yet. Other section-targeting tests in this suite typically verify route.is_affected_by(authorization) (or equivalent readiness) before sending requests. The autouse commit fixture waits for the policy to be ready, which should cover this, but an explicit is_affected_by assertion makes the intent clearer and the diagnostic signal on failure more specific.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@testsuite/tests/singlecluster/gateway/authpolicy/test_authpolicy_named_http_route_rule.py`
around lines 42 - 57, The test
test_authpolicy_section_name_targeting_named_http_route_rule relies only on HTTP
responses and should assert the policy is active first; add an explicit
readiness check using the route object's is_affected_by(authorization) (or the
equivalent helper used in other tests) before issuing requests so the test
verifies that the named HTTPRoute rule is affected by the AuthPolicy section;
locate the route/authorization objects used in this test and insert a short
assert like route.is_affected_by(authorization) (or call the same helper used
elsewhere in the suite) prior to the client.get calls to avoid flakiness.
testsuite/gateway/gateway_api/route.py (1)

93-95: Nit: PEP 484 implicit Optional.

Ruff RUF013 flags name: str = None (and the same on Line 115). Prefer name: str | None = None for consistency with modern typing.

Proposed change
-    def add_rule(
-        self, backend: "Backend", *route_matches: RouteMatch, filters: list[URLRewriteFilter] = None, name: str = None
-    ):
+    def add_rule(
+        self,
+        backend: "Backend",
+        *route_matches: RouteMatch,
+        filters: list[URLRewriteFilter] = None,
+        name: str | None = None,
+    ):
-    def add_backend(self, backend: "Backend", prefix="/", name: str = None):
+    def add_backend(self, backend: "Backend", prefix="/", name: str | None = None):
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@testsuite/gateway/gateway_api/route.py` around lines 93 - 95, The parameter
annotations use implicit Optional by assigning None (e.g., in add_rule); update
the signature(s) to explicitly allow None using union types (for example change
name: str = None to name: str | None = None) and do the same for the other
occurrence noted (the similar parameter on Line 115) so typing is PEP 484 /
modern-typing compliant; locate the add_rule function and the other flagged
function and replace the `: str = None` patterns with `: str | None = None`.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@testsuite/gateway/gateway_api/route.py`:
- Around line 93-95: The parameter annotations use implicit Optional by
assigning None (e.g., in add_rule); update the signature(s) to explicitly allow
None using union types (for example change name: str = None to name: str | None
= None) and do the same for the other occurrence noted (the similar parameter on
Line 115) so typing is PEP 484 / modern-typing compliant; locate the add_rule
function and the other flagged function and replace the `: str = None` patterns
with `: str | None = None`.

In
`@testsuite/tests/singlecluster/gateway/authpolicy/test_authpolicy_named_http_route_rule.py`:
- Line 9: Update the pytest marks to include the issue link by adding
pytest.mark.issue("https://github.com/Kuadrant/testsuite/issues/942") into the
pytestmark list used in this test (the pytestmark variable at top of
test_authpolicy_named_http_route_rule.py) and mirror the same addition in the
corresponding limitador test file; ensure the new pytest.mark.issue entry is
included alongside pytest.mark.authorino and pytest.mark.kuadrant_only so Report
Portal can trace the test to issue `#942`.
- Around line 42-57: The test
test_authpolicy_section_name_targeting_named_http_route_rule relies only on HTTP
responses and should assert the policy is active first; add an explicit
readiness check using the route object's is_affected_by(authorization) (or the
equivalent helper used in other tests) before issuing requests so the test
verifies that the named HTTPRoute rule is affected by the AuthPolicy section;
locate the route/authorization objects used in this test and insert a short
assert like route.is_affected_by(authorization) (or call the same helper used
elsewhere in the suite) prior to the client.get calls to avoid flakiness.

In `@testsuite/tests/singlecluster/limitador/section/test_named_route_rule.py`:
- Around line 27-34: The test_limit_match_named_route_rule test exhausts the
/get rate limit and leaves the counter in a 429 state for the remainder of the
window; to avoid impacting later assertions, either move the `/anything` check
to run before the get_many()/additional get() calls (i.e., call
client.get("/anything") first) or increase the limit/window used by the test so
a single extra request won't hit 429; update the test function
test_limit_match_named_route_rule to perform the non-limited assertion before
exhausting the /get counter or adjust the rate-limit parameters accordingly.
- Line 22: The test passes the section name "get-rule" positionally to
RateLimitPolicy.create_instance which has signature (cluster, name, target,
section_name=None, labels=None) and is fragile; change the call to pass
section_name="get-rule" as a keyword argument to match the existing style (see
RateLimitPolicy.create_instance and the call site rlp =
RateLimitPolicy.create_instance(...)) so future argument reordering won't break
the test.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 35e43c2b-d8db-412c-9cbb-857f7564e86a

📥 Commits

Reviewing files that changed from the base of the PR and between b8c9e2a and 7a48117.

📒 Files selected for processing (3)
  • testsuite/gateway/gateway_api/route.py
  • testsuite/tests/singlecluster/gateway/authpolicy/test_authpolicy_named_http_route_rule.py
  • testsuite/tests/singlecluster/limitador/section/test_named_route_rule.py

@Tiago-Vier-Preto Tiago-Vier-Preto force-pushed the feature/add-tests-for-named-httprouterule branch from 7a48117 to 0b25dad Compare April 20, 2026 17:15
Copy link
Copy Markdown
Member

@azgabur azgabur left a comment

Choose a reason for hiding this comment

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

Please run make commit-acceptance or/and make reformat and fix some formatting issues but otherwise I say LGTM, thanks for contribution!

Copy link
Copy Markdown
Member

@averevki averevki left a comment

Choose a reason for hiding this comment

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

Looks great! Only left the smallest nit. Please make sure that linters and other github actions are successful so it can allow us to merge 👍

@averevki averevki added the test case New test case label Apr 24, 2026
@averevki averevki moved this to In Review in Kuadrant Apr 24, 2026
@Tiago-Vier-Preto Tiago-Vier-Preto force-pushed the feature/add-tests-for-named-httprouterule branch from 03ba389 to 78e36e1 Compare April 24, 2026 14:19
Copy link
Copy Markdown
Contributor

@emmaaroche emmaaroche left a comment

Choose a reason for hiding this comment

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

Hey @Tiago-Vier-Preto, thank you for your contribution! The PR is failing mypy type checking on line 118: error: Incompatible types in assignment (expression has type "str", target has type "list[Any]")

I left a suggestion of a fix, but also feel free to find your own work around. Once you make changes, run make commit-acceptance locally to verify the fix! 👍

Comment thread testsuite/gateway/gateway_api/route.py
@emmaaroche
Copy link
Copy Markdown
Contributor

Hi @Tiago-Vier-Preto, are you still working on this?

@Tiago-Vier-Preto
Copy link
Copy Markdown
Author

Yes, I am! I'm really sorry for the delay guys!

Tiago-Vier-Preto and others added 4 commits May 19, 2026 22:23
Signed-off-by: Tiago Vier Preto <tvpreto@gmail.com>
Signed-off-by: Tiago Vier Preto <83984051+Tiago-Vier-Preto@users.noreply.github.com>
Signed-off-by: Tiago Vier Preto <83984051+Tiago-Vier-Preto@users.noreply.github.com>
Co-authored-by: Emma Roche <eroche@redhat.com>
Signed-off-by: Tiago Vier Preto <83984051+Tiago-Vier-Preto@users.noreply.github.com>
Signed-off-by: Tiago Vier Preto <83984051+Tiago-Vier-Preto@users.noreply.github.com>
@Tiago-Vier-Preto Tiago-Vier-Preto force-pushed the feature/add-tests-for-named-httprouterule branch from 9070085 to 3bda78a Compare May 19, 2026 22:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

test case New test case

Projects

Status: In Review

Development

Successfully merging this pull request may close these issues.

4 participants