blob: 4cc5c601b28ce15d71f7765608edf0333d8a2b5a [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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 "util/cgroup_util.h"
#include <glog/logging.h>
#include <gtest/gtest-message.h>
#include <gtest/gtest-test-part.h>
#include <fstream>
#include "common/cgroup_memory_ctl.h"
#include "gtest/gtest_pred_impl.h"
#include "testutil/test_util.h"
#include "util/cgroup_util.h"
namespace doris {
class CGroupUtilTest : public ::testing::Test {
protected:
CGroupUtilTest() {}
~CGroupUtilTest() override = default;
};
TEST_F(CGroupUtilTest, ReadMetrics) {
std::string dir_path = GetCurrentRunningDir();
std::string memory_limit_in_bytes_path(dir_path);
memory_limit_in_bytes_path += "/util/test_data/memory.limit_in_bytes";
int64_t value;
auto st = CGroupUtil::read_int_line_from_cgroup_file(memory_limit_in_bytes_path, &value);
EXPECT_TRUE(st.ok());
EXPECT_EQ(6291456000, value);
std::string memory_stat_path(dir_path);
memory_stat_path += "/util/test_data/memory.stat";
std::unordered_map<std::string, int64_t> metrics_map;
CGroupUtil::read_int_metric_from_cgroup_file(memory_stat_path, metrics_map);
EXPECT_EQ(5443584, metrics_map["inactive_file"]);
EXPECT_EQ(0, metrics_map["rss"]);
std::string error_memory_limit_in_bytes_path(dir_path);
error_memory_limit_in_bytes_path += "/util/test_data/Zzz/memory.limit_in_bytes";
int64_t error_value;
auto st2 = CGroupUtil::read_int_line_from_cgroup_file(error_memory_limit_in_bytes_path,
&error_value);
EXPECT_FALSE(st2.ok());
std::string error_memory_stat_path(dir_path);
error_memory_stat_path += "/util/test_data/Zzz/memory.stat";
std::unordered_map<std::string, int64_t> error_metrics_map;
CGroupUtil::read_int_metric_from_cgroup_file(error_memory_stat_path, error_metrics_map);
EXPECT_TRUE(error_metrics_map.empty());
}
TEST_F(CGroupUtilTest, memlimit) {
LOG(INFO) << CGroupMemoryCtl::debug_string();
int64_t mem_limit;
int64_t mem_usage;
auto status1 = CGroupMemoryCtl::find_cgroup_mem_limit(&mem_limit);
auto status2 = CGroupMemoryCtl::find_cgroup_mem_usage(&mem_usage);
if (CGroupUtil::cgroupsv1_enable() || CGroupUtil::cgroupsv2_enable()) {
std::ifstream file("/proc/self/cgroup");
if (file.peek() == std::ifstream::traits_type::eof()) {
EXPECT_FALSE(status1.ok());
EXPECT_FALSE(status2.ok());
} else {
EXPECT_TRUE(status1.ok());
EXPECT_TRUE(status2.ok());
}
} else {
EXPECT_FALSE(status1.ok());
EXPECT_FALSE(status2.ok());
}
}
TEST_F(CGroupUtilTest, readcpu) {
std::string dir_path = GetCurrentRunningDir();
std::string cpuset_1_path(dir_path + "/util/test_data/cgroup_cpu_data/cpuset1");
std::string cpuset_1_str = "";
Status ret1 = CGroupUtil::read_string_line_from_cgroup_file(cpuset_1_path, &cpuset_1_str);
EXPECT_TRUE(ret1.ok());
int cpu_count1 = 0;
static_cast<void>(CGroupUtil::parse_cpuset_line(cpuset_1_str, &cpu_count1));
EXPECT_TRUE(cpu_count1 == 3);
std::string cpuset_2_path(dir_path + "/util/test_data/cgroup_cpu_data/cpuset2");
std::string cpuset_2_str = "";
Status ret2 = CGroupUtil::read_string_line_from_cgroup_file(cpuset_2_path, &cpuset_2_str);
EXPECT_TRUE(ret2.ok());
int cpu_count2 = 0;
static_cast<void>(CGroupUtil::parse_cpuset_line(cpuset_2_str, &cpu_count2));
EXPECT_TRUE(cpu_count2 == 11);
std::string cpuset_3_path(dir_path + "/util/test_data/cgroup_cpu_data/cpuset3");
std::string cpuset_3_str = "";
Status ret3 = CGroupUtil::read_string_line_from_cgroup_file(cpuset_3_path, &cpuset_3_str);
EXPECT_TRUE(ret3.ok());
int cpu_count3 = 0;
static_cast<void>(CGroupUtil::parse_cpuset_line(cpuset_3_str, &cpu_count3));
EXPECT_TRUE(cpu_count3 == 10);
int ret = CGroupUtil::get_cgroup_limited_cpu_number(16);
EXPECT_TRUE(ret > 0);
// 1 read cgroup v2 quota
// 1.1 read default value
std::filesystem::path path11 = dir_path + "/util/test_data/cgroup_cpu_data/test11/child";
std::filesystem::path default_path_11 = dir_path + "/util/test_data/cgroup_cpu_data/test11";
int ret11 = CGroupUtil::get_cgroup_v2_cpu_quota_number(path11, default_path_11, 96);
EXPECT_TRUE(ret11 == 96);
// 1.2 read from child to parent
std::filesystem::path path12 = dir_path + "/util/test_data/cgroup_cpu_data/test12/child";
std::filesystem::path default_path_12 = dir_path + "/util/test_data/cgroup_cpu_data/test12";
int ret12 = CGroupUtil::get_cgroup_v2_cpu_quota_number(path12, default_path_12, 96);
EXPECT_TRUE(ret12 == 2);
// 1.3 read parent
std::filesystem::path path13 = dir_path + "/util/test_data/cgroup_cpu_data/test13/child";
std::filesystem::path default_path_13 = dir_path + "/util/test_data/cgroup_cpu_data/test13";
int ret13 = CGroupUtil::get_cgroup_v2_cpu_quota_number(path13, default_path_13, 96);
EXPECT_TRUE(ret13 == 2);
// 1.4 read child
std::filesystem::path path14 = dir_path + "/util/test_data/cgroup_cpu_data/test14/child";
std::filesystem::path default_path_14 = dir_path + "/util/test_data/cgroup_cpu_data/test14";
int ret14 = CGroupUtil::get_cgroup_v2_cpu_quota_number(path14, default_path_14, 96);
EXPECT_TRUE(ret14 == 3);
// 2 read cgroup v2 cpuset
// 2.1 read child
std::filesystem::path path21 = dir_path + "/util/test_data/cgroup_cpu_data/test21/child";
std::filesystem::path default_path_21 = dir_path + "/util/test_data/cgroup_cpu_data/test21";
int ret21 = CGroupUtil::get_cgroup_v2_cpuset_number(path21, default_path_21, 96);
EXPECT_TRUE(ret21 == 2);
// 2.2 read parent
std::filesystem::path path22 = dir_path + "/util/test_data/cgroup_cpu_data/test22/child";
std::filesystem::path default_path_22 = dir_path + "/util/test_data/cgroup_cpu_data/test22";
int ret22 = CGroupUtil::get_cgroup_v2_cpuset_number(path22, default_path_22, 96);
EXPECT_TRUE(ret22 == 7);
// 3 read cgroup v1 quota
// 3.1 read child
std::filesystem::path path31 = dir_path + "/util/test_data/cgroup_cpu_data/test31/child";
std::filesystem::path default_path_31 = dir_path + "/util/test_data/cgroup_cpu_data/test31";
int ret31 = CGroupUtil::get_cgroup_v1_cpu_quota_number(path31, default_path_31, 96);
EXPECT_TRUE(ret31 == 5);
// 3.2 read parent
std::filesystem::path path32 = dir_path + "/util/test_data/cgroup_cpu_data/test32/child";
std::filesystem::path default_path_32 = dir_path + "/util/test_data/cgroup_cpu_data/test32";
int ret32 = CGroupUtil::get_cgroup_v1_cpu_quota_number(path32, default_path_32, 96);
EXPECT_TRUE(ret32 == 6);
// 3.3 read default
std::filesystem::path path33 = dir_path + "/util/test_data/cgroup_cpu_data/test33/child";
std::filesystem::path default_path_33 = dir_path + "/util/test_data/cgroup_cpu_data/test33";
int ret33 = CGroupUtil::get_cgroup_v1_cpu_quota_number(path33, default_path_33, 96);
EXPECT_TRUE(ret33 == 96);
// 4 read cgroup v1 cpuset
std::filesystem::path path41 = dir_path + "/util/test_data/cgroup_cpu_data/test41";
int ret41 = CGroupUtil::get_cgroup_v1_cpuset_number(path41, 96);
EXPECT_TRUE(ret41 == 3);
}
} // namespace doris