diff --git a/.github/workflows/code_quality.yml b/.github/workflows/code_quality.yml index b70825388..abc00f84e 100644 --- a/.github/workflows/code_quality.yml +++ b/.github/workflows/code_quality.yml @@ -39,3 +39,4 @@ jobs: uses: JetBrains/qodana-action@v2023.3.1 with: use-caches: false + upload-result: true diff --git a/.github/workflows/run-integration-tests-default.yml b/.github/workflows/run-integration-tests-default.yml index 33ea91d98..a5c73922c 100644 --- a/.github/workflows/run-integration-tests-default.yml +++ b/.github/workflows/run-integration-tests-default.yml @@ -5,6 +5,7 @@ on: push: branches: - main + - fix/multiaz-cluster-creation permissions: id-token: write # This is required for requesting the JWT @@ -17,7 +18,7 @@ jobs: strategy: fail-fast: false matrix: - dbEngine: [ "mysql-aurora", "mysql-multi-az", "pg-aurora", "pg-multi-az" ] + dbEngine: [ "mysql-multi-az", "pg-multi-az" ] steps: - name: 'Clone repository' uses: actions/checkout@v4 diff --git a/.github/workflows/run-integration-tests-latest.yml b/.github/workflows/run-integration-tests-latest.yml index e5438d000..5bf52f3eb 100644 --- a/.github/workflows/run-integration-tests-latest.yml +++ b/.github/workflows/run-integration-tests-latest.yml @@ -5,6 +5,7 @@ on: push: branches: - main + - fix/multiaz-cluster-creation permissions: id-token: write # This is required for requesting the JWT @@ -17,7 +18,7 @@ jobs: strategy: fail-fast: false matrix: - dbEngine: [ "mysql-aurora", "mysql-multi-az", "pg-aurora", "pg-multi-az" ] + dbEngine: [ "mysql-multi-az","pg-multi-az" ] steps: - name: 'Clone repository' uses: actions/checkout@v4 diff --git a/wrapper/src/test/java/integration/util/AuroraTestUtility.java b/wrapper/src/test/java/integration/util/AuroraTestUtility.java index b74bf124f..97e6a0474 100644 --- a/wrapper/src/test/java/integration/util/AuroraTestUtility.java +++ b/wrapper/src/test/java/integration/util/AuroraTestUtility.java @@ -96,8 +96,11 @@ import software.amazon.awssdk.services.rds.model.DescribeDbEngineVersionsRequest; import software.amazon.awssdk.services.rds.model.DescribeDbEngineVersionsResponse; import software.amazon.awssdk.services.rds.model.DescribeDbInstancesResponse; +import software.amazon.awssdk.services.rds.model.DescribeOrderableDbInstanceOptionsResponse; import software.amazon.awssdk.services.rds.model.FailoverDbClusterResponse; import software.amazon.awssdk.services.rds.model.Filter; +import software.amazon.awssdk.services.rds.model.OrderableDBInstanceOption; +import software.amazon.awssdk.services.rds.model.RdsException; import software.amazon.awssdk.services.rds.model.RebootDbClusterResponse; import software.amazon.awssdk.services.rds.model.RebootDbInstanceResponse; import software.amazon.awssdk.services.rds.model.Tag; @@ -114,8 +117,6 @@ public class AuroraTestUtility { private static final Logger LOGGER = Logger.getLogger(AuroraTestUtility.class.getName()); private static final String DUPLICATE_IP_ERROR_CODE = "InvalidPermission.Duplicate"; private static final String DEFAULT_SECURITY_GROUP = "default"; - private static final String DEFAULT_STORAGE_TYPE = "gp3"; - private static final int DEFAULT_IOPS = 64000; private static final int MULTI_AZ_SIZE = 3; private static final Random rand = new Random(); @@ -234,7 +235,7 @@ public void createCluster( } createMultiAzCluster( - username, password, dbName, identifier, region, engine, instanceClass, version); + username, password, dbName, identifier, region, engine, version); break; default: throw new UnsupportedOperationException(deployment.toString()); @@ -330,8 +331,6 @@ public void createAuroraCluster( * @param region the region that the cluster should be created in * @param engine the engine to use, refer to * CreateDbClusterRequest.engine - * @param instanceClass the instance class, refer to - * Supported instance classes * @param version the database engine's version * @throws InterruptedException when clusters have not started after 30 minutes */ @@ -341,9 +340,10 @@ public void createMultiAzCluster(String username, String identifier, String region, String engine, - String instanceClass, String version) throws InterruptedException { + + final List options = getAvailableDBInstances(engine, version); final Tag testRunnerTag = Tag.builder().key("env").value("test-runner").build(); CreateDbClusterRequest.Builder clusterBuilder = CreateDbClusterRequest.builder() @@ -360,13 +360,27 @@ public void createMultiAzCluster(String username, .storageEncrypted(true) .tags(testRunnerTag); - clusterBuilder = - clusterBuilder.allocatedStorage(400) - .dbClusterInstanceClass(instanceClass) - .storageType(DEFAULT_STORAGE_TYPE) - .iops(DEFAULT_IOPS); + boolean buildSuccess = false; + for (OrderableDBInstanceOption option : options) { + try { + clusterBuilder = + clusterBuilder.allocatedStorage(option.maxStorageSize()) + .dbClusterInstanceClass(option.dbInstanceClass()) + .storageType(option.storageType()); - rdsClient.createDBCluster(clusterBuilder.build()); + rdsClient.createDBCluster(clusterBuilder.build()); + buildSuccess = true; + break; + } catch (RdsException e) { + LOGGER.finest("Multi-AZ DB Cluster creation process failed: " + e.getMessage()); + // RDS exception will get thrown if the instance class doesn't Multi-AZ DB clusters. + } + } + + if (!buildSuccess) { + throw new InterruptedException( + "Unable to find compatible instance classes for the specified MultiAZ cluster engine that has at least 3 availabile zones."); + } // For multi-AZ deployments, the cluster instances are created automatically. Wait for all instances to be up. final RdsWaiter waiter = rdsClient.waiter(); @@ -384,6 +398,15 @@ public void createMultiAzCluster(String username, } } + private List getAvailableDBInstances(String engine, String version) { + return rdsClient + .describeOrderableDBInstanceOptions((builder) -> builder.engineVersion(version).engine(engine)) + .orderableDBInstanceOptions() + .stream() + .filter(o -> !o.supportsIops() && o.availabilityZones().size() >= 3) + .collect(Collectors.toList()); + } + /** * Creates an RDS instance under the current cluster and waits until it is up. *