Tests for a derivation that needs wrapping

I’ve been struggling with this for awhile so I’ve decided that I could really use another set of eyes on this. I should add that this is my first time writing a wrapper derivation & passthru.test, so maybe I’m not doing something about this correctly or should go a completely different route instead.

We have a binary package for the OpenWatcom compiler suite (nixpkgs/default.nix at 7a01a0efeb82d5f114ed4fb181548f0b44a9b7fc · NixOS/nixpkgs · GitHub) because it’s a dependency for some virtualbox BIOS stuff. But nobody seems to have bothered with actually writing some nice wrapping for the suite? tl;dr you’re supposed to add hostPlatform-specific paths to PATH & set some some special envvars for the tools but it doesn’t have any of the required wrapping to work on its own, only when virtualbox detects it & sets everything up on its own.

I’m now writing a derivation for a fork of this suite with afew more features (open-watcom-v2: init at unstable 2021-11-14 by OPNA2608 · Pull Request #124000 · NixOS/nixpkgs · GitHub). Since this will need the same kind of wrapping I decided to try my hand at writing a wrapper function wrapWatcom. Done, so far so good.

Next, since building the suite from source can take anywhere from 25 minutes to almost 3 hours depending on the settings, and writing the wrapper went so smooth, I figured that writing some simple tests would be a good idea. Here’s where my problems start:

From what I gathered, when writing a passthru.tests entry, the test needs to explicitly reference the to-be-tested package. For this, the package needs to get itself as an argument. For example if we take a look at the hello package, we see:

{ lib
, stdenv
, fetchurl
, testVersion
, *hello*
}:

stdenv.mkDerivation rec {
  pname = "hello";
  # ...
  passthru.tests.version =
    testVersion { package = *hello*; };
}

With a wrapper function that returns the package symlinkJoined with the wrappers, I’m not sure how I’m supposed to get this to work. Maybe I’m just overthinking this and going another way would be much nicer & easier? Any help would be appreciated. :slightly_smiling_face:

You can simply take the wrapper function and the current package as inputs and combine them in passthru.tests, no?

If you meant something like

let
  wrapper =
    {}:
    # stuff
    symlinkJoin {
      passthru = {
        # ...
        tests = let
          nativeBuildInputs = [ (wrapper {}) ];
        in {
          # tests here
        };
      };
    };
in
lib.makeOverridable wrapper

then yes, that indeed fixed it!* I thought something like that would lead to an infinite recursion of sorts so I never tried that, I guess it doesn’t :sweat_smile:. Now I can finally finish up my PR.

* And if it’s not, could you maybe explain with some example code? Maybe there’s a better solution still.