mirror of
https://github.com/valitydev/testcontainers-annotations.git
synced 2024-11-06 08:55:19 +00:00
parent
84f5ed2789
commit
8b95a81424
2
pom.xml
2
pom.xml
@ -12,7 +12,7 @@
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<artifactId>testcontainers-annotations</artifactId>
|
||||
<version>1.0.5</version>
|
||||
<version>1.0.6</version>
|
||||
<url>https://github.com/rbkmoney/testcontainers-annotations</url>
|
||||
|
||||
<licenses>
|
||||
|
@ -124,8 +124,8 @@ public class CephTestcontainerExtension
|
||||
String[] properties) {
|
||||
var container = THREAD_CONTAINER.get();
|
||||
TestPropertyValues.of(
|
||||
"storage.endpoint=" + container.getContainerIpAddress() + ":"
|
||||
+ container.getMappedPort(8080),
|
||||
"storage.endpoint=" + container.getContainerIpAddress() + ":" +
|
||||
container.getMappedPort(8080),
|
||||
"storage.signingRegion=" + signingRegion,
|
||||
"storage.accessKey=" + loadDefaultLibraryProperty(ACCESS_KEY),
|
||||
"storage.secretKey=" + loadDefaultLibraryProperty(SECRET_KEY),
|
||||
|
@ -4,12 +4,11 @@ import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Synchronized;
|
||||
import org.testcontainers.containers.GenericContainer;
|
||||
import org.testcontainers.containers.wait.strategy.HttpWaitStrategy;
|
||||
import org.testcontainers.containers.wait.strategy.WaitStrategy;
|
||||
import org.testcontainers.utility.DockerImageName;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
import static com.rbkmoney.testcontainers.annotations.util.GenericContainerUtil.getWaitStrategy;
|
||||
import static com.rbkmoney.testcontainers.annotations.util.SpringApplicationPropertiesLoader.loadDefaultLibraryProperty;
|
||||
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
@ -56,23 +55,11 @@ public class CephTestcontainerFactory {
|
||||
.withEnv("CEPH_DEMO_ACCESS_KEY", loadDefaultLibraryProperty(ACCESS_KEY))
|
||||
.withEnv("CEPH_DEMO_SECRET_KEY", loadDefaultLibraryProperty(SECRET_KEY))
|
||||
.withEnv("CEPH_DEMO_BUCKET", "TEST")
|
||||
.waitingFor(cephHealthCheck())) {
|
||||
.waitingFor(getWaitStrategy("/api/v0.1/health", 200, 5000, Duration.ofMinutes(1)))) {
|
||||
return container;
|
||||
}
|
||||
}
|
||||
|
||||
private WaitStrategy cephHealthCheck() {
|
||||
return getWaitStrategy("/api/v0.1/health", 200, 5000, Duration.ofMinutes(1));
|
||||
}
|
||||
|
||||
private static WaitStrategy getWaitStrategy(String path, Integer statusCode, Integer port, Duration duration) {
|
||||
return new HttpWaitStrategy()
|
||||
.forPath(path)
|
||||
.forPort(port)
|
||||
.forStatusCode(statusCode)
|
||||
.withStartupTimeout(duration);
|
||||
}
|
||||
|
||||
private static class SingletonHolder {
|
||||
|
||||
private static final CephTestcontainerFactory INSTANCE = new CephTestcontainerFactory();
|
||||
|
@ -0,0 +1,28 @@
|
||||
package com.rbkmoney.testcontainers.annotations.minio;
|
||||
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target({ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@ExtendWith(MinioTestcontainerExtension.class)
|
||||
public @interface MinioTestcontainer {
|
||||
|
||||
/**
|
||||
* properties = {"postgresql.make.happy=true",...}
|
||||
*/
|
||||
String[] properties() default {};
|
||||
|
||||
String signingRegion() default "RU";
|
||||
|
||||
String clientProtocol() default "HTTP";
|
||||
|
||||
String clientMaxErrorRetry() default "10";
|
||||
|
||||
String bucketName() default "TEST";
|
||||
|
||||
}
|
@ -0,0 +1,139 @@
|
||||
package com.rbkmoney.testcontainers.annotations.minio;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import lombok.var;
|
||||
import org.junit.jupiter.api.extension.AfterAllCallback;
|
||||
import org.junit.jupiter.api.extension.BeforeAllCallback;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.api.extension.TestInstancePostProcessor;
|
||||
import org.junit.platform.commons.support.AnnotationSupport;
|
||||
import org.springframework.boot.test.util.TestPropertyValues;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.test.context.ContextConfigurationAttributes;
|
||||
import org.springframework.test.context.ContextCustomizer;
|
||||
import org.springframework.test.context.ContextCustomizerFactory;
|
||||
import org.testcontainers.containers.GenericContainer;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import static com.rbkmoney.testcontainers.annotations.minio.MinioTestcontainerFactory.MINIO_PASSWORD;
|
||||
import static com.rbkmoney.testcontainers.annotations.minio.MinioTestcontainerFactory.MINIO_USER;
|
||||
import static com.rbkmoney.testcontainers.annotations.util.GenericContainerUtil.startContainer;
|
||||
import static com.rbkmoney.testcontainers.annotations.util.SpringApplicationPropertiesLoader.loadDefaultLibraryProperty;
|
||||
|
||||
@Slf4j
|
||||
public class MinioTestcontainerExtension
|
||||
implements TestInstancePostProcessor, BeforeAllCallback, AfterAllCallback {
|
||||
|
||||
private static final ThreadLocal<GenericContainer<?>> THREAD_CONTAINER = new ThreadLocal<>();
|
||||
|
||||
@Override
|
||||
public void postProcessTestInstance(Object testInstance, ExtensionContext context) {
|
||||
var annotation = findMinioTestcontainerSingletonAnnotation(context);
|
||||
if (!annotation.isPresent()) {
|
||||
return;
|
||||
}
|
||||
var container = MinioTestcontainerFactory.singletonContainer();
|
||||
if (!container.isRunning()) {
|
||||
startContainer(container);
|
||||
}
|
||||
THREAD_CONTAINER.set(container);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeAll(ExtensionContext context) {
|
||||
var annotation = findMinioTestcontainerAnnotation(context);
|
||||
if (!annotation.isPresent()) {
|
||||
return;
|
||||
}
|
||||
var container = MinioTestcontainerFactory.container();
|
||||
if (!container.isRunning()) {
|
||||
startContainer(container);
|
||||
}
|
||||
THREAD_CONTAINER.set(container);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterAll(ExtensionContext context) {
|
||||
if (findMinioTestcontainerAnnotation(context).isPresent()) {
|
||||
var container = THREAD_CONTAINER.get();
|
||||
if (container != null && container.isRunning()) {
|
||||
container.stop();
|
||||
}
|
||||
THREAD_CONTAINER.remove();
|
||||
} else if (findMinioTestcontainerSingletonAnnotation(context).isPresent()) {
|
||||
THREAD_CONTAINER.remove();
|
||||
}
|
||||
}
|
||||
|
||||
private static Optional<MinioTestcontainer> findMinioTestcontainerAnnotation(ExtensionContext context) {
|
||||
return AnnotationSupport.findAnnotation(context.getElement(), MinioTestcontainer.class);
|
||||
}
|
||||
|
||||
private static Optional<MinioTestcontainer> findMinioTestcontainerAnnotation(Class<?> testClass) {
|
||||
return AnnotationSupport.findAnnotation(testClass, MinioTestcontainer.class);
|
||||
}
|
||||
|
||||
private static Optional<MinioTestcontainerSingleton> findMinioTestcontainerSingletonAnnotation(
|
||||
ExtensionContext context) {
|
||||
return AnnotationSupport.findAnnotation(context.getElement(), MinioTestcontainerSingleton.class);
|
||||
}
|
||||
|
||||
private static Optional<MinioTestcontainerSingleton> findMinioTestcontainerSingletonAnnotation(
|
||||
Class<?> testClass) {
|
||||
return AnnotationSupport.findAnnotation(testClass, MinioTestcontainerSingleton.class);
|
||||
}
|
||||
|
||||
public static class MinioTestcontainerContextCustomizerFactory implements ContextCustomizerFactory {
|
||||
|
||||
@Override
|
||||
public ContextCustomizer createContextCustomizer(
|
||||
Class<?> testClass,
|
||||
List<ContextConfigurationAttributes> configAttributes) {
|
||||
return (context, mergedConfig) -> {
|
||||
var minioTestcontainerAnnotation = findMinioTestcontainerAnnotation(testClass);
|
||||
if (minioTestcontainerAnnotation.isPresent()) {
|
||||
var annotation = minioTestcontainerAnnotation.get();
|
||||
init(
|
||||
context,
|
||||
annotation.signingRegion(),
|
||||
annotation.clientProtocol(),
|
||||
annotation.clientMaxErrorRetry(),
|
||||
annotation.bucketName(),
|
||||
annotation.properties());
|
||||
} else {
|
||||
findMinioTestcontainerSingletonAnnotation(testClass).ifPresent(
|
||||
annotation -> init(
|
||||
context,
|
||||
annotation.signingRegion(),
|
||||
annotation.clientProtocol(),
|
||||
annotation.clientMaxErrorRetry(),
|
||||
annotation.bucketName(),
|
||||
annotation.properties()));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void init(
|
||||
ConfigurableApplicationContext context,
|
||||
String signingRegion,
|
||||
String clientProtocol,
|
||||
String clientMaxErrorRetry,
|
||||
String bucketName,
|
||||
String[] properties) {
|
||||
var container = THREAD_CONTAINER.get();
|
||||
TestPropertyValues.of(
|
||||
"storage.endpoint=" + container.getContainerIpAddress() + ":" +
|
||||
container.getMappedPort(9000),
|
||||
"storage.signingRegion=" + signingRegion,
|
||||
"storage.accessKey=" + loadDefaultLibraryProperty(MINIO_USER),
|
||||
"storage.secretKey=" + loadDefaultLibraryProperty(MINIO_PASSWORD),
|
||||
"storage.clientProtocol=" + clientProtocol,
|
||||
"storage.clientMaxErrorRetry=" + clientMaxErrorRetry,
|
||||
"storage.bucketName=" + bucketName)
|
||||
.and(properties)
|
||||
.applyTo(context);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
package com.rbkmoney.testcontainers.annotations.minio;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Synchronized;
|
||||
import org.testcontainers.containers.GenericContainer;
|
||||
import org.testcontainers.utility.DockerImageName;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
import static com.rbkmoney.testcontainers.annotations.util.GenericContainerUtil.getWaitStrategy;
|
||||
import static com.rbkmoney.testcontainers.annotations.util.SpringApplicationPropertiesLoader.loadDefaultLibraryProperty;
|
||||
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class MinioTestcontainerFactory {
|
||||
|
||||
public static final String MINIO_USER = "testcontainers.minio.user";
|
||||
public static final String MINIO_PASSWORD = "testcontainers.minio.password";
|
||||
private static final String MINIO_IMAGE_NAME = "minio/minio";
|
||||
private static final String TAG_PROPERTY = "testcontainers.minio.tag";
|
||||
|
||||
private GenericContainer<?> minioContainer;
|
||||
|
||||
public static GenericContainer<?> container() {
|
||||
return instance().create();
|
||||
}
|
||||
|
||||
public static GenericContainer<?> singletonContainer() {
|
||||
return instance().getOrCreateSingletonContainer();
|
||||
}
|
||||
|
||||
private static MinioTestcontainerFactory instance() {
|
||||
return SingletonHolder.INSTANCE;
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
private GenericContainer<?> getOrCreateSingletonContainer() {
|
||||
if (minioContainer != null) {
|
||||
return minioContainer;
|
||||
}
|
||||
minioContainer = create();
|
||||
return minioContainer;
|
||||
}
|
||||
|
||||
private GenericContainer<?> create() {
|
||||
try (GenericContainer<?> container = new GenericContainer<>(
|
||||
DockerImageName
|
||||
.parse(MINIO_IMAGE_NAME)
|
||||
.withTag(loadDefaultLibraryProperty(TAG_PROPERTY)))
|
||||
.withNetworkAliases("minio")
|
||||
.withEnv("MINIO_ROOT_USER", loadDefaultLibraryProperty(MINIO_USER))
|
||||
.withEnv("MINIO_ROOT_PASSWORD", loadDefaultLibraryProperty(MINIO_PASSWORD))
|
||||
.waitingFor(getWaitStrategy("/minio/health/live", 200, 9000, Duration.ofMinutes(1)))) {
|
||||
return container;
|
||||
}
|
||||
}
|
||||
|
||||
private static class SingletonHolder {
|
||||
|
||||
private static final MinioTestcontainerFactory INSTANCE = new MinioTestcontainerFactory();
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package com.rbkmoney.testcontainers.annotations.minio;
|
||||
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target({ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@ExtendWith(MinioTestcontainerExtension.class)
|
||||
@Transactional
|
||||
public @interface MinioTestcontainerSingleton {
|
||||
|
||||
/**
|
||||
* properties = {"postgresql.make.happy=true",...}
|
||||
*/
|
||||
String[] properties() default {};
|
||||
|
||||
String signingRegion() default "RU";
|
||||
|
||||
String clientProtocol() default "HTTP";
|
||||
|
||||
String clientMaxErrorRetry() default "10";
|
||||
|
||||
String bucketName() default "TEST";
|
||||
|
||||
}
|
@ -1,8 +1,11 @@
|
||||
package com.rbkmoney.testcontainers.annotations.util;
|
||||
|
||||
import org.testcontainers.containers.GenericContainer;
|
||||
import org.testcontainers.containers.wait.strategy.HttpWaitStrategy;
|
||||
import org.testcontainers.containers.wait.strategy.WaitStrategy;
|
||||
import org.testcontainers.lifecycle.Startables;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@ -15,4 +18,12 @@ public class GenericContainerUtil {
|
||||
assertThat(container.isRunning())
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
public static WaitStrategy getWaitStrategy(String path, Integer statusCode, Integer port, Duration duration) {
|
||||
return new HttpWaitStrategy()
|
||||
.forPath(path)
|
||||
.forPort(port)
|
||||
.forStatusCode(statusCode)
|
||||
.withStartupTimeout(duration);
|
||||
}
|
||||
}
|
||||
|
@ -3,4 +3,5 @@ org.springframework.test.context.ContextCustomizerFactory=\
|
||||
com.rbkmoney.testcontainers.annotations.postgresql.PostgresqlTestcontainerExtension.PostgresqlTestcontainerContextCustomizerFactory,\
|
||||
com.rbkmoney.testcontainers.annotations.kafka.KafkaTestcontainerExtension.KafkaTestcontainerContextCustomizerFactory,\
|
||||
com.rbkmoney.testcontainers.annotations.clickhouse.ClickhouseTestcontainerExtension.ClickhouseTestcontainerContextCustomizerFactory,\
|
||||
com.rbkmoney.testcontainers.annotations.ceph.CephTestcontainerExtension.CephTestcontainerContextCustomizerFactory
|
||||
com.rbkmoney.testcontainers.annotations.ceph.CephTestcontainerExtension.CephTestcontainerContextCustomizerFactory,\
|
||||
com.rbkmoney.testcontainers.annotations.minio.MinioTestcontainerExtension.MinioTestcontainerContextCustomizerFactory
|
||||
|
@ -9,3 +9,7 @@ testcontainers:
|
||||
tag: 'v3.0.5-stable-3.0-luminous-centos-7'
|
||||
accessKey: 'test'
|
||||
secretKey: 'test'
|
||||
minio:
|
||||
tag: 'latest'
|
||||
user: 'user'
|
||||
password: 'password'
|
||||
|
Loading…
Reference in New Issue
Block a user