@@ -3,6 +3,7 @@ package graphql.introspection
33import graphql.ExecutionInput
44import graphql.ExecutionResult
55import graphql.TestUtil
6+ import graphql.execution.AbortExecutionException
67import graphql.execution.CoercedVariables
78import graphql.language.Document
89import graphql.normalized.ExecutableNormalizedOperationFactory
@@ -15,6 +16,7 @@ class GoodFaithIntrospectionInstrumentationTest extends Specification {
1516 def setup () {
1617 GoodFaithIntrospection . enabledJvmWide(true )
1718 }
19+
1820 def cleanup () {
1921 GoodFaithIntrospection . enabledJvmWide(true )
2022 }
@@ -23,11 +25,11 @@ class GoodFaithIntrospectionInstrumentationTest extends Specification {
2325
2426 when :
2527 Document document = TestUtil . toDocument(IntrospectionQuery . INTROSPECTION_QUERY )
26- def eno = ExecutableNormalizedOperationFactory . createExecutableNormalizedOperation(graphql. getGraphQLSchema(),document,
27- " IntrospectionQuery" , CoercedVariables . emptyVariables())
28+ def eno = ExecutableNormalizedOperationFactory . createExecutableNormalizedOperation(graphql. getGraphQLSchema(), document,
29+ " IntrospectionQuery" , CoercedVariables . emptyVariables())
2830
2931 then :
30- eno. getOperationFieldCount() < GoodFaithIntrospection . GOOD_FAITH_MAX_FIELDS_COUNT // currently 62
32+ eno. getOperationFieldCount() < GoodFaithIntrospection . GOOD_FAITH_MAX_FIELDS_COUNT // currently 189
3133 eno. getOperationDepth() < GoodFaithIntrospection . GOOD_FAITH_MAX_DEPTH_COUNT // currently 13
3234 }
3335
@@ -89,7 +91,7 @@ class GoodFaithIntrospectionInstrumentationTest extends Specification {
8991 a1: __type(name : "t") { name }
9092 a2 : __type(name : "t1") { name }
9193 }
92- """ | _
94+ """ | _
9395 // a case for schema repeated - dont ask twice
9496 """ query badActor {
9597 __schema { types { name} }
@@ -101,7 +103,7 @@ class GoodFaithIntrospectionInstrumentationTest extends Specification {
101103 a1: __schema { types { name} }
102104 a2 : __schema { types { name} }
103105 }
104- """ | _
106+ """ | _
105107
106108 }
107109
@@ -161,4 +163,70 @@ class GoodFaithIntrospectionInstrumentationTest extends Specification {
161163 ! er. errors. isEmpty()
162164 er. errors[0 ] instanceof GoodFaithIntrospection.BadFaithIntrospectionError
163165 }
166+
167+ def " can stop deep queries" () {
168+
169+ when :
170+ def query = createDeepQuery(depth)
171+ def then = System . currentTimeMillis()
172+ ExecutionResult er = graphql. execute(query)
173+ def ms = System . currentTimeMillis()- then
174+
175+ then :
176+ ! er. errors. isEmpty()
177+ er. errors[0 ]. class == targetError
178+ er. data == null // it stopped hard - it did not continue to normal business
179+ println " Took " + ms + " ms"
180+
181+ where :
182+ depth | targetError
183+ 2 | GoodFaithIntrospection.BadFaithIntrospectionError . class
184+ 10 | AbortExecutionException . class
185+ 15 | AbortExecutionException . class
186+ 20 | AbortExecutionException . class
187+ 25 | AbortExecutionException . class
188+ 50 | AbortExecutionException . class
189+ 100 | AbortExecutionException . class
190+ }
191+
192+ String createDeepQuery (int depth = 25 ) {
193+ def result = """
194+ query test {
195+ __schema {
196+ types {
197+ ...F1
198+ }
199+ }
200+ }
201+ """
202+ for (int i = 1 ; i < depth; i++ ) {
203+ result + = """
204+ fragment F$i on __Type {
205+ fields {
206+ type {
207+ ...F${ i + 1}
208+ }
209+ }
210+
211+ ofType {
212+ ...F${ i + 1}
213+ }
214+ }
215+
216+
217+ """
218+ }
219+ result + = """
220+ fragment F$depth on __Type {
221+ fields {
222+ type {
223+ name
224+ }
225+ }
226+ }
227+
228+
229+ """
230+ return result
231+ }
164232}
0 commit comments