Skip to content

Commit

Permalink
Introduce unit tests that illustrate the problem
Browse files Browse the repository at this point in the history
In #3170 we introduced a cycle check to the solver. This check is necessary to
reject cycling solutions (which would previously have resulted in an internal
error when we verify the install plan). However, this by itself is not
sufficient. If we have a cycle through setup dependencies, the solver loops
because it starts building an infinite tree. This is explained in detail in

In this commit we just add some unit tests that provide a minimal example that
exposes the bug.
  • Loading branch information
edsko authored and dcoutts committed Mar 13, 2016
1 parent 8581bdd commit 98ab6e0
Showing 1 changed file with 31 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,14 @@ tests = [
, runTest $ mkTest db12 "baseShim6" ["E"] (Just [("E", 1), ("syb", 2)])
]
, testGroup "Cycles" [
runTest $ mkTest db14 "simpleCycle1" ["A"] Nothing
, runTest $ mkTest db14 "simpleCycle2" ["A", "B"] Nothing
, runTest $ mkTest db14 "cycleWithFlagChoice1" ["C"] (Just [("C", 1), ("E", 1)])
runTest $ mkTest db14 "simpleCycle1" ["A"] Nothing
, runTest $ mkTest db14 "simpleCycle2" ["A", "B"] Nothing
, runTest $ mkTest db14 "cycleWithFlagChoice1" ["C"] (Just [("C", 1), ("E", 1)])
, runTest $ mkTest db15 "cycleThroughSetupDep1" ["A"] Nothing
, runTest $ mkTest db15 "cycleThroughSetupDep2" ["B"] Nothing
-- , runTest $ mkTest db15 "cycleThroughSetupDep3" ["C"] Nothing -- TODO
-- , runTest $ mkTest db15 "cycleThroughSetupDep4" ["D"] Nothing -- TODO
, runTest $ mkTest db15 "cycleThroughSetupDep5" ["E"] (Just [("C", 2), ("D", 1), ("E", 1)])
]
, testGroup "Extensions" [
runTest $ mkTestExts [EnableExtension CPP] dbExts1 "unsupported" ["A"] Nothing
Expand Down Expand Up @@ -442,6 +447,29 @@ db14 = [
, Right $ exAv "E" 1 []
]

-- | Cycles through setup dependencies
--
-- The first cycle is unsolvable: package A has a setup dependency on B,
-- B has a regular dependency on A, and we only have a single version available
-- for both.
--
-- The second cycle can be broken by picking different versions: package C-2.0
-- has a setup dependency on D, and D has a regular dependency on C-*. However,
-- version C-1.0 is already available (perhaps it didn't have this setup dep).
-- Thus, we should be able to break this cycle even if we are installing package
-- E, which explictly depends on C-2.0.
db15 :: ExampleDb
db15 = [
-- First example (real cycle, no solution)
Right $ exAv "A" 1 [] `withSetupDeps` [ExAny "B"]
, Right $ exAv "B" 1 [ExAny "A"]
-- Second example (cycle can be broken by picking versions carefully)
, Left $ exInst "C" 1 "C-1-inst" []
, Right $ exAv "C" 2 [] `withSetupDeps` [ExAny "D"]
, Right $ exAv "D" 1 [ExAny "C" ]
, Right $ exAv "E" 1 [ExFix "C" 2]
]

dbExts1 :: ExampleDb
dbExts1 = [
Right $ exAv "A" 1 [ExExt (EnableExtension RankNTypes)]
Expand Down

0 comments on commit 98ab6e0

Please sign in to comment.