What’s the correct way to run my tests when I build?
I wrote a script and put it in a container, and it wasn’t quite doing what it was supposed to, so I added some tests. At the time, I created a shell.nix and just put a call to bats in there that invokes bats on the script. And I embedded all my tests in the script.
It worked great, found and fixed the bugs, and added some regression tests.
The problem now – what’s really the best way to run these tests? I tried adding a checkPhase but it doesn’t get executed during build. I tried adding doCheck=true; but they still don’t run.
default.nix:
let nixpkgs = <nixpkgs>; pkgs = import nixpkgs { config = {}; overlays = []; };
in
{
package = pkgs.callPackage ./package.nix {};
container = pkgs.callPackage ./container.nix {};
}
package.nix
{ lib, stdenv, config, }:
let pkgs = import <nixpkgs> { config = {}; overlays = []; }; in
stdenv.mkDerivation {
name = "package";
version = "0";
src = ../scripts;
doCheck = true; # edit: <- typo here was the main issue! doChek != doCheck
buildInputs = with pkgs; [
bash #runtime
coreutils #runtime
gnugrep #runtime
bats #build/test time
];
nativeBuildInputs = [ pkgs.makeWrapper ];
installPhase = ''
mkdir -p $out/bin
install -m755 script.sh $out/bin/entry-point.sh
wrapProgram $out/bin/entry-point.sh \
--prefix PATH : ${lib.makeBinPath [
pkgs.bash
pkgs.coreutils
pkgs.gnugrep
]}
'';
checkPhase = ''
bats test-entry-point.sh
'';
}
container.nix:
{
lib,
stdenv,
}:
let
pkgs = import <nixpkgs> { config = {}; overlays = []; };
package = pkgs.callPackage ./package.nix { inherit lib; inherit stdenv; };
in pkgs.dockerTools.buildImage {
name = "helper";
tag = "nix";
copyToRoot = pkgs.buildEnv {
name = "image-root";
paths = [ package pkgs.bash ];
pathsToLink = [ "/bin" "${package}" ];
};
config = {
User = "root";
EntryPoint = [ "${package}/bin/entry-point.sh" ];
cmd = [ "${pkgs.bash}/bin/bash" ];
};
runAsRoot = ''
${pkgs.dockerTools.shadowSetup}
'';
}
File hierarchy looks like this:
root/
├── nix
│ ├── container.nix
│ ├── default.nix
│ ├── package.nix
│ └── shell.nix
└── scripts
└── script.sh
I pull it all together thusly:
docker image load -i "$(nix-build nix -A container)"
The shell.nix has a shellHook which calls bats on ${package}/scripts/test-entry-point.sh and then does an exit $? to propogate the error code. All the pieces work, if the above doesn’t work because of a syntax or other issue, it’s probably just a typo on my part while making a simpler version of the real stuff for sharing. I just don’t know how to make the package run tests when I build it. All I have been able to find on google about it says rather nebulously to set doCheck=true but doesn’t say where that needs to be done. Also something about running nix develop but that looked interactive and I just want it to run when I build. I’ll probably resort to a justfile or a makefile to call the things in order, but it would be really nice if the nix-build would run it.