----------
-* porting the unit tests of core libgpiod library to using GLib
-
-Once libgpiod-test is ready, we can think about reusing existing testing
-frameworks instead of using a custom solution.
-
-For the core C library a good candidate would be the GLib unit testing library.
-GLib already provides a significant number of functionalities we currently use
-like starting sub-processes, reading files, assertions plus it also offers a
-range of output formatting and report generation options.
-
-----------
-
* use a proper unit testing framework for C++ bindings and reuse libgpiod-test
The actual framework for testing is TBD but libgpiod-test could be reused as is
if test "x$with_tests" = xtrue
then
- AC_CHECK_FUNC([qsort], [], [FUNC_NOT_FOUND_TESTS([qsort])])
- AC_CHECK_FUNC([regexec], [], [FUNC_NOT_FOUND_TESTS([regexec])])
AC_CHECK_HEADERS([linux/version.h], [], [HEADER_NOT_FOUND_TESTS([linux/version.h])])
+ # For libgpiomockup
+ AC_CHECK_FUNC([qsort], [], [FUNC_NOT_FOUND_TESTS([qsort])])
PKG_CHECK_MODULES([KMOD], [libkmod >= 18])
PKG_CHECK_MODULES([UDEV], [libudev >= 215])
+
+ # For core library tests
+ PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.50])
+
+ if test "x$with_tools" = xtrue
+ then
+ AC_CHECK_PROG([has_bats], [bats], [true], [false])
+ if test "x$has_bats" = "xflase"
+ then
+ AC_MSG_NOTICE(["bats not found - gpio-tools tests cannot be run])
+ fi
+ fi
fi
# ABI version for libgpiomockup (we need this since it can be installed if we
AM_CFLAGS = -I$(top_srcdir)/include/ -I$(top_srcdir)/tests/mockup/
AM_CFLAGS += -include $(top_builddir)/config.h
-AM_CFLAGS += -Wall -Wextra -g
+AM_CFLAGS += -Wall -Wextra -g $(GLIB_CFLAGS)
AM_LDFLAGS = -pthread
LDADD = $(top_builddir)/lib/libgpiod.la
LDADD += $(top_builddir)/tests/mockup/libgpiomockup.la
+LDADD += $(GLIB_LIBS)
bin_PROGRAMS = gpiod-test
tests-line.c \
tests-misc.c
-if WITH_TOOLS
-
-gpiod_test_SOURCES += tests-gpiodetect.c \
- tests-gpiofind.c \
- tests-gpioget.c \
- tests-gpioinfo.c \
- tests-gpiomon.c \
- tests-gpioset.c
-
-endif
-
all-local: gpiod-test
@echo " ********************************************************"
- @echo " * Tests have been built as tests/gpiod-test. *"
+ @echo " * Core tests have been built as tests/gpiod-test. *"
@echo " * *"
@echo " * They require a recent linux kernel version and the *"
@echo " * gpio-mockup module (must not be built-in). *"
/*
* This file is part of libgpiod.
*
- * Copyright (C) 2017-2018 Bartosz Golaszewski <bartekgola@gmail.com>
* Copyright (C) 2019 Bartosz Golaszewski <bgolaszewski@baylibre.com>
*/
-#include <ctype.h>
#include <errno.h>
-#include <fcntl.h>
+#include <glib/gstdio.h>
#include <gpio-mockup.h>
-#include <libgen.h>
-#include <poll.h>
-#include <pthread.h>
-#include <regex.h>
-#include <signal.h>
-#include <stdarg.h>
+#include <linux/version.h>
#include <stdio.h>
-#include <string.h>
-#include <sys/signalfd.h>
-#include <sys/time.h>
-#include <sys/types.h>
#include <sys/utsname.h>
-#include <sys/wait.h>
#include <unistd.h>
#include "gpiod-test.h"
-#define NORETURN __attribute__((noreturn))
-#define MALLOC __attribute__((malloc))
-
-static const unsigned int min_kern_major = 5;
-static const unsigned int min_kern_minor = 1;
-static const unsigned int min_kern_release = 0;
-
-struct event_thread {
- pthread_t thread_id;
- pthread_mutex_t lock;
- pthread_cond_t cond;
- bool running;
- bool should_stop;
- unsigned int chip_index;
- unsigned int line_offset;
- unsigned int freq;
-};
-
-struct gpiotool_proc {
- pid_t pid;
- bool running;
- int stdin_fd;
- int stdout_fd;
- int stderr_fd;
- char *stdout;
- char *stderr;
- int sig_fd;
- int exit_status;
-};
-
-struct test_context {
- size_t num_chips;
- bool test_failed;
- char *failed_msg;
- char *custom_str;
- struct event_thread event;
- struct gpiotool_proc tool_proc;
- bool running;
+#define MIN_KERNEL_MAJOR 5
+#define MIN_KERNEL_MINOR 1
+#define MIN_KERNEL_RELEASE 0
+#define MIN_KERNEL_VERSION KERNEL_VERSION(MIN_KERNEL_MAJOR, \
+ MIN_KERNEL_MINOR, \
+ MIN_KERNEL_RELEASE)
+
+struct gpiod_test_event_thread {
+ GThread *id;
+ GMutex lock;
+ GCond cond;
+ gboolean should_stop;
+ guint chip_index;
+ guint line_offset;
+ guint freq;
};
static struct {
- struct _test_case *test_list_head;
- struct _test_case *test_list_tail;
- unsigned int num_tests;
- unsigned int tests_failed;
+ _GpiodTestCase *test_list_head;
+ _GpiodTestCase *test_list_tail;
+ guint num_tests;
struct gpio_mockup *mockup;
- struct test_context test_ctx;
- pid_t main_pid;
- int pipesize;
- char *pipebuf;
- char *toolpath;
} globals;
-enum {
- CNORM = 0,
- CGREEN,
- CRED,
- CREDBOLD,
- CYELLOW,
-};
-
-static const char *const term_colors[] = {
- "\033[0m",
- "\033[32m",
- "\033[31m",
- "\033[1m\033[31m",
- "\033[33m",
-};
-
-static void set_color(int color)
-{
- fprintf(stderr, "%s", term_colors[color]);
-}
-
-static void reset_color(void)
-{
- fprintf(stderr, "%s", term_colors[CNORM]);
-}
-
-static void pr_raw_v(const char *fmt, va_list va)
-{
- vfprintf(stderr, fmt, va);
-}
-
-static TEST_PRINTF(1, 2) void pr_raw(const char *fmt, ...)
-{
- va_list va;
-
- va_start(va, fmt);
- pr_raw_v(fmt, va);
- va_end(va);
-}
-
-static void print_header(const char *hdr, int color)
-{
- char buf[9];
-
- snprintf(buf, sizeof(buf), "[%s]", hdr);
-
- set_color(color);
- pr_raw("%-8s", buf);
- reset_color();
-}
-
-static void vmsgn(const char *hdr, int hdr_clr, const char *fmt, va_list va)
-{
- print_header(hdr, hdr_clr);
- pr_raw_v(fmt, va);
-}
-
-static void vmsg(const char *hdr, int hdr_clr, const char *fmt, va_list va)
-{
- vmsgn(hdr, hdr_clr, fmt, va);
- pr_raw("\n");
-}
-
-static TEST_PRINTF(1, 2) void msg(const char *fmt, ...)
-{
- va_list va;
-
- va_start(va, fmt);
- vmsg("INFO", CGREEN, fmt, va);
- va_end(va);
-}
-
-static TEST_PRINTF(1, 2) void err(const char *fmt, ...)
-{
- va_list va;
-
- va_start(va, fmt);
- vmsg("ERROR", CRED, fmt, va);
- va_end(va);
-}
-
-static void die_test_cleanup(void)
-{
- struct gpiotool_proc *proc = &globals.test_ctx.tool_proc;
- int rv;
-
- if (proc->running) {
- kill(proc->pid, SIGKILL);
- waitpid(proc->pid, &rv, 0);
- }
-
- if (globals.test_ctx.running)
- pr_raw("\n");
-}
-
-static TEST_PRINTF(1, 2) NORETURN void die(const char *fmt, ...)
-{
- va_list va;
-
- die_test_cleanup();
-
- va_start(va, fmt);
- vmsg("FATAL", CRED, fmt, va);
- va_end(va);
-
- exit(EXIT_FAILURE);
-}
-
-static TEST_PRINTF(1, 2) NORETURN void die_perr(const char *fmt, ...)
-{
- va_list va;
-
- die_test_cleanup();
-
- va_start(va, fmt);
- vmsgn("FATAL", CRED, fmt, va);
- pr_raw(": %s\n", strerror(errno));
- va_end(va);
-
- exit(EXIT_FAILURE);
-}
-
-static MALLOC void *xmalloc(size_t size)
-{
- void *ptr;
-
- ptr = malloc(size);
- if (!ptr)
- die("out of memory");
-
- return ptr;
-}
-
-static MALLOC void *xzalloc(size_t size)
-{
- void *ptr;
-
- ptr = xmalloc(size);
- memset(ptr, 0, size);
-
- return ptr;
-}
-
-static MALLOC void *xcalloc(size_t nmemb, size_t size)
-{
- void *ptr;
-
- ptr = calloc(nmemb, size);
- if (!ptr)
- die("out of memory");
-
- return ptr;
-}
-
-static MALLOC char *xstrdup(const char *str)
-{
- char *ret;
-
- ret = strdup(str);
- if (!ret)
- die("out of memory");
-
- return ret;
-}
-
-static TEST_PRINTF(2, 3) char *xappend(char *str, const char *fmt, ...)
-{
- char *new, *ret;
- va_list va;
- int rv;
-
- va_start(va, fmt);
- rv = vasprintf(&new, fmt, va);
- va_end(va);
- if (rv < 0)
- die_perr("vasprintf");
-
- if (!str)
- return new;
-
- ret = realloc(str, strlen(str) + strlen(new) + 1);
- if (!ret)
- die("out of memory");
-
- strcat(ret, new);
- free(new);
-
- return ret;
-}
-
-static int get_pipesize(void)
-{
- int pipe_fds[2], rv;
-
- rv = pipe(pipe_fds);
- if (rv < 0)
- die_perr("unable to create a pipe");
-
- /*
- * Since linux v2.6.11 the default pipe capacity is 16 system pages.
- * We make an assumption here that gpio-tools won't output more than
- * that, so we can read everything after the program terminated. If
- * they did output more than the pipe capacity however, the write()
- * system call would block and the process would be killed by the
- * testing framework.
- */
- rv = fcntl(pipe_fds[0], F_GETPIPE_SZ);
- if (rv < 0)
- die_perr("unable to retrieve the pipe capacity");
-
- close(pipe_fds[0]);
- close(pipe_fds[1]);
-
- return rv;
-}
-
-static void check_chip_index(unsigned int index)
-{
- if (index >= globals.test_ctx.num_chips)
- die("invalid chip number requested from test code");
-}
-
-static void cleanup_func(void)
-{
- /* Don't cleanup from child processes. */
- if (globals.main_pid != getpid())
- return;
-
- msg("cleaning up");
-
- free(globals.pipebuf);
- if (globals.toolpath)
- free(globals.toolpath);
-
- if (globals.mockup)
- gpio_mockup_unref(globals.mockup);
-}
-
-static void event_lock(void)
-{
- pthread_mutex_lock(&globals.test_ctx.event.lock);
-}
-
-static void event_unlock(void)
-{
- pthread_mutex_unlock(&globals.test_ctx.event.lock);
-}
-
-static void *event_worker(void *data TEST_UNUSED)
-{
- struct event_thread *ev = &globals.test_ctx.event;
- struct timeval tv_now, tv_add, tv_res;
- struct timespec ts;
- int rv, i;
-
- for (i = 0;; i++) {
- event_lock();
- if (ev->should_stop) {
- event_unlock();
- break;
- }
-
- gettimeofday(&tv_now, NULL);
- tv_add.tv_sec = 0;
- tv_add.tv_usec = ev->freq * 1000;
- timeradd(&tv_now, &tv_add, &tv_res);
- ts.tv_sec = tv_res.tv_sec;
- ts.tv_nsec = tv_res.tv_usec * 1000;
-
- rv = pthread_cond_timedwait(&ev->cond, &ev->lock, &ts);
- if (rv == ETIMEDOUT) {
- rv = gpio_mockup_set_pull(globals.mockup, ev->chip_index,
- ev->line_offset, i % 2);
- if (rv)
- die_perr("error generating line event");
- } else if (rv != 0) {
- die("error waiting for conditional variable: %s",
- strerror(rv));
- }
-
- event_unlock();
- }
-
- return NULL;
-}
-
-static void gpiotool_proc_make_pipes(int *in_fds, int *out_fds, int *err_fds)
-{
- int rv, i, *fds[3];
-
- fds[0] = in_fds;
- fds[1] = out_fds;
- fds[2] = err_fds;
-
- for (i = 0; i < 3; i++) {
- rv = pipe(fds[i]);
- if (rv < 0)
- die_perr("unable to create a pipe");
- }
-}
-
-static void gpiotool_proc_dup_fds(int in_fd, int out_fd, int err_fd)
-{
- int old_fds[3], new_fds[3], i, rv;
-
- old_fds[0] = in_fd;
- old_fds[1] = out_fd;
- old_fds[2] = err_fd;
-
- new_fds[0] = STDIN_FILENO;
- new_fds[1] = STDOUT_FILENO;
- new_fds[2] = STDERR_FILENO;
-
- for (i = 0; i < 3; i++) {
- rv = dup2(old_fds[i], new_fds[i]);
- if (rv < 0)
- die_perr("unable to duplicate a file descriptor");
-
- close(old_fds[i]);
- }
-}
-
-static NORETURN void gpiotool_proc_exec(const char *path, va_list va)
-{
- size_t num_args;
- unsigned int i;
- char **argv;
- va_list va2;
-
- va_copy(va2, va);
- for (num_args = 2; va_arg(va2, char *) != NULL; num_args++)
- ;
- va_end(va2);
-
- argv = xcalloc(num_args, sizeof(char *));
-
- argv[0] = (char *)path;
- for (i = 1; i < num_args; i++)
- argv[i] = va_arg(va, char *);
- va_end(va);
-
- execv(path, argv);
- die_perr("unable to exec '%s'", path);
-}
-
-static void gpiotool_proc_cleanup(void)
-{
- struct gpiotool_proc *proc = &globals.test_ctx.tool_proc;
-
- if (proc->stdout)
- free(proc->stdout);
-
- if (proc->stderr)
- free(proc->stderr);
-
- proc->stdout = proc->stderr = NULL;
-}
-
-void test_tool_signal(int signum)
-{
- struct gpiotool_proc *proc = &globals.test_ctx.tool_proc;
- int rv;
-
- rv = kill(proc->pid, signum);
- if (rv)
- die_perr("unable to send signal to process %d", proc->pid);
-}
-
-void test_tool_stdin_write(const char *fmt, ...)
-{
- struct gpiotool_proc *proc = &globals.test_ctx.tool_proc;
- ssize_t written;
- va_list va;
- char *in;
- int rv;
-
- va_start(va, fmt);
- rv = vasprintf(&in, fmt, va);
- va_end(va);
- if (rv < 0)
- die_perr("error building string");
-
- written = write(proc->stdin_fd, in, rv);
- free(in);
- if (written < 0)
- die_perr("error writing to child process' stdin");
- if (written != rv)
- die("unable to write all data to child process' stdin");
-}
-
-void test_tool_run(char *tool, ...)
-{
- int in_fds[2], out_fds[2], err_fds[2], rv;
- struct gpiotool_proc *proc;
- sigset_t sigmask;
- char *path;
- va_list va;
-
- proc = &globals.test_ctx.tool_proc;
- if (proc->running)
- die("unable to start %s - another tool already running", tool);
-
- if (proc->pid)
- gpiotool_proc_cleanup();
-
- event_lock();
- if (globals.test_ctx.event.running)
- die("refusing to fork when the event thread is running");
- if (!globals.toolpath)
- die("asked to run tests for gpio-tools, but the executables were not found");
-
- gpiotool_proc_make_pipes(in_fds, out_fds, err_fds);
-
- path = xappend(NULL, "%s/%s", globals.toolpath, tool);
- rv = access(path, R_OK | X_OK);
- if (rv)
- die_perr("unable to execute '%s'", path);
-
- sigemptyset(&sigmask);
- sigaddset(&sigmask, SIGCHLD);
-
- rv = sigprocmask(SIG_BLOCK, &sigmask, NULL);
- if (rv)
- die_perr("unable to block SIGCHLD");
-
- proc->sig_fd = signalfd(-1, &sigmask, 0);
- if (proc->sig_fd < 0)
- die_perr("unable to create signalfd");
-
- proc->pid = fork();
- if (proc->pid < 0) {
- die_perr("unable to fork");
- } else if (proc->pid == 0) {
- /* Child process. */
- close(proc->sig_fd);
- gpiotool_proc_dup_fds(in_fds[0], out_fds[1], err_fds[1]);
- va_start(va, tool);
- gpiotool_proc_exec(path, va);
- } else {
- /* Parent process. */
- close(in_fds[0]);
- proc->stdin_fd = in_fds[1];
- close(out_fds[1]);
- proc->stdout_fd = out_fds[0];
- close(err_fds[1]);
- proc->stderr_fd = err_fds[0];
-
- proc->running = true;
- }
-
- event_unlock();
- free(path);
-}
-
-static void gpiotool_readall(int fd, char **out)
-{
- ssize_t rd;
- int i;
-
- memset(globals.pipebuf, 0, globals.pipesize);
- rd = read(fd, globals.pipebuf, globals.pipesize);
- if (rd < 0) {
- die_perr("error reading output from subprocess");
- } else if (rd == 0) {
- *out = NULL;
- } else {
- for (i = 0; i < rd; i++) {
- if (!isascii(globals.pipebuf[i]))
- die("GPIO tool program printed a non-ASCII character");
- }
-
- *out = xzalloc(rd + 1);
- memcpy(*out, globals.pipebuf, rd);
- }
-}
-
-void test_tool_wait(void)
-{
- struct signalfd_siginfo sinfo;
- struct gpiotool_proc *proc;
- struct pollfd pfd;
- sigset_t sigmask;
- ssize_t rd;
- int rv;
-
- proc = &globals.test_ctx.tool_proc;
-
- if (!proc->running)
- die("gpiotool process not running");
-
- pfd.fd = proc->sig_fd;
- pfd.events = POLLIN | POLLPRI;
-
- rv = poll(&pfd, 1, 5000);
- if (rv == 0)
- die("tool program is taking too long to terminate");
- else if (rv < 0)
- die_perr("error when polling the signalfd");
-
- rd = read(proc->sig_fd, &sinfo, sizeof(sinfo));
- close(proc->sig_fd);
- if (rd < 0)
- die_perr("error reading signal info");
- else if (rd != sizeof(sinfo))
- die("invalid size of signal info");
-
- sigemptyset(&sigmask);
- sigaddset(&sigmask, SIGCHLD);
-
- rv = sigprocmask(SIG_UNBLOCK, &sigmask, NULL);
- if (rv)
- die_perr("unable to unblock SIGCHLD");
-
- gpiotool_readall(proc->stdout_fd, &proc->stdout);
- gpiotool_readall(proc->stderr_fd, &proc->stderr);
-
- waitpid(proc->pid, &proc->exit_status, 0);
-
- close(proc->stdin_fd);
- close(proc->stdout_fd);
- close(proc->stderr_fd);
-
- proc->running = false;
-}
-
-const char *test_tool_stdout(void)
-{
- struct gpiotool_proc *proc = &globals.test_ctx.tool_proc;
-
- return proc->stdout;
-}
-
-const char *test_tool_stderr(void)
-{
- struct gpiotool_proc *proc = &globals.test_ctx.tool_proc;
-
- return proc->stderr;
-}
-
-bool test_tool_exited(void)
-{
- struct gpiotool_proc *proc = &globals.test_ctx.tool_proc;
-
- return WIFEXITED(proc->exit_status);
-}
-
-int test_tool_exit_status(void)
-{
- struct gpiotool_proc *proc = &globals.test_ctx.tool_proc;
-
- return WEXITSTATUS(proc->exit_status);
-}
-
static void check_kernel(void)
{
- unsigned int major, minor, release;
+ guint major, minor, release;
struct utsname un;
- int rv;
+ gint ret;
- msg("checking the linux kernel version");
+ g_debug("checking linux kernel version");
- rv = uname(&un);
- if (rv)
- die_perr("uname");
+ ret = uname(&un);
+ if (ret)
+ g_error("unable to read the kernel release version: %s",
+ g_strerror(errno));
- rv = sscanf(un.release, "%u.%u.%u", &major, &minor, &release);
- if (rv != 3)
- die("error reading kernel release version");
+ ret = sscanf(un.release, "%u.%u.%u", &major, &minor, &release);
+ if (ret != 3)
+ g_error("error reading kernel release version");
- if (major < min_kern_major) {
- goto bad_version;
- } else if (major > min_kern_major) {
- goto good_version;
- } else {
- if (minor < min_kern_minor) {
- goto bad_version;
- } else if (minor > min_kern_minor) {
- goto good_version;
- } else {
- if (release < min_kern_release)
- goto bad_version;
- else
- goto good_version;
- }
- }
+ if (KERNEL_VERSION(major, minor, release) < MIN_KERNEL_VERSION)
+ g_error("linux kernel version must be at least v%u.%u.%u - got v%u.%u.%u",
+ MIN_KERNEL_MAJOR, MIN_KERNEL_MINOR, MIN_KERNEL_RELEASE,
+ major, minor, release);
-good_version:
- msg("kernel release is v%u.%u.%u - ok to run tests",
- major, minor, release);
+ g_debug("kernel release is v%u.%u.%u - ok to run tests",
+ major, minor, release);
return;
-
-bad_version:
- die("linux kernel version must be at least v%u.%u.%u - got v%u.%u.%u",
- min_kern_major, min_kern_minor, min_kern_release,
- major, minor, release);
}
-static void check_tool_path(void)
+static void test_func_wrapper(gconstpointer data)
{
- /*
- * Let's check gpiodetect only and assume all the other tools are in
- * the same directory.
- */
- static const char *const tool = "gpiodetect";
-
- char *progpath, *progdir, *toolpath, *pathenv, *tok;
-
- /* First check if we're running the from the top source directory. */
- progpath = xstrdup(program_invocation_name);
- progdir = dirname(progpath);
+ const _GpiodTestCase *test = data;
+ gint ret, flags = 0;
- toolpath = xappend(NULL, "%s/../../tools/%s", progdir, tool);
- if (access(toolpath, R_OK | X_OK) == 0) {
- free(progpath);
- goto out;
- }
- free(toolpath);
-
- /* Is the tool in the same directory maybe? */
- toolpath = xappend(NULL, "%s/%s", progdir, tool);
- free(progpath);
- if (access(toolpath, R_OK | X_OK) == 0)
- goto out;
- free(toolpath);
-
- /* Next iterate over directories in $PATH. */
- pathenv = getenv("PATH");
- if (!pathenv)
- return;
-
- progpath = xstrdup(pathenv);
- tok = strtok(progpath, ":");
- while (tok) {
- toolpath = xappend(NULL, "%s/%s", tok, tool);
- if (access(toolpath, R_OK) == 0) {
- free(progpath);
- goto out;
- }
-
- free(toolpath);
- tok = strtok(NULL, ":");
- }
-
- free(progpath);
- toolpath = NULL;
-
-out:
- if (toolpath) {
- toolpath = dirname(toolpath);
- msg("using gpio-tools from '%s'", toolpath);
- globals.toolpath = toolpath;
- }
-}
-
-static void prepare_test(struct _test_chip_descr *descr)
-{
- unsigned int *chip_sizes, i;
- struct test_context *ctx;
- int rv, flags = 0;
-
- ctx = &globals.test_ctx;
- memset(ctx, 0, sizeof(*ctx));
- ctx->num_chips = descr->num_chips;
- pthread_mutex_init(&ctx->event.lock, NULL);
- pthread_cond_init(&ctx->event.cond, NULL);
-
- /* Don't try to load the module if we don't need any chips. */
- if (!ctx->num_chips)
- return;
-
- chip_sizes = calloc(ctx->num_chips, sizeof(unsigned int));
- if (!chip_sizes)
- die("out of memory");
-
- for (i = 0; i < ctx->num_chips; i++)
- chip_sizes[i] = descr->num_lines[i];
-
- if (descr->flags & TEST_FLAG_NAMED_LINES)
+ if (test->flags & GPIOD_TEST_FLAG_NAMED_LINES)
flags |= GPIO_MOCKUP_FLAG_NAMED_LINES;
- rv = gpio_mockup_probe(globals.mockup,
- ctx->num_chips, chip_sizes, flags);
- if (rv)
- die_perr("unable to load gpio-mockup kernel module");
-
- free(chip_sizes);
-}
+ ret = gpio_mockup_probe(globals.mockup, test->num_chips,
+ test->chip_sizes, flags);
+ if (ret)
+ g_error("unable to probe gpio-mockup: %s", g_strerror(errno));
-static void run_test(struct _test_case *test)
-{
- errno = 0;
-
- print_header("TEST", CYELLOW);
- pr_raw("'%s': ", test->name);
-
- globals.test_ctx.running = true;
test->func();
- globals.test_ctx.running = false;
- if (globals.test_ctx.test_failed) {
- globals.tests_failed++;
- set_color(CREDBOLD);
- pr_raw("FAILED:");
- reset_color();
- set_color(CRED);
- pr_raw("\n\t\t'%s': %s\n",
- test->name, globals.test_ctx.failed_msg);
- reset_color();
- free(globals.test_ctx.failed_msg);
- } else {
- set_color(CGREEN);
- pr_raw("PASS\n");
- reset_color();
- }
+ ret = gpio_mockup_remove(globals.mockup);
+ if (ret)
+ g_error("unable to remove gpio_mockup: %s", g_strerror(errno));
}
-static void teardown_test(void)
+static void unref_mockup(void)
{
- struct gpiotool_proc *tool_proc;
- struct test_context *ctx;
- struct event_thread *ev;
- int rv;
-
- ctx = &globals.test_ctx;
-
- event_lock();
- ev = &ctx->event;
-
- if (ev->running) {
- ev->should_stop = true;
- pthread_cond_broadcast(&ev->cond);
- event_unlock();
-
- rv = pthread_join(ctx->event.thread_id, NULL);
- if (rv != 0)
- die("error joining event thread: %s",
- strerror(rv));
-
- pthread_mutex_destroy(&ctx->event.lock);
- pthread_cond_destroy(&ctx->event.cond);
- } else {
- event_unlock();
- }
-
- tool_proc = &ctx->tool_proc;
- if (tool_proc->running) {
- test_tool_signal(SIGKILL);
- test_tool_wait();
- }
-
- if (tool_proc->pid)
- gpiotool_proc_cleanup();
-
- if (ctx->custom_str)
- free(ctx->custom_str);
-
- if (!ctx->num_chips)
- return;
-
- rv = gpio_mockup_remove(globals.mockup);
- if (rv)
- die_perr("unable to remove gpio-mockup kernel module");
+ gpio_mockup_unref(globals.mockup);
}
-int main(int argc TEST_UNUSED, char **argv TEST_UNUSED)
+int main(gint argc, gchar **argv)
{
- struct _test_case *test;
+ _GpiodTestCase *test;
- globals.main_pid = getpid();
- globals.pipesize = get_pipesize();
- globals.pipebuf = xmalloc(globals.pipesize);
- atexit(cleanup_func);
+ g_test_init(&argc, &argv, NULL);
+ g_test_set_nonfatal_assertions();
- msg("libgpiod test suite");
- msg("%u tests registered", globals.num_tests);
+ g_debug("running libgpiod test suite");
+ g_debug("%u tests registered", globals.num_tests);
+ /*
+ * Setup libgpiomockup first so that it runs its own kernel version
+ * check before we tell the user our local requirements are met as
+ * well.
+ */
globals.mockup = gpio_mockup_new();
if (!globals.mockup)
- die_perr("error checking the availability of gpio-mockup");
+ g_error("unable to initialize gpio-mockup library: %s",
+ g_strerror(errno));
+ atexit(unref_mockup);
check_kernel();
- check_tool_path();
- msg("running tests");
+ for (test = globals.test_list_head; test; test = test->_next)
+ g_test_add_data_func(test->path, test, test_func_wrapper);
- for (test = globals.test_list_head; test; test = test->_next) {
- prepare_test(&test->chip_descr);
- run_test(test);
- teardown_test();
- }
-
- if (!globals.tests_failed)
- msg("all tests passed");
- else
- err("%u out of %u tests failed",
- globals.tests_failed, globals.num_tests);
-
- return globals.tests_failed ? EXIT_FAILURE : EXIT_SUCCESS;
-}
-
-void test_close_chip(struct gpiod_chip **chip)
-{
- if (*chip)
- gpiod_chip_close(*chip);
+ return g_test_run();
}
-void test_line_close_chip(struct gpiod_line **line)
+void _gpiod_test_register(_GpiodTestCase *test)
{
- if (*line)
- gpiod_line_close_chip(*line);
-}
+ _GpiodTestCase *tmp;
-void test_free_chip_iter(struct gpiod_chip_iter **iter)
-{
- if (*iter)
- gpiod_chip_iter_free(*iter);
-}
-
-void test_free_line_iter(struct gpiod_line_iter **iter)
-{
- if (*iter)
- gpiod_line_iter_free(*iter);
-}
+ if (!globals.test_list_head) {
+ globals.test_list_head = globals.test_list_tail = test;
+ test->_next = NULL;
+ } else {
+ tmp = globals.test_list_tail;
+ globals.test_list_tail = test;
+ test->_next = NULL;
+ tmp->_next = test;
+ }
-void test_free_chip_iter_noclose(struct gpiod_chip_iter **iter)
-{
- if (*iter)
- gpiod_chip_iter_free_noclose(*iter);
+ globals.num_tests++;
}
-const char *test_chip_path(unsigned int index)
+const gchar *gpiod_test_chip_path(guint index)
{
- check_chip_index(index);
+ const gchar *path;
- return gpio_mockup_chip_path(globals.mockup, index);
-}
-
-const char *test_chip_name(unsigned int index)
-{
- check_chip_index(index);
+ path = gpio_mockup_chip_path(globals.mockup, index);
+ if (!path)
+ g_error("unable to retrieve the chip path: %s",
+ g_strerror(errno));
- return gpio_mockup_chip_name(globals.mockup, index);
+ return path;
}
-unsigned int test_chip_num(unsigned int index)
+const gchar *gpiod_test_chip_name(guint index)
{
- int chip_num;
+ const gchar *name;
- check_chip_index(index);
+ name = gpio_mockup_chip_name(globals.mockup, index);
+ if (!name)
+ g_error("unable to retrieve the chip name: %s",
+ g_strerror(errno));
- chip_num = gpio_mockup_chip_num(globals.mockup, index);
- if (chip_num < 0)
- die_perr("error getting the chip number");
-
- return chip_num;
+ return name;
}
-int test_debugfs_get_value(unsigned int chip_index, unsigned int line_offset)
+gint gpiod_test_chip_num(unsigned int index)
{
- int rv;
-
- rv = gpio_mockup_get_value(globals.mockup, chip_index, line_offset);
- if (rv < 0)
- die_perr("error reading the debugfs line attribute");
+ gint num;
- return rv;
-}
-
-void test_debugfs_set_value(unsigned int chip_index,
- unsigned int line_offset, int val)
-{
- int rv;
+ num = gpio_mockup_chip_num(globals.mockup, index);
+ if (num < 0)
+ g_error("unable to retrieve the chip number: %s",
+ g_strerror(errno));
- rv = gpio_mockup_set_pull(globals.mockup, chip_index,
- line_offset, val);
- if (rv)
- die_perr("error writing to the debugfs line attribute");
+ return num;
}
-void _test_register(struct _test_case *test)
+gint gpiod_test_chip_get_value(guint chip_index, guint line_offset)
{
- struct _test_case *tmp;
+ gint ret;
- if (!globals.test_list_head) {
- globals.test_list_head = globals.test_list_tail = test;
- test->_next = NULL;
- } else {
- tmp = globals.test_list_tail;
- globals.test_list_tail = test;
- test->_next = NULL;
- tmp->_next = test;
- }
+ ret = gpio_mockup_get_value(globals.mockup, chip_index, line_offset);
+ if (ret < 0)
+ g_error("unable to read line value from gpio-mockup: %s",
+ g_strerror(errno));
- globals.num_tests++;
+ return ret;
}
-void _test_print_failed(const char *fmt, ...)
+void gpiod_test_chip_set_pull(guint chip_index, guint line_offset, gint pull)
{
- va_list va;
- int rv;
-
- va_start(va, fmt);
- rv = vasprintf(&globals.test_ctx.failed_msg, fmt, va);
- va_end(va);
- if (rv < 0)
- die_perr("vasprintf");
+ gint ret;
- globals.test_ctx.test_failed = true;
+ ret = gpio_mockup_set_pull(globals.mockup, chip_index,
+ line_offset, pull);
+ if (ret)
+ g_error("unable to set line pull in gpio-mockup: %s",
+ g_strerror(errno));
}
-void test_set_event(unsigned int chip_index,
- unsigned int line_offset, unsigned int freq)
+static gpointer event_worker_func(gpointer data)
{
- struct event_thread *ev = &globals.test_ctx.event;
- int rv;
-
- event_lock();
-
- if (!ev->running) {
- rv = pthread_create(&ev->thread_id, NULL, event_worker, NULL);
- if (rv != 0)
- die("error creating event thread: %s",
- strerror(rv));
-
- ev->running = true;
- }
-
- ev->chip_index = chip_index;
- ev->line_offset = line_offset;
- ev->freq = freq;
+ GpiodTestEventThread *thread = data;
+ gboolean signalled;
+ gint64 end_time;
+ gint i;
- pthread_cond_broadcast(&ev->cond);
+ for (i = 0;; i++) {
+ g_mutex_lock(&thread->lock);
+ if (thread->should_stop) {
+ g_mutex_unlock(&thread->lock);
+ break;
+ }
- event_unlock();
-}
+ end_time = g_get_monotonic_time() + thread->freq * 1000;
-void test_trigger_event(unsigned int chip_index, unsigned int line_offset)
-{
- int val, rv;
+ signalled = g_cond_wait_until(&thread->cond,
+ &thread->lock, end_time);
+ if (!signalled)
+ gpiod_test_chip_set_pull(thread->chip_index,
+ thread->line_offset, i % 2);
- val = gpio_mockup_get_value(globals.mockup, chip_index, line_offset);
- if (val < 0)
- die_perr("error reading GPIO value from debugfs");
+ g_mutex_unlock(&thread->lock);
+ }
- rv = gpio_mockup_set_pull(globals.mockup, chip_index,
- line_offset, val ? 0 : 1);
- if (rv)
- die_perr("error setting GPIO line pull over debugfs");
+ return NULL;
}
-bool test_regex_match(const char *str, const char *pattern)
+GpiodTestEventThread *
+gpiod_test_start_event_thread(guint chip_index, guint line_offset, guint freq)
{
- char errbuf[128];
- regex_t regex;
- bool ret;
- int rv;
+ GpiodTestEventThread *thread = g_malloc0(sizeof(*thread));
- rv = regcomp(®ex, pattern, REG_EXTENDED | REG_NEWLINE);
- if (rv) {
- regerror(rv, ®ex, errbuf, sizeof(errbuf));
- die("unable to compile regex '%s': %s", pattern, errbuf);
- }
+ g_mutex_init(&thread->lock);
+ g_cond_init(&thread->cond);
- rv = regexec(®ex, str, 0, 0, 0);
- if (rv == REG_NOERROR) {
- ret = true;
- } else if (rv == REG_NOMATCH) {
- ret = false;
- } else {
- regerror(rv, ®ex, errbuf, sizeof(errbuf));
- die("unable to run a regex match: %s", errbuf);
- }
+ thread->chip_index = chip_index;
+ thread->line_offset = line_offset;
+ thread->freq = freq;
- regfree(®ex);
+ thread->id = g_thread_new("event-worker", event_worker_func, thread);
- return ret;
+ return thread;
}
-const char *test_build_str(const char *fmt, ...)
+void gpiod_test_stop_event_thread(GpiodTestEventThread *thread)
{
- va_list va;
- char *str;
- int rv;
-
- if (globals.test_ctx.custom_str)
- free(globals.test_ctx.custom_str);
-
- va_start(va, fmt);
- rv = vasprintf(&str, fmt, va);
- va_end(va);
- if (rv < 0)
- die_perr("error creating custom string");
+ g_mutex_lock(&thread->lock);
+ thread->should_stop = TRUE;
+ g_cond_broadcast(&thread->cond);
+ g_mutex_unlock(&thread->lock);
- globals.test_ctx.custom_str = str;
+ (void)g_thread_join(thread->id);
- return str;
+ g_mutex_clear(&thread->lock);
+ g_cond_clear(&thread->cond);
+ g_free(thread);
}
/*
* This file is part of libgpiod.
*
- * Copyright (C) 2017-2018 Bartosz Golaszewski <bartekgola@gmail.com>
* Copyright (C) 2019 Bartosz Golaszewski <bgolaszewski@baylibre.com>
*/
-/* Testing framework - functions and definitions used by test cases. */
+/*
+ * Testing framework for the core library.
+ *
+ * This file contains functions and definitions extending the GLib unit testing
+ * framework with functionalities necessary to test the libgpiod core C API as
+ * well as the kernel-to-user-space interface.
+ */
#ifndef __GPIOD_TEST_H__
#define __GPIOD_TEST_H__
+#include <glib.h>
#include <gpiod.h>
-#include <string.h>
-
-#define TEST_CONSUMER "gpiod-test"
-#define TEST_INIT __attribute__((constructor))
-#define TEST_UNUSED __attribute__((unused))
-#define TEST_PRINTF(fmt, arg) __attribute__((format(printf, fmt, arg)))
-#define TEST_CLEANUP(func) __attribute__((cleanup(func)))
-#define TEST_BIT(nr) (1UL << (nr))
-
-#define TEST_ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
+/*
+ * These typedefs are needed to make g_autoptr work - it doesn't accept
+ * regular 'struct typename' syntax.
+ */
+typedef struct gpiod_chip gpiod_chip_struct;
+typedef struct gpiod_chip_iter gpiod_chip_iter_struct;
+typedef struct gpiod_line_iter gpiod_line_iter_struct;
-typedef void (*_test_func)(void);
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(gpiod_chip_struct, gpiod_chip_close);
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(gpiod_chip_iter_struct, gpiod_chip_iter_free);
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(gpiod_line_iter_struct, gpiod_line_iter_free);
-struct _test_chip_descr {
- unsigned int num_chips;
- unsigned int *num_lines;
- int flags;
-};
+/* There are private definitions and should not be used directly. */
+typedef void (*_gpiod_test_func)(void);
-struct _test_case {
- struct _test_case *_next;
+typedef struct _gpiod_test_case _GpiodTestCase;
+struct _gpiod_test_case {
+ _GpiodTestCase *_next;
- const char *name;
- _test_func func;
+ const gchar *path;
+ _gpiod_test_func func;
- struct _test_chip_descr chip_descr;
+ guint num_chips;
+ guint *chip_sizes;
+ gint flags;
};
-void _test_register(struct _test_case *test);
-void _test_print_failed(const char *fmt, ...) TEST_PRINTF(1, 2);
+void _gpiod_test_register(_GpiodTestCase *test);
+
+#define _GPIOD_TEST_PATH(_name) \
+ "/gpiod/" GPIOD_TEST_GROUP "/" G_STRINGIFY(_name)
enum {
- TEST_FLAG_NAMED_LINES = TEST_BIT(0),
+ /* Dummy lines for this test case should have names assigned. */
+ GPIOD_TEST_FLAG_NAMED_LINES = (1 << 0),
};
/*
- * This macro should be used for code brevity instead of manually declaring
- * the _test_case structure.
- *
- * The macro accepts the following arguments:
- * _a_func: name of the test function
- * _a_name: name of the test case (will be shown to user)
- * _a_flags: various switches for the test case
- *
- * The last argument must be an array of unsigned integers specifying the
- * number of GPIO lines in each subsequent mockup chip. The size of this
- * array will at the same time specify the number of gpiochips to create.
+ * Register a test case function. The last argument is the array of numbers
+ * of lines per mockup chip.
*/
-#define TEST_DEFINE(_a_func, _a_name, _a_flags, ...) \
- static unsigned int _##_a_func##_lines[] = __VA_ARGS__; \
- static struct _test_case _##_a_func##_descr = { \
- .name = _a_name, \
- .func = _a_func, \
- .chip_descr = { \
- .num_chips = TEST_ARRAY_SIZE( \
- _##_a_func##_lines), \
- .num_lines = _##_a_func##_lines, \
- .flags = _a_flags, \
- }, \
+#define GPIOD_TEST_CASE(_name, _flags, ...) \
+ static void _name(void); \
+ static guint _##_name##_chip_sizes[] = __VA_ARGS__; \
+ static _GpiodTestCase _##_name##_test_case = { \
+ .path = _GPIOD_TEST_PATH(_name), \
+ .func = _name, \
+ .num_chips = G_N_ELEMENTS(_##_name##_chip_sizes), \
+ .chip_sizes = _##_name##_chip_sizes, \
+ .flags = _flags, \
}; \
- static TEST_INIT void _test_register_##_a_func##_test(void) \
+ static __attribute__((constructor)) void \
+ _##_name##_test_register(void) \
{ \
- _test_register(&_##_a_func##_descr); \
+ _gpiod_test_register(&_##_name##_test_case); \
} \
- static int _test_##_a_func##_sentinel TEST_UNUSED
-
-/*
- * We want libgpiod tests to co-exist with gpiochips created by other GPIO
- * drivers. For that reason we can't just use hardcoded device file paths or
- * gpiochip names.
- *
- * The test suite detects the chips that were exported by the gpio-mockup
- * module and stores them in the internal test context structure. Test cases
- * should use the routines declared below to access the gpiochip path, name
- * or number by index corresponding with the order in which the mockup chips
- * were requested in the TEST_DEFINE() macro.
- */
-const char *test_chip_path(unsigned int index);
-const char *test_chip_name(unsigned int index);
-unsigned int test_chip_num(unsigned int index);
-
-int test_debugfs_get_value(unsigned int chip_index, unsigned int line_offset);
-void test_debugfs_set_value(unsigned int chip_index,
- unsigned int line_offset, int val);
+ static void _name(void)
-/* Last argument is the delay between line value switches in microseconds. */
-void test_set_event(unsigned int chip_index,
- unsigned int line_offset, unsigned int freq);
+#define GPIOD_TEST_CONSUMER "gpiod-test"
-void test_trigger_event(unsigned int chip_index, unsigned int line_offset);
-
-void test_tool_run(char *tool, ...);
-void test_tool_wait(void);
-const char *test_tool_stdout(void);
-const char *test_tool_stderr(void);
-bool test_tool_exited(void);
-int test_tool_exit_status(void);
-void test_tool_signal(int signum);
-void test_tool_stdin_write(const char *fmt, ...) TEST_PRINTF(1, 2);
-
-/*
- * Every TEST_ASSERT_*() macro expansion can make a test function return, so
- * it would be quite difficult to keep track of every resource allocation. At
- * the same time we don't want any deliberate memory leaks as we also use this
- * test suite to find actual memory leaks in the library with valgrind.
- *
- * For this reason, the tests should generally always use the TEST_CLEANUP()
- * macro for dynamically allocated variables and objects that need closing.
- *
- * The functions below can be reused by different tests for common use cases.
- */
-void test_close_chip(struct gpiod_chip **chip);
-void test_line_close_chip(struct gpiod_line **line);
-void test_free_chip_iter(struct gpiod_chip_iter **iter);
-void test_free_chip_iter_noclose(struct gpiod_chip_iter **iter);
-void test_free_line_iter(struct gpiod_line_iter **iter);
-
-#define TEST_CLEANUP_CHIP TEST_CLEANUP(test_close_chip)
-
-bool test_regex_match(const char *str, const char *pattern);
-
-/*
- * Return a custom string built according to printf() formatting rules. The
- * returned string is valid until the next call to this routine.
- */
-const char *test_build_str(const char *fmt, ...) TEST_PRINTF(1, 2);
-
-#define TEST_ASSERT(statement) \
+#define gpiod_test_return_if_failed() \
do { \
- if (!(statement)) { \
- _test_print_failed( \
- "assertion failed (%s:%d): '%s'", \
- __FILE__, __LINE__, #statement); \
+ if (g_test_failed()) \
return; \
- } \
} while (0)
-#define TEST_ASSERT_FALSE(statement) TEST_ASSERT(!(statement))
-#define TEST_ASSERT_NOT_NULL(ptr) TEST_ASSERT((ptr) != NULL)
-#define TEST_ASSERT_RET_OK(status) TEST_ASSERT((status) == 0)
-#define TEST_ASSERT_NULL(ptr) TEST_ASSERT((ptr) == NULL)
-#define TEST_ASSERT_ERRNO_IS(errnum) TEST_ASSERT(errno == (errnum))
-#define TEST_ASSERT_EQ(a1, a2) TEST_ASSERT((a1) == (a2))
-#define TEST_ASSERT_NOTEQ(a1, a2) TEST_ASSERT((a1) != (a2))
-#define TEST_ASSERT_STR_EQ(s1, s2) TEST_ASSERT(strcmp(s1, s2) == 0)
-#define TEST_ASSERT_STR_CONTAINS(s, p) TEST_ASSERT(strstr(s, p) != NULL)
-#define TEST_ASSERT_STR_NOTCONT(s, p) TEST_ASSERT(strstr(s, p) == NULL)
-#define TEST_ASSERT_REGEX_MATCH(s, p) TEST_ASSERT(test_regex_match(s, p))
-#define TEST_ASSERT_REGEX_NOMATCH(s, p) TEST_ASSERT(!test_regex_match(s, p))
+/* Wrappers around libgpiomockup helpers. */
+const gchar *gpiod_test_chip_path(guint index);
+const gchar *gpiod_test_chip_name(guint index);
+gint gpiod_test_chip_num(guint index);
+gint gpiod_test_chip_get_value(guint chip_index, guint line_offset);
+void gpiod_test_chip_set_pull(guint chip_index, guint line_offset, gint pull);
+
+/* Helpers for triggering line events in a separate thread. */
+struct gpiod_test_event_thread;
+typedef struct gpiod_test_event_thread GpiodTestEventThread;
+
+GpiodTestEventThread *
+gpiod_test_start_event_thread(guint chip_index,
+ guint line_offset, guint freq);
+void gpiod_test_stop_event_thread(GpiodTestEventThread *thread);
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(GpiodTestEventThread,
+ gpiod_test_stop_event_thread);
#endif /* __GPIOD_TEST_H__ */
/*
* This file is part of libgpiod.
*
- * Copyright (C) 2017-2018 Bartosz Golaszewski <bartekgola@gmail.com>
+ * Copyright (C) 2019 Bartosz Golaszewski <bgolaszewski@baylibre.com>
*/
-/* Test cases for GPIO chip handling. */
-
#include <errno.h>
-#include <stdio.h>
#include "gpiod-test.h"
-static void chip_open_good(void)
+#define GPIOD_TEST_GROUP "chip"
+
+GPIOD_TEST_CASE(open_good, 0, { 8 })
{
- TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL;
+ g_autoptr(gpiod_chip_struct) chip = NULL;
- chip = gpiod_chip_open(test_chip_path(0));
- TEST_ASSERT_NOT_NULL(chip);
+ chip = gpiod_chip_open(gpiod_test_chip_path(0));
+ g_assert_nonnull(chip);
}
-TEST_DEFINE(chip_open_good,
- "gpiod_chip_open() - good",
- 0, { 8 });
-static void chip_open_nonexistent(void)
+GPIOD_TEST_CASE(open_nonexistent, 0, { 8 })
{
struct gpiod_chip *chip;
chip = gpiod_chip_open("/dev/nonexistent_gpiochip");
- TEST_ASSERT_NULL(chip);
- TEST_ASSERT_ERRNO_IS(ENOENT);
+ g_assert_null(chip);
+ g_assert_cmpint(errno, ==, ENOENT);
}
-TEST_DEFINE(chip_open_nonexistent,
- "gpiod_chip_open() - nonexistent chip",
- 0, { 8 });
-static void chip_open_notty(void)
+GPIOD_TEST_CASE(open_notty, 0, { 8 })
{
struct gpiod_chip *chip;
chip = gpiod_chip_open("/dev/null");
- TEST_ASSERT_NULL(chip);
- TEST_ASSERT_ERRNO_IS(ENOTTY);
+ g_assert_null(chip);
+ g_assert_cmpint(errno, ==, ENOTTY);
}
-TEST_DEFINE(chip_open_notty,
- "gpiod_chip_open() - notty",
- 0, { 8 });
-static void chip_open_by_name_good(void)
+GPIOD_TEST_CASE(open_by_name_good, 0, { 8 })
{
- TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL;
+ g_autoptr(gpiod_chip_struct) chip = NULL;
- chip = gpiod_chip_open_by_name(test_chip_name(0));
- TEST_ASSERT_NOT_NULL(chip);
+ chip = gpiod_chip_open_by_name(gpiod_test_chip_name(0));
+ g_assert_nonnull(chip);
}
-TEST_DEFINE(chip_open_by_name_good,
- "gpiod_chip_open_by_name() - good",
- 0, { 8 });
-static void chip_open_by_number_good(void)
+GPIOD_TEST_CASE(open_by_number_good, 0, { 8 })
{
- TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL;
+ g_autoptr(gpiod_chip_struct) chip = NULL;
- chip = gpiod_chip_open_by_number(test_chip_num(0));
- TEST_ASSERT_NOT_NULL(chip);
+ chip = gpiod_chip_open_by_number(gpiod_test_chip_num(0));
+ g_assert_nonnull(chip);
}
-TEST_DEFINE(chip_open_by_number_good,
- "gpiod_chip_open_by_number() - good",
- 0, { 8 });
-static void chip_open_lookup(void)
+GPIOD_TEST_CASE(open_by_label_good, 0, { 4, 4, 4, 4, 4 })
{
- TEST_CLEANUP_CHIP struct gpiod_chip *chip_by_label = NULL;
- TEST_CLEANUP_CHIP struct gpiod_chip *chip_by_name = NULL;
- TEST_CLEANUP_CHIP struct gpiod_chip *chip_by_path = NULL;
- TEST_CLEANUP_CHIP struct gpiod_chip *chip_by_num = NULL;
-
- chip_by_name = gpiod_chip_open_lookup(test_chip_name(1));
- chip_by_path = gpiod_chip_open_lookup(test_chip_path(1));
- chip_by_num = gpiod_chip_open_lookup(
- test_build_str("%u", test_chip_num(1)));
- chip_by_label = gpiod_chip_open_lookup("gpio-mockup-B");
-
- TEST_ASSERT_NOT_NULL(chip_by_name);
- TEST_ASSERT_NOT_NULL(chip_by_path);
- TEST_ASSERT_NOT_NULL(chip_by_num);
- TEST_ASSERT_NOT_NULL(chip_by_label);
+ g_autoptr(gpiod_chip_struct) chip = NULL;
- TEST_ASSERT_STR_EQ(gpiod_chip_name(chip_by_name), test_chip_name(1));
- TEST_ASSERT_STR_EQ(gpiod_chip_name(chip_by_path), test_chip_name(1));
- TEST_ASSERT_STR_EQ(gpiod_chip_name(chip_by_num), test_chip_name(1));
- TEST_ASSERT_STR_EQ(gpiod_chip_name(chip_by_label), test_chip_name(1));
+ chip = gpiod_chip_open_by_label("gpio-mockup-D");
+ g_assert_nonnull(chip);
+ gpiod_test_return_if_failed();
+ g_assert_cmpstr(gpiod_chip_name(chip), ==, gpiod_test_chip_name(3));
}
-TEST_DEFINE(chip_open_lookup,
- "gpiod_chip_open_lookup() - good",
- 0, { 8, 8, 8 });
-static void chip_open_by_label_good(void)
+GPIOD_TEST_CASE(open_by_label_bad, 0, { 4, 4, 4, 4, 4 })
{
- TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL;
+ struct gpiod_chip *chip;
- chip = gpiod_chip_open_by_label("gpio-mockup-D");
- TEST_ASSERT_NOT_NULL(chip);
- TEST_ASSERT_STR_EQ(gpiod_chip_name(chip), test_chip_name(3));
+ chip = gpiod_chip_open_by_label("nonexistent_gpio_chip");
+ g_assert_null(chip);
+ g_assert_cmpint(errno, ==, ENOENT);
}
-TEST_DEFINE(chip_open_by_label_good,
- "gpiod_chip_open_by_label() - good",
- 0, { 4, 4, 4, 4, 4 });
-static void chip_open_by_label_bad(void)
+GPIOD_TEST_CASE(open_lookup_good, 0, { 8, 8, 8})
{
- TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL;
+ g_autoptr(gpiod_chip_struct) chip_by_label = NULL;
+ g_autoptr(gpiod_chip_struct) chip_by_name = NULL;
+ g_autoptr(gpiod_chip_struct) chip_by_path = NULL;
+ g_autoptr(gpiod_chip_struct) chip_by_num = NULL;
+ g_autofree gchar *chip_num_str = g_strdup_printf(
+ "%u", gpiod_test_chip_num(1));
+
+ chip_by_name = gpiod_chip_open_lookup(gpiod_test_chip_name(1));
+ chip_by_path = gpiod_chip_open_lookup(gpiod_test_chip_path(1));
+ chip_by_num = gpiod_chip_open_lookup(chip_num_str);
+ chip_by_label = gpiod_chip_open_lookup("gpio-mockup-B");
- chip = gpiod_chip_open_by_label("nonexistent_gpio_chip");
- TEST_ASSERT_NULL(chip);
- TEST_ASSERT_ERRNO_IS(ENOENT);
+ g_assert_nonnull(chip_by_name);
+ g_assert_nonnull(chip_by_path);
+ g_assert_nonnull(chip_by_num);
+ g_assert_nonnull(chip_by_label);
+ gpiod_test_return_if_failed();
+
+ g_assert_cmpstr(gpiod_chip_name(chip_by_name),
+ ==, gpiod_test_chip_name(1));
+ g_assert_cmpstr(gpiod_chip_name(chip_by_path),
+ ==, gpiod_test_chip_name(1));
+ g_assert_cmpstr(gpiod_chip_name(chip_by_num),
+ ==, gpiod_test_chip_name(1));
+ g_assert_cmpstr(gpiod_chip_name(chip_by_label),
+ ==, gpiod_test_chip_name(1));
}
-TEST_DEFINE(chip_open_by_label_bad,
- "gpiod_chip_open_by_label() - bad",
- 0, { 4, 4, 4, 4, 4 });
-static void chip_name(void)
+GPIOD_TEST_CASE(get_name, 0, { 8, 8, 8})
{
- TEST_CLEANUP_CHIP struct gpiod_chip *chip0 = NULL;
- TEST_CLEANUP_CHIP struct gpiod_chip *chip1 = NULL;
- TEST_CLEANUP_CHIP struct gpiod_chip *chip2 = NULL;
-
- chip0 = gpiod_chip_open(test_chip_path(0));
- chip1 = gpiod_chip_open(test_chip_path(1));
- chip2 = gpiod_chip_open(test_chip_path(2));
- TEST_ASSERT_NOT_NULL(chip0);
- TEST_ASSERT_NOT_NULL(chip1);
- TEST_ASSERT_NOT_NULL(chip2);
-
- TEST_ASSERT_STR_EQ(gpiod_chip_name(chip0), test_chip_name(0));
- TEST_ASSERT_STR_EQ(gpiod_chip_name(chip1), test_chip_name(1));
- TEST_ASSERT_STR_EQ(gpiod_chip_name(chip2), test_chip_name(2));
+ g_autoptr(gpiod_chip_struct) chip0 = NULL;
+ g_autoptr(gpiod_chip_struct) chip1 = NULL;
+ g_autoptr(gpiod_chip_struct) chip2 = NULL;
+
+ chip0 = gpiod_chip_open(gpiod_test_chip_path(0));
+ chip1 = gpiod_chip_open(gpiod_test_chip_path(1));
+ chip2 = gpiod_chip_open(gpiod_test_chip_path(2));
+
+ g_assert_nonnull(chip0);
+ g_assert_nonnull(chip1);
+ g_assert_nonnull(chip2);
+ gpiod_test_return_if_failed();
+
+ g_assert_cmpstr(gpiod_chip_name(chip0), ==, gpiod_test_chip_name(0));
+ g_assert_cmpstr(gpiod_chip_name(chip1), ==, gpiod_test_chip_name(1));
+ g_assert_cmpstr(gpiod_chip_name(chip2), ==, gpiod_test_chip_name(2));
}
-TEST_DEFINE(chip_name,
- "gpiod_chip_name()",
- 0, { 8, 8, 8 });
-static void chip_label(void)
+GPIOD_TEST_CASE(get_label, 0, { 8, 8, 8})
{
- TEST_CLEANUP_CHIP struct gpiod_chip *chip0 = NULL;
- TEST_CLEANUP_CHIP struct gpiod_chip *chip1 = NULL;
- TEST_CLEANUP_CHIP struct gpiod_chip *chip2 = NULL;
-
- chip0 = gpiod_chip_open(test_chip_path(0));
- chip1 = gpiod_chip_open(test_chip_path(1));
- chip2 = gpiod_chip_open(test_chip_path(2));
- TEST_ASSERT_NOT_NULL(chip0);
- TEST_ASSERT_NOT_NULL(chip1);
- TEST_ASSERT_NOT_NULL(chip2);
-
- TEST_ASSERT_STR_EQ(gpiod_chip_label(chip0), "gpio-mockup-A");
- TEST_ASSERT_STR_EQ(gpiod_chip_label(chip1), "gpio-mockup-B");
- TEST_ASSERT_STR_EQ(gpiod_chip_label(chip2), "gpio-mockup-C");
+ g_autoptr(gpiod_chip_struct) chip0 = NULL;
+ g_autoptr(gpiod_chip_struct) chip1 = NULL;
+ g_autoptr(gpiod_chip_struct) chip2 = NULL;
+
+ chip0 = gpiod_chip_open(gpiod_test_chip_path(0));
+ chip1 = gpiod_chip_open(gpiod_test_chip_path(1));
+ chip2 = gpiod_chip_open(gpiod_test_chip_path(2));
+
+ g_assert_nonnull(chip0);
+ g_assert_nonnull(chip1);
+ g_assert_nonnull(chip2);
+ gpiod_test_return_if_failed();
+
+ g_assert_cmpstr(gpiod_chip_label(chip0), ==, "gpio-mockup-A");
+ g_assert_cmpstr(gpiod_chip_label(chip1), ==, "gpio-mockup-B");
+ g_assert_cmpstr(gpiod_chip_label(chip2), ==, "gpio-mockup-C");
}
-TEST_DEFINE(chip_label,
- "gpiod_chip_label()",
- 0, { 8, 8, 8 });
-static void chip_num_lines(void)
+GPIOD_TEST_CASE(num_lines, 0, { 1, 4, 8, 16, 32 })
{
- TEST_CLEANUP_CHIP struct gpiod_chip *chip0 = NULL;
- TEST_CLEANUP_CHIP struct gpiod_chip *chip1 = NULL;
- TEST_CLEANUP_CHIP struct gpiod_chip *chip2 = NULL;
- TEST_CLEANUP_CHIP struct gpiod_chip *chip3 = NULL;
- TEST_CLEANUP_CHIP struct gpiod_chip *chip4 = NULL;
-
- chip0 = gpiod_chip_open(test_chip_path(0));
- chip1 = gpiod_chip_open(test_chip_path(1));
- chip2 = gpiod_chip_open(test_chip_path(2));
- chip3 = gpiod_chip_open(test_chip_path(3));
- chip4 = gpiod_chip_open(test_chip_path(4));
- TEST_ASSERT_NOT_NULL(chip0);
- TEST_ASSERT_NOT_NULL(chip1);
- TEST_ASSERT_NOT_NULL(chip2);
- TEST_ASSERT_NOT_NULL(chip3);
- TEST_ASSERT_NOT_NULL(chip4);
-
- TEST_ASSERT_EQ(gpiod_chip_num_lines(chip0), 1);
- TEST_ASSERT_EQ(gpiod_chip_num_lines(chip1), 4);
- TEST_ASSERT_EQ(gpiod_chip_num_lines(chip2), 8);
- TEST_ASSERT_EQ(gpiod_chip_num_lines(chip3), 16);
- TEST_ASSERT_EQ(gpiod_chip_num_lines(chip4), 32);
+ g_autoptr(gpiod_chip_struct) chip0 = NULL;
+ g_autoptr(gpiod_chip_struct) chip1 = NULL;
+ g_autoptr(gpiod_chip_struct) chip2 = NULL;
+ g_autoptr(gpiod_chip_struct) chip3 = NULL;
+ g_autoptr(gpiod_chip_struct) chip4 = NULL;
+
+ chip0 = gpiod_chip_open(gpiod_test_chip_path(0));
+ chip1 = gpiod_chip_open(gpiod_test_chip_path(1));
+ chip2 = gpiod_chip_open(gpiod_test_chip_path(2));
+ chip3 = gpiod_chip_open(gpiod_test_chip_path(3));
+ chip4 = gpiod_chip_open(gpiod_test_chip_path(4));
+
+ g_assert_nonnull(chip0);
+ g_assert_nonnull(chip1);
+ g_assert_nonnull(chip2);
+ g_assert_nonnull(chip3);
+ g_assert_nonnull(chip4);
+ gpiod_test_return_if_failed();
+
+ g_assert_cmpuint(gpiod_chip_num_lines(chip0), ==, 1);
+ g_assert_cmpuint(gpiod_chip_num_lines(chip1), ==, 4);
+ g_assert_cmpuint(gpiod_chip_num_lines(chip2), ==, 8);
+ g_assert_cmpuint(gpiod_chip_num_lines(chip3), ==, 16);
+ g_assert_cmpuint(gpiod_chip_num_lines(chip4), ==, 32);
}
-TEST_DEFINE(chip_num_lines,
- "gpiod_chip_num_lines()",
- 0, { 1, 4, 8, 16, 32 });
-static void chip_get_lines(void)
+GPIOD_TEST_CASE(get_line, 0, { 16 })
{
- TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL;
- struct gpiod_line_bulk bulk;
- unsigned int offsets[4];
+ g_autoptr(gpiod_chip_struct) chip = NULL;
struct gpiod_line *line;
- int rv;
- chip = gpiod_chip_open(test_chip_path(0));
- TEST_ASSERT_NOT_NULL(chip);
+ chip = gpiod_chip_open(gpiod_test_chip_path(0));
+ g_assert_nonnull(chip);
+ gpiod_test_return_if_failed();
+
+ line = gpiod_chip_get_line(chip, 3);
+ g_assert_nonnull(line);
+ g_assert_cmpuint(gpiod_line_offset(line), ==, 3);
+}
+
+GPIOD_TEST_CASE(get_lines, 0, { 16 })
+{
+ struct gpiod_line *line0, *line1, *line2, *line3;
+ g_autoptr(gpiod_chip_struct) chip = NULL;
+ struct gpiod_line_bulk bulk;
+ guint offsets[4];
+ gint ret;
+
+ chip = gpiod_chip_open(gpiod_test_chip_path(0));
+ g_assert_nonnull(chip);
+ gpiod_test_return_if_failed();
offsets[0] = 1;
offsets[1] = 3;
offsets[2] = 4;
offsets[3] = 7;
- rv = gpiod_chip_get_lines(chip, offsets, 4, &bulk);
- TEST_ASSERT_RET_OK(rv);
-
- TEST_ASSERT_EQ(gpiod_line_bulk_num_lines(&bulk), 4);
- line = gpiod_line_bulk_get_line(&bulk, 0);
- TEST_ASSERT_EQ(gpiod_line_offset(line), 1);
- line = gpiod_line_bulk_get_line(&bulk, 1);
- TEST_ASSERT_EQ(gpiod_line_offset(line), 3);
- line = gpiod_line_bulk_get_line(&bulk, 2);
- TEST_ASSERT_EQ(gpiod_line_offset(line), 4);
- line = gpiod_line_bulk_get_line(&bulk, 3);
- TEST_ASSERT_EQ(gpiod_line_offset(line), 7);
+ ret = gpiod_chip_get_lines(chip, offsets, 4, &bulk);
+ g_assert_cmpint(ret, ==, 0);
+ g_assert_cmpuint(gpiod_line_bulk_num_lines(&bulk), ==, 4);
+ gpiod_test_return_if_failed();
+
+ line0 = gpiod_line_bulk_get_line(&bulk, 0);
+ line1 = gpiod_line_bulk_get_line(&bulk, 1);
+ line2 = gpiod_line_bulk_get_line(&bulk, 2);
+ line3 = gpiod_line_bulk_get_line(&bulk, 3);
+
+ g_assert_cmpuint(gpiod_line_offset(line0), ==, 1);
+ g_assert_cmpuint(gpiod_line_offset(line1), ==, 3);
+ g_assert_cmpuint(gpiod_line_offset(line2), ==, 4);
+ g_assert_cmpuint(gpiod_line_offset(line3), ==, 7);
}
-TEST_DEFINE(chip_get_lines,
- "gpiod_chip_get_lines()",
- 0, { 16 });
-static void chip_get_all_lines(void)
+GPIOD_TEST_CASE(get_all_lines, 0, { 4 })
{
- TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL;
+ struct gpiod_line *line0, *line1, *line2, *line3;
+ g_autoptr(gpiod_chip_struct) chip = NULL;
struct gpiod_line_bulk bulk;
- struct gpiod_line *line;
- int rv;
-
- chip = gpiod_chip_open(test_chip_path(0));
- TEST_ASSERT_NOT_NULL(chip);
-
- rv = gpiod_chip_get_all_lines(chip, &bulk);
- TEST_ASSERT_RET_OK(rv);
-
- TEST_ASSERT_EQ(gpiod_line_bulk_num_lines(&bulk), 4);
- line = gpiod_line_bulk_get_line(&bulk, 0);
- TEST_ASSERT_EQ(gpiod_line_offset(line), 0);
- line = gpiod_line_bulk_get_line(&bulk, 1);
- TEST_ASSERT_EQ(gpiod_line_offset(line), 1);
- line = gpiod_line_bulk_get_line(&bulk, 2);
- TEST_ASSERT_EQ(gpiod_line_offset(line), 2);
- line = gpiod_line_bulk_get_line(&bulk, 3);
- TEST_ASSERT_EQ(gpiod_line_offset(line), 3);
+ int ret;
+
+ chip = gpiod_chip_open(gpiod_test_chip_path(0));
+ g_assert_nonnull(chip);
+ gpiod_test_return_if_failed();
+
+ ret = gpiod_chip_get_all_lines(chip, &bulk);
+ g_assert_cmpint(ret, ==, 0);
+ g_assert_cmpuint(gpiod_line_bulk_num_lines(&bulk), ==, 4);
+ gpiod_test_return_if_failed();
+
+ line0 = gpiod_line_bulk_get_line(&bulk, 0);
+ line1 = gpiod_line_bulk_get_line(&bulk, 1);
+ line2 = gpiod_line_bulk_get_line(&bulk, 2);
+ line3 = gpiod_line_bulk_get_line(&bulk, 3);
+
+ g_assert_cmpuint(gpiod_line_offset(line0), ==, 0);
+ g_assert_cmpuint(gpiod_line_offset(line1), ==, 1);
+ g_assert_cmpuint(gpiod_line_offset(line2), ==, 2);
+ g_assert_cmpuint(gpiod_line_offset(line3), ==, 3);
}
-TEST_DEFINE(chip_get_all_lines,
- "gpiod_chip_get_all_lines()",
- 0, { 4 });
-static void chip_find_line_good(void)
+GPIOD_TEST_CASE(find_line_good, GPIOD_TEST_FLAG_NAMED_LINES, { 8, 8, 8 })
{
- TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL;
+ g_autoptr(gpiod_chip_struct) chip = NULL;
struct gpiod_line *line;
- chip = gpiod_chip_open(test_chip_path(1));
- TEST_ASSERT_NOT_NULL(chip);
+ chip = gpiod_chip_open(gpiod_test_chip_path(1));
+ g_assert_nonnull(chip);
+ gpiod_test_return_if_failed();
line = gpiod_chip_find_line(chip, "gpio-mockup-B-4");
- TEST_ASSERT_NOT_NULL(line);
- TEST_ASSERT_EQ(gpiod_line_offset(line), 4);
- TEST_ASSERT_STR_EQ(gpiod_line_name(line), "gpio-mockup-B-4");
+ g_assert_nonnull(line);
+ gpiod_test_return_if_failed();
+ g_assert_cmpuint(gpiod_line_offset(line), ==, 4);
+ g_assert_cmpstr(gpiod_line_name(line), ==, "gpio-mockup-B-4");
}
-TEST_DEFINE(chip_find_line_good,
- "gpiod_chip_find_line() - good",
- TEST_FLAG_NAMED_LINES, { 8, 8, 8 });
-static void chip_find_line_not_found(void)
+GPIOD_TEST_CASE(find_line_not_found, GPIOD_TEST_FLAG_NAMED_LINES, { 8, 8, 8 })
{
- TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL;
+ g_autoptr(gpiod_chip_struct) chip = NULL;
struct gpiod_line *line;
- chip = gpiod_chip_open(test_chip_path(1));
- TEST_ASSERT_NOT_NULL(chip);
+ chip = gpiod_chip_open(gpiod_test_chip_path(1));
+ g_assert_nonnull(chip);
+ gpiod_test_return_if_failed();
line = gpiod_chip_find_line(chip, "nonexistent");
- TEST_ASSERT_NULL(line);
- TEST_ASSERT_ERRNO_IS(ENOENT);
+ g_assert_null(line);
+ g_assert_cmpint(errno, ==, ENOENT);
}
-TEST_DEFINE(chip_find_line_not_found,
- "gpiod_chip_find_line() - not found",
- TEST_FLAG_NAMED_LINES, { 8, 8, 8 });
-static void chip_find_lines_good(void)
+GPIOD_TEST_CASE(find_lines_good, GPIOD_TEST_FLAG_NAMED_LINES, { 8, 8, 8 })
{
- static const char *names[] = { "gpio-mockup-B-3",
- "gpio-mockup-B-6",
- "gpio-mockup-B-7",
- NULL };
+ static const gchar *names[] = { "gpio-mockup-B-3",
+ "gpio-mockup-B-6",
+ "gpio-mockup-B-7",
+ NULL };
- TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL;
+ g_autoptr(gpiod_chip_struct) chip = NULL;
+ struct gpiod_line *line0, *line1, *line2;
struct gpiod_line_bulk bulk;
- struct gpiod_line *line;
- int rv;
-
- chip = gpiod_chip_open(test_chip_path(1));
- TEST_ASSERT_NOT_NULL(chip);
-
- rv = gpiod_chip_find_lines(chip, names, &bulk);
- TEST_ASSERT_RET_OK(rv);
- TEST_ASSERT_EQ(gpiod_line_bulk_num_lines(&bulk), 3);
- line = gpiod_line_bulk_get_line(&bulk, 0);
- TEST_ASSERT_EQ(gpiod_line_offset(line), 3);
- line = gpiod_line_bulk_get_line(&bulk, 1);
- TEST_ASSERT_EQ(gpiod_line_offset(line), 6);
- line = gpiod_line_bulk_get_line(&bulk, 2);
- TEST_ASSERT_EQ(gpiod_line_offset(line), 7);
+ gint ret;
+
+ chip = gpiod_chip_open(gpiod_test_chip_path(1));
+ g_assert_nonnull(chip);
+ gpiod_test_return_if_failed();
+
+ ret = gpiod_chip_find_lines(chip, names, &bulk);
+ g_assert_cmpint(ret, ==, 0);
+ g_assert_cmpuint(gpiod_line_bulk_num_lines(&bulk), ==, 3);
+ gpiod_test_return_if_failed();
+
+ line0 = gpiod_line_bulk_get_line(&bulk, 0);
+ line1 = gpiod_line_bulk_get_line(&bulk, 1);
+ line2 = gpiod_line_bulk_get_line(&bulk, 2);
+
+ g_assert_cmpuint(gpiod_line_offset(line0), ==, 3);
+ g_assert_cmpuint(gpiod_line_offset(line1), ==, 6);
+ g_assert_cmpuint(gpiod_line_offset(line2), ==, 7);
}
-TEST_DEFINE(chip_find_lines_good,
- "gpiod_chip_find_lines() - good",
- TEST_FLAG_NAMED_LINES, { 8, 8, 8 });
-static void chip_find_lines_not_found(void)
+GPIOD_TEST_CASE(fine_lines_not_found, GPIOD_TEST_FLAG_NAMED_LINES, { 8, 8, 8 })
{
- static const char *names[] = { "gpio-mockup-B-3",
- "nonexistent",
- "gpio-mockup-B-7",
- NULL };
+ static const gchar *names[] = { "gpio-mockup-B-3",
+ "nonexistent",
+ "gpio-mockup-B-7",
+ NULL };
- TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL;
+ g_autoptr(gpiod_chip_struct) chip = NULL;
struct gpiod_line_bulk bulk;
- int rv;
+ gint ret;
- chip = gpiod_chip_open(test_chip_path(1));
- TEST_ASSERT_NOT_NULL(chip);
+ chip = gpiod_chip_open(gpiod_test_chip_path(1));
+ g_assert_nonnull(chip);
+ gpiod_test_return_if_failed();
- rv = gpiod_chip_find_lines(chip, names, &bulk);
- TEST_ASSERT_EQ(rv, -1);
- TEST_ASSERT_ERRNO_IS(ENOENT);
+ ret = gpiod_chip_find_lines(chip, names, &bulk);
+ g_assert_cmpint(ret, ==, -1);
+ g_assert_cmpint(errno, ==, ENOENT);
}
-TEST_DEFINE(chip_find_lines_not_found,
- "gpiod_chip_find_lines() - not found",
- TEST_FLAG_NAMED_LINES, { 8, 8, 8 });
/*
* This file is part of libgpiod.
*
- * Copyright (C) 2017-2018 Bartosz Golaszewski <bartekgola@gmail.com>
* Copyright (C) 2019 Bartosz Golaszewski <bgolaszewski@baylibre.com>
*/
-/* Test cases for the high-level API. */
-
#include <errno.h>
#include "gpiod-test.h"
-static void ctxless_get_value(void)
+#define GPIOD_TEST_GROUP "ctxless"
+
+GPIOD_TEST_CASE(get_value, 0, { 8 })
{
- int rv;
+ gint ret;
- rv = gpiod_ctxless_get_value(test_chip_name(0), 3,
- false, TEST_CONSUMER);
- TEST_ASSERT_EQ(rv, 0);
+ ret = gpiod_ctxless_get_value(gpiod_test_chip_name(0), 3,
+ false, GPIOD_TEST_CONSUMER);
+ g_assert_cmpint(ret, ==, 0);
- test_debugfs_set_value(0, 3, 1);
+ gpiod_test_chip_set_pull(0, 3, 1);
+
+ ret = gpiod_ctxless_get_value(gpiod_test_chip_name(0), 3,
+ false, GPIOD_TEST_CONSUMER);
+ g_assert_cmpint(ret, ==, 1);
+}
- rv = gpiod_ctxless_get_value(test_chip_name(0), 3,
- false, TEST_CONSUMER);
- TEST_ASSERT_EQ(rv, 1);
+static void set_value_check(gpointer data G_GNUC_UNUSED)
+{
+ g_assert_cmpint(gpiod_test_chip_get_value(0, 3), ==, 1);
}
-TEST_DEFINE(ctxless_get_value,
- "ctxless get value - single line",
- 0, { 8 });
-static void ctxless_set_value_check(void *data)
+GPIOD_TEST_CASE(set_value, 0, { 8 })
{
- int *val = data;
+ gint ret;
+
+ gpiod_test_chip_set_pull(0, 3, 0);
- *val = test_debugfs_get_value(0, 3);
+ ret = gpiod_ctxless_set_value(gpiod_test_chip_name(0), 3, 1,
+ false, GPIOD_TEST_CONSUMER,
+ set_value_check, NULL);
+ gpiod_test_return_if_failed();
+ g_assert_cmpint(ret, ==, 0);
+
+ g_assert_cmpint(gpiod_test_chip_get_value(0, 3), ==, 0);
}
-static void ctxless_set_value(void)
+static const guint get_value_multiple_offsets[] = {
+ 1, 3, 4, 5, 6, 7, 8, 9, 13, 14
+};
+
+static const gint get_value_multiple_expected[] = {
+ 1, 1, 1, 0, 0, 0, 1, 0, 1, 1
+};
+
+GPIOD_TEST_CASE(get_value_multiple, 0, { 16 })
{
- int rv, val;
+ gint ret, values[10];
+ guint i;
- TEST_ASSERT_EQ(test_debugfs_get_value(0, 3), 0);
+ for (i = 0; i < G_N_ELEMENTS(get_value_multiple_offsets); i++)
+ gpiod_test_chip_set_pull(0, get_value_multiple_offsets[i],
+ get_value_multiple_expected[i]);
- rv = gpiod_ctxless_set_value(test_chip_name(0), 3, 1,
- false, TEST_CONSUMER,
- ctxless_set_value_check, &val);
- TEST_ASSERT_RET_OK(rv);
+ ret = gpiod_ctxless_get_value_multiple(gpiod_test_chip_name(0),
+ get_value_multiple_offsets,
+ values, 10, false,
+ GPIOD_TEST_CONSUMER);
+ g_assert_cmpint(ret, ==, 0);
- TEST_ASSERT_EQ(val, 1);
- TEST_ASSERT_EQ(test_debugfs_get_value(0, 3), 0);
+ for (i = 0; i < G_N_ELEMENTS(get_value_multiple_offsets); i++)
+ g_assert_cmpint(values[i], ==, get_value_multiple_expected[i]);
}
-TEST_DEFINE(ctxless_set_value,
- "ctxless set value - single line",
- 0, { 8 });
-static const unsigned int ctxless_set_value_multiple_offsets[] = {
+static const guint set_value_multiple_offsets[] = {
0, 1, 2, 3, 4, 5, 6, 12, 13, 15
};
-static const int ctxless_set_value_multiple_values[] = {
+static const gint set_value_multiple_values[] = {
1, 1, 1, 0, 0, 1, 0, 1, 0, 0
};
-static void ctxless_set_value_multiple_check(void *data)
+static void set_value_multiple_check(gpointer data G_GNUC_UNUSED)
{
- bool *vals_correct = data;
- unsigned int offset, i;
- int val, exp;
-
- for (i = 0;
- i < TEST_ARRAY_SIZE(ctxless_set_value_multiple_values);
- i++) {
- offset = ctxless_set_value_multiple_offsets[i];
- exp = ctxless_set_value_multiple_values[i];
- val = test_debugfs_get_value(0, offset);
-
- if (val != exp) {
- *vals_correct = false;
- break;
- }
+ guint i, offset;
+ gint val, exp;
+
+ for (i = 0; i < G_N_ELEMENTS(set_value_multiple_values); i++) {
+ offset = set_value_multiple_offsets[i];
+ exp = set_value_multiple_values[i];
+ val = gpiod_test_chip_get_value(0, offset);
+
+ g_assert_cmpint(val, ==, exp);
}
}
-static void ctxless_set_get_value_multiple(void)
+GPIOD_TEST_CASE(set_value_multiple, 0, { 16 })
{
- bool vals_correct = true;
- int values[10], rv;
- unsigned int i;
-
- for (i = 0;
- i < TEST_ARRAY_SIZE(ctxless_set_value_multiple_offsets);
- i++) {
- TEST_ASSERT_EQ(test_debugfs_get_value(0,
- ctxless_set_value_multiple_offsets[i]), 0);
- }
+ gint values[10], ret;
+ guint i;
- for (i = 0;
- i < TEST_ARRAY_SIZE(ctxless_set_value_multiple_values);
- i++) {
- values[i] = ctxless_set_value_multiple_values[i];
- }
+ for (i = 0; i < G_N_ELEMENTS(set_value_multiple_offsets); i++)
+ values[i] = set_value_multiple_values[i];
- rv = gpiod_ctxless_set_value_multiple(test_chip_name(0),
- ctxless_set_value_multiple_offsets,
- values, 10, false, TEST_CONSUMER,
- ctxless_set_value_multiple_check,
- &vals_correct);
- TEST_ASSERT_RET_OK(rv);
- TEST_ASSERT(vals_correct);
+ ret = gpiod_ctxless_set_value_multiple(gpiod_test_chip_name(0),
+ set_value_multiple_offsets, values, 10, false,
+ GPIOD_TEST_CONSUMER, set_value_multiple_check, NULL);
+ gpiod_test_return_if_failed();
+ g_assert_cmpint(ret, ==, 0);
}
-TEST_DEFINE(ctxless_set_get_value_multiple,
- "ctxless set/get value - multiple lines",
- 0, { 16 });
-static void ctxless_get_value_multiple_max_lines(void)
+GPIOD_TEST_CASE(get_value_multiple_max_lines, 0, { 128 })
{
- unsigned int offsets[GPIOD_LINE_BULK_MAX_LINES + 1];
- int values[GPIOD_LINE_BULK_MAX_LINES + 1], rv;
-
- rv = gpiod_ctxless_get_value_multiple(test_chip_name(0), offsets,
- values,
- GPIOD_LINE_BULK_MAX_LINES + 1,
- false, TEST_CONSUMER);
- TEST_ASSERT_NOTEQ(rv, 0);
- TEST_ASSERT_ERRNO_IS(EINVAL);
+ gint values[GPIOD_LINE_BULK_MAX_LINES + 1], ret;
+ guint offsets[GPIOD_LINE_BULK_MAX_LINES + 1];
+
+ ret = gpiod_ctxless_get_value_multiple(gpiod_test_chip_name(0),
+ offsets, values,
+ GPIOD_LINE_BULK_MAX_LINES + 1,
+ false, GPIOD_TEST_CONSUMER);
+ g_assert_cmpint(ret, ==, -1);
+ g_assert_cmpint(errno, ==, EINVAL);
}
-TEST_DEFINE(ctxless_get_value_multiple_max_lines,
- "gpiod_ctxless_get_value_multiple() exceed max lines",
- 0, { 128 });
-static void ctxless_set_value_multiple_max_lines(void)
+GPIOD_TEST_CASE(set_value_multiple_max_lines, 0, { 128 })
{
- unsigned int offsets[GPIOD_LINE_BULK_MAX_LINES + 1];
- int values[GPIOD_LINE_BULK_MAX_LINES + 1], rv;
-
- rv = gpiod_ctxless_set_value_multiple(test_chip_name(0), offsets,
- values,
- GPIOD_LINE_BULK_MAX_LINES + 1,
- false, TEST_CONSUMER,
- NULL, NULL);
- TEST_ASSERT_NOTEQ(rv, 0);
- TEST_ASSERT_ERRNO_IS(EINVAL);
+ gint values[GPIOD_LINE_BULK_MAX_LINES + 1], ret;
+ guint offsets[GPIOD_LINE_BULK_MAX_LINES + 1];
+
+ ret = gpiod_ctxless_set_value_multiple(gpiod_test_chip_name(0),
+ offsets, values, GPIOD_LINE_BULK_MAX_LINES + 1,
+ false, GPIOD_TEST_CONSUMER, NULL, NULL);
+ g_assert_cmpint(ret, ==, -1);
+ g_assert_cmpint(errno, ==, EINVAL);
}
-TEST_DEFINE(ctxless_set_value_multiple_max_lines,
- "gpiod_ctxless_set_value_multiple() exceed max lines",
- 0, { 128 });
struct ctxless_event_data {
- bool got_rising_edge;
- bool got_falling_edge;
- unsigned int offset;
- unsigned int count;
+ gboolean got_rising_edge;
+ gboolean got_falling_edge;
+ guint offset;
+ guint count;
};
-static int ctxless_event_cb(int evtype, unsigned int offset,
- const struct timespec *ts TEST_UNUSED, void *data)
+static int ctxless_event_cb(gint evtype, guint offset,
+ const struct timespec *ts G_GNUC_UNUSED,
+ gpointer data)
{
struct ctxless_event_data *evdata = data;
if (evtype == GPIOD_CTXLESS_EVENT_CB_RISING_EDGE)
- evdata->got_rising_edge = true;
+ evdata->got_rising_edge = TRUE;
else if (evtype == GPIOD_CTXLESS_EVENT_CB_FALLING_EDGE)
- evdata->got_falling_edge = true;
+ evdata->got_falling_edge = TRUE;
evdata->offset = offset;
: GPIOD_CTXLESS_EVENT_CB_RET_OK;
}
-static void ctxless_event_monitor(void)
+GPIOD_TEST_CASE(event_monitor, 0, { 8 })
{
+ g_autoptr(GpiodTestEventThread) ev_thread = NULL;
struct ctxless_event_data evdata = { false, false, 0, 0 };
struct timespec ts = { 1, 0 };
- int rv;
-
- test_set_event(0, 3, 100);
-
- rv = gpiod_ctxless_event_monitor(test_chip_name(0),
- GPIOD_CTXLESS_EVENT_BOTH_EDGES,
- 3, false, TEST_CONSUMER, &ts,
- NULL, ctxless_event_cb, &evdata);
-
- TEST_ASSERT_RET_OK(rv);
- TEST_ASSERT(evdata.got_rising_edge);
- TEST_ASSERT(evdata.got_falling_edge);
- TEST_ASSERT_EQ(evdata.count, 2);
- TEST_ASSERT_EQ(evdata.offset, 3);
+ gint ret;
+
+ ev_thread = gpiod_test_start_event_thread(0, 3, 100);
+
+ ret = gpiod_ctxless_event_monitor(gpiod_test_chip_name(0),
+ GPIOD_CTXLESS_EVENT_BOTH_EDGES,
+ 3, false, GPIOD_TEST_CONSUMER, &ts,
+ NULL, ctxless_event_cb, &evdata);
+ g_assert_cmpint(ret, ==, 0);
+ g_assert_true(evdata.got_rising_edge);
+ g_assert_true(evdata.got_falling_edge);
+ g_assert_cmpuint(evdata.count, ==, 2);
+ g_assert_cmpuint(evdata.offset, ==, 3);
}
-TEST_DEFINE(ctxless_event_monitor,
- "gpiod_ctxless_event_monitor() - single event",
- 0, { 8 });
-static void ctxless_event_monitor_single_event_type(void)
+GPIOD_TEST_CASE(event_monitor_single_event_type, 0, { 8 })
{
+ g_autoptr(GpiodTestEventThread) ev_thread = NULL;
struct ctxless_event_data evdata = { false, false, 0, 0 };
struct timespec ts = { 1, 0 };
- int rv;
-
- test_set_event(0, 3, 100);
-
- rv = gpiod_ctxless_event_monitor(test_chip_name(0),
- GPIOD_CTXLESS_EVENT_FALLING_EDGE,
- 3, false, TEST_CONSUMER, &ts,
- NULL, ctxless_event_cb, &evdata);
-
- TEST_ASSERT_RET_OK(rv);
- TEST_ASSERT(evdata.got_falling_edge);
- TEST_ASSERT_FALSE(evdata.got_rising_edge);
- TEST_ASSERT_EQ(evdata.count, 2);
- TEST_ASSERT_EQ(evdata.offset, 3);
+ gint ret;
+
+ ev_thread = gpiod_test_start_event_thread(0, 3, 100);
+
+ ret = gpiod_ctxless_event_monitor(gpiod_test_chip_name(0),
+ GPIOD_CTXLESS_EVENT_FALLING_EDGE,
+ 3, false, GPIOD_TEST_CONSUMER, &ts,
+ NULL, ctxless_event_cb, &evdata);
+ g_assert_cmpint(ret, ==, 0);
+ g_assert_false(evdata.got_rising_edge);
+ g_assert_true(evdata.got_falling_edge);
+ g_assert_cmpuint(evdata.count, ==, 2);
+ g_assert_cmpuint(evdata.offset, ==, 3);
}
-TEST_DEFINE(ctxless_event_monitor_single_event_type,
- "gpiod_ctxless_event_monitor() - specify event type",
- 0, { 8 });
-static void ctxless_event_monitor_multiple(void)
+GPIOD_TEST_CASE(event_monitor_multiple, 0, { 8 })
{
+ g_autoptr(GpiodTestEventThread) ev_thread = NULL;
struct ctxless_event_data evdata = { false, false, 0, 0 };
struct timespec ts = { 1, 0 };
- unsigned int offsets[4];
- int rv;
+ guint offsets[4];
+ gint ret;
offsets[0] = 2;
offsets[1] = 3;
offsets[2] = 5;
offsets[3] = 6;
- test_set_event(0, 3, 100);
-
- rv = gpiod_ctxless_event_monitor_multiple(
- test_chip_name(0),
- GPIOD_CTXLESS_EVENT_BOTH_EDGES,
- offsets, 4, false, TEST_CONSUMER,
- &ts, NULL, ctxless_event_cb, &evdata);
+ ev_thread = gpiod_test_start_event_thread(0, 3, 100);
- TEST_ASSERT_RET_OK(rv);
- TEST_ASSERT(evdata.got_rising_edge);
- TEST_ASSERT(evdata.got_falling_edge);
- TEST_ASSERT_EQ(evdata.count, 2);
- TEST_ASSERT_EQ(evdata.offset, 3);
+ ret = gpiod_ctxless_event_monitor_multiple(gpiod_test_chip_name(0),
+ GPIOD_CTXLESS_EVENT_BOTH_EDGES, offsets, 4, false,
+ GPIOD_TEST_CONSUMER, &ts, NULL, ctxless_event_cb, &evdata);
+ g_assert_cmpint(ret, ==, 0);
+ g_assert_true(evdata.got_rising_edge);
+ g_assert_true(evdata.got_falling_edge);
+ g_assert_cmpuint(evdata.count, ==, 2);
+ g_assert_cmpuint(evdata.offset, ==, 3);
}
-TEST_DEFINE(ctxless_event_monitor_multiple,
- "gpiod_ctxless_event_monitor_multiple() - single event",
- 0, { 8 });
-
-static int error_event_cb(int evtype TEST_UNUSED,
- unsigned int offset TEST_UNUSED,
- const struct timespec *ts TEST_UNUSED,
- void *data TEST_UNUSED)
+
+static int error_event_cb(gint evtype G_GNUC_UNUSED,
+ guint offset G_GNUC_UNUSED,
+ const struct timespec *ts G_GNUC_UNUSED,
+ gpointer data G_GNUC_UNUSED)
{
errno = ENOTBLK;
return GPIOD_CTXLESS_EVENT_CB_RET_ERR;
}
-static void ctxless_event_monitor_indicate_error(void)
+GPIOD_TEST_CASE(event_monitor_indicate_error, 0, { 8 })
{
+ g_autoptr(GpiodTestEventThread) ev_thread = NULL;
struct timespec ts = { 1, 0 };
- int rv;
-
- test_set_event(0, 3, 100);
+ gint ret;
- rv = gpiod_ctxless_event_monitor(test_chip_name(0),
- GPIOD_CTXLESS_EVENT_BOTH_EDGES,
- 3, false, TEST_CONSUMER, &ts,
- NULL, error_event_cb, NULL);
+ ev_thread = gpiod_test_start_event_thread(0, 3, 100);
- TEST_ASSERT_EQ(rv, -1);
- TEST_ASSERT_ERRNO_IS(ENOTBLK);
+ ret = gpiod_ctxless_event_monitor(gpiod_test_chip_name(0),
+ GPIOD_CTXLESS_EVENT_BOTH_EDGES,
+ 3, false, GPIOD_TEST_CONSUMER, &ts,
+ NULL, error_event_cb, NULL);
+ g_assert_cmpint(ret, ==, -1);
+ g_assert_cmpint(errno, ==, ENOTBLK);
}
-TEST_DEFINE(ctxless_event_monitor_indicate_error,
- "gpiod_ctxless_event_monitor() - error in callback",
- 0, { 8 });
-static void ctxless_event_monitor_indicate_error_timeout(void)
+static int error_event_cb_timeout(gint evtype,
+ guint offset G_GNUC_UNUSED,
+ const struct timespec *ts G_GNUC_UNUSED,
+ gpointer data G_GNUC_UNUSED)
{
- struct timespec ts = { 0, 100000 };
- int rv;
+ errno = ENOTBLK;
- rv = gpiod_ctxless_event_monitor(test_chip_name(0),
- GPIOD_CTXLESS_EVENT_BOTH_EDGES,
- 3, false, TEST_CONSUMER, &ts,
- NULL, error_event_cb, NULL);
+ g_assert_cmpint(evtype, ==, GPIOD_CTXLESS_EVENT_CB_TIMEOUT);
- TEST_ASSERT_EQ(rv, -1);
- TEST_ASSERT_ERRNO_IS(ENOTBLK);
+ return GPIOD_CTXLESS_EVENT_CB_RET_ERR;
+}
+
+GPIOD_TEST_CASE(event_monitor_indicate_error_timeout, 0, { 8 })
+{
+ struct timespec ts = { 0, 100000 };
+ gint ret;
+
+ ret = gpiod_ctxless_event_monitor(gpiod_test_chip_name(0),
+ GPIOD_CTXLESS_EVENT_BOTH_EDGES,
+ 3, false, GPIOD_TEST_CONSUMER, &ts,
+ NULL, error_event_cb_timeout, NULL);
+ g_assert_cmpint(ret, ==, -1);
+ g_assert_cmpint(errno, ==, ENOTBLK);
}
-TEST_DEFINE(ctxless_event_monitor_indicate_error_timeout,
- "gpiod_ctxless_event_monitor() - error in callback after timeout",
- 0, { 8 });
-static void ctxless_find_line_good(void)
+GPIOD_TEST_CASE(find_line, GPIOD_TEST_FLAG_NAMED_LINES, { 8, 16, 16, 8 })
{
- unsigned int offset;
- char chip[32];
- int rv;
-
- rv = gpiod_ctxless_find_line("gpio-mockup-C-14", chip,
- sizeof(chip), &offset);
- TEST_ASSERT_EQ(rv, 1);
- TEST_ASSERT_EQ(offset, 14);
- TEST_ASSERT_STR_EQ(chip, test_chip_name(2));
+ gchar chip[32];
+ guint offset;
+ gint ret;
+
+ ret = gpiod_ctxless_find_line("gpio-mockup-C-14", chip,
+ sizeof(chip), &offset);
+ g_assert_cmpint(ret, ==, 1);
+ g_assert_cmpuint(offset, ==, 14);
+ g_assert_cmpstr(chip, ==, gpiod_test_chip_name(2));
}
-TEST_DEFINE(ctxless_find_line_good,
- "gpiod_ctxless_find_line() - good",
- TEST_FLAG_NAMED_LINES, { 8, 16, 16, 8 });
-static void ctxless_find_line_truncated(void)
+GPIOD_TEST_CASE(find_line_truncated,
+ GPIOD_TEST_FLAG_NAMED_LINES, { 8, 16, 16, 8 })
{
- unsigned int offset;
- char chip[6];
- int rv;
-
- rv = gpiod_ctxless_find_line("gpio-mockup-C-14", chip,
- sizeof(chip), &offset);
- TEST_ASSERT_EQ(rv, 1);
- TEST_ASSERT_EQ(offset, 14);
- TEST_ASSERT_STR_EQ(chip, "gpioc");
+ gchar chip[6];
+ guint offset;
+ gint ret;
+
+ ret = gpiod_ctxless_find_line("gpio-mockup-C-14", chip,
+ sizeof(chip), &offset);
+ g_assert_cmpint(ret, ==, 1);
+ g_assert_cmpuint(offset, ==, 14);
+ g_assert_cmpstr(chip, ==, "gpioc");
}
-TEST_DEFINE(ctxless_find_line_truncated,
- "gpiod_ctxless_find_line() - chip name truncated",
- TEST_FLAG_NAMED_LINES, { 8, 16, 16, 8 });
-static void ctxless_find_line_not_found(void)
+GPIOD_TEST_CASE(find_line_not_found,
+ GPIOD_TEST_FLAG_NAMED_LINES, { 8, 16, 16, 8 })
{
- unsigned int offset;
- char chip[32];
- int rv;
+ gchar chip[32];
+ guint offset;
+ gint ret;
- rv = gpiod_ctxless_find_line("nonexistent", chip,
- sizeof(chip), &offset);
- TEST_ASSERT_EQ(rv, 0);
+ ret = gpiod_ctxless_find_line("nonexistent", chip,
+ sizeof(chip), &offset);
+ g_assert_cmpint(ret, ==, 0);
}
-TEST_DEFINE(ctxless_find_line_not_found,
- "gpiod_ctxless_find_line() - not found",
- TEST_FLAG_NAMED_LINES, { 8, 16, 16, 8 });
/*
* This file is part of libgpiod.
*
- * Copyright (C) 2017-2018 Bartosz Golaszewski <bartekgola@gmail.com>
* Copyright (C) 2019 Bartosz Golaszewski <bgolaszewski@baylibre.com>
*/
-/* Test cases for GPIO line events. */
-
#include <errno.h>
#include <unistd.h>
#include "gpiod-test.h"
-static void event_rising_edge_good(void)
+#define GPIOD_TEST_GROUP "event"
+
+GPIOD_TEST_CASE(rising_edge_good, 0, { 8 })
{
- TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL;
+ g_autoptr(GpiodTestEventThread) ev_thread = NULL;
+ g_autoptr(gpiod_chip_struct) chip = NULL;
struct timespec ts = { 1, 0 };
struct gpiod_line_event ev;
struct gpiod_line *line;
- int rv;
+ gint ret;
- chip = gpiod_chip_open(test_chip_path(0));
- TEST_ASSERT_NOT_NULL(chip);
+ chip = gpiod_chip_open(gpiod_test_chip_path(0));
+ g_assert_nonnull(chip);
+ gpiod_test_return_if_failed();
line = gpiod_chip_get_line(chip, 7);
- TEST_ASSERT_NOT_NULL(line);
+ g_assert_nonnull(line);
+ gpiod_test_return_if_failed();
- rv = gpiod_line_request_rising_edge_events(line, TEST_CONSUMER);
- TEST_ASSERT_RET_OK(rv);
+ ret = gpiod_line_request_rising_edge_events(line, GPIOD_TEST_CONSUMER);
+ g_assert_cmpint(ret, ==, 0);
- test_set_event(0, 7, 100);
+ ev_thread = gpiod_test_start_event_thread(0, 7, 100);
- rv = gpiod_line_event_wait(line, &ts);
- TEST_ASSERT_EQ(rv, 1);
+ ret = gpiod_line_event_wait(line, &ts);
+ g_assert_cmpint(ret, ==, 1);
- rv = gpiod_line_event_read(line, &ev);
- TEST_ASSERT_RET_OK(rv);
+ ret = gpiod_line_event_read(line, &ev);
+ g_assert_cmpint(ret, ==, 0);
- TEST_ASSERT_EQ(ev.event_type, GPIOD_LINE_EVENT_RISING_EDGE);
+ g_assert_cmpint(ev.event_type, ==, GPIOD_LINE_EVENT_RISING_EDGE);
}
-TEST_DEFINE(event_rising_edge_good,
- "events - receive single rising edge event",
- 0, { 8 });
-static void event_falling_edge_good(void)
+GPIOD_TEST_CASE(falling_edge_good, 0, { 8 })
{
- TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL;
+ g_autoptr(GpiodTestEventThread) ev_thread = NULL;
+ g_autoptr(gpiod_chip_struct) chip = NULL;
struct timespec ts = { 1, 0 };
struct gpiod_line_event ev;
struct gpiod_line *line;
- int rv;
+ gint ret;
- chip = gpiod_chip_open(test_chip_path(0));
- TEST_ASSERT_NOT_NULL(chip);
+ chip = gpiod_chip_open(gpiod_test_chip_path(0));
+ g_assert_nonnull(chip);
+ gpiod_test_return_if_failed();
line = gpiod_chip_get_line(chip, 7);
- TEST_ASSERT_NOT_NULL(line);
+ g_assert_nonnull(line);
+ gpiod_test_return_if_failed();
- rv = gpiod_line_request_falling_edge_events(line, TEST_CONSUMER);
- TEST_ASSERT_RET_OK(rv);
+ ret = gpiod_line_request_falling_edge_events(line,
+ GPIOD_TEST_CONSUMER);
+ g_assert_cmpint(ret, ==, 0);
- test_set_event(0, 7, 100);
+ ev_thread = gpiod_test_start_event_thread(0, 7, 100);
- rv = gpiod_line_event_wait(line, &ts);
- TEST_ASSERT_EQ(rv, 1);
+ ret = gpiod_line_event_wait(line, &ts);
+ g_assert_cmpint(ret, ==, 1);
- rv = gpiod_line_event_read(line, &ev);
- TEST_ASSERT_RET_OK(rv);
+ ret = gpiod_line_event_read(line, &ev);
+ g_assert_cmpint(ret, ==, 0);
- TEST_ASSERT_EQ(ev.event_type, GPIOD_LINE_EVENT_FALLING_EDGE);
+ g_assert_cmpint(ev.event_type, ==, GPIOD_LINE_EVENT_FALLING_EDGE);
}
-TEST_DEFINE(event_falling_edge_good,
- "events - receive single falling edge event",
- 0, { 8 });
-static void event_rising_edge_ignore_falling(void)
+GPIOD_TEST_CASE(rising_edge_ignore_falling, 0, { 8 })
{
- TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL;
- struct timespec ts = { 0, 300 };
+ g_autoptr(GpiodTestEventThread) ev_thread = NULL;
+ g_autoptr(gpiod_chip_struct) chip = NULL;
+ struct timespec ts = { 1, 0 };
+ struct gpiod_line_event ev[3];
struct gpiod_line *line;
- int rv;
+ gint ret;
- chip = gpiod_chip_open(test_chip_path(0));
- TEST_ASSERT_NOT_NULL(chip);
+ chip = gpiod_chip_open(gpiod_test_chip_path(0));
+ g_assert_nonnull(chip);
+ gpiod_test_return_if_failed();
line = gpiod_chip_get_line(chip, 7);
- TEST_ASSERT_NOT_NULL(line);
+ g_assert_nonnull(line);
+ gpiod_test_return_if_failed();
+
+ ret = gpiod_line_request_rising_edge_events(line, GPIOD_TEST_CONSUMER);
+ g_assert_cmpint(ret, ==, 0);
+
+ ev_thread = gpiod_test_start_event_thread(0, 7, 100);
+
+ ret = gpiod_line_event_wait(line, &ts);
+ g_assert_cmpint(ret, ==, 1);
+ ret = gpiod_line_event_read(line, &ev[0]);
+ g_assert_cmpint(ret, ==, 0);
- rv = gpiod_line_request_rising_edge_events(line, TEST_CONSUMER);
- TEST_ASSERT_RET_OK(rv);
+ ret = gpiod_line_event_wait(line, &ts);
+ g_assert_cmpint(ret, ==, 1);
+ ret = gpiod_line_event_read(line, &ev[1]);
+ g_assert_cmpint(ret, ==, 0);
- test_set_event(0, 7, 100);
+ ret = gpiod_line_event_wait(line, &ts);
+ g_assert_cmpint(ret, ==, 1);
+ ret = gpiod_line_event_read(line, &ev[2]);
+ g_assert_cmpint(ret, ==, 0);
- rv = gpiod_line_event_wait(line, &ts);
- TEST_ASSERT_EQ(rv, 0);
+ g_assert_cmpint(ev[0].event_type, ==, GPIOD_LINE_EVENT_RISING_EDGE);
+ g_assert_cmpint(ev[1].event_type, ==, GPIOD_LINE_EVENT_RISING_EDGE);
+ g_assert_cmpint(ev[2].event_type, ==, GPIOD_LINE_EVENT_RISING_EDGE);
}
-TEST_DEFINE(event_rising_edge_ignore_falling,
- "events - request rising edge & ignore falling edge events",
- 0, { 8 });
-static void event_rising_edge_active_low(void)
+GPIOD_TEST_CASE(rising_edge_active_low, 0, { 8 })
{
- TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL;
+ g_autoptr(GpiodTestEventThread) ev_thread = NULL;
+ g_autoptr(gpiod_chip_struct) chip = NULL;
struct timespec ts = { 1, 0 };
struct gpiod_line_event ev;
struct gpiod_line *line;
- int rv;
+ gint ret;
- chip = gpiod_chip_open(test_chip_path(0));
- TEST_ASSERT_NOT_NULL(chip);
+ chip = gpiod_chip_open(gpiod_test_chip_path(0));
+ g_assert_nonnull(chip);
+ gpiod_test_return_if_failed();
line = gpiod_chip_get_line(chip, 7);
- TEST_ASSERT_NOT_NULL(line);
+ g_assert_nonnull(line);
+ gpiod_test_return_if_failed();
- rv = gpiod_line_request_rising_edge_events_flags(line, TEST_CONSUMER,
- GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW);
- TEST_ASSERT_RET_OK(rv);
+ ret = gpiod_line_request_rising_edge_events_flags(line,
+ GPIOD_TEST_CONSUMER, GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW);
+ g_assert_cmpint(ret, ==, 0);
- test_set_event(0, 7, 100);
+ ev_thread = gpiod_test_start_event_thread(0, 7, 100);
- rv = gpiod_line_event_wait(line, &ts);
- TEST_ASSERT_EQ(rv, 1);
+ ret = gpiod_line_event_wait(line, &ts);
+ g_assert_cmpint(ret, ==, 1);
- rv = gpiod_line_event_read(line, &ev);
- TEST_ASSERT_RET_OK(rv);
+ ret = gpiod_line_event_read(line, &ev);
+ g_assert_cmpint(ret, ==, 0);
- TEST_ASSERT_EQ(ev.event_type, GPIOD_LINE_EVENT_RISING_EDGE);
+ g_assert_cmpint(ev.event_type, ==, GPIOD_LINE_EVENT_RISING_EDGE);
}
-TEST_DEFINE(event_rising_edge_active_low,
- "events - single rising edge event with low active state",
- 0, { 8 });
-static void event_get_value(void)
+GPIOD_TEST_CASE(get_value, 0, { 8 })
{
- TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL;
+ g_autoptr(GpiodTestEventThread) ev_thread = NULL;
+ g_autoptr(gpiod_chip_struct) chip = NULL;
struct timespec ts = { 1, 0 };
struct gpiod_line_event ev;
struct gpiod_line *line;
- int rv;
+ gint ret;
- chip = gpiod_chip_open(test_chip_path(0));
- TEST_ASSERT_NOT_NULL(chip);
+ chip = gpiod_chip_open(gpiod_test_chip_path(0));
+ g_assert_nonnull(chip);
+ gpiod_test_return_if_failed();
line = gpiod_chip_get_line(chip, 7);
- TEST_ASSERT_NOT_NULL(line);
+ g_assert_nonnull(line);
+ gpiod_test_return_if_failed();
- rv = gpiod_line_request_rising_edge_events(line, TEST_CONSUMER);
- TEST_ASSERT_RET_OK(rv);
+ gpiod_test_chip_set_pull(0, 7, 1);
- rv = gpiod_line_get_value(line);
- TEST_ASSERT_EQ(rv, 0);
+ ret = gpiod_line_request_falling_edge_events(line, GPIOD_TEST_CONSUMER);
+ g_assert_cmpint(ret, ==, 0);
- test_set_event(0, 7, 100);
+ ret = gpiod_line_get_value(line);
+ g_assert_cmpint(ret, ==, 1);
- rv = gpiod_line_event_wait(line, &ts);
- TEST_ASSERT_EQ(rv, 1);
+ ev_thread = gpiod_test_start_event_thread(0, 7, 100);
- rv = gpiod_line_event_read(line, &ev);
- TEST_ASSERT_RET_OK(rv);
+ ret = gpiod_line_event_wait(line, &ts);
+ g_assert_cmpint(ret, ==, 1);
- TEST_ASSERT_EQ(ev.event_type, GPIOD_LINE_EVENT_RISING_EDGE);
+ ret = gpiod_line_event_read(line, &ev);
+ g_assert_cmpint(ret, ==, 0);
- rv = gpiod_line_get_value(line);
- TEST_ASSERT_EQ(rv, 1);
+ g_assert_cmpint(ev.event_type, ==, GPIOD_LINE_EVENT_FALLING_EDGE);
}
-TEST_DEFINE(event_get_value,
- "events - mixing events and gpiod_line_get_value()",
- 0, { 8 });
-static void event_get_value_active_low(void)
+GPIOD_TEST_CASE(get_value_active_low, 0, { 8 })
{
- TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL;
+ g_autoptr(GpiodTestEventThread) ev_thread = NULL;
+ g_autoptr(gpiod_chip_struct) chip = NULL;
struct timespec ts = { 1, 0 };
struct gpiod_line_event ev;
struct gpiod_line *line;
- int rv;
+ gint ret;
- chip = gpiod_chip_open(test_chip_path(0));
- TEST_ASSERT_NOT_NULL(chip);
+ chip = gpiod_chip_open(gpiod_test_chip_path(0));
+ g_assert_nonnull(chip);
+ gpiod_test_return_if_failed();
line = gpiod_chip_get_line(chip, 7);
- TEST_ASSERT_NOT_NULL(line);
+ g_assert_nonnull(line);
+ gpiod_test_return_if_failed();
- rv = gpiod_line_request_falling_edge_events_flags(line, TEST_CONSUMER,
- GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW);
- TEST_ASSERT_RET_OK(rv);
+ gpiod_test_chip_set_pull(0, 7, 1);
- rv = gpiod_line_get_value(line);
- TEST_ASSERT_EQ(rv, 1);
+ ret = gpiod_line_request_falling_edge_events_flags(line,
+ GPIOD_TEST_CONSUMER, GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW);
+ g_assert_cmpint(ret, ==, 0);
- test_set_event(0, 7, 100);
+ ret = gpiod_line_get_value(line);
+ g_assert_cmpint(ret, ==, 0);
- rv = gpiod_line_event_wait(line, &ts);
- TEST_ASSERT_EQ(rv, 1);
+ ev_thread = gpiod_test_start_event_thread(0, 7, 100);
- rv = gpiod_line_event_read(line, &ev);
- TEST_ASSERT_RET_OK(rv);
+ ret = gpiod_line_event_wait(line, &ts);
+ g_assert_cmpint(ret, ==, 1);
- TEST_ASSERT_EQ(ev.event_type, GPIOD_LINE_EVENT_FALLING_EDGE);
+ ret = gpiod_line_event_read(line, &ev);
+ g_assert_cmpint(ret, ==, 0);
- rv = gpiod_line_get_value(line);
- TEST_ASSERT_EQ(rv, 1);
+ g_assert_cmpint(ev.event_type, ==, GPIOD_LINE_EVENT_FALLING_EDGE);
}
-TEST_DEFINE(event_get_value_active_low,
- "events - mixing events and gpiod_line_get_value() (active-low flag)",
- 0, { 8 });
-static void event_wait_multiple(void)
+GPIOD_TEST_CASE(wait_multiple, 0, { 8 })
{
- TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL;
+ g_autoptr(GpiodTestEventThread) ev_thread = NULL;
+ g_autoptr(gpiod_chip_struct) chip = NULL;
struct gpiod_line_bulk bulk, event_bulk;
struct timespec ts = { 1, 0 };
+ struct gpiod_line_event ev;
struct gpiod_line *line;
- int rv, i;
+ gint ret, i;
- chip = gpiod_chip_open(test_chip_path(0));
- TEST_ASSERT_NOT_NULL(chip);
+ chip = gpiod_chip_open(gpiod_test_chip_path(0));
+ g_assert_nonnull(chip);
+ gpiod_test_return_if_failed();
gpiod_line_bulk_init(&bulk);
-
for (i = 0; i < 8; i++) {
line = gpiod_chip_get_line(chip, i);
- TEST_ASSERT_NOT_NULL(line);
+ g_assert_nonnull(line);
+ gpiod_test_return_if_failed();
gpiod_line_bulk_add(&bulk, line);
}
- rv = gpiod_line_request_bulk_both_edges_events(&bulk, TEST_CONSUMER);
- TEST_ASSERT_RET_OK(rv);
+ ret = gpiod_line_request_bulk_rising_edge_events(&bulk,
+ GPIOD_TEST_CONSUMER);
+ g_assert_cmpint(ret, ==, 0);
- test_set_event(0, 4, 100);
+ ev_thread = gpiod_test_start_event_thread(0, 4, 100);
- rv = gpiod_line_event_wait_bulk(&bulk, &ts, &event_bulk);
- TEST_ASSERT_EQ(rv, 1);
+ ret = gpiod_line_event_wait_bulk(&bulk, &ts, &event_bulk);
+ g_assert_cmpint(ret, ==, 1);
- TEST_ASSERT_EQ(gpiod_line_bulk_num_lines(&event_bulk), 1);
+ g_assert_cmpuint(gpiod_line_bulk_num_lines(&event_bulk), ==, 1);
line = gpiod_line_bulk_get_line(&event_bulk, 0);
- TEST_ASSERT_EQ(gpiod_line_offset(line), 4);
+ g_assert_cmpuint(gpiod_line_offset(line), ==, 4);
+
+ ret = gpiod_line_event_read(line, &ev);
+ g_assert_cmpint(ret, ==, 0);
+ g_assert_cmpint(ev.event_type, ==, GPIOD_LINE_EVENT_RISING_EDGE);
}
-TEST_DEFINE(event_wait_multiple,
- "events - wait for events on multiple lines",
- 0, { 8 });
-static void event_get_fd_when_values_requested(void)
+GPIOD_TEST_CASE(get_fd_when_values_requested, 0, { 8 })
{
- TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL;
+ g_autoptr(gpiod_chip_struct) chip = NULL;
struct gpiod_line *line;
- int rv, fd;
+ gint ret, fd;
- chip = gpiod_chip_open(test_chip_path(0));
- TEST_ASSERT_NOT_NULL(chip);
+ chip = gpiod_chip_open(gpiod_test_chip_path(0));
+ g_assert_nonnull(chip);
+ gpiod_test_return_if_failed();
line = gpiod_chip_get_line(chip, 3);
- TEST_ASSERT_NOT_NULL(line);
+ g_assert_nonnull(line);
+ gpiod_test_return_if_failed();
- rv = gpiod_line_request_input(line, TEST_CONSUMER);
- TEST_ASSERT_RET_OK(rv);
+ ret = gpiod_line_request_input(line, GPIOD_TEST_CONSUMER);
+ g_assert_cmpint(ret, ==, 0);
fd = gpiod_line_event_get_fd(line);
- TEST_ASSERT_EQ(fd, -1);
- TEST_ASSERT_ERRNO_IS(EPERM);
+ g_assert_cmpint(fd, ==, -1);
+ g_assert_cmpint(errno, ==, EPERM);
}
-TEST_DEFINE(event_get_fd_when_values_requested,
- "events - gpiod_line_event_get_fd(): line requested for values",
- 0, { 8 });
-static void event_request_bulk_fail(void)
+GPIOD_TEST_CASE(request_bulk_fail, 0, { 8 })
{
- TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL;
+ g_autoptr(gpiod_chip_struct) chip = NULL;
struct gpiod_line_bulk bulk = GPIOD_LINE_BULK_INITIALIZER;
struct gpiod_line *line;
- int rv, i;
+ gint ret, i;
- chip = gpiod_chip_open(test_chip_path(0));
- TEST_ASSERT_NOT_NULL(chip);
+ chip = gpiod_chip_open(gpiod_test_chip_path(0));
+ g_assert_nonnull(chip);
+ gpiod_test_return_if_failed();
- line = gpiod_chip_get_line(chip, 5);
- TEST_ASSERT_NOT_NULL(line);
+ line = gpiod_chip_get_line(chip, 7);
+ g_assert_nonnull(line);
+ gpiod_test_return_if_failed();
- rv = gpiod_line_request_input(line, TEST_CONSUMER);
- TEST_ASSERT_RET_OK(rv);
+ ret = gpiod_line_request_input(line, GPIOD_TEST_CONSUMER);
+ g_assert_cmpint(ret, ==, 0);
for (i = 0; i < 8; i++) {
line = gpiod_chip_get_line(chip, i);
- TEST_ASSERT_NOT_NULL(line);
+ g_assert_nonnull(line);
+ gpiod_test_return_if_failed();
gpiod_line_bulk_add(&bulk, line);
}
- rv = gpiod_line_request_bulk_both_edges_events(&bulk, TEST_CONSUMER);
- TEST_ASSERT_EQ(rv, -1);
- TEST_ASSERT_ERRNO_IS(EBUSY);
+ ret = gpiod_line_request_bulk_both_edges_events(&bulk,
+ GPIOD_TEST_CONSUMER);
+ g_assert_cmpint(ret, ==, -1);
+ g_assert_cmpint(errno, ==, EBUSY);
}
-TEST_DEFINE(event_request_bulk_fail,
- "events - failed bulk request (test reversed release)",
- 0, { 8 });
-static void event_invalid_fd(void)
+GPIOD_TEST_CASE(invalid_fd, 0, { 8 })
{
- TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL;
+ g_autoptr(gpiod_chip_struct) chip = NULL;
struct gpiod_line_bulk bulk = GPIOD_LINE_BULK_INITIALIZER;
struct gpiod_line_bulk ev_bulk;
struct timespec ts = { 1, 0 };
struct gpiod_line *line;
- int rv, fd;
+ gint ret, fd;
- chip = gpiod_chip_open(test_chip_path(0));
- TEST_ASSERT_NOT_NULL(chip);
+ chip = gpiod_chip_open(gpiod_test_chip_path(0));
+ g_assert_nonnull(chip);
+ gpiod_test_return_if_failed();
- line = gpiod_chip_get_line(chip, 5);
- TEST_ASSERT_NOT_NULL(line);
+ line = gpiod_chip_get_line(chip, 7);
+ g_assert_nonnull(line);
+ gpiod_test_return_if_failed();
- rv = gpiod_line_request_both_edges_events(line, TEST_CONSUMER);
- TEST_ASSERT_RET_OK(rv);
+ ret = gpiod_line_request_both_edges_events(line, GPIOD_TEST_CONSUMER);
+ g_assert_cmpint(ret, ==, 0);
fd = gpiod_line_event_get_fd(line);
close(fd);
- rv = gpiod_line_event_wait(line, &ts);
- TEST_ASSERT_EQ(rv, -1);
- TEST_ASSERT_ERRNO_IS(EINVAL);
+ ret = gpiod_line_event_wait(line, &ts);
+ g_assert_cmpint(ret, ==, -1);
+ g_assert_cmpint(errno, ==, EINVAL);
/*
* The single line variant calls gpiod_line_event_wait_bulk() with the
* as well.
*/
gpiod_line_bulk_add(&bulk, line);
- rv = gpiod_line_event_wait_bulk(&bulk, &ts, &ev_bulk);
- TEST_ASSERT_EQ(rv, -1);
- TEST_ASSERT_ERRNO_IS(EINVAL);
+ ret = gpiod_line_event_wait_bulk(&bulk, &ts, &ev_bulk);
+ g_assert_cmpint(ret, ==, -1);
+ g_assert_cmpint(errno, ==, EINVAL);
}
-TEST_DEFINE(event_invalid_fd,
- "events - gpiod_line_event_wait() error on closed fd",
- 0, { 8 });
+++ /dev/null
-// SPDX-License-Identifier: LGPL-2.1-or-later
-/*
- * This file is part of libgpiod.
- *
- * Copyright (C) 2017-2018 Bartosz Golaszewski <bartekgola@gmail.com>
- */
-
-/* Test cases for the gpiodetect program. */
-
-#include <stdio.h>
-
-#include "gpiod-test.h"
-
-static void gpiodetect_simple(void)
-{
- test_tool_run("gpiodetect", (char *)NULL);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_RET_OK(test_tool_exit_status());
- TEST_ASSERT_NOT_NULL(test_tool_stdout());
- TEST_ASSERT_STR_CONTAINS(test_tool_stdout(),
- test_build_str("%s [gpio-mockup-A] (4 lines)",
- test_chip_name(0)));
- TEST_ASSERT_STR_CONTAINS(test_tool_stdout(),
- test_build_str("%s [gpio-mockup-B] (8 lines)",
- test_chip_name(1)));
- TEST_ASSERT_STR_CONTAINS(test_tool_stdout(),
- test_build_str("%s [gpio-mockup-C] (16 lines)",
- test_chip_name(2)));
- TEST_ASSERT_NULL(test_tool_stderr());
-}
-TEST_DEFINE(gpiodetect_simple,
- "tools: gpiodetect - simple",
- 0, { 4, 8, 16 });
-
-static void gpiodetect_invalid_args(void)
-{
- test_tool_run("gpiodetect", "unused argument", (char *)NULL);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_EQ(test_tool_exit_status(), 1);
- TEST_ASSERT_NULL(test_tool_stdout());
- TEST_ASSERT_NOT_NULL(test_tool_stderr());
- TEST_ASSERT_STR_CONTAINS(test_tool_stderr(), "unrecognized argument");
-}
-TEST_DEFINE(gpiodetect_invalid_args,
- "tools: gpiodetect - invalid arguments",
- 0, { });
+++ /dev/null
-// SPDX-License-Identifier: LGPL-2.1-or-later
-/*
- * This file is part of libgpiod.
- *
- * Copyright (C) 2017-2018 Bartosz Golaszewski <bartekgola@gmail.com>
- */
-
-/* Test cases for the gpiofind program. */
-
-#include <stdio.h>
-
-#include "gpiod-test.h"
-
-static void gpiofind_found(void)
-{
- test_tool_run("gpiofind", "gpio-mockup-B-7", (char *)NULL);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_RET_OK(test_tool_exit_status());
- TEST_ASSERT_NOT_NULL(test_tool_stdout());
- TEST_ASSERT_STR_EQ(test_tool_stdout(),
- test_build_str("%s 7\n", test_chip_name(1)));
- TEST_ASSERT_NULL(test_tool_stderr());
-}
-TEST_DEFINE(gpiofind_found,
- "tools: gpiofind - found",
- TEST_FLAG_NAMED_LINES, { 4, 8 });
-
-static void gpiofind_not_found(void)
-{
- test_tool_run("gpiofind", "nonexistent", (char *)NULL);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_EQ(test_tool_exit_status(), 1);
- TEST_ASSERT_NULL(test_tool_stdout());
- TEST_ASSERT_NULL(test_tool_stderr());
-}
-TEST_DEFINE(gpiofind_not_found,
- "tools: gpiofind - not found",
- TEST_FLAG_NAMED_LINES, { 4, 8 });
-
-static void gpiofind_invalid_args(void)
-{
- test_tool_run("gpiofind", (char *)NULL);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_EQ(test_tool_exit_status(), 1);
- TEST_ASSERT_NULL(test_tool_stdout());
- TEST_ASSERT_NOT_NULL(test_tool_stderr());
- TEST_ASSERT_STR_CONTAINS(test_tool_stderr(),
- "exactly one GPIO line name must be specified");
-
- test_tool_run("gpiofind", "first argument",
- "second argument", (char *)NULL);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_EQ(test_tool_exit_status(), 1);
- TEST_ASSERT_NULL(test_tool_stdout());
- TEST_ASSERT_NOT_NULL(test_tool_stderr());
- TEST_ASSERT_STR_CONTAINS(test_tool_stderr(),
- "exactly one GPIO line name must be specified");
-}
-TEST_DEFINE(gpiofind_invalid_args,
- "tools: gpiofind - invalid arguments",
- 0, { });
+++ /dev/null
-// SPDX-License-Identifier: LGPL-2.1-or-later
-/*
- * This file is part of libgpiod.
- *
- * Copyright (C) 2017-2018 Bartosz Golaszewski <bartekgola@gmail.com>
- * Copyright (C) 2019 Bartosz Golaszewski <bgolaszewski@baylibre.com>
- */
-
-/* Test cases for the gpioget program. */
-
-#include "gpiod-test.h"
-
-static void gpioget_read_all_lines(void)
-{
- test_debugfs_set_value(1, 2, 1);
- test_debugfs_set_value(1, 3, 1);
- test_debugfs_set_value(1, 5, 1);
- test_debugfs_set_value(1, 7, 1);
-
- test_tool_run("gpioget", test_chip_name(1),
- "0", "1", "2", "3", "4", "5", "6", "7", (char *)NULL);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_RET_OK(test_tool_exit_status());
- TEST_ASSERT_NOT_NULL(test_tool_stdout());
- TEST_ASSERT_NULL(test_tool_stderr());
- TEST_ASSERT_STR_EQ(test_tool_stdout(), "0 0 1 1 0 1 0 1\n");
-}
-TEST_DEFINE(gpioget_read_all_lines,
- "tools: gpioget - read all lines",
- 0, { 8, 8, 8 });
-
-static void gpioget_read_all_lines_active_low(void)
-{
- test_debugfs_set_value(1, 2, 1);
- test_debugfs_set_value(1, 3, 1);
- test_debugfs_set_value(1, 5, 1);
- test_debugfs_set_value(1, 7, 1);
-
- test_tool_run("gpioget", "--active-low", test_chip_name(1),
- "0", "1", "2", "3", "4", "5", "6", "7", (char *)NULL);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_RET_OK(test_tool_exit_status());
- TEST_ASSERT_NOT_NULL(test_tool_stdout());
- TEST_ASSERT_NULL(test_tool_stderr());
- TEST_ASSERT_STR_EQ(test_tool_stdout(), "1 1 0 0 1 0 1 0\n");
-}
-TEST_DEFINE(gpioget_read_all_lines_active_low,
- "tools: gpioget - read all lines (active-low)",
- 0, { 8, 8, 8 });
-
-static void gpioget_read_some_lines(void)
-{
- test_debugfs_set_value(1, 1, 1);
- test_debugfs_set_value(1, 4, 1);
- test_debugfs_set_value(1, 6, 1);
-
- test_tool_run("gpioget", test_chip_name(1),
- "0", "1", "4", "6", (char *)NULL);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_RET_OK(test_tool_exit_status());
- TEST_ASSERT_NOT_NULL(test_tool_stdout());
- TEST_ASSERT_NULL(test_tool_stderr());
- TEST_ASSERT_STR_EQ(test_tool_stdout(), "0 1 1 1\n");
-}
-TEST_DEFINE(gpioget_read_some_lines,
- "tools: gpioget - read some lines",
- 0, { 8, 8, 8 });
-
-static void gpioget_no_arguments(void)
-{
- test_tool_run("gpioget", (char *)NULL);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_EQ(test_tool_exit_status(), 1);
- TEST_ASSERT_NULL(test_tool_stdout());
- TEST_ASSERT_NOT_NULL(test_tool_stderr());
- TEST_ASSERT_STR_CONTAINS(test_tool_stderr(),
- "gpiochip must be specified");
-}
-TEST_DEFINE(gpioget_no_arguments,
- "tools: gpioget - no arguments",
- 0, { });
-
-static void gpioget_no_lines_specified(void)
-{
- test_tool_run("gpioget", test_chip_name(1), (char *)NULL);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_EQ(test_tool_exit_status(), 1);
- TEST_ASSERT_NULL(test_tool_stdout());
- TEST_ASSERT_NOT_NULL(test_tool_stderr());
- TEST_ASSERT_STR_CONTAINS(test_tool_stderr(),
- "at least one GPIO line offset must be specified");
-}
-TEST_DEFINE(gpioget_no_lines_specified,
- "tools: gpioget - no lines specified",
- 0, { 4, 4 });
-
-static void gpioget_too_many_lines_specified(void)
-{
- test_tool_run("gpioget", test_chip_name(0),
- "0", "1", "2", "3", "4", (char *)NULL);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_EQ(test_tool_exit_status(), 1);
- TEST_ASSERT_NULL(test_tool_stdout());
- TEST_ASSERT_NOT_NULL(test_tool_stderr());
- TEST_ASSERT_STR_CONTAINS(test_tool_stderr(),
- "error reading GPIO values");
-}
-TEST_DEFINE(gpioget_too_many_lines_specified,
- "tools: gpioget - too many lines specified",
- 0, { 4 });
+++ /dev/null
-// SPDX-License-Identifier: LGPL-2.1-or-later
-/*
- * This file is part of libgpiod.
- *
- * Copyright (C) 2017-2018 Bartosz Golaszewski <bartekgola@gmail.com>
- */
-
-/* Test cases for the gpioinfo program. */
-
-#include <stdio.h>
-
-#include "gpiod-test.h"
-
-static void gpioinfo_dump_all_chips(void)
-{
- test_tool_run("gpioinfo", (char *)NULL);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_RET_OK(test_tool_exit_status());
- TEST_ASSERT_NOT_NULL(test_tool_stdout());
- TEST_ASSERT_STR_CONTAINS(test_tool_stdout(),
- test_build_str("%s - 4 lines:",
- test_chip_name(0)));
- TEST_ASSERT_STR_CONTAINS(test_tool_stdout(),
- test_build_str("%s - 8 lines:",
- test_chip_name(1)));
- TEST_ASSERT_REGEX_MATCH(test_tool_stdout(),
- "\\s+line\\s+0:\\s+unnamed\\s+unused\\s+input\\s+active-high");
- TEST_ASSERT_REGEX_MATCH(test_tool_stdout(),
- "\\s+line\\s+7:\\s+unnamed\\s+unused\\s+input\\s+active-high");
-}
-TEST_DEFINE(gpioinfo_dump_all_chips,
- "tools: gpioinfo - dump all chips",
- 0, { 4, 8 });
-
-static void gpioinfo_dump_all_chips_one_exported(void)
-{
- TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL;
- struct gpiod_line *line;
- int rv;
-
- chip = gpiod_chip_open(test_chip_path(1));
- TEST_ASSERT_NOT_NULL(chip);
-
- line = gpiod_chip_get_line(chip, 7);
- TEST_ASSERT_NOT_NULL(line);
-
- rv = gpiod_line_request_input_flags(line, TEST_CONSUMER,
- GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW);
- TEST_ASSERT_RET_OK(rv);
-
- test_tool_run("gpioinfo", (char *)NULL);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_RET_OK(test_tool_exit_status());
- TEST_ASSERT_NOT_NULL(test_tool_stdout());
- TEST_ASSERT_STR_CONTAINS(test_tool_stdout(),
- test_build_str("%s - 4 lines:",
- test_chip_name(0)));
- TEST_ASSERT_STR_CONTAINS(test_tool_stdout(),
- test_build_str("%s - 8 lines:",
- test_chip_name(1)));
- TEST_ASSERT_REGEX_MATCH(test_tool_stdout(),
- "\\s+line\\s+0:\\s+unnamed\\s+unused\\s+input\\s+active-high");
- TEST_ASSERT_REGEX_MATCH(test_tool_stdout(),
- "\\s+line\\s+7:\\s+unnamed\\s+\\\"" TEST_CONSUMER "\\\"\\s+input\\s+active-low");
-}
-TEST_DEFINE(gpioinfo_dump_all_chips_one_exported,
- "tools: gpioinfo - dump all chips (one line exported)",
- 0, { 4, 8 });
-
-static void gpioinfo_dump_one_chip(void)
-{
- test_tool_run("gpioinfo", test_chip_name(1), (char *)NULL);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_RET_OK(test_tool_exit_status());
- TEST_ASSERT_NOT_NULL(test_tool_stdout());
- TEST_ASSERT_STR_NOTCONT(test_tool_stdout(),
- test_build_str("%s - 8 lines:",
- test_chip_name(0)));
- TEST_ASSERT_STR_CONTAINS(test_tool_stdout(),
- test_build_str("%s - 4 lines:",
- test_chip_name(1)));
- TEST_ASSERT_REGEX_MATCH(test_tool_stdout(),
- "\\s+line\\s+0:\\s+unnamed\\s+unused\\s+input\\s+active-high");
- TEST_ASSERT_REGEX_NOMATCH(test_tool_stdout(),
- "\\s+line\\s+7:\\s+unnamed\\s+unused\\s+input\\s+active-high");
-}
-TEST_DEFINE(gpioinfo_dump_one_chip,
- "tools: gpioinfo - dump one chip",
- 0, { 8, 4 });
-
-static void gpioinfo_dump_all_but_one_chip(void)
-{
- test_tool_run("gpioinfo", test_chip_name(0),
- test_chip_name(1), test_chip_name(3), (char *)NULL);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_RET_OK(test_tool_exit_status());
- TEST_ASSERT_NOT_NULL(test_tool_stdout());
- TEST_ASSERT_STR_NOTCONT(test_tool_stdout(),
- test_build_str("%s - 8 lines:",
- test_chip_name(2)));
- TEST_ASSERT_STR_CONTAINS(test_tool_stdout(),
- test_build_str("%s - 4 lines:",
- test_chip_name(0)));
- TEST_ASSERT_STR_CONTAINS(test_tool_stdout(),
- test_build_str("%s - 4 lines:",
- test_chip_name(1)));
- TEST_ASSERT_STR_CONTAINS(test_tool_stdout(),
- test_build_str("%s - 4 lines:",
- test_chip_name(3)));
- TEST_ASSERT_REGEX_MATCH(test_tool_stdout(),
- "\\s+line\\s+0:\\s+unnamed\\s+unused\\s+input\\s+active-high");
- TEST_ASSERT_REGEX_NOMATCH(test_tool_stdout(),
- "\\s+line\\s+7:\\s+unnamed\\s+unused\\s+input\\s+active-high");
-}
-TEST_DEFINE(gpioinfo_dump_all_but_one_chip,
- "tools: gpioinfo - dump all but one chip",
- 0, { 4, 4, 8, 4 });
-
-static void gpioinfo_inexistent_chip(void)
-{
- test_tool_run("gpioinfo", "inexistent", (char *)NULL);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_EQ(test_tool_exit_status(), 1);
- TEST_ASSERT_NULL(test_tool_stdout());
- TEST_ASSERT_NOT_NULL(test_tool_stderr());
- TEST_ASSERT_STR_CONTAINS(test_tool_stderr(),
- "looking up chip inexistent");
-}
-TEST_DEFINE(gpioinfo_inexistent_chip,
- "tools: gpioinfo - inexistent chip",
- 0, { 8, 4 });
+++ /dev/null
-// SPDX-License-Identifier: LGPL-2.1-or-later
-/*
- * This file is part of libgpiod.
- *
- * Copyright (C) 2017-2018 Bartosz Golaszewski <bartekgola@gmail.com>
- * Copyright (C) 2019 Bartosz Golaszewski <bgolaszewski@baylibre.com>
- */
-
-/* Test cases for the gpiomon program. */
-
-#include <signal.h>
-#include <unistd.h>
-
-#include "gpiod-test.h"
-
-static void gpiomon_single_rising_edge_event(void)
-{
- test_tool_run("gpiomon", "--rising-edge", "--num-events=1",
- test_chip_name(1), "4", (char *)NULL);
- test_set_event(1, 4, 200);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_RET_OK(test_tool_exit_status());
- TEST_ASSERT_NOT_NULL(test_tool_stdout());
- TEST_ASSERT_NULL(test_tool_stderr());
- TEST_ASSERT_REGEX_MATCH(test_tool_stdout(),
- "event\\:\\s+RISING\\s+EDGE\\s+offset\\:\\s+4\\s+timestamp:\\s+\\[[0-9]+\\.[0-9]+\\]");
-}
-TEST_DEFINE(gpiomon_single_rising_edge_event,
- "tools: gpiomon - single rising edge event",
- 0, { 8, 8 });
-
-static void gpiomon_single_rising_edge_event_active_low(void)
-{
- test_tool_run("gpiomon", "--rising-edge", "--num-events=1",
- "--active-low", test_chip_name(1), "4", (char *)NULL);
- test_set_event(1, 4, 200);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_RET_OK(test_tool_exit_status());
- TEST_ASSERT_NOT_NULL(test_tool_stdout());
- TEST_ASSERT_NULL(test_tool_stderr());
- TEST_ASSERT_REGEX_MATCH(test_tool_stdout(),
- "event\\:\\s+RISING\\s+EDGE\\s+offset\\:\\s+4\\s+timestamp:\\s+\\[[0-9]+\\.[0-9]+\\]");
-}
-TEST_DEFINE(gpiomon_single_rising_edge_event_active_low,
- "tools: gpiomon - single rising edge event (active-low)",
- 0, { 8, 8 });
-
-static void gpiomon_single_rising_edge_event_silent(void)
-{
- test_tool_run("gpiomon", "--rising-edge", "--num-events=1",
- "--silent", test_chip_name(1), "4", (char *)NULL);
- test_set_event(1, 4, 200);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_RET_OK(test_tool_exit_status());
- TEST_ASSERT_NULL(test_tool_stdout());
- TEST_ASSERT_NULL(test_tool_stderr());
-}
-TEST_DEFINE(gpiomon_single_rising_edge_event_silent,
- "tools: gpiomon - single rising edge event (silent mode)",
- 0, { 8, 8 });
-
-static void gpiomon_four_alternating_events(void)
-{
- test_tool_run("gpiomon", "--num-events=4",
- test_chip_name(1), "4", (char *)NULL);
- test_set_event(1, 4, 100);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_RET_OK(test_tool_exit_status());
- TEST_ASSERT_NOT_NULL(test_tool_stdout());
- TEST_ASSERT_NULL(test_tool_stderr());
- TEST_ASSERT_REGEX_MATCH(test_tool_stdout(),
- "event\\:\\s+FALLING\\s+EDGE\\s+offset\\:\\s+4\\s+timestamp:\\s+\\[[0-9]+\\.[0-9]+\\]");
- TEST_ASSERT_REGEX_MATCH(test_tool_stdout(),
- "event\\:\\s+RISING\\s+EDGE\\s+offset\\:\\s+4\\s+timestamp:\\s+\\[[0-9]+\\.[0-9]+\\]");
-}
-TEST_DEFINE(gpiomon_four_alternating_events,
- "tools: gpiomon - four alternating events",
- 0, { 8, 8 });
-
-static void gpiomon_falling_edge_events_sigint(void)
-{
- test_tool_run("gpiomon", "--falling-edge",
- test_chip_name(0), "4", (char *)NULL);
- test_set_event(0, 4, 100);
- usleep(400000);
- test_tool_signal(SIGINT);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_RET_OK(test_tool_exit_status());
- TEST_ASSERT_NOT_NULL(test_tool_stdout());
- TEST_ASSERT_NULL(test_tool_stderr());
- TEST_ASSERT_REGEX_MATCH(test_tool_stdout(),
- "event\\:\\s+FALLING\\s+EDGE\\s+offset\\:\\s+4\\s+timestamp:\\s+\\[[0-9]+\\.[0-9]+\\]");
-}
-TEST_DEFINE(gpiomon_falling_edge_events_sigint,
- "tools: gpiomon - receive falling edge events and kill with SIGINT",
- 0, { 8, 8 });
-
-static void gpiomon_both_events_sigterm(void)
-{
- test_tool_run("gpiomon", "--falling-edge", "--rising-edge",
- test_chip_name(0), "4", (char *)NULL);
- test_set_event(0, 4, 100);
- usleep(400000);
- test_tool_signal(SIGTERM);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_RET_OK(test_tool_exit_status());
- TEST_ASSERT_NOT_NULL(test_tool_stdout());
- TEST_ASSERT_NULL(test_tool_stderr());
- TEST_ASSERT_REGEX_MATCH(test_tool_stdout(),
- "event\\:\\s+FALLING\\s+EDGE\\s+offset\\:\\s+4\\s+timestamp:\\s+\\[[0-9]+\\.[0-9]+\\]");
- TEST_ASSERT_REGEX_MATCH(test_tool_stdout(),
- "event\\:\\s+RISING\\s+EDGE\\s+offset\\:\\s+4\\s+timestamp:\\s+\\[[0-9]+\\.[0-9]+\\]");
-}
-TEST_DEFINE(gpiomon_both_events_sigterm,
- "tools: gpiomon - receive both types of events and kill with SIGTERM",
- 0, { 8, 8 });
-
-static void gpiomon_watch_multiple_lines(void)
-{
- test_tool_run("gpiomon", "--format=%o", test_chip_name(0),
- "1", "2", "3", "4", "5", (char *)NULL);
- usleep(100000);
- test_trigger_event(0, 2);
- usleep(100000);
- test_trigger_event(0, 3);
- usleep(100000);
- test_trigger_event(0, 4);
- usleep(100000);
- test_tool_signal(SIGTERM);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_RET_OK(test_tool_exit_status());
- TEST_ASSERT_NULL(test_tool_stderr());
- TEST_ASSERT_NOT_NULL(test_tool_stdout());
- TEST_ASSERT_STR_EQ(test_tool_stdout(), "2\n3\n4\n");
-
-}
-TEST_DEFINE(gpiomon_watch_multiple_lines,
- "tools: gpiomon - watch multiple lines",
- 0, { 8, 8 });
-
-static void gpiomon_watch_multiple_lines_not_in_order(void)
-{
- test_tool_run("gpiomon", "--format=%o", test_chip_name(0),
- "5", "2", "7", "1", "6", (char *)NULL);
- usleep(100000);
- test_trigger_event(0, 2);
- usleep(100000);
- test_trigger_event(0, 1);
- usleep(100000);
- test_trigger_event(0, 6);
- usleep(100000);
- test_tool_signal(SIGTERM);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_RET_OK(test_tool_exit_status());
- TEST_ASSERT_NULL(test_tool_stderr());
- TEST_ASSERT_NOT_NULL(test_tool_stdout());
- TEST_ASSERT_STR_EQ(test_tool_stdout(), "2\n1\n6\n");
-
-}
-TEST_DEFINE(gpiomon_watch_multiple_lines_not_in_order,
- "tools: gpiomon - watch multiple lines (offsets not in order)",
- 0, { 8, 8 });
-
-static void gpiomon_request_the_same_line_twice(void)
-{
- test_tool_run("gpiomon", test_chip_name(0), "2", "2", (char *)NULL);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_EQ(test_tool_exit_status(), 1);
- TEST_ASSERT_NULL(test_tool_stdout());
- TEST_ASSERT_NOT_NULL(test_tool_stderr());
- TEST_ASSERT_STR_CONTAINS(test_tool_stderr(),
- "error waiting for events");
-}
-TEST_DEFINE(gpiomon_request_the_same_line_twice,
- "tools: gpiomon - request the same line twice",
- 0, { 8, 8 });
-
-static void gpiomon_no_arguments(void)
-{
- test_tool_run("gpiomon", (char *)NULL);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_EQ(test_tool_exit_status(), 1);
- TEST_ASSERT_NULL(test_tool_stdout());
- TEST_ASSERT_NOT_NULL(test_tool_stderr());
- TEST_ASSERT_STR_CONTAINS(test_tool_stderr(),
- "gpiochip must be specified");
-}
-TEST_DEFINE(gpiomon_no_arguments,
- "tools: gpiomon - no arguments",
- 0, { });
-
-static void gpiomon_line_not_specified(void)
-{
- test_tool_run("gpiomon", test_chip_name(1), (char *)NULL);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_EQ(test_tool_exit_status(), 1);
- TEST_ASSERT_NULL(test_tool_stdout());
- TEST_ASSERT_NOT_NULL(test_tool_stderr());
- TEST_ASSERT_STR_CONTAINS(test_tool_stderr(),
- "GPIO line offset must be specified");
-}
-TEST_DEFINE(gpiomon_line_not_specified,
- "tools: gpiomon - line not specified",
- 0, { 4, 4 });
-
-static void gpiomon_line_out_of_range(void)
-{
- test_tool_run("gpiomon", test_chip_name(0), "4", (char *)NULL);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_EQ(test_tool_exit_status(), 1);
- TEST_ASSERT_NULL(test_tool_stdout());
- TEST_ASSERT_NOT_NULL(test_tool_stderr());
- TEST_ASSERT_STR_CONTAINS(test_tool_stderr(),
- "error waiting for events");
-}
-TEST_DEFINE(gpiomon_line_out_of_range,
- "tools: gpiomon - line out of range",
- 0, { 4 });
-
-static void gpiomon_custom_format_event_and_offset(void)
-{
- test_tool_run("gpiomon", "--num-events=1", "--format=%e %o",
- test_chip_name(0), "3", (char *)NULL);
- test_set_event(0, 3, 100);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_RET_OK(test_tool_exit_status());
- TEST_ASSERT_NOT_NULL(test_tool_stdout());
- TEST_ASSERT_NULL(test_tool_stderr());
- TEST_ASSERT_STR_EQ(test_tool_stdout(), "1 3\n");
-}
-TEST_DEFINE(gpiomon_custom_format_event_and_offset,
- "tools: gpiomon - custom output format: event and offset",
- 0, { 8, 8 });
-
-static void gpiomon_custom_format_event_and_offset_joined(void)
-{
- test_tool_run("gpiomon", "--num-events=1", "--format=%e%o",
- test_chip_name(0), "3", (char *)NULL);
- test_set_event(0, 3, 100);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_RET_OK(test_tool_exit_status());
- TEST_ASSERT_NOT_NULL(test_tool_stdout());
- TEST_ASSERT_NULL(test_tool_stderr());
- TEST_ASSERT_STR_EQ(test_tool_stdout(), "13\n");
-}
-TEST_DEFINE(gpiomon_custom_format_event_and_offset_joined,
- "tools: gpiomon - custom output format: event and offset, joined strings",
- 0, { 8, 8 });
-
-static void gpiomon_custom_format_timestamp(void)
-{
- test_tool_run("gpiomon", "--num-events=1", "--format=%e %o %s.%n",
- test_chip_name(0), "3", (char *)NULL);
- test_set_event(0, 3, 100);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_RET_OK(test_tool_exit_status());
- TEST_ASSERT_NOT_NULL(test_tool_stdout());
- TEST_ASSERT_NULL(test_tool_stderr());
- TEST_ASSERT_REGEX_MATCH(test_tool_stdout(), "1 3 [0-9]+\\.[0-9]+");
-}
-TEST_DEFINE(gpiomon_custom_format_timestamp,
- "tools: gpiomon - custom output format: timestamp",
- 0, { 8, 8 });
-
-static void gpiomon_custom_format_double_percent_sign(void)
-{
- test_tool_run("gpiomon", "--num-events=1", "--format=%%",
- test_chip_name(0), "3", (char *)NULL);
- test_set_event(0, 3, 100);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_RET_OK(test_tool_exit_status());
- TEST_ASSERT_NOT_NULL(test_tool_stdout());
- TEST_ASSERT_NULL(test_tool_stderr());
- TEST_ASSERT_STR_EQ(test_tool_stdout(), "%\n");
-}
-TEST_DEFINE(gpiomon_custom_format_double_percent_sign,
- "tools: gpiomon - custom output format: double percent sign",
- 0, { 8, 8 });
-
-static void gpiomon_custom_format_double_percent_sign_and_spec(void)
-{
- test_tool_run("gpiomon", "--num-events=1", "--format=%%e",
- test_chip_name(0), "3", (char *)NULL);
- test_set_event(0, 3, 100);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_RET_OK(test_tool_exit_status());
- TEST_ASSERT_NOT_NULL(test_tool_stdout());
- TEST_ASSERT_NULL(test_tool_stderr());
- TEST_ASSERT_STR_EQ(test_tool_stdout(), "%e\n");
-}
-TEST_DEFINE(gpiomon_custom_format_double_percent_sign_and_spec,
- "tools: gpiomon - custom output format: double percent sign with specifier",
- 0, { 8, 8 });
-
-static void gpiomon_custom_format_single_percent_sign(void)
-{
- test_tool_run("gpiomon", "--num-events=1", "--format=%",
- test_chip_name(0), "3", (char *)NULL);
- test_set_event(0, 3, 100);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_RET_OK(test_tool_exit_status());
- TEST_ASSERT_NOT_NULL(test_tool_stdout());
- TEST_ASSERT_NULL(test_tool_stderr());
- TEST_ASSERT_STR_EQ(test_tool_stdout(), "%\n");
-}
-TEST_DEFINE(gpiomon_custom_format_single_percent_sign,
- "tools: gpiomon - custom output format: single percent sign",
- 0, { 8, 8 });
-
-static void gpiomon_custom_format_single_percent_sign_between_chars(void)
-{
- test_tool_run("gpiomon", "--num-events=1", "--format=foo % bar",
- test_chip_name(0), "3", (char *)NULL);
- test_set_event(0, 3, 100);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_RET_OK(test_tool_exit_status());
- TEST_ASSERT_NOT_NULL(test_tool_stdout());
- TEST_ASSERT_NULL(test_tool_stderr());
- TEST_ASSERT_STR_EQ(test_tool_stdout(), "foo % bar\n");
-}
-TEST_DEFINE(gpiomon_custom_format_single_percent_sign_between_chars,
- "tools: gpiomon - custom output format: single percent sign between other characters",
- 0, { 8, 8 });
-
-static void gpiomon_custom_format_unknown_specifier(void)
-{
- test_tool_run("gpiomon", "--num-events=1", "--format=%x",
- test_chip_name(0), "3", (char *)NULL);
- test_set_event(0, 3, 100);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_RET_OK(test_tool_exit_status());
- TEST_ASSERT_NOT_NULL(test_tool_stdout());
- TEST_ASSERT_NULL(test_tool_stderr());
- TEST_ASSERT_STR_EQ(test_tool_stdout(), "%x\n");
-}
-TEST_DEFINE(gpiomon_custom_format_unknown_specifier,
- "tools: gpiomon - custom output format: unknown specifier",
- 0, { 8, 8 });
+++ /dev/null
-// SPDX-License-Identifier: LGPL-2.1-or-later
-/*
- * This file is part of libgpiod.
- *
- * Copyright (C) 2017-2018 Bartosz Golaszewski <bartekgola@gmail.com>
- * Copyright (C) 2019 Bartosz Golaszewski <bgolaszewski@baylibre.com>
- */
-
-/* Test cases for the gpioset program. */
-
-#include <signal.h>
-#include <unistd.h>
-
-#include "gpiod-test.h"
-
-static void gpioset_set_lines_and_exit(void)
-{
- test_tool_run("gpioset",
- "--mode=signal", test_chip_name(2),
- "0=0", "1=0", "2=1", "3=1",
- "4=1", "5=1", "6=0", "7=1", (char *)NULL);
- usleep(200000);
-
- TEST_ASSERT_EQ(test_debugfs_get_value(2, 0), 0);
- TEST_ASSERT_EQ(test_debugfs_get_value(2, 1), 0);
- TEST_ASSERT_EQ(test_debugfs_get_value(2, 2), 1);
- TEST_ASSERT_EQ(test_debugfs_get_value(2, 3), 1);
- TEST_ASSERT_EQ(test_debugfs_get_value(2, 4), 1);
- TEST_ASSERT_EQ(test_debugfs_get_value(2, 5), 1);
- TEST_ASSERT_EQ(test_debugfs_get_value(2, 6), 0);
- TEST_ASSERT_EQ(test_debugfs_get_value(2, 7), 1);
-
- test_tool_signal(SIGTERM);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_RET_OK(test_tool_exit_status());
- TEST_ASSERT_NULL(test_tool_stdout());
- TEST_ASSERT_NULL(test_tool_stderr());
-}
-TEST_DEFINE(gpioset_set_lines_and_exit,
- "tools: gpioset - set lines and exit",
- 0, { 8, 8, 8 });
-
-static void gpioset_set_lines_and_exit_active_low(void)
-{
- test_tool_run("gpioset",
- "--mode=signal", "--active-low", test_chip_name(2),
- "0=0", "1=0", "2=1", "3=1",
- "4=1", "5=1", "6=0", "7=1", (char *)NULL);
- usleep(200000);
-
- TEST_ASSERT_EQ(test_debugfs_get_value(2, 0), 1);
- TEST_ASSERT_EQ(test_debugfs_get_value(2, 1), 1);
- TEST_ASSERT_EQ(test_debugfs_get_value(2, 2), 0);
- TEST_ASSERT_EQ(test_debugfs_get_value(2, 3), 0);
- TEST_ASSERT_EQ(test_debugfs_get_value(2, 4), 0);
- TEST_ASSERT_EQ(test_debugfs_get_value(2, 5), 0);
- TEST_ASSERT_EQ(test_debugfs_get_value(2, 6), 1);
- TEST_ASSERT_EQ(test_debugfs_get_value(2, 7), 0);
-
- test_tool_signal(SIGTERM);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_RET_OK(test_tool_exit_status());
- TEST_ASSERT_NULL(test_tool_stdout());
- TEST_ASSERT_NULL(test_tool_stderr());
-}
-TEST_DEFINE(gpioset_set_lines_and_exit_active_low,
- "tools: gpioset - set lines and exit (active-low)",
- 0, { 8, 8, 8 });
-
-static void gpioset_set_some_lines_and_wait_for_enter(void)
-{
- test_tool_run("gpioset", "--mode=wait", test_chip_name(2),
- "1=0", "2=1", "5=1", "6=0", "7=1", (char *)NULL);
- usleep(200000);
-
- TEST_ASSERT_EQ(test_debugfs_get_value(2, 1), 0);
- TEST_ASSERT_EQ(test_debugfs_get_value(2, 2), 1);
- TEST_ASSERT_EQ(test_debugfs_get_value(2, 5), 1);
- TEST_ASSERT_EQ(test_debugfs_get_value(2, 6), 0);
- TEST_ASSERT_EQ(test_debugfs_get_value(2, 7), 1);
-
- test_tool_stdin_write("\n");
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_RET_OK(test_tool_exit_status());
- TEST_ASSERT_NULL(test_tool_stdout());
- TEST_ASSERT_NULL(test_tool_stderr());
-}
-TEST_DEFINE(gpioset_set_some_lines_and_wait_for_enter,
- "tools: gpioset - set some lines and wait for enter",
- 0, { 8, 8, 8 });
-
-static void gpioset_set_some_lines_and_wait_for_signal(void)
-{
- static const int signals[] = { SIGTERM, SIGINT };
-
- unsigned int i;
-
- for (i = 0; i < TEST_ARRAY_SIZE(signals); i++) {
- test_tool_run("gpioset", "--mode=signal", test_chip_name(2),
- "1=0", "2=1", "5=0", "6=0", "7=1", (char *)NULL);
- usleep(200000);
-
- TEST_ASSERT_EQ(test_debugfs_get_value(2, 1), 0);
- TEST_ASSERT_EQ(test_debugfs_get_value(2, 2), 1);
- TEST_ASSERT_EQ(test_debugfs_get_value(2, 5), 0);
- TEST_ASSERT_EQ(test_debugfs_get_value(2, 6), 0);
- TEST_ASSERT_EQ(test_debugfs_get_value(2, 7), 1);
-
- test_tool_signal(signals[i]);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_RET_OK(test_tool_exit_status());
- TEST_ASSERT_NULL(test_tool_stdout());
- TEST_ASSERT_NULL(test_tool_stderr());
- }
-}
-TEST_DEFINE(gpioset_set_some_lines_and_wait_for_signal,
- "tools: gpioset - set some lines and wait for signal",
- 0, { 8, 8, 8 });
-
-static void gpioset_set_some_lines_and_wait_time(void)
-{
- test_tool_run("gpioset", "--mode=time",
- "--usec=600000", "--sec=0", test_chip_name(0),
- "1=1", "2=0", "5=1", (char *)NULL);
- usleep(200000);
-
- TEST_ASSERT_EQ(test_debugfs_get_value(0, 1), 1);
- TEST_ASSERT_EQ(test_debugfs_get_value(0, 2), 0);
- TEST_ASSERT_EQ(test_debugfs_get_value(0, 5), 1);
-
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_RET_OK(test_tool_exit_status());
- TEST_ASSERT_NULL(test_tool_stdout());
- TEST_ASSERT_NULL(test_tool_stderr());
-}
-TEST_DEFINE(gpioset_set_some_lines_and_wait_time,
- "tools: gpioset - set some lines and wait for specified time",
- 0, { 8, 8, 8 });
-
-static void gpioset_no_arguments(void)
-{
- test_tool_run("gpioset", (char *)NULL);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_EQ(test_tool_exit_status(), 1);
- TEST_ASSERT_NULL(test_tool_stdout());
- TEST_ASSERT_NOT_NULL(test_tool_stderr());
- TEST_ASSERT_STR_CONTAINS(test_tool_stderr(),
- "gpiochip must be specified");
-}
-TEST_DEFINE(gpioset_no_arguments,
- "tools: gpioset - no arguments",
- 0, { });
-
-static void gpioset_no_lines_specified(void)
-{
- test_tool_run("gpioset", test_chip_name(1), (char *)NULL);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_EQ(test_tool_exit_status(), 1);
- TEST_ASSERT_NULL(test_tool_stdout());
- TEST_ASSERT_NOT_NULL(test_tool_stderr());
- TEST_ASSERT_STR_CONTAINS(test_tool_stderr(),
- "at least one GPIO line offset to value mapping must be specified");
-}
-TEST_DEFINE(gpioset_no_lines_specified,
- "tools: gpioset - no lines specified",
- 0, { 4, 4 });
-
-static void gpioset_too_many_lines_specified(void)
-{
- test_tool_run("gpioset", test_chip_name(0),
- "0=1", "1=1", "2=1", "3=1", "4=1", (char *)NULL);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_EQ(test_tool_exit_status(), 1);
- TEST_ASSERT_NULL(test_tool_stdout());
- TEST_ASSERT_NOT_NULL(test_tool_stderr());
- TEST_ASSERT_STR_CONTAINS(test_tool_stderr(),
- "error setting the GPIO line values");
-}
-TEST_DEFINE(gpioset_too_many_lines_specified,
- "tools: gpioset - too many lines specified",
- 0, { 4 });
-
-static void gpioset_sec_usec_without_time(void)
-{
- test_tool_run("gpioset", "--mode=exit", "--sec=1",
- test_chip_name(0), "0=1", (char *)NULL);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_EQ(test_tool_exit_status(), 1);
- TEST_ASSERT_NULL(test_tool_stdout());
- TEST_ASSERT_NOT_NULL(test_tool_stderr());
- TEST_ASSERT_STR_CONTAINS(test_tool_stderr(),
- "can't specify wait time in this mode");
-
- test_tool_run("gpioset", "--mode=exit", "--usec=100",
- test_chip_name(0), "0=1", (char *)NULL);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_EQ(test_tool_exit_status(), 1);
- TEST_ASSERT_NULL(test_tool_stdout());
- TEST_ASSERT_NOT_NULL(test_tool_stderr());
- TEST_ASSERT_STR_CONTAINS(test_tool_stderr(),
- "can't specify wait time in this mode");
-}
-TEST_DEFINE(gpioset_sec_usec_without_time,
- "tools: gpioset - using --sec/--usec with mode other than 'time'",
- 0, { 4 });
-
-static void gpioset_invalid_mapping(void)
-{
- test_tool_run("gpioset", test_chip_name(0), "0=c", (char *)NULL);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_EQ(test_tool_exit_status(), 1);
- TEST_ASSERT_NULL(test_tool_stdout());
- TEST_ASSERT_NOT_NULL(test_tool_stderr());
- TEST_ASSERT_STR_CONTAINS(test_tool_stderr(),
- "invalid offset<->value mapping");
-}
-TEST_DEFINE(gpioset_invalid_mapping,
- "tools: gpioset - invalid offset<->value mapping",
- 0, { 4 });
-
-static void gpioset_invalid_value(void)
-{
- test_tool_run("gpioset", test_chip_name(0), "0=3", (char *)NULL);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_EQ(test_tool_exit_status(), 1);
- TEST_ASSERT_NULL(test_tool_stdout());
- TEST_ASSERT_NOT_NULL(test_tool_stderr());
- TEST_ASSERT_STR_CONTAINS(test_tool_stderr(), "value must be 0 or 1");
-}
-TEST_DEFINE(gpioset_invalid_value,
- "tools: gpioset - value different than 0 or 1",
- 0, { 4 });
-
-static void gpioset_invalid_offset(void)
-{
- test_tool_run("gpioset", test_chip_name(0),
- "4000000000=1", (char *)NULL);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_EQ(test_tool_exit_status(), 1);
- TEST_ASSERT_NULL(test_tool_stdout());
- TEST_ASSERT_NOT_NULL(test_tool_stderr());
- TEST_ASSERT_STR_CONTAINS(test_tool_stderr(), "invalid offset");
-}
-TEST_DEFINE(gpioset_invalid_offset,
- "tools: gpioset - invalid offset",
- 0, { 4 });
-
-static void gpioset_daemonize_in_wrong_mode(void)
-{
- test_tool_run("gpioset", "--background",
- test_chip_name(0), "0=1", (char *)NULL);
- test_tool_wait();
-
- TEST_ASSERT(test_tool_exited());
- TEST_ASSERT_EQ(test_tool_exit_status(), 1);
- TEST_ASSERT_NULL(test_tool_stdout());
- TEST_ASSERT_NOT_NULL(test_tool_stderr());
- TEST_ASSERT_STR_CONTAINS(test_tool_stderr(),
- "can't daemonize in this mode");
-}
-TEST_DEFINE(gpioset_daemonize_in_wrong_mode,
- "tools: gpioset - daemonize in wrong mode",
- 0, { 4 });
/*
* This file is part of libgpiod.
*
- * Copyright (C) 2017-2018 Bartosz Golaszewski <bartekgola@gmail.com>
+ * Copyright (C) 2019 Bartosz Golaszewski <bgolaszewski@baylibre.com>
*/
-/* Iterator test cases. */
+#include <string.h>
#include "gpiod-test.h"
-static void chip_iter(void)
+#define GPIOD_TEST_GROUP "iter"
+
+GPIOD_TEST_CASE(chip_iter, 0, { 8, 8, 8 })
{
- TEST_CLEANUP(test_free_chip_iter) struct gpiod_chip_iter *iter = NULL;
+ g_autoptr(gpiod_chip_iter_struct) iter = NULL;
struct gpiod_chip *chip;
- bool A, B, C;
+ gboolean A, B, C;
- A = B = C = false;
+ A = B = C = FALSE;
iter = gpiod_chip_iter_new();
- TEST_ASSERT_NOT_NULL(iter);
+ g_assert_nonnull(iter);
+ gpiod_test_return_if_failed();
gpiod_foreach_chip(iter, chip) {
if (strcmp(gpiod_chip_label(chip), "gpio-mockup-A") == 0)
- A = true;
+ A = TRUE;
else if (strcmp(gpiod_chip_label(chip), "gpio-mockup-B") == 0)
- B = true;
+ B = TRUE;
else if (strcmp(gpiod_chip_label(chip), "gpio-mockup-C") == 0)
- C = true;
+ C = TRUE;
}
- TEST_ASSERT(A);
- TEST_ASSERT(B);
- TEST_ASSERT(C);
+ g_assert_true(A);
+ g_assert_true(B);
+ g_assert_true(C);
}
-TEST_DEFINE(chip_iter,
- "gpiod_chip_iter - simple loop",
- 0, { 8, 8, 8 });
-static void chip_iter_noclose(void)
+GPIOD_TEST_CASE(chip_iter_no_close, 0, { 8, 8, 8 })
{
- TEST_CLEANUP(test_free_chip_iter_noclose)
- struct gpiod_chip_iter *iter = NULL;
- TEST_CLEANUP_CHIP struct gpiod_chip *chipA = NULL;
- TEST_CLEANUP_CHIP struct gpiod_chip *chipB = NULL;
- TEST_CLEANUP_CHIP struct gpiod_chip *chipC = NULL;
+ g_autoptr(gpiod_chip_iter_struct) iter = NULL;
+ g_autoptr(gpiod_chip_struct) chipA = NULL;
+ g_autoptr(gpiod_chip_struct) chipB = NULL;
+ g_autoptr(gpiod_chip_struct) chipC = NULL;
struct gpiod_chip *chip;
- bool A, B, C;
-
- A = B = C = false;
iter = gpiod_chip_iter_new();
- TEST_ASSERT_NOT_NULL(iter);
+ g_assert_nonnull(iter);
+ gpiod_test_return_if_failed();
gpiod_foreach_chip_noclose(iter, chip) {
- if (strcmp(gpiod_chip_label(chip), "gpio-mockup-A") == 0) {
- A = true;
+ if (strcmp(gpiod_chip_label(chip), "gpio-mockup-A") == 0)
chipA = chip;
- } else if (strcmp(gpiod_chip_label(chip),
- "gpio-mockup-B") == 0) {
- B = true;
+ else if (strcmp(gpiod_chip_label(chip), "gpio-mockup-B") == 0)
chipB = chip;
- } else if (strcmp(gpiod_chip_label(chip),
- "gpio-mockup-C") == 0) {
- C = true;
+ else if (strcmp(gpiod_chip_label(chip), "gpio-mockup-C") == 0)
chipC = chip;
- } else {
+ else
gpiod_chip_close(chip);
- }
}
- TEST_ASSERT(A);
- TEST_ASSERT(B);
- TEST_ASSERT(C);
+ g_assert_nonnull(chipA);
+ g_assert_nonnull(chipB);
+ g_assert_nonnull(chipC);
gpiod_chip_iter_free_noclose(iter);
iter = NULL;
/* See if the chips are still open and usable. */
- TEST_ASSERT_STR_EQ(gpiod_chip_label(chipA), "gpio-mockup-A");
- TEST_ASSERT_STR_EQ(gpiod_chip_label(chipB), "gpio-mockup-B");
- TEST_ASSERT_STR_EQ(gpiod_chip_label(chipC), "gpio-mockup-C");
+ g_assert_cmpstr(gpiod_chip_label(chipA), ==, "gpio-mockup-A");
+ g_assert_cmpstr(gpiod_chip_label(chipB), ==, "gpio-mockup-B");
+ g_assert_cmpstr(gpiod_chip_label(chipC), ==, "gpio-mockup-C");
}
-TEST_DEFINE(chip_iter_noclose,
- "gpiod_chip_iter - simple loop, noclose variant",
- 0, { 8, 8, 8 });
-static void chip_iter_break(void)
+GPIOD_TEST_CASE(chip_iter_break, 0, { 8, 8, 8, 8, 8 })
{
- TEST_CLEANUP(test_free_chip_iter) struct gpiod_chip_iter *iter = NULL;
+ g_autoptr(gpiod_chip_iter_struct) iter = NULL;
struct gpiod_chip *chip;
- int i = 0;
+ guint i = 0;
iter = gpiod_chip_iter_new();
- TEST_ASSERT_NOT_NULL(iter);
+ g_assert_nonnull(iter);
+ gpiod_test_return_if_failed();
gpiod_foreach_chip(iter, chip) {
if ((strcmp(gpiod_chip_label(chip), "gpio-mockup-A") == 0) ||
gpiod_chip_iter_free(iter);
iter = NULL;
- TEST_ASSERT_EQ(i, 3);
+ g_assert_cmpuint(i, ==, 3);
}
-TEST_DEFINE(chip_iter_break,
- "gpiod_chip_iter - break",
- 0, { 8, 8, 8, 8, 8 });
-static void line_iter(void)
+GPIOD_TEST_CASE(line_iter, 0, { 8 })
{
- TEST_CLEANUP(test_free_line_iter) struct gpiod_line_iter *iter = NULL;
- TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL;
+ g_autoptr(gpiod_line_iter_struct) iter = NULL;
+ g_autoptr(gpiod_chip_struct) chip = NULL;
struct gpiod_line *line;
- unsigned int i = 0;
+ guint i = 0;
- chip = gpiod_chip_open(test_chip_path(0));
- TEST_ASSERT_NOT_NULL(chip);
+ chip = gpiod_chip_open(gpiod_test_chip_path(0));
+ g_assert_nonnull(chip);
+ gpiod_test_return_if_failed();
iter = gpiod_line_iter_new(chip);
- TEST_ASSERT_NOT_NULL(iter);
+ g_assert_nonnull(iter);
+ gpiod_test_return_if_failed();
gpiod_foreach_line(iter, line) {
- TEST_ASSERT_EQ(i, gpiod_line_offset(line));
+ g_assert_cmpuint(i, ==, gpiod_line_offset(line));
i++;
}
- TEST_ASSERT_EQ(8, i);
+ g_assert_cmpuint(i, ==, 8);
}
-TEST_DEFINE(line_iter,
- "gpiod_line_iter - simple loop, check offsets",
- 0, { 8 });
/*
* This file is part of libgpiod.
*
- * Copyright (C) 2017-2018 Bartosz Golaszewski <bartekgola@gmail.com>
* Copyright (C) 2019 Bartosz Golaszewski <bgolaszewski@baylibre.com>
*/
-/* GPIO line test cases. */
-
#include <errno.h>
+#include <string.h>
#include "gpiod-test.h"
-static void line_request_output(void)
+#define GPIOD_TEST_GROUP "line"
+
+GPIOD_TEST_CASE(request_output, 0, { 8 })
{
- TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL;
- struct gpiod_line *line_0;
- struct gpiod_line *line_1;
- int rv;
-
- chip = gpiod_chip_open(test_chip_path(0));
- TEST_ASSERT_NOT_NULL(chip);
-
- line_0 = gpiod_chip_get_line(chip, 2);
- line_1 = gpiod_chip_get_line(chip, 5);
- TEST_ASSERT_NOT_NULL(line_0);
- TEST_ASSERT_NOT_NULL(line_1);
-
- rv = gpiod_line_request_output(line_0, TEST_CONSUMER, 0);
- TEST_ASSERT_RET_OK(rv);
- rv = gpiod_line_request_output(line_1, TEST_CONSUMER, 1);
- TEST_ASSERT_RET_OK(rv);
-
- TEST_ASSERT_EQ(test_debugfs_get_value(0, 2), 0);
- TEST_ASSERT_EQ(test_debugfs_get_value(0, 5), 1);
+ g_autoptr(gpiod_chip_struct) chip = NULL;
+ struct gpiod_line *line0;
+ struct gpiod_line *line1;
+ gint ret;
+
+ chip = gpiod_chip_open(gpiod_test_chip_path(0));
+ g_assert_nonnull(chip);
+ gpiod_test_return_if_failed();
+
+ line0 = gpiod_chip_get_line(chip, 2);
+ line1 = gpiod_chip_get_line(chip, 5);
+ g_assert_nonnull(line0);
+ g_assert_nonnull(line1);
+ gpiod_test_return_if_failed();
+
+ ret = gpiod_line_request_output(line0, GPIOD_TEST_CONSUMER, 0);
+ g_assert_cmpint(ret, ==, 0);
+ ret = gpiod_line_request_output(line1, GPIOD_TEST_CONSUMER, 1);
+ g_assert_cmpint(ret, ==, 0);
+
+ g_assert_cmpint(gpiod_test_chip_get_value(0, 2), ==, 0);
+ g_assert_cmpint(gpiod_test_chip_get_value(0, 5), ==, 1);
}
-TEST_DEFINE(line_request_output,
- "gpiod_line_request_output() - good",
- 0, { 8 });
-static void line_request_already_requested(void)
+GPIOD_TEST_CASE(request_already_requested, 0, { 8 })
{
- TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL;
+ g_autoptr(gpiod_chip_struct) chip = NULL;
struct gpiod_line *line;
- int rv;
+ gint ret;
- chip = gpiod_chip_open(test_chip_path(0));
- TEST_ASSERT_NOT_NULL(chip);
+ chip = gpiod_chip_open(gpiod_test_chip_path(0));
+ g_assert_nonnull(chip);
+ gpiod_test_return_if_failed();
line = gpiod_chip_get_line(chip, 0);
- TEST_ASSERT_NOT_NULL(line);
+ g_assert_nonnull(line);
+ gpiod_test_return_if_failed();
- rv = gpiod_line_request_input(line, TEST_CONSUMER);
- TEST_ASSERT_RET_OK(rv);
+ ret = gpiod_line_request_input(line, GPIOD_TEST_CONSUMER);
+ g_assert_cmpint(ret, ==, 0);
- rv = gpiod_line_request_input(line, TEST_CONSUMER);
- TEST_ASSERT_NOTEQ(rv, 0);
- TEST_ASSERT_ERRNO_IS(EBUSY);
+ ret = gpiod_line_request_input(line, GPIOD_TEST_CONSUMER);
+ g_assert_cmpint(ret, ==, -1);
+ g_assert_cmpint(errno, ==, EBUSY);
}
-TEST_DEFINE(line_request_already_requested,
- "gpiod_line_request() - already requested",
- 0, { 8 });
-static void line_consumer(void)
+GPIOD_TEST_CASE(consumer, 0, { 8 })
{
- TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL;
+ g_autoptr(gpiod_chip_struct) chip = NULL;
struct gpiod_line *line;
- int rv;
+ gint ret;
- chip = gpiod_chip_open(test_chip_path(0));
- TEST_ASSERT_NOT_NULL(chip);
+ chip = gpiod_chip_open(gpiod_test_chip_path(0));
+ g_assert_nonnull(chip);
+ gpiod_test_return_if_failed();
line = gpiod_chip_get_line(chip, 0);
- TEST_ASSERT_NOT_NULL(line);
-
- TEST_ASSERT_NULL(gpiod_line_consumer(line));
+ g_assert_nonnull(line);
+ gpiod_test_return_if_failed();
- rv = gpiod_line_request_input(line, TEST_CONSUMER);
- TEST_ASSERT_RET_OK(rv);
+ g_assert_null(gpiod_line_consumer(line));
- TEST_ASSERT(!gpiod_line_needs_update(line));
- TEST_ASSERT_STR_EQ(gpiod_line_consumer(line), TEST_CONSUMER);
+ ret = gpiod_line_request_input(line, GPIOD_TEST_CONSUMER);
+ g_assert_cmpint(ret, ==, 0);
+ g_assert_false(gpiod_line_needs_update(line));
+ g_assert_cmpstr(gpiod_line_consumer(line), ==, GPIOD_TEST_CONSUMER);
}
-TEST_DEFINE(line_consumer,
- "gpiod_line_consumer() - good",
- 0, { 8 });
-static void line_consumer_long_string(void)
+GPIOD_TEST_CASE(consumer_long_string, 0, { 8 })
{
- TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL;
+ g_autoptr(gpiod_chip_struct) chip = NULL;
struct gpiod_line *line;
- int rv;
+ gint ret;
- chip = gpiod_chip_open(test_chip_path(0));
- TEST_ASSERT_NOT_NULL(chip);
+ chip = gpiod_chip_open(gpiod_test_chip_path(0));
+ g_assert_nonnull(chip);
+ gpiod_test_return_if_failed();
line = gpiod_chip_get_line(chip, 0);
- TEST_ASSERT_NOT_NULL(line);
-
- TEST_ASSERT_NULL(gpiod_line_consumer(line));
-
- rv = gpiod_line_request_input(line,
- "consumer string over 32 characters long");
- TEST_ASSERT_RET_OK(rv);
-
- TEST_ASSERT(!gpiod_line_needs_update(line));
- TEST_ASSERT_STR_EQ(gpiod_line_consumer(line),
- "consumer string over 32 charact");
- TEST_ASSERT_EQ(strlen(gpiod_line_consumer(line)), 31);
+ g_assert_nonnull(line);
+ gpiod_test_return_if_failed();
+
+ g_assert_null(gpiod_line_consumer(line));
+
+ ret = gpiod_line_request_input(line,
+ "consumer string over 32 characters long");
+ g_assert_cmpint(ret, ==, 0);
+ g_assert_false(gpiod_line_needs_update(line));
+ g_assert_cmpstr(gpiod_line_consumer(line), ==,
+ "consumer string over 32 charact");
+ g_assert_cmpuint(strlen(gpiod_line_consumer(line)), ==, 31);
}
-TEST_DEFINE(line_consumer_long_string,
- "gpiod_line_consumer() - long consumer string",
- 0, { 8 });
-static void line_request_bulk_output(void)
+GPIOD_TEST_CASE(request_bulk_output, 0, { 8, 8 })
{
- TEST_CLEANUP_CHIP struct gpiod_chip *chipA = NULL;
- TEST_CLEANUP_CHIP struct gpiod_chip *chipB = NULL;
- struct gpiod_line_bulk bulkB = GPIOD_LINE_BULK_INITIALIZER;
- struct gpiod_line_bulk bulkA;
- struct gpiod_line *lineA0;
- struct gpiod_line *lineA1;
- struct gpiod_line *lineA2;
- struct gpiod_line *lineA3;
- struct gpiod_line *lineB0;
- struct gpiod_line *lineB1;
- struct gpiod_line *lineB2;
- struct gpiod_line *lineB3;
- int valA[4], valB[4];
- int rv;
-
- chipA = gpiod_chip_open(test_chip_path(0));
- chipB = gpiod_chip_open(test_chip_path(1));
- TEST_ASSERT_NOT_NULL(chipA);
- TEST_ASSERT_NOT_NULL(chipB);
-
- gpiod_line_bulk_init(&bulkA);
+ g_autoptr(gpiod_chip_struct) chipA = NULL;
+ g_autoptr(gpiod_chip_struct) chipB = NULL;
+ struct gpiod_line_bulk bulkB = GPIOD_LINE_BULK_INITIALIZER, bulkA;
+ struct gpiod_line *lineA0, *lineA1, *lineA2, *lineA3,
+ *lineB0, *lineB1, *lineB2, *lineB3;
+ gint valA[4], valB[4], ret;
+
+ chipA = gpiod_chip_open(gpiod_test_chip_path(0));
+ chipB = gpiod_chip_open(gpiod_test_chip_path(1));
+ g_assert_nonnull(chipA);
+ g_assert_nonnull(chipB);
+ gpiod_test_return_if_failed();
lineA0 = gpiod_chip_get_line(chipA, 0);
lineA1 = gpiod_chip_get_line(chipA, 1);
lineB2 = gpiod_chip_get_line(chipB, 2);
lineB3 = gpiod_chip_get_line(chipB, 3);
- TEST_ASSERT_NOT_NULL(lineA0);
- TEST_ASSERT_NOT_NULL(lineA1);
- TEST_ASSERT_NOT_NULL(lineA2);
- TEST_ASSERT_NOT_NULL(lineA3);
- TEST_ASSERT_NOT_NULL(lineB0);
- TEST_ASSERT_NOT_NULL(lineB1);
- TEST_ASSERT_NOT_NULL(lineB2);
- TEST_ASSERT_NOT_NULL(lineB3);
+ g_assert_nonnull(lineA0);
+ g_assert_nonnull(lineA1);
+ g_assert_nonnull(lineA2);
+ g_assert_nonnull(lineA3);
+ g_assert_nonnull(lineB0);
+ g_assert_nonnull(lineB1);
+ g_assert_nonnull(lineB2);
+ g_assert_nonnull(lineB3);
+ gpiod_test_return_if_failed();
+ gpiod_line_bulk_init(&bulkA);
gpiod_line_bulk_add(&bulkA, lineA0);
gpiod_line_bulk_add(&bulkA, lineA1);
gpiod_line_bulk_add(&bulkA, lineA2);
valA[1] = 0;
valA[2] = 0;
valA[3] = 1;
- rv = gpiod_line_request_bulk_output(&bulkA, TEST_CONSUMER, valA);
- TEST_ASSERT_RET_OK(rv);
+ ret = gpiod_line_request_bulk_output(&bulkA,
+ GPIOD_TEST_CONSUMER, valA);
+ g_assert_cmpint(ret, ==, 0);
valB[0] = 0;
valB[1] = 1;
valB[2] = 0;
valB[3] = 1;
- rv = gpiod_line_request_bulk_output(&bulkB, TEST_CONSUMER, valB);
- TEST_ASSERT_RET_OK(rv);
-
- TEST_ASSERT_EQ(test_debugfs_get_value(0, 0), 1);
- TEST_ASSERT_EQ(test_debugfs_get_value(0, 1), 0);
- TEST_ASSERT_EQ(test_debugfs_get_value(0, 2), 0);
- TEST_ASSERT_EQ(test_debugfs_get_value(0, 3), 1);
-
- TEST_ASSERT_EQ(test_debugfs_get_value(1, 0), 0);
- TEST_ASSERT_EQ(test_debugfs_get_value(1, 1), 1);
- TEST_ASSERT_EQ(test_debugfs_get_value(1, 2), 0);
- TEST_ASSERT_EQ(test_debugfs_get_value(1, 3), 1);
+ ret = gpiod_line_request_bulk_output(&bulkB,
+ GPIOD_TEST_CONSUMER, valB);
+ g_assert_cmpint(ret, ==, 0);
+
+ g_assert_cmpint(gpiod_test_chip_get_value(0, 0), ==, 1);
+ g_assert_cmpint(gpiod_test_chip_get_value(0, 1), ==, 0);
+ g_assert_cmpint(gpiod_test_chip_get_value(0, 2), ==, 0);
+ g_assert_cmpint(gpiod_test_chip_get_value(0, 3), ==, 1);
+
+ g_assert_cmpint(gpiod_test_chip_get_value(1, 0), ==, 0);
+ g_assert_cmpint(gpiod_test_chip_get_value(1, 1), ==, 1);
+ g_assert_cmpint(gpiod_test_chip_get_value(1, 2), ==, 0);
+ g_assert_cmpint(gpiod_test_chip_get_value(1, 3), ==, 1);
}
-TEST_DEFINE(line_request_bulk_output,
- "gpiod_line_request_bulk_output() - good",
- 0, { 8, 8 });
-static void line_request_bulk_different_chips(void)
+GPIOD_TEST_CASE(request_bulk_different_chips, 0, { 8, 8 })
{
- TEST_CLEANUP_CHIP struct gpiod_chip *chipA = NULL;
- TEST_CLEANUP_CHIP struct gpiod_chip *chipB = NULL;
+ g_autoptr(gpiod_chip_struct) chipA = NULL;
+ g_autoptr(gpiod_chip_struct) chipB = NULL;
+ struct gpiod_line *lineA0, *lineA1, *lineB0, *lineB1;
struct gpiod_line_request_config req;
struct gpiod_line_bulk bulk;
- struct gpiod_line *lineA0;
- struct gpiod_line *lineA1;
- struct gpiod_line *lineB0;
- struct gpiod_line *lineB1;
- int rv;
+ gint ret;
- chipA = gpiod_chip_open(test_chip_path(0));
- chipB = gpiod_chip_open(test_chip_path(1));
- TEST_ASSERT_NOT_NULL(chipA);
- TEST_ASSERT_NOT_NULL(chipB);
+ chipA = gpiod_chip_open(gpiod_test_chip_path(0));
+ chipB = gpiod_chip_open(gpiod_test_chip_path(1));
+ g_assert_nonnull(chipA);
+ g_assert_nonnull(chipB);
+ gpiod_test_return_if_failed();
lineA0 = gpiod_chip_get_line(chipA, 0);
lineA1 = gpiod_chip_get_line(chipA, 1);
lineB0 = gpiod_chip_get_line(chipB, 0);
lineB1 = gpiod_chip_get_line(chipB, 1);
- TEST_ASSERT_NOT_NULL(lineA0);
- TEST_ASSERT_NOT_NULL(lineA1);
- TEST_ASSERT_NOT_NULL(lineB0);
- TEST_ASSERT_NOT_NULL(lineB1);
+ g_assert_nonnull(lineA0);
+ g_assert_nonnull(lineA1);
+ g_assert_nonnull(lineB0);
+ g_assert_nonnull(lineB1);
+ gpiod_test_return_if_failed();
gpiod_line_bulk_init(&bulk);
gpiod_line_bulk_add(&bulk, lineA0);
gpiod_line_bulk_add(&bulk, lineB0);
gpiod_line_bulk_add(&bulk, lineB1);
- req.consumer = TEST_CONSUMER;
+ req.consumer = GPIOD_TEST_CONSUMER;
req.request_type = GPIOD_LINE_REQUEST_DIRECTION_INPUT;
req.flags = GPIOD_LINE_ACTIVE_STATE_HIGH;
- rv = gpiod_line_request_bulk(&bulk, &req, NULL);
- TEST_ASSERT_NOTEQ(rv, 0);
- TEST_ASSERT_ERRNO_IS(EINVAL);
+ ret = gpiod_line_request_bulk(&bulk, &req, NULL);
+ g_assert_cmpint(ret, ==, -1);
+ g_assert_cmpint(errno, ==, EINVAL);
}
-TEST_DEFINE(line_request_bulk_different_chips,
- "gpiod_line_request_bulk() - different chips",
- 0, { 8, 8 });
-static void line_request_null_default_vals_for_output(void)
+GPIOD_TEST_CASE(request_null_default_vals_for_output, 0, { 8 })
{
- TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL;
+ g_autoptr(gpiod_chip_struct) chip = NULL;
struct gpiod_line_bulk bulk = GPIOD_LINE_BULK_INITIALIZER;
- struct gpiod_line *line;
- int rv, vals[3];
+ struct gpiod_line *line0, *line1, *line2;
+ gint ret;
- chip = gpiod_chip_open(test_chip_path(0));
- TEST_ASSERT_NOT_NULL(chip);
+ chip = gpiod_chip_open(gpiod_test_chip_path(0));
+ g_assert_nonnull(chip);
+ gpiod_test_return_if_failed();
- line = gpiod_chip_get_line(chip, 0);
- gpiod_line_bulk_add(&bulk, line);
- line = gpiod_chip_get_line(chip, 1);
- gpiod_line_bulk_add(&bulk, line);
- line = gpiod_chip_get_line(chip, 2);
- gpiod_line_bulk_add(&bulk, line);
+ line0 = gpiod_chip_get_line(chip, 0);
+ line1 = gpiod_chip_get_line(chip, 1);
+ line2 = gpiod_chip_get_line(chip, 2);
- rv = gpiod_line_request_bulk_output(&bulk, TEST_CONSUMER, NULL);
- TEST_ASSERT_RET_OK(rv);
+ g_assert_nonnull(line0);
+ g_assert_nonnull(line1);
+ g_assert_nonnull(line2);
+ gpiod_test_return_if_failed();
- gpiod_line_release_bulk(&bulk);
-
- rv = gpiod_line_request_bulk_input(&bulk, TEST_CONSUMER);
- TEST_ASSERT_RET_OK(rv);
+ gpiod_line_bulk_add(&bulk, line0);
+ gpiod_line_bulk_add(&bulk, line1);
+ gpiod_line_bulk_add(&bulk, line2);
- memset(vals, 0, sizeof(vals));
+ ret = gpiod_line_request_bulk_output(&bulk, GPIOD_TEST_CONSUMER, NULL);
+ g_assert_cmpint(ret, ==, 0);
- TEST_ASSERT_EQ(test_debugfs_get_value(0, 0), 0);
- TEST_ASSERT_EQ(test_debugfs_get_value(0, 1), 0);
- TEST_ASSERT_EQ(test_debugfs_get_value(0, 2), 0);
+ g_assert_cmpint(gpiod_test_chip_get_value(0, 0), ==, 0);
+ g_assert_cmpint(gpiod_test_chip_get_value(0, 1), ==, 0);
+ g_assert_cmpint(gpiod_test_chip_get_value(0, 2), ==, 0);
}
-TEST_DEFINE(line_request_null_default_vals_for_output,
- "gpiod_line_request_bulk() - null default vals for output",
- 0, { 8 });
-static void line_set_value(void)
+GPIOD_TEST_CASE(set_value, 0, { 8 })
{
- TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL;
+ g_autoptr(gpiod_chip_struct) chip = NULL;
struct gpiod_line *line;
- int rv;
+ gint ret;
- chip = gpiod_chip_open(test_chip_path(0));
- TEST_ASSERT_NOT_NULL(chip);
+ chip = gpiod_chip_open(gpiod_test_chip_path(0));
+ g_assert_nonnull(chip);
+ gpiod_test_return_if_failed();
line = gpiod_chip_get_line(chip, 2);
- TEST_ASSERT_NOT_NULL(line);
-
- rv = gpiod_line_request_output(line, TEST_CONSUMER, 0);
- TEST_ASSERT_RET_OK(rv);
-
- TEST_ASSERT_RET_OK(gpiod_line_set_value(line, 1));
- TEST_ASSERT_EQ(test_debugfs_get_value(0, 2), 1);
- TEST_ASSERT_RET_OK(gpiod_line_set_value(line, 0));
- TEST_ASSERT_EQ(test_debugfs_get_value(0, 2), 0);
+ g_assert_nonnull(line);
+ gpiod_test_return_if_failed();
+
+ ret = gpiod_line_request_output(line, GPIOD_TEST_CONSUMER, 0);
+ g_assert_cmpint(ret, ==, 0);
+
+ ret = gpiod_line_set_value(line, 1);
+ g_assert_cmpint(ret, ==, 0);
+ g_assert_cmpint(gpiod_test_chip_get_value(0, 2), ==, 1);
+ ret = gpiod_line_set_value(line, 0);
+ g_assert_cmpint(ret, ==, 0);
+ g_assert_cmpint(gpiod_test_chip_get_value(0, 2), ==, 0);
}
-TEST_DEFINE(line_set_value,
- "gpiod_line_set_value() - good",
- 0, { 8 });
-static void line_get_value_different_chips(void)
+GPIOD_TEST_CASE(get_value_different_chips, 0, { 8, 8 })
{
- TEST_CLEANUP_CHIP struct gpiod_chip *chipA = NULL;
- TEST_CLEANUP_CHIP struct gpiod_chip *chipB = NULL;
- struct gpiod_line *lineA1, *lineA2, *lineB1, *lineB2;
+ g_autoptr(gpiod_chip_struct) chipA = NULL;
+ g_autoptr(gpiod_chip_struct) chipB = NULL;
+ struct gpiod_line *lineA0, *lineA1, *lineB0, *lineB1;
struct gpiod_line_bulk bulkA, bulkB, bulk;
- int rv, vals[4];
+ gint ret, vals[4];
- chipA = gpiod_chip_open(test_chip_path(0));
- TEST_ASSERT_NOT_NULL(chipA);
+ chipA = gpiod_chip_open(gpiod_test_chip_path(0));
+ chipB = gpiod_chip_open(gpiod_test_chip_path(1));
+ g_assert_nonnull(chipA);
+ g_assert_nonnull(chipB);
+ gpiod_test_return_if_failed();
- chipB = gpiod_chip_open(test_chip_path(1));
- TEST_ASSERT_NOT_NULL(chipB);
+ lineA0 = gpiod_chip_get_line(chipA, 3);
+ lineA1 = gpiod_chip_get_line(chipA, 4);
+ lineB0 = gpiod_chip_get_line(chipB, 5);
+ lineB1 = gpiod_chip_get_line(chipB, 6);
- lineA1 = gpiod_chip_get_line(chipA, 3);
- lineA2 = gpiod_chip_get_line(chipA, 4);
- lineB1 = gpiod_chip_get_line(chipB, 5);
- lineB2 = gpiod_chip_get_line(chipB, 6);
- TEST_ASSERT_NOT_NULL(lineA1);
- TEST_ASSERT_NOT_NULL(lineA2);
- TEST_ASSERT_NOT_NULL(lineB1);
- TEST_ASSERT_NOT_NULL(lineB2);
+ g_assert_nonnull(lineA0);
+ g_assert_nonnull(lineA1);
+ g_assert_nonnull(lineB0);
+ g_assert_nonnull(lineB1);
+ gpiod_test_return_if_failed();
gpiod_line_bulk_init(&bulkA);
gpiod_line_bulk_init(&bulkB);
gpiod_line_bulk_init(&bulk);
- gpiod_line_bulk_add(&bulk, lineA1);
- gpiod_line_bulk_add(&bulk, lineA2);
- gpiod_line_bulk_add(&bulk, lineB1);
- gpiod_line_bulk_add(&bulk, lineB2);
-
+ gpiod_line_bulk_add(&bulkA, lineA0);
gpiod_line_bulk_add(&bulkA, lineA1);
- gpiod_line_bulk_add(&bulkA, lineA2);
+ gpiod_line_bulk_add(&bulkB, lineB0);
gpiod_line_bulk_add(&bulkB, lineB1);
- gpiod_line_bulk_add(&bulkB, lineB2);
+ gpiod_line_bulk_add(&bulk, lineA0);
gpiod_line_bulk_add(&bulk, lineA1);
- gpiod_line_bulk_add(&bulk, lineA2);
+ gpiod_line_bulk_add(&bulk, lineB0);
gpiod_line_bulk_add(&bulk, lineB1);
- gpiod_line_bulk_add(&bulk, lineB2);
- rv = gpiod_line_request_bulk_input(&bulkA, TEST_CONSUMER);
- TEST_ASSERT_RET_OK(rv);
+ ret = gpiod_line_request_bulk_input(&bulkA, GPIOD_TEST_CONSUMER);
+ g_assert_cmpint(ret, ==, 0);
+ ret = gpiod_line_request_bulk_input(&bulkB, GPIOD_TEST_CONSUMER);
+ g_assert_cmpint(ret, ==, 0);
- rv = gpiod_line_request_bulk_input(&bulkB, TEST_CONSUMER);
- TEST_ASSERT_RET_OK(rv);
-
- rv = gpiod_line_get_value_bulk(&bulk, vals);
- TEST_ASSERT_EQ(rv, -1);
- TEST_ASSERT_ERRNO_IS(EINVAL);
+ ret = gpiod_line_get_value_bulk(&bulk, vals);
+ g_assert_cmpint(ret, ==, -1);
+ g_assert_cmpint(errno, ==, EINVAL);
}
-TEST_DEFINE(line_get_value_different_chips,
- "gpiod_line_get_value_bulk() - different chips",
- 0, { 8, 8 });
-static void line_get_good(void)
+GPIOD_TEST_CASE(get_line_helper, 0, { 16, 16, 32, 16 })
{
- TEST_CLEANUP(test_line_close_chip) struct gpiod_line *line = NULL;
+ g_autoptr(gpiod_chip_struct) chip = NULL;
+ struct gpiod_line *line;
- line = gpiod_line_get(test_chip_name(2), 18);
- TEST_ASSERT_NOT_NULL(line);
- TEST_ASSERT_EQ(gpiod_line_offset(line), 18);
+ line = gpiod_line_get(gpiod_test_chip_name(2), 18);
+ g_assert_nonnull(line);
+ gpiod_test_return_if_failed();
+ chip = gpiod_line_get_chip(line);
+ g_assert_cmpint(gpiod_line_offset(line), ==, 18);
}
-TEST_DEFINE(line_get_good,
- "gpiod_line_get() - good",
- TEST_FLAG_NAMED_LINES, { 16, 16, 32, 16 });
-static void line_get_invalid_offset(void)
+GPIOD_TEST_CASE(get_line_helper_invalid_offset, 0, { 16, 16, 32, 16 })
{
- TEST_CLEANUP(test_line_close_chip) struct gpiod_line *line = NULL;
+ struct gpiod_line *line;
- line = gpiod_line_get(test_chip_name(3), 18);
- TEST_ASSERT_NULL(line);
- TEST_ASSERT_ERRNO_IS(EINVAL);
+ line = gpiod_line_get(gpiod_test_chip_name(3), 18);
+ g_assert_null(line);
+ g_assert_cmpint(errno, ==, EINVAL);
}
-TEST_DEFINE(line_get_invalid_offset,
- "gpiod_line_get() - invalid offset",
- TEST_FLAG_NAMED_LINES, { 16, 16, 32, 16 });
-static void line_find_good(void)
+GPIOD_TEST_CASE(find_good, GPIOD_TEST_FLAG_NAMED_LINES, { 16, 16, 32, 16 })
{
- TEST_CLEANUP(test_line_close_chip) struct gpiod_line *line = NULL;
+ g_autoptr(gpiod_chip_struct) chip = NULL;
+ struct gpiod_line *line;
line = gpiod_line_find("gpio-mockup-C-12");
- TEST_ASSERT_NOT_NULL(line);
-
- TEST_ASSERT_EQ(gpiod_line_offset(line), 12);
+ g_assert_nonnull(line);
+ gpiod_test_return_if_failed();
+ chip = gpiod_line_get_chip(line);
+ g_assert_cmpint(gpiod_line_offset(line), ==, 12);
}
-TEST_DEFINE(line_find_good,
- "gpiod_line_find() - good",
- TEST_FLAG_NAMED_LINES, { 16, 16, 32, 16 });
-static void line_find_not_found(void)
+GPIOD_TEST_CASE(find_not_found,
+ GPIOD_TEST_FLAG_NAMED_LINES, { 16, 16, 32, 16 })
{
- TEST_CLEANUP(test_line_close_chip) struct gpiod_line *line = NULL;
+ struct gpiod_line *line;
line = gpiod_line_find("nonexistent");
- TEST_ASSERT_NULL(line);
- TEST_ASSERT_ERRNO_IS(ENOENT);
+ g_assert_null(line);
+ g_assert_cmpint(errno, ==, ENOENT);
}
-TEST_DEFINE(line_find_not_found,
- "gpiod_line_find() - not found",
- TEST_FLAG_NAMED_LINES, { 16, 16, 32, 16 });
-static void line_find_unnamed_lines(void)
+GPIOD_TEST_CASE(find_unnamed_lines, 0, { 16, 16, 32, 16 })
{
- TEST_CLEANUP(test_line_close_chip) struct gpiod_line *line = NULL;
+ struct gpiod_line *line;
line = gpiod_line_find("gpio-mockup-C-12");
- TEST_ASSERT_NULL(line);
- TEST_ASSERT_ERRNO_IS(ENOENT);
+ g_assert_null(line);
+ g_assert_cmpint(errno, ==, ENOENT);
}
-TEST_DEFINE(line_find_unnamed_lines,
- "gpiod_line_find() - unnamed lines",
- 0, { 16, 16, 32, 16 });
-static void line_direction(void)
+GPIOD_TEST_CASE(direction, 0, { 8 })
{
- TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL;
+ g_autoptr(gpiod_chip_struct) chip = NULL;
struct gpiod_line *line;
- int rv;
+ gint ret;
- chip = gpiod_chip_open(test_chip_path(0));
- TEST_ASSERT_NOT_NULL(chip);
+ chip = gpiod_chip_open(gpiod_test_chip_path(0));
+ g_assert_nonnull(chip);
+ gpiod_test_return_if_failed();
line = gpiod_chip_get_line(chip, 5);
- TEST_ASSERT_NOT_NULL(line);
+ g_assert_nonnull(line);
+ gpiod_test_return_if_failed();
- rv = gpiod_line_request_output(line, TEST_CONSUMER, 0);
- TEST_ASSERT_RET_OK(rv);
-
- TEST_ASSERT_EQ(gpiod_line_direction(line), GPIOD_LINE_DIRECTION_OUTPUT);
+ ret = gpiod_line_request_output(line, GPIOD_TEST_CONSUMER, 0);
+ g_assert_cmpint(ret, ==, 0);
+ g_assert_cmpint(gpiod_line_direction(line), ==,
+ GPIOD_LINE_DIRECTION_OUTPUT);
gpiod_line_release(line);
- rv = gpiod_line_request_input(line, TEST_CONSUMER);
- TEST_ASSERT_RET_OK(rv);
-
- TEST_ASSERT_EQ(gpiod_line_direction(line), GPIOD_LINE_DIRECTION_INPUT);
+ ret = gpiod_line_request_input(line, GPIOD_TEST_CONSUMER);
+ g_assert_cmpint(ret, ==, 0);
+ g_assert_cmpint(gpiod_line_direction(line), ==,
+ GPIOD_LINE_DIRECTION_INPUT);
}
-TEST_DEFINE(line_direction,
- "gpiod_line_direction() - set & get",
- 0, { 8 });
-static void line_active_state(void)
+GPIOD_TEST_CASE(active_state, 0, { 8 })
{
- TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL;
+ g_autoptr(gpiod_chip_struct) chip = NULL;
struct gpiod_line *line;
- int rv;
+ gint ret;
- chip = gpiod_chip_open(test_chip_path(0));
- TEST_ASSERT_NOT_NULL(chip);
+ chip = gpiod_chip_open(gpiod_test_chip_path(0));
+ g_assert_nonnull(chip);
+ gpiod_test_return_if_failed();
line = gpiod_chip_get_line(chip, 5);
- TEST_ASSERT_NOT_NULL(line);
+ g_assert_nonnull(line);
+ gpiod_test_return_if_failed();
- rv = gpiod_line_request_input(line, TEST_CONSUMER);
- TEST_ASSERT_RET_OK(rv);
+ ret = gpiod_line_request_input(line, GPIOD_TEST_CONSUMER);
+ g_assert_cmpint(ret, ==, 0);
- TEST_ASSERT_EQ(gpiod_line_active_state(line),
- GPIOD_LINE_ACTIVE_STATE_HIGH);
+ g_assert_cmpint(gpiod_line_active_state(line), ==,
+ GPIOD_LINE_ACTIVE_STATE_HIGH);
gpiod_line_release(line);
- rv = gpiod_line_request_input_flags(line, TEST_CONSUMER,
+ ret = gpiod_line_request_input_flags(line, GPIOD_TEST_CONSUMER,
GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW);
- TEST_ASSERT_RET_OK(rv);
+ g_assert_cmpint(ret, ==, 0);
- TEST_ASSERT_EQ(gpiod_line_direction(line), GPIOD_LINE_DIRECTION_INPUT);
+ g_assert_cmpint(gpiod_line_direction(line), ==,
+ GPIOD_LINE_DIRECTION_INPUT);
}
-TEST_DEFINE(line_active_state,
- "gpiod_line_active_state() - set & get",
- 0, { 8 });
-static void line_misc_flags(void)
+GPIOD_TEST_CASE(misc_flags, 0, { 8 })
{
- TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL;
+ g_autoptr(gpiod_chip_struct) chip = NULL;
struct gpiod_line_request_config config;
struct gpiod_line *line;
- int rv;
+ gint ret;
- chip = gpiod_chip_open(test_chip_path(0));
- TEST_ASSERT_NOT_NULL(chip);
+ chip = gpiod_chip_open(gpiod_test_chip_path(0));
+ g_assert_nonnull(chip);
+ gpiod_test_return_if_failed();
line = gpiod_chip_get_line(chip, 2);
- TEST_ASSERT_NOT_NULL(line);
+ g_assert_nonnull(line);
+ gpiod_test_return_if_failed();
- TEST_ASSERT_FALSE(gpiod_line_is_used(line));
- TEST_ASSERT_FALSE(gpiod_line_is_open_drain(line));
- TEST_ASSERT_FALSE(gpiod_line_is_open_source(line));
+ g_assert_false(gpiod_line_is_used(line));
+ g_assert_false(gpiod_line_is_open_drain(line));
+ g_assert_false(gpiod_line_is_open_source(line));
config.request_type = GPIOD_LINE_REQUEST_DIRECTION_OUTPUT;
- config.consumer = TEST_CONSUMER;
+ config.consumer = GPIOD_TEST_CONSUMER;
config.flags = GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN;
- rv = gpiod_line_request(line, &config, 0);
- TEST_ASSERT_RET_OK(rv);
+ ret = gpiod_line_request(line, &config, 0);
+ g_assert_cmpint(ret, ==, 0);
- TEST_ASSERT(gpiod_line_is_used(line));
- TEST_ASSERT(gpiod_line_is_open_drain(line));
- TEST_ASSERT_FALSE(gpiod_line_is_open_source(line));
+ g_assert_true(gpiod_line_is_used(line));
+ g_assert_true(gpiod_line_is_open_drain(line));
+ g_assert_false(gpiod_line_is_open_source(line));
gpiod_line_release(line);
config.flags = GPIOD_LINE_REQUEST_FLAG_OPEN_SOURCE;
- rv = gpiod_line_request(line, &config, 0);
- TEST_ASSERT_RET_OK(rv);
+ ret = gpiod_line_request(line, &config, 0);
+ g_assert_cmpint(ret, ==, 0);
- TEST_ASSERT(gpiod_line_is_used(line));
- TEST_ASSERT_FALSE(gpiod_line_is_open_drain(line));
- TEST_ASSERT(gpiod_line_is_open_source(line));
+ g_assert_true(gpiod_line_is_used(line));
+ g_assert_false(gpiod_line_is_open_drain(line));
+ g_assert_true(gpiod_line_is_open_source(line));
}
-TEST_DEFINE(line_misc_flags,
- "gpiod_line - misc flags",
- 0, { 8 });
-static void line_open_source_open_drain_input_invalid(void)
+GPIOD_TEST_CASE(open_source_open_drain_input_mode, 0, { 8 })
{
- TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL;
+ g_autoptr(gpiod_chip_struct) chip = NULL;
struct gpiod_line *line;
- int rv;
+ gint ret;
- chip = gpiod_chip_open(test_chip_path(0));
- TEST_ASSERT_NOT_NULL(chip);
+ chip = gpiod_chip_open(gpiod_test_chip_path(0));
+ g_assert_nonnull(chip);
+ gpiod_test_return_if_failed();
line = gpiod_chip_get_line(chip, 2);
- TEST_ASSERT_NOT_NULL(line);
+ g_assert_nonnull(line);
+ gpiod_test_return_if_failed();
- rv = gpiod_line_request_input_flags(line, TEST_CONSUMER,
+ ret = gpiod_line_request_input_flags(line, GPIOD_TEST_CONSUMER,
GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN);
- TEST_ASSERT_EQ(rv, -1);
- TEST_ASSERT_ERRNO_IS(EINVAL);
+ g_assert_cmpint(ret, ==, -1);
+ g_assert_cmpint(errno, ==, EINVAL);
- rv = gpiod_line_request_input_flags(line, TEST_CONSUMER,
+ ret = gpiod_line_request_input_flags(line, GPIOD_TEST_CONSUMER,
GPIOD_LINE_REQUEST_FLAG_OPEN_SOURCE);
- TEST_ASSERT_EQ(rv, -1);
- TEST_ASSERT_ERRNO_IS(EINVAL);
+ g_assert_cmpint(ret, ==, -1);
+ g_assert_cmpint(errno, ==, EINVAL);
}
-TEST_DEFINE(line_open_source_open_drain_input_invalid,
- "gpiod_line - open-source & open-drain for input mode (invalid)",
- 0, { 8 });
-static void line_open_source_open_drain_simultaneously(void)
+GPIOD_TEST_CASE(open_source_open_drain_simultaneously, 0, { 8 })
{
- TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL;
+ g_autoptr(gpiod_chip_struct) chip = NULL;
struct gpiod_line *line;
- int rv;
+ gint ret;
- chip = gpiod_chip_open(test_chip_path(0));
- TEST_ASSERT_NOT_NULL(chip);
+ chip = gpiod_chip_open(gpiod_test_chip_path(0));
+ g_assert_nonnull(chip);
+ gpiod_test_return_if_failed();
line = gpiod_chip_get_line(chip, 2);
- TEST_ASSERT_NOT_NULL(line);
-
- rv = gpiod_line_request_output_flags(line, TEST_CONSUMER,
- GPIOD_LINE_REQUEST_FLAG_OPEN_SOURCE |
- GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN, 1);
- TEST_ASSERT_EQ(rv, -1);
- TEST_ASSERT_ERRNO_IS(EINVAL);
+ g_assert_nonnull(line);
+ gpiod_test_return_if_failed();
+
+ ret = gpiod_line_request_output_flags(line, GPIOD_TEST_CONSUMER,
+ GPIOD_LINE_REQUEST_FLAG_OPEN_SOURCE |
+ GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN, 1);
+ g_assert_cmpint(ret, ==, -1);
+ g_assert_cmpint(errno, ==, EINVAL);
}
-TEST_DEFINE(line_open_source_open_drain_simultaneously,
- "gpiod_line - open-source & open-drain flags simultaneously",
- 0, { 8 });
/* Verify that the reference counting of the line fd handle works correctly. */
-static void line_release_one_use_another(void)
+GPIOD_TEST_CASE(release_one_use_another, 0, { 8 })
{
- TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL;
+ g_autoptr(gpiod_chip_struct) chip = NULL;
struct gpiod_line_bulk bulk;
+ struct gpiod_line *line0;
struct gpiod_line *line1;
- struct gpiod_line *line2;
- int rv, vals[2];
+ gint ret, vals[2];
- chip = gpiod_chip_open(test_chip_path(0));
- TEST_ASSERT_NOT_NULL(chip);
+ chip = gpiod_chip_open(gpiod_test_chip_path(0));
+ g_assert_nonnull(chip);
+ gpiod_test_return_if_failed();
- line1 = gpiod_chip_get_line(chip, 2);
- TEST_ASSERT_NOT_NULL(line1);
- line2 = gpiod_chip_get_line(chip, 3);
- TEST_ASSERT_NOT_NULL(line2);
+ line0 = gpiod_chip_get_line(chip, 2);
+ line1 = gpiod_chip_get_line(chip, 3);
+ g_assert_nonnull(line0);
+ g_assert_nonnull(line1);
+ gpiod_test_return_if_failed();
gpiod_line_bulk_init(&bulk);
+ gpiod_line_bulk_add(&bulk, line0);
gpiod_line_bulk_add(&bulk, line1);
- gpiod_line_bulk_add(&bulk, line2);
vals[0] = vals[1] = 1;
- rv = gpiod_line_request_bulk_output(&bulk, TEST_CONSUMER, vals);
- TEST_ASSERT_RET_OK(rv);
-
- gpiod_line_release(line1);
+ ret = gpiod_line_request_bulk_output(&bulk, GPIOD_TEST_CONSUMER, vals);
+ g_assert_cmpint(ret, ==, 0);
- rv = gpiod_line_get_value(line1);
- TEST_ASSERT_EQ(rv, -1);
- TEST_ASSERT_ERRNO_IS(EPERM);
+ gpiod_line_release(line0);
- rv = gpiod_line_get_value(line2);
- TEST_ASSERT_EQ(rv, 1);
+ ret = gpiod_line_get_value(line0);
+ g_assert_cmpint(ret, ==, -1);
+ g_assert_cmpint(errno, ==, EPERM);
}
-TEST_DEFINE(line_release_one_use_another,
- "gpiod_line - request two, release one, use the other one",
- 0, { 8 });
-static void line_null_consumer(void)
+GPIOD_TEST_CASE(null_consumer, 0, { 8 })
{
- TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL;
+ g_autoptr(gpiod_chip_struct) chip = NULL;
struct gpiod_line_request_config config;
struct gpiod_line *line;
- int rv;
+ gint ret;
- chip = gpiod_chip_open(test_chip_path(0));
- TEST_ASSERT_NOT_NULL(chip);
+ chip = gpiod_chip_open(gpiod_test_chip_path(0));
+ g_assert_nonnull(chip);
+ gpiod_test_return_if_failed();
line = gpiod_chip_get_line(chip, 2);
- TEST_ASSERT_NOT_NULL(line);
+ g_assert_nonnull(line);
+ gpiod_test_return_if_failed();
config.request_type = GPIOD_LINE_REQUEST_DIRECTION_INPUT;
config.consumer = NULL;
config.flags = 0;
- rv = gpiod_line_request(line, &config, 0);
- TEST_ASSERT_RET_OK(rv);
- TEST_ASSERT_STR_EQ(gpiod_line_consumer(line), "?");
+ ret = gpiod_line_request(line, &config, 0);
+ g_assert_cmpint(ret, ==, 0);
+ g_assert_cmpstr(gpiod_line_consumer(line), ==, "?");
gpiod_line_release(line);
*/
config.request_type = GPIOD_LINE_REQUEST_EVENT_BOTH_EDGES;
- rv = gpiod_line_request(line, &config, 0);
- TEST_ASSERT_RET_OK(rv);
- TEST_ASSERT_STR_EQ(gpiod_line_consumer(line), "?");
+ ret = gpiod_line_request(line, &config, 0);
+ g_assert_cmpint(ret, ==, 0);
+ g_assert_cmpstr(gpiod_line_consumer(line), ==, "?");
}
-TEST_DEFINE(line_null_consumer,
- "line request - NULL consumer string",
- 0, { 8 });
-static void line_empty_consumer(void)
+GPIOD_TEST_CASE(empty_consumer, 0, { 8 })
{
- TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL;
+ g_autoptr(gpiod_chip_struct) chip = NULL;
struct gpiod_line_request_config config;
struct gpiod_line *line;
- int rv;
+ gint ret;
- chip = gpiod_chip_open(test_chip_path(0));
- TEST_ASSERT_NOT_NULL(chip);
+ chip = gpiod_chip_open(gpiod_test_chip_path(0));
+ g_assert_nonnull(chip);
+ gpiod_test_return_if_failed();
line = gpiod_chip_get_line(chip, 2);
- TEST_ASSERT_NOT_NULL(line);
+ g_assert_nonnull(line);
+ gpiod_test_return_if_failed();
config.request_type = GPIOD_LINE_REQUEST_DIRECTION_INPUT;
config.consumer = "";
config.flags = 0;
- rv = gpiod_line_request(line, &config, 0);
- TEST_ASSERT_RET_OK(rv);
- TEST_ASSERT_STR_EQ(gpiod_line_consumer(line), "?");
+ ret = gpiod_line_request(line, &config, 0);
+ g_assert_cmpint(ret, ==, 0);
+ g_assert_cmpstr(gpiod_line_consumer(line), ==, "?");
gpiod_line_release(line);
*/
config.request_type = GPIOD_LINE_REQUEST_EVENT_BOTH_EDGES;
- rv = gpiod_line_request(line, &config, 0);
- TEST_ASSERT_RET_OK(rv);
- TEST_ASSERT_STR_EQ(gpiod_line_consumer(line), "?");
+ ret = gpiod_line_request(line, &config, 0);
+ g_assert_cmpint(ret, ==, 0);
+ g_assert_cmpstr(gpiod_line_consumer(line), ==, "?");
}
-TEST_DEFINE(line_empty_consumer,
- "line request - empty consumer string",
- 0, { 8 });
-static void line_bulk_foreach(void)
+GPIOD_TEST_CASE(bulk_foreach, GPIOD_TEST_FLAG_NAMED_LINES, { 8 })
{
- static const char *const line_names[] = { "gpio-mockup-A-0",
- "gpio-mockup-A-1",
- "gpio-mockup-A-2",
- "gpio-mockup-A-3" };
+ static const gchar *const line_names[] = { "gpio-mockup-A-0",
+ "gpio-mockup-A-1",
+ "gpio-mockup-A-2",
+ "gpio-mockup-A-3" };
- TEST_CLEANUP_CHIP struct gpiod_chip *chip = NULL;
+ g_autoptr(gpiod_chip_struct) chip = NULL;
struct gpiod_line_bulk bulk = GPIOD_LINE_BULK_INITIALIZER;
struct gpiod_line *line, **lineptr;
- int i;
+ gint i;
- chip = gpiod_chip_open(test_chip_path(0));
- TEST_ASSERT_NOT_NULL(chip);
+ chip = gpiod_chip_open(gpiod_test_chip_path(0));
+ g_assert_nonnull(chip);
+ gpiod_test_return_if_failed();
for (i = 0; i < 4; i++) {
line = gpiod_chip_get_line(chip, i);
- TEST_ASSERT_NOT_NULL(line);
+ g_assert_nonnull(line);
+ gpiod_test_return_if_failed();
gpiod_line_bulk_add(&bulk, line);
}
i = 0;
gpiod_line_bulk_foreach_line(&bulk, line, lineptr)
- TEST_ASSERT_STR_EQ(gpiod_line_name(line), line_names[i++]);
+ g_assert_cmpstr(gpiod_line_name(line), ==, line_names[i++]);
i = 0;
gpiod_line_bulk_foreach_line(&bulk, line, lineptr) {
- TEST_ASSERT_STR_EQ(gpiod_line_name(line), line_names[i++]);
+ g_assert_cmpstr(gpiod_line_name(line), ==, line_names[i++]);
if (i == 2)
break;
}
}
-TEST_DEFINE(line_bulk_foreach,
- "line bulk - iterate over all lines",
- TEST_FLAG_NAMED_LINES, { 8 });
/*
* This file is part of libgpiod.
*
- * Copyright (C) 2017-2018 Bartosz Golaszewski <bartekgola@gmail.com>
+ * Copyright (C) 2019 Bartosz Golaszewski <bgolaszewski@baylibre.com>
*/
-/* Misc test cases. */
-
-#include <errno.h>
+#include <string.h>
#include "gpiod-test.h"
-static void version_string(void)
+#define GPIOD_TEST_GROUP "misc"
+
+GPIOD_TEST_CASE(version_string, 0, { 1 })
{
- /* Check that gpiod_version_string() returns an actual string. */
- TEST_ASSERT_NOT_NULL(gpiod_version_string());
- TEST_ASSERT(strlen(gpiod_version_string()) > 0);
- TEST_ASSERT_REGEX_MATCH(gpiod_version_string(),
- "^[0-9]+\\.[0-9]+[0-9a-zA-Z\\.]*$");
+ g_autoptr(GRegex) regex = NULL;
+ GError *err = NULL;
+ const gchar *ver;
+
+ ver = gpiod_version_string();
+ g_assert_nonnull(ver);
+ gpiod_test_return_if_failed();
+ g_assert_cmpuint(strlen(ver), >, 0);
+
+ regex = g_regex_new("^[0-9]+\\.[0-9]+[0-9a-zA-Z\\.]*$", 0, 0, &err);
+ g_assert_null(err);
+ gpiod_test_return_if_failed();
+ g_assert_true(g_regex_match(regex, ver, 0, NULL));
}
-TEST_DEFINE(version_string,
- "gpiod_version_string()",
- 0, { });
gpiomon_SOURCES = gpiomon.c
gpiofind_SOURCES = gpiofind.c
+
+EXTRA_DIST = gpio-tools-test.bats
+
+if WITH_TESTS
+
+bin_SCRIPTS = gpio-tools-test.bats
+
+endif
--- /dev/null
+#!/usr/bin/env bats
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
+#
+# This file is part of libgpiod.
+#
+# Copyright (C) 2019 Bartosz Golaszewski <bgolaszewski@baylibre.com>
+#
+
+# Simple test harness for the gpio-tools.
+
+# Where output from coprocesses is stored
+COPROC_OUTPUT=$BATS_TMPDIR/gpio-tools-test-output
+# Save the PID of coprocess - otherwise we won't be able to wait for it
+# once it exits as the COPROC_PID will be cleared.
+COPROC_SAVED_PID=""
+
+# Run the command in $* and return 0 if the command failed. The way we do it
+# here is a workaround for the way bats handles failing processes.
+assert_fail() {
+ $* || return 0
+ return 1
+}
+
+# Check if the string in $2 matches against the pattern in $1.
+regex_matches() {
+ local PATTERN=$1
+ local STRING=$2
+
+ [[ $STRING =~ $PATTERN ]]
+}
+
+# Iterate over all lines in the output of the last command invoked with bats'
+# 'run' or the coproc helper and check if at least one is equal to $1.
+output_contains_line() {
+ local LINE=$1
+
+ for line in "${lines[@]}"
+ do
+ test "$line" = "$LINE" && return 0
+ done
+
+ return 1
+}
+
+# Same as above but match against the regex pattern in $1.
+output_regex_match() {
+ local PATTERN=$1
+
+ for line in "${lines[@]}"
+ do
+ regex_matches "$PATTERN" "$line" && return 0
+ done
+
+ return 1
+}
+
+# Probe the gpio-mockup kernel module. The routine expects a list of chip
+# sizes and optionally the 'named-lines' flag.
+gpio_mockup_probe() {
+ local CMDLINE="gpio_mockup_ranges="
+
+ for ARG in $*
+ do
+ if [ $ARG = "named-lines" ]
+ then
+ CMDLINE="gpio_mockup_named_lines $CMDLINE"
+ continue
+ fi
+
+ regex_matches "[0-9]+" "$ARG"
+
+ CMDLINE="$CMDLINE-1,$ARG,"
+ done
+
+ CMDLINE=${CMDLINE%?}
+
+ modprobe gpio-mockup $CMDLINE
+ udevadm settle
+}
+
+gpio_mockup_remove() {
+ if [ -d /sys/module/gpio_mockup ]
+ then
+ rmmod gpio-mockup
+ fi
+}
+
+gpio_mockup_chip_name() {
+ local CHIPNUM=$1
+
+ test -d /sys/devices/platform/gpio-mockup.$CHIPNUM/ || return 1
+ echo $(ls /sys/devices/platform/gpio-mockup.$CHIPNUM/ | grep gpiochip)
+}
+
+gpio_mockup_set_pull() {
+ local CHIPNUM=$1
+ local LINE=$2
+ local PULL=$3
+
+ FILE="/sys/kernel/debug/gpio-mockup/$(gpio_mockup_chip_name $CHIPNUM)/$LINE"
+ test -f $FILE || return 1
+ echo "$PULL" > $FILE
+}
+
+gpio_mockup_check_value() {
+ local CHIPNUM=$1
+ local LINE=$2
+ local EXPECTED=$3
+
+ FILE="/sys/kernel/debug/gpio-mockup/$(gpio_mockup_chip_name $CHIPNUM)/$LINE"
+ test -f $FILE || return 1
+
+ VAL=$(cat $FILE)
+ test $VAL -eq $EXPECTED || return 1
+}
+
+run_tool() {
+ # Executables to test are expected to be in the same directory as the
+ # testing script.
+ run timeout 10s $BATS_TEST_DIRNAME/"$@"
+}
+
+coproc_run_tool() {
+ rm -f $BR_PROC_OUTPUT
+ coproc timeout 10s $BATS_TEST_DIRNAME/"$@" > $COPROC_OUTPUT 2> $COPROC_OUTPUT
+ COPROC_SAVED_PID=$COPROC_PID
+ # FIXME We're giving the background process some time to get up, but really this
+ # should be more reliable...
+ sleep 0.2
+}
+
+coproc_tool_stdin_write() {
+ echo $* >&${COPROC[1]}
+}
+
+coproc_tool_kill() {
+ SIGNUM=$1
+
+ kill $SIGNUM $COPROC_SAVED_PID
+}
+
+coproc_tool_wait() {
+ status="0"
+ # A workaround for the way bats handles command failures.
+ wait $COPROC_SAVED_PID || export status=$?
+ test "$status" -ne 0 || export status="0"
+ output=$(cat $COPROC_OUTPUT)
+ local ORIG_IFS="$IFS"
+ IFS=$'\n' lines=($output)
+ IFS="$ORIG_IFS"
+ rm -f $COPROC_OUTPUT
+}
+
+setup() {
+ echo $BATS_TMPDIR >> /tmp/dirdir
+ gpio_mockup_remove
+}
+
+teardown() {
+ if [ -n "$BG_PROC_PID" ]
+ then
+ kill -9 $BG_PROC_PID
+ run wait $BG_PROC_PID
+ BG_PROC_PID=""
+ fi
+
+ gpio_mockup_remove
+}
+
+#
+# gpiodetect test cases
+#
+
+@test "gpiodetect: list chips" {
+ gpio_mockup_probe 4 8 16
+
+ run_tool gpiodetect
+
+ test "$status" -eq 0
+ output_contains_line "$(gpio_mockup_chip_name 0) [gpio-mockup-A] (4 lines)"
+ output_contains_line "$(gpio_mockup_chip_name 1) [gpio-mockup-B] (8 lines)"
+ output_contains_line "$(gpio_mockup_chip_name 2) [gpio-mockup-C] (16 lines)"
+}
+
+@test "gpiodetect: invalid args" {
+ run_tool gpiodetect unimplemented-arg
+ test "$status" -eq 1
+}
+
+#
+# gpioinfo test cases
+#
+
+@test "gpioinfo: dump all chips" {
+ gpio_mockup_probe 4 8
+
+ run_tool gpioinfo
+
+ test "$status" -eq 0
+ output_contains_line "$(gpio_mockup_chip_name 0) - 4 lines:"
+ output_contains_line "$(gpio_mockup_chip_name 1) - 8 lines:"
+
+ output_regex_match "\\s+line\\s+0:\\s+unnamed\\s+unused\\s+input\\s+active-high"
+ output_regex_match "\\s+line\\s+7:\\s+unnamed\\s+unused\\s+input\\s+active-high"
+}
+
+@test "gpioinfo: dump all chips with one line exported" {
+ gpio_mockup_probe 4 8
+
+ coproc_run_tool gpioset --mode=signal --active-low "$(gpio_mockup_chip_name 1)" 7=1
+
+ run_tool gpioinfo
+
+ test "$status" -eq 0
+ output_contains_line "$(gpio_mockup_chip_name 0) - 4 lines:"
+ output_contains_line "$(gpio_mockup_chip_name 1) - 8 lines:"
+ output_regex_match "\\s+line\\s+0:\\s+unnamed\\s+unused\\s+input\\s+active-high"
+ output_regex_match "\\s+line\\s+7:\\s+unnamed\\s+\\\"gpioset\\\"\\s+output\\s+active-low"
+
+ coproc_tool_kill
+ coproc_tool_wait
+}
+
+@test "gpioinfo: dump one chip" {
+ gpio_mockup_probe 8 4
+
+ run_tool gpioinfo "$(gpio_mockup_chip_name 1)"
+
+ test "$status" -eq 0
+ assert_fail output_contains_line "$(gpio_mockup_chip_name 0) - 8 lines:"
+ output_contains_line "$(gpio_mockup_chip_name 1) - 4 lines:"
+ output_regex_match "\\s+line\\s+0:\\s+unnamed\\s+unused\\s+input\\s+active-high"
+ assert_fail output_regex_match "\\s+line\\s+7:\\s+unnamed\\s+unused\\s+input\\s+active-high"
+}
+
+@test "gpioinfo: dump all but one chip" {
+ gpio_mockup_probe 4 4 8 4
+
+ run_tool gpioinfo "$(gpio_mockup_chip_name 0)" \
+ "$(gpio_mockup_chip_name 1)" "$(gpio_mockup_chip_name 3)"
+
+ test "$status" -eq 0
+ output_contains_line "$(gpio_mockup_chip_name 0) - 4 lines:"
+ output_contains_line "$(gpio_mockup_chip_name 1) - 4 lines:"
+ assert_fail output_contains_line "$(gpio_mockup_chip_name 2) - 8 lines:"
+ output_contains_line "$(gpio_mockup_chip_name 3) - 4 lines:"
+ output_regex_match "\\s+line\\s+0:\\s+unnamed\\s+unused\\s+input\\s+active-high"
+ assert_fail output_regex_match "\\s+line\\s+7:\\s+unnamed\\s+unused\\s+input\\s+active-high"
+}
+
+@test "gpioinfo: inexistent chip" {
+ run_tool gpioinfo "inexistent"
+
+ test "$status" -eq 1
+}
+
+#
+# gpiofind test cases
+#
+
+@test "gpiofind: line found" {
+ gpio_mockup_probe named-lines 4 8 16
+
+ run_tool gpiofind gpio-mockup-B-7
+
+ test "$status" -eq "0"
+ test "$output" = "$(gpio_mockup_chip_name 1) 7"
+}
+
+@test "gpiofind: line not found" {
+ gpio_mockup_probe named-lines 4 8 16
+
+ run_tool gpiofind nonexistent-line
+
+ test "$status" -eq "1"
+}
+
+@test "gpiofind: invalid args" {
+ run_tool gpiodetect unimplemented-arg
+ test "$status" -eq 1
+}
+
+#
+# gpioget test cases
+#
+
+@test "gpioget: read all lines" {
+ gpio_mockup_probe 8 8 8
+
+ gpio_mockup_set_pull 1 2 1
+ gpio_mockup_set_pull 1 3 1
+ gpio_mockup_set_pull 1 5 1
+ gpio_mockup_set_pull 1 7 1
+
+ run_tool gpioget "$(gpio_mockup_chip_name 1)" 0 1 2 3 4 5 6 7
+
+ test "$status" -eq "0"
+ test "$output" = "0 0 1 1 0 1 0 1"
+}
+
+@test "gpioget: read all lines (active-low)" {
+ gpio_mockup_probe 8 8 8
+
+ gpio_mockup_set_pull 1 2 1
+ gpio_mockup_set_pull 1 3 1
+ gpio_mockup_set_pull 1 5 1
+ gpio_mockup_set_pull 1 7 1
+
+ run_tool gpioget --active-low "$(gpio_mockup_chip_name 1)" 0 1 2 3 4 5 6 7
+
+ test "$status" -eq "0"
+ test "$output" = "1 1 0 0 1 0 1 0"
+}
+
+@test "gpioget: read some lines" {
+ gpio_mockup_probe 8 8 8
+
+ gpio_mockup_set_pull 1 1 1
+ gpio_mockup_set_pull 1 4 1
+ gpio_mockup_set_pull 1 6 1
+
+ run_tool gpioget "$(gpio_mockup_chip_name 1)" 0 1 4 6
+
+ test "$status" -eq "0"
+ test "$output" = "0 1 1 1"
+}
+
+@test "gpioget: no arguments" {
+ run_tool gpioget
+
+ test "$status" -eq "1"
+ output_regex_match ".*gpiochip must be specified"
+}
+
+@test "gpioget: no lines specified" {
+ gpio_mockup_probe 8 8 8
+
+ run_tool gpioget "$(gpio_mockup_chip_name 1)"
+
+ test "$status" -eq "1"
+ output_regex_match ".*at least one GPIO line offset must be specified"
+}
+
+@test "gpioget: too many lines specified" {
+ gpio_mockup_probe 4
+
+ run_tool gpioget "$(gpio_mockup_chip_name 1)" 0 1 2 3 4
+
+ test "$status" -eq "1"
+ output_regex_match ".*error reading GPIO values"
+}
+
+@test "gpioget: same line twice" {
+ gpio_mockup_probe 8 8 8
+
+ run_tool gpioget "$(gpio_mockup_chip_name 1)" 0 0
+
+ test "$status" -eq "1"
+ output_regex_match ".*error reading GPIO values.*"
+}
+
+#
+# gpioset test cases
+#
+
+@test "gpioset: set lines and wait for SIGTERM" {
+ gpio_mockup_probe 8 8 8
+
+ coproc_run_tool gpioset --mode=signal "$(gpio_mockup_chip_name 2)" \
+ 0=0 1=0 2=1 3=1 4=1 5=1 6=0 7=1
+
+ gpio_mockup_check_value 2 0 0
+ gpio_mockup_check_value 2 1 0
+ gpio_mockup_check_value 2 2 1
+ gpio_mockup_check_value 2 3 1
+ gpio_mockup_check_value 2 4 1
+ gpio_mockup_check_value 2 5 1
+ gpio_mockup_check_value 2 6 0
+ gpio_mockup_check_value 2 7 1
+
+ coproc_tool_kill
+ coproc_tool_wait
+
+ test "$status" -eq "0"
+}
+
+@test "gpioset: set lines and wait for SIGTERM (active-low)" {
+ gpio_mockup_probe 8 8 8
+
+ coproc_run_tool gpioset --active-low --mode=signal "$(gpio_mockup_chip_name 2)" \
+ 0=0 1=0 2=1 3=1 4=1 5=1 6=0 7=1
+
+ gpio_mockup_check_value 2 0 1
+ gpio_mockup_check_value 2 1 1
+ gpio_mockup_check_value 2 2 0
+ gpio_mockup_check_value 2 3 0
+ gpio_mockup_check_value 2 4 0
+ gpio_mockup_check_value 2 5 0
+ gpio_mockup_check_value 2 6 1
+ gpio_mockup_check_value 2 7 0
+
+ coproc_tool_kill
+ coproc_tool_wait
+
+ test "$status" -eq "0"
+}
+
+@test "gpioset: set some lines and wait for ENTER" {
+ gpio_mockup_probe 8 8 8
+
+ coproc_run_tool gpioset --mode=wait "$(gpio_mockup_chip_name 2)" \
+ 1=0 2=1 5=1 6=0 7=1
+
+ gpio_mockup_check_value 2 1 0
+ gpio_mockup_check_value 2 2 1
+ gpio_mockup_check_value 2 5 1
+ gpio_mockup_check_value 2 6 0
+ gpio_mockup_check_value 2 7 1
+
+ coproc_tool_stdin_write ""
+ coproc_tool_wait
+
+ test "$status" -eq "0"
+}
+
+@test "gpioset: set some lines and wait for SIGINT" {
+ gpio_mockup_probe 8
+
+ coproc_run_tool gpioset --mode=signal "$(gpio_mockup_chip_name 0)" 0=1
+
+ gpio_mockup_check_value 0 0 1
+
+ coproc_tool_kill -SIGINT
+ coproc_tool_wait
+
+ test "$status" -eq "0"
+}
+
+@test "gpioset: set some lines and wait with --mode=time" {
+ gpio_mockup_probe 8 8 8
+
+ coproc_run_tool gpioset --mode=time --sec=1 --usec=200000 \
+ "$(gpio_mockup_chip_name 1)" 0=1 5=0 7=1
+
+ gpio_mockup_check_value 1 0 1
+ gpio_mockup_check_value 1 5 0
+ gpio_mockup_check_value 1 7 1
+
+ coproc_tool_wait
+
+ test "$status" -eq "0"
+}
+
+@test "gpioset: no arguments" {
+ run_tool gpioset
+
+ test "$status" -eq "1"
+ output_regex_match ".*gpiochip must be specified"
+}
+
+@test "gpioset: no lines specified" {
+ gpio_mockup_probe 8 8 8
+
+ run_tool gpioset "$(gpio_mockup_chip_name 1)"
+
+ test "$status" -eq "1"
+ output_regex_match ".*at least one GPIO line offset to value mapping must be specified"
+}
+
+@test "gpioset: too many lines specified" {
+ gpio_mockup_probe 4
+
+ run_tool gpioset "$(gpio_mockup_chip_name 1)" 0=1 1=1 2=1 3=1 4=1 5=1
+
+ test "$status" -eq "1"
+ output_regex_match ".*error setting the GPIO line values"
+}
+
+@test "gpioset: use --sec without --mode=time" {
+ gpio_mockup_probe 8 8 8
+
+ run_tool gpioset --mode=exit --sec=1 "$(gpio_mockup_chip_name 1)" 0=1
+
+ test "$status" -eq "1"
+ output_regex_match ".*can't specify wait time in this mode"
+}
+
+@test "gpioset: use --usec without --mode=time" {
+ gpio_mockup_probe 8 8 8
+
+ run_tool gpioset --mode=exit --usec=1 "$(gpio_mockup_chip_name 1)" 0=1
+
+ test "$status" -eq "1"
+ output_regex_match ".*can't specify wait time in this mode"
+}
+
+@test "gpioset: invalid mapping" {
+ gpio_mockup_probe 8 8 8
+
+ run_tool gpioset "$(gpio_mockup_chip_name 1)" 0=c
+
+ test "$status" -eq "1"
+ output_regex_match ".*invalid offset<->value mapping"
+}
+
+@test "gpioset: invalid value" {
+ gpio_mockup_probe 8 8 8
+
+ run_tool gpioset "$(gpio_mockup_chip_name 1)" 0=3
+
+ test "$status" -eq "1"
+ output_regex_match ".*value must be 0 or 1"
+}
+
+@test "gpioset: invalid offset" {
+ gpio_mockup_probe 8 8 8
+
+ run_tool gpioset "$(gpio_mockup_chip_name 1)" 4000000000=0
+
+ test "$status" -eq "1"
+ output_regex_match ".*invalid offset"
+}
+
+@test "gpioset: daemonize in invalid mode" {
+ gpio_mockup_probe 8 8 8
+
+ run_tool gpioset --background "$(gpio_mockup_chip_name 1)" 0=1
+
+ test "$status" -eq "1"
+ output_regex_match ".*can't daemonize in this mode"
+}
+
+@test "gpioset: same line twice" {
+ gpio_mockup_probe 8 8 8
+
+ run_tool gpioset "$(gpio_mockup_chip_name 1)" 0=1 0=1
+
+ test "$status" -eq "1"
+ output_regex_match ".*error setting the GPIO line values.*"
+}
+
+#
+# gpiomon test cases
+#
+
+@test "gpiomon: single rising edge event" {
+ gpio_mockup_probe 8 8
+
+ coproc_run_tool gpiomon --rising-edge "$(gpio_mockup_chip_name 1)" 4
+
+ gpio_mockup_set_pull 1 4 1
+ sleep 0.2
+
+ coproc_tool_kill
+ coproc_tool_wait
+
+ test "$status" -eq "0"
+ output_regex_match \
+"event:\\s+RISING\\s+EDGE\\s+offset:\\s+4\\s+timestamp:\\s+\[[0-9]+\.[0-9]+\]"
+}
+
+@test "gpiomon: single falling edge event" {
+ gpio_mockup_probe 8 8
+
+ coproc_run_tool gpiomon --falling-edge "$(gpio_mockup_chip_name 1)" 4
+
+ gpio_mockup_set_pull 1 4 1
+ gpio_mockup_set_pull 1 4 0
+ sleep 0.2
+
+ coproc_tool_kill
+ coproc_tool_wait
+
+ test "$status" -eq "0"
+ output_regex_match \
+"event:\\s+FALLING\\s+EDGE\\s+offset:\\s+4\\s+timestamp:\\s+\[[0-9]+\.[0-9]+\]"
+}
+
+@test "gpiomon: single rising edge event (active-low)" {
+ gpio_mockup_probe 8 8
+
+ coproc_run_tool gpiomon --rising-edge --active-low "$(gpio_mockup_chip_name 1)" 4
+
+ gpio_mockup_set_pull 1 4 1
+ sleep 0.2
+
+ coproc_tool_kill
+ coproc_tool_wait
+
+ test "$status" -eq "0"
+ output_regex_match \
+"event:\\s+RISING\\s+EDGE\\s+offset:\\s+4\\s+timestamp:\\s+\[[0-9]+\.[0-9]+\]"
+
+}
+
+@test "gpiomon: single rising edge event (silent mode)" {
+ gpio_mockup_probe 8 8
+
+ coproc_run_tool gpiomon --rising-edge --silent "$(gpio_mockup_chip_name 1)" 4
+
+ gpio_mockup_set_pull 1 4 1
+ sleep 0.2
+
+ coproc_tool_kill
+ coproc_tool_wait
+
+ test "$status" -eq "0"
+ test -z "$output"
+}
+
+@test "gpiomon: four alternating events" {
+ gpio_mockup_probe 8 8 8
+
+ coproc_run_tool gpiomon --num-events=4 "$(gpio_mockup_chip_name 1)" 4
+
+ gpio_mockup_set_pull 1 4 1
+ sleep 0.2
+ gpio_mockup_set_pull 1 4 0
+ sleep 0.2
+ gpio_mockup_set_pull 1 4 1
+ sleep 0.2
+ gpio_mockup_set_pull 1 4 0
+ sleep 0.2
+
+ coproc_tool_wait
+
+ test "$status" -eq "0"
+ output_regex_match \
+"event\\:\\s+FALLING\\s+EDGE\\s+offset\\:\\s+4\\s+timestamp:\\s+\\[[0-9]+\\.[0-9]+\\]"
+ output_regex_match \
+"event\\:\\s+RISING\\s+EDGE\\s+offset\\:\\s+4\\s+timestamp:\\s+\\[[0-9]+\\.[0-9]+\\]"
+}
+
+@test "gpiomon: exit after SIGINT" {
+ gpio_mockup_probe 8 8 8
+
+ coproc_run_tool gpiomon "$(gpio_mockup_chip_name 1)" 4
+
+ coproc_tool_kill -SIGINT
+ coproc_tool_wait
+
+ test "$status" -eq "0"
+ test -z "$output"
+}
+
+@test "gpiomon: exit after SIGTERM" {
+ gpio_mockup_probe 8 8 8
+
+ coproc_run_tool gpiomon "$(gpio_mockup_chip_name 1)" 4
+
+ coproc_tool_kill -SIGTERM
+ coproc_tool_wait
+
+ test "$status" -eq "0"
+ test -z "$output"
+}
+
+@test "gpiomon: both event flags" {
+ gpio_mockup_probe 8 8 8
+
+ coproc_run_tool gpiomon --falling-edge --rising-edge "$(gpio_mockup_chip_name 1)" 4
+
+ gpio_mockup_set_pull 1 4 1
+ sleep 0.2
+ gpio_mockup_set_pull 1 4 0
+ sleep 0.2
+
+ coproc_tool_kill
+ coproc_tool_wait
+
+ test "$status" -eq "0"
+ output_regex_match \
+"event\\:\\s+FALLING\\s+EDGE\\s+offset\\:\\s+4\\s+timestamp:\\s+\\[[0-9]+\\.[0-9]+\\]"
+ output_regex_match \
+"event\\:\\s+RISING\\s+EDGE\\s+offset\\:\\s+4\\s+timestamp:\\s+\\[[0-9]+\\.[0-9]+\\]"
+}
+
+@test "gpiomon: watch multiple lines" {
+ gpio_mockup_probe 8 8 8
+
+ coproc_run_tool gpiomon --format=%o "$(gpio_mockup_chip_name 1)" 1 2 3 4 5
+
+ gpio_mockup_set_pull 1 2 1
+ gpio_mockup_set_pull 1 3 1
+ gpio_mockup_set_pull 1 4 1
+ sleep 0.2
+
+ coproc_tool_kill
+ coproc_tool_wait
+
+ test "$status" -eq "0"
+ test "${lines[0]}" = "2"
+ test "${lines[1]}" = "3"
+ test "${lines[2]}" = "4"
+}
+
+@test "gpiomon: watch multiple lines (lines in mixed-up order)" {
+ gpio_mockup_probe 8 8 8
+
+ coproc_run_tool gpiomon --format=%o "$(gpio_mockup_chip_name 1)" 5 2 7 1 6
+
+ gpio_mockup_set_pull 1 2 1
+ gpio_mockup_set_pull 1 1 1
+ gpio_mockup_set_pull 1 6 1
+ sleep 0.2
+
+ coproc_tool_kill
+ coproc_tool_wait
+
+ test "$status" -eq "0"
+ test "${lines[0]}" = "2"
+ test "${lines[1]}" = "1"
+ test "${lines[2]}" = "6"
+}
+
+@test "gpiomon: same line twice" {
+ gpio_mockup_probe 8 8 8
+
+ run_tool gpiomon "$(gpio_mockup_chip_name 1)" 0 0
+
+ test "$status" -eq "1"
+ output_regex_match ".*error waiting for events.*"
+}
+
+@test "gpiomon: no arguments" {
+ run_tool gpiomon
+
+ test "$status" -eq "1"
+ output_regex_match ".*gpiochip must be specified"
+}
+
+@test "gpiomon: line not specified" {
+ gpio_mockup_probe 8 8 8
+
+ run_tool gpiomon "$(gpio_mockup_chip_name 1)"
+
+ test "$status" -eq "1"
+ output_regex_match ".*GPIO line offset must be specified"
+}
+
+@test "gpiomon: line out of range" {
+ gpio_mockup_probe 4
+
+ run_tool gpiomon "$(gpio_mockup_chip_name 0)" 5
+
+ test "$status" -eq "1"
+ output_regex_match ".*error waiting for events"
+}
+
+@test "gpiomon: custom format (event type + offset)" {
+ gpio_mockup_probe 8 8 8
+
+ coproc_run_tool gpiomon "--format=%e %o" "$(gpio_mockup_chip_name 1)" 4
+
+ gpio_mockup_set_pull 1 4 1
+ sleep 0.2
+
+ coproc_tool_kill
+ coproc_tool_wait
+
+ test "$status" -eq "0"
+ test "$output" = "1 4"
+}
+
+@test "gpiomon: custom format (event type + offset joined)" {
+ gpio_mockup_probe 8 8 8
+
+ coproc_run_tool gpiomon "--format=%e%o" "$(gpio_mockup_chip_name 1)" 4
+
+ gpio_mockup_set_pull 1 4 1
+ sleep 0.2
+
+ coproc_tool_kill
+ coproc_tool_wait
+
+ test "$status" -eq "0"
+ test "$output" = "14"
+}
+
+@test "gpiomon: custom format (timestamp)" {
+ gpio_mockup_probe 8 8 8
+
+ coproc_run_tool gpiomon "--format=%e %o %s.%n" "$(gpio_mockup_chip_name 1)" 4
+
+ gpio_mockup_set_pull 1 4 1
+ sleep 0.2
+
+ coproc_tool_kill
+ coproc_tool_wait
+
+ test "$status" -eq "0"
+ output_regex_match "1 4 [0-9]+\\.[0-9]+"
+}
+
+@test "gpiomon: custom format (double percent sign)" {
+ gpio_mockup_probe 8 8 8
+
+ coproc_run_tool gpiomon "--format=%%" "$(gpio_mockup_chip_name 1)" 4
+
+ gpio_mockup_set_pull 1 4 1
+ sleep 0.2
+
+ coproc_tool_kill
+ coproc_tool_wait
+
+ test "$status" -eq "0"
+ test "$output" = "%"
+}
+
+@test "gpiomon: custom format (double percent sign + event type specifier)" {
+ gpio_mockup_probe 8 8 8
+
+ coproc_run_tool gpiomon "--format=%%e" "$(gpio_mockup_chip_name 1)" 4
+
+ gpio_mockup_set_pull 1 4 1
+ sleep 0.2
+
+ coproc_tool_kill
+ coproc_tool_wait
+
+ test "$status" -eq "0"
+ test "$output" = "%e"
+}
+
+@test "gpiomon: custom format (single percent sign)" {
+ gpio_mockup_probe 8 8 8
+
+ coproc_run_tool gpiomon "--format=%" "$(gpio_mockup_chip_name 1)" 4
+
+ gpio_mockup_set_pull 1 4 1
+ sleep 0.2
+
+ coproc_tool_kill
+ coproc_tool_wait
+
+ test "$status" -eq "0"
+ test "$output" = "%"
+}
+
+@test "gpiomon: custom format (single percent sign between other characters)" {
+ gpio_mockup_probe 8 8 8
+
+ coproc_run_tool gpiomon "--format=foo % bar" "$(gpio_mockup_chip_name 1)" 4
+
+ gpio_mockup_set_pull 1 4 1
+ sleep 0.2
+
+ coproc_tool_kill
+ coproc_tool_wait
+
+ test "$status" -eq "0"
+ test "$output" = "foo % bar"
+}
+
+@test "gpiomon: custom format (unknown specifier)" {
+ gpio_mockup_probe 8 8 8
+
+ coproc_run_tool gpiomon "--format=%x" "$(gpio_mockup_chip_name 1)" 4
+
+ gpio_mockup_set_pull 1 4 1
+ sleep 0.2
+
+ coproc_tool_kill
+ coproc_tool_wait
+
+ test "$status" -eq "0"
+ test "$output" = "%x"
+}