From bfc31230963407326f32693f50cb229046bc7014 Mon Sep 17 00:00:00 2001
From: Cheng Shao <terrorjack@type.dance>
Date: Sun, 2 Apr 2023 12:09:24 +0000
Subject: [PATCH] testsuite: wasm32-specific fixes

This patch includes all wasm32-specific testsuite fixes.

(cherry picked from commit bd2bfdecc8040a9a70478cd8d646a34b5fa77c35)
---
 libraries/base/tests/IO/all.T               |  7 ++++---
 libraries/base/tests/IO/openFile008.hs      |  3 +--
 libraries/base/tests/all.T                  |  2 +-
 testsuite/config/ghc                        |  1 +
 testsuite/driver/testlib.py                 |  7 +++++++
 testsuite/tests/codeGen/should_run/all.T    |  6 +++---
 testsuite/tests/concurrent/should_run/all.T | 11 +++++++++--
 testsuite/tests/ffi/should_run/all.T        |  4 ++--
 testsuite/tests/lib/base/all.T              |  2 +-
 testsuite/tests/perf/compiler/all.T         |  3 ++-
 testsuite/tests/profiling/should_run/all.T  |  4 +++-
 testsuite/tests/rts/all.T                   | 19 +++++++++++++++----
 testsuite/tests/rts/flags/all.T             |  5 ++++-
 testsuite/tests/typecheck/testeq1/test.T    |  2 ++
 14 files changed, 55 insertions(+), 21 deletions(-)

diff --git a/libraries/base/tests/IO/all.T b/libraries/base/tests/IO/all.T
index 896aa6fbc19..a572983db8a 100644
--- a/libraries/base/tests/IO/all.T
+++ b/libraries/base/tests/IO/all.T
@@ -35,7 +35,7 @@ test('hReady001', js_broken(22374), compile_and_run, ['-cpp'])
 # work for the 'ghci' way because in that case we already pipe input from
 # a script, so hence omit_ways(['ghci'])
 test('hReady002', [cmd_prefix('sleep 1 |'), omit_ways(['ghci']),
-                   multi_cpu_race, js_broken(22374)],
+                   multi_cpu_race, js_broken(22374), when(arch('wasm32'), fragile(23275))],
      compile_and_run, [''])
 
 test('hSeek001', normal, compile_and_run, [''])
