Skip to content
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

Refactor CI avoiding test circular dependencies #227

Merged
merged 2 commits into from
Jul 2, 2020

Conversation

vdukhovni
Copy link
Contributor

Instead of running tests in the parent "bytestring" project, with
circular dependencies from the test frameworks, build and run them in
the child bytestring-tests project, which builds the parent as a
dependency that does not run tests, avoiding all the loops.

This requires cabal-install >= 2.4 with cabal.project doing most of the
heavy lifting.

@vdukhovni
Copy link
Contributor Author

@sjakobi @hvr @cartazio @bgamari @Bodigrim
I believe this is ready and makes testing substantially easier going forward.

@cartazio
Copy link

cartazio commented May 27, 2020 via email

Copy link
Member

@sjakobi sjakobi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the load of questions. This is clearly a good direction, I'm just homing in on the details. :)

Also feel free to ignore what seems to go too far! :)

I haven't actually tried to use this locally yet. Would you consider adding instructions on how to build an run the tests to the readme? I'd definitely give those a spin! :)

tests/bytestring-tests.cabal Show resolved Hide resolved
Comment on lines 8 to 9
package bytesting-tests
tests: True
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not

Suggested change
package bytesting-tests
tests: True
tests: True

?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't want to test any of our dependencies. I am not sure what the scope of that is, it may cover dependencies.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default scope are the packages listed above AFAIK.

cabal.project Show resolved Hide resolved
cabal.project Outdated
@@ -0,0 +1,5 @@
packages: bytestring.cabal
allow-newer: *:bytestring
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Surely there can't be any reverse dependencies of bytestring involved here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When testing with GHC-head, text, et. al. needed for the tests want an older bytestring than the one we're testing, but we want to force them to use the new one.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But this cabal.project doesn't include the tests?!

.travis.yml Outdated Show resolved Hide resolved
.travis.yml Show resolved Hide resolved
.travis.yml Outdated
Comment on lines 39 to 49
- cabal v2-configure; cabal v2-build
- cabal v2-sdist -o .
# Remove to enable build of sdist.
- rm -f cabal.project
- rm -f tests/test-builder.tix
- (cd tests; cabal v2-configure; cabal v2-test)
# "cabal check" disabled due to -O2 warning
- export SRC_TGZ=$(cabal info . | awk '{print $2 ".tar.gz";exit}') ;
cd dist/;
if [ -f "$SRC_TGZ" ]; then
cabal install --force-reinstalls "$SRC_TGZ";
- export SRC=$(cabal info . | awk '{print $2; exit}');
if [ -f "$SRC.tar.gz" ]; then
cabal get "./$SRC.tar.gz";
(cd "$SRC"; cabal install --force-reinstalls .);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you consider simply using https://github.com/haskell-CI/haskell-ci to generate this script?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, that might be tricky…

I can give this a spin once this PR has been merged.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm having a devil of a time getting it to work portably between Cabal 2.4, 3.0 and 3.2, not sure the autogenerated one would fare better.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it to work, but had to resort to v1-install with Cabal 3.x, if you figure out a working, non-deprecated syntax, I'm all ears...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Compatibility issues like that are a haskell-ci specialty. ;)

No worries though. Looks like CI is finally green now!

@@ -0,0 +1,9 @@
packages: bytestring-tests.cabal
../bytestring.cabal
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why include the bytestring package here? Doesn't this cause test dependencies to be recompiled after changes to bytestring code?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC the test frameworks and text need to use the same version of ByteString as being tested. We compiling the tests with code that also uses Text, which uses ByteString, ... that cyclic thing. But here we're build the test module, and bytestring is just one of the dependencies to build along with the others.

Give it a try:

cd tests
cabal configure
cabal test

then tweak cabal.project and try again...

@sjakobi
Copy link
Member

sjakobi commented May 28, 2020

Many thanks for responding to my comments above, @vdukhovni! I have, in turn, tried to respond to your responses, but I don't have the necessary permissions to "unresolve" discussions. Would you mind unresolving these things for me?

