Skip to content

Commit 5e486c0

Browse files
authored
chore: clean up test environment before each run (#1562)
1 parent 788112e commit 5e486c0

File tree

4 files changed

+196
-0
lines changed

4 files changed

+196
-0
lines changed

.github/workflows/run-integration-tests-default.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,12 @@ jobs:
6565
name: html-summary-report-default-${{ matrix.dbEngine }}
6666
path: ./wrapper/build/report
6767
retention-days: 5
68+
- name: Get Github Action IP
69+
if: always()
70+
id: ip
71+
uses: haythem/public-ip@v1.3
72+
73+
- name: Remove Github Action IP
74+
if: always()
75+
run: |
76+
aws ec2 revoke-security-group-ingress --group-name default --protocol all --port 0-65535 --cidr ${{ steps.ip.outputs.ipv4 }}/32

.github/workflows/run-integration-tests-latest.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,12 @@ jobs:
6565
name: html-summary-report-latest-${{ matrix.dbEngine }}
6666
path: ./wrapper/build/report
6767
retention-days: 5
68+
- name: Get Github Action IP
69+
if: always()
70+
id: ip
71+
uses: haythem/public-ip@v1.3
72+
73+
- name: Remove Github Action IP
74+
if: always()
75+
run: |
76+
aws ec2 revoke-security-group-ingress --group-name default --protocol all --port 0-65535 --cidr ${{ steps.ip.outputs.ipv4 }}/32

wrapper/src/test/java/integration/host/TestEnvironment.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,24 @@ public static TestEnvironment build(TestEnvironmentRequest request) throws IOExc
178178
return env;
179179
}
180180

