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/exception.hpp"
30 #include "lxcpp/process.hpp"
31 #include "lxcpp/cgroups/devices.hpp"
32 #include "lxcpp/cgroups/cgroup-config.hpp"
34 #include "lxcpp/commands/cgroups.hpp"
36 #include "utils/text.hpp"
47 BOOST_FIXTURE_TEST_SUITE(LxcppCGroupsSuite, Fixture)
49 using namespace lxcpp;
51 // assume cgroups are supprted by the system
52 BOOST_AUTO_TEST_CASE(GetAvailable)
54 std::vector<std::string> subs;
56 BOOST_CHECK_NO_THROW(subs = Subsystem::availableSubsystems());
57 BOOST_CHECK_MESSAGE(subs.size() > 0, "Control groups not supported");
60 LOGD(s.getName() << ": " << (s.isAttached() ? s.getMountPoint() : "[not attached]"));
64 BOOST_AUTO_TEST_CASE(GetCGroupsByPid)
66 std::vector<std::string> cg;
68 BOOST_CHECK_NO_THROW(cg=Subsystem::getCGroups(::getpid()));
69 BOOST_CHECK(cg.size() > 0);
72 BOOST_AUTO_TEST_CASE(GetPidsByCGroup)
74 CGroup cg = CGroup::getCGroup("memory", ::getpid());
75 std::vector<pid_t> pids;
77 BOOST_CHECK_NO_THROW(pids = cg.getPids());
78 BOOST_CHECK(pids.size() > 0);
81 BOOST_AUTO_TEST_CASE(SubsysAttach)
83 Subsystem sub("freezer");
85 BOOST_CHECK_MESSAGE(sub.isAvailable(), "freezer not found");
87 if (!sub.isAvailable()) return ;
89 if (sub.isAttached()) {
90 std::string mp = sub.getMountPoint();
91 BOOST_CHECK_NO_THROW(Subsystem::detach(mp));
92 BOOST_CHECK(Subsystem(sub.getName()).isAttached()==false);
93 BOOST_CHECK_NO_THROW(Subsystem::attach(mp, {sub.getName()}));
94 BOOST_CHECK(Subsystem(sub.getName()).isAttached()==true);
97 std::string mp = "/sys/fs/cgroup/" + sub.getName();
98 BOOST_CHECK_NO_THROW(Subsystem::attach(mp, {sub.getName()}));
99 BOOST_CHECK(Subsystem(sub.getName()).isAttached()==true);
100 BOOST_CHECK_NO_THROW(Subsystem::detach(mp));
101 BOOST_CHECK(Subsystem(sub.getName()).isAttached()==false);
105 BOOST_AUTO_TEST_CASE(ModifyCGroupParams)
107 CGroup memg("memory:/ut-params");
112 // this test can fail if prev. test round left unexpected
113 BOOST_CHECK_MESSAGE(memg.exists() == false, "Cgroup alredy exists");
114 BOOST_CHECK_NO_THROW(memg.create());
115 BOOST_CHECK(memg.exists() == true);
117 if (!memg.exists()) {
121 pid_t pid = lxcpp::fork();
123 BOOST_CHECK_NO_THROW(memg.assignPid(::getpid()));
124 BOOST_CHECK_NO_THROW(memg.assignGroup(::getpid()));
126 BOOST_CHECK_NO_THROW(memg.setValue("limit_in_bytes", "10k"));
127 BOOST_CHECK_NO_THROW(memg.setValue("soft_limit_in_bytes", "10k"));
128 BOOST_CHECK_THROW(memg.getValue("non-existing-name"), CGroupException);
129 BOOST_CHECK_THROW(memg.setValue("non-existing-name", "xxx"), CGroupException);
131 LOGD("limit_in_bytes: " << memg.getValue("limit_in_bytes"));
132 LOGD("soft_limit_in_bytes: " << memg.getValue("soft_limit_in_bytes"));
133 LOGD("max_usage_in_bytes: " << memg.getValue("max_usage_in_bytes"));
135 CGroup memtop("memory:/");
136 memtop.assignPid(::getpid());
137 memtop.setCommonValue("procs", std::to_string(::getpid()));
138 ::_exit(EXIT_SUCCESS);
141 BOOST_CHECK_NO_THROW(memg.destroy());
144 BOOST_AUTO_TEST_CASE(LisDevicesPermissions)
146 DevicesCGroup devgrp("/tmp");
148 BOOST_CHECK_NO_THROW(devgrp.create());
150 std::vector<DevicePermission> list;
151 BOOST_CHECK_NO_THROW(list = devgrp.list());
152 for (__attribute__((unused)) const auto& i : list) {
153 LOGD(std::string("perm = ") + i.type + " " +
154 std::to_string(i.major) + ":" + std::to_string(i.minor) + " " + i.permission);
157 BOOST_CHECK_NO_THROW(devgrp.destroy());
160 BOOST_AUTO_TEST_CASE(CGroupConfigSerialization)
163 std::string tmpConfigFile = "/tmp/cgconfig.conf";
165 BOOST_CHECK_NO_THROW(config::saveToJsonString(cfg));
167 cfg.subsystems.push_back(SubsystemConfig{"cpu", "/tmp/cgroup/cpu"});
169 CGroupConfig cpucfg = {"cpu", "/testcpu", {}, {}};
170 cfg.cgroups.push_back(cpucfg);
171 config::saveToJsonFile(tmpConfigFile, cfg);
174 BOOST_CHECK_NO_THROW(config::loadFromJsonFile(tmpConfigFile, cfg2));
175 BOOST_CHECK(cfg2.subsystems.size()==cfg.subsystems.size());
178 BOOST_AUTO_TEST_CASE(CGroupCommands)
181 Subsystem sub("cpu");
182 std::string mp = sub.isAttached() ? sub.getMountPoint() : "/tmp/cgroup/cpu";
184 cfg.subsystems.push_back(SubsystemConfig{"cpu", mp});
185 CGroupConfig cpucfg = {"cpu", "/testcpu", {}, {}};
186 cfg.cgroups.push_back(cpucfg);
188 CGroupMakeAll cmd(cfg);
189 BOOST_CHECK_NO_THROW(cmd.execute());
191 CGroup cpugrp("cpu", "/testcpu");
192 BOOST_CHECK_NO_THROW(cpugrp.destroy());
195 BOOST_AUTO_TEST_SUITE_END()