diff options
author | Chanwoo Choi <cw00.choi@samsung.com> | 2023-03-14 19:39:56 +0900 |
---|---|---|
committer | Chanwoo Choi <cw00.choi@samsung.com> | 2023-03-16 07:57:38 +0900 |
commit | 21edd91c87e5712220f8bea4b19959428722c0a6 (patch) | |
tree | 4054079f264b69c75c63cd625189dfc074e684cc | |
parent | 8edca4051c4d8d47e50a9235790c3a76ef3fb824 (diff) | |
download | pass-sandbox/chanwoochoi/pass-resmon.tar.gz pass-sandbox/chanwoochoi/pass-resmon.tar.bz2 pass-sandbox/chanwoochoi/pass-resmon.zip |
tests: unittest: Add pass-resmon-unittestssandbox/chanwoochoi/pass-resmon
Add support of pass-resmon-unittests
to test Resource Monitor module (pass-resmon).
[Test result of pass-resmon-unittests]
[ 33s] 1: Test command: /home/abuild/rpmbuild/BUILD/pass-2.0.0/tests/unittest/pass-resmon/pass-resmon-unittests
[ 33s] 1: Working Directory: /home/abuild/rpmbuild/BUILD/pass-2.0.0/tests/unittest/pass-resmon
[ 33s] 1: Test timeout computed to be: 10000000
[ 33s] 1: [==========] Running 12 tests from 2 test suites.
[ 33s] 1: [----------] Global test environment set-up.
[ 33s] 1: [----------] 2 tests from PassResmonInitExitTest
[ 33s] 1: [ RUN ] PassResmonInitExitTest.pass_resmon_prepare_init_and_exit_unprepare_valid
[ 33s] 1: [ OK ] PassResmonInitExitTest.pass_resmon_prepare_init_and_exit_unprepare_valid (0 ms)
[ 33s] 1: [ RUN ] PassResmonInitExitTest.pass_resmon_prepare_init_and_exit_unprepare_invalid
[ 33s] 1: [ OK ] PassResmonInitExitTest.pass_resmon_prepare_init_and_exit_unprepare_invalid (0 ms)
[ 33s] 1: [----------] 2 tests from PassResmonInitExitTest (0 ms total)
[ 33s] 1:
[ 33s] 1: [----------] 10 tests from PassResmonTest
[ 33s] 1: [ RUN ] PassResmonTest.pass_resmon_register_timer
[ 33s] 1: [ OK ] PassResmonTest.pass_resmon_register_timer (0 ms)
[ 33s] 1: [ RUN ] PassResmonTest.pass_resmon_register_timer_invalid
[ 33s] 1: [ OK ] PassResmonTest.pass_resmon_register_timer_invalid (0 ms)
[ 33s] 1: [ RUN ] PassResmonTest.pass_resmon_unregister_timer
[ 33s] 1: [ OK ] PassResmonTest.pass_resmon_unregister_timer (0 ms)
[ 33s] 1: [ RUN ] PassResmonTest.pass_resmon_unregister_timer_invalid
[ 33s] 1: [ OK ] PassResmonTest.pass_resmon_unregister_timer_invalid (0 ms)
[ 33s] 1: [ RUN ] PassResmonTest.pass_resmon_update_timer_interval
[ 33s] 1: [ OK ] PassResmonTest.pass_resmon_update_timer_interval (0 ms)
[ 33s] 1: [ RUN ] PassResmonTest.pass_resmon_update_timer_interval_invalid
[ 33s] 1: [ OK ] PassResmonTest.pass_resmon_update_timer_interval_invalid (0 ms)
[ 33s] 1: [ RUN ] PassResmonTest.pass_resmon_register_uevent
[ 33s] 1: [ OK ] PassResmonTest.pass_resmon_register_uevent (0 ms)
[ 33s] 1: [ RUN ] PassResmonTest.pass_resmon_register_uevent_invalid
[ 33s] 1: [ OK ] PassResmonTest.pass_resmon_register_uevent_invalid (0 ms)
[ 33s] 1: [ RUN ] PassResmonTest.pass_resmon_unregister_uevent
[ 33s] 1: [ OK ] PassResmonTest.pass_resmon_unregister_uevent (0 ms)
[ 33s] 1: [ RUN ] PassResmonTest.pass_resmon_unregister_uevent_invalid
[ 33s] 1: [ OK ] PassResmonTest.pass_resmon_unregister_uevent_invalid (0 ms)
[ 33s] 1: [----------] 10 tests from PassResmonTest (3 ms total)
[ 33s] 1:
[ 33s] 1: [----------] Global test environment tear-down
[ 33s] 1: [==========] 12 tests from 2 test suites ran. (3 ms total)
[ 33s] 1: [ PASSED ] 12 tests.
[ 33s] 1/1 Test #1: pass-resmon-unittests ............ Passed 0.01 sec
[ 33s]
[ 33s] 100% tests passed, 0 tests failed out of 1
[ 33s]
[ 33s] Total Test time (real) = 0.01 sec
Change-Id: Idcb8bac8d5d69862d898a810ddf0f802452b6883
Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
-rw-r--r-- | CMakeLists.txt | 1 | ||||
-rw-r--r-- | packaging/pass.spec | 1 | ||||
-rw-r--r-- | tests/unittest/pass-resmon/CMakeLists.txt | 46 | ||||
-rw-r--r-- | tests/unittest/pass-resmon/pass-hal-mock.cpp | 302 | ||||
-rw-r--r-- | tests/unittest/pass-resmon/pass-hal-mock.hpp | 215 | ||||
-rw-r--r-- | tests/unittest/pass-resmon/pass-resmon-unittests.cc | 379 |
6 files changed, 944 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 1b8b64a..d171547 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -150,6 +150,7 @@ ADD_SUBDIRECTORY(tests/integration-test) ADD_SUBDIRECTORY(tests/haltest) ADD_SUBDIRECTORY(tests/unittest/pass-hal-and-parser) ADD_SUBDIRECTORY(tests/unittest/pass-rescon) +ADD_SUBDIRECTORY(tests/unittest/pass-resmon) ADD_SUBDIRECTORY(lib) diff --git a/packaging/pass.spec b/packaging/pass.spec index 7e4fc3e..f2384f2 100644 --- a/packaging/pass.spec +++ b/packaging/pass.spec @@ -91,6 +91,7 @@ make %{?jobs:-j%jobs} %check (cd tests/unittest/pass-hal-and-parser && LD_LIBRARY_PATH=../../ ctest -V) (cd tests/unittest/pass-rescon && LD_LIBRARY_PATH=../../ ctest -V) +(cd tests/unittest/pass-resmon && LD_LIBRARY_PATH=../../ ctest -V) %install rm -rf %{buildroot} diff --git a/tests/unittest/pass-resmon/CMakeLists.txt b/tests/unittest/pass-resmon/CMakeLists.txt new file mode 100644 index 0000000..d95b5ef --- /dev/null +++ b/tests/unittest/pass-resmon/CMakeLists.txt @@ -0,0 +1,46 @@ +ENABLE_TESTING() +SET(PASS_UNITTEST "pass-resmon-unittests") + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -Wall -Werror") +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} -Wall -Werror") + +SET(PASS_SRCS + ${CMAKE_SOURCE_DIR}/src/util/common.c + ${CMAKE_SOURCE_DIR}/src/util/timer.c + ${CMAKE_SOURCE_DIR}/src/pass/pass-resmon.c + ${CMAKE_SOURCE_DIR}/src/pass/pass-resmon-source.c +) + +AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/ PASS_UNITTEST_SRCS) +ADD_EXECUTABLE(${PASS_UNITTEST} ${PASS_UNITTEST_SRCS} ${PASS_SRCS}) + +TARGET_INCLUDE_DIRECTORIES(${PASS_UNITTEST} PUBLIC + "${CMAKE_CURRENT_SOURCE_DIR}/../../include" + "${CMAKE_SOURCE_DIR}" + "${CMAKE_SOURCE_DIR}/src" + "${CMAKE_SOURCE_DIR}/src/pass" + "${CMAKE_SOURCE_DIR}/include" +) + +INCLUDE(FindPkgConfig) +pkg_check_modules(pass_unittest_pkgs REQUIRED + glib-2.0 + gio-2.0 + libudev + gmock + dlog + json-c +) + +FOREACH(flag ${pass_unittest_pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +TARGET_LINK_LIBRARIES(${PASS_UNITTEST} ${pass_unittest_pkgs_LDFLAGS}) +SET_TARGET_PROPERTIES(${PASS_UNITTEST} PROPERTIES COMPILE_FLAGS "-fPIE -fvisibility=default") +SET_TARGET_PROPERTIES(${PASS_UNITTEST} PROPERTIES LINK_FLAGS "-pie") + +ADD_TEST( + NAME ${PASS_UNITTEST} + COMMAND ${PASS_UNITTEST} +) diff --git a/tests/unittest/pass-resmon/pass-hal-mock.cpp b/tests/unittest/pass-resmon/pass-hal-mock.cpp new file mode 100644 index 0000000..5f3eb2f --- /dev/null +++ b/tests/unittest/pass-resmon/pass-hal-mock.cpp @@ -0,0 +1,302 @@ +/* + * Copyright (C) 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <iostream> +#include <unistd.h> +#include <stdlib.h> + +#include <gio/gio.h> +#include <gtest/gtest.h> +#include <gmock/gmock.h> + +extern "C" { +#include "pass.h" +#include "pass-hal.h" +} + +#include "pass-hal-mock.hpp" + +using namespace std; +using ::testing::Return; +using ::testing::_; + +PassHalMock *gPassHalMock; + +int pass_hal_get_curr_governor(struct pass_resource *res, char *governor) +{ + if (!gPassHalMock) + return -ENOTSUP; + + return gPassHalMock->pass_hal_get_curr_governor(res, governor); +} + +int pass_hal_set_curr_governor(struct pass_resource *res, char *governor) +{ + if (!gPassHalMock) + return -ENOTSUP; + + return gPassHalMock->pass_hal_set_curr_governor(res, governor); +} + +int pass_hal_get_curr_freq(struct pass_resource *res) +{ + if (!gPassHalMock) + return -ENOTSUP; + + return gPassHalMock->pass_hal_get_curr_freq(res); +} + +int pass_hal_get_min_freq(struct pass_resource *res) +{ + if (!gPassHalMock) + return -ENOTSUP; + + return gPassHalMock->pass_hal_get_min_freq(res); +} + +int pass_hal_set_min_freq(struct pass_resource *res, int freq) +{ + if (!gPassHalMock) + return -ENOTSUP; + + return gPassHalMock->pass_hal_set_min_freq(res, freq); +} + +int pass_hal_get_max_freq(struct pass_resource *res) +{ + if (!gPassHalMock) + return -ENOTSUP; + + return gPassHalMock->pass_hal_get_max_freq(res); +} + +int pass_hal_set_max_freq(struct pass_resource *res, int freq) +{ + if (!gPassHalMock) + return -ENOTSUP; + + return gPassHalMock->pass_hal_set_max_freq(res, freq); +} + +int pass_hal_get_available_min_freq(struct pass_resource *res) +{ + if (!gPassHalMock) + return -ENOTSUP; + + return gPassHalMock->pass_hal_get_available_min_freq(res); +} + +int pass_hal_get_available_max_freq(struct pass_resource *res) +{ + if (!gPassHalMock) + return -ENOTSUP; + + return gPassHalMock->pass_hal_get_available_max_freq(res); +} + +int pass_hal_get_up_threshold(struct pass_resource *res) +{ + if (!gPassHalMock) + return -ENOTSUP; + + return gPassHalMock->pass_hal_get_up_threshold(res); +} + +int pass_hal_set_up_threshold(struct pass_resource *res, int up_threshold) +{ + if (!gPassHalMock) + return -ENOTSUP; + + return gPassHalMock->pass_hal_set_up_threshold(res, up_threshold); +} + +int pass_hal_get_online_state(struct pass_resource *res, int cpu) +{ + if (!gPassHalMock) + return -ENOTSUP; + + return gPassHalMock->pass_hal_get_online_state(res, cpu); +} + +int pass_hal_set_online_state(struct pass_resource *res, int cpu, int on) +{ + if (!gPassHalMock) + return -ENOTSUP; + + return gPassHalMock->pass_hal_set_online_state(res, cpu, on); +} + +int pass_hal_get_online_min_num(struct pass_resource *res) +{ + if (!gPassHalMock) + return -ENOTSUP; + + return gPassHalMock->pass_hal_get_online_min_num(res); +} + +int pass_hal_set_online_min_num(struct pass_resource *res, int num) +{ + if (!gPassHalMock) + return -ENOTSUP; + + return gPassHalMock->pass_hal_set_online_min_num(res, num); +} + +int pass_hal_get_online_max_num(struct pass_resource *res) +{ + if (!gPassHalMock) + return -ENOTSUP; + + return gPassHalMock->pass_hal_get_online_max_num(res); +} + +int pass_hal_set_online_max_num(struct pass_resource *res, int num) +{ + if (!gPassHalMock) + return -ENOTSUP; + + return gPassHalMock->pass_hal_set_online_max_num(res, num); +} + +int pass_hal_get_temp(struct pass_resource *res) +{ + if (!gPassHalMock) + return -ENOTSUP; + + return gPassHalMock->pass_hal_get_temp(res); +} + +int pass_hal_get_tmu_policy(struct pass_resource *res, char *policy) +{ + if (!gPassHalMock) + return -ENOTSUP; + + return gPassHalMock->pass_hal_get_tmu_policy(res, policy); +} + +int pass_hal_get_cooling_device_state(struct pass_resource *res) +{ + if (!gPassHalMock) + return -ENOTSUP; + + return gPassHalMock->pass_hal_get_cooling_device_state(res); +} + +int pass_hal_set_cooling_device_state(struct pass_resource *res, int state) +{ + if (!gPassHalMock) + return -ENOTSUP; + + return gPassHalMock->pass_hal_set_cooling_device_state(res, state); +} + +int pass_hal_get_cooling_device_max_state(struct pass_resource *res) +{ + if (!gPassHalMock) + return -ENOTSUP; + + return gPassHalMock->pass_hal_get_cooling_device_max_state(res); +} + +int pass_hal_set_battery_charging_status(struct pass_resource *res, int charging_status) +{ + if (!gPassHalMock) + return -ENOTSUP; + + return gPassHalMock->pass_hal_set_battery_charging_status(res, charging_status); +} + +int pass_hal_get_battery_charging_status(struct pass_resource *res) +{ + if (!gPassHalMock) + return -ENOTSUP; + + return gPassHalMock->pass_hal_get_battery_charging_status(res); +} + +int pass_hal_set_battery_charging_current(struct pass_resource *res, + int charging_current_uA) +{ + if (!gPassHalMock) + return -ENOTSUP; + + return gPassHalMock->pass_hal_set_battery_charging_current(res, charging_current_uA); +} + +int pass_hal_get_battery_charging_current(struct pass_resource *res) +{ + if (!gPassHalMock) + return -ENOTSUP; + + return gPassHalMock->pass_hal_get_battery_charging_current(res); +} + +int pass_hal_set_fault_around_bytes(struct pass_resource *res, + int fault_around_bytes) +{ + if (!gPassHalMock) + return -ENOTSUP; + + return gPassHalMock->pass_hal_set_fault_around_bytes(res, fault_around_bytes); +} + +int pass_hal_get_fault_around_bytes(struct pass_resource *res) +{ + if (!gPassHalMock) + return -ENOTSUP; + + return gPassHalMock->pass_hal_get_fault_around_bytes(res); +} + +int pass_hal_set_pmqos_data(struct pass_resource *res, void *data) +{ + if (!gPassHalMock) + return -ENOTSUP; + + return gPassHalMock->pass_hal_set_pmqos_data(res, data); +} + +int pass_hal_save_initdata(struct pass_resource *res) +{ + if (!gPassHalMock) + return -ENOTSUP; + + return gPassHalMock->pass_hal_save_initdata(res); +} + +int pass_hal_restore_initdata(struct pass_resource *res) +{ + if (!gPassHalMock) + return -ENOTSUP; + + return gPassHalMock->pass_hal_restore_initdata(res); +} + +int pass_hal_get_resource(struct pass_resource *res) +{ + if (!gPassHalMock) + return -ENOTSUP; + + return gPassHalMock->pass_hal_get_resource(res); +} + +int pass_hal_put_resource(struct pass_resource *res) +{ + if (!gPassHalMock) + return -ENOTSUP; + + return gPassHalMock->pass_hal_put_resource(res); +} diff --git a/tests/unittest/pass-resmon/pass-hal-mock.hpp b/tests/unittest/pass-resmon/pass-hal-mock.hpp new file mode 100644 index 0000000..6d93b8e --- /dev/null +++ b/tests/unittest/pass-resmon/pass-hal-mock.hpp @@ -0,0 +1,215 @@ +/* + * Copyright (C) 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <iostream> +#include <unistd.h> +#include <stdlib.h> + +#include <gio/gio.h> +#include <gtest/gtest.h> +#include <gmock/gmock.h> + +extern "C" { +#include "pass.h" +#include "pass-hal.h" +} + +using namespace std; +using ::testing::Return; +using ::testing::_; + +class PassHalMockInterface { +public: + virtual ~PassHalMockInterface() {}; + + /*** + * Functions for all H/W resources + */ + /* Get and put the h/w resource. */ + virtual int pass_hal_get_resource(struct pass_resource *res) = 0; + virtual int pass_hal_put_resource(struct pass_resource *res) = 0; + + /* Save and restore the initial data of the h/w resource. */ + virtual int pass_hal_save_initdata(struct pass_resource *pass_res) = 0; + virtual int pass_hal_restore_initdata(struct pass_resource *pass_res) = 0; + + /*** + * Functions for CPU/BUS/GPU H/W resources + */ + /* Get and the current governor. */ + virtual int pass_hal_get_curr_governor(struct pass_resource *res, char *governor) = 0; + virtual int pass_hal_set_curr_governor(struct pass_resource *res, char *governor) = 0; + + /* Get the current frequency. */ + virtual int pass_hal_get_curr_freq(struct pass_resource *res) = 0; + + /* Get and set the minimum frequency. */ + virtual int pass_hal_get_min_freq(struct pass_resource *res) = 0; + virtual int pass_hal_set_min_freq(struct pass_resource *res, int freq) = 0; + + /* Get and set the maximum frequency. */ + virtual int pass_hal_get_max_freq(struct pass_resource *res) = 0; + virtual int pass_hal_set_max_freq(struct pass_resource *res, int freq) = 0; + + /* Get the minimum/maximum frequency which can be set to resource. */ + virtual int pass_hal_get_available_min_freq(struct pass_resource *res) = 0; + virtual int pass_hal_get_available_max_freq(struct pass_resource *res) = 0; + + /* Get and set the up_threshold to support boosting. */ + virtual int pass_hal_get_up_threshold(struct pass_resource *res) = 0; + virtual int pass_hal_set_up_threshold(struct pass_resource *res, int up_threshold) = 0; + + /* Get the temperature and policy of thermal unit on specific h/w. */ + virtual int pass_hal_get_temp(struct pass_resource *res) = 0; + virtual int pass_hal_get_tmu_policy(struct pass_resource *res, char *policy) = 0; + + /* Get and set the state of cooling device on specific h/w. */ + virtual int pass_hal_get_cooling_device_state(struct pass_resource *res) = 0; + virtual int pass_hal_set_cooling_device_state(struct pass_resource *res, int state) = 0; + virtual int pass_hal_get_cooling_device_max_state(struct pass_resource *res) = 0; + + /* Get and set the battery charging state. */ + virtual int pass_hal_set_battery_charging_status(struct pass_resource *res, int charging_status) = 0; + virtual int pass_hal_get_battery_charging_status(struct pass_resource *res) = 0; + + /* Get and set the battery charging current. */ + virtual int pass_hal_set_battery_charging_current(struct pass_resource *res, int charging_current_uA) = 0; + virtual int pass_hal_get_battery_charging_current(struct pass_resource *res) = 0; + + /*** + * Functions for CPU H/W resources + */ + /* Get and set online state of cpu. */ + virtual int pass_hal_get_online_state(struct pass_resource *res, int cpu) = 0; + virtual int pass_hal_set_online_state(struct pass_resource *res, int cpu, int on) = 0; + /* Get and set the minimum number of online CPUs */ + virtual int pass_hal_get_online_min_num(struct pass_resource *res) = 0; + virtual int pass_hal_set_online_min_num(struct pass_resource *res, int num) = 0; + /* Get and set the maximum number of online CPUs */ + virtual int pass_hal_get_online_max_num(struct pass_resource *res) = 0; + virtual int pass_hal_set_online_max_num(struct pass_resource *res, int num) = 0; + + /*** + * Functions for Memory h/w resource + */ + /* Get and set the /sys/kernel/debug/fault_around_bytes */ + virtual int pass_hal_get_fault_around_bytes(struct pass_resource *res) = 0; + virtual int pass_hal_set_fault_around_bytes(struct pass_resource *res, int fault_around_bytes) = 0; + + /*** + * Functions for Nonstandard H/W resources + */ + /* + * NOTE: It is not propper method. But PASS must need to keep + * the backwards compatibility, set the PMQoS's data from + * platform to hal. So, It is not recommended to use it. + * + * This function will be removed after finding the proper method. + */ + virtual int pass_hal_set_pmqos_data(struct pass_resource *res, void *data) = 0; +}; + +class PassHalMock:PassHalMockInterface { +public: + /*** + * Functions for all H/W resources + */ + /* Get and put the h/w resource. */ + MOCK_METHOD1(pass_hal_get_resource, int (struct pass_resource *res)); + MOCK_METHOD1(pass_hal_put_resource, int (struct pass_resource *res)); + + /* Save and restore the initial data of the h/w resource. */ + MOCK_METHOD1(pass_hal_save_initdata, int (struct pass_resource *pass_res)); + MOCK_METHOD1(pass_hal_restore_initdata, int (struct pass_resource *pass_res)); + + /*** + * Functions for CPU/BUS/GPU H/W resources + */ + /* Get and the current governor. */ + MOCK_METHOD2(pass_hal_get_curr_governor, int (struct pass_resource *res, char *governor)); + MOCK_METHOD2(pass_hal_set_curr_governor, int (struct pass_resource *res, char *governor)); + + /* Get the current frequency. */ + MOCK_METHOD1(pass_hal_get_curr_freq, int (struct pass_resource *res)); + + /* Get and set the minimum frequency. */ + MOCK_METHOD1(pass_hal_get_min_freq, int (struct pass_resource *res)); + MOCK_METHOD2(pass_hal_set_min_freq, int (struct pass_resource *res, int freq)); + + /* Get and set the maximum frequency. */ + MOCK_METHOD1(pass_hal_get_max_freq, int (struct pass_resource *res)); + MOCK_METHOD2(pass_hal_set_max_freq, int (struct pass_resource *res, int freq)); + + /* Get the minimum/maximum frequency which can be set to resource. */ + MOCK_METHOD1(pass_hal_get_available_min_freq, int (struct pass_resource *res)); + MOCK_METHOD1(pass_hal_get_available_max_freq, int (struct pass_resource *res)); + + /* Get and set the up_threshold to support boosting. */ + MOCK_METHOD1(pass_hal_get_up_threshold, int (struct pass_resource *res)); + MOCK_METHOD2(pass_hal_set_up_threshold, int (struct pass_resource *res, int up_threshold)); + + /* Get the temperature and policy of thermal unit on specific h/w. */ + MOCK_METHOD1(pass_hal_get_temp, int (struct pass_resource *res)); + MOCK_METHOD2(pass_hal_get_tmu_policy, int (struct pass_resource *res, char *policy)); + + /* Get and set the state of cooling device on specific h/w. */ + MOCK_METHOD1(pass_hal_get_cooling_device_state, int (struct pass_resource *res)); + MOCK_METHOD2(pass_hal_set_cooling_device_state, int (struct pass_resource *res, int state)); + MOCK_METHOD1(pass_hal_get_cooling_device_max_state, int (struct pass_resource *res)); + + /* Get and set the battery charging state. */ + MOCK_METHOD2(pass_hal_set_battery_charging_status, int (struct pass_resource *res, int charging_status)); + MOCK_METHOD1(pass_hal_get_battery_charging_status, int (struct pass_resource *res)); + + /* Get and set the battery charging current. */ + MOCK_METHOD2(pass_hal_set_battery_charging_current, int (struct pass_resource *res, int charging_current_uA)); + MOCK_METHOD1(pass_hal_get_battery_charging_current, int (struct pass_resource *res)); + + /*** + * Functions for CPU H/W resources + */ + /* Get and set online state of cpu. */ + MOCK_METHOD2(pass_hal_get_online_state, int (struct pass_resource *res, int cpu)); + MOCK_METHOD3(pass_hal_set_online_state, int (struct pass_resource *res, int cpu, int on)); + /* Get and set the minimum number of online CPUs */ + MOCK_METHOD1(pass_hal_get_online_min_num, int (struct pass_resource *res)); + MOCK_METHOD2(pass_hal_set_online_min_num, int (struct pass_resource *res, int num)); + /* Get and set the maximum number of online CPUs */ + MOCK_METHOD1(pass_hal_get_online_max_num, int (struct pass_resource *res)); + MOCK_METHOD2(pass_hal_set_online_max_num, int (struct pass_resource *res, int num)); + + /*** + * Functions for Memory h/w resource + */ + /* Get and set the /sys/kernel/debug/fault_around_bytes */ + MOCK_METHOD1(pass_hal_get_fault_around_bytes, int (struct pass_resource *res)); + MOCK_METHOD2(pass_hal_set_fault_around_bytes, int (struct pass_resource *res, int fault_around_bytes)); + + /*** + * Functions for Nonstandard H/W resources + */ + /* + * NOTE: It is not propper method. But PASS must need to keep + * the backwards compatibility, set the PMQoS's data from + * platform to hal. So, It is not recommended to use it. + * + * This function will be removed after finding the proper method. + */ + MOCK_METHOD2(pass_hal_set_pmqos_data, int (struct pass_resource *res, void *data)); + +}; + +extern PassHalMock *gPassHalMock; diff --git a/tests/unittest/pass-resmon/pass-resmon-unittests.cc b/tests/unittest/pass-resmon/pass-resmon-unittests.cc new file mode 100644 index 0000000..9740128 --- /dev/null +++ b/tests/unittest/pass-resmon/pass-resmon-unittests.cc @@ -0,0 +1,379 @@ +/* + * Copyright (C) 2023 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <iostream> +#include <unistd.h> + +#include <gio/gio.h> +#include <gtest/gtest.h> +#include <gmock/gmock.h> + +extern "C" { +#include <util/common.h> + +#include "pass.h" +#include "pass-hal.h" +#include "pass-resmon.h" +#include "pass-hal-mock.hpp" +} + +#define INIT_LEVEL_VALUE 100 + +using namespace std; +using ::testing::Return; +using ::testing::_; + +static struct pass_resource *g_resource; + +static int resmon_func(void *result, void *user_data) { return 0; } + +static void init_pass_hal(void) +{ + if (gPassHalMock) + return; + + gPassHalMock = new PassHalMock(); + + g_resource = (struct pass_resource *)calloc(1, sizeof(struct pass_resource)); + g_resource->config_data.res_type = PASS_RESOURCE_CPU_ID; + + EXPECT_CALL(*gPassHalMock, pass_hal_save_initdata(_)).WillRepeatedly(Return(0)); + EXPECT_CALL(*gPassHalMock, pass_hal_restore_initdata(_)).WillRepeatedly(Return(0)); + + /* Get and the current governor. */ + EXPECT_CALL(*gPassHalMock, pass_hal_get_curr_governor(_, _)).WillRepeatedly(Return(0)); + EXPECT_CALL(*gPassHalMock, pass_hal_set_curr_governor(_, _)).WillRepeatedly(Return(0)); + + /* Get the current frequency. */ + EXPECT_CALL(*gPassHalMock, pass_hal_get_curr_freq(_)).WillRepeatedly(Return(0)); + + /* Get and set the minimum frequency. */ + EXPECT_CALL(*gPassHalMock, pass_hal_get_min_freq(_)).WillRepeatedly(Return(0)); + EXPECT_CALL(*gPassHalMock, pass_hal_set_min_freq(_, _)).WillRepeatedly(Return(0)); + + /* Get and set the maximum frequency. */ + EXPECT_CALL(*gPassHalMock, pass_hal_get_max_freq(_)).WillRepeatedly(Return(0)); + EXPECT_CALL(*gPassHalMock, pass_hal_set_max_freq(_, _)).WillRepeatedly(Return(0)); + + /* Get the minimum/maximum frequency which can be set to resource. */ + EXPECT_CALL(*gPassHalMock, pass_hal_get_available_min_freq(_)).WillRepeatedly(Return(0)); + EXPECT_CALL(*gPassHalMock, pass_hal_get_available_max_freq(_)).WillRepeatedly(Return(0)); + + /* Get and set the up_threshold to support boosting. */ + EXPECT_CALL(*gPassHalMock, pass_hal_get_up_threshold(_)).WillRepeatedly(Return(0)); + EXPECT_CALL(*gPassHalMock, pass_hal_set_up_threshold(_, _)).WillRepeatedly(Return(0)); + + /* Get the temperature and policy of thermal unit on specific h/w. */ + EXPECT_CALL(*gPassHalMock, pass_hal_get_temp(_)).WillRepeatedly(Return(0)); + EXPECT_CALL(*gPassHalMock, pass_hal_get_tmu_policy(_, _)).WillRepeatedly(Return(0)); + + /* Get and set the state of cooling device on specific h/w. */ + EXPECT_CALL(*gPassHalMock, pass_hal_get_cooling_device_state(_)).WillRepeatedly(Return(0)); + EXPECT_CALL(*gPassHalMock, pass_hal_set_cooling_device_state(_, _)).WillRepeatedly(Return(0)); + EXPECT_CALL(*gPassHalMock, pass_hal_get_cooling_device_max_state(_)).WillRepeatedly(Return(0)); + + /* Get and set the battery charging state. */ + EXPECT_CALL(*gPassHalMock, pass_hal_set_battery_charging_status(_, _)).WillRepeatedly(Return(0)); + EXPECT_CALL(*gPassHalMock, pass_hal_get_battery_charging_status(_)).WillRepeatedly(Return(0)); + + /* Get and set the battery charging current. */ + EXPECT_CALL(*gPassHalMock, pass_hal_set_battery_charging_current(_, _)).WillRepeatedly(Return(0)); + EXPECT_CALL(*gPassHalMock, pass_hal_get_battery_charging_current(_)).WillRepeatedly(Return(0)); + + /* Get and set online state of cpu. */ + EXPECT_CALL(*gPassHalMock, pass_hal_get_online_state(_, _)).WillRepeatedly(Return(0)); + EXPECT_CALL(*gPassHalMock, pass_hal_set_online_state(_, _, _)).WillRepeatedly(Return(0)); + /* Get and set the minimum number of online CPUs */ + EXPECT_CALL(*gPassHalMock, pass_hal_get_online_min_num(_)).WillRepeatedly(Return(0)); + EXPECT_CALL(*gPassHalMock, pass_hal_set_online_min_num(_, _)).WillRepeatedly(Return(0)); + /* Get and set the maximum number of online CPUs */ + EXPECT_CALL(*gPassHalMock, pass_hal_get_online_max_num(_)).WillRepeatedly(Return(0)); + EXPECT_CALL(*gPassHalMock, pass_hal_set_online_max_num(_, _)).WillRepeatedly(Return(0)); + + /* Get and set the /sys/kernel/debug/fault_around_bytes */ + EXPECT_CALL(*gPassHalMock, pass_hal_get_fault_around_bytes(_)).WillRepeatedly(Return(0)); + EXPECT_CALL(*gPassHalMock, pass_hal_set_fault_around_bytes(_, _)).WillRepeatedly(Return(0)); + + /* + * NOTE: It is not propper method. But PASS must need to keep + * the backwards compatibility, set the PMQoS's data from + * platform to hal. So, It is not recommended to use it. + * + * This function will be removed after finding the proper method. + */ + EXPECT_CALL(*gPassHalMock, pass_hal_set_pmqos_data(_, _)).WillRepeatedly(Return(0)); +} + +static void exit_pass_hal(void) +{ + free(g_resource); + g_resource = NULL; + + if (!gPassHalMock) + return; + + delete gPassHalMock; + gPassHalMock = NULL; +} + +class PassResmonInitExitTest : public testing::Test { +public: + void SetUp() override { + init_pass_hal(); + } + + void TearDown() override { + exit_pass_hal(); + } +}; + +TEST_F(PassResmonInitExitTest, pass_resmon_prepare_init_and_exit_unprepare_valid) { + int ret = pass_resmon_prepare(g_resource); + EXPECT_EQ(ret, 0); + ret = pass_resmon_init(g_resource); + EXPECT_EQ(ret, 0); + ret = pass_resmon_exit_and_unprepare(g_resource); + EXPECT_EQ(ret, 0); +} + +TEST_F(PassResmonInitExitTest, pass_resmon_prepare_init_and_exit_unprepare_invalid) { + int ret = pass_resmon_prepare(NULL); + EXPECT_NE(ret, 0); + ret = pass_resmon_init(NULL); + EXPECT_NE(ret, 0); + ret = pass_resmon_exit_and_unprepare(g_resource); + EXPECT_NE(ret, 0); +} + +static int init_config_data(struct pass_resource *res, + int num_levels, + int num_scenario_levels) { + if (!res) + return -EINVAL; + + res->config_data.levels = (struct pass_level *)calloc(num_levels, + sizeof(struct pass_level)); + if (!res->config_data.levels) + return -ENOMEM; + + res->config_data.scenario_levels = (struct pass_level *)calloc(num_scenario_levels, + sizeof(struct pass_level)); + if (!res->config_data.scenario_levels) { + free(res->config_data.scenario_levels); + return -ENOMEM; + } + + return 0; +} + +static void exit_config_data(struct pass_resource *res) { + if (!res) + return; + + free(res->config_data.scenario_levels); + free(res->config_data.levels); +} + +class PassResmonTest : public testing::Test { +public: + void SetUp() override { + init_pass_hal(); + + pass_resmon_prepare(g_resource); + pass_resmon_init(g_resource); + + init_config_data(g_resource, 5, 5); + } + + void TearDown() override { + pass_resmon_exit_and_unprepare(g_resource); + + exit_pass_hal(); + exit_config_data(g_resource); + } +}; + +TEST_F(PassResmonTest, pass_resmon_register_timer) { + /* Test registering tiemr */ + int timer_id = pass_resmon_register_timer( + g_resource, RESMON_SRC_THERMAL, + RESMON_TIMER_PERIODIC, 1000, + resmon_func, g_resource); + EXPECT_LT(0, timer_id); +} + +TEST_F(PassResmonTest, pass_resmon_register_timer_invalid) { + /* Test invalid resource instance */ + int timer_id = pass_resmon_register_timer( + NULL, RESMON_SRC_THERMAL, RESMON_TIMER_PERIODIC, + 1000, resmon_func, g_resource); + EXPECT_NE(timer_id, 0); + + /* Test invalid enum resmon_src_type */ + timer_id = pass_resmon_register_timer( + NULL, RESMON_SRC_UNKNOWN, RESMON_TIMER_UNKNOWN, + 1000, resmon_func, g_resource); + EXPECT_NE(timer_id, 0); + + /* Test invalid enum resmon_timer_type */ + timer_id = pass_resmon_register_timer( + g_resource, RESMON_SRC_THERMAL, RESMON_TIMER_UNKNOWN, + 1000, resmon_func, g_resource); + EXPECT_NE(timer_id, 0); + + /* Test invalid timer_interval */ + timer_id = pass_resmon_register_timer( + g_resource, RESMON_SRC_THERMAL, RESMON_TIMER_PERIODIC, + -1, resmon_func, g_resource); + EXPECT_NE(timer_id, 0); + + /* Test invalid user_func */ + timer_id = pass_resmon_register_timer( + g_resource, RESMON_SRC_THERMAL, RESMON_TIMER_PERIODIC, + 1000, NULL, g_resource); + EXPECT_NE(0, timer_id); +} + +TEST_F(PassResmonTest, pass_resmon_unregister_timer) { + int timer_id = pass_resmon_register_timer( + g_resource, RESMON_SRC_THERMAL, + RESMON_TIMER_PERIODIC, 1000, + resmon_func, g_resource); + EXPECT_LT(0, timer_id); + + /* Test unregistering timer */ + int ret = pass_resmon_unregister_timer(g_resource, timer_id); + EXPECT_EQ(0, ret); +} + +TEST_F(PassResmonTest, pass_resmon_unregister_timer_invalid) { + /* Test invalid timer interval */ + int ret = pass_resmon_unregister_timer(g_resource, -1); + EXPECT_NE(ret, 0); + + /* Test invalid resource instance */ + ret = pass_resmon_unregister_timer(NULL, 0); + EXPECT_NE(ret, 0); +} + +TEST_F(PassResmonTest, pass_resmon_update_timer_interval) { + int timer_id = pass_resmon_register_timer( + g_resource, RESMON_SRC_THERMAL, + RESMON_TIMER_PERIODIC, 1000, + resmon_func, g_resource); + EXPECT_LT(0, timer_id); + + /* Test updateing timer_interval */ + int ret = pass_resmon_update_timer_interval(g_resource, timer_id, 1000); + EXPECT_EQ(ret, 0); + + ret = pass_resmon_unregister_timer(g_resource, timer_id); + EXPECT_EQ(0, ret); +} + +TEST_F(PassResmonTest, pass_resmon_update_timer_interval_invalid) { + int timer_id = pass_resmon_register_timer( + g_resource, RESMON_SRC_THERMAL, + RESMON_TIMER_PERIODIC, 1000, + resmon_func, g_resource); + EXPECT_LT(0, timer_id); + + /* Test invalid resource instance */ + int ret = pass_resmon_update_timer_interval(NULL, timer_id, 1000); + EXPECT_NE(ret, 0); + + /* Test invalid timer_id */ + ret = pass_resmon_update_timer_interval(g_resource, -1, 1000); + EXPECT_NE(ret, 0); + + /* Test invalid timer interval */ + ret = pass_resmon_update_timer_interval(g_resource, timer_id, -1); + EXPECT_NE(ret, 0); + ret = pass_resmon_update_timer_interval(g_resource, timer_id, 0); + EXPECT_NE(ret, 0); + ret = pass_resmon_update_timer_interval(g_resource, timer_id, UINT_MAX); + EXPECT_NE(ret, 0); + + ret = pass_resmon_unregister_timer(g_resource, timer_id); + EXPECT_EQ(0, ret); +} + +TEST_F(PassResmonTest, pass_resmon_register_uevent) { + /* Test registering uevent */ + int uevent_id = pass_resmon_register_uevent( + g_resource, RESMON_SRC_THERMAL, + resmon_func, NULL); + EXPECT_LT(0, uevent_id); +} + +TEST_F(PassResmonTest, pass_resmon_register_uevent_invalid) { + /* Test invalid resource instance */ + int uevent_id = pass_resmon_register_uevent( + NULL, RESMON_SRC_THERMAL, + resmon_func, NULL); + EXPECT_NE(uevent_id, 0); + + /* Test invalid enum resmon_src_type */ + uevent_id = pass_resmon_register_uevent( + g_resource, RESMON_SRC_UNKNOWN, + resmon_func, NULL); + EXPECT_NE(uevent_id, 0); + + /* Test invalid user_func */ + uevent_id = pass_resmon_register_uevent( + g_resource, RESMON_SRC_THERMAL, + NULL, NULL); + EXPECT_NE(uevent_id, 0); +} + +TEST_F(PassResmonTest, pass_resmon_unregister_uevent) { + int uevent_id = pass_resmon_register_uevent( + g_resource, RESMON_SRC_THERMAL, + resmon_func, NULL); + EXPECT_LT(0, uevent_id); + + /* Test unregistering uevent */ + int ret = pass_resmon_unregister_uevent(g_resource, uevent_id); + EXPECT_EQ(ret, 0); +} + +TEST_F(PassResmonTest, pass_resmon_unregister_uevent_invalid) { + int uevent_id = pass_resmon_register_uevent( + g_resource, RESMON_SRC_THERMAL, + resmon_func, NULL); + EXPECT_LT(0, uevent_id); + + /* Test invalid uvent id */ + int ret = pass_resmon_unregister_uevent(g_resource, 0); + EXPECT_NE(ret, 0); + + /* Test invalid resource instance */ + ret = pass_resmon_unregister_uevent(NULL, uevent_id); + EXPECT_NE(ret, 0); + + ret = pass_resmon_unregister_uevent(g_resource, uevent_id); + EXPECT_EQ(ret, 0); +} + +int main(int argc, char *argv[]) +{ + try { + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); + } catch (...) { + return EXIT_FAILURE; + } +} |