From 90b19b080503be29b4d0f6a1d1a1fab5226e49b3 Mon Sep 17 00:00:00 2001 From: Gautier de Saint Martin Lacaze Date: Sun, 5 Feb 2023 14:48:07 +0100 Subject: [PATCH] WIP --- pom.xml | 23 +++++- .../gitlab4j/api/UserApiIntegrationTest.java | 19 +++++ .../EnableForGitLabVersionAndSuperior.java | 22 +++++ ...eForGitLabVersionAndSuperiorCondition.java | 72 ++++++++++++++++ .../org/gitlab4j/test/GitLabContainer.java | 42 ++++++++++ .../test/GitLabInvocationContextProvider.java | 54 ++++++++++++ .../SetupTeardownLauncherSessionListener.java | 82 +++++++++++++++++++ src/test/java/org/gitlab4j/test/Version.java | 30 +++++++ 8 files changed, 341 insertions(+), 3 deletions(-) create mode 100644 src/test/java/org/gitlab4j/api/UserApiIntegrationTest.java create mode 100644 src/test/java/org/gitlab4j/test/EnableForGitLabVersionAndSuperior.java create mode 100644 src/test/java/org/gitlab4j/test/EnableForGitLabVersionAndSuperiorCondition.java create mode 100644 src/test/java/org/gitlab4j/test/GitLabContainer.java create mode 100644 src/test/java/org/gitlab4j/test/GitLabInvocationContextProvider.java create mode 100644 src/test/java/org/gitlab4j/test/SetupTeardownLauncherSessionListener.java create mode 100644 src/test/java/org/gitlab4j/test/Version.java diff --git a/pom.xml b/pom.xml index 4b18d4626..ebd707775 100644 --- a/pom.xml +++ b/pom.xml @@ -57,8 +57,8 @@ 4.0.4 1.2.2 - 5.8.2 - 1.15.3 + 5.9.2 + 1.17.6 4.4.0 1.3 1.19.0 @@ -423,13 +423,30 @@ jakarta.servlet-api ${servlet.version} - org.junit.jupiter junit-jupiter ${junit.version} test + + org.junit.platform + junit-platform-launcher + 1.9.1 + test + + + org.testcontainers + testcontainers + ${testcontainers.version} + test + + + org.testcontainers + junit-jupiter + ${testcontainers.version} + test + org.mockito mockito-core diff --git a/src/test/java/org/gitlab4j/api/UserApiIntegrationTest.java b/src/test/java/org/gitlab4j/api/UserApiIntegrationTest.java new file mode 100644 index 000000000..1e3bb8766 --- /dev/null +++ b/src/test/java/org/gitlab4j/api/UserApiIntegrationTest.java @@ -0,0 +1,19 @@ +package org.gitlab4j.api; + +import org.gitlab4j.test.GitLabContainer; +import org.gitlab4j.test.GitLabInvocationContextProvider; +import org.junit.jupiter.api.TestTemplate; +import org.junit.jupiter.api.extension.ExtendWith; + +@ExtendWith(GitLabInvocationContextProvider.class) +class UserApiIntegrationTest { + + + @TestTemplate + void testName(GitLabContainer container) throws Exception { + + System.out.println(container.version); + + } + +} diff --git a/src/test/java/org/gitlab4j/test/EnableForGitLabVersionAndSuperior.java b/src/test/java/org/gitlab4j/test/EnableForGitLabVersionAndSuperior.java new file mode 100644 index 000000000..750e4fb88 --- /dev/null +++ b/src/test/java/org/gitlab4j/test/EnableForGitLabVersionAndSuperior.java @@ -0,0 +1,22 @@ +package org.gitlab4j.test; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.junit.jupiter.api.extension.ExtendWith; + +@Target({ ElementType.TYPE, ElementType.METHOD }) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@ExtendWith(EnableForGitLabVersionAndSuperiorCondition.class) +public @interface EnableForGitLabVersionAndSuperior { + + /** + * The minimal version on which this test will be executed. + */ + String version() default ""; + +} diff --git a/src/test/java/org/gitlab4j/test/EnableForGitLabVersionAndSuperiorCondition.java b/src/test/java/org/gitlab4j/test/EnableForGitLabVersionAndSuperiorCondition.java new file mode 100644 index 000000000..d18d1631e --- /dev/null +++ b/src/test/java/org/gitlab4j/test/EnableForGitLabVersionAndSuperiorCondition.java @@ -0,0 +1,72 @@ +package org.gitlab4j.test; + +import java.lang.reflect.AnnotatedElement; +import java.lang.reflect.Method; +import java.util.List; +import java.util.stream.Collectors; + +import org.junit.jupiter.api.extension.ConditionEvaluationResult; +import org.junit.jupiter.api.extension.ExtensionConfigurationException; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.InvocationInterceptor; +import org.junit.jupiter.api.extension.ReflectiveInvocationContext; +import org.junit.platform.commons.util.AnnotationUtils; +import org.opentest4j.TestAbortedException; + +public class EnableForGitLabVersionAndSuperiorCondition implements InvocationInterceptor { + + private static final ConditionEvaluationResult ENABLED = ConditionEvaluationResult + .enabled("@EnableForGitLabVersionAndSuperiorCondition is not present"); + + @Override + public void interceptTestTemplateMethod(Invocation invocation, + ReflectiveInvocationContext invocationContext, ExtensionContext extensionContext) throws Throwable { + Method testMethod = extensionContext.getRequiredTestMethod(); + List arguments = invocationContext.getArguments(); + + List containers = arguments.stream().filter(o -> { + if (o instanceof GitLabContainer) { + return true; + } + return false; + }) + .collect(Collectors.toList()); + + if (containers.size() != 1) { + throw new ExtensionConfigurationException( + String.format( + "Method %s should declare 1 GitLabContainer. It's actually declare %d.", + testMethod.getName(), + containers.size() + ) + ); + } + + GitLabContainer gitlabContainer = (GitLabContainer) containers.get(0); + + + AnnotatedElement element = extensionContext.getElement().orElse(null); + ConditionEvaluationResult result = AnnotationUtils.findAnnotation(element, EnableForGitLabVersionAndSuperior.class) // + .map(annotation -> toResult(annotation, gitlabContainer)) // + .orElse(ENABLED); + + if (result.isDisabled()) { + throw new TestAbortedException(result.getReason().get()); + } + + invocation.proceed(); + + } + + private ConditionEvaluationResult toResult(EnableForGitLabVersionAndSuperior annotation, GitLabContainer gitlabContainer) { + Version minimalVersion = new Version(annotation.version()); + Version currentVersion = gitlabContainer.parsedVersion; + + if (currentVersion.isBefore(minimalVersion)) { + return ConditionEvaluationResult.disabled(String.format("The minimal version of GitLab for this test is %s. Current execution is against GitLab %s", minimalVersion.version(), currentVersion.version())); + } + return ConditionEvaluationResult.enabled(minimalVersion.toString()); + } +} + + diff --git a/src/test/java/org/gitlab4j/test/GitLabContainer.java b/src/test/java/org/gitlab4j/test/GitLabContainer.java new file mode 100644 index 000000000..34d5dab15 --- /dev/null +++ b/src/test/java/org/gitlab4j/test/GitLabContainer.java @@ -0,0 +1,42 @@ +package org.gitlab4j.test; + +import java.time.Duration; + +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.containers.wait.strategy.WaitStrategy; +import org.testcontainers.utility.DockerImageName; + +public class GitLabContainer extends GenericContainer { + + + public final String version; + public final Version parsedVersion; + + public GitLabContainer(String version) { + super(DockerImageName.parse("gitlab/gitlab-ce:" + version)); + this.version = version; + this.parsedVersion = new Version(version); + + this.withExposedPorts(80) + .withEnv("GITLAB_OMNIBUS_CONFIG", "gitlab_rails['initial_root_password']=\"password\";gitlab_rails['lfs_enabled']=false;") + .waitingFor( + Wait + .forHttp("/") + .forStatusCode(302) + .forStatusCode(200) + .withStartupTimeout(Duration.ofSeconds(300)) + ); + } + + public String url() { + return "http://localhost:" + getMappedPort(80) + ""; + } + + @Override + public String toString() { + return "GitLabContainer [version=" + version + ", parsedVersion=" + parsedVersion + ", url()= " + url() + " ]"; + } + + +} diff --git a/src/test/java/org/gitlab4j/test/GitLabInvocationContextProvider.java b/src/test/java/org/gitlab4j/test/GitLabInvocationContextProvider.java new file mode 100644 index 000000000..efd20707d --- /dev/null +++ b/src/test/java/org/gitlab4j/test/GitLabInvocationContextProvider.java @@ -0,0 +1,54 @@ +package org.gitlab4j.test; + +import static java.util.Arrays.asList; + +import java.util.List; +import java.util.stream.Stream; + +import org.gitlab4j.test.SetupTeardownLauncherSessionListener.GitLabContainers; +import org.junit.jupiter.api.extension.Extension; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.ParameterContext; +import org.junit.jupiter.api.extension.ParameterResolver; +import org.junit.jupiter.api.extension.TestTemplateInvocationContext; +import org.junit.jupiter.api.extension.TestTemplateInvocationContextProvider; + +public class GitLabInvocationContextProvider implements TestTemplateInvocationContextProvider { + + @Override + public boolean supportsTestTemplate(ExtensionContext context) { + return true; + } + + @Override + public Stream provideTestTemplateInvocationContexts(ExtensionContext context) { + return GitLabContainers.containers().stream().map(this::invocationContext); + } + + private TestTemplateInvocationContext invocationContext(GitLabContainer gitLabcontainer) { + return new TestTemplateInvocationContext() { + + @Override + public String getDisplayName(int invocationIndex) { + return gitLabcontainer.version; + } + + @Override + public List getAdditionalExtensions() { + return asList( + new ParameterResolver() { + @Override + public boolean supportsParameter(ParameterContext parameterCtx, ExtensionContext extensionCtx) { + return parameterCtx.getParameter().getType().equals(GitLabContainer.class); + } + + @Override + public Object resolveParameter(ParameterContext parameterCtx, ExtensionContext extensionCtx) { + return gitLabcontainer; + } + }); + } + }; + } + +} \ No newline at end of file diff --git a/src/test/java/org/gitlab4j/test/SetupTeardownLauncherSessionListener.java b/src/test/java/org/gitlab4j/test/SetupTeardownLauncherSessionListener.java new file mode 100644 index 000000000..9e90885cb --- /dev/null +++ b/src/test/java/org/gitlab4j/test/SetupTeardownLauncherSessionListener.java @@ -0,0 +1,82 @@ +package org.gitlab4j.test; + +import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.gitlab4j.api.GitLabApi; +import org.gitlab4j.api.GitLabApiException; +import org.gitlab4j.api.models.User; +import org.junit.platform.launcher.LauncherSession; +import org.junit.platform.launcher.LauncherSessionListener; +import org.junit.platform.launcher.TestExecutionListener; +import org.junit.platform.launcher.TestPlan; + +public class SetupTeardownLauncherSessionListener implements LauncherSessionListener { + + private GitLabContainers gitLabContainers; + + @Override + public void launcherSessionOpened(LauncherSession session) { + session.getLauncher().registerTestExecutionListeners(new TestExecutionListener() { + @Override + public void testPlanExecutionStarted(TestPlan testPlan) { + if (gitLabContainers == null) { + gitLabContainers = new GitLabContainers(); + gitLabContainers.setUp(); + } + } + }); + } + + @Override + public void launcherSessionClosed(LauncherSession session) { + if (gitLabContainers != null) { + gitLabContainers.tearDown(); + gitLabContainers = null; + } + } + + static class GitLabContainers { + + private static final String[] GITLAB_VERSIONS = { + "15.4.2-ce.0", + "14.10.5-ce.0", + }; + + private static final Map containers = new HashMap<>(); + + public GitLabContainers() { + String propertyVersion = System.getProperty("gitlab4j.gitlab.version"); + + if (propertyVersion == null) { + for (String version : GITLAB_VERSIONS) { + containers.put(version, new GitLabContainer(version)); + } + } else { + containers.put(propertyVersion, new GitLabContainer(propertyVersion)); + } + } + + public static Collection containers() { + return Collections.unmodifiableCollection(containers.values()); + } + + void setUp() { +// containers.forEach((version, container) -> container.start()); + } + + void tearDown() { + containers.forEach((version, container) -> { + if (container.isRunning()) { + container.stop(); + } + }); + } + } +} \ No newline at end of file diff --git a/src/test/java/org/gitlab4j/test/Version.java b/src/test/java/org/gitlab4j/test/Version.java new file mode 100644 index 000000000..159bfae87 --- /dev/null +++ b/src/test/java/org/gitlab4j/test/Version.java @@ -0,0 +1,30 @@ +package org.gitlab4j.test; + +public class Version { + final String version; + final int major; + final int minor; + final int fix; + + Version(String version) { + this.version = version; + String[] split = version.substring(0, version.indexOf('-')).split("\\."); + major = Integer.valueOf(split[0]).intValue(); + minor = Integer.valueOf(split[1]).intValue(); + fix = Integer.valueOf(split[2]).intValue(); + } + + + public String version() { + return version; + } + + public boolean isBefore(Version minimalVersion) { + return major < minimalVersion.major || minor < minimalVersion.minor || minor < minimalVersion.fix; + } + + @Override + public String toString() { + return "Version [major=" + major + ", minor=" + minor + ", fix=" + fix + "]"; + } +} \ No newline at end of file