windows: run tests using WFVM
This commit is contained in:
parent
1b79bdaa20
commit
8111b2f42b
|
@ -42,9 +42,7 @@ let
|
||||||
artiqVersion = import "${generatedNix}/pkgs/artiq-version.nix" (with pkgs; { inherit stdenv fetchgit git; });
|
artiqVersion = import "${generatedNix}/pkgs/artiq-version.nix" (with pkgs; { inherit stdenv fetchgit git; });
|
||||||
windowsRunner = overrides:
|
windowsRunner = overrides:
|
||||||
import "${generatedNix}/windows/run-test.nix" ({
|
import "${generatedNix}/windows/run-test.nix" ({
|
||||||
inherit pkgs;
|
inherit pkgs artiqpkgs;
|
||||||
sipycoPkg = artiqpkgs.conda-sipyco;
|
|
||||||
artiqPkg = artiqpkgs.conda-artiq;
|
|
||||||
} // overrides);
|
} // overrides);
|
||||||
jobs = (builtins.mapAttrs (key: value: pkgs.lib.hydraJob value) artiqpkgs);
|
jobs = (builtins.mapAttrs (key: value: pkgs.lib.hydraJob value) artiqpkgs);
|
||||||
in
|
in
|
||||||
|
@ -61,7 +59,7 @@ in
|
||||||
buildInputs = [ (windowsRunner {}) ];
|
buildInputs = [ (windowsRunner {}) ];
|
||||||
phases = [ "buildPhase" ];
|
phases = [ "buildPhase" ];
|
||||||
buildPhase = ''
|
buildPhase = ''
|
||||||
${windowsRunner {}}/bin/run.sh
|
${windowsRunner {}}/bin/wfvm-run-windows-tests
|
||||||
touch $out
|
touch $out
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
@ -119,7 +117,7 @@ in
|
||||||
export ARTIQ_LOW_LATENCY=1
|
export ARTIQ_LOW_LATENCY=1
|
||||||
python -m unittest discover -v artiq.test.coredevice
|
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&&python -m unittest discover -v artiq.test.coredevice"; }}/bin/run.sh
|
${windowsRunner { testCommand = "set ARTIQ_ROOT=%cd%\\Anaconda3\\envs\\artiq-env\\Lib\\site-packages\\artiq\\examples\\kc705_nist_clock&& python -m unittest discover -v artiq.test.coredevice"; }}/bin/wfvm-run-windows-tests
|
||||||
)
|
)
|
||||||
|
|
||||||
mkdir $out
|
mkdir $out
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
# Preparation steps
|
|
||||||
|
|
||||||
## Install a Windows image
|
|
||||||
|
|
||||||
```shell
|
|
||||||
nix-build install.nix -I artiqSrc=…/artiq
|
|
||||||
result/bin/windows-installer.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
Follow the instructions.
|
|
||||||
|
|
||||||
## Install Anaconda to the image
|
|
||||||
|
|
||||||
```shell
|
|
||||||
result/bin/anaconda-installer.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
Move the image `c.img` to one of Nix' `extra-sandbox-paths` (`nix.sandboxPaths` on NixOS).
|
|
||||||
|
|
||||||
|
|
||||||
# Running the tests manually
|
|
||||||
|
|
||||||
```shell
|
|
||||||
nix-build --pure --arg diskImage "\"…/c.img\"" -I artiqSrc=…/artiq manual-test-run.nix
|
|
||||||
```
|
|
|
@ -1,91 +0,0 @@
|
||||||
{ pkgs ? import <nixpkgs> {},
|
|
||||||
diskImageSize ? "22G",
|
|
||||||
qemuMem ? "4G",
|
|
||||||
}:
|
|
||||||
|
|
||||||
with pkgs;
|
|
||||||
|
|
||||||
let
|
|
||||||
windowsIso = fetchurl {
|
|
||||||
url = "https://software-download.microsoft.com/download/sg/17763.107.101029-1455.rs5_release_svc_refresh_CLIENT_LTSC_EVAL_x64FRE_en-us.iso";
|
|
||||||
sha256 = "668fe1af70c2f7416328aee3a0bb066b12dc6bbd2576f40f812b95741e18bc3a";
|
|
||||||
};
|
|
||||||
anaconda = fetchurl {
|
|
||||||
url = "https://repo.anaconda.com/archive/Anaconda3-2019.03-Windows-x86_64.exe";
|
|
||||||
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 (escape cmd);
|
|
||||||
scp = qemu.scp;
|
|
||||||
|
|
||||||
sshCondaEnv = cmd: ssh "anaconda\\scripts\\activate && ${cmd}";
|
|
||||||
condaEnv = "artiq-env";
|
|
||||||
condaDepSpecs =
|
|
||||||
builtins.concatStringsSep " "
|
|
||||||
(map (s: "\"${s}\"")
|
|
||||||
(import ../conda/artiq-deps.nix));
|
|
||||||
|
|
||||||
instructions =
|
|
||||||
builtins.toFile "install.txt"
|
|
||||||
(builtins.readFile ./install.txt);
|
|
||||||
in
|
|
||||||
stdenv.mkDerivation {
|
|
||||||
name = "windows-installer";
|
|
||||||
src = windowsIso;
|
|
||||||
setSourceRoot = "sourceRoot=`pwd`";
|
|
||||||
unpackCmd = ''
|
|
||||||
ln -s $curSrc windows.iso
|
|
||||||
'';
|
|
||||||
propagatedBuildInputs = qemu.inputs;
|
|
||||||
dontBuild = true;
|
|
||||||
installPhase = ''
|
|
||||||
mkdir -p $out/bin $out/data
|
|
||||||
ln -s $(readlink windows.iso) $out/data/windows.iso
|
|
||||||
cat > $out/bin/windows-installer.sh << EOF
|
|
||||||
#!/usr/bin/env bash
|
|
||||||
set -e -m
|
|
||||||
|
|
||||||
${qemu.qemu-img} create -f qcow2 c.img ${diskImageSize}
|
|
||||||
${qemu.runQemu false [] [
|
|
||||||
"-boot" "order=d"
|
|
||||||
"-drive" "file=c.img,index=0,media=disk,cache=unsafe"
|
|
||||||
"-drive" "file=$out/data/windows.iso,index=1,media=cdrom,cache=unsafe"
|
|
||||||
]} &
|
|
||||||
cat ${instructions}
|
|
||||||
wait
|
|
||||||
EOF
|
|
||||||
|
|
||||||
cat > $out/bin/anaconda-installer.sh << EOF
|
|
||||||
#!/usr/bin/env bash
|
|
||||||
set -e -m
|
|
||||||
|
|
||||||
${qemu.runQemu false [] [
|
|
||||||
"-boot" "order=c"
|
|
||||||
"-drive" "file=c.img,index=0,media=disk"
|
|
||||||
]} &
|
|
||||||
sleep 10
|
|
||||||
${ssh "ver"}
|
|
||||||
|
|
||||||
${scp anaconda "Anaconda.exe"}
|
|
||||||
${ssh "start /wait \"\" Anaconda.exe /S /D=%cd%\\anaconda"}
|
|
||||||
|
|
||||||
${sshCondaEnv "conda config --add channels conda-forge"}
|
|
||||||
${sshCondaEnv "conda config --add channels m-labs"}
|
|
||||||
( ${sshCondaEnv "conda update -y conda"} ) || true
|
|
||||||
${sshCondaEnv "conda update -y --all"}
|
|
||||||
${sshCondaEnv "conda create -y -n ${condaEnv}"}
|
|
||||||
${sshCondaEnv "conda install -y -n ${condaEnv} ${condaDepSpecs}"}
|
|
||||||
${ssh "shutdown /p /f"}
|
|
||||||
|
|
||||||
echo "Waiting for qemu exit"
|
|
||||||
wait
|
|
||||||
EOF
|
|
||||||
chmod a+x $out/bin/*.sh
|
|
||||||
'';
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
Add user account with expected password [user/user].
|
|
||||||
Enable the OpenSSH server:
|
|
||||||
- "Add or remove programs"
|
|
||||||
- "Manage optional features"
|
|
||||||
- "Add a feature"
|
|
||||||
- "OpenSSH Server"
|
|
||||||
- "Install"
|
|
||||||
- Open "Services"
|
|
||||||
- Double-click the "OpenSSH SSH Server" service
|
|
||||||
- Set "Startup type" to "Automatic"
|
|
||||||
- "Start"
|
|
||||||
- "Ok"
|
|
||||||
Then press ENTER here to proceed with automatic installation
|
|
|
@ -1,30 +1,10 @@
|
||||||
# This runs `run-test.nix` with `nix-build`
|
{ pkgs ? import <nixpkgs> {} }:
|
||||||
|
|
||||||
{ pkgs ? import <nixpkgs> {},
|
|
||||||
artiqpkgs ? import ../. { inherit pkgs; },
|
|
||||||
diskImage ? "/opt/windows/c.img",
|
|
||||||
qemuMem ? "2G",
|
|
||||||
testTimeout ? 180,
|
|
||||||
}:
|
|
||||||
|
|
||||||
with pkgs;
|
|
||||||
|
|
||||||
let
|
let
|
||||||
windowsRunner = overrides:
|
artiqpkgs = import ../. { inherit pkgs; };
|
||||||
import ./run-test.nix ({
|
run-test = import ./run-test.nix {
|
||||||
inherit pkgs diskImage qemuMem testTimeout;
|
inherit pkgs artiqpkgs;
|
||||||
sipycoPkg = artiqpkgs.conda-sipyco;
|
testCommand = "set ARTIQ_ROOT=%cd%\\Anaconda3\\envs\\artiq-env\\Lib\\site-packages\\artiq\\examples\\kc705_nist_clock&& python -m unittest discover -v sipyco.test && python -m unittest discover -v artiq.test";
|
||||||
artiqPkg = artiqpkgs.conda-artiq;
|
};
|
||||||
} // overrides);
|
|
||||||
in
|
in
|
||||||
|
run-test
|
||||||
stdenv.mkDerivation {
|
|
||||||
name = "windows-test";
|
|
||||||
|
|
||||||
phases = [ "installPhase" "checkPhase" ];
|
|
||||||
installPhase = "touch $out";
|
|
||||||
doCheck = true;
|
|
||||||
checkPhase = ''
|
|
||||||
${windowsRunner { testCommand = "set ARTIQ_ROOT=%cd%\\anaconda\\envs\\artiq-env\\Lib\\site-packages\\artiq\\examples\\kc705_nist_clock&&python -m unittest discover -v artiq.test"; }}/bin/run.sh
|
|
||||||
'';
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,55 +0,0 @@
|
||||||
{ pkgs,
|
|
||||||
diskImage,
|
|
||||||
qemuMem,
|
|
||||||
sshUser ? "user",
|
|
||||||
sshPassword ? "user",
|
|
||||||
}:
|
|
||||||
|
|
||||||
with pkgs;
|
|
||||||
|
|
||||||
let
|
|
||||||
qemu-img = "${qemu_kvm}/bin/qemu-img";
|
|
||||||
runQemu = isolateNetwork: forwardedPorts: extraArgs:
|
|
||||||
let
|
|
||||||
restrict =
|
|
||||||
if isolateNetwork
|
|
||||||
then "on"
|
|
||||||
else "off";
|
|
||||||
# use socat instead of `tcp:…` to allow multiple connections
|
|
||||||
guestfwds =
|
|
||||||
builtins.concatStringsSep ""
|
|
||||||
(map ({ listenAddr, targetAddr, port }:
|
|
||||||
",guestfwd=tcp:${listenAddr}:${toString port}-cmd:${socat}/bin/socat\\ -\\ tcp:${targetAddr}:${toString port}"
|
|
||||||
) forwardedPorts);
|
|
||||||
args = [
|
|
||||||
"-enable-kvm"
|
|
||||||
"-m" qemuMem
|
|
||||||
"-bios" "${OVMF.fd}/FV/OVMF.fd"
|
|
||||||
"-netdev" "user,id=n1,net=192.168.1.0/24,restrict=${restrict},hostfwd=tcp::2022-:22${guestfwds}"
|
|
||||||
"-device" "e1000,netdev=n1"
|
|
||||||
];
|
|
||||||
argStr = builtins.concatStringsSep " " (args ++ extraArgs);
|
|
||||||
in "${qemu_kvm}/bin/qemu-system-x86_64 ${argStr}";
|
|
||||||
|
|
||||||
# Pass empty config file to prevent ssh from failing to create ~/.ssh
|
|
||||||
sshOpts = "-F /dev/null -o StrictHostKeyChecking=accept-new -o UserKnownHostsFile=\$TMP/known_hosts";
|
|
||||||
sshWithQuotes = quotes: cmd: ''
|
|
||||||
echo ssh windows ${quotes}${cmd}${quotes}
|
|
||||||
${sshpass}/bin/sshpass -p${sshPassword} -- \
|
|
||||||
${openssh}/bin/ssh -np 2022 ${sshOpts} \
|
|
||||||
${sshUser}@localhost \
|
|
||||||
${quotes}${cmd}${quotes}
|
|
||||||
'';
|
|
||||||
ssh = sshWithQuotes "'";
|
|
||||||
scp = src: target: ''
|
|
||||||
echo "Copy ${src} to ${target}"
|
|
||||||
${sshpass}/bin/sshpass -p${sshPassword} -- \
|
|
||||||
${openssh}/bin/scp -P 2022 ${sshOpts} \
|
|
||||||
"${src}" "${sshUser}@localhost:${target}"
|
|
||||||
'';
|
|
||||||
|
|
||||||
in
|
|
||||||
{
|
|
||||||
inherit qemu-img runQemu ssh sshWithQuotes scp;
|
|
||||||
inputs = [ qemu_kvm openssh sshpass ];
|
|
||||||
}
|
|
|
@ -1,24 +1,6 @@
|
||||||
{ pkgs,
|
{ pkgs, artiqpkgs, testCommand }:
|
||||||
sipycoPkg,
|
|
||||||
artiqPkg,
|
|
||||||
diskImage ? "/opt/windows/c.img",
|
|
||||||
qemuMem ? "2G",
|
|
||||||
testTimeout ? 600,
|
|
||||||
testCommand ? "python -m unittest discover -v sipyco.test && python -m unittest discover -v artiq.test",
|
|
||||||
}:
|
|
||||||
|
|
||||||
with pkgs;
|
|
||||||
|
|
||||||
let
|
let
|
||||||
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 (escape cmd);
|
|
||||||
sshUnquoted = qemu.sshWithQuotes "\"";
|
|
||||||
scp = qemu.scp;
|
|
||||||
condaEnv = "artiq-env";
|
condaEnv = "artiq-env";
|
||||||
tcpPorts = [ 1380 1381 1382 1383 ];
|
tcpPorts = [ 1380 1381 1382 1383 ];
|
||||||
forwardedPorts =
|
forwardedPorts =
|
||||||
|
@ -27,58 +9,44 @@ let
|
||||||
targetAddr = "192.168.1.50";
|
targetAddr = "192.168.1.50";
|
||||||
inherit port;
|
inherit port;
|
||||||
}) tcpPorts;
|
}) tcpPorts;
|
||||||
|
|
||||||
|
wfvm = import ../wfvm/default.nix { inherit pkgs; };
|
||||||
|
conda-deps = {
|
||||||
|
name = "conda-deps";
|
||||||
|
script = let
|
||||||
|
conda-deps-noarch = import ./conda_noarch_packages.nix { inherit pkgs; };
|
||||||
|
conda-deps-win-64 = import ./conda_win-64_packages.nix { inherit pkgs; };
|
||||||
|
conda-packages-put = pkgs.lib.strings.concatStringsSep "\n"
|
||||||
|
( (map (package: ''win-put ${package} 'fake-channel/noarch' '') conda-deps-noarch)
|
||||||
|
++ (map (package: ''win-put ${package} 'fake-channel/win-64' '') conda-deps-win-64) );
|
||||||
|
in
|
||||||
|
''
|
||||||
|
win-exec 'mkdir fake-channel && mkdir fake-channel\noarch && mkdir fake-channel\win-64'
|
||||||
|
|
||||||
|
${conda-packages-put}
|
||||||
|
|
||||||
|
win-put ${artiqpkgs.conda-windows-binutils-or1k}/win-64/*.tar.bz2 'fake-channel/win-64'
|
||||||
|
win-put ${artiqpkgs.conda-windows-llvm-or1k}/win-64/*.tar.bz2 'fake-channel/win-64'
|
||||||
|
win-put ${artiqpkgs.conda-windows-llvmlite-artiq}/win-64/*.tar.bz2 'fake-channel/win-64'
|
||||||
|
|
||||||
|
win-put ${artiqpkgs.conda-pythonparser}/noarch/*.tar.bz2 'fake-channel/noarch'
|
||||||
|
win-put ${artiqpkgs.conda-sipyco}/noarch/*.tar.bz2 'fake-channel/noarch'
|
||||||
|
win-put ${artiqpkgs.conda-quamash}/noarch/*.tar.bz2 'fake-channel/noarch'
|
||||||
|
'';
|
||||||
|
};
|
||||||
in
|
in
|
||||||
|
wfvm.utils.wfvm-run {
|
||||||
|
name = "windows-tests";
|
||||||
|
image = wfvm.makeWindowsImage { installCommands = [ wfvm.layers.anaconda3 conda-deps ]; };
|
||||||
|
inherit forwardedPorts;
|
||||||
|
script =
|
||||||
|
''
|
||||||
|
${wfvm.utils.win-put}/bin/win-put ${artiqpkgs.conda-artiq}/noarch/*.tar.bz2 'fake-channel/noarch'
|
||||||
|
|
||||||
stdenv.mkDerivation {
|
${wfvm.utils.win-exec}/bin/win-exec ".\Anaconda3\scripts\activate && conda index fake-channel"
|
||||||
name = "windows-test-runner";
|
${wfvm.utils.win-exec}/bin/win-exec ".\Anaconda3\scripts\activate && conda create -n ${condaEnv} --offline"
|
||||||
src = ./.;
|
${wfvm.utils.win-exec}/bin/win-exec ".\Anaconda3\scripts\activate ${condaEnv} && conda install -y -c file:///C:/users/wfvm/fake-channel --offline artiq"
|
||||||
|
#${pkgs.sshpass}/bin/sshpass -p1234 -- ${pkgs.openssh}/bin/ssh -p 2022 wfvm@localhost -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null
|
||||||
propagatedBuildInputs = qemu.inputs;
|
${wfvm.utils.win-exec}/bin/win-exec ".\Anaconda3\scripts\activate ${condaEnv} && ${testCommand}"
|
||||||
dontBuild = true;
|
'';
|
||||||
installPhase = ''
|
}
|
||||||
mkdir -p $out/bin
|
|
||||||
cat > $out/bin/run.sh << EOF
|
|
||||||
#!/usr/bin/env bash
|
|
||||||
set -e -m
|
|
||||||
|
|
||||||
# +1 day from last modification of the disk image
|
|
||||||
CLOCK=$(date -Is -d @$(expr $(stat -c %Y ${diskImage}) + 86400))
|
|
||||||
${qemu.runQemu true forwardedPorts [
|
|
||||||
"-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 30
|
|
||||||
${ssh "ver"}
|
|
||||||
i=0
|
|
||||||
for pkg in ${sipycoPkg}/noarch/sipyco*.tar.bz2 ${artiqPkg}/noarch/artiq*.tar.bz2 ; do
|
|
||||||
${scp "\\$pkg" "to_install\\$i.tar.bz2"}
|
|
||||||
${sshUnquoted "anaconda\\scripts\\activate ${condaEnv} && conda install to_install\\$i.tar.bz2"}
|
|
||||||
((i=i+1))
|
|
||||||
done
|
|
||||||
|
|
||||||
# Schedule a timed shutdown against hanging test runs
|
|
||||||
${ssh "shutdown -s -t ${toString testTimeout}"}
|
|
||||||
|
|
||||||
FAIL=n
|
|
||||||
( ${ssh "anaconda\\scripts\\activate ${condaEnv} && ${testCommand}"} ) || FAIL=y
|
|
||||||
|
|
||||||
# Abort timeouted shutdown
|
|
||||||
${ssh "shutdown -a"}
|
|
||||||
# Power off immediately
|
|
||||||
${ssh "shutdown -p -f"}
|
|
||||||
wait
|
|
||||||
|
|
||||||
if [ "\$FAIL" = "y" ]; then
|
|
||||||
exit 1
|
|
||||||
else
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
EOF
|
|
||||||
chmod a+x $out/bin/run.sh
|
|
||||||
'';
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue