[RFC/PATCH v3 2/2] tests: Improve tests for watchdog ioctl commands
Sahil Siddiq
icegambit91 at gmail.com
Wed Aug 7 19:59:56 UTC 2024
Add new tests for WDIOC_GETSUPPORT and WDIOC_SETOPTIONS
decoders. Also enhance tests for currently available
watchdog ioctl decoders. This enables the verification
of their behaviour when:
1. the ioctl is successful (returns a non-negative
integer).
2. strace is run with the -v option.
* tests/.gitignore (ioctl_watchdog-success.c,
ioctl_watchdog-success-v.c): New entries.
* tests/Makefile.am (ioctl_watchdog-success.c,
ioctl_watchdog-success-v.c): New entries.
* tests/gen_tests.in (ioctl_watchdog-success.c,
ioctl_watchdog-success-v.c): New entries.
* tests/ioctl_watchdog-success.c: New file.
* tests/ioctl_watchdog-success-v.c: New file.
* tests/ioctl_watchdog.c:
- (do_ioctl, do_ioctl_ptr): New functions.
- (main): Place argc, argv in argument list.
- (WDIOC_GETSUPPORT, WDIOC_SETOPTIONS): Add decoder tests.
- (WDIOC_GET*): Improve existing decoder tests.
Signed-off-by: Sahil Siddiq <sahilcdq at proton.me>
---
Changes v1 -> v2: None
Changes v2 -> v3:
- Moved tests from v2 into its own commit.
- tests/.gitignore (ioctl_watchdog-success.c,
ioctl_watchdog-success-v.c): New entries.
- tests/Makefile.am (ioctl_watchdog-success.c,
ioctl_watchdog-success-v.c): New entries.
- tests/gen_tests.in (ioctl_watchdog-success.c,
ioctl_watchdog-success-v.c): New entries.
- ioctl_watchdog-success-v.c: New file.
- ioctl_watchdog-success.c: New file.
- tests/ioctl_watchdog.c:
- Added tests that use syscall retval injection.
- Added tests to check behaviour under -v/--no-abbrev
option.
tests/.gitignore | 2 +
tests/Makefile.am | 2 +
tests/gen_tests.in | 4 +-
tests/ioctl_watchdog-success-v.c | 2 +
tests/ioctl_watchdog-success.c | 2 +
tests/ioctl_watchdog.c | 154 ++++++++++++++++++++++++++-----
6 files changed, 143 insertions(+), 23 deletions(-)
create mode 100644 tests/ioctl_watchdog-success-v.c
create mode 100644 tests/ioctl_watchdog-success.c
diff --git a/tests/.gitignore b/tests/.gitignore
index 1944c808f..b437b21d9 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -430,6 +430,8 @@ ioctl_v4l2-v-Xabbrev
ioctl_v4l2-v-Xraw
ioctl_v4l2-v-Xverbose
ioctl_watchdog
+ioctl_watchdog-success
+ioctl_watchdog-success-v
ioctl_winsize
ioperm
iopl
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 378146b6f..e1254c364 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -243,6 +243,8 @@ check_PROGRAMS = $(PURE_EXECUTABLES) \
ioctl_v4l2-success-v-Xabbrev \
ioctl_v4l2-success-v-Xraw \
ioctl_v4l2-success-v-Xverbose \
+ ioctl_watchdog-success \
+ ioctl_watchdog-success-v \
ioprio--pidns-translation \
ip_local_port_range-success \
ip_local_port_range-success-Xabbrev \
diff --git a/tests/gen_tests.in b/tests/gen_tests.in
index 80e4b266f..140d43a2b 100644
--- a/tests/gen_tests.in
+++ b/tests/gen_tests.in
@@ -450,7 +450,9 @@ ioctl_v4l2-v +ioctl.test -v
ioctl_v4l2-v-Xabbrev +ioctl.test -v -Xabbrev
ioctl_v4l2-v-Xraw +ioctl.test -v -Xraw
ioctl_v4l2-v-Xverbose +ioctl.test -v -Xverbose
-ioctl_watchdog +ioctl.test
+ioctl_watchdog +ioctl.test -a14
+ioctl_watchdog-success +ioctl-success.sh -a14
+ioctl_watchdog-success-v +ioctl-success.sh -a14 -v
ioctl_winsize +ioctl.test
ioperm -a27
iopl -a8
diff --git a/tests/ioctl_watchdog-success-v.c b/tests/ioctl_watchdog-success-v.c
new file mode 100644
index 000000000..69b3c590b
--- /dev/null
+++ b/tests/ioctl_watchdog-success-v.c
@@ -0,0 +1,2 @@
+#define VERBOSE 1
+#include "ioctl_watchdog-success.c"
diff --git a/tests/ioctl_watchdog-success.c b/tests/ioctl_watchdog-success.c
new file mode 100644
index 000000000..34e0b997d
--- /dev/null
+++ b/tests/ioctl_watchdog-success.c
@@ -0,0 +1,2 @@
+#define INJECT_RETVAL 42
+#include "ioctl_watchdog.c"
diff --git a/tests/ioctl_watchdog.c b/tests/ioctl_watchdog.c
index 744947e87..f3ad2d787 100644
--- a/tests/ioctl_watchdog.c
+++ b/tests/ioctl_watchdog.c
@@ -10,6 +10,7 @@
#include "tests.h"
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <linux/watchdog.h>
@@ -18,41 +19,150 @@
#include "xlat/watchdog_ioctl_cmds.h"
#undef XLAT_MACROS_ONLY
+static const char *errstr;
+
+static int
+do_ioctl(kernel_ulong_t cmd, kernel_ulong_t arg)
+{
+ int rc = ioctl(-1, cmd, arg);
+ errstr = sprintrc(rc);
+
+#ifdef INJECT_RETVAL
+ if (rc != INJECT_RETVAL)
+ error_msg_and_fail("Return value [%d] does not match"
+ " expectations [%d]", rc, INJECT_RETVAL);
+
+ static char inj_errstr[4096];
+
+ snprintf(inj_errstr, sizeof(inj_errstr), "%s (INJECTED)", errstr);
+ errstr = inj_errstr;
+#endif
+
+ return rc;
+}
+
+static int
+do_ioctl_ptr(kernel_ulong_t cmd, const void *arg)
+{
+ return do_ioctl(cmd, (uintptr_t) arg);
+}
+
int
-main(void)
+main(int argc, const char *argv[])
{
- int val = 123;
+#ifdef INJECT_RETVAL
+ unsigned long num_skip;
+ bool locked = false;
+
+ if (argc < 2)
+ error_msg_and_fail("Usage: %s NUM_SKIP", argv[0]);
+
+ num_skip = strtoul(argv[1], NULL, 0);
+
+ for (size_t i = 0; i < num_skip; i++) {
+ long ret = ioctl(-1, WDIOC_GETSUPPORT, 0);
+
+ printf("ioctl(-1, WDIOC_GETSUPPORT, NULL) = %s%s\n",
+ sprintrc(ret),
+ ret == INJECT_RETVAL ? " (INJECTED)" : "");
+
+ if (ret != INJECT_RETVAL)
+ continue;
+
+ locked = true;
+ break;
+ }
+
+ if (!locked)
+ error_msg_and_fail("Issued %lu ioctl syscalls but failed"
+ " to detect an injected return code %d",
+ num_skip, INJECT_RETVAL);
+#endif
+
+ TAIL_ALLOC_OBJECT_CONST_PTR(struct watchdog_info, ident);
+#define IDENT_OPTIONS 0x87ff
+ ident->options = IDENT_OPTIONS;
+ ident->firmware_version = 6;
+ memset(ident->identity, 'A', sizeof(ident->identity));
+ ident->identity[sizeof(ident->identity) - 1] = '\0';
+
+ int rc = do_ioctl_ptr(WDIOC_GETSUPPORT, ident);
+ if (rc < 0) {
+ printf("ioctl(-1, WDIOC_GETSUPPORT, %p) = %s\n", ident, errstr);
+ } else {
+ printf("ioctl(-1, WDIOC_GETSUPPORT, {options=%s, ",
+ XLAT_KNOWN(IDENT_OPTIONS,
+ "WDIOF_OVERHEAT|WDIOF_FANFAULT|"
+ "WDIOF_EXTERN1|WDIOF_EXTERN2|"
+ "WDIOF_POWERUNDER|WDIOF_CARDRESET|"
+ "WDIOF_POWEROVER|WDIOF_SETTIMEOUT|"
+ "WDIOF_MAGICCLOSE|WDIOF_PRETIMEOUT|"
+ "WDIOF_ALARMONLY|WDIOF_KEEPALIVEPING"));
+#if VERBOSE
+ printf("firmware_version=%u, identity=\"%s\"",
+ ident->firmware_version,
+ ident->identity);
+#else
+ printf("...");
+#endif
+ printf("}) = %s\n", errstr);
+ }
+
+ static const struct {
+ uint32_t cmd;
+ const char *str;
+ } simple_get_cmds[] = {
+ { ARG_STR(WDIOC_GETSTATUS) },
+ { ARG_STR(WDIOC_GETBOOTSTATUS) },
+ { ARG_STR(WDIOC_GETTEMP) },
+ { ARG_STR(WDIOC_GETTIMEOUT) },
+ { ARG_STR(WDIOC_GETPRETIMEOUT) },
+ { ARG_STR(WDIOC_GETTIMELEFT) },
+ };
- ioctl(-1, WDIOC_GETSTATUS, &val);
- printf("ioctl(-1, WDIOC_GETSTATUS, %p)" RVAL_EBADF, &val);
+ TAIL_ALLOC_OBJECT_CONST_PTR(int, val);
+ *val = 123;
- ioctl(-1, WDIOC_GETBOOTSTATUS, &val);
- printf("ioctl(-1, WDIOC_GETBOOTSTATUS, %p)" RVAL_EBADF, &val);
+ for (size_t i = 0; i < ARRAY_SIZE(simple_get_cmds); ++i) {
+ int rc = do_ioctl_ptr(simple_get_cmds[i].cmd, val);
+ printf("ioctl(-1, " XLAT_FMT ", ",
+ XLAT_SEL(simple_get_cmds[i].cmd, simple_get_cmds[i].str));
+ if (rc < 0) {
+ printf("%p) = %s\n", val, errstr);
+ } else {
+ printf("[%d]) = %s\n", *val, errstr);
+ }
+ }
- ioctl(-1, WDIOC_GETTEMP, &val);
- printf("ioctl(-1, WDIOC_GETTEMP, %p)" RVAL_EBADF, &val);
+ do_ioctl_ptr(WDIOC_SETTIMEOUT, val);
+ printf("ioctl(-1, WDIOC_SETTIMEOUT, [123]) = %s\n", errstr);
- ioctl(-1, WDIOC_GETTIMEOUT, &val);
- printf("ioctl(-1, WDIOC_GETTIMEOUT, %p)" RVAL_EBADF, &val);
+ do_ioctl_ptr(WDIOC_SETPRETIMEOUT, val);
+ printf("ioctl(-1, WDIOC_SETPRETIMEOUT, [123]) = %s\n", errstr);
- ioctl(-1, WDIOC_GETPRETIMEOUT, &val);
- printf("ioctl(-1, WDIOC_GETPRETIMEOUT, %p)" RVAL_EBADF, &val);
+ TAIL_ALLOC_OBJECT_CONST_PTR(unsigned int, options);
- ioctl(-1, WDIOC_GETTIMELEFT, &val);
- printf("ioctl(-1, WDIOC_GETTIMELEFT, %p)" RVAL_EBADF, &val);
+ *options = 1;
+ do_ioctl_ptr(WDIOC_SETOPTIONS, options);
+ printf("ioctl(-1, WDIOC_SETOPTIONS, [%s]) = %s\n",
+ XLAT_KNOWN(0x1, "WDIOS_DISABLECARD"), errstr);
- ioctl(-1, WDIOC_SETTIMEOUT, &val);
- printf("ioctl(-1, WDIOC_SETTIMEOUT, [123])" RVAL_EBADF);
+ *options = 6;
+ do_ioctl_ptr(WDIOC_SETOPTIONS, options);
+ printf("ioctl(-1, WDIOC_SETOPTIONS, [%s]) = %s\n",
+ XLAT_KNOWN(0x6, "WDIOS_ENABLECARD|WDIOS_TEMPPANIC"), errstr);
- ioctl(-1, WDIOC_SETPRETIMEOUT, &val);
- printf("ioctl(-1, WDIOC_SETPRETIMEOUT, [123])" RVAL_EBADF);
+ *options = 0xfed8;
+ do_ioctl_ptr(WDIOC_SETOPTIONS, options);
+ printf("ioctl(-1, WDIOC_SETOPTIONS, [%s]) = %s\n",
+ XLAT_UNKNOWN(0xfed8, "WDIOS_???"), errstr);
- ioctl(-1, WDIOC_KEEPALIVE);
- printf("ioctl(-1, WDIOC_KEEPALIVE)" RVAL_EBADF);
+ do_ioctl_ptr(WDIOC_KEEPALIVE, NULL);
+ printf("ioctl(-1, WDIOC_KEEPALIVE) = %s\n", errstr);
ioctl(-1, _IOC(_IOC_NONE, 'W', 0xff, 0), &val);
- printf("ioctl(-1, _IOC(_IOC_NONE, %#x, 0xff, 0), %p)" RVAL_EBADF,
- 'W', &val);
+ printf("ioctl(-1, _IOC(_IOC_NONE, %#x, 0xff, 0), %p) = %s\n",
+ 'W', &val, errstr);
puts("+++ exited with 0 +++");
return 0;
--
2.45.2
More information about the Strace-devel
mailing list