-
Notifications
You must be signed in to change notification settings - Fork 0
/
boogie-runner.py
executable file
·117 lines (100 loc) · 3.83 KB
/
boogie-runner.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#!/usr/bin/env python
# vim: set sw=2 ts=2 softtabstop=2 expandtab:
"""
Script to run a Boogie tool on a single boogie program
"""
import argparse
import logging
import os
from BoogieRunner import ConfigLoader
from BoogieRunner import RunnerFactory
import traceback
import yaml
import sys
_logger = None
def entryPoint(args):
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("-l","--log-level",type=str, default="info", dest="log_level", choices=['debug','info','warning','error'])
parser.add_argument("--dry", action='store_true', help="Stop after initialising runners")
parser.add_argument("config_file", help="YAML configuration file")
parser.add_argument("boogie_program", help="Boogie program to pass to tool")
parser.add_argument("working_dir", help="Working directory")
parser.add_argument("yaml_output", help="path to write YAML output to")
pargs = parser.parse_args()
logLevel = getattr(logging, pargs.log_level.upper(),None)
if logLevel == logging.DEBUG:
logFormat = '%(levelname)s:%(threadName)s: %(filename)s:%(lineno)d %(funcName)s() : %(message)s'
else:
logFormat = '%(levelname)s:%(threadName)s: %(message)s'
logging.basicConfig(level=logLevel, format=logFormat)
_logger = logging.getLogger(__name__)
# Compute absolute path to boogie program
boogieProgram = os.path.abspath(pargs.boogie_program)
if not os.path.exists(boogieProgram):
_logger.error('Specified boogie program "{}" does not exist'.format(boogieProgram))
return 1
config = None
try:
_logger.debug('Loading configuration from "{}"'.format(pargs.config_file))
config = ConfigLoader.load(pargs.config_file)
except ConfigLoader.ConfigLoaderException as e:
_logger.error(e)
_logger.debug(traceback.format_exc())
return 1
yamlOutputFile = os.path.abspath(pargs.yaml_output)
if os.path.exists(yamlOutputFile):
_logger.error('yaml_output file ("{}") already exists'.format(yamlOutputFile))
return 1
# Setup the working directory
workDir = os.path.abspath(pargs.working_dir)
if os.path.exists(workDir):
# Check it's a directory and it's empty
if not os.path.isdir(workDir):
_logger.error('"{}" exists but is not a directory'.format(workDir))
return 1
workDirRootContents = next(os.walk(workDir, topdown=True))
if len(workDirRootContents[1]) > 0 or len(workDirRootContents[2]) > 0:
_logger.error('"{}" is not empty ({},{})'.format(workDir,
workDirRootContents[1], workDirRootContents[2]))
return 1
else:
# Try to create the working directory
try:
os.mkdir(workDir)
except Exception as e:
_logger.error('Failed to create working_dirs_root "{}"'.format(workDirsRoot))
_logger.error(e)
_logger.debug(traceback.format_exc())
return 1
# Get Runner class to use
RunnerClass = RunnerFactory.getRunnerClass(config['runner'])
runner = RunnerClass(boogieProgram, workDir, config['runner_config'])
if pargs.dry:
_logger.info('Not running runner')
return 0
# Run the runner
report = [ ]
exitCode = 0
try:
runner.run()
report.append(runner.getResults())
except KeyboardInterrupt:
_logger.error('Keyboard interrupt')
except:
_logger.error("Error handling:{}".format(runner.program))
_logger.error(traceback.format_exc())
# Attempt to add the error to the report
errorLog = {}
errorLog['program'] = runner.program
errorLog['error'] = traceback.format_exc()
report.append(errorLog)
exitCode = 1
# Write result to YAML file
_logger.info('Writing output to {}'.format(yamlOutputFile))
result = yaml.dump(report, default_flow_style=False)
with open(yamlOutputFile, 'w') as f:
f.write('# BoogieRunner report using runner {}\n'.format(config['runner']))
f.write(result)
return exitCode
if __name__ == '__main__':
sys.exit(entryPoint(sys.argv[1:]))