@@ -3,8 +3,10 @@ module Test.Utils.Docker
33 , withDocker
44 ) where
55
6+ import Control.Concurrent.Async (race , wait , withAsync )
67import Control.Concurrent (MVar , newMVar , modifyMVar )
7- import Control.Exception (throwIO , ErrorCall (.. ))
8+ import Control.Concurrent.Async (race_ )
9+ import Control.Exception (ErrorCall (.. ), throwIO )
810import Control.Monad (forM_ )
911import System.Exit (ExitCode (.. ))
1012import System.IO
@@ -22,12 +24,15 @@ import System.Process
2224 ( CreateProcess (.. )
2325 , StdStream (.. )
2426 , proc
25- , withCreateProcess
2627 , waitForProcess
2728 , createPipe
29+ , cleanupProcess
30+ , terminateProcess
31+ , withCreateProcess
2832 )
2933import System.IO.Unsafe (unsafePerformIO )
3034import Utils.Async (withAsyncThrow )
35+ import Utils.Delay (delay , seconds )
3136
3237data DockerCommand
3338 = DockerRun
@@ -57,19 +62,31 @@ withDocker debug tag cmd act =
5762 , std_err = UseHandle hwrite
5863 , create_group = True
5964 }
60- withCreateProcess create $ \ _ _ _ p ->
61- withAsyncThrow (wait name p) $
62- if debug
63- then tracing name hread act
64- else act hread
65+ withCreateProcess create $ \ stdin stdout stderr p -> do
66+ let pinfo = (stdin, stdout, stderr, p)
67+ withAsync (waitFor name pinfo) $ \ a -> do
68+ r <- race (wait a) $ if debug
69+ then tracing name hread act
70+ else act hread
71+ terminate pinfo
72+ case r of
73+ Left _ -> error " impossible"
74+ Right v -> return v
6575 where
76+ terminate pinfo = race_ (cleanupProcess pinfo) (forceEnd pinfo)
77+
78+ forceEnd (_,_,_,p) = do
79+ putStrLn $ " Forcing end of container: " <> tag
80+ delay (seconds 5 )
81+ terminateProcess p
82+
6683 withPipe f = do
6784 (hread, hwrite) <- createPipe
6885 hSetBuffering hread LineBuffering
6986 hSetBuffering hwrite LineBuffering
7087 f hread hwrite
7188
72- wait name p = do
89+ waitFor name (_,_,_,p) = do
7390 exit <- waitForProcess p
7491 throwIO $ ErrorCall $ case exit of
7592 ExitSuccess -> " unexpected successful termination of container " <> name
0 commit comments