-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Change default behavior of @WithTestResource
#42852
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package io.quarkus.test.common; | ||
|
||
/** | ||
* Defines how Quarkus behaves with regard to the application of the resource to this test and the testsuite in general | ||
*/ | ||
public enum TestResourceScope { | ||
|
||
/* | ||
* The declaration order must be from the narrowest scope to the widest | ||
*/ | ||
|
||
/** | ||
* Means that Quarkus will run the test in complete isolation, i.e. it will restart every time it finds such a resource | ||
*/ | ||
RESTRICTED_TO_CLASS, | ||
/** | ||
* Means that Quarkus will not restart when running consecutive tests that use the same resource | ||
*/ | ||
MATCHING_RESOURCE, | ||
|
||
/** | ||
* Means the resource applies to all tests in the testsuite | ||
*/ | ||
GLOBAL | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,11 +13,20 @@ | |
/** | ||
* Used to define a test resource, which can affect various aspects of the application lifecycle. | ||
* <p> | ||
* As of Quarkus 3.16, the default behavior of the annotation (meaning that {@code scope} has not been set) | ||
* is that test classes annotated with the same {@code WithTestResource} will <strong>not</strong> force a restart | ||
* of Quarkus. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe I'm blind but while I see the code to order the restricted to class first, I'm not exactly sure how the tests with the same resources are actually grouped? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are you talking about There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes I'm talking about this specific class. I think someone said it was ordering classes depending on resources and I don't see that in the code. I just see some grouping by if they have per-class test resources. Don't we want to group classes which have similar test resources? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can look into this in a follow up (or maybe @famod can since he wrote the ordering code). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
At a first glimpse I don't see that either. 🤔 It is has been a while, so I'd need some time to look into it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
As this PR is breaking and meant to go into There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yeah, it probably makes sense to have those executed at the beginning or the end of the run, but that's definitely something for after this PR is in. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Given they are supposed to be faster and lower level, let's execute them first. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FYI, I haven't had the time to take a stab at the QuarkusTestProfileAwareClassOrderer change. I might have some time for that by the end of next week. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🙏🏽 |
||
* <p> | ||
* The equivalent behavior to {@code QuarkusTestResource(restrictToAnnotatedClass = false)} is to use | ||
* {@code WithTestResource(scope = TestResourceScope.GLOBAL)}, | ||
* while the equivalent behavior to {@code QuarkusTestResource(restrictToAnnotatedClass = true)} is to use | ||
* {@code WithTestResource(scope = TestResourceScope.RESTRICTED_TO_CLASS)}, | ||
* <p> | ||
* WARNING: this annotation, introduced in 3.13, caused some issues so it was decided to undeprecate | ||
* {@link QuarkusTestResource} and rework the behavior of this annotation. For now, we recommend not using it | ||
* until we improve its behavior. | ||
* <p> | ||
* Note: When using the {@code restrictToAnnotatedClass=true} (which is the default), each test that is annotated | ||
* Note: When using the {@code scope=TestResourceScope.RESTRICTED_TO_CLASS}, each test that is annotated | ||
* with {@code @WithTestResource} will result in the application being re-augmented and restarted (in a similar fashion | ||
* as happens in dev-mode when a change is detected) in order to incorporate the settings configured by the annotation. | ||
* If there are many instances of the annotation used throughout the testsuite, this could result in slow test execution. | ||
|
@@ -28,14 +37,6 @@ | |
* started <b>before</b> <b>any</b> test is run. | ||
* <p> | ||
* Note that test resources are never restarted when running {@code @Nested} test classes. | ||
* <p> | ||
* The only difference with {@link QuarkusTestResource} is that the default value for | ||
* {@link #restrictToAnnotatedClass()} {@code == true}. | ||
* </p> | ||
* <p> | ||
* This means that any resources managed by {@link #value()} apply to an individual test class or test profile, unlike with | ||
* {@link QuarkusTestResource} where a resource applies to all test classes. | ||
* </p> | ||
*/ | ||
@Target(ElementType.TYPE) | ||
@Retention(RetentionPolicy.RUNTIME) | ||
|
@@ -61,15 +62,11 @@ | |
boolean parallel() default false; | ||
|
||
/** | ||
* Whether this annotation should only be enabled if it is placed on the currently running test class or test profile. | ||
* Note that this defaults to true for meta-annotations since meta-annotations are only considered | ||
* for the current test class or test profile. | ||
* <p> | ||
* Note: When this is set to {@code true} (which is the default), the annotation {@code @WithTestResource} will result | ||
* in the application being re-augmented and restarted (in a similar fashion as happens in dev-mode when a change is | ||
* detected) in order to incorporate the settings configured by the annotation. | ||
* Defines how Quarkus behaves with regard to the application of the resource to this test and the test-suite in general. | ||
* The default is {@link TestResourceScope#MATCHING_RESOURCE} which means that if two tests are annotated with the same | ||
* {@link WithTestResource} annotation, no restart will take place between tests. | ||
*/ | ||
boolean restrictToAnnotatedClass() default true; | ||
TestResourceScope scope() default TestResourceScope.MATCHING_RESOURCE; | ||
|
||
@Target(ElementType.TYPE) | ||
@Retention(RetentionPolicy.RUNTIME) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package io.quarkus.test.common; | ||
|
||
import static io.quarkus.test.common.TestResourceManager.testResourcesRequireReload; | ||
import static io.quarkus.test.common.TestResourceScope.*; | ||
import static org.junit.jupiter.api.Assertions.assertFalse; | ||
import static org.junit.jupiter.api.Assertions.assertTrue; | ||
|
||
import java.util.Collections; | ||
import java.util.Set; | ||
|
||
import org.junit.jupiter.api.Test; | ||
|
||
import io.quarkus.test.common.TestResourceManager.TestResourceComparisonInfo; | ||
|
||
public class TestResourceManagerReloadTest { | ||
|
||
@Test | ||
public void emptyResources() { | ||
assertFalse(testResourcesRequireReload(Collections.emptySet(), Set.of())); | ||
} | ||
|
||
@Test | ||
public void differentCount() { | ||
assertTrue(testResourcesRequireReload(Collections.emptySet(), | ||
Set.of(new TestResourceComparisonInfo("test", RESTRICTED_TO_CLASS)))); | ||
|
||
assertTrue(testResourcesRequireReload(Set.of(new TestResourceComparisonInfo("test", RESTRICTED_TO_CLASS)), | ||
Collections.emptySet())); | ||
} | ||
|
||
@Test | ||
public void sameSingleRestrictedToClassResource() { | ||
assertTrue(testResourcesRequireReload( | ||
Set.of(new TestResourceComparisonInfo("test", RESTRICTED_TO_CLASS)), | ||
Set.of(new TestResourceComparisonInfo("test", RESTRICTED_TO_CLASS)))); | ||
} | ||
|
||
@Test | ||
public void sameSingleMatchingResource() { | ||
assertFalse(testResourcesRequireReload( | ||
Set.of(new TestResourceComparisonInfo("test", MATCHING_RESOURCE)), | ||
Set.of(new TestResourceComparisonInfo("test", MATCHING_RESOURCE)))); | ||
} | ||
|
||
@Test | ||
public void differentSingleMatchingResource() { | ||
assertTrue(testResourcesRequireReload( | ||
Set.of(new TestResourceComparisonInfo("test", MATCHING_RESOURCE)), | ||
Set.of(new TestResourceComparisonInfo("test2", MATCHING_RESOURCE)))); | ||
} | ||
|
||
@Test | ||
public void sameMultipleMatchingResource() { | ||
assertFalse(testResourcesRequireReload( | ||
Set.of( | ||
new TestResourceComparisonInfo("test", MATCHING_RESOURCE), | ||
new TestResourceComparisonInfo("test2", MATCHING_RESOURCE), | ||
new TestResourceComparisonInfo("test3", GLOBAL)), | ||
Set.of(new TestResourceComparisonInfo("test3", GLOBAL), | ||
new TestResourceComparisonInfo("test2", MATCHING_RESOURCE), | ||
new TestResourceComparisonInfo("test", MATCHING_RESOURCE)))); | ||
} | ||
|
||
@Test | ||
public void differentMultipleMatchingResource() { | ||
assertTrue(testResourcesRequireReload( | ||
Set.of( | ||
new TestResourceComparisonInfo("test", MATCHING_RESOURCE), | ||
new TestResourceComparisonInfo("test2", MATCHING_RESOURCE), | ||
new TestResourceComparisonInfo("test3", GLOBAL)), | ||
Set.of(new TestResourceComparisonInfo("test3", GLOBAL), | ||
new TestResourceComparisonInfo("test2", MATCHING_RESOURCE), | ||
new TestResourceComparisonInfo("TEST", MATCHING_RESOURCE)))); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same resource or the same set of resources? If the former how do you group to restart the resources less often?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Users can't really influence the order of test execution, but if Quarkus does its job correctly, restarting will be minimized
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How? (for my benefit).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://github.com/quarkusio/quarkus/blob/dcd9928aed836f1b2b4d4a2274bef1b767a97311/test-framework%2Fjunit5%2Fsrc%2Fmain%2Fjava%2Fio%2Fquarkus%2Ftest%2Fjunit%2Futil%2FQuarkusTestProfileAwareClassOrderer.java
We might need to update it a little, but the idea is that we can tell JUnit the order with which tests can be executed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also my question was
@WithTestResource(value={Resource1.class, Resource2.class, Resource3.class})
will it run in the same batch as
@WithTestResource(value={Resource3.class})
what about
@WithTestResource(value={Resource3.class, Resource4.class})
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even if those are executed one after the other, they still force a restart because they don't match
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, thanks. So i'ts not the same resource that matches, it's the exact resource set (or list of resoruces) that matches.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct!