]> Kevux Git Server - fll/commitdiff
Update: Add unit tests for f_account.
authorKevin Day <thekevinday@gmail.com>
Fri, 14 Jan 2022 04:53:13 +0000 (22:53 -0600)
committerKevin Day <thekevinday@gmail.com>
Fri, 14 Jan 2022 04:53:13 +0000 (22:53 -0600)
20 files changed:
level_0/f_account/data/build/dependencies-tests [new file with mode: 0644]
level_0/f_account/data/build/settings-mocks [new file with mode: 0644]
level_0/f_account/data/build/settings-tests [new file with mode: 0644]
level_0/f_account/data/build/testfile [new file with mode: 0644]
level_0/f_account/tests/c/mock-account.c [new file with mode: 0644]
level_0/f_account/tests/c/mock-account.h [new file with mode: 0644]
level_0/f_account/tests/c/test-account-by_id.c [new file with mode: 0644]
level_0/f_account/tests/c/test-account-by_id.h [new file with mode: 0644]
level_0/f_account/tests/c/test-account-by_name.c [new file with mode: 0644]
level_0/f_account/tests/c/test-account-by_name.h [new file with mode: 0644]
level_0/f_account/tests/c/test-account-id_group_by_name.c [new file with mode: 0644]
level_0/f_account/tests/c/test-account-id_group_by_name.h [new file with mode: 0644]
level_0/f_account/tests/c/test-account-id_user_by_name.c [new file with mode: 0644]
level_0/f_account/tests/c/test-account-id_user_by_name.h [new file with mode: 0644]
level_0/f_account/tests/c/test-account-name_group_by_id.c [new file with mode: 0644]
level_0/f_account/tests/c/test-account-name_group_by_id.h [new file with mode: 0644]
level_0/f_account/tests/c/test-account-name_user_by_id.c [new file with mode: 0644]
level_0/f_account/tests/c/test-account-name_user_by_id.h [new file with mode: 0644]
level_0/f_account/tests/c/test-account.c [new file with mode: 0644]
level_0/f_account/tests/c/test-account.h [new file with mode: 0644]

diff --git a/level_0/f_account/data/build/dependencies-tests b/level_0/f_account/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_account/data/build/settings-mocks b/level_0/f_account/data/build/settings-mocks
new file mode 100644 (file)
index 0000000..6d11bbd
--- /dev/null
@@ -0,0 +1,82 @@
+# fss-0001
+
+project_name f_account
+
+version_major 0
+version_minor 5
+version_micro 8
+version_file micro
+version_target minor
+
+environment
+
+process_pre
+process_post
+
+modes individual
+modes_default individual
+
+build_compiler gcc
+build_indexer ar
+build_indexer_arguments rcs
+build_language c
+build_libraries -lc
+build_libraries-individual -lf_memory -lf_string
+build_libraries_shared
+build_libraries_static
+build_sources_library account.c private-account.c ../../tests/c/mock-account.c
+build_sources_library_shared
+build_sources_library_static
+build_sources_program
+build_sources_program_shared
+build_sources_program_static
+build_sources_headers account.h account-common.h
+build_sources_headers_shared
+build_sources_headers_static
+build_sources_script
+build_sources_setting
+build_script yes
+build_shared yes
+build_static no
+
+path_headers fll/level_0
+path_headers_preserve no
+path_library_script script
+path_library_shared shared
+path_library_static static
+path_program_script script
+path_program_shared shared
+path_program_static static
+path_sources
+path_standard yes
+
+search_exclusive yes
+search_shared yes
+search_static yes
+
+defines
+defines_library
+defines_library_shared
+defines_library_static
+defines_program
+defines_program_shared
+defines_program_static
+defines_static
+defines_shared
+
+flags -O2 -z now -g -fdiagnostics-color=always -Wno-logical-not-parentheses -Wno-logical-op-parentheses -Wno-parentheses
+flags_library -fPIC
+flags_library_shared
+flags_library_static
+flags_program -fPIE
+flags_program_shared
+flags_program_static
+flags_shared
+flags_static
+
+# Inject mocks.
+flags -Wl,--wrap=getpwnam_r
+flags -Wl,--wrap=getpwuid_r
+flags -Wl,--wrap=getgrnam_r
+flags -Wl,--wrap=getgrgid_r
+flags -Wl,--wrap=sysconf
diff --git a/level_0/f_account/data/build/settings-tests b/level_0/f_account/data/build/settings-tests
new file mode 100644 (file)
index 0000000..c623264
--- /dev/null
@@ -0,0 +1,46 @@
+# fss-0001
+
+project_name test-f_account
+
+version_major 0
+version_minor 5
+version_micro 8
+version_file major
+version_target major
+
+modes individual level monolithic
+modes_default individual
+
+build_compiler gcc
+build_indexer ar
+build_indexer_arguments rcs
+build_language c
+build_libraries -lc -lcmocka
+build_libraries-individual -lf_memory -lf_string -lf_type_array -lf_account
+build_libraries-level -lfll_0
+build_libraries-monolithic -lfll
+build_sources_program test-account-by_id.c test-account-by_name.c test-account-id_group_by_name.c test-account-id_user_by_name.c test-account-name_group_by_id.c test-account-name_user_by_id.c test-account.c
+build_script no
+build_shared yes
+build_static no
+
+path_headers tests/c
+path_headers_preserve no
+path_sources tests/c
+path_standard no
+
+search_exclusive yes
+search_shared yes
+search_static yes
+
+defines
+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-logical-op-parentheses -Wno-parentheses
+flags_program -fPIE
+flags_program_shared
+flags_program_static
+flags_shared
+flags_static
diff --git a/level_0/f_account/data/build/testfile b/level_0/f_account/data/build/testfile
new file mode 100644 (file)
index 0000000..6acb1da
--- /dev/null
@@ -0,0 +1,45 @@
+# fss-0005 iki-0002
+
+settings:
+  load_build yes
+  fail exit
+
+  environment LD_LIBRARY_PATH
+
+main:
+  build settings-mocks
+  build settings-tests
+
+  operate ld_library_path
+
+  if exists build/programs/shared/test-f_account
+    shell build/programs/shared/test-f_account
+
+  if exists build/programs/static/test-f_account
+    shell build/programs/static/test-f_account
+
+  if not exists build/programs/shared/test-f_account
+  and not exists build/programs/static/test-f_account
+    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:"error"
+
+  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_account/tests/c/mock-account.c b/level_0/f_account/tests/c/mock-account.c
new file mode 100644 (file)
index 0000000..d3c95da
--- /dev/null
@@ -0,0 +1,78 @@
+#include "mock-account.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int __wrap_getpwnam_r(const char *name, struct passwd *pwd, char *buf, size_t buflen, struct passwd **result) {
+
+  bool failure = mock_type(bool);
+
+  if (failure) {
+    errno = mock_type(int);
+
+    return 1;
+  }
+
+  *pwd = *mock_type(struct passwd *);
+  *result = mock_type(struct passwd *);
+
+  return 0;
+}
+
+int __wrap_getpwuid_r(uid_t uid, struct passwd *pwd, char *buf, size_t buflen, struct passwd **result) {
+
+  bool failure = mock_type(bool);
+
+  if (failure) {
+    errno = mock_type(int);
+
+    return 1;
+  }
+
+  *pwd = *mock_type(struct passwd *);
+  *result = mock_type(struct passwd *);
+
+  return 0;
+}
+
+int __wrap_getgrnam_r(const char *name, struct group *grp, char *buf, size_t buflen, struct group **result) {
+
+  bool failure = mock_type(bool);
+
+  if (failure) {
+    errno = mock_type(int);
+
+    return 1;
+  }
+
+  *grp = *mock_type(struct group *);
+  *result = mock_type(struct group *);
+
+  return 0;
+}
+
+int __wrap_getgrgid_r(uid_t uid, struct group *grp, char *buf, size_t buflen, struct group **result) {
+
+  bool failure = mock_type(bool);
+
+  if (failure) {
+    errno = mock_type(int);
+
+    return 1;
+  }
+
+  *grp = *mock_type(struct group *);
+  *result = mock_type(struct group *);
+
+  return 0;
+}
+
+long __wrap_sysconf(int name) {
+
+  return mock_type(long);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_account/tests/c/mock-account.h b/level_0/f_account/tests/c/mock-account.h
new file mode 100644 (file)
index 0000000..d299173
--- /dev/null
@@ -0,0 +1,41 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Account
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the account project.
+ */
+#ifndef _MOCK__account_h
+#define _MOCK__account_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/account.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+const static int mock_errno_generic = 32767;
+
+extern int __wrap_getpwnam_r(const char *name, struct passwd *pwd, char *buf, size_t buflen, struct passwd **result);
+extern int __wrap_getpwuid_r(uid_t uid, struct passwd *pwd, char *buf, size_t buflen, struct passwd **result);
+extern int __wrap_getgrgid_r(uid_t uid, struct group *grp, char *buf, size_t buflen, struct group **result);
+extern int __wrap_getgrnam_r(const char *name, struct group *grp, char *buf, size_t buflen, struct group **result);
+extern long __wrap_sysconf(int name);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _MOCK__account_h
diff --git a/level_0/f_account/tests/c/test-account-by_id.c b/level_0/f_account/tests/c/test-account-by_id.c
new file mode 100644 (file)
index 0000000..3c43894
--- /dev/null
@@ -0,0 +1,108 @@
+#include "test-account.h"
+#include "test-account-by_id.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_account_by_id__not_found(void **state) {
+
+  const long size = 20;
+  struct passwd password;
+  uid_t uid = 0;
+  f_account_t account = f_account_t_initialize;
+
+  {
+    will_return(__wrap_sysconf, size);
+    will_return(__wrap_getpwuid_r, false);
+    will_return(__wrap_getpwuid_r, &password);
+    will_return(__wrap_getpwuid_r, (struct passwd *) 0);
+
+    const f_status_t status = f_account_by_id(uid, &account);
+
+    assert_int_equal(status, F_exist_not);
+  }
+
+  macro_f_account_t_delete_simple(account);
+}
+
+void test__f_account_by_id__works(void **state) {
+
+  const long size = 20;
+  struct passwd password;
+  struct passwd pointer;
+  uid_t uid = 1;
+  f_account_t account = f_account_t_initialize;
+
+  password.pw_uid = uid;
+  password.pw_gid = 2;
+  password.pw_dir = "pw_dir";
+  password.pw_gecos = "pw_gecos";
+  password.pw_name = "pw_name";
+  password.pw_passwd = "pw_passwd";
+  password.pw_shell = "pw_shell";
+
+  {
+    will_return(__wrap_sysconf, size);
+    will_return(__wrap_getpwuid_r, false);
+    will_return(__wrap_getpwuid_r, &password);
+    will_return(__wrap_getpwuid_r, &pointer);
+
+    const f_status_t status = f_account_by_id(uid, &account);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(account.id_user, password.pw_uid);
+    assert_int_equal(account.id_group, password.pw_gid);
+    assert_string_equal(account.home.string, password.pw_dir);
+    assert_string_equal(account.label.string, password.pw_gecos);
+    assert_string_equal(account.name.string, password.pw_name);
+    assert_string_equal(account.password.string, password.pw_passwd);
+    assert_string_equal(account.shell.string, password.pw_shell);
+  }
+
+  macro_f_account_t_delete_simple(account);
+}
+
+void test__f_account_by_id__fails(void **state) {
+
+  const long size = 20;
+  uid_t uid = 0;
+  f_account_t account = f_account_t_initialize;
+
+  int errnos[] = {
+    EINTR,
+    EIO,
+    EMFILE,
+    ENFILE,
+    ENOMEM,
+    ERANGE,
+    mock_errno_generic,
+  };
+
+  f_status_t statuss[] = {
+    F_interrupt,
+    F_input_output,
+    F_file_descriptor_max,
+    F_file_open_max,
+    F_memory_not,
+    F_buffer_too_small,
+    F_failure,
+  };
+
+  for (int i = 0; i < 7; ++i) {
+
+    will_return(__wrap_sysconf, size);
+    will_return(__wrap_getpwuid_r, true);
+    will_return(__wrap_getpwuid_r, errnos[i]);
+
+    const f_status_t status = f_account_by_id(uid, &account);
+
+    assert_int_equal(F_status_set_fine(status), statuss[i]);
+  } // for
+
+  macro_f_account_t_delete_simple(account);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_account/tests/c/test-account-by_id.h b/level_0/f_account/tests/c/test-account-by_id.h
new file mode 100644 (file)
index 0000000..00c9d31
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Account
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the account project.
+ */
+#ifndef _TEST__F_account_by_id_
+#define _TEST__F_account_by_id_
+
+/**
+ * Test that function works but the account does not exist.
+ *
+ * @see f_account_by_id()
+ */
+extern void test__f_account_by_id__not_found(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_account_by_id()
+ */
+extern void test__f_account_by_id__works(void **state);
+
+/**
+ * Test that function fails.
+ *
+ * @see f_account_by_id()
+ */
+extern void test__f_account_by_id__fails(void **state);
+
+#endif // _TEST__F_account_by_id_
diff --git a/level_0/f_account/tests/c/test-account-by_name.c b/level_0/f_account/tests/c/test-account-by_name.c
new file mode 100644 (file)
index 0000000..d3a9075
--- /dev/null
@@ -0,0 +1,108 @@
+#include "test-account.h"
+#include "test-account-by_name.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_account_by_name__not_found(void **state) {
+
+  const long size = 20;
+  struct passwd password;
+  char *name = "the_name";
+  f_account_t account = f_account_t_initialize;
+
+  {
+    will_return(__wrap_sysconf, size);
+    will_return(__wrap_getpwnam_r, false);
+    will_return(__wrap_getpwnam_r, &password);
+    will_return(__wrap_getpwnam_r, (struct passwd *) 0);
+
+    const f_status_t status = f_account_by_name(name, &account);
+
+    assert_int_equal(status, F_exist_not);
+  }
+
+  macro_f_account_t_delete_simple(account);
+}
+
+void test__f_account_by_name__works(void **state) {
+
+  const long size = 20;
+  struct passwd password;
+  struct passwd pointer;
+  char *name = "the_name";
+  f_account_t account = f_account_t_initialize;
+
+  password.pw_uid = 1;
+  password.pw_gid = 2;
+  password.pw_dir = "pw_dir";
+  password.pw_gecos = "pw_gecos";
+  password.pw_name = name;
+  password.pw_passwd = "pw_passwd";
+  password.pw_shell = "pw_shell";
+
+  {
+    will_return(__wrap_sysconf, size);
+    will_return(__wrap_getpwnam_r, false);
+    will_return(__wrap_getpwnam_r, &password);
+    will_return(__wrap_getpwnam_r, &pointer);
+
+    const f_status_t status = f_account_by_name(name, &account);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(account.id_user, password.pw_uid);
+    assert_int_equal(account.id_group, password.pw_gid);
+    assert_string_equal(account.home.string, password.pw_dir);
+    assert_string_equal(account.label.string, password.pw_gecos);
+    assert_string_equal(account.name.string, password.pw_name);
+    assert_string_equal(account.password.string, password.pw_passwd);
+    assert_string_equal(account.shell.string, password.pw_shell);
+  }
+
+  macro_f_account_t_delete_simple(account);
+}
+
+void test__f_account_by_name__fails(void **state) {
+
+  const long size = 20;
+  char *name = "the_name";
+  f_account_t account = f_account_t_initialize;
+
+  int errnos[] = {
+    EINTR,
+    EIO,
+    EMFILE,
+    ENFILE,
+    ENOMEM,
+    ERANGE,
+    mock_errno_generic,
+  };
+
+  f_status_t statuss[] = {
+    F_interrupt,
+    F_input_output,
+    F_file_descriptor_max,
+    F_file_open_max,
+    F_memory_not,
+    F_buffer_too_small,
+    F_failure,
+  };
+
+  for (int i = 0; i < 7; ++i) {
+
+    will_return(__wrap_sysconf, size);
+    will_return(__wrap_getpwnam_r, true);
+    will_return(__wrap_getpwnam_r, errnos[i]);
+
+    const f_status_t status = f_account_by_name(name, &account);
+
+    assert_int_equal(F_status_set_fine(status), statuss[i]);
+  } // for
+
+  macro_f_account_t_delete_simple(account);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_account/tests/c/test-account-by_name.h b/level_0/f_account/tests/c/test-account-by_name.h
new file mode 100644 (file)
index 0000000..4653293
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Account
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the account project.
+ */
+#ifndef _TEST__F_account_by_name_
+#define _TEST__F_account_by_name_
+
+/**
+ * Test that function works but the account does not exist.
+ *
+ * @see f_account_by_name()
+ */
+extern void test__f_account_by_name__not_found(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_account_by_name()
+ */
+extern void test__f_account_by_name__works(void **state);
+
+/**
+ * Test that function fails.
+ *
+ * @see f_account_by_name()
+ */
+extern void test__f_account_by_name__fails(void **state);
+
+#endif // _TEST__F_account_by_name_
diff --git a/level_0/f_account/tests/c/test-account-id_group_by_name.c b/level_0/f_account/tests/c/test-account-id_group_by_name.c
new file mode 100644 (file)
index 0000000..b547d98
--- /dev/null
@@ -0,0 +1,93 @@
+#include "test-account.h"
+#include "test-account-id_group_by_name.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_account_id_group_by_name__not_found(void **state) {
+
+  const long size = 20;
+  struct group group_data;
+  char *name = "the_name";
+  gid_t gid = 0;
+
+  {
+    will_return(__wrap_sysconf, size);
+    will_return(__wrap_getgrnam_r, false);
+    will_return(__wrap_getgrnam_r, &group_data);
+    will_return(__wrap_getgrnam_r, (struct group *) 0);
+
+    const f_status_t status = f_account_id_group_by_name(name, &gid);
+
+    assert_int_equal(status, F_exist_not);
+  }
+}
+
+void test__f_account_id_group_by_name__works(void **state) {
+
+  const long size = 20;
+  struct group group_data;
+  struct group pointer;
+  char *pointers[] = { "gr_mem", 0 };
+  gid_t gid = 0;
+
+  group_data.gr_gid = 1;
+  group_data.gr_name = "the_name";
+  group_data.gr_passwd = "gr_passwd";
+  group_data.gr_mem = pointers;
+
+  {
+    will_return(__wrap_sysconf, size);
+    will_return(__wrap_getgrnam_r, false);
+    will_return(__wrap_getgrnam_r, &group_data);
+    will_return(__wrap_getgrnam_r, &pointer);
+
+    const f_status_t status = f_account_id_group_by_name(group_data.gr_name, &gid);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(gid, group_data.gr_gid);
+  }
+}
+
+void test__f_account_id_group_by_name__fails(void **state) {
+
+  const long size = 20;
+  char *name = "the_name";
+  gid_t gid = 0;
+
+  int errnos[] = {
+    EINTR,
+    EIO,
+    EMFILE,
+    ENFILE,
+    ENOMEM,
+    ERANGE,
+    mock_errno_generic,
+  };
+
+  f_status_t statuss[] = {
+    F_interrupt,
+    F_input_output,
+    F_file_descriptor_max,
+    F_file_open_max,
+    F_memory_not,
+    F_buffer_too_small,
+    F_failure,
+  };
+
+  for (int i = 0; i < 7; ++i) {
+
+    will_return(__wrap_sysconf, size);
+    will_return(__wrap_getgrnam_r, true);
+    will_return(__wrap_getgrnam_r, errnos[i]);
+
+    const f_status_t status = f_account_id_group_by_name(name, &gid);
+
+    assert_int_equal(F_status_set_fine(status), statuss[i]);
+  } // for
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_account/tests/c/test-account-id_group_by_name.h b/level_0/f_account/tests/c/test-account-id_group_by_name.h
new file mode 100644 (file)
index 0000000..81f0c77
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Account
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the account project.
+ */
+#ifndef _TEST__F_account_id_group_by_name_
+#define _TEST__F_account_id_group_by_name_
+
+/**
+ * Test that function works but the group does not exist.
+ *
+ * @see f_account_id_group_by_name()
+ */
+extern void test__f_account_id_group_by_name__not_found(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_account_id_group_by_name()
+ */
+extern void test__f_account_id_group_by_name__works(void **state);
+
+/**
+ * Test that function fails.
+ *
+ * @see f_account_id_group_by_name()
+ */
+extern void test__f_account_id_group_by_name__fails(void **state);
+
+#endif // _TEST__F_account_id_group_by_name_
diff --git a/level_0/f_account/tests/c/test-account-id_user_by_name.c b/level_0/f_account/tests/c/test-account-id_user_by_name.c
new file mode 100644 (file)
index 0000000..17811ed
--- /dev/null
@@ -0,0 +1,95 @@
+#include "test-account.h"
+#include "test-account-id_user_by_name.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_account_id_user_by_name__not_found(void **state) {
+
+  const long size = 20;
+  struct passwd password;
+  char *name = "the_name";
+  uid_t uid = 0;
+
+  {
+    will_return(__wrap_sysconf, size);
+    will_return(__wrap_getpwnam_r, false);
+    will_return(__wrap_getpwnam_r, &password);
+    will_return(__wrap_getpwnam_r, (struct passwd *) 0);
+
+    const f_status_t status = f_account_id_user_by_name(name, &uid);
+
+    assert_int_equal(status, F_exist_not);
+  }
+}
+
+void test__f_account_id_user_by_name__works(void **state) {
+
+  const long size = 20;
+  struct passwd password;
+  struct passwd pointer;
+  uid_t uid = 0;
+
+  password.pw_uid = 1;
+  password.pw_gid = 2;
+  password.pw_dir = "pw_dir";
+  password.pw_gecos = "pw_gecos";
+  password.pw_name = "the_name";
+  password.pw_passwd = "pw_passwd";
+  password.pw_shell = "pw_shell";
+
+  {
+    will_return(__wrap_sysconf, size);
+    will_return(__wrap_getpwnam_r, false);
+    will_return(__wrap_getpwnam_r, &password);
+    will_return(__wrap_getpwnam_r, &pointer);
+
+    const f_status_t status = f_account_id_user_by_name(password.pw_name, &uid);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(uid, password.pw_uid);
+  }
+}
+
+void test__f_account_id_user_by_name__fails(void **state) {
+
+  const long size = 20;
+  char *name = "the_name";
+  uid_t uid = 0;
+
+  int errnos[] = {
+    EINTR,
+    EIO,
+    EMFILE,
+    ENFILE,
+    ENOMEM,
+    ERANGE,
+    mock_errno_generic,
+  };
+
+  f_status_t statuss[] = {
+    F_interrupt,
+    F_input_output,
+    F_file_descriptor_max,
+    F_file_open_max,
+    F_memory_not,
+    F_buffer_too_small,
+    F_failure,
+  };
+
+  for (int i = 0; i < 7; ++i) {
+
+    will_return(__wrap_sysconf, size);
+    will_return(__wrap_getpwnam_r, true);
+    will_return(__wrap_getpwnam_r, errnos[i]);
+
+    const f_status_t status = f_account_id_user_by_name(name, &uid);
+
+    assert_int_equal(F_status_set_fine(status), statuss[i]);
+  } // for
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_account/tests/c/test-account-id_user_by_name.h b/level_0/f_account/tests/c/test-account-id_user_by_name.h
new file mode 100644 (file)
index 0000000..d60904a
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Account
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the account project.
+ */
+#ifndef _TEST__F_account_id_user_by_name_
+#define _TEST__F_account_id_user_by_name_
+
+/**
+ * Test that function works but the group does not exist.
+ *
+ * @see f_account_id_user_by_name()
+ */
+extern void test__f_account_id_user_by_name__not_found(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_account_id_user_by_name()
+ */
+extern void test__f_account_id_user_by_name__works(void **state);
+
+/**
+ * Test that function fails.
+ *
+ * @see f_account_id_user_by_name()
+ */
+extern void test__f_account_id_user_by_name__fails(void **state);
+
+#endif // _TEST__F_account_id_user_by_name_
diff --git a/level_0/f_account/tests/c/test-account-name_group_by_id.c b/level_0/f_account/tests/c/test-account-name_group_by_id.c
new file mode 100644 (file)
index 0000000..d1ff343
--- /dev/null
@@ -0,0 +1,100 @@
+#include "test-account.h"
+#include "test-account-name_group_by_id.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_account_name_group_by_id__not_found(void **state) {
+
+  const long size = 20;
+  struct group group_data;
+  gid_t gid = 0;
+  f_string_dynamic_t name = f_string_dynamic_t_initialize;
+
+  {
+    will_return(__wrap_sysconf, size);
+    will_return(__wrap_getgrgid_r, false);
+    will_return(__wrap_getgrgid_r, &group_data);
+    will_return(__wrap_getgrgid_r, (struct group *) 0);
+
+    const f_status_t status = f_account_name_group_by_id(gid, &name);
+
+    assert_int_equal(status, F_exist_not);
+  }
+
+  f_string_dynamic_resize(0, &name);
+}
+
+void test__f_account_name_group_by_id__works(void **state) {
+
+  const long size = 20;
+  struct group group_data;
+  struct group pointer;
+  char *pointers[] = { "gr_mem", 0 };
+  gid_t gid = 0;
+  f_string_dynamic_t name = f_string_dynamic_t_initialize;
+
+  group_data.gr_gid = 1;
+  group_data.gr_name = "gr_name";
+  group_data.gr_passwd = "gr_passwd";
+  group_data.gr_mem = pointers;
+
+  {
+    will_return(__wrap_sysconf, size);
+    will_return(__wrap_getgrgid_r, false);
+    will_return(__wrap_getgrgid_r, &group_data);
+    will_return(__wrap_getgrgid_r, &pointer);
+
+    const f_status_t status = f_account_name_group_by_id(gid, &name);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(name.string, group_data.gr_name);
+  }
+
+  f_string_dynamic_resize(0, &name);
+}
+
+void test__f_account_name_group_by_id__fails(void **state) {
+
+  const long size = 20;
+  gid_t gid = 0;
+  f_string_dynamic_t name = f_string_dynamic_t_initialize;
+
+  int errnos[] = {
+    EINTR,
+    EIO,
+    EMFILE,
+    ENFILE,
+    ENOMEM,
+    ERANGE,
+    mock_errno_generic,
+  };
+
+  f_status_t statuss[] = {
+    F_interrupt,
+    F_input_output,
+    F_file_descriptor_max,
+    F_file_open_max,
+    F_memory_not,
+    F_buffer_too_small,
+    F_failure,
+  };
+
+  for (int i = 0; i < 7; ++i) {
+
+    will_return(__wrap_sysconf, size);
+    will_return(__wrap_getgrgid_r, true);
+    will_return(__wrap_getgrgid_r, errnos[i]);
+
+    const f_status_t status = f_account_name_group_by_id(gid, &name);
+
+    assert_int_equal(F_status_set_fine(status), statuss[i]);
+  } // for
+
+  f_string_dynamic_resize(0, &name);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_account/tests/c/test-account-name_group_by_id.h b/level_0/f_account/tests/c/test-account-name_group_by_id.h
new file mode 100644 (file)
index 0000000..6d44b98
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Account
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the account project.
+ */
+#ifndef _TEST__F_account_name_group_by_id_
+#define _TEST__F_account_name_group_by_id_
+
+/**
+ * Test that function works but the group does not exist.
+ *
+ * @see f_account_name_group_by_id()
+ */
+extern void test__f_account_name_group_by_id__not_found(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_account_name_group_by_id()
+ */
+extern void test__f_account_name_group_by_id__works(void **state);
+
+/**
+ * Test that function fails.
+ *
+ * @see f_account_name_group_by_id()
+ */
+extern void test__f_account_name_group_by_id__fails(void **state);
+
+#endif // _TEST__F_account_name_group_by_id_
diff --git a/level_0/f_account/tests/c/test-account-name_user_by_id.c b/level_0/f_account/tests/c/test-account-name_user_by_id.c
new file mode 100644 (file)
index 0000000..bf14520
--- /dev/null
@@ -0,0 +1,102 @@
+#include "test-account.h"
+#include "test-account-name_user_by_id.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_account_name_user_by_id__not_found(void **state) {
+
+  const long size = 20;
+  struct passwd password;
+  uid_t uid = 0;
+  f_string_dynamic_t name = f_string_dynamic_t_initialize;
+
+  {
+    will_return(__wrap_sysconf, size);
+    will_return(__wrap_getpwuid_r, false);
+    will_return(__wrap_getpwuid_r, &password);
+    will_return(__wrap_getpwuid_r, (struct passwd *) 0);
+
+    const f_status_t status = f_account_name_user_by_id(uid, &name);
+
+    assert_int_equal(status, F_exist_not);
+  }
+
+  f_string_dynamic_resize(0, &name);
+}
+
+void test__f_account_name_user_by_id__works(void **state) {
+
+  const long size = 20;
+  struct passwd password;
+  struct passwd pointer;
+  uid_t uid = 0;
+  f_string_dynamic_t name = f_string_dynamic_t_initialize;
+
+  password.pw_uid = 1;
+  password.pw_gid = 2;
+  password.pw_dir = "pw_dir";
+  password.pw_gecos = "pw_gecos";
+  password.pw_name = "the_name";
+  password.pw_passwd = "pw_passwd";
+  password.pw_shell = "pw_shell";
+
+  {
+    will_return(__wrap_sysconf, size);
+    will_return(__wrap_getpwuid_r, false);
+    will_return(__wrap_getpwuid_r, &password);
+    will_return(__wrap_getpwuid_r, &pointer);
+
+    const f_status_t status = f_account_name_user_by_id(uid, &name);
+
+    assert_int_equal(status, F_none);
+    assert_string_equal(name.string, password.pw_name);
+  }
+
+  f_string_dynamic_resize(0, &name);
+}
+
+void test__f_account_name_user_by_id__fails(void **state) {
+
+  const long size = 20;
+  uid_t uid = 0;
+  f_string_dynamic_t name = f_string_dynamic_t_initialize;
+
+  int errnos[] = {
+    EINTR,
+    EIO,
+    EMFILE,
+    ENFILE,
+    ENOMEM,
+    ERANGE,
+    mock_errno_generic,
+  };
+
+  f_status_t statuss[] = {
+    F_interrupt,
+    F_input_output,
+    F_file_descriptor_max,
+    F_file_open_max,
+    F_memory_not,
+    F_buffer_too_small,
+    F_failure,
+  };
+
+  for (int i = 0; i < 7; ++i) {
+
+    will_return(__wrap_sysconf, size);
+    will_return(__wrap_getpwuid_r, true);
+    will_return(__wrap_getpwuid_r, errnos[i]);
+
+    const f_status_t status = f_account_name_user_by_id(uid, &name);
+
+    assert_int_equal(F_status_set_fine(status), statuss[i]);
+  } // for
+
+  f_string_dynamic_resize(0, &name);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_account/tests/c/test-account-name_user_by_id.h b/level_0/f_account/tests/c/test-account-name_user_by_id.h
new file mode 100644 (file)
index 0000000..5954e64
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Account
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the account project.
+ */
+#ifndef _TEST__F_account_name_user_by_id_
+#define _TEST__F_account_name_user_by_id_
+
+/**
+ * Test that function works but the group does not exist.
+ *
+ * @see f_account_name_user_by_id()
+ */
+extern void test__f_account_name_user_by_id__not_found(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_account_name_user_by_id()
+ */
+extern void test__f_account_name_user_by_id__works(void **state);
+
+/**
+ * Test that function fails.
+ *
+ * @see f_account_name_user_by_id()
+ */
+extern void test__f_account_name_user_by_id__fails(void **state);
+
+#endif // _TEST__F_account_name_user_by_id_
diff --git a/level_0/f_account/tests/c/test-account.c b/level_0/f_account/tests/c/test-account.c
new file mode 100644 (file)
index 0000000..534c6cf
--- /dev/null
@@ -0,0 +1,52 @@
+#include "test-account.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_account_by_id__not_found),
+    cmocka_unit_test(test__f_account_by_id__works),
+    cmocka_unit_test(test__f_account_by_id__fails),
+
+    cmocka_unit_test(test__f_account_by_name__not_found),
+    cmocka_unit_test(test__f_account_by_name__works),
+    cmocka_unit_test(test__f_account_by_name__fails),
+
+    cmocka_unit_test(test__f_account_id_group_by_name__not_found),
+    cmocka_unit_test(test__f_account_id_group_by_name__works),
+    cmocka_unit_test(test__f_account_id_group_by_name__fails),
+
+    cmocka_unit_test(test__f_account_id_user_by_name__not_found),
+    cmocka_unit_test(test__f_account_id_user_by_name__works),
+    cmocka_unit_test(test__f_account_id_user_by_name__fails),
+
+    cmocka_unit_test(test__f_account_id_group_by_name__not_found),
+    cmocka_unit_test(test__f_account_id_group_by_name__works),
+    cmocka_unit_test(test__f_account_id_group_by_name__fails),
+
+    cmocka_unit_test(test__f_account_id_user_by_name__not_found),
+    cmocka_unit_test(test__f_account_id_user_by_name__works),
+    cmocka_unit_test(test__f_account_id_user_by_name__fails),
+  };
+
+  return cmocka_run_group_tests(tests, setup, setdown);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_account/tests/c/test-account.h b/level_0/f_account/tests/c/test-account.h
new file mode 100644 (file)
index 0000000..030f92f
--- /dev/null
@@ -0,0 +1,77 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Account
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the account project.
+ */
+#ifndef _TEST__F_account_h
+#define _TEST__F_account_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/account.h>
+
+// mock includes.
+#include "mock-account.h"
+
+// test includes.
+#include "test-account-by_id.h"
+#include "test-account-by_name.h"
+#include "test-account-id_group_by_name.h"
+#include "test-account-id_user_by_name.h"
+#include "test-account-name_group_by_id.h"
+#include "test-account-name_user_by_id.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_account_h