All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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