[LTP] [RFC PATCH 2/2] testcaes/lib: Add shell loader

Martin Doucha mdoucha@suse.cz
Wed Jul 24 14:54:19 CEST 2024


Hi,
one note below.

On 16. 07. 24 17:36, Cyril Hrubis wrote:
> This commit implements a shell loader so that we don't have to write a C
> loader for each LTP shell test. The idea is simple, the loader parses
> the shell test and prepares the tst_test structure accordingly, then
> runs the actual shell test. Only small subset of the flags is
> implemented at the moment, since this is RFC, however it should be clear
> where this is going.
> 
> Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
> ---
>   testcases/lib/.gitignore                      |  1 +
>   testcases/lib/Makefile                        |  3 +-
>   testcases/lib/run_tests.sh                    |  2 +
>   testcases/lib/tests/shell_loader.sh           | 11 ++-
>   .../lib/tests/shell_loader_all_filesystems.sh | 22 ++++++
>   testcases/lib/tst_run_shell.c                 | 78 +++++++++++++++++++
>   6 files changed, 114 insertions(+), 3 deletions(-)
>   mode change 100644 => 100755 testcases/lib/tests/shell_loader.sh
>   create mode 100755 testcases/lib/tests/shell_loader_all_filesystems.sh
>   create mode 100644 testcases/lib/tst_run_shell.c
> 
> diff --git a/testcases/lib/.gitignore b/testcases/lib/.gitignore
> index d0dacf62a..385f3c3ca 100644
> --- a/testcases/lib/.gitignore
> +++ b/testcases/lib/.gitignore
> @@ -24,3 +24,4 @@
>   /tst_supported_fs
>   /tst_timeout_kill
>   /tst_res_
> +/tst_run_shell
> diff --git a/testcases/lib/Makefile b/testcases/lib/Makefile
> index 928d76d62..fef284e35 100644
> --- a/testcases/lib/Makefile
> +++ b/testcases/lib/Makefile
> @@ -13,6 +13,7 @@ MAKE_TARGETS		:= tst_sleep tst_random tst_checkpoint tst_rod tst_kvcmp\
>   			   tst_getconf tst_supported_fs tst_check_drivers tst_get_unused_port\
>   			   tst_get_median tst_hexdump tst_get_free_pids tst_timeout_kill\
>   			   tst_check_kconfigs tst_cgctl tst_fsfreeze tst_ns_create tst_ns_exec\
> -			   tst_ns_ifmove tst_lockdown_enabled tst_secureboot_enabled tst_res_
> +			   tst_ns_ifmove tst_lockdown_enabled tst_secureboot_enabled tst_res_\
> +			   tst_run_shell
>   
>   include $(top_srcdir)/include/mk/generic_trunk_target.mk
> diff --git a/testcases/lib/run_tests.sh b/testcases/lib/run_tests.sh
> index 88607b146..9637ae327 100755
> --- a/testcases/lib/run_tests.sh
> +++ b/testcases/lib/run_tests.sh
> @@ -8,3 +8,5 @@ export PATH=$PATH:$PWD:$PWD/tests/
>   ./tests/shell_test04
>   ./tests/shell_test05
>   ./tests/shell_test06
> +./tst_run_shell shell_loader.sh
> +./tst_run_shell shell_loader_all_filesystems.sh
> diff --git a/testcases/lib/tests/shell_loader.sh b/testcases/lib/tests/shell_loader.sh
> old mode 100644
> new mode 100755
> index c3b3cf5fd..1a255fdee
> --- a/testcases/lib/tests/shell_loader.sh
> +++ b/testcases/lib/tests/shell_loader.sh
> @@ -1,5 +1,12 @@
> -#!/usr/bin/env tst_run_shell
> +#!/bin/sh
> +#
> +# needs_tmpdir=1
>   
>   . tst_env.sh
>   
> -tst_res TPASS "Shell loader works fine!"
> +case "$PWD" in
> +	/tmp/*)
> +	tst_res TPASS "We are running in temp directory in $PWD";;
> +	*)
> +	tst_res TFAIL "We are not running in temp directory but $PWD";;
> +esac
> diff --git a/testcases/lib/tests/shell_loader_all_filesystems.sh b/testcases/lib/tests/shell_loader_all_filesystems.sh
> new file mode 100755
> index 000000000..86d09d393
> --- /dev/null
> +++ b/testcases/lib/tests/shell_loader_all_filesystems.sh
> @@ -0,0 +1,22 @@
> +#!/bin/sh
> +#
> +# needs_root=1
> +# mount_device=1
> +# all_filesystems=1
> +
> +TST_MNTPOINT=ltp_mntpoint
> +
> +. tst_env.sh
> +
> +tst_res TINFO "IN shell"
> +
> +mounted=$(grep $TST_MNTPOINT /proc/mounts)

This check might produce false positive for example when another LTP 
shell script runs in parallel in another temp directory. I'd recommend 
using $(realpath ...) to disambiguate the mountpoints.

> +
> +if [ -n "$mounted" ]; then
> +	device=$(echo $mounted |cut -d' ' -f 1)
> +	path=$(echo $mounted |cut -d' ' -f 2)
> +
> +	tst_res TPASS "$device mounted at $path"
> +else
> +	tst_res TFAIL "Device not mounted!"
> +fi
> diff --git a/testcases/lib/tst_run_shell.c b/testcases/lib/tst_run_shell.c
> new file mode 100644
> index 000000000..583807376
> --- /dev/null
> +++ b/testcases/lib/tst_run_shell.c
> @@ -0,0 +1,78 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2024 Cyril Hrubis <chrubis@suse.cz>
> + */
> +#define TST_NO_DEFAULT_MAIN
> +#include "tst_test.h"
> +#include "tst_safe_stdio.h"
> +
> +static char *shell_filename;
> +
> +static void run_shell(void)
> +{
> +	tst_run_shell(shell_filename, NULL);
> +}
> +
> +struct tst_test test = {
> +	.test_all = run_shell,
> +	.runs_shell = 1,
> +};
> +
> +static void print_help(void)
> +{
> +	printf("Usage: tst_shell_loader ltp_shell_test.sh ...");
> +}
> +
> +#define FLAG_MATCH(str, name) (!strcmp(str, name "=1"))
> +#define PARAM_MATCH(str, name) (!strncmp(str, name "=", sizeof(name)))
> +#define PARAM_VAL(str, name) strdup(str + sizeof(name))
> +
> +static void prepare_test_struct(void)
> +{
> +	FILE *f;
> +	char line[4096];
> +	char path[4096];
> +
> +	if (tst_get_path(shell_filename, path, sizeof(path)) == -1)
> +		tst_brk(TBROK, "Failed to find %s in $PATH", shell_filename);
> +
> +	f = SAFE_FOPEN(path, "r");
> +
> +	while (fscanf(f, "%4096s[^\n]", line) != EOF) {
> +		if (FLAG_MATCH(line, "needs_tmpdir"))
> +			test.needs_tmpdir = 1;
> +		else if (FLAG_MATCH(line, "needs_root"))
> +			test.needs_root = 1;
> +		else if (FLAG_MATCH(line, "needs_device"))
> +			test.needs_device = 1;
> +		else if (FLAG_MATCH(line, "needs_checkpoints"))
> +			test.needs_checkpoints = 1;
> +		else if (FLAG_MATCH(line, "needs_overlay"))
> +			test.needs_overlay = 1;
> +		else if (FLAG_MATCH(line, "format_device"))
> +			test.format_device = 1;
> +		else if (FLAG_MATCH(line, "mount_device"))
> +			test.mount_device = 1;
> +		else if (PARAM_MATCH(line, "TST_MNTPOINT"))
> +			test.mntpoint = PARAM_VAL(line, "TST_MNTPOINT");
> +		else if (FLAG_MATCH(line, "all_filesystems"))
> +			test.all_filesystems = 1;
> +	}
> +
> +	fclose(f);
> +}
> +
> +int main(int argc, char *argv[])
> +{
> +	if (argc < 2)
> +		goto help;
> +
> +	shell_filename = argv[1];
> +
> +	prepare_test_struct();
> +
> +	tst_run_tcases(argc - 1, argv + 1, &test);
> +help:
> +	print_help();
> +	return 1;
> +}

-- 
Martin Doucha   mdoucha@suse.cz
SW Quality Engineer
SUSE LINUX, s.r.o.
CORSO IIa
Krizikova 148/34
186 00 Prague 8
Czech Republic



More information about the ltp mailing list