Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions execution/engine/federation_integration_static_test.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
//go:build !race

package engine

import (
Expand All @@ -16,14 +14,15 @@ import (
"github.com/wundergraph/graphql-go-tools/v2/pkg/testing/flags"
)

// This tests produces data races in the generated gql code. Disable it when the race
// detector is enabled.
func TestExecutionEngine_FederationAndSubscription_IntegrationTest(t *testing.T) {
t.Parallel()

if flags.IsWindows {
t.Skip("skip on windows - test is timing dependent")
}

t.Run("operation", func(t *testing.T) {
t.Parallel()
ctx, cancelFn := context.WithCancel(context.Background())
setup := federationtesting.NewFederationSetup()
t.Cleanup(func() {
Expand Down Expand Up @@ -60,6 +59,7 @@ func TestExecutionEngine_FederationAndSubscription_IntegrationTest(t *testing.T)
})

t.Run("subscription", func(t *testing.T) {
t.Parallel()
ctx, cancelFn := context.WithCancel(context.Background())
setup := federationtesting.NewFederationSetup()
t.Cleanup(func() {
Expand Down
139 changes: 38 additions & 101 deletions execution/engine/federation_integration_test.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
//go:build !race

package engine_test

import (
Expand All @@ -21,7 +19,6 @@ import (

"github.com/wundergraph/graphql-go-tools/execution/federationtesting"
"github.com/wundergraph/graphql-go-tools/execution/federationtesting/gateway"
products "github.com/wundergraph/graphql-go-tools/execution/federationtesting/products/graph"
)

func addGateway(enableART bool) func(setup *federationtesting.FederationSetup) *httptest.Server {
Expand Down Expand Up @@ -77,37 +74,39 @@ func TestFederationIntegrationTestWithArt(t *testing.T) {
})
}

// This tests produces data races in the generated gql code. Disable it when the race
// detector is enabled.
func TestFederationIntegrationTest(t *testing.T) {
t.Parallel()

// Shared setup for all read-only tests (minimizes open ports)
setup := federationtesting.NewFederationSetup(addGateway(false))
t.Cleanup(setup.Close)
gqlClient := NewGraphqlClient(http.DefaultClient)

t.Run("single upstream query operation", func(t *testing.T) {
setup := federationtesting.NewFederationSetup(addGateway(false))
t.Cleanup(setup.Close)
gqlClient := NewGraphqlClient(http.DefaultClient)
t.Parallel()
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
resp := gqlClient.Query(ctx, setup.GatewayServer.URL, testQueryPath("queries/single_upstream.query"), nil, t)
assert.Equal(t, `{"data":{"me":{"id":"1234","username":"Me"}}}`, string(resp))
})

t.Run("query spans multiple federated servers", func(t *testing.T) {
setup := federationtesting.NewFederationSetup(addGateway(false))
t.Cleanup(setup.Close)
gqlClient := NewGraphqlClient(http.DefaultClient)
t.Parallel()
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
resp := gqlClient.Query(ctx, setup.GatewayServer.URL, testQueryPath("queries/multiple_upstream.query"), nil, t)
assert.Equal(t, `{"data":{"topProducts":[{"name":"Trilby","reviews":[{"body":"A highly effective form of birth control.","author":{"username":"Me"}}]},{"name":"Fedora","reviews":[{"body":"Fedoras are one of the most fashionable hats around and can look great with a variety of outfits.","author":{"username":"Me"}}]}]}}`, string(resp))
})

// Mutation test needs its own setup because AddReview modifies the reviews resolver state
t.Run("mutation operation with variables", func(t *testing.T) {
setup := federationtesting.NewFederationSetup(addGateway(false))
t.Cleanup(setup.Close)
gqlClient := NewGraphqlClient(http.DefaultClient)
t.Parallel()
mutSetup := federationtesting.NewFederationSetup(addGateway(false))
t.Cleanup(mutSetup.Close)
mutClient := NewGraphqlClient(http.DefaultClient)
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
resp := gqlClient.Query(ctx, setup.GatewayServer.URL, testQueryPath("mutations/mutation_with_variables.query"), queryVariables{
resp := mutClient.Query(ctx, mutSetup.GatewayServer.URL, testQueryPath("mutations/mutation_with_variables.query"), queryVariables{
"authorID": "3210",
"upc": "top-1",
"review": "This is the last straw. Hat you will wear. 11/10",
Expand All @@ -116,36 +115,27 @@ func TestFederationIntegrationTest(t *testing.T) {
})

t.Run("union query", func(t *testing.T) {
setup := federationtesting.NewFederationSetup(addGateway(false))
t.Cleanup(setup.Close)
gqlClient := NewGraphqlClient(http.DefaultClient)
t.Parallel()
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
resp := gqlClient.Query(ctx, setup.GatewayServer.URL, testQueryPath("queries/union.query"), nil, t)
assert.Equal(t, `{"data":{"me":{"username":"Me","history":[{"__typename":"Purchase","wallet":{"amount":123}},{"__typename":"Sale","rating":5},{"__typename":"Purchase","wallet":{"amount":123}}]}}}`, string(resp))
})

t.Run("interface query", func(t *testing.T) {
setup := federationtesting.NewFederationSetup(addGateway(false))
t.Cleanup(setup.Close)
gqlClient := NewGraphqlClient(http.DefaultClient)
t.Parallel()
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
resp := gqlClient.Query(ctx, setup.GatewayServer.URL, testQueryPath("queries/interface.query"), nil, t)
assert.Equal(t, `{"data":{"me":{"username":"Me","history":[{"wallet":{"amount":123,"specialField1":"some special value 1"}},{"rating":5},{"wallet":{"amount":123,"specialField2":"some special value 2"}}]}}}`, string(resp))
})

t.Run("subscription query through WebSocket transport", func(t *testing.T) {
setup := federationtesting.NewFederationSetup(addGateway(false))
t.Cleanup(setup.Close)
gqlClient := NewGraphqlClient(http.DefaultClient)
t.Parallel()
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
// Reset the products slice to the original state
defer products.Reset()

wsAddr := strings.ReplaceAll(setup.GatewayServer.URL, "http://", "ws://")
// fmt.Println("setup.GatewayServer.URL", wsAddr)
messages := gqlClient.Subscription(ctx, wsAddr, testQueryPath("subscriptions/subscription.query"), queryVariables{
"upc": "top-1",
}, t)
Expand All @@ -155,9 +145,7 @@ func TestFederationIntegrationTest(t *testing.T) {
})

t.Run("Multiple queries and nested fragments", func(t *testing.T) {
setup := federationtesting.NewFederationSetup(addGateway(false))
t.Cleanup(setup.Close)
gqlClient := NewGraphqlClient(http.DefaultClient)
t.Parallel()
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
resp := gqlClient.Query(ctx, setup.GatewayServer.URL, testQueryPath("queries/multiple_queries_with_nested_fragments.query"), nil, t)
Expand Down Expand Up @@ -205,9 +193,7 @@ func TestFederationIntegrationTest(t *testing.T) {
})

t.Run("Multiple queries with __typename", func(t *testing.T) {
setup := federationtesting.NewFederationSetup(addGateway(false))
t.Cleanup(setup.Close)
gqlClient := NewGraphqlClient(http.DefaultClient)
t.Parallel()
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
resp := gqlClient.Query(ctx, setup.GatewayServer.URL, testQueryPath("queries/multiple_queries.query"), nil, t)
Expand Down Expand Up @@ -237,9 +223,7 @@ func TestFederationIntegrationTest(t *testing.T) {
})

t.Run("Query that returns union", func(t *testing.T) {
setup := federationtesting.NewFederationSetup(addGateway(false))
t.Cleanup(setup.Close)
gqlClient := NewGraphqlClient(http.DefaultClient)
t.Parallel()
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
resp := gqlClient.Query(ctx, setup.GatewayServer.URL, testQueryPath("queries/multiple_queries_with_union_return.query"), nil, t)
Expand Down Expand Up @@ -316,9 +300,7 @@ func TestFederationIntegrationTest(t *testing.T) {
})

t.Run("Object response type with interface and object fragment", func(t *testing.T) {
setup := federationtesting.NewFederationSetup(addGateway(false))
t.Cleanup(setup.Close)
gqlClient := NewGraphqlClient(http.DefaultClient)
t.Parallel()
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
resp := gqlClient.Query(ctx, setup.GatewayServer.URL, testQueryPath("queries/interface_fragment_on_object.graphql"), nil, t)
Expand All @@ -335,9 +317,7 @@ func TestFederationIntegrationTest(t *testing.T) {
})

t.Run("Interface response type with object fragment", func(t *testing.T) {
setup := federationtesting.NewFederationSetup(addGateway(false))
t.Cleanup(setup.Close)
gqlClient := NewGraphqlClient(http.DefaultClient)
t.Parallel()
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
resp := gqlClient.Query(ctx, setup.GatewayServer.URL, testQueryPath("queries/object_fragment_on_interface.graphql"), nil, t)
Expand All @@ -355,39 +335,31 @@ func TestFederationIntegrationTest(t *testing.T) {
})

t.Run("recursive fragment", func(t *testing.T) {
setup := federationtesting.NewFederationSetup(addGateway(false))
t.Cleanup(setup.Close)
gqlClient := NewGraphqlClient(http.DefaultClient)
t.Parallel()
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
resp := gqlClient.QueryStatusCode(ctx, setup.GatewayServer.URL, testQueryPath("queries/recursive_fragment.graphql"), nil, http.StatusInternalServerError, t)
assert.Len(t, resp, 0)
})

t.Run("empty fragment", func(t *testing.T) {
setup := federationtesting.NewFederationSetup(addGateway(false))
t.Cleanup(setup.Close)
gqlClient := NewGraphqlClient(http.DefaultClient)
t.Parallel()
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
resp := gqlClient.QueryStatusCode(ctx, setup.GatewayServer.URL, testQueryPath("queries/empty_fragment.graphql"), nil, http.StatusInternalServerError, t)
assert.Len(t, resp, 0)
})

t.Run("empty fragment variant", func(t *testing.T) {
setup := federationtesting.NewFederationSetup(addGateway(false))
t.Cleanup(setup.Close)
gqlClient := NewGraphqlClient(http.DefaultClient)
t.Parallel()
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
resp := gqlClient.QueryStatusCode(ctx, setup.GatewayServer.URL, testQueryPath("queries/empty_fragment_variant.graphql"), nil, http.StatusInternalServerError, t)
assert.Len(t, resp, 0)
})

t.Run("Union response type with interface fragments", func(t *testing.T) {
setup := federationtesting.NewFederationSetup(addGateway(false))
t.Cleanup(setup.Close)
gqlClient := NewGraphqlClient(http.DefaultClient)
t.Parallel()
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
resp := gqlClient.Query(ctx, setup.GatewayServer.URL, testQueryPath("queries/interface_fragments_on_union.graphql"), nil, t)
Expand Down Expand Up @@ -429,10 +401,7 @@ func TestFederationIntegrationTest(t *testing.T) {
// Duplicated properties (and therefore invalid JSON) are usually removed during normalization processes.
// It is not yet decided whether this should be addressed before these normalization processes.
t.Run("Complex nesting", func(t *testing.T) {
setup := federationtesting.NewFederationSetup(addGateway(false))
defer setup.Close()

gqlClient := NewGraphqlClient(http.DefaultClient)
t.Parallel()
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
resp := gqlClient.Query(ctx, setup.GatewayServer.URL, testQueryPath("queries/complex_nesting.graphql"), nil, t)
Expand All @@ -441,10 +410,7 @@ func TestFederationIntegrationTest(t *testing.T) {
})

t.Run("More complex nesting", func(t *testing.T) {
setup := federationtesting.NewFederationSetup(addGateway(false))
defer setup.Close()

gqlClient := NewGraphqlClient(http.DefaultClient)
t.Parallel()
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
resp := gqlClient.Query(ctx, setup.GatewayServer.URL, testQueryPath("queries/more_complex_nesting.graphql"), nil, t)
Expand All @@ -453,10 +419,7 @@ func TestFederationIntegrationTest(t *testing.T) {
})

t.Run("Multiple nested interfaces", func(t *testing.T) {
setup := federationtesting.NewFederationSetup(addGateway(false))
defer setup.Close()

gqlClient := NewGraphqlClient(http.DefaultClient)
t.Parallel()
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
resp := gqlClient.Query(ctx, setup.GatewayServer.URL, testQueryPath("queries/titlename.graphql"), nil, t)
Expand All @@ -465,10 +428,7 @@ func TestFederationIntegrationTest(t *testing.T) {
})

t.Run("Multiple nested unions", func(t *testing.T) {
setup := federationtesting.NewFederationSetup(addGateway(false))
defer setup.Close()

gqlClient := NewGraphqlClient(http.DefaultClient)
t.Parallel()
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
resp := gqlClient.Query(ctx, setup.GatewayServer.URL, testQueryPath("queries/cd.graphql"), nil, t)
Expand All @@ -477,10 +437,7 @@ func TestFederationIntegrationTest(t *testing.T) {
})

t.Run("More complex nesting typename variant", func(t *testing.T) {
setup := federationtesting.NewFederationSetup(addGateway(false))
defer setup.Close()

gqlClient := NewGraphqlClient(http.DefaultClient)
t.Parallel()
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
resp := gqlClient.Query(ctx, setup.GatewayServer.URL, testQueryPath("queries/more_complex_nesting_typename_variant.graphql"), nil, t)
Expand All @@ -489,10 +446,7 @@ func TestFederationIntegrationTest(t *testing.T) {
})

t.Run("Abstract object", func(t *testing.T) {
setup := federationtesting.NewFederationSetup(addGateway(false))
defer setup.Close()

gqlClient := NewGraphqlClient(http.DefaultClient)
t.Parallel()
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
resp := gqlClient.Query(ctx, setup.GatewayServer.URL, testQueryPath("queries/abstract_object.graphql"), nil, t)
Expand All @@ -501,10 +455,7 @@ func TestFederationIntegrationTest(t *testing.T) {
})

t.Run("Abstract object non shared", func(t *testing.T) {
setup := federationtesting.NewFederationSetup(addGateway(false))
defer setup.Close()

gqlClient := NewGraphqlClient(http.DefaultClient)
t.Parallel()
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
resp := gqlClient.Query(ctx, setup.GatewayServer.URL, testQueryPath("queries/abstract_object_non_shared.graphql"), nil, t)
Expand All @@ -513,10 +464,7 @@ func TestFederationIntegrationTest(t *testing.T) {
})

t.Run("Abstract object nested", func(t *testing.T) {
setup := federationtesting.NewFederationSetup(addGateway(false))
defer setup.Close()

gqlClient := NewGraphqlClient(http.DefaultClient)
t.Parallel()
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
resp := gqlClient.Query(ctx, setup.GatewayServer.URL, testQueryPath("queries/abstract_object_nested.graphql"), nil, t)
Expand All @@ -525,10 +473,7 @@ func TestFederationIntegrationTest(t *testing.T) {
})

t.Run("Abstract object nested reverse", func(t *testing.T) {
setup := federationtesting.NewFederationSetup(addGateway(false))
defer setup.Close()

gqlClient := NewGraphqlClient(http.DefaultClient)
t.Parallel()
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
resp := gqlClient.Query(ctx, setup.GatewayServer.URL, testQueryPath("queries/abstract_object_nested_reverse.graphql"), nil, t)
Expand All @@ -537,10 +482,7 @@ func TestFederationIntegrationTest(t *testing.T) {
})

t.Run("Abstract object mixed", func(t *testing.T) {
setup := federationtesting.NewFederationSetup(addGateway(false))
defer setup.Close()

gqlClient := NewGraphqlClient(http.DefaultClient)
t.Parallel()
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
resp := gqlClient.Query(ctx, setup.GatewayServer.URL, testQueryPath("queries/abstract_object_mixed.graphql"), nil, t)
Expand All @@ -549,10 +491,7 @@ func TestFederationIntegrationTest(t *testing.T) {
})

t.Run("Abstract interface field", func(t *testing.T) {
setup := federationtesting.NewFederationSetup(addGateway(false))
defer setup.Close()

gqlClient := NewGraphqlClient(http.DefaultClient)
t.Parallel()
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
resp := gqlClient.Query(ctx, setup.GatewayServer.URL, testQueryPath("queries/ab.graphql"), nil, t)
Expand All @@ -561,9 +500,7 @@ func TestFederationIntegrationTest(t *testing.T) {
})

t.Run("Merged fields are still resolved", func(t *testing.T) {
setup := federationtesting.NewFederationSetup(addGateway(false))
t.Cleanup(setup.Close)
gqlClient := NewGraphqlClient(http.DefaultClient)
t.Parallel()
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
resp := gqlClient.Query(ctx, setup.GatewayServer.URL, testQueryPath("queries/merged_field.graphql"), nil, t)
Expand Down
6 changes: 3 additions & 3 deletions execution/federationtesting/gateway/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ func Handler(
httpClient *http.Client,
enableART bool,
) *Gateway {
upgrader := &ws.DefaultHTTPUpgrader
upgrader.Header = http.Header{}
// upgrader.Header.Add("Sec-Websocket-Protocol", "graphql-ws")
upgrader := &ws.HTTPUpgrader{
Header: http.Header{},
}

datasourceWatcher := datasourcePoller

Expand Down
Loading