]> Kevux Git Server - fll/commitdiff
Update: Add unit tests for f_signal project.
authorKevin Day <thekevinday@gmail.com>
Wed, 8 Jun 2022 04:46:30 +0000 (23:46 -0500)
committerKevin Day <thekevinday@gmail.com>
Wed, 8 Jun 2022 04:46:30 +0000 (23:46 -0500)
34 files changed:
level_0/f_signal/data/build/dependencies-tests [new file with mode: 0644]
level_0/f_signal/data/build/settings-mocks [new file with mode: 0644]
level_0/f_signal/data/build/settings-tests [new file with mode: 0644]
level_0/f_signal/data/build/testfile [new file with mode: 0644]
level_0/f_signal/tests/unit/c/mock-signal.c [new file with mode: 0644]
level_0/f_signal/tests/unit/c/mock-signal.h [new file with mode: 0644]
level_0/f_signal/tests/unit/c/test-signal-close.c [new file with mode: 0644]
level_0/f_signal/tests/unit/c/test-signal-close.h [new file with mode: 0644]
level_0/f_signal/tests/unit/c/test-signal-mask.c [new file with mode: 0644]
level_0/f_signal/tests/unit/c/test-signal-mask.h [new file with mode: 0644]
level_0/f_signal/tests/unit/c/test-signal-open.c [new file with mode: 0644]
level_0/f_signal/tests/unit/c/test-signal-open.h [new file with mode: 0644]
level_0/f_signal/tests/unit/c/test-signal-queue.c [new file with mode: 0644]
level_0/f_signal/tests/unit/c/test-signal-queue.h [new file with mode: 0644]
level_0/f_signal/tests/unit/c/test-signal-read.c [new file with mode: 0644]
level_0/f_signal/tests/unit/c/test-signal-read.h [new file with mode: 0644]
level_0/f_signal/tests/unit/c/test-signal-send.c [new file with mode: 0644]
level_0/f_signal/tests/unit/c/test-signal-send.h [new file with mode: 0644]
level_0/f_signal/tests/unit/c/test-signal-set_add.c [new file with mode: 0644]
level_0/f_signal/tests/unit/c/test-signal-set_add.h [new file with mode: 0644]
level_0/f_signal/tests/unit/c/test-signal-set_delete.c [new file with mode: 0644]
level_0/f_signal/tests/unit/c/test-signal-set_delete.h [new file with mode: 0644]
level_0/f_signal/tests/unit/c/test-signal-set_empty.c [new file with mode: 0644]
level_0/f_signal/tests/unit/c/test-signal-set_empty.h [new file with mode: 0644]
level_0/f_signal/tests/unit/c/test-signal-set_fill.c [new file with mode: 0644]
level_0/f_signal/tests/unit/c/test-signal-set_fill.h [new file with mode: 0644]
level_0/f_signal/tests/unit/c/test-signal-set_has.c [new file with mode: 0644]
level_0/f_signal/tests/unit/c/test-signal-set_has.h [new file with mode: 0644]
level_0/f_signal/tests/unit/c/test-signal-wait.c [new file with mode: 0644]
level_0/f_signal/tests/unit/c/test-signal-wait.h [new file with mode: 0644]
level_0/f_signal/tests/unit/c/test-signal-wait_until.c [new file with mode: 0644]
level_0/f_signal/tests/unit/c/test-signal-wait_until.h [new file with mode: 0644]
level_0/f_signal/tests/unit/c/test-signal.c [new file with mode: 0644]
level_0/f_signal/tests/unit/c/test-signal.h [new file with mode: 0644]

diff --git a/level_0/f_signal/data/build/dependencies-tests b/level_0/f_signal/data/build/dependencies-tests
new file mode 100644 (file)
index 0000000..dea3179
--- /dev/null
@@ -0,0 +1,3 @@
+# fss-0001
+
+cmocka 1.*
diff --git a/level_0/f_signal/data/build/settings-mocks b/level_0/f_signal/data/build/settings-mocks
new file mode 100644 (file)
index 0000000..e942368
--- /dev/null
@@ -0,0 +1,74 @@
+# fss-0001
+#
+# Build the project with appropriate mocks linked in via the dynamic linker's "--wrap" functionality.
+#
+# The -Wl,--wrap does not work across shared files.
+# Therefore, this file is a work-around to inject the mocks into the library for testing purposes.
+# This should exactly match the "settings" file, except for the additional "-Wl,--wrap" parts and the additional mock source file.
+#
+# The flags -o0 must be passed to prevent the compiler from optimizing away any functions being mocked (which results in the mock not happening and a real function being called).
+# Alternatively, figure out which optimization that is disabled by -o0 and have that specific optimization disabled.
+#
+
+build_name f_signal
+
+version_major 0
+version_minor 5
+version_micro 10
+version_file micro
+version_target minor
+
+modes individual clang test coverage
+modes_default individual test
+
+build_compiler gcc
+build_compiler-clang clang
+build_indexer ar
+build_indexer_arguments rcs
+build_language c
+
+build_libraries -lc
+build_libraries-individual -lf_memory -lf_string
+
+build_sources_library signal.c ../../tests/unit/c/mock-signal.c
+
+build_sources_headers signal.h signal/common.h
+
+build_script yes
+build_shared yes
+build_static no
+
+path_headers fll/level_0
+path_library_script script
+path_library_shared shared
+path_library_static static
+
+has_path_standard yes
+preserve_path_headers yes
+
+search_exclusive yes
+search_shared yes
+search_static yes
+
+flags -O0 -z now -g -fdiagnostics-color=always -Wno-logical-not-parentheses -Wno-parentheses
+flags-clang -Wno-logical-op-parentheses
+flags-test -fstack-protector -Wall -Wno-missing-braces
+flags-coverage --coverage -fprofile-abs-path -fprofile-dir=build/coverage/
+
+flags_library -fPIC
+
+# Inject mocks.
+flags -Wl,--wrap=close
+flags -Wl,--wrap=kill
+flags -Wl,--wrap=poll
+flags -Wl,--wrap=read
+flags -Wl,--wrap=sigaddset
+flags -Wl,--wrap=sigdelset
+flags -Wl,--wrap=sigemptyset
+flags -Wl,--wrap=sigfillset
+flags -Wl,--wrap=sigismember
+flags -Wl,--wrap=signalfd
+flags -Wl,--wrap=sigprocmask
+flags -Wl,--wrap=sigqueue
+flags -Wl,--wrap=sigtimedwait
+flags -Wl,--wrap=sigwaitinfo
diff --git a/level_0/f_signal/data/build/settings-tests b/level_0/f_signal/data/build/settings-tests
new file mode 100644 (file)
index 0000000..9c3f2be
--- /dev/null
@@ -0,0 +1,54 @@
+# fss-0001
+#
+# Builds a program that is links to the generated library and is executed to perform tests.
+#
+# Memory leaks in the test program can be checked for by running valgrind with this executable.
+#
+
+build_name test-f_signal
+
+version_major 0
+version_minor 5
+version_micro 10
+version_file major
+version_target major
+
+modes individual clang test coverage
+modes_default individual test
+
+build_compiler gcc
+build_compiler-clang clang
+build_indexer ar
+build_indexer_arguments rcs
+build_language c
+
+build_libraries -lc -lcmocka
+build_libraries-individual -lf_memory -lf_string -lf_signal
+
+build_sources_program test-signal-close.c test-signal-mask.c test-signal-open.c test-signal-queue.c test-signal-read.c test-signal-send.c test-signal-set_add.c test-signal-set_delete.c test-signal-set_empty.c test-signal-set_fill.c test-signal-set_has.c test-signal-wait.c test-signal-wait_until.c
+build_sources_program test-signal.c
+
+build_script no
+build_shared yes
+build_static no
+
+path_headers tests/unit/c
+path_sources tests/unit/c
+
+has_path_standard no
+preserve_path_headers yes
+
+search_exclusive yes
+search_shared yes
+search_static yes
+
+defines -Ibuild/includes
+defines_static -Lbuild/libraries/static
+defines_shared -Lbuild/libraries/shared
+
+flags -O2 -z now -g -fdiagnostics-color=always -Wno-logical-not-parentheses -Wno-parentheses
+flags-clang -Wno-logical-op-parentheses
+flags-test -fstack-protector -Wall -Wno-missing-braces
+flags-coverage -O0 --coverage -fprofile-abs-path -fprofile-dir=build/coverage/
+
+flags_program -fPIE
diff --git a/level_0/f_signal/data/build/testfile b/level_0/f_signal/data/build/testfile
new file mode 100644 (file)
index 0000000..d88ba07
--- /dev/null
@@ -0,0 +1,55 @@
+# fss-0005 iki-0002
+
+settings:
+  load_build yes
+  fail exit
+
+  environment LD_LIBRARY_PATH
+  environment CMOCKA_XML_FILE CMOCKA_MESSAGE_OUTPUT CMOCKA_TEST_ABORT
+
+  # Cmcka is not fully thread-safe, set this to "1" to have cmocka call abort() on a test failure.
+  #CMOCKA_TEST_ABORT 1
+
+  # One of: STDOUT, SUBUNIT, TAP, or XML.
+  #define CMOCKA_MESSAGE_OUTPUT STDOUT
+
+  # When in "XML" output mode, output to this file rather than stdout.
+  #define CMOCKA_XML_FILE ./out.xml
+
+main:
+  build settings-mocks individual test
+  build settings-tests individual test
+
+  operate ld_library_path
+
+  if exists build/programs/shared/test-f_signal
+    shell build/programs/shared/test-f_signal
+
+  if exists build/programs/static/test-f_signal
+    shell build/programs/static/test-f_signal
+
+  if not exists build/programs/shared/test-f_signal
+  and not exists build/programs/static/test-f_signal
+    operate not_created
+
+not_created:
+  print
+  print 'context:"error"Failed to test due to being unable to find either a shared or static test binary to perform tests. context:"reset"'
+
+  exit failure
+
+ld_library_path:
+  if defined environment LD_LIBRARY_PATH
+  and defined parameter work
+    define LD_LIBRARY_PATH 'build/libraries/shared:parameter:"work:value"libraries/shared:define:"LD_LIBRARY_PATH"'
+
+  else
+  if defined environment LD_LIBRARY_PATH
+    define LD_LIBRARY_PATH 'build/libraries/shared:parameter:define:"LD_LIBRARY_PATH"'
+
+  else
+  if defined parameter work
+    define LD_LIBRARY_PATH 'build/libraries/shared:parameter:"work:value"libraries/shared'
+
+  else
+    define LD_LIBRARY_PATH build/libraries/shared
diff --git a/level_0/f_signal/tests/unit/c/mock-signal.c b/level_0/f_signal/tests/unit/c/mock-signal.c
new file mode 100644 (file)
index 0000000..6bf8978
--- /dev/null
@@ -0,0 +1,193 @@
+#include "mock-signal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int __wrap_close(int fd) {
+
+  const bool failure = mock_type(bool);
+
+  if (failure) {
+    errno = mock_type(int);
+
+    return -1;
+  }
+
+  return 0;
+}
+
+int __wrap_kill(pid_t pid, int sig) {
+
+  const bool failure = mock_type(bool);
+
+  if (failure) {
+    errno = mock_type(int);
+
+    return -1;
+  }
+
+  return 0;
+}
+
+int __wrap_poll(struct pollfd *fds, nfds_t nfds, int timeout) {
+
+  const bool failure = mock_type(bool);
+
+  if (failure) {
+    errno = mock_type(int);
+
+    return -1;
+  }
+
+  fds->revents = mock_type(short);
+
+  return mock_type(int);
+}
+
+ssize_t __wrap_read(int fd, void *buf, size_t count) {
+
+  const bool failure = mock_type(bool);
+
+  if (failure) {
+    errno = mock_type(int);
+
+    return -1;
+  }
+
+  return mock_type(int);
+}
+
+int __wrap_sigaddset(sigset_t *set, int signum) {
+
+  const bool failure = mock_type(bool);
+
+  if (failure) {
+    errno = mock_type(int);
+
+    return -1;
+  }
+
+  return 0;
+}
+
+int __wrap_sigdelset(sigset_t *set, int signum) {
+
+  const bool failure = mock_type(bool);
+
+  if (failure) {
+    errno = mock_type(int);
+
+    return -1;
+  }
+
+  return 0;
+}
+
+int __wrap_sigemptyset(sigset_t *set) {
+
+  const bool failure = mock_type(bool);
+
+  if (failure) {
+    errno = mock_type(int);
+
+    return -1;
+  }
+
+  return 0;
+}
+
+int __wrap_sigfillset(sigset_t *set) {
+
+  const bool failure = mock_type(bool);
+
+  if (failure) {
+    errno = mock_type(int);
+
+    return -1;
+  }
+
+  return 0;
+}
+
+int __wrap_sigismember(const sigset_t *set, int signum) {
+
+  const bool failure = mock_type(bool);
+
+  if (failure) {
+    errno = mock_type(int);
+
+    return -1;
+  }
+
+  return mock_type(int);
+}
+
+int __wrap_signalfd(int fd, const sigset_t *mask, int flags) {
+
+  const bool failure = mock_type(bool);
+
+  if (failure) {
+    errno = mock_type(int);
+
+    return -1;
+  }
+
+  return mock_type(int);
+}
+
+int __wrap_sigprocmask(int how, const sigset_t *set, sigset_t *oldset) {
+
+  const bool failure = mock_type(bool);
+
+  if (failure) {
+    errno = mock_type(int);
+
+    return -1;
+  }
+
+  return 0;
+}
+
+int __wrap_sigqueue(pid_t pid, int sig, const union sigval value) {
+
+  const bool failure = mock_type(bool);
+
+  if (failure) {
+    errno = mock_type(int);
+
+    return -1;
+  }
+
+  return 0;
+}
+
+int __wrap_sigtimedwait(const sigset_t *set, siginfo_t *info, const struct timespec *timeout) {
+
+  const bool failure = mock_type(bool);
+
+  if (failure) {
+    errno = mock_type(int);
+
+    return -1;
+  }
+
+  return 0;
+}
+
+int __wrap_sigwaitinfo(const sigset_t *set, siginfo_t *info) {
+
+  const bool failure = mock_type(bool);
+
+  if (failure) {
+    errno = mock_type(int);
+
+    return -1;
+  }
+
+  return 0;
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_signal/tests/unit/c/mock-signal.h b/level_0/f_signal/tests/unit/c/mock-signal.h
new file mode 100644 (file)
index 0000000..93c7d2e
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Account
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the signal project.
+ */
+#ifndef _MOCK__signal_h
+#define _MOCK__signal_h
+
+// Libc includes.
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <stdint.h>
+
+// cmocka includes.
+#include <cmocka.h>
+
+// FLL-0 includes.
+#include <fll/level_0/signal.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+const static int mock_errno_generic = 32767;
+
+extern int __wrap_close(int fd);
+extern int __wrap_kill(pid_t pid, int sig);
+extern int __wrap_poll(struct pollfd *fds, nfds_t nfds, int timeout);
+extern ssize_t __wrap_read(int fd, void *buf, size_t count);
+extern int __wrap_sigaddset(sigset_t *set, int signum);
+extern int __wrap_sigdelset(sigset_t *set, int signum);
+extern int __wrap_sigemptyset(sigset_t *set);
+extern int __wrap_sigfillset(sigset_t *set);
+extern int __wrap_sigismember(const sigset_t *set, int signum);
+extern int __wrap_signalfd(int fd, const sigset_t *mask, int flags);
+extern int __wrap_sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
+extern int __wrap_sigqueue(pid_t pid, int sig, const union sigval value);
+extern int __wrap_sigtimedwait(const sigset_t *set, siginfo_t *info, const struct timespec *timeout);
+extern int __wrap_sigwaitinfo(const sigset_t *set, siginfo_t *info);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _MOCK__signal_h
diff --git a/level_0/f_signal/tests/unit/c/test-signal-close.c b/level_0/f_signal/tests/unit/c/test-signal-close.c
new file mode 100644 (file)
index 0000000..910b457
--- /dev/null
@@ -0,0 +1,65 @@
+#include "test-signal.h"
+#include "test-signal-close.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_signal_close__fails(void **state) {
+
+  f_signal_t signal = f_signal_t_initialize;
+
+  int errnos[] = {
+    EBADF,
+    EDQUOT,
+    EINTR,
+    EIO,
+    ENOSPC,
+    mock_errno_generic,
+  };
+
+  f_status_t statuss[] = {
+    F_descriptor,
+    F_filesystem_quota_block,
+    F_interrupt,
+    F_input_output,
+    F_parameter,
+    F_failure,
+  };
+
+  for (int i = 0; i < 6; ++i) {
+
+    will_return(__wrap_close, true);
+    will_return(__wrap_close, errnos[i]);
+
+    const f_status_t status = f_signal_close(&signal);
+
+    assert_int_equal(status, F_status_set_error(statuss[i]));
+  } // for
+}
+
+void test__f_signal_close__parameter_checking(void **state) {
+
+  {
+    const f_status_t status = f_signal_close(0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+  }
+}
+
+void test__f_signal_close__works(void **state) {
+
+  f_signal_t signal = f_signal_t_initialize;
+
+  {
+    will_return(__wrap_close, false);
+
+    const f_status_t status = f_signal_close(&signal);
+
+    assert_int_equal(status, F_none);
+  }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_signal/tests/unit/c/test-signal-close.h b/level_0/f_signal/tests/unit/c/test-signal-close.h
new file mode 100644 (file)
index 0000000..d1982c5
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Signal
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the signal project.
+ */
+#ifndef _TEST__F_signal_close_h
+#define _TEST__F_signal_close_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_signal_close()
+ */
+extern void test__f_signal_close__fails(void **state);
+
+/**
+ * Test that parameter checking works as expected.
+ *
+ * @see f_signal_close()
+ */
+extern void test__f_signal_close__parameter_checking(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_signal_close()
+ */
+extern void test__f_signal_close__works(void **state);
+
+#endif // _TEST__F_signal_close_h
diff --git a/level_0/f_signal/tests/unit/c/test-signal-mask.c b/level_0/f_signal/tests/unit/c/test-signal-mask.c
new file mode 100644 (file)
index 0000000..c227755
--- /dev/null
@@ -0,0 +1,67 @@
+#include "test-signal.h"
+#include "test-signal-mask.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_signal_mask__fails(void **state) {
+
+  int errnos[] = {
+    EFAULT,
+    EINVAL,
+    mock_errno_generic,
+  };
+
+  f_status_t statuss[] = {
+    F_buffer,
+    F_parameter,
+    F_failure,
+  };
+
+  for (int i = 0; i < 3; ++i) {
+
+    sigset_t next;
+    sigset_t current;
+
+    memset(&next, 0, sizeof(sigset_t));
+    memset(&current, 0, sizeof(sigset_t));
+
+    will_return(__wrap_sigprocmask, true);
+    will_return(__wrap_sigprocmask, errnos[i]);
+
+    const f_status_t status = f_signal_mask(0, &next, &current);
+
+    assert_int_equal(status, F_status_set_error(statuss[i]));
+  } // for
+}
+
+void test__f_signal_mask__parameter_checking(void **state) {
+
+  {
+    const f_status_t status = f_signal_mask(0, 0, 0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+  }
+}
+
+void test__f_signal_mask__works(void **state) {
+
+  {
+    sigset_t next;
+    sigset_t current;
+
+    memset(&next, 0, sizeof(sigset_t));
+    memset(&current, 0, sizeof(sigset_t));
+
+    will_return(__wrap_sigprocmask, false);
+
+    const f_status_t status = f_signal_mask(0, &next, &current);
+
+    assert_int_equal(status, F_none);
+  }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_signal/tests/unit/c/test-signal-mask.h b/level_0/f_signal/tests/unit/c/test-signal-mask.h
new file mode 100644 (file)
index 0000000..6208d99
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Signal
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the signal project.
+ */
+#ifndef _TEST__F_signal_mask_h
+#define _TEST__F_signal_mask_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_signal_mask()
+ */
+extern void test__f_signal_mask__fails(void **state);
+
+/**
+ * Test that parameter checking works as expected.
+ *
+ * @see f_signal_mask()
+ */
+extern void test__f_signal_mask__parameter_checking(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_signal_mask()
+ */
+extern void test__f_signal_mask__works(void **state);
+
+#endif // _TEST__F_signal_mask_h
diff --git a/level_0/f_signal/tests/unit/c/test-signal-open.c b/level_0/f_signal/tests/unit/c/test-signal-open.c
new file mode 100644 (file)
index 0000000..4d90a75
--- /dev/null
@@ -0,0 +1,68 @@
+#include "test-signal.h"
+#include "test-signal-open.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_signal_open__fails(void **state) {
+
+  f_signal_t signal = f_signal_t_initialize;
+
+  int errnos[] = {
+    EINVAL,
+    EMFILE,
+    ENFILE,
+    ENODEV,
+    ENOMEM,
+    mock_errno_generic,
+  };
+
+  f_status_t statuss[] = {
+    F_parameter,
+    F_file_descriptor_max,
+    F_file_open_max,
+    F_device,
+    F_memory_not,
+    F_failure,
+  };
+
+  for (int i = 0; i < 6; ++i) {
+
+    will_return(__wrap_signalfd, true);
+    will_return(__wrap_signalfd, errnos[i]);
+
+    const f_status_t status = f_signal_open(&signal);
+
+    assert_int_equal(status, F_status_set_error(statuss[i]));
+  } // for
+}
+
+void test__f_signal_open__parameter_checking(void **state) {
+
+  {
+    const f_status_t status = f_signal_open(0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+  }
+}
+
+void test__f_signal_open__works(void **state) {
+
+  f_signal_t signal = f_signal_t_initialize;
+
+  {
+    const int id = 1;
+    will_return(__wrap_signalfd, false);
+    will_return(__wrap_signalfd, id);
+
+    const f_status_t status = f_signal_open(&signal);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(signal.id, id);
+  }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_signal/tests/unit/c/test-signal-open.h b/level_0/f_signal/tests/unit/c/test-signal-open.h
new file mode 100644 (file)
index 0000000..a6bd4ea
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Signal
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the signal project.
+ */
+#ifndef _TEST__F_signal_open_h
+#define _TEST__F_signal_open_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_signal_open()
+ */
+extern void test__f_signal_open__fails(void **state);
+
+/**
+ * Test that parameter checking works as expected.
+ *
+ * @see f_signal_open()
+ */
+extern void test__f_signal_open__parameter_checking(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_signal_open()
+ */
+extern void test__f_signal_open__works(void **state);
+
+#endif // _TEST__F_signal_open_h
diff --git a/level_0/f_signal/tests/unit/c/test-signal-queue.c b/level_0/f_signal/tests/unit/c/test-signal-queue.c
new file mode 100644 (file)
index 0000000..34a575e
--- /dev/null
@@ -0,0 +1,58 @@
+#include "test-signal.h"
+#include "test-signal-queue.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_signal_queue__fails(void **state) {
+
+  union sigval value;
+
+  memset(&value, 0, sizeof(union sigval));
+
+  int errnos[] = {
+    EAGAIN,
+    ENOSYS,
+    EINVAL,
+    ESRCH,
+    mock_errno_generic,
+  };
+
+  f_status_t statuss[] = {
+    F_resource_not,
+    F_supported_not,
+    F_parameter,
+    F_found_not,
+    F_failure,
+  };
+
+  for (int i = 0; i < 5; ++i) {
+
+    will_return(__wrap_sigqueue, true);
+    will_return(__wrap_sigqueue, errnos[i]);
+
+    const f_status_t status = f_signal_queue(0, 0, value);
+
+    assert_int_equal(status, F_status_set_error(statuss[i]));
+  } // for
+}
+
+void test__f_signal_queue__works(void **state) {
+
+  union sigval value;
+
+  memset(&value, 0, sizeof(union sigval));
+
+  {
+    will_return(__wrap_sigqueue, false);
+
+    const f_status_t status = f_signal_queue(0, 0, value);
+
+    assert_int_equal(status, F_none);
+  }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_signal/tests/unit/c/test-signal-queue.h b/level_0/f_signal/tests/unit/c/test-signal-queue.h
new file mode 100644 (file)
index 0000000..56509fc
--- /dev/null
@@ -0,0 +1,27 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Signal
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the signal project.
+ */
+#ifndef _TEST__F_signal_queue_h
+#define _TEST__F_signal_queue_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_signal_queue()
+ */
+extern void test__f_signal_queue__fails(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_signal_queue()
+ */
+extern void test__f_signal_queue__works(void **state);
+
+#endif // _TEST__F_signal_queue_h
diff --git a/level_0/f_signal/tests/unit/c/test-signal-read.c b/level_0/f_signal/tests/unit/c/test-signal-read.c
new file mode 100644 (file)
index 0000000..4198f9c
--- /dev/null
@@ -0,0 +1,140 @@
+#include "test-signal.h"
+#include "test-signal-read.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_signal_read__fails(void **state) {
+
+  f_signal_t signal = f_signal_t_initialize;
+
+  {
+    int errnos[] = {
+      EFAULT,
+      EINTR,
+      EINVAL,
+      ENOMEM,
+      mock_errno_generic,
+    };
+
+    f_status_t statuss[] = {
+      F_buffer,
+      F_interrupt,
+      F_parameter,
+      F_memory_not,
+      F_failure,
+    };
+
+    struct signalfd_siginfo information;
+
+    memset(&information, 0, sizeof(struct signalfd_siginfo));
+
+    for (int i = 0; i < 5; ++i) {
+
+      will_return(__wrap_poll, true);
+      will_return(__wrap_poll, errnos[i]);
+
+      const f_status_t status = f_signal_read(signal, 0, &information);
+
+      assert_int_equal(status, F_status_set_error(statuss[i]));
+    } // for
+  }
+
+  {
+    int errnos[] = {
+      EAGAIN,
+      EBADF,
+      EFAULT,
+      EINTR,
+      EINVAL,
+      EIO,
+      EISDIR,
+      EWOULDBLOCK,
+      mock_errno_generic,
+    };
+
+    f_status_t statuss[] = {
+      F_block,
+      F_descriptor,
+      F_buffer,
+      F_interrupt,
+      F_parameter,
+      F_input_output,
+      F_file_type_directory,
+      F_block,
+      F_failure,
+    };
+
+    struct signalfd_siginfo information;
+
+    memset(&information, 0, sizeof(struct signalfd_siginfo));
+
+    for (int i = 0; i < 9; ++i) {
+
+      will_return(__wrap_poll, false);
+      will_return(__wrap_poll, POLLIN);
+      will_return(__wrap_poll, 1);
+
+      will_return(__wrap_read, true);
+      will_return(__wrap_read, errnos[i]);
+
+      const f_status_t status = f_signal_read(signal, 0, &information);
+
+      assert_int_equal(status, F_status_set_error(statuss[i]));
+    } // for
+  }
+}
+
+void test__f_signal_read__parameter_checking(void **state) {
+
+  f_signal_t signal = f_signal_t_initialize;
+
+  {
+    const f_status_t status = f_signal_read(signal, 0, 0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+  }
+}
+
+void test__f_signal_read__works(void **state) {
+
+  {
+    f_signal_t signal = f_signal_t_initialize;
+    struct signalfd_siginfo information;
+
+    memset(&information, 0, sizeof(struct signalfd_siginfo));
+
+    will_return(__wrap_poll, false);
+    will_return(__wrap_poll, 0);
+    will_return(__wrap_poll, 0);
+
+    const f_status_t status = f_signal_read(signal, 0, &information);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(signal.id, -1);
+  }
+
+  {
+    f_signal_t signal = f_signal_t_initialize;
+    signal.id = 1;
+    struct signalfd_siginfo information;
+
+    memset(&information, 0, sizeof(struct signalfd_siginfo));
+
+    will_return(__wrap_poll, false);
+    will_return(__wrap_poll, POLLIN);
+    will_return(__wrap_poll, 1);
+
+    will_return(__wrap_read, false);
+    will_return(__wrap_read, 1);
+
+    const f_status_t status = f_signal_read(signal, 0, &information);
+
+    assert_int_equal(status, F_signal);
+  }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_signal/tests/unit/c/test-signal-read.h b/level_0/f_signal/tests/unit/c/test-signal-read.h
new file mode 100644 (file)
index 0000000..1d31522
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Signal
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the signal project.
+ */
+#ifndef _TEST__F_signal_read_h
+#define _TEST__F_signal_read_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_signal_read()
+ */
+extern void test__f_signal_read__fails(void **state);
+
+/**
+ * Test that parameter checking works as expected.
+ *
+ * @see f_signal_read()
+ */
+extern void test__f_signal_read__parameter_checking(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_signal_read()
+ */
+extern void test__f_signal_read__works(void **state);
+
+#endif // _TEST__F_signal_read_h
diff --git a/level_0/f_signal/tests/unit/c/test-signal-send.c b/level_0/f_signal/tests/unit/c/test-signal-send.c
new file mode 100644 (file)
index 0000000..f56a3d5
--- /dev/null
@@ -0,0 +1,48 @@
+#include "test-signal.h"
+#include "test-signal-send.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_signal_send__fails(void **state) {
+
+  int errnos[] = {
+    EINVAL,
+    EPERM,
+    ESRCH,
+    mock_errno_generic,
+  };
+
+  f_status_t statuss[] = {
+    F_parameter,
+    F_prohibited,
+    F_found_not,
+    F_failure,
+  };
+
+  for (int i = 0; i < 4; ++i) {
+
+    will_return(__wrap_kill, true);
+    will_return(__wrap_kill, errnos[i]);
+
+    const f_status_t status = f_signal_send(0, 0);
+
+    assert_int_equal(status, F_status_set_error(statuss[i]));
+  } // for
+}
+
+void test__f_signal_send__works(void **state) {
+
+  {
+    will_return(__wrap_kill, false);
+
+    const f_status_t status = f_signal_send(0, 0);
+
+    assert_int_equal(status, F_none);
+  }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_signal/tests/unit/c/test-signal-send.h b/level_0/f_signal/tests/unit/c/test-signal-send.h
new file mode 100644 (file)
index 0000000..eef7ef5
--- /dev/null
@@ -0,0 +1,27 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Signal
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the signal project.
+ */
+#ifndef _TEST__F_signal_send_h
+#define _TEST__F_signal_send_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_signal_send()
+ */
+extern void test__f_signal_send__fails(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_signal_send()
+ */
+extern void test__f_signal_send__works(void **state);
+
+#endif // _TEST__F_signal_send_h
diff --git a/level_0/f_signal/tests/unit/c/test-signal-set_add.c b/level_0/f_signal/tests/unit/c/test-signal-set_add.c
new file mode 100644 (file)
index 0000000..f963f9f
--- /dev/null
@@ -0,0 +1,61 @@
+#include "test-signal.h"
+#include "test-signal-set_add.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_signal_set_add__fails(void **state) {
+
+  int errnos[] = {
+    EINVAL,
+    mock_errno_generic,
+  };
+
+  f_status_t statuss[] = {
+    F_parameter,
+    F_failure,
+  };
+
+  for (int i = 0; i < 2; ++i) {
+
+    sigset_t set;
+
+    memset(&set, 0, sizeof(sigset_t));
+
+    will_return(__wrap_sigaddset, true);
+    will_return(__wrap_sigaddset, errnos[i]);
+
+    const f_status_t status = f_signal_set_add(0, &set);
+
+    assert_int_equal(status, F_status_set_error(statuss[i]));
+  } // for
+}
+
+void test__f_signal_set_add__parameter_checking(void **state) {
+
+  {
+    const f_status_t status = f_signal_set_add(0, 0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+  }
+}
+
+void test__f_signal_set_add__works(void **state) {
+
+  {
+    sigset_t set;
+
+    memset(&set, 0, sizeof(sigset_t));
+
+    will_return(__wrap_sigaddset, false);
+
+    const f_status_t status = f_signal_set_add(0, &set);
+
+    assert_int_equal(status, F_none);
+  }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_signal/tests/unit/c/test-signal-set_add.h b/level_0/f_signal/tests/unit/c/test-signal-set_add.h
new file mode 100644 (file)
index 0000000..9101ef8
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Signal
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the signal project.
+ */
+#ifndef _TEST__F_signal_set_add_h
+#define _TEST__F_signal_set_add_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_signal_set_add()
+ */
+extern void test__f_signal_set_add__fails(void **state);
+
+/**
+ * Test that parameter checking works as expected.
+ *
+ * @see f_signal_set_add()
+ */
+extern void test__f_signal_set_add__parameter_checking(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_signal_set_add()
+ */
+extern void test__f_signal_set_add__works(void **state);
+
+#endif // _TEST__F_signal_set_add_h
diff --git a/level_0/f_signal/tests/unit/c/test-signal-set_delete.c b/level_0/f_signal/tests/unit/c/test-signal-set_delete.c
new file mode 100644 (file)
index 0000000..3a885ee
--- /dev/null
@@ -0,0 +1,61 @@
+#include "test-signal.h"
+#include "test-signal-set_delete.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_signal_set_delete__fails(void **state) {
+
+  int errnos[] = {
+    EINVAL,
+    mock_errno_generic,
+  };
+
+  f_status_t statuss[] = {
+    F_parameter,
+    F_failure,
+  };
+
+  for (int i = 0; i < 2; ++i) {
+
+    sigset_t set;
+
+    memset(&set, 0, sizeof(sigset_t));
+
+    will_return(__wrap_sigdelset, true);
+    will_return(__wrap_sigdelset, errnos[i]);
+
+    const f_status_t status = f_signal_set_delete(0, &set);
+
+    assert_int_equal(status, F_status_set_error(statuss[i]));
+  } // for
+}
+
+void test__f_signal_set_delete__parameter_checking(void **state) {
+
+  {
+    const f_status_t status = f_signal_set_delete(0, 0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+  }
+}
+
+void test__f_signal_set_delete__works(void **state) {
+
+  {
+    sigset_t set;
+
+    memset(&set, 0, sizeof(sigset_t));
+
+    will_return(__wrap_sigdelset, false);
+
+    const f_status_t status = f_signal_set_delete(0, &set);
+
+    assert_int_equal(status, F_none);
+  }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_signal/tests/unit/c/test-signal-set_delete.h b/level_0/f_signal/tests/unit/c/test-signal-set_delete.h
new file mode 100644 (file)
index 0000000..6de0838
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Signal
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the signal project.
+ */
+#ifndef _TEST__F_signal_set_delete_h
+#define _TEST__F_signal_set_delete_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_signal_set_delete()
+ */
+extern void test__f_signal_set_delete__fails(void **state);
+
+/**
+ * Test that parameter checking works as expected.
+ *
+ * @see f_signal_set_delete()
+ */
+extern void test__f_signal_set_delete__parameter_checking(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_signal_set_delete()
+ */
+extern void test__f_signal_set_delete__works(void **state);
+
+#endif // _TEST__F_signal_set_delete_h
diff --git a/level_0/f_signal/tests/unit/c/test-signal-set_empty.c b/level_0/f_signal/tests/unit/c/test-signal-set_empty.c
new file mode 100644 (file)
index 0000000..55258c2
--- /dev/null
@@ -0,0 +1,61 @@
+#include "test-signal.h"
+#include "test-signal-set_empty.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_signal_set_empty__fails(void **state) {
+
+  int errnos[] = {
+    EINVAL,
+    mock_errno_generic,
+  };
+
+  f_status_t statuss[] = {
+    F_parameter,
+    F_failure,
+  };
+
+  for (int i = 0; i < 2; ++i) {
+
+    sigset_t set;
+
+    memset(&set, 0, sizeof(sigset_t));
+
+    will_return(__wrap_sigemptyset, true);
+    will_return(__wrap_sigemptyset, errnos[i]);
+
+    const f_status_t status = f_signal_set_empty(&set);
+
+    assert_int_equal(status, F_status_set_error(statuss[i]));
+  } // for
+}
+
+void test__f_signal_set_empty__parameter_checking(void **state) {
+
+  {
+    const f_status_t status = f_signal_set_empty(0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+  }
+}
+
+void test__f_signal_set_empty__works(void **state) {
+
+  {
+    sigset_t set;
+
+    memset(&set, 0, sizeof(sigset_t));
+
+    will_return(__wrap_sigemptyset, false);
+
+    const f_status_t status = f_signal_set_empty(&set);
+
+    assert_int_equal(status, F_none);
+  }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_signal/tests/unit/c/test-signal-set_empty.h b/level_0/f_signal/tests/unit/c/test-signal-set_empty.h
new file mode 100644 (file)
index 0000000..b2b3b8d
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Signal
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the signal project.
+ */
+#ifndef _TEST__F_signal_set_empty_h
+#define _TEST__F_signal_set_empty_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_signal_set_empty()
+ */
+extern void test__f_signal_set_empty__fails(void **state);
+
+/**
+ * Test that parameter checking works as expected.
+ *
+ * @see f_signal_set_empty()
+ */
+extern void test__f_signal_set_empty__parameter_checking(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_signal_set_empty()
+ */
+extern void test__f_signal_set_empty__works(void **state);
+
+#endif // _TEST__F_signal_set_empty_h
diff --git a/level_0/f_signal/tests/unit/c/test-signal-set_fill.c b/level_0/f_signal/tests/unit/c/test-signal-set_fill.c
new file mode 100644 (file)
index 0000000..35fa0f7
--- /dev/null
@@ -0,0 +1,63 @@
+#include "test-signal.h"
+#include "test-signal-set_fill.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_signal_set_fill__fails(void **state) {
+
+  int errnos[] = {
+    EFAULT,
+    EINVAL,
+    mock_errno_generic,
+  };
+
+  f_status_t statuss[] = {
+    F_buffer,
+    F_parameter,
+    F_failure,
+  };
+
+  for (int i = 0; i < 3; ++i) {
+
+    sigset_t set;
+
+    memset(&set, 0, sizeof(sigset_t));
+
+    will_return(__wrap_sigfillset, true);
+    will_return(__wrap_sigfillset, errnos[i]);
+
+    const f_status_t status = f_signal_set_fill(&set);
+
+    assert_int_equal(status, F_status_set_error(statuss[i]));
+  } // for
+}
+
+void test__f_signal_set_fill__parameter_checking(void **state) {
+
+  {
+    const f_status_t status = f_signal_set_fill(0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+  }
+}
+
+void test__f_signal_set_fill__works(void **state) {
+
+  {
+    sigset_t set;
+
+    memset(&set, 0, sizeof(sigset_t));
+
+    will_return(__wrap_sigfillset, false);
+
+    const f_status_t status = f_signal_set_fill(&set);
+
+    assert_int_equal(status, F_none);
+  }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_signal/tests/unit/c/test-signal-set_fill.h b/level_0/f_signal/tests/unit/c/test-signal-set_fill.h
new file mode 100644 (file)
index 0000000..ad65081
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Signal
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the signal project.
+ */
+#ifndef _TEST__F_signal_set_fill_h
+#define _TEST__F_signal_set_fill_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_signal_set_fill()
+ */
+extern void test__f_signal_set_fill__fails(void **state);
+
+/**
+ * Test that parameter checking works as expected.
+ *
+ * @see f_signal_set_fill()
+ */
+extern void test__f_signal_set_fill__parameter_checking(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_signal_set_fill()
+ */
+extern void test__f_signal_set_fill__works(void **state);
+
+#endif // _TEST__F_signal_set_fill_h
diff --git a/level_0/f_signal/tests/unit/c/test-signal-set_has.c b/level_0/f_signal/tests/unit/c/test-signal-set_has.c
new file mode 100644 (file)
index 0000000..850a8f1
--- /dev/null
@@ -0,0 +1,75 @@
+#include "test-signal.h"
+#include "test-signal-set_has.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_signal_set_has__fails(void **state) {
+
+  int errnos[] = {
+    EINVAL,
+    mock_errno_generic,
+  };
+
+  f_status_t statuss[] = {
+    F_parameter,
+    F_failure,
+  };
+
+  for (int i = 0; i < 2; ++i) {
+
+    sigset_t set;
+
+    memset(&set, 0, sizeof(sigset_t));
+
+    will_return(__wrap_sigismember, true);
+    will_return(__wrap_sigismember, errnos[i]);
+
+    const f_status_t status = f_signal_set_has(0, &set);
+
+    assert_int_equal(status, F_status_set_error(statuss[i]));
+  } // for
+}
+
+void test__f_signal_set_has__parameter_checking(void **state) {
+
+  {
+    const f_status_t status = f_signal_set_has(0, 0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+  }
+}
+
+void test__f_signal_set_has__works(void **state) {
+
+  {
+    sigset_t set;
+
+    memset(&set, 0, sizeof(sigset_t));
+
+    will_return(__wrap_sigismember, false);
+    will_return(__wrap_sigismember, false);
+
+    const f_status_t status = f_signal_set_has(0, &set);
+
+    assert_int_equal(status, F_false);
+  }
+
+  {
+    sigset_t set;
+
+    memset(&set, 0, sizeof(sigset_t));
+
+    will_return(__wrap_sigismember, false);
+    will_return(__wrap_sigismember, true);
+
+    const f_status_t status = f_signal_set_has(0, &set);
+
+    assert_int_equal(status, F_true);
+  }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_signal/tests/unit/c/test-signal-set_has.h b/level_0/f_signal/tests/unit/c/test-signal-set_has.h
new file mode 100644 (file)
index 0000000..2f953d8
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Signal
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the signal project.
+ */
+#ifndef _TEST__F_signal_set_has_h
+#define _TEST__F_signal_set_has_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_signal_set_has()
+ */
+extern void test__f_signal_set_has__fails(void **state);
+
+/**
+ * Test that parameter checking works as expected.
+ *
+ * @see f_signal_set_has()
+ */
+extern void test__f_signal_set_has__parameter_checking(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_signal_set_has()
+ */
+extern void test__f_signal_set_has__works(void **state);
+
+#endif // _TEST__F_signal_set_has_h
diff --git a/level_0/f_signal/tests/unit/c/test-signal-wait.c b/level_0/f_signal/tests/unit/c/test-signal-wait.c
new file mode 100644 (file)
index 0000000..1e00c29
--- /dev/null
@@ -0,0 +1,58 @@
+#include "test-signal.h"
+#include "test-signal-wait.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_signal_wait__fails(void **state) {
+
+  int errnos[] = {
+    EINTR,
+    EINVAL,
+    mock_errno_generic,
+  };
+
+  f_status_t statuss[] = {
+    F_interrupt,
+    F_parameter,
+    F_failure,
+  };
+
+  for (int i = 0; i < 3; ++i) {
+
+    sigset_t set;
+    siginfo_t information;
+
+    memset(&set, 0, sizeof(sigset_t));
+    memset(&set, 0, sizeof(siginfo_t));
+
+    will_return(__wrap_sigwaitinfo, true);
+    will_return(__wrap_sigwaitinfo, errnos[i]);
+
+    const f_status_t status = f_signal_wait(&set, &information);
+
+    assert_int_equal(status, F_status_set_error(statuss[i]));
+  } // for
+}
+
+void test__f_signal_wait__works(void **state) {
+
+  {
+    sigset_t set;
+    siginfo_t information;
+
+    memset(&set, 0, sizeof(sigset_t));
+    memset(&set, 0, sizeof(siginfo_t));
+
+    will_return(__wrap_sigwaitinfo, false);
+
+    const f_status_t status = f_signal_wait(&set, &information);
+
+    assert_int_equal(status, F_none);
+  }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_signal/tests/unit/c/test-signal-wait.h b/level_0/f_signal/tests/unit/c/test-signal-wait.h
new file mode 100644 (file)
index 0000000..d17d6ee
--- /dev/null
@@ -0,0 +1,27 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Signal
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the signal project.
+ */
+#ifndef _TEST__F_signal_wait_h
+#define _TEST__F_signal_wait_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_signal_wait()
+ */
+extern void test__f_signal_wait__fails(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_signal_wait()
+ */
+extern void test__f_signal_wait__works(void **state);
+
+#endif // _TEST__F_signal_wait_h
diff --git a/level_0/f_signal/tests/unit/c/test-signal-wait_until.c b/level_0/f_signal/tests/unit/c/test-signal-wait_until.c
new file mode 100644 (file)
index 0000000..4018ee3
--- /dev/null
@@ -0,0 +1,64 @@
+#include "test-signal.h"
+#include "test-signal-wait_until.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_signal_wait_until__fails(void **state) {
+
+  int errnos[] = {
+    EAGAIN,
+    EINTR,
+    EINVAL,
+    mock_errno_generic,
+  };
+
+  f_status_t statuss[] = {
+    F_time_out,
+    F_status_set_error(F_interrupt),
+    F_status_set_error(F_parameter),
+    F_status_set_error(F_failure),
+  };
+
+  for (int i = 0; i < 4; ++i) {
+
+    sigset_t set;
+    siginfo_t information;
+    struct timespec timeout;
+
+    memset(&set, 0, sizeof(sigset_t));
+    memset(&set, 0, sizeof(siginfo_t));
+    memset(&set, 0, sizeof(struct timespec));
+
+    will_return(__wrap_sigtimedwait, true);
+    will_return(__wrap_sigtimedwait, errnos[i]);
+
+    const f_status_t status = f_signal_wait_until(&set, &timeout, &information);
+
+    assert_int_equal(status, statuss[i]);
+  } // for
+}
+
+void test__f_signal_wait_until__works(void **state) {
+
+  {
+    sigset_t set;
+    siginfo_t information;
+    struct timespec timeout;
+
+    memset(&set, 0, sizeof(sigset_t));
+    memset(&set, 0, sizeof(siginfo_t));
+    memset(&set, 0, sizeof(struct timespec));
+
+    will_return(__wrap_sigtimedwait, false);
+
+    const f_status_t status = f_signal_wait_until(&set, &timeout, &information);
+
+    assert_int_equal(status, F_none);
+  }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_signal/tests/unit/c/test-signal-wait_until.h b/level_0/f_signal/tests/unit/c/test-signal-wait_until.h
new file mode 100644 (file)
index 0000000..a027e4d
--- /dev/null
@@ -0,0 +1,27 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Signal
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the signal project.
+ */
+#ifndef _TEST__F_signal_wait_until_h
+#define _TEST__F_signal_wait_until_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_signal_wait_until()
+ */
+extern void test__f_signal_wait_until__fails(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_signal_wait_until()
+ */
+extern void test__f_signal_wait_until__works(void **state);
+
+#endif // _TEST__F_signal_wait_until_h
diff --git a/level_0/f_signal/tests/unit/c/test-signal.c b/level_0/f_signal/tests/unit/c/test-signal.c
new file mode 100644 (file)
index 0000000..c49b5de
--- /dev/null
@@ -0,0 +1,83 @@
+#include "test-signal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int setup(void **state) {
+
+  return 0;
+}
+
+int setdown(void **state) {
+
+  errno = 0;
+
+  return 0;
+}
+
+int main(void) {
+
+  const struct CMUnitTest tests[] = {
+    cmocka_unit_test(test__f_signal_close__fails),
+    cmocka_unit_test(test__f_signal_close__works),
+
+    cmocka_unit_test(test__f_signal_mask__fails),
+    cmocka_unit_test(test__f_signal_mask__works),
+
+    cmocka_unit_test(test__f_signal_open__fails),
+    cmocka_unit_test(test__f_signal_open__works),
+
+    cmocka_unit_test(test__f_signal_queue__fails),
+    cmocka_unit_test(test__f_signal_queue__works),
+
+    cmocka_unit_test(test__f_signal_read__fails),
+    cmocka_unit_test(test__f_signal_read__works),
+
+    cmocka_unit_test(test__f_signal_send__fails),
+    cmocka_unit_test(test__f_signal_send__works),
+
+    cmocka_unit_test(test__f_signal_set_add__fails),
+    cmocka_unit_test(test__f_signal_set_add__works),
+
+    cmocka_unit_test(test__f_signal_set_delete__fails),
+    cmocka_unit_test(test__f_signal_set_delete__works),
+
+    cmocka_unit_test(test__f_signal_set_empty__fails),
+    cmocka_unit_test(test__f_signal_set_empty__works),
+
+    cmocka_unit_test(test__f_signal_set_fill__fails),
+    cmocka_unit_test(test__f_signal_set_fill__works),
+
+    cmocka_unit_test(test__f_signal_set_has__fails),
+    cmocka_unit_test(test__f_signal_set_has__works),
+
+    cmocka_unit_test(test__f_signal_wait__fails),
+    cmocka_unit_test(test__f_signal_wait__works),
+
+    cmocka_unit_test(test__f_signal_wait_until__fails),
+    cmocka_unit_test(test__f_signal_wait_until__works),
+
+    #ifndef _di_level_0_parameter_checking_
+      cmocka_unit_test(test__f_signal_close__parameter_checking),
+      cmocka_unit_test(test__f_signal_mask__parameter_checking),
+      cmocka_unit_test(test__f_signal_open__parameter_checking),
+      // f_signal_queue() doesn't use parameter checking.
+      cmocka_unit_test(test__f_signal_read__parameter_checking),
+      // f_signal_send() doesn't use parameter checking.
+      cmocka_unit_test(test__f_signal_set_add__parameter_checking),
+      cmocka_unit_test(test__f_signal_set_delete__parameter_checking),
+      cmocka_unit_test(test__f_signal_set_empty__parameter_checking),
+      cmocka_unit_test(test__f_signal_set_fill__parameter_checking),
+      cmocka_unit_test(test__f_signal_set_has__parameter_checking),
+      // f_signal_wait() doesn't use parameter checking.
+      // f_signal_wait_until() doesn't use parameter checking.
+    #endif // _di_level_0_parameter_checking_
+  };
+
+  return cmocka_run_group_tests(tests, setup, setdown);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_signal/tests/unit/c/test-signal.h b/level_0/f_signal/tests/unit/c/test-signal.h
new file mode 100644 (file)
index 0000000..4919bc1
--- /dev/null
@@ -0,0 +1,84 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Account
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the signal project.
+ */
+#ifndef _TEST__F_signal_h
+#define _TEST__F_signal_h
+
+// Libc includes.
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <stdint.h>
+
+// cmocka includes.
+#include <cmocka.h>
+
+// FLL-0 includes.
+#include <fll/level_0/signal.h>
+
+// Mock includes.
+#include "mock-signal.h"
+
+// Test includes.
+#include "test-signal-close.h"
+#include "test-signal-mask.h"
+#include "test-signal-open.h"
+#include "test-signal-queue.h"
+#include "test-signal-read.h"
+#include "test-signal-send.h"
+#include "test-signal-set_add.h"
+#include "test-signal-set_delete.h"
+#include "test-signal-set_empty.h"
+#include "test-signal-set_fill.h"
+#include "test-signal-set_has.h"
+#include "test-signal-wait.h"
+#include "test-signal-wait_until.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Perform any setup operations.
+ *
+ * @param state
+ *   The test state.
+ *
+ * @return
+ *   The status of this function, where 0 means success.
+ */
+extern int setup(void **state);
+
+/**
+ * Peform any setdown operations.
+ *
+ * @param state
+ *   The test state.
+ *
+ * @return
+ *   The status of this function, where 0 means success.
+ */
+extern int setdown(void **state);
+
+/**
+ * Run all tests.
+ *
+ * @return
+ *   The final result of the tests.
+ *
+ * @see cmocka_run_group_tests()
+ * @see cmocka_unit_test()
+ */
+extern int main(void);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _TEST__F_signal_h