diff --git a/build.gradle b/build.gradle index 0fc7fa651f..3dd485847f 100644 --- a/build.gradle +++ b/build.gradle @@ -26,7 +26,9 @@ ext { ':client:java-spring-boot-autoconfigure': "${rootProject.name}-client-spring-boot-autoconfigure", ':client:java-spring-boot-starter': "${rootProject.name}-client-spring-boot-starter", ':client:java-spring-boot1-autoconfigure': "${rootProject.name}-client-spring-boot1-autoconfigure", - ':client:java-spring-boot1-starter': "${rootProject.name}-client-spring-boot1-starter" + ':client:java-spring-boot1-starter': "${rootProject.name}-client-spring-boot1-starter", + // Set the correct artifactId of 'testing-common'. + ':testing:testing-common': "${rootProject.name}-testing-common" ] } @@ -89,6 +91,10 @@ configure(projectsWithFlags('java')) { testCompile 'org.hamcrest:hamcrest-library' testCompile 'org.assertj:assertj-core' testCompile 'org.mockito:mockito-core' + testCompile 'org.junit.jupiter:junit-jupiter-api' + testRuntime 'org.junit.jupiter:junit-jupiter-engine' + testRuntime 'org.junit.platform:junit-platform-launcher' + testRuntime 'org.junit.vintage:junit-vintage-engine' } // Target Java 8. diff --git a/dependencies.yml b/dependencies.yml index bb9d6bfe25..800f76b818 100644 --- a/dependencies.yml +++ b/dependencies.yml @@ -150,6 +150,20 @@ junit: javadocs: - https://junit.org/junit4/javadoc/4.12/ +org.junit.jupiter: + junit-jupiter-api: + version: &JUNIT_JUPITER_VERSION '5.5.2' + javadocs: + - https://junit.org/junit5/docs/5.5.2/api/ + junit-jupiter-engine: + version: *JUNIT_JUPITER_VERSION +org.junit.platform: + junit-platform-launcher: + version: '1.5.2' +org.junit.vintage: + junit-vintage-engine: + version: '5.5.2' + kr.motd.gradle: sphinx-gradle-plugin: { version: '2.6.1' } diff --git a/it/src/test/java/com/linecorp/centraldogma/it/AbstractMultiClientTest.java b/it/src/test/java/com/linecorp/centraldogma/it/AbstractMultiClientTest.java index 98d7f63f71..4b72ce895e 100644 --- a/it/src/test/java/com/linecorp/centraldogma/it/AbstractMultiClientTest.java +++ b/it/src/test/java/com/linecorp/centraldogma/it/AbstractMultiClientTest.java @@ -27,7 +27,7 @@ import org.junit.runners.Parameterized.Parameters; import com.linecorp.centraldogma.client.CentralDogma; -import com.linecorp.centraldogma.testing.CentralDogmaRule; +import com.linecorp.centraldogma.testing.junit4.CentralDogmaRule; @RunWith(Parameterized.class) public abstract class AbstractMultiClientTest { diff --git a/it/src/test/java/com/linecorp/centraldogma/it/CacheTest.java b/it/src/test/java/com/linecorp/centraldogma/it/CacheTest.java index 11663a7d5a..bd973378c1 100644 --- a/it/src/test/java/com/linecorp/centraldogma/it/CacheTest.java +++ b/it/src/test/java/com/linecorp/centraldogma/it/CacheTest.java @@ -36,7 +36,7 @@ import com.linecorp.centraldogma.common.PushResult; import com.linecorp.centraldogma.common.Query; import com.linecorp.centraldogma.common.Revision; -import com.linecorp.centraldogma.testing.CentralDogmaRule; +import com.linecorp.centraldogma.testing.junit4.CentralDogmaRule; public class CacheTest extends AbstractMultiClientTest { diff --git a/it/src/test/java/com/linecorp/centraldogma/it/CentralDogmaEndpointGroupTest.java b/it/src/test/java/com/linecorp/centraldogma/it/CentralDogmaEndpointGroupTest.java index 498becfc5b..7a2db7cde1 100644 --- a/it/src/test/java/com/linecorp/centraldogma/it/CentralDogmaEndpointGroupTest.java +++ b/it/src/test/java/com/linecorp/centraldogma/it/CentralDogmaEndpointGroupTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 LINE Corporation + * Copyright 2020 LINE Corporation * * LINE Corporation licenses this file to you under the Apache License, * version 2.0 (the "License"); you may not use this file except in compliance @@ -25,8 +25,9 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Timeout; +import org.junit.jupiter.api.extension.RegisterExtension; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; @@ -41,9 +42,10 @@ import com.linecorp.centraldogma.common.Change; import com.linecorp.centraldogma.common.Query; import com.linecorp.centraldogma.common.Revision; -import com.linecorp.centraldogma.testing.CentralDogmaRule; +import com.linecorp.centraldogma.testing.junit.CentralDogmaExtension; + +class CentralDogmaEndpointGroupTest { -public class CentralDogmaEndpointGroupTest { private static final List HOST_AND_PORT_LIST = ImmutableList.of( "1.2.3.4:5678", "centraldogma-sample001.com:1234"); @@ -62,8 +64,8 @@ public class CentralDogmaEndpointGroupTest { Endpoint.of("1.2.3.4", 5678), Endpoint.of("centraldogma-sample001.com", 1234)); - @Rule - public final CentralDogmaRule dogma = new CentralDogmaRule() { + @RegisterExtension + final CentralDogmaExtension dogma = new CentralDogmaExtension() { @Override protected void scaffold(CentralDogma client) { client.createProject("directory").join(); @@ -78,10 +80,15 @@ protected void scaffold(CentralDogma client) { String.join("\n", HOST_AND_PORT_LIST))) .join(); } + + @Override + protected boolean runForEachTest() { + return true; + } }; @Test - public void json() throws Exception { + void json() throws Exception { try (Watcher watcher = dogma.client().fileWatcher("directory", "my-service", Query.ofJson("/endpoint.json"))) { final CentralDogmaEndpointGroup endpointGroup = CentralDogmaEndpointGroup.ofWatcher( @@ -91,8 +98,9 @@ public void json() throws Exception { } } - @Test(timeout = 10000) - public void text() throws Exception { + @Test + @Timeout(10) + void text() throws Exception { try (Watcher watcher = dogma.client().fileWatcher("directory", "my-service", Query.ofText("/endpoints.txt"))) { final CountDownLatch latch = new CountDownLatch(2); @@ -114,7 +122,7 @@ public void text() throws Exception { } @Test - public void recoverFromNotFound() throws Exception { + void recoverFromNotFound() throws Exception { try (Watcher watcher = dogma.client().fileWatcher("directory", "new-service", Query.ofText("/endpoints.txt"))) { diff --git a/it/src/test/java/com/linecorp/centraldogma/it/CentralDogmaRuleWithScaffolding.java b/it/src/test/java/com/linecorp/centraldogma/it/CentralDogmaRuleWithScaffolding.java index 9a79fc18fd..6d24d0dfc8 100644 --- a/it/src/test/java/com/linecorp/centraldogma/it/CentralDogmaRuleWithScaffolding.java +++ b/it/src/test/java/com/linecorp/centraldogma/it/CentralDogmaRuleWithScaffolding.java @@ -27,7 +27,7 @@ import com.linecorp.centraldogma.client.CentralDogma; import com.linecorp.centraldogma.common.Change; import com.linecorp.centraldogma.common.Revision; -import com.linecorp.centraldogma.testing.CentralDogmaRule; +import com.linecorp.centraldogma.testing.junit4.CentralDogmaRule; public class CentralDogmaRuleWithScaffolding extends CentralDogmaRule { diff --git a/it/src/test/java/com/linecorp/centraldogma/it/ClientType.java b/it/src/test/java/com/linecorp/centraldogma/it/ClientType.java index 924fecf480..a5b5c15590 100644 --- a/it/src/test/java/com/linecorp/centraldogma/it/ClientType.java +++ b/it/src/test/java/com/linecorp/centraldogma/it/ClientType.java @@ -19,7 +19,7 @@ import java.util.function.Function; import com.linecorp.centraldogma.client.CentralDogma; -import com.linecorp.centraldogma.testing.CentralDogmaRule; +import com.linecorp.centraldogma.testing.junit4.CentralDogmaRule; enum ClientType { DEFAULT(CentralDogmaRule::client), diff --git a/it/src/test/java/com/linecorp/centraldogma/it/MergeFileTest.java b/it/src/test/java/com/linecorp/centraldogma/it/MergeFileTest.java index d968953da3..87508fb8ca 100644 --- a/it/src/test/java/com/linecorp/centraldogma/it/MergeFileTest.java +++ b/it/src/test/java/com/linecorp/centraldogma/it/MergeFileTest.java @@ -35,7 +35,7 @@ import com.linecorp.centraldogma.common.MergedEntry; import com.linecorp.centraldogma.common.QueryExecutionException; import com.linecorp.centraldogma.common.Revision; -import com.linecorp.centraldogma.testing.CentralDogmaRule; +import com.linecorp.centraldogma.testing.junit4.CentralDogmaRule; public class MergeFileTest extends AbstractMultiClientTest { diff --git a/it/src/test/java/com/linecorp/centraldogma/it/mirror/git/GitMirrorAuthTest.java b/it/src/test/java/com/linecorp/centraldogma/it/mirror/git/GitMirrorAuthTest.java index adb9fe0405..9676b7b8b6 100644 --- a/it/src/test/java/com/linecorp/centraldogma/it/mirror/git/GitMirrorAuthTest.java +++ b/it/src/test/java/com/linecorp/centraldogma/it/mirror/git/GitMirrorAuthTest.java @@ -52,7 +52,7 @@ import com.linecorp.centraldogma.server.CentralDogmaBuilder; import com.linecorp.centraldogma.server.MirroringService; import com.linecorp.centraldogma.server.storage.project.Project; -import com.linecorp.centraldogma.testing.CentralDogmaRule; +import com.linecorp.centraldogma.testing.junit4.CentralDogmaRule; @RunWith(Parameterized.class) public class GitMirrorAuthTest { diff --git a/it/src/test/java/com/linecorp/centraldogma/it/mirror/git/GitMirrorTest.java b/it/src/test/java/com/linecorp/centraldogma/it/mirror/git/GitMirrorTest.java index b774ca65fc..da4f69cde8 100644 --- a/it/src/test/java/com/linecorp/centraldogma/it/mirror/git/GitMirrorTest.java +++ b/it/src/test/java/com/linecorp/centraldogma/it/mirror/git/GitMirrorTest.java @@ -61,7 +61,7 @@ import com.linecorp.centraldogma.server.MirrorException; import com.linecorp.centraldogma.server.MirroringService; import com.linecorp.centraldogma.server.storage.project.Project; -import com.linecorp.centraldogma.testing.CentralDogmaRule; +import com.linecorp.centraldogma.testing.junit4.CentralDogmaRule; public class GitMirrorTest { diff --git a/it/src/test/java/com/linecorp/centraldogma/it/updater/CentralDogmaBeanTest.java b/it/src/test/java/com/linecorp/centraldogma/it/updater/CentralDogmaBeanTest.java index 0f1c329ba3..19499dd5bf 100644 --- a/it/src/test/java/com/linecorp/centraldogma/it/updater/CentralDogmaBeanTest.java +++ b/it/src/test/java/com/linecorp/centraldogma/it/updater/CentralDogmaBeanTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 LINE Corporation + * Copyright 2020 LINE Corporation * * LINE Corporation licenses this file to you under the Apache License, * version 2.0 (the "License"); you may not use this file except in compliance @@ -29,9 +29,9 @@ import javax.annotation.Nullable; import org.awaitility.core.ConditionTimeoutException; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.ImmutableList; @@ -43,12 +43,12 @@ import com.linecorp.centraldogma.common.Change; import com.linecorp.centraldogma.common.PushResult; import com.linecorp.centraldogma.common.Revision; -import com.linecorp.centraldogma.testing.CentralDogmaRule; +import com.linecorp.centraldogma.testing.junit.CentralDogmaExtension; -public class CentralDogmaBeanTest { +class CentralDogmaBeanTest { - @ClassRule - public static final CentralDogmaRule dogma = new CentralDogmaRule() { + @RegisterExtension + static final CentralDogmaExtension dogma = new CentralDogmaExtension() { @Override protected void scaffold(CentralDogma client) { client.createProject("a").join(); @@ -64,13 +64,13 @@ protected void scaffold(CentralDogma client) { private CentralDogmaBeanFactory factory; - @Before - public void setup() { + @BeforeEach + void setUp() { factory = new CentralDogmaBeanFactory(dogma.client(), objectMapper); } @Test - public void stayDefault() { + void stayDefault() { final TestPropertyDefault property = factory.get(new TestPropertyDefault(), TestPropertyDefault.class); // Delay to detect if data for this bean has already been written to the server. @@ -82,7 +82,7 @@ public void stayDefault() { } @Test - public void test() throws Exception { + void test() { final int[] called = new int[1]; final Consumer listener = testProperty -> called[0] = 1; final CentralDogma client = dogma.client(); @@ -142,7 +142,7 @@ public void test() throws Exception { } @Test - public void overrideSettings() throws Exception { + void overrideSettings() { final CentralDogma client = dogma.client(); client.push("alice", "bob", Revision.HEAD, "Add charlie.json", @@ -173,7 +173,7 @@ public void overrideSettings() throws Exception { } @Test - public void updateListenerIgnoreDefault() { + void updateListenerIgnoreDefault() { final CentralDogma client = dogma.client(); final AtomicReference update = new AtomicReference<>(); diff --git a/server-auth/saml/src/test/java/com/linecorp/centraldogma/server/auth/saml/SamlAuthTest.java b/server-auth/saml/src/test/java/com/linecorp/centraldogma/server/auth/saml/SamlAuthTest.java index a8e9cdd4e7..ee7565eaa6 100644 --- a/server-auth/saml/src/test/java/com/linecorp/centraldogma/server/auth/saml/SamlAuthTest.java +++ b/server-auth/saml/src/test/java/com/linecorp/centraldogma/server/auth/saml/SamlAuthTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 LINE Corporation + * Copyright 2020 LINE Corporation * * LINE Corporation licenses this file to you under the Apache License, * version 2.0 (the "License"); you may not use this file except in compliance @@ -17,8 +17,8 @@ import static org.assertj.core.api.Assertions.assertThat; -import org.junit.ClassRule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import com.linecorp.armeria.common.AggregatedHttpResponse; import com.linecorp.armeria.common.HttpHeaderNames; @@ -27,9 +27,9 @@ import com.linecorp.centraldogma.internal.Jackson; import com.linecorp.centraldogma.server.CentralDogmaBuilder; import com.linecorp.centraldogma.server.auth.AuthProvider; -import com.linecorp.centraldogma.testing.CentralDogmaRule; +import com.linecorp.centraldogma.testing.junit.CentralDogmaExtension; -public class SamlAuthTest { +class SamlAuthTest { private static final SamlAuthProperties PROPERTIES; @@ -60,8 +60,8 @@ public class SamlAuthTest { } } - @ClassRule - public static final CentralDogmaRule rule = new CentralDogmaRule() { + @RegisterExtension + static final CentralDogmaExtension dogma = new CentralDogmaExtension() { @Override protected void configure(CentralDogmaBuilder builder) { builder.authProviderFactory(new SamlAuthProviderFactory()); @@ -71,32 +71,32 @@ protected void configure(CentralDogmaBuilder builder) { }; @Test - public void shouldUseBuiltinWebPageOnlyForLogout() throws Exception { + void shouldUseBuiltinWebPageOnlyForLogout() { AggregatedHttpResponse resp; // Receive HTML which submits SAMLRequest to IdP. - resp = rule.httpClient().get(AuthProvider.LOGIN_PATH).aggregate().join(); + resp = dogma.httpClient().get(AuthProvider.LOGIN_PATH).aggregate().join(); assertThat(resp.status()).isEqualTo(HttpStatus.OK); assertThat(resp.headers().contentType()).isEqualTo(MediaType.HTML_UTF_8); assertThat(resp.contentUtf8()).contains(" { @@ -55,17 +55,22 @@ protected void configure(CentralDogmaBuilder builder) { })); builder.webAppEnabled(true); } + + @Override + protected boolean runForEachTest() { + return true; + } }; private WebClient client; - @Before - public void setClient() { - client = rule.httpClient(); + @BeforeEach + void setClient() { + client = dogma.httpClient(); } @Test - public void password() throws Exception { // grant_type=password + void password() throws Exception { // grant_type=password loginAndLogout(login(client, USERNAME, PASSWORD)); } @@ -84,23 +89,23 @@ private void loginAndLogout(AggregatedHttpResponse loginRes) throws Exception { } @Test - public void basicAuth() throws Exception { + void basicAuth() throws Exception { loginAndLogout(loginWithBasicAuth(client, USERNAME, PASSWORD)); } @Test - public void incorrectLogin() throws Exception { + void incorrectLogin() { assertThat(login(client, USERNAME, WRONG_PASSWORD).status()).isEqualTo(HttpStatus.UNAUTHORIZED); } @Test - public void incorrectLogout() throws Exception { + void incorrectLogout() { assertThat(logout(client, WRONG_SESSION_ID).status()).isEqualTo(HttpStatus.UNAUTHORIZED); assertThat(logout(client, MALFORMED_SESSION_ID).status()).isEqualTo(HttpStatus.UNAUTHORIZED); } @Test - public void shouldUseBuiltinWebPages() throws Exception { + void shouldUseBuiltinWebPages() { AggregatedHttpResponse resp; resp = client.get(AuthProvider.LOGIN_PATH).aggregate().join(); assertThat(resp.status()).isEqualTo(HttpStatus.MOVED_PERMANENTLY); diff --git a/server/src/test/java/com/linecorp/centraldogma/server/ContentCompressionTest.java b/server/src/test/java/com/linecorp/centraldogma/server/ContentCompressionTest.java index 90d2027764..7a7fa60e67 100644 --- a/server/src/test/java/com/linecorp/centraldogma/server/ContentCompressionTest.java +++ b/server/src/test/java/com/linecorp/centraldogma/server/ContentCompressionTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 LINE Corporation + * Copyright 2020 LINE Corporation * * LINE Corporation licenses this file to you under the Apache License, * version 2.0 (the "License"); you may not use this file except in compliance @@ -25,8 +25,8 @@ import java.util.zip.InflaterInputStream; import org.apache.thrift.TException; -import org.junit.ClassRule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import com.fasterxml.jackson.core.JsonParseException; import com.google.common.base.Strings; @@ -50,20 +50,20 @@ import com.linecorp.centraldogma.internal.thrift.GetFileResult; import com.linecorp.centraldogma.internal.thrift.Query; import com.linecorp.centraldogma.internal.thrift.QueryType; -import com.linecorp.centraldogma.testing.CentralDogmaRule; +import com.linecorp.centraldogma.testing.junit.CentralDogmaExtension; /** * Makes sure an API response is compressed if a client requested with an 'accept-encoding' header. */ -public class ContentCompressionTest { +class ContentCompressionTest { private static final String PROJ = "proj"; private static final String REPO = "repo"; private static final String PATH = "/foo.txt"; private static final String CONTENT = Strings.repeat("Central Dogma ", 1024); - @ClassRule - public static final CentralDogmaRule rule = new CentralDogmaRule() { + @RegisterExtension + static final CentralDogmaExtension dogma = new CentralDogmaExtension() { @Override protected void scaffold(CentralDogma client) { client.createProject(PROJ).join(); @@ -74,14 +74,14 @@ protected void scaffold(CentralDogma client) { }; @Test - public void thrift() throws Exception { + void thrift() throws Exception { final com.linecorp.centraldogma.internal.thrift.Revision head = new com.linecorp.centraldogma.internal.thrift.Revision(-1, 0); final Query query = new Query(PATH, QueryType.IDENTITY, ImmutableList.of()); // Should fail to decode without the decompressor. final Iface clientWithoutDecompressor = new ClientBuilder( - "ttext+http://127.0.0.1:" + rule.serverAddress().getPort() + "/cd/thrift/v1") + "ttext+http://127.0.0.1:" + dogma.serverAddress().getPort() + "/cd/thrift/v1") .setHttpHeader(HttpHeaderNames.AUTHORIZATION, "Bearer " + CsrfToken.ANONYMOUS) .setHttpHeader(HttpHeaderNames.ACCEPT_ENCODING, "deflate") .build(Iface.class); @@ -102,9 +102,9 @@ public void thrift() throws Exception { } @Test - public void http() throws Exception { + void http() throws Exception { final WebClient client = - WebClient.builder("http://127.0.0.1:" + rule.serverAddress().getPort()) + WebClient.builder("http://127.0.0.1:" + dogma.serverAddress().getPort()) .setHttpHeader(HttpHeaderNames.AUTHORIZATION, "Bearer " + CsrfToken.ANONYMOUS) .setHttpHeader(HttpHeaderNames.ACCEPT_ENCODING, "deflate") .build(); diff --git a/server/src/test/java/com/linecorp/centraldogma/server/MetricsTest.java b/server/src/test/java/com/linecorp/centraldogma/server/MetricsTest.java index 5ed94feb50..6f320f27b5 100644 --- a/server/src/test/java/com/linecorp/centraldogma/server/MetricsTest.java +++ b/server/src/test/java/com/linecorp/centraldogma/server/MetricsTest.java @@ -25,7 +25,7 @@ import com.linecorp.armeria.common.AggregatedHttpResponse; import com.linecorp.armeria.common.HttpStatus; import com.linecorp.armeria.common.MediaType; -import com.linecorp.centraldogma.testing.CentralDogmaRule; +import com.linecorp.centraldogma.testing.junit4.CentralDogmaRule; import io.micrometer.prometheus.PrometheusMeterRegistry; import io.prometheus.client.exporter.common.TextFormat; diff --git a/server/src/test/java/com/linecorp/centraldogma/server/TlsServerTest.java b/server/src/test/java/com/linecorp/centraldogma/server/TlsServerTest.java index 6e9c041a70..ea0c80b99c 100644 --- a/server/src/test/java/com/linecorp/centraldogma/server/TlsServerTest.java +++ b/server/src/test/java/com/linecorp/centraldogma/server/TlsServerTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 LINE Corporation + * Copyright 2020 LINE Corporation * * LINE Corporation licenses this file to you under the Apache License, * version 2.0 (the "License"); you may not use this file except in compliance @@ -17,19 +17,19 @@ import static org.assertj.core.api.Assertions.assertThat; -import org.junit.ClassRule; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; -import com.linecorp.centraldogma.testing.CentralDogmaRule; +import com.linecorp.centraldogma.testing.junit.CentralDogmaExtension; -public class TlsServerTest { +class TlsServerTest { - @ClassRule - public static CentralDogmaRule rule = new CentralDogmaRule(true); + @RegisterExtension + static CentralDogmaExtension dogma = new CentralDogmaExtension(true); @Test - public void tls() { - rule.client().createProject("overTls").join(); - assertThat(rule.client().listProjects().join()).contains("overTls"); + void tls() { + dogma.client().createProject("overTls").join(); + assertThat(dogma.client().listProjects().join()).contains("overTls"); } } diff --git a/server/src/test/java/com/linecorp/centraldogma/server/internal/api/AdministrativeServiceTest.java b/server/src/test/java/com/linecorp/centraldogma/server/internal/api/AdministrativeServiceTest.java index 30a4a23354..cbe44b2d18 100644 --- a/server/src/test/java/com/linecorp/centraldogma/server/internal/api/AdministrativeServiceTest.java +++ b/server/src/test/java/com/linecorp/centraldogma/server/internal/api/AdministrativeServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 LINE Corporation + * Copyright 2020 LINE Corporation * * LINE Corporation licenses this file to you under the Apache License, * version 2.0 (the "License"); you may not use this file except in compliance @@ -22,9 +22,9 @@ import java.net.InetSocketAddress; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import com.linecorp.armeria.client.WebClient; import com.linecorp.armeria.common.AggregatedHttpResponse; @@ -33,17 +33,22 @@ import com.linecorp.armeria.common.HttpStatus; import com.linecorp.armeria.common.MediaType; import com.linecorp.armeria.common.RequestHeaders; -import com.linecorp.centraldogma.testing.CentralDogmaRule; +import com.linecorp.centraldogma.testing.junit.CentralDogmaExtension; -public class AdministrativeServiceTest { +class AdministrativeServiceTest { - @Rule - public final CentralDogmaRule dogma = new CentralDogmaRule(); + @RegisterExtension + final CentralDogmaExtension dogma = new CentralDogmaExtension() { + @Override + protected boolean runForEachTest() { + return true; + } + }; private static WebClient webClient; - @Before - public void init() { + @BeforeEach + void setUp() { final InetSocketAddress serverAddress = dogma.dogma().activePort().get().localAddress(); final String serverUri = "http://127.0.0.1:" + serverAddress.getPort(); webClient = WebClient.builder(serverUri) @@ -52,7 +57,7 @@ public void init() { } @Test - public void status() { + void status() { final AggregatedHttpResponse res = webClient.get(API_V1_PATH_PREFIX + "status").aggregate().join(); assertThat(res.status()).isEqualTo(HttpStatus.OK); assertThatJson(res.contentUtf8()).isEqualTo( @@ -60,7 +65,7 @@ public void status() { } @Test - public void updateStatus_setUnwritable() { + void updateStatus_setUnwritable() { final AggregatedHttpResponse res = webClient.execute( RequestHeaders.of(HttpMethod.PATCH, API_V1_PATH_PREFIX + "status", HttpHeaderNames.CONTENT_TYPE, MediaType.JSON_PATCH), @@ -72,7 +77,7 @@ public void updateStatus_setUnwritable() { } @Test - public void updateStatus_setUnwritableAndNonReplicating() { + void updateStatus_setUnwritableAndNonReplicating() { final AggregatedHttpResponse res = webClient.execute( RequestHeaders.of(HttpMethod.PATCH, API_V1_PATH_PREFIX + "status", HttpHeaderNames.CONTENT_TYPE, MediaType.JSON_PATCH), @@ -85,7 +90,7 @@ public void updateStatus_setUnwritableAndNonReplicating() { } @Test - public void updateStatus_setWritableAndNonReplicating() { + void updateStatus_setWritableAndNonReplicating() { final AggregatedHttpResponse res = webClient.execute( RequestHeaders.of(HttpMethod.PATCH, API_V1_PATH_PREFIX + "status", HttpHeaderNames.CONTENT_TYPE, MediaType.JSON_PATCH), @@ -96,7 +101,7 @@ public void updateStatus_setWritableAndNonReplicating() { } @Test - public void redundantUpdateStatus_Writable() { + void redundantUpdateStatus_Writable() { final AggregatedHttpResponse res = webClient.execute( RequestHeaders.of(HttpMethod.PATCH, API_V1_PATH_PREFIX + "status", HttpHeaderNames.CONTENT_TYPE, MediaType.JSON_PATCH), @@ -106,7 +111,7 @@ public void redundantUpdateStatus_Writable() { } @Test - public void redundantUpdateStatus_Replicating() { + void redundantUpdateStatus_Replicating() { final AggregatedHttpResponse res = webClient.execute( RequestHeaders.of(HttpMethod.PATCH, API_V1_PATH_PREFIX + "status", HttpHeaderNames.CONTENT_TYPE, MediaType.JSON_PATCH), @@ -116,7 +121,7 @@ public void redundantUpdateStatus_Replicating() { } @Test - public void updateStatus_leaveReadOnlyMode() { + void updateStatus_leaveReadOnlyMode() { // Enter read-only mode. updateStatus_setUnwritable(); // Try to enter writable mode. diff --git a/server/src/test/java/com/linecorp/centraldogma/server/internal/api/ContentServiceV1TestBase.java b/server/src/test/java/com/linecorp/centraldogma/server/internal/api/ContentServiceV1TestBase.java index 1ebf714222..fdd3153e99 100644 --- a/server/src/test/java/com/linecorp/centraldogma/server/internal/api/ContentServiceV1TestBase.java +++ b/server/src/test/java/com/linecorp/centraldogma/server/internal/api/ContentServiceV1TestBase.java @@ -26,7 +26,7 @@ import com.linecorp.armeria.common.MediaType; import com.linecorp.armeria.common.RequestHeaders; import com.linecorp.centraldogma.server.CentralDogmaBuilder; -import com.linecorp.centraldogma.testing.CentralDogmaRule; +import com.linecorp.centraldogma.testing.junit4.CentralDogmaRule; public class ContentServiceV1TestBase { diff --git a/server/src/test/java/com/linecorp/centraldogma/server/internal/api/ListCommitsAndDiffTest.java b/server/src/test/java/com/linecorp/centraldogma/server/internal/api/ListCommitsAndDiffTest.java index 290e58796d..824acc2141 100644 --- a/server/src/test/java/com/linecorp/centraldogma/server/internal/api/ListCommitsAndDiffTest.java +++ b/server/src/test/java/com/linecorp/centraldogma/server/internal/api/ListCommitsAndDiffTest.java @@ -30,7 +30,7 @@ import com.linecorp.armeria.common.HttpMethod; import com.linecorp.armeria.common.MediaType; import com.linecorp.armeria.common.RequestHeaders; -import com.linecorp.centraldogma.testing.CentralDogmaRule; +import com.linecorp.centraldogma.testing.junit4.CentralDogmaRule; public class ListCommitsAndDiffTest { diff --git a/server/src/test/java/com/linecorp/centraldogma/server/internal/api/ProjectServiceV1Test.java b/server/src/test/java/com/linecorp/centraldogma/server/internal/api/ProjectServiceV1Test.java index 444eafdf1f..752fa2267e 100644 --- a/server/src/test/java/com/linecorp/centraldogma/server/internal/api/ProjectServiceV1Test.java +++ b/server/src/test/java/com/linecorp/centraldogma/server/internal/api/ProjectServiceV1Test.java @@ -39,7 +39,7 @@ import com.linecorp.armeria.common.ResponseHeaders; import com.linecorp.centraldogma.common.ProjectExistsException; import com.linecorp.centraldogma.internal.Jackson; -import com.linecorp.centraldogma.testing.CentralDogmaRule; +import com.linecorp.centraldogma.testing.junit4.CentralDogmaRule; public class ProjectServiceV1Test { diff --git a/server/src/test/java/com/linecorp/centraldogma/server/internal/api/RepositoryServiceV1Test.java b/server/src/test/java/com/linecorp/centraldogma/server/internal/api/RepositoryServiceV1Test.java index 14a8e67c5f..897f2524c5 100644 --- a/server/src/test/java/com/linecorp/centraldogma/server/internal/api/RepositoryServiceV1Test.java +++ b/server/src/test/java/com/linecorp/centraldogma/server/internal/api/RepositoryServiceV1Test.java @@ -42,7 +42,7 @@ import com.linecorp.centraldogma.common.RepositoryExistsException; import com.linecorp.centraldogma.internal.Jackson; import com.linecorp.centraldogma.server.storage.project.Project; -import com.linecorp.centraldogma.testing.CentralDogmaRule; +import com.linecorp.centraldogma.testing.junit4.CentralDogmaRule; public class RepositoryServiceV1Test { diff --git a/server/src/test/java/com/linecorp/centraldogma/server/internal/replication/StartStopWithoutInitialQuorumTest.java b/server/src/test/java/com/linecorp/centraldogma/server/internal/replication/StartStopWithoutInitialQuorumTest.java index 777eebf295..531e1643e3 100644 --- a/server/src/test/java/com/linecorp/centraldogma/server/internal/replication/StartStopWithoutInitialQuorumTest.java +++ b/server/src/test/java/com/linecorp/centraldogma/server/internal/replication/StartStopWithoutInitialQuorumTest.java @@ -30,7 +30,7 @@ import com.linecorp.centraldogma.server.CentralDogmaBuilder; import com.linecorp.centraldogma.server.ZooKeeperAddress; import com.linecorp.centraldogma.server.ZooKeeperReplicationConfig; -import com.linecorp.centraldogma.testing.CentralDogmaRule; +import com.linecorp.centraldogma.testing.junit4.CentralDogmaRule; /** * Makes sure that we can stop a replica that's waiting for the initial quorum. diff --git a/server/src/test/java/com/linecorp/centraldogma/server/metadata/ThriftBackwardCompatibilityTest.java b/server/src/test/java/com/linecorp/centraldogma/server/metadata/ThriftBackwardCompatibilityTest.java index 2dfc2d7136..caef353b0a 100644 --- a/server/src/test/java/com/linecorp/centraldogma/server/metadata/ThriftBackwardCompatibilityTest.java +++ b/server/src/test/java/com/linecorp/centraldogma/server/metadata/ThriftBackwardCompatibilityTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 LINE Corporation + * Copyright 2020 LINE Corporation * * LINE Corporation licenses this file to you under the Apache License, * version 2.0 (the "License"); you may not use this file except in compliance @@ -28,9 +28,9 @@ import java.util.List; import java.util.stream.Collectors; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.Test; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; import com.fasterxml.jackson.databind.JsonNode; import com.google.common.collect.ImmutableList; @@ -47,12 +47,12 @@ import com.linecorp.centraldogma.internal.thrift.ChangeType; import com.linecorp.centraldogma.internal.thrift.Comment; import com.linecorp.centraldogma.internal.thrift.Revision; -import com.linecorp.centraldogma.testing.CentralDogmaRule; +import com.linecorp.centraldogma.testing.junit.CentralDogmaExtension; -public class ThriftBackwardCompatibilityTest { +class ThriftBackwardCompatibilityTest { - @ClassRule - public static final CentralDogmaRule dogma = new CentralDogmaRule(); + @RegisterExtension + static final CentralDogmaExtension dogma = new CentralDogmaExtension(); private static WebClient webClient; private static Iface client; @@ -62,8 +62,8 @@ public class ThriftBackwardCompatibilityTest { private static final String projectName = "foo"; - @BeforeClass - public static void init() { + @BeforeAll + static void init() { final InetSocketAddress serverAddress = dogma.dogma().activePort().get().localAddress(); webClient = WebClient.builder("http://127.0.0.1:" + serverAddress.getPort()) .addHttpHeader(HttpHeaderNames.AUTHORIZATION, "Bearer " + CsrfToken.ANONYMOUS) @@ -75,7 +75,7 @@ public static void init() { } @Test - public void shouldBackwardCompatible() throws Exception { + void shouldBackwardCompatible() throws Exception { final String repo1 = "repo1"; client.createProject(projectName); diff --git a/settings.gradle b/settings.gradle index dc077d72bf..2897e1bfb5 100644 --- a/settings.gradle +++ b/settings.gradle @@ -18,7 +18,12 @@ includeWithFlags ':common-legacy', 'java', 'publish', ' includeWithFlags ':server', 'java', 'publish', 'relocate' includeWithFlags ':server-auth:saml', 'java', 'publish', 'relocate' includeWithFlags ':server-auth:shiro', 'java', 'publish', 'relocate' -includeWithFlags ':testing', 'java', 'publish', 'relocate' +includeWithFlags ':testing:testing-common', 'java', 'publish', 'relocate' +includeWithFlags ':testing:junit', 'java', 'publish', 'relocate' +includeWithFlags ':testing:junit4', 'java', 'publish', 'relocate' + +// Set correct directory names +project(':testing:testing-common').projectDir = file('testing/common') // Command line interface include ':cli' diff --git a/testing-internal/build.gradle b/testing-internal/build.gradle index 6aa6bd8ab4..4710374fc6 100644 --- a/testing-internal/build.gradle +++ b/testing-internal/build.gradle @@ -1,6 +1,7 @@ dependencies { - compile project(':testing') - compile 'junit:junit' + compile project(':testing:junit') + compile project(':testing:junit4') + compile 'org.assertj:assertj-core' compile 'net.javacrumbs.json-unit:json-unit-fluent' compile 'ch.qos.logback:logback-classic' diff --git a/testing/build.gradle b/testing/common/build.gradle similarity index 79% rename from testing/build.gradle rename to testing/common/build.gradle index a4964e9602..24da3641f4 100644 --- a/testing/build.gradle +++ b/testing/common/build.gradle @@ -1,5 +1,4 @@ dependencies { compile project(':client:java-armeria-legacy') compile project(':server') - compile 'junit:junit' } diff --git a/testing/src/main/java/com/linecorp/centraldogma/testing/CentralDogmaRule.java b/testing/common/src/main/java/com/linecorp/centraldogma/testing/internal/CentralDogmaRuleDelegate.java similarity index 76% rename from testing/src/main/java/com/linecorp/centraldogma/testing/CentralDogmaRule.java rename to testing/common/src/main/java/com/linecorp/centraldogma/testing/internal/CentralDogmaRuleDelegate.java index 2024fb72e1..150368319d 100644 --- a/testing/src/main/java/com/linecorp/centraldogma/testing/CentralDogmaRule.java +++ b/testing/common/src/main/java/com/linecorp/centraldogma/testing/internal/CentralDogmaRuleDelegate.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 LINE Corporation + * Copyright 2020 LINE Corporation * * LINE Corporation licenses this file to you under the Apache License, * version 2.0 (the "License"); you may not use this file except in compliance @@ -14,10 +14,10 @@ * under the License. */ -package com.linecorp.centraldogma.testing; +package com.linecorp.centraldogma.testing.internal; +import java.io.File; import java.io.IOError; -import java.io.IOException; import java.net.InetSocketAddress; import java.net.UnknownHostException; import java.util.Optional; @@ -25,11 +25,6 @@ import javax.annotation.Nullable; -import org.junit.Rule; -import org.junit.rules.TemporaryFolder; - -import com.spotify.futures.CompletableFutures; - import com.linecorp.armeria.client.ClientFactory; import com.linecorp.armeria.client.WebClient; import com.linecorp.armeria.common.SessionProtocol; @@ -49,23 +44,9 @@ import io.netty.util.NetUtil; /** - * JUnit {@link Rule} that starts an embedded Central Dogma server. - * - *
{@code
- * > public class MyTest {
- * >     @ClassRule
- * >     public static final CentralDogmaRule rule = new CentralDogmaRule();
- * >
- * >     @Test
- * >     public void test() throws Exception {
- * >         CentralDogma dogma = rule.client();
- * >         dogma.push(...).join();
- * >         ...
- * >     }
- * > }
- * }
+ * A delegate that has common testing methods of {@link com.linecorp.centraldogma.server.CentralDogma}. */ -public class CentralDogmaRule extends TemporaryFolder { +public class CentralDogmaRuleDelegate { private static final InetSocketAddress TEST_PORT = new InetSocketAddress(NetUtil.LOCALHOST4, 0); @@ -81,12 +62,91 @@ public class CentralDogmaRule extends TemporaryFolder { @Nullable private volatile InetSocketAddress serverAddress; - public CentralDogmaRule() { - this(false); + /** + * Creates a new instance. + */ + public CentralDogmaRuleDelegate(boolean useTls) { + this.useTls = useTls; } - public CentralDogmaRule(boolean useTls) { - this.useTls = useTls; + /** + * Starts an embedded server and calls {@link #scaffold(CentralDogma)}. + */ + public void setUp(File dataDir) { + startAsync(dataDir).join(); + final CentralDogma client = this.client; + assert client != null; + assert legacyClient != null; + scaffold(client); + } + + /** + * Creates a new server, configures it with {@link #configure(CentralDogmaBuilder)}, + * and starts the server asynchronously. + */ + public final CompletableFuture startAsync(File dataDir) { + final CentralDogmaBuilder builder = new CentralDogmaBuilder(dataDir) + .port(TEST_PORT, useTls ? SessionProtocol.HTTPS : SessionProtocol.HTTP) + .webAppEnabled(false) + .mirroringEnabled(false) + .gracefulShutdownTimeout(new GracefulShutdownTimeout(0, 0)); + + if (useTls) { + try { + final SelfSignedCertificate ssc = new SelfSignedCertificate(); + builder.tls(new TlsConfig(ssc.certificate(), ssc.privateKey(), null)); + } catch (Exception e) { + Exceptions.throwUnsafely(e); + } + } + + configure(builder); + + final com.linecorp.centraldogma.server.CentralDogma dogma = builder.build(); + this.dogma = dogma; + return dogma.start().thenRun(() -> { + final Optional activePort = dogma.activePort(); + if (!activePort.isPresent()) { + // Stopped already. + return; + } + + final InetSocketAddress serverAddress = activePort.get().localAddress(); + this.serverAddress = serverAddress; + + final ArmeriaCentralDogmaBuilder clientBuilder = new ArmeriaCentralDogmaBuilder(); + final LegacyCentralDogmaBuilder legacyClientBuilder = new LegacyCentralDogmaBuilder(); + + configureClientCommon(clientBuilder); + configureClientCommon(legacyClientBuilder); + configureClient(clientBuilder); + configureClient(legacyClientBuilder); + + try { + client = clientBuilder.build(); + legacyClient = legacyClientBuilder.build(); + } catch (UnknownHostException e) { + // Should never reach here. + throw new IOError(e); + } + + webClient = WebClient.of( + "h2c://" + serverAddress.getHostString() + ':' + serverAddress.getPort()); + }); + } + + /** + * Stops the server. + */ + public final CompletableFuture stopAsync() { + final com.linecorp.centraldogma.server.CentralDogma dogma = this.dogma; + this.dogma = null; + + if (dogma != null) { + return dogma.stop(); + } else { + return CompletableFuture.completedFuture(null); + } } /** @@ -171,91 +231,25 @@ public final InetSocketAddress serverAddress() { } /** - * Starts an embedded server with {@link #start()} and calls {@link #scaffold(CentralDogma)}. + * Override this method to configure the server. */ - @Override - protected void before() throws Throwable { - super.before(); - start(); - final CentralDogma client = this.client; - assert client != null; - assert legacyClient != null; - scaffold(client); - } + protected void configure(CentralDogmaBuilder builder) {} /** - * Creates a new server, configures it with {@link #configure(CentralDogmaBuilder)} and starts the server. - * Note that you don't need to call this method if you did not stop the server with {@link #stop()}, - * because the server is automatically started up by JUnit. + * Override this method to configure the HTTP-based {@link CentralDogma} client builder. */ - public final void start() { - startAsync().join(); - } + protected void configureClient(ArmeriaCentralDogmaBuilder builder) {} /** - * Creates a new server, configures it with {@link #configure(CentralDogmaBuilder)} and starts the server - * asynchronously. + * Override this method to configure the Thrift-based {@link CentralDogma} client builder. */ - public final CompletableFuture startAsync() { - // Create the root folder first if not. - try { - getRoot(); - } catch (IllegalStateException unused) { - try { - create(); - } catch (IOException e) { - return CompletableFutures.exceptionallyCompletedFuture(e); - } - } - - final CentralDogmaBuilder builder = new CentralDogmaBuilder(getRoot()) - .port(TEST_PORT, useTls ? SessionProtocol.HTTPS : SessionProtocol.HTTP) - .webAppEnabled(false) - .mirroringEnabled(false) - .gracefulShutdownTimeout(new GracefulShutdownTimeout(0, 0)); - - if (useTls) { - try { - final SelfSignedCertificate ssc = new SelfSignedCertificate(); - builder.tls(new TlsConfig(ssc.certificate(), ssc.privateKey(), null)); - } catch (Exception e) { - Exceptions.throwUnsafely(e); - } - } - - configure(builder); - - final com.linecorp.centraldogma.server.CentralDogma dogma = builder.build(); - this.dogma = dogma; - return dogma.start().thenRun(() -> { - final Optional activePort = dogma.activePort(); - if (!activePort.isPresent()) { - // Stopped already. - return; - } - - final InetSocketAddress serverAddress = activePort.get().localAddress(); - this.serverAddress = serverAddress; - - final ArmeriaCentralDogmaBuilder clientBuilder = new ArmeriaCentralDogmaBuilder(); - final LegacyCentralDogmaBuilder legacyClientBuilder = new LegacyCentralDogmaBuilder(); - - configureClientCommon(clientBuilder); - configureClientCommon(legacyClientBuilder); - configureClient(clientBuilder); - configureClient(legacyClientBuilder); + protected void configureClient(LegacyCentralDogmaBuilder builder) {} - try { - client = clientBuilder.build(); - legacyClient = legacyClientBuilder.build(); - } catch (UnknownHostException e) { - // Should never reach here. - throw new IOError(e); - } - webClient = WebClient.of( - "h2c://" + serverAddress.getHostString() + ':' + serverAddress.getPort()); - }); - } + /** + * Override this method to perform the initial updates on the server, + * such as creating a repository and populating sample data. + */ + protected void scaffold(CentralDogma client) {} private void configureClientCommon(AbstractArmeriaCentralDogmaBuilder builder) { final InetSocketAddress serverAddress = this.serverAddress; @@ -271,56 +265,4 @@ private void configureClientCommon(AbstractArmeriaCentralDogmaBuilder builder .build()); } } - - /** - * Override this method to configure the server. - */ - protected void configure(CentralDogmaBuilder builder) {} - - /** - * Override this method to configure the HTTP-based {@link CentralDogma} client builder. - */ - protected void configureClient(ArmeriaCentralDogmaBuilder builder) {} - - /** - * Override this method to configure the Thrift-based {@link CentralDogma} client builder. - */ - protected void configureClient(LegacyCentralDogmaBuilder builder) {} - - /** - * Override this method to perform the initial updates on the server, such as creating a repository and - * populating sample data. - */ - protected void scaffold(CentralDogma client) {} - - /** - * Stops the server and deletes the temporary files created by the server. - */ - @Override - protected void after() { - stopAsync().whenComplete((unused1, unused2) -> delete()); - } - - /** - * Stops the server and deletes the temporary files created by the server. Note that you don't usually need - * to call this method manually because the server is automatically stopped at the end by JUnit. - */ - public final void stop() { - stopAsync().join(); - } - - /** - * Stops the server and deletes the temporary files created by the server. Note that you don't usually need - * to call this method manually because the server is automatically stopped at the end by JUnit. - */ - public final CompletableFuture stopAsync() { - final com.linecorp.centraldogma.server.CentralDogma dogma = this.dogma; - this.dogma = null; - - if (dogma != null) { - return dogma.stop(); - } else { - return CompletableFuture.completedFuture(null); - } - } } diff --git a/testing/common/src/main/java/com/linecorp/centraldogma/testing/internal/package-info.java b/testing/common/src/main/java/com/linecorp/centraldogma/testing/internal/package-info.java new file mode 100644 index 0000000000..4b8b623429 --- /dev/null +++ b/testing/common/src/main/java/com/linecorp/centraldogma/testing/internal/package-info.java @@ -0,0 +1,23 @@ +/* + * Copyright 2020 LINE Corporation + * + * LINE Corporation licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +/** + * Internal testing utilities. + */ +@NonNullByDefault +package com.linecorp.centraldogma.testing.internal; + +import com.linecorp.centraldogma.common.util.NonNullByDefault; diff --git a/testing/junit/build.gradle b/testing/junit/build.gradle new file mode 100644 index 0000000000..06b24efc48 --- /dev/null +++ b/testing/junit/build.gradle @@ -0,0 +1,4 @@ +dependencies { + compile project(':testing:testing-common') + compile 'org.junit.jupiter:junit-jupiter-api' +} diff --git a/testing/junit/src/main/java/com/linecorp/centraldogma/testing/junit/AbstractAllOrEachExtension.java b/testing/junit/src/main/java/com/linecorp/centraldogma/testing/junit/AbstractAllOrEachExtension.java new file mode 100644 index 0000000000..b7c24a963d --- /dev/null +++ b/testing/junit/src/main/java/com/linecorp/centraldogma/testing/junit/AbstractAllOrEachExtension.java @@ -0,0 +1,87 @@ +/* + * Copyright 2020 LINE Corporation + * + * LINE Corporation licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package com.linecorp.centraldogma.testing.junit; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.AfterAllCallback; +import org.junit.jupiter.api.extension.AfterEachCallback; +import org.junit.jupiter.api.extension.BeforeAllCallback; +import org.junit.jupiter.api.extension.BeforeEachCallback; +import org.junit.jupiter.api.extension.ExtensionContext; + +/** + * A base class for JUnit5 extensions that allows implementations to control whether the callbacks are run + * around the entire class, like {@link BeforeAll} or {@link AfterAll}, or around each test method, like + * {@link BeforeEach} or {@link AfterEach}. By default, the extension will run around the entire class - + * implementations that want to run around each test method should override {@link #runForEachTest}. + */ +public abstract class AbstractAllOrEachExtension + implements BeforeAllCallback, AfterAllCallback, BeforeEachCallback, AfterEachCallback { + + /** + * A method that should be run at the beginning of a test lifecycle. If {@link #runForEachTest()} + * returns {@code false}, this is run once before all tests, otherwise it is run before each test + * method. + */ + protected abstract void before(ExtensionContext context) throws Exception; + + /** + * A method that should be run at the end of a test lifecycle. If {@link #runForEachTest()} + * returns {@code false}, this is run once after all tests, otherwise it is run after each test + * method. + */ + protected abstract void after(ExtensionContext context) throws Exception; + + @Override + public final void beforeAll(ExtensionContext context) throws Exception { + if (!runForEachTest()) { + before(context); + } + } + + @Override + public final void afterAll(ExtensionContext context) throws Exception { + if (!runForEachTest()) { + after(context); + } + } + + @Override + public final void beforeEach(ExtensionContext context) throws Exception { + if (runForEachTest()) { + before(context); + } + } + + @Override + public final void afterEach(ExtensionContext context) throws Exception { + if (runForEachTest()) { + after(context); + } + } + + /** + * Returns whether this extension should run around each test method instead of the entire test class. + * Implementations should override this method to return {@code true} to run around each test method. + */ + protected boolean runForEachTest() { + return false; + } +} diff --git a/testing/junit/src/main/java/com/linecorp/centraldogma/testing/junit/CentralDogmaExtension.java b/testing/junit/src/main/java/com/linecorp/centraldogma/testing/junit/CentralDogmaExtension.java new file mode 100644 index 0000000000..bc3ff5b2c0 --- /dev/null +++ b/testing/junit/src/main/java/com/linecorp/centraldogma/testing/junit/CentralDogmaExtension.java @@ -0,0 +1,257 @@ +/* + * Copyright 2020 LINE Corporation + * + * LINE Corporation licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package com.linecorp.centraldogma.testing.junit; + +import java.io.File; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Comparator; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; + +import javax.annotation.Nullable; + +import org.junit.jupiter.api.extension.Extension; +import org.junit.jupiter.api.extension.ExtensionContext; + +import com.spotify.futures.CompletableFutures; + +import com.linecorp.armeria.client.WebClient; +import com.linecorp.centraldogma.client.CentralDogma; +import com.linecorp.centraldogma.client.armeria.ArmeriaCentralDogmaBuilder; +import com.linecorp.centraldogma.client.armeria.legacy.LegacyCentralDogmaBuilder; +import com.linecorp.centraldogma.server.CentralDogmaBuilder; +import com.linecorp.centraldogma.server.MirroringService; +import com.linecorp.centraldogma.testing.internal.CentralDogmaRuleDelegate; + +/** + * A JUnit {@link Extension} that starts an embedded Central Dogma server. + * + *
{@code
+ * > class MyTest {
+ * >     @RegisterExtension
+ * >     static final CentralDogmaExtension extension = new CentralDogmaExtension();
+ * >
+ * >     @Test
+ * >     void test() throws Exception {
+ * >         CentralDogma dogma = extension.client();
+ * >         dogma.push(...).join();
+ * >         ...
+ * >     }
+ * > }
+ * }
+ */ +public class CentralDogmaExtension extends AbstractAllOrEachExtension { + + private final CentralDogmaRuleDelegate delegate; + @Nullable + private File dataDir; + + /** + * Creates a new instance with TLS disabled. + */ + public CentralDogmaExtension() { + this(false); + } + + /** + * Creates a new instance. + */ + public CentralDogmaExtension(boolean useTls) { + delegate = new CentralDogmaRuleDelegate(useTls) { + @Override + protected void configure(CentralDogmaBuilder builder) { + CentralDogmaExtension.this.configure(builder); + } + + @Override + protected void configureClient(ArmeriaCentralDogmaBuilder builder) { + CentralDogmaExtension.this.configureClient(builder); + } + + @Override + protected void configureClient(LegacyCentralDogmaBuilder builder) { + CentralDogmaExtension.this.configureClient(builder); + } + + @Override + protected void scaffold(CentralDogma client) { + CentralDogmaExtension.this.scaffold(client); + } + }; + } + + @Override + public void before(ExtensionContext context) throws Exception { + createDataDir(); + assert dataDir != null; + delegate.setUp(dataDir); + } + + @Override + public void after(ExtensionContext context) throws Exception { + stopAsync().whenComplete((unused1, unused2) -> { + try { + deleteDataDir(); + } catch (IOException e) { + throw new CompletionException(e); + } + }); + } + + /** + * Creates a new server, configures it with {@link #configure(CentralDogmaBuilder)} and starts the server. + * Note that you don't need to call this method if you did not stop the server with {@link #stop()}, + * because the server is automatically started up by JUnit. + */ + public final void start() { + startAsync().join(); + } + + /** + * Creates a new server, configures it with {@link #configure(CentralDogmaBuilder)}, + * and starts the server asynchronously. + */ + public final CompletableFuture startAsync() { + // Create the root folder first if it doesn't exist. + if (dataDir == null) { + try { + createDataDir(); + } catch (IOException e) { + return CompletableFutures.exceptionallyCompletedFuture(e); + } + } + + return delegate.startAsync(dataDir); + } + + /** + * Stops the server and deletes the temporary files created by the server. Note that you don't usually need + * to call this method manually because the server is automatically stopped at the end by JUnit. + */ + public final void stop() { + stopAsync().join(); + } + + /** + * Stops the server and deletes the temporary files created by the server. Note that you don't usually need + * to call this method manually because the server is automatically stopped at the end by JUnit. + */ + public final CompletableFuture stopAsync() { + return delegate.stopAsync(); + } + + /** + * Returns whether the server is running over TLS or not. + */ + public boolean useTls() { + return delegate.useTls(); + } + + /** + * Returns the server. + * + * @throws IllegalStateException if Central Dogma did not start yet + */ + public final com.linecorp.centraldogma.server.CentralDogma dogma() { + return delegate.dogma(); + } + + /** + * Returns the {@link MirroringService} of the server. + * + * @throws IllegalStateException if Central Dogma did not start yet + */ + public final MirroringService mirroringService() { + return delegate.mirroringService(); + } + + /** + * Returns the HTTP-based {@link CentralDogma} client. + * + * @throws IllegalStateException if Central Dogma did not start yet + */ + public final CentralDogma client() { + return delegate.client(); + } + + /** + * Returns the Thrift-based {@link CentralDogma} client. + * + * @throws IllegalStateException if Central Dogma did not start yet + */ + public final CentralDogma legacyClient() { + return delegate.legacyClient(); + } + + /** + * Returns the HTTP client. + * + * @throws IllegalStateException if Central Dogma did not start yet + */ + public final WebClient httpClient() { + return delegate.httpClient(); + } + + /** + * Returns the server address. + * + * @throws IllegalStateException if Central Dogma did not start yet + */ + public final InetSocketAddress serverAddress() { + return delegate.serverAddress(); + } + + /** + * Override this method to configure the server. + */ + protected void configure(CentralDogmaBuilder builder) {} + + /** + * Override this method to configure the HTTP-based {@link CentralDogma} client builder. + */ + protected void configureClient(ArmeriaCentralDogmaBuilder builder) {} + + /** + * Override this method to configure the Thrift-based {@link CentralDogma} client builder. + */ + protected void configureClient(LegacyCentralDogmaBuilder builder) {} + + /** + * Override this method to perform the initial updates on the server, + * such as creating a repository and populating sample data. + */ + protected void scaffold(CentralDogma client) {} + + private void createDataDir() throws IOException { + dataDir = Files.createTempDirectory("centraldogma").toFile(); + } + + private void deleteDataDir() throws IOException { + if (dataDir == null) { + return; + } + + Files.walk(dataDir.toPath()) + .sorted(Comparator.reverseOrder()) + .map(Path::toFile) + .forEach(File::delete); + + dataDir = null; + } +} diff --git a/testing/src/main/java/com/linecorp/centraldogma/testing/package-info.java b/testing/junit/src/main/java/com/linecorp/centraldogma/testing/junit/package-info.java similarity index 89% rename from testing/src/main/java/com/linecorp/centraldogma/testing/package-info.java rename to testing/junit/src/main/java/com/linecorp/centraldogma/testing/junit/package-info.java index 1ba061d9b7..75f3d8e1f8 100644 --- a/testing/src/main/java/com/linecorp/centraldogma/testing/package-info.java +++ b/testing/junit/src/main/java/com/linecorp/centraldogma/testing/junit/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 LINE Corporation + * Copyright 2020 LINE Corporation * * LINE Corporation licenses this file to you under the Apache License, * version 2.0 (the "License"); you may not use this file except in compliance @@ -13,10 +13,11 @@ * License for the specific language governing permissions and limitations * under the License. */ + /** * Simplifies the integration testing with Central Dogma. */ @NonNullByDefault -package com.linecorp.centraldogma.testing; +package com.linecorp.centraldogma.testing.junit; import com.linecorp.centraldogma.common.util.NonNullByDefault; diff --git a/testing/junit/src/test/java/com/linecorp/centraldogma/testing/junit/AbstractAllOrEachExtensionTest.java b/testing/junit/src/test/java/com/linecorp/centraldogma/testing/junit/AbstractAllOrEachExtensionTest.java new file mode 100644 index 0000000000..b4514178e9 --- /dev/null +++ b/testing/junit/src/test/java/com/linecorp/centraldogma/testing/junit/AbstractAllOrEachExtensionTest.java @@ -0,0 +1,101 @@ +/* + * Copyright 2020 LINE Corporation + * + * LINE Corporation licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package com.linecorp.centraldogma.testing.junit; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.concurrent.atomic.AtomicInteger; + +import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.TestInstance.Lifecycle; +import org.junit.jupiter.api.TestMethodOrder; +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.RegisterExtension; + +@TestInstance(Lifecycle.PER_CLASS) +@TestMethodOrder(OrderAnnotation.class) +class AbstractAllOrEachExtensionTest { + private static final AtomicInteger BEFORE_ALL_NUM_INVOCATIONS = new AtomicInteger(); + + @RegisterExtension + @Order(Integer.MAX_VALUE) + static final AbstractAllOrEachExtension BEFORE_ALL_EXTENSION = new AbstractAllOrEachExtension() { + @Override + protected void before(ExtensionContext context) throws Exception { + BEFORE_ALL_NUM_INVOCATIONS.incrementAndGet(); + } + + @Override + protected void after(ExtensionContext context) throws Exception { + BEFORE_ALL_NUM_INVOCATIONS.incrementAndGet(); + } + }; + + private static final AtomicInteger BEFORE_EACH_NUM_INVOCATIONS = new AtomicInteger(); + + @RegisterExtension + @Order(Integer.MAX_VALUE) + static final AbstractAllOrEachExtension BEFORE_EACH_EXTENSION = new AbstractAllOrEachExtension() { + @Override + protected void before(ExtensionContext context) throws Exception { + BEFORE_EACH_NUM_INVOCATIONS.incrementAndGet(); + } + + @Override + protected void after(ExtensionContext context) throws Exception { + BEFORE_EACH_NUM_INVOCATIONS.incrementAndGet(); + } + + @Override + protected boolean runForEachTest() { + return true; + } + }; + + @RegisterExtension + @Order(1) + static final BeforeAllCallback CHECK_START = context -> { + assertThat(BEFORE_ALL_NUM_INVOCATIONS).hasValue(0); + assertThat(BEFORE_EACH_NUM_INVOCATIONS).hasValue(0); + }; + + @RegisterExtension + @Order(1) + static final AfterAllCallback CHECK_END = context -> { + assertThat(BEFORE_ALL_NUM_INVOCATIONS).hasValue(2); + assertThat(BEFORE_EACH_NUM_INVOCATIONS).hasValue(4); + }; + + @Test + @Order(1) + void first() { + assertThat(BEFORE_ALL_NUM_INVOCATIONS).hasValue(1); + assertThat(BEFORE_EACH_NUM_INVOCATIONS).hasValue(1); + } + + @Test + @Order(2) + void second() { + assertThat(BEFORE_ALL_NUM_INVOCATIONS).hasValue(1); + assertThat(BEFORE_EACH_NUM_INVOCATIONS).hasValue(3); + } +} diff --git a/testing/junit4/build.gradle b/testing/junit4/build.gradle new file mode 100644 index 0000000000..34506aa364 --- /dev/null +++ b/testing/junit4/build.gradle @@ -0,0 +1,4 @@ +dependencies { + compile project(':testing:testing-common') + compile 'junit:junit' +} diff --git a/testing/junit4/src/main/java/com/linecorp/centraldogma/testing/junit4/CentralDogmaRule.java b/testing/junit4/src/main/java/com/linecorp/centraldogma/testing/junit4/CentralDogmaRule.java new file mode 100644 index 0000000000..d3cbe7b9ff --- /dev/null +++ b/testing/junit4/src/main/java/com/linecorp/centraldogma/testing/junit4/CentralDogmaRule.java @@ -0,0 +1,233 @@ +/* + * Copyright 2020 LINE Corporation + * + * LINE Corporation licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package com.linecorp.centraldogma.testing.junit4; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.concurrent.CompletableFuture; + +import org.junit.Rule; +import org.junit.rules.TemporaryFolder; + +import com.spotify.futures.CompletableFutures; + +import com.linecorp.armeria.client.WebClient; +import com.linecorp.centraldogma.client.CentralDogma; +import com.linecorp.centraldogma.client.armeria.ArmeriaCentralDogmaBuilder; +import com.linecorp.centraldogma.client.armeria.legacy.LegacyCentralDogmaBuilder; +import com.linecorp.centraldogma.server.CentralDogmaBuilder; +import com.linecorp.centraldogma.server.MirroringService; +import com.linecorp.centraldogma.testing.internal.CentralDogmaRuleDelegate; + +/** + * A JUnit {@link Rule} that starts an embedded Central Dogma server. + * + *
{@code
+ * > public class MyTest {
+ * >     @ClassRule
+ * >     public static final CentralDogmaRule rule = new CentralDogmaRule();
+ * >
+ * >     @Test
+ * >     public void test() throws Exception {
+ * >         CentralDogma dogma = rule.client();
+ * >         dogma.push(...).join();
+ * >         ...
+ * >     }
+ * > }
+ * }
+ */ +public class CentralDogmaRule extends TemporaryFolder { + + private final CentralDogmaRuleDelegate delegate; + + /** + * Creates a new instance with TLS disabled. + */ + public CentralDogmaRule() { + this(false); + } + + /** + * Creates a new instance. + */ + public CentralDogmaRule(boolean useTls) { + delegate = new CentralDogmaRuleDelegate(useTls) { + @Override + protected void configure(CentralDogmaBuilder builder) { + CentralDogmaRule.this.configure(builder); + } + + @Override + protected void configureClient(ArmeriaCentralDogmaBuilder builder) { + CentralDogmaRule.this.configureClient(builder); + } + + @Override + protected void configureClient(LegacyCentralDogmaBuilder builder) { + CentralDogmaRule.this.configureClient(builder); + } + + @Override + protected void scaffold(CentralDogma client) { + CentralDogmaRule.this.scaffold(client); + } + }; + } + + /** + * Starts an embedded server and calls {@link #scaffold(CentralDogma)}. + */ + @Override + protected void before() throws Throwable { + super.before(); + delegate.setUp(getRoot()); + } + + /** + * Stops the server and deletes the temporary files created by the server. + */ + @Override + protected void after() { + stopAsync().whenComplete((unused1, unused2) -> delete()); + } + + /** + * Creates a new server, configures it with {@link #configure(CentralDogmaBuilder)} and starts the server. + * Note that you don't need to call this method if you did not stop the server with {@link #stop()}, + * because the server is automatically started up by JUnit. + */ + public final void start() { + startAsync().join(); + } + + /** + * Creates a new server, configures it with {@link #configure(CentralDogmaBuilder)}, + * and starts the server asynchronously. + */ + public final CompletableFuture startAsync() { + // Create the root folder first if it doesn't exist. + try { + getRoot(); + } catch (IllegalStateException unused) { + try { + create(); + } catch (IOException e) { + return CompletableFutures.exceptionallyCompletedFuture(e); + } + } + + return delegate.startAsync(getRoot()); + } + + /** + * Stops the server and deletes the temporary files created by the server. Note that you don't usually need + * to call this method manually because the server is automatically stopped at the end by JUnit. + */ + public final void stop() { + stopAsync().join(); + } + + /** + * Stops the server and deletes the temporary files created by the server. Note that you don't usually need + * to call this method manually because the server is automatically stopped at the end by JUnit. + */ + public final CompletableFuture stopAsync() { + return delegate.stopAsync(); + } + + /** + * Returns whether the server is running over TLS or not. + */ + public boolean useTls() { + return delegate.useTls(); + } + + /** + * Returns the server. + * + * @throws IllegalStateException if Central Dogma did not start yet + */ + public final com.linecorp.centraldogma.server.CentralDogma dogma() { + return delegate.dogma(); + } + + /** + * Returns the {@link MirroringService} of the server. + * + * @throws IllegalStateException if Central Dogma did not start yet + */ + public final MirroringService mirroringService() { + return delegate.mirroringService(); + } + + /** + * Returns the HTTP-based {@link CentralDogma} client. + * + * @throws IllegalStateException if Central Dogma did not start yet + */ + public final CentralDogma client() { + return delegate.client(); + } + + /** + * Returns the Thrift-based {@link CentralDogma} client. + * + * @throws IllegalStateException if Central Dogma did not start yet + */ + public final CentralDogma legacyClient() { + return delegate.legacyClient(); + } + + /** + * Returns the HTTP client. + * + * @throws IllegalStateException if Central Dogma did not start yet + */ + public final WebClient httpClient() { + return delegate.httpClient(); + } + + /** + * Returns the server address. + * + * @throws IllegalStateException if Central Dogma did not start yet + */ + public final InetSocketAddress serverAddress() { + return delegate.serverAddress(); + } + + /** + * Override this method to configure the server. + */ + protected void configure(CentralDogmaBuilder builder) {} + + /** + * Override this method to configure the HTTP-based {@link CentralDogma} client builder. + */ + protected void configureClient(ArmeriaCentralDogmaBuilder builder) {} + + /** + * Override this method to configure the Thrift-based {@link CentralDogma} client builder. + */ + protected void configureClient(LegacyCentralDogmaBuilder builder) {} + + /** + * Override this method to perform the initial updates on the server, + * such as creating a repository and populating sample data. + */ + protected void scaffold(CentralDogma client) {} +} diff --git a/testing/junit4/src/main/java/com/linecorp/centraldogma/testing/junit4/package-info.java b/testing/junit4/src/main/java/com/linecorp/centraldogma/testing/junit4/package-info.java new file mode 100644 index 0000000000..f547b877d0 --- /dev/null +++ b/testing/junit4/src/main/java/com/linecorp/centraldogma/testing/junit4/package-info.java @@ -0,0 +1,23 @@ +/* + * Copyright 2020 LINE Corporation + * + * LINE Corporation licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +/** + * Simplifies the integration testing with Central Dogma. + */ +@NonNullByDefault +package com.linecorp.centraldogma.testing.junit4; + +import com.linecorp.centraldogma.common.util.NonNullByDefault;