Skip to content

Commit

Permalink
Refactor JPA integration tests
Browse files Browse the repository at this point in the history
  • Loading branch information
romain-grecourt committed Aug 8, 2024
1 parent 3c8b4f6 commit 3204e6b
Show file tree
Hide file tree
Showing 128 changed files with 4,486 additions and 4,919 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ jobs:
strategy:
matrix:
os: [ ubuntu-20.04 ]
moduleSet: [ core, it, dbclient, dbclient-oracle, others ]
moduleSet: [ core, it, jpa, jpa-oracle, dbclient, dbclient-oracle, others ]
include:
- { os: ubuntu-20.04, platform: linux }
runs-on: ${{ matrix.os }}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2023 Oracle and/or its affiliates.
* Copyright (c) 2024 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.
Expand All @@ -13,18 +13,22 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.helidon.tests.integration.jpa.appl;

package io.helidon.microprofile.testing.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;

/**
* Test method annotation.
* This is security enhancement which restricts methods invoked by Dispatcher only to those with this annotation.
* Identifies static methods of which the values should be added to MicroProfile configuration.
* The return type of the annotated methods must be of type {@code Map<String, String>}.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MPTest {
@Target({ElementType.METHOD})
@Inherited
public @interface AddConfigMap {
}

Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,14 @@
import java.lang.reflect.Constructor;
import java.lang.reflect.Executable;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Deque;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
Expand Down Expand Up @@ -110,7 +113,6 @@ class HelidonJunitExtension implements BeforeAllCallback,
private SeContainer container;


@SuppressWarnings("unchecked")
@Override
public void beforeAll(ExtensionContext context) {
testClass = context.getRequiredTestClass();
Expand Down Expand Up @@ -154,6 +156,7 @@ public void beforeAll(ExtensionContext context) {
classLevelBeans.add(WeldRequestScopeLiteral.INSTANCE);
}

addConfigMaps();
configure(classLevelConfigMeta);

if (!classLevelConfigMeta.useExisting) {
Expand Down Expand Up @@ -188,7 +191,7 @@ private <T extends Annotation> T[] getAnnotations(Class<?> testClass, Class<T> a
}

@Override
public void beforeEach(ExtensionContext context) throws Exception {
public void beforeEach(ExtensionContext context) {
if (resetPerTest) {
Method method = context.getRequiredTestMethod();
AddConfig[] configs = method.getAnnotationsByType(AddConfig.class);
Expand Down Expand Up @@ -219,13 +222,14 @@ public void beforeEach(ExtensionContext context) throws Exception {
}

@Override
public void afterEach(ExtensionContext context) throws Exception {
public void afterEach(ExtensionContext context) {
if (resetPerTest) {
releaseConfig();
stopContainer();
}
}

@SuppressWarnings("ExtractMethodRecommender")
private void validatePerClass() {
Method[] methods = testClass.getMethods();
for (Method method : methods) {
Expand Down Expand Up @@ -270,6 +274,7 @@ private boolean hasHelidonTestAnnotation(AnnotatedElement element) {
return false;
}

@SuppressWarnings("ExtractMethodRecommender")
private void validatePerTest() {
Constructor<?>[] constructors = testClass.getConstructors();
if (constructors.length > 1) {
Expand Down Expand Up @@ -337,6 +342,35 @@ private void configure(ConfigMeta configMeta) {
configProviderResolver.registerConfig(config, Thread.currentThread().getContextClassLoader());
}
}

private void addConfigMaps() {
Deque<Class<?>> stack = new ArrayDeque<>();
stack.push(testClass);
while (!stack.isEmpty()) {
Class<?> clazz = stack.pop();
try {
for (Method method : clazz.getDeclaredMethods()) {
if (Modifier.isStatic(method.getModifiers()) && method.isAnnotationPresent(AddConfigMap.class)) {
method.setAccessible(true);
Object value = method.invoke(null);
if (value instanceof Map<?, ?> map) {
classLevelConfigMeta.addConfigMap(map);
}
}
}
} catch (InvocationTargetException | IllegalAccessException e) {
throw new RuntimeException(e);
}
Class<?> superclass = clazz.getSuperclass();
if (superclass != null) {
stack.push(superclass);
}
for (Class<?> interfaceClass : clazz.getInterfaces()) {
stack.push(interfaceClass);
}
}
}

private void releaseConfig() {
if (configProviderResolver != null && config != null) {
configProviderResolver.releaseConfig(config);
Expand Down Expand Up @@ -400,11 +434,12 @@ public <T> T interceptTestClassConstructor(Invocation<T> invocation,
if (container == null) {
// at this early stage the class should be checked whether it is annotated with
// @TestInstance(TestInstance.Lifecycle.PER_CLASS) to start correctly the container
Class<?> testClass = extensionContext.getRequiredTestClass();
TestInstance testClassAnnotation = testClass.getAnnotation(TestInstance.class);
if (testClassAnnotation != null && testClassAnnotation.value().equals(TestInstance.Lifecycle.PER_CLASS)){
throw new RuntimeException("When a class is annotated with @HelidonTest, "
+ "it is not compatible with @TestInstance(TestInstance.Lifecycle.PER_CLASS)"
+ "annotation, as it is a Singleton CDI Bean.");
+ " annotation, as it is a Singleton CDI Bean.");
}
startContainer(classLevelBeans, classLevelExtensions, classLevelDisableDiscovery);
}
Expand Down Expand Up @@ -444,11 +479,8 @@ public boolean supportsParameter(ParameterContext parameterContext, ExtensionCon
if (paramType.equals(SeContainer.class)) {
return true;
}
if (paramType.equals(WebTarget.class)) {
return true;
}
return paramType.equals(WebTarget.class);
}

return false;
}

Expand Down Expand Up @@ -518,7 +550,7 @@ private AddBeansExtension(Class<?> testClass, List<AddBean> addBeans) {
}


void processSocketInjectionPoints(@Observes ProcessInjectionPoint<?, WebTarget> event) throws Exception{
void processSocketInjectionPoints(@Observes ProcessInjectionPoint<?, WebTarget> event) {
InjectionPoint injectionPoint = event.getInjectionPoint();
Set<Annotation> qualifiers = injectionPoint.getQualifiers();
for (Annotation qualifier : qualifiers) {
Expand All @@ -533,17 +565,16 @@ void processSocketInjectionPoints(@Observes ProcessInjectionPoint<?, WebTarget>

void registerOtherBeans(@Observes AfterBeanDiscovery event) {

@SuppressWarnings("resource")
Client client = ClientBuilder.newClient();

//register for all named Ports
socketAnnotations.forEach((namedPort, qualifier) -> {

event.addBean()
.addType(WebTarget.class)
.scope(ApplicationScoped.class)
.qualifiers(qualifier)
.createWith(context -> getWebTarget(client, namedPort));
});
socketAnnotations.forEach((namedPort, qualifier) -> event
.addBean()
.addType(WebTarget.class)
.scope(ApplicationScoped.class)
.qualifiers(qualifier)
.createWith(context -> getWebTarget(client, namedPort)));

event.addBean()
.addType(jakarta.ws.rs.client.WebTarget.class)
Expand Down Expand Up @@ -592,7 +623,7 @@ void registerAddedBeans(@Observes BeforeBeanDiscovery event) {
}

private boolean hasBda(Class<?> value) {
// does it have bean defining annotation?
// does it have a "bean defining annotation"?
for (Class<? extends Annotation> aClass : BEAN_DEFINING.keySet()) {
if (value.getAnnotation(aClass) != null) {
return true;
Expand Down Expand Up @@ -649,6 +680,15 @@ private void addConfigBlock(AddConfigBlock config) {
this.block = config.value();
}

private void addConfigMap(Map<?, ?> map) {
map.forEach((k, v) -> {
String key = k.toString();
if (v != null) {
additionalKeys.put(key, v.toString());
}
});
}

ConfigMeta nextMethod() {
ConfigMeta methodMeta = new ConfigMeta();

Expand Down Expand Up @@ -747,5 +787,4 @@ public Class<? extends Extension> value() {
return CdiComponentProvider.class;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package io.helidon.tests.functional.requestscope;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

import io.helidon.faulttolerance.Async;
Expand All @@ -27,6 +28,7 @@
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Response.Status;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
Expand All @@ -40,18 +42,21 @@ class TenantTest {
private WebTarget baseTarget;

@Test
@Timeout(value = 1, unit = TimeUnit.MINUTES)
public void test() throws Exception {
asyncCalls(() -> baseTarget.path("test").request()
.header("x-tenant-id", "123").get(), null);
}

@Test
@Timeout(value = 1, unit = TimeUnit.MINUTES)
public void test2() throws Exception {
asyncCalls(() -> baseTarget.path("test2").request()
.header("x-tenant-id", "123").get(), null);
}

@Test
@Timeout(value = 1, unit = TimeUnit.MINUTES)
public void test3() throws Exception {
asyncCalls(() -> baseTarget.path("test3").queryParam("param1", "1").request()
.header("x-tenant-id", "123").get(), "1");
Expand Down
Loading

0 comments on commit 3204e6b

Please sign in to comment.