use of edu.uiowa.clc.verdict.merit.MeritAssignment in project VERDICT by ge-high-assurance.
the class App method runCrv.
/**
* Run CRV.
*
* @param vdmPath VDM input file
* @param modelName Name of model
* @param instrPath temporary instrumented model file
* @param lustrePath temporary Lustre file
* @param threats list of threats to instrument (LB, NI, etc.)
* @throws VerdictRunException
*/
public static void runCrv(String vdmPath, String modelName, String instrPath, String lustrePath, List<String> threats, boolean blameAssignment, boolean componentLevel, boolean globalOptimization, boolean atg, boolean meritAssignment, boolean oneIVC, boolean allMIVC, boolean oneMIVC, String outputPath, String outputBaPath, String debugDir, String kind2Bin) throws VerdictRunException {
checkFile(vdmPath, true, false, false, false, ".xml");
checkFile(lustrePath, false, false, true, false, ".lus");
checkFile(outputPath, false, false, true, false, null);
String outputFormat;
if (outputPath.endsWith(".xml")) {
outputFormat = "-xml";
} else if (outputPath.endsWith(".json")) {
outputFormat = "-json";
} else {
throw new VerdictRunException("Output file must be .xml or .json");
}
if (debugDir != null) {
logHeader("DEBUGGING XML OUTPUT");
}
deleteFile(instrPath);
deleteFile(lustrePath);
deleteFile(outputPath);
if (outputBaPath != null) {
deleteFile(outputBaPath);
}
File vdmFile = new File(vdmPath);
Model vdmModel = VdmTranslator.unmarshalFromXml(vdmFile);
logHeader("VDM Instrumentor");
Instrumentor instrumentor = null;
if (!threats.isEmpty()) {
log("Instrumenting model");
// Instrument loaded model
Timer.Sample sample = Timer.start(Metrics.globalRegistry);
instrumentor = new Instrumentor(vdmModel);
instrumentor.instrument(vdmModel, threats, blameAssignment, componentLevel);
sample.stop(Metrics.timer("Timer.crv.instrumentor", "model", modelName));
} else {
log("No threats selected, no instrumentation necessary");
}
debugOutVdm(debugDir, "VERDICT_output_debug_instr.xml", vdmModel);
{
// For some reason we need to do this...?
VdmTranslator.marshalToXml(vdmModel, new File(instrPath));
vdmModel = VdmTranslator.unmarshalFromXml(new File(instrPath));
}
debugOutVdm(debugDir, "VERDICT_output_debug_instr_reloaded.xml", vdmModel);
logHeader("VDM2LUS");
log("Converting instrumented Verdict data model to Lustre");
// Build Lustre model
Timer.Sample vdm2lusSample = Timer.start(Metrics.globalRegistry);
VDM2Lustre vdm2lus = new VDM2Lustre(vdmModel);
Model lustreModel = vdm2lus.translate();
vdm2lusSample.stop(Metrics.timer("Timer.crv.vdm2lus", "model", modelName));
debugOutVdm(debugDir, "VERDICT_output_debug_lus", lustreModel);
if (atg) {
logHeader("Verdict ATG");
log("Verdict Automatic Test-case Generation");
log("Generating opposite guarantees");
// Why do we do this to vdmModel and not lustreModel?
// Good question. I don't know, but it works.
Timer.Sample sample = Timer.start(Metrics.globalRegistry);
VerdictTestInstrumentor atgInstrumentor = new VerdictTestInstrumentor(vdmModel);
atgInstrumentor.instrumentTests();
sample.stop(Metrics.timer("Timer.crv.atgInstrumentor", "model", modelName));
debugOutVdm(debugDir, "VERDICT_output_debug_lus_atg", lustreModel);
}
logHeader("Output Lustre");
log("Output Lustre file: " + lustrePath);
// Output Lustre model
Timer.Sample verdictlustreSample = Timer.start(Metrics.globalRegistry);
VerdictLustreTranslator.marshalToLustre(lustreModel, new File(lustrePath));
verdictlustreSample.stop(Metrics.timer("Timer.crv.verdictlustre", "model", modelName));
logHeader("Kind2");
log("Running Kind2 model checker");
log("Output XML file: " + outputPath);
log("Kind2 is running. Please be patient...");
if (atg) {
log("Test cases are embedded in XML");
if (!threats.isEmpty()) {
log("Counter-examples/test cases may be induced by the presence of threats");
}
}
boolean mustSet = meritAssignment && (oneMIVC || allMIVC);
Timer.Sample kind2Sample = Timer.start(Metrics.globalRegistry);
try {
ExecuteStreamHandler redirect = new PumpStreamHandler(new FileOutputStream(new File(outputPath)), System.err);
if (blameAssignment && instrumentor != null && instrumentor.emptyIntrumentation() == false) {
Binary.invokeBin(kind2Bin, null, redirect, outputFormat, lustrePath, "--check_subproperties", "false", "--enable", "MCS", "--print_mcs_legacy", "true", "--mcs_approximate", Boolean.toString(!globalOptimization));
} else {
Binary.invokeBin(kind2Bin, null, redirect, outputFormat, lustrePath, "--check_subproperties", "false", "--ivc", Boolean.toString(meritAssignment), "--ivc_approximate", Boolean.toString(oneIVC), "--ivc_all", Boolean.toString(allMIVC), "--ivc_category", "contracts", "--ivc_must_set", Boolean.toString(mustSet));
}
} catch (Binary.ExecutionException e) {
// Kind2 does some weird things with exit codes
if (e.getCode().isPresent()) {
switch(e.getCode().get()) {
case 20:
// Success
log("All properties are valid");
break;
case 10:
if (atg) {
// Some properties invalid, but those might just be the ATG negative
// properties
log("Kind2 finished");
} else {
// Some properties invalid
log("Some properties are invalid");
}
break;
case 2:
log("Kind2 terminated with an error");
XMLProcessor.parseLog(new File(outputPath));
// Terminate the process?
break;
case 0:
log("Kind2 timed out");
break;
default:
throw new VerdictRunException("Failed to execute kind2", e);
}
} else {
throw new VerdictRunException("Failed to execute kind2", e);
}
} catch (IOException e) {
throw new VerdictRunException("Failed to execute kind2", e);
} finally {
kind2Sample.stop(Metrics.timer("Timer.crv.kind2", "model", modelName));
}
if (meritAssignment) {
logHeader("Merit Assignment");
MeritAssignment ma = new MeritAssignment(new File(outputPath));
ma.readAndPrintInfo();
}
if (blameAssignment && instrumentor != null) {
logHeader("Blame Assignment");
// TODO Perform blame assignment post-analysis
// I already passed the correct parameter to Kind2 above
// Kind2 XML/JSON is in outputPath (it's probably OK to ignore JSON for now)
// BA output XML should go to outputBaPath
// VDM instrumentor instance is vdmInstrumentor
// If it is null then there were no threat models selected for instrumentations
log("Blame assignment output: " + outputBaPath);
try {
Timer.Sample sample = Timer.start(Metrics.globalRegistry);
BlameAssignment ba = new BlameAssignment();
ba = ba.compute_blame_assignment(new File(outputPath), instrumentor.getAttackMap(), componentLevel);
XMLProcessor.dumpXML(ba, new File(outputBaPath));
sample.stop(Metrics.timer("Timer.crv.blameassignment", "model", modelName));
} catch (FileNotFoundException e) {
throw new VerdictRunException("Failed to perform blame assignment", e);
}
}
logHeader("Finished");
}
Aggregations