Skip to content

Commit

Permalink
First step to manage timeout in Maven goals based on the output #351
Browse files Browse the repository at this point in the history
  • Loading branch information
surli committed Mar 21, 2018
1 parent e127325 commit a385f45
Show file tree
Hide file tree
Showing 15 changed files with 192 additions and 59 deletions.
2 changes: 1 addition & 1 deletion repairnator/repairnator-pipeline/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
<dependency>
<groupId>org.apache.maven.shared</groupId>
<artifactId>maven-invoker</artifactId>
<version>2.2</version>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@
import org.slf4j.LoggerFactory;

import java.io.File;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Properties;

Expand All @@ -45,6 +48,7 @@ public class MavenHelper {
"skip.gulp",
"skip.bower"
);
private static final int TIMEOUT_WITHOUT_OUTPUT = 10; // in minutes

private final Logger logger = LoggerFactory.getLogger(MavenHelper.class);

Expand All @@ -53,6 +57,7 @@ public class MavenHelper {
private Properties properties;
private String name;
private ProjectInspector inspector;
private Instant limitOutputDate;

private InvocationOutputHandler errorHandler;
private InvocationOutputHandler outputHandler;
Expand All @@ -65,11 +70,56 @@ public MavenHelper(String pomFile, String goal, Properties properties, String na
this.inspector = inspector;

if (enableHandlers) {
this.errorHandler = new MavenErrorHandler(this.inspector, this.name);
this.outputHandler = new MavenFilterOutputHandler(this.inspector, this.name);
this.errorHandler = new MavenErrorHandler(this);
this.outputHandler = new MavenFilterOutputHandler(this);
} else {
this.outputHandler = new MavenMuteOutputHandler(this.inspector, this.name);
this.outputHandler = new MavenMuteOutputHandler(this);
}

this.updateProperties();
}

private void updateProperties() {
if (this.properties == null) {
this.properties = new Properties();
}

this.properties.setProperty("maven.repo.local", this.inspector.getM2LocalPath());
for (String skip : SKIP_LIST) {
this.properties.setProperty(skip, "true");
}
}

public String getGoal() {
return goal;
}

public String getPomFile() {
return pomFile;
}

public Properties getProperties() {
return properties;
}

public String getName() {
return name;
}

public ProjectInspector getInspector() {
return inspector;
}

public InvocationOutputHandler getErrorHandler() {
return errorHandler;
}

public InvocationOutputHandler getOutputHandler() {
return outputHandler;
}

public void updateLastOutputDate() {
this.limitOutputDate = new Date().toInstant().plus(TIMEOUT_WITHOUT_OUTPUT, ChronoUnit.MINUTES);
}

public void setErrorHandler(InvocationOutputHandler errorHandler) {
Expand All @@ -90,37 +140,23 @@ public static Model readPomXml(File pomXml, String localMavenRepository) throws
return new DefaultModelBuilderFactory().newInstance().build(req).getEffectiveModel();
}

public int run() {
InvocationRequest request = new DefaultInvocationRequest();
request.setPomFile(new File(this.pomFile));
request.setGoals(Arrays.asList(this.goal));

if (properties == null) {
properties = new Properties();
}

properties.setProperty("maven.repo.local", this.inspector.getM2LocalPath());
for (String skip : SKIP_LIST) {
properties.setProperty(skip, "true");
public int run() throws InterruptedException {
RunnableMavenInvoker runnableMavenInvoker = new RunnableMavenInvoker(this);
Thread t = new Thread(runnableMavenInvoker);
this.updateLastOutputDate();
t.start();

while (t.isAlive()) {
Instant now = new Date().toInstant();

if (now.isAfter(this.limitOutputDate)) {
t.interrupt();
throw new InterruptedException("Timeout occured because no output in the last "+TIMEOUT_WITHOUT_OUTPUT+" minutes.");
} else {
Thread.sleep(1000);
}
}
request.setProperties(properties);

Invoker invoker = new DefaultInvoker();

if (this.errorHandler != null) {
invoker.setErrorHandler(this.errorHandler);
}
invoker.setOutputHandler(this.outputHandler);

try {
InvocationResult result = invoker.execute(request);
return result.getExitCode();
} catch (MavenInvocationException e) {
this.logger.error("Error while executing goal :" + this.goal + " on the following pom file: " + this.pomFile
+ ". Properties: " + this.properties);
this.logger.debug(e.getMessage());
this.inspector.getJobStatus().addStepError(name, e.getMessage());
return MAVEN_ERROR;
}
return runnableMavenInvoker.getExitCode();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package fr.inria.spirals.repairnator.process.maven;

import org.apache.maven.shared.invoker.DefaultInvocationRequest;
import org.apache.maven.shared.invoker.DefaultInvoker;
import org.apache.maven.shared.invoker.InvocationRequest;
import org.apache.maven.shared.invoker.InvocationResult;
import org.apache.maven.shared.invoker.Invoker;
import org.apache.maven.shared.invoker.MavenInvocationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.util.Arrays;

public class RunnableMavenInvoker implements Runnable {
private final Logger logger = LoggerFactory.getLogger(RunnableMavenInvoker.class);

private MavenHelper mavenHelper;
private int exitCode;

public RunnableMavenInvoker(MavenHelper mavenHelper) {
this.mavenHelper = mavenHelper;
this.exitCode = -1;
}

@Override
public void run() {
InvocationRequest request = new DefaultInvocationRequest();
request.setPomFile(new File(this.mavenHelper.getPomFile()));
request.setGoals(Arrays.asList(this.mavenHelper.getGoal()));

request.setProperties(this.mavenHelper.getProperties());

Invoker invoker = new DefaultInvoker();

if (this.mavenHelper.getErrorHandler() != null) {
invoker.setErrorHandler(this.mavenHelper.getErrorHandler());
}
invoker.setOutputHandler(this.mavenHelper.getOutputHandler());

try {
InvocationResult result = invoker.execute(request);
this.exitCode = result.getExitCode();
} catch (MavenInvocationException e) {
this.logger.error("Error while executing goal :" + this.mavenHelper.getGoal() + " on the following pom file: " + this.mavenHelper.getPomFile()
+ ". Properties: " + this.mavenHelper.getProperties());
this.logger.debug(e.getMessage());
this.mavenHelper.getInspector().getJobStatus().addStepError(this.mavenHelper.getName(), e.getMessage());
this.exitCode = MavenHelper.MAVEN_ERROR;
}
}

public int getExitCode() {
return exitCode;
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package fr.inria.spirals.repairnator.process.maven.output;

import fr.inria.spirals.repairnator.process.inspectors.ProjectInspector;
import fr.inria.spirals.repairnator.process.maven.MavenHelper;

/**
* Created by urli on 09/01/2017.
*/
public class MavenErrorHandler extends MavenOutputHandler {

public MavenErrorHandler(ProjectInspector inspector, String name) {
super(inspector, name);

public MavenErrorHandler(MavenHelper mavenHelper) {
super(mavenHelper);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package fr.inria.spirals.repairnator.process.maven.output;

import fr.inria.spirals.repairnator.process.inspectors.ProjectInspector;
import fr.inria.spirals.repairnator.process.maven.MavenHelper;

/**
* Created by urli on 09/01/2017.
*/
public class MavenFilterOutputHandler extends MavenOutputHandler {

public MavenFilterOutputHandler(ProjectInspector inspector, String name) {
super(inspector, name);

public MavenFilterOutputHandler(MavenHelper mavenHelper) {
super(mavenHelper);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package fr.inria.spirals.repairnator.process.maven.output;

import fr.inria.spirals.repairnator.process.inspectors.ProjectInspector;
import fr.inria.spirals.repairnator.process.maven.MavenHelper;

import java.util.ArrayList;
import java.util.List;
Expand All @@ -22,8 +23,8 @@ public class MavenFilterTestOutputHandler extends MavenFilterOutputHandler {
private List<String> failingClasses;
private boolean failingWithTest;

public MavenFilterTestOutputHandler(ProjectInspector inspector, String name) {
super(inspector, name);
public MavenFilterTestOutputHandler(MavenHelper mavenHelper) {
super(mavenHelper);
this.mvnTestPattern = Pattern.compile(MVN_TEST_PATTERN);
this.mvnGoalFailPattern = Pattern.compile(MVN_GOAL_FAILED_WITH_TEST_FAILURE);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package fr.inria.spirals.repairnator.process.maven.output;

import fr.inria.spirals.repairnator.process.inspectors.ProjectInspector;
import fr.inria.spirals.repairnator.process.maven.MavenHelper;

/**
* Created by urli on 09/01/2017.
*/
public class MavenMuteOutputHandler extends MavenOutputHandler {
public MavenMuteOutputHandler(ProjectInspector inspector, String name) {
super(inspector, name);

public MavenMuteOutputHandler(MavenHelper mavenHelper) {
super(mavenHelper);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,31 @@
package fr.inria.spirals.repairnator.process.maven.output;

import fr.inria.spirals.repairnator.process.inspectors.ProjectInspector;
import fr.inria.spirals.repairnator.process.maven.MavenHelper;
import org.apache.maven.shared.invoker.InvocationOutputHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.FileWriter;
import java.io.IOException;
import java.time.Instant;

/**
* Created by urli on 15/02/2017.
*/
public abstract class MavenOutputHandler implements InvocationOutputHandler {

private final Logger logger = LoggerFactory.getLogger(this.getClass());

private MavenHelper mavenHelper;
protected ProjectInspector inspector;
protected String name;
private FileWriter fileWriter;

public MavenOutputHandler(ProjectInspector inspector, String name) {
this.inspector = inspector;
this.name = name;
public MavenOutputHandler(MavenHelper mavenHelper) {
this.mavenHelper = mavenHelper;
this.inspector = mavenHelper.getInspector();
this.name = mavenHelper.getName();
this.initFileWriter();
}

Expand Down Expand Up @@ -48,12 +53,12 @@ private void writeToFile(String s) {
} catch (IOException e) {
this.getLogger().error("Error while writing to maven log", e);
}

}
}

@Override
public void consumeLine(String s) {
this.mavenHelper.updateLastOutputDate();
this.writeToFile(s + "\n");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ public void addStepError(String error) {

public void addStepError(String error, Throwable exception) {
getLogger().error(error, exception);
this.inspector.getJobStatus().addStepError(this.name, error + "Original msg: " + exception.getMessage());
this.inspector.getJobStatus().addStepError(this.name, error + " Original msg: " + exception.getMessage());
}

protected void executeNextStep() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,13 @@ protected void businessExecute() {
this.getLogger().debug("Installing artifacts without test execution...");
MavenHelper helper = new MavenHelper(this.getPom(), "install", properties, this.getClass().getSimpleName(), this.inspector, true);

int result = helper.run();
int result;
try {
result = helper.run();
} catch (InterruptedException e) {
this.addStepError("Error while building", e);
result = MavenHelper.MAVEN_ERROR;
}

if (result == MavenHelper.MAVEN_SUCCESS) {
this.setPipelineState(PipelineState.BUILDABLE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,12 @@ protected void businessExecute() {
MavenHelper helper = new MavenHelper(pomModule, goal, properties, this.getClass().getSimpleName(),
this.inspector, true);

int result = helper.run();
int result = MavenHelper.MAVEN_ERROR;
try {
result = helper.run();
} catch (InterruptedException e) {
this.addStepError("Error with maven goal", e);
}

if (result != MavenHelper.MAVEN_SUCCESS) {
this.getLogger().debug("Error while computing classpath maven");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,12 @@ protected void businessExecute() {
this.getLogger().info("NPE found, start NPEFix");

MavenHelper mavenHelper = new MavenHelper(this.getPom(), NPEFIX_GOAL, null, this.getName(), this.getInspector(), true );
int status = mavenHelper.run();
int status = MavenHelper.MAVEN_ERROR;
try {
status = mavenHelper.run();
} catch (InterruptedException e) {
this.addStepError("Error while executing Maven goal", e);
}

if (status == MavenHelper.MAVEN_ERROR) {
this.addStepError("Error while running NPE fix: maybe the project does not contain a NPE?");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@ protected void businessExecute() {
this.getLogger().debug("Installing artifacts without test execution...");
MavenHelper helper = new MavenHelper(this.getPom(), "dependency:resolve", null, this.getClass().getSimpleName(), this.inspector, true);

int result = helper.run();
int result = MavenHelper.MAVEN_ERROR;
try {
result = helper.run();
} catch (InterruptedException e) {
this.addStepError("Error while executing Maven goal", e);
}

if (result == MavenHelper.MAVEN_SUCCESS) {
this.setPipelineState(PipelineState.DEPENDENCY_RESOLVED);
Expand Down

0 comments on commit a385f45

Please sign in to comment.