From 7cf10e14cbebd1b602130ebbdb07a2d11a2ce7d8 Mon Sep 17 00:00:00 2001 From: William Koch Date: Thu, 9 Oct 2025 09:58:54 -0400 Subject: [PATCH] [issue-2375] [issue-2377] Re-enables PermissionTest and SecurityIT tests * Adds the verify goal to the default set of goals for the Maven failsafe plugin to ensure integration test failures are caught by `mvn test` * Switches from OpenTable's otj-pg-embedded to Zonky embedded-postgres * OpenTable's 0.13.1 doesn't support Apple Silicon * Newer versions of OpenTable use Docker and testcontainers under the hood * OpenTable recommends using Zonky in cases where a non-Docker solution is preferred: https://github.com/opentable/otj-pg-embedded/issues/166 --- pom.xml | 69 +++++++++++++++++-- .../ohdsi/webapi/PostgresSingletonRule.java | 3 +- .../webapi/pathway/PathwayAnalysisTest.java | 11 ++- .../ohdsi/webapi/security/PermissionTest.java | 3 - .../java/org/ohdsi/webapi/test/ITStarter.java | 2 +- .../org/ohdsi/webapi/test/SecurityIT.java | 41 ++++++++--- .../java/org/ohdsi/webapi/test/WebApiIT.java | 23 +++++-- 7 files changed, 125 insertions(+), 27 deletions(-) diff --git a/pom.xml b/pom.xml index 00cf5f7878..af33ef9421 100644 --- a/pom.xml +++ b/pom.xml @@ -436,6 +436,7 @@ 2.22.2 ${skipUnitTests} + false @@ -465,12 +466,14 @@ 2.22.2 ${skipITtests} + false test integration-test + verify @@ -583,6 +586,13 @@ redshift-jdbc42-no-awssdk 1.2.10.1009 + + io.zonky.test.postgres + embedded-postgres-binaries-bom + 17.6.0 + pom + import + @@ -1218,12 +1228,13 @@ org.ehcache ehcache 3.9.11 - - com.opentable.components - otj-pg-embedded - 0.13.1 - test + + io.zonky.test + embedded-postgres + 2.1.1 + test + org.springframework.boot spring-boot-starter-test @@ -2024,5 +2035,53 @@ + + windows-x86-zonky-postgres + + + Windows + amd64 + + + + + io.zonky.test.postgres + embedded-postgres-binaries-windows-amd64 + test + + + + + apple-silicon-zonky-postgres + + + mac + aarch64 + + + + + io.zonky.test.postgres + embedded-postgres-binaries-darwin-arm64v8 + test + + + + + linux-x86-zonky-postgres + + + unix + amd64 + + + + + io.zonky.test.postgres + embedded-postgres-binaries-linux-amd64-alpine + test + + + diff --git a/src/test/java/org/ohdsi/webapi/PostgresSingletonRule.java b/src/test/java/org/ohdsi/webapi/PostgresSingletonRule.java index 61966edc8e..00f0380fd6 100644 --- a/src/test/java/org/ohdsi/webapi/PostgresSingletonRule.java +++ b/src/test/java/org/ohdsi/webapi/PostgresSingletonRule.java @@ -31,9 +31,10 @@ import java.io.IOException; import java.sql.Connection; import java.sql.SQLException; + +import io.zonky.test.db.postgres.embedded.EmbeddedPostgres; import org.junit.rules.ExternalResource; -import com.opentable.db.postgres.embedded.EmbeddedPostgres; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/test/java/org/ohdsi/webapi/pathway/PathwayAnalysisTest.java b/src/test/java/org/ohdsi/webapi/pathway/PathwayAnalysisTest.java index 9ff81cecb8..85b276c476 100644 --- a/src/test/java/org/ohdsi/webapi/pathway/PathwayAnalysisTest.java +++ b/src/test/java/org/ohdsi/webapi/pathway/PathwayAnalysisTest.java @@ -42,14 +42,19 @@ import org.ohdsi.sql.SqlTranslate; import org.ohdsi.webapi.AbstractDatabaseTest; import org.ohdsi.webapi.job.JobExecutionResource; +import org.ohdsi.webapi.pathway.converter.PathwayAnalysisToPathwayVersionConverter; +import org.ohdsi.webapi.pathway.converter.PathwayVersionToPathwayVersionFullDTOConverter; import org.ohdsi.webapi.pathway.converter.SerializedPathwayAnalysisToPathwayAnalysisConverter; import org.ohdsi.webapi.pathway.domain.PathwayAnalysisEntity; import org.ohdsi.webapi.pathway.domain.PathwayAnalysisGenerationEntity; +import org.ohdsi.webapi.pathway.dto.PathwayAnalysisExportDTO; import org.ohdsi.webapi.source.Source; import org.ohdsi.webapi.source.SourceDaimon; import org.ohdsi.webapi.source.SourceRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.convert.ConversionService; +import org.springframework.core.convert.support.DefaultConversionService; /** * @@ -87,6 +92,9 @@ public class PathwayAnalysisTest extends AbstractDatabaseTest { @Autowired private PathwayService pathwayService; + @Autowired + private ConversionService conversionService; + @Value("${datasource.ohdsi.schema}") private String ohdsiSchema; @@ -110,7 +118,8 @@ public void setUp() throws Exception { resetSequence(String.format("%s.%s", ohdsiSchema, "pathway_analysis_sequence")); truncateTable(String.format("%s.%s", ohdsiSchema, "generation_cache")); prepareCdmSchema(); - prepareResultSchema(); + prepareResultSchema(); + SerializedPathwayAnalysisToPathwayAnalysisConverter.setConversionService(conversionService); } @After diff --git a/src/test/java/org/ohdsi/webapi/security/PermissionTest.java b/src/test/java/org/ohdsi/webapi/security/PermissionTest.java index dddcbe2bfd..c8a83be095 100644 --- a/src/test/java/org/ohdsi/webapi/security/PermissionTest.java +++ b/src/test/java/org/ohdsi/webapi/security/PermissionTest.java @@ -25,7 +25,6 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.ohdsi.webapi.AbstractDatabaseTest; import org.ohdsi.webapi.shiro.PermissionManager; @@ -65,7 +64,6 @@ public void setup() { ThreadContext.bind(subject); } -// @Ignore @Test public void permsTest() throws Exception { // need to clear authorization cache before each test @@ -88,7 +86,6 @@ public void permsTest() throws Exception { } -// @Ignore @Test public void wildcardTest() throws Exception { // need to clear authorization cache before each test diff --git a/src/test/java/org/ohdsi/webapi/test/ITStarter.java b/src/test/java/org/ohdsi/webapi/test/ITStarter.java index cf7593e17f..ce10da58b3 100644 --- a/src/test/java/org/ohdsi/webapi/test/ITStarter.java +++ b/src/test/java/org/ohdsi/webapi/test/ITStarter.java @@ -1,6 +1,6 @@ package org.ohdsi.webapi.test; -import com.opentable.db.postgres.embedded.EmbeddedPostgres; +import io.zonky.test.db.postgres.embedded.EmbeddedPostgres; import org.apache.shiro.subject.SimplePrincipalCollection; import org.apache.shiro.subject.Subject; import org.junit.AfterClass; diff --git a/src/test/java/org/ohdsi/webapi/test/SecurityIT.java b/src/test/java/org/ohdsi/webapi/test/SecurityIT.java index 3dc65d779d..242a084247 100644 --- a/src/test/java/org/ohdsi/webapi/test/SecurityIT.java +++ b/src/test/java/org/ohdsi/webapi/test/SecurityIT.java @@ -1,9 +1,12 @@ package org.ohdsi.webapi.test; +import com.github.springtestdbunit.DbUnitTestExecutionListener; import com.github.springtestdbunit.annotation.DatabaseOperation; import com.github.springtestdbunit.annotation.DatabaseTearDown; +import com.github.springtestdbunit.annotation.DbUnitConfiguration; import com.google.common.collect.ImmutableMap; +import org.apache.catalina.webresources.TomcatURLStreamHandlerFactory; import org.glassfish.jersey.server.model.Parameter; import org.glassfish.jersey.server.model.Resource; import org.glassfish.jersey.server.model.ResourceMethod; @@ -12,23 +15,38 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ErrorCollector; +import org.junit.runner.RunWith; import org.ohdsi.webapi.JerseyConfig; +import org.ohdsi.webapi.WebApi; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.http.*; -import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.TestExecutionListeners; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringRunner; import org.springframework.web.util.UriComponentsBuilder; import javax.ws.rs.core.MediaType; +import java.io.IOException; import java.net.URI; import java.util.*; import static org.assertj.core.api.Java6Assertions.assertThat; +import static org.springframework.test.context.TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS; +@RunWith(SpringRunner.class) +@SpringBootTest(classes = {WebApi.class, WebApiIT.DbUnitConfiguration.class}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@ActiveProfiles("test") +@DbUnitConfiguration(databaseConnection = "dbUnitDatabaseConnection") +@TestExecutionListeners(value = {DbUnitTestExecutionListener.class}, mergeMode = MERGE_WITH_DEFAULTS) @DatabaseTearDown(value = "/database/empty.xml", type = DatabaseOperation.DELETE_ALL) -public class SecurityIT extends WebApiIT { +@TestPropertySource(properties = {"security.provider=AtlasRegularSecurity"}) +public class SecurityIT { private final Map EXPECTED_RESPONSE_CODES = ImmutableMap.builder() .put("/info/", HttpStatus.OK) @@ -47,25 +65,26 @@ public class SecurityIT extends WebApiIT { @Autowired private JerseyConfig jerseyConfig; + @Value("${baseUri}") + private String baseUri; + @Rule public ErrorCollector collector = new ErrorCollector(); private final Logger LOG = LoggerFactory.getLogger(SecurityIT.class); @BeforeClass - public static void prepare() { - - System.setProperty("security.provider", "AtlasRegularSecurity"); + public static void before() throws IOException { + TomcatURLStreamHandlerFactory.disable(); + ITStarter.before(); } @AfterClass - public static void disableSecurity() { - - System.setProperty("security.provider", "DisabledSecurity"); + public static void after() { + ITStarter.tearDownSubject(); } @Test - @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD) public void testServiceSecurity() { Map> serviceMap = getServiceMap(); @@ -76,7 +95,7 @@ public void testServiceSecurity() { serviceInfo.pathPrefix = "/" + serviceInfo.pathPrefix; } serviceInfo.pathPrefix = serviceInfo.pathPrefix.replaceAll("//", "/"); - String rawUrl = getBaseUri() + serviceInfo.pathPrefix; + String rawUrl = baseUri + serviceInfo.pathPrefix; URI uri = null; try { Map parametersMap = prepareParameters(serviceInfo.parameters); @@ -195,4 +214,4 @@ public String getMessage() { return serviceName + ": " + super.getMessage(); } } -} \ No newline at end of file +} diff --git a/src/test/java/org/ohdsi/webapi/test/WebApiIT.java b/src/test/java/org/ohdsi/webapi/test/WebApiIT.java index ed2af1e0c5..1f7dd6c5c3 100644 --- a/src/test/java/org/ohdsi/webapi/test/WebApiIT.java +++ b/src/test/java/org/ohdsi/webapi/test/WebApiIT.java @@ -1,6 +1,7 @@ package org.ohdsi.webapi.test; import static org.junit.Assert.assertEquals; +import static org.springframework.test.context.TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS; import com.github.springtestdbunit.DbUnitTestExecutionListener; import com.github.springtestdbunit.annotation.DbUnitConfiguration; @@ -9,6 +10,7 @@ import java.util.Arrays; import java.util.Collection; +import com.github.springtestdbunit.bean.DatabaseDataSourceConnectionFactoryBean; import com.odysseusinc.arachne.commons.types.DBMSType; import com.odysseusinc.arachne.execution_engine_common.api.v1.dto.KerberosAuthMechanism; import org.apache.catalina.webresources.TomcatURLStreamHandlerFactory; @@ -26,6 +28,8 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.test.context.TestExecutionListeners; import org.springframework.test.context.junit4.SpringRunner; @@ -33,14 +37,14 @@ import org.springframework.http.ResponseEntity; import org.springframework.test.context.ActiveProfiles; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.test.context.support.DependencyInjectionTestExecutionListener; -import org.springframework.test.context.support.DirtiesContextTestExecutionListener; + +import javax.sql.DataSource; @RunWith(SpringRunner.class) -@SpringBootTest(classes = WebApi.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@SpringBootTest(classes = {WebApi.class, WebApiIT.DbUnitConfiguration.class}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @ActiveProfiles("test") -@DbUnitConfiguration(databaseConnection = {"primaryDataSource"}) -@TestExecutionListeners({DependencyInjectionTestExecutionListener.class, DbUnitTestExecutionListener.class, DirtiesContextTestExecutionListener.class}) +@DbUnitConfiguration(databaseConnection = "dbUnitDatabaseConnection") +@TestExecutionListeners(value = {DbUnitTestExecutionListener.class}, mergeMode = MERGE_WITH_DEFAULTS) public abstract class WebApiIT { protected final Logger log = LoggerFactory.getLogger(getClass()); @@ -68,6 +72,15 @@ public abstract class WebApiIT { "/ddl/results/achilles_result_concept_count.sql" ); + @TestConfiguration + public static class DbUnitConfiguration { + @Bean + DatabaseDataSourceConnectionFactoryBean dbUnitDatabaseConnection(DataSource primaryDataSource) { + DatabaseDataSourceConnectionFactoryBean dbUnitDatabaseConnection = new DatabaseDataSourceConnectionFactoryBean(primaryDataSource); + dbUnitDatabaseConnection.setSchema("public"); + return dbUnitDatabaseConnection; + } + } @Value("${baseUri}") private String baseUri;