@@ -75,30 +75,26 @@ public class CayenneTestsEnv implements BeforeEachCallback, AfterEachCallback {
7575 COMMON_SCHEMA .rebuildSchema ();
7676 }
7777
78+ public static CayenneTestsEnv forProject (String project ) {
79+ // Soft refs by default instead of weak — avoids GC-sensitive test flakiness.
80+ return new CayenneTestsEnv (project , new Module [0 ], true , "soft" );
81+ }
82+
7883 private final String project ;
7984 private final Module [] extraModules ;
8085 private final boolean autoClean ;
8186 private final String retainStrategy ;
8287
83- // single-test scoped vars
84- private DataContext context ;
85- private DbHelper dbHelper ;
86- private DbCleaner dbCleaner ;
87- private CayenneRuntime runtime ;
88- private TestDbAdapter testDbAdapter ;
88+ // created in beforeEach, discarded in afterEach
89+ private TestScope scope ;
8990
9091 private CayenneTestsEnv (String project , Module [] extraModules , boolean autoClean , String retainStrategy ) {
9192 this .project = Objects .requireNonNull (project );
9293 this .extraModules = extraModules ;
9394 this .autoClean = autoClean ;
9495 this .retainStrategy = retainStrategy ;
9596 }
96-
97- public static CayenneTestsEnv forProject (String project ) {
98- // Soft refs by default instead of weak — avoids GC-sensitive test flakiness.
99- return new CayenneTestsEnv (project , new Module [0 ], true , "soft" );
100- }
101-
97+
10298 public CayenneTestsEnv withExtraModules (Module ... modules ) {
10399 return new CayenneTestsEnv (project , modules , autoClean , retainStrategy );
104100 }
@@ -113,38 +109,36 @@ public CayenneTestsEnv withWeakReferences() {
113109
114110 @ Override
115111 public void beforeEach (ExtensionContext ctx ) {
116- this . runtime = buildRuntime ();
117- this . context = (DataContext ) runtime .newContext ();
112+ CayenneRuntime runtime = buildRuntime ();
113+ DataContext context = (DataContext ) runtime .newContext ();
118114
119115 DbAdapter firstAdapter = runtime .getDataDomain ().getDataNodes ().iterator ().next ().getAdapter ();
120- this . testDbAdapter = TestDbAdapter .of (firstAdapter );
116+ TestDbAdapter testDbAdapter = TestDbAdapter .of (firstAdapter );
121117 tweakProcedures (runtime , testDbAdapter );
122118
123- this . dbHelper = new FlavorAwareDbHelper (
119+ DbHelper dbHelper = new FlavorAwareDbHelper (
124120 COMMON_SCHEMA .dataSource (),
125121 firstAdapter .getQuotingStrategy (),
126122 context .getEntityResolver ().getDataMaps ().iterator ().next ());
127123
128- this . dbCleaner = new DbCleaner (
124+ DbCleaner dbCleaner = new DbCleaner (
129125 COMMON_SCHEMA ,
130126 dbHelper ,
131127 context .getEntityResolver ().getDataMaps ().stream ().map (DataMap ::getName ).collect (Collectors .toSet ()));
132128
129+ this .scope = new TestScope (runtime , context , testDbAdapter , dbHelper , dbCleaner );
130+
133131 if (autoClean ) {
134- dbCleaner .clean ();
132+ scope .clean ();
135133 }
136134 }
137135
138136 @ Override
139137 public void afterEach (ExtensionContext ctx ) {
140- if (runtime != null ) {
141- runtime .shutdown ();
138+ if (scope != null ) {
139+ scope .shutdown ();
140+ this .scope = null ;
142141 }
143- this .context = null ;
144- this .dbHelper = null ;
145- this .dbCleaner = null ;
146- this .runtime = null ;
147- this .testDbAdapter = null ;
148142 }
149143
150144 private CayenneRuntime buildRuntime () {
@@ -170,47 +164,63 @@ private static void tweakProcedures(CayenneRuntime runtime, TestDbAdapter adapte
170164 }
171165
172166 public DataContext context () {
173- return context ;
167+ return scope . context () ;
174168 }
175169
176170 public TableHelper table (String tableName , String ... columns ) {
177- return new TableHelper (dbHelper , tableName , columns );
171+ return new TableHelper (scope . dbHelper () , tableName , columns );
178172 }
179173
180174 public CayenneRuntime runtime () {
181- return runtime ;
175+ return scope . runtime () ;
182176 }
183177
184178 public TestDbAdapter testDbAdapter () {
185- return testDbAdapter ;
179+ return scope . testDbAdapter () ;
186180 }
187181
188182 public EntityResolver entityResolver () {
189- return runtime .getDataDomain ().getEntityResolver ();
183+ return scope . runtime () .getDataDomain ().getEntityResolver ();
190184 }
191185
192186 public DataNode dataNode () {
193- DataDomain channel = runtime .getDataDomain ();
187+ DataDomain channel = scope . runtime () .getDataDomain ();
194188 return channel .getDataNodes ().iterator ().next ();
195189 }
196190
197191 public void runWithQueriesBlocked (Runnable task ) {
198- TestTelemetry .runWithQueriesBlocked (runtime , task );
192+ TestTelemetry .runWithQueriesBlocked (scope . runtime () , task );
199193 }
200194
201195 public int runWithQueryCounter (Runnable task ) {
202- return TestTelemetry .runWithQueryCounter (runtime , task );
196+ return TestTelemetry .runWithQueryCounter (scope . runtime () , task );
203197 }
204198
205199 public AdhocObjectFactory adhocObjectFactory () {
206- return runtime .getInjector ().getInstance (AdhocObjectFactory .class );
200+ return scope . runtime () .getInjector ().getInstance (AdhocObjectFactory .class );
207201 }
208202
209203 public DbCleaner dbCleaner () {
210- return dbCleaner ;
204+ return scope . dbCleaner () ;
211205 }
212206
213207 public SQLTemplateCustomizer sqlTemplateCustomizer () {
214208 return SQLTemplateCustomizer .of (dataNode ().getAdapter ());
215209 }
210+
211+ private record TestScope (
212+ CayenneRuntime runtime ,
213+ DataContext context ,
214+ TestDbAdapter testDbAdapter ,
215+ DbHelper dbHelper ,
216+ DbCleaner dbCleaner ) {
217+
218+ void clean () {
219+ dbCleaner .clean ();
220+ }
221+
222+ void shutdown () {
223+ runtime .shutdown ();
224+ }
225+ }
216226}
0 commit comments