process-cpp 3.0.0
A simple convenience library for handling processes in C++11.
linux_process_test.cpp
Go to the documentation of this file.
1/*
2 * Copyright © 2013 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program 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
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 */
18
19#include <core/posix/fork.h>
21
26
27#include <gtest/gtest.h>
28
29#include <map>
30
31TEST(LinuxProcess, accessing_proc_stats_works)
32{
33 auto child = core::posix::fork(
34 [](){ while(true); return core::posix::exit::Status::success;},
36
38 EXPECT_NO_THROW(child >> stat);
40}
41
42TEST(LinuxProcess, accessing_proc_oom_score_works)
43{
45 EXPECT_NO_THROW(core::posix::this_process::instance() >> oom_score);
46}
47
48TEST(LinuxProcess, accessing_proc_oom_score_adj_works)
49{
51 EXPECT_NO_THROW(core::posix::this_process::instance() >> oom_score_adj);
52}
53
54namespace
55{
56// A custom predicate to evaluate values in /proc/pid/oom_score.
57// The file contains the oom_score as calculated by the kernel and we are racing
58// against the badness heuristics. However, we only accept values within an error
59// margin of 10 as the test process does not extensively allocate memory, uses hw devices etc..
60::testing::AssertionResult is_approximately_equal(int a, int b)
61{
62 static const int error_margin = 10;
63
64 if (::abs(a-b) <= 10)
65 return ::testing::AssertionSuccess() << ::abs(a-b) << " <= " << error_margin;
66
67 return ::testing::AssertionFailure() << ::abs(a-b) << " > " << error_margin;
68}
69}
70
71TEST(LinuxProcess, adjusting_proc_oom_score_adj_works)
72{
74 {
76 };
77 EXPECT_NO_THROW(core::posix::this_process::instance() << oom_score_adj);
78 EXPECT_NO_THROW(core::posix::this_process::instance() >> oom_score_adj);
80 oom_score_adj.value);
82 EXPECT_NO_THROW(core::posix::this_process::instance() >> oom_score);
83 EXPECT_TRUE(is_approximately_equal(oom_score.value, core::posix::linux::proc::process::OomScoreAdj::max_value()));
84}
85
86// For this test we assume that we are not privileged and that the test binary
87// does not have CAP_SYS_RESOURCE capabilities.
88TEST(LinuxProcess, adjusting_proc_oom_score_adj_to_privileged_values_only_works_if_root)
89{
91 {
93 };
94 EXPECT_NO_THROW(core::posix::this_process::instance() << oom_score_adj);
95 EXPECT_NO_THROW(core::posix::this_process::instance() >> oom_score_adj);
96
97 // If we are running on virtualized builders or buildds we are running under a fakeroot environment.
98 // However, that environment does not give us the required privileges and capabilities to adjust OOM values
99 // as we like. At any rate, this check seems to be flaky and we just comment it out.
100 // EXPECT_NE(core::posix::linux::proc::process::OomScoreAdj::min_value(),
101 // oom_score_adj.value);
102}
103
104TEST(LinuxProcess, trying_to_write_an_invalid_oom_score_adj_throws)
105{
107 {
109 };
110
112}
113
114TEST(LinuxProcess, adjusting_proc_oom_adj_works)
115{
117 {
119 };
120 EXPECT_NO_THROW(core::posix::this_process::instance() << oom_adj);
121 EXPECT_NO_THROW(core::posix::this_process::instance() >> oom_adj);
123 oom_adj.value);
125 EXPECT_NO_THROW(core::posix::this_process::instance() >> oom_score);
126 // This looks weird as we are comparing to OomScoreAdj as opposed to OomAdj.
127 // However, /proc/pid/oom_adj is deprecated as of linux 2.6.36 and the value
128 // reported in oom_score is in the scale of /proc/pid/oom_score_adj, i.e., [-1000, 1000].
129 EXPECT_TRUE(is_approximately_equal(oom_score.value, core::posix::linux::proc::process::OomScoreAdj::max_value()));
130}
131
132// For this test we assume that we are not privileged and that the test binary
133// does not have CAP_SYS_RESOURCE capabilities.
134TEST(LinuxProcess, adjusting_proc_oom_adj_to_privileged_values_does_not_work)
135{
137 {
139 };
140 EXPECT_NO_THROW(core::posix::this_process::instance() << oom_adj);
141 EXPECT_NO_THROW(core::posix::this_process::instance() >> oom_adj);
142
143 // If we are running on virtualized builders or buildds we are running under a fakeroot environment.
144 // However, that environment does not give us the required privileges and capabilities to adjust OOM values
145 // as we like. At any rate, this check seems to be flaky and we just comment it out.
146 // EXPECT_NE(core::posix::linux::proc::process::OomAdj::min_value(),
147 // oom_adj.value);
148}
149
150TEST(LinuxProcess, trying_to_write_an_invalid_oom_adj_throws)
151{
153 {
155 };
156
158}
EXPECT_ANY_THROW(auto death_observer=core::posix::ChildProcess::DeathObserver::create_once_with_signal_trap(trap))
TEST(LinuxProcess, accessing_proc_stats_works)
CORE_POSIX_DLL_PUBLIC Process instance() noexcept(true)
Returns a Process instance corresponding to this process.
CORE_POSIX_DLL_PUBLIC ChildProcess fork(const std::function< posix::exit::Status()> &main, const StandardStream &flags)
fork forks a new process and executes the provided main function in the newly forked process.
Definition: fork.cpp:57
static int max_value()
Returns the maximum valid value.
Definition: oom_adj.cpp:50
static int min_value()
Returns the minimum valid value.
Definition: oom_adj.cpp:45
static int min_value()
Returns the minimum valid value.
static int max_value()
Returns the maximum valid value.
int value
Current OomScore as calculated by the kernel.
Definition: oom_score.h:52
The Stat struct encapsulates status information about a process.
Definition: stat.h:42