diff --git a/artiq/windows/default.nix b/artiq/windows/default.nix index 4cd5987..2e37569 100644 --- a/artiq/windows/default.nix +++ b/artiq/windows/default.nix @@ -3,93 +3,60 @@ qemuMem ? "2G", testTimeout ? 180, artiqPkg ? import ../conda-artiq.nix { inherit pkgs; }, + testCommand ? "python -m unittest discover -v artiq.test", }: with pkgs; let - artiqSrc = ; - artiqVersion = - pkgs.runCommand "artiq-version" { - buildInputs = [ pkgs.nix pkgs.git ]; - } '' - REV=`git --git-dir ${artiqSrc}/.git rev-parse HEAD` - echo \"5e.`cut -c1-8 <<< $REV`\" > $out - ''; - - generateTestOkHash = - pkgs.runCommand "generate-test-ok-hash" { - buildInputs = [ pkgs.nix ]; - } '' - TMPDIR=`mktemp -d` - cp ${artiqVersion} $TMPDIR/passed - HASH=`nix-hash --type sha256 --base32 $TMPDIR` - echo \"$HASH\" > $out - ''; - + escape = builtins.replaceStrings [ "\\" ] [ "\\\\" ]; qemu = import ./qemu.nix { inherit pkgs qemuMem; diskImage = "c.img"; }; - ssh = qemu.ssh; + # Double-escape because we produce a script from a shell heredoc + ssh = cmd: qemu.ssh (escape cmd); scp = qemu.scp; condaEnv = "artiq"; +in - makeTest = name: testCommand: - stdenv.mkDerivation { - name = "windows-test-conda-artiq-${name}"; +stdenv.mkDerivation { + name = "windows-test-runner"; + src = ./.; - outputHashAlgo = "sha256"; - outputHashMode = "recursive"; - outputHash = import generateTestOkHash; - __hydraRetry = false; + buildInputs = qemu.inputs; + dontBuild = true; + installPhase = '' + mkdir -p $out/bin + cat > $out/bin/run.sh << EOF + # +1 day from last modification of the disk image + CLOCK=$(date -Is -d @$(expr $(stat -c %Y ${diskImage}) + 86400)) + ${qemu.runQemu true [ + "-boot" "order=c" + "-snapshot" + "-drive" "file=${diskImage},index=0,media=disk,cache=unsafe" + "-rtc" "base=$CLOCK" + "-display" "none" + ]} & - phases = [ "buildPhase" ]; - buildInputs = qemu.inputs; - buildPhase = '' - # +1 day from last modification of the disk image - CLOCK=$(date -Is -d @$(expr $(stat -c %Y ${diskImage}) + 86400)) - ${qemu.runQemu true [ - "-boot" "order=c" - "-snapshot" - "-drive" "file=${diskImage},index=0,media=disk,cache=unsafe" - "-rtc" "base=$CLOCK" - "-display" "none" - ]} & + echo "Wait for Windows to boot" + sleep 10 + ${ssh "ver"} + for pkg in ${artiqPkg}/noarch/artiq*.tar.bz2 ; do + ${scp "\$pkg" "artiq.tar.bz2"} + ${ssh "anaconda\\scripts\\activate ${condaEnv} && conda install artiq.tar.bz2"} + done - echo "Wait for Windows to boot" - sleep 10 - ${ssh "ver"} - for pkg in ${artiqPkg}/noarch/artiq*.tar.bz2 ; do - ${scp "\$pkg" "artiq.tar.bz2"} - ${ssh "anaconda\\scripts\\activate ${condaEnv} && conda install artiq.tar.bz2"} - done + # Allow tests to run for 2 minutes + ${ssh "shutdown -s -t ${toString testTimeout}"} - # Allow tests to run for 2 minutes - ${ssh "shutdown -s -t ${toString testTimeout}"} + ${ssh "anaconda\\scripts\\activate ${condaEnv} && ${testCommand}"} - ${testCommand} - - # Abort timeouted shutdown - ${ssh "shutdown -a"} - # Power off immediately - ${ssh "shutdown -p -f"} - - mkdir $out - cp ${artiqVersion} $out/passed - ''; - }; -in { - standalone = - makeTest "standalone" - (ssh "anaconda\\scripts\\activate ${condaEnv} && python -m unittest discover -v artiq.test"); - kc705 = - makeTest "kc705" - # This weirdly mangled syntax is legit for Windows - (ssh (builtins.replaceStrings [ "\n" ] [ "" ] '' - anaconda\scripts\activate ${condaEnv} - && set ARTIQ_ROOT=%cd%\anaconda\envs\artiq-env\Lib\site-packages\artiq\examples\kc705_nist_clock - && set ARTIQ_LOW_LATENCY=1 - && python -m unittest discover -v artiq.test.coredevice - '')); + # Abort timeouted shutdown + ${ssh "shutdown -a"} + # Power off immediately + ${ssh "shutdown -p -f"} + EOF + chmod a+x $out/bin/run.sh + ''; } diff --git a/artiq/windows/install.nix b/artiq/windows/install.nix index 680bb6f..3bce92b 100644 --- a/artiq/windows/install.nix +++ b/artiq/windows/install.nix @@ -15,12 +15,13 @@ let sha256 = "1f9icm5rwab6l1f23a70dw0qixzrl62wbglimip82h4zhxlh3jfj"; }; + escape = builtins.replaceStrings [ "\\" ] [ "\\\\" ]; qemu = import ./qemu.nix { inherit pkgs qemuMem; diskImage = "c.img"; }; # Double-escape because we produce a script from a shell heredoc - ssh = cmd: qemu.ssh (qemu.escape cmd); + ssh = cmd: qemu.ssh (escape cmd); scp = qemu.scp; sshCondaEnv = cmd: ssh "anaconda\\scripts\\activate && ${cmd}"; diff --git a/artiq/windows/qemu.nix b/artiq/windows/qemu.nix index bdd9618..ecb7c8d 100644 --- a/artiq/windows/qemu.nix +++ b/artiq/windows/qemu.nix @@ -26,14 +26,13 @@ let argStr = builtins.concatStringsSep " " (args ++ extraArgs); in "qemu-system-x86_64 ${argStr}"; - escape = builtins.replaceStrings [ "\\" ] [ "\\\\" ]; sshOpts = "-o StrictHostKeyChecking=accept-new -o UserKnownHostsFile=/tmp/known_hosts"; ssh = cmd: '' - echo ssh windows '${escape cmd}' + echo ssh windows '${cmd}' ${sshpass}/bin/sshpass -p${sshPassword} -- \ ${openssh}/bin/ssh -np 2022 ${sshOpts} \ ${sshUser}@localhost \ - '${escape cmd}' + '${cmd}' ''; scp = src: target: '' echo "Copy ${src} to ${target}" @@ -44,6 +43,6 @@ let in { - inherit qemu-img runQemu escape ssh scp; + inherit qemu-img runQemu ssh scp; inputs = [ qemu openssh sshpass ]; } diff --git a/main.nix b/main.nix index a32082a..efc07e4 100644 --- a/main.nix +++ b/main.nix @@ -30,6 +30,11 @@ let ''; artiqpkgs = import "${generatedNix}/default.nix" { inherit pkgs; }; artiqVersion = import "${generatedNix}/pkgs/artiq-version.nix"; + windowsRunner = overrides: + import "${generatedNix}/windows" ({ + inherit pkgs; + artiqPkg = artiqpkgs.conda-artiq; + } // overrides); jobs = (builtins.mapAttrs (key: value: pkgs.lib.hydraJob value) artiqpkgs) // { # This is in the example in the ARTIQ manual - precompile it to speed up # installation for users. @@ -46,13 +51,26 @@ in constituents = builtins.attrValues jobs; }; + windows-no-hardware-tests = pkgs.stdenv.mkDerivation { + name = "windows-no-hardware-tests"; + src = ./.; + buildInputs = [ artiqpkgs.conda-artiq ]; + phases = [ "buildPhase" ]; + buildPhase = '' + ${windowsRunner {}}/bin/run.sh + + mkdir $out + touch $out/passed + ''; + }; + # HACK: Abuse fixed-output derivations to escape the sandbox and run the hardware # unit tests, all integrated in the Hydra interface. # One major downside of this hack is the tests are only run when generateTestOkHash # changes, i.e. when the ARTIQ version changes (and not the dependencies). # Impure derivations, when they land in Nix/Hydra, should improve the situation. - kc705-tests = pkgs.stdenv.mkDerivation { - name = "kc705-tests"; + extended-tests = pkgs.stdenv.mkDerivation { + name = "extended-tests"; outputHashAlgo = "sha256"; outputHashMode = "recursive"; @@ -79,9 +97,13 @@ in sleep 15 # ping: socket: Operation not permitted #ping kc705-1 -c10 -w30 + export ARTIQ_ROOT=`python -c "import artiq; print(artiq.__path__[0])"`/examples/kc705_nist_clock export ARTIQ_LOW_LATENCY=1 python -m unittest discover -v artiq.test.coredevice + + ${windowsRunner { testCommand = "set ARTIQ_ROOT=%cd%\\anaconda\\envs\\artiq-env\\Lib\\site-packages\\artiq\\examples\\kc705_nist_clock&&set ARTIQ_LOW_LATENCY=1&&python -m unittest discover -v artiq.test.coredevice"; }}/bin/run.sh + mkdir $out cp ${generatedNix}/pkgs/artiq-version.nix $out/passed '';