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

nixpkgs-docs: when to prefer passthru.tests over installCheckPhase #119731

Conversation

raboof
Copy link
Member

@raboof raboof commented Apr 17, 2021

Motivation for this change

Make it easier to add tests by documenting better how.

Things done
  • Tested using sandboxing (nix.useSandbox on NixOS, or option sandbox in nix.conf on non-NixOS linux)
  • Built on platform(s)
    • NixOS
    • macOS
    • other Linux distributions
  • Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • Tested compilation of all pkgs that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Determined the impact on package closure size (by running nix path-info -S before and after)
  • Ensured that relevant documentation is up to date
  • Fits CONTRIBUTING.md.

@github-actions github-actions bot added the 8.has: documentation This PR adds or changes documentation label Apr 17, 2021
@ofborg ofborg bot added 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin 10.rebuild-linux: 0 This PR does not cause any packages to rebuild on Linux labels Apr 17, 2021
Comment on lines 709 to 710
Because this adds overhead to every build, it is usually recommended to add the test to
<xref linkend="var-meta-tests"/> instead.
Copy link
Contributor

Choose a reason for hiding this comment

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

My 2c is that I think installCheck is primarily useful for applications that have test-suites in tree (that maybe rely on build system configuration artifacts), that aren't then shipped as part of the package build.

If you as a package maintainer are defining a test, then it probably does make sense to add it as a separate passthru.tests test.

Copy link
Member Author

Choose a reason for hiding this comment

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

that's a great distinction, updated to make that more clear

@raboof raboof force-pushed the document-preferring-passthru-tests-over-installChecks branch from fb4f37d to 5f39e96 Compare April 18, 2021 07:45
@raboof raboof requested a review from lukegb April 18, 2021 07:47
@raboof raboof force-pushed the document-preferring-passthru-tests-over-installChecks branch from 5f39e96 to 467f558 Compare April 18, 2021 07:52
@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/contributor-retention/12412/74

Copy link
Contributor

@danieldk danieldk left a comment

Choose a reason for hiding this comment

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

Thanks for improving the passthru.tests documentation. I only have a comment about the example.

Comment on lines 144 to 156
{ /* ... */ }:
let
key = mkDerivation {
# ...
passthru.tests = {
version-check = runCommand "key-help" {} ''
${key}/bin/KeY --help | grep -Fw ${version}
touch $out
'';
}
}
};
in key
Copy link
Contributor

Choose a reason for hiding this comment

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

I am not sure if we should present the example like this, we might end up with a lot of people submitting PRs with ugly let ... in ... wrapped derivations, which do not look very canonical. I think it's really much cleaner to just callPackage a separate derivation file with tests. Or if it must really be inline pass pkgs as an argument (both work because pkgs is a fixed-point).

Also, running a command seems quite lightweight. So, if it is not checked by the regular tests, I think it is easier to just add them to the postInstallCheck phase. I think passthru.tests is particularly useful for cases where you really want to test use as a separate derivation, e.g. checking whether you can compile against a library and the library works as expected.

Copy link
Member Author

@raboof raboof Apr 18, 2021

Choose a reason for hiding this comment

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

ugly let ... in ... wrapped derivations, which do not look very canonical

I agree the let ... in ... is rather awkward (I saw it in another passthru).

I think it's really much cleaner to just callPackage a separate derivation file with tests. Or if it must really be inline pass pkgs as an argument (both work because pkgs is a fixed-point).

Using callPackage (or passing pkgs - or perhaps even the package itself?) looks neater, but is a bit dangerous: if you add any overrides to the package, the tests exposed by the package-with-overrides will still test the package-without-overrides. If that's a limitation we're happy to live with then that works for me ;).

So perhaps the guidance we should document is: if it's a check that is expected to be quick and can be easily expressed inline, add it to the installCheckPhase, otherwise move it to its own file and add it to passthru.tests?

Copy link
Member

@Ekleog Ekleog Apr 18, 2021

Choose a reason for hiding this comment

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

I'd personally kind of prefer having the let ... in ... trick, even though it's not yet canonical, for the reason mentioned by @raboof of actually testing what we think we're testing. As for embedding wrapped derivations inline, if people think it looks bad (which makes sense) one solution would be to have a separate file that looks like:

# .../tests.nix
{ runCommand }:
key: version:
{
    version-check = runCommand "key-help" {} ''
      ${key}/bin/KeY --help | grep -Fw ${version}
      touch $out
    '';
}

Which would then be called with:

{ /* ... */ }:
let
  key = mkDerivation {
    # ...
    passthru.tests = callPackage ./tests.nix {} key version;
  };
in key

Copy link
Contributor

@danieldk danieldk Apr 18, 2021

Choose a reason for hiding this comment

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

I agree that not running tests for overrides is unexpected. But let self = ...; in self always felt like accidental complexity that makes derivations much harder to read unless you have in-dept Nix knowledge.

I am wondering if there isn't a more elegant solution. E.g. allowing tests to be self-taking functions and having mkDerivation pass self?

Copy link
Member

Choose a reason for hiding this comment

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

I had that in mind at some point too, but never actually got to it, mostly because anything that touches mkDerivation itself I'm trying not to touch — but also because passthru is expected to be passed through, so if mkDerivation started changing that it would technically be a breaking change.

Overall, I'd be all for such a change! But I don't have the time or energy to see it through myself these days, so… :/

As for the current PR, given that the manual that will be online for the next 6 months is currently being defined (and it's too late to land changes to mkDerivation), I'd think that having this non-elegant workaround in the manual would make sense so people at least know to make tests, and hopefully by the time the next release freezes we will have introduced the necessary mkDerivation machinery?

Copy link
Contributor

Choose a reason for hiding this comment

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

As for the current PR, given that the manual that will be online for the next 6 months is currently being defined (and it's too late to land changes to mkDerivation), I'd think that having this non-elegant workaround in the manual would make sense so people at least know to make tests, and hopefully by the time the next release freezes we will have introduced the necessary mkDerivation machinery?

Sounds fair 👍

Copy link
Member Author

Choose a reason for hiding this comment

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

I am wondering if there isn't a more elegant solution. E.g. allowing tests to be self-taking functions and having mkDerivation pass self?

With this in mind I think I'd like to show the approach without let, since that'll likely be easier to refactor to the new approach later.

Copy link
Member

Choose a reason for hiding this comment

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

FWIW, I'm not sure we'll actually manage to properly do the self-taking approach in a reasonable timeframe (I'm pretty sure I personally won't do it anytime soon, and don't know whether other people are planning to); and there may be issues that make it harder than expected (eg. programs that are split between a common.nix and vX-Y.nix, or files that are being callPackage'd multiple times from the top-level with various overrides).

So I wouldn't be too optimistic and would assume that it never actually happens in practice for the documentation we write today, though I'd love to be proven wrong 😅

Copy link
Member Author

Choose a reason for hiding this comment

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

So I wouldn't be too optimistic and would assume that it never actually happens in practice for the documentation we write today

I agree in general - here it just seemed like a nice tie-breaker ;)

Copy link
Member

Choose a reason for hiding this comment

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

This does the trick: #119942

and it's too late to land changes to mkDerivation

I would argue that this is an addition, not a change. It also causes no rebuilds and it's easy to revert.

@zowoq
Copy link
Contributor

zowoq commented Apr 18, 2021

NixOS/ofborg#524

ofborg eval doesn't check passthru, we probably want to resolve that first before we recommend it in the manual.

@raboof
Copy link
Member Author

raboof commented Apr 18, 2021

NixOS/ofborg#524

ofborg eval doesn't check passthru, we probably want to resolve that first before we recommend it in the manual.

we should definitely double-check that - my impression is that ofborg will run the tests for derivations that it builds. That issue seems to say ofbord usually checks derivations it doesn't build at least evaluate correctly, but that that doesn't work for passthru derivations. Not sure though.

@raboof raboof marked this pull request as draft April 18, 2021 09:42
@raboof
Copy link
Member Author

raboof commented Apr 18, 2021

ofborg eval doesn't check passthru

we should definitely double-check that

It does run it for packages it builds, see for example #119781 . That seems sufficient to me, WDYT?

@zowoq
Copy link
Contributor

zowoq commented Apr 18, 2021

... ofborg will run the tests for derivations that it builds. That issue seems to say ofbord usually checks derivations it doesn't build at least evaluate correctly, but that that doesn't work for passthru derivations.

Yes.

It's easy it overlook and people would assume a ✅ from ofborg means that it's okay and nobody notices until it fails on Hydra.

Copy link
Member

@Ekleog Ekleog left a comment

Choose a reason for hiding this comment

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

Looks great to me, thank you! Just have two small comments below :)

