Tests.hs 15.2 KB
Newer Older
1
module PackageTests.Tests(tests) where
2
3
4
5
6
7
8
9

import PackageTests.PackageTester

import qualified PackageTests.BenchmarkStanza.Check
import qualified PackageTests.TestStanza.Check
import qualified PackageTests.DeterministicAr.Check
import qualified PackageTests.TestSuiteTests.ExeV10.Check

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

15
16
import Control.Monad

17
import System.Directory
18
import Data.Version
19
import Test.Tasty (mkTimeout, localOption)
20

21
22
tests :: SuiteConfig -> TestTreeM ()
tests config = do
23
24
25
26
27

  ---------------------------------------------------------------------
  -- * External tests

  -- Test that Cabal parses 'benchmark' sections correctly
28
  tc "BenchmarkStanza"  PackageTests.BenchmarkStanza.Check.suite
29
30

  -- Test that Cabal parses 'test' sections correctly
31
  tc "TestStanza"       PackageTests.TestStanza.Check.suite
32
33

  -- Test that Cabal determinstically generates object archives
34
  tc "DeterministicAr"  PackageTests.DeterministicAr.Check.suite
35
36
37
38

  ---------------------------------------------------------------------
  -- * Test suite tests

39
  groupTests "TestSuiteTests/ExeV10" $
40
      (PackageTests.TestSuiteTests.ExeV10.Check.tests config)
41

42
43
44
45
46
47
48
49
  -- Test if detailed-0.9 builds correctly
  tcs "TestSuiteTests/LibV09" "Build" $ cabal_build ["--enable-tests"]

  -- Tests for #2489, stdio deadlock
  mapTestTrees (localOption (mkTimeout $ 10 ^ (8 :: Int)))
   . tcs "TestSuiteTests/LibV09" "Deadlock" $ do
      cabal_build ["--enable-tests"]
      shouldFail $ cabal "test" []
50
51
52
53
54

  ---------------------------------------------------------------------
  -- * Inline tests

  -- Test if exitcode-stdio-1.0 benchmark builds correctly
55
  tc "BenchmarkExeV10" $ cabal_build ["--enable-benchmarks"]
56
57

  -- Test --benchmark-option(s) flags on ./Setup bench
58
  tc "BenchmarkOptions" $ do
59
60
61
62
63
64
65
66
      cabal_build ["--enable-benchmarks"]
      cabal "bench" [ "--benchmark-options=1 2 3" ]
      cabal "bench" [ "--benchmark-option=1"
                    , "--benchmark-option=2"
                    , "--benchmark-option=3"
                    ]

  -- Test --test-option(s) flags on ./Setup test
67
  tc "TestOptions" $ do
68
69
70
71
72
73
74
75
76
      cabal_build ["--enable-tests"]
      cabal "test" ["--test-options=1 2 3"]
      cabal "test" [ "--test-option=1"
                   , "--test-option=2"
                   , "--test-option=3"
                   ]

  -- Test attempt to have executable depend on internal
  -- library, but cabal-version is too old.
77
  tc "BuildDeps/InternalLibrary0" $ do
78
      r <- shouldFail $ cabal' "configure" []
79
80
81
82
83
      -- Should tell you how to enable the desired behavior
      let sb = "library which is defined within the same package."
      assertOutputContains sb r

  -- Test executable depends on internal library.
84
  tc "BuildDeps/InternalLibrary1" $ cabal_build []
85
86
87

  -- Test that internal library is preferred to an installed on
  -- with the same name and version
88
  tc "BuildDeps/InternalLibrary2" $ internal_lib_test "internal"
89
90
91

  -- Test that internal library is preferred to an installed on
  -- with the same name and LATER version
92
  tc "BuildDeps/InternalLibrary3" $ internal_lib_test "internal"
93
94
95

  -- Test that an explicit dependency constraint which doesn't
  -- match the internal library causes us to use external library
96
  tc "BuildDeps/InternalLibrary4" $ internal_lib_test "installed"
97
98
99
100

  -- Test "old build-dep behavior", where we should get the
  -- same package dependencies on all targets if cabal-version
  -- is sufficiently old.
101
  tc "BuildDeps/SameDepsAllRound" $ cabal_build []
102
103
104
105

  -- Test "new build-dep behavior", where each target gets
  -- separate dependencies.  This tests that an executable
  -- dep does not leak into the library.
106
  tc "BuildDeps/TargetSpecificDeps1" $ do
107
      cabal "configure" []
108
      r <- shouldFail $ cabal' "build" []
