Skip to content

Commit f73d124

Browse files
authored
Merge pull request #666 from graph-gophers/fuzz-test-schema-exec
test: fuzz test schema exec
2 parents 19a4516 + 544066e commit f73d124

File tree

2 files changed

+59
-0
lines changed

2 files changed

+59
-0
lines changed

fuzz_test.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package graphql_test
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
"github.com/graph-gophers/graphql-go"
8+
"github.com/graph-gophers/graphql-go/example/starwars"
9+
)
10+
11+
func FuzzSchemaExec(f *testing.F) {
12+
resolver := &starwars.Resolver{}
13+
opts := []graphql.SchemaOpt{graphql.MaxDepth(3)}
14+
schema, err := graphql.ParseSchema(starwars.Schema, resolver, opts...)
15+
if err != nil {
16+
f.Errorf("ParseSchema: %v", err)
17+
return
18+
}
19+
20+
// Seed the fuzzing corpus with a variety of valid GraphQL queries.
21+
queries := []string{
22+
`{ hero { name } }`,
23+
`{ hero { name appearsIn } }`,
24+
`{ hero { name appearsIn friends { name } } }`,
25+
`{ hero(episode: EMPIRE) { name } }`,
26+
`{ episode(episode: EMPIRE) { title characters { name } reviews { stars commentary } } }`,
27+
`{ episode(episode: EMPIRE) { title characters { name friends { name } reviews { stars commentary } } }`,
28+
`query { episode(episode: EMPIRE) { title characters { name friends { name } } } }`,
29+
`query HeroName { hero { name } }`,
30+
`query HeroNameAndFriends { hero { name friends { name } } }`,
31+
`mutation { createReview(episode: EMPIRE, review: { stars: 5, commentary: "Great!" }) }`,
32+
}
33+
for _, q := range queries {
34+
f.Add(q)
35+
}
36+
37+
f.Fuzz(func(t *testing.T, query string) {
38+
// ignore invalid queries in order to test only the execution against the schema
39+
errs := schema.Validate(query)
40+
if len(errs) > 0 {
41+
t.Skip()
42+
}
43+
44+
res := schema.Exec(context.Background(), query, "", nil)
45+
if res.Data != nil && len(res.Errors) > 0 {
46+
t.Errorf("Exec(%q) returned both data and errors: %v", query, res.Errors)
47+
}
48+
if res.Errors != nil {
49+
t.Logf("Exec(%q) returned errors: %v", query, res.Errors)
50+
}
51+
if res.Data == nil && len(res.Errors) == 0 {
52+
t.Errorf("Exec(%q) returned nil data and no errors", query)
53+
}
54+
})
55+
}

graphql.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,10 @@ func (s *Schema) ValidateWithVariables(queryString string, variables map[string]
233233
return []*errors.QueryError{qErr}
234234
}
235235

236+
if len(doc.Operations) == 0 {
237+
return []*errors.QueryError{errors.Errorf("executable document must contain at least one operation")}
238+
}
239+
236240
return validation.Validate(s.schema, doc, variables, s.maxDepth)
237241
}
238242

0 commit comments

Comments
 (0)