# SPDX-License-Identifier: CC0-1.0 { system, apps, testPkgs, hostPkgs, lib, depot }: let testDriver = with hostPkgs; stdenv.mkDerivation { name = "nova-genode-test-driver"; preferLocalBuild = true; buildInputs = [ makeWrapper expect ]; dontUnpack = true; installPhase = '' install -Dm555 ${./nova-test-driver.exp} $out/bin/genode-test-driver wrapProgram $out/bin/genode-test-driver \ --prefix PATH : "${lib.makeBinPath [ expect coreutils ]}" ''; }; runTests = driver: hostPkgs.stdenv.mkDerivation { name = "nova-" + driver.testName; preferLocalBuild = true; buildCommand = '' mkdir -p $out/nix-support ${driver}/bin/genode-test-driver | tee $out/log touch $out/nix-support echo "report testlog $out log" >> $out/nix-support/hydra-build-products ''; }; mkTest = { name ? "unamed", testScript, testConfig, env ? { }, qemuMem ? 32 , ... # TODO: remove ... }@t: let env' = { DHALL_PRELUDE = "${testPkgs.dhallPrelude}/package.dhall"; DHALL_GENODE = "${testPkgs.dhallGenode}/package.dhall"; BASE_MANIFEST = testPkgs.genode.base.manifest; BASE_NOVA_MANIFEST = testPkgs.genode.base-nova.manifest; OS_MANIFEST = testPkgs.genode.os.manifest; SOTEST_PRODUCER_MANIFEST = testPkgs.sotest-producer.manifest; } // env; iso = apps.nova-iso.function env' "${./driver-nova-config.dhall} ${testConfig}"; baseSetup = '' ## # Wait for a specific output of a already running spawned proce # proc wait_for_output { wait_for_re timeout_value running_spawn_id } { global output if {$wait_for_re == "forever"} { set timeout -1 interact { \003 { send_user "Expect: 'interact' received 'strg+c' and was cancelled\n"; exit } -i $running_spawn_id } } else { set timeout $timeout_value } expect { -i $running_spawn_id -re $wait_for_re { } eof { puts stderr "Error: Spawned process died unexpectedly"; exit -1 } timeout { puts stderr "Error: Test execution timed out"; exit -1 } } set output $expect_out(buffer) } proc run_genode_until {{wait_for_re forever} {timeout_value 0} {running_spawn_id -1}} { # # If a running_spawn_id is specified, wait for the expected output # if {$running_spawn_id != -1} { wait_for_output $wait_for_re $timeout_value $running_spawn_id return } global spawn_id spawn ${hostPkgs.qemu_test}/bin/qemu-system-x86_64 \ -machine q35 -serial mon:stdio -nographic \ -m size=${toString qemuMem} \ -cdrom ${iso} wait_for_output $wait_for_re $timeout_value $spawn_id } # TODO: not in TCL global env set out $env(out) set fd [open "$out/nix-support/hydra-build-products" w] puts $fd "file iso ${iso}" close $fd ''; driver = with hostPkgs; buildPackages.runCommand "genode-test-driver-${name}" { buildInputs = [ makeWrapper expect ]; inherit baseSetup testConfig testScript; preferLocalBuild = true; testName = name; } '' mkdir -p $out/bin echo "$testScript" > $out/test-script echo "$baseSetup" > $out/base-setup ln -s ${testDriver}/bin/genode-test-driver $out/bin/ wrapProgram $out/bin/genode-test-driver \ --run "export testScript=\"\$(cat $out/test-script)\"" \ --run "export baseSetup=\"\$(cat $out/base-setup)\"" \ ''; passMeta = drv: drv // lib.optionalAttrs (t ? meta) { meta = (drv.meta or { }) // t.meta; }; test = passMeta (runTests driver); in test // { inherit driver iso test; config = hostPkgs.runCommand (name + ".dhall") env' '' ${apps.dhall.program} <<< "(${ ./driver-nova-config.dhall } ${testConfig})" > $out ''; xml = hostPkgs.runCommand (name + ".config") env' '' ${apps.render-init.program} "(${ ./driver-nova-config.dhall } ${testConfig}).config" > $out''; sotest = hostPkgs.runCommand "nova-${name}-sotest" env' '' export XDG_CACHE_HOME=${TMPDIR:-/tmp} ${apps.nova-image.program} image.elf \ ${./driver-nova-config.dhall} ${testConfig} cp "${testPkgs.bender}" bender cp "${testPkgs.NOVA}/hypervisor-x86_64" hypervisor mkdir -p $out/nix-support ${hostPkgs.zip}/bin/zip "$out/binaries.zip" \ bender hypervisor image.elf ${apps.dhall-to-yaml.program} < ${ ./sotest_config.dhall } > "$out/sotest_config.yaml" echo file zip $out/binaries.zip >> "$out/nix-support/hydra-build-products" echo file config $out/sotest_config.yaml >> "$out/nix-support/hydra-build-products" ''; }; in { callTest = path: args: (import path ({ testEnv = { inherit mkTest lib; isLinux = false; isNova = true; }; pkgs = testPkgs; inherit depot; } // args)); }