* Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
* libkperf licensed under the Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
* PURPOSE.
* See the Mulan PSL v2 for more details.
* Author: Ms.Wu
* Create: 2025-7-9
* Description: Unit tests for cgroup collection.
******************************************************************************/
#include "test_common.h"
#include "common.h"
#include <cerrno>
#include <unistd.h>
using namespace std;
class TestCgroup : public testing::Test {
public:
string testCgroupPath;
void SetUp()
{
demoPid = RunTestApp(exePath);
testCgroupPath = GetCgroupPath(::testing::UnitTest::GetInstance()->current_test_info()->name());
if (testCgroupPath.empty()) {
FAIL() << "Cgroup Path does not exist: " << testCgroupPath;
}
}
void TearDown()
{
KillApp(demoPid);
if (data != nullptr) {
PmuDataFree(data);
data = nullptr;
}
PmuClose(pd);
for (int i = 0; i< pdNums; ++i) {
PmuClose(pds[i]);
}
std::ofstream ofs(testCgroupPath + "/cgroup.procs");
if (ofs.is_open()) {
ofs << "";
ofs.close();
}
rmdir(testCgroupPath.c_str());
}
protected:
PmuAttr GetPmuAttribute()
{
PmuAttr attr = {0};
attr.evtList = evtList;
attr.numEvt = numEvt;
attr.freq = 1000;
attr.useFreq = 1;
attr.symbolMode = RESOLVE_ELF_DWARF;
return attr;
}
protected:
static const string exePath;
static pid_t demoPid;
static const unsigned numEvt = 1;
static const string expectFilename;
static const unsigned collectInterval = 100;
char *evtList[numEvt] = {"cycles"};
int pd = 0;
static const int pdNums = 2;
int pds[pdNums] = {0};
PmuData *data = nullptr;
};
pid_t TestCgroup::demoPid;
const string TestCgroup::exePath = "simple";
const string TestCgroup::expectFilename = "simple.cpp";
TEST_F(TestCgroup, ValidCgroupName)
{
ASSERT_EQ(mkdir(testCgroupPath.c_str(), 0755), 0) << strerror(errno);
auto attr = GetPmuAttribute();
char* cgroupName[1];
cgroupName[0] = (char*)"ValidCgroupName";
attr.cgroupNameList = cgroupName;
attr.numCgroup = 1;
pd = PmuOpen(SAMPLING, &attr);
ASSERT_GT(pd, 0);
}
TEST_F(TestCgroup, TestCgroupCounting) {
ASSERT_EQ(mkdir(testCgroupPath.c_str(), 0755), 0) << strerror(errno);
ofstream ofs(testCgroupPath + "/cgroup.procs");
ofs << demoPid;
ofs.close();
auto attr = GetPmuAttribute();
char* cgroupName[1];
cgroupName[0] = (char*)"TestCgroupCounting";
attr.cgroupNameList = cgroupName;
attr.numCgroup = 1;
pd = PmuOpen(COUNTING, &attr);
ASSERT_NE(pd, -1);
int ret = PmuCollect(pd, 1000, collectInterval);
ASSERT_EQ(ret, SUCCESS);
int len = PmuRead(pd, &data);
ASSERT_GT(len, 0);
ASSERT_STREQ(data[0].cgroupName, "TestCgroupCounting");
}
TEST_F(TestCgroup, TestCgroupSampling)
{
ASSERT_EQ(mkdir(testCgroupPath.c_str(), 0755), 0) << strerror(errno);
ofstream ofs(testCgroupPath + "/cgroup.procs");
ofs << demoPid;
ofs.close();
auto attr = GetPmuAttribute();
attr.period = 1000;
attr.dataFilter = SPE_DATA_ALL;
attr.evFilter = SPE_EVENT_RETIRED;
attr.minLatency = 0x40;
char* cgroupName[1];
cgroupName[0] = (char*)"TestCgroupSampling";
attr.cgroupNameList = cgroupName;
attr.numCgroup = 1;
pd = PmuOpen(SAMPLING, &attr);
ASSERT_NE(pd, -1);
int ret = PmuCollect(pd, 5000, collectInterval);
int len = PmuRead(pd, &data);
ASSERT_GT(len, 0);
ASSERT_STREQ(data[0].cgroupName, "TestCgroupSampling");
ASSERT_GT(data[0].period, 0);
}
TEST_F(TestCgroup, TestCgroupSPE)
{
if (!HasSpeDevice()) {
GTEST_SKIP();
}
ASSERT_EQ(mkdir(testCgroupPath.c_str(), 0755), 0) << strerror(errno);
ofstream ofs(testCgroupPath + "/cgroup.procs");
ofs << demoPid;
ofs.close();
auto attr = GetPmuAttribute();
attr.dataFilter = LOAD_FILTER;
attr.period = 8192;
char* cgroupName[1];
cgroupName[0] = (char*)"TestCgroupSPE";
attr.cgroupNameList = cgroupName;
attr.numCgroup = 1;
pd = PmuOpen(SAMPLING, &attr);
ASSERT_NE(pd, -1);
int ret = PmuCollect(pd, 5000, collectInterval);
int len = PmuRead(pd, &data);
ASSERT_GT(len, 0);
ASSERT_STREQ(data[0].cgroupName, "TestCgroupSPE");
ASSERT_GT(data[0].period, 0);
}