Skip to content

Commit

Permalink
Remove support for method injection. This is likely not needed as it …
Browse files Browse the repository at this point in the history
…would add a performance impact when start/stopping a container for each method.

Signed-off-by: James R. Perkins <[email protected]>
  • Loading branch information
jamezp committed Jul 3, 2024
1 parent 138f2f2 commit 67da7f7
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
Expand Down Expand Up @@ -51,7 +50,8 @@ public void enrich(final Object testCase) {
if (testcontainer.type() == GenericContainer.class) {
if (!(GenericContainer.class.isAssignableFrom(field.getType()))) {
throw new IllegalArgumentException(
String.format("Field %s is not assignable to %s", field, testcontainer.type().getName()));
String.format("Field %s is not assignable to %s", field, testcontainer.type()
.getName()));
}
} else {
// An explicit type was defined, make sure we can assign the type to the field
Expand All @@ -62,8 +62,9 @@ public void enrich(final Object testCase) {
}
}

value = instances.get().lookupOrCreate((Class<GenericContainer<?>>) field.getType(), field, testcontainer,
qualifiers);
value = instances.get()
.lookupOrCreate((Class<GenericContainer<?>>) field.getType(), field, testcontainer,
qualifiers);
} catch (Exception e) {
throw new RuntimeException("Could not lookup value for field " + field, e);
}
Expand All @@ -83,40 +84,7 @@ public void enrich(final Object testCase) {

@Override
public Object[] resolve(final Method method) {
final Object[] values = new Object[method.getParameterTypes().length];
if (!isAnnotatedWith(method.getDeclaringClass(), DockerRequired.class)) {
return values;
}
final Parameter[] parameters = method.getParameters();
for (int i = 0; i < parameters.length; i++) {
final Parameter parameter = parameters[i];
if (parameter.isAnnotationPresent(Testcontainer.class)) {
final Testcontainer testcontainer = parameter.getAnnotation(Testcontainer.class);
final List<Annotation> qualifiers = Stream.of(parameter.getAnnotations())
.filter(a -> !(a instanceof Testcontainer))
.collect(Collectors.toList());

// If the field is the default GenericContainer, validate the field is a GenericContainer
if (testcontainer.type() == GenericContainer.class) {
if (!(GenericContainer.class.isAssignableFrom(parameter.getType()))) {
throw new IllegalArgumentException(
String.format("Parameter %s is not assignable to %s", parameter,
testcontainer.type().getName()));
}
} else {
// An explicit type was defined, make sure we can assign the type to the field
if (!(parameter.getType().isAssignableFrom(testcontainer.type()))) {
throw new IllegalArgumentException(
String.format("Parameter %s is not assignable to %s", parameter, testcontainer.type()
.getName()));
}
}
values[i] = instances.get().lookupOrCreate((Class<GenericContainer<?>>) parameter.getType(), parameter,
testcontainer,
qualifiers);
}
}
return values;
return new Object[method.getParameterTypes().length];
}

private static void checkForDocker(boolean isDockerAvailable) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@
package org.jboss.arquillian.testcontainers;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Parameter;

import org.jboss.arquillian.container.spi.ContainerRegistry;
import org.jboss.arquillian.core.api.Instance;
Expand Down Expand Up @@ -55,24 +53,10 @@ public void stopContainer(@Observes AfterClass afterClass) {
public void startContainer(@Observes(precedence = 500) final AfterEnrichment event) {
// Look for the servers to start on fields only
for (TestcontainerDescription description : containerRegistry.get()) {
if (!(description.element instanceof Field)) {
continue;
}
if (description.testcontainer.value()) {
description.instance.start();
}
}
// Check the method
if (event.getMethod() != null) {
// Look for the servers to start on fields for this method
for (Parameter parameter : event.getMethod().getParameters()) {
for (TestcontainerDescription description : containerRegistry.get()) {
if (parameter.equals(description.element) && description.testcontainer.value()) {
description.instance.start();
}
}
}
}
}

private void checkForDocker(boolean failIfNoDocker, boolean isDockerAvailable) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,41 @@
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
import java.lang.reflect.Parameter;

import org.testcontainers.containers.GenericContainer;

/**
* Used to annotate a field or parameter which <strong>must</strong> be an instance of a
* {@link GenericContainer}. A {@link DockerRequired} annotation must be present on the
* type to use Testcontainer injection.
* Used to annotate a field which <strong>must</strong> be an instance of a {@link GenericContainer}. A
* {@link DockerRequired} annotation must be present on the type to use Testcontainer injection.
*
* <pre>
* &#064;ExtendWith(ArquillianExtension.class)
* &#064;RunAsClient
* // By throwing the TestAbortedException, the test will be skipped if docker is not available
* &#064;DockerRequired(TestAbortedException.class)
* public class ContainerTest {
*
* &#064;Testcontainer
* private CustomTestContainer container;
*
* &#064;Deployment
* public static JavaArchive createDeployment() {
* return ShrinkWrap.create(JavaArchive.class)
* .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
* }
*
* &#064;Test
* public void testContainerInjected() {
* Assertions.assertNotNull(container, "Expected the container to be injected.");
* Assertions.assertTrue(container.isRunning(), "Expected the container to be running");
* }
* }
* </pre>
*/
@Inherited
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD, ElementType.PARAMETER })
@Target(ElementType.FIELD)
public @interface Testcontainer {

/**
Expand All @@ -35,10 +57,10 @@
boolean value() default true;

/**
* The type used to create the value for the field or parameter. The type must have a no-arg constructor.
* The type used to create the value for the field. The type must have a no-arg constructor.
* <p>
* If left as the default value, {@link GenericContainer}, the type to construct is derived from the
* {@linkplain Field#getType() field} or {@linkplain Parameter#getType() parameter}.
* {@linkplain Field#getType() field}.
* </p>
*
* @return the type to construct
Expand Down

0 comments on commit 67da7f7

Please sign in to comment.