Skip to content

Commit acf8866

Browse files
smyrickShane Myrick
and
Shane Myrick
authored
Reduce number of class scanners created in tests (#646)
In an attempt to fix the out of memory errors, I simplified some of our unit tests to create few ClassScanners and SchemaGenerators, and close all usages of the ones we still have left Co-authored-by: Shane Myrick <[email protected]>
1 parent 20e512b commit acf8866

File tree

9 files changed

+57
-56
lines changed

9 files changed

+57
-56
lines changed

graphql-kotlin-schema-generator/src/main/kotlin/com/expediagroup/graphql/generator/SchemaGenerator.kt

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ import kotlin.reflect.full.createType
4242
*/
4343
open class SchemaGenerator(internal val config: SchemaGeneratorConfig) : Closeable {
4444

45-
internal val additionalTypes = mutableSetOf<KType>()
45+
internal val additionalTypes: MutableSet<KType> = mutableSetOf()
4646
internal val classScanner = ClassScanner(config.supportedPackages)
4747
internal val cache = TypesCache(config.supportedPackages)
4848
internal val codeRegistry = GraphQLCodeRegistry.newCodeRegistry()
@@ -66,11 +66,8 @@ open class SchemaGenerator(internal val config: SchemaGeneratorConfig) : Closeab
6666
builder.additionalTypes(generateAdditionalTypes())
6767
builder.additionalDirectives(directives.values.toSet())
6868
builder.codeRegistry(codeRegistry.build())
69-
val schema = config.hooks.willBuildSchema(builder).build()
7069

71-
classScanner.close()
72-
73-
return schema
70+
return config.hooks.willBuildSchema(builder).build()
7471
}
7572

7673
/**
@@ -113,7 +110,7 @@ open class SchemaGenerator(internal val config: SchemaGeneratorConfig) : Closeab
113110
*/
114111
override fun close() {
115112
classScanner.close()
116-
cache.clear()
113+
cache.close()
117114
additionalTypes.clear()
118115
directives.clear()
119116
}

graphql-kotlin-schema-generator/src/main/kotlin/com/expediagroup/graphql/generator/state/TypesCache.kt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,13 @@ import com.expediagroup.graphql.generator.extensions.qualifiedName
2525
import graphql.schema.GraphQLNamedType
2626
import graphql.schema.GraphQLType
2727
import graphql.schema.GraphQLTypeReference
28+
import java.io.Closeable
2829
import kotlin.reflect.KClass
2930
import kotlin.reflect.KType
3031
import kotlin.reflect.full.isSubclassOf
3132
import kotlin.reflect.full.starProjectedType
3233

33-
internal class TypesCache(private val supportedPackages: List<String>) {
34+
internal class TypesCache(private val supportedPackages: List<String>) : Closeable {
3435

3536
private val cache: MutableMap<String, KGraphQLType> = mutableMapOf()
3637
private val typesUnderConstruction: MutableSet<TypesCacheKey> = mutableSetOf()
@@ -64,9 +65,12 @@ internal class TypesCache(private val supportedPackages: List<String>) {
6465
}
6566

6667
/**
67-
* Clear the map of all saved values
68+
* Clear the cache of all saved values
6869
*/
69-
internal fun clear() = cache.clear()
70+
override fun close() {
71+
cache.clear()
72+
typesUnderConstruction.clear()
73+
}
7074

7175
internal fun doesNotContainGraphQLType(graphQLType: GraphQLNamedType) =
7276
cache.none { (_, v) -> v.graphQLType.name == graphQLType.name }

graphql-kotlin-schema-generator/src/test/kotlin/com/expediagroup/graphql/generator/ToSchemaTest.kt

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,13 @@ class ToSchemaTest {
7272
@Test
7373
fun `SchemaGenerator generates a simple GraphQL schema with default builder`() {
7474
val schemaGenerator = SchemaGenerator(testSchemaConfig)
75-
val schema = schemaGenerator.generateSchema(
76-
queries = listOf(TopLevelObject(QueryObject())),
77-
mutations = listOf(TopLevelObject(MutationObject())),
78-
subscriptions = emptyList()
79-
)
75+
val schema = schemaGenerator.use {
76+
it.generateSchema(
77+
queries = listOf(TopLevelObject(QueryObject())),
78+
mutations = listOf(TopLevelObject(MutationObject())),
79+
subscriptions = emptyList()
80+
)
81+
}
8082

8183
val graphQL = GraphQL.newGraphQL(schema).build()
8284

graphql-kotlin-schema-generator/src/test/kotlin/com/expediagroup/graphql/generator/state/ClassScannerTest.kt

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package com.expediagroup.graphql.generator.state
1818

19+
import com.expediagroup.graphql.defaultSupportedPackages
20+
import org.junit.jupiter.api.AfterAll
1921
import org.junit.jupiter.api.Test
2022
import kotlin.test.assertEquals
2123

@@ -59,54 +61,53 @@ internal class ClassScannerTest {
5961
@SimpleAnnotation
6062
private class MyClassWithAnnotaiton
6163

64+
private val basicClassScanner = ClassScanner(defaultSupportedPackages)
65+
6266
@Test
6367
fun `valid subtypes`() {
64-
val classScanner = ClassScanner(listOf("com.expediagroup.graphql"))
65-
val list = classScanner.getSubTypesOf(MyInterface::class)
66-
68+
val list = basicClassScanner.getSubTypesOf(MyInterface::class)
6769
assertEquals(expected = 2, actual = list.size)
6870
}
6971

7072
@Test
7173
fun `abstract subtypes`() {
72-
val classScanner = ClassScanner(listOf("com.expediagroup.graphql"))
73-
val list = classScanner.getSubTypesOf(MyAbstractClass::class)
74-
74+
val list = basicClassScanner.getSubTypesOf(MyAbstractClass::class)
7575
assertEquals(expected = 1, actual = list.size)
7676
}
7777

7878
@Test
7979
fun `subtypes of non-supported packages`() {
80-
val classScanner = ClassScanner(listOf("com.example"))
81-
val list = classScanner.getSubTypesOf(MyInterface::class)
82-
80+
val classScannerOfOtherPackages = ClassScanner(listOf("com.example"))
81+
val list = classScannerOfOtherPackages.getSubTypesOf(MyInterface::class)
8382
assertEquals(expected = 0, actual = list.size)
83+
classScannerOfOtherPackages.close()
8484
}
8585

8686
@Test
8787
fun `interface with no subtypes`() {
88-
val classScanner = ClassScanner(listOf("com.expediagroup.graphql"))
89-
val list = classScanner.getSubTypesOf(NoSubTypesInterface::class)
90-
88+
val list = basicClassScanner.getSubTypesOf(NoSubTypesInterface::class)
9189
assertEquals(expected = 0, actual = list.size)
9290
}
9391

9492
@Test
9593
fun `abstract class with no subtypes`() {
96-
val classScanner = ClassScanner(listOf("com.expediagroup.graphql"))
97-
val list = classScanner.getSubTypesOf(NoSubTypesClass::class)
98-
94+
val list = basicClassScanner.getSubTypesOf(NoSubTypesClass::class)
9995
assertEquals(expected = 0, actual = list.size)
10096
}
10197

10298
@Test
10399
fun `classes with annotation returns all values`() {
104-
val classScanner = ClassScanner(listOf("com.expediagroup.graphql.generator"))
105-
106-
val invalidClasses = classScanner.getClassesWithAnnotation(OtherSimpleAnnotation::class)
100+
val invalidClasses = basicClassScanner.getClassesWithAnnotation(OtherSimpleAnnotation::class)
107101
assertEquals(0, invalidClasses.size)
108102

109-
val validClasses = classScanner.getClassesWithAnnotation(SimpleAnnotation::class)
103+
val validClasses = basicClassScanner.getClassesWithAnnotation(SimpleAnnotation::class)
110104
assertEquals(1, validClasses.size)
111105
}
106+
107+
companion object {
108+
@AfterAll
109+
fun afterAll(classScannerTest: ClassScannerTest) {
110+
classScannerTest.basicClassScanner.close()
111+
}
112+
}
112113
}

graphql-kotlin-schema-generator/src/test/kotlin/com/expediagroup/graphql/generator/types/GenerateDirectiveTest.kt

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import com.expediagroup.graphql.generator.SchemaGenerator
2222
import com.expediagroup.graphql.generator.extensions.isTrue
2323
import com.expediagroup.graphql.getTestSchemaConfigWithMockedDirectives
2424
import com.expediagroup.graphql.test.utils.SimpleDirective
25-
import org.junit.jupiter.api.BeforeEach
25+
import org.junit.jupiter.api.AfterAll
2626
import org.junit.jupiter.api.Test
2727
import kotlin.reflect.KClass
2828
import kotlin.test.assertEquals
@@ -77,12 +77,7 @@ internal class GenerateDirectiveTest {
7777
val noDirective: String
7878
)
7979

80-
private lateinit var basicGenerator: SchemaGenerator
81-
82-
@BeforeEach
83-
fun setUp() {
84-
basicGenerator = SchemaGenerator(getTestSchemaConfigWithMockedDirectives())
85-
}
80+
private val basicGenerator = SchemaGenerator(getTestSchemaConfigWithMockedDirectives())
8681

8782
@Test
8883
fun `no annotation`() {
@@ -182,4 +177,11 @@ internal class GenerateDirectiveTest {
182177
val noPrefixResult = generateDirectives(basicGenerator, MyClassWithConstructorArgs::noPrefix, null)
183178
assertEquals(expected = 0, actual = noPrefixResult.size)
184179
}
180+
181+
companion object {
182+
@AfterAll
183+
fun cleanUp(generateDirectiveTest: GenerateDirectiveTest) {
184+
generateDirectiveTest.basicGenerator.close()
185+
}
186+
}
185187
}

graphql-kotlin-schema-generator/src/test/kotlin/com/expediagroup/graphql/generator/types/GeneratePropertyTest.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,5 +207,6 @@ internal class GeneratePropertyTest : TypeTestHelper() {
207207
val targetDataFetcher = localGenerator.codeRegistry.getDataFetcher(coordinates, result)
208208
assertFalse(targetDataFetcher is PropertyDataFetcher)
209209
assertEquals(expected = mockDataFetcher, actual = targetDataFetcher)
210+
localGenerator.close()
210211
}
211212
}

graphql-kotlin-schema-generator/src/test/kotlin/com/expediagroup/graphql/generator/types/TypeTestHelper.kt

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import com.expediagroup.graphql.directives.KotlinSchemaDirectiveWiring
2323
import com.expediagroup.graphql.execution.KotlinDataFetcherFactoryProvider
2424
import com.expediagroup.graphql.execution.SimpleKotlinDataFetcherFactoryProvider
2525
import com.expediagroup.graphql.generator.SchemaGenerator
26-
import com.expediagroup.graphql.generator.state.ClassScanner
2726
import com.expediagroup.graphql.hooks.SchemaGeneratorHooks
2827
import io.mockk.every
2928
import io.mockk.spyk
@@ -40,7 +39,6 @@ import org.junit.jupiter.api.TestInstance.Lifecycle
4039
@TestInstance(Lifecycle.PER_CLASS)
4140
open class TypeTestHelper {
4241
private val supportedPackages = listOf("com.expediagroup.graphql")
43-
private val classScanner = ClassScanner(supportedPackages)
4442
private val dataFetcherFactory: KotlinDataFetcherFactoryProvider = SimpleKotlinDataFetcherFactoryProvider()
4543
private val topLevelNames = TopLevelNames(
4644
query = "TestTopLevelQuery",
@@ -62,7 +60,7 @@ open class TypeTestHelper {
6260

6361
generator.additionalTypes.clear()
6462
generator.directives.clear()
65-
generator.cache.clear()
63+
generator.cache.close()
6664

6765
every { config.hooks } returns hooks
6866
every { config.dataFetcherFactoryProvider } returns dataFetcherFactory
@@ -73,7 +71,7 @@ open class TypeTestHelper {
7371

7472
@AfterAll
7573
fun cleanup() {
76-
classScanner.close()
74+
generator.close()
7775
}
7876

7977
open fun beforeTest() {}

graphql-kotlin-spring-server/src/main/kotlin/com/expediagroup/graphql/spring/exception/SimpleKotlinGraphQLError.kt

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,12 @@ open class SimpleKotlinGraphQLError(
3232
) : GraphQLError {
3333
override fun getErrorType(): ErrorClassification = errorType
3434

35-
override fun getExtensions(): Map<String, Any> {
36-
val newExtensions = mutableMapOf<String, Any>()
35+
override fun getExtensions(): Map<String, Any> =
3736
if (exception is GraphQLError && exception.extensions != null) {
38-
newExtensions.putAll(exception.extensions)
37+
exception.extensions
38+
} else {
39+
emptyMap()
3940
}
40-
return newExtensions
41-
}
4241

4342
override fun getLocations(): List<SourceLocation> = locations
4443

graphql-kotlin-spring-server/src/test/kotlin/com/expediagroup/graphql/spring/instrumentation/InstrumentationIT.kt

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,10 @@ class InstrumentationIT(@Autowired private val testClient: WebTestClient) {
4545

4646
class OrderedInstrumentation(private val instrumentationOrder: Int, private val counter: AtomicInteger) : SimpleInstrumentation(), Ordered {
4747
override fun instrumentExecutionResult(executionResult: ExecutionResult, parameters: InstrumentationExecutionParameters): CompletableFuture<ExecutionResult> {
48-
val extensions = mutableMapOf<Any, Any>()
49-
extensions[instrumentationOrder] = counter.getAndIncrement()
50-
val currentExt: Map<Any, Any>? = executionResult.extensions
51-
if (currentExt != null) {
52-
extensions.putAll(currentExt)
53-
}
54-
return CompletableFuture.completedFuture(ExecutionResultImpl(executionResult.getData(), executionResult.errors, extensions))
48+
val currentExt: MutableMap<Any, Any> = executionResult.extensions?.toMutableMap() ?: mutableMapOf()
49+
currentExt[instrumentationOrder] = counter.getAndIncrement()
50+
51+
return CompletableFuture.completedFuture(ExecutionResultImpl(executionResult.getData(), executionResult.errors, currentExt))
5552
}
5653

5754
override fun getOrder(): Int = instrumentationOrder

0 commit comments

Comments
 (0)