| ... |
... |
@@ -23,7 +23,7 @@ import subprocess |
|
23
|
23
|
|
|
24
|
24
|
from testglobals import config, ghc_env, default_testopts, brokens, t, \
|
|
25
|
25
|
TestRun, TestResult, TestOptions, PerfMetric
|
|
26
|
|
-from testutil import strip_quotes, lndir, link_or_copy_file, passed, \
|
|
|
26
|
+from testutil import discover_io_managers, strip_quotes, lndir, link_or_copy_file, passed, \
|
|
27
|
27
|
failBecause, residency_testing_metrics, \
|
|
28
|
28
|
stable_perf_counters, \
|
|
29
|
29
|
PassFail, badResult, str_warn, str_removeprefix
|
| ... |
... |
@@ -190,7 +190,7 @@ def no_lint( name, opts ): |
|
190
|
190
|
|
|
191
|
191
|
def stage1(name, opts):
|
|
192
|
192
|
# See Note [Why is there no stage1 setup function?]
|
|
193
|
|
- framework_fail(name, 'stage1 setup function does not exist',
|
|
|
193
|
+ framework_fail(name, None,
|
|
194
|
194
|
'add your test to testsuite/tests/stage1 instead')
|
|
195
|
195
|
|
|
196
|
196
|
# Note [Why is there no stage1 setup function?]
|
| ... |
... |
@@ -341,7 +341,7 @@ def req_th( name, opts ): |
|
341
|
341
|
req_interp(name, opts);
|
|
342
|
342
|
|
|
343
|
343
|
if ghc_dynamic():
|
|
344
|
|
- return _omit_ways(name, opts, ['profasm', 'profthreaded'])
|
|
|
344
|
+ return _omit_ways(name, opts, [WayName('profasm'), WayName('profthreaded')])
|
|
345
|
345
|
|
|
346
|
346
|
def req_plugins( name, opts ):
|
|
347
|
347
|
"""
|
| ... |
... |
@@ -355,7 +355,7 @@ def req_plugins( name, opts ): |
|
355
|
355
|
req_interp(name, opts)
|
|
356
|
356
|
|
|
357
|
357
|
# Plugins aren't supported with the external interpreter (#14335)
|
|
358
|
|
- expect_broken_for(14335,['ext-interp'])(name,opts)
|
|
|
358
|
+ expect_broken_for(IssueNumber(14335),[WayName('ext-interp')])(name,opts)
|
|
359
|
359
|
|
|
360
|
360
|
if config.cross:
|
|
361
|
361
|
opts.skip = True
|
| ... |
... |
@@ -569,6 +569,33 @@ def extra_ways( ways: List[WayName] ): |
|
569
|
569
|
|
|
570
|
570
|
return helper
|
|
571
|
571
|
|
|
|
572
|
+# -----
|
|
|
573
|
+
|
|
|
574
|
+def _io_managers( name: TestName, opts, io_mgrs: List[str] ) -> None:
|
|
|
575
|
+ opts.io_managers = io_mgrs
|
|
|
576
|
+
|
|
|
577
|
+def io_managers( io_mgrs: List[str] ):
|
|
|
578
|
+ """
|
|
|
579
|
+ Run this test once for each of the given I/O managers (identified by
|
|
|
580
|
+ the name used with GHC's `--io-manager` RTS flag, e.g. 'mio',
|
|
|
581
|
+ 'select', 'winio'), instead of the usual set of ways. I/O managers
|
|
|
582
|
+ that are not supported on the current platform/build are silently
|
|
|
583
|
+ skipped.
|
|
|
584
|
+ """
|
|
|
585
|
+ return lambda name, opts: _io_managers(name, opts, io_mgrs)
|
|
|
586
|
+
|
|
|
587
|
+def all_io_managers( name: TestName, opts ):
|
|
|
588
|
+ """
|
|
|
589
|
+ Run this test once for each I/O manager supported by this
|
|
|
590
|
+ platform/build.
|
|
|
591
|
+ """
|
|
|
592
|
+ _io_managers(name, opts, config.io_managers_all)
|
|
|
593
|
+
|
|
|
594
|
+def all_io_managers_except(exclude: List[str]):
|
|
|
595
|
+ """
|
|
|
596
|
+ Like all_io_managers, but excluding the given I/O managers.
|
|
|
597
|
+ """
|
|
|
598
|
+ return lambda name, opts: _io_managers(name, opts, list(set(config.io_managers_all) - set(exclude)))
|
|
572
|
599
|
|
|
573
|
600
|
# -----
|
|
574
|
601
|
|
| ... |
... |
@@ -661,18 +688,15 @@ def collect_size ( deviation, path ): |
|
661
|
688
|
def collect_size_func ( deviation, path_func ):
|
|
662
|
689
|
return collect_generic_stat ( 'size', deviation, lambda way: os.path.getsize(in_testdir(path_func())) )
|
|
663
|
690
|
|
|
664
|
|
-def get_dir_size(path):
|
|
|
691
|
+def get_dir_size(path) -> int:
|
|
665
|
692
|
total = 0
|
|
666
|
|
- try:
|
|
667
|
|
- with os.scandir(path) as it:
|
|
668
|
|
- for entry in it:
|
|
669
|
|
- if entry.is_file():
|
|
670
|
|
- total += entry.stat().st_size
|
|
671
|
|
- elif entry.is_dir():
|
|
672
|
|
- total += get_dir_size(entry.path)
|
|
673
|
|
- return total
|
|
674
|
|
- except FileNotFoundError:
|
|
675
|
|
- print("Exception: Could not find: " + path)
|
|
|
693
|
+ with os.scandir(path) as it:
|
|
|
694
|
+ for entry in it:
|
|
|
695
|
+ if entry.is_file():
|
|
|
696
|
+ total += entry.stat().st_size
|
|
|
697
|
+ elif entry.is_dir():
|
|
|
698
|
+ total += get_dir_size(entry.path)
|
|
|
699
|
+ return total
|
|
676
|
700
|
|
|
677
|
701
|
def collect_size_dir ( deviation, path ):
|
|
678
|
702
|
return collect_size_dir_func ( deviation, lambda: path )
|
| ... |
... |
@@ -790,7 +814,7 @@ def find_non_inplace_so(lib): |
|
790
|
814
|
return _find_so(lib,path_from_ghcPkg(lib, "dynamic-library-dirs"),False)
|
|
791
|
815
|
|
|
792
|
816
|
|
|
793
|
|
-def collect_generic_stat ( metric, deviation: Optional[int], get_stat: Callable[[WayName], str]):
|
|
|
817
|
+def collect_generic_stat ( metric, deviation: Optional[int], get_stat: Callable[[WayName], Any]):
|
|
794
|
818
|
"""
|
|
795
|
819
|
Define a generic stat test, which computes the statistic by calling the function
|
|
796
|
820
|
given as the third argument.
|
| ... |
... |
@@ -1135,7 +1159,7 @@ def _collect_compiler_perf_counters(counters: Set[str], deviation: Optional[int] |
|
1135
|
1159
|
# Slightly hacky, we need the requested perf_counters in 'simple_run'.
|
|
1136
|
1160
|
# Thus, we have to globally register these counters
|
|
1137
|
1161
|
opts.compiler_perf_counters += list(counters)
|
|
1138
|
|
- _collect_stats(name, opts, counters, deviation, False, True, True)
|
|
|
1162
|
+ _collect_stats(name, opts, counters, deviation, None, True, True)
|
|
1139
|
1163
|
return f
|
|
1140
|
1164
|
|
|
1141
|
1165
|
|
| ... |
... |
@@ -1334,21 +1358,22 @@ def check_errmsg(needle): |
|
1334
|
1358
|
# grep_errmsg(regex,[groups])
|
|
1335
|
1359
|
# If groups are given, return only the matched groups
|
|
1336
|
1360
|
# that matches the regex.
|
|
1337
|
|
-def grep_errmsg_norm(needle:str, groups = None):
|
|
|
1361
|
+def grep_errmsg_norm(needle:str, groups_may = None):
|
|
1338
|
1362
|
|
|
1339
|
|
- def get_match(str:str):
|
|
1340
|
|
- m = re.search(needle,str)
|
|
1341
|
|
- if m:
|
|
1342
|
|
- return "".join([m.group(g) for g in groups if m.group(g) is not None])
|
|
1343
|
|
- else:
|
|
1344
|
|
- return None
|
|
1345
|
|
-
|
|
1346
|
|
- def norm(str) -> str:
|
|
1347
|
|
- if groups == None:
|
|
|
1363
|
+ def norm(string) -> str:
|
|
|
1364
|
+ if groups_may == None:
|
|
1348
|
1365
|
return "".join( filter(lambda l: re.search(needle,l),
|
|
1349
|
|
- str.splitlines(True)))
|
|
|
1366
|
+ string.splitlines(True)))
|
|
1350
|
1367
|
else:
|
|
1351
|
|
- matches = [get_match(x) for x in str.splitlines(True)]
|
|
|
1368
|
+ groups = groups_may
|
|
|
1369
|
+ def get_match(string: str):
|
|
|
1370
|
+ m = re.search(needle, string)
|
|
|
1371
|
+ if m:
|
|
|
1372
|
+ return "".join([m.group(g) for g in groups if m.group(g) is not None])
|
|
|
1373
|
+ else:
|
|
|
1374
|
+ return None
|
|
|
1375
|
+
|
|
|
1376
|
+ matches = [get_match(x) for x in string.splitlines(True)]
|
|
1352
|
1377
|
res = "\n".join([x for x in matches if x])
|
|
1353
|
1378
|
return res
|
|
1354
|
1379
|
return norm
|
| ... |
... |
@@ -1573,6 +1598,12 @@ do_not_copy = ('.hi', '.o', '.dyn_hi' |
|
1573
|
1598
|
, '.dyn_o', '.out'
|
|
1574
|
1599
|
,'.hi-boot', '.o-boot') # 12112
|
|
1575
|
1600
|
|
|
|
1601
|
+def way_supports_io_manager(way: WayName, io_manager: None | str) -> bool:
|
|
|
1602
|
+ if not io_manager:
|
|
|
1603
|
+ return True
|
|
|
1604
|
+ way_is_threaded = '-threaded' in config.way_rts_flags[way]
|
|
|
1605
|
+ return io_manager in config.io_managers_threaded if way_is_threaded else io_manager in config.io_managers_nonthreaded
|
|
|
1606
|
+
|
|
1576
|
1607
|
async def test_common_work(name: TestName, opts,
|
|
1577
|
1608
|
func, args) -> None:
|
|
1578
|
1609
|
try:
|
| ... |
... |
@@ -1582,11 +1613,14 @@ async def test_common_work(name: TestName, opts, |
|
1582
|
1613
|
package_conf_cache_file_start_timestamp = get_package_cache_timestamp()
|
|
1583
|
1614
|
|
|
1584
|
1615
|
# All the ways we might run this test
|
|
|
1616
|
+ func_has_io_manager_param = False
|
|
1585
|
1617
|
if func == compile or func == multimod_compile:
|
|
1586
|
1618
|
all_ways = config.compile_ways
|
|
1587
|
1619
|
elif func in [compile_and_run, multi_compile_and_run, multimod_compile_and_run]:
|
|
1588
|
1620
|
all_ways = config.run_ways
|
|
|
1621
|
+ func_has_io_manager_param = True
|
|
1589
|
1622
|
elif func == ghci_script or func == ghci_multiunit_script:
|
|
|
1623
|
+ func_has_io_manager_param = True
|
|
1590
|
1624
|
if config.have_interp:
|
|
1591
|
1625
|
all_ways = [WayName('ghci'), WayName('ghci-opt')]
|
|
1592
|
1626
|
else:
|
| ... |
... |
@@ -1616,12 +1650,28 @@ async def test_common_work(name: TestName, opts, |
|
1616
|
1650
|
if needsTargetWrapper():
|
|
1617
|
1651
|
opts.skip = True
|
|
1618
|
1652
|
else:
|
|
|
1653
|
+ if func in [backpack_run, warn_and_run]:
|
|
|
1654
|
+ func_has_io_manager_param = True
|
|
1619
|
1655
|
all_ways = [WayName('normal')]
|
|
1620
|
1656
|
|
|
1621
|
1657
|
# A test itself can request extra ways by setting opts.extra_ways
|
|
1622
|
1658
|
all_ways = list(OrderedDict.fromkeys(all_ways + [way for way in opts.extra_ways if way not in all_ways]))
|
|
1623
|
1659
|
|
|
1624
|
|
- t.total_test_cases += len(all_ways)
|
|
|
1660
|
+ # We run each way over each io manager (or just None meaning the default IO Manager)
|
|
|
1661
|
+ all_io_managers = opts.io_managers if func_has_io_manager_param and opts.io_managers else [None]
|
|
|
1662
|
+ all_ways_and_io_managers = dict(
|
|
|
1663
|
+ (
|
|
|
1664
|
+ way,
|
|
|
1665
|
+ [io_manager
|
|
|
1666
|
+ for io_manager in all_io_managers
|
|
|
1667
|
+ if way_supports_io_manager(way, io_manager)
|
|
|
1668
|
+ ]
|
|
|
1669
|
+ )
|
|
|
1670
|
+ for way in all_ways
|
|
|
1671
|
+ )
|
|
|
1672
|
+
|
|
|
1673
|
+ for io_managers in all_ways_and_io_managers.values():
|
|
|
1674
|
+ t.total_test_cases += len(io_managers)
|
|
1625
|
1675
|
|
|
1626
|
1676
|
only_ways = getTestOpts().only_ways
|
|
1627
|
1677
|
ok_way = lambda way: \
|
| ... |
... |
@@ -1704,17 +1754,26 @@ async def test_common_work(name: TestName, opts, |
|
1704
|
1754
|
|
|
1705
|
1755
|
# Run the required tests...
|
|
1706
|
1756
|
for way in do_ways:
|
|
1707
|
|
- if stopping():
|
|
1708
|
|
- break
|
|
1709
|
|
- try:
|
|
1710
|
|
- await do_test(name, way, func, args, files)
|
|
1711
|
|
- except KeyboardInterrupt:
|
|
1712
|
|
- stopNow()
|
|
1713
|
|
- except Exception as e:
|
|
1714
|
|
- traceback.print_exc()
|
|
1715
|
|
- framework_fail(name, way, traceback.format_exc())
|
|
|
1757
|
+ for io_manager in all_ways_and_io_managers[way]:
|
|
|
1758
|
+ if stopping():
|
|
|
1759
|
+ break
|
|
|
1760
|
+ try:
|
|
|
1761
|
+ await do_test(
|
|
|
1762
|
+ name,
|
|
|
1763
|
+ way,
|
|
|
1764
|
+ io_manager,
|
|
|
1765
|
+ func,
|
|
|
1766
|
+ args,
|
|
|
1767
|
+ files)
|
|
|
1768
|
+ except KeyboardInterrupt:
|
|
|
1769
|
+ stopNow()
|
|
|
1770
|
+ except Exception as e:
|
|
|
1771
|
+ traceback.print_exc()
|
|
|
1772
|
+ framework_fail(name, way, traceback.format_exc())
|
|
|
1773
|
+
|
|
|
1774
|
+ for skipped_way in set(all_ways) - set(do_ways):
|
|
|
1775
|
+ t.n_tests_skipped += len(all_ways_and_io_managers[skipped_way])
|
|
1716
|
1776
|
|
|
1717
|
|
- t.n_tests_skipped += len(set(all_ways) - set(do_ways))
|
|
1718
|
1777
|
if getTestOpts().expect == 'missing-lib': t.n_missing_libs += 1
|
|
1719
|
1778
|
|
|
1720
|
1779
|
if config.cleanup and do_ways:
|
| ... |
... |
@@ -1733,6 +1792,7 @@ async def test_common_work(name: TestName, opts, |
|
1733
|
1792
|
|
|
1734
|
1793
|
async def do_test(name: TestName,
|
|
1735
|
1794
|
way: WayName,
|
|
|
1795
|
+ io_manager: None | str,
|
|
1736
|
1796
|
func: Callable[..., Awaitable[PassFail]],
|
|
1737
|
1797
|
args,
|
|
1738
|
1798
|
files: Set[str]
|
| ... |
... |
@@ -1740,6 +1800,8 @@ async def do_test(name: TestName, |
|
1740
|
1800
|
opts = getTestOpts()
|
|
1741
|
1801
|
|
|
1742
|
1802
|
full_name = name + '(' + way + ')'
|
|
|
1803
|
+ if io_manager:
|
|
|
1804
|
+ full_name += ' (IO Manager: {})'.format(io_manager)
|
|
1743
|
1805
|
test_n = len(allTestNames)
|
|
1744
|
1806
|
progress_args = [ full_name, t.total_tests, test_n,
|
|
1745
|
1807
|
[len(t.unexpected_passes),
|
| ... |
... |
@@ -1820,7 +1882,20 @@ async def do_test(name: TestName, |
|
1820
|
1882
|
# Don't continue and try to run the test if the pre_cmd fails.
|
|
1821
|
1883
|
return
|
|
1822
|
1884
|
|
|
1823
|
|
- result = await func(*[name,way] + args)
|
|
|
1885
|
+
|
|
|
1886
|
+ func_has_io_manager_param = func in [
|
|
|
1887
|
+ backpack_run,
|
|
|
1888
|
+ compile_and_run,
|
|
|
1889
|
+ ghci_multiunit_script,
|
|
|
1890
|
+ ghci_script,
|
|
|
1891
|
+ multi_compile_and_run,
|
|
|
1892
|
+ multimod_compile_and_run,
|
|
|
1893
|
+ warn_and_run
|
|
|
1894
|
+ ]
|
|
|
1895
|
+
|
|
|
1896
|
+ io_manager_arg = [io_manager] if func_has_io_manager_param else []
|
|
|
1897
|
+
|
|
|
1898
|
+ result = await func(*[name,way] + io_manager_arg + args)
|
|
1824
|
1899
|
|
|
1825
|
1900
|
if opts.expect not in ['pass', 'fail', 'missing-lib']:
|
|
1826
|
1901
|
framework_fail(name, way, 'bad expected ' + opts.expect)
|
| ... |
... |
@@ -1909,7 +1984,7 @@ def framework_warn(name: TestName, way: WayName, reason: str) -> None: |
|
1909
|
1984
|
# run_command.
|
|
1910
|
1985
|
|
|
1911
|
1986
|
async def run_command( name, way, cmd ):
|
|
1912
|
|
- return await simple_run( name, '', override_options(cmd), '' )
|
|
|
1987
|
+ return await simple_run( name, WayName(''), None, override_options(cmd), '' )
|
|
1913
|
1988
|
|
|
1914
|
1989
|
async def makefile_test( name, way, target=None ):
|
|
1915
|
1990
|
if target is None:
|
| ... |
... |
@@ -1921,7 +1996,7 @@ async def makefile_test( name, way, target=None ): |
|
1921
|
1996
|
# -----------------------------------------------------------------------------
|
|
1922
|
1997
|
# GHCi tests
|
|
1923
|
1998
|
|
|
1924
|
|
-async def ghci_script( name, way, script):
|
|
|
1999
|
+async def ghci_script( name, way, io_manager, script):
|
|
1925
|
2000
|
flags = ' '.join(get_compiler_flags())
|
|
1926
|
2001
|
way_flags = ' '.join(config.way_flags[way])
|
|
1927
|
2002
|
|
| ... |
... |
@@ -1932,9 +2007,9 @@ async def ghci_script( name, way, script): |
|
1932
|
2007
|
# NB: put way_flags before flags so that flags in all.T can override others
|
|
1933
|
2008
|
|
|
1934
|
2009
|
getTestOpts().stdin = script
|
|
1935
|
|
- return await simple_run( name, way, cmd, getTestOpts().extra_run_opts )
|
|
|
2010
|
+ return await simple_run( name, way, io_manager, cmd, getTestOpts().extra_run_opts )
|
|
1936
|
2011
|
|
|
1937
|
|
-async def ghci_multiunit_script( name, way, units, script):
|
|
|
2012
|
+async def ghci_multiunit_script( name, way, io_manager, units, script):
|
|
1938
|
2013
|
flags = ' '.join(get_compiler_flags())
|
|
1939
|
2014
|
way_flags = ' '.join(config.way_flags[way])
|
|
1940
|
2015
|
unit_flags = ' '.join(['-unit @%s' % unit for unit in units])
|
| ... |
... |
@@ -1946,7 +2021,7 @@ async def ghci_multiunit_script( name, way, units, script): |
|
1946
|
2021
|
# NB: put way_flags before flags so that flags in all.T can override others
|
|
1947
|
2022
|
|
|
1948
|
2023
|
getTestOpts().stdin = script
|
|
1949
|
|
- return await simple_run( name, way, cmd, getTestOpts().extra_run_opts )
|
|
|
2024
|
+ return await simple_run( name, way, io_manager, cmd, getTestOpts().extra_run_opts )
|
|
1950
|
2025
|
|
|
1951
|
2026
|
# -----------------------------------------------------------------------------
|
|
1952
|
2027
|
# Compile-only tests
|
| ... |
... |
@@ -1995,7 +2070,7 @@ async def multi_compile_fail( name, way, top_mod, extra_mods, extra_hc_opts ): |
|
1995
|
2070
|
return await do_compile( name, way, True, top_mod, extra_mods, [], extra_hc_opts)
|
|
1996
|
2071
|
|
|
1997
|
2072
|
async def make_depend( name, way, mods, extra_hc_opts ):
|
|
1998
|
|
- return await do_compile( name, way, False, ' '.join(mods), [], [], extra_hc_opts, mode = '-M')
|
|
|
2073
|
+ return await do_compile( name, way, False, Path(' '.join(mods)), [], [], extra_hc_opts, mode = '-M')
|
|
1999
|
2074
|
|
|
2000
|
2075
|
async def do_compile(name: TestName,
|
|
2001
|
2076
|
way: WayName,
|
| ... |
... |
@@ -2126,7 +2201,8 @@ async def compile_grep_core(name: TestName, |
|
2126
|
2201
|
|
|
2127
|
2202
|
async def compile_and_run__(name: TestName,
|
|
2128
|
2203
|
way: WayName,
|
|
2129
|
|
- top_mod: Path,
|
|
|
2204
|
+ io_manager: None | str,
|
|
|
2205
|
+ top_mod: Path | None,
|
|
2130
|
2206
|
extra_mods: List[str],
|
|
2131
|
2207
|
extra_hc_opts: str,
|
|
2132
|
2208
|
backpack: bool=False,
|
| ... |
... |
@@ -2168,22 +2244,22 @@ async def compile_and_run__(name: TestName, |
|
2168
|
2244
|
cmd = './' + name + extension
|
|
2169
|
2245
|
|
|
2170
|
2246
|
# we don't check the compiler's stderr for a compile-and-run test
|
|
2171
|
|
- return await simple_run( name, way, cmd, getTestOpts().extra_run_opts )
|
|
|
2247
|
+ return await simple_run( name, way, io_manager, cmd, getTestOpts().extra_run_opts )
|
|
2172
|
2248
|
|
|
2173
|
|
-async def compile_and_run( name, way, extra_hc_opts ):
|
|
2174
|
|
- return await compile_and_run__( name, way, None, [], extra_hc_opts)
|
|
|
2249
|
+async def compile_and_run( name, way, io_manager, extra_hc_opts ):
|
|
|
2250
|
+ return await compile_and_run__( name, way, io_manager, None, [], extra_hc_opts)
|
|
2175
|
2251
|
|
|
2176
|
|
-async def backpack_run( name, way, extra_hc_opts ):
|
|
2177
|
|
- return await compile_and_run__( name, way, None, [], extra_hc_opts, backpack=True )
|
|
|
2252
|
+async def backpack_run( name, way, io_manager, extra_hc_opts ):
|
|
|
2253
|
+ return await compile_and_run__( name, way, io_manager, None, [], extra_hc_opts, backpack=True )
|
|
2178
|
2254
|
|
|
2179
|
|
-async def multimod_compile_and_run( name, way, top_mod, extra_hc_opts ):
|
|
2180
|
|
- return await compile_and_run__( name, way, top_mod, [], extra_hc_opts)
|
|
|
2255
|
+async def multimod_compile_and_run( name, way, io_manager, top_mod, extra_hc_opts ):
|
|
|
2256
|
+ return await compile_and_run__( name, way, io_manager, top_mod, [], extra_hc_opts)
|
|
2181
|
2257
|
|
|
2182
|
|
-async def multi_compile_and_run( name, way, top_mod, extra_mods, extra_hc_opts ):
|
|
2183
|
|
- return await compile_and_run__( name, way, top_mod, extra_mods, extra_hc_opts)
|
|
|
2258
|
+async def multi_compile_and_run( name, way, io_manager, top_mod, extra_mods, extra_hc_opts ):
|
|
|
2259
|
+ return await compile_and_run__( name, way, io_manager, top_mod, extra_mods, extra_hc_opts)
|
|
2184
|
2260
|
|
|
2185
|
|
-async def warn_and_run( name, way, extra_hc_opts ):
|
|
2186
|
|
- return await compile_and_run__( name, way, None, [], extra_hc_opts, compile_stderr = True)
|
|
|
2261
|
+async def warn_and_run( name, way, io_manager, extra_hc_opts ):
|
|
|
2262
|
+ return await compile_and_run__( name, way, io_manager, None, [], extra_hc_opts, compile_stderr = True)
|
|
2187
|
2263
|
|
|
2188
|
2264
|
async def static_stats( name, way ):
|
|
2189
|
2265
|
opts = getTestOpts()
|
| ... |
... |
@@ -2390,7 +2466,7 @@ async def simple_build(name: Union[TestName, str], |
|
2390
|
2466
|
# from /dev/null. Route output to testname.run.stdout and
|
|
2391
|
2467
|
# testname.run.stderr. Returns the exit code of the run.
|
|
2392
|
2468
|
|
|
2393
|
|
-async def simple_run(name: TestName, way: WayName, prog: str, extra_run_opts: str) -> Any:
|
|
|
2469
|
+async def simple_run(name: TestName, way: WayName, io_manager: None | str, prog: str, extra_run_opts: str) -> Any:
|
|
2394
|
2470
|
opts = getTestOpts()
|
|
2395
|
2471
|
|
|
2396
|
2472
|
# figure out what to use for stdin
|
| ... |
... |
@@ -2409,6 +2485,9 @@ async def simple_run(name: TestName, way: WayName, prog: str, extra_run_opts: st |
|
2409
|
2485
|
|
|
2410
|
2486
|
my_rts_flags = rts_flags(way)
|
|
2411
|
2487
|
|
|
|
2488
|
+ if io_manager:
|
|
|
2489
|
+ my_rts_flags += '+RTS --io-manager={0} -RTS'.format(io_manager)
|
|
|
2490
|
+
|
|
2412
|
2491
|
# Collect runtime stats if necessary:
|
|
2413
|
2492
|
# isStatsTest and not isCompilerStatsTest():
|
|
2414
|
2493
|
# assume we are running a ghc compiled program. Collect stats.
|
| ... |
... |
@@ -2434,6 +2513,12 @@ async def simple_run(name: TestName, way: WayName, prog: str, extra_run_opts: st |
|
2434
|
2513
|
|
|
2435
|
2514
|
output_file = perfStatsFile(False, name)
|
|
2436
|
2515
|
|
|
|
2516
|
+ # Check that IO Manager is available
|
|
|
2517
|
+ if io_manager:
|
|
|
2518
|
+ available_io_managers = discover_io_managers(prog, opts.testdir)
|
|
|
2519
|
+ if io_manager not in available_io_managers:
|
|
|
2520
|
+ framework_fail(name, way, 'IO Manager {} unexpectedly unavailable (available IO Managers: {}). `-non-threaded`/`-threaded` is only supported through way RTS flags (not manually added via test modifiers/args) when testing over IO Managers.'.format(io_manager, available_io_managers))
|
|
|
2521
|
+
|
|
2437
|
2522
|
# run the command
|
|
2438
|
2523
|
exit_code = await runCmdPerf(opts.compiler_perf_counters, cmd, output_file,
|
|
2439
|
2524
|
working_dir=opts.testdir,
|
| ... |
... |
@@ -2495,7 +2580,7 @@ def rts_flags(way: WayName) -> str: |
|
2495
|
2580
|
async def interpreter_run(name: TestName,
|
|
2496
|
2581
|
way: WayName,
|
|
2497
|
2582
|
extra_hc_opts: str,
|
|
2498
|
|
- top_mod: Path
|
|
|
2583
|
+ top_mod: Path | None
|
|
2499
|
2584
|
) -> PassFail:
|
|
2500
|
2585
|
opts = getTestOpts()
|
|
2501
|
2586
|
|
| ... |
... |
@@ -2866,11 +2951,11 @@ async def compare_outputs( |
|
2866
|
2951
|
if config.accept_platform:
|
|
2867
|
2952
|
if_verbose(1, 'Accepting new output for platform "'
|
|
2868
|
2953
|
+ config.platform + '".')
|
|
2869
|
|
- expected_path += '-' + config.platform
|
|
|
2954
|
+ expected_path = Path(str(expected_path) + '-' + config.platform)
|
|
2870
|
2955
|
elif config.accept_os:
|
|
2871
|
2956
|
if_verbose(1, 'Accepting new output for os "'
|
|
2872
|
2957
|
+ config.os + '".')
|
|
2873
|
|
- expected_path += '-' + config.os
|
|
|
2958
|
+ expected_path = Path(str(expected_path) + '-' + config.os)
|
|
2874
|
2959
|
else:
|
|
2875
|
2960
|
if_verbose(1, 'Accepting new output.')
|
|
2876
|
2961
|
|
| ... |
... |
@@ -3500,7 +3585,7 @@ def find_expected_file(name: TestName, suff: str, way: WayName) -> Path: |
|
3500
|
3585
|
|
|
3501
|
3586
|
for f in files:
|
|
3502
|
3587
|
if in_srcdir(f).exists():
|
|
3503
|
|
- return f
|
|
|
3588
|
+ return Path(f)
|
|
3504
|
3589
|
|
|
3505
|
3590
|
return basename
|
|
3506
|
3591
|
|