Interactive NixOS tests
A quick guide to running NixOS tests interactively like you would in other testing framework.
-
Insert the following line where you’d like to interact in
testScript
:breakpoint()
-
Build and run the test driver for your test after replacing
TEST
with your actual test name:"$(nix-build -A nixosTests.TEST.driver)/bin/nixos-test-driver"
Once you get a Python debugger prompt like (Pdb)
you’re in an interactive
Python shell, and can run Python commands interactively. This terminal
unfortunately does not have auto-complete enabled, but it does support
discovery via the ?
special command:
(Pdb) ?
Documented commands (type help <topic>):
========================================
EOF c d h list q rv undisplay
a cl debug help ll quit s unt
alias clear disable ignore longlist r source until
args commands display interact n restart step up
b condition down j next return tbreak w
break cont enable jump p retval u whatis
bt continue exit l pp run unalias where
⚠ Machine logs will continue to print to your terminal after the prompt shows up! You can try the example session below to see this in action. If you suspect that the prompt has been buried in logs, just press Enter. If you’ve not yet reached the prompt it should simply draw an empty line.
You can also get into an interactive shell on any of the nodes you have started
by running the following after replacing NODE
with your node name:
NODE.shell_interact()
Once you’re done, exit with Ctrl-d like you would a normal shell to get back into the Python debugger.
Once you’re done in the Python debugger, either run continue
to finish running
the tests or press Ctrl-d to cancel the test run.
Example session
Using current nixpkgs:
-
Add a breakpoint after starting all the machines in the SSH audit test:
sed --in-place --expression='/start_all()/a\ breakpoint()' nixos/tests/ssh-audit.nix
-
Run the test:
"$(nix-build -A nixosTests.ssh-audit.driver)/bin/nixos-test-driver"
- Wait for the output to quieten down.
- Press Enter to re-draw the Python debugger prompt.
- Run
server.shell_interact()
to start Bash in the server VM. - Run
hostname
to verify that you’re indeed on the server VM. - Press Ctrl-d to return to the Python debugger prompt.
- Press Ctrl-d again to end debugging.
-
Remove the SSH audit test breakpoint:
sed --in-place --expression='/ breakpoint()/d' nixos/tests/ssh-audit.nix
⚠ Interactivity broke for me in weird ways during testing. Once after exiting
Bash I got a new Bash prompt rather than going back to the Python debugger, and
the shell seemed to be broken. Another time the shell would no longer show any
of my input, but did show command output. Another user mentioned how pressing
either Ctrl-c or Ctrl-d could cause the entire session to
end from within shell_interact()
. This points to some broken signal handling,
so try to be careful with using the minimum amount of
Ctrl-c/Ctrl-d while debugging. And if anything like this
happens, you’ll probably want to run reset
once you get back to your native
shell. Update: I’ve reported
the easily reproducible findings.