Skip to content

Commit 15e7de4

Browse files
committed
Test case for issue #2899.
1 parent e64f21f commit 15e7de4

File tree

1 file changed

+36
-0
lines changed
  • cabal-install/tests/UnitTests/Distribution/Solver/Modular

1 file changed

+36
-0
lines changed

cabal-install/tests/UnitTests/Distribution/Solver/Modular/MemoryUsage.hs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ tests :: [TestTree]
1010
tests = [
1111
runTest $ basicTest "basic space leak test"
1212
, runTest $ flagsTest "package with many flags"
13+
, runTest $ issue2899 "issue #2899"
1314
]
1415

1516
-- | This test solves for n packages that each have two versions. Backjumping
@@ -56,3 +57,38 @@ flagsTest name =
5657

5758
orderedFlags :: [ExampleVar]
5859
orderedFlags = [F None "pkg" (flagName i) | i <- [1..n]]
60+
61+
-- | Test for a space leak caused by sharing of search trees under packages with
62+
-- link choices (issue #2899).
63+
--
64+
-- The goal order is fixed so that the solver chooses setup-dep and then
65+
-- target-setup.setup-dep at the top of the search tree. target-setup.setup-dep
66+
-- has two choices: link to setup-dep, and don't link to setup-dep. setup-dep
67+
-- has a long chain of dependencies (pkg-1 through pkg-n). However, pkg-n
68+
-- depends on pkg-n+1, which doesn't exist, so there is no solution. Since each
69+
-- dependency has two versions, the solver must try 2^n combinations when
70+
-- backjumping is disabled. These combinations create large search trees under
71+
-- each of the two choices for target-setup.setup-dep. Although the choice to
72+
-- not link is disallowed by the Single Instance Restriction, the solver doesn't
73+
-- know that until it has explored (and evaluated) the whole tree under the
74+
-- choice to link. If the two trees are shared, memory usage spikes.
75+
issue2899 :: String -> SolverTest
76+
issue2899 name =
77+
disableBackjumping $
78+
goalOrder goals $ mkTest pkgs name ["target"] anySolverFailure
79+
where
80+
n :: Int
81+
n = 16
82+
83+
pkgs :: ExampleDb
84+
pkgs = map Right $
85+
[ exAv "target" 1 [ExAny "setup-dep"] `withSetupDeps` [ExAny "setup-dep"]
86+
, exAv "setup-dep" 1 [ExAny $ pkgName 1]]
87+
++ [ exAv (pkgName i) v [ExAny $ pkgName (i + 1)]
88+
| i <- [1..n], v <- [1, 2]]
89+
90+
pkgName :: Int -> ExamplePkgName
91+
pkgName x = "pkg-" ++ show x
92+
93+
goals :: [ExampleVar]
94+
goals = [P None "setup-dep", P (Setup "target") "setup-dep"]

0 commit comments

Comments
 (0)