2 * Copyright (C) 2015 Samsung Electronics Co., Ltd All Rights Reserved
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License version 2.1 as published by the Free Software Foundation.
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 * @author Krzysztof Dynowski (k.dynowski@samsung.com)
21 * @brief Unit tests of lxcpp cgroups managment
25 #include "config/manager.hpp"
27 #include "logger/logger.hpp"
29 #include "lxcpp/cgroups/devices.hpp"
30 #include "lxcpp/cgroups/cgroup-config.hpp"
32 #include "lxcpp/commands/cgroups.hpp"
34 #include "lxcpp/exception.hpp"
35 #include "utils/text.hpp"
46 BOOST_FIXTURE_TEST_SUITE(LxcppCGroupsSuite, Fixture)
48 using namespace lxcpp;
50 // assume cgroups are supprted by the system
51 BOOST_AUTO_TEST_CASE(GetAvailable)
53 std::vector<std::string> subs;
55 BOOST_CHECK_NO_THROW(subs = Subsystem::availableSubsystems());
56 BOOST_CHECK_MESSAGE(subs.size() > 0, "Control groups not supported");
59 LOGD(s.getName() << ": " << (s.isAttached() ? s.getMountPoint() : "[not attached]"));
63 BOOST_AUTO_TEST_CASE(GetCGroupsByPid)
65 std::vector<std::string> cg;
67 BOOST_CHECK_NO_THROW(cg=Subsystem::getCGroups(::getpid()));
68 BOOST_CHECK(cg.size() > 0);
71 BOOST_AUTO_TEST_CASE(GetPidsByCGroup)
73 CGroup cg = CGroup::getCGroup("memory", ::getpid());
74 std::vector<pid_t> pids;
76 BOOST_CHECK_NO_THROW(pids = cg.getPids());
77 BOOST_CHECK(pids.size() > 0);
80 BOOST_AUTO_TEST_CASE(SubsysAttach)
82 Subsystem sub("freezer");
84 BOOST_CHECK_MESSAGE(sub.isAvailable(), "freezer not found");
86 if (!sub.isAvailable()) return ;
88 if (sub.isAttached()) {
89 std::string mp = sub.getMountPoint();
90 BOOST_CHECK_NO_THROW(Subsystem::detach(mp));
91 BOOST_CHECK(Subsystem(sub.getName()).isAttached()==false);
92 BOOST_CHECK_NO_THROW(Subsystem::attach(mp, {sub.getName()}));
93 BOOST_CHECK(Subsystem(sub.getName()).isAttached()==true);
96 std::string mp = "/sys/fs/cgroup/" + sub.getName();
97 BOOST_CHECK_NO_THROW(Subsystem::attach(mp, {sub.getName()}));
98 BOOST_CHECK(Subsystem(sub.getName()).isAttached()==true);
99 BOOST_CHECK_NO_THROW(Subsystem::detach(mp));
100 BOOST_CHECK(Subsystem(sub.getName()).isAttached()==false);
104 BOOST_AUTO_TEST_CASE(ControlGroupParams)
106 CGroup memg("memory:/ut-params");
108 // this test can fail if prev. test round left unexpected
109 BOOST_CHECK_MESSAGE(memg.exists() == false, "Cgroup alredy exists");
110 BOOST_CHECK_NO_THROW(memg.create());
111 BOOST_CHECK(memg.exists() == true);
113 if (!memg.exists()) {
117 BOOST_CHECK_NO_THROW(memg.assignPid(::getpid()));
118 BOOST_CHECK_NO_THROW(memg.assignGroup(::getpid()));
120 BOOST_CHECK_NO_THROW(memg.setValue("limit_in_bytes", "10k"));
121 BOOST_CHECK_NO_THROW(memg.setValue("soft_limit_in_bytes", "10k"));
122 BOOST_CHECK_THROW(memg.getValue("non-existing-name"), CGroupException);
123 BOOST_CHECK_THROW(memg.setValue("non-existing-name", "xxx"), CGroupException);
125 LOGD("limit_in_bytes: " << memg.getValue("limit_in_bytes"));
126 LOGD("soft_limit_in_bytes: " << memg.getValue("soft_limit_in_bytes"));
127 LOGD("max_usage_in_bytes: " << memg.getValue("max_usage_in_bytes"));
129 CGroup memtop("memory:/");
130 memtop.assignPid(::getpid());
131 memtop.setCommonValue("procs", std::to_string(::getpid()));
133 BOOST_CHECK_NO_THROW(memg.destroy());
136 BOOST_AUTO_TEST_CASE(DevicesParams)
138 DevicesCGroup devgrp("/tmp");
140 BOOST_CHECK_NO_THROW(devgrp.create());
142 std::vector<DevicePermission> list;
143 BOOST_CHECK_NO_THROW(list = devgrp.list());
144 for (__attribute__((unused)) const auto& i : list) {
145 LOGD(std::string("perm = ") + i.type + " " +
146 std::to_string(i.major) + ":" + std::to_string(i.minor) + " " + i.permission);
149 BOOST_CHECK_NO_THROW(devgrp.destroy());
152 BOOST_AUTO_TEST_CASE(CGroupConfigSerialization)
155 std::string tmpConfigFile = "/tmp/cgconfig.conf";
157 BOOST_CHECK_NO_THROW(config::saveToJsonString(cfg));
159 cfg.subsystems.push_back(SubsystemConfig{"cpu", "/tmp/cgroup/cpu"});
161 CGroupConfig cpucfg = {"cpu", "/testcpu", {}, {}};
162 cfg.cgroups.push_back(cpucfg);
163 config::saveToJsonFile(tmpConfigFile, cfg);
166 BOOST_CHECK_NO_THROW(config::loadFromJsonFile(tmpConfigFile, cfg2));
167 BOOST_CHECK(cfg2.subsystems.size()==cfg.subsystems.size());
170 BOOST_AUTO_TEST_CASE(CGroupCommands)
173 Subsystem sub("cpu");
174 std::string mp = sub.isAttached() ? sub.getMountPoint() : "/tmp/cgroup/cpu";
176 cfg.subsystems.push_back(SubsystemConfig{"cpu", mp});
177 CGroupConfig cpucfg = {"cpu", "/testcpu", {}, {}};
178 cfg.cgroups.push_back(cpucfg);
180 CGroupMakeAll cmd(cfg);
181 BOOST_CHECK_NO_THROW(cmd.execute());
183 CGroup cpugrp("cpu", "/testcpu");
184 BOOST_CHECK_NO_THROW(cpugrp.destroy());
187 BOOST_AUTO_TEST_SUITE_END()