summaryrefslogtreecommitdiffstats
path: root/debuginfo-tests/dexter/dex/tools/TestToolBase.py
diff options
context:
space:
mode:
Diffstat (limited to 'debuginfo-tests/dexter/dex/tools/TestToolBase.py')
-rw-r--r--debuginfo-tests/dexter/dex/tools/TestToolBase.py148
1 files changed, 148 insertions, 0 deletions
diff --git a/debuginfo-tests/dexter/dex/tools/TestToolBase.py b/debuginfo-tests/dexter/dex/tools/TestToolBase.py
new file mode 100644
index 00000000000..7e00fc54b19
--- /dev/null
+++ b/debuginfo-tests/dexter/dex/tools/TestToolBase.py
@@ -0,0 +1,148 @@
+# DExTer : Debugging Experience Tester
+# ~~~~~~ ~ ~~ ~ ~~
+#
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+"""Base class for subtools that do build/run tests."""
+
+import abc
+from datetime import datetime
+import os
+import sys
+
+from dex.builder import add_builder_tool_arguments
+from dex.builder import handle_builder_tool_options
+from dex.debugger.Debuggers import add_debugger_tool_arguments
+from dex.debugger.Debuggers import handle_debugger_tool_options
+from dex.heuristic.Heuristic import add_heuristic_tool_arguments
+from dex.tools.ToolBase import ToolBase
+from dex.utils import get_root_directory, warn
+from dex.utils.Exceptions import Error, ToolArgumentError
+from dex.utils.ReturnCode import ReturnCode
+
+
+class TestToolBase(ToolBase):
+ def __init__(self, *args, **kwargs):
+ super(TestToolBase, self).__init__(*args, **kwargs)
+ self.build_script: str = None
+
+ def add_tool_arguments(self, parser, defaults):
+ parser.description = self.__doc__
+ add_builder_tool_arguments(parser)
+ add_debugger_tool_arguments(parser, self.context, defaults)
+ add_heuristic_tool_arguments(parser)
+
+ parser.add_argument(
+ 'test_path',
+ type=str,
+ metavar='<test-path>',
+ nargs='?',
+ default=os.path.abspath(
+ os.path.join(get_root_directory(), '..', 'tests')),
+ help='directory containing test(s)')
+
+ parser.add_argument(
+ '--results-directory',
+ type=str,
+ metavar='<directory>',
+ default=os.path.abspath(
+ os.path.join(get_root_directory(), '..', 'results',
+ datetime.now().strftime('%Y-%m-%d-%H%M-%S'))),
+ help='directory to save results')
+
+ def handle_options(self, defaults):
+ options = self.context.options
+
+ # We accept either or both of --binary and --builder.
+ if not options.binary and not options.builder:
+ raise Error('expected --builder or --binary')
+
+ # --binary overrides --builder
+ if options.binary:
+ if options.builder:
+ warn(self.context, "overriding --builder with --binary\n")
+
+ options.binary = os.path.abspath(options.binary)
+ if not os.path.isfile(options.binary):
+ raise Error('<d>could not find binary file</> <r>"{}"</>'
+ .format(options.binary))
+ else:
+ try:
+ self.build_script = handle_builder_tool_options(self.context)
+ except ToolArgumentError as e:
+ raise Error(e)
+
+ try:
+ handle_debugger_tool_options(self.context, defaults)
+ except ToolArgumentError as e:
+ raise Error(e)
+
+ options.test_path = os.path.abspath(options.test_path)
+ if not os.path.isfile(options.test_path) and not os.path.isdir(options.test_path):
+ raise Error(
+ '<d>could not find test path</> <r>"{}"</>'.format(
+ options.test_path))
+
+ options.results_directory = os.path.abspath(options.results_directory)
+ if not os.path.isdir(options.results_directory):
+ try:
+ os.makedirs(options.results_directory, exist_ok=True)
+ except OSError as e:
+ raise Error(
+ '<d>could not create directory</> <r>"{}"</> <y>({})</>'.
+ format(options.results_directory, e.strerror))
+
+ def go(self) -> ReturnCode: # noqa
+ options = self.context.options
+
+ options.executable = os.path.join(
+ self.context.working_directory.path, 'tmp.exe')
+
+ if os.path.isdir(options.test_path):
+
+ subdirs = sorted([
+ r for r, _, f in os.walk(options.test_path)
+ if 'test.cfg' in f
+ ])
+
+ for subdir in subdirs:
+
+ # TODO: read file extensions from the test.cfg file instead so
+ # that this isn't just limited to C and C++.
+ options.source_files = [
+ os.path.normcase(os.path.join(subdir, f))
+ for f in os.listdir(subdir) if any(
+ f.endswith(ext) for ext in ['.c', '.cpp'])
+ ]
+
+ self._run_test(self._get_test_name(subdir))
+ else:
+ options.source_files = [options.test_path]
+ self._run_test(self._get_test_name(options.test_path))
+
+ return self._handle_results()
+
+ @staticmethod
+ def _is_current_directory(test_directory):
+ return test_directory == '.'
+
+ def _get_test_name(self, test_path):
+ """Get the test name from either the test file, or the sub directory
+ path it's stored in.
+ """
+ # test names are distinguished by their relative path from the
+ # specified test path.
+ test_name = os.path.relpath(test_path,
+ self.context.options.test_path)
+ if self._is_current_directory(test_name):
+ test_name = os.path.basename(test_path)
+ return test_name
+
+ @abc.abstractmethod
+ def _run_test(self, test_dir):
+ pass
+
+ @abc.abstractmethod
+ def _handle_results(self) -> ReturnCode:
+ pass
OpenPOWER on IntegriCloud