process-cpp: /build/process-cpp/src/process-cpp-3.0.1/tests/linux_process_test.cpp Source File

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>
20 #include <core/posix/this_process.h>
21
22 #include <core/posix/linux/proc/process/stat.h>
23 #include <core/posix/linux/proc/process/oom_adj.h>
24 #include <core/posix/linux/proc/process/oom_score.h>
25 #include <core/posix/linux/proc/process/oom_score_adj.h>
26
27 #include <gtest/gtest.h>
28
29 #include <map>
30
31 TEST(LinuxProcess, accessing_proc_stats_works)
32 {
33 auto child = core::posix::fork(
34 [](){ while(true); return core::posix::exit::Status::success;},
35 core::posix::StandardStream::empty);
36
37 core::posix::linux::proc::process::Stat stat;
38 EXPECT_NO_THROW(child >> stat);
39 ASSERT_EQ(core::posix::linux::proc::process::State::running, stat.state);
40 }
41
42 TEST(LinuxProcess, accessing_proc_oom_score_works)
43 {
44 core::posix::linux::proc::process::OomScore oom_score;
45 EXPECT_NO_THROW(core::posix::this_process::instance() >> oom_score);
46 }
47
48 TEST(LinuxProcess, accessing_proc_oom_score_adj_works)
49 {
50 core::posix::linux::proc::process::OomScoreAdj oom_score_adj;
51 EXPECT_NO_THROW(core::posix::this_process::instance() >> oom_score_adj);
52 }
53
54 namespace
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
71 TEST(LinuxProcess, adjusting_proc_oom_score_adj_works)
72 {
73 core::posix::linux::proc::process::OomScoreAdj oom_score_adj
74 {
75 core::posix::linux::proc::process::OomScoreAdj::max_value()
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);
79 EXPECT_EQ(core::posix::linux::proc::process::OomScoreAdj::max_value(),
80 oom_score_adj.value);
81 core::posix::linux::proc::process::OomScore oom_score;
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.
88 TEST(LinuxProcess, adjusting_proc_oom_score_adj_to_privileged_values_only_works_if_root)
89 {
90 core::posix::linux::proc::process::OomScoreAdj oom_score_adj
91 {
92 core::posix::linux::proc::process::OomScoreAdj::min_value()
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
104 TEST(LinuxProcess, trying_to_write_an_invalid_oom_score_adj_throws)
105 {
106 core::posix::linux::proc::process::OomScoreAdj invalid_adj
107 {
108 core::posix::linux::proc::process::OomScoreAdj::min_value() -1000
109 };
110
111 EXPECT_ANY_THROW(core::posix::this_process::instance() << invalid_adj);
112 }
113
114 TEST(LinuxProcess, adjusting_proc_oom_adj_works)
115 {
116 core::posix::linux::proc::process::OomAdj oom_adj
117 {
118 core::posix::linux::proc::process::OomAdj::max_value()
119 };
120 EXPECT_NO_THROW(core::posix::this_process::instance() << oom_adj);
121 EXPECT_NO_THROW(core::posix::this_process::instance() >> oom_adj);
122 EXPECT_EQ(core::posix::linux::proc::process::OomAdj::max_value(),
123 oom_adj.value);
124 core::posix::linux::proc::process::OomScore oom_score;
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.
134 TEST(LinuxProcess, adjusting_proc_oom_adj_to_privileged_values_does_not_work)
135 {
136 core::posix::linux::proc::process::OomAdj oom_adj
137 {
138 core::posix::linux::proc::process::OomAdj::min_value()
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
150 TEST(LinuxProcess, trying_to_write_an_invalid_oom_adj_throws)
151 {
152 core::posix::linux::proc::process::OomAdj invalid_adj
153 {
154 core::posix::linux::proc::process::OomAdj::min_value() - 1000
155 };
156
157 EXPECT_ANY_THROW(core::posix::this_process::instance() << invalid_adj);
158 }
core::posix::this_process::instance
CORE_POSIX_DLL_PUBLIC Process instance() noexcept(true)
Returns a Process instance corresponding to this process.
Definition: this_process.cpp:150
TEST
TEST(LinuxProcess, accessing_proc_stats_works)
Definition: linux_process_test.cpp:31
core::posix::linux::proc::process::OomScoreAdj::min_value
static int min_value()
Returns the minimum valid value.
Definition: oom_score_adj.cpp:40
core::posix::linux::proc::process::OomScoreAdj
Definition: oom_score_adj.h:82
fork.h
oom_score_adj.h
core::posix::linux::proc::process::OomScore::value
int value
Current OomScore as calculated by the kernel.
Definition: oom_score.h:52
core::posix::linux::proc::process::OomScoreAdj::max_value
static int max_value()
Returns the maximum valid value.
Definition: oom_score_adj.cpp:45
core::posix::linux::proc::process::State::running
@ running
core::posix::linux::proc::process::OomScore
Definition: oom_score.h:51
core::posix::linux::proc::process::Stat
The Stat struct encapsulates status information about a process.
Definition: stat.h:42
this_process.h
core::posix::linux::proc::process::OomAdj
Definition: oom_adj.h:51
core::posix::fork
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
oom_adj.h
EXPECT_ANY_THROW
EXPECT_ANY_THROW(auto death_observer=core::posix::ChildProcess::DeathObserver::create_once_with_signal_trap(trap))
stat.h
oom_score.h
core::posix::linux::proc::process::OomAdj::min_value
static int min_value()
Returns the minimum valid value.
Definition: oom_adj.cpp:45
core::posix::linux::proc::process::OomAdj::max_value
static int max_value()
Returns the maximum valid value.
Definition: oom_adj.cpp:50