109
110
111
      assertRegex "error should be in MyLibrary.hs" "^MyLibrary.hs:" r
      assertRegex
        "error should be \"Could not find module `Text\\.PrettyPrint\""
112
        "(Could not find module|Failed to load interface for).*Text\\.PrettyPrint" r
113
114
115

  -- This is a control on TargetSpecificDeps1; it should
  -- succeed.
116
  tc "BuildDeps/TargetSpecificDeps2" $ cabal_build []
117
118
119
120

  -- Test "new build-dep behavior", where each target gets
  -- separate dependencies.  This tests that an library
  -- dep does not leak into the executable.
121
  tc "BuildDeps/TargetSpecificDeps3" $ do
122
      cabal "configure" []
123
      r <- shouldFail $ cabal' "build" []
124
125
126
      assertRegex "error should be in lemon.hs" "^lemon.hs:" r
      assertRegex
        "error should be \"Could not find module `Text\\.PrettyPrint\""
127
        "(Could not find module|Failed to load interface for).*Text\\.PrettyPrint" r
128
129

  -- Test that Paths module is generated and available for executables.
130
  tc "PathsModule/Executable" $ cabal_build []
131
132

  -- Test that Paths module is generated and available for libraries.
133
  tc "PathsModule/Library" $ cabal_build []
134
135

  -- Check that preprocessors (hsc2hs) are run
136
  tc "PreProcess" $ cabal_build ["--enable-tests", "--enable-benchmarks"]
137
138

  -- Check that preprocessors that generate extra C sources are handled
Mikhail Glushenkov's avatar
Mikhail Glushenkov committed
139
140
  tc "PreProcessExtraSources" $ cabal_build ["--enable-tests",
                                             "--enable-benchmarks"]
141
142

  -- Test building a vanilla library/executable which uses Template Haskell
143
  tc "TemplateHaskell/vanilla" $ cabal_build []
144
145
146

  -- Test building a profiled library/executable which uses Template Haskell
  -- (Cabal has to build the non-profiled version first)
Mikhail Glushenkov's avatar
Mikhail Glushenkov committed
147
148
  tc "TemplateHaskell/profiling" $ cabal_build ["--enable-library-profiling",
                                                "--enable-profiling"]
149

150
151
  -- Test building a dynamic library/executable which uses Template
  -- Haskell
152
  testWhen (hasSharedLibraries config) $
Mikhail Glushenkov's avatar
Mikhail Glushenkov committed
153
154
    tc "TemplateHaskell/dynamic" $ cabal_build ["--enable-shared",
                                                "--enable-executable-dynamic"]
155

156
157
  -- Test building an executable whose main() function is defined in a C
  -- file
158
  tc "CMain" $ cabal_build []
159
160

  -- Test build when the library is empty, for #1241
161
  tc "EmptyLib" $
162
163
164
      withPackage "empty" $ cabal_build []

  -- Test that "./Setup haddock" works correctly
165
  tc "Haddock" $ do
166
167
168
169
170
171
172
173
174
      dist_dir <- distDir
      let haddocksDir = dist_dir </> "doc" </> "html" </> "Haddock"
      cabal "configure" []
      cabal "haddock" []
      let docFiles
              = map (haddocksDir </>)
                    ["CPP.html", "Literate.html", "NoCPP.html", "Simple.html"]
      mapM_ (assertFindInFile "For hiding needles.") docFiles

Edward Z. Yang's avatar
Edward Z. Yang committed
175
  -- Test that Haddock with a newline in synopsis works correctly, #3004
176
  tc "HaddockNewline" $ do
Edward Z. Yang's avatar
Edward Z. Yang committed
177
178
179
        cabal "configure" []
        cabal "haddock" []

180
181
  -- Test that Cabal properly orders GHC flags passed to GHC (when
  -- there are multiple ghc-options fields.)
182
  tc "OrderFlags" $ cabal_build []
183
184
185

  -- Test that reexported modules build correctly
  -- TODO: should also test that they import OK!
186
  tc "ReexportedModules" $ do
187
188
189
      whenGhcVersion (>= Version [7,9] []) $ cabal_build []

  -- Test that Cabal computes different IPIDs when the source changes.
190
  tc "UniqueIPID" . withPackageDb $ do
191
192
193
194
      withPackage "P1" $ cabal "configure" []
      withPackage "P2" $ cabal "configure" []
      withPackage "P1" $ cabal "build" []
      withPackage "P1" $ cabal "build" [] -- rebuild should work
195
      r1 <- withPackage "P1" $ cabal' "register" ["--print-ipid", "--inplace"]
196
      withPackage "P2" $ cabal "build" []
197
      r2 <- withPackage "P2" $ cabal' "register" ["--print-ipid", "--inplace"]
198
199
200
201
202
203
      let exIPID s = takeWhile (/= '\n') $
               head . filter (isPrefixOf $ "UniqueIPID-0.1-") $ (tails s)
      when ((exIPID $ resultOutput r1) == (exIPID $ resultOutput r2)) $
        assertFailure $ "cabal has not calculated different Installed " ++
          "package ID when source is changed."

204
205
  -- Test that if two components have the same module name, they do not
  -- clobber each other.
206
  tc "DuplicateModuleName" $ do
207
208
209
210
211
212
213
214
      cabal_build ["--enable-tests"]
      r1 <- shouldFail $ cabal' "test" ["foo"]
      assertOutputContains "test B" r1
      assertOutputContains "test A" r1
      r2 <- shouldFail $ cabal' "test" ["foo2"]
      assertOutputContains "test C" r2
      assertOutputContains "test A" r2

215
216
217
  -- Test that if test suite has a name which conflicts with a package
  -- which is in the database, we can still use the test case (they
  -- should NOT shadow).
218
  tc "TestNameCollision" $ do
219
220
221
222
223
224
        withPackageDb $ do
          withPackage "parent" $ cabal_install []
          withPackage "child" $ do
            cabal_build ["--enable-tests"]
            cabal "test" []

Mikhail Glushenkov's avatar
Mikhail Glushenkov committed
225
  -- Test that '--allow-newer' works via the 'Setup.hs configure' interface.
226
  tc "AllowNewer" $ do
Mikhail Glushenkov's avatar
Mikhail Glushenkov committed
227
228
229
230
        shouldFail $ cabal "configure" []
        cabal "configure" ["--allow-newer"]
        shouldFail $ cabal "configure" ["--allow-newer=baz,quux"]
        cabal "configure" ["--allow-newer=base", "--allow-newer=baz,quux"]
231
232
        cabal "configure" ["--allow-newer=bar", "--allow-newer=base,baz"
                          ,"--allow-newer=quux"]
Mikhail Glushenkov's avatar
Mikhail Glushenkov committed
233
234
235
236
237
238
239
        shouldFail $ cabal "configure" ["--enable-tests"]
        cabal "configure" ["--enable-tests", "--allow-newer"]
        shouldFail $ cabal "configure" ["--enable-benchmarks"]
        cabal "configure" ["--enable-benchmarks", "--allow-newer"]
        shouldFail $ cabal "configure" ["--enable-benchmarks", "--enable-tests"]
        cabal "configure" ["--enable-benchmarks", "--enable-tests"
                          ,"--allow-newer"]
240
241
242
243
244
245
246
247
248
        shouldFail $ cabal "configure" ["--allow-newer=Foo:base"]
        shouldFail $ cabal "configure" ["--allow-newer=Foo:base"
                                       ,"--enable-tests", "--enable-benchmarks"]
        cabal "configure" ["--allow-newer=AllowNewer:base"]
        cabal "configure" ["--allow-newer=AllowNewer:base"
                          ,"--allow-newer=Foo:base"]
        cabal "configure" ["--allow-newer=AllowNewer:base"
                          ,"--allow-newer=Foo:base"
                          ,"--enable-tests", "--enable-benchmarks"]
Mikhail Glushenkov's avatar
Mikhail Glushenkov committed
249

250
251
252
  -- Test that Cabal can choose flags to disable building a component when that
  -- component's dependencies are unavailable. The build should succeed without
  -- requiring the component's dependencies or imports.
253
254
255
256
  tc "BuildableField" $ do
      r <- cabal' "configure" ["-v"]
      assertOutputContains "Flags chosen: build-exe=False" r
      cabal "build" []
257

258
259
260
261
262
  -- TODO: Enable these tests on Windows
  unlessWindows $ do
      tc "GhcPkgGuess/SameDirectory" $ ghc_pkg_guess "ghc"
      tc "GhcPkgGuess/SameDirectoryVersion" $ ghc_pkg_guess "ghc-7.10"
      tc "GhcPkgGuess/SameDirectoryGhcVersion" $ ghc_pkg_guess "ghc-7.10"
263

264
265
266
267
  unlessWindows $ do
      tc "GhcPkgGuess/Symlink" $ ghc_pkg_guess "ghc"
      tc "GhcPkgGuess/SymlinkVersion" $ ghc_pkg_guess "ghc"
      tc "GhcPkgGuess/SymlinkGhcVersion" $ ghc_pkg_guess "ghc"
268

269
270
271
272
  -- Basic test for internal libraries (in p); package q is to make
  -- sure that the internal library correctly is used, not the
  -- external library.
  tc "InternalLibraries" $ do
273
274
275
276
      withPackageDb $ do
          withPackage "q" $ cabal_install []
          withPackage "p" $ do
              cabal_install []
277
278
              cabal "clean" []
              r <- runInstalledExe' "foo" []
279
280
              assertOutputContains "I AM THE ONE" r

281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
  -- Internal libraries used by a statically linked executable:
  -- no libraries should get installed or registered.
  tcs "InternalLibraries/Executable" "Static" $ multiple_libraries_executable False

  -- Internal libraries used by a dynamically linked executable:
  -- ONLY the dynamic library should be installed, no registration
  tcs "InternalLibraries/Executable" "Dynamic" $ multiple_libraries_executable True

  -- Internal library used by public library; it must be installed and
  -- registered.
  tc "InternalLibraries/Library" $ do
      withPackageDb $ do
          withPackage "foolib" $ cabal_install []
          withPackage "fooexe" $ do
              cabal_build []
              runExe' "fooexe" []
                  >>= assertOutputContains "25"

  -- Test to ensure that cabal_macros.h are computed per-component.
  tc "Macros" $ do
      cabal_build []
      runExe' "macros-a" []
          >>= assertOutputContains "macros-a.exe"
      runExe' "macros-b" []
          >>= assertOutputContains "macros-b.exe"

307
  where
308
309
310
311
312
313
314
315
    ghc_pkg_guess bin_name = do
        cwd <- packageDir
        with_ghc <- getWithGhcPath
        r <- withEnv [("WITH_GHC", Just with_ghc)]
           . shouldFail $ cabal' "configure" ["-w", cwd </> bin_name]
        assertOutputContains "is version 9999999" r
        return ()

316
317
318
319
    -- Shared test function for BuildDeps/InternalLibrary* tests.
    internal_lib_test expect = withPackageDb $ do
        withPackage "to-install" $ cabal_install []
        cabal_build []
320
        r <- runExe' "lemon" []
321
322
        assertEqual
            ("executable should have linked with the " ++ expect ++ " library")
323
324
            ("foo foo myLibFunc " ++ expect)
            (concatOutput (resultOutput r))
325

326
327
328
329
330
    assertRegex :: String -> String -> Result -> TestM ()
    assertRegex msg regex r = let out = resultOutput r
                              in assertBool (msg ++ ",\nactual output:\n" ++ out)
                                 (out =~ regex)

331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
    multiple_libraries_executable is_dynamic =
        withPackageDb $ do
            cabal_install $ [ if is_dynamic then "--enable-executable-dynamic"
                                            else "--disable-executable-dynamic"
                            , "--enable-shared"]
            dist_dir <- distDir
            lbi <- liftIO $ getPersistBuildConfig dist_dir
            let pkg_descr = localPkgDescr lbi
                compiler_id = compilerId (compiler lbi)
                cname = (CLibName "foo-internal")
                Just clbi = maybeGetComponentLocalBuildInfo lbi cname
                uid = componentUnitId clbi
                dir = libdir (absoluteInstallDirs pkg_descr lbi uid NoCopyDest)
            assertBool "interface files should NOT be installed" . not
                =<< liftIO (doesFileExist (dir </> "Foo.hi"))
            assertBool "static library should NOT be installed" . not
                =<< liftIO (doesFileExist (dir </> mkLibName uid))
            if is_dynamic
              then
                assertBool "dynamic library MUST be installed"
                    =<< liftIO (doesFileExist (dir </> mkSharedLibName compiler_id uid))
              else
                assertBool "dynamic library should NOT be installed" . not
                    =<< liftIO (doesFileExist (dir </> mkSharedLibName compiler_id uid))
            shouldFail $ ghcPkg "describe" ["foo"]
            -- clean away the dist directory so that we catch accidental
            -- dependence on the inplace files
            cabal "clean" []
            runInstalledExe' "foo" [] >>= assertOutputContains "46"

361
    tc :: FilePath -> TestM a -> TestTreeM ()
362
363
364
365
366
    tc name = testTree config name

    tcs :: FilePath -> FilePath -> TestM a -> TestTreeM ()
    tcs name sub_name m
        = testTreeSub config name sub_name m