Alternatively, maybe @hvr or @cartazio could give me the necessary permissions. That would be greatly appreciated! :)

@vdukhovni
Copy link
Contributor Author

I've unresolved all the previous comments, which I marked "resolved" primarily so I could see what I had not yet addressed, otherwise hard to find... Sorry...

@sjakobi
Copy link
Member

sjakobi commented May 29, 2020

I just gave this PR as spin on my local machine. The issue that I believe we're close to eliminating now is that after any change to the bytestring library code, the entire set of test dependencies is rebuilt, which takes a bit of time. A development ergonomics problem, IMHO.

What we need to do is to keep the local bytestring package out of the bytestring-test.

At this point, that's very simple to achieve:

  1. Revert 84f15d5 (I really don't understand where you wanted to go with that @vdukhovni)
  2. Remove the local bytestring package from the test cabal.project:
--- a/tests/cabal.project
+++ b/tests/cabal.project
@@ -1,5 +1,4 @@
 packages: bytestring-tests.cabal
-          ../bytestring.cabal

 allow-newer: *:bytestring
            , *:ghc-prim

Now, rebuilding the tests is super-fast. Great!

@sjakobi
Copy link
Member

sjakobi commented May 29, 2020

(And thanks for unresolving my earlier comments! It's a bit of a shame that we have to jump through these hoops to collaborate!)

@vdukhovni
Copy link
Contributor Author

I just gave this PR as spin on my local machine. The issue that I believe we're close to eliminating now is that after any change to the bytestring library code, the entire set of test dependencies is rebuilt, which takes a bit of time. A development ergonomics problem, IMHO.

Rebuilding the test dependencies against the updated bytestring is actually necessary. Otherwise the test dependencies are linked against the wrong bytestring. The time to run the tests while making changes to bytestring should not influence the decision much or at all. It is pretty quick anyway.

What we need to do is to keep the local bytestring package out of the bytestring-test.

No, we actually need to make sure that we're testing the local bytestring package and not the stock bytestring from the package cache.

At this point, that's very simple to achieve:

  1. Revert 84f15d5 (I really don't understand where you wanted to go with that @vdukhovni)
  2. Remove the local bytestring package from the test cabal.project:

I disagree. Please try for example building Andrew Martin's PR, or the ryu PR without this. (For the former you'll need GHC master, and Simon PJ's patch), ...

Now, rebuilding the tests is super-fast. Great!

I disagree, and don't find the time to build tests a deciding factor.

@sjakobi
Copy link
Member

sjakobi commented May 29, 2020

Rebuilding the test dependencies against the updated bytestring is actually necessary. Otherwise the test dependencies are linked against the wrong bytestring.

Ok, I'm curious now. Why ought the test dependencies to be linked against the new/local bytestring?

The time to run the tests while making changes to bytestring should not influence the decision much or at all.

I think it's actually pretty important.

Note that the containers setup takes this idea even further. It's containers-tests sub-package simply has the same library component as containers proper. That way, modules used by multiple testsuites are recompiled only once.

@vdukhovni
Copy link
Contributor Author

Note that the containers setup takes this idea even further. It's containers-tests sub-package simply has the same library component as containers proper. That way, modules used by multiple testsuites are recompiled only once.

Are you reachable via any interactive channels? (Skype, Hangouts, Signal)? Please send me an email [email protected]. For me the test runtime from cold start was:

real    1m57.371s
user    2m44.350s
sys     0m16.233s

Which is not a barrier to running tests now and then... Builds w/o tests take 16s (cold).

@sjakobi
Copy link
Member

sjakobi commented May 29, 2020

I've sent you an email.

My concern is about interactive development. You're working on some function, and you want to run the tests for that. Recompilation should be as fast as possible then. 1 or even 2 minutes would be very frustrating already.

@vdukhovni vdukhovni force-pushed the ci-refactor branch 3 times, most recently from ce572c3 to 29567fe Compare May 29, 2020 20:36
@vdukhovni
Copy link
Contributor Author

With great help from @sjakobi I've simplified this further, and expect I've addressed his concerns. The CI should shortly show up green. The cabal.project files are now quite short, and we're no longer rebuilding the test dependencies against the new bytestring, just testing bytestring-test as suggested.

The only downside is that modules need to be listed in two .cabal files, bytestring and bytestring-test

@sjakobi
Copy link
Member

sjakobi commented May 29, 2020

Thanks @vdukhovni. I very much enjoyed our chat! :)

FYI, I believe I've found the discussion on the cabal feature that would make much of this work redundant by allowing circular dependencies in testsuites: haskell/cabal#4087

@vdukhovni
Copy link
Contributor Author

vdukhovni commented May 29, 2020

FYI, I believe I've found the discussion on the cabal feature that would make much of this work redundant by allowing circular dependencies in testsuites: haskell/cabal#4087

Yeah, that would have been nice. But it's been under discussion for 3 years, so I'm not expecting a miracle... I've had to just force push a small fix, it seems I needed a v2-build rather than build for testing that that the unpacked sdist is buildable...

Edit: Finally all green again: https://travis-ci.org/github/haskell/bytestring/builds/692741896?utm_source=github_status&utm_medium=notification

Barring any surprises, I'm calling this done. Moving on to better things...

Copy link
Member

@sjakobi sjakobi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be great if someone with better bash skills (EDIT: than mine) could review the Travis script.

For local development, this setup seems quite awesome! :)

Again, many thanks, @vdukhovni!

.travis.yml Outdated Show resolved Hide resolved
@vdukhovni
Copy link
Contributor Author

It would be great if someone with better bash skills could review the Travis script.

I guess, sadly, my own bash power-user status does not count, you're looking for someone else to review...

@vdukhovni
Copy link
Contributor Author

@hvr, @cartazio. At this point I'm looking for a final review and merge, after addressing any issues.

@sjakobi
Copy link
Member

sjakobi commented May 29, 2020

It would be great if someone with better bash skills could review the Travis script.

I guess, sadly, my own bash power-user status does not count, you're looking for someone else to review...

Indeed. I'm looking for a second pair of eyeballs in addition to yours here. My own count for at most half an eye… ,)

@bgamari
Copy link
Contributor

bgamari commented Jun 20, 2020

@hvr, @cartazio, @dcoutts, this is in need of review.

Instead of running tests in the parent "bytestring" project, with
circular dependencies from the test frameworks, build and run them in
the child `bytestring-tests` project, which builds the parent as a
dependency that does not run tests, avoiding all the loops.

This requires cabal-install >= 2.4 with cabal.project doing most of the
heavy lifting.
@vdukhovni
Copy link
Contributor Author

Rebased as mentioned in #214

@sjakobi sjakobi linked an issue Jun 25, 2020 that may be closed by this pull request
@sjakobi
Copy link
Member

sjakobi commented Jul 1, 2020

@Bodigrim, @hsyl20, could you take a look at this?

I'm not too worried about potential problems with this. If any issue with CI comes up, we can fix it on the go.

If no one points out any problems with this patch, I'd simply merge it in 2 or 3 days.

Copy link
Contributor

@Bodigrim Bodigrim left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me.
We will have to switch to 8.8.4 and 8.10.2 anytime soon, but I guess we can do it in a separate PR as well.

@hsyl20
Copy link
Contributor

hsyl20 commented Jul 2, 2020

Looks good to me too.

@sjakobi sjakobi merged commit 5970194 into haskell:master Jul 2, 2020
@sjakobi
Copy link
Member

sjakobi commented Jul 2, 2020

Thank you, @vdukhovni! :)

- export SRC=$(cabal info . | awk '{print $2; exit}');
if [ -f "$SRC.tar.gz" ]; then
cabal get "./$SRC.tar.gz";
(cd "$SRC"; cabal v2-build);
else
echo "expected '$SRC_TGZ' not found";
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, the error message here is not quite right, it should be $SRC.tar.gz not $SRC_TGZ which is no longer set. This should not happen, but if it ever did, the error message would be confusing...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sjakobi Would you care to fix the error message?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not too worried about it. Feel free to send a PR or open an issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Full rebuild on test modification
7 participants