From 8dacfe492e20ad25a779c1b99f966759a98087bc Mon Sep 17 00:00:00 2001 From: Christian Mauderer Date: Tue, 28 Jun 2016 15:13:09 +0200 Subject: testsuite/cdev01: Add test for cdev functions. --- libbsd.py | 1 + libbsd_waf.py | 11 +++ testsuite/cdev01/test_cdev.c | 159 +++++++++++++++++++++++++++++++++++++++++ testsuite/cdev01/test_cdev01.h | 54 ++++++++++++++ testsuite/cdev01/test_main.c | 139 +++++++++++++++++++++++++++++++++++ 5 files changed, 364 insertions(+) create mode 100644 testsuite/cdev01/test_cdev.c create mode 100644 testsuite/cdev01/test_cdev01.h create mode 100644 testsuite/cdev01/test_main.c diff --git a/libbsd.py b/libbsd.py index 7771a4ff..48f0abeb 100755 --- a/libbsd.py +++ b/libbsd.py @@ -2548,6 +2548,7 @@ def tests(mm): mod.addTest(mm.generator['test']('log01', ['test_main'])) mod.addTest(mm.generator['test']('rcconf01', ['test_main'])) mod.addTest(mm.generator['test']('rcconf02', ['test_main'])) + mod.addTest(mm.generator['test']('cdev01', ['test_main', 'test_cdev'])) return mod # diff --git a/libbsd_waf.py b/libbsd_waf.py index b80dad5c..8e6414b9 100644 --- a/libbsd_waf.py +++ b/libbsd_waf.py @@ -1205,6 +1205,17 @@ def build(bld): lib = ["m", "z"], install_path = None) + test_cdev01 = ['testsuite/cdev01/test_cdev.c', + 'testsuite/cdev01/test_main.c'] + bld.program(target = "cdev01.exe", + features = "cprogram", + cflags = cflags, + includes = includes, + source = test_cdev01, + use = ["bsd"], + lib = ["m", "z"], + install_path = None) + test_commands01 = ['testsuite/commands01/test_main.c'] bld.program(target = "commands01.exe", features = "cprogram", diff --git a/testsuite/cdev01/test_cdev.c b/testsuite/cdev01/test_cdev.c new file mode 100644 index 00000000..19fb1a5e --- /dev/null +++ b/testsuite/cdev01/test_cdev.c @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2016 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include + +#include + +#include + +#include "test_cdev01.h" + +static d_open_t testopen; +static d_close_t testclose; +static d_read_t testread; +static d_write_t testwrite; +static d_ioctl_t testioctl; +static d_poll_t testpoll; +static d_kqfilter_t testkqfilter; + +static struct cdevsw test_cdevsw = { + .d_version = D_VERSION, + .d_flags = 0, +/* FIXME: check for D_PSEUDO | D_NEEDMINOR | D_NEEDGIANT | D_TRACKCLOSE */ + .d_name = "test", + .d_open = testopen, + .d_close = testclose, + .d_read = testread, + .d_write = testwrite, + .d_ioctl = testioctl, + .d_poll = testpoll, + .d_kqfilter = testkqfilter, +}; + +static int +testopen(struct cdev *dev, int oflags, int devtype, struct thread *td) +{ + test_state *state = dev->si_drv1; + + assert(*state == TEST_NEW); + *state = TEST_OPEN; + + return 0; +} + +static int +testclose(struct cdev *dev, int fflag, int devtype, struct thread *td) +{ + test_state *state = dev->si_drv1; + + assert(*state == TEST_KQFILTER); + *state = TEST_CLOSED; + + return 0; +} + +static int +testread(struct cdev *dev, struct uio *uio, int ioflag) +{ + test_state *state = dev->si_drv1; + + assert(*state == TEST_OPEN || *state == TEST_IOCTL); + if(*state == TEST_OPEN) { + *state = TEST_READ; + } else { + *state = TEST_READV; + } + + return 0; +} + +static int +testwrite(struct cdev *dev, struct uio *uio, int ioflag) +{ + test_state *state = dev->si_drv1; + + assert(*state == TEST_READ || *state == TEST_READV); + if(*state == TEST_READ) { + *state = TEST_WRITE; + } else { + *state = TEST_WRITEV; + } + + return 0; +} + +static int +testioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, + struct thread *td) +{ + test_state *state = dev->si_drv1; + + assert(cmd == TEST_IOCTL_CMD); + assert(*state == TEST_WRITE); + *state = TEST_IOCTL; + + return 0; +} + +static int +testpoll(struct cdev *dev, int events, struct thread *td) +{ + test_state *state = dev->si_drv1; + + assert(*state == TEST_WRITEV); + *state = TEST_POLL; + + return 1; +} + +static int +testkqfilter(struct cdev *dev, struct knote *kn) +{ + test_state *state = dev->si_drv1; + + assert(*state == TEST_POLL); + *state = TEST_KQFILTER; + + return TEST_KQ_ERRNO; +} + +void +test_make_dev(test_state *state, const char *name) +{ + struct cdev *dev = NULL; + + dev = make_dev(&test_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, name); + assert(dev != NULL); + dev->si_drv1 = state; +} diff --git a/testsuite/cdev01/test_cdev01.h b/testsuite/cdev01/test_cdev01.h new file mode 100644 index 00000000..a83001b5 --- /dev/null +++ b/testsuite/cdev01/test_cdev01.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2016 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef TEST_CDEV01_H +#define TEST_CDEV01_H + +typedef enum { + TEST_NEW, + TEST_OPEN, + TEST_READ, + TEST_WRITE, + TEST_IOCTL, + TEST_READV, + TEST_WRITEV, + TEST_POLL, + TEST_KQFILTER, + TEST_CLOSED +} test_state; + +void test_make_dev(test_state *state, const char *name); + +#define TEST_IOCTL_CMD 0x12344321 +#define TEST_KQ_ERRNO ENOTTY /* This should never happen in normal kq */ +#define TEST_UDATA ((void *) 0xcafe) + +#endif /* TEST_CDEV01_H */ diff --git a/testsuite/cdev01/test_main.c b/testsuite/cdev01/test_main.c new file mode 100644 index 00000000..898eb174 --- /dev/null +++ b/testsuite/cdev01/test_main.c @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2016 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "test_cdev01.h" + +#define TEST_NAME "LIBBSD CDEV 1" + +static void test_cdev(void) +{ + const char *name = "test"; + const char *path = "/dev/test"; + const struct timespec *timeout = NULL; + + test_state state = TEST_NEW; + int rv = 0; + int fd = 0; + char buf[1]; + ssize_t n = 0; + off_t off = 0; + struct iovec iov = { + .iov_base = &buf [0], + .iov_len = (int) sizeof(buf) + }; + struct pollfd fds[1]; + int kq; + struct kevent change; + + test_make_dev(&state, name); + + fd = open(path, O_RDWR); + assert(fd >= 0); + fds[0].fd = fd; + fds[0].events = POLLOUT | POLLIN; + + n = read(fd, buf, sizeof(buf)); + assert(n == 0); + + n = write(fd, buf, sizeof(buf)); + assert(n == 0); + + rv = ioctl(fd, TEST_IOCTL_CMD); + assert(rv == 0); + + off = lseek(fd, off, SEEK_SET); + assert(off == 0); + + rv = ftruncate(fd, 0); + assert(rv == -1); + assert(errno == EINVAL); + + rv = fsync(fd); + assert(rv == -1); + assert(errno == EINVAL); + + rv = fdatasync(fd); + assert(rv == -1); + assert(errno == EINVAL); + + rv = fcntl(fd, F_GETFD); + assert(rv >= 0); + + rv = readv(fd, &iov, 1); + assert(rv == 0); + + rv = writev(fd, &iov, 1); + assert(rv == 0); + + rv = poll(fds, sizeof(fds)/sizeof(fds[0]), 500); + assert(rv > 0); + + kq = kqueue(); + assert(kq >= 0); + + EV_SET(&change, fd, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, TEST_UDATA); + + rv = kevent(kq, &change, 1, NULL, 0, timeout); + assert(rv == -1); + assert(errno == TEST_KQ_ERRNO); + + rv = close(fd); + assert(rv == 0); + + rv = unlink(path); + assert(rv == 0); + + assert(state == TEST_CLOSED); +} + +static void +test_main(void) +{ + test_cdev(); + + exit(0); +} + +#include -- cgit v1.2.3