Skip to content

Commit 38d03c2

Browse files
committed
feat: show repl stderr on exceptions in test
1 parent 368a0e7 commit 38d03c2

File tree

2 files changed

+48
-36
lines changed
  • tests/integration

2 files changed

+48
-36
lines changed

tests/integration/lib/StackTest/Repl.hs

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,19 @@ module StackTest.Repl
1010
, replGetLine
1111
) where
1212

13+
import Control.Exception (SomeException, catch, displayException, finally)
1314
import Control.Monad (unless, when)
1415
import Control.Monad.IO.Class (liftIO)
1516
import Data.Maybe (fromMaybe)
1617
import GHC.Stack (HasCallStack)
18+
import System.Directory (removeFile)
1719
import System.Environment (lookupEnv)
18-
import System.Exit (ExitCode (..))
20+
import System.Exit (ExitCode (..), exitFailure)
1921
import System.IO
20-
( BufferMode (NoBuffering, LineBuffering), Handle
21-
, hClose, hGetChar, hGetLine, hPutStrLn, hSetBuffering
22+
( BufferMode (NoBuffering, LineBuffering), Handle, IOMode (ReadMode)
23+
, hClose, hGetChar, hGetContents', hGetLine, hPutStrLn, hSetBuffering
2224
, openTempFile
25+
, withFile
2326
)
2427

2528
import Control.Monad.Trans (lift)
@@ -87,6 +90,18 @@ runRepl cmd args actions = do
8790

8891
-- run the test script which is to talk to the GHCi subprocess.
8992
runReaderT actions (ReplConnection rStdin rStdout)
93+
-- the nested actions script may fail in arbitrary ways; handle that here,
94+
-- attaching the subprocess stderr as relevant context
95+
`catch` \(e :: SomeException) -> do
96+
putStrLn "=============================="
97+
putStrLn "EXCEPTION in test: "
98+
putStrLn . quote $ displayException e
99+
putStrLn "------[ stderr of repl ]------"
100+
withFile stderrBufPath ReadMode $ \h -> hGetContents' h >>= putStr . quote
101+
putStrLn "=============================="
102+
`finally` do
103+
hClose stderrBufHandle
104+
removeFile stderrBufPath
90105

91106
-- once done with the test, signal EOF on stdin for clean termination of ghci
92107
hClose rStdin
@@ -104,5 +119,9 @@ repl :: HasCallStack => [String] -> Repl () -> IO ()
104119
repl args action = do
105120
stackExe' <- stackExe
106121
ec <- runRepl stackExe' ("repl" : "--ghci-options=-ignore-dot-ghci" : args) action
107-
unless (ec == ExitSuccess) $
108-
error $ "GHCi exited with " <> show ec
122+
unless (ec == ExitSuccess) $ do
123+
putStrLn $ "repl exited with " <> show ec
124+
exitFailure
125+
126+
quote :: String -> String
127+
quote = unlines . map ("> " <>) . lines

tests/integration/tests/3926-ghci-with-sublibraries/Main.hs

Lines changed: 24 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,37 +5,30 @@ import StackTest
55
import StackTest.Repl
66

77
main :: IO ()
8-
main
9-
| isWindows =
10-
putStrLn "This test was disabled on Windows on 25 June 2023 (see \
11-
\https://github.com/commercialhaskell/stack/issues/6170)."
12-
| otherwise = do
13-
stack ["clean"] -- to make sure we can load the code even after a clean
14-
copy "src/Lib.v1" "src/Lib.hs"
15-
copy "src-internal/Internal.v1" "src-internal/Internal.hs"
16-
stack ["build"] -- need a build before ghci at the moment, see #4148
17-
replThread
18-
19-
replThread :: IO ()
20-
replThread = repl [] $ do
21-
-- The command must be issued before searching the output for the next prompt,
22-
-- otherwise, on Windows from msys2-20230526, `stack repl` encounters a EOF
23-
-- and terminates gracefully.
24-
replCommand ":main"
25-
liftIO $ putStrLn "Awaiting prompt..."
26-
nextPrompt
27-
liftIO $ putStrLn "Initial prompt received"
28-
line <- replGetLine
29-
let expected = "hello world"
30-
when (line /= expected) $
31-
error $
32-
"Main module didn't load correctly.\n"
33-
<> "Expected: " <> expected <> "\n"
34-
<> "Actual : " <> line <> "\n"
35-
liftIO $ copy "src-internal/Internal.v2" "src-internal/Internal.hs"
36-
reloadAndTest "testInt" "42" "Internal library didn't reload."
37-
liftIO $ copy "src/Lib.v2" "src/Lib.hs"
38-
reloadAndTest "testStr" "\"OK\"" "Main library didn't reload."
8+
main = do
9+
stack ["clean"] -- to make sure we can load the code even after a clean
10+
copy "src/Lib.v1" "src/Lib.hs"
11+
copy "src-internal/Internal.v1" "src-internal/Internal.hs"
12+
stack ["build"] -- need a build before ghci at the moment, see #4148
13+
repl [] $ do
14+
-- The command must be issued before searching the output for the next prompt,
15+
-- otherwise, on Windows from msys2-20230526, `stack repl` encounters a EOF
16+
-- and terminates gracefully.
17+
replCommand ":main"
18+
liftIO $ putStrLn "Awaiting prompt..."
19+
nextPrompt
20+
liftIO $ putStrLn "Initial prompt received"
21+
line <- replGetLine
22+
let expected = "hello world"
23+
when (line /= expected) $
24+
error $
25+
"Main module didn't load correctly.\n"
26+
<> "Expected: " <> expected <> "\n"
27+
<> "Actual : " <> line <> "\n"
28+
liftIO $ copy "src-internal/Internal.v2" "src-internal/Internal.hs"
29+
reloadAndTest "testInt" "42" "Internal library didn't reload."
30+
liftIO $ copy "src/Lib.v2" "src/Lib.hs"
31+
reloadAndTest "testStr" "\"OK\"" "Main library didn't reload."
3932

4033
reloadAndTest :: String -> String -> String -> Repl ()
4134
reloadAndTest cmd exp err = do

0 commit comments

Comments
 (0)