/**
* Copyright (c) 2009-2011, The HATS Consortium. All rights reserved.
* This file is licensed under the terms of the Modified BSD License.
*/
package eu.hats_project.build.maven.plugin;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.codehaus.plexus.util.FileUtils;
import abs.backend.tests.ABSTestRunnerGenerator;
/**
* A Maven 2 plugin to simulate ABS test code in Maude
*
* @goal maudetest
* @requiresDependencyResolution
* @phase test
*/
public class MaudeTestMojo extends AbstractTestMojo {
/**
* @parameter expression="${abs.maude.interpreter}"
* @required
*/
private File maudeInterpreter;
/**
* The ABS Maude Backend output file.
*
* @parameter expression="${abs.maudetest.testOutput}"
* default-value="${project.build.directory}/abs/gen/maude/test.maude"
*/
private File absMaudeBackendTestOutputFile;
/**
* The maude executable
*
* @parameter expression="${maude.executable}" default-value="maude"
*/
private String maude;
/**
* Delta names to applied during testing
*
* @parameter
*
*/
private String[] deltaNames;
/**
* @parameter expression="${abs.maudetest.timed}"
* default-value=false
*/
private boolean timed;
private static final Pattern termination = Pattern.compile("^.*\\[State\\]:.*$", Pattern.MULTILINE);
@Override
protected void makeTest() throws Exception {
if (productName != null && deltaNames != null && deltaNames.length > 0) {
throw new MojoExecutionException("Cannot perform product selection"
+ "and apply deltas on rewrite at the same time");
}
// generate test.maude
MaudeGenerator generator = new MaudeGenerator();
List<String> args = new ArrayList<String>();
if (absTestRunnerFile.exists()) {
args.add(absTestRunnerFile.getAbsolutePath());
}
args.addAll(getABSArguments());
args = generator.generateMaude(
absfrontEnd,
absTestSrcFolder,
args,
absMaudeBackendTestOutputFile,
checkProductSelection,
verbose,
stdlib,
loctype,
productName,
(mainBlock == null) ? ABSTestRunnerGenerator.RUNNER_MAIN : mainBlock,
timed,
getLog());
// run maude
final String maudeOutput = runMaude();
if (!maudeTerminatesSuccessfully(maudeOutput)) {
getLog().error("Maude Test fails.");
getLog().error(maudeOutput);
throw new MojoFailureException("One or more maude tests have failed, see log information for details.");
}
// only in debug
getLog().debug(maudeOutput);
}
/**
* XXX Copied from {@link abs.backend.maude.MaudeTests}
*
* @throws Exception
*/
private String runMaude() throws Exception {
String generatedMaudeCode = FileUtils.fileRead(absMaudeBackendTestOutputFile);
return getMaudeOutput(generatedMaudeCode);
}
/**
* XXX Copied from {@link abs.backend.maude.MaudeTests}
*
* @throws Exception
*/
protected String getMaudeOutput(String maudeCode) throws IOException, InterruptedException {
StringBuffer result = new StringBuffer();
ProcessBuilder pb = new ProcessBuilder();
String[] cmd = { maude, "-no-banner", "-no-ansi-color", "-no-wrap", "-batch",
maudeInterpreter.getAbsolutePath() };
new DebugArgOutput().debug("Executing Maude Code", cmd, getLog());
pb.command(cmd);
// pb.redirectErrorStream(true);
Process p = pb.start();
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
PrintWriter out = new PrintWriter(p.getOutputStream());
while (in.ready()) {
result.append(in.readLine());
}
out.println(maudeCode);
out.flush();
while (in.ready()) {
result.append(in.readLine());
}
if (deltaNames == null || deltaNames.length == 0) {
out.println("rew start .");
} else {
// apply deltas
String names = "";
for (String name : deltaNames) {
names = names + "\"" + name + "\" ";
}
out.println("rew start (" + names + ") .");
}
out.flush();
while (in.ready()) {
result.append(in.readLine() + "\n");
}
out.println("quit");
out.flush();
p.waitFor();
while (in.ready()) {
result.append(in.readLine() + "\n");
}
return result.toString();
}
/**
* Check that the input string representing the Maude output does not match
* against '[State]' as this indicates the simulation did not terminate
* successfully.
*
* @param maudeOutput
* @return
*/
boolean maudeTerminatesSuccessfully(String maudeOutput) {
return !termination.matcher(maudeOutput).find();
}
}