[firefly] [PATCH 3/3 RFC v2] selftest: net: add socket options test with IPv6 testcases

Daniel Baluta daniel.baluta at gmail.com
Thu Apr 25 13:35:38 EEST 2013


Please use selftests/net instead of selftests:net: as subject.

On Thu, Apr 25, 2013 at 10:45 AM, Alexandru Copot
<alex.mihai.c at gmail.com> wrote:
> Only a part of the boolean socket options for IPv6 are tested.
>
> Signed-of by Alexandru Copot <alex.mihai.c at gmail.com>
> Cc: Daniel Baluta <dbaluta at ixiacom.com>
> ---
>  tools/testing/selftests/net/Makefile         |   3 +-
>  tools/testing/selftests/net/run_netsocktests |  10 ++
>  tools/testing/selftests/net/sockopt.c        | 185 +++++++++++++++++++++++++++
>  3 files changed, 197 insertions(+), 1 deletion(-)
>  create mode 100644 tools/testing/selftests/net/sockopt.c
>
> diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile
> index 7984f80..087e9a0 100644
> --- a/tools/testing/selftests/net/Makefile
> +++ b/tools/testing/selftests/net/Makefile
> @@ -5,13 +5,14 @@ CFLAGS = -Wall -O2 -g
>
>  CFLAGS += -I../../../../usr/include/ -I../lib
>
> -NET_PROGS = socket psock_fanout psock_tpacket
> +NET_PROGS = socket sockopt psock_fanout psock_tpacket
>
>  LIB = ../lib/selftests.a
>
>  all: $(NET_PROGS)
>
>  socket: socket.o $(LIB)
> +sockopt: sockopt.o $(LIB)
>
>  %.o: %.c
>         $(CC) $(CFLAGS) -c -o $@ $^
> diff --git a/tools/testing/selftests/net/run_netsocktests b/tools/testing/selftests/net/run_netsocktests
> index c09a682..9f21498 100644
> --- a/tools/testing/selftests/net/run_netsocktests
> +++ b/tools/testing/selftests/net/run_netsocktests
> @@ -10,3 +10,13 @@ else
>         echo "[PASS]"
>  fi
>
> +echo "--------------------"
> +echo "running setsockopt test"
> +echo "--------------------"
> +./sockopt
> +if [ $? -ne 0 ]; then
> +       echo "[FAIL]"
> +else
> +       echo "[PASS]"
> +fi
> +
> diff --git a/tools/testing/selftests/net/sockopt.c b/tools/testing/selftests/net/sockopt.c
> new file mode 100644
> index 0000000..56311bc
> --- /dev/null
> +++ b/tools/testing/selftests/net/sockopt.c
> @@ -0,0 +1,185 @@
> +#include <stdio.h>
> +#include <errno.h>
> +#include <unistd.h>
> +#include <string.h>
> +#include <sys/types.h>
> +#include <sys/socket.h>
> +#include <linux/ipv6.h>
> +#include <linux/in.h>
> +
> +#include "selftests.h"
> +
> +struct sockopt_testcase {
> +       /* socket */
> +       int     domain;
> +       int     type;
> +       int     protocol;
> +
> +       /* option */
> +       int     level;
> +       int     optname;
> +       void    *value;
> +       socklen_t size;
> +
> +       #define TYPE_INT   1
> +       #define TYPE_DATA  2
> +       int data_type;
> +       /* 0    = valid file descriptor
> +        * -foo = error foo
> +        */
> +       int     expect_set;
> +       int     expect_get;
> +
> +       /* If non-zero, accept EAFNOSUPPORT to handle the case
> +        * of the protocol not being configured into the kernel.
> +        */
> +       int     nosupport_ok;
> +};
> +
> +static struct sockopt_testcase tests_inet6[] = {
> +
> +       { AF_INET6, SOCK_STREAM, IPPROTO_TCP,   IPPROTO_IPV6, IPV6_V6ONLY,                  (void*)1, sizeof(int),  TYPE_INT, 0,  0,  0},
> +       { AF_INET6, SOCK_STREAM, IPPROTO_TCP,   IPPROTO_IPV6, IPV6_V6ONLY,                  (void*)0, sizeof(int),  TYPE_INT, 0,  0,  0},
> +
> +       { AF_INET6, SOCK_STREAM, IPPROTO_TCP,   IPPROTO_IPV6, IPV6_RECVPKTINFO,             (void*)1, sizeof(int),  TYPE_INT, 0,  0,  0},
> +       { AF_INET6, SOCK_STREAM, IPPROTO_TCP,   IPPROTO_IPV6, IPV6_RECVPKTINFO,             (void*)0, sizeof(int),  TYPE_INT, 0,  0,  0},
> +
> +       { AF_INET6, SOCK_STREAM, IPPROTO_TCP,   IPPROTO_IPV6, IPV6_2292PKTINFO,             (void*)1, sizeof(int),  TYPE_INT, 0,  0,  0},
> +       { AF_INET6, SOCK_STREAM, IPPROTO_TCP,   IPPROTO_IPV6, IPV6_2292PKTINFO,             (void*)0, sizeof(int),  TYPE_INT, 0,  0,  0},
> +
> +       { AF_INET6, SOCK_STREAM, IPPROTO_TCP,   IPPROTO_IPV6, IPV6_RECVHOPLIMIT,            (void*)1, sizeof(int),  TYPE_INT, 0,  0,  0},
> +       { AF_INET6, SOCK_STREAM, IPPROTO_TCP,   IPPROTO_IPV6, IPV6_RECVHOPLIMIT,            (void*)0, sizeof(int),  TYPE_INT, 0,  0,  0},
> +
> +       { AF_INET6, SOCK_STREAM, IPPROTO_TCP,   IPPROTO_IPV6, IPV6_2292HOPLIMIT,            (void*)1, sizeof(int),  TYPE_INT, 0,  0,  0},
> +       { AF_INET6, SOCK_STREAM, IPPROTO_TCP,   IPPROTO_IPV6, IPV6_2292HOPLIMIT,            (void*)0, sizeof(int),  TYPE_INT, 0,  0,  0},
> +
> +       { AF_INET6, SOCK_STREAM, IPPROTO_TCP,   IPPROTO_IPV6, IPV6_RECVRTHDR,               (void*)1, sizeof(int),  TYPE_INT, 0,  0,  0},
> +       { AF_INET6, SOCK_STREAM, IPPROTO_TCP,   IPPROTO_IPV6, IPV6_RECVRTHDR,               (void*)0, sizeof(int),  TYPE_INT, 0,  0,  0},
> +
> +       { AF_INET6, SOCK_STREAM, IPPROTO_TCP,   IPPROTO_IPV6, IPV6_2292RTHDR,               (void*)1, sizeof(int),  TYPE_INT, 0,  0,  0},
> +       { AF_INET6, SOCK_STREAM, IPPROTO_TCP,   IPPROTO_IPV6, IPV6_2292RTHDR,               (void*)0, sizeof(int),  TYPE_INT, 0,  0,  0},
> +
> +       { AF_INET6, SOCK_STREAM, IPPROTO_TCP,   IPPROTO_IPV6, IPV6_RECVHOPOPTS,             (void*)1, sizeof(int),  TYPE_INT, 0,  0,  0},
> +       { AF_INET6, SOCK_STREAM, IPPROTO_TCP,   IPPROTO_IPV6, IPV6_RECVHOPOPTS,             (void*)0, sizeof(int),  TYPE_INT, 0,  0,  0},
> +
> +       { AF_INET6, SOCK_STREAM, IPPROTO_TCP,   IPPROTO_IPV6, IPV6_2292HOPOPTS,             (void*)1, sizeof(int),  TYPE_INT, 0,  0,  0},
> +       { AF_INET6, SOCK_STREAM, IPPROTO_TCP,   IPPROTO_IPV6, IPV6_2292HOPOPTS,             (void*)0, sizeof(int),  TYPE_INT, 0,  0,  0},
> +
> +       { AF_INET6, SOCK_STREAM, IPPROTO_TCP,   IPPROTO_IPV6, IPV6_RECVDSTOPTS,             (void*)1, sizeof(int),  TYPE_INT, 0,  0,  0},
> +       { AF_INET6, SOCK_STREAM, IPPROTO_TCP,   IPPROTO_IPV6, IPV6_RECVDSTOPTS,             (void*)0, sizeof(int),  TYPE_INT, 0,  0,  0},
> +
> +       { AF_INET6, SOCK_STREAM, IPPROTO_TCP,   IPPROTO_IPV6, IPV6_2292DSTOPTS,             (void*)1, sizeof(int),  TYPE_INT, 0,  0,  0},
> +       { AF_INET6, SOCK_STREAM, IPPROTO_TCP,   IPPROTO_IPV6, IPV6_2292DSTOPTS,             (void*)0, sizeof(int),  TYPE_INT, 0,  0,  0},
> +
> +       { AF_INET6, SOCK_STREAM, IPPROTO_TCP,   IPPROTO_IPV6, IPV6_TCLASS,                  (void*)1, sizeof(int),  TYPE_INT, 0,  0,  0},
> +       { AF_INET6, SOCK_STREAM, IPPROTO_TCP,   IPPROTO_IPV6, IPV6_TCLASS,                  (void*)0, sizeof(int),  TYPE_INT, 0,  0,  0},
> +
> +       { AF_INET6, SOCK_STREAM, IPPROTO_TCP,   IPPROTO_IPV6, IPV6_RECVTCLASS,              (void*)1, sizeof(int),  TYPE_INT, 0,  0,  0},
> +       { AF_INET6, SOCK_STREAM, IPPROTO_TCP,   IPPROTO_IPV6, IPV6_RECVTCLASS,              (void*)0, sizeof(int),  TYPE_INT, 0,  0,  0},
> +
> +       { AF_INET6, SOCK_STREAM, IPPROTO_TCP,   IPPROTO_IPV6, IPV6_FLOWINFO,                (void*)1, sizeof(int),  TYPE_INT, 0,  0},
> +       { AF_INET6, SOCK_STREAM, IPPROTO_TCP,   IPPROTO_IPV6, IPV6_FLOWINFO,                (void*)0, sizeof(int),  TYPE_INT, 0,  0},
> +
> +       { AF_INET6, SOCK_STREAM, IPPROTO_TCP,   IPPROTO_IPV6, IPV6_RECVPATHMTU,             (void*)1, sizeof(int),  TYPE_INT, 0,  0},
> +       { AF_INET6, SOCK_STREAM, IPPROTO_TCP,   IPPROTO_IPV6, IPV6_RECVPATHMTU,             (void*)0, sizeof(int),  TYPE_INT, 0,  0},
> +
> +       { AF_INET6, SOCK_STREAM, IPPROTO_TCP,   IPPROTO_IPV6, IPV6_RECVORIGDSTADDR,         (void*)1, sizeof(int),  TYPE_INT, 0,  0},
> +       { AF_INET6, SOCK_STREAM, IPPROTO_TCP,   IPPROTO_IPV6, IPV6_RECVORIGDSTADDR,         (void*)0, sizeof(int),  TYPE_INT, 0,  0},
> +
> +       { AF_INET6, SOCK_STREAM, IPPROTO_TCP,   IPPROTO_IPV6, IPV6_MTU,                     (void*)512,          sizeof(int),  TYPE_INT, -EINVAL, -ENOTCONN, 0},
> +       { AF_INET6, SOCK_STREAM, IPPROTO_TCP,   IPPROTO_IPV6, IPV6_MTU,                     (void*)IPV6_MIN_MTU, sizeof(int),  TYPE_INT,       0, -ENOTCONN, 0},
> +
> +       { AF_INET6, SOCK_STREAM, IPPROTO_TCP,   IPPROTO_IPV6, IPV6_DONTFRAG,                (void*)1,            sizeof(int),  TYPE_INT,       0,         0, 0},
> +       { AF_INET6, SOCK_STREAM, IPPROTO_TCP,   IPPROTO_IPV6, IPV6_DONTFRAG,                (void*)0,            sizeof(int),  TYPE_INT,       0,         0, 0},
> +
> +       { AF_INET6, SOCK_STREAM, IPPROTO_TCP,   IPPROTO_IPV6, IPV6_MTU_DISCOVER,             (void*)IP_PMTUDISC_DONT, sizeof(int),  TYPE_INT,       0,     0, 0},
> +       { AF_INET6, SOCK_STREAM, IPPROTO_TCP,   IPPROTO_IPV6, IPV6_MTU_DISCOVER,             (void*)IP_PMTUDISC_WANT, sizeof(int),  TYPE_INT,       0,     0, 0},
> +       { AF_INET6, SOCK_STREAM, IPPROTO_TCP,   IPPROTO_IPV6, IPV6_MTU_DISCOVER,             (void*)IP_PMTUDISC_DO,   sizeof(int),  TYPE_INT,       0,     0, 0},
> +       { AF_INET6, SOCK_STREAM, IPPROTO_TCP,   IPPROTO_IPV6, IPV6_MTU_DISCOVER,             (void*)IP_PMTUDISC_PROBE,sizeof(int),  TYPE_INT,       0,     0, 0},
> +
> +};
> +
> +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
> +#define ERR_STRING_SZ  64
> +
> +static test_result_t my_run_testcase(void *arg)
> +{
> +       struct sockopt_testcase *s = (struct sockopt_testcase*)arg;
> +       int fd, rc, val;
> +       void *optdata;
> +       socklen_t readsize;
> +       test_result_t ret;
> +
> +       ret = 0;
> +       fd = socket(s->domain, s->type, s->protocol);
> +       abort(fd > 0);
> +
> +       if (s->data_type == TYPE_INT) {
> +               val = (long)s->value;
> +               optdata = &val;
> +       } else {
> +               optdata = s->value;
> +       }
> +
> +       rc = setsockopt(fd, s->level, s->optname, optdata, s->size);
> +       check(rc == 0 || errno == -s->expect_set, clean_socket, ret,
> +             "setsockopt option %d", s->optname);
> +
> +       if (s->data_type == TYPE_INT) {
> +               optdata = &val;
> +               val = -1;
> +       } else {
> +               optdata = malloc(s->size);
> +               abort(optdata != NULL);
> +       }
> +
> +       readsize = s->size;
> +       rc = getsockopt(fd, s->level, s->optname, optdata, &readsize);
> +       check(rc == 0 || errno == -s->expect_get, clean_data, ret,
> +             "getsockopt option %d", s->optname);
> +       abort(readsize == s->size);
> +
> +       if (!rc) {
> +               if (s->data_type == TYPE_INT) {
> +                       check(val == (long)s->value, clean_socket, ret,
> +                             "option %d: Read value different from written value\n", s->optname);
> +               } else {
> +                       check(!memcmp(optdata, s->value, s->size), clean_data, ret,
> +                             "option %d: Read value different from written value\n", s->optname);
> +               }
> +       }
> +
> +clean_data:
> +       if (s->data_type != TYPE_INT)
> +               free(optdata);
> +clean_socket:
> +       abort(close(fd) == 0);
> +
> +       return ret;
> +}
> +
> +static int run_tests(void)
> +{
> +       int rc;
> +       struct generic_test test1 = {
> +               .name = "sockopt AF_INET6",
> +               .prepare = NULL,
> +               .run = my_run_testcase,
> +               .testcases = tests_inet6,
> +               .testcase_size = sizeof(struct sockopt_testcase),
> +               .testcase_count = ARRAY_SIZE(tests_inet6),
> +               .abort_on_fail = 1,
> +       };
> +
> +       rc = 0;
> +       rc |= run_all_tests(&test1, NULL);
> +
> +       return rc;
> +}
> +
> +int main(void)
> +{
> +       int err = run_tests();
> +
> +       return err;
> +}

Otherwise looks good. Thanks Alex.


More information about the firefly mailing list