Skip to content

Commit

Permalink
Allow the extension to inject into fields annotated with Junit annota…
Browse files Browse the repository at this point in the history
…tions.

Restricting to only the specific annotations was a little too restrictive.

Signed-off-by: Sam Barker <[email protected]>
  • Loading branch information
SamBarker committed Oct 2, 2023
1 parent 429e5da commit ca54975
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,28 @@
*/
package io.kroxylicious.testing.kafka.junit5ext;

import io.kroxylicious.testing.kafka.api.KafkaCluster;
import io.kroxylicious.testing.kafka.api.KafkaClusterConstraint;
import io.kroxylicious.testing.kafka.api.KafkaClusterProvisioningStrategy;
import io.kroxylicious.testing.kafka.api.KroxyliciousTestInfo;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.ServiceLoader;
import java.util.UUID;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.apache.kafka.clients.admin.Admin;
import org.apache.kafka.clients.consumer.Consumer;
import org.apache.kafka.clients.consumer.KafkaConsumer;
Expand Down Expand Up @@ -57,27 +75,10 @@
import org.junit.platform.commons.util.ExceptionUtils;
import org.junit.platform.commons.util.ReflectionUtils;

import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.ServiceLoader;
import java.util.UUID;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import io.kroxylicious.testing.kafka.api.KafkaCluster;
import io.kroxylicious.testing.kafka.api.KafkaClusterConstraint;
import io.kroxylicious.testing.kafka.api.KafkaClusterProvisioningStrategy;
import io.kroxylicious.testing.kafka.api.KroxyliciousTestInfo;

import static java.lang.System.Logger.Level.TRACE;
import static org.junit.platform.commons.support.ReflectionSupport.findFields;
Expand Down Expand Up @@ -515,8 +516,8 @@ private static boolean supportsParameter(Parameter parameter) {
return KafkaCluster.class.isAssignableFrom(type) || (isKafkaClient(type) && isCandidate(parameter));
}

private static boolean isCandidate(AnnotatedElement parameter) {
return noAnnotations(parameter) || isAnnotatedByExtensionAnnotation(parameter);
private static boolean isCandidate(AnnotatedElement annotatedElement) {
return noAnnotations(annotatedElement) || hasOnlySupportedAnnotations(annotatedElement);
}

private static boolean isKafkaClient(Class<?> type) {
Expand All @@ -527,20 +528,20 @@ private static boolean noAnnotations(AnnotatedElement parameter) {
return parameter.getAnnotations().length == 0;
}

private static boolean isAnnotatedByExtensionAnnotation(AnnotatedElement parameter) {
final Annotation[] annotations = parameter.getAnnotations();
for (Annotation annotation : annotations) {
if (KafkaClusterConstraint.class.isAssignableFrom(annotation.annotationType())) {
return true;
}
if (Name.class.isAssignableFrom(annotation.annotationType())) {
return true;
}
if (KafkaCluster.class.isAssignableFrom(annotation.annotationType())) {
return true;
/**
* We want to avoid conflicts with annotations such as mockito's @Mock. However, maintaining a list of
* conflicting annotations would be mad. So it seems simpler to maintain a set of known safe annotations with which
* we can inject still inject.
*/
private static boolean hasOnlySupportedAnnotations(AnnotatedElement parameter) {
boolean supported = true;
for (Annotation annotation : parameter.getAnnotations()) {
final String canonicalName = annotation.annotationType().getCanonicalName();
if (!canonicalName.startsWith("io.kroxylicious") && !canonicalName.startsWith("org.junit")) {
supported = false;
}
}
return false;
return supported;
}

private void injectInstanceFields(ExtensionContext context, Object instance) {
Expand Down Expand Up @@ -1083,12 +1084,4 @@ private void assertSupportedType(String target, Class<?> type) {
}
}

@FunctionalInterface
private interface ClientFactory<T, X extends T> {
X getClient(String description,
AnnotatedElement sourceElement,
Class<X> type,
Type genericType,
ExtensionContext extensionContext);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import static org.junit.jupiter.api.Assertions.assertInstanceOf;

@ExtendWith(KafkaClusterExtension.class)
public class StaticFieldExtensionTest extends AbstractExtensionTest {
class StaticFieldExtensionTest extends AbstractExtensionTest {

@Order(1)
@BrokerCluster(numBrokers = 1)
Expand All @@ -39,7 +39,7 @@ public class StaticFieldExtensionTest extends AbstractExtensionTest {
static AdminClient staticAdminClient;

@Test
public void testKafkaClusterStaticField()
void testKafkaClusterStaticField()
throws ExecutionException, InterruptedException {
var dc = describeCluster(staticCluster.getKafkaClientConfiguration());
assertEquals(1, dc.nodes().get().size());
Expand All @@ -48,47 +48,47 @@ public void testKafkaClusterStaticField()
}

@Test
public void adminStaticField() throws ExecutionException, InterruptedException {
void adminStaticField() throws ExecutionException, InterruptedException {
assertSameCluster(staticCluster, staticAdmin);
}

@Test
public void adminClientStaticField() throws ExecutionException, InterruptedException {
void adminClientStaticField() throws ExecutionException, InterruptedException {
assertSameCluster(staticCluster, staticAdminClient);
}

@Test
public void adminParameter(Admin admin) throws ExecutionException, InterruptedException {
void adminParameter(Admin admin) throws ExecutionException, InterruptedException {
assertSameCluster(staticCluster, admin);
}

@Test
public void adminClientParameter(AdminClient admin) throws ExecutionException, InterruptedException {
void adminClientParameter(AdminClient admin) throws ExecutionException, InterruptedException {
assertSameCluster(staticCluster, admin);
}

@Test
public void kafkaAdminClientParameter(KafkaAdminClient admin) throws ExecutionException, InterruptedException {
void kafkaAdminClientParameter(KafkaAdminClient admin) throws ExecutionException, InterruptedException {
assertSameCluster(staticCluster, admin);
}

@Test
public void producerParameter(Producer<String, String> producer) throws ExecutionException, InterruptedException {
void producerParameter(Producer<String, String> producer) throws ExecutionException, InterruptedException {
doProducer(producer, "hello", "world");
}

@Test
public void kafkaProducerParameter(KafkaProducer<String, String> producer) throws ExecutionException, InterruptedException {
void kafkaProducerParameter(KafkaProducer<String, String> producer) throws ExecutionException, InterruptedException {
doProducer(producer, "hello", "world");
}

@Test
public void consumerParameter(Consumer<String, String> consumer) {
void consumerParameter(Consumer<String, String> consumer) {
doConsumer(consumer);
}

@Test
public void kafkaConsumerParameter(KafkaConsumer<String, String> consumer) {
void kafkaConsumerParameter(KafkaConsumer<String, String> consumer) {
doConsumer(consumer);
}

Expand Down

0 comments on commit ca54975

Please sign in to comment.