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

Eugene Loh eugene.loh at oracle.com
Mon Nov 13 21:03:38 UTC 2023


Nice tests to some new, interesting functionality.  Thanks.

A few comments.

1.  I'd be inclined to squash these tests into the previous patch.  The 
feature support and the tests clearly go hand-in-hand.  Separating the 
two doesn't really help with review since each test stands by itself.  
Not a big deal one way or the other.

2.  There should perhaps also be some err.* tests to check, e.g., errors 
when printsize is specified in some problematic manner or when some 
D_PRINT_ADDR or D_PRINT_SIZE error is encountered.

3.  We have stopped adding that:
+if (( $# != 1 )); then
+       echo "expected one argument: <dtrace-path>" >&2
+       exit 2
+fi
sequence, since it becomes (has become) excessive boilerplate.

4.  Instead of having .sh scripts that do error checking, how about 
making these .d scripts, putting the anticipated results in 
corresponding .r files.  That should make both the D scripts and the 
results files easier to read, relying on runtests.sh's mechanisms for 
error checking instead.  Also, might as well add @@nosort to the .d files.

Also...

On 11/13/23 06:41, Alan Maguire via DTrace-devel wrote:
> use local type declaration + alloca() to create custom types for

Capitalize "use."

> 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)


No need to report test results.  It is understood that the tests should 
pass.

> 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



More information about the DTrace-devel mailing list