Copy link
Member

@abathur abathur left a comment

Choose a reason for hiding this comment

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

Just some phrasing tweaks; mostly:

  • trimming syllables/words/clauses/sentences
  • more active phrasing

@abathur
Copy link
Member

abathur commented Apr 18, 2021

On discourse I said:

the nixpkgs manual ... is thin on how you’d write a test from scratch or what would be meaningful.

This PR is already a well-scoped stepwise improvement that bites off a big part of how you'd write a test from scratch, so I decided to sketch out how I think about what would be meaningful in case it helps clarify whether anything is missing or should be shaded differently? I don't want to force a broader scope or gum the PR up, so I'm posting it in the discourse thread: https://discourse.nixos.org/t/contributor-retention/12412/75

The main place I think it intersects with the how-to documentation already in this PR:

  • Without a resource covering what to test, I imagine some readers will see the help/version example here as a straightforward example of a test that is good/desirable or at least acceptable. It might be good to drop some breadcrumbs about where it sits on the various scales (Is it just a trivial example that was once acceptable but would get laughed out of PR review these days? Is it the minimum-meaningful test, or all we should aspire until everything is at this level?)
    • If it is trivial, saying so is probably enough. If it is meaningful, a quick high-level note on ~why it's meaningful might be a good stop-gap for orienting people towards appropriate values?

@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/contributor-retention/12412/80

@raboof raboof force-pushed the document-preferring-passthru-tests-over-installChecks branch from 467f558 to 519f9e7 Compare April 19, 2021 20:14
@raboof raboof marked this pull request as ready for review April 19, 2021 20:17
@raboof raboof requested review from danieldk and abathur April 20, 2021 06:46
Copy link
Member

@abathur abathur left a comment

Choose a reason for hiding this comment

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

LGTM.

I highlighted something I mentioned earlier and didn't see a comment on just in case you know the answer, but feel free to ignore it if not.

Comment on lines 139 to 157
#### Regular tests

Tests that are part of the source package are often executed in the `installCheckPhase`. Prefer `passthru.tests` for tests that are introduced in nixpkgs because `installCheckPhase` adds overhead to each build and we can run `passthru.tests` independently.

```nix
{ /* ... */, key }:

mkDerivation rec {
# ...
passthru.tests = {
version-check = runCommand "key-help" {} ''
${key}/bin/KeY --help | grep -Fw ${version}
touch $out
'';
};
}
```

Copy link
Member

Choose a reason for hiding this comment

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

I mentioned this out in the main thread, but I guess I'll attach it here since you pinged me :)

Without a resource covering what to test, I imagine some readers will see the help/version example here as a straightforward example of a test that is good/desirable or at least acceptable. It might be good to drop some breadcrumbs about where it sits on the various scales (Is it just a trivial example that was once acceptable but would get laughed out of PR review these days? Is it the minimum-meaningful test, or all we should aspire until everything is at this level?)

If it is trivial, saying so is probably enough. If it is meaningful, a quick high-level note on ~why it's meaningful might be a good stop-gap for orienting people towards appropriate values?

I think it would be good to have a little context on this before or after the example, but I don't see it as a blocker and realize you might not know the answer.

