2
0
Fork 0
Browse Source

Add NOVA tests

20.02
Emery Hemingway 3 years ago
parent
commit
9096313d6c
  1. 3
      tests/default.nix
  2. 191
      tests/driver-nova.nix
  3. 1
      tests/fs_report.nix
  4. 137
      tests/genode.ld
  5. 3
      tests/libc.nix
  6. 1
      tests/log.nix
  7. 6
      tests/nova-bss.ld
  8. 5
      tests/nova-isolinux.cfg
  9. 75
      tests/nova-test-driver.exp
  10. 3
      tests/signal.nix
  11. 3
      tests/solo5.nix

3
tests/default.nix

@ -32,10 +32,11 @@ let
| dhall text \
> $out
'';
};
in {
linux = tests
(import ./driver-linux.nix { inherit testPkgs hostPkgs lib; }).callTest;
nova = tests
(import ./driver-nova.nix { inherit testPkgs hostPkgs lib; }).callTest;
}

191
tests/driver-nova.nix

@ -0,0 +1,191 @@
# SPDX-FileCopyrightText: Emery Hemingway
#
# SPDX-License-Identifier: LicenseRef-Hippocratic-1.1
{ testPkgs, hostPkgs, lib }:
let
testDriver = with hostPkgs;
stdenv.mkDerivation {
name = "nova-genode-test-driver";
buildInputs = [ makeWrapper expect ];
dontUnpack = true;
preferLocalBuild = 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 = "test-run-${driver.testName}";
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
'';
};
makeTest = { testScript, testConfig, name ? "unamed", ... }@t:
let
baseSetup = with testPkgs;
''
global modules
set HOSTLD ${buildPackages.binutils}/bin/x86_64-unknown-genode-elf-ld
file link -s timer ${genode.base-nova}/bin/nova_timer_drv
file link -s ld.lib.so ${depot.base-nova}/lib/ld.lib.so
file link -s core-nova.o ${depot.base-nova}/lib/core-nova.o
file link -s init ${genode.os}/bin/init
file link -s config ${./driver-config.xml}
file link -s test.config $env(testConfig)
set modules {
timer
ld.lib.so
init
config
test.config
}
set qemu_mem 64
##
# Link core image containing given modules
#
proc build_core {lib modules target} {
global env
# generate assembly code aggregating the modules data
set asm_src [generate_boot_modules_asm $modules]
# compile the boot modules into one object file
exec $env(CC) -c -x assembler -o boot_modules.o - << $asm_src
# link final image
global HOSTLD
exec $HOSTLD -nostdlib \
-T${./genode.ld} \
-T${./nova-bss.ld} \
-z max-page-size=0x1000 \
-Ttext=0x100000 -gc-sections \
--whole-archive \
$lib boot_modules.o --no-whole-archive \
-o $target
}
proc build_iso {target} {
# TODO: take our own build of NOVA
file mkdir boot/syslinux
file copy ${nova}/hypervisor-x86_64 boot/hypervisor
file copy ${./nova-isolinux.cfg} boot/syslinux/isolinux.cfg
file copy ${hostPkgs.syslinux}/share/syslinux/isolinux.bin boot/syslinux/isolinux.bin
file copy ${hostPkgs.syslinux}/share/syslinux/ldlinux.c32 boot/syslinux/ldlinux.c32
file copy ${hostPkgs.syslinux}/share/syslinux/libcom32.c32 boot/syslinux/libcom32.c32
file copy ${hostPkgs.syslinux}/share/syslinux/mboot.c32 boot/syslinux/mboot.c32
exec chmod +w boot/syslinux/isolinux.bin
catch { exec ${hostPkgs.cdrkit}/bin/mkisofs -o $target \
-b syslinux/isolinux.bin -c syslinux/boot.cat \
-no-emul-boot -boot-load-size 4 -boot-info-table \
-iso-level 2 \
boot
}
puts "built ISO?"
}
##
# Wait for a specific output of a already running spawned process
#
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 env modules qemu_mem
file mkdir boot
build_core core-nova.o $modules boot/image.elf
set out $env(out)
build_iso $out/test.iso
global spawn_id
spawn ${hostPkgs.qemu_test}/bin/qemu-system-x86_64 -cdrom $out/test.iso -nographic -m $qemu_mem
wait_for_output $wait_for_re $timeout_value $spawn_id
}
'';
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 "$testConfig" > $out/test.config
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 testConfig=\"$testConfig\"" \
--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 test; };
in {
callTest = path: args:
makeTest (import path ({
pkgs = testPkgs;
inherit lib;
} // args));
}

1
tests/fs_report.nix

@ -13,6 +13,7 @@ with pkgs;
file link -s ram_fs ${depot.ram_fs}/bin/ram_fs
file link -s vfs.lib.so ${depot.vfs}/lib/vfs.lib.so
file link -s test-fs_report ${depot.test-fs_report}/bin/test-fs_report
append modules { fs_report fs_rom ram_fs vfs.lib.so test-fs_report }
run_genode_until {child "test-fs_report" exited with exit value 0} 15
'';
}

137
tests/genode.ld

@ -0,0 +1,137 @@
/*
* \brief Linker script for Genode programs
* \author Christian Helmuth
* \date 2006-04-12
*/
/*
* Copyright (C) 2006-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
ENTRY(_start)
PHDRS
{
ro PT_LOAD;
rw PT_LOAD;
boot PT_LOAD FLAGS(4);
}
SECTIONS
{
.text : {
/* begin of program image (link address) */
_prog_img_beg = .;
/* put entry code at the start of the text segment / raw binary */
KEEP (*(.text.crt0))
*(.init)
*(.text .text.* .gnu.linkonce.t.*)
*(.fini)
*(.rodata .rodata.* .gnu.linkonce.r.*)
. = ALIGN(0x08);
_ctors_start = .;
KEEP (*(.ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.init_array)) /* list of constructors specific for ARM eabi */
_ctors_end = .;
_dtors_start = .;
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
_dtors_end = .;
} : ro = 0x0
/* Linux: exception section for uaccess mechanism */
__ex_table : { *(__ex_table) }
.eh_frame_hdr : { *(.eh_frame_hdr) }
__eh_frame_hdr_start = SIZEOF(.eh_frame_hdr) > 0 ? ADDR(.eh_frame_hdr) : 0;
__eh_frame_hdr_end = SIZEOF(.eh_frame_hdr) > 0 ? . : 0;
. = ALIGN(0x1000);
.data : {
/*
* Leave space for parent capability parameters at start of data
* section. The protection domain creator is reponsible for storing
* sane values here.
*/
_parent_cap = .;
_parent_cap_thread_id = .;
LONG(0xffffffff);
_parent_cap_local_name = .;
LONG(0xffffffff);
LONG(0xffffffff);
LONG(0xffffffff);
LONG(0xffffffff);
LONG(0xffffffff);
LONG(0xffffffff);
LONG(0xffffffff);
/*
* Platform-specific entry for Fiasco.OC.
*
* PIC-code compiled for Fiasco.OC, needs some PIC-compatible
* way to enter the kernel, the fixed address of the kernel
* entry code address needs to be found here.
*/
__l4sys_invoke_indirect = .;
LONG(0xeacff000);
*(.data .gnu.linkonce.d.*)
/* include all data subsections except those of the boot modules */
*(EXCLUDE_FILE (*boot_modules.o) .data.*)
} : rw
/* exception frames for C++ */
.eh_frame : {
__eh_frame_start__ = .;
__eh_frame_start = .;
KEEP (*(.eh_frame))
__eh_frame_end = .;
LONG(0)
} : rw
.gcc_except_table : {
KEEP(*(.gcc_except_table))
KEEP(*(.gcc_except_table.*))
}
.dynamic : { *(.dynamic) }
/* .ARM.exidx is sorted, so has to go in its own output section */
__exidx_start = .;
.ARM.exidx : {
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
}
__exidx_end = .;
.ARM.extab : {
*(.ARM.extab*)
} : rw
.bss : {
_bss_start = ALIGN(4);
*(.bss .bss.* .gnu.linkonce.b.* COMMON)
}
_bss_end = ALIGN(4);
/* separate location for the binaries of the boot modules */
.data.boot_modules_binaries : { *(.data.boot_modules_binaries) } : boot
/* end of program image -- must be after last section */
_prog_img_end = .;
/DISCARD/ : {
*(.note)
*(.note.ABI-tag)
*(.comment)
}
}

3
tests/libc.nix

@ -8,11 +8,14 @@ rec {
testConfig = lib.renderDhallInit ./libc.dhall "{=}";
testScript = ''
global qemu_mem
file link -s libc.lib.so ${depot.libc}/lib/libc.lib.so
file link -s libm.lib.so ${depot.libc}/lib/libm.lib.so
file link -s posix.lib.so ${depot.posix}/lib/posix.lib.so
file link -s vfs.lib.so ${depot.vfs}/lib/vfs.lib.so
file link -s test-libc ${depot.test-libc}/bin/test-libc
append modules { libc.lib.so libm.lib.so posix.lib.so vfs.lib.so test-libc }
set qemu_mem 384
run_genode_until "child .* exited with exit value 0.*\n" 30
'';
}

1
tests/log.nix

@ -9,6 +9,7 @@ rec {
testScript = ''
file link -s test-log ${genode.base}/bin/test-log
append modules { test-log }
run_genode_until {Test done.} 10
'';
}

6
tests/nova-bss.ld

@ -0,0 +1,6 @@
SECTIONS
{
.data : {
*(.bss .bss.* .gnu.linkonce.b.* COMMON)
} : rw
}

5
tests/nova-isolinux.cfg

@ -0,0 +1,5 @@
SERIAL
DEFAULT 0
LABEL 0
KERNEL mboot.c32
APPEND /hypervisor iommu novpid serial --- /image.elf

75
tests/nova-test-driver.exp

@ -0,0 +1,75 @@
#!/usr/bin/env expect
##
# Generate assembly code aggregating boot-module data from specified files.
#
proc generate_boot_modules_asm {modules} {
# architecture dependent definitions
set address_type ".quad"
# header
set asm_src {}
append asm_src ".set MIN_PAGE_SIZE_LOG2, 12\n"
append asm_src ".set DATA_ACCESS_ALIGNM_LOG2, 3\n"
append asm_src "\n"
append asm_src ".section .data\n"
append asm_src "\n"
append asm_src ".p2align DATA_ACCESS_ALIGNM_LOG2\n"
append asm_src ".global _boot_modules_headers_begin\n"
append asm_src "_boot_modules_headers_begin:\n"
append asm_src "\n"
# module list
set i 0
foreach module $modules {
incr i
append asm_src "${address_type} _boot_module_${i}_name\n"
append asm_src "${address_type} _boot_module_${i}_begin\n"
append asm_src "${address_type} _boot_module_${i}_end -"
append asm_src " _boot_module_${i}_begin\n"
append asm_src "\n"
}
append asm_src ".global _boot_modules_headers_end\n"
append asm_src "_boot_modules_headers_end:\n"
append asm_src "\n"
# module names
set i 0
foreach module $modules {
incr i
append asm_src ".p2align DATA_ACCESS_ALIGNM_LOG2\n"
append asm_src "_boot_module_${i}_name:\n"
append asm_src ".string \"${module}\"\n"
append asm_src ".byte 0\n"
append asm_src "\n"
}
# header end
append asm_src ".section .data.boot_modules_binaries\n"
append asm_src "\n"
append asm_src ".global _boot_modules_binaries_begin\n"
append asm_src "_boot_modules_binaries_begin:\n"
append asm_src "\n"
# module data
set i 0
foreach module $modules {
incr i
append asm_src ".p2align MIN_PAGE_SIZE_LOG2\n"
append asm_src "_boot_module_${i}_begin:\n"
append asm_src ".incbin \"${module}\"\n"
append asm_src "_boot_module_${i}_end:\n"
append asm_src "\n"
}
append asm_src ".p2align MIN_PAGE_SIZE_LOG2\n"
append asm_src ".global _boot_modules_binaries_end\n"
append asm_src "_boot_modules_binaries_end:\n"
return $asm_src
}
eval $env(baseSetup)
eval $env(testScript)

3
tests/signal.nix

@ -9,6 +9,7 @@ rec {
testScript = ''
file link -s test-signal ${depot.test-signal}/bin/test-signal
run_genode_until {--- Signalling test finished ---} 60
append modules { test-signal }
run_genode_until {--- Signalling test finished ---} 80
'';
}

3
tests/solo5.nix

@ -8,8 +8,11 @@ rec {
testConfig = lib.renderDhallInit ./solo5.dhall "{=}";
testScript = ''
global modules
file link -s solo5.lib.so ${solo5}/lib/solo5-bindings-genode/solo5.lib.so
file link -s solo5-test_hello ${solo5.tests}/bin/solo5-test_hello
append modules { solo5.lib.so solo5-test_hello }
run_genode_until "child .* exited with exit value 0.*\n" 30
'';
}

Loading…
Cancel
Save