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

Cyril Hrubis chrubis@suse.cz
Tue Jul 16 17:36:04 CEST 2024


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)
+
+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;
+}
-- 
2.44.2



More information about the ltp mailing list