-
Notifications
You must be signed in to change notification settings - Fork 695
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow "cycles" through test suite dependencies #3422
base: master
Are you sure you want to change the base?
Conversation
(See #3402 (comment))
@dcoutts Thanks for the explanation. I thought about it some more, and I think that allowing inconsistent versions of the library is fine, since it only affects test suites that would otherwise have cyclic dependencies. I think the problem is that the PR also allows inconsistent versions of the library's dependencies. Here's an example of a package without cyclic dependencies that might be broken by this change. I haven't actually tested it, so I could be wrong. (These aren't real versions)
Say AFAICT, this PR would qualify the test suite dependencies that aren't shared with the library, i.e., it would qualify Forcing both instances of the library (if there's a cycle) to have consistent dependencies would be safer, and I think it would still support the use cases. |
@23Skidoo , @grayjay I took a look at the failing test case. The test in question is we're trying to solve for A and B as independent goals using the DB db17 :: ExampleDb
db17 = [
Right $ exAv "A" 1 [ExAny "C"] `withTest` ExTest "test" [ExFix "D" 1]
, Right $ exAv "B" 1 [ExAny "C"] `withTest` ExTest "test" [ExFix "D" 1]
, Right $ exAv "C" 1 [ExAny "D"]
, Right $ exAv "D" 1 []
, Right $ exAv "D" 2 []
] The idea of the test is that the solver first picks version 2.0 of This the modification in this PR, actually, the constraint on D doesn't apply to 0.D, but is instead applied to 0.A-test.D (or B.A-test.D), and so we will actually simply install two versions of D (one for the test suite and one for the main package). The backtracking behaviour that the tests intended to test for no longer happens: The failures we discover when we explore this tree we find immediately when trying to link, so the test is no longer testing what it was intended for. I'm not entirely sure how to come up with a different test case though; that might not be so simple. Moreover, if @grayjay 's objection above (#3422 (comment)) is implemented, then I think the test will be fixed again. I'm not entirely sure of the implications of @grayjay 's comments, but (/cc also @dcoutts ) it is somewhat strange that if, in this example, |
@23Skidoo , regarding
what needs to happen is that as part of the set of |
@edsko Is there any way to defer introducing the |
@grayjay I like this suggestion. Adding some infrastructure that would enable unit tests to reorder the tree would be very useful, I think. Not exactly sure what shape this should take though. But feel free to propose something :) |
Discussion with @dcoutts : we should only consider the direct dependencies of the library, but all dependencies. That makes more sense to me, but it would be a lot more difficult to do (at the point in the solver where we qualify we might not even know all indirect dependencies yet?). For instance, if the library depends on A, which depends on B, and the test suite depends directly on B, then the two dependencies on B should probably match (but that indirect dependency on B might depend on flag choices..). |
@edsko I'm not sure I understand. Are you suggesting changing the part of the PR that adds the "test" qualifier (https://github.com/haskell/cabal/pull/3422/files#diff-684698b6af4c57398afaa2c1e4194338R283) so that it avoids qualifying all dependencies of the library, instead of just the direct dependencies? |
Of course, this test currently fails.
When a test suite has a dependency which is not shared with the main library, we can consider it independent. This addresses #1575 to some degree. Suppose * optparse-applicative has a test suite that depends on tasty * tasty has a (regular) dependency on optparse-applicative We can resolve this by linking optparse-applicative's test suite against an older version of itself. This only works provided that optparse-applicative's test suite does not declare optparse-applicative as a dependency (and instead just compiles in the modules from the src/ directory or whatever). If the test suite did declare the library as a dependency, then clearly the test suite needs to be built against _this_ version of the library; it would be terribly confusing if the test suite got built against an older version. But if the test suite gets built against the library itself, then if the test suite also needs tasty, we cannot pick two different versions in the same application (yet). In this commit we add the appropriate qualifiers; however, the resulting install plan will now be rejected by the internal validity check. That's next up.
For test suites etc. we might want to allow for inconsistent dependencies. For instance, in the optparse-applicative -> tasty -> optparse-applicative dependency cycle we might want to allow two versions of optparse-applicative in the same executable (one that is the library-under-test and one used internally by tasty).
Details of the test in the README.
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
[ci skip]
@grayjay so if I understand your example and your point correctly, you're saying the property we want to achieve is that all dependencies (direct or indirect) that are shared between a lib/exe and associated test suite / benchmark should be consistent, and that we only allow picking versions of deps independently when they are used only by the test suite / benchmarks and not the main libs/exes in the package. So if I've understood correctly then I think @edsko and I agree. Do you have any suggestion about how we might get the solver to pick such solutions? |
@dcoutts That sounds right. I forgot that this PR also supports choosing different versions of test frameworks for different packages' test suites, so it is important that all of the test-only dependencies are independent from the library. I have an idea, but it's messy, and I don't know if it will work. I'm not very familiar with how cabal currently handles a test's dependency on the library. For a package The idea is that the solver has to solve for the library twice (ignoring cyclic dependencies), once for |
I think this PR is superseded by other work to the solver. Does that sound right? |
The original issue, #1575, isn't fixed yet, though this PR would probably require a lot of work to be merged. There was also discussion of solving cyclic dependencies with a different approach towards the end of #1575 (require the library to have consistent versions, but allow cycles between components). |
Marking this PR as draft 🙂 |
A version of #3232/#3290/#3402 updated to work with
master
. Also moved the branch to the upstream repo so that others can push to it.Current status: