test-modules: convert to use LkmcCliFunction

This commit is contained in:
Ciro Santilli
2019-01-22 00:00:00 +00:00
committed by Ciro Santilli 六四事件 法轮功
parent 4a92813252
commit 718941f3cf
8 changed files with 112 additions and 77 deletions

View File

@@ -3159,15 +3159,17 @@ Result on <<p51>> at bad30f513c46c1b0995d3a10c0d9bc2a33dc4fa0:
=== User mode tests === User mode tests
Automatically run non-interactive userland tests that don't depend on any kernel modules: Automatically run non-interactive userland tests that can be run in user mode simulation:
.... ....
./build-userland --all-archs --all-emulators ./build-userland --all-archs --all-emulators
./build-userland --all-archs --all-emulators --static --userland-build-id static ./build-userland --all-archs --all-emulators --static --userland-build-id static
./test-userland --all-archs --all-emulators ./test-user-mode --all-archs --all-emulators
.... ....
Source: link:test-userland[] Source: link:test-user-mode[]
This testing excludes notably kernel module tests which depend on a full running kernel.
The gem5 tests require building statically with build id `static`, see also: <<gem5-syscall-emulation-mode>>. TODO automate this better. The gem5 tests require building statically with build id `static`, see also: <<gem5-syscall-emulation-mode>>. TODO automate this better.
@@ -11696,11 +11698,11 @@ They contain data structs and magic constant for kernel to userland communicatio
Userland test programs. They can be used in the following ways: Userland test programs. They can be used in the following ways:
* inside a full system simulation * inside a full system simulation, e.g.: <<qemu-buildroot-setup>>
* inside <<user-mode-simulation>> * inside <<user-mode-simulation>>
* directly on the host * directly on the host: <<userland-directory-host-build>>
For usage inside full system, first ensure that Buildroot has been built for the toolchain, and then build the examples with: For usage inside full system simulation, first ensure that Buildroot has been built for the toolchain, and then build the examples with:
.... ....
./build-userland ./build-userland
@@ -11898,7 +11900,7 @@ Sources:
* link:build-test[] * link:build-test[]
* link:test[] * link:test[]
* link:test-modules[] * link:test-userland[]
* <<user-mode-tests>> * <<user-mode-tests>>
* <<baremetal-tests>> * <<baremetal-tests>>
@@ -11909,7 +11911,7 @@ See the sources of those test scripts to learn how to run more specialized tests
One important tip is that you can select multiple archs and emulators of interest with a command such as: One important tip is that you can select multiple archs and emulators of interest with a command such as:
.... ....
./test-userland \ ./test-user-mode \
--arch x86_64 \ --arch x86_64 \
--arch aarch64 \ --arch aarch64 \
--emulator gem5 \ --emulator gem5 \

View File

@@ -1,25 +1,27 @@
#!/bin/sh #!/bin/sh
test_dir="${1:-.}"
for test in \ for test in \
/anonymous_inode.sh \ anonymous_inode.sh \
/character_device.sh \ character_device.sh \
/character_device_create.sh \ character_device_create.sh \
/debugfs.sh \ debugfs.sh \
/dep.sh \ dep.sh \
/fops.sh \ fops.sh \
/init_module.sh \ init_module.sh \
/ioctl.sh \ ioctl.sh \
/kstrto.sh \ kstrto.sh \
/mmap.sh \ mmap.sh \
/netlink.sh \ netlink.sh \
/params.sh \ params.sh \
/procfs.sh \ procfs.sh \
/seq_file.sh \ seq_file.sh \
/seq_file_single_open.sh \ seq_file_single_open.sh \
/sysfs.sh \ sysfs.sh \
; do ; do
if ! "$test"; then if ! "${test_dir}/${test}"; then
echo "lkmc_test_fail: ${test}" echo "Test failed: ${test}"
test_fail.sh
exit 1 exit 1
fi fi
done done
echo lkmc_test_pass echo 'All tests passed.'

4
rootfs_overlay/test_fail.sh Executable file
View File

@@ -0,0 +1,4 @@
#!/bin/sh
# Print the magic fail string that our scripts detect
# as a simulation failure.
echo lkmc_test_fail

7
run
View File

@@ -618,9 +618,10 @@ Run QEMU with VNC instead of the default SDL. Connect to it with:
if not self.env['userland']: if not self.env['userland']:
if os.path.exists(self.env['guest_terminal_file']): if os.path.exists(self.env['guest_terminal_file']):
with open(self.env['guest_terminal_file'], 'br') as logfile: with open(self.env['guest_terminal_file'], 'br') as logfile:
lines = logfile.readlines() for line in logfile.readlines():
if lines and lines[-1].rstrip() == self.env['magic_fail_string']: if line.rstrip() == self.env['magic_fail_string']:
exit_status = 1 exit_status = 1
break
if exit_status != 0: if exit_status != 0:
self.log_error('simulation error detected by parsing logs') self.log_error('simulation error detected by parsing logs')
return exit_status return exit_status

4
test
View File

@@ -10,7 +10,7 @@ while [ $# -gt 0 ]; do
esac esac
done done
./bench-boot --size "$test_size" ./bench-boot --size "$test_size"
./test-modules ./test-modules --all-archs --all-emulators
./test-gdb --all-archs --all-emulators ./test-gdb --all-archs --all-emulators
./test-baremetal --all-archs --all-emulators ./test-baremetal --all-archs --all-emulators
./test-userland --all-archs --all-emulators ./test-user-mode --all-archs --all-emulators

View File

@@ -1,7 +0,0 @@
#!/usr/bin/env bash
set -eu
root_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
getvar="${root_dir}/getvar"
termout_file="$("$getvar" termout_file)"
./run --eval-busybox '/test_all.sh;/poweroff.out' --kvm
grep -q lkmc_test_pass "$termout_file"

64
test-user-mode Executable file
View File

@@ -0,0 +1,64 @@
#!/usr/bin/env python3
import os
import sys
import common
class Main(common.LkmcCliFunction):
def __init__(self):
super().__init__(
defaults={
'print_time': False,
},
description='''\
https://github.com/cirosantilli/linux-kernel-module-cheat#user-mode-tests
'''
,
)
self.add_argument(
'tests',
nargs='*',
help='''\
If given, run only the given tests. Otherwise, run all tests.
'''
)
def timed_main(self):
run = self.import_path_main('run')
run_args = self.get_common_args()
if self.env['emulator'] == 'gem5':
run_args['userland_build_id'] = 'static'
if self.env['tests'] == []:
sources = [
'add.c',
'hello.c',
'hello_cpp.cpp',
'print_argv.c',
]
if self.env['arch'] == 'x86_64':
arch_sources = [
'asm_hello'
]
elif self.env['arch'] == 'aarch64':
arch_sources = [
'asm_hello'
]
else:
arch_sources = []
arch_sources[:] = [os.path.join('arch', self.env['arch'], arch_source) for arch_source in arch_sources]
sources.extend(arch_sources)
else:
sources = self.env['tests']
for source in sources:
run_args['userland'] = source
run_args['background'] = True
test_id_string = self.test_setup(run_args, source)
exit_status = run(**run_args)
self.test_teardown(run)
if exit_status != 0:
self.log_error('test failed, program exit status: {} test id: {}'.format(exit_status, test_id_string))
sys.exit(1)
if __name__ == '__main__':
Main().cli()

View File

@@ -11,50 +11,19 @@ class Main(common.LkmcCliFunction):
defaults={ defaults={
'print_time': False, 'print_time': False,
}, },
) description='''\
self.add_argument( Boot Linux and run all non-interactive userland tests, including those
'tests', for kernel modules.
nargs='*',
help='''\ Detect failure based on the magic terminal failure string.
If given, run only the given tests. Otherwise, run all tests.
''' '''
) )
def timed_main(self): def timed_main(self):
run = self.import_path_main('run') run = self.import_path_main('run')
run_args = self.get_common_args() run_args = self.get_common_args()
if self.env['emulator'] == 'gem5': run_args['eval_after'] = '/test_all.sh;/poweroff.out'
run_args['userland_build_id'] = 'static' run(**run_args)
if self.env['tests'] == []:
sources = [
'add.c',
'hello.c',
'hello_cpp.cpp',
'print_argv.c',
]
if self.env['arch'] == 'x86_64':
arch_sources = [
'asm_hello'
]
elif self.env['arch'] == 'aarch64':
arch_sources = [
'asm_hello'
]
else:
arch_sources = []
arch_sources[:] = [os.path.join('arch', self.env['arch'], arch_source) for arch_source in arch_sources]
sources.extend(arch_sources)
else:
sources = self.env['tests']
for source in sources:
run_args['userland'] = source
run_args['background'] = True
test_id_string = self.test_setup(run_args, source)
exit_status = run(**run_args)
self.test_teardown(run)
if exit_status != 0:
self.log_error('test failed, program exit status: {} test id: {}'.format(exit_status, test_id_string))
sys.exit(1)
if __name__ == '__main__': if __name__ == '__main__':
Main().cli() Main().cli()