From 125b8aaa3161a669578345c54bbc44874ff43661 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Sat, 30 Aug 2025 15:21:37 -0500 Subject: [PATCH] Progress: Add more functions to f_schedule. This adds: - `f_schedule_policy_get()` - `f_schedule_policy_set()` - `f_schedule_priority_get()` - `f_schedule_priority_set()` - `f_schedule_value_get()` - `f_schedule_value_set()` --- level_0/f_schedule/c/schedule.c | 119 ++++++++++++++ level_0/f_schedule/c/schedule.h | 175 ++++++++++++++++++++- level_0/f_schedule/c/schedule/common.h | 26 +++ level_0/f_schedule/data/build/settings-mocks | 6 + level_0/f_schedule/data/build/settings-tests | 3 + level_0/f_schedule/tests/unit/c/mock-schedule.c | 82 ++++++++++ level_0/f_schedule/tests/unit/c/mock-schedule.h | 7 + .../tests/unit/c/test-schedule-policy_get.c | 68 ++++++++ .../tests/unit/c/test-schedule-policy_get.h | 34 ++++ .../tests/unit/c/test-schedule-policy_set.c | 63 ++++++++ .../tests/unit/c/test-schedule-policy_set.h | 34 ++++ .../tests/unit/c/test-schedule-priority_get.c | 70 +++++++++ .../tests/unit/c/test-schedule-priority_get.h | 34 ++++ .../tests/unit/c/test-schedule-priority_set.c | 52 ++++++ .../tests/unit/c/test-schedule-priority_set.h | 27 ++++ .../tests/unit/c/test-schedule-value_get.c | 68 ++++++++ .../tests/unit/c/test-schedule-value_get.h | 34 ++++ .../tests/unit/c/test-schedule-value_set.c | 63 ++++++++ .../tests/unit/c/test-schedule-value_set.h | 34 ++++ level_0/f_schedule/tests/unit/c/test-schedule.c | 24 +++ level_0/f_schedule/tests/unit/c/test-schedule.h | 6 + 21 files changed, 1022 insertions(+), 7 deletions(-) create mode 100644 level_0/f_schedule/tests/unit/c/test-schedule-policy_get.c create mode 100644 level_0/f_schedule/tests/unit/c/test-schedule-policy_get.h create mode 100644 level_0/f_schedule/tests/unit/c/test-schedule-policy_set.c create mode 100644 level_0/f_schedule/tests/unit/c/test-schedule-policy_set.h create mode 100644 level_0/f_schedule/tests/unit/c/test-schedule-priority_get.c create mode 100644 level_0/f_schedule/tests/unit/c/test-schedule-priority_get.h create mode 100644 level_0/f_schedule/tests/unit/c/test-schedule-priority_set.c create mode 100644 level_0/f_schedule/tests/unit/c/test-schedule-priority_set.h create mode 100644 level_0/f_schedule/tests/unit/c/test-schedule-value_get.c create mode 100644 level_0/f_schedule/tests/unit/c/test-schedule-value_get.h create mode 100644 level_0/f_schedule/tests/unit/c/test-schedule-value_set.c create mode 100644 level_0/f_schedule/tests/unit/c/test-schedule-value_set.h diff --git a/level_0/f_schedule/c/schedule.c b/level_0/f_schedule/c/schedule.c index 067036c..2c38f63 100644 --- a/level_0/f_schedule/c/schedule.c +++ b/level_0/f_schedule/c/schedule.c @@ -23,6 +23,125 @@ extern "C" { } #endif // _di_f_schedule_nice_ +#ifndef _di_f_schedule_policy_get_ + f_status_t f_schedule_policy_get(const pid_t id, int * const policy) { + #ifndef _di_level_0_parameter_checking_ + if (!policy) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + const int result = sched_getscheduler(id); + + if (result == -1) { + if (errno == EINVAL) return F_status_set_error(F_parameter); + if (errno == EPERM) return F_status_set_error(F_prohibited); + if (errno == ESRCH) return F_status_set_error(F_search); + + return F_status_set_error(F_failure); + } + + *policy = result; + + return F_okay; + } +#endif // _di_f_schedule_policy_get_ + +#ifndef _di_f_schedule_policy_set_ + f_status_t f_schedule_policy_set(const pid_t id, const int policy, const f_schedule_value_t * const value) { + #ifndef _di_level_0_parameter_checking_ + if (!value) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (sched_setscheduler(id, policy, value) == -1) { + if (errno == EINVAL) return F_status_set_error(F_parameter); + if (errno == EPERM) return F_status_set_error(F_prohibited); + if (errno == ESRCH) return F_status_set_error(F_search); + + return F_status_set_error(F_failure); + } + + return F_okay; + } +#endif // _di_f_schedule_policy_set_ + +#ifndef _di_f_schedule_priority_get_ + f_status_t f_schedule_priority_get(const int type, const id_t id, int * const priority) { + #ifndef _di_level_0_parameter_checking_ + if (!priority) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + const int result = getpriority(type, id); + + if (result == -1) { + if (errno == EACCES) return F_status_set_error(F_access_denied); + if (errno == EINVAL) return F_status_set_error(F_parameter); + if (errno == EPERM) return F_status_set_error(F_prohibited); + if (errno == ESRCH) return F_status_set_error(F_search); + + return F_status_set_error(F_failure); + } + + *priority = result; + + return F_okay; + } +#endif // _di_f_schedule_priority_get_ + +#ifndef _di_f_schedule_priority_set_ + f_status_t f_schedule_priority_set(const int type, const id_t id, const int priority) { + + if (setpriority(type, id, priority) == -1) { + if (errno == EACCES) return F_status_set_error(F_access_denied); + if (errno == EINVAL) return F_status_set_error(F_parameter); + if (errno == EPERM) return F_status_set_error(F_prohibited); + if (errno == ESRCH) return F_status_set_error(F_search); + + return F_status_set_error(F_failure); + } + + return F_okay; + } +#endif // _di_f_schedule_priority_set_ + +#ifndef _di_f_schedule_value_get_ + f_status_t f_schedule_value_get(const pid_t id, f_schedule_value_t * const value) { + #ifndef _di_level_0_parameter_checking_ + if (!value) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + f_schedule_value_t result = f_schedule_value_t_initialize; + + if (sched_getparam(id, &result) == -1) { + if (errno == EINVAL) return F_status_set_error(F_parameter); + if (errno == EPERM) return F_status_set_error(F_prohibited); + if (errno == ESRCH) return F_status_set_error(F_search); + + return F_status_set_error(F_failure); + } + + *value = result; + + return F_okay; + } +#endif // _di_f_schedule_value_get_ + +#ifndef _di_f_schedule_value_set_ + f_status_t f_schedule_value_set(const pid_t id, const f_schedule_value_t * const value) { + #ifndef _di_level_0_parameter_checking_ + if (!value) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (sched_setparam(id, value) == -1) { + if (errno == EINVAL) return F_status_set_error(F_parameter); + if (errno == EPERM) return F_status_set_error(F_prohibited); + if (errno == ESRCH) return F_status_set_error(F_search); + + return F_status_set_error(F_failure); + } + + return F_okay; + } +#endif // _di_f_schedule_value_set_ + #ifdef __cplusplus } // extern "C" #endif diff --git a/level_0/f_schedule/c/schedule.h b/level_0/f_schedule/c/schedule.h index 554b2f2..9dca3df 100644 --- a/level_0/f_schedule/c/schedule.h +++ b/level_0/f_schedule/c/schedule.h @@ -11,6 +11,9 @@ #define _F_schedule_h // Libc includes. +#include +#include +#include #include // FLL-0 includes. @@ -41,7 +44,7 @@ extern "C" { * The max value is 19 and the lowest value is -20. * * @return - * F_okay on success but no signal found. + * F_okay on success. * * F_too_large (with error bit) if the niceness value is too large (greater than 19). * F_too_small (with error bit) if the niceness value is too small (less than -20). @@ -55,14 +58,172 @@ extern "C" { extern f_status_t f_schedule_nice(const int niceness); #endif // _di_f_schedule_nice_ +/** + * Get the process policy. + * + * @param id + * The process ID. + * + * If id is 0, then the policy of the current process thread is returned. + * @param policy + * The retrieved policy. + * + * Must not be NULL. + * + * @return + * F_okay on success. + * + * F_parameter (with error bit) if a parameter is invalid. + * F_prohibited (with error bit) if a ID is valid but the effective ID or real ID does not match the callers and CAP_SYS_NICE is not set. + * F_search (with error bit) if ID could not be found. + * + * F_failure (with error bit) for any other error. + * + * @see sched_getscheduler() + */ +#ifndef _di_f_schedule_policy_get_ + extern f_status_t f_schedule_policy_get(const pid_t id, int * const policy); +#endif // _di_f_schedule_policy_get_ + +/** + * Set the process policy. + * + * @param id + * The process ID, process group ID, or user ID. + * @param policy + * The policy to set. + * @param value + * The scheduler value. + * + * Must not be NULL. + * + * @return + * F_okay on success. + * + * F_parameter (with error bit) if a parameter is invalid. + * F_prohibited (with error bit) if a ID is valid but the effective ID or real ID does not match the callers and CAP_SYS_NICE is not set. + * F_search (with error bit) if ID could not be found. + * + * F_failure (with error bit) for any other error. + * + * @see sched_setscheduler() + */ +#ifndef _di_f_schedule_policy_set_ + extern f_status_t f_schedule_policy_set(const pid_t id, const int policy, const f_schedule_value_t * const value); +#endif // _di_f_schedule_policy_set_ + +/** + * Get the process priority. + * + * The highest priority of anything associated with the given ID is returned. + * + * @param type + * The type being whose schedule priority is being retrieved + * One of f_schedule_priority_*_d. + * @param id + * The process ID, process group ID, or user ID. + * @param priority + * The retrieved priority. + * + * Must not be NULL. + * + * @return + * F_okay on success. + * + * F_access_denied (with error bit) If caller has insufficient priviledges to get the priority. + * F_parameter (with error bit) if a parameter is invalid. + * F_prohibited (with error bit) if a ID is valid but the effective ID or real ID does not match the callers and CAP_SYS_NICE is not set. + * F_search (with error bit) if ID could not be found. + * + * F_failure (with error bit) for any other error. + * + * @see getpriority() + */ +#ifndef _di_f_schedule_priority_get_ + extern f_status_t f_schedule_priority_get(const int type, const id_t id, int * const priority); +#endif // _di_f_schedule_priority_get_ + +/** + * Set the process priority. + * + * @param type + * The type being whose schedule priority is being set + * One of f_schedule_priority_*_d. + * @param id + * The process ID, process group ID, or user ID. + * @param priority + * The priority to set. + * + * @return + * F_okay on success. + * + * F_access_denied (with error bit) If caller has insufficient priviledges to set the priority. + * F_parameter (with error bit) if a parameter is invalid. + * F_prohibited (with error bit) if a ID is valid but the effective ID or real ID does not match the callers and CAP_SYS_NICE is not set. + * F_search (with error bit) if ID could not be found. + * + * F_failure (with error bit) for any other error. + * + * @see setpriority() + */ +#ifndef _di_f_schedule_priority_set_ + extern f_status_t f_schedule_priority_set(const int type, const id_t id, const int priority); +#endif // _di_f_schedule_priority_set_ + +/** + * Get the schedule parameter value. + * + * @param id + * The process ID. + * + * If id is 0, then the value of the current process thread is returned. + * @param value + * The retrieved scheduler value. + * + * Must not be NULL. + * + * @return + * F_okay on success. + * + * F_parameter (with error bit) if a parameter is invalid. + * F_prohibited (with error bit) if a ID is valid but the effective ID or real ID does not match the callers and CAP_SYS_NICE is not set. + * F_search (with error bit) if ID could not be found. + * + * F_failure (with error bit) for any other error. + * + * @see sched_getparam() + */ +#ifndef _di_f_schedule_value_get_ + extern f_status_t f_schedule_value_get(const pid_t id, f_schedule_value_t * const value); +#endif // _di_f_schedule_value_get_ + +/** + * Set the schedule parameter value. + * + * @param id + * The process ID, process group ID, or user ID. + * @param value + * The scheduler value. + * + * Must not be NULL. + * + * @return + * F_okay on success. + * + * F_parameter (with error bit) if a parameter is invalid. + * F_prohibited (with error bit) if a ID is valid but the effective ID or real ID does not match the callers and CAP_SYS_NICE is not set. + * F_search (with error bit) if ID could not be found. + * + * F_failure (with error bit) for any other error. + * + * @see sched_setparam() + */ +#ifndef _di_f_schedule_value_set_ + extern f_status_t f_schedule_value_set(const pid_t id, const f_schedule_value_t * const value); +#endif // _di_f_schedule_value_set_ + /* * @todo: add all of these: - getpriority() - setpriority() - sched_setscheduler() - sched_getscheduler() - sched_setparam() - sched_getparam() sched_get_priority_max() sched_get_priority_min() sched_rr_get_interval() diff --git a/level_0/f_schedule/c/schedule/common.h b/level_0/f_schedule/c/schedule/common.h index 312488a..2f1d6fa 100644 --- a/level_0/f_schedule/c/schedule/common.h +++ b/level_0/f_schedule/c/schedule/common.h @@ -34,6 +34,32 @@ extern "C" { #define f_schedule_policy_standard_d SCHED_OTHER #endif // _di_f_schedule_policy_d_ +/** + * Thread scheduler priority defines. + * + * f_schedule_priority_*_d: + * - group: A process group. + * - process: A process. + * - user: A user. + */ +#ifndef _di_f_schedule_priority_d_ + #define f_schedule_priority_group_d PRIO_PGRP + #define f_schedule_priority_process_d PRIO_PROCESS + #define f_schedule_priority_user_d PRIO_USER +#endif // _di_f_schedule_priority_d_ + +/** + * A typedef for representing a sched_param structure from . + * + * Note that the actual path might be something like . + */ +#ifndef _di_f_schedule_value_t_ + typedef struct sched_param f_schedule_value_t; + + #define f_schedule_value_t_initialize { 0 } + + #define macro_f_schedule_value_t_initialize_1(priority) { .sched_priority = priority } +#endif // _di_f_schedule_value_t_ #ifdef __cplusplus } // extern "C" diff --git a/level_0/f_schedule/data/build/settings-mocks b/level_0/f_schedule/data/build/settings-mocks index bd7744c..af58b0c 100644 --- a/level_0/f_schedule/data/build/settings-mocks +++ b/level_0/f_schedule/data/build/settings-mocks @@ -64,4 +64,10 @@ flags-test -fstack-protector-strong -Wall -Wno-missing-braces flags_library -fPIC # Inject mocks. +flags -Wl,--wrap=getpriority flags -Wl,--wrap=nice +flags -Wl,--wrap=sched_getparam +flags -Wl,--wrap=sched_getscheduler +flags -Wl,--wrap=sched_setparam +flags -Wl,--wrap=sched_setscheduler +flags -Wl,--wrap=setpriority diff --git a/level_0/f_schedule/data/build/settings-tests b/level_0/f_schedule/data/build/settings-tests index d6096b3..670b31b 100644 --- a/level_0/f_schedule/data/build/settings-tests +++ b/level_0/f_schedule/data/build/settings-tests @@ -26,6 +26,9 @@ build_libraries -lc -lcmocka build_libraries-individual -lf_memory -lf_string -lf_schedule build_sources_program test-schedule-nice.c +build_sources_program test-schedule-policy_get.c test-schedule-policy_set.c +build_sources_program test-schedule-priority_get.c test-schedule-priority_set.c +build_sources_program test-schedule-value_get.c test-schedule-value_set.c build_sources_program test-schedule.c build_script no diff --git a/level_0/f_schedule/tests/unit/c/mock-schedule.c b/level_0/f_schedule/tests/unit/c/mock-schedule.c index 573833e..513aabc 100644 --- a/level_0/f_schedule/tests/unit/c/mock-schedule.c +++ b/level_0/f_schedule/tests/unit/c/mock-schedule.c @@ -4,6 +4,19 @@ extern "C" { #endif +int __wrap_getpriority(int which, id_t who) { + + const bool failure = mock_type(bool); + + if (failure) { + errno = mock_type(int); + + return -1; + } + + return mock_type(int); +} + int __wrap_nice(int inc) { const bool failure = mock_type(bool); @@ -17,6 +30,75 @@ int __wrap_nice(int inc) { return 0; } +int __wrap_sched_getparam(pid_t pid, struct sched_param *param) { + + const bool failure = mock_type(bool); + + if (failure) { + errno = mock_type(int); + + return -1; + } + + f_schedule_value_t *mock_param = mock_ptr_type(f_schedule_value_t *); + + *param = *mock_param; + + return 0; +} + +int __wrap_sched_getscheduler(pid_t pid) { + + const bool failure = mock_type(bool); + + if (failure) { + errno = mock_type(int); + + return -1; + } + + return mock_type(int); +} + +int __wrap_sched_setparam(pid_t pid, const struct sched_param *param) { + + const bool failure = mock_type(bool); + + if (failure) { + errno = mock_type(int); + + return -1; + } + + return 0; +} + +int __wrap_sched_setscheduler(pid_t pid, int policy, const struct sched_param *param) { + + const bool failure = mock_type(bool); + + if (failure) { + errno = mock_type(int); + + return -1; + } + + return 0; +} + +int __wrap_setpriority(int which, id_t who, int prio) { + + 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_schedule/tests/unit/c/mock-schedule.h b/level_0/f_schedule/tests/unit/c/mock-schedule.h index 23d2888..9f1c93d 100644 --- a/level_0/f_schedule/tests/unit/c/mock-schedule.h +++ b/level_0/f_schedule/tests/unit/c/mock-schedule.h @@ -28,7 +28,14 @@ extern "C" { const static int mock_errno_generic = 32767; +extern int __wrap_getpriority(int which, id_t who); extern int __wrap_nice(int inc); +extern int __wrap_sched_getparam(pid_t pid, struct sched_param *param); +extern int __wrap_sched_getscheduler(pid_t pid); +extern int __wrap_sched_setparam(pid_t pid, const struct sched_param *param); +extern int __wrap_sched_setscheduler(pid_t pid, int policy, const struct sched_param *param); +extern int __wrap_setpriority(int which, id_t who, int prio); + #ifdef __cplusplus } // extern "C" diff --git a/level_0/f_schedule/tests/unit/c/test-schedule-policy_get.c b/level_0/f_schedule/tests/unit/c/test-schedule-policy_get.c new file mode 100644 index 0000000..d745fb2 --- /dev/null +++ b/level_0/f_schedule/tests/unit/c/test-schedule-policy_get.c @@ -0,0 +1,68 @@ +#include "test-schedule.h" +#include "test-schedule-policy_get.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void test__f_schedule_policy_get__fails(void **state) { + + { + int errnos[] = { + EINVAL, + EPERM, + ESRCH, + mock_errno_generic, + }; + + f_status_t statuss[] = { + F_parameter, + F_prohibited, + F_search, + F_failure, + }; + + for (int i = 0; i < 4; ++i) { + + int policy = 0; + + will_return(__wrap_sched_getscheduler, true); + will_return(__wrap_sched_getscheduler, errnos[i]); + + const f_status_t status = f_schedule_policy_get(0, &policy); + + assert_int_equal(status, F_status_set_error(statuss[i])); + } // for + } +} + +void test__f_schedule_policy_get__parameter_checking(void **state) { + + { + const f_status_t status = f_schedule_policy_get(0, 0); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } +} + + +void test__f_schedule_policy_get__works(void **state) { + + const int expected = 2; + + { + int policy = 0; + + will_return(__wrap_sched_getscheduler, false); + will_return(__wrap_sched_getscheduler, expected); + + const f_status_t status = f_schedule_policy_get(0, &policy); + + assert_int_equal(status, F_okay); + assert_int_equal(policy, expected); + } +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_schedule/tests/unit/c/test-schedule-policy_get.h b/level_0/f_schedule/tests/unit/c/test-schedule-policy_get.h new file mode 100644 index 0000000..88b2583 --- /dev/null +++ b/level_0/f_schedule/tests/unit/c/test-schedule-policy_get.h @@ -0,0 +1,34 @@ +/** + * FLL - Level 0 + * + * Project: Schedule + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Test the schedule project. + */ +#ifndef _TEST__F_schedule_policy_get_h +#define _TEST__F_schedule_policy_get_h + +/** + * Test that function fails. + * + * @see f_schedule_policy_get() + */ +extern void test__f_schedule_policy_get__fails(void **state); + +/** + * Test that the function correctly fails on invalid parameter. + * + * @see f_schedule_policy_get() + */ +extern void test__f_schedule_policy_get__parameter_checking(void **state); + +/** + * Test that function works. + * + * @see f_schedule_policy_get() + */ +extern void test__f_schedule_policy_get__works(void **state); + +#endif // _TEST__F_schedule_policy_get_h diff --git a/level_0/f_schedule/tests/unit/c/test-schedule-policy_set.c b/level_0/f_schedule/tests/unit/c/test-schedule-policy_set.c new file mode 100644 index 0000000..b05783f --- /dev/null +++ b/level_0/f_schedule/tests/unit/c/test-schedule-policy_set.c @@ -0,0 +1,63 @@ +#include "test-schedule.h" +#include "test-schedule-policy_set.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void test__f_schedule_policy_set__fails(void **state) { + + { + int errnos[] = { + EINVAL, + EPERM, + ESRCH, + mock_errno_generic, + }; + + f_status_t statuss[] = { + F_parameter, + F_prohibited, + F_search, + F_failure, + }; + + for (int i = 0; i < 4; ++i) { + + f_schedule_value_t value = f_schedule_value_t_initialize; + + will_return(__wrap_sched_setscheduler, true); + will_return(__wrap_sched_setscheduler, errnos[i]); + + const f_status_t status = f_schedule_policy_set(0, 0, &value); + + assert_int_equal(status, F_status_set_error(statuss[i])); + } // for + } +} + +void test__f_schedule_policy_set__parameter_checking(void **state) { + + { + const f_status_t status = f_schedule_policy_set(0, 0, 0); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } +} + +void test__f_schedule_policy_set__works(void **state) { + + { + f_schedule_value_t value = f_schedule_value_t_initialize; + + will_return(__wrap_sched_setscheduler, false); + + const f_status_t status = f_schedule_policy_set(0, 0, &value); + + assert_int_equal(status, F_okay); + } +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_schedule/tests/unit/c/test-schedule-policy_set.h b/level_0/f_schedule/tests/unit/c/test-schedule-policy_set.h new file mode 100644 index 0000000..46dba95 --- /dev/null +++ b/level_0/f_schedule/tests/unit/c/test-schedule-policy_set.h @@ -0,0 +1,34 @@ +/** + * FLL - Level 0 + * + * Project: Schedule + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Test the schedule project. + */ +#ifndef _TEST__F_schedule_policy_set_h +#define _TEST__F_schedule_policy_set_h + +/** + * Test that function fails. + * + * @see f_schedule_policy_set() + */ +extern void test__f_schedule_policy_set__fails(void **state); + +/** + * Test that the function correctly fails on invalid parameter. + * + * @see f_schedule_policy_set() + */ +extern void test__f_schedule_policy_set__parameter_checking(void **state); + +/** + * Test that function works. + * + * @see f_schedule_policy_set() + */ +extern void test__f_schedule_policy_set__works(void **state); + +#endif // _TEST__F_schedule_policy_set_h diff --git a/level_0/f_schedule/tests/unit/c/test-schedule-priority_get.c b/level_0/f_schedule/tests/unit/c/test-schedule-priority_get.c new file mode 100644 index 0000000..3ca582f --- /dev/null +++ b/level_0/f_schedule/tests/unit/c/test-schedule-priority_get.c @@ -0,0 +1,70 @@ +#include "test-schedule.h" +#include "test-schedule-priority_get.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void test__f_schedule_priority_get__fails(void **state) { + + { + int errnos[] = { + EACCES, + EINVAL, + EPERM, + ESRCH, + mock_errno_generic, + }; + + f_status_t statuss[] = { + F_access_denied, + F_parameter, + F_prohibited, + F_search, + F_failure, + }; + + for (int i = 0; i < 5; ++i) { + + int priority = 0; + + will_return(__wrap_getpriority, true); + will_return(__wrap_getpriority, errnos[i]); + + const f_status_t status = f_schedule_priority_get(0, 0, &priority); + + assert_int_equal(status, F_status_set_error(statuss[i])); + } // for + } +} + +void test__f_schedule_priority_get__parameter_checking(void **state) { + + { + const f_status_t status = f_schedule_priority_get(0, 0, 0); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } +} + + +void test__f_schedule_priority_get__works(void **state) { + + const int expected = 2; + + { + int priority = 0; + + will_return(__wrap_getpriority, false); + will_return(__wrap_getpriority, expected); + + const f_status_t status = f_schedule_priority_get(0, 0, &priority); + + assert_int_equal(status, F_okay); + assert_int_equal(priority, expected); + } +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_schedule/tests/unit/c/test-schedule-priority_get.h b/level_0/f_schedule/tests/unit/c/test-schedule-priority_get.h new file mode 100644 index 0000000..3c9cd6c --- /dev/null +++ b/level_0/f_schedule/tests/unit/c/test-schedule-priority_get.h @@ -0,0 +1,34 @@ +/** + * FLL - Level 0 + * + * Project: Schedule + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Test the schedule project. + */ +#ifndef _TEST__F_schedule_priority_get_h +#define _TEST__F_schedule_priority_get_h + +/** + * Test that function fails. + * + * @see f_schedule_priority_get() + */ +extern void test__f_schedule_priority_get__fails(void **state); + +/** + * Test that the function correctly fails on invalid parameter. + * + * @see f_schedule_priority_get() + */ +extern void test__f_schedule_priority_get__parameter_checking(void **state); + +/** + * Test that function works. + * + * @see f_schedule_priority_get() + */ +extern void test__f_schedule_priority_get__works(void **state); + +#endif // _TEST__F_schedule_priority_get_h diff --git a/level_0/f_schedule/tests/unit/c/test-schedule-priority_set.c b/level_0/f_schedule/tests/unit/c/test-schedule-priority_set.c new file mode 100644 index 0000000..9918c51 --- /dev/null +++ b/level_0/f_schedule/tests/unit/c/test-schedule-priority_set.c @@ -0,0 +1,52 @@ +#include "test-schedule.h" +#include "test-schedule-priority_set.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void test__f_schedule_priority_set__fails(void **state) { + + { + int errnos[] = { + EACCES, + EINVAL, + EPERM, + ESRCH, + mock_errno_generic, + }; + + f_status_t statuss[] = { + F_access_denied, + F_parameter, + F_prohibited, + F_search, + F_failure, + }; + + for (int i = 0; i < 5; ++i) { + + will_return(__wrap_setpriority, true); + will_return(__wrap_setpriority, errnos[i]); + + const f_status_t status = f_schedule_priority_set(0, 0, 0); + + assert_int_equal(status, F_status_set_error(statuss[i])); + } // for + } +} + +void test__f_schedule_priority_set__works(void **state) { + + { + will_return(__wrap_setpriority, false); + + const f_status_t status = f_schedule_priority_set(0, 0, 0); + + assert_int_equal(status, F_okay); + } +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_schedule/tests/unit/c/test-schedule-priority_set.h b/level_0/f_schedule/tests/unit/c/test-schedule-priority_set.h new file mode 100644 index 0000000..5fd9b8e --- /dev/null +++ b/level_0/f_schedule/tests/unit/c/test-schedule-priority_set.h @@ -0,0 +1,27 @@ +/** + * FLL - Level 0 + * + * Project: Schedule + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Test the schedule project. + */ +#ifndef _TEST__F_schedule_priority_set_h +#define _TEST__F_schedule_priority_set_h + +/** + * Test that function fails. + * + * @see f_schedule_priority_set() + */ +extern void test__f_schedule_priority_set__fails(void **state); + +/** + * Test that function works. + * + * @see f_schedule_priority_set() + */ +extern void test__f_schedule_priority_set__works(void **state); + +#endif // _TEST__F_schedule_priority_set_h diff --git a/level_0/f_schedule/tests/unit/c/test-schedule-value_get.c b/level_0/f_schedule/tests/unit/c/test-schedule-value_get.c new file mode 100644 index 0000000..6cff16f --- /dev/null +++ b/level_0/f_schedule/tests/unit/c/test-schedule-value_get.c @@ -0,0 +1,68 @@ +#include "test-schedule.h" +#include "test-schedule-value_get.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void test__f_schedule_value_get__fails(void **state) { + + { + int errnos[] = { + EINVAL, + EPERM, + ESRCH, + mock_errno_generic, + }; + + f_status_t statuss[] = { + F_parameter, + F_prohibited, + F_search, + F_failure, + }; + + for (int i = 0; i < 4; ++i) { + + f_schedule_value_t value = f_schedule_value_t_initialize; + + will_return(__wrap_sched_getparam, true); + will_return(__wrap_sched_getparam, errnos[i]); + + const f_status_t status = f_schedule_value_get(0, &value); + + assert_int_equal(status, F_status_set_error(statuss[i])); + } // for + } +} + +void test__f_schedule_value_get__parameter_checking(void **state) { + + { + const f_status_t status = f_schedule_value_get(0, 0); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } +} + + +void test__f_schedule_value_get__works(void **state) { + + f_schedule_value_t expected = macro_f_schedule_value_t_initialize_1(2); + + { + f_schedule_value_t value = f_schedule_value_t_initialize; + + will_return(__wrap_sched_getparam, false); + will_return(__wrap_sched_getparam, &expected); + + const f_status_t status = f_schedule_value_get(0, &value); + + assert_int_equal(status, F_okay); + assert_int_equal(value.sched_priority, expected.sched_priority); + } +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_schedule/tests/unit/c/test-schedule-value_get.h b/level_0/f_schedule/tests/unit/c/test-schedule-value_get.h new file mode 100644 index 0000000..afc8483 --- /dev/null +++ b/level_0/f_schedule/tests/unit/c/test-schedule-value_get.h @@ -0,0 +1,34 @@ +/** + * FLL - Level 0 + * + * Project: Schedule + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Test the schedule project. + */ +#ifndef _TEST__F_schedule_value_get_h +#define _TEST__F_schedule_value_get_h + +/** + * Test that function fails. + * + * @see f_schedule_value_get() + */ +extern void test__f_schedule_value_get__fails(void **state); + +/** + * Test that the function correctly fails on invalid parameter. + * + * @see f_schedule_value_get() + */ +extern void test__f_schedule_value_get__parameter_checking(void **state); + +/** + * Test that function works. + * + * @see f_schedule_value_get() + */ +extern void test__f_schedule_value_get__works(void **state); + +#endif // _TEST__F_schedule_value_get_h diff --git a/level_0/f_schedule/tests/unit/c/test-schedule-value_set.c b/level_0/f_schedule/tests/unit/c/test-schedule-value_set.c new file mode 100644 index 0000000..fbc690e --- /dev/null +++ b/level_0/f_schedule/tests/unit/c/test-schedule-value_set.c @@ -0,0 +1,63 @@ +#include "test-schedule.h" +#include "test-schedule-value_set.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void test__f_schedule_value_set__fails(void **state) { + + { + int errnos[] = { + EINVAL, + EPERM, + ESRCH, + mock_errno_generic, + }; + + f_status_t statuss[] = { + F_parameter, + F_prohibited, + F_search, + F_failure, + }; + + for (int i = 0; i < 4; ++i) { + + f_schedule_value_t value = f_schedule_value_t_initialize; + + will_return(__wrap_sched_setparam, true); + will_return(__wrap_sched_setparam, errnos[i]); + + const f_status_t status = f_schedule_value_set(0, &value); + + assert_int_equal(status, F_status_set_error(statuss[i])); + } // for + } +} + +void test__f_schedule_value_set__parameter_checking(void **state) { + + { + const f_status_t status = f_schedule_value_set(0, 0); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } +} + +void test__f_schedule_value_set__works(void **state) { + + { + f_schedule_value_t value = f_schedule_value_t_initialize; + + will_return(__wrap_sched_setparam, false); + + const f_status_t status = f_schedule_value_set(0, &value); + + assert_int_equal(status, F_okay); + } +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_schedule/tests/unit/c/test-schedule-value_set.h b/level_0/f_schedule/tests/unit/c/test-schedule-value_set.h new file mode 100644 index 0000000..3d904e7 --- /dev/null +++ b/level_0/f_schedule/tests/unit/c/test-schedule-value_set.h @@ -0,0 +1,34 @@ +/** + * FLL - Level 0 + * + * Project: Schedule + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Test the schedule project. + */ +#ifndef _TEST__F_schedule_value_set_h +#define _TEST__F_schedule_value_set_h + +/** + * Test that function fails. + * + * @see f_schedule_value_set() + */ +extern void test__f_schedule_value_set__fails(void **state); + +/** + * Test that the function correctly fails on invalid parameter. + * + * @see f_schedule_value_set() + */ +extern void test__f_schedule_value_set__parameter_checking(void **state); + +/** + * Test that function works. + * + * @see f_schedule_value_set() + */ +extern void test__f_schedule_value_set__works(void **state); + +#endif // _TEST__F_schedule_value_set_h diff --git a/level_0/f_schedule/tests/unit/c/test-schedule.c b/level_0/f_schedule/tests/unit/c/test-schedule.c index ca39255..ec80813 100644 --- a/level_0/f_schedule/tests/unit/c/test-schedule.c +++ b/level_0/f_schedule/tests/unit/c/test-schedule.c @@ -25,8 +25,32 @@ int main(void) { cmocka_unit_test(test__f_schedule_nice__returns_too_large), cmocka_unit_test(test__f_schedule_nice__returns_too_small), + cmocka_unit_test(test__f_schedule_policy_get__fails), + cmocka_unit_test(test__f_schedule_policy_get__works), + + cmocka_unit_test(test__f_schedule_policy_set__fails), + cmocka_unit_test(test__f_schedule_policy_set__works), + + cmocka_unit_test(test__f_schedule_priority_get__fails), + cmocka_unit_test(test__f_schedule_priority_get__works), + + cmocka_unit_test(test__f_schedule_priority_set__fails), + cmocka_unit_test(test__f_schedule_priority_set__works), + + cmocka_unit_test(test__f_schedule_value_get__fails), + cmocka_unit_test(test__f_schedule_value_get__works), + + cmocka_unit_test(test__f_schedule_value_set__fails), + cmocka_unit_test(test__f_schedule_value_set__works), + #ifndef _di_level_0_parameter_checking_ // f_schedule_nice() doesn't use parameter checking. + cmocka_unit_test(test__f_schedule_policy_get__parameter_checking), + cmocka_unit_test(test__f_schedule_policy_set__parameter_checking), + cmocka_unit_test(test__f_schedule_priority_get__parameter_checking), + // f_schedule_priority_set() doesn't use parameter checking. + cmocka_unit_test(test__f_schedule_value_get__parameter_checking), + cmocka_unit_test(test__f_schedule_value_set__parameter_checking), #endif // _di_level_0_parameter_checking_ }; diff --git a/level_0/f_schedule/tests/unit/c/test-schedule.h b/level_0/f_schedule/tests/unit/c/test-schedule.h index 466b529..8c5932b 100644 --- a/level_0/f_schedule/tests/unit/c/test-schedule.h +++ b/level_0/f_schedule/tests/unit/c/test-schedule.h @@ -27,6 +27,12 @@ // Test includes. #include "test-schedule-nice.h" +#include "test-schedule-policy_get.h" +#include "test-schedule-policy_set.h" +#include "test-schedule-priority_get.h" +#include "test-schedule-priority_set.h" +#include "test-schedule-value_get.h" +#include "test-schedule-value_set.h" #ifdef __cplusplus extern "C" { -- 1.8.3.1