Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resources not cleaned up with Ctrl+C #354

Open
brandonchinn178 opened this issue Nov 29, 2022 · 2 comments
Open

Resources not cleaned up with Ctrl+C #354

brandonchinn178 opened this issue Nov 29, 2022 · 2 comments

Comments

@brandonchinn178
Copy link
Contributor

Minimal repro:

import Control.Concurrent
import Control.Exception
import Test.Tasty
import Test.Tasty.HUnit

main :: IO ()
main = defaultMain $
  testCase "test" $ do
    putStrLn "Sleeping..."
    threadDelay 100000000 `finally`
      ( do
          putStrLn "finally.1"
          threadDelay 1000000
          putStrLn "finally.2"
      )

Observed behaviors:

Ctrl+C
test: Sleeping...
^Cfinally.1
foo-test: SignalException 15
Ctrl+C without second threadDelay
test: Sleeping...
^Cfinally.1
finally.2
pkill -INT
test: Sleeping...
finally.1
finally.2

foo> Test suite foo-test failed
Test suite failure for package foo-0.1
    foo-test:  exited with: ExitFailure (-2)
Logs printed to console
pkill -15
test: Sleeping...
finally.1
finally.2
foo-test: SignalException 15

foo> Test suite foo-test failed
Test suite failure for package foo-0.1
    foo-test:  exited with: ExitFailure 1
Logs printed to console

This behavior also happens with unliftio's finally, which uses uninterruptibleMask. It also fails to clean up any bracket or withResource wrapping the entire test, e.g. cleanup will never be printed in the following snippet:

main = defaultMain $
  withResource (putStrLn "setup") (\_ -> putStrLn "cleanup") $ \_ ->
    -- same code as above

Changing the second threadDelay to threadDelay 1 does clean up, so it's not threadDelay itself, just anything taking a long time. In our case, connecting to a postgres database (e.g. with postgresql-libpq's connectStart function) in the finally block also shows this behavior.

This only happens with stack test. Manually compiling with ghc Main.hs && ./Main will clean up, and cabal test --test-show-details=streaming will exit immediately, but finish the cleanup in the background (as a zombie thread?).

@Bodigrim
Copy link
Collaborator

I'm afraid we can only be hold responsible for the behavior of a vanilla test executable. If stack test / cabal test perform some magic tricks to catch signals, the ball is in their court.

@brandonchinn178
Copy link
Contributor Author

Thanks @Bodigrim opened one here: commercialhaskell/stack#6236

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants