Skip to content

chore(policy): consolidate sort integration helpers, add tiebreaker tests, add test cleanup #3403

Merged
dsm20 merged 15 commits into
mainfrom
sort-testing-sql-refactor
May 4, 2026
Merged

chore(policy): consolidate sort integration helpers, add tiebreaker tests, add test cleanup #3403
dsm20 merged 15 commits into
mainfrom
sort-testing-sql-refactor

Conversation

@dsm20

@dsm20 dsm20 commented Apr 27, 2026

Copy link
Copy Markdown
Contributor

Proposed Changes

Consolidates integration test helpers across all policy sort test suites, adds proper test cleanup, and adds tiebreaker-specific integration tests that verify the id ASC fallback produces deterministic ordering.

Changes

Integration Test Helpers -- service/integration/utils.go

  • forceDeleteRows: hard-deletes rows by ID via raw SQL, bypassing the API's soft-delete/deactivate limitation for test cleanup
  • forceCreatedAtTie: sets created_at to a fixed timestamp for given IDs, guaranteeing that the ORDER BY tiebreaker (id ASC) determines sort order

Integration Test Consolidation -- service/integration/*_test.go

  • Refactored createSortTest* helpers from (label string) to (prefixes []string) across all RPCs, giving each test explicit control over resource names
  • Added defer cleanup calls to all sort integration tests via deleteSortTest* helpers
  • Added Test_List*_SortTieBreaker_CreatedAtWithIDFallback for all 8 RPCs: Namespaces, Attributes, KeyAccessServers, KasKeys, Obligations, RegisteredResources, SubjectMappings, SubjectConditionSets

Tiebreaker Test Strategy

Each tiebreaker test:

  1. Creates 3 resources
  2. Forces identical created_at timestamps via forceCreatedAtTie
  3. Sorts the UUIDs lexicographically to get expected order
  4. Lists with created_at ASC and asserts rows match the UUID-sorted order

This proves the id ASC tiebreaker added in #3402 produces deterministic results when the primary sort column ties.

Summary by CodeRabbit

Release Notes

  • Tests
    • Standardized sort test helpers across integration tests to ensure consistent attribute, key, namespace, obligation, and resource creation with deterministic timestamps.
    • Added tie-breaker tests to validate deterministic ordering behavior when creation timestamps are equal.
    • Enhanced test utilities for database cleanup and timestamp management.

@dsm20
dsm20 requested review from a team as code owners April 27, 2026 17:02
@dsm20
dsm20 marked this pull request as draft April 27, 2026 17:02
@coderabbitai

coderabbitai Bot commented Apr 27, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@dsm20 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 38 minutes and 51 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ 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: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: a60e05d5-16c0-48fb-9a39-c12b254d3be7

📥 Commits

Reviewing files that changed from the base of the PR and between 0fdb7bc and 25cf944.

📒 Files selected for processing (4)
  • service/integration/attributes_test.go
  • service/integration/kas_registry_test.go
  • service/integration/namespaces_test.go
  • service/integration/subject_mappings_test.go
📝 Walkthrough

Walkthrough

This PR refactors integration tests across seven files in service/integration/ to standardize sort test fixture creation via prefix-driven helpers, adds utility functions for test cleanup and timestamp manipulation via raw SQL, implements deferred cleanup for all sort tests, and introduces tie-breaker tests that validate deterministic ID-based ordering when created_at values collide.

Changes

Sort Test Refactoring and Tie-Breaker Validation

Layer / File(s) Summary
Test Utilities
service/integration/utils.go
Adds forceDeleteRows(...) and forceCreatedAtTie(...) to delete rows by UUID and force identical created_at timestamps via raw SQL Exec calls.
Test Helper Unification
service/integration/attributes_test.go, service/integration/kas_registry_key_test.go, service/integration/kas_registry_test.go, service/integration/namespaces_test.go, service/integration/obligations_test.go, service/integration/registered_resources_test.go, service/integration/subject_mappings_test.go
Replaces per-entity sort helpers with unified createSortTestX(prefixes []string) pattern (creates one entity per prefix with 5ms gaps) and adds corresponding deleteSortTestX(ids []string) cleanup helpers.
Sort Test Updates
service/integration/attributes_test.go, service/integration/kas_registry_key_test.go, service/integration/kas_registry_test.go, service/integration/namespaces_test.go, service/integration/obligations_test.go, service/integration/registered_resources_test.go, service/integration/subject_mappings_test.go
All sort tests (name, created_at, updated_at, and defaulting behavior) refactored to call unified helpers with explicit per-entity prefixes and deferred cleanup; assertions updated to use returned ID slices.
Tie-Breaker Tests
service/integration/attributes_test.go, service/integration/kas_registry_key_test.go, service/integration/kas_registry_test.go, service/integration/namespaces_test.go, service/integration/obligations_test.go, service/integration/registered_resources_test.go, service/integration/subject_mappings_test.go
New Test_*_SortTieBreaker_CreatedAtWithIDFallback tests added to each suite; each forces identical created_at timestamps, derives expected order via slices.Sorted(...), and asserts created_at ASC returns entities in that deterministic ID-based fallback order.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • c-r33d
  • elizabethhealy
  • marythought

🐰 With whiskers twitching in delight,
Sort helpers now unified and tight,
Tie-breakers tested with SQL's might,
Each entity ID-ordered right!
Refactored tests hop into the light.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main changes: consolidating sort integration helpers, adding tiebreaker tests, and implementing test cleanup across the test suite.
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
  • Commit unit tests in branch sort-testing-sql-refactor

Warning

Review ran into problems

🔥 Problems

Timed out fetching pipeline failures after 30000ms

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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
Review rate limit: 0/1 reviews remaining, refill in 38 minutes and 51 seconds.

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

@github-actions github-actions Bot added comp:db DB component comp:policy Policy Configuration ( attributes, subject mappings, resource mappings, kas registry) labels Apr 27, 2026
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request improves the reliability and maintainability of the policy service's list operations and integration tests. By introducing a deterministic tiebreaker to SQL sorting logic, it ensures stable result ordering. Additionally, it refactors test helper methods to be more robust and includes automatic cleanup, which simplifies test maintenance and improves test suite stability.

Highlights

  • SQL Sorting Tiebreakers: Added a deterministic tiebreaker (id ASC) to SQL queries for listing resources, ensuring consistent ordering when primary sort fields have identical values.
  • Integration Test Refactoring: Consolidated and improved integration test helpers for creating and cleaning up test resources, including the addition of automatic resource deletion via defer.
  • Test Coverage: Added new integration tests to verify the behavior of sort tiebreakers across various policy resources.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.


In tables where the timestamps align, / A tiebreaker makes the order fine. / With ID as the final guide, / No ambiguity can hide.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request implements deterministic sorting tie-breakers by adding id ASC to the ORDER BY clauses in SQL queries for Namespaces, Obligations, Registered Resources, and Key Access Servers, alongside updated integration tests. Feedback highlights that SQL tie-breakers for Attributes and Subject Mappings are missing, which will cause their new tests to fail. Additionally, the reviewer noted potential Go version compatibility issues with Go 1.23 slice functions, possible test flakiness due to high-precision timestamps, a potential panic in KAS key test helpers, and inconsistent timestamp generation within single requests.

Comment thread service/integration/attributes_test.go
Comment thread service/integration/attributes_test.go
Comment thread service/integration/attributes_test.go
Comment thread service/integration/kas_registry_key_test.go Outdated
Comment thread service/integration/kas_registry_key_test.go Outdated
@dsm20

dsm20 commented Apr 27, 2026

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request implements deterministic sorting for several list endpoints by adding a secondary 'id ASC' tiebreaker to SQL queries when 'created_at' timestamps are identical. It includes updates to the database layer for namespaces, obligations, registered resources, and KAS keys, along with corresponding integration tests and a new 'forceCreatedAtTie' utility. Feedback highlights that several entities—specifically attributes, key access servers, subject mappings, and subject condition sets—are missing the necessary database-level tiebreaker logic to support the newly added tests. Additionally, one test helper in the subject mappings suite remains unrefactored, creating an inconsistency with the rest of the integration test suite.

Comment thread service/integration/attributes_test.go
Comment thread service/integration/kas_registry_test.go
Comment thread service/integration/subject_mappings_test.go
Comment thread service/integration/subject_mappings_test.go
Comment thread service/integration/subject_mappings_test.go

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This PR introduces deterministic sorting by adding a secondary id ASC tiebreaker to several policy entity list queries and adds integration tests to verify this behavior. Feedback indicates that several SQL files (Attributes, Key Access Servers, Subject Mappings) were omitted from the update, leading to potential test failures. Additionally, a missing import in the attributes test and a table name typo in the subject mapping tests need to be addressed.

Comment thread service/integration/attributes_test.go
Comment thread service/integration/attributes_test.go
Comment thread service/integration/kas_registry_test.go
Comment thread service/integration/subject_mappings_test.go
Comment thread service/integration/subject_mappings_test.go
Comment thread service/integration/subject_mappings_test.go
@github-actions

Copy link
Copy Markdown
Contributor
Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 184.648246ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 94.905083ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 392.701651ms
Throughput 254.65 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 41.976555351s
Average Latency 417.969023ms
Throughput 119.11 requests/second

@dsm20
dsm20 marked this pull request as ready for review April 27, 2026 20:28

@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: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
service/integration/subject_mappings_test.go (1)

2774-2811: ⚠️ Potential issue | 🟠 Major

Sort-test cleanup leaks SubjectConditionSet rows created via NewSubjectConditionSet

Line 2784 creates a new subject condition set per mapping, but Lines 2847-2848 only delete the subject mapping. Since deleting a mapping does not delete its condition set, this leaves orphan rows and pollutes later list/sort tests in the same suite.

💡 Proposed fix
 func (s *SubjectMappingsSuite) deleteSortTestSubjectMappings(ids []string) {
 	for _, id := range ids {
-		_, err := s.db.PolicyClient.DeleteSubjectMapping(s.ctx, id)
+		sm, err := s.db.PolicyClient.GetSubjectMapping(s.ctx, id)
+		s.Require().NoError(err)
+
+		_, err = s.db.PolicyClient.DeleteSubjectMapping(s.ctx, id)
 		s.Require().NoError(err)
+
+		if scs := sm.GetSubjectConditionSet(); scs != nil && scs.GetId() != "" {
+			_, err = s.db.PolicyClient.DeleteSubjectConditionSet(s.ctx, scs.GetId())
+			s.Require().NoError(err)
+		}
 	}
 }

Also applies to: 2844-2850

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

In `@service/integration/subject_mappings_test.go` around lines 2774 - 2811,
createSortTestSubjectMappings creates a new SubjectConditionSet for each mapping
but test cleanup only deletes the mapping, leaving orphan SubjectConditionSet
rows; update createSortTestSubjectMappings and the cleanup to capture the
subject-condition-set id returned by CreateSubjectMapping (e.g.,
created.GetSubjectConditionSetId() or the appropriate field on the response)
alongside created.GetId(), return or record both ids, and ensure the teardown
calls PolicyClient.DeleteSubjectConditionSet (or the service method that deletes
condition sets) for each captured SubjectConditionSet id in addition to deleting
the SubjectMapping; reference createSortTestSubjectMappings,
SubjectConditionSetCreate, CreateSubjectMapping and the mapping deletion code to
implement this.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@service/integration/namespaces_test.go`:
- Around line 1416-1422: The helper deleteSortTestNamespaces only calls
s.db.PolicyClient.DeactivateNamespace which leaves rows visible to queries that
use ACTIVE_STATE_ENUM_ANY; update deleteSortTestNamespaces to also permanently
remove or purge the test rows after deactivation by invoking the corresponding
delete method on the PolicyClient (e.g., call s.db.PolicyClient.DeleteNamespace
or the service's purge/delete API for a namespace) for each id and assert no
error, so tests that list with ACTIVE_STATE_ENUM_ANY no longer see leftover
namespaces; ensure you check the returned error from both DeactivateNamespace
and the permanent delete call.

---

Outside diff comments:
In `@service/integration/subject_mappings_test.go`:
- Around line 2774-2811: createSortTestSubjectMappings creates a new
SubjectConditionSet for each mapping but test cleanup only deletes the mapping,
leaving orphan SubjectConditionSet rows; update createSortTestSubjectMappings
and the cleanup to capture the subject-condition-set id returned by
CreateSubjectMapping (e.g., created.GetSubjectConditionSetId() or the
appropriate field on the response) alongside created.GetId(), return or record
both ids, and ensure the teardown calls PolicyClient.DeleteSubjectConditionSet
(or the service method that deletes condition sets) for each captured
SubjectConditionSet id in addition to deleting the SubjectMapping; reference
createSortTestSubjectMappings, SubjectConditionSetCreate, CreateSubjectMapping
and the mapping deletion code to implement this.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: aa93d939-9982-4bf3-bead-75a9ee122c27

📥 Commits

Reviewing files that changed from the base of the PR and between 179da95 and 3ef050b.

📒 Files selected for processing (16)
  • service/integration/attributes_test.go
  • service/integration/kas_registry_key_test.go
  • service/integration/kas_registry_test.go
  • service/integration/namespaces_test.go
  • service/integration/obligations_test.go
  • service/integration/registered_resources_test.go
  • service/integration/subject_mappings_test.go
  • service/integration/utils.go
  • service/policy/db/key_access_server_registry.sql.go
  • service/policy/db/namespaces.sql.go
  • service/policy/db/obligations.sql.go
  • service/policy/db/queries/key_access_server_registry.sql
  • service/policy/db/queries/namespaces.sql
  • service/policy/db/queries/obligations.sql
  • service/policy/db/queries/registered_resources.sql
  • service/policy/db/registered_resources.sql.go

Comment thread service/integration/namespaces_test.go
@github-actions

Copy link
Copy Markdown
Contributor
Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 142.915761ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 95.022196ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 334.465736ms
Throughput 298.98 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 33.977082814s
Average Latency 337.608329ms
Throughput 147.16 requests/second

@github-actions

Copy link
Copy Markdown
Contributor

@dsm20
dsm20 marked this pull request as draft April 28, 2026 22:42
dsm20 added 6 commits May 4, 2026 12:22
add deletion wrappers/helpers for tests missing it, and then added that func as a defer call in each test. namespaces and attributes use Deactivate __ (soft delete), the others use Delete __ (hard delete). the helpers/wrappers simply loop over the IDs and call those deletion functions to clear up the test DB
across all 7 list RPCs getting sort functionality. how it works:
1. create 3 rows without sleep gaps (same created_at)
2. sort the returned row IDs manually (slices.sorted)
3. call the API with created_at ASC
4. timestamps tie (intended), leaving the tiebreaker the sorting factor
5. compare returned IDs against the manual sorted order from earlier (id ASC), these should be the same
All 8 tiebreaker integration tests assume created_at timestamps collide
when resources are created in a tight loop, but PostgreSQL's microsecond
precision means they don't. The tiebreaker (id ASC) never fires, causing
tests to assert random UUID order equals creation order — which fails ~83%
of the time.

Solution: add forceCreatedAtTie helper that forces all 3 IDs to the same
created_at via raw SQL UPDATE. This guarantees the tiebreaker determines
sort order and actually tests the feature.

Also fixed KAS key test helper issues from code review:
- Guard prefixes[0] access against empty slice
- Capture time.Now().UnixNano() once per iteration instead of twice

All tiebreaker tests now call forceCreatedAtTie before listing:
- attributes_test.go: attribute_definitions
- namespaces_test.go: attribute_namespaces
- obligations_test.go: obligation_definitions
- registered_resources_test.go: registered_resources
- kas_registry_test.go: key_access_servers
- kas_registry_key_test.go: key_access_server_keys
- subject_mappings_test.go: subject_mappings and subject_condition_set
inconsistency pointed out by gemini. createSortTestSM and createSortTestSCS now accept []string prefixes
integration testing cleanup was "soft deleting" (setting active to false) which proved to be useless. added a new util func to hard delete the test data in the DB (which is what is performed on the other endpoints, just with pre-existing functions, the api doesn't let you hard delete for namespaces or attributes)
@dsm20
dsm20 force-pushed the sort-testing-sql-refactor branch from f7302cf to 0fdb7bc Compare May 4, 2026 16:29
@github-actions

github-actions Bot commented May 4, 2026

Copy link
Copy Markdown
Contributor
Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 208.514248ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 109.296374ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 429.523084ms
Throughput 232.82 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 45.532965184s
Average Latency 453.64278ms
Throughput 109.81 requests/second

@github-actions

github-actions Bot commented May 4, 2026

Copy link
Copy Markdown
Contributor

@dsm20 dsm20 changed the title chore(policy): add sort SQL tiebreakers, consolidate integration test helpers, and add test cleanup test(policy): consolidate sort integration helpers, add tiebreaker tests, add test cleanup May 4, 2026
@dsm20 dsm20 changed the title test(policy): consolidate sort integration helpers, add tiebreaker tests, add test cleanup chore(policy): consolidate sort integration helpers, add tiebreaker tests, add test cleanup May 4, 2026
@dsm20
dsm20 marked this pull request as ready for review May 4, 2026 17:05

@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: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (5)
service/integration/namespaces_test.go (1)

476-510: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add deferred cleanup to these namespace sort tests.

These three cases create namespaces but never call defer s.deleteSortTestNamespaces(ids). Because they list with ACTIVE_STATE_ENUM_ANY, the leftovers remain query-visible for the rest of the suite.

Suggested fix
 func (s *NamespacesSuite) Test_ListNamespaces_SortByUnspecifiedDirection_DefaultsToDESC() {
 	ids := s.createSortTestNamespaces([]string{"unspecified-dir-ns-0", "unspecified-dir-ns-1", "unspecified-dir-ns-2"})
+	defer s.deleteSortTestNamespaces(ids)

 	listRsp, err := s.db.PolicyClient.ListNamespaces(s.ctx, &namespaces.ListNamespacesRequest{
 		State: common.ActiveStateEnum_ACTIVE_STATE_ENUM_ANY,
@@
 func (s *NamespacesSuite) Test_ListNamespaces_SortByBothUnspecified_DefaultsToCreatedAtDESC() {
 	ids := s.createSortTestNamespaces([]string{"both-unspecified-ns-0", "both-unspecified-ns-1", "both-unspecified-ns-2"})
+	defer s.deleteSortTestNamespaces(ids)

 	listRsp, err := s.db.PolicyClient.ListNamespaces(s.ctx, &namespaces.ListNamespacesRequest{
 		State: common.ActiveStateEnum_ACTIVE_STATE_ENUM_ANY,
@@
 func (s *NamespacesSuite) Test_ListNamespaces_SortOmitted() {
 	ids := s.createSortTestNamespaces([]string{"sort-omitted-ns-0", "sort-omitted-ns-1", "sort-omitted-ns-2"})
+	defer s.deleteSortTestNamespaces(ids)

 	listRsp, err := s.db.PolicyClient.ListNamespaces(s.ctx, &namespaces.ListNamespacesRequest{
 		State: common.ActiveStateEnum_ACTIVE_STATE_ENUM_ANY,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@service/integration/namespaces_test.go` around lines 476 - 510, Each of the
three tests (Test_ListNamespaces_SortByUnspecifiedDirection_DefaultsToDESC,
Test_ListNamespaces_SortByBothUnspecified_DefaultsToCreatedAtDESC, and
Test_ListNamespaces_SortOmitted) creates test namespaces via
createSortTestNamespaces but never cleans them up; add a deferred cleanup by
calling defer s.deleteSortTestNamespaces(ids) immediately after each ids :=
s.createSortTestNamespaces(...) line so the created namespaces are removed after
the test.
service/integration/attributes_test.go (1)

691-727: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Restore deferred cleanup in these three sort tests.

Unlike the earlier sort cases, these tests never call defer s.deleteSortTestAttributes(ids). The created rows stay around for the rest of the suite and can bleed into later list/pagination assertions.

Suggested fix
 func (s *AttributesSuite) Test_ListAttributes_SortByUnspecifiedDirection_DefaultsToDESC() {
 	nsID := s.createSortTestNamespace("sort-unspecified-dir")
 	ids := s.createSortTestAttributes(nsID, []string{"unspecified-dir-attr-0", "unspecified-dir-attr-1", "unspecified-dir-attr-2"})
+	defer s.deleteSortTestAttributes(ids)

 	listRsp, err := s.db.PolicyClient.ListAttributes(s.ctx, &attributes.ListAttributesRequest{
 		Namespace: nsID,
@@
 func (s *AttributesSuite) Test_ListAttributes_SortByBothUnspecified_DefaultsToCreatedAtDESC() {
 	nsID := s.createSortTestNamespace("sort-both-unspecified")
 	ids := s.createSortTestAttributes(nsID, []string{"both-unspecified-attr-0", "both-unspecified-attr-1", "both-unspecified-attr-2"})
+	defer s.deleteSortTestAttributes(ids)

 	listRsp, err := s.db.PolicyClient.ListAttributes(s.ctx, &attributes.ListAttributesRequest{
 		Namespace: nsID,
@@
 func (s *AttributesSuite) Test_ListAttributes_SortOmitted() {
 	nsID := s.createSortTestNamespace("sort-omitted")
 	ids := s.createSortTestAttributes(nsID, []string{"omitted-sort-attr-0", "omitted-sort-attr-1", "omitted-sort-attr-2"})
+	defer s.deleteSortTestAttributes(ids)

 	listRsp, err := s.db.PolicyClient.ListAttributes(s.ctx, &attributes.ListAttributesRequest{
 		Namespace: nsID,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@service/integration/attributes_test.go` around lines 691 - 727, These three
tests (Test_ListAttributes_SortByUnspecifiedDirection_DefaultsToDESC,
Test_ListAttributes_SortByBothUnspecified_DefaultsToCreatedAtDESC, and
Test_ListAttributes_SortOmitted) create test attributes but omit deferred
cleanup, causing data to leak into later tests; fix by adding a defer
s.deleteSortTestAttributes(ids) immediately after each call to
s.createSortTestAttributes(...) (and if other tests use createSortTestNamespace
add defer s.deleteSortTestNamespace(nsID) where missing) so the created rows are
removed after the test completes.
service/integration/subject_mappings_test.go (2)

1627-1666: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add missing cleanup defers in three SubjectConditionSets sort tests.

Line 1628, Line 1643, and Line 1658 create test subject condition sets without cleanup. These rows persist and can skew list-ordering and pagination assertions over time.

Patch
func (s *SubjectMappingsSuite) Test_ListSubjectConditionSets_SortByUnspecifiedDirection_DefaultsToDESC() {
 	ids := s.createSortTestSubjectConditionSets([]string{"unspecified-dir-scs-0", "unspecified-dir-scs-1", "unspecified-dir-scs-2"})
+	defer s.deleteSortTestSubjectConditionSets(ids)

 	listRsp, err := s.db.PolicyClient.ListSubjectConditionSets(s.ctx, &subjectmapping.ListSubjectConditionSetsRequest{
@@
func (s *SubjectMappingsSuite) Test_ListSubjectConditionSets_SortByBothUnspecified_DefaultsToCreatedAtDESC() {
 	ids := s.createSortTestSubjectConditionSets([]string{"both-unspecified-scs-0", "both-unspecified-scs-1", "both-unspecified-scs-2"})
+	defer s.deleteSortTestSubjectConditionSets(ids)

 	listRsp, err := s.db.PolicyClient.ListSubjectConditionSets(s.ctx, &subjectmapping.ListSubjectConditionSetsRequest{
@@
func (s *SubjectMappingsSuite) Test_ListSubjectConditionSets_SortOmitted() {
 	ids := s.createSortTestSubjectConditionSets([]string{"sort-omitted-scs-0", "sort-omitted-scs-1", "sort-omitted-scs-2"})
+	defer s.deleteSortTestSubjectConditionSets(ids)

 	listRsp, err := s.db.PolicyClient.ListSubjectConditionSets(s.ctx, &subjectmapping.ListSubjectConditionSetsRequest{})
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@service/integration/subject_mappings_test.go` around lines 1627 - 1666, The
tests Test_ListSubjectConditionSets_SortByUnspecifiedDirection_DefaultsToDESC,
Test_ListSubjectConditionSets_SortByBothUnspecified_DefaultsToCreatedAtDESC, and
Test_ListSubjectConditionSets_SortOmitted create subject condition sets via
createSortTestSubjectConditionSets but do not clean them up; add defers to
remove the created entries to avoid polluting subsequent tests. After calling
ids := s.createSortTestSubjectConditionSets(...), immediately iterate the
returned ids and defer a cleanup call (e.g., for _, id := range ids { defer
s.deleteSubjectConditionSet(id) } or the suite's appropriate deletion helper) so
each created SubjectConditionSet is deleted when the test finishes. Ensure the
defer uses the per-id variable correctly (capture loop variable) and reference
the existing createSortTestSubjectConditionSets and the suite's delete/cleanup
helper when implementing.

755-794: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add missing cleanup defers in three SubjectMappings sort tests.

Line 756, Line 771, and Line 786 create test subject mappings but never clean them up. This leaks rows and can destabilize later integration tests.

Patch
func (s *SubjectMappingsSuite) Test_ListSubjectMappings_SortByUnspecifiedDirection_DefaultsToDESC() {
 	ids := s.createSortTestSubjectMappings([]string{"unspecified-dir-sm-0", "unspecified-dir-sm-1", "unspecified-dir-sm-2"})
+	defer s.deleteSortTestSubjectMappings(ids)

 	listRsp, err := s.db.PolicyClient.ListSubjectMappings(s.ctx, &subjectmapping.ListSubjectMappingsRequest{
@@
func (s *SubjectMappingsSuite) Test_ListSubjectMappings_SortByBothUnspecified_DefaultsToCreatedAtDESC() {
 	ids := s.createSortTestSubjectMappings([]string{"both-unspecified-sm-0", "both-unspecified-sm-1", "both-unspecified-sm-2"})
+	defer s.deleteSortTestSubjectMappings(ids)

 	listRsp, err := s.db.PolicyClient.ListSubjectMappings(s.ctx, &subjectmapping.ListSubjectMappingsRequest{
@@
func (s *SubjectMappingsSuite) Test_ListSubjectMappings_SortOmitted() {
 	ids := s.createSortTestSubjectMappings([]string{"sort-omitted-sm-0", "sort-omitted-sm-1", "sort-omitted-sm-2"})
+	defer s.deleteSortTestSubjectMappings(ids)

 	listRsp, err := s.db.PolicyClient.ListSubjectMappings(s.ctx, &subjectmapping.ListSubjectMappingsRequest{})
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@service/integration/subject_mappings_test.go` around lines 755 - 794, The
three tests (Test_ListSubjectMappings_SortByUnspecifiedDirection_DefaultsToDESC,
Test_ListSubjectMappings_SortByBothUnspecified_DefaultsToCreatedAtDESC,
Test_ListSubjectMappings_SortOmitted) call createSortTestSubjectMappings(...) to
insert rows but never remove them; add a defer immediately after each ids := ...
line to clean up the created IDs (e.g. defer s.deleteSubjectMappings(ids) or the
existing test teardown helper your suite uses) so the created subject mappings
are removed after the test finishes, ensuring no leaked rows affect other
integration tests.
service/integration/kas_registry_test.go (1)

1066-1079: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Missing defer cleanup in three sort tests leaves orphaned DB rows

Test_ListKeyAccessServers_SortByUnspecifiedDirection_DefaultsToDESC (line 1067), Test_ListKeyAccessServers_SortByBothUnspecified_DefaultsToCreatedAtDESC (line 1082), and Test_ListKeyAccessServers_SortOmitted (line 1097) each call createSortTestKeyAccessServers but never register a defer s.deleteSortTestKeyAccessServers(ids). Every other refactored sort test in this file defers cleanup. The PR objective explicitly states cleanup should be added to all sort tests. Accumulated rows from prior test runs can shift the created_at DESC window and cause flaky assertions.

🐛 Proposed fix — add the missing defers
 func (s *KasRegistrySuite) Test_ListKeyAccessServers_SortByUnspecifiedDirection_DefaultsToDESC() {
 	ids := s.createSortTestKeyAccessServers([]string{"unspecified-dir-kas-0", "unspecified-dir-kas-1", "unspecified-dir-kas-2"})
+	defer s.deleteSortTestKeyAccessServers(ids)
 func (s *KasRegistrySuite) Test_ListKeyAccessServers_SortByBothUnspecified_DefaultsToCreatedAtDESC() {
 	ids := s.createSortTestKeyAccessServers([]string{"both-unspecified-kas-0", "both-unspecified-kas-1", "both-unspecified-kas-2"})
+	defer s.deleteSortTestKeyAccessServers(ids)
 func (s *KasRegistrySuite) Test_ListKeyAccessServers_SortOmitted() {
 	ids := s.createSortTestKeyAccessServers([]string{"sort-omitted-kas-0", "sort-omitted-kas-1", "sort-omitted-kas-2"})
+	defer s.deleteSortTestKeyAccessServers(ids)

Also applies to: 1081-1094, 1096-1105

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

In `@service/integration/kas_registry_test.go` around lines 1066 - 1079, In the
three tests Test_ListKeyAccessServers_SortByUnspecifiedDirection_DefaultsToDESC,
Test_ListKeyAccessServers_SortByBothUnspecified_DefaultsToCreatedAtDESC, and
Test_ListKeyAccessServers_SortOmitted add a deferred cleanup after calling
createSortTestKeyAccessServers by immediately calling defer
s.deleteSortTestKeyAccessServers(ids) so the test-created rows are removed;
locate the call to createSortTestKeyAccessServers(...) in each test and insert
the defer statement referencing the returned ids to match the other refactored
sort tests.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@service/integration/attributes_test.go`:
- Around line 1911-1914: The helper deleteSortTestAttributes currently only
removes rows from attribute_definitions (via forceDeleteRows) and thus leaks the
per-test namespace created by createSortTestNamespace plus any auto-seeded
actions; change deleteSortTestAttributes to accept the namespace id (nsID) and
delete the namespace row and its seeded actions as well (e.g. call
forceDeleteRows for "namespaces" and the table storing auto-seeded actions in
addition to "attribute_definitions"), keep the original deletion of
attribute_definitions using forceDeleteRows, and update all callers to pass the
nsID and call it with defer (defer s.deleteSortTestAttributes(nsID, ids)) so the
per-test namespace and actions are cleaned up immediately after each sort test.

---

Outside diff comments:
In `@service/integration/attributes_test.go`:
- Around line 691-727: These three tests
(Test_ListAttributes_SortByUnspecifiedDirection_DefaultsToDESC,
Test_ListAttributes_SortByBothUnspecified_DefaultsToCreatedAtDESC, and
Test_ListAttributes_SortOmitted) create test attributes but omit deferred
cleanup, causing data to leak into later tests; fix by adding a defer
s.deleteSortTestAttributes(ids) immediately after each call to
s.createSortTestAttributes(...) (and if other tests use createSortTestNamespace
add defer s.deleteSortTestNamespace(nsID) where missing) so the created rows are
removed after the test completes.

In `@service/integration/kas_registry_test.go`:
- Around line 1066-1079: In the three tests
Test_ListKeyAccessServers_SortByUnspecifiedDirection_DefaultsToDESC,
Test_ListKeyAccessServers_SortByBothUnspecified_DefaultsToCreatedAtDESC, and
Test_ListKeyAccessServers_SortOmitted add a deferred cleanup after calling
createSortTestKeyAccessServers by immediately calling defer
s.deleteSortTestKeyAccessServers(ids) so the test-created rows are removed;
locate the call to createSortTestKeyAccessServers(...) in each test and insert
the defer statement referencing the returned ids to match the other refactored
sort tests.

In `@service/integration/namespaces_test.go`:
- Around line 476-510: Each of the three tests
(Test_ListNamespaces_SortByUnspecifiedDirection_DefaultsToDESC,
Test_ListNamespaces_SortByBothUnspecified_DefaultsToCreatedAtDESC, and
Test_ListNamespaces_SortOmitted) creates test namespaces via
createSortTestNamespaces but never cleans them up; add a deferred cleanup by
calling defer s.deleteSortTestNamespaces(ids) immediately after each ids :=
s.createSortTestNamespaces(...) line so the created namespaces are removed after
the test.

In `@service/integration/subject_mappings_test.go`:
- Around line 1627-1666: The tests
Test_ListSubjectConditionSets_SortByUnspecifiedDirection_DefaultsToDESC,
Test_ListSubjectConditionSets_SortByBothUnspecified_DefaultsToCreatedAtDESC, and
Test_ListSubjectConditionSets_SortOmitted create subject condition sets via
createSortTestSubjectConditionSets but do not clean them up; add defers to
remove the created entries to avoid polluting subsequent tests. After calling
ids := s.createSortTestSubjectConditionSets(...), immediately iterate the
returned ids and defer a cleanup call (e.g., for _, id := range ids { defer
s.deleteSubjectConditionSet(id) } or the suite's appropriate deletion helper) so
each created SubjectConditionSet is deleted when the test finishes. Ensure the
defer uses the per-id variable correctly (capture loop variable) and reference
the existing createSortTestSubjectConditionSets and the suite's delete/cleanup
helper when implementing.
- Around line 755-794: The three tests
(Test_ListSubjectMappings_SortByUnspecifiedDirection_DefaultsToDESC,
Test_ListSubjectMappings_SortByBothUnspecified_DefaultsToCreatedAtDESC,
Test_ListSubjectMappings_SortOmitted) call createSortTestSubjectMappings(...) to
insert rows but never remove them; add a defer immediately after each ids := ...
line to clean up the created IDs (e.g. defer s.deleteSubjectMappings(ids) or the
existing test teardown helper your suite uses) so the created subject mappings
are removed after the test finishes, ensuring no leaked rows affect other
integration tests.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 326e172d-b541-4789-9358-b12e83695a00

📥 Commits

Reviewing files that changed from the base of the PR and between f7302cf and 0fdb7bc.

📒 Files selected for processing (8)
  • service/integration/attributes_test.go
  • service/integration/kas_registry_key_test.go
  • service/integration/kas_registry_test.go
  • service/integration/namespaces_test.go
  • service/integration/obligations_test.go
  • service/integration/registered_resources_test.go
  • service/integration/subject_mappings_test.go
  • service/integration/utils.go

Comment thread service/integration/attributes_test.go
#3402 added more integration tests that needed cleanup calls
@github-actions

github-actions Bot commented May 4, 2026

Copy link
Copy Markdown
Contributor
Benchmark results, click to expand

Benchmark authorization.GetDecisions Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 177.502393ms

Benchmark authorization.v2.GetMultiResourceDecision Results:

Metric Value
Approved Decision Requests 1000
Denied Decision Requests 0
Total Time 91.760524ms

Benchmark Statistics

Name № Requests Avg Duration Min Duration Max Duration

Bulk Benchmark Results

Metric Value
Total Decrypts 100
Successful Decrypts 100
Failed Decrypts 0
Total Time 439.210507ms
Throughput 227.68 requests/second

TDF3 Benchmark Results:

Metric Value
Total Requests 5000
Successful Requests 5000
Failed Requests 0
Concurrent Requests 50
Total Time 43.200343793s
Average Latency 430.134059ms
Throughput 115.74 requests/second

@github-actions

github-actions Bot commented May 4, 2026

Copy link
Copy Markdown
Contributor

⚠️ Govulncheck found vulnerabilities ⚠️

The following modules have known vulnerabilities:

  • tests-bdd

See the workflow run for details.

@github-actions

github-actions Bot commented May 4, 2026

Copy link
Copy Markdown
Contributor

Comment thread service/integration/attributes_test.go

@elizabethhealy elizabethhealy left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

lgtm, left an optional nit

@dsm20
dsm20 added this pull request to the merge queue May 4, 2026
Merged via the queue into main with commit cffcb73 May 4, 2026
39 checks passed
@dsm20
dsm20 deleted the sort-testing-sql-refactor branch May 4, 2026 21:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp:db DB component comp:policy Policy Configuration ( attributes, subject mappings, resource mappings, kas registry) size/s

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants