From: Kevin Day Date: Fri, 14 Jan 2022 04:53:13 +0000 (-0600) Subject: Update: Add unit tests for f_account. X-Git-Tag: 0.5.8~118 X-Git-Url: https://git.kevux.org/?a=commitdiff_plain;h=ff9c22e50497ee35c72c4c7e0143765d75aded30;p=fll Update: Add unit tests for f_account. --- diff --git a/level_0/f_account/data/build/dependencies-tests b/level_0/f_account/data/build/dependencies-tests new file mode 100644 index 0000000..dea3179 --- /dev/null +++ b/level_0/f_account/data/build/dependencies-tests @@ -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 index 0000000..6d11bbd --- /dev/null +++ b/level_0/f_account/data/build/settings-mocks @@ -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 index 0000000..c623264 --- /dev/null +++ b/level_0/f_account/data/build/settings-tests @@ -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 index 0000000..6acb1da --- /dev/null +++ b/level_0/f_account/data/build/testfile @@ -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 index 0000000..d3c95da --- /dev/null +++ b/level_0/f_account/tests/c/mock-account.c @@ -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 index 0000000..d299173 --- /dev/null +++ b/level_0/f_account/tests/c/mock-account.h @@ -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 +#include +#include +#include + +// cmocka includes. +#include + +// fll-0 includes. +#include + +#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 index 0000000..3c43894 --- /dev/null +++ b/level_0/f_account/tests/c/test-account-by_id.c @@ -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 index 0000000..00c9d31 --- /dev/null +++ b/level_0/f_account/tests/c/test-account-by_id.h @@ -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 index 0000000..d3a9075 --- /dev/null +++ b/level_0/f_account/tests/c/test-account-by_name.c @@ -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 index 0000000..4653293 --- /dev/null +++ b/level_0/f_account/tests/c/test-account-by_name.h @@ -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 index 0000000..b547d98 --- /dev/null +++ b/level_0/f_account/tests/c/test-account-id_group_by_name.c @@ -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 index 0000000..81f0c77 --- /dev/null +++ b/level_0/f_account/tests/c/test-account-id_group_by_name.h @@ -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 index 0000000..17811ed --- /dev/null +++ b/level_0/f_account/tests/c/test-account-id_user_by_name.c @@ -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 index 0000000..d60904a --- /dev/null +++ b/level_0/f_account/tests/c/test-account-id_user_by_name.h @@ -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 index 0000000..d1ff343 --- /dev/null +++ b/level_0/f_account/tests/c/test-account-name_group_by_id.c @@ -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 index 0000000..6d44b98 --- /dev/null +++ b/level_0/f_account/tests/c/test-account-name_group_by_id.h @@ -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 index 0000000..bf14520 --- /dev/null +++ b/level_0/f_account/tests/c/test-account-name_user_by_id.c @@ -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 index 0000000..5954e64 --- /dev/null +++ b/level_0/f_account/tests/c/test-account-name_user_by_id.h @@ -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 index 0000000..534c6cf --- /dev/null +++ b/level_0/f_account/tests/c/test-account.c @@ -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 index 0000000..030f92f --- /dev/null +++ b/level_0/f_account/tests/c/test-account.h @@ -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 +#include +#include +#include + +// cmocka includes. +#include + +// fll-0 includes. +#include + +// 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