@@ -68,6 +68,8 @@ import Stack.Build.ExecuteEnv
6868 ( ExcludeTHLoading (.. ), ExecuteEnv (.. ), KeepOutputOpen (.. )
6969 , OutputType (.. ), withSingleContext
7070 )
71+ import Stack.Build.TestSuiteTimeout
72+ ( forceKill , prepareForEscalation , terminateGracefully )
7173import Stack.Build.Source ( addUnlistedToBuildCache )
7274import Stack.Config.ConfigureScript ( ensureConfigureScript )
7375import Stack.ConfigureOpts
@@ -1156,13 +1158,47 @@ singleTest topts testsToRun ac ee task installedMap = do
11561158 )
11571159 createSource
11581160 OTLogFile _ h -> Nothing <$ useHandleOpen h
1159- optionalTimeout action
1161+ runOutput p =
1162+ case (getStdout p, getStderr p) of
1163+ (Nothing , Nothing ) -> pure ()
1164+ (Just x, Just y) -> concurrently_ x y
1165+ (x, y) -> assert False $
1166+ concurrently_
1167+ (fromMaybe (pure () ) x)
1168+ (fromMaybe (pure () ) y)
1169+ timeoutWithGrace p maxSecs graceSecs = do
1170+ mExit <- timeout (maxSecs * 1000000 ) (waitExitCode p)
1171+ case mExit of
1172+ Just ec -> pure (Just ec)
1173+ Nothing -> do
1174+ terminateGracefully p
1175+ mGraceExit <- timeout (graceSecs * 1000000 )
1176+ (waitExitCode p)
1177+ case mGraceExit of
1178+ Just _ -> pure Nothing
1179+ Nothing -> do
1180+ forceKill p
1181+ void $ waitExitCode p
1182+ pure Nothing
1183+ runWithTimeout pc
1184+ | Just maxSecs <- topts. maximumTimeSeconds, maxSecs > 0
1185+ , Just graceSecs <- topts. timeoutGraceSeconds
1186+ , graceSecs > 0 =
1187+ withProcessWait (prepareForEscalation pc) $ \ p -> do
1188+ (_, mec') <- concurrently
1189+ (runOutput p)
1190+ (timeoutWithGrace p maxSecs graceSecs)
1191+ pure mec'
11601192 | Just maxSecs <- topts. maximumTimeSeconds, maxSecs > 0 =
1161- timeout (maxSecs * 1000000 ) action
1162- | otherwise = Just <$> action
1193+ timeout (maxSecs * 1000000 ) $
1194+ withProcessWait pc $ \ p -> do
1195+ runOutput p
1196+ waitExitCode p
1197+ | otherwise =
1198+ Just <$> withProcessWait pc (\ p -> runOutput p *> waitExitCode p)
11631199
11641200 mec <- withWorkingDir (toFilePath pkgDir) $
1165- optionalTimeout $ proc (toFilePath exePath) args $ \ pc0 -> do
1201+ proc (toFilePath exePath) args $ \ pc0 -> do
11661202 changeStdin <-
11671203 if isTestTypeLib
11681204 then do
@@ -1185,15 +1221,7 @@ singleTest topts testsToRun ac ee task installedMap = do
11851221 $ setStdout output
11861222 $ setStderr output
11871223 pc0
1188- withProcessWait pc $ \ p -> do
1189- case (getStdout p, getStderr p) of
1190- (Nothing , Nothing ) -> pure ()
1191- (Just x, Just y) -> concurrently_ x y
1192- (x, y) -> assert False $
1193- concurrently_
1194- (fromMaybe (pure () ) x)
1195- (fromMaybe (pure () ) y)
1196- waitExitCode p
1224+ runWithTimeout pc
11971225 -- Add a trailing newline, incase the test
11981226 -- output didn't finish with a newline.
11991227 case outputType of
0 commit comments