3737import io .quarkus .bootstrap .workspace .SourceDir ;
3838import io .quarkus .bootstrap .workspace .WorkspaceModule ;
3939import io .quarkus .commons .classloading .ClassLoaderHelper ;
40+ import io .quarkus .maven .dependency .DependencyFlags ;
4041import io .quarkus .paths .PathList ;
4142import io .quarkus .runtime .LaunchMode ;
4243import io .quarkus .test .common .PathTestHelper ;
@@ -57,27 +58,14 @@ public class AppMakerHelper {
5758 private static List <Object > testMethodInvokers ;
5859 private Runnable configCleanup ;
5960
60- public static class PrepareResult {
61- protected final AugmentAction augmentAction ;
62- public final QuarkusTestProfile profileInstance ;
63- protected final CuratedApplication curatedApplication ;
64-
65- public PrepareResult (AugmentAction augmentAction , QuarkusTestProfile profileInstance ,
66- CuratedApplication curatedApplication ) {
67-
68- this .augmentAction = augmentAction ;
69- this .profileInstance = profileInstance ;
70- this .curatedApplication = curatedApplication ;
71- }
72- }
73-
7461 public static ApplicationModel getGradleAppModelForIDE (Path projectRoot ) throws IOException , AppModelResolverException {
7562 return System .getProperty (BootstrapConstants .SERIALIZED_TEST_APP_MODEL ) == null
7663 ? BuildToolHelper .enableGradleAppModelForTest (projectRoot )
7764 : null ;
7865 }
7966
80- private PrepareResult createAugmentor (final Class <?> requiredTestClass , String displayName , boolean isContinuousTesting ,
67+ private QuarkusTestPrepareResult createAugmentor (final Class <?> requiredTestClass , String displayName ,
68+ boolean isContinuousTesting ,
8169 CuratedApplication curatedApplication ,
8270 Class <? extends QuarkusTestProfile > profile ,
8371 Collection <Runnable > shutdownTasks ) throws AppModelResolverException , BootstrapException , IOException ,
@@ -86,65 +74,70 @@ private PrepareResult createAugmentor(final Class<?> requiredTestClass, String d
8674 if (curatedApplication == null ) {
8775 curatedApplication = makeCuratedApplication (requiredTestClass , displayName , isContinuousTesting , shutdownTasks );
8876 }
77+
8978 Path testClassLocation = getTestClassesLocation (requiredTestClass , curatedApplication );
9079
9180 // clear the test.url system property as the value leaks into the run when using different profiles
9281 System .clearProperty ("test.url" );
93- Map <String , String > additional = new HashMap <>();
94-
95- QuarkusTestProfile profileInstance = null ;
96- if (profile != null ) {
97-
98- profileInstance = new ClassCoercingTestProfile (profile .getConstructor ()
99- .newInstance ());
100- // TODO we make this twice, also in abstractjvmextension can we streamline that?
101- // TODO We can't get rid of the one here because config needs to be set before augmentation, but maybe we can get rid of it on the test side?
102- additional .putAll (profileInstance .getConfigOverrides ());
103- if (!profileInstance .getEnabledAlternatives ()
104- .isEmpty ()) {
105- additional .put ("quarkus.arc.selected-alternatives" , profileInstance .getEnabledAlternatives ()
106- .stream ()
107- .peek ((c ) -> {
108- try {
109- // TODO is string comparison more efficient?
110- if (!c .isAnnotationPresent ((Class <? extends Annotation >) profile .getClassLoader ()
111- .loadClass (Alternative .class .getName ()))) {
112- throw new RuntimeException (
113- "Enabled alternative " + c + " is not annotated with @Alternative" );
114- }
115- } catch (ClassNotFoundException e ) {
116- throw new RuntimeException (e );
117- }
118- })
119- .map (Class ::getName )
120- .collect (Collectors .joining ("," )));
121- }
122- if (profileInstance .disableApplicationLifecycleObservers ()) {
123- additional .put ("quarkus.arc.test.disable-application-lifecycle-observers" , "true" );
124- }
125- if (profileInstance .getConfigProfile () != null ) {
126- additional .put (LaunchMode .TEST .getProfileKey (), profileInstance .getConfigProfile ());
127- }
128-
129- //we just use system properties for now
130- //it's a lot simpler
131- // TODO this is really ugly, set proper config on the app
132- // Sadly, I don't think #42715 helps, because it kicks in after this code
133- configCleanup = RestorableSystemProperties .setProperties (additional )::close ;
134- }
135-
136- if (curatedApplication
137- .getApplicationModel ().getRuntimeDependencies ().isEmpty ()) {
138- throw new RuntimeException (
139- "The tests were run against a directory that does not contain a Quarkus project. Please ensure that the test is configured to use the proper working directory." );
140- }
14182
14283 // TODO should we do this here, or when we prepare the curated application?
14384 // Or is it needed at all?
14485 Index testClassesIndex = TestClassIndexer .indexTestClasses (testClassLocation );
14586 // we need to write the Index to make it reusable from other parts of the testing infrastructure that run in different ClassLoaders
14687 TestClassIndexer .writeIndex (testClassesIndex , testClassLocation , requiredTestClass );
14788
89+ return getPrepareResult (requiredTestClass , curatedApplication , profile , testClassLocation );
90+ }
91+
92+ private QuarkusTestProfile getQuarkusTestProfile (Class <? extends QuarkusTestProfile > profile )
93+ throws InstantiationException , IllegalAccessException , InvocationTargetException , NoSuchMethodException {
94+ if (profile == null ) {
95+ return null ;
96+ }
97+ final QuarkusTestProfile profileInstance = new ClassCoercingTestProfile (profile .getConstructor ()
98+ .newInstance ());
99+ final Map <String , String > additional = new HashMap <>();
100+ // TODO we make this twice, also in abstractjvmextension can we streamline that?
101+ // TODO We can't get rid of the one here because config needs to be set before augmentation, but maybe we can get rid of it on the test side?
102+ additional .putAll (profileInstance .getConfigOverrides ());
103+ if (!profileInstance .getEnabledAlternatives ()
104+ .isEmpty ()) {
105+ additional .put ("quarkus.arc.selected-alternatives" , profileInstance .getEnabledAlternatives ()
106+ .stream ()
107+ .peek ((c ) -> {
108+ try {
109+ // TODO is string comparison more efficient?
110+ if (!c .isAnnotationPresent ((Class <? extends Annotation >) profile .getClassLoader ()
111+ .loadClass (Alternative .class .getName ()))) {
112+ throw new RuntimeException (
113+ "Enabled alternative " + c + " is not annotated with @Alternative" );
114+ }
115+ } catch (ClassNotFoundException e ) {
116+ throw new RuntimeException (e );
117+ }
118+ })
119+ .map (Class ::getName )
120+ .collect (Collectors .joining ("," )));
121+ }
122+ if (profileInstance .disableApplicationLifecycleObservers ()) {
123+ additional .put ("quarkus.arc.test.disable-application-lifecycle-observers" , "true" );
124+ }
125+ if (profileInstance .getConfigProfile () != null ) {
126+ additional .put (LaunchMode .TEST .getProfileKey (), profileInstance .getConfigProfile ());
127+ }
128+
129+ //we just use system properties for now
130+ //it's a lot simpler
131+ // TODO this is really ugly, set proper config on the app
132+ // Sadly, I don't think #42715 helps, because it kicks in after this code
133+ configCleanup = RestorableSystemProperties .setProperties (additional )::close ;
134+ return profileInstance ;
135+ }
136+
137+ private QuarkusTestPrepareResult getPrepareResult (Class <?> requiredTestClass , CuratedApplication curatedApplication ,
138+ Class <? extends QuarkusTestProfile > profile , Path testClassLocation )
139+ throws InvocationTargetException , InstantiationException , IllegalAccessException , NoSuchMethodException {
140+ QuarkusTestProfile profileInstance = getQuarkusTestProfile (profile );
148141 Timing .staticInitStarted (curatedApplication
149142 .getOrCreateBaseRuntimeClassLoader (),
150143 curatedApplication
@@ -156,12 +149,12 @@ private PrepareResult createAugmentor(final Class<?> requiredTestClass, String d
156149 if (profile != null ) {
157150 props .put (TEST_PROFILE , profile .getName ());
158151 }
159- return new PrepareResult (curatedApplication
152+ return new QuarkusTestPrepareResult (curatedApplication
160153 .createAugmentor (TestBuildChainFunction .class .getName (), props ), profileInstance ,
161154 curatedApplication );
162155 }
163156
164- public CuratedApplication makeCuratedApplication (Class <?> requiredTestClass , String displayName ,
157+ public static CuratedApplication makeCuratedApplication (Class <?> requiredTestClass , String displayName ,
165158 boolean isContinuousTesting ,
166159 Collection <Runnable > shutdownTasks ) throws IOException , AppModelResolverException , BootstrapException {
167160 final PathList .Builder rootBuilder = PathList .builder ();
@@ -255,6 +248,12 @@ public CuratedApplication makeCuratedApplication(Class<?> requiredTestClass, Str
255248 .bootstrap ();
256249 shutdownTasks .add (curatedApplication ::close );
257250
251+ if (!curatedApplication .getApplicationModel ().getDependencies (DependencyFlags .RUNTIME_CP ).iterator ().hasNext ()) {
252+ throw new RuntimeException (
253+ "The tests were run against a directory that does not contain a Quarkus project. Please ensure that the test is configured to use the proper working directory." );
254+
255+ }
256+
258257 // TODO can we consolidate some of this with TestSupport? The code over there is
259258 // final QuarkusBootstrap.Builder bootstrapConfig = curatedApplication.getQuarkusBootstrap().clonedBuilder()
260259 // .setMode(QuarkusBootstrap.Mode.TEST)
@@ -276,14 +275,14 @@ public CuratedApplication makeCuratedApplication(Class<?> requiredTestClass, Str
276275 // Note that curated application cannot be re-used between restarts, so this application
277276 // should have been freshly created
278277 // TODO maybe don't even accept one? is that comment right?
279- public StartupAction getStartupAction (Class testClass , CuratedApplication curatedApplication ,
278+ public StartupAction getStartupAction (Class <?> testClass , CuratedApplication curatedApplication ,
280279 boolean isContinuousTesting , Class profile ) throws AppModelResolverException , BootstrapException , IOException ,
281280 InvocationTargetException , NoSuchMethodException , InstantiationException , IllegalAccessException {
282281
283- Collection <Runnable > shutdownTasks = new HashSet ();
284- PrepareResult result = createAugmentor (testClass , "(QuarkusTest)" , isContinuousTesting , curatedApplication , profile ,
285- shutdownTasks );
286- AugmentAction augmentAction = result .augmentAction ;
282+ Collection <Runnable > shutdownTasks = new HashSet <> ();
283+ final AugmentAction augmentAction = createAugmentor (testClass , "(QuarkusTest)" , isContinuousTesting , curatedApplication ,
284+ profile ,
285+ shutdownTasks ) .augmentAction () ;
287286
288287 try {
289288 StartupAction startupAction = augmentAction .createInitialRuntimeApplication ();
0 commit comments