Copy link
Member Author

Choose a reason for hiding this comment

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

but I don't see it as a blocker and realize you might not know the answer.

Correct, I don't know if we have enough experience/consensus to be able to put into words authoritative advice on this yet, so I left it out for now.

@raboof raboof force-pushed the document-preferring-passthru-tests-over-installChecks branch from 519f9e7 to 82a912d Compare April 21, 2021 08:37
@raboof raboof requested a review from danieldk April 21, 2021 08:37
@davidak
Copy link
Member

davidak commented Apr 24, 2021

This is great improvement of the reference in the manual.

I finally came to document the best practices of how to create package test today: #120534

When that is merged, you should just add a minimal example that runs tests.nix and update the terms accordingly "package tests" instead of "Regular tests".

* `installCheckPhase` adds overhead to each build

```nix
{ /* ... */, key }:
Copy link
Member

@SuperSandro2000 SuperSandro2000 Apr 26, 2021

Choose a reason for hiding this comment

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

Suggested change
{ /* ... */, key }:
{ ..., key }:

Copy link
Member

Choose a reason for hiding this comment

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

I disagree. /* ... */ is clearly intended as meta-syntax, whereas ... is actual syntax.

Copy link
Member Author

Choose a reason for hiding this comment

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

@SuperSandro2000 can you clarify why you wanted /* ... */ to be replaced by ..., so we can perhaps find a third alternative that is better than the 2 competing ones here?

Copy link
Member Author

Choose a reason for hiding this comment

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

(I moved this example to doc/contributing/coding-conventions.chapter.md and changed this to (UTF-8 ellipsis) to be consistent with the other already-existing example there)

{ /* ... */, key }:

mkDerivation rec {
# ...
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
# ...
...

Copy link
Member

Choose a reason for hiding this comment

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

I disagree. # ... is clearly intended as meta-syntax, whereas ... is close to actual syntax. It's a valid token in the language.

Copy link
Member Author

Choose a reason for hiding this comment

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

@SuperSandro2000 can you clarify why you wanted # ... to be replaced by ..., so we can perhaps find a third alternative that is better than the 2 competing ones here?

Copy link
Member Author

Choose a reason for hiding this comment

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

(I moved this example to doc/contributing/coding-conventions.chapter.md and changed this to (UTF-8 ellipsis) to be consistent with the other already-existing example there)

@raboof raboof force-pushed the document-preferring-passthru-tests-over-installChecks branch from 82a912d to 7cd0ff5 Compare April 26, 2021 06:44
@raboof raboof force-pushed the document-preferring-passthru-tests-over-installChecks branch from 7cd0ff5 to 306ea76 Compare May 6, 2021 11:11
@raboof raboof requested review from roberth and SuperSandro2000 May 6, 2021 11:13
@raboof raboof force-pushed the document-preferring-passthru-tests-over-installChecks branch from 306ea76 to 0518c62 Compare May 6, 2021 11:14
@raboof raboof changed the title nixpkgs-docs: prefer passthru.tests over installCheckPhase nixpkgs-docs: when to prefer passthru.tests over installCheckPhase Aug 14, 2021
And mention you can have either lightweight 'package' or
more heavyweight 'NixOS' (module) tests.

This was suggested at
nix-community/nixpkgs-update#260 (comment)
and discussed further at
NixOS#119731
@raboof raboof force-pushed the document-preferring-passthru-tests-over-installChecks branch from 0518c62 to d09e0be Compare August 14, 2021 07:47
@raboof raboof merged commit c580b69 into NixOS:master Aug 14, 2021
@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/improve-the-jdk-infrastructure-on-nixpkgs/45678/20

@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/improve-the-jdk-infrastructure-on-nixpkgs/45678/33

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
8.has: documentation This PR adds or changes documentation 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin 10.rebuild-linux: 0 This PR does not cause any packages to rebuild on Linux
Projects
None yet
Development

Successfully merging this pull request may close these issues.