--- /dev/null
+/*
+ * 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 <stdlib.h>
+
+#include <gio/gio.h>
+#include <gtest/gtest.h>
+#include <gmock/gmock.h>
+
+#include <util/common.h>
+
+#include <vector>
+#include <memory>
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "resource-monitor.h"
+
+#define UNKNOWN_ID 9999
+
+using namespace std;
+
+class ResourceMonitorTest : public testing::Test {
+public:
+ void SetUp() override {}
+ void TearDown() override {}
+};
+
+TEST_F(ResourceMonitorTest, pass_resource_monitor_init_and_exit)
+{
+ int id = pass_resource_monitor_init();
+ EXPECT_TRUE(id > 0);
+
+ pass_resource_monitor_exit(id);
+}
+
+TEST_F(ResourceMonitorTest, pass_resource_monitor_get_resource_count_valid)
+{
+ int i;
+ int res_types[] = {
+ RESOURCE_TYPE_CPU,
+ RESOURCE_TYPE_BUS,
+ RESOURCE_TYPE_GPU,
+ RESOURCE_TYPE_MEMORY,
+ RESOURCE_TYPE_BATTERY,
+ RESOURCE_TYPE_PROCESS,
+ RESOURCE_TYPE_DISPLAY,
+ RESOURCE_TYPE_SYSTEM,
+ RESOURCE_TYPE_PROCESS_GROUP,
+ };
+
+ int id = pass_resource_monitor_init();
+ EXPECT_TRUE(id > 0);
+
+ for (i = 0; i < (int)ARRAY_SIZE(res_types); i++) {
+ int ret = pass_resource_monitor_get_resource_count(id, res_types[i]);
+ EXPECT_TRUE(ret >= 0);
+ }
+
+ pass_resource_monitor_exit(id);
+}
+
+TEST_F(ResourceMonitorTest, pass_resource_monitor_get_resource_count_invalid)
+{
+ int i;
+ int res_types[] = {
+ RESOURCE_TYPE_UNKNOWN,
+ RESOURCE_TYPE_NONSTANDARD,
+ };
+
+ int id = pass_resource_monitor_init();
+ EXPECT_TRUE(id > 0);
+
+ for (i = 0; i < (int)ARRAY_SIZE(res_types); i++) {
+ int ret = pass_resource_monitor_get_resource_count(id, res_types[i]);
+ EXPECT_EQ(ret, 0);
+ }
+
+ pass_resource_monitor_exit(id);
+}
+
+TEST_F(ResourceMonitorTest,
+ pass_resource_monitor_is_resource_attr_supported_invalid)
+{
+ int i, j;
+ int res_type = RESOURCE_TYPE_CPU;
+ u_int64_t res_attr_ids[] = {
+ BIT(50),
+ BIT(51),
+ BIT(52),
+ };
+
+ int id = pass_resource_monitor_init();
+ EXPECT_TRUE(id > 0);
+
+ int count = pass_resource_monitor_get_resource_count(id, res_type);
+ EXPECT_TRUE(count >= 0);
+
+ for (i = 0; i < count; i++) {
+ int res_id = pass_resource_monitor_create_resource(id, res_type);
+ EXPECT_TRUE(res_id >= 0);
+
+ int ret = pass_resource_monitor_set_resource_ctrl(id, res_id,
+ CPU_CTRL_CLUSTER_ID, i);
+ EXPECT_EQ(ret, 0);
+
+ for (j = 0; j < (int)ARRAY_SIZE(res_attr_ids); j++) {
+ bool supported = pass_resource_monitor_is_resource_attr_supported(
+ id, res_id,
+ res_attr_ids[j]);
+ EXPECT_EQ(supported, false);
+
+ supported = pass_resource_monitor_is_resource_attr_supported(
+ UNKNOWN_ID, res_id,
+ res_attr_ids[j]);
+ EXPECT_EQ(supported, false);
+
+ supported = pass_resource_monitor_is_resource_attr_supported(
+ id, UNKNOWN_ID,
+ res_attr_ids[j]);
+ EXPECT_EQ(supported, false);
+ }
+
+ ret = pass_resource_monitor_delete_resource(id, res_id);
+ EXPECT_EQ(ret, 0);
+ }
+
+ pass_resource_monitor_exit(id);
+}
+
+struct resource_attr_info {
+ u_int64_t attr_id;
+ int attr_type;
+};
+
+class ResourceInfo {
+public:
+ const int type;
+ const char *name;
+ int mon_id;
+ int res_id;
+ int count;
+ const u_int64_t ctrl_id;
+ const int num_attrs;
+ vector<struct resource_attr_info> attrs;
+
+ ResourceInfo(
+ const int type_,
+ const char *name_,
+ int mon_id_,
+ int res_id_,
+ int count_,
+ const u_int64_t ctrl_id_,
+ const int num_attrs_,
+ vector<struct resource_attr_info> attrs_) :
+ type(type_),
+ name(name_),
+ mon_id(mon_id_),
+ res_id(res_id_),
+ count(count_),
+ ctrl_id(ctrl_id_),
+ num_attrs(num_attrs_),
+ attrs(attrs_) {}
+};
+
+class EachResourceMonitorTest : public ::testing::TestWithParam<ResourceInfo> {};
+
+INSTANTIATE_TEST_CASE_P (ResourceMonitorTest, EachResourceMonitorTest,
+ ::testing::Values (
+ ResourceInfo (
+ RESOURCE_TYPE_CPU,
+ "RESOURCE_TYPE_CPU",
+ -1,
+ -1,
+ 0,
+ CPU_CTRL_CLUSTER_ID,
+ 5,
+ vector<struct resource_attr_info> {
+ { .attr_id = CPU_ATTR_CUR_FREQ, .attr_type = DATA_TYPE_INT, },
+ { .attr_id = CPU_ATTR_MIN_FREQ, .attr_type = DATA_TYPE_INT, },
+ { .attr_id = CPU_ATTR_MAX_FREQ, .attr_type = DATA_TYPE_INT, },
+ { .attr_id = CPU_ATTR_AVAILABLE_MIN_FREQ, .attr_type = DATA_TYPE_INT, },
+ { .attr_id = CPU_ATTR_AVAILABLE_MAX_FREQ, .attr_type = DATA_TYPE_INT, },
+ }
+ ),
+
+ ResourceInfo (
+ RESOURCE_TYPE_BUS,
+ "RESOURCE_TYPE_BUS",
+ -1,
+ -1,
+ 0,
+ BUS_CTRL_DEVICE_ID,
+ 5,
+ vector<struct resource_attr_info> {
+ { .attr_id = BUS_ATTR_CUR_FREQ, .attr_type = DATA_TYPE_INT, },
+ { .attr_id = BUS_ATTR_MIN_FREQ, .attr_type = DATA_TYPE_INT, },
+ { .attr_id = BUS_ATTR_MAX_FREQ, .attr_type = DATA_TYPE_INT, },
+ { .attr_id = BUS_ATTR_AVAILABLE_MIN_FREQ, .attr_type = DATA_TYPE_INT, },
+ { .attr_id = BUS_ATTR_AVAILABLE_MAX_FREQ, .attr_type = DATA_TYPE_INT, },
+ }
+ ),
+
+ ResourceInfo (
+ RESOURCE_TYPE_GPU,
+ "RESOURCE_TYPE_GPU",
+ -1,
+ -1,
+ 0,
+ GPU_CTRL_DEVICE_ID,
+ 6,
+ vector<struct resource_attr_info> {
+ { .attr_id = GPU_ATTR_CUR_FREQ, .attr_type = DATA_TYPE_INT, },
+ { .attr_id = GPU_ATTR_MIN_FREQ, .attr_type = DATA_TYPE_INT, },
+ { .attr_id = GPU_ATTR_MAX_FREQ, .attr_type = DATA_TYPE_INT, },
+ { .attr_id = GPU_ATTR_AVAILABLE_MIN_FREQ, .attr_type = DATA_TYPE_INT, },
+ { .attr_id = GPU_ATTR_AVAILABLE_MAX_FREQ, .attr_type = DATA_TYPE_INT, },
+ { .attr_id = GPU_ATTR_CUR_GOVERNOR, .attr_type = DATA_TYPE_STRING, },
+ }
+ )
+));
+
+TEST_P(EachResourceMonitorTest, pass_resource_monitor_create_resource_and_delete)
+{
+ auto res = GetParam();
+ int i;
+
+ res.mon_id = pass_resource_monitor_init();
+ ASSERT_TRUE(res.mon_id > 0);
+
+ res.count = pass_resource_monitor_get_resource_count(res.mon_id, res.type);
+ EXPECT_TRUE(res.count >= 0);
+
+ for (i = 0; i < res.count; i++) {
+ /* Test pass_resource_monitor_create_resource */
+ res.res_id = pass_resource_monitor_create_resource(res.mon_id, res.type);
+ EXPECT_TRUE(res.res_id >= 0);
+
+ /* Test pass_resource_monitor_delete_resource */
+ int ret = pass_resource_monitor_delete_resource(res.mon_id, res.res_id);
+ EXPECT_EQ(ret, 0);
+ }
+
+ pass_resource_monitor_exit(res.mon_id);
+}
+
+TEST_P(EachResourceMonitorTest, pass_resource_monitor_set_resource_ctrl)
+{
+ auto res = GetParam();
+ int i;
+
+ res.mon_id = pass_resource_monitor_init();
+ ASSERT_TRUE(res.mon_id > 0);
+
+ res.count = pass_resource_monitor_get_resource_count(res.mon_id, res.type);
+ EXPECT_TRUE(res.count >= 0);
+
+ for (i = 0; i < res.count; i++) {
+ res.res_id = pass_resource_monitor_create_resource(res.mon_id, res.type);
+ EXPECT_TRUE(res.res_id >= 0);
+
+ /* Test pass_resource_monitor_set_resource_ctrl */
+ int ret = pass_resource_monitor_set_resource_ctrl(res.mon_id, res.res_id,
+ res.ctrl_id, i);
+ if (res.ctrl_id > 0 )
+ EXPECT_EQ(ret, 0);
+ else
+ EXPECT_NE(ret, 0);
+
+ ret = pass_resource_monitor_delete_resource(res.mon_id, res.res_id);
+ EXPECT_EQ(ret, 0);
+ }
+
+ pass_resource_monitor_exit(res.mon_id);
+}
+
+static int __pass_resource_monitor_set_resource_attr(int mon_id, int res_id, int num_attrs,
+ std::vector<struct resource_attr_info> attrs)
+{
+ int i, ret;
+ u_int64_t mask = 0;
+
+ for (i = 0; i < num_attrs; i++) {
+ bool supported = pass_resource_monitor_is_resource_attr_supported(
+ mon_id, res_id, attrs[i].attr_id);
+ if (supported)
+ mask |= attrs[i].attr_id;
+ }
+
+ ret = pass_resource_monitor_set_resource_attr(mon_id, res_id, mask);
+ EXPECT_EQ(ret, 0);
+
+ return ret;
+}
+
+TEST_P(EachResourceMonitorTest, pass_resource_monitor_set_resource_attr)
+{
+ auto res = GetParam();
+ int i;
+
+ res.mon_id = pass_resource_monitor_init();
+ ASSERT_TRUE(res.mon_id > 0);
+
+ res.count = pass_resource_monitor_get_resource_count(res.mon_id, res.type);
+ EXPECT_TRUE(res.count >= 0);
+
+ for (i = 0; i < res.count; i++) {
+ res.res_id = pass_resource_monitor_create_resource(res.mon_id, res.type);
+ EXPECT_TRUE(res.res_id >= 0);
+
+ /*
+ * Test both pass_resource_monitor_set_resource_attr
+ * and pass_resource_monitor_is_resource_attr_supported
+ * */
+ int ret = pass_resource_monitor_set_resource_ctrl(res.mon_id, res.res_id,
+ res.ctrl_id, i);
+ if (res.ctrl_id > 0 ) {
+ ret = __pass_resource_monitor_set_resource_attr(res.mon_id,
+ res.res_id,
+ res.num_attrs,
+ res.attrs);
+ EXPECT_EQ(ret, 0);
+ } else {
+ EXPECT_NE(ret, 0);
+ }
+
+ ret = pass_resource_monitor_delete_resource(res.mon_id, res.res_id);
+ EXPECT_EQ(ret, 0);
+ }
+
+ pass_resource_monitor_exit(res.mon_id);
+}
+
+static int __pass_resource_monitor_get_value(int mon_id, int res_id, int num_attrs,
+ std::vector<struct resource_attr_info> attrs)
+{
+ int i, ret, err_count = 0;
+
+ for (i = 0; i < num_attrs; i++) {
+ bool supported = pass_resource_monitor_is_resource_attr_supported(
+ mon_id, res_id, attrs[i].attr_id);
+ if (!supported)
+ continue;
+
+ switch (attrs[i].attr_type) {
+ case DATA_TYPE_INT:
+ int32_t value_int32;
+ ret = pass_resource_monitor_get_value_int(mon_id, res_id,
+ attrs[i].attr_id, &value_int32);
+ EXPECT_EQ(ret, 0);
+ break;
+ case DATA_TYPE_INT64:
+ int64_t value_int64;
+ ret = pass_resource_monitor_get_value_int64(mon_id, res_id,
+ attrs[i].attr_id, &value_int64);
+ EXPECT_EQ(ret, 0);
+ break;
+ case DATA_TYPE_UINT:
+ u_int32_t value_uint32;
+ ret = pass_resource_monitor_get_value_uint(mon_id, res_id,
+ attrs[i].attr_id, &value_uint32);
+ EXPECT_EQ(ret, 0);
+ break;
+ case DATA_TYPE_UINT64:
+ u_int64_t value_uint64;
+ ret = pass_resource_monitor_get_value_uint64(mon_id, res_id,
+ attrs[i].attr_id, &value_uint64);
+ EXPECT_EQ(ret, 0);
+ break;
+ case DATA_TYPE_DOUBLE:
+ double value_double;
+ ret = pass_resource_monitor_get_value_double(mon_id, res_id,
+ attrs[i].attr_id, &value_double);
+ EXPECT_EQ(ret, 0);
+ break;
+ case DATA_TYPE_STRING:
+ char value_str[BUFF_MAX];
+ ret = pass_resource_monitor_get_value_string(mon_id, res_id,
+ attrs[i].attr_id, value_str);
+ EXPECT_EQ(ret, 0);
+ break;
+ default:
+ ret = -EINVAL;
+ EXPECT_EQ(ret, 0);
+ break;
+ }
+
+ if (ret < 0)
+ err_count++;
+ }
+
+ return err_count ? -EINVAL : 0;
+}
+
+TEST_P(EachResourceMonitorTest, pass_resource_monitor_get_value)
+{
+ auto res = GetParam();
+ int i;
+
+ res.mon_id = pass_resource_monitor_init();
+ ASSERT_TRUE(res.mon_id > 0);
+
+ res.count = pass_resource_monitor_get_resource_count(res.mon_id, res.type);
+ EXPECT_TRUE(res.count >= 0);
+
+ for (i = 0; i < res.count; i++) {
+ res.res_id = pass_resource_monitor_create_resource(res.mon_id, res.type);
+ EXPECT_TRUE(res.res_id >= 0);
+
+ int ret = pass_resource_monitor_set_resource_ctrl(res.mon_id, res.res_id,
+ res.ctrl_id, i);
+ if (res.ctrl_id > 0 ) {
+ ret = __pass_resource_monitor_set_resource_attr(res.mon_id,
+ res.res_id,
+ res.num_attrs,
+ res.attrs);
+ EXPECT_EQ(ret, 0);
+ } else {
+ EXPECT_NE(ret, 0);
+ }
+
+ /* Test both pass_resource_monitor_get_value_[data type] */
+ ret = __pass_resource_monitor_get_value(res.mon_id,
+ res.res_id,
+ res.num_attrs,
+ res.attrs);
+ EXPECT_EQ(ret, 0);
+
+ ret = pass_resource_monitor_delete_resource(res.mon_id, res.res_id);
+ EXPECT_EQ(ret, 0);
+ }
+
+ pass_resource_monitor_exit(res.mon_id);
+}
+
+int main(int argc, char *argv[])
+{
+ try {
+ testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+ } catch (...) {
+ return EXIT_FAILURE;
+ }
+}