lxcpp: fix cgroup unit tests
[platform/core/security/vasum.git] / tests / unit_tests / lxcpp / ut-cgroups.cpp
1 /*
2  *  Copyright (C) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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.
7  *
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.
12  *
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
16  */
17
18 /**
19  * @file
20  * @author  Krzysztof Dynowski (k.dynowski@samsung.com)
21  * @brief   Unit tests of lxcpp cgroups managment
22  */
23
24 #include "config.hpp"
25 #include "config/manager.hpp"
26 #include "ut.hpp"
27 #include "logger/logger.hpp"
28
29 #include "lxcpp/exception.hpp"
30 #include "lxcpp/process.hpp"
31 #include "lxcpp/cgroups/devices.hpp"
32 #include "lxcpp/cgroups/cgroup-config.hpp"
33
34 #include "lxcpp/commands/cgroups.hpp"
35
36 #include "utils/text.hpp"
37
38 namespace {
39
40 struct Fixture {
41     Fixture() {}
42     ~Fixture() {}
43 };
44
45 } // namespace
46
47 BOOST_FIXTURE_TEST_SUITE(LxcppCGroupsSuite, Fixture)
48
49 using namespace lxcpp;
50
51 // assume cgroups are supprted by the system
52 BOOST_AUTO_TEST_CASE(GetAvailable)
53 {
54     std::vector<std::string> subs;
55
56     BOOST_CHECK_NO_THROW(subs = Subsystem::availableSubsystems());
57     BOOST_CHECK_MESSAGE(subs.size() > 0, "Control groups not supported");
58     for (auto n : subs){
59         Subsystem s(n);
60         LOGD(s.getName() << ": " << (s.isAttached() ? s.getMountPoint() : "[not attached]"));
61     }
62 }
63
64 BOOST_AUTO_TEST_CASE(GetCGroupsByPid)
65 {
66     std::vector<std::string> cg;
67
68     BOOST_CHECK_NO_THROW(cg=Subsystem::getCGroups(::getpid()));
69     BOOST_CHECK(cg.size() > 0);
70 }
71
72 BOOST_AUTO_TEST_CASE(GetPidsByCGroup)
73 {
74     CGroup cg = CGroup::getCGroup("memory", ::getpid());
75     std::vector<pid_t> pids;
76
77     BOOST_CHECK_NO_THROW(pids = cg.getPids());
78     BOOST_CHECK(pids.size() > 0);
79 }
80
81 BOOST_AUTO_TEST_CASE(SubsysAttach)
82 {
83     Subsystem sub("freezer");
84
85     BOOST_CHECK_MESSAGE(sub.isAvailable(), "freezer not found");
86
87     if (!sub.isAvailable()) return ;
88
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);
95     }
96     else {
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);
102     }
103 }
104
105 BOOST_AUTO_TEST_CASE(ModifyCGroupParams)
106 {
107     CGroup memg("memory:/ut-params");
108     if (memg.exists()) {
109         memg.destroy();
110     }
111
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);
116
117     if (!memg.exists()) {
118         return ;
119     }
120
121     pid_t pid = lxcpp::fork();
122     if (pid == 0) {
123         BOOST_CHECK_NO_THROW(memg.assignPid(::getpid()));
124         BOOST_CHECK_NO_THROW(memg.assignGroup(::getpid()));
125
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);
130
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"));
134
135         CGroup memtop("memory:/");
136         memtop.assignPid(::getpid());
137         memtop.setCommonValue("procs", std::to_string(::getpid()));
138         ::_exit(EXIT_SUCCESS);
139     }
140     lxcpp::waitpid(pid);
141     BOOST_CHECK_NO_THROW(memg.destroy());
142 }
143
144 BOOST_AUTO_TEST_CASE(LisDevicesPermissions)
145 {
146     DevicesCGroup devgrp("/tmp");
147
148     BOOST_CHECK_NO_THROW(devgrp.create());
149
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);
155     }
156
157     BOOST_CHECK_NO_THROW(devgrp.destroy());
158 }
159
160 BOOST_AUTO_TEST_CASE(CGroupConfigSerialization)
161 {
162     CGroupsConfig cfg;
163     std::string tmpConfigFile = "/tmp/cgconfig.conf";
164
165     BOOST_CHECK_NO_THROW(config::saveToJsonString(cfg));
166
167     cfg.subsystems.push_back(SubsystemConfig{"cpu", "/tmp/cgroup/cpu"});
168
169     CGroupConfig cpucfg = {"cpu", "/testcpu", {}, {}};
170     cfg.cgroups.push_back(cpucfg);
171     config::saveToJsonFile(tmpConfigFile, cfg);
172
173     CGroupsConfig cfg2;
174     BOOST_CHECK_NO_THROW(config::loadFromJsonFile(tmpConfigFile, cfg2));
175     BOOST_CHECK(cfg2.subsystems.size()==cfg.subsystems.size());
176 }
177
178 BOOST_AUTO_TEST_CASE(CGroupCommands)
179 {
180     CGroupsConfig cfg;
181     Subsystem sub("cpu");
182     std::string mp = sub.isAttached() ? sub.getMountPoint() : "/tmp/cgroup/cpu";
183
184     cfg.subsystems.push_back(SubsystemConfig{"cpu", mp});
185     CGroupConfig cpucfg = {"cpu", "/testcpu", {}, {}};
186     cfg.cgroups.push_back(cpucfg);
187
188     CGroupMakeAll cmd(cfg);
189     BOOST_CHECK_NO_THROW(cmd.execute());
190
191     CGroup cpugrp("cpu", "/testcpu");
192     BOOST_CHECK_NO_THROW(cpugrp.destroy());
193 }
194
195 BOOST_AUTO_TEST_SUITE_END()