181+
private static void cleanUp(TestEnvironment env) {
182+
DatabaseEngineDeployment deployment = env.info.getRequest().getDatabaseEngineDeployment();
183+
if (deployment == DatabaseEngineDeployment.AURORA
184+
|| deployment == DatabaseEngineDeployment.RDS
185+
|| deployment == DatabaseEngineDeployment.RDS_MULTI_AZ_INSTANCE
186+
|| deployment == DatabaseEngineDeployment.RDS_MULTI_AZ_CLUSTER) {
187+
// These environment require creating external database cluster that should be publicly available.
188+
// Corresponding AWS Security Groups should be configured and the test task runner IP address
189+
// should be whitelisted.
190+
191+
if (env.info.getRequest().getFeatures().contains(TestEnvironmentFeatures.AWS_CREDENTIALS_ENABLED)) {
192+
env.auroraUtil.testClustersCleanUp();
193+
env.auroraUtil.testInstancesCleanUp();
194+
env.auroraUtil.securityGroupRulesCleanUp();
195+
}
196+
}
197+
}
198+
181199
private static void authorizeRunnerIpAddress(TestEnvironment env) {
182200
DatabaseEngineDeployment deployment = env.info.getRequest().getDatabaseEngineDeployment();
183201
if (deployment == DatabaseEngineDeployment.AURORA
@@ -256,18 +274,21 @@ private static TestEnvironment createAuroraOrMultiAzEnvironment(TestEnvironmentR
256274
switch (request.getDatabaseEngineDeployment()) {
257275
case RDS_MULTI_AZ_INSTANCE:
258276
initEnv(env);
277+
cleanUp(env);
259278
authorizeRunnerIpAddress(env);
260279
createMultiAzInstance(env);
261280
configureIamAccess(env);
262281
break;
263282
case RDS_MULTI_AZ_CLUSTER:
264283
initEnv(env);
284+
cleanUp(env);
265285
authorizeRunnerIpAddress(env);
266286
createDbCluster(env);
267287
configureIamAccess(env);
268288
break;
269289
case AURORA:
270290
initEnv(env);
291+
cleanUp(env);
271292
authorizeRunnerIpAddress(env);
272293

273294
if (!env.reuseDb

wrapper/src/test/java/integration/util/AuroraTestUtility.java

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,11 @@
4949
import java.time.ZoneId;
5050
import java.time.ZonedDateTime;
5151
import java.time.format.DateTimeFormatter;
52+
import java.time.temporal.ChronoUnit;
5253
import java.util.ArrayList;
5354
import java.util.Arrays;
55+
import java.util.Collection;
56+
import java.util.Collections;
5457
import java.util.Comparator;
5558
import java.util.List;
5659
import java.util.Optional;
@@ -71,6 +74,7 @@
7174
import java.util.logging.Logger;
7275
import java.util.stream.Collectors;
7376
import org.checkerframework.checker.nullness.qual.Nullable;
77+
import org.junit.jupiter.api.Test;
7478
import org.testcontainers.shaded.org.apache.commons.lang3.NotImplementedException;
7579
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
7680
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
@@ -81,10 +85,16 @@
8185
import software.amazon.awssdk.core.waiters.WaiterResponse;
8286
import software.amazon.awssdk.regions.Region;
8387
import software.amazon.awssdk.services.ec2.Ec2Client;
88+
import software.amazon.awssdk.services.ec2.model.DescribeSecurityGroupRulesRequest;
89+
import software.amazon.awssdk.services.ec2.model.DescribeSecurityGroupRulesResponse;
90+
import software.amazon.awssdk.services.ec2.model.DescribeSecurityGroupsRequest;
8491
import software.amazon.awssdk.services.ec2.model.DescribeSecurityGroupsResponse;
8592
import software.amazon.awssdk.services.ec2.model.Ec2Exception;
8693
import software.amazon.awssdk.services.ec2.model.IpPermission;
8794
import software.amazon.awssdk.services.ec2.model.IpRange;
95+
import software.amazon.awssdk.services.ec2.model.RevokeSecurityGroupIngressRequest;
96+
import software.amazon.awssdk.services.ec2.model.SecurityGroup;
97+
import software.amazon.awssdk.services.ec2.model.SecurityGroupRule;
8898
import software.amazon.awssdk.services.rds.RdsClient;
8999
import software.amazon.awssdk.services.rds.RdsClientBuilder;
90100
import software.amazon.awssdk.services.rds.model.ApplyMethod;
@@ -2172,4 +2182,151 @@ private Tag getTag() {
21722182
.key("created").value(timeStr)
21732183
.build();
21742184
}
2185+
2186+
public void testClustersCleanUp() {
2187+
try {
2188+
DescribeDbClustersResponse describeDbClustersResponse = rdsClient.describeDBClusters();
2189+
for (DBCluster dbCluster : describeDbClustersResponse.dbClusters()) {
2190+
//LOGGER.finest(String.format("Test cluster: %s, status: %s, create time: %s, now: %s",
2191+
// dbCluster.dbClusterIdentifier(), dbCluster.status(), dbCluster.clusterCreateTime(), Instant.now()));
2192+
if (!dbCluster.dbClusterIdentifier().startsWith("test-")) {
2193+
continue;
2194+
}
2195+
if (!"available".equalsIgnoreCase(dbCluster.status())
2196+
&& !"rebooting".equalsIgnoreCase(dbCluster.status())) {
2197+
continue;
2198+
}
2199+
if (dbCluster.clusterCreateTime().plus(12, ChronoUnit.HOURS).isAfter(Instant.now())) {
2200+
// cluster is created less than 12 hours ago
2201+
continue;
2202+
}
2203+
2204+
if (dbCluster.engine().startsWith("aurora-")) {
2205+
if (dbCluster.dbClusterMembers().isEmpty()) {
2206+
// empty cluster
2207+
LOGGER.finest("Deleting cluster " + dbCluster.dbClusterIdentifier());
2208+
try {
2209+
rdsClient.deleteDBCluster(builder -> builder
2210+
.dbClusterIdentifier(dbCluster.dbClusterIdentifier())
2211+
.skipFinalSnapshot(true)
2212+
.build());
2213+
} catch (Exception ex) {
2214+
LOGGER.warning(ex.getMessage());
2215+
}
2216+
} else {
2217+
for (DBClusterMember dbClusterMember : dbCluster.dbClusterMembers()) {
2218+
if (!dbClusterMember.dbInstanceIdentifier().startsWith("test-")) {
2219+
continue;
2220+
}
2221+
LOGGER.finest("Deleting instance " + dbClusterMember.dbInstanceIdentifier());
2222+
try {
2223+
rdsClient.deleteDBInstance(builder -> builder
2224+
.dbInstanceIdentifier(dbClusterMember.dbInstanceIdentifier())
2225+
.skipFinalSnapshot(true)
2226+
.build());
2227+
} catch (Exception ex) {
2228+
LOGGER.warning(ex.getMessage());
2229+
}
2230+
}
2231+
}
2232+
} else {
2233+
LOGGER.finest("Deleting cluster " + dbCluster.dbClusterIdentifier());
2234+
try {
2235+
rdsClient.deleteDBCluster(builder -> builder
2236+
.dbClusterIdentifier(dbCluster.dbClusterIdentifier())
2237+
.skipFinalSnapshot(true)
2238+
.build());
2239+
} catch (Exception ex) {
2240+
LOGGER.warning(ex.getMessage());
2241+
}
2242+
}
2243+
}
2244+
} catch (Exception ex) {
2245+
LOGGER.warning(ex.getMessage());
2246+
}
2247+
}
2248+
2249+
public void testInstancesCleanUp() {
2250+
try {
2251+
DescribeDbInstancesResponse describeDbInstancesResponse = rdsClient.describeDBInstances();
2252+
for (DBInstance dbInstance : describeDbInstancesResponse.dbInstances()) {
2253+
//LOGGER.fine("Test instance: " + dbInstance.dbInstanceIdentifier());
2254+
if (!dbInstance.dbInstanceIdentifier().startsWith("test-")) {
2255+
continue;
2256+
}
2257+
if (!"available".equalsIgnoreCase(dbInstance.dbInstanceStatus())) {
2258+
continue;
2259+
}
2260+
if (dbInstance.instanceCreateTime() != null
2261+
&& dbInstance.instanceCreateTime().plus(12, ChronoUnit.HOURS).isAfter(Instant.now())) {
2262+
// cluster is created less than 12 hours ago
2263+
continue;
2264+
}
2265+
LOGGER.finest("Deleting instance " + dbInstance.dbInstanceIdentifier());
2266+
try {
2267+
rdsClient.deleteDBInstance(builder -> builder
2268+
.dbInstanceIdentifier(dbInstance.dbInstanceIdentifier())
2269+
.skipFinalSnapshot(true)
2270+
.build());
2271+
} catch (Exception ex) {
2272+
LOGGER.warning(ex.getMessage());
2273+
}
2274+
}
2275+
} catch (Exception ex) {
2276+
LOGGER.warning(ex.getMessage());
2277+
}
2278+
}
2279+
2280+
public void securityGroupRulesCleanUp() {
2281+
try {
2282+
DescribeSecurityGroupsResponse groupResponse = ec2Client.describeSecurityGroups(
2283+
DescribeSecurityGroupsRequest.builder().groupNames("default").build());
2284+
2285+
if (groupResponse.securityGroups().isEmpty()) {
2286+
return;
2287+
}
2288+
2289+
SecurityGroup defaultSecurityGroup = groupResponse.securityGroups().get(0);
2290+
2291+
final software.amazon.awssdk.services.ec2.model.Filter groupIdFilter =
2292+
software.amazon.awssdk.services.ec2.model.Filter.builder()
2293+
.name("group-id")
2294+
.values(defaultSecurityGroup.groupId())
2295+
.build();
2296+
DescribeSecurityGroupRulesResponse rulesResponse = ec2Client.describeSecurityGroupRules(
2297+
DescribeSecurityGroupRulesRequest.builder().filters(groupIdFilter).build());
2298+
2299+
if (rulesResponse.securityGroupRules().isEmpty()) {
2300+
return;
2301+
}
2302+
2303+
for (SecurityGroupRule rule : rulesResponse.securityGroupRules()) {
2304+
if (!rule.isEgress() && rule.description() != null && rule.description().startsWith("Test run at ")) {
2305+
try {
2306+
String instantStr = rule.description().replaceAll("Test run at ", "");
2307+
Instant createdAt = Instant.parse(instantStr);
2308+
if (createdAt.plus(12, ChronoUnit.HOURS).isAfter(Instant.now())) {
2309+
continue;
2310+
}
2311+
2312+
LOGGER.finest("Deleting security group rule: " + rule.securityGroupRuleId());
2313+
try {
2314+
ec2Client.revokeSecurityGroupIngress(
2315+
RevokeSecurityGroupIngressRequest.builder()
2316+
.groupId(rule.groupId())
2317+
.securityGroupRuleIds(rule.securityGroupRuleId())
2318+
.build());
2319+
} catch (Exception ex) {
2320+
LOGGER.warning("Error deleting security group rule: " + ex.getMessage());
2321+
}
2322+
2323+
} catch (Exception ex) {
2324+
LOGGER.warning(ex.getMessage());
2325+
}
2326+
}
2327+
}
2328+
} catch (Exception ex) {
2329+
LOGGER.warning(ex.getMessage());
2330+
}
2331+
}
21752332
}

0 commit comments

Comments
 (0)