
io.github.carousell.aws.WaitMojo Maven / Gradle / Ivy
package io.github.carousell.aws;
import com.amazonaws.services.devicefarm.AWSDeviceFarm;
import com.amazonaws.services.devicefarm.model.GetRunRequest;
import com.amazonaws.services.devicefarm.model.Run;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** Mojo for waiting until a set of scheduled task has been completed on AWS Device Farm. */
@Mojo(name = "wait")
public class WaitMojo extends AbstractMojo {
private static final Logger LOG = LoggerFactory.getLogger(RunMojo.class);
@Parameter(defaultValue = "${project}", readonly = true, required = true)
private MavenProject project;
@Parameter(required = true)
private String awsDeviceFarmAccessKey;
@Parameter(required = true)
private String awsDeviceFarmSecretKey;
@Parameter(defaultValue = "us-east-1")
private String awsRegion;
@Parameter(required = true)
private String[] runArns;
@Parameter(defaultValue = "10", required = false) // in seconds
private int interval;
@Parameter(defaultValue = "60", required = false) // in minutes
private int timeout;
@Parameter(defaultValue = "1", required = false)
private long threshold;
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
AWSDeviceFarm aws =
new AWSDeviceFarmService(awsDeviceFarmAccessKey, awsDeviceFarmSecretKey, awsRegion)
.getAwsDeviceFarm();
List runRequests;
long startTime = System.currentTimeMillis();
long elapsedTime;
do {
boolean completed = true;
int totalTests = 0;
int totalFailures = 0;
long maxFailures = 0;
runRequests = new ArrayList();
for (String runArn : runArns) {
GetRunRequest runRequest = new GetRunRequest().withArn(runArn);
runRequests.add(runRequest);
totalTests += aws.getRun(runRequest).getRun().getCounters().getTotal();
}
maxFailures = totalTests * (1 - threshold);
LOG.debug(
"Total tests: {}, threshold: {} => no more than {} tests may fail",
totalTests,
threshold,
(int) Math.floor(maxFailures));
for (int i = 1; i <= runRequests.size(); i++) {
Run testRun = aws.getRun(runRequests.get(i - 1)).getRun();
elapsedTime = System.currentTimeMillis() - startTime;
if (!testRun.getStatus().equals("COMPLETED") && !testRun.getStatus().equals("STOPPING")) {
LOG.info(
"Slot {} has status {} {} elapsed",
i,
String.format("%1$-20s", testRun.getStatus()),
formatMilliseconds(elapsedTime));
completed = false;
} else {
LOG.info(
"Slot {} has status {} {}/{} tests passed",
i,
String.format("%1$-20s", testRun.getStatus()),
testRun.getCounters().getPassed(),
testRun.getCounters().getTotal());
}
totalFailures +=
testRun.getCounters().getFailed()
+ testRun.getCounters().getErrored()
+ testRun.getCounters().getSkipped()
+ testRun.getCounters().getStopped();
}
if (totalFailures > maxFailures) {
LOG.error(
"At least {} tests didn't pass which is more than the threshold of {}% ({} tests). Marking the build as failed!",
totalFailures, threshold * 100, maxFailures);
System.exit(1);
}
if (completed) {
LOG.info(
"All test runs have finished. There were {} total tests and {} failures.",
totalTests,
totalFailures);
System.exit(0);
}
try {
Thread.sleep(interval * 1000);
} catch (InterruptedException exception) {
LOG.error("Error during wait", exception);
}
elapsedTime = System.currentTimeMillis() - startTime;
} while (elapsedTime < timeout * 60 * 1000);
LOG.error("The tests didn't complete within the {} minute timeout!", timeout);
System.exit(1);
}
private String formatMilliseconds(long millis) {
return String.format(
"%02d:%02d:%02d",
TimeUnit.MILLISECONDS.toHours(millis),
TimeUnit.MILLISECONDS.toMinutes(millis)
- TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)),
TimeUnit.MILLISECONDS.toSeconds(millis)
- TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy