[DTrace-devel] [RFC 2/2] unittest/print: add unit tests to verify print() action behaviour

Alan Maguire alan.maguire at oracle.com
Mon Nov 13 11:41:23 UTC 2023


use local type declaration + alloca() to create custom types for
testing.  Verify

- various types are printed correctly
- zeroed values are skipped
- we truncate display at offset <value> with -x printsize=<value>

Also verify that we can print kernel-defined type correctly.

We see all tests pass:

test/unittest/print/tst.print.local.sh: PASS.
test/unittest/print/tst.print.local.trunc.sh: PASS.
test/unittest/print/tst.print.local.zeroed.sh: PASS.
test/unittest/print/tst.print.skb.sh: PASS.
4 cases (4 PASS, 0 FAIL, 0 XPASS, 0 XFAIL, 0 SKIP)

Signed-off-by: Alan Maguire <alan.maguire at oracle.com>
---
 test/unittest/print/tst.print.local.sh        | 91 +++++++++++++++++++
 test/unittest/print/tst.print.local.trunc.sh  | 82 +++++++++++++++++
 test/unittest/print/tst.print.local.zeroed.sh | 84 +++++++++++++++++
 test/unittest/print/tst.print.skb.sh          | 53 +++++++++++
 4 files changed, 310 insertions(+)
 create mode 100755 test/unittest/print/tst.print.local.sh
 create mode 100755 test/unittest/print/tst.print.local.trunc.sh
 create mode 100755 test/unittest/print/tst.print.local.zeroed.sh
 create mode 100755 test/unittest/print/tst.print.skb.sh

diff --git a/test/unittest/print/tst.print.local.sh b/test/unittest/print/tst.print.local.sh
new file mode 100755
index 00000000..d4da5147
--- /dev/null
+++ b/test/unittest/print/tst.print.local.sh
@@ -0,0 +1,91 @@
+#!/bin/bash
+#
+# Oracle Linux DTrace.
+# Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+# Licensed under the Universal Permissive License v 1.0 as shown at
+# http://oss.oracle.com/licenses/upl.
+
+#
+# Ensure print() action prints locally-defined data structures as expected.
+# Use alloca() to allocate storage for data used.
+#
+
+if (( $# != 1 )); then
+	echo "expected one argument: <dtrace-path>" >&2
+	exit 2
+fi
+
+dtrace=$1
+testdir="$(dirname $_test)"
+
+file=$tmpdir/print.out.$$
+
+$dtrace $dt_flags -qs /dev/stdin <<EODTRACE 1>$file
+
+enum eh { FIRSTVAL = 0, SECONDVAL = 1, THIRDVAL = 3 };
+
+/* DTrace will not parse nested anonymous structs/unions; also bitfields are not supported. */
+struct test_struct {
+	int	a;
+	char	b[5];
+	union {
+		__u8 c;
+		__u64 d;
+	} u;
+	struct {
+		void *e;
+		uint64_t f;
+	} s;
+	bool g;
+	enum eh h;
+};
+
+BEGIN
+{
+	t = (struct test_struct *)alloca(sizeof (struct test_struct));
+	t->a = 1;
+	t->b[0] = 't';
+	t->b[1] = 'e';
+	t->b[2] = 's';
+	t->b[3] = 't';
+	t->b[4] = '\0';
+	t->u.d = 123456789;
+	t->s.e = (void *)0xffff9b7aca7e0000,
+	t->s.f = 987654321;
+	t->g = 1;
+	t->h = SECONDVAL;
+	print(t);
+	exit(0);
+}
+EODTRACE
+
+if [[ -f $file ]]; then
+	for compar in "(struct test_struct) {"		\
+                      ".a = (int)1,"			\
+                      ".b = (char [5]) ["		\
+                      "(char)'t',"			\
+                      "(char)'e',"			\
+                      "(char)'s',"			\
+                      "(char)'t',"			\
+                      "],"				\
+		      ".u = (union) {"			\
+		      ".c = (__u8)21"			\
+		      ".d = (__u64)123456789,"		\
+		      ".s = (struct) {"			\
+		      ".e = (void *)0xffff9b7aca7e0000," \
+		      ".f = (uint64_t)987654321,"	\
+		      ".g = (bool)1,"			\
+		      ".h = (enum eh)SECONDVAL,"	\
+                      "}" ; do
+		res=$(grep -F "$compar" $file)
+		if [[ -z "$res" ]]; then
+			echo "'$compar' missing in $file"
+			cat $file
+			exit 1
+		fi
+	done
+	exit 0
+else
+	echo "No such file $file"
+	exit 1
+fi
diff --git a/test/unittest/print/tst.print.local.trunc.sh b/test/unittest/print/tst.print.local.trunc.sh
new file mode 100755
index 00000000..ee9dc1ca
--- /dev/null
+++ b/test/unittest/print/tst.print.local.trunc.sh
@@ -0,0 +1,82 @@
+#!/bin/bash
+#
+# Oracle Linux DTrace.
+# Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+# Licensed under the Universal Permissive License v 1.0 as shown at
+# http://oss.oracle.com/licenses/upl.
+
+#
+# Ensure print() action prints locally-defined data structures as expected,
+# and truncates at printsize value.
+#
+# Use alloca() to allocate storage for data used.
+#
+
+if (( $# != 1 )); then
+	echo "expected one argument: <dtrace-path>" >&2
+	exit 2
+fi
+
+dtrace=$1
+testdir="$(dirname $_test)"
+
+file=$tmpdir/print.out.$$
+
+$dtrace $dt_flags -x printsize=8 -qs /dev/stdin <<EODTRACE 1>$file
+
+enum eh { FIRSTVAL = 1, SECONDVAL = 2, THIRDVAL= 3 };
+
+/* DTrace will not parse nested anonymous structs/unions; also bitfields are not supported. */
+struct test_struct {
+	int	a;
+	char	b[5];
+	union {
+		__u8 c;
+		__u64 d;
+	} u;
+	struct {
+		void *e;
+		uint64_t f;
+	} s;
+	bool g;
+	enum eh h;
+};
+
+BEGIN
+{
+	t = (struct test_struct *)alloca(sizeof (struct test_struct));
+	t->a = 1;
+	t->b[0] = 't';
+	t->b[1] = 'e';
+	t->b[2] = 's';
+	t->b[3] = 't';
+	t->b[4] = '\0';
+	t->u.d = 12345678,
+	t->s.e = (void *)0xfeedfacefeedface;
+	t->s.f = 100,
+	t->g = 1;
+	t->h = FIRSTVAL;
+	print(t);
+	exit(0);
+}
+EODTRACE
+
+if [[ -f $file ]]; then
+	for compar in ".c = (__u8)"			\
+		      ".d = (__u64)"			\
+		      ".e = (void *)"			\
+		      ".f = (uint64_t)"			\
+		      ".g = (bool)"			\
+		      ".h = (enum eh)" ; do
+		res=$(grep -F "$compar" $file)
+		if [[ -n "$res" ]]; then
+			echo "'$compar' unexpectedly found in $file"
+			cat $file
+			exit 1
+		fi
+	done
+	exit 0
+else
+	echo "No such file $file"
+	exit 1
+fi
diff --git a/test/unittest/print/tst.print.local.zeroed.sh b/test/unittest/print/tst.print.local.zeroed.sh
new file mode 100755
index 00000000..8522f03d
--- /dev/null
+++ b/test/unittest/print/tst.print.local.zeroed.sh
@@ -0,0 +1,84 @@
+#!/bin/bash
+#
+# Oracle Linux DTrace.
+# Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+# Licensed under the Universal Permissive License v 1.0 as shown at
+# http://oss.oracle.com/licenses/upl.
+
+#
+# Ensure print() action prints locally-defined data structures as expected,
+# and zero-valued fields are not printed.
+#
+# Use alloca() to allocate storage for data used.
+#
+
+if (( $# != 1 )); then
+	echo "expected one argument: <dtrace-path>" >&2
+	exit 2
+fi
+
+dtrace=$1
+testdir="$(dirname $_test)"
+
+file=$tmpdir/print.out.$$
+
+$dtrace $dt_flags -qs /dev/stdin <<EODTRACE 1>$file
+
+enum eh { FIRSTVAL = 0, SECONDVAL = 1, THIRDVAL= 2 };
+
+/* DTrace will not parse nested anonymous structs/unions; also bitfields are not supported. */
+struct test_struct {
+	int	a;
+	char	b[5];
+	union {
+		__u8 c;
+		__u64 d;
+	} u;
+	struct {
+		void *e;
+		uint64_t f;
+	} s;
+	bool g;
+	enum eh h;
+};
+
+BEGIN
+{
+	t = (struct test_struct *)alloca(sizeof (struct test_struct));
+	t->a = 0;
+	/* initial null should prevent displaying rest of char array */
+	t->b[0] = '\0';
+	t->b[1] = 'e';
+	t->b[2] = 's';
+	t->b[3] = 't';
+	t->b[4] = '\0';
+	t->u.d = 0,
+	t->s.e = (void *)NULL,
+	t->s.f = 0,
+	t->g = 1;
+	t->h = FIRSTVAL;
+	print(t);
+	exit(0);
+}
+EODTRACE
+
+if [[ -f $file ]]; then
+	for compar in ".a = (int)"			\
+                      "(char)'"				\
+		      ".c = (__u8)"			\
+		      ".d = (__u64)"			\
+		      ".e = (void *)"			\
+		      ".f = (uint64_t)"			\
+		      ".h = (enum eh)"; do
+		res=$(grep -F "$compar" $file)
+		if [[ -n "$res" ]]; then
+			echo "'$compar' unexpectedly found in $file"
+			cat $file
+			exit 1
+		fi
+	done
+	exit 0
+else
+	echo "No such file $file"
+	exit 1
+fi
diff --git a/test/unittest/print/tst.print.skb.sh b/test/unittest/print/tst.print.skb.sh
new file mode 100755
index 00000000..1252aadb
--- /dev/null
+++ b/test/unittest/print/tst.print.skb.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+#
+# Oracle Linux DTrace.
+# Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+# Licensed under the Universal Permissive License v 1.0 as shown at
+# http://oss.oracle.com/licenses/upl.
+
+#
+# Ensure print() action prints kernel-defined data structures as expected.
+# Use alloca() to allocate storage for data used.
+#
+
+if (( $# != 1 )); then
+	echo "expected one argument: <dtrace-path>" >&2
+	exit 2
+fi
+
+dtrace=$1
+testdir="$(dirname $_test)"
+
+file=$tmpdir/print.out.$$
+
+$dtrace $dt_flags -qs /dev/stdin <<EODTRACE 1>$file
+
+BEGIN
+{
+	skb = (struct sk_buff *)alloca(sizeof (struct sk_buff));
+	skb->len = 123;
+	skb->network_header = 32;
+	skb->data = (unsigned char *)0xfeedfacefeedface;
+	print(skb);
+	exit(0);
+}
+EODTRACE
+
+if [[ -f $file ]]; then
+	for compar in "(struct sk_buff) {"				\
+                      ".len = (unsigned int)123,"			\
+		      ".network_header = (__u16)32"			\
+		      ".data = (unsigned char *)0xfeedfacefeedface,"	\
+		      "}" ; do
+		res=$(grep -F "$compar" $file)
+		if [[ -z "$res" ]]; then
+			echo "'$compar' missing in $file"
+			cat $file
+			exit 1
+		fi
+	done
+	exit 0
+else
+	echo "No such file $file"
+	exit 1
+fi
-- 
2.39.3




More information about the DTrace-devel mailing list