summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChanwoo Choi <cw00.choi@samsung.com>2023-03-14 19:39:56 +0900
committerChanwoo Choi <cw00.choi@samsung.com>2023-03-16 07:57:38 +0900
commit21edd91c87e5712220f8bea4b19959428722c0a6 (patch)
tree4054079f264b69c75c63cd625189dfc074e684cc
parent8edca4051c4d8d47e50a9235790c3a76ef3fb824 (diff)
downloadpass-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.txt1
-rw-r--r--packaging/pass.spec1
-rw-r--r--tests/unittest/pass-resmon/CMakeLists.txt46
-rw-r--r--tests/unittest/pass-resmon/pass-hal-mock.cpp302
-rw-r--r--tests/unittest/pass-resmon/pass-hal-mock.hpp215
-rw-r--r--tests/unittest/pass-resmon/pass-resmon-unittests.cc379
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;
+ }
+}