Skip to content

Commit 0ecdcea

Browse files
committed
Tests for internal libraries (haskell#269) and separate cabal_macros.h (haskell#1893)
Signed-off-by: Edward Z. Yang <[email protected]>
1 parent e71332e commit 0ecdcea

File tree

22 files changed

+235
-26
lines changed

22 files changed

+235
-26
lines changed

Cabal/Cabal.cabal

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -95,14 +95,17 @@ extra-source-files:
9595
tests/PackageTests/HaddockNewline/A.hs
9696
tests/PackageTests/HaddockNewline/HaddockNewline.cabal
9797
tests/PackageTests/HaddockNewline/Setup.hs
98-
tests/PackageTests/MultipleLibraries/p.cabal
99-
tests/PackageTests/MultipleLibraries/p/P.hs
100-
tests/PackageTests/MultipleLibraries/p/Foo.hs
101-
tests/PackageTests/MultipleLibraries/p/p.cabal
102-
tests/PackageTests/MultipleLibraries/p/p/P.hs
103-
tests/PackageTests/MultipleLibraries/p/q/Q.hs
104-
tests/PackageTests/MultipleLibraries/q/Q.hs
105-
tests/PackageTests/MultipleLibraries/q/q.cabal
98+
tests/PackageTests/InternalLibraries/Executable/dist-test.Dynamic/test.sh
99+
tests/PackageTests/InternalLibraries/Executable/dist-test.Static/test.sh
100+
tests/PackageTests/InternalLibraries/Executable/exe/Main.hs
101+
tests/PackageTests/InternalLibraries/Executable/foo.cabal
102+
tests/PackageTests/InternalLibraries/Executable/src/Foo.hs
103+
tests/PackageTests/InternalLibraries/p/Foo.hs
104+
tests/PackageTests/InternalLibraries/p/p.cabal
105+
tests/PackageTests/InternalLibraries/p/p/P.hs
106+
tests/PackageTests/InternalLibraries/p/q/Q.hs
107+
tests/PackageTests/InternalLibraries/q/Q.hs
108+
tests/PackageTests/InternalLibraries/q/q.cabal
106109
tests/PackageTests/OrderFlags/Foo.hs
107110
tests/PackageTests/OrderFlags/my.cabal
108111
tests/PackageTests/PathsModule/Executable/Main.hs
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import Foo
2+
main = print (foo 23)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
name: foo
2+
version: 0.1.0.0
3+
license: BSD3
4+
author: Edward Z. Yang
5+
maintainer: [email protected]
6+
build-type: Simple
7+
cabal-version: >=1.23
8+
9+
library foo-internal
10+
exposed-modules: Foo
11+
build-depends: base
12+
hs-source-dirs: src
13+
default-language: Haskell2010
14+
15+
executable foo
16+
main-is: Main.hs
17+
build-depends: base, foo-internal
18+
hs-source-dirs: exe
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module Foo where
2+
{-# NOINLINE foo #-}
3+
foo :: Int -> Int
4+
foo x = x + 23
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module Main where
2+
3+
import Foo
4+
5+
main :: IO ()
6+
main = print foo
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
name: fooexe
2+
version: 0.1.0.0
3+
license: BSD3
4+
author: Edward Z. Yang
5+
maintainer: [email protected]
6+
build-type: Simple
7+
cabal-version: >=1.10
8+
9+
executable fooexe
10+
main-is: Main.hs
11+
build-depends: base, foolib
12+
default-language: Haskell2010
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module Foo where
2+
import Internal
3+
foo = internal + 2
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
name: foolib
2+
version: 0.1.0.0
3+
license: BSD3
4+
author: Edward Z. Yang
5+
maintainer: [email protected]
6+
build-type: Simple
7+
cabal-version: >=1.23
8+
9+
library foolib-internal
10+
exposed-modules: Internal
11+
hs-source-dirs: private
12+
build-depends: base
13+
14+
library
15+
exposed-modules: Foo
16+
build-depends: base, foolib-internal
17+
default-language: Haskell2010
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module Internal where
2+
{-# NOINLINE internal #-}
3+
internal :: Int
4+
internal = 23

Cabal/tests/PackageTests/Macros/A.hs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{-# LANGUAGE CPP #-}
2+
import C
3+
#ifdef VERSION_filepath
4+
#error "Should not see macro from library"
5+
#endif
6+
#ifdef VERSION_containers
7+
#error "Should not see macro from executable macros-b"
8+
#endif
9+
main = do
10+
putStrLn CURRENT_COMPONENT_ID

Cabal/tests/PackageTests/Macros/B.hs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{-# LANGUAGE CPP #-}
2+
import C
3+
#ifdef VERSION_filepath
4+
#error "Should not see macro from library"
5+
#endif
6+
#ifdef VERSION_deepseq
7+
#error "Should not see macro from executable macros-a"
8+
#endif
9+
main = do
10+
putStrLn CURRENT_COMPONENT_ID
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module Main where
2+
3+
main :: IO ()
4+
main = putStrLn "Hello, Haskell!"
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: macros
2+
version: 0.1.0.0
3+
license: BSD3
4+
license-file: LICENSE
5+
author: Edward Z. Yang
6+
maintainer: [email protected]
7+
build-type: Simple
8+
cabal-version: >=1.10
9+
10+
library macros
11+
exposed-modules: C
12+
hs-source-dirs: src
13+
build-depends: base, filepath
14+
15+
executable macros-a
16+
main-is: A.hs
17+
build-depends: base, deepseq, macros
18+
default-language: Haskell2010
19+
20+
executable macros-b
21+
main-is: B.hs
22+
build-depends: base, containers, macros
23+
default-language: Haskell2010
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{-# LANGUAGE CPP #-}
2+
module C where
3+
#ifdef VERSION_deepseq
4+
#error "Should not see macro from executable macros-a"
5+
#endif
6+
#ifdef VERSION_containers
7+
#error "Should not see macro from executable macros-b"
8+
#endif
9+
c :: String
10+
c = CURRENT_COMPONENT_ID

Cabal/tests/PackageTests/PackageTester.hs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ module PackageTests.PackageTester
2727
, run
2828
, runExe
2929
, runExe'
30+
, runInstalledExe
31+
, runInstalledExe'
3032
, rawRun
3133
, rawCompileSetup
3234
, withPackage
@@ -66,7 +68,7 @@ import Distribution.Simple.Configure
6668
import Distribution.Verbosity (Verbosity)
6769
import Distribution.Simple.BuildPaths (exeExtension)
6870

69-
#ifndef CURRENT_PACKAGE_KEY
71+
#ifndef LOCAL_COMPONENT_ID
7072
import Distribution.Simple.Utils (cabalVersion)
7173
import Distribution.Text (display)
7274
#endif
@@ -267,7 +269,7 @@ cabal' cmd extraArgs0 = do
267269
-- Would really like to do this, but we're not always
268270
-- going to be building against sufficiently recent
269271
-- Cabal which provides this macro.
270-
-- , "--dependency=Cabal=" ++ THIS_PACKAGE_KEY
272+
-- , "--dependency=Cabal=" ++ LOCAL_COMPONENT_ID
271273
-- These flags make the test suite run faster
272274
-- Can't do this unless we LD_LIBRARY_PATH correctly
273275
-- , "--enable-executable-dynamic"
@@ -340,10 +342,10 @@ rawCompileSetup verbosity suite e path = do
340342
ghcPackageDBParams (ghcVersion suite) (packageDBStack suite) ++
341343
[ "-hide-all-packages"
342344
, "-package base"
343-
#ifdef CURRENT_PACKAGE_KEY
345+
#ifdef LOCAL_COMPONENT_ID
344346
-- This is best, but we don't necessarily have it
345347
-- if we're bootstrapping with old Cabal.
346-
, "-package-id " ++ CURRENT_PACKAGE_KEY
348+
, "-package-id " ++ LOCAL_COMPONENT_ID
347349
#else
348350
-- This mostly works, UNLESS you've installed a
349351
-- version of Cabal with the SAME version number.
@@ -421,6 +423,17 @@ runExe' exe_name args = do
421423
let exe = dist_dir </> "build" </> exe_name </> exe_name
422424
run Nothing exe args
423425

426+
-- | Run an executable that was installed by cabal. The @exe_name@
427+
-- is precisely the name of the executable.
428+
runInstalledExe :: String -> [String] -> TestM ()
429+
runInstalledExe exe_name args = void (runInstalledExe' exe_name args)
430+
431+
runInstalledExe' :: String -> [String] -> TestM Result
432+
runInstalledExe' exe_name args = do
433+
usr <- prefixDir
434+
let exe = usr </> "bin" </> exe_name
435+
run Nothing exe args
436+
424437
run :: Maybe FilePath -> String -> [String] -> TestM Result
425438
run mb_cwd path args = do
426439
verbosity <- getVerbosity
@@ -480,13 +493,13 @@ requireSuccess r@Result { resultCommand = cmd
480493

481494
record :: Result -> TestM ()
482495
record res = do
483-
build_dir <- distDir
496+
log_dir <- topDir
484497
(suite, _) <- ask
485-
liftIO $ createDirectoryIfMissing True build_dir
486-
liftIO $ C.appendFile (build_dir </> "test.log")
498+
liftIO $ createDirectoryIfMissing True log_dir
499+
liftIO $ C.appendFile (log_dir </> "test.log")
487500
(C.pack $ "+ " ++ resultCommand res ++ "\n"
488501
++ resultOutput res ++ "\n\n")
489-
let test_sh = build_dir </> "test.sh"
502+
let test_sh = log_dir </> "test.sh"
490503
b <- liftIO $ doesFileExist test_sh
491504
when (not b) . liftIO $ do
492505
-- This is hella racey but this is not that security important

Cabal/tests/PackageTests/Tests.hs

Lines changed: 80 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,14 @@ import qualified PackageTests.TestStanza.Check
77
import qualified PackageTests.DeterministicAr.Check
88
import qualified PackageTests.TestSuiteTests.ExeV10.Check
99

10+
import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(localPkgDescr, compiler), absoluteInstallDirs, InstallDirs(libdir), maybeGetComponentLocalBuildInfo, ComponentLocalBuildInfo(componentId), ComponentName(CLibName))
11+
import Distribution.Simple.InstallDirs (CopyDest(NoCopyDest))
12+
import Distribution.Simple.BuildPaths (mkLibName, mkSharedLibName)
13+
import Distribution.Simple.Compiler (compilerId)
14+
1015
import Control.Monad
1116

17+
import System.Directory
1218
import Data.Version
1319
import Test.Tasty (TestTree, testGroup, mkTimeout, localOption)
1420
import Test.Tasty.HUnit (testCase)
@@ -42,17 +48,12 @@ tests config =
4248

4349
-- Test detailed-0.9 test suites
4450
, testGroup "LibV09" $
45-
let
46-
tcs :: FilePath -> TestM a -> TestTree
47-
tcs name m
48-
= testCase name (runTestM config ("TestSuiteTests/LibV09")
49-
(Just name) m)
50-
in -- Test if detailed-0.9 builds correctly
51-
[ tcs "Build" $ cabal_build ["--enable-tests"]
51+
-- Test if detailed-0.9 builds correctly
52+
[ tcs "" "Build" $ cabal_build ["--enable-tests"]
5253

5354
-- Tests for #2489, stdio deadlock
5455
, localOption (mkTimeout $ 10 ^ (8 :: Int))
55-
. tcs "Deadlock" $ do
56+
. tcs "" "Deadlock" $ do
5657
cabal_build ["--enable-tests"]
5758
shouldFail $ cabal "test" []
5859
]
@@ -207,6 +208,8 @@ tests config =
207208
assertFailure $ "cabal has not calculated different Installed " ++
208209
"package ID when source is changed."
209210

211+
-- Test that if two components have the same module name, they do not
212+
-- clobber each other.
210213
, tc "DuplicateModuleName" $ do
211214
cabal_build ["--enable-tests"]
212215
r1 <- shouldFail $ cabal' "test" ["foo"]
@@ -216,21 +219,54 @@ tests config =
216219
assertOutputContains "test C" r2
217220
assertOutputContains "test A" r2
218221

222+
-- Test that if test suite has a name which conflicts with a package
223+
-- which is in the database, we can still use the test case (they
224+
-- should NOT shadow).
219225
, tc "TestNameCollision" $ do
220226
withPackageDb $ do
221227
withPackage "parent" $ cabal_install []
222228
withPackage "child" $ do
223229
cabal_build ["--enable-tests"]
224230
cabal "test" []
225231

226-
, tc "MultipleLibraries" $ do
232+
-- Basic test for internal libraries (in p); package q is to make
233+
-- sure that the internal library correctly is used, not the
234+
-- external library.
235+
, tc "InternalLibraries" $ do
227236
withPackageDb $ do
228237
withPackage "q" $ cabal_install []
229238
withPackage "p" $ do
230239
cabal_install []
231-
r <- runExe' "foo" []
240+
cabal "clean" []
241+
r <- runInstalledExe' "foo" []
232242
assertOutputContains "I AM THE ONE" r
233243

244+
-- Internal libraries used by a statically linked executable:
245+
-- no libraries should get installed or registered.
246+
, tcs "InternalLibraries/Executable" "Static" $ multiple_libraries_executable False
247+
248+
-- Internal libraries used by a dynamically linked executable:
249+
-- ONLY the dynamic library should be installed, no registration
250+
, tcs "InternalLibraries/Executable" "Dynamic" $ multiple_libraries_executable True
251+
252+
-- Internal library used by public library; it must be installed and
253+
-- registered.
254+
, tc "InternalLibraries/Library" $ do
255+
withPackageDb $ do
256+
withPackage "foolib" $ cabal_install []
257+
withPackage "fooexe" $ do
258+
cabal_build []
259+
runExe' "fooexe" []
260+
>>= assertOutputContains "25"
261+
262+
-- Test to ensure that cabal_macros.h are computed per-component.
263+
, tc "Macros" $ do
264+
cabal_build []
265+
runExe' "macros-a" []
266+
>>= assertOutputContains "macros-a.exe"
267+
runExe' "macros-b" []
268+
>>= assertOutputContains "macros-b.exe"
269+
234270
]
235271
where
236272
-- Shared test function for BuildDeps/InternalLibrary* tests.
@@ -243,6 +279,40 @@ tests config =
243279
("myLibFunc " ++ expect)
244280
(concat $ lines (resultOutput r))
245281

282+
multiple_libraries_executable is_dynamic =
283+
withPackageDb $ do
284+
cabal_install $ [ if is_dynamic then "--enable-executable-dynamic"
285+
else "--disable-executable-dynamic"
286+
, "--enable-shared"]
287+
dist_dir <- distDir
288+
lbi <- liftIO $ getPersistBuildConfig dist_dir
289+
let pkg_descr = localPkgDescr lbi
290+
compiler_id = compilerId (compiler lbi)
291+
cname = (CLibName "foo-internal")
292+
Just clbi = maybeGetComponentLocalBuildInfo lbi cname
293+
cid = componentId clbi
294+
dir = libdir (absoluteInstallDirs pkg_descr lbi cid NoCopyDest)
295+
assertBool "interface files should NOT be installed" . not
296+
=<< liftIO (doesFileExist (dir </> "Foo.hi"))
297+
assertBool "static library should NOT be installed" . not
298+
=<< liftIO (doesFileExist (dir </> mkLibName cid))
299+
if is_dynamic
300+
then
301+
assertBool "dynamic library MUST be installed"
302+
=<< liftIO (doesFileExist (dir </> mkSharedLibName compiler_id cid))
303+
else
304+
assertBool "dynamic library should NOT be installed" . not
305+
=<< liftIO (doesFileExist (dir </> mkSharedLibName compiler_id cid))
306+
shouldFail $ ghcPkg "describe" ["foo"]
307+
-- clean away the dist directory so that we catch accidental
308+
-- dependence on the inplace files
309+
cabal "clean" []
310+
runInstalledExe' "foo" [] >>= assertOutputContains "46"
311+
246312
tc :: FilePath -> TestM a -> TestTree
247313
tc name m
248314
= testCase name (runTestM config name Nothing m)
315+
316+
tcs :: FilePath -> FilePath -> TestM a -> TestTree
317+
tcs name sub_name m
318+
= testCase (name </> sub_name) (runTestM config name (Just sub_name) m)

0 commit comments

Comments
 (0)