Merge tag 'linux-kselftest-4.21-rc1' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 29 Dec 2018 05:27:13 +0000 (21:27 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 29 Dec 2018 05:27:13 +0000 (21:27 -0800)
Pull Kselftest updates from Shuah Khan:

 - fixes and improvements to the framework, and individual tests

 - a new media test for IR encoders from Sean Young

 - a new watchdog test option to find time left on a timer

* tag 'linux-kselftest-4.21-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest:
  selftests: Fix test errors related to lib.mk khdr target
  fix dma-buf/udmabuf selftest
  selftests: watchdog: fix spelling mistake "experies" -> "expires"
  selftests: watchdog: Add gettimeleft command line arg
  selftests: do not macro-expand failed assertion expressions
  selftests/ftrace: Fix invalid SPDX identifiers
  selftests: gpio: Find libmount with pkg-config if available
  selftests: firmware: add CONFIG_FW_LOADER_USER_HELPER_FALLBACK to config
  selftests: firmware: remove use of non-standard diff -Z option
  media: rc: self test for IR encoders and decoders

17 files changed:
tools/testing/selftests/Makefile
tools/testing/selftests/drivers/dma-buf/Makefile
tools/testing/selftests/drivers/dma-buf/udmabuf.c
tools/testing/selftests/firmware/config
tools/testing/selftests/firmware/fw_filesystem.sh
tools/testing/selftests/ftrace/test.d/ftrace/func-filter-stacktrace.tc
tools/testing/selftests/ftrace/test.d/ftrace/func_cpumask.tc
tools/testing/selftests/ftrace/test.d/template
tools/testing/selftests/ftrace/test.d/tracer/wakeup.tc
tools/testing/selftests/ftrace/test.d/tracer/wakeup_rt.tc
tools/testing/selftests/gpio/Makefile
tools/testing/selftests/ir/.gitignore [new file with mode: 0644]
tools/testing/selftests/ir/Makefile [new file with mode: 0644]
tools/testing/selftests/ir/ir_loopback.c [new file with mode: 0644]
tools/testing/selftests/ir/ir_loopback.sh [new file with mode: 0755]
tools/testing/selftests/kselftest_harness.h
tools/testing/selftests/watchdog/watchdog-test.c

index 24b9934fb26958c6569e1e211d7be88bfe950b56..eb54df682d5622a69744a61f3f29242555172f01 100644 (file)
@@ -6,6 +6,7 @@ TARGETS += capabilities
 TARGETS += cgroup
 TARGETS += cpufreq
 TARGETS += cpu-hotplug
+TARGETS += drivers/dma-buf
 TARGETS += efivarfs
 TARGETS += exec
 TARGETS += filesystems
@@ -15,6 +16,7 @@ TARGETS += futex
 TARGETS += gpio
 TARGETS += intel_pstate
 TARGETS += ipc
+TARGETS += ir
 TARGETS += kcmp
 TARGETS += kvm
 TARGETS += lib
index 4154c3d7aa585f1a8f36b07128dce44af08aed7f..f22c3f7cf612d1bd53b10f52c1bc9f299212e0ef 100644 (file)
@@ -2,4 +2,6 @@ CFLAGS += -I../../../../../usr/include/
 
 TEST_GEN_PROGS := udmabuf
 
+top_srcdir ?=../../../../..
+
 include ../../lib.mk
index 376b1d6730bd9965fcab295a5ba070375c6fde25..4de902ea14d82be9c06908e62e5d9bdb771a6279 100644 (file)
@@ -4,7 +4,7 @@
 #include <unistd.h>
 #include <string.h>
 #include <errno.h>
-#include <fcntl.h>
+#include <linux/fcntl.h>
 #include <malloc.h>
 
 #include <sys/ioctl.h>
@@ -33,12 +33,19 @@ int main(int argc, char *argv[])
                exit(77);
        }
 
-       memfd = memfd_create("udmabuf-test", MFD_CLOEXEC);
+       memfd = memfd_create("udmabuf-test", MFD_ALLOW_SEALING);
        if (memfd < 0) {
                printf("%s: [skip,no-memfd]\n", TEST_PREFIX);
                exit(77);
        }
 
+       ret = fcntl(memfd, F_ADD_SEALS, F_SEAL_SHRINK);
+       if (ret < 0) {
+               printf("%s: [skip,fcntl-add-seals]\n", TEST_PREFIX);
+               exit(77);
+       }
+
+
        size = getpagesize() * NUM_PAGES;
        ret = ftruncate(memfd, size);
        if (ret == -1) {
index bf634dda07201fe7108f16496834543223164204..913a25a4a32bebb3c7a73499035a56da7ebd0f6b 100644 (file)
@@ -1,5 +1,6 @@
 CONFIG_TEST_FIRMWARE=y
 CONFIG_FW_LOADER=y
 CONFIG_FW_LOADER_USER_HELPER=y
+CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
index a4320c4b44dc9ccf021e3fc3376640593d46aa4f..466cf2f91ba0155b2dc759487f2bc87112b5e3ad 100755 (executable)
@@ -155,11 +155,8 @@ read_firmwares()
 {
        for i in $(seq 0 3); do
                config_set_read_fw_idx $i
-               # Verify the contents are what we expect.
-               # -Z required for now -- check for yourself, md5sum
-               # on $FW and DIR/read_firmware will yield the same. Even
-               # cmp agrees, so something is off.
-               if ! diff -q -Z "$FW" $DIR/read_firmware 2>/dev/null ; then
+               # Verify the contents match
+               if ! diff -q "$FW" $DIR/read_firmware 2>/dev/null ; then
                        echo "request #$i: firmware was not loaded" >&2
                        exit 1
                fi
@@ -171,7 +168,7 @@ read_firmwares_expect_nofile()
        for i in $(seq 0 3); do
                config_set_read_fw_idx $i
                # Ensures contents differ
-               if diff -q -Z "$FW" $DIR/read_firmware 2>/dev/null ; then
+               if diff -q "$FW" $DIR/read_firmware 2>/dev/null ; then
                        echo "request $i: file was not expected to match" >&2
                        exit 1
                fi
index bf72e783d01442375b8ae1f9c9376f87283bbfe0..36fb59f886ea81baef28a712c13f6d4ff204ac12 100644 (file)
@@ -1,5 +1,5 @@
 #!/bin/sh
-# SPDX-License-Identifier: GPL2.0
+# SPDX-License-Identifier: GPL-2.0
 # description: ftrace - stacktrace filter command
 # flags: instance
 
index 0e6810743576b4b1ce4292cf80f22450918400ee..86a1f07ef2ca70c672b4ea897340dfde4515d2f7 100644 (file)
@@ -1,5 +1,5 @@
 #!/bin/sh
-# SPDX-License-Identifier: GPL2.0
+# SPDX-License-Identifier: GPL-2.0
 # description: ftrace - function trace with cpumask
 
 if ! which nproc ; then
index 799da7e0b3c914001e2aaae33a045720ea6180cd..e1a5d14c4eaf7cdeab5169aa0a28b78ba8d125ac 100644 (file)
@@ -1,5 +1,5 @@
 #!/bin/sh
-# SPDX-License-Identifier: GPL2.0
+# SPDX-License-Identifier: GPL-2.0
 # description: %HERE DESCRIBE WHAT THIS DOES%
 # you have to add ".tc" extention for your testcase file
 # Note that all tests are run with "errexit" option.
index e3005fa785f090ed8f6dc60faa9a124e14d8e424..b0893d7edda3a4a26d0f9d6da4105e7b77793704 100644 (file)
@@ -1,5 +1,5 @@
 #!/bin/sh
-# SPDX-License-Identifier: GPL2.0
+# SPDX-License-Identifier: GPL-2.0
 # description: Test wakeup tracer
 
 if ! which chrt ; then
index f99b5178e00abd42f861bdad5a8d6d5cfb8b781d..b9b6669a623b6443a15340fd9f6ae8472bd517ba 100644 (file)
@@ -1,5 +1,5 @@
 #!/bin/sh
-# SPDX-License-Identifier: GPL2.0
+# SPDX-License-Identifier: GPL-2.0
 # description: Test wakeup RT tracer
 
 if ! which chrt ; then
index 07f572a1bd3f63d0a78e7e016731b0520a46861c..0bb80619db580af1dcb23ff8fde3235d20a2c825 100644 (file)
@@ -1,7 +1,13 @@
 # SPDX-License-Identifier: GPL-2.0
 
-CFLAGS += -O2 -g -std=gnu99 -Wall -I../../../../usr/include/
-LDLIBS += -lmount -I/usr/include/libmount
+MOUNT_CFLAGS := $(shell pkg-config --cflags mount 2>/dev/null)
+MOUNT_LDLIBS := $(shell pkg-config --libs mount 2>/dev/null)
+ifeq ($(MOUNT_LDLIBS),)
+MOUNT_LDLIBS := -lmount -I/usr/include/libmount
+endif
+
+CFLAGS += -O2 -g -std=gnu99 -Wall -I../../../../usr/include/ $(MOUNT_CFLAGS)
+LDLIBS += $(MOUNT_LDLIBS)
 
 TEST_PROGS := gpio-mockup.sh
 TEST_FILES := gpio-mockup-sysfs.sh
diff --git a/tools/testing/selftests/ir/.gitignore b/tools/testing/selftests/ir/.gitignore
new file mode 100644 (file)
index 0000000..070ea0c
--- /dev/null
@@ -0,0 +1 @@
+ir_loopback
diff --git a/tools/testing/selftests/ir/Makefile b/tools/testing/selftests/ir/Makefile
new file mode 100644 (file)
index 0000000..f4ba8eb
--- /dev/null
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+TEST_PROGS := ir_loopback.sh
+TEST_GEN_PROGS_EXTENDED := ir_loopback
+
+include ../lib.mk
diff --git a/tools/testing/selftests/ir/ir_loopback.c b/tools/testing/selftests/ir/ir_loopback.c
new file mode 100644 (file)
index 0000000..858c19c
--- /dev/null
@@ -0,0 +1,199 @@
+// SPDX-License-Identifier: GPL-2.0
+// test ir decoder
+//
+// Copyright (C) 2018 Sean Young <sean@mess.org>
+
+// When sending LIRC_MODE_SCANCODE, the IR will be encoded. rc-loopback
+// will send this IR to the receiver side, where we try to read the decoded
+// IR. Decoding happens in a separate kernel thread, so we will need to
+// wait until that is scheduled, hence we use poll to check for read
+// readiness.
+
+#include <linux/lirc.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include <unistd.h>
+#include <poll.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "../kselftest.h"
+
+#define TEST_SCANCODES 10
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+
+static const struct {
+       enum rc_proto proto;
+       const char *name;
+       unsigned int mask;
+       const char *decoder;
+} protocols[] = {
+       { RC_PROTO_RC5, "rc-5", 0x1f7f, "rc-5" },
+       { RC_PROTO_RC5X_20, "rc-5x-20", 0x1f7f3f, "rc-5" },
+       { RC_PROTO_RC5_SZ, "rc-5-sz", 0x2fff, "rc-5-sz" },
+       { RC_PROTO_JVC, "jvc", 0xffff, "jvc" },
+       { RC_PROTO_SONY12, "sony-12", 0x1f007f, "sony" },
+       { RC_PROTO_SONY15, "sony-15", 0xff007f, "sony" },
+       { RC_PROTO_SONY20, "sony-20", 0x1fff7f, "sony" },
+       { RC_PROTO_NEC, "nec", 0xffff, "nec" },
+       { RC_PROTO_NECX, "nec-x", 0xffffff, "nec" },
+       { RC_PROTO_NEC32, "nec-32", 0xffffffff, "nec" },
+       { RC_PROTO_SANYO, "sanyo", 0x1fffff, "sanyo" },
+       { RC_PROTO_RC6_0, "rc-6-0", 0xffff, "rc-6" },
+       { RC_PROTO_RC6_6A_20, "rc-6-6a-20", 0xfffff, "rc-6" },
+       { RC_PROTO_RC6_6A_24, "rc-6-6a-24", 0xffffff, "rc-6" },
+       { RC_PROTO_RC6_6A_32, "rc-6-6a-32", 0xffffffff, "rc-6" },
+       { RC_PROTO_RC6_MCE, "rc-6-mce", 0x00007fff, "rc-6" },
+       { RC_PROTO_SHARP, "sharp", 0x1fff, "sharp" },
+};
+
+int lirc_open(const char *rc)
+{
+       struct dirent *dent;
+       char buf[100];
+       DIR *d;
+       int fd;
+
+       snprintf(buf, sizeof(buf), "/sys/class/rc/%s", rc);
+
+       d = opendir(buf);
+       if (!d)
+               ksft_exit_fail_msg("cannot open %s: %m\n", buf);
+
+       while ((dent = readdir(d)) != NULL) {
+               if (!strncmp(dent->d_name, "lirc", 4)) {
+                       snprintf(buf, sizeof(buf), "/dev/%s", dent->d_name);
+                       break;
+               }
+       }
+
+       if (!dent)
+               ksft_exit_fail_msg("cannot find lirc device for %s\n", rc);
+
+       closedir(d);
+
+       fd = open(buf, O_RDWR | O_NONBLOCK);
+       if (fd == -1)
+               ksft_exit_fail_msg("cannot open: %s: %m\n", buf);
+
+       return fd;
+}
+
+int main(int argc, char **argv)
+{
+       unsigned int mode;
+       char buf[100];
+       int rlircfd, wlircfd, protocolfd, i, n;
+
+       srand(time(NULL));
+
+       if (argc != 3)
+               ksft_exit_fail_msg("Usage: %s <write rcN> <read rcN>\n",
+                                  argv[0]);
+
+       rlircfd = lirc_open(argv[2]);
+       mode = LIRC_MODE_SCANCODE;
+       if (ioctl(rlircfd, LIRC_SET_REC_MODE, &mode))
+               ksft_exit_fail_msg("failed to set scancode rec mode %s: %m\n",
+                                  argv[2]);
+
+       wlircfd = lirc_open(argv[1]);
+       if (ioctl(wlircfd, LIRC_SET_SEND_MODE, &mode))
+               ksft_exit_fail_msg("failed to set scancode send mode %s: %m\n",
+                                  argv[1]);
+
+       snprintf(buf, sizeof(buf), "/sys/class/rc/%s/protocols", argv[2]);
+       protocolfd = open(buf, O_WRONLY);
+       if (protocolfd == -1)
+               ksft_exit_fail_msg("failed to open %s: %m\n", buf);
+
+       printf("Sending IR on %s and receiving IR on %s.\n", argv[1], argv[2]);
+
+       for (i = 0; i < ARRAY_SIZE(protocols); i++) {
+               if (write(protocolfd, protocols[i].decoder,
+                         strlen(protocols[i].decoder)) == -1)
+                       ksft_exit_fail_msg("failed to set write decoder\n");
+
+               printf("Testing protocol %s for decoder %s (%d/%d)...\n",
+                      protocols[i].name, protocols[i].decoder,
+                      i + 1, (int)ARRAY_SIZE(protocols));
+
+               for (n = 0; n < TEST_SCANCODES; n++) {
+                       unsigned int scancode = rand() & protocols[i].mask;
+                       unsigned int rc_proto = protocols[i].proto;
+
+                       if (rc_proto == RC_PROTO_RC6_MCE)
+                               scancode |= 0x800f0000;
+
+                       if (rc_proto == RC_PROTO_NECX &&
+                           (((scancode >> 16) ^ ~(scancode >> 8)) & 0xff) == 0)
+                               continue;
+
+                       if (rc_proto == RC_PROTO_NEC32 &&
+                           (((scancode >> 8) ^ ~scancode) & 0xff) == 0)
+                               continue;
+
+                       struct lirc_scancode lsc = {
+                               .rc_proto = rc_proto,
+                               .scancode = scancode
+                       };
+
+                       printf("Testing scancode:%x\n", scancode);
+
+                       while (write(wlircfd, &lsc, sizeof(lsc)) < 0) {
+                               if (errno == EINTR)
+                                       continue;
+
+                               ksft_exit_fail_msg("failed to send ir: %m\n");
+                       }
+
+                       struct pollfd pfd = { .fd = rlircfd, .events = POLLIN };
+                       struct lirc_scancode lsc2;
+
+                       poll(&pfd, 1, 1000);
+
+                       bool decoded = true;
+
+                       while (read(rlircfd, &lsc2, sizeof(lsc2)) < 0) {
+                               if (errno == EINTR)
+                                       continue;
+
+                               ksft_test_result_error("no scancode decoded: %m\n");
+                               decoded = false;
+                               break;
+                       }
+
+                       if (!decoded)
+                               continue;
+
+                       if (lsc.rc_proto != lsc2.rc_proto)
+                               ksft_test_result_error("decoded protocol is different: %d\n",
+                                                      lsc2.rc_proto);
+
+                       else if (lsc.scancode != lsc2.scancode)
+                               ksft_test_result_error("decoded scancode is different: %llx\n",
+                                                      lsc2.scancode);
+                       else
+                               ksft_inc_pass_cnt();
+               }
+
+               printf("OK\n");
+       }
+
+       close(rlircfd);
+       close(wlircfd);
+       close(protocolfd);
+
+       if (ksft_get_fail_cnt() > 0)
+               ksft_exit_fail();
+       else
+               ksft_exit_pass();
+
+       return 0;
+}
diff --git a/tools/testing/selftests/ir/ir_loopback.sh b/tools/testing/selftests/ir/ir_loopback.sh
new file mode 100755 (executable)
index 0000000..0a0b8df
--- /dev/null
@@ -0,0 +1,20 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+
+# Kselftest framework requirement - SKIP code is 4.
+ksft_skip=4
+
+if ! /sbin/modprobe -q -n rc-loopback; then
+        echo "ir_loopback: module rc-loopback is not found [SKIP]"
+        exit $ksft_skip
+fi
+
+/sbin/modprobe rc-loopback
+if [ $? -ne 0 ]; then
+       exit
+fi
+
+RCDEV=$(grep -l DRV_NAME=rc-loopback /sys/class/rc/rc*/uevent | grep -o 'rc[0-9]\+')
+
+./ir_loopback $RCDEV $RCDEV
+exit
index 6ae3730c4ee35b1cfc2e93ed39aac6b2bf3755ad..76d654ef3234a4cab8b34427d6436a25b7066055 100644 (file)
  * ASSERT_EQ(expected, measured): expected == measured
  */
 #define ASSERT_EQ(expected, seen) \
-       __EXPECT(expected, seen, ==, 1)
+       __EXPECT(expected, #expected, seen, #seen, ==, 1)
 
 /**
  * ASSERT_NE(expected, seen)
  * ASSERT_NE(expected, measured): expected != measured
  */
 #define ASSERT_NE(expected, seen) \
-       __EXPECT(expected, seen, !=, 1)
+       __EXPECT(expected, #expected, seen, #seen, !=, 1)
 
 /**
  * ASSERT_LT(expected, seen)
  * ASSERT_LT(expected, measured): expected < measured
  */
 #define ASSERT_LT(expected, seen) \
-       __EXPECT(expected, seen, <, 1)
+       __EXPECT(expected, #expected, seen, #seen, <, 1)
 
 /**
  * ASSERT_LE(expected, seen)
  * ASSERT_LE(expected, measured): expected <= measured
  */
 #define ASSERT_LE(expected, seen) \
-       __EXPECT(expected, seen, <=, 1)
+       __EXPECT(expected, #expected, seen, #seen, <=, 1)
 
 /**
  * ASSERT_GT(expected, seen)
  * ASSERT_GT(expected, measured): expected > measured
  */
 #define ASSERT_GT(expected, seen) \
-       __EXPECT(expected, seen, >, 1)
+       __EXPECT(expected, #expected, seen, #seen, >, 1)
 
 /**
  * ASSERT_GE(expected, seen)
  * ASSERT_GE(expected, measured): expected >= measured
  */
 #define ASSERT_GE(expected, seen) \
-       __EXPECT(expected, seen, >=, 1)
+       __EXPECT(expected, #expected, seen, #seen, >=, 1)
 
 /**
  * ASSERT_NULL(seen)
  * ASSERT_NULL(measured): NULL == measured
  */
 #define ASSERT_NULL(seen) \
-       __EXPECT(NULL, seen, ==, 1)
+       __EXPECT(NULL, "NULL", seen, #seen, ==, 1)
 
 /**
  * ASSERT_TRUE(seen)
  * ASSERT_TRUE(measured): measured != 0
  */
 #define ASSERT_TRUE(seen) \
-       ASSERT_NE(0, seen)
+       __EXPECT(0, "0", seen, #seen, !=, 1)
 
 /**
  * ASSERT_FALSE(seen)
  * ASSERT_FALSE(measured): measured == 0
  */
 #define ASSERT_FALSE(seen) \
-       ASSERT_EQ(0, seen)
+       __EXPECT(0, "0", seen, #seen, ==, 1)
 
 /**
  * ASSERT_STREQ(expected, seen)
  * EXPECT_EQ(expected, measured): expected == measured
  */
 #define EXPECT_EQ(expected, seen) \
-       __EXPECT(expected, seen, ==, 0)
+       __EXPECT(expected, #expected, seen, #seen, ==, 0)
 
 /**
  * EXPECT_NE(expected, seen)
  * EXPECT_NE(expected, measured): expected != measured
  */
 #define EXPECT_NE(expected, seen) \
-       __EXPECT(expected, seen, !=, 0)
+       __EXPECT(expected, #expected, seen, #seen, !=, 0)
 
 /**
  * EXPECT_LT(expected, seen)
  * EXPECT_LT(expected, measured): expected < measured
  */
 #define EXPECT_LT(expected, seen) \
-       __EXPECT(expected, seen, <, 0)
+       __EXPECT(expected, #expected, seen, #seen, <, 0)
 
 /**
  * EXPECT_LE(expected, seen)
  * EXPECT_LE(expected, measured): expected <= measured
  */
 #define EXPECT_LE(expected, seen) \
-       __EXPECT(expected, seen, <=, 0)
+       __EXPECT(expected, #expected, seen, #seen, <=, 0)
 
 /**
  * EXPECT_GT(expected, seen)
  * EXPECT_GT(expected, measured): expected > measured
  */
 #define EXPECT_GT(expected, seen) \
-       __EXPECT(expected, seen, >, 0)
+       __EXPECT(expected, #expected, seen, #seen, >, 0)
 
 /**
  * EXPECT_GE(expected, seen)
  * EXPECT_GE(expected, measured): expected >= measured
  */
 #define EXPECT_GE(expected, seen) \
-       __EXPECT(expected, seen, >=, 0)
+       __EXPECT(expected, #expected, seen, #seen, >=, 0)
 
 /**
  * EXPECT_NULL(seen)
  * EXPECT_NULL(measured): NULL == measured
  */
 #define EXPECT_NULL(seen) \
-       __EXPECT(NULL, seen, ==, 0)
+       __EXPECT(NULL, "NULL", seen, #seen, ==, 0)
 
 /**
  * EXPECT_TRUE(seen)
  * EXPECT_TRUE(measured): 0 != measured
  */
 #define EXPECT_TRUE(seen) \
-       EXPECT_NE(0, seen)
+       __EXPECT(0, "0", seen, #seen, !=, 0)
 
 /**
  * EXPECT_FALSE(seen)
  * EXPECT_FALSE(measured): 0 == measured
  */
 #define EXPECT_FALSE(seen) \
-       EXPECT_EQ(0, seen)
+       __EXPECT(0, "0", seen, #seen, ==, 0)
 
 /**
  * EXPECT_STREQ(expected, seen)
        if (_metadata->passed && _metadata->step < 255) \
                _metadata->step++;
 
-#define __EXPECT(_expected, _seen, _t, _assert) do { \
+#define __EXPECT(_expected, _expected_str, _seen, _seen_str, _t, _assert) do { \
        /* Avoid multiple evaluation of the cases */ \
        __typeof__(_expected) __exp = (_expected); \
        __typeof__(_seen) __seen = (_seen); \
                unsigned long long __exp_print = (uintptr_t)__exp; \
                unsigned long long __seen_print = (uintptr_t)__seen; \
                __TH_LOG("Expected %s (%llu) %s %s (%llu)", \
-                        #_expected, __exp_print, #_t, \
-                        #_seen, __seen_print); \
+                        _expected_str, __exp_print, #_t, \
+                        _seen_str, __seen_print); \
                _metadata->passed = 0; \
                /* Ensure the optional handler is triggered */ \
                _metadata->trigger = 1; \
index c6bd9a68306bef345edc54ac8466384fd2a7ed1b..c2333c78cf04dbd2fe94e356b24dc8500fe5cad9 100644 (file)
@@ -19,7 +19,7 @@
 
 int fd;
 const char v = 'V';
-static const char sopts[] = "bdehp:t:Tn:N";
+static const char sopts[] = "bdehp:t:Tn:NL";
 static const struct option lopts[] = {
        {"bootstatus",          no_argument, NULL, 'b'},
        {"disable",             no_argument, NULL, 'd'},
@@ -30,6 +30,7 @@ static const struct option lopts[] = {
        {"gettimeout",          no_argument, NULL, 'T'},
        {"pretimeout",    required_argument, NULL, 'n'},
        {"getpretimeout",       no_argument, NULL, 'N'},
+       {"gettimeleft",         no_argument, NULL, 'L'},
        {NULL,                  no_argument, NULL, 0x0}
 };
 
@@ -77,6 +78,7 @@ static void usage(char *progname)
        printf(" -T, --gettimeout    Get the timeout\n");
        printf(" -n, --pretimeout=T  Set the pretimeout to T seconds\n");
        printf(" -N, --getpretimeout Get the pretimeout\n");
+       printf(" -L, --gettimeleft   Get the time left until timer expires\n");
        printf("\n");
        printf("Parameters are parsed left-to-right in real-time.\n");
        printf("Example: %s -d -t 10 -p 5 -e\n", progname);
@@ -180,6 +182,15 @@ int main(int argc, char *argv[])
                        else
                                printf("WDIOC_GETPRETIMEOUT error '%s'\n", strerror(errno));
                        break;
+               case 'L':
+                       oneshot = 1;
+                       ret = ioctl(fd, WDIOC_GETTIMELEFT, &flags);
+                       if (!ret)
+                               printf("WDIOC_GETTIMELEFT returns %u seconds.\n", flags);
+                       else
+                               printf("WDIOC_GETTIMELEFT error '%s'\n", strerror(errno));
+                       break;
+
                default:
                        usage(argv[0]);
                        goto end;