@@ -57,7 +57,7 @@ test('hSetBuffering004', set_stdin('hSetBuffering004.hs'), compile_and_run, ['']
 test('ioeGetErrorString001', normal, compile_and_run, ['-cpp'])
 test('ioeGetFileName001',    normal, compile_and_run, ['-cpp'])
 test('ioeGetHandle001',      normal, compile_and_run, ['-cpp'])
-test('isEOF001', extra_run_opts('</dev/null'), compile_and_run, [''])
+test('isEOF001', [extra_run_opts('</dev/null'), when(arch('wasm32'), fragile(23275))], compile_and_run, [''])
 
 test('misc001', [extra_run_opts('misc001.hs misc001.out')], compile_and_run,
      [''])
@@ -70,7 +70,7 @@ test('openFile005', js_broken(22261), compile_and_run, [''])
 test('openFile006', [], compile_and_run, [''])
 test('openFile007', js_broken(22261), compile_and_run, [''])
 test('openFile008', [js_broken(22349), cmd_prefix('ulimit -n 1024; ')], compile_and_run, [''])
-test('openFile009', [], compile_and_run, [''])
+test('openFile009', [when(arch('wasm32'), fragile(23284))], compile_and_run, [''])
 
 test('putStr001',    normal, compile_and_run, [''])
 test('readFile001', js_broken(22261), compile_and_run, [''])
@@ -146,6 +146,7 @@ test('encodingerror001', normal, compile_and_run, [''])
 
 # Requires use of the FD interface which is not supported under WINIO
 test('T4808', [when(opsys('mingw32'), skip)
+              , when(arch('wasm32'), fragile(23284))
               ,fragile_for(16909, concurrent_ways), exit_code(1)]
               , compile_and_run, [''])
 test('T4895', normal, compile_and_run, [''])
diff --git a/libraries/base/tests/IO/openFile008.hs b/libraries/base/tests/IO/openFile008.hs
index 9c1a1c47f8a..fb4d0bce44e 100644
--- a/libraries/base/tests/IO/openFile008.hs
+++ b/libraries/base/tests/IO/openFile008.hs
@@ -1,5 +1,4 @@
 import System.IO
-import System.Cmd
 import System.FilePath
 import Text.Printf
 import System.Directory
@@ -10,7 +9,7 @@ testdir = "openFile008_testdir"
 -- Test repeated opening/closing of 1000 files.  This is useful for guaging
 -- the performance of open/close and file locking.
 main = do
-  system ("rm -rf " ++ testdir)
+  removePathForcibly testdir
   createDirectory testdir
   let filenames = [testdir </> printf "file%03d" (n::Int) | n <- [1..1000]]
 
diff --git a/libraries/base/tests/all.T b/libraries/base/tests/all.T
index ed16544fa23..0d5af400b4a 100644
--- a/libraries/base/tests/all.T
+++ b/libraries/base/tests/all.T
@@ -169,7 +169,7 @@ test('qsemn001', normal, compile_and_run, [''])
 
 test('T7457', normal, compile_and_run, [''])
 
-test('T7773', [when(opsys('mingw32'), skip), js_broken(22261)], compile_and_run, [''])
+test('T7773', [when(opsys('mingw32'), skip), js_broken(22261), when(arch('wasm32'), fragile(23275))], compile_and_run, [''])
 # Andreas says that T7773 will not (and should not) work on Windows
 
 # Tests for kind-polymorphic Category
diff --git a/testsuite/config/ghc b/testsuite/config/ghc
index 6e55d868a95..1d0fef92eca 100644
--- a/testsuite/config/ghc
+++ b/testsuite/config/ghc
@@ -80,6 +80,7 @@ if not config.arch == "javascript":
 
 if config.arch == "wasm32":
     config.have_process = False
+    config.supports_dynamic_libs = False
 
 config.way_flags = {
     'normal'       : [],
diff --git a/testsuite/driver/testlib.py b/testsuite/driver/testlib.py
index 41b191b2f96..1bcfb45adaa 100644
--- a/testsuite/driver/testlib.py
+++ b/testsuite/driver/testlib.py
@@ -256,6 +256,9 @@ def req_dynamic_hs( name, opts ):
 def req_interp( name, opts ):
     if not config.have_interp or isCross():
         opts.expect = 'fail'
+    # skip on wasm32, otherwise they show up as unexpected passes
+    if arch('wasm32'):
+        skip(name, opts)
     # JS backend doesn't provide an interpreter yet
     js_skip(name, opts)
 
@@ -491,6 +494,10 @@ def _exit_code( name, opts, v ):
 def signal_exit_code( val: int ):
     if opsys('solaris2'):
         return exit_code( val )
+    elif arch('wasm32'):
+        # wasmtime always exits with 1 when wasm program exits with a
+        # non-zero exit code
+        return exit_code(1)
     else:
         # When application running on Linux receives fatal error
         # signal, then its exit code is encoded as 128 + signal
diff --git a/testsuite/tests/codeGen/should_run/all.T b/testsuite/tests/codeGen/should_run/all.T
index 47ef6d82f1e..8e737e87aa6 100644
--- a/testsuite/tests/codeGen/should_run/all.T
+++ b/testsuite/tests/codeGen/should_run/all.T
@@ -29,7 +29,7 @@ test('cgrun021', extra_ways(['nursery_chunks']), compile_and_run, [''])
 test('cgrun022', normal, compile_and_run, [''])
 test('cgrun024', normal, compile_and_run, [''])
 test('cgrun025',
-     [ extra_run_opts('cgrun025.hs < /dev/null'), exit_code(1)],
+     [ extra_run_opts('cgrun025.hs < /dev/null'), exit_code(1), when(arch('wasm32'), fragile(23275))],
      compile_and_run, [''])
 test('cgrun026', normal, compile_and_run, [''])
 test('cgrun027', normal, compile_and_run, [''])
@@ -74,7 +74,7 @@ test('cgrun065', normal, compile_and_run, [''])
 test('cgrun066', normal, compile_and_run, [''])
 test('cgrun067', [extra_files(['Cgrun067A.hs'])], compile_and_run, [''])
 test('cgrun069',
-     [ omit_ways(['ghci']), req_cmm],
+     [ omit_ways(['ghci']), req_cmm, when(arch('wasm32'), fragile(22854))],
      multi_compile_and_run,
      ['cgrun069', [('cgrun069_cmm.cmm', '')], ''])
 test('cgrun070', normal, compile_and_run, [''])
@@ -212,7 +212,7 @@ test('T16617', normal, compile_and_run, [''])
 test('T16449_2', exit_code(0), compile_and_run, [''])
 test('T16846', [only_ways(['optasm']), exit_code(1)], compile_and_run, [''])
 
-test('T17920', cmm_src, compile_and_run, [''])
+test('T17920', [cmm_src, when(arch('wasm32'), fragile(22854))], compile_and_run, [''])
 test('T18527', req_c, compile_and_run, ['T18527FFI.c'])
 test('T19149', [req_c,only_ways('sanity')], compile_and_run, ['T19149_c.c'])
 test('T20275', normal, compile_and_run, [''])
diff --git a/testsuite/tests/concurrent/should_run/all.T b/testsuite/tests/concurrent/should_run/all.T
index 541e0cc8e32..7588b820e95 100644
--- a/testsuite/tests/concurrent/should_run/all.T
+++ b/testsuite/tests/concurrent/should_run/all.T
@@ -25,7 +25,11 @@ test('conc072', only_ways(concurrent_ways), compile_and_run, [''])
 test('conc073', normal, compile_and_run, [''])
 
 test('T367_letnoescape',
-     [run_timeout_multiplier(0.02), expect_broken_for(7297,['optllvm'])],
+     [run_timeout_multiplier(0.02), expect_broken_for(7297,['optllvm']),
+     # wasm32 rts has no timer and scheduler always behaves as -C0,
+     # see Note [No timer on wasm32] in rts. It'll be stuck in the
+     # thread that infinitely loops, which is the expected behavior.
+     when(arch('wasm32'), skip)],
      compile_and_run, ['-fno-omit-yields'])
 
 test('T1980', normal, compile_and_run, [''])
@@ -86,7 +90,10 @@ test('T7970', normal, compile_and_run, [''])
 test('AtomicPrimops', normal, compile_and_run, [''])
 
 # test uses 2 threads and yield, scheduling can vary with threaded2
-test('threadstatus-9333', [fragile_for(16555, ['ghci', 'profthreaded']), omit_ways(concurrent_ways)], compile_and_run, [''])
+test('threadstatus-9333', [fragile_for(16555, ['ghci', 'profthreaded']), omit_ways(concurrent_ways),
+# wasm32 rts has no timer and scheduler always behaves as -C0. See
+# Note [No timer on wasm32] in rts
+when(arch('wasm32'), skip)], compile_and_run, [''])
 
 test('T9379', normal, compile_and_run, [''])
 
diff --git a/testsuite/tests/ffi/should_run/all.T b/testsuite/tests/ffi/should_run/all.T
index f2270fc2ab5..1b0e021d630 100644
--- a/testsuite/tests/ffi/should_run/all.T
+++ b/testsuite/tests/ffi/should_run/all.T
@@ -144,9 +144,9 @@ if config.os == 'mingw32':
 	flagsForT4038 = ['-optl-Wl,--stack,10485760']
 else:
 	flagsForT4038 = ['']
-test('T4038', js_broken(22261), compile_and_run, flagsForT4038)
+test('T4038', [js_broken(22261), when(arch('wasm32'), fragile(22606))], compile_and_run, flagsForT4038)
 
-test('T4221', [omit_ways(['ghci']),req_c], compile_and_run, ['T4221_c.c'])
+test('T4221', [omit_ways(['ghci']),req_c, when(arch('wasm32'), fragile(22606))], compile_and_run, ['T4221_c.c'])
 
 test('T5402', [ omit_ways(['ghci']),
                 exit_code(42),
diff --git a/testsuite/tests/lib/base/all.T b/testsuite/tests/lib/base/all.T
index e04bb27eae6..a23fb4cdcc3 100644
--- a/testsuite/tests/lib/base/all.T
+++ b/testsuite/tests/lib/base/all.T
@@ -4,7 +4,7 @@ test('T16586', normal, compile_and_run, ['-O2'])
 test('T16916', [when(opsys('mingw32'), skip), js_broken(22261), fragile(16966), req_ghc_with_threaded_rts], compile_and_run, ['-O2 -threaded -with-rtsopts="-I0" -rtsopts'])
 test('T17310', normal, compile, [''])
 test('T19691', normal, compile, [''])
-test('executablePath', [extra_run_opts(config.os), js_broken(22261)], compile_and_run, [''])
+test('executablePath', [extra_run_opts(config.os), js_broken(22261), when(arch('wasm32'), fragile(23248))], compile_and_run, [''])
 test('T17472', normal, compile_and_run, [''])
 test('T19569b', normal, compile_and_run, [''])
 test('Monoid_ByteArray', normal, compile_and_run, [''])
diff --git a/testsuite/tests/perf/compiler/all.T b/testsuite/tests/perf/compiler/all.T
index 8c009c5a6c6..fdb83026852 100644
--- a/testsuite/tests/perf/compiler/all.T
+++ b/testsuite/tests/perf/compiler/all.T
@@ -42,6 +42,7 @@ test('T4801',
      [collect_compiler_stats('bytes allocated',2),
       only_ways(['normal']),
       extra_hc_opts('-static'),
+      when(arch('wasm32') and unregisterised(), fragile(23290))
       ],
      compile,
      [''])
@@ -667,6 +668,6 @@ test('T21839c',
     ['-O'])
 
 test ('InfiniteListFusion',
-      [collect_stats('bytes allocated',2), when(arch('i386'), skip)],
+      [collect_stats('bytes allocated',2), when(wordsize(32), skip)],
       compile_and_run,
       ['-O2 -package ghc'])
diff --git a/testsuite/tests/profiling/should_run/all.T b/testsuite/tests/profiling/should_run/all.T
index 34d0f5d8799..c9e147ca1f6 100644
--- a/testsuite/tests/profiling/should_run/all.T
+++ b/testsuite/tests/profiling/should_run/all.T
@@ -60,7 +60,9 @@ test('heapprof001',
      compile_and_run, [''])
 
 test('T2592',
-     [only_ways(['profasm']), extra_run_opts('+RTS -M1m -A1m -RTS'), exit_code(251)],
+     [only_ways(['profasm']), extra_run_opts('+RTS -M1m -A1m -RTS'),
+     exit_code(1 if arch('wasm32') else 251),
+     when(arch('wasm32'), ignore_stderr)],
      compile_and_run, [''])
 
 test('T3001', [only_ways(['prof_hb']), extra_ways(['prof_hb'])],
diff --git a/testsuite/tests/rts/all.T b/testsuite/tests/rts/all.T
index 99b4decf575..aeaf1505768 100644
--- a/testsuite/tests/rts/all.T
+++ b/testsuite/tests/rts/all.T
@@ -3,7 +3,8 @@ test('testblockalloc',
      compile_and_run, [''])
 
 test('testmblockalloc',
-     [c_src, only_ways(['normal','threaded1']), extra_run_opts('+RTS -I0')],
+     [c_src, only_ways(['normal','threaded1']), extra_run_opts('+RTS -I0'),
+      when(arch('wasm32'), skip)], # MBlocks can't be freed on wasm32, see Note [Megablock allocator on wasm] in rts
      compile_and_run, [''])
 # -I0 is important: the idle GC will run the memory leak detector,
 # which will crash because the mblocks we allocate are not in a state
@@ -353,8 +354,12 @@ test('ListStaticPointers', [when(doing_ghci(), extra_hc_opts('-fobject-code'))],
 # 251 = RTS exit code for "out of memory"
 test('overflow1', [ js_skip, exit_code(251), when(wordsize(32), expect_broken(15255)) ],
      compile_and_run, [''])
-test('overflow2', [ js_skip, exit_code(251) ], compile_and_run, [''])
-test('overflow3', [ js_skip, exit_code(251) ], compile_and_run, [''])
+test('overflow2', [ js_skip,
+                    exit_code(1 if arch('wasm32') else 251),
+                    when(arch('wasm32'), ignore_stderr) ], compile_and_run, [''])
+test('overflow3', [ js_skip,
+                    exit_code(1 if arch('wasm32') else 251),
+                    when(arch('wasm32'), ignore_stderr) ], compile_and_run, [''])
 
 def grep_stderr(pattern):
     def wrapper(cmd, pattern=pattern):
@@ -499,7 +504,7 @@ test('keep-cafs',
 
 # Test proper functioning of C++ exceptions within a C++ program.
 # On darwin, this requires -fcompact-unwind.
-test('T11829', [ req_c, check_errmsg("This is a test") ], compile_and_run,
+test('T11829', [ req_c, check_errmsg("This is a test"), when(arch('wasm32'), fragile(23244)) ], compile_and_run,
      ['T11829_c.cpp -package system-cxx-std-lib'])
 
 test('T16514', req_c, compile_and_run, ['T16514_c.c'])
@@ -529,12 +534,18 @@ test('T15427', js_broken(22374), compile_and_run, [''])
 test('T19481',
      [extra_run_opts('+RTS -T -RTS'),
       js_broken(22374),
+      # MBlocks can't be freed on wasm32, see Note [Megablock
+      # allocator on wasm] in rts
+      when(arch('wasm32'), skip),
       # memory behavior changes appreciably with the nonmoving collector
       omit_ways(['nonmoving', 'nonmoving_thr', 'nonmoving_thr_sanity'])],
      compile_and_run, [''])
 test('T19381',
      [extra_run_opts('+RTS -T -RTS'),
       js_broken(22374),
+      # MBlocks can't be freed on wasm32, see Note [Megablock
+      # allocator on wasm] in rts
+      when(arch('wasm32'), skip),
       # memory behavior changes appreciably with the nonmoving collector
       omit_ways(['nonmoving', 'nonmoving_thr', 'nonmoving_thr_sanity'])],
      compile_and_run, [''])
diff --git a/testsuite/tests/rts/flags/all.T b/testsuite/tests/rts/flags/all.T
index 65de43681a8..b7505cd2d30 100644
--- a/testsuite/tests/rts/flags/all.T
+++ b/testsuite/tests/rts/flags/all.T
@@ -44,7 +44,10 @@ test('T12870f',
 # Check handling of env variables
 test('T12870g',
     [extra_files(['T12870g.hs']), cmd_prefix('GHCRTS=-G7 '), extra_files(['T12870g.hs']),
-        only_ways(['normal'])],
+        only_ways(['normal']),
+        # cross emulator for wasm32 always clears host environment
+        # variables
+        when(arch('wasm32'), skip)],
     multimod_compile_and_run,
     ['T12870g', '-rtsopts -with-rtsopts="-G3"'])
 
diff --git a/testsuite/tests/typecheck/testeq1/test.T b/testsuite/tests/typecheck/testeq1/test.T
index 9000e8f640d..58dfc33e166 100644
--- a/testsuite/tests/typecheck/testeq1/test.T
+++ b/testsuite/tests/typecheck/testeq1/test.T
@@ -2,5 +2,7 @@
 test('typecheck.testeq1', [ extra_files(['FakePrelude.hs', 'Main.hs', 'TypeCast.hs', 'TypeEq.hs'])
                           , when(fast(), skip)
                           , js_broken(22355)
+                          # https://gitlab.haskell.org/ghc/ghc/-/issues/23238
+                          , when(arch('wasm32'), skip)
                           ], multimod_compile_and_run,
      ['Main', '-v0'])
-- 
GitLab