Skip to content

Commit 8a0a0f0

Browse files
mpickeringjulialongtin
authored andcommitted
testsuite: Be explicit about runtime test dependencies
Issue #8356 reports occasional errors from running the testsuite about multiple package versions available. This stems from the invokation of `runghc` not being explicit about all dependencies of the testsuite. The solution is provide a component in the cabal file which is explicit about which packages the tests can depend on. This component has a build-depends section which lists all the dependencies that the tests require. It would be better if this component was a library component but we can't do this with a Custom setup because of limitations to do with per-component builds. Then we also enable `-hide-all-packages`, so the dependency will not be available if it is not explicitly listed as a dependency. You could also imagine a future where the Setup.hs script found the test files and compiled a single executable which would run all the tests, rather than invoking runghc on each one individually. Fixes #8356
1 parent c3a92e5 commit 8a0a0f0

File tree

5 files changed

+42
-13
lines changed

5 files changed

+42
-13
lines changed

cabal-testsuite/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,15 @@ Otherwise, here is a walkthrough:
9696
...
9797
```
9898

99+
The dependencies which your test is allowed to use are listed in the
100+
cabal file under the `test-runtime-deps` executable. At compile-time there is
101+
a custom Setup.hs script which inspects this list and records the versions of
102+
each package in a generated file. These are then used when `cabal-tests` runs
103+
when it invokes `runghc` to run each test.
104+
We ensure they are built and available by listing `test-runtime-deps` in the
105+
build-tool-depends section of the cabal-tests executable.
106+
107+
99108
3. Run your tests using `cabal-tests` (no need to rebuild when
100109
you add or modify a test; it is automatically picked up).
101110
The first time you run a test, assuming everything else is

cabal-testsuite/Setup.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ canonicalizePackageDB x = return x
7373
-- non-Backpack.
7474
cabalTestsPackages :: LocalBuildInfo -> [(OpenUnitId, ModuleRenaming)]
7575
cabalTestsPackages lbi =
76-
case componentNameCLBIs lbi (CExeName (mkUnqualComponentName "cabal-tests")) of
76+
case componentNameCLBIs lbi (CExeName (mkUnqualComponentName "test-runtime-deps")) of
7777
[clbi] -> -- [ (unUnitId $ unDefUnitId duid,rn) | (DefiniteUnitId duid, rn) <- componentIncludes clbi ]
7878
componentIncludes clbi
7979
_ -> error "cabalTestsPackages"

cabal-testsuite/cabal-testsuite.cabal

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ executable cabal-tests
9090
main-is: cabal-tests.hs
9191
hs-source-dirs: main
9292
ghc-options: -threaded
93+
-- Make sure these are built before the executable is run
94+
build-tool-depends: cabal-testsuite:test-runtime-deps
9395
build-depends:
9496
, cabal-testsuite
9597
-- constraints inherited via lib:cabal-testsuite component
@@ -101,18 +103,6 @@ executable cabal-tests
101103
, transformers
102104
-- dependencies specific to exe:cabal-tests
103105
, clock ^>= 0.7.2 || ^>=0.8
104-
-- Extra dependencies used by PackageTests.
105-
--
106-
-- The runner allows the tests to use extra dependencies and the custom Prelude
107-
-- from 'cabal-testsuite'.
108-
-- However, if the tests use a dependency, say 'directory', and there are two
109-
-- packages with the same unit id available in the store, the test fails since
110-
-- it doesn't know which one to pick.
111-
-- By including an extra dependency to directory, we force the test runner to
112-
-- use a specific version directory, fixing the test failure.
113-
--
114-
-- See issue description and discussion: https://github.com/haskell/cabal/issues/8356
115-
, directory
116106

117107
build-tool-depends: cabal-testsuite:setup
118108
default-extensions: TypeOperators
@@ -122,6 +112,32 @@ executable setup
122112
import: shared
123113
main-is: Setup.simple.hs
124114

115+
-- This executable component is used to describe the runtime dependencies of
116+
-- the tests. The Main.hs file and resulting executable are not useful in any way.
117+
118+
-- Ideally this would be an empty library, but because build-type: Custom, we can't
119+
-- have sublibraries.
120+
121+
-- If you require an external dependency for a test it must be listed here.
122+
executable test-runtime-deps
123+
build-depends: cabal-testsuite,
124+
base,
125+
directory,
126+
Cabal,
127+
Cabal-syntax,
128+
filepath,
129+
transformers,
130+
bytestring,
131+
time,
132+
process,
133+
exceptions
134+
main-is: static/Main.hs
135+
if !os(windows)
136+
build-depends: unix
137+
else
138+
build-depends:
139+
, Win32
140+
125141
custom-setup
126142
-- we only depend on even stable releases of lib:Cabal
127143
-- and due to Custom complexity and ConstraintSetupCabalMaxVersion

cabal-testsuite/src/Test/Cabal/Script.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ runnerGhcArgs senv =
9393
where
9494
ghc_options = M.mempty { ghcOptPackageDBs = runnerPackageDbStack senv
9595
, ghcOptPackages = toNubListR (runnerPackages senv)
96+
, ghcOptHideAllPackages = Flag True
9697
-- Avoid picking stray module files that look
9798
-- like our imports
9899
, ghcOptSourcePathClear = Flag True }

cabal-testsuite/static/Main.hs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module Main where
2+
3+
main = return ()

0 commit comments

Comments
 (0)