Refactoring of duplicate code in metaval's tool-info module.
The code for changing the current working directory was present twice.
Because this code is quite critical and error-prone
(as indicated by the number of iterations we needed to write it),
it needs to be deduplicated to make sure future changes will not
introduce inconsistencies.
@@ -22,6 +22,7 @@ import argparse
import benchexec.util as util
import benchexec.tools.template
import benchexec.result as result
+import contextlib
import os
import threading
@@ -47,21 +48,29 @@ class Tool(benchexec.tools.template.BaseTool):
def name(self):
return "metaval"
- def determine_result(self, returncode, returnsignal, output, isTimeout):
- if hasattr(self, "wrappedTool"):
+ @contextlib.contextmanager
+ def _in_tool_directory(self):
+ """
+ Context manager that sets the current working directory to the tool's directory
+ and resets its afterward. The returned value is the previous working directory.
+ """
with self.lock:
try:
oldcwd = os.getcwd()
- os.chdir(
- os.path.join(oldcwd, self.TOOL_TO_PATH_MAP[self.verifierName])
- )
- return self.wrappedTool.determine_result(
- returncode, returnsignal, output, isTimeout
- )
+ os.chdir(os.path.join(oldcwd, self.TOOL_TO_PATH_MAP[self.verifierName]))
+ yield oldcwd
finally:
os.chdir(oldcwd)
+
+ def determine_result(self, returncode, returnsignal, output, isTimeout):
+ if not hasattr(self, "wrappedTool"):
return "METAVAL ERROR"
+ with self._in_tool_directory():
+ return self.wrappedTool.determine_result(
+ returncode, returnsignal, output, isTimeout
+ )
+
def cmdline(self, executable, options, tasks, propertyfile=None, rlimits={}):
parser = argparse.ArgumentParser(add_help=False, usage=argparse.SUPPRESS)
parser.add_argument("--metavalWitness", required=True)
@@ -92,10 +101,7 @@ class Tool(benchexec.tools.template.BaseTool):
exit("metaval is called with mixed wrapped tools")
if hasattr(self, "wrappedTool"):
- with self.lock:
- try:
- oldcwd = os.getcwd()
- os.chdir(os.path.join(oldcwd, self.TOOL_TO_PATH_MAP[verifierName]))
+ with self._in_tool_directory() as oldcwd:
wrappedOptions = self.wrappedTool.cmdline(
self.wrappedTool.executable(),
options,
@@ -103,8 +109,6 @@ class Tool(benchexec.tools.template.BaseTool):
os.path.relpath(os.path.join(oldcwd, propertyfile)),
rlimits,
)
- finally:
- os.chdir(oldcwd)
return (
[
executable,
