diff --git a/docs/mp/testing/01_testing.adoc b/docs/mp/testing/01_testing.adoc
index ed1c0901a..a693454ec 100644
--- a/docs/mp/testing/01_testing.adoc
+++ b/docs/mp/testing/01_testing.adoc
@@ -41,6 +41,11 @@ A test can be annotated with `io.helidon.microprofile.tests.junit5.HelidonTest`
CDI test. This annotation will start the CDI container before any test method is invoked, and stop it after
the last method is invoked. This annotation also enables injection into the test class itself.
+The annotations described in this section are inherited (for the non-repeatable ones), and additive (for repeatable).
+So if you declare `@DisableDiscovery` on abstract class, all implementations will have discovery disabled, unless you
+annotate the implementation class with `@DisableDiscovery(false)`.
+If you declare `@AddBean` on both abstract class and implementation class, both beans will be added.
+
In addition to this simplification, the following annotations are supported:
- `io.helidon.microprofile.tests.junit5.AddBean` - to add one or more beans to the container
@@ -49,6 +54,7 @@ In addition to this simplification, the following annotations are supported:
(if not added through service loader, or when discovery is disabled)
- `io.helidon.microprofile.tests.junit5.AddConfig` - to add one or more configuration properties to MicroProfile config
without the need of creating a `microprofile-config.properties` file
+- `io.helidon.microprofile.tests.junit5.DisableDiscovery` - to disable automated discovery of beans and extensions
[source,java]
.Code sample
@@ -84,10 +90,23 @@ This will change the behavior as follows:
== Usage - configuration
In addition to the `@AddConfig` annotation, you can also use
- `@Configuration`.
+ `@Configuration` to configure additional classpath properties config sources using `configSources`, and to
+mark that a custom configuration is desired.
+You can set up config in `@BeforeAll` method and register it with `ConfigProviderResolver` using MP Config APIs, and declare
+`@Configuration(useExisting=true)`.
+Note that this is not compatible with repeatable tests that use method sources that access CDI, as we must delay the CDI
+startup to the test class instantiation (which is too late, as the method sources are already invoked by this time).
-This allows you to do the following:
+*If you want to use method sources that use CDI with repeatable tests, please do not use `@Configuration(useExisting=true)`*
-- when `useExisting` is set to `true`, the configuration will not be changed
- and current MP configuration will be used
-- you can configure additional classpath properties config sources using `configSources`
\ No newline at end of file
+== Usage - added parameters and injection types
+The following types are available for injection (when a single CDI container is used per test class):
+
+- `WebTarget` - a JAX-RS client's target configured for the current hostname and port when `helidon-micorprofile-server` is on
+ the classpath
+
+The following types are available as method parameters (in any type of Helidon tests):
+
+- `WebTarget` - a JAX-RS client's target configured for the current hostname and port when `helidon-micorprofile-server` is on
+ the classpath
+- `SeContainer` - the current container instance
\ No newline at end of file
diff --git a/fault-tolerance/src/test/java/io/helidon/faulttolerance/RetryTest.java b/fault-tolerance/src/test/java/io/helidon/faulttolerance/RetryTest.java
index ce0be4894..72aee3323 100644
--- a/fault-tolerance/src/test/java/io/helidon/faulttolerance/RetryTest.java
+++ b/fault-tolerance/src/test/java/io/helidon/faulttolerance/RetryTest.java
@@ -36,9 +36,8 @@ import org.junit.jupiter.api.Test;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.isOneOf;
import static org.hamcrest.Matchers.contains;
-import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.hamcrest.Matchers.isOneOf;
class RetryTest {
@Test
diff --git a/microprofile/config/pom.xml b/microprofile/config/pom.xml
index 0179203f6..51543ce65 100644
--- a/microprofile/config/pom.xml
+++ b/microprofile/config/pom.xml
@@ -86,5 +86,10 @@
${project.version}
test
+
+ io.helidon.microprofile.tests
+ helidon-microprofile-tests-junit5
+ test
+
diff --git a/microprofile/config/src/test/java/io/helidon/microprofile/config/MpConfigInjectionTest.java b/microprofile/config/src/test/java/io/helidon/microprofile/config/MpConfigInjectionTest.java
index 774670959..f687e9387 100644
--- a/microprofile/config/src/test/java/io/helidon/microprofile/config/MpConfigInjectionTest.java
+++ b/microprofile/config/src/test/java/io/helidon/microprofile/config/MpConfigInjectionTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2020 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,30 +18,23 @@ package io.helidon.microprofile.config;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
-import java.util.Map;
import javax.enterprise.context.Dependent;
-import javax.enterprise.inject.se.SeContainer;
-import javax.enterprise.inject.se.SeContainerInitializer;
-import javax.enterprise.inject.spi.CDI;
-import javax.enterprise.util.AnnotationLiteral;
import javax.inject.Inject;
import javax.inject.Qualifier;
-import io.helidon.config.test.infra.RestoreSystemPropertiesExt;
import io.helidon.microprofile.config.Converters.Ctor;
import io.helidon.microprofile.config.Converters.Of;
import io.helidon.microprofile.config.Converters.Parse;
import io.helidon.microprofile.config.Converters.ValueOf;
+import io.helidon.microprofile.tests.junit5.AddBean;
+import io.helidon.microprofile.tests.junit5.AddConfig;
+import io.helidon.microprofile.tests.junit5.HelidonTest;
import org.eclipse.microprofile.config.inject.ConfigProperty;
-import org.eclipse.microprofile.config.spi.ConfigProviderResolver;
-import org.eclipse.microprofile.config.spi.ConfigSource;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
+import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -51,41 +44,23 @@ import static org.junit.jupiter.api.Assertions.assertAll;
/**
* Unit test for MP config injection.
*/
-@ExtendWith(RestoreSystemPropertiesExt.class)
+@HelidonTest
+@AddConfig(key = "inject.of", value = "of")
+@AddConfig(key = "inject.valueOf", value = "valueOf")
+@AddConfig(key = "inject.parse", value = "parse")
+@AddConfig(key = "inject.ctor", value = "ctor")
+@AddBean(value = MpConfigInjectionTest.Bean.class, scope = Dependent.class)
+@AddBean(value = MpConfigInjectionTest.SubBean.class, scope = Dependent.class)
class MpConfigInjectionTest {
- private static SeContainer container;
+ @Inject
+ private Bean bean;
- @BeforeAll
- static void initClass() {
-
- // Removed use of system properties, as those stay around after test is finished
- ConfigProviderResolver configProvider = ConfigProviderResolver.instance();
-
- configProvider.registerConfig(configProvider.getBuilder()
- .addDefaultSources()
- .withSources(new TestSource())
- .build(),
- Thread.currentThread().getContextClassLoader());
-
-
- // CDI container
- container = SeContainerInitializer.newInstance()
- .addBeanClasses(Bean.class, SubBean.class)
- .initialize();
- }
-
- @AfterAll
- static void destroyClass() {
- if (null != container) {
- container.close();
- }
- }
+ @Inject
+ @Specific
+ private SubBean subBean;
@Test
public void testImplicitConversion() {
-
- Bean bean = CDI.current().select(Bean.class).get();
-
assertAll("Implicit conversion injection",
() -> assertThat("of", bean.of, is(Of.of("of"))),
() -> assertThat("valueOf", bean.valueOf, is(ValueOf.valueOf("valueOf"))),
@@ -96,22 +71,15 @@ class MpConfigInjectionTest {
@Test
public void testImplicitConversionSubclass() {
-
- Bean bean = CDI.current().select(SubBean.class,
- new AnnotationLiteral() {
- }).get();
-
assertAll("Implicit conversion injection",
- () -> assertThat("of", bean.of, is(Of.of("of"))),
- () -> assertThat("valueOf", bean.valueOf, is(ValueOf.valueOf("valueOf"))),
- () -> assertThat("parse", bean.parse, is(Parse.parse("parse"))),
- () -> assertThat("ctor", bean.ctor, is(new Ctor("ctor")))
+ () -> assertThat("of", subBean.of, is(Of.of("of"))),
+ () -> assertThat("valueOf", subBean.valueOf, is(ValueOf.valueOf("valueOf"))),
+ () -> assertThat("parse", subBean.parse, is(Parse.parse("parse"))),
+ () -> assertThat("ctor", subBean.ctor, is(new Ctor("ctor")))
);
}
- @Dependent
public static class Bean {
-
@Inject
@ConfigProperty(name = "inject.of")
public Of of;
@@ -131,36 +99,11 @@ class MpConfigInjectionTest {
@Qualifier
@Retention(RUNTIME)
- @Target(TYPE)
+ @Target({TYPE, FIELD})
public @interface Specific {
}
- @Dependent
@Specific
public static class SubBean extends Bean {
}
-
- private static class TestSource implements ConfigSource {
- private final Map properties = Map.of(
- "inject.of", "of",
- "inject.valueOf", "valueOf",
- "inject.parse", "parse",
- "inject.ctor", "ctor"
- );
-
- @Override
- public Map getProperties() {
- return properties;
- }
-
- @Override
- public String getValue(String propertyName) {
- return properties.get(propertyName);
- }
-
- @Override
- public String getName() {
- return getClass().getName();
- }
- }
}
diff --git a/microprofile/config/src/test/java/io/helidon/microprofile/config/MutableMpTest.java b/microprofile/config/src/test/java/io/helidon/microprofile/config/MutableMpTest.java
index 4cdc273bf..b72950bec 100644
--- a/microprofile/config/src/test/java/io/helidon/microprofile/config/MutableMpTest.java
+++ b/microprofile/config/src/test/java/io/helidon/microprofile/config/MutableMpTest.java
@@ -22,22 +22,25 @@ import java.util.function.BiConsumer;
import javax.enterprise.context.Dependent;
import javax.enterprise.inject.se.SeContainer;
-import javax.enterprise.inject.se.SeContainerInitializer;
-import javax.enterprise.inject.spi.CDI;
import javax.inject.Inject;
+import io.helidon.microprofile.tests.junit5.AddBean;
+import io.helidon.microprofile.tests.junit5.Configuration;
+import io.helidon.microprofile.tests.junit5.HelidonTest;
+
import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.eclipse.microprofile.config.spi.ConfigProviderResolver;
import org.eclipse.microprofile.config.spi.ConfigSource;
-import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
-public class MutableMpTest {
- private static SeContainer container;
+@HelidonTest
+@Configuration(useExisting = true)
+@AddBean(value = MutableMpTest.Bean.class, scope = Dependent.class)
+class MutableMpTest {
private static MutableSource source;
@BeforeAll
@@ -50,35 +53,21 @@ public class MutableMpTest {
.withSources(source)
.build(),
Thread.currentThread().getContextClassLoader());
-
- // CDI container
- container = SeContainerInitializer.newInstance()
- .addBeanClasses(Bean.class)
- .initialize();
- }
-
- @AfterAll
- static void destroyClass() {
- if (null != container) {
- container.close();
- }
- source = null;
}
@Test
- public void testMutable() {
- Bean bean = CDI.current().select(Bean.class).get();
+ public void testMutable(SeContainer cdi) {
+ Bean bean = cdi.select(Bean.class).get();
assertThat(bean.value, is("initial"));
source.setValue("updated");
- bean = CDI.current().select(Bean.class).get();
+ bean = cdi.select(Bean.class).get();
assertThat(bean.value, is("updated"));
}
- @Dependent
public static class Bean {
@Inject
@ConfigProperty(name = "value")
diff --git a/microprofile/cors/pom.xml b/microprofile/cors/pom.xml
index 9f5060a7c..138d201cc 100644
--- a/microprofile/cors/pom.xml
+++ b/microprofile/cors/pom.xml
@@ -71,5 +71,10 @@
helidon-microprofile-server
test
+
+ io.helidon.microprofile.tests
+ helidon-microprofile-tests-junit5
+ test
+
diff --git a/microprofile/cors/src/test/java/io/helidon/microprofile/cors/CrossOriginTest.java b/microprofile/cors/src/test/java/io/helidon/microprofile/cors/CrossOriginTest.java
index 52e26e2a1..0e1232b8c 100644
--- a/microprofile/cors/src/test/java/io/helidon/microprofile/cors/CrossOriginTest.java
+++ b/microprofile/cors/src/test/java/io/helidon/microprofile/cors/CrossOriginTest.java
@@ -16,26 +16,23 @@
package io.helidon.microprofile.cors;
-import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.RequestScoped;
+import javax.inject.Inject;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.HttpMethod;
import javax.ws.rs.OPTIONS;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
-import javax.ws.rs.client.Client;
-import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
-import javax.ws.rs.core.Application;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
-import java.util.Set;
-import io.helidon.microprofile.server.Server;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
+import io.helidon.microprofile.tests.junit5.AddBean;
+import io.helidon.microprofile.tests.junit5.AddConfig;
+import io.helidon.microprofile.tests.junit5.HelidonTest;
+
import org.junit.jupiter.api.Test;
import static io.helidon.common.http.Http.Header.ORIGIN;
@@ -54,42 +51,22 @@ import static org.hamcrest.MatcherAssert.assertThat;
/**
* Class CrossOriginTest.
*/
-public class CrossOriginTest {
-
- private static Client client;
- private static Server server;
- private static WebTarget target;
+@HelidonTest
+@AddBean(CrossOriginTest.CorsResource0.class)
+@AddBean(CrossOriginTest.CorsResource1.class)
+@AddBean(CrossOriginTest.CorsResource2.class)
+@AddBean(CrossOriginTest.CorsResource3.class)
+@AddConfig(key = "cors.paths.0.path-pattern", value = "/cors3")
+@AddConfig(key = "cors.paths.0.allow-origins", value = "http://foo.bar, http://bar.foo")
+@AddConfig(key = "cors.paths.0.allow-methods", value = "DELETE, PUT")
+class CrossOriginTest {
+ @Inject
+ private WebTarget target;
static {
System.setProperty("sun.net.http.allowRestrictedHeaders", "true");
}
- @BeforeAll
- static void initClass() {
- server = Server.builder()
- .addApplication("/app", new CorsApplication())
- .build();
- server.start();
- client = ClientBuilder.newClient();
- target = client.target("http://localhost:" + server.port());
- }
-
- @AfterAll
- static void destroyClass() {
- server.stop();
- client.close();
- }
-
- @ApplicationScoped
- static public class CorsApplication extends Application {
-
- @Override
- public Set> getClasses() {
- return Set.of(CorsResource0.class, CorsResource1.class, CorsResource2.class, CorsResource3.class);
- }
- }
-
- @RequestScoped
@Path("/cors1")
static public class CorsResource1 {
@@ -134,7 +111,7 @@ public class CrossOriginTest {
}
@RequestScoped
- @Path("/cors3") // Configured in META-INF/microprofile-config.properties
+ @Path("/cors3")
static public class CorsResource3 {
@DELETE
@@ -178,7 +155,7 @@ public class CrossOriginTest {
@Test
void test1PreFlightAllowedOrigin() {
- Response res = target.path("/app/cors1")
+ Response res = target.path("/cors1")
.request()
.header(ORIGIN, "http://foo.bar")
.header(ACCESS_CONTROL_REQUEST_METHOD, "PUT")
@@ -192,7 +169,7 @@ public class CrossOriginTest {
@Test
void test1PreFlightAllowedHeaders1() {
- Response res = target.path("/app/cors1")
+ Response res = target.path("/cors1")
.request()
.header(ORIGIN, "http://foo.bar")
.header(ACCESS_CONTROL_REQUEST_METHOD, "PUT")
@@ -207,7 +184,7 @@ public class CrossOriginTest {
@Test
void test1PreFlightAllowedHeaders2() {
- Response res = target.path("/app/cors1")
+ Response res = target.path("/cors1")
.request()
.header(ORIGIN, "http://foo.bar")
.header(ACCESS_CONTROL_REQUEST_METHOD, "PUT")
@@ -225,7 +202,7 @@ public class CrossOriginTest {
@Test
void test2PreFlightForbiddenOrigin() {
- Response res = target.path("/app/cors2")
+ Response res = target.path("/cors2")
.request()
.header(ORIGIN, "http://not.allowed")
.header(ACCESS_CONTROL_REQUEST_METHOD, "PUT")
@@ -235,7 +212,7 @@ public class CrossOriginTest {
@Test
void test2PreFlightAllowedOrigin() {
- Response res = target.path("/app/cors2")
+ Response res = target.path("/cors2")
.request()
.header(ORIGIN, "http://foo.bar")
.header(ACCESS_CONTROL_REQUEST_METHOD, "PUT")
@@ -250,7 +227,7 @@ public class CrossOriginTest {
@Test
void test2PreFlightForbiddenMethod() {
- Response res = target.path("/app/cors2")
+ Response res = target.path("/cors2")
.request()
.header(ORIGIN, "http://foo.bar")
.header(ACCESS_CONTROL_REQUEST_METHOD, "POST")
@@ -260,7 +237,7 @@ public class CrossOriginTest {
@Test
void test2PreFlightForbiddenHeader() {
- Response res = target.path("/app/cors2")
+ Response res = target.path("/cors2")
.request()
.header(ORIGIN, "http://foo.bar")
.header(ACCESS_CONTROL_REQUEST_METHOD, "PUT")
@@ -271,7 +248,7 @@ public class CrossOriginTest {
@Test
void test2PreFlightAllowedHeaders1() {
- Response res = target.path("/app/cors2")
+ Response res = target.path("/cors2")
.request()
.header(ORIGIN, "http://foo.bar")
.header(ACCESS_CONTROL_REQUEST_METHOD, "PUT")
@@ -288,7 +265,7 @@ public class CrossOriginTest {
@Test
void test2PreFlightAllowedHeaders2() {
- Response res = target.path("/app/cors2")
+ Response res = target.path("/cors2")
.request()
.header(ORIGIN, "http://foo.bar")
.header(ACCESS_CONTROL_REQUEST_METHOD, "PUT")
@@ -307,7 +284,7 @@ public class CrossOriginTest {
@Test
void test2PreFlightAllowedHeaders3() {
- Response res = target.path("/app/cors2")
+ Response res = target.path("/cors2")
.request()
.header(ORIGIN, "http://foo.bar")
.header(ACCESS_CONTROL_REQUEST_METHOD, "PUT")
@@ -327,7 +304,7 @@ public class CrossOriginTest {
@Test
void test1ActualAllowedOrigin() {
- Response res = target.path("/app/cors1")
+ Response res = target.path("/cors1")
.request()
.header(ORIGIN, "http://foo.bar")
.header(ACCESS_CONTROL_REQUEST_METHOD, "PUT")
@@ -338,7 +315,7 @@ public class CrossOriginTest {
@Test
void test2ActualAllowedOrigin() {
- Response res = target.path("/app/cors2")
+ Response res = target.path("/cors2")
.request()
.header(ORIGIN, "http://foo.bar")
.put(Entity.entity("", MediaType.TEXT_PLAIN_TYPE));
@@ -349,7 +326,7 @@ public class CrossOriginTest {
@Test
void test3PreFlightAllowedOrigin() {
- Response res = target.path("/app/cors3")
+ Response res = target.path("/cors3")
.request()
.header(ORIGIN, "http://foo.bar")
.header(ACCESS_CONTROL_REQUEST_METHOD, "PUT")
@@ -363,7 +340,7 @@ public class CrossOriginTest {
@Test
void test3ActualAllowedOrigin() {
- Response res = target.path("/app/cors3")
+ Response res = target.path("/cors3")
.request()
.header(ORIGIN, "http://foo.bar")
.header(ACCESS_CONTROL_REQUEST_METHOD, "PUT")
@@ -374,7 +351,7 @@ public class CrossOriginTest {
@Test
void testErrorResponse() {
- Response res = target.path("/app/notfound")
+ Response res = target.path("/notfound")
.request()
.header(ORIGIN, "http://foo.bar")
.header(ACCESS_CONTROL_REQUEST_METHOD, "PUT")
@@ -385,7 +362,7 @@ public class CrossOriginTest {
@Test
void testMainPathInPresenceOfSubpath() {
- Response res = target.path("/app/cors0")
+ Response res = target.path("/cors0")
.request()
.header(ORIGIN, "http://foo.bar")
.get();
@@ -396,7 +373,7 @@ public class CrossOriginTest {
@Test
void testSubPathPreflightAllowed() {
- Response res = target.path("/app/cors0/subpath")
+ Response res = target.path("/cors0/subpath")
.request()
.header(ORIGIN, "http://foo.bar")
.header(ACCESS_CONTROL_REQUEST_METHOD, "PUT")
@@ -410,7 +387,7 @@ public class CrossOriginTest {
@Test
void testSubPathActualAllowed() {
- Response res = target.path("/app/cors0/subpath")
+ Response res = target.path("/cors0/subpath")
.request()
.header(ORIGIN, "http://foo.bar")
.header(ACCESS_CONTROL_REQUEST_METHOD, "PUT")
diff --git a/microprofile/cors/src/test/resources/META-INF/microprofile-config.properties b/microprofile/cors/src/test/resources/META-INF/microprofile-config.properties
deleted file mode 100644
index 558527c0f..000000000
--- a/microprofile/cors/src/test/resources/META-INF/microprofile-config.properties
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Copyright (c) 2019, 2020 Oracle and/or its affiliates.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-cors.paths.0.path-pattern=/cors3
-cors.paths.0.allow-origins=http://foo.bar, http://bar.foo
-cors.paths.0.allow-methods=DELETE, PUT
diff --git a/microprofile/fault-tolerance/src/test/java/io/helidon/microprofile/faulttolerance/RetryTest.java b/microprofile/fault-tolerance/src/test/java/io/helidon/microprofile/faulttolerance/RetryTest.java
index 7fbe30042..45edda77e 100644
--- a/microprofile/fault-tolerance/src/test/java/io/helidon/microprofile/faulttolerance/RetryTest.java
+++ b/microprofile/fault-tolerance/src/test/java/io/helidon/microprofile/faulttolerance/RetryTest.java
@@ -22,6 +22,7 @@ import java.util.concurrent.CompletionStage;
import java.util.stream.Stream;
import io.helidon.microprofile.tests.junit5.AddBean;
+
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
diff --git a/microprofile/health/pom.xml b/microprofile/health/pom.xml
index 3205c4ada..68a05b35b 100644
--- a/microprofile/health/pom.xml
+++ b/microprofile/health/pom.xml
@@ -58,6 +58,10 @@
+
+ io.helidon.health
+ helidon-health-common
+
org.junit.jupiter
junit-jupiter-api
@@ -69,8 +73,9 @@
test
- io.helidon.health
- helidon-health-common
+ io.helidon.microprofile.tests
+ helidon-microprofile-tests-junit5
+ test
diff --git a/microprofile/health/src/test/java/io/helidon/microprofile/health/HealthMpServiceIT.java b/microprofile/health/src/test/java/io/helidon/microprofile/health/HealthMpServiceIT.java
index 1a5647791..d298c0dd0 100644
--- a/microprofile/health/src/test/java/io/helidon/microprofile/health/HealthMpServiceIT.java
+++ b/microprofile/health/src/test/java/io/helidon/microprofile/health/HealthMpServiceIT.java
@@ -19,59 +19,37 @@ package io.helidon.microprofile.health;
import java.io.StringReader;
import java.util.Arrays;
import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.LogManager;
-import java.util.logging.Logger;
import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
import javax.json.Json;
import javax.json.JsonObject;
-import javax.ws.rs.client.Client;
-import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
-import io.helidon.microprofile.server.Server;
+import io.helidon.microprofile.tests.junit5.AddBean;
+import io.helidon.microprofile.tests.junit5.HelidonTest;
import org.eclipse.microprofile.health.Health;
import org.eclipse.microprofile.health.HealthCheck;
import org.eclipse.microprofile.health.HealthCheckResponse;
-import org.glassfish.jersey.client.ClientProperties;
-import org.glassfish.jersey.logging.LoggingFeature;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
+import org.eclipse.microprofile.health.Liveness;
+import org.eclipse.microprofile.health.Readiness;
+import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;
-
+@HelidonTest
+@AddBean(HealthMpServiceIT.HealthCheckOne.class)
+@AddBean(HealthMpServiceIT.HealthCheckTwo.class)
+@AddBean(HealthMpServiceIT.HealthCheckBad.class)
public class HealthMpServiceIT {
- private static final Logger LOGGER = Logger.getLogger(HealthMpServiceIT.class.getName());
-
- private static Server server;
-
- private static Client client;
-
- @BeforeAll
- public static void startServer() throws Exception {
- LogManager.getLogManager().readConfiguration(HealthMpServiceIT.class.getResourceAsStream("/logging.properties"));
-
- server = Server.create().start();
-
- client = ClientBuilder.newBuilder()
- .register(new LoggingFeature(LOGGER, Level.WARNING, LoggingFeature.Verbosity.PAYLOAD_ANY, 500))
- .property(ClientProperties.FOLLOW_REDIRECTS, true)
- .build();
- }
-
- @AfterAll
- public static void stopServer() {
- if (server != null) {
- server.stop();
- }
- }
+ @Inject
+ private WebTarget webTarget;
/**
* Verify that the {@link HealthCheck} CDI beans (inner classes below)
@@ -104,12 +82,14 @@ public class HealthMpServiceIT {
@Test
public void shouldAddProvidedHealthChecks() {
JsonObject json = getHealthJson();
- assertThat(healthCheckExists(json, "Three"), is(true));
- assertThat(healthCheckExists(json, "Four"), is(true));
- assertThat(healthCheckExists(json, "Five"), is(true));
- assertThat(healthCheckExists(json, "Six"), is(true));
- }
+ Assertions.assertAll(
+ () -> assertThat("Three exists", healthCheckExists(json, "Three"), is(true)),
+ () -> assertThat("Four exists", healthCheckExists(json, "Four"), is(true)),
+ () -> assertThat("Five exists", healthCheckExists(json, "Five"), is(true)),
+ () -> assertThat("Six exists", healthCheckExists(json, "Six"), is(true))
+ );
+ }
private boolean healthCheckExists(JsonObject json, String name) {
return json.getJsonArray("checks")
@@ -120,7 +100,7 @@ public class HealthMpServiceIT {
private JsonObject getHealthJson() {
// request the application metrics in json format from the web server
- String health = client.target("http://localhost:" + server.port())
+ String health = webTarget
.path("health")
.request()
.accept(MediaType.APPLICATION_JSON)
@@ -136,8 +116,7 @@ public class HealthMpServiceIT {
* A test {@link HealthCheck} bean that should be discovered
* by CDI and added to the health check endpoint.
*/
- @Health
- @ApplicationScoped
+ @Readiness
public static class HealthCheckOne
implements HealthCheck {
@@ -151,8 +130,7 @@ public class HealthMpServiceIT {
* A test {@link HealthCheck} bean that should be discovered
* by CDI and added to the health check endpoint.
*/
- @Health
- @ApplicationScoped
+ @Liveness
public static class HealthCheckTwo
implements HealthCheck {
diff --git a/microprofile/health/src/test/resources/META-INF/beans.xml b/microprofile/health/src/test/resources/META-INF/beans.xml
deleted file mode 100644
index 70f5bd0fe..000000000
--- a/microprofile/health/src/test/resources/META-INF/beans.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
diff --git a/microprofile/jwt-auth/pom.xml b/microprofile/jwt-auth/pom.xml
index 7fb8a08d7..10a2dc9b9 100644
--- a/microprofile/jwt-auth/pom.xml
+++ b/microprofile/jwt-auth/pom.xml
@@ -92,5 +92,10 @@
mockito-core
test
+
+ io.helidon.microprofile.tests
+ helidon-microprofile-tests-junit5
+ test
+
diff --git a/microprofile/jwt-auth/src/test/java/io/helidon/microprofile/jwt/auth/JwtAuthTest.java b/microprofile/jwt-auth/src/test/java/io/helidon/microprofile/jwt/auth/JwtAuthTest.java
index 0e6e39e80..6646fab6f 100644
--- a/microprofile/jwt-auth/src/test/java/io/helidon/microprofile/jwt/auth/JwtAuthTest.java
+++ b/microprofile/jwt-auth/src/test/java/io/helidon/microprofile/jwt/auth/JwtAuthTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2020 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,15 +26,14 @@ import javax.inject.Inject;
import javax.json.JsonString;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
-import javax.ws.rs.client.Client;
-import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.SecurityContext;
import io.helidon.config.Config;
-import io.helidon.microprofile.server.Server;
+import io.helidon.microprofile.tests.junit5.AddBean;
+import io.helidon.microprofile.tests.junit5.HelidonTest;
import io.helidon.security.EndpointConfig;
import io.helidon.security.OutboundSecurityResponse;
import io.helidon.security.Principal;
@@ -47,8 +46,6 @@ import org.eclipse.microprofile.jwt.Claim;
import org.eclipse.microprofile.jwt.ClaimValue;
import org.eclipse.microprofile.jwt.Claims;
import org.eclipse.microprofile.jwt.JsonWebToken;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
@@ -60,27 +57,13 @@ import static org.mockito.Mockito.when;
/**
* Unit test for {@link io.helidon.microprofile.jwt.auth.JsonWebTokenProducer}.
*/
+@HelidonTest
+@AddBean(JwtAuthTest.MyApp.class)
+@AddBean(JwtAuthTest.MyResource.class)
+@AddBean(JwtAuthTest.ResourceWithPublicMethod.class)
class JwtAuthTest {
- private static Server server;
- private static Client client;
-
- @BeforeAll
- static void startServer() {
- server = Server.create(MyApp.class);
- server.start();
-
- client = ClientBuilder.newClient();
- }
-
- @AfterAll
- static void stopServer() {
- if (null != server) {
- server.stop();
- }
- if (null != client) {
- client.close();
- }
- }
+ @Inject
+ private WebTarget target;
@Test
void testRsa() {
@@ -126,8 +109,6 @@ class JwtAuthTest {
String signedToken = response.requestHeaders().get("Authorization").get(0);
- WebTarget target = client.target("http://localhost:" + server.port());
-
// authenticated
String httpResponse = target.path("/hello")
.request()
@@ -147,8 +128,6 @@ class JwtAuthTest {
@Test
void testPublicEndpoint() {
- WebTarget target = client.target("http://localhost:" + server.port());
-
// public
String httpResponse = target.path("/public")
.request()
diff --git a/microprofile/jwt-auth/src/test/resources/META-INF/beans.xml b/microprofile/jwt-auth/src/test/resources/META-INF/beans.xml
deleted file mode 100644
index d094c3f7b..000000000
--- a/microprofile/jwt-auth/src/test/resources/META-INF/beans.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
diff --git a/microprofile/server/src/test/java/io/helidon/microprofile/server/ServerImplTest.java b/microprofile/server/src/test/java/io/helidon/microprofile/server/ServerImplTest.java
index 19e3db68b..0f63a2660 100644
--- a/microprofile/server/src/test/java/io/helidon/microprofile/server/ServerImplTest.java
+++ b/microprofile/server/src/test/java/io/helidon/microprofile/server/ServerImplTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2020 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -51,6 +51,7 @@ class ServerImplTest {
client.close();
}
+ @Test
void testCustomExecutorService() {
Server server = Server.builder()
.addApplication("/app1", new TestApplication1())
diff --git a/microprofile/tests/junit5-tests/pom.xml b/microprofile/tests/junit5-tests/pom.xml
new file mode 100644
index 000000000..d58ee1e30
--- /dev/null
+++ b/microprofile/tests/junit5-tests/pom.xml
@@ -0,0 +1,58 @@
+
+
+
+
+ 4.0.0
+
+ io.helidon.microprofile.tests
+ tests-project
+ 2.0.3-SNAPSHOT
+
+
+ helidon-microprofile-tests-junit5-tests
+ Helidon Microprofile Tests Junit5 unit tests
+
+
+ Test for JUnit5 integration to prevent cyclic dependendcies,
+ so the module can be used in MP config implementation
+
+
+
+
+ io.helidon.microprofile.server
+ helidon-microprofile-server
+ test
+
+
+ io.helidon.microprofile.tests
+ helidon-microprofile-tests-junit5
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ test
+
+
+ org.hamcrest
+ hamcrest-core
+ test
+
+
+
\ No newline at end of file
diff --git a/microprofile/tests/junit5-tests/src/test/java/io/helidon/microprofile/tests/junit5/AbstractTest.java b/microprofile/tests/junit5-tests/src/test/java/io/helidon/microprofile/tests/junit5/AbstractTest.java
new file mode 100644
index 000000000..369caef5e
--- /dev/null
+++ b/microprofile/tests/junit5-tests/src/test/java/io/helidon/microprofile/tests/junit5/AbstractTest.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2020 Oracle and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.helidon.microprofile.tests.junit5;
+
+import javax.inject.Inject;
+
+import org.eclipse.microprofile.config.inject.ConfigProperty;
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+@HelidonTest
+@AddConfig(key = "key", value = "value")
+abstract class AbstractTest {
+ @Inject
+ @ConfigProperty(name = "key")
+ private String key;
+
+ @Test
+ void testKey() {
+ assertThat(key, is("value"));
+ }
+}
diff --git a/microprofile/tests/junit5/src/test/java/io/helidon/microprofile/tests/junit5/TestAddBean.java b/microprofile/tests/junit5-tests/src/test/java/io/helidon/microprofile/tests/junit5/TestAddBean.java
similarity index 100%
rename from microprofile/tests/junit5/src/test/java/io/helidon/microprofile/tests/junit5/TestAddBean.java
rename to microprofile/tests/junit5-tests/src/test/java/io/helidon/microprofile/tests/junit5/TestAddBean.java
diff --git a/microprofile/tests/junit5-tests/src/test/java/io/helidon/microprofile/tests/junit5/TestChild1.java b/microprofile/tests/junit5-tests/src/test/java/io/helidon/microprofile/tests/junit5/TestChild1.java
new file mode 100644
index 000000000..3de720506
--- /dev/null
+++ b/microprofile/tests/junit5-tests/src/test/java/io/helidon/microprofile/tests/junit5/TestChild1.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2020 Oracle and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.helidon.microprofile.tests.junit5;
+
+import javax.inject.Inject;
+
+import org.eclipse.microprofile.config.inject.ConfigProperty;
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+@AddConfig(key = "key1", value = "value1")
+class TestChild1 extends AbstractTest {
+ @Inject
+ @ConfigProperty(name = "key1")
+ private String childKey;
+
+ @Test
+ void testChildKey() {
+ assertThat(childKey, is("value1"));
+ }
+}
diff --git a/microprofile/tests/junit5-tests/src/test/java/io/helidon/microprofile/tests/junit5/TestChild2.java b/microprofile/tests/junit5-tests/src/test/java/io/helidon/microprofile/tests/junit5/TestChild2.java
new file mode 100644
index 000000000..f185a7c95
--- /dev/null
+++ b/microprofile/tests/junit5-tests/src/test/java/io/helidon/microprofile/tests/junit5/TestChild2.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2020 Oracle and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.helidon.microprofile.tests.junit5;
+
+import javax.inject.Inject;
+
+import org.eclipse.microprofile.config.inject.ConfigProperty;
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+@AddConfig(key = "key2", value = "value2")
+class TestChild2 extends AbstractTest {
+ @Inject
+ @ConfigProperty(name = "key2")
+ private String childKey;
+
+ @Test
+ void testChildKey() {
+ assertThat(childKey, is("value2"));
+ }
+}
diff --git a/microprofile/tests/junit5/src/test/java/io/helidon/microprofile/tests/junit5/TestConfigSources.java b/microprofile/tests/junit5-tests/src/test/java/io/helidon/microprofile/tests/junit5/TestConfigSources.java
similarity index 97%
rename from microprofile/tests/junit5/src/test/java/io/helidon/microprofile/tests/junit5/TestConfigSources.java
rename to microprofile/tests/junit5-tests/src/test/java/io/helidon/microprofile/tests/junit5/TestConfigSources.java
index 07830e790..3f2825d10 100644
--- a/microprofile/tests/junit5/src/test/java/io/helidon/microprofile/tests/junit5/TestConfigSources.java
+++ b/microprofile/tests/junit5-tests/src/test/java/io/helidon/microprofile/tests/junit5/TestConfigSources.java
@@ -26,7 +26,7 @@ import static org.hamcrest.MatcherAssert.assertThat;
@HelidonTest
@Configuration(configSources = "testConfigSources.properties")
-public class TestConfigSources {
+class TestConfigSources {
@Inject
@ConfigProperty(name = "some.key")
private String someKey;
diff --git a/microprofile/tests/junit5/src/test/java/io/helidon/microprofile/tests/junit5/TestConstructorInjection.java b/microprofile/tests/junit5-tests/src/test/java/io/helidon/microprofile/tests/junit5/TestConstructorInjection.java
similarity index 97%
rename from microprofile/tests/junit5/src/test/java/io/helidon/microprofile/tests/junit5/TestConstructorInjection.java
rename to microprofile/tests/junit5-tests/src/test/java/io/helidon/microprofile/tests/junit5/TestConstructorInjection.java
index 095c81ff5..d2d1d6513 100644
--- a/microprofile/tests/junit5/src/test/java/io/helidon/microprofile/tests/junit5/TestConstructorInjection.java
+++ b/microprofile/tests/junit5-tests/src/test/java/io/helidon/microprofile/tests/junit5/TestConstructorInjection.java
@@ -31,7 +31,7 @@ import static org.hamcrest.MatcherAssert.assertThat;
@HelidonTest
@DisableDiscovery
@AddBean(TestConstructorInjection.MyBean.class)
-public class TestConstructorInjection {
+class TestConstructorInjection {
private final int currentPort;
@Inject
diff --git a/microprofile/tests/junit5/src/test/java/io/helidon/microprofile/tests/junit5/TestCustomConfig.java b/microprofile/tests/junit5-tests/src/test/java/io/helidon/microprofile/tests/junit5/TestCustomConfig.java
similarity index 100%
rename from microprofile/tests/junit5/src/test/java/io/helidon/microprofile/tests/junit5/TestCustomConfig.java
rename to microprofile/tests/junit5-tests/src/test/java/io/helidon/microprofile/tests/junit5/TestCustomConfig.java
diff --git a/microprofile/tests/junit5/src/test/java/io/helidon/microprofile/tests/junit5/TestCustomExtension.java b/microprofile/tests/junit5-tests/src/test/java/io/helidon/microprofile/tests/junit5/TestCustomExtension.java
similarity index 100%
rename from microprofile/tests/junit5/src/test/java/io/helidon/microprofile/tests/junit5/TestCustomExtension.java
rename to microprofile/tests/junit5-tests/src/test/java/io/helidon/microprofile/tests/junit5/TestCustomExtension.java
diff --git a/microprofile/tests/junit5/src/test/java/io/helidon/microprofile/tests/junit5/TestDefaults.java b/microprofile/tests/junit5-tests/src/test/java/io/helidon/microprofile/tests/junit5/TestDefaults.java
similarity index 100%
rename from microprofile/tests/junit5/src/test/java/io/helidon/microprofile/tests/junit5/TestDefaults.java
rename to microprofile/tests/junit5-tests/src/test/java/io/helidon/microprofile/tests/junit5/TestDefaults.java
diff --git a/microprofile/tests/junit5/src/test/java/io/helidon/microprofile/tests/junit5/TestNoDiscovery.java b/microprofile/tests/junit5-tests/src/test/java/io/helidon/microprofile/tests/junit5/TestNoDiscovery.java
similarity index 100%
rename from microprofile/tests/junit5/src/test/java/io/helidon/microprofile/tests/junit5/TestNoDiscovery.java
rename to microprofile/tests/junit5-tests/src/test/java/io/helidon/microprofile/tests/junit5/TestNoDiscovery.java
diff --git a/microprofile/tests/junit5/src/test/java/io/helidon/microprofile/tests/junit5/TestPerMethod.java b/microprofile/tests/junit5-tests/src/test/java/io/helidon/microprofile/tests/junit5/TestPerMethod.java
similarity index 97%
rename from microprofile/tests/junit5/src/test/java/io/helidon/microprofile/tests/junit5/TestPerMethod.java
rename to microprofile/tests/junit5-tests/src/test/java/io/helidon/microprofile/tests/junit5/TestPerMethod.java
index 23a817442..a36442779 100644
--- a/microprofile/tests/junit5/src/test/java/io/helidon/microprofile/tests/junit5/TestPerMethod.java
+++ b/microprofile/tests/junit5-tests/src/test/java/io/helidon/microprofile/tests/junit5/TestPerMethod.java
@@ -54,7 +54,7 @@ class TestPerMethod {
@Test
@AddConfig(key = "key-1", value = "value-1")
- @AddBean(TestPerMethod.MyBean.class)
+ @AddBean(MyBean.class)
void testWithAdditionalConfig() {
String configured = CDI.current()
.select(MyBean.class)
@@ -65,7 +65,7 @@ class TestPerMethod {
}
@Test
- @AddExtension(TestPerMethod.MyExtension.class)
+ @AddExtension(MyExtension.class)
void testCustomExtension() {
assertThat("Extension should have been called, as it observes application scope", MyExtension.called, is(true));
}
diff --git a/microprofile/tests/junit5-tests/src/test/java/io/helidon/microprofile/tests/junit5/TestWebTarget.java b/microprofile/tests/junit5-tests/src/test/java/io/helidon/microprofile/tests/junit5/TestWebTarget.java
new file mode 100644
index 000000000..260a16c12
--- /dev/null
+++ b/microprofile/tests/junit5-tests/src/test/java/io/helidon/microprofile/tests/junit5/TestWebTarget.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2020 Oracle and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.helidon.microprofile.tests.junit5;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.client.WebTarget;
+
+import io.helidon.microprofile.server.JaxRsCdiExtension;
+import io.helidon.microprofile.server.ServerCdiExtension;
+
+import org.glassfish.jersey.ext.cdi1x.internal.CdiComponentProvider;
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+@HelidonTest(resetPerTest = true)
+@DisableDiscovery
+@AddExtension(ServerCdiExtension.class)
+@AddExtension(JaxRsCdiExtension.class)
+@AddExtension(CdiComponentProvider.class)
+@AddBean(TestWebTarget.ResourceClass.class)
+class TestWebTarget {
+ @Test
+ void testFirst(WebTarget target) {
+ assertThat(target, notNullValue());
+ String response = target.path("/test")
+ .request()
+ .get(String.class);
+ assertThat(response, is("Hello from ResourceClass"));
+ }
+
+ @Test
+ void testSecond(WebTarget target) {
+ assertThat(target, notNullValue());
+ String response = target.path("/test")
+ .request()
+ .get(String.class);
+ assertThat(response, is("Hello from ResourceClass"));
+ }
+
+ @Path("/test")
+ public static class ResourceClass {
+ @GET
+ public String getIt() {
+ return "Hello from ResourceClass";
+ }
+ }
+}
\ No newline at end of file
diff --git a/microprofile/tests/junit5-tests/src/test/java/io/helidon/microprofile/tests/junit5/TestWebTargetPerMethod.java b/microprofile/tests/junit5-tests/src/test/java/io/helidon/microprofile/tests/junit5/TestWebTargetPerMethod.java
new file mode 100644
index 000000000..9d8110f5a
--- /dev/null
+++ b/microprofile/tests/junit5-tests/src/test/java/io/helidon/microprofile/tests/junit5/TestWebTargetPerMethod.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2020 Oracle and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.helidon.microprofile.tests.junit5;
+
+import javax.inject.Inject;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.client.WebTarget;
+
+import io.helidon.microprofile.server.JaxRsCdiExtension;
+import io.helidon.microprofile.server.ServerCdiExtension;
+
+import org.glassfish.jersey.ext.cdi1x.internal.CdiComponentProvider;
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+@HelidonTest
+@DisableDiscovery
+@AddExtension(ServerCdiExtension.class)
+@AddExtension(JaxRsCdiExtension.class)
+@AddExtension(CdiComponentProvider.class)
+@AddBean(TestWebTargetPerMethod.ResourceClass.class)
+class TestWebTargetPerMethod {
+ @Inject
+ private WebTarget injected;
+
+ @Test
+ void testIt() {
+ assertThat(injected, notNullValue());
+ String response = injected.path("/test")
+ .request()
+ .get(String.class);
+ assertThat(response, is("Hello from ResourceClass"));
+ }
+
+ @Test
+ void testInMethod(WebTarget method) {
+ assertThat(method, notNullValue());
+ String response = method.path("/test")
+ .request()
+ .get(String.class);
+ assertThat(response, is("Hello from ResourceClass"));
+ }
+
+ @Path("/test")
+ public static class ResourceClass {
+ @GET
+ public String getIt() {
+ return "Hello from ResourceClass";
+ }
+ }
+}
\ No newline at end of file
diff --git a/microprofile/tests/junit5/src/test/resources/testConfigSources.properties b/microprofile/tests/junit5-tests/src/test/resources/testConfigSources.properties
similarity index 100%
rename from microprofile/tests/junit5/src/test/resources/testConfigSources.properties
rename to microprofile/tests/junit5-tests/src/test/resources/testConfigSources.properties
diff --git a/microprofile/tests/junit5/pom.xml b/microprofile/tests/junit5/pom.xml
index c35df2df1..50d49e67d 100644
--- a/microprofile/tests/junit5/pom.xml
+++ b/microprofile/tests/junit5/pom.xml
@@ -38,16 +38,15 @@
helidon-microprofile-cdi
provided
-
- io.helidon.microprofile.config
- helidon-microprofile-config
- provided
-
org.junit.jupiter
junit-jupiter-api
provided
+
+ io.helidon.jersey
+ helidon-jersey-client
+
org.hamcrest
hamcrest-core
diff --git a/microprofile/tests/junit5/src/main/java/io/helidon/microprofile/tests/junit5/Configuration.java b/microprofile/tests/junit5/src/main/java/io/helidon/microprofile/tests/junit5/Configuration.java
index 320b956df..b66307e3d 100644
--- a/microprofile/tests/junit5/src/main/java/io/helidon/microprofile/tests/junit5/Configuration.java
+++ b/microprofile/tests/junit5/src/main/java/io/helidon/microprofile/tests/junit5/Configuration.java
@@ -17,6 +17,7 @@
package io.helidon.microprofile.tests.junit5;
import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@@ -26,11 +27,16 @@ import java.lang.annotation.Target;
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
+@Inherited
public @interface Configuration {
/**
* If set to {@code true}, the existing (or default) MicroProfile configuration would be used.
* By default uses a configuration constructed using all {@link io.helidon.microprofile.tests.junit5.AddConfig}
* annotations and {@link #configSources()}.
+ * When set to false and a {@link org.junit.jupiter.api.BeforeAll} method registers a custom configuration
+ * with {@link org.eclipse.microprofile.config.spi.ConfigProviderResolver}, the result is undefined, though
+ * tests have shown that the registered config may be used (as BeforeAll ordering is undefined by
+ * JUnit, it may be called after our extension)
*
* @return whether to use existing (or default) configuration, or customized one
*/
diff --git a/microprofile/tests/junit5/src/main/java/io/helidon/microprofile/tests/junit5/DisableDiscovery.java b/microprofile/tests/junit5/src/main/java/io/helidon/microprofile/tests/junit5/DisableDiscovery.java
index 2f25c9412..bbb6e3e2b 100644
--- a/microprofile/tests/junit5/src/main/java/io/helidon/microprofile/tests/junit5/DisableDiscovery.java
+++ b/microprofile/tests/junit5/src/main/java/io/helidon/microprofile/tests/junit5/DisableDiscovery.java
@@ -17,6 +17,7 @@
package io.helidon.microprofile.tests.junit5;
import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@@ -37,6 +38,7 @@ import java.lang.annotation.Target;
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
+@Inherited
public @interface DisableDiscovery {
/**
* By default if you annotate a class or a method, discovery gets disabled.
diff --git a/microprofile/tests/junit5/src/main/java/io/helidon/microprofile/tests/junit5/HelidonJunitExtension.java b/microprofile/tests/junit5/src/main/java/io/helidon/microprofile/tests/junit5/HelidonJunitExtension.java
index 50507a302..1eb2c8f7d 100644
--- a/microprofile/tests/junit5/src/main/java/io/helidon/microprofile/tests/junit5/HelidonJunitExtension.java
+++ b/microprofile/tests/junit5/src/main/java/io/helidon/microprofile/tests/junit5/HelidonJunitExtension.java
@@ -32,14 +32,21 @@ import java.util.Map;
import java.util.Set;
import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.context.Dependent;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.se.SeContainer;
import javax.enterprise.inject.se.SeContainerInitializer;
+import javax.enterprise.inject.spi.AfterBeanDiscovery;
import javax.enterprise.inject.spi.BeforeBeanDiscovery;
+import javax.enterprise.inject.spi.CDI;
import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.inject.spi.configurator.AnnotatedTypeConfigurator;
import javax.inject.Inject;
import javax.inject.Singleton;
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.WebTarget;
import io.helidon.config.mp.MpConfigSources;
@@ -70,6 +77,14 @@ class HelidonJunitExtension implements BeforeAllCallback,
ParameterResolver {
private static final Set> HELIDON_TEST_ANNOTATIONS =
Set.of(AddBean.class, AddConfig.class, AddExtension.class, Configuration.class);
+ private static final Map, Annotation> BEAN_DEFINING = new HashMap<>();
+
+ static {
+ BEAN_DEFINING.put(ApplicationScoped.class, ApplicationScoped.Literal.INSTANCE);
+ BEAN_DEFINING.put(Singleton.class, ApplicationScoped.Literal.INSTANCE);
+ BEAN_DEFINING.put(RequestScoped.class, RequestScoped.Literal.INSTANCE);
+ BEAN_DEFINING.put(Dependent.class, Dependent.Literal.INSTANCE);
+ }
private final List classLevelExtensions = new ArrayList<>();
private final List classLevelBeans = new ArrayList<>();
@@ -87,15 +102,15 @@ class HelidonJunitExtension implements BeforeAllCallback,
public void beforeAll(ExtensionContext context) {
testClass = context.getRequiredTestClass();
- AddConfig[] configs = testClass.getAnnotationsByType(AddConfig.class);
+ AddConfig[] configs = getAnnotations(testClass, AddConfig.class);
classLevelConfigMeta.addConfig(configs);
classLevelConfigMeta.configuration(testClass.getAnnotation(Configuration.class));
configProviderResolver = ConfigProviderResolver.instance();
- AddExtension[] extensions = testClass.getAnnotationsByType(AddExtension.class);
+ AddExtension[] extensions = getAnnotations(testClass, AddExtension.class);
classLevelExtensions.addAll(Arrays.asList(extensions));
- AddBean[] beans = testClass.getAnnotationsByType(AddBean.class);
+ AddBean[] beans = getAnnotations(testClass, AddBean.class);
classLevelBeans.addAll(Arrays.asList(beans));
HelidonTest testAnnot = testClass.getAnnotation(HelidonTest.class);
@@ -117,7 +132,35 @@ class HelidonJunitExtension implements BeforeAllCallback,
configure(classLevelConfigMeta);
- startContainer(classLevelBeans, classLevelExtensions, classLevelDisableDiscovery);
+ if (!classLevelConfigMeta.useExisting) {
+ // the container startup is delayed in case we `useExisting`, so the is first set up by the user
+ // when we do not need to `useExisting`, we want to start early, so parameterized test method sources that use CDI
+ // can work
+ startContainer(classLevelBeans, classLevelExtensions, classLevelDisableDiscovery);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private T[] getAnnotations(Class> testClass, Class annotClass) {
+ // inherited does not help, as it only returns annot from superclass if
+ // child has none
+ T[] directAnnotations = testClass.getAnnotationsByType(annotClass);
+
+ List allAnnotations = new ArrayList<>(List.of(directAnnotations));
+
+ Class> superClass = testClass.getSuperclass();
+ while (superClass != null) {
+ directAnnotations = superClass.getAnnotationsByType(annotClass);
+ allAnnotations.addAll(List.of(directAnnotations));
+ superClass = superClass.getSuperclass();
+ }
+
+ Object result = Array.newInstance(annotClass, allAnnotations.size());
+ for (int i = 0; i < allAnnotations.size(); i++) {
+ Array.set(result, i, allAnnotations.get(i));
+ }
+
+ return (T[]) result;
}
@Override
@@ -310,6 +353,12 @@ class HelidonJunitExtension implements BeforeAllCallback,
return invocation.proceed();
}
+ // we need to start container before the test class is instantiated, to honor @BeforeAll that
+ // creates a custom MP config
+ if (container == null) {
+ startContainer(classLevelBeans, classLevelExtensions, classLevelDisableDiscovery);
+ }
+
// we need to replace instantiation with CDI lookup, to properly injection into fields (and constructors)
invocation.skip();
@@ -328,15 +377,26 @@ class HelidonJunitExtension implements BeforeAllCallback,
throw new ParameterResolutionException(
"When a test class is annotated with @HelidonTest(resetPerMethod=true), constructor must not have "
+ "parameters.");
- } else if (executable instanceof Method) {
- if (parameterContext.getParameter().getType().equals(SeContainer.class)) {
- return true;
- }
+ }
+ } else {
+ // we need to start container before the test class is instantiated, to honor @BeforeAll that
+ // creates a custom MP config
+ if (container == null) {
+ startContainer(classLevelBeans, classLevelExtensions, classLevelDisableDiscovery);
}
}
+ Class> paramType = parameterContext.getParameter().getType();
+
if (executable instanceof Constructor) {
- return !container.select(parameterContext.getParameter().getType()).isUnsatisfied();
+ return !container.select(paramType).isUnsatisfied();
+ } else if (executable instanceof Method) {
+ if (paramType.equals(SeContainer.class)) {
+ return true;
+ }
+ if (paramType.equals(WebTarget.class)) {
+ return true;
+ }
}
return false;
@@ -345,16 +405,22 @@ class HelidonJunitExtension implements BeforeAllCallback,
@Override
public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext)
throws ParameterResolutionException {
+ Executable executable = parameterContext.getParameter().getDeclaringExecutable();
+ Class> paramType = parameterContext.getParameter().getType();
- if (parameterContext.getParameter().getType().equals(SeContainer.class)) {
- return container;
+ if (executable instanceof Method) {
+ if (paramType.equals(SeContainer.class)) {
+ return container;
+ }
+ if (paramType.equals(WebTarget.class)) {
+ return container.select(WebTarget.class).get();
+ }
}
// we return null, as construction of the object is done by CDI
// for primitive types we must return appropriate primitive default
- Class> type = parameterContext.getParameter().getType();
- if (type.isPrimitive()) {
+ if (paramType.isPrimitive()) {
// a hack to get to default value of a primitive type
- return Array.get(Array.newInstance(type, 1), 0);
+ return Array.get(Array.newInstance(paramType, 1), 0);
} else {
return null;
}
@@ -371,6 +437,28 @@ class HelidonJunitExtension implements BeforeAllCallback,
this.addBeans = addBeans;
}
+ @SuppressWarnings("unchecked")
+ void registerOtherBeans(@Observes AfterBeanDiscovery event) {
+ Client client = ClientBuilder.newClient();
+
+ event.addBean()
+ .addType(javax.ws.rs.client.WebTarget.class)
+ .scope(ApplicationScoped.class)
+ .createWith(context -> {
+ try {
+ Class extends Extension> extClass = (Class extends Extension>) Class
+ .forName("io.helidon.microprofile.server.ServerCdiExtension");
+ Extension extension = CDI.current().getBeanManager().getExtension(extClass);
+ Method m = extension.getClass().getMethod("port");
+ int port = (int) m.invoke(extension);
+ String uri = "http://localhost:" + port;
+ return client.target(uri);
+ } catch (Exception e) {
+ return client.target("http://localhost:7001");
+ }
+ });
+ }
+
void registerAddedBeans(@Observes BeforeBeanDiscovery event) {
event.addAnnotatedType(testClass, "junit-" + testClass.getName())
.add(ApplicationScoped.Literal.INSTANCE);
@@ -379,20 +467,32 @@ class HelidonJunitExtension implements BeforeAllCallback,
Annotation scope;
Class extends Annotation> definedScope = addBean.scope();
- if (definedScope.equals(ApplicationScoped.class) || definedScope.equals(Singleton.class)) {
- scope = ApplicationScoped.Literal.INSTANCE;
- } else if (definedScope.equals(RequestScoped.class)) {
- scope = RequestScoped.Literal.INSTANCE;
- } else {
+ scope = BEAN_DEFINING.get(definedScope);
+
+ if (scope == null) {
throw new IllegalStateException(
- "Only Singleton, ApplicationScoped and RequestScoped are allowed in tests. Scope " + definedScope
- .getName() + " is not allowed for bean " + addBean.value().getName());
+ "Only on of " + BEAN_DEFINING.keySet() + " scopes are allowed in tests. Scope "
+ + definedScope.getName() + " is not allowed for bean " + addBean.value().getName());
}
- event.addAnnotatedType(addBean.value(), "junit-" + addBean.value().getName())
- .add(scope);
+ AnnotatedTypeConfigurator> configurator = event
+ .addAnnotatedType(addBean.value(), "junit-" + addBean.value().getName());
+ if (!hasBda(addBean.value())) {
+ configurator.add(scope);
+ }
}
}
+
+ private boolean hasBda(Class> value) {
+ // does it have bean defining annotation?
+ for (Class extends Annotation> aClass : BEAN_DEFINING.keySet()) {
+ if (value.getAnnotation(aClass) != null) {
+ return true;
+ }
+ }
+
+ return false;
+ }
}
private static final class ConfigMeta {
@@ -401,8 +501,11 @@ class HelidonJunitExtension implements BeforeAllCallback,
private boolean useExisting;
private ConfigMeta() {
+ // to allow SeContainerInitializer (forbidden by default because of native image)
additionalKeys.put("mp.initializer.allow", "true");
additionalKeys.put("mp.initializer.no-warn", "true");
+ // to run on random port
+ additionalKeys.put("server.port", "0");
// higher ordinal then all the defaults, system props and environment variables
additionalKeys.putIfAbsent(ConfigSource.CONFIG_ORDINAL, "1000");
}
@@ -421,7 +524,7 @@ class HelidonJunitExtension implements BeforeAllCallback,
additionalSources.addAll(List.of(config.configSources()));
}
- public ConfigMeta nextMethod() {
+ ConfigMeta nextMethod() {
ConfigMeta methodMeta = new ConfigMeta();
methodMeta.additionalKeys.putAll(this.additionalKeys);
diff --git a/microprofile/tests/junit5/src/main/java/io/helidon/microprofile/tests/junit5/HelidonTest.java b/microprofile/tests/junit5/src/main/java/io/helidon/microprofile/tests/junit5/HelidonTest.java
index 40e89b901..1278627bd 100644
--- a/microprofile/tests/junit5/src/main/java/io/helidon/microprofile/tests/junit5/HelidonTest.java
+++ b/microprofile/tests/junit5/src/main/java/io/helidon/microprofile/tests/junit5/HelidonTest.java
@@ -16,6 +16,7 @@
package io.helidon.microprofile.tests.junit5;
import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@@ -36,6 +37,7 @@ import org.junit.jupiter.api.extension.ExtendWith;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@ExtendWith(HelidonJunitExtension.class)
+@Inherited
public @interface HelidonTest {
/**
* By default, CDI container is created once before the class is initialized and shut down
diff --git a/microprofile/tests/pom.xml b/microprofile/tests/pom.xml
index 3eecce3c0..ea97a2d1d 100644
--- a/microprofile/tests/pom.xml
+++ b/microprofile/tests/pom.xml
@@ -41,6 +41,7 @@
arquillian
junit5
+ junit5-tests