From b82c7dc17ba26131a2bfab3267ecc7eb382f776e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Crocquesel?=
<88554524+scrocquesel@users.noreply.github.com>
Date: Thu, 23 Feb 2023 20:09:34 +0100
Subject: [PATCH] Add support for repeatable annotation-based test resources
---
.../asciidoc/getting-started-testing.adoc | 24 ++++++++
.../common/QuarkusTestResourceRepeatable.java | 24 ++++++++
.../test/common/TestResourceManager.java | 11 ++++
.../test/common/TestResourceManagerTest.java | 56 +++++++++++++++++++
4 files changed, 115 insertions(+)
create mode 100644 test-framework/common/src/main/java/io/quarkus/test/common/QuarkusTestResourceRepeatable.java
diff --git a/docs/src/main/asciidoc/getting-started-testing.adoc b/docs/src/main/asciidoc/getting-started-testing.adoc
index f95460d80e315..aebc5d8f720fd 100644
--- a/docs/src/main/asciidoc/getting-started-testing.adoc
+++ b/docs/src/main/asciidoc/getting-started-testing.adoc
@@ -1187,6 +1187,30 @@ public class KubernetesServerTestResource
}
----
+If you want to make the annotation repeatable, the containing annotation type must be annotated with `@QuarkusTestResourceRepeatable`.
+For example, this would define a repeatable `@WithRepeatableTestResource` annotation.
+
+[source,java]
+----
+@QuarkusTestResource(KubernetesServerTestResource.class)
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+@Repeatable(WithRepeatableTestResource.List.class)
+public @interface WithRepeatableTestResource {
+
+ String key() default "";
+
+ @Target(ElementType.TYPE)
+ @Retention(RetentionPolicy.RUNTIME)
+ @QuarkusTestResourceRepeatable(WithRepeatableTestResource.class)
+ @interface List {
+ WithRepeatableTestResource[] value();
+ }
+}
+----
+
+
+
== Hang Detection
`@QuarkusTest` has support for hang detection to help diagnose any unexpected hangs. If no progress is made for a specified
diff --git a/test-framework/common/src/main/java/io/quarkus/test/common/QuarkusTestResourceRepeatable.java b/test-framework/common/src/main/java/io/quarkus/test/common/QuarkusTestResourceRepeatable.java
new file mode 100644
index 0000000000000..859a863e272e3
--- /dev/null
+++ b/test-framework/common/src/main/java/io/quarkus/test/common/QuarkusTestResourceRepeatable.java
@@ -0,0 +1,24 @@
+package io.quarkus.test.common;
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Used to indicate the type of the repeatable annotation
+ * type annotated with a {@code QuarkusTestResource} annotations.
+ *
+ */
+@Target(ElementType.ANNOTATION_TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface QuarkusTestResourceRepeatable {
+
+ /**
+ * @return The class annotated with a {@code QuarkusTestResource} annotations.
+ */
+ Class extends Annotation> value();
+}
diff --git a/test-framework/common/src/main/java/io/quarkus/test/common/TestResourceManager.java b/test-framework/common/src/main/java/io/quarkus/test/common/TestResourceManager.java
index 05fcffc736e64..72b98a7f9764e 100644
--- a/test-framework/common/src/main/java/io/quarkus/test/common/TestResourceManager.java
+++ b/test-framework/common/src/main/java/io/quarkus/test/common/TestResourceManager.java
@@ -335,6 +335,17 @@ private void collectMetaAnnotations(Class> testClassFromTCCL, Function props = manager.start();
+ Assertions.assertEquals("value", props.get("annotationkey1"));
+ Assertions.assertEquals("value", props.get("annotationkey2"));
+ }
+
+ public static class AnnotationBasedQuarkusTestResource
+ implements QuarkusTestResourceConfigurableLifecycleManager {
+
+ private String key;
+
+ @Override
+ public void init(WithAnnotationBasedTestResource annotation) {
+ this.key = annotation.key();
+ }
+
+ @Override
+ public Map start() {
+ Map props = new HashMap<>();
+ props.put(key, "value");
+ return props;
+ }
+
+ @Override
+ public void stop() {
+ }
+ }
+
+ @QuarkusTestResource(AnnotationBasedQuarkusTestResource.class)
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target(ElementType.TYPE)
+ @Repeatable(WithAnnotationBasedTestResource.List.class)
+ public @interface WithAnnotationBasedTestResource {
+ String key() default "";
+
+ @Target(ElementType.TYPE)
+ @Retention(RetentionPolicy.RUNTIME)
+ @QuarkusTestResourceRepeatable(WithAnnotationBasedTestResource.class)
+ @interface List {
+ WithAnnotationBasedTestResource[] value();
+ }
+ }
+
+ @WithAnnotationBasedTestResource(key = "annotationkey1")
+ @WithAnnotationBasedTestResource(key = "annotationkey2")
+ public static class RepeatableAnnotationBasedTestResourcesTest {
+ }
}