From b74bac0d180fddbc13f2b8e47e8644ec00aa8203 Mon Sep 17 00:00:00 2001 From: Thomas Tuegel <ttuegel@gmail.com> Date: Sat, 28 Mar 2015 22:26:28 -0500 Subject: [PATCH] fix deadlock in detailed-0.9 test suite runner Fixes #2489. The detailed-0.9 test suite runner would deadlock because the IO manager was not draining the output pipe of the child process. Thanks to @r0ml for the patch. --- Cabal/Distribution/Simple/Test/LibV09.hs | 12 ++++--- Cabal/tests/PackageTests.hs | 12 +++---- .../TestSuiteTests/ExeV10/Check.hs | 14 ++++---- .../TestSuiteTests/LibV09/Check.hs | 34 ++++++++++--------- .../TestSuiteTests/LibV09/tests/Deadlock.hs | 2 +- 5 files changed, 40 insertions(+), 34 deletions(-) diff --git a/Cabal/Distribution/Simple/Test/LibV09.hs b/Cabal/Distribution/Simple/Test/LibV09.hs index 482953822d..859e6a9958 100644 --- a/Cabal/Distribution/Simple/Test/LibV09.hs +++ b/Cabal/Distribution/Simple/Test/LibV09.hs @@ -29,8 +29,9 @@ import Distribution.TestSuite import Distribution.Text import Distribution.Verbosity ( normal ) +import Control.Concurrent (forkIO) import Control.Exception ( bracket ) -import Control.Monad ( when, unless ) +import Control.Monad ( when, unless, void ) import Data.Maybe ( mapMaybe ) import System.Directory ( createDirectoryIfMissing, doesDirectoryExist, doesFileExist @@ -81,6 +82,12 @@ runTest pkg_descr lbi flags suite = do hPutStr wIn $ show (tempLog, PD.testName suite) hClose wIn + -- Append contents of temporary log file to the final human- + -- readable log file + logText <- hGetContents rOut + -- Force the IO manager to drain the test output pipe + void $ forkIO $ length logText `seq` return () + -- Run test executable _ <- do let opts = map (testOption pkg_descr lbi suite) $ testOptions flags dataDirPath = pwd </> PD.dataDir pkg_descr @@ -118,9 +125,6 @@ runTest pkg_descr lbi flags suite = do -- Write summary notice to log file indicating start of test suite appendFile (logFile suiteLog) $ summarizeSuiteStart $ PD.testName suite - -- Append contents of temporary log file to the final human- - -- readable log file - logText <- hGetContents rOut appendFile (logFile suiteLog) logText -- Write end-of-suite summary notice to log file diff --git a/Cabal/tests/PackageTests.hs b/Cabal/tests/PackageTests.hs index 458c2a0aa1..e065f0f9d7 100644 --- a/Cabal/tests/PackageTests.hs +++ b/Cabal/tests/PackageTests.hs @@ -79,12 +79,12 @@ tests config version = -- only for higher versions. , testGroup "TestSuiteTests" [ testGroup "ExeV10" - (PackageTests.TestSuiteTests.ExeV10.Check.checks ghcPath) + (PackageTests.TestSuiteTests.ExeV10.Check.checks config) , testGroup "LibV09" - (PackageTests.TestSuiteTests.LibV09.Check.checks inplaceSpec ghcPath) + (PackageTests.TestSuiteTests.LibV09.Check.checks config) ] - , testCase "TestOptions" (PackageTests.TestOptions.Check.suite ghcPath) - , testCase "BenchmarkStanza" (PackageTests.BenchmarkStanza.Check.suite ghcPath) + , testCase "TestOptions" (PackageTests.TestOptions.Check.suite config) + , testCase "BenchmarkStanza" (PackageTests.BenchmarkStanza.Check.suite config) -- ^ The benchmark stanza test will eventually be required -- only for higher versions. , testCase "BenchmarkExeV10/Test" @@ -101,8 +101,8 @@ tests config version = , testCase "DeterministicAr" (PackageTests.DeterministicAr.Check.suite config) , testCase "EmptyLib/emptyLib" - (PackageTests.EmptyLib.Check.emptyLib ghcPath) - , testCase "Haddock" (PackageTests.Haddock.Check.suite ghcPath) + (PackageTests.EmptyLib.Check.emptyLib config) + , testCase "Haddock" (PackageTests.Haddock.Check.suite config) , testCase "OrderFlags" (PackageTests.OrderFlags.Check.suite config) , testCase "TemplateHaskell/dynamic" diff --git a/Cabal/tests/PackageTests/TestSuiteTests/ExeV10/Check.hs b/Cabal/tests/PackageTests/TestSuiteTests/ExeV10/Check.hs index 758ce679d4..299e29ccb9 100644 --- a/Cabal/tests/PackageTests/TestSuiteTests/ExeV10/Check.hs +++ b/Cabal/tests/PackageTests/TestSuiteTests/ExeV10/Check.hs @@ -24,13 +24,13 @@ import Distribution.Version (Version(..), orLaterVersion) import PackageTests.PackageTester -checks :: FilePath -> [TestTree] -checks ghcPath = - [ testCase "Test" $ checkTest ghcPath - , testGroup "WithHpc" $ hpcTestMatrix ghcPath +checks :: SuiteConfig -> [TestTree] +checks config = + [ testCase "Test" $ checkTest config + , testGroup "WithHpc" $ hpcTestMatrix config , testGroup "WithoutHpc" - [ testCase "NoTix" $ checkTestNoHpcNoTix ghcPath - , testCase "NoMarkup" $ checkTestNoHpcNoMarkup ghcPath + [ testCase "NoTix" $ checkTestNoHpcNoTix config + , testCase "NoMarkup" $ checkTestNoHpcNoMarkup config ] ] @@ -59,7 +59,7 @@ hpcTestMatrix config = do enable cond flag | cond = Just $ "--enable-" ++ flag | otherwise = Nothing - return $ testCase name $ checkTestWithHpc ghcPath ("WithHpc-" ++ name) opts + return $ testCase name $ checkTestWithHpc config ("WithHpc-" ++ name) opts dir :: FilePath dir = "PackageTests" </> "TestSuiteTests" </> "ExeV10" diff --git a/Cabal/tests/PackageTests/TestSuiteTests/LibV09/Check.hs b/Cabal/tests/PackageTests/TestSuiteTests/LibV09/Check.hs index 1526a72182..ba9920dab0 100644 --- a/Cabal/tests/PackageTests/TestSuiteTests/LibV09/Check.hs +++ b/Cabal/tests/PackageTests/TestSuiteTests/LibV09/Check.hs @@ -9,31 +9,33 @@ import PackageTests.PackageTester dir :: FilePath dir = "PackageTests" </> "TestSuiteTests" </> "LibV09" -checks :: PackageSpec -> FilePath -> [TestTree] -checks inplaceSpec ghcPath = - [ testCase "Build" $ checkBuild inplaceSpec ghcPath - , localOption (mkTimeout $ 10 * 10 ^ (6 :: Int)) - $ testCase "Deadlock" $ checkDeadlock inplaceSpec ghcPath +checks :: SuiteConfig -> [TestTree] +checks config = + [ testCase "Build" (checkBuild config) + , localOption (mkTimeout $ 10 ^ (8 :: Int)) + $ testCase "Deadlock" (checkDeadlock config) ] -checkBuild :: PackageSpec -> FilePath -> Assertion -checkBuild inplaceSpec ghcPath = do - let spec = inplaceSpec +checkBuild :: SuiteConfig -> Assertion +checkBuild config = do + let spec = (inplaceSpec config) { directory = dir , distPref = Just $ "dist-Build" - , configOpts = "--enable-tests" : configOpts inplaceSpec + , configOpts = "--enable-tests" + : configOpts (inplaceSpec config) } - buildResult <- cabal_build spec ghcPath + buildResult <- cabal_build config spec assertBuildSucceeded buildResult -checkDeadlock :: PackageSpec -> FilePath -> Assertion -checkDeadlock inplaceSpec ghcPath = do - let spec = inplaceSpec +checkDeadlock :: SuiteConfig -> Assertion +checkDeadlock config = do + let spec = (inplaceSpec config) { directory = dir , distPref = Just $ "dist-Test" - , configOpts = "--enable-tests" : configOpts inplaceSpec + , configOpts = "--enable-tests" + : configOpts (inplaceSpec config) } - buildResult <- cabal_build spec ghcPath + buildResult <- cabal_build config spec assertBuildSucceeded buildResult - testResult <- cabal_test spec [] [] ghcPath + testResult <- cabal_test config spec [] [] assertTestFailed testResult diff --git a/Cabal/tests/PackageTests/TestSuiteTests/LibV09/tests/Deadlock.hs b/Cabal/tests/PackageTests/TestSuiteTests/LibV09/tests/Deadlock.hs index c20804bd55..5d7db101ed 100644 --- a/Cabal/tests/PackageTests/TestSuiteTests/LibV09/tests/Deadlock.hs +++ b/Cabal/tests/PackageTests/TestSuiteTests/LibV09/tests/Deadlock.hs @@ -5,4 +5,4 @@ import Distribution.TestSuite import Lib tests :: IO [Test] -tests = return [nullt x | x <- [1 .. 10000]] +tests = return [nullt x | x <- [1 .. 1000]] -- GitLab