Skip to content

fix: enable parallel execution for federation integration tests#1385

Merged
devsergiy merged 3 commits intomasterfrom
jensneuse/improve-execution-test-speed
Feb 16, 2026
Merged

fix: enable parallel execution for federation integration tests#1385
devsergiy merged 3 commits intomasterfrom
jensneuse/improve-execution-test-speed

Conversation

@jensneuse
Copy link
Copy Markdown
Member

@jensneuse jensneuse commented Feb 16, 2026

Move mutable global state into per-Resolver instances so each FederationSetup gets isolated data. This eliminates the global mutex that serialized all tests and fixes the data race in subscription resolvers by copying products before mutation.

Summary by CodeRabbit

  • Tests

    • Enabled parallel execution across federation integration tests, restructured setups to isolate state, and removed the previous build constraint so tests run with race detectors enabled.
    • Mutation tests now use isolated setups to avoid cross-test interference.
  • Refactor

    • Replaced global test state with instance-scoped resolver state and factory-backed data initialization.
    • Removed global synchronization around test setup to allow concurrent execution.

Checklist

  • I have discussed my proposed changes in an issue and have received approval to proceed.
  • I have followed the coding standards of the project.
  • Tests or benchmarks have been added or updated.

Move mutable global state into per-Resolver instances so each
FederationSetup gets isolated data. This eliminates the global mutex
that serialized all tests and fixes the data race in subscription
resolvers by copying products before mutation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@jensneuse jensneuse requested a review from a team as a code owner February 16, 2026 12:28
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 16, 2026

No actionable comments were generated in the recent review. 🎉


📝 Walkthrough

Walkthrough

Move package-level test and fixture globals into resolver instances and factory functions, remove synchronized setup teardown, add parallel test execution (t.Parallel()), and make products/reviews resolvers stateful with configurable pricing/update behavior.

Changes

Cohort / File(s) Summary
Test Parallelization
execution/engine/federation_integration_static_test.go, execution/engine/federation_integration_test.go
Enable parallel tests (t.Parallel()), remove race-only build constraint, introduce shared read-only setup and isolated mutation setup to avoid port/state contention.
Products — Resolver & Handler
execution/federationtesting/products/graph/resolver.go, execution/federationtesting/products/graph/handler.go
Replace empty Resolver with stateful struct (products, randomness, price bounds, currentPrice, updateInterval, mutex); handler now constructs and injects the populated Resolver.
Products — Data & Resolvers
execution/federationtesting/products/graph/products.go, execution/federationtesting/products/graph/entity.resolvers.go, execution/federationtesting/products/graph/schema.resolvers.go
Remove package-level globals; add newProducts() factory; resolver methods now use r.products, operate on copied product pointers for streams, and read pricing/update config from the resolver.
Reviews — Resolver & Handler
execution/federationtesting/reviews/graph/resolver.go, execution/federationtesting/reviews/graph/handler.go
Expand Resolver to hold reviews and attachments; handler initializes and passes the populated Resolver to the schema.
Reviews — Data & Resolvers
execution/federationtesting/reviews/graph/reviews.go, execution/federationtesting/reviews/graph/attachments.go, execution/federationtesting/reviews/graph/schema.resolvers.go
Replace package-level reviews/attachments with newReviews()/newAttachments() factories; resolvers updated to use r.reviews/r.attachments.
Infrastructure & Cleanup
execution/federationtesting/gateway/main.go, execution/federationtesting/util.go, execution/federationtesting/products/graph/variables.go
Remove global mutex around FederationSetup (unsynchronized init/teardown), delete now-unused variables.go, and replace ws.DefaultHTTPUpgrader with an explicit ws.HTTPUpgrader{Header: ...} literal.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly describes the main objective of the changeset: enabling parallel execution for federation integration tests.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into master

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch jensneuse/improve-execution-test-speed

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

Copy link
Copy Markdown
Contributor

@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.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@execution/federationtesting/products/graph/schema.resolvers.go`:
- Line 24: The TopProducts resolver currently returns
r.products[:len(r.products)-1] which will panic on empty slices and ignores the
first parameter; update the TopProducts function to first guard for empty
r.products (return nil, nil or empty slice) and then compute an upper bound as
min(len(r.products), first) (also handle non-positive first by returning empty)
before slicing (e.g., return r.products[:bound], nil). Ensure you reference and
use r.products and the first parameter in TopProducts to safely clamp the slice.
- Around line 35-48: The subscription goroutine mutates shared resolver state
r.currentPrice without synchronization; add a sync.Mutex field (e.g., priceMu
sync.Mutex) to the Resolver type and use priceMu.Lock()/priceMu.Unlock() around
every read/write of r.currentPrice in the UpdatedPrice handler (the section that
sets p.Price = r.currentPrice and increments r.currentPrice), and ensure the
sync package is imported so concurrent subscriptions cannot race on
currentPrice.
🧹 Nitpick comments (1)
execution/federationtesting/products/graph/handler.go (1)

19-19: Global websocketConnections counter may produce misleading values in parallel tests.

The websocketConnections atomic counter remains a package-level variable. While atomic operations prevent data races, parallel tests sharing this counter will see aggregated values from all concurrent test instances. Line 34's Store(0) reset could also clear counts from other parallel tests mid-execution.

If WebsocketConnectionsHandler is only used for debugging and not asserted in tests, this is acceptable. Otherwise, consider moving the counter into the resolver or handler struct for isolation.

Also applies to: 34-34

Comment thread execution/federationtesting/products/graph/schema.resolvers.go Outdated
…rice

Address PR review feedback:
- Guard TopProducts against empty products slice and respect the first parameter
- Add sync.Mutex to protect r.currentPrice from concurrent subscription races

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@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.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@execution/federationtesting/products/graph/schema.resolvers.go`:
- Around line 42-57: The case branch can panic when r.products is empty or has
one element; add a guard using n := len(r.products) and if n == 0 { continue }
before accessing r.products, and when picking a random product use idx :=
rand.Intn(n) (rand.Intn requires >0) so it works for n==1 (returns 0); replace
direct uses of r.products[len(r.products)-1] and rand.Intn(len(r.products)-1)
with r.products[n-1] and r.products[idx] respectively, preserving the Price
mutation logic (use p := *product, set p.Price, send via updatedPrice) and keep
synchronization around r.currentPrice with r.priceMu as before.

Comment thread execution/federationtesting/products/graph/schema.resolvers.go
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@devsergiy devsergiy merged commit 09d9348 into master Feb 16, 2026
7 checks passed
@devsergiy devsergiy deleted the jensneuse/improve-execution-test-speed branch February 16, 2026 13:15
jensneuse pushed a commit that referenced this pull request Feb 16, 2026
🤖 I have created a release *beep* *boop*
---


##
[1.8.0](execution/v1.7.0...execution/v1.8.0)
(2026-02-16)


### Features

* add flag for relaxed nullability checks on same shape
([#1378](#1378))
([6be2e74](6be2e74))


### Bug Fixes

* enable parallel execution for federation integration tests
([#1385](#1385))
([09d9348](09d9348))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
  * Added a flag for relaxed nullability checks
* **Bug Fixes**
  * Enabled parallel execution for federation integration tests

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants