summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2022-10-17 23:09:25 -0400
committerCheng Shao <terrorjack@type.dance>2023-03-30 18:43:53 +0000
commit79d0cb3210e71bc5eca97af7e12a654134336d1f (patch)
treef9b9f88ef32dcfcc3d88bd2b20da8f915f89d72f
parentcea56ccca154d477d858f3b25008df42b68a2b17 (diff)
downloadhaskell-79d0cb3210e71bc5eca97af7e12a654134336d1f.tar.gz
testsuite/driver: Add basic support for testing cross-compilers
-rw-r--r--testsuite/driver/runtests.py2
-rw-r--r--testsuite/driver/testglobals.py11
-rw-r--r--testsuite/driver/testlib.py18
3 files changed, 29 insertions, 2 deletions
diff --git a/testsuite/driver/runtests.py b/testsuite/driver/runtests.py
index 5cd8b9697f..73c832031d 100644
--- a/testsuite/driver/runtests.py
+++ b/testsuite/driver/runtests.py
@@ -71,6 +71,7 @@ parser.add_argument("--config", action='append', help="config field")
parser.add_argument("--rootdir", action='append', help="root of tree containing tests (default: .)")
parser.add_argument("--metrics-file", help="file in which to save (append) the performance test metrics. If omitted, git notes will be used.")
parser.add_argument("--summary-file", help="file in which to save the (human-readable) summary")
+parser.add_argument("--target-wrapper", help="wrapper executable to use when executing binaries compiled for the target")
parser.add_argument("--no-print-summary", action="store_true", help="should we print the summary?")
parser.add_argument("--only", action="append", help="just this test (can be give multiple --only= flags)")
parser.add_argument("--way", action="append", help="just this way")
@@ -119,6 +120,7 @@ hasMetricsFile = config.metrics_file is not None
config.summary_file = args.summary_file
config.no_print_summary = args.no_print_summary
config.baseline_commit = args.perf_baseline
+config.target_wrapper = args.target_wrapper
if args.top:
config.top = args.top
diff --git a/testsuite/driver/testglobals.py b/testsuite/driver/testglobals.py
index 62643f2acc..eb72e5e202 100644
--- a/testsuite/driver/testglobals.py
+++ b/testsuite/driver/testglobals.py
@@ -178,6 +178,11 @@ class TestConfig:
# threads
self.threads = 1
+ # An optional executable used to wrap target code execution
+ # When set tests which aren't marked with TestConfig.cross_okay
+ # are skipped.
+ self.target_wrapper = None
+
# tests which should be considered to be broken during this testsuite
# run.
self.broken_tests = set() # type: Set[TestName]
@@ -448,6 +453,12 @@ class TestOptions:
# Should we copy the files of symlink the files for the test?
self.copy_files = False
+ # Should the test be run in a cross-compiled tree?
+ # None: infer from test function
+ # True: run when --target-wrapper is set
+ # False: do not run in cross-compiled trees
+ self.cross_okay = None # type: Optional[bool]
+
# The extra hadrian dependencies we need for this particular test
self.hadrian_deps = set(["test:ghc"]) # type: Set[str]
diff --git a/testsuite/driver/testlib.py b/testsuite/driver/testlib.py
index a1242faeb3..173f96c908 100644
--- a/testsuite/driver/testlib.py
+++ b/testsuite/driver/testlib.py
@@ -90,6 +90,10 @@ def setLocalTestOpts(opts: TestOptions) -> None:
global testopts_local
testopts_local.x = opts
+def isCross() -> bool:
+ """ Are we testing a cross-compiler? """
+ return config.target_wrapper is not None
+
def isCompilerStatsTest() -> bool:
opts = getTestOpts()
return bool(opts.is_compiler_stats_test)
@@ -255,7 +259,7 @@ def req_dynamic_hs( name, opts ):
opts.expect = 'fail'
def req_interp( name, opts ):
- if not config.have_interp:
+ if not config.have_interp or isCross():
opts.expect = 'fail'
# JS backend doesn't provide an interpreter yet
js_skip(name, opts)
@@ -1098,14 +1102,21 @@ def test_common_work(name: TestName, opts,
all_ways = [WayName('ghci')]
else:
all_ways = []
+ if isCross():
+ opts.cross_okay = False
elif func in [makefile_test, run_command]:
# makefile tests aren't necessarily runtime or compile-time
# specific. Assume we can run them in all ways. See #16042 for what
# happened previously.
all_ways = config.compile_ways + config.run_ways
+ if isCross():
+ opts.cross_okay = False
else:
all_ways = [WayName('normal')]
+ if isCross() and opts.cross_okay is False:
+ opts.skip = True
+
# A test itself can request extra ways by setting opts.extra_ways
all_ways = list(OrderedDict.fromkeys(all_ways + [way for way in opts.extra_ways if way not in all_ways]))
@@ -1831,7 +1842,10 @@ def simple_run(name: TestName, way: WayName, prog: str, extra_run_opts: str) ->
stats_args = ''
# Put extra_run_opts last: extra_run_opts('+RTS foo') should work.
- cmd = ' '.join([prog, stats_args, my_rts_flags, extra_run_opts])
+ args = [prog, stats_args, my_rts_flags, extra_run_opts]
+ if config.target_wrapper is not None:
+ args = [config.target_wrapper] + args
+ cmd = ' '.join(args)
if opts.cmd_wrapper is not None:
cmd = opts.cmd_wrapper(cmd)