From 924d45fda71aa93a7c6517333154b32efe7d1ba1 Mon Sep 17 00:00:00 2001 From: Gabriel Roldan Date: Mon, 6 Jan 2025 23:33:57 -0300 Subject: [PATCH] Fix race condition in tests using the same temporary data directories Replace hardcoded temporary data directories in test application.yml/bootstrap.yml files by dynamic property sources to avoid unwanted dependencies from tests on the temporary directory existing, or parallel tests stepping on each other. --- .../gwc/app/GeoWebCacheApplicationTest.java | 39 ++++++++++++++ .../gwc/src/test/resources/bootstrap-test.yml | 2 +- .../restconfig/RestConfigApplicationTest.java | 44 ++++++++++++++-- .../src/test/resources/bootstrap-test.yml | 2 +- .../cloud/wcs/WcsApplicationTest.java | 12 +++++ .../wcs/src/test/resources/bootstrap-test.yml | 13 +---- .../cloud/web/app/AclIntegrationTest.java | 16 ++++++ .../cloud/web/app/WebUIApplicationTest.java | 17 +++++++ .../src/test/resources/bootstrap-test.yml | 16 +----- src/apps/geoserver/wfs/pom.xml | 22 -------- .../app/WfsApplicationDataDirectoryIT.java | 5 +- .../src/test/resources/bootstrap-datadir.yml | 12 +---- .../app/WmsApplicationDataDirectoryTest.java | 7 ++- .../wms/app/WmsApplicationJdbcconfigTest.java | 20 +++++++- .../wms/src/test/resources/bootstrap-test.yml | 2 - .../resources/bootstrap-testjdbcconfig.yml | 2 +- .../cloud/wps/WpsApplicationTest.java | 8 ++- .../wps/src/test/resources/bootstrap-test.yml | 12 +---- .../DataDirectoryAutoConfigurationTest.java | 9 ++-- .../DataDirectoryUpdateSequenceTest.java | 12 ++++- .../src/test/resources/application.yml | 14 +---- .../src/test/resources/bootstrap-test.yml | 42 --------------- .../src/test/resources/application.yml | 25 --------- .../core/src/test/resources/application.yml | 25 --------- .../cloud/config/jndi/JNDIInitializer.java | 51 ++++++++++++++----- src/pom.xml | 4 ++ .../src/test/resources/application.yml | 33 ------------ 27 files changed, 221 insertions(+), 245 deletions(-) delete mode 100644 src/catalog/jackson-bindings/geoserver/src/test/resources/bootstrap-test.yml diff --git a/src/apps/geoserver/gwc/src/test/java/org/geoserver/cloud/gwc/app/GeoWebCacheApplicationTest.java b/src/apps/geoserver/gwc/src/test/java/org/geoserver/cloud/gwc/app/GeoWebCacheApplicationTest.java index 73e86cb15..67ba4e4aa 100644 --- a/src/apps/geoserver/gwc/src/test/java/org/geoserver/cloud/gwc/app/GeoWebCacheApplicationTest.java +++ b/src/apps/geoserver/gwc/src/test/java/org/geoserver/cloud/gwc/app/GeoWebCacheApplicationTest.java @@ -5,14 +5,22 @@ package org.geoserver.cloud.gwc.app; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertTrue; import static org.springframework.http.MediaType.APPLICATION_JSON; import static org.springframework.http.MediaType.APPLICATION_XML; import com.google.gson.JsonElement; import com.google.gson.JsonParser; +import java.io.IOException; import java.net.URI; +import java.nio.file.Files; +import java.nio.file.Path; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.io.TempDir; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; @@ -20,15 +28,31 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) @ActiveProfiles("test") class GeoWebCacheApplicationTest { @Autowired private TestRestTemplate restTemplate; + static @TempDir Path datadir; + + @DynamicPropertySource + static void setUpDataDir(DynamicPropertyRegistry registry) throws IOException { + var gwcdir = datadir.resolve("gwc"); + if (!Files.exists(gwcdir)) { + Files.createDirectory(gwcdir); + } + registry.add("geoserver.backend.data-directory.location", datadir::toAbsolutePath); + registry.add("gwc.cache-directory", gwcdir::toAbsolutePath); + } + @BeforeEach void before() { restTemplate = restTemplate.withBasicAuth("admin", "geoserver"); @@ -36,7 +60,20 @@ void before() { assertThat(rootUri).isNotEmpty(); } + /** + * REVISIT: for some reason, running the REST API tests right after starting off an empty data directory produce a 403 forbidden + * response. We're hence forcing the order of the tests and the reload of the context for the time being + */ + @Test + @Order(1) + @DirtiesContext + void smokeTest() { + assertTrue(true); + } + @Test + @Order(2) + @DirtiesContext void testRESTDefaultContentType() { ResponseEntity response = testGetRequestContentType("/gwc/rest/layers", APPLICATION_JSON); JsonElement parsed = JsonParser.parseString(response.getBody()); @@ -44,6 +81,8 @@ void testRESTDefaultContentType() { } @Test + @Order(3) + @DirtiesContext void testRESTPathExtensionContentNegotiation() { ResponseEntity response = testGetRequestContentType("/gwc/rest/layers.json", APPLICATION_JSON); JsonElement parsed = JsonParser.parseString(response.getBody()); diff --git a/src/apps/geoserver/gwc/src/test/resources/bootstrap-test.yml b/src/apps/geoserver/gwc/src/test/resources/bootstrap-test.yml index 6c7d3c7f5..57993d7c2 100644 --- a/src/apps/geoserver/gwc/src/test/resources/bootstrap-test.yml +++ b/src/apps/geoserver/gwc/src/test/resources/bootstrap-test.yml @@ -10,7 +10,7 @@ geoserver: backend: data-directory: enabled: true - location: ${data_directory:${java.io.tmpdir}/geoserver_cloud_data_directory} + location: # to be set by test classes logging: level: diff --git a/src/apps/geoserver/restconfig/src/test/java/org/geoserver/cloud/restconfig/RestConfigApplicationTest.java b/src/apps/geoserver/restconfig/src/test/java/org/geoserver/cloud/restconfig/RestConfigApplicationTest.java index d903821a7..de1114d9d 100644 --- a/src/apps/geoserver/restconfig/src/test/java/org/geoserver/cloud/restconfig/RestConfigApplicationTest.java +++ b/src/apps/geoserver/restconfig/src/test/java/org/geoserver/cloud/restconfig/RestConfigApplicationTest.java @@ -5,13 +5,21 @@ package org.geoserver.cloud.restconfig; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertTrue; import static org.springframework.http.MediaType.APPLICATION_JSON; import static org.springframework.http.MediaType.APPLICATION_XML; import static org.springframework.http.MediaType.TEXT_HTML; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; import org.geoserver.catalog.SLDHandler; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.io.TempDir; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; @@ -19,30 +27,60 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) @ActiveProfiles("test") class RestConfigApplicationTest { @Autowired private TestRestTemplate restTemplate; + static @TempDir Path datadir; + + @DynamicPropertySource + static void setUpDataDir(DynamicPropertyRegistry registry) throws IOException { + var gwcdir = datadir.resolve("gwc"); + if (!Files.exists(gwcdir)) { + Files.createDirectory(gwcdir); + } + registry.add("geoserver.backend.data-directory.location", datadir::toAbsolutePath); + registry.add("gwc.cache-directory", gwcdir::toAbsolutePath); + } + @BeforeEach - void before() { + void before() throws Exception { restTemplate = restTemplate.withBasicAuth("admin", "geoserver"); } + /** + * REVISIT: for some reason, running the REST API tests right after starting off + * an empty data directory produce a 403 forbidden response. We're hence forcing + * the order of the tests and the reload of the context for the time being + */ @Test - void testDefaultContentType() { + @Order(1) + @DirtiesContext + void smokeTest() { + assertTrue(true); + } + @Test + @Order(2) + @DirtiesContext + void testDefaultContentType() { testPathExtensionContentType("/rest/workspaces", APPLICATION_JSON); testPathExtensionContentType("/rest/layers", APPLICATION_JSON); } @Test + @Order(3) + @DirtiesContext void testPathExtensionContentNegotiation() { - testPathExtensionContentType("/rest/styles/line.json", APPLICATION_JSON); testPathExtensionContentType("/rest/styles/line.xml", APPLICATION_XML); testPathExtensionContentType("/rest/styles/line.html", TEXT_HTML); diff --git a/src/apps/geoserver/restconfig/src/test/resources/bootstrap-test.yml b/src/apps/geoserver/restconfig/src/test/resources/bootstrap-test.yml index c47caca7c..5a2f2c61c 100644 --- a/src/apps/geoserver/restconfig/src/test/resources/bootstrap-test.yml +++ b/src/apps/geoserver/restconfig/src/test/resources/bootstrap-test.yml @@ -14,7 +14,7 @@ geoserver: backend: data-directory: enabled: true - location: ${data_directory:${java.io.tmpdir}/geoserver_cloud_data_directory} + location: # to be set by the test class logging: level: diff --git a/src/apps/geoserver/wcs/src/test/java/org/geoserver/cloud/wcs/WcsApplicationTest.java b/src/apps/geoserver/wcs/src/test/java/org/geoserver/cloud/wcs/WcsApplicationTest.java index 6984dd438..80fbfc9a8 100644 --- a/src/apps/geoserver/wcs/src/test/java/org/geoserver/cloud/wcs/WcsApplicationTest.java +++ b/src/apps/geoserver/wcs/src/test/java/org/geoserver/cloud/wcs/WcsApplicationTest.java @@ -6,18 +6,30 @@ import static org.assertj.core.api.Assertions.assertThat; +import java.io.IOException; +import java.nio.file.Path; import java.util.stream.Stream; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; @SpringBootTest @ActiveProfiles("test") class WcsApplicationTest { protected @Autowired ConfigurableApplicationContext context; + static @TempDir Path datadir; + + @DynamicPropertySource + static void setUpDataDir(DynamicPropertyRegistry registry) throws IOException { + registry.add("geoserver.backend.data-directory.location", datadir::toAbsolutePath); + } + @Test void testWcsCoreBeans() { expectBean("legacyWcsLoader", org.geoserver.wcs.WCSLoader.class); diff --git a/src/apps/geoserver/wcs/src/test/resources/bootstrap-test.yml b/src/apps/geoserver/wcs/src/test/resources/bootstrap-test.yml index 59181b330..245bd4169 100644 --- a/src/apps/geoserver/wcs/src/test/resources/bootstrap-test.yml +++ b/src/apps/geoserver/wcs/src/test/resources/bootstrap-test.yml @@ -6,6 +6,7 @@ spring: cloud.config.enabled: false cloud.config.discovery.enabled: false cloud.discovery.enabled: false + cloud.bus.enabled: false eureka.client.enabled: false geoserver: @@ -13,17 +14,7 @@ geoserver: backend: data-directory: enabled: true - location: ${data_directory:${java.io.tmpdir}/geoserver_cloud_data_directory} - jdbcconfig: - enabled: false - web.enabled: false - initdb: true - cache-directory: ${java.io.tmpdir}/geoserver-jdbcconfig-cache - datasource: - driverClassname: org.h2.Driver - url: jdbc:h2:mem:test;DB_CLOSE_DELAY=-1 - username: sa - password: + location: # to be set by the test class logging: level: diff --git a/src/apps/geoserver/webui/src/test/java/org/geoserver/cloud/web/app/AclIntegrationTest.java b/src/apps/geoserver/webui/src/test/java/org/geoserver/cloud/web/app/AclIntegrationTest.java index 7882b32cf..68572e527 100644 --- a/src/apps/geoserver/webui/src/test/java/org/geoserver/cloud/web/app/AclIntegrationTest.java +++ b/src/apps/geoserver/webui/src/test/java/org/geoserver/cloud/web/app/AclIntegrationTest.java @@ -6,6 +6,9 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.ArrayList; import java.util.List; import java.util.Locale; @@ -16,6 +19,7 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; @@ -24,6 +28,8 @@ import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextImpl; import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; @SpringBootTest( properties = { @@ -41,6 +47,16 @@ class AclIntegrationTest { private @Autowired GeoServerApplication app; private WicketTester tester; + static @TempDir Path datadir; + + @DynamicPropertySource + static void setUpDataDir(DynamicPropertyRegistry registry) throws IOException { + var gwcdir = datadir.resolve("gwc"); + Files.createDirectory(gwcdir); + registry.add("geoserver.backend.data-directory.location", datadir::toAbsolutePath); + registry.add("gwc.cache-directory", gwcdir::toAbsolutePath); + } + static @BeforeAll void beforeAll() { System.setProperty("wicket.configuration", "deployment"); // Disable CSRF protection for tests, since the test framework doesn't set the Referer diff --git a/src/apps/geoserver/webui/src/test/java/org/geoserver/cloud/web/app/WebUIApplicationTest.java b/src/apps/geoserver/webui/src/test/java/org/geoserver/cloud/web/app/WebUIApplicationTest.java index ccb0e2803..9c0044af8 100644 --- a/src/apps/geoserver/webui/src/test/java/org/geoserver/cloud/web/app/WebUIApplicationTest.java +++ b/src/apps/geoserver/webui/src/test/java/org/geoserver/cloud/web/app/WebUIApplicationTest.java @@ -8,6 +8,9 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.ArrayList; import java.util.List; import java.util.Locale; @@ -27,6 +30,7 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; @@ -35,6 +39,8 @@ import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextImpl; import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; @SpringBootTest( properties = { @@ -49,6 +55,17 @@ class WebUIApplicationTest { private @Autowired GeoServerApplication app; private WicketTester tester; + static @TempDir Path tmpdir; + static Path datadir; + + @DynamicPropertySource + static void setUpDataDir(DynamicPropertyRegistry registry) throws IOException { + datadir = Files.createDirectory(tmpdir.resolve("datadir")); + var gwcdir = Files.createDirectory(datadir.resolve("gwc")); + registry.add("geoserver.backend.data-directory.location", datadir::toAbsolutePath); + registry.add("gwc.cache-directory", gwcdir::toAbsolutePath); + } + static @BeforeAll void beforeAll() { System.setProperty("wicket.configuration", "deployment"); // Disable CSRF protection for tests, since the test framework doesn't set the Referer diff --git a/src/apps/geoserver/webui/src/test/resources/bootstrap-test.yml b/src/apps/geoserver/webui/src/test/resources/bootstrap-test.yml index f03a8aa15..1b4d9456b 100644 --- a/src/apps/geoserver/webui/src/test/resources/bootstrap-test.yml +++ b/src/apps/geoserver/webui/src/test/resources/bootstrap-test.yml @@ -6,28 +6,16 @@ spring: cloud.config.enabled: false cloud.config.discovery.enabled: false cloud.discovery.enabled: false + cloud.bus.enabled: false eureka.client.enabled: false -gwc: - cache-directory: ${java.io.tmpdir}/gs-webui-tmp - geoserver: acl.enabled: false security.enabled: true backend: data-directory: enabled: true - location: ${data_directory:${java.io.tmpdir}/geoserver_cloud_data_directory} - jdbcconfig: - enabled: false - web.enabled: false - initdb: true - cache-directory: ${java.io.tmpdir}/geoserver-jdbcconfig-cache - datasource: - driverClassname: org.h2.Driver - url: jdbc:h2:mem:test;DB_CLOSE_DELAY=-1 - username: sa - password: + location: # to be set by the test classes logging: level: diff --git a/src/apps/geoserver/wfs/pom.xml b/src/apps/geoserver/wfs/pom.xml index 9b277e143..c1e91d0fc 100644 --- a/src/apps/geoserver/wfs/pom.xml +++ b/src/apps/geoserver/wfs/pom.xml @@ -45,26 +45,4 @@ test - - - - org.apache.maven.plugins - maven-failsafe-plugin - - - - integration-test - verify - - - false - 1 - false - false - - - - - - diff --git a/src/apps/geoserver/wfs/src/test/java/org/geoserver/cloud/wfs/app/WfsApplicationDataDirectoryIT.java b/src/apps/geoserver/wfs/src/test/java/org/geoserver/cloud/wfs/app/WfsApplicationDataDirectoryIT.java index 9876d65c6..b4752081c 100644 --- a/src/apps/geoserver/wfs/src/test/java/org/geoserver/cloud/wfs/app/WfsApplicationDataDirectoryIT.java +++ b/src/apps/geoserver/wfs/src/test/java/org/geoserver/cloud/wfs/app/WfsApplicationDataDirectoryIT.java @@ -5,7 +5,6 @@ package org.geoserver.cloud.wfs.app; import java.io.IOException; -import java.nio.file.Files; import java.nio.file.Path; import org.junit.jupiter.api.io.TempDir; import org.springframework.boot.test.context.SpringBootTest; @@ -18,12 +17,10 @@ @ActiveProfiles("datadir") class WfsApplicationDataDirectoryIT extends WfsApplicationTest { - static @TempDir Path tmpdir; - static Path datadir; + static @TempDir Path datadir; @DynamicPropertySource static void setUpDataDir(DynamicPropertyRegistry registry) throws IOException { - datadir = Files.createDirectory(tmpdir.resolve("datadir")); registry.add("geoserver.backend.data-directory.location", datadir::toAbsolutePath); } } diff --git a/src/apps/geoserver/wfs/src/test/resources/bootstrap-datadir.yml b/src/apps/geoserver/wfs/src/test/resources/bootstrap-datadir.yml index 98d7bd758..e0f28bb59 100644 --- a/src/apps/geoserver/wfs/src/test/resources/bootstrap-datadir.yml +++ b/src/apps/geoserver/wfs/src/test/resources/bootstrap-datadir.yml @@ -14,17 +14,7 @@ geoserver: backend: data-directory: enabled: true - location: ${data_directory:${java.io.tmpdir}/geoserver_cloud_data_directory} - jdbcconfig: - enabled: false - web.enabled: false - initdb: true - cache-directory: ${java.io.tmpdir}/geoserver-jdbcconfig-cache - datasource: - driverClassname: org.h2.Driver - url: jdbc:h2:mem:test;DB_CLOSE_DELAY=-1 - username: sa - password: + location: # set by test classes logging: level: diff --git a/src/apps/geoserver/wms/src/test/java/org/geoserver/cloud/wms/app/WmsApplicationDataDirectoryTest.java b/src/apps/geoserver/wms/src/test/java/org/geoserver/cloud/wms/app/WmsApplicationDataDirectoryTest.java index abf6a104d..7585cf93d 100644 --- a/src/apps/geoserver/wms/src/test/java/org/geoserver/cloud/wms/app/WmsApplicationDataDirectoryTest.java +++ b/src/apps/geoserver/wms/src/test/java/org/geoserver/cloud/wms/app/WmsApplicationDataDirectoryTest.java @@ -5,7 +5,6 @@ package org.geoserver.cloud.wms.app; import java.io.IOException; -import java.nio.file.Files; import java.nio.file.Path; import java.util.Map; import org.junit.jupiter.api.BeforeEach; @@ -27,13 +26,13 @@ @ActiveProfiles({"test"}) class WmsApplicationDataDirectoryTest extends WmsApplicationTest { - static @TempDir Path tmpdir; - static Path datadir; + static @TempDir Path datadir; @DynamicPropertySource static void setUpDataDir(DynamicPropertyRegistry registry) throws IOException { - datadir = Files.createDirectory(tmpdir.resolve("datadir")); + var gwcdir = datadir.resolve("gwc"); registry.add("geoserver.backend.data-directory.location", datadir::toAbsolutePath); + registry.add("gwc.cache-directory", gwcdir::toAbsolutePath); } private String baseURL; diff --git a/src/apps/geoserver/wms/src/test/java/org/geoserver/cloud/wms/app/WmsApplicationJdbcconfigTest.java b/src/apps/geoserver/wms/src/test/java/org/geoserver/cloud/wms/app/WmsApplicationJdbcconfigTest.java index 0abdb0017..c4098a30b 100644 --- a/src/apps/geoserver/wms/src/test/java/org/geoserver/cloud/wms/app/WmsApplicationJdbcconfigTest.java +++ b/src/apps/geoserver/wms/src/test/java/org/geoserver/cloud/wms/app/WmsApplicationJdbcconfigTest.java @@ -4,10 +4,28 @@ */ package org.geoserver.cloud.wms.app; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import org.junit.jupiter.api.io.TempDir; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; /** See {@code src/test/resources/bootstrap-testjdbcconfig.yml} */ @SpringBootTest(properties = "gwc.wms-integration=true") @ActiveProfiles({"test", "testjdbcconfig"}) -class WmsApplicationJdbcconfigTest extends WmsApplicationTest {} +class WmsApplicationJdbcconfigTest extends WmsApplicationTest { + + static @TempDir Path tmpdir; + static Path datadir; + + @DynamicPropertySource + static void setUpDataDir(DynamicPropertyRegistry registry) throws IOException { + datadir = Files.createDirectory(tmpdir.resolve("jdbc-temp-datadir")); + var gwcdir = Files.createDirectory(datadir.resolve("gwc")); + registry.add("geoserver.backend.jdbcconfig.cache-directory", datadir.toAbsolutePath()::toString); + registry.add("gwc.cache-directory", gwcdir::toAbsolutePath); + } +} diff --git a/src/apps/geoserver/wms/src/test/resources/bootstrap-test.yml b/src/apps/geoserver/wms/src/test/resources/bootstrap-test.yml index 890c86ca6..778eca07e 100644 --- a/src/apps/geoserver/wms/src/test/resources/bootstrap-test.yml +++ b/src/apps/geoserver/wms/src/test/resources/bootstrap-test.yml @@ -12,8 +12,6 @@ eureka.client.enabled: false geoserver: acl.enabled: false -gwc.cache-directory: ${java.io.tmpdir}/gs-wms-tmp - logging: level: root: WARN diff --git a/src/apps/geoserver/wms/src/test/resources/bootstrap-testjdbcconfig.yml b/src/apps/geoserver/wms/src/test/resources/bootstrap-testjdbcconfig.yml index ff45d212f..5d493bf69 100644 --- a/src/apps/geoserver/wms/src/test/resources/bootstrap-testjdbcconfig.yml +++ b/src/apps/geoserver/wms/src/test/resources/bootstrap-testjdbcconfig.yml @@ -4,7 +4,7 @@ geoserver: enabled: true web.enabled: true initdb: true - cache-directory: ${java.io.tmpdir}/geoserver-jdbcconfig-cache + cache-directory: # to be set by the test classes datasource: driverClassname: org.h2.Driver url: jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE diff --git a/src/apps/geoserver/wps/src/test/java/org/geoserver/cloud/wps/WpsApplicationTest.java b/src/apps/geoserver/wps/src/test/java/org/geoserver/cloud/wps/WpsApplicationTest.java index 556952071..8a145b2fb 100644 --- a/src/apps/geoserver/wps/src/test/java/org/geoserver/cloud/wps/WpsApplicationTest.java +++ b/src/apps/geoserver/wps/src/test/java/org/geoserver/cloud/wps/WpsApplicationTest.java @@ -5,7 +5,6 @@ package org.geoserver.cloud.wps; import java.io.IOException; -import java.nio.file.Files; import java.nio.file.Path; import java.util.Map; import org.junit.jupiter.api.Test; @@ -23,14 +22,13 @@ @ActiveProfiles("test") class WpsApplicationTest { - static @TempDir Path tmpdir; - static Path datadir; + static @TempDir Path datadir; @DynamicPropertySource static void setUpDataDir(DynamicPropertyRegistry registry) throws IOException { - datadir = tmpdir.resolve("datadir"); - if (!Files.exists(datadir)) datadir = Files.createDirectory(datadir); + var gwcdir = datadir.resolve("gwc"); registry.add("geoserver.backend.data-directory.location", datadir::toAbsolutePath); + registry.add("gwc.cache-directory", gwcdir::toAbsolutePath); } private TestRestTemplate restTemplate = new TestRestTemplate("admin", "geoserver"); diff --git a/src/apps/geoserver/wps/src/test/resources/bootstrap-test.yml b/src/apps/geoserver/wps/src/test/resources/bootstrap-test.yml index bb021d0ec..b3df1c5c6 100644 --- a/src/apps/geoserver/wps/src/test/resources/bootstrap-test.yml +++ b/src/apps/geoserver/wps/src/test/resources/bootstrap-test.yml @@ -14,17 +14,7 @@ geoserver: backend: data-directory: enabled: true - location: ${data_directory:${java.io.tmpdir}/geoserver_cloud_data_directory} - jdbcconfig: - enabled: false - web.enabled: false - initdb: true - cache-directory: ${java.io.tmpdir}/geoserver-jdbcconfig-cache - datasource: - driverClassname: org.h2.Driver - url: jdbc:h2:mem:test;DB_CLOSE_DELAY=-1 - username: sa - password: + location: # to be set by the test classes logging: level: diff --git a/src/catalog/backends/datadir/src/test/java/org/geoserver/cloud/autoconfigure/catalog/backend/datadir/DataDirectoryAutoConfigurationTest.java b/src/catalog/backends/datadir/src/test/java/org/geoserver/cloud/autoconfigure/catalog/backend/datadir/DataDirectoryAutoConfigurationTest.java index 5703d52b3..91b3d4a7e 100644 --- a/src/catalog/backends/datadir/src/test/java/org/geoserver/cloud/autoconfigure/catalog/backend/datadir/DataDirectoryAutoConfigurationTest.java +++ b/src/catalog/backends/datadir/src/test/java/org/geoserver/cloud/autoconfigure/catalog/backend/datadir/DataDirectoryAutoConfigurationTest.java @@ -7,7 +7,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertSame; -import java.nio.file.Paths; +import java.nio.file.Path; import org.geoserver.GeoServerConfigurationLock; import org.geoserver.catalog.CatalogFacade; import org.geoserver.catalog.plugin.CatalogPlugin; @@ -24,6 +24,7 @@ import org.geoserver.platform.GeoServerResourceLoader; import org.geoserver.platform.config.UpdateSequence; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; @@ -33,6 +34,8 @@ */ class DataDirectoryAutoConfigurationTest { + static @TempDir Path datadir; + private ApplicationContextRunner runner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of( // AutoConfigurations from gs-cloud-catalog-backend-common @@ -50,7 +53,7 @@ class DataDirectoryAutoConfigurationTest { // .withPropertyValues( "geoserver.backend.dataDirectory.enabled=true", // - "geoserver.backend.dataDirectory.location=/tmp/data_dir_autoconfiguration_test" // + "geoserver.backend.dataDirectory.location=%s".formatted(datadir.toAbsolutePath()) // ); @Test @@ -61,7 +64,7 @@ void testProperties() { assertThat(context).hasSingleBean(DataDirectoryProperties.class); assertThat(context) .getBean(DataDirectoryProperties.class) - .hasFieldOrPropertyWithValue("location", Paths.get("/tmp/data_dir_autoconfiguration_test")); + .hasFieldOrPropertyWithValue("location", datadir.toAbsolutePath()); }); } diff --git a/src/catalog/backends/datadir/src/test/java/org/geoserver/cloud/autoconfigure/catalog/backend/datadir/DataDirectoryUpdateSequenceTest.java b/src/catalog/backends/datadir/src/test/java/org/geoserver/cloud/autoconfigure/catalog/backend/datadir/DataDirectoryUpdateSequenceTest.java index 32b0edf5b..6b367a94e 100644 --- a/src/catalog/backends/datadir/src/test/java/org/geoserver/cloud/autoconfigure/catalog/backend/datadir/DataDirectoryUpdateSequenceTest.java +++ b/src/catalog/backends/datadir/src/test/java/org/geoserver/cloud/autoconfigure/catalog/backend/datadir/DataDirectoryUpdateSequenceTest.java @@ -4,14 +4,19 @@ */ package org.geoserver.cloud.autoconfigure.catalog.backend.datadir; +import java.io.IOException; +import java.nio.file.Path; import org.geoserver.cloud.config.catalog.backend.datadirectory.DataDirectoryBackendConfiguration; import org.geoserver.cloud.config.catalog.backend.datadirectory.DataDirectoryUpdateSequence; import org.geoserver.config.GeoServer; import org.geoserver.platform.config.UpdateSequence; import org.geoserver.platform.config.UpdateSequenceConformanceTest; +import org.junit.jupiter.api.io.TempDir; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; /** * Test {@link DataDirectoryBackendConfiguration} through {@link DataDirectoryAutoConfiguration} @@ -21,13 +26,18 @@ classes = DataDirectoryTestConfiguration.class, // properties = { "geoserver.backend.dataDirectory.enabled=true", - "geoserver.backend.dataDirectory.location=/tmp/data_dir_autoconfiguration_test" }) @ActiveProfiles("test") class DataDirectoryUpdateSequenceTest implements UpdateSequenceConformanceTest { private @Autowired DataDirectoryUpdateSequence updateSequence; private @Autowired GeoServer geoserver; + static @TempDir Path datadir; + + @DynamicPropertySource + static void setUpDataDir(DynamicPropertyRegistry registry) throws IOException { + registry.add("geoserver.backend.data-directory.location", datadir::toAbsolutePath); + } @Override public UpdateSequence getUpdataSequence() { diff --git a/src/catalog/backends/datadir/src/test/resources/application.yml b/src/catalog/backends/datadir/src/test/resources/application.yml index 8ca8b8f34..dfaf6d6c2 100644 --- a/src/catalog/backends/datadir/src/test/resources/application.yml +++ b/src/catalog/backends/datadir/src/test/resources/application.yml @@ -1,31 +1,19 @@ -info.instance-id: test-instance-id spring: main: banner-mode: off allow-bean-definition-overriding: true # false by default since spring-boot 2.6.0, breaks geoserver initialization allow-circular-references: true - cloud.bus.enabled: false autoconfigure: exclude: - org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration - -eureka.client.enabled: false - geoserver: backend: data-directory: enabled: false - location: ${java.io.tmpdir}/geoserver_cloud_data_directory + location: # to be set by the test classes logging: level: root: WARN - #org.geoserver.platform: ERROR - org.geoserver: warn - org.geoserver.cloud: warn - org.geoserver.cloud.config.factory: warn - org.geoserver.jdbcconfig: warn - org.geoserver.jdbcstore: warn - org.geoserver.cloud.catalog.locking: info diff --git a/src/catalog/jackson-bindings/geoserver/src/test/resources/bootstrap-test.yml b/src/catalog/jackson-bindings/geoserver/src/test/resources/bootstrap-test.yml deleted file mode 100644 index 6f0cf7222..000000000 --- a/src/catalog/jackson-bindings/geoserver/src/test/resources/bootstrap-test.yml +++ /dev/null @@ -1,42 +0,0 @@ -geoserver: - security.enabled: false - catalog: - isolated: true - advertised: true - localWorkspace: true - secure: true - backend: - data-directory: - enabled: false - location: ${java.io.tmpdir}/gscloud_tests/data_directory_${random.uuid} - jdbcconfig: - enabled: false - initdb: true - cache-directory: ${java.io.tmpdir}/gscloud_tests/jdbcconfig_cache_${random.uuid} - datasource: - driverClassname: org.h2.Driver - url: jdbc:h2:mem:test; - username: sa - password: - - -spring: - main: - banner-mode: off - allow-bean-definition-overriding: true - allow-circular-references: true # false by default since spring-boot 2.6.0, breaks geoserver initialization - cloud.config.enabled: false - cloud.config.discovery.enabled: false - cloud.bus.enabled: false -eureka.client.enabled: false - -feign.logger.level: full - -logging: - level: - root: WARN - org.geoserver.platform: ERROR - org.geoserver.cloud: DEBUG - org.geoserver.cloud.config.factory: TRACE - org.springframework.test: ERROR - org.springframework.integration.handler.LoggingHandler: OFF #spurious "Could Not Convert Output" stack traces during tests diff --git a/src/gwc/autoconfigure/src/test/resources/application.yml b/src/gwc/autoconfigure/src/test/resources/application.yml index 02d5f6dd4..bd0437588 100644 --- a/src/gwc/autoconfigure/src/test/resources/application.yml +++ b/src/gwc/autoconfigure/src/test/resources/application.yml @@ -4,32 +4,7 @@ spring: allow-bean-definition-overriding: true allow-circular-references: true # false by default since spring-boot 2.6.0, breaks geoserver initialization cloud.bus.enabled: false - cloud.config.enabled: false - cloud.config.discovery.enabled: false -eureka.client.enabled: false - -geoserver: - security.enabled: true - backend: - data-directory: - enabled: true - location: ${data_directory:${java.io.tmpdir}/geoserver_cloud_data_directory} - jdbcconfig: - enabled: false - web.enabled: false - initdb: true - cache-directory: ${java.io.tmpdir}/geoserver-jdbcconfig-cache} - datasource: - driverClassname: org.h2.Driver - url: jdbc:h2:mem:test;DB_CLOSE_DELAY=-1 - username: sa - password: logging: level: ROOT: WARN - org.geoserver.platform: ERROR - org.geoserver.cloud: DEBUG - org.geoserver.cloud.config.factory: INFO - org.springframework.test: ERROR - diff --git a/src/gwc/core/src/test/resources/application.yml b/src/gwc/core/src/test/resources/application.yml index 02d5f6dd4..432c0f63b 100644 --- a/src/gwc/core/src/test/resources/application.yml +++ b/src/gwc/core/src/test/resources/application.yml @@ -3,33 +3,8 @@ spring: banner-mode: off allow-bean-definition-overriding: true allow-circular-references: true # false by default since spring-boot 2.6.0, breaks geoserver initialization - cloud.bus.enabled: false - cloud.config.enabled: false - cloud.config.discovery.enabled: false -eureka.client.enabled: false - -geoserver: - security.enabled: true - backend: - data-directory: - enabled: true - location: ${data_directory:${java.io.tmpdir}/geoserver_cloud_data_directory} - jdbcconfig: - enabled: false - web.enabled: false - initdb: true - cache-directory: ${java.io.tmpdir}/geoserver-jdbcconfig-cache} - datasource: - driverClassname: org.h2.Driver - url: jdbc:h2:mem:test;DB_CLOSE_DELAY=-1 - username: sa - password: logging: level: ROOT: WARN - org.geoserver.platform: ERROR - org.geoserver.cloud: DEBUG - org.geoserver.cloud.config.factory: INFO - org.springframework.test: ERROR diff --git a/src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/config/jndi/JNDIInitializer.java b/src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/config/jndi/JNDIInitializer.java index bc3c5b4ae..b1ec7a23c 100644 --- a/src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/config/jndi/JNDIInitializer.java +++ b/src/library/spring-boot-simplejndi/src/main/java/org/geoserver/cloud/config/jndi/JNDIInitializer.java @@ -11,6 +11,7 @@ import javax.naming.spi.NamingManager; import javax.sql.DataSource; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.ApplicationContextException; import org.springframework.jdbc.support.DatabaseStartupValidator; @@ -20,20 +21,16 @@ * @since 1.0 */ @Slf4j(topic = "org.geoserver.cloud.config.jndidatasource") -public class JNDIInitializer implements InitializingBean { +public class JNDIInitializer implements InitializingBean, DisposableBean { private JNDIDataSourcesConfigurationProperties config; - static boolean initialized = false; - JNDIInitializer(JNDIDataSourcesConfigurationProperties config) { this.config = config; } @Override public void afterPropertiesSet() throws Exception { - if (initialized) throw new IllegalStateException("JNDI already initialized or failed. Giving up."); - initialized = true; Map configs = config.getDatasources(); @@ -57,6 +54,31 @@ public void afterPropertiesSet() throws Exception { } } + @Override + public void destroy() throws Exception { + Map configs = config.getDatasources(); + if (null == configs || configs.isEmpty()) { + return; + } + Context initialContext; + try { + initialContext = getInitialContext(); + } catch (Exception e) { + log.error("Error getting initial context during destroy", e); + return; + } + + configs.entrySet().forEach(e -> { + String jndiName = toJndiDatasourceName(e.getKey()); + try { + HikariDataSource dataSource = (HikariDataSource) initialContext.lookup(jndiName); + dataSource.close(); + } catch (NamingException ex) { + log.warn("Error looking up data source {}", jndiName, ex); + } + }); + } + String toJndiDatasourceName(String dsname) { final String prefix = "java:comp/env/jdbc/"; if (!dsname.startsWith(prefix)) { @@ -78,12 +100,7 @@ void setUpDataSource(String jndiName, JNDIDatasourceConfig props) { return; } - Context initialContext; - try { - initialContext = NamingManager.getInitialContext(null); - } catch (NamingException e) { - throw new ApplicationContextException("No JNDI initial context bound", e); - } + Context initialContext = getInitialContext(); DataSource dataSource = createDataSource(props); waitForIt(jndiName, dataSource, props); @@ -103,6 +120,16 @@ void setUpDataSource(String jndiName, JNDIDatasourceConfig props) { } } + private Context getInitialContext() { + Context initialContext; + try { + initialContext = NamingManager.getInitialContext(null); + } catch (NamingException e) { + throw new ApplicationContextException("No JNDI initial context bound", e); + } + return initialContext; + } + private void waitForIt(String jndiName, DataSource dataSource, JNDIDatasourceConfig props) { if (props.isWaitForIt()) { log.info("Waiting up to {} seconds for datasource {}", props.getWaitTimeout(), jndiName); @@ -113,7 +140,7 @@ private void waitForIt(String jndiName, DataSource dataSource, JNDIDatasourceCon } } - protected DataSource createDataSource(JNDIDatasourceConfig props) { + protected HikariDataSource createDataSource(JNDIDatasourceConfig props) { HikariDataSource dataSource = props.initializeDataSourceBuilder() // .type(HikariDataSource.class) .build(); diff --git a/src/pom.xml b/src/pom.xml index e26fff53e..522f50086 100644 --- a/src/pom.xml +++ b/src/pom.xml @@ -975,6 +975,7 @@ true false + 1C --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.text=ALL-UNNAMED --add-opens=java.desktop/java.awt.font=ALL-UNNAMED --add-opens=java.desktop/sun.awt.image=ALL-UNNAMED --add-opens=java.naming/com.sun.jndi.ldap=ALL-UNNAMED @@ -1299,6 +1300,9 @@ org.apache.maven.plugins maven-failsafe-plugin + false + 1C + false --add-exports=java.desktop/sun.awt.image=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED diff --git a/src/starters/spring-boot/src/test/resources/application.yml b/src/starters/spring-boot/src/test/resources/application.yml index 7c54c27ff..776db89ad 100644 --- a/src/starters/spring-boot/src/test/resources/application.yml +++ b/src/starters/spring-boot/src/test/resources/application.yml @@ -1,46 +1,13 @@ -info: - instance-id: test-instance-id spring: main: banner-mode: off allow-bean-definition-overriding: true # false by default since spring-boot 2.6.0, breaks geoserver initialization allow-circular-references: true - cloud.bus.enabled: false autoconfigure: exclude: - org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration - -eureka.client.enabled: false - -geoserver: - backend: - catalog-service: - enabled: false - url: catalog-service -# resource-store.fallback.enabled: ${java.io.tmpdir}/gs_cloud/catalog_client_resource_store_fallback -# resource-store.fallback: ${java.io.tmpdir}/gs_cloud/catalog_client_resource_store_fallback - data-directory: - enabled: false - location: ${java.io.tmpdir}/geoserver_cloud_data_directory - jdbcconfig: - enabled: false - web.enabled: false - initdb: true - cache-directory: ${java.io.tmpdir}/geoserver-jdbcconfig-cache - datasource: - driverClassname: org.h2.Driver - url: jdbc:h2:mem:test;DB_CLOSE_DELAY=-1 - username: sa - password: - logging: level: root: WARN - #org.geoserver.platform: ERROR - org.geoserver: INFO - org.geoserver.cloud: INFO - org.geoserver.cloud.config.factory: INFO - org.geoserver.jdbcconfig: WARN - org.geoserver.jdbcstore: WARN \ No newline at end of file