9 sys
.path
.insert(0, '@FOAM_PYTHON_DIR@')
10 from FreeFOAM
.compat
import *
11 import FreeFOAM
.tutorial
14 class LogParserError(Exception):
15 """Thrown when parsing of the log file failed."""
16 def __init__(self
, msg
):
17 Exception.__init
__(self
, msg
)
22 class AllTutorialsRunner(FreeFOAM
.tutorial
.TutorialRunner
):
24 FreeFOAM
.tutorial
.TutorialRunner
.__init
__(self
)
25 self
.tutorials_dir
= os
.path
.abspath(os
.path
.dirname(sys
.argv
[0]))
28 # prevent python from creating byte-compiled files (python >= 2.6)
30 sys
.dont_write_bytecode
= True
33 # Recursively run all tutorials
36 for parent
, dirs
, files
in os
.walk(self
.tutorials_dir
):
37 if parent
== self
.tutorials_dir
:
44 f
= open('Allrun', 'rt')
46 m
= imp
.load_module('Allrun'+str(i
), f
, f
.name
,
47 (os
.path
.splitext(f
.name
)[1], 'r', imp
.PY_SOURCE
))
48 if hasattr(m
, 'register_cases') and inspect
.isfunction(
50 m
.register_cases(self
)
54 if inspect
.isclass(a
) and (
55 FreeFOAM
.tutorial
.CaseRunner
in inspect
.getmro(a
)):
59 '${RED}*** Error ***${NORMAL} In '+os
.path
.abspath(f
.name
))
63 FreeFOAM
.tutorial
.TutorialRunner
.main(self
)
65 # Analyse all log files
67 os
.path
.join(self
.tutorials_dir
, 'testLoopReport'), 'wt')
68 logs
= open(os
.path
.join(self
.tutorials_dir
, 'logs'), 'wt')
69 for parent
, dirs
, files
in os
.walk(self
.tutorials_dir
):
72 # skip test directories if not in test_mode and vice versa
73 if bool(parent
[-5:] == '-test') ^
bool(self
.test_mode
):
75 l
= os
.path
.join(parent
, f
)
76 logs
.writelines(open(l
, 'rt').readlines())
78 self
._logReport
(l
, testReport
)
85 def _logReport(self
, logName
, reportFile
):
86 """Extracts useful info from log file `logName` and writes it to file
87 object `reportFile`."""
95 for l
in open(logName
, 'rt'):
97 r
'(?:APPLICATION:\s+(?P<app>\S+)|CASE:\s+(?P<case>\S+))', l
)
104 if re
.search('FOAM FATAL', l
):
106 elif re
.search(r
'U[xyz](:|\s)*solution singularity', l
):
108 elif re
.match(r
'^\s*[Ee]nd\s*\.?\s*$', l
):
110 elif re
.match(r
'^REPORT:\s+SUCCESS', l
):
113 m
= re
.search(r
'Execution\S+\s+=\s+(?P<time>\S+\s+\S+)', l
)
115 time
= m
.group('time')
117 if bool(case
) != bool(app
):
118 raise LogParserError('Failed to parse "%s"'%logName
)
119 elif not case
and not app
:
123 self
.tutorials_dir
= os
.path
.abspath(os
.path
.dirname(__file__
))
124 appAndCase
= "Application %s - case %s"%(app
,
125 os
.path
.relpath(case
, self
.tutorials_dir
))
128 reportFile
.write('%s: ** FOAM FATAL ERROR **\n'%appAndCase
)
130 reportFile
.write('%s: ** Solution singularity **\n'%appAndCase
)
131 elif completed
and success
:
132 reportFile
.write('%s: completed'%appAndCase
)
134 reportFile
.write(' in %s\n'%time
)
136 reportFile
.write('\n')
138 reportFile
.write('%s: unconfirmed completion\n'%appAndCase
)
140 def _testReport(self
):
145 'interpolationScheme',
152 for parent
, dirs
, files
in os
.walk(self
.tutorials_dir
):
153 # skip test directories if not in test_mode and vice versa
154 if bool(parent
[-5:] == '-test') ^
bool(self
.test_mode
):
159 # scan log for APPLICATION and then for schemes and solver
161 log
= open(os
.path
.join(parent
, f
), 'rt')
165 m
= re
.match(r
'APPLICATION:\s*(?P<app>\S+)', l
)
167 app
= os
.path
.basename(m
.group('app'))
168 if app
not in solvers_tmp
:
169 solvers_tmp
[app
] = set()
170 schemes_tmp
[app
] = {}
172 for st
in fv_schemes
:
174 if st
not in schemes_tmp
[app
]:
175 schemes_tmp
[app
][st
] = set()
176 schemes_tmp
[app
][st
].add(l
.split()[-1])
177 m
= re
.match(r
'(\S+):\s+Solving for', l
)
179 solvers_tmp
[app
].add(m
.group(1))
180 # write schemes and solvers information per application
181 SC
= open(os
.path
.join(self
.tutorials_dir
, 'FvSchemes'), 'wt')
182 SO
= open(os
.path
.join(self
.tutorials_dir
, 'FvSolution'), 'wt')
183 applications
= solvers_tmp
.keys()
185 for app
in applications
:
188 for st
in fv_schemes
:
190 if st
in schemes_tmp
[app
] and len(schemes_tmp
[app
][st
]) > 0:
191 tmp
= list(schemes_tmp
[app
][st
])
193 SC
.write(' '+'\n '.join(tmp
)+'\n')
194 if len(solvers_tmp
[app
]) > 0:
195 tmp
= list(solvers_tmp
[app
])
197 SO
.write(' '+'\n '.join(tmp
)+'\n')
201 if __name__
== '__main__':
202 os
.chdir(os
.path
.abspath(os
.path
.dirname(sys
.argv
[0])))
203 sys
.exit(AllTutorialsRunner().main())
205 # ------------------- vim: set sw=3 sts=3 ft=python et: ------------ end-of-file