/******************************************************************************* | |
* Copyright (c) 2019 CEA LIST. | |
* | |
* All rights reserved. This program and the accompanying materials | |
* are made available under the terms of the Eclipse Public License v1.0 | |
* which accompanies this distribution, and is available at | |
* http://www.eclipse.org/legal/epl-v10.html | |
* | |
* Contributors: | |
* Arnault Lapitre (CEA LIST) arnault.lapitre@cea.fr | |
* - Initial API and Implementation | |
*******************************************************************************/ | |
package org.eclipse.efm.execution.launchconfiguration.job.sew; | |
import java.util.regex.Matcher; | |
import java.util.regex.Pattern; | |
import org.eclipse.core.resources.IFile; | |
import org.eclipse.core.runtime.CoreException; | |
import org.eclipse.core.runtime.IPath; | |
import org.eclipse.core.runtime.Path; | |
import org.eclipse.debug.core.DebugPlugin; | |
import org.eclipse.debug.core.ILaunchConfiguration; | |
import org.eclipse.debug.core.ILaunchManager; | |
import org.eclipse.efm.execution.core.preferences.SymbexPreferenceUtil; | |
import org.eclipse.efm.execution.core.util.WorkflowFileUtils; | |
public class SymbexWorkflowProvider implements ISymbexWorkflowProvider { | |
protected int fIndex; | |
protected IPath[] fXliaModelsPath; | |
protected IPath fXliaModelPath; | |
protected IFile fWorkflowFile; | |
protected IPath fWorkflowPath; | |
protected IPath fWorkingDirectoryPath; | |
protected String[] fEnvironment; | |
protected String[] fCommandLine; | |
protected String fJobName; | |
protected String fRunDebugLaunchMode; | |
protected String fAnalysisProfileName; | |
protected boolean fConsistencyFlag; | |
protected boolean fWellFormednessFlag; | |
protected boolean fErrorFlag; | |
protected long fExecutionStepCount; | |
protected long fExecutionContextCount; | |
protected long fExecutionHeightMax; | |
protected long fExecutionWidthMax; | |
protected long fExecutionTime; | |
protected long fDeadlockCount; | |
protected long fLivelockCount; | |
protected long fRunExitCount; | |
protected long fTrivialLoopCount; | |
protected long fTrivialLoopTest; | |
protected long fRedundancyCount; | |
protected long fRedundancyTest; | |
protected String fExecutionVerdict; | |
public SymbexWorkflowProvider() { | |
this.fIndex = 0; | |
this.fXliaModelsPath = DEFAULT_XLIA_MODELS; | |
this.fXliaModelPath = null; | |
this.fWorkflowFile = null; | |
this.fWorkflowPath = null; | |
this.fWorkingDirectoryPath = WorkflowFileUtils.WORKSPACE_PATH; | |
this.fEnvironment = DEFAULT_ENVIRONMENT_VARS; | |
this.fCommandLine = null; | |
this.fJobName = DEFAULT_SYMBEX_WORKFLOW_JOB_NAME; | |
this.fRunDebugLaunchMode = ILaunchManager.RUN_MODE; | |
this.fAnalysisProfileName = DEFAULT_SYMBEX_ANALYSIS_PROFILE; | |
resetExecutionStats(); | |
} | |
public SymbexWorkflowProvider(final SymbexWorkflowProvider symbexWorkflow) { | |
assert (symbexWorkflow != null) : "Unexpected a null Symbex Workflow Provider"; | |
this.fIndex = 0; | |
this.fXliaModelsPath = symbexWorkflow.fXliaModelsPath; | |
this.fXliaModelPath = symbexWorkflow.fXliaModelPath; | |
this.fWorkflowFile = symbexWorkflow.fWorkflowFile; | |
this.fWorkflowPath = symbexWorkflow.fWorkflowPath; | |
this.fWorkingDirectoryPath = symbexWorkflow.fWorkingDirectoryPath; | |
this.fEnvironment = symbexWorkflow.fEnvironment; | |
this.fCommandLine = symbexWorkflow.fCommandLine; | |
this.fJobName = "Profile " + symbexWorkflow.fJobName; | |
this.fRunDebugLaunchMode = ILaunchManager.RUN_MODE; | |
this.fAnalysisProfileName = symbexWorkflow.fAnalysisProfileName; | |
this.fConsistencyFlag = symbexWorkflow.fConsistencyFlag; | |
this.fWellFormednessFlag = symbexWorkflow.fWellFormednessFlag; | |
this.fErrorFlag = symbexWorkflow.fErrorFlag; | |
} | |
public SymbexWorkflowProvider(final String jobName, | |
final String analysisProfileName, final IFile symbexWorkflowFile) | |
{ | |
assert (symbexWorkflowFile != null) : "Unexpected a null Workflow File"; | |
this.fIndex = 0; | |
this.fXliaModelsPath = DEFAULT_XLIA_MODELS; | |
this.fXliaModelPath = null; | |
this.fWorkflowFile = symbexWorkflowFile; | |
this.fWorkflowPath = symbexWorkflowFile.getLocation(); | |
this.fWorkingDirectoryPath = WorkflowFileUtils.WORKSPACE_PATH; | |
this.fEnvironment = DEFAULT_ENVIRONMENT_VARS; | |
this.fCommandLine = new String[] { | |
SymbexPreferenceUtil.strDiversityAvmExecLocation(), // SYMBEX_EXE | |
symbexWorkflowFile.getLocation().toOSString(), // SEW | |
SYMBEX_LAUNCH_OPTION_ENABLE_SERVER_MODE, | |
SYMBEX_LAUNCH_OPTION_ENABLE_PRINT_SPIDER_POSITIONS | |
}; | |
this.fJobName = jobName; | |
this.fRunDebugLaunchMode = ILaunchManager.RUN_MODE; | |
this.fAnalysisProfileName = analysisProfileName; | |
this.fConsistencyFlag = true; | |
this.fWellFormednessFlag = true; | |
this.fErrorFlag = false; | |
} | |
public SymbexWorkflowProvider(final String jobName, | |
final String analysisProfileName, final IPath symbexWorkflowPath) | |
{ | |
assert (symbexWorkflowPath != null) : "Unexpected a null Workflow Path"; | |
this.fIndex = 0; | |
this.fXliaModelsPath = DEFAULT_XLIA_MODELS; | |
this.fXliaModelPath = null; | |
this.fWorkflowFile = WorkflowFileUtils.findFile(symbexWorkflowPath); | |
this.fWorkflowPath = symbexWorkflowPath; | |
this.fWorkingDirectoryPath = WorkflowFileUtils.WORKSPACE_PATH; | |
this.fEnvironment = DEFAULT_ENVIRONMENT_VARS; | |
this.fCommandLine = new String[] { | |
SymbexPreferenceUtil.strDiversityAvmExecLocation(), // SYMBEX_EXE | |
symbexWorkflowPath.toOSString(), // SEW | |
SYMBEX_LAUNCH_OPTION_ENABLE_SERVER_MODE, | |
SYMBEX_LAUNCH_OPTION_ENABLE_PRINT_SPIDER_POSITIONS | |
}; | |
this.fJobName = jobName; | |
this.fRunDebugLaunchMode = ILaunchManager.RUN_MODE; | |
this.fAnalysisProfileName = analysisProfileName; | |
this.fConsistencyFlag = true; | |
this.fWellFormednessFlag = true; | |
this.fErrorFlag = false; | |
} | |
public SymbexWorkflowProvider(final ILaunchConfiguration configuration, | |
final String runDebuglaunchMode, final String analysisProfileName, | |
final String[] commandLine, final IPath workingDirectoryPath) { | |
assert (commandLine != null) : "Unexpected a null Command Line"; | |
assert (commandLine.length > 1) : "No enough a null Command Line Args"; | |
this.fIndex = 0; | |
this.fXliaModelsPath = DEFAULT_XLIA_MODELS; | |
this.fXliaModelPath = null; | |
this.fWorkflowPath = new Path(commandLine[1]); | |
this.fWorkflowFile = WorkflowFileUtils.findFile(this.fWorkflowPath); | |
this.fWorkingDirectoryPath = (workingDirectoryPath != null) ? | |
workingDirectoryPath : WorkflowFileUtils.WORKSPACE_PATH; | |
try { | |
this.fEnvironment = DebugPlugin.getDefault() | |
.getLaunchManager().getEnvironment(configuration); | |
} catch (final CoreException e) { | |
this.fEnvironment = DEFAULT_ENVIRONMENT_VARS; | |
e.printStackTrace(); | |
} | |
this.fCommandLine = commandLine; | |
this.fJobName = configuration.getName(); | |
this.fRunDebugLaunchMode = runDebuglaunchMode; | |
this.fAnalysisProfileName = analysisProfileName; | |
resetExecutionStats(); | |
this.fConsistencyFlag = true; | |
this.fWellFormednessFlag = true; | |
this.fErrorFlag = false; | |
} | |
public SymbexWorkflowProvider(final String jobName, | |
final String runDebuglaunchMode, final String[] commandLine, | |
final IPath workingDirectoryPath, final String[] environment) { | |
assert (commandLine != null) : "Unexpected a null Command Line"; | |
assert (commandLine.length > 1) : "No enough a null Command Line Args"; | |
this.fIndex = 0; | |
this.fXliaModelsPath = DEFAULT_XLIA_MODELS; | |
this.fXliaModelPath = null; | |
this.fWorkflowPath = new Path(commandLine[1]); | |
this.fWorkflowFile = WorkflowFileUtils.findFile(this.fWorkflowPath); | |
this.fWorkingDirectoryPath = (workingDirectoryPath != null) ? | |
workingDirectoryPath : WorkflowFileUtils.WORKSPACE_PATH; | |
this.fEnvironment = (environment != null) ? | |
environment : DEFAULT_ENVIRONMENT_VARS; | |
this.fCommandLine = commandLine; | |
this.fJobName = jobName; | |
this.fRunDebugLaunchMode = runDebuglaunchMode; | |
this.fAnalysisProfileName = DEFAULT_SYMBEX_ANALYSIS_PROFILE; | |
resetExecutionStats(); | |
this.fConsistencyFlag = true; | |
this.fWellFormednessFlag = true; | |
this.fErrorFlag = false; | |
} | |
public void resetExecutionStats() { | |
// this.fConsistencyFlag = false; | |
// this.fWellFormednessFlag = false; | |
this.fErrorFlag = false; | |
this.fExecutionStepCount = 0; | |
this.fExecutionContextCount = 0; | |
this.fExecutionHeightMax = 0; | |
this.fExecutionWidthMax = 0; | |
this.fExecutionTime = 0; | |
this.fDeadlockCount = 0; | |
this.fLivelockCount = 0; | |
this.fRunExitCount = 0; | |
this.fTrivialLoopCount = 0; | |
this.fTrivialLoopTest = 0; | |
this.fRedundancyCount = 0; | |
this.fRedundancyTest = 0; | |
this.fExecutionVerdict = null; | |
} | |
/* | |
* JOB / PROCESS | |
* NAME | |
*/ | |
@Override | |
public String getJobName() { | |
return (fJobName != null) ? fJobName : DEFAULT_SYMBEX_WORKFLOW_JOB_NAME; | |
} | |
@Override | |
public String getProcessName() { | |
if( fJobName != null ) { | |
return fJobName; | |
} | |
else if( fWorkflowPath != null ) { | |
return fWorkflowPath.lastSegment(); | |
} | |
return DEFAULT_SYMBEX_PROCESS_NAME; | |
} | |
/* | |
* ANALYSIS PROFILE / LAUNCH MODE | |
* NAME | |
*/ | |
@Override | |
public String getSymbexlAnalysisProfileName() { | |
return this.fAnalysisProfileName; | |
} | |
@Override | |
public String getRunDebugLaunchMode() { | |
return fRunDebugLaunchMode; | |
} | |
/* | |
* | |
*/ | |
@Override | |
public IPath getWorkingDirectoryPath() { | |
return fWorkingDirectoryPath; | |
} | |
@Override | |
public String[] getEnvironment() { | |
return fEnvironment; | |
} | |
/* | |
* ITERATOR | |
*/ | |
@Override | |
public void next() { | |
this.fIndex = this.fIndex + 1; | |
} | |
@Override | |
public boolean hasNext() { | |
return (this.fIndex < this.fXliaModelsPath.length) ; | |
} | |
/* | |
* WORKFLOW | |
*/ | |
@Override | |
public boolean isIterable() { | |
return false; | |
} | |
@Override | |
public int count() { | |
return this.fXliaModelsPath.length; | |
} | |
@Override | |
public int index() { | |
return this.fIndex; | |
} | |
@Override | |
public boolean isConsistent() { | |
return this.fConsistencyFlag; | |
} | |
/* | |
* SYMBEX WORKFLOW | |
*/ | |
@Override | |
public IPath genSymbexWorkflow() { | |
return this.fWorkflowPath; | |
} | |
@Override | |
public IPath getSymbexWorkflowPath() { | |
return this.fWorkflowPath; | |
} | |
@Override | |
public IFile getRefreshResource() { | |
return this.fWorkflowFile; | |
} | |
/* | |
* XLIA MODEL | |
*/ | |
@Override | |
public IPath getXliaModelPath() { | |
return this.fXliaModelPath; | |
} | |
/* | |
* COMMAND LINE | |
*/ | |
@Override | |
public String[] getCommandLine() { | |
return fCommandLine; | |
} | |
/* | |
* REPORTING | |
*/ | |
final static Pattern PATTERN_EXECUTION_STOP_STATS = Pattern.compile( | |
"stop:\\s*(\\d+)\\s*,\\s*context:\\s*(\\d+)\\s*," | |
+ "\\s*height:\\s*(\\d+)\\s*,\\s*width:\\s*(\\d+).*"); | |
final static Pattern PATTERN_EXECUTION_TIME = Pattern.compile( | |
"\\$time<\\s*(\\d+)\\s*ms.+"); | |
// "time:\\(real:\\s*(\\d+).+"); | |
final static Pattern PATTERN_DEADLOCK_COUNT = Pattern.compile( | |
"The DEADLOCK found : (\\d+).*"); | |
final static Pattern PATTERN_LIVELOCK_COUNT = Pattern.compile( | |
"The DEADLOCK found : (\\d+).*"); | |
final static Pattern PATTERN_RUN_EXIT_COUNT = Pattern.compile( | |
"The RUN#EXIT found : (\\d+).*"); | |
final static Pattern PATTERN_REDUNDANCY_COUNT = Pattern.compile( | |
"The redundancy count: (\\d+) for (\\d+) tests.*"); | |
final static Pattern PATTERN_TRIVIAL_LOOP_COUNT = Pattern.compile( | |
"The trivial loop count: (\\d+) for (\\d+) tests.*"); | |
@Override | |
public void analyzeReport(final String line) { | |
Matcher matcher = null; | |
if( (matcher = PATTERN_DEADLOCK_COUNT.matcher(line)).find() ) { | |
this.fDeadlockCount = Long.parseUnsignedLong( matcher.group(1) ); | |
} | |
else if( (matcher = PATTERN_LIVELOCK_COUNT.matcher(line)).find() ) { | |
this.fLivelockCount = Long.parseUnsignedLong( matcher.group(1) ); | |
} | |
else if( (matcher = PATTERN_RUN_EXIT_COUNT.matcher(line)).find() ) { | |
this.fRunExitCount = Long.parseUnsignedLong( matcher.group(1) ); | |
} | |
else if( (matcher = PATTERN_REDUNDANCY_COUNT.matcher(line)).find() ) { | |
this.fRedundancyCount = Integer.parseUnsignedInt( matcher.group(1) ); | |
this.fRedundancyTest = Integer.parseUnsignedInt( matcher.group(2) ); | |
} | |
else if( (matcher = PATTERN_TRIVIAL_LOOP_COUNT.matcher(line)).find() ) { | |
this.fTrivialLoopCount = Integer.parseUnsignedInt( matcher.group(1) ); | |
this.fTrivialLoopTest = Integer.parseUnsignedInt( matcher.group(2) ); | |
} | |
else if( (matcher = PATTERN_EXECUTION_STOP_STATS.matcher(line)).find() ) { | |
this.fExecutionStepCount = Integer.parseUnsignedInt( matcher.group(1) ); | |
this.fExecutionContextCount = Integer.parseUnsignedInt( matcher.group(2) ); | |
this.fExecutionHeightMax = Integer.parseUnsignedInt( matcher.group(3) ); | |
this.fExecutionWidthMax = Integer.parseUnsignedInt( matcher.group(4) ); | |
} | |
else if( (matcher = PATTERN_EXECUTION_TIME.matcher(line)).find() ) { | |
this.fExecutionTime = Long.parseUnsignedLong( matcher.group(1) ); | |
} | |
} | |
@Override | |
public void reportCoverage(final String coverage) { | |
System.out.println("COVRAGE: " + coverage); | |
} | |
@Override | |
public void setError() { | |
this.fErrorFlag = true; | |
} | |
/* | |
* SYMBEX VERDICT | |
*/ | |
@Override | |
public boolean hasVerdict() { | |
// final boolean livenessFlag = | |
// (this.fRedundancyCount == 1) && | |
// (this.fRedundancyTest == 1) && | |
// (this.fDeadlockCount == 0) && | |
// (this.fRunExitCount == 0); | |
// | |
// return livenessFlag; | |
return false; | |
} | |
@Override | |
public String getVerdict() { | |
final boolean livenessFlag = | |
(this.fRedundancyCount == 1) && | |
(this.fRedundancyTest == 1) && | |
(this.fDeadlockCount == 0) && | |
(this.fRunExitCount == 0); | |
return livenessFlag ? "LIVE" : "NO"; | |
} | |
@Override | |
public void setVerdict(final String verdict) { | |
this.fExecutionVerdict = verdict; | |
System.out.println("VERDICT: " + verdict); | |
} | |
/* | |
* INITIALIZE / START / FINALIZE | |
*/ | |
@Override | |
public | |
boolean initialize() { | |
fIndex = 0; | |
return( this.fCommandLine != null ); | |
} | |
@Override | |
public void finalize() { | |
} | |
/* | |
* LOGGING | |
*/ | |
@Override | |
public void beginLoggingSymbex() { | |
resetExecutionStats(); | |
} | |
@Override | |
public void log(final String message) { | |
} | |
@Override | |
public void endLoggingSymbex() { | |
} | |
} |