[PATCHv2 4/4] Add a test case for "-e write=all" option for sendmmsg system call

Dmitry V. Levin ldv at altlinux.org
Fri Nov 7 04:34:22 UTC 2014


On Fri, Nov 07, 2014 at 11:38:22AM +0900, Masatake YAMATO wrote:
> * tests/Makefile.am: Add mmsg to CHECK_PROGRAMS. Add mmsg.test to TESTS.
> 
> * tests/mmsg.test: New file.
> 
> * tests/mmsg.c: New target program to be traced by testes strace.

Do not forget to add new executables to tests/.gitignore.

> In v2 patch: Nothing is changed.

This needs a bit more work.

> --- /dev/null
> +++ b/tests/mmsg.c
> @@ -0,0 +1,91 @@
> +/* Derived from man page of sendmmsg(2) and recvmmsg(2) */

Please don't.  Use tests/scm_rights.c and tests/uio.c as examples.

> +#define _GNU_SOURCE

Use config.h instead, it would be needed for HAVE_SENDMMSG anyway.

> +#include <sys/socket.h>
> +#include <unistd.h>
> +#include <sys/types.h>
> +#include <errno.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +
> +static char xbuf[4096];

This shouldn't be needed.

> +
> +int
> +main(void)
> +{
> +  int sv[2];
> +  pid_t pid;

The build environment might not provide recvmmsg/sendmmsg, so
a check like in tests/uio.c is required.

> +
> +  if (socketpair (AF_UNIX, SOCK_DGRAM, 0, sv) < 0)
> +    {
> +      perror("socketpair");
> +      exit (1);
> +    }

With assert, you can write such code in one line.
This is a test, there is not much you can do besides exit with an error
code, so please use assert like in tests/scm_rights.c.

You wouldn't need to include <stdio.h> and <errno.h>, just <assert.h>.

> +  pid = fork ();

You can do without forking.  In tests/scm_rights.c I had to use fork
because of descriptor passing, this test can be written without it,
just sendmmsg(1, ...), close(1), recvmmsg(0, ...), close(0).

> +  else if (pid == 0)
> +    {
> +      struct mmsghdr msg[2];
> +      struct iovec msg1[2], msg2;

Please don't name iovec variables as msg*, it's confusing.

> +      char one[4] = "one", two[4] = "two", three[6] = "three";
> +      memset(msg1, 0, sizeof(msg1));
> +      msg1[0].iov_base = one;
> +      msg1[0].iov_len = 3;
> +      msg1[1].iov_base = xbuf;
> +      msg1[1].iov_len = 4096;
> +      msg1[1].iov_base = two;
> +      msg1[1].iov_len = 3;

This way of specifying sizes and lengths is fragile.
Please use sizeof instead.

BTW, what is this "xbuf" doing here?

> +      memset(&msg2, 0, sizeof(msg2));
> +      msg2.iov_base = three;
> +      msg2.iov_len = 5;
> +
> +      memset(msg, 0, sizeof(msg));
> +      msg[0].msg_hdr.msg_iov = msg1;
> +      msg[0].msg_hdr.msg_iovlen = 2;
> +      msg[1].msg_hdr.msg_iov = &msg2;
> +      msg[1].msg_hdr.msg_iovlen = 1;
> +
> +      if (sendmmsg (sv[0], msg, 2, 0) < 0)
> +        {
> +          perror("sendmsg");
> +          exit (1);
> +        }
> +    }
> +  else
> +    {
> +      struct mmsghdr msg[2];
> +      struct iovec msg1[2], msg2;
> +      char one[4], two[4], three[6];
> +
> +      memset(msg1, 0, sizeof(msg1));
> +      msg1[0].iov_base = one;
> +      msg1[0].iov_len = 3;
> +      msg1[1].iov_base = two;
> +      msg1[1].iov_len = 3;
> +
> +      memset(&msg2, 0, sizeof(msg2));
> +      msg2.iov_base = three;
> +      msg2.iov_len = 5;

The same comment about sizes and lengths is applicable here as well.

> +      memset(msg, 0, sizeof(msg));
> +      msg[0].msg_hdr.msg_iov = msg1;
> +      msg[0].msg_hdr.msg_iovlen = 2;
> +      msg[1].msg_hdr.msg_iov = &msg2;
> +      msg[1].msg_hdr.msg_iovlen = 1;
> +
> +      if (recvmmsg(sv[1], msg, 2, 0, NULL) < 0)
> +        {
> +          perror ("recvmmsg");
> +          exit (1);
> +        }
> +    }
> +  return 0;
> +}
> diff --git a/tests/mmsg.test b/tests/mmsg.test
> new file mode 100755
> index 0000000..20252f9
> --- /dev/null
> +++ b/tests/mmsg.test
> @@ -0,0 +1,44 @@
> +#!/bin/sh
> +
> +# Ensure that strace -k works.

This test is about recvmmsg/sendmmsg decoding. :)

> +
> +. "${srcdir=.}/init.sh"
> +
> +args="-e write=all -f ./mmsg"
> +$STRACE $args > $LOG 2>&1 || {
> +	cat $LOG
> +	fail_ "$STRACE $args failed"
> +}

First, ./mmsg itself has to be tested like in many other tests.

I think you can move socket descriptors to well-known values like I did
in tests/scm_rights.c, it would allow more precise testing like
strace -e trace=recvmmsg,sendmmsg -e read=0 -e write=1

This way the strace output becomes immutable, so you can save expected
output in a file and compare it with $LOG.


-- 
ldv
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 181 bytes
Desc: not available
URL: <http://lists.strace.io/pipermail/strace-devel/attachments/20141107/a9f6d90d/attachment.bin>


More information about the Strace-devel mailing list