diff --git a/docs/configuration/advanced/application-yml.md b/docs/configuration/advanced/application-yml.md index 2ecd595839..896b7f858b 100644 --- a/docs/configuration/advanced/application-yml.md +++ b/docs/configuration/advanced/application-yml.md @@ -151,6 +151,7 @@ floci: rds: enabled: true + mock: false # true = clusters/instances created without Docker (useful for CI) proxy-base-port: 7001 proxy-max-port: 7099 default-postgres-image: "postgres:16-alpine" diff --git a/docs/configuration/environment-variables.md b/docs/configuration/environment-variables.md index ff8806fe82..401ffa449d 100644 --- a/docs/configuration/environment-variables.md +++ b/docs/configuration/environment-variables.md @@ -319,6 +319,7 @@ These services spawn Docker containers. They require access to the Docker socket | Variable | Default | Description | |---|---|---| | `FLOCI_SERVICES_RDS_ENABLED` | `true` | Enable the RDS service | +| `FLOCI_SERVICES_RDS_MOCK` | `false` | When `true`, DB clusters and instances are created instantly without a real container or auth proxy (API only) | | `FLOCI_SERVICES_RDS_PROXY_BASE_PORT` | `7001` | First port in the RDS proxy range | | `FLOCI_SERVICES_RDS_PROXY_MAX_PORT` | `7099` | Last port in the RDS proxy range | | `FLOCI_SERVICES_RDS_DEFAULT_POSTGRES_IMAGE` | `postgres:16-alpine` | Default PostgreSQL Docker image | diff --git a/docs/services/rds.md b/docs/services/rds.md index 1a2d55748b..754f88ed51 100644 --- a/docs/services/rds.md +++ b/docs/services/rds.md @@ -40,6 +40,7 @@ RDS Data API (`rds-data`) is documented separately because it uses REST JSON rou | Variable | Default | Description | |---|---|---| | `FLOCI_SERVICES_RDS_ENABLED` | `true` | Enable or disable the service | +| `FLOCI_SERVICES_RDS_MOCK` | `false` | `true` = metadata only (no Docker container or auth proxy) | | `FLOCI_SERVICES_RDS_PROXY_BASE_PORT` | `7000` | First host port in the RDS proxy range | | `FLOCI_SERVICES_RDS_PROXY_MAX_PORT` | `7099` | Last host port in the RDS proxy range | | `FLOCI_SERVICES_RDS_DEFAULT_POSTGRES_IMAGE` | `postgres:16-alpine` | Docker image for PostgreSQL instances | @@ -64,6 +65,27 @@ services: FLOCI_SERVICES_RDS_PROXY_BASE_PORT: "7001" ``` +### Mock mode (CI / tests) + +Set `FLOCI_SERVICES_RDS_MOCK=true` when you only need the management API shape: clusters and +instances are registered as `available` immediately, with no Docker container or auth proxy behind +them. Each resource still gets a unique endpoint port, but nothing listens on it. + +```yaml +# docker-compose.yml — CI / test environment +services: + floci: + image: floci/floci:latest + environment: + FLOCI_SERVICES_RDS_MOCK: "true" +``` + +!!! note "Switching modes over persisted state" + With a persistent storage mode, changing `FLOCI_SERVICES_RDS_MOCK` between restarts is + best-effort, as with the other mock-capable services: resources created in real mode and + deleted under mock leave their containers and volumes behind, and resources created in mock + mode are restored with fresh, empty containers when loaded in real mode. + ## Examples ```bash diff --git a/src/main/java/io/github/hectorvent/floci/config/EmulatorConfig.java b/src/main/java/io/github/hectorvent/floci/config/EmulatorConfig.java index f4ea15a04b..de6ca24d68 100644 --- a/src/main/java/io/github/hectorvent/floci/config/EmulatorConfig.java +++ b/src/main/java/io/github/hectorvent/floci/config/EmulatorConfig.java @@ -695,6 +695,12 @@ interface RdsServiceConfig { @WithDefault("true") boolean enabled(); + /** When true, DB clusters and instances are created instantly without a real Docker + * container or auth proxy (API/metadata only). Useful for CI and environments without + * access to the Docker socket. */ + @WithDefault("false") + boolean mock(); + @WithDefault("7000") int proxyBasePort(); diff --git a/src/main/java/io/github/hectorvent/floci/services/rds/RdsService.java b/src/main/java/io/github/hectorvent/floci/services/rds/RdsService.java index 47dabd2cce..55205aaef6 100644 --- a/src/main/java/io/github/hectorvent/floci/services/rds/RdsService.java +++ b/src/main/java/io/github/hectorvent/floci/services/rds/RdsService.java @@ -222,6 +222,9 @@ public DbInstance createDbInstance(String id, String engineParam, String engineV getDbSubnetGroup(dbSubnetGroupName); } validateInstanceParameterGroup(paramGroupName, engineParam, engineVersion); + boolean mock = config.services().rds().mock(); + // Always reserve a unique port (even in mock) so endpoints stay distinct and usedPorts + // is consistent; mock mode only skips starting the container and auth proxy. int proxyPort = allocateProxyPort(); if (masterUsername == null || masterUsername.isBlank()) { masterUsername = "root"; @@ -230,8 +233,8 @@ public DbInstance createDbInstance(String id, String engineParam, String engineV masterPassword = generatedMasterPassword(); } - String backendHost; - int backendPort; + String backendHost = null; + int backendPort = 0; String containerId = null; String containerHost = null; int containerPort = 0; @@ -240,7 +243,7 @@ public DbInstance createDbInstance(String id, String engineParam, String engineV PlacementResolution placement; if (dbClusterIdentifier != null && !dbClusterIdentifier.isBlank()) { - // Cluster member — share the cluster's container + // Cluster member — share the cluster's container (none exists in mock mode) DbCluster cluster = clusters.get(dbClusterIdentifier).orElseThrow(() -> new AwsException("DBClusterNotFoundFault", "DB cluster " + dbClusterIdentifier + " not found.", 404)); @@ -249,25 +252,31 @@ public DbInstance createDbInstance(String id, String engineParam, String engineV containerId = cluster.getContainerId(); containerHost = cluster.getContainerHost(); containerPort = cluster.getContainerPort(); - instanceDockerVolumeName = cluster.getDockerVolumeName() != null - ? cluster.getDockerVolumeName() - : volumeName(cluster.getVolumeId(), cluster.getDbClusterIdentifier()); + if (!mock) { + // In mock mode the cluster has no volume id, so the fallback would persist a + // bogus volume name that a later non-mock restore could try to reference. + instanceDockerVolumeName = cluster.getDockerVolumeName() != null + ? cluster.getDockerVolumeName() + : volumeName(cluster.getVolumeId(), cluster.getDbClusterIdentifier()); + } placement = PlacementResolution.fromCluster(cluster); } else { placement = resolvePlacement(dbSubnetGroupName, availabilityZone, multiAz); - // Standalone instance — start its own container - String image = imageForEngine(engine, engineVersion); - instanceVolumeId = String.format("%06x", new SecureRandom().nextInt(0xFFFFFF)); - RdsContainerHandle handle = containerManager.start(id, instanceVolumeId, engine, image, masterUsername, masterPassword, dbName); - backendHost = handle.getHost(); - backendPort = handle.getPort(); - containerId = handle.getContainerId(); - containerHost = handle.getHost(); - containerPort = handle.getPort(); - instanceDockerVolumeName = volumeName(instanceVolumeId, id); + if (!mock) { + // Standalone instance — start its own container + String image = imageForEngine(engine, engineVersion); + instanceVolumeId = String.format("%06x", new SecureRandom().nextInt(0xFFFFFF)); + RdsContainerHandle handle = containerManager.start(id, instanceVolumeId, engine, image, masterUsername, masterPassword, dbName); + backendHost = handle.getHost(); + backendPort = handle.getPort(); + containerId = handle.getContainerId(); + containerHost = handle.getHost(); + containerPort = handle.getPort(); + instanceDockerVolumeName = volumeName(instanceVolumeId, id); + } } - DbEndpoint endpoint = new DbEndpoint(proxyEndpointHost(), proxyPort); + DbEndpoint endpoint = new DbEndpoint(mock ? "localhost" : proxyEndpointHost(), proxyPort); DbInstance instance = new DbInstance(id, engine, engineVersion, masterUsername, masterPassword, dbName, dbInstanceClass, allocatedStorage, DbInstanceStatus.AVAILABLE, endpoint, iamEnabled, paramGroupName, dbClusterIdentifier, Instant.now(), proxyPort); @@ -291,9 +300,11 @@ public DbInstance createDbInstance(String id, String engineParam, String engineV attachManagedMasterUserSecret(instance, region, masterUserSecretKmsKeyId); } - proxyManager.startProxy(id, engine, iamEnabled, proxyPort, backendHost, backendPort, - masterUsername, masterPassword, dbName, - (user, pw) -> validateDbPassword(id, user, pw)); + if (!mock) { + proxyManager.startProxy(id, engine, iamEnabled, proxyPort, backendHost, backendPort, + masterUsername, masterPassword, dbName, + (user, pw) -> validateDbPassword(id, user, pw)); + } if (dbClusterIdentifier != null && !dbClusterIdentifier.isBlank()) { DbCluster cluster = clusters.get(dbClusterIdentifier).orElse(null); @@ -443,34 +454,39 @@ public DbInstance rebootDbInstance(String id) { instance.setStatus(DbInstanceStatus.REBOOTING); instances.put(id, instance); - // Stop proxy during reboot - proxyManager.stopProxy(id); - - // Restart container if it's a standalone instance - if (instance.getDbClusterIdentifier() == null && instance.getContainerId() != null) { - try { - containerManager.stop(buildHandle(instance)); - } catch (Exception e) { - LOG.warnv("Error stopping container during reboot of {0}: {1}", id, e.getMessage()); + boolean mock = config.services().rds().mock(); + if (!mock) { + // Stop proxy during reboot + proxyManager.stopProxy(id); + + // Restart container if it's a standalone instance + if (instance.getDbClusterIdentifier() == null && instance.getContainerId() != null) { + try { + containerManager.stop(buildHandle(instance)); + } catch (Exception e) { + LOG.warnv("Error stopping container during reboot of {0}: {1}", id, e.getMessage()); + } + String image = imageForEngine(instance.getEngine(), instance.getEngineVersion()); + RdsContainerHandle handle = containerManager.start(id, instance.getVolumeId(), instance.getEngine(), image, + instance.getMasterUsername(), instance.getMasterPassword(), instance.getDbName()); + instance.setContainerId(handle.getContainerId()); + instance.setContainerHost(handle.getHost()); + instance.setContainerPort(handle.getPort()); } - String image = imageForEngine(instance.getEngine(), instance.getEngineVersion()); - RdsContainerHandle handle = containerManager.start(id, instance.getVolumeId(), instance.getEngine(), image, - instance.getMasterUsername(), instance.getMasterPassword(), instance.getDbName()); - instance.setContainerId(handle.getContainerId()); - instance.setContainerHost(handle.getHost()); - instance.setContainerPort(handle.getPort()); } instance.setStatus(DbInstanceStatus.AVAILABLE); instances.put(id, instance); - String effectiveMasterUser = instance.getMasterUsername() != null - ? instance.getMasterUsername() : "root"; - proxyManager.startProxy(id, instance.getEngine(), - instance.isIamDatabaseAuthenticationEnabled(), - instance.getProxyPort(), instance.getContainerHost(), instance.getContainerPort(), - effectiveMasterUser, instance.getMasterPassword(), instance.getDbName(), - (user, pw) -> validateDbPassword(id, user, pw)); + if (!mock) { + String effectiveMasterUser = instance.getMasterUsername() != null + ? instance.getMasterUsername() : "root"; + proxyManager.startProxy(id, instance.getEngine(), + instance.isIamDatabaseAuthenticationEnabled(), + instance.getProxyPort(), instance.getContainerHost(), instance.getContainerPort(), + effectiveMasterUser, instance.getMasterPassword(), instance.getDbName(), + (user, pw) -> validateDbPassword(id, user, pw)); + } LOG.infov("DB instance {0} rebooted", id); return instance; @@ -488,15 +504,20 @@ public void deleteDbInstance(String id) { instance.setStatus(DbInstanceStatus.DELETING); instances.put(id, instance); - proxyManager.stopProxy(id); + boolean mock = config.services().rds().mock(); + if (!mock) { + proxyManager.stopProxy(id); + } String clusterId = instance.getDbClusterIdentifier(); if (clusterId == null || clusterId.isBlank()) { - // Standalone — stop its container and clean up its Docker volume - if (instance.getContainerId() != null) { - containerManager.stop(buildHandle(instance)); + // Standalone — stop its container and clean up its Docker volume (neither exists in mock mode) + if (!mock) { + if (instance.getContainerId() != null) { + containerManager.stop(buildHandle(instance)); + } + containerManager.removeVolume(instance.getDbInstanceIdentifier(), instance.getVolumeId()); } - containerManager.removeVolume(instance.getDbInstanceIdentifier(), instance.getVolumeId()); } else { // Cluster member — remove from cluster's member list DbCluster cluster = clusters.get(clusterId).orElse(null); @@ -534,21 +555,25 @@ public DbCluster createDbCluster(String id, String engineParam, String engineVer DatabaseEngine engine = resolveEngine(engineParam); validateClusterParameterGroup(paramGroupName, engineParam, engineVersion); PlacementResolution placement = resolvePlacement(dbSubnetGroupName, availabilityZone, multiAz); - int proxyPort = allocateProxyPort(); - String image = imageForEngine(engine, engineVersion); - String clusterVolumeId = String.format("%06x", new SecureRandom().nextInt(0xFFFFFF)); - - RdsContainerHandle handle = containerManager.start(id, clusterVolumeId, engine, image, masterUsername, masterPassword, databaseName); - DbEndpoint endpoint = new DbEndpoint(proxyEndpointHost(), proxyPort); + boolean mock = config.services().rds().mock(); + // Always reserve a unique port (even in mock) so endpoints stay distinct and usedPorts + // is consistent; mock mode only skips starting the container and auth proxy. + int proxyPort = allocateProxyPort(); + DbEndpoint endpoint = new DbEndpoint(mock ? "localhost" : proxyEndpointHost(), proxyPort); DbCluster cluster = new DbCluster(id, engine, engineVersion, masterUsername, masterPassword, databaseName, DbInstanceStatus.AVAILABLE, endpoint, endpoint, iamEnabled, new ArrayList<>(), paramGroupName, Instant.now(), proxyPort); - cluster.setContainerId(handle.getContainerId()); - cluster.setContainerHost(handle.getHost()); - cluster.setContainerPort(handle.getPort()); - cluster.setVolumeId(clusterVolumeId); - cluster.setDockerVolumeName(volumeName(clusterVolumeId, id)); + if (!mock) { + String image = imageForEngine(engine, engineVersion); + String clusterVolumeId = String.format("%06x", new SecureRandom().nextInt(0xFFFFFF)); + RdsContainerHandle handle = containerManager.start(id, clusterVolumeId, engine, image, masterUsername, masterPassword, databaseName); + cluster.setContainerId(handle.getContainerId()); + cluster.setContainerHost(handle.getHost()); + cluster.setContainerPort(handle.getPort()); + cluster.setVolumeId(clusterVolumeId); + cluster.setDockerVolumeName(volumeName(clusterVolumeId, id)); + } cluster.setDbSubnetGroupName(placement.dbSubnetGroupName()); cluster.setVpcId(placement.vpcId()); cluster.setAvailabilityZone(placement.availabilityZone()); @@ -559,13 +584,16 @@ public DbCluster createDbCluster(String id, String engineParam, String engineVer cluster.setDbClusterResourceId("cluster-" + java.util.UUID.randomUUID().toString().replace("-", "").substring(0, 24).toUpperCase()); cluster.setDbClusterArn(regionResolver.buildArn("rds", region, "cluster:" + id)); - String effectiveMasterUser = masterUsername != null ? masterUsername : "root"; - proxyManager.startProxy(id, engine, iamEnabled, proxyPort, handle.getHost(), handle.getPort(), - effectiveMasterUser, masterPassword, databaseName, - (user, pw) -> validateDbClusterPassword(id, user, pw)); + if (!mock) { + String effectiveMasterUser = masterUsername != null ? masterUsername : "root"; + proxyManager.startProxy(id, engine, iamEnabled, proxyPort, cluster.getContainerHost(), cluster.getContainerPort(), + effectiveMasterUser, masterPassword, databaseName, + (user, pw) -> validateDbClusterPassword(id, user, pw)); + } clusters.put(id, cluster); - LOG.infov("DB cluster {0} created, engine={1}, endpoint=localhost:{2}", id, engine, String.valueOf(proxyPort)); + LOG.infov("DB cluster {0} created (mock={1}), engine={2}, endpoint=localhost:{3}", + id, String.valueOf(mock), engine, String.valueOf(proxyPort)); return cluster; } @@ -608,12 +636,13 @@ public void deleteDbCluster(String id) { cluster.setStatus(DbInstanceStatus.DELETING); clusters.put(id, cluster); - proxyManager.stopProxy(id); - - if (cluster.getContainerId() != null) { - containerManager.stop(buildClusterHandle(cluster)); + if (!config.services().rds().mock()) { + proxyManager.stopProxy(id); + if (cluster.getContainerId() != null) { + containerManager.stop(buildClusterHandle(cluster)); + } + containerManager.removeVolume(id, cluster.getVolumeId()); } - containerManager.removeVolume(id, cluster.getVolumeId()); releaseProxyPort(cluster.getProxyPort()); clusters.delete(id); @@ -927,6 +956,14 @@ private void restoreClusters() { if (cluster.getStatus() == DbInstanceStatus.DELETING) { continue; } + if (config.services().rds().mock()) { + int mockPort = reserveOrAllocateProxyPort(cluster.getProxyPort()); + cluster.setProxyPort(mockPort); + cluster.setEndpoint(new DbEndpoint("localhost", mockPort)); + cluster.setReaderEndpoint(new DbEndpoint("localhost", mockPort)); + cluster.setStatus(DbInstanceStatus.AVAILABLE); + continue; + } int proxyPort = reserveOrAllocateProxyPort(cluster.getProxyPort()); cluster.setProxyPort(proxyPort); cluster.setEndpoint(new DbEndpoint(proxyEndpointHost(), proxyPort)); @@ -963,6 +1000,13 @@ private void restoreInstances() { if (instance.getStatus() == DbInstanceStatus.DELETING) { continue; } + if (config.services().rds().mock()) { + int mockPort = reserveOrAllocateProxyPort(instance.getProxyPort()); + instance.setProxyPort(mockPort); + instance.setEndpoint(new DbEndpoint("localhost", mockPort)); + instance.setStatus(DbInstanceStatus.AVAILABLE); + continue; + } int proxyPort = reserveOrAllocateProxyPort(instance.getProxyPort()); instance.setProxyPort(proxyPort); instance.setEndpoint(new DbEndpoint(proxyEndpointHost(), proxyPort)); diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index dc42dca5fd..51f58258bb 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -221,6 +221,7 @@ floci: default-image: "valkey/valkey:8" rds: enabled: true + mock: false # FLOCI_SERVICES_RDS_MOCK — true = metadata only, no Docker (useful for CI) proxy-base-port: 7001 proxy-max-port: 7099 default-postgres-image: "postgres:16-alpine" diff --git a/src/test/java/io/github/hectorvent/floci/services/rds/RdsServiceTest.java b/src/test/java/io/github/hectorvent/floci/services/rds/RdsServiceTest.java index d372a32047..2677a81870 100644 --- a/src/test/java/io/github/hectorvent/floci/services/rds/RdsServiceTest.java +++ b/src/test/java/io/github/hectorvent/floci/services/rds/RdsServiceTest.java @@ -14,6 +14,7 @@ import io.github.hectorvent.floci.services.rds.container.RdsContainerHandle; import io.github.hectorvent.floci.services.rds.container.RdsContainerManager; import io.github.hectorvent.floci.services.rds.model.DbInstance; +import io.github.hectorvent.floci.services.rds.model.DbInstanceStatus; import io.github.hectorvent.floci.services.rds.model.DbParameterGroup; import io.github.hectorvent.floci.services.rds.model.DbSubnetGroup; import io.github.hectorvent.floci.services.rds.proxy.RdsProxyManager; @@ -341,6 +342,108 @@ void deleteDbClusterFailsWhenMembersRemain() { assertTrue(exception.getMessage().contains("still has DB instances")); } + @Test + void mockModeCreatesClusterAvailableWithoutContainerOrProxy() { + when(config.services().rds().mock()).thenReturn(true); + + DbCluster cluster = rdsService.createDbCluster("cluster1", "aurora-postgresql", "16.3", + "admin", "password", "dbname", false, null); + + assertEquals(DbInstanceStatus.AVAILABLE, cluster.getStatus()); + assertEquals("localhost", cluster.getEndpoint().address()); + assertTrue(cluster.getEndpoint().port() > 0); + assertNull(cluster.getContainerId()); + verify(containerManager, never()).start(any(), any(), any(), any(), any(), any(), any()); + verify(proxyManager, never()).startProxy(any(), any(), anyBoolean(), anyInt(), any(), anyInt(), + any(), any(), any(), any()); + } + + @Test + void mockModeCreatesClusterInstanceAvailableWithoutContainer() { + when(config.services().rds().mock()).thenReturn(true); + rdsService.createDbCluster("cluster1", "aurora-postgresql", "16.3", + "admin", "password", "dbname", false, null); + + DbInstance instance = rdsService.createDbInstance("inst1", "aurora-postgresql", "16.3", + "admin", "password", "dbname", "db.serverless", + 0, false, null, null, "cluster1"); + + assertEquals(DbInstanceStatus.AVAILABLE, instance.getStatus()); + assertEquals("localhost", instance.getEndpoint().address()); + // No Docker volume name may be persisted: the mock cluster has a null volume id, so the + // fallback would fabricate a name that a later non-mock restore could try to reference. + assertNull(instance.getDockerVolumeName()); + verify(containerManager, never()).start(any(), any(), any(), any(), any(), any(), any()); + verify(proxyManager, never()).startProxy(any(), any(), anyBoolean(), anyInt(), any(), anyInt(), + any(), any(), any(), any()); + } + + @Test + void mockModeCreatesStandaloneInstanceAvailableWithoutContainer() { + when(config.services().rds().mock()).thenReturn(true); + + DbInstance instance = rdsService.createDbInstance("standalone", "postgres", "16", + "admin", "password", "dbname", "db.t3.micro", + 20, false, null, null, null); + + assertEquals(DbInstanceStatus.AVAILABLE, instance.getStatus()); + assertNull(instance.getContainerId()); + verify(containerManager, never()).start(any(), any(), any(), any(), any(), any(), any()); + } + + @Test + void mockModeDeleteClusterSkipsDockerCleanup() { + when(config.services().rds().mock()).thenReturn(true); + rdsService.createDbCluster("cluster1", "aurora-postgresql", "16.3", + "admin", "password", "dbname", false, null); + + rdsService.deleteDbCluster("cluster1"); + + verify(containerManager, never()).stop(any()); + verify(containerManager, never()).removeVolume(any(), any()); + } + + @Test + void mockModeDeleteStandaloneInstanceSkipsDockerCleanup() { + when(config.services().rds().mock()).thenReturn(true); + rdsService.createDbInstance("standalone", "postgres", "16", + "admin", "password", "dbname", "db.t3.micro", + 20, false, null, null, null); + + rdsService.deleteDbInstance("standalone"); + + verify(containerManager, never()).stop(any()); + verify(containerManager, never()).removeVolume(any(), any()); + } + + @Test + void mockModeAssignsDistinctEndpointPorts() { + when(config.services().rds().mock()).thenReturn(true); + + DbCluster a = rdsService.createDbCluster("cluster-a", "aurora-postgresql", "16.3", + "admin", "password", "dbname", false, null); + DbCluster b = rdsService.createDbCluster("cluster-b", "aurora-postgresql", "16.3", + "admin", "password", "dbname", false, null); + + assertNotEquals(a.getEndpoint().port(), b.getEndpoint().port()); + } + + @Test + void mockModeRebootSkipsContainerAndProxy() { + when(config.services().rds().mock()).thenReturn(true); + rdsService.createDbInstance("standalone", "postgres", "16", + "admin", "password", "dbname", "db.t3.micro", + 20, false, null, null, null); + + DbInstance rebooted = rdsService.rebootDbInstance("standalone"); + + assertEquals(DbInstanceStatus.AVAILABLE, rebooted.getStatus()); + verify(containerManager, never()).start(any(), any(), any(), any(), any(), any(), any()); + verify(containerManager, never()).stop(any()); + verify(proxyManager, never()).startProxy(any(), any(), anyBoolean(), anyInt(), any(), anyInt(), + any(), any(), any(), any()); + } + @Test void createDbClusterRejectsUnknownClusterParameterGroup() { AwsException exception = assertThrows(AwsException.class, () -> rdsService.createDbCluster("cluster1", "aurora-postgresql", "16.3", diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml index d52b7ef23b..6944ef2208 100644 --- a/src/test/resources/application.yml +++ b/src/test/resources/application.yml @@ -120,6 +120,7 @@ floci: default-image: "valkey/valkey:8" rds: enabled: true + mock: false proxy-base-port: 7001 proxy-max-port: 7099 default-postgres-image: "postgres:16-alpine"