Skip to content

Commit 78fbe09

Browse files
authored
Merge pull request #7397 from Mikolaj/master
Add regression test for #5782, which requires extending test harness to v2-install
2 parents ac5cb4c + 576d7ca commit 78fbe09

File tree

8 files changed

+118
-9
lines changed

8 files changed

+118
-9
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# issue5782 E
2+
"AAA"
3+
# issue5782 E
4+
"BBB"
5+
# issue5782 E
6+
"CCC"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
packages: issue5782
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
-- When Module.f is changed, with cabal <= 3.2 this non-deterministically fails
2+
-- to compile and, if it doesn't fail, it also non-deterministically gives
3+
-- a wrong answer (ignoring the change to Module.f in the output, despite
4+
-- recompiling, so probably the wrong library is linked in); when running
5+
-- manually on my machine, three changes to Module.hs are enough to trigger
6+
-- the error, often two are enough, even with cabal 3.2, even to get
7+
-- compilation error
8+
-- "Ambiguous module name `Module': it was found in multiple packages: issue5782-0.1 issue5782-0.1"
9+
-- not only the wrong result from exe run.
10+
--
11+
-- The dummy "--installdir=." is needed for cabal <= 3.2
12+
-- and also to match cabal output on different OSes
13+
-- (default installdir is different on various OSes).
14+
--
15+
-- `withShorterPathForNewBuildStore` is needed to avoid some path mismatches, etc.,
16+
-- in the output, but MacOS still insists on processing internal libraries
17+
-- in a different order and Windows additionally still can't recognize
18+
-- the paths match. Hence `recordMode DoNotRecord` to mute the output,
19+
-- which is fine in this case, because the problem manifests either
20+
-- as failed compilation or wrong exe output, which I do check.
21+
22+
import Test.Cabal.Prelude
23+
main = withShorterPathForNewBuildStore $ \storeDir ->
24+
cabalTest $
25+
withSourceCopy . withDelay $ do
26+
writeSourceFile "issue5782/src/Module.hs" "module Module where\nf = \"AAA\""
27+
recordMode DoNotRecord $
28+
cabalG ["--store-dir=" ++ storeDir, "--installdir=" ++ storeDir, "--overwrite-policy=always"] "v2-install" ["issue5782"]
29+
withPlan $
30+
runPlanExe' "issue5782" "E" []
31+
>>= assertOutputContains "AAA"
32+
delay
33+
writeSourceFile "issue5782/src/Module.hs" "module Module where\nf = \"BBB\""
34+
recordMode DoNotRecord $
35+
cabalG ["--store-dir=" ++ storeDir, "--installdir=" ++ storeDir, "--overwrite-policy=always"] "v2-install" ["issue5782"]
36+
withPlan $
37+
runPlanExe' "issue5782" "E" []
38+
>>= assertOutputContains "BBB"
39+
writeSourceFile "issue5782/src/Module.hs" "module Module where\nf = \"CCC\""
40+
delay -- different spot to try another scenario
41+
recordMode DoNotRecord $
42+
cabalG ["--store-dir=" ++ storeDir, "--installdir=" ++ storeDir, "--overwrite-policy=always"] "v2-install" ["issue5782"]
43+
withPlan $
44+
runPlanExe' "issue5782" "E" []
45+
>>= assertOutputContains "CCC"
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import Module
2+
3+
main = print f
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
cabal-version: 2.2
2+
3+
name: issue5782
4+
version: 0.1
5+
build-type: Simple
6+
7+
library a
8+
hs-source-dirs: src
9+
exposed-modules: Module
10+
build-depends: base
11+
default-language: Haskell2010
12+
13+
library
14+
hs-source-dirs: src2
15+
build-depends: a, base
16+
default-language: Haskell2010
17+
reexported-modules: Module
18+
19+
library b
20+
hs-source-dirs: src2
21+
build-depends: a, base
22+
default-language: Haskell2010
23+
reexported-modules: Module
24+
25+
executable E
26+
main-is: Main.hs
27+
build-depends: issue5782, b, base
28+
default-language: Haskell2010

cabal-testsuite/PackageTests/Regression/T5782Diamond/issue5782/src/.gitkeep

Whitespace-only changes.

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

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
-- | Utilities for understanding @plan.json@.
44
module Test.Cabal.Plan (
55
Plan,
6+
DistDirOrBinFile(..),
67
planDistDir,
78
) where
89

@@ -20,7 +21,7 @@ data Plan = Plan { planInstallPlan :: [InstallItem] }
2021

2122
data InstallItem
2223
= APreExisting
23-
| AConfiguredGlobal
24+
| AConfiguredGlobal ConfiguredGlobal
2425
| AConfiguredInplace ConfiguredInplace
2526

2627
-- local or inplace package
@@ -29,6 +30,11 @@ data ConfiguredInplace = ConfiguredInplace
2930
, configuredInplacePackageName :: PackageName
3031
, configuredInplaceComponentName :: Maybe ComponentName }
3132

33+
data ConfiguredGlobal = ConfiguredGlobal
34+
{ configuredGlobalBinFile :: Maybe FilePath
35+
, configuredGlobalPackageName :: PackageName
36+
, configuredGlobalComponentName :: Maybe ComponentName }
37+
3238
instance FromJSON Plan where
3339
parseJSON (Object v) = fmap Plan (v .: "install-plan")
3440
parseJSON invalid = typeMismatch "Plan" invalid
@@ -41,7 +47,7 @@ instance FromJSON InstallItem where
4147
"configured" -> do
4248
s <- v .: "style"
4349
case s :: String of
44-
"global" -> return AConfiguredGlobal
50+
"global" -> AConfiguredGlobal `fmap` parseJSON obj
4551
"inplace" -> AConfiguredInplace `fmap` parseJSON obj
4652
"local" -> AConfiguredInplace `fmap` parseJSON obj
4753
_ -> fail $ "unrecognized value of 'style' field: " ++ s
@@ -56,6 +62,14 @@ instance FromJSON ConfiguredInplace where
5662
return (ConfiguredInplace dist_dir pkg_name component_name)
5763
parseJSON invalid = typeMismatch "ConfiguredInplace" invalid
5864

65+
instance FromJSON ConfiguredGlobal where
66+
parseJSON (Object v) = do
67+
bin_file <- v .:? "bin-file"
68+
pkg_name <- v .: "pkg-name"
69+
component_name <- v .:? "component-name"
70+
return (ConfiguredGlobal bin_file pkg_name component_name)
71+
parseJSON invalid = typeMismatch "ConfiguredGlobal" invalid
72+
5973
instance FromJSON PackageName where
6074
parseJSON (String t) = return (mkPackageName (Text.unpack t))
6175
parseJSON invalid = typeMismatch "PackageName" invalid
@@ -68,21 +82,30 @@ instance FromJSON ComponentName where
6882
where s = Text.unpack t
6983
parseJSON invalid = typeMismatch "ComponentName" invalid
7084

71-
planDistDir :: Plan -> PackageName -> ComponentName -> FilePath
85+
data DistDirOrBinFile = DistDir FilePath | BinFile FilePath
86+
87+
planDistDir :: Plan -> PackageName -> ComponentName -> DistDirOrBinFile
7288
planDistDir plan pkg_name cname =
7389
case concatMap p (planInstallPlan plan) of
7490
[x] -> x
7591
[] -> error $ "planDistDir: component " ++ prettyShow cname
7692
++ " of package " ++ prettyShow pkg_name ++ " either does not"
77-
++ " exist in the install plan or does not have a dist-dir"
93+
++ " exist in the install plan or does not have a dist-dir nor bin-file"
7894
_ -> error $ "planDistDir: found multiple copies of component " ++ prettyShow cname
7995
++ " of package " ++ prettyShow pkg_name ++ " in install plan"
8096
where
8197
p APreExisting = []
82-
p AConfiguredGlobal = []
98+
p (AConfiguredGlobal conf) = do
99+
guard (configuredGlobalPackageName conf == pkg_name)
100+
guard $ case configuredGlobalComponentName conf of
101+
Nothing -> True
102+
Just cname' -> cname == cname'
103+
case configuredGlobalBinFile conf of
104+
Nothing -> []
105+
Just bin_file -> return $ BinFile bin_file
83106
p (AConfiguredInplace conf) = do
84107
guard (configuredInplacePackageName conf == pkg_name)
85108
guard $ case configuredInplaceComponentName conf of
86109
Nothing -> True
87110
Just cname' -> cname == cname'
88-
return (configuredInplaceDistDir conf)
111+
return $ DistDir $ configuredInplaceDistDir conf

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -335,11 +335,14 @@ runPlanExe' :: String {- package name -} -> String {- component name -}
335335
-> [String] -> TestM Result
336336
runPlanExe' pkg_name cname args = do
337337
Just plan <- testPlan `fmap` getTestEnv
338-
let dist_dir = planDistDir plan (mkPackageName pkg_name)
339-
(CExeName (mkUnqualComponentName cname))
338+
let distDirOrBinFile = planDistDir plan (mkPackageName pkg_name)
339+
(CExeName (mkUnqualComponentName cname))
340+
exePath = case distDirOrBinFile of
341+
DistDir dist_dir -> dist_dir </> "build" </> cname </> cname
342+
BinFile bin_file -> bin_file
340343
defaultRecordMode RecordAll $ do
341344
recordHeader [pkg_name, cname]
342-
runM (dist_dir </> "build" </> cname </> cname) args Nothing
345+
runM exePath args Nothing
343346

344347
------------------------------------------------------------------------
345348
-- * Running ghc-pkg

0 commit comments

Comments
 (0)