tests: unittest: Add pass-resmon-unittests 07/289707/5 accepted/tizen/unified/20230322.080545
authorChanwoo Choi <cw00.choi@samsung.com>
Tue, 14 Mar 2023 10:39:56 +0000 (19:39 +0900)
committerChanwoo Choi <cw00.choi@samsung.com>
Fri, 17 Mar 2023 05:24:23 +0000 (14:24 +0900)
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>
CMakeLists.txt
packaging/pass.spec
tests/unittest/pass-resmon/CMakeLists.txt [new file with mode: 0644]
tests/unittest/pass-resmon/pass-hal-mock.cpp [new file with mode: 0644]
tests/unittest/pass-resmon/pass-hal-mock.hpp [new file with mode: 0644]
tests/unittest/pass-resmon/pass-resmon-unittests.cc [new file with mode: 0644]

index 1b8b64a93ef3ee5101d80168c17fe7bb03578378..d171547b8a0225302e7aed7c3c114911266d58fe 100644 (file)
@@ -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)
 
index 7e4fc3e813e5a37acf08fc7bfe9b94a6c860c840..f2384f29bf00c438a3ba3b1fe08f093de7ec67ae 100644 (file)
@@ -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 (file)
index 0000000..d95b5ef
--- /dev/null
@@ -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 (file)
index 0000000..5f3eb2f
--- /dev/null
@@ -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 (file)
index 0000000..6d93b8e
--- /dev/null
@@ -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 (file)
index 0000000..9740128
--- /dev/null
@@ -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;
+       }
+}