xrpld
Toggle main menu visibility
Loading...
Searching...
No Matches
tests
libxrpl
basics
tests/libxrpl/basics/MallocTrim.cpp
1
#include <xrpl/basics/MallocTrim.h>
2
3
#include <xrpl/beast/utility/Journal.h>
4
5
#include <boost/predef.h>
6
7
#include <gtest/gtest.h>
8
9
#include <
string
>
10
11
using namespace
xrpl
;
12
13
// cSpell:ignore statm
14
15
#if defined(__GLIBC__) && BOOST_OS_LINUX
16
namespace
xrpl::detail
{
17
long
18
parseStatmRSSkB(std::string
const
& statm);
19
}
// namespace xrpl::detail
20
#endif
21
22
TEST
(
MallocTrimReport
, structure)
23
{
24
// Test default construction
25
MallocTrimReport
report;
26
EXPECT_EQ(report.
supported
,
false
);
27
EXPECT_EQ(report.
trimResult
, -1);
28
EXPECT_EQ(report.
rssBeforeKB
, -1);
29
EXPECT_EQ(report.
rssAfterKB
, -1);
30
EXPECT_EQ(report.
durationUs
,
std::chrono::microseconds
{-1});
31
EXPECT_EQ(report.
minfltDelta
, -1);
32
EXPECT_EQ(report.
majfltDelta
, -1);
33
EXPECT_EQ(report.
deltaKB
(), 0);
34
35
// Test deltaKB calculation - memory freed
36
report.
rssBeforeKB
= 1000;
37
report.
rssAfterKB
= 800;
38
EXPECT_EQ(report.
deltaKB
(), -200);
39
40
// Test deltaKB calculation - memory increased
41
report.
rssBeforeKB
= 500;
42
report.
rssAfterKB
= 600;
43
EXPECT_EQ(report.
deltaKB
(), 100);
44
45
// Test deltaKB calculation - no change
46
report.
rssBeforeKB
= 1234;
47
report.
rssAfterKB
= 1234;
48
EXPECT_EQ(report.
deltaKB
(), 0);
49
}
50
51
#if defined(__GLIBC__) && BOOST_OS_LINUX
52
TEST
(ParseStatmRSSkB, standard_format)
53
{
54
using
xrpl::detail::parseStatmRSSkB;
55
56
// Test standard format: size resident shared text lib data dt
57
// Assuming 4KB page size: resident=1000 pages = 4000 KB
58
{
59
std::string
const
statm =
"25365 1000 2377 0 0 5623 0"
;
60
long
const
result = parseStatmRSSkB(statm);
61
// Note: actual result depends on system page size
62
// On most systems it's 4KB, so 1000 pages = 4000 KB
63
EXPECT_GT(result, 0);
64
}
65
66
// Test with newline
67
{
68
std::string
const
statm =
"12345 2000 1234 0 0 3456 0\n"
;
69
long
const
result = parseStatmRSSkB(statm);
70
EXPECT_GT(result, 0);
71
}
72
73
// Test with tabs
74
{
75
std::string
const
statm =
"12345\t2000\t1234\t0\t0\t3456\t0"
;
76
long
const
result = parseStatmRSSkB(statm);
77
EXPECT_GT(result, 0);
78
}
79
80
// Test zero resident pages
81
{
82
std::string
const
statm =
"25365 0 2377 0 0 5623 0"
;
83
long
const
result = parseStatmRSSkB(statm);
84
EXPECT_EQ(result, 0);
85
}
86
87
// Test with extra whitespace
88
{
89
std::string
const
statm =
" 25365 1000 2377 "
;
90
long
const
result = parseStatmRSSkB(statm);
91
EXPECT_GT(result, 0);
92
}
93
94
// Test empty string
95
{
96
std::string
const
statm;
97
long
const
result = parseStatmRSSkB(statm);
98
EXPECT_EQ(result, -1);
99
}
100
101
// Test malformed data (only one field)
102
{
103
std::string
const
statm =
"25365"
;
104
long
const
result = parseStatmRSSkB(statm);
105
EXPECT_EQ(result, -1);
106
}
107
108
// Test malformed data (non-numeric)
109
{
110
std::string
const
statm =
"abc def ghi"
;
111
long
const
result = parseStatmRSSkB(statm);
112
EXPECT_EQ(result, -1);
113
}
114
115
// Test malformed data (second field non-numeric)
116
{
117
std::string
const
statm =
"25365 abc 2377"
;
118
long
const
result = parseStatmRSSkB(statm);
119
EXPECT_EQ(result, -1);
120
}
121
}
122
#endif
123
124
TEST
(MallocTrim, without_debug_logging)
125
{
126
beast::Journal
const
journal{
beast::Journal::getNullSink
()};
127
128
MallocTrimReport
const
report =
mallocTrim
(
"without_debug"
, journal);
129
130
#if defined(__GLIBC__) && BOOST_OS_LINUX
131
EXPECT_EQ(report.
supported
,
true
);
132
EXPECT_GE(report.
trimResult
, 0);
133
EXPECT_EQ(report.
durationUs
,
std::chrono::microseconds
{-1});
134
EXPECT_EQ(report.
minfltDelta
, -1);
135
EXPECT_EQ(report.
majfltDelta
, -1);
136
#else
137
EXPECT_EQ(report.
supported
,
false
);
138
EXPECT_EQ(report.
trimResult
, -1);
139
EXPECT_EQ(report.
rssBeforeKB
, -1);
140
EXPECT_EQ(report.
rssAfterKB
, -1);
141
EXPECT_EQ(report.
durationUs
,
std::chrono::microseconds
{-1});
142
EXPECT_EQ(report.
minfltDelta
, -1);
143
EXPECT_EQ(report.
majfltDelta
, -1);
144
#endif
145
}
146
147
TEST
(MallocTrim, empty_tag)
148
{
149
beast::Journal
const
journal{
beast::Journal::getNullSink
()};
150
MallocTrimReport
const
report =
mallocTrim
(
""
, journal);
151
152
#if defined(__GLIBC__) && BOOST_OS_LINUX
153
EXPECT_EQ(report.
supported
,
true
);
154
EXPECT_GE(report.
trimResult
, 0);
155
#else
156
EXPECT_EQ(report.
supported
,
false
);
157
#endif
158
}
159
160
TEST
(MallocTrim, with_debug_logging)
161
{
162
struct
DebugSink
:
public
beast::Journal::Sink
163
{
164
DebugSink
() : Sink(beast::
Severity
::
Debug
, false)
165
{
166
}
167
void
168
write
(
beast::Severity
, std::string
const
&)
override
169
{
170
}
171
void
172
writeAlways(
beast::Severity
, std::string
const
&)
override
173
{
174
}
175
};
176
177
DebugSink
sink;
178
beast::Journal
const
journal{sink};
179
180
MallocTrimReport
const
report =
mallocTrim
(
"debug_test"
, journal);
181
182
#if defined(__GLIBC__) && BOOST_OS_LINUX
183
EXPECT_EQ(report.
supported
,
true
);
184
EXPECT_GE(report.
trimResult
, 0);
185
EXPECT_GE(report.
durationUs
.
count
(), 0);
186
EXPECT_GE(report.
minfltDelta
, 0);
187
EXPECT_GE(report.
majfltDelta
, 0);
188
#else
189
EXPECT_EQ(report.
supported
,
false
);
190
EXPECT_EQ(report.
trimResult
, -1);
191
EXPECT_EQ(report.
durationUs
,
std::chrono::microseconds
{-1});
192
EXPECT_EQ(report.
minfltDelta
, -1);
193
EXPECT_EQ(report.
majfltDelta
, -1);
194
#endif
195
}
196
197
TEST
(MallocTrim, repeated_calls)
198
{
199
beast::Journal
const
journal{
beast::Journal::getNullSink
()};
200
201
// Call malloc_trim multiple times to ensure it's safe
202
for
(
auto
i = 0uz; i < 5; ++i)
203
{
204
MallocTrimReport
const
report =
mallocTrim
(
"iteration_"
+
std::to_string
(i), journal);
205
206
#if defined(__GLIBC__) && BOOST_OS_LINUX
207
EXPECT_EQ(report.
supported
,
true
);
208
EXPECT_GE(report.
trimResult
, 0);
209
#else
210
EXPECT_EQ(report.
supported
,
false
);
211
#endif
212
}
213
}
std::string
beast::Journal::Sink
Abstraction for the underlying message destination.
Definition
Journal.h:59
beast::Journal
A generic endpoint for log messages.
Definition
Journal.h:44
beast::Journal::getNullSink
static Sink & getNullSink()
Returns a Sink which does nothing.
Definition
beast_Journal.cpp:63
xrpl::DebugSink
Definition
Log.cpp:338
xrpl::DebugSink::DebugSink
DebugSink()
Definition
Log.cpp:345
std::chrono::microseconds::count
T count(T... args)
std::chrono::microseconds
beast::Severity
Severity
Severity level / threshold of a Journal message.
Definition
Journal.h:16
beast::Severity::Debug
@ Debug
Definition
Journal.h:20
xrpl::detail
Definition
base_uint.h:37
xrpl::node_store::write
void write(nudb::detail::ostream &os, std::size_t t)
Definition
Varint.h:120
xrpl
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition
algorithm.h:5
xrpl::TEST
TEST(FileUtilitiesTest, get_file_contents)
Definition
tests/libxrpl/basics/FileUtilities.cpp:60
xrpl::mallocTrim
MallocTrimReport mallocTrim(std::string_view tag, beast::Journal journal)
Attempt to return freed memory to the operating system.
Definition
libxrpl/basics/MallocTrim.cpp:77
string
xrpl::MallocTrimReport
Definition
MallocTrim.h:28
xrpl::MallocTrimReport::supported
bool supported
Definition
MallocTrim.h:29
xrpl::MallocTrimReport::majfltDelta
std::int64_t majfltDelta
Definition
MallocTrim.h:35
xrpl::MallocTrimReport::minfltDelta
std::int64_t minfltDelta
Definition
MallocTrim.h:34
xrpl::MallocTrimReport::durationUs
std::chrono::microseconds durationUs
Definition
MallocTrim.h:33
xrpl::MallocTrimReport::trimResult
int trimResult
Definition
MallocTrim.h:30
xrpl::MallocTrimReport::deltaKB
std::int64_t deltaKB() const noexcept
Definition
MallocTrim.h:38
xrpl::MallocTrimReport::rssAfterKB
std::int64_t rssAfterKB
Definition
MallocTrim.h:32
xrpl::MallocTrimReport::rssBeforeKB
std::int64_t rssBeforeKB
Definition
MallocTrim.h:31
std::to_string
T to_string(T... args)
Generated by
1.17.0