2
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
25
#include "precompiled.hpp"
27
// This test performs mocking of certain JVM functionality. This works by
28
// including the source file under test inside an anonymous namespace (which
29
// prevents linking conflicts) with the mocked symbols redefined.
31
// The include list should mirror the one found in the included source file -
32
// with the ones that should pick up the mocks removed. Those should be included
33
// later after the mocks have been defined.
35
#include "jfr/jfrEvents.hpp"
36
#include "jfr/metadata/jfrSerializer.hpp"
37
#include "jfr/periodic/jfrOSInterface.hpp"
38
#include "jfr/utilities/jfrTime.hpp"
39
#include "jfr/utilities/jfrTypes.hpp"
40
#include "logging/log.hpp"
41
#include "runtime/os_perf.hpp"
42
#include "utilities/globalDefinitions.hpp"
43
#include "utilities/growableArray.hpp"
45
#include "utilities/vmassert_uninstall.hpp"
49
#include "utilities/vmassert_reinstall.hpp"
51
#include "unittest.hpp"
55
class MockFastUnorderedElapsedCounterSource : public ::FastUnorderedElapsedCounterSource {
57
static jlong current_ticks;
61
static uint64_t nanoseconds(Type value) {
66
typedef TimeInstant<CounterRepresentation, MockFastUnorderedElapsedCounterSource> MockJfrTicks;
67
typedef TimeInterval<CounterRepresentation, MockFastUnorderedElapsedCounterSource> MockJfrTickspan;
69
class MockJfrCheckpointWriter {
72
std::map<traceid, std::string> ids;
74
const JfrCheckpointContext context() const {
75
return JfrCheckpointContext();
77
intptr_t reserve(size_t size) {
80
void write_key(traceid id) {
83
void write_type(JfrTypeId id) {}
84
MockJfrCheckpointWriter() {}
85
void write(const char* data) {}
86
void set_context(const JfrCheckpointContext ctx) { }
87
void write_count(u4 nof_entries) { }
90
class MockJfrSerializer {
92
static bool register_serializer(JfrTypeId id, bool permit_cache, MockJfrSerializer* serializer) {
95
virtual void on_rotation() {}
96
virtual void serialize(MockJfrCheckpointWriter& writer) {}
99
struct MockNetworkInterface {
104
MockNetworkInterface(std::string name, uint64_t bytes_in, uint64_t bytes_out, traceid id) :
105
name(name), bytes_in(bytes_in), bytes_out(bytes_out), id(id) {}
107
bool operator==(const MockNetworkInterface& rhs) const {
108
return name == rhs.name;
112
class NetworkInterface : public ::NetworkInterface {
114
NetworkInterface(const char* name, uint64_t bytes_in, uint64_t bytes_out, NetworkInterface* next) :
115
::NetworkInterface(name, bytes_in, bytes_out, next) {}
116
NetworkInterface* next(void) const {
117
return reinterpret_cast<NetworkInterface*>(::NetworkInterface::next());
121
class MockJfrOSInterface {
122
static std::list<MockNetworkInterface> _interfaces;
124
MockJfrOSInterface() {}
125
static int network_utilization(NetworkInterface** network_interfaces) {
126
*network_interfaces = nullptr;
127
for (std::list<MockNetworkInterface>::const_iterator i = _interfaces.begin();
128
i != _interfaces.end();
130
// The gtests are compiled with exceptions, which requires operator delete.
131
// Allocate in CHeap instead.
132
void* mem = AllocateHeap(sizeof(NetworkInterface), mtTest);
133
NetworkInterface* cur = ::new (mem) NetworkInterface(i->name.c_str(), i->bytes_in, i->bytes_out, *network_interfaces);
134
*network_interfaces = cur;
138
static MockNetworkInterface& add_interface(const std::string& name, traceid id) {
139
MockNetworkInterface iface(name, 0, 0, id);
140
_interfaces.push_front(iface);
141
return _interfaces.front();
143
static void remove_interface(const MockNetworkInterface& iface) {
144
_interfaces.remove(iface);
146
static void clear_interfaces() {
149
static const MockNetworkInterface& get_interface(traceid id) {
150
std::list<MockNetworkInterface>::const_iterator i = _interfaces.begin();
151
for (; i != _interfaces.end(); ++i) {
160
std::list<MockNetworkInterface> MockJfrOSInterface::_interfaces;
162
class MockEventNetworkUtilization : public ::EventNetworkUtilization {
167
static std::vector<MockEventNetworkUtilization> committed;
168
MockJfrCheckpointWriter writer;
171
MockEventNetworkUtilization(EventStartTime timing=TIMED) :
172
::EventNetworkUtilization(timing) {}
174
void set_networkInterface(traceid new_value) {
175
const MockNetworkInterface& entry = MockJfrOSInterface::get_interface(new_value);
178
void set_readRate(s8 new_value) {
179
readRate = new_value;
181
void set_writeRate(s8 new_value) {
182
writeRate = new_value;
186
committed.push_back(*this);
189
void set_starttime(const MockJfrTicks& time) {}
190
void set_endtime(const MockJfrTicks& time) {}
192
static const MockEventNetworkUtilization& get_committed(const std::string& name) {
193
static MockEventNetworkUtilization placeholder;
194
for (std::vector<MockEventNetworkUtilization>::const_iterator i = committed.begin();
195
i != committed.end();
197
if (name == i->iface) {
205
std::vector<MockEventNetworkUtilization> MockEventNetworkUtilization::committed;
207
jlong MockFastUnorderedElapsedCounterSource::current_ticks;
209
// Reincluding source files in the anonymous namespace unfortunately seems to
210
// behave strangely with precompiled headers (only when using gcc though)
211
#ifndef DONT_USE_PRECOMPILED_HEADER
212
#define DONT_USE_PRECOMPILED_HEADER
215
#define EventNetworkUtilization MockEventNetworkUtilization
216
#define FastUnorderedElapsedCounterSource MockFastUnorderedElapsedCounterSource
217
#define JfrOSInterface MockJfrOSInterface
218
#define JfrSerializer MockJfrSerializer
219
#define JfrCheckpointWriter MockJfrCheckpointWriter
220
#define JfrTicks MockJfrTicks
221
#define JfrTickspan MockJfrTickspan
223
#include "jfr/periodic/jfrNetworkUtilization.hpp"
224
#include "jfr/periodic/jfrNetworkUtilization.cpp"
226
#undef EventNetworkUtilization
227
#undef FastUnorderedElapsedCounterSource
230
#undef JfrCheckpointWriter
234
} // anonymous namespace
236
class JfrTestNetworkUtilization : public ::testing::Test {
239
MockEventNetworkUtilization::committed.clear();
240
MockJfrOSInterface::clear_interfaces();
241
// Ensure that tests are separated in time
242
MockFastUnorderedElapsedCounterSource::current_ticks += 1 * NANOSECS_PER_SEC;
246
JfrNetworkUtilization::destroy();
250
static traceid id = 0;
252
TEST_VM_F(JfrTestNetworkUtilization, RequestFunctionBasic) {
254
MockNetworkInterface& eth0 = MockJfrOSInterface::add_interface("eth0", ++id);
255
JfrNetworkUtilization::send_events();
256
ASSERT_EQ(0u, MockEventNetworkUtilization::committed.size());
259
MockFastUnorderedElapsedCounterSource::current_ticks += 2 * NANOSECS_PER_SEC;
261
JfrNetworkUtilization::send_events();
262
ASSERT_EQ(1u, MockEventNetworkUtilization::committed.size());
263
MockEventNetworkUtilization& e = MockEventNetworkUtilization::committed[0];
264
EXPECT_EQ(40, e.readRate);
265
EXPECT_EQ(0, e.writeRate);
266
EXPECT_STREQ("eth0", e.iface.c_str());
269
TEST_VM_F(JfrTestNetworkUtilization, RequestFunctionMultiple) {
271
MockNetworkInterface& eth0 = MockJfrOSInterface::add_interface("eth0", ++id);
272
MockNetworkInterface& eth1 = MockJfrOSInterface::add_interface("eth1", ++id);
273
MockNetworkInterface& ppp0 = MockJfrOSInterface::add_interface("ppp0", ++id);
274
JfrNetworkUtilization::send_events();
275
ASSERT_EQ(0u, MockEventNetworkUtilization::committed.size());
278
eth1.bytes_in += 100;
279
ppp0.bytes_out += 50;
280
MockFastUnorderedElapsedCounterSource::current_ticks += 2 * NANOSECS_PER_SEC;
282
JfrNetworkUtilization::send_events();
283
ASSERT_EQ(3u, MockEventNetworkUtilization::committed.size());
284
const MockEventNetworkUtilization& eth0_event = MockEventNetworkUtilization::get_committed("eth0");
285
const MockEventNetworkUtilization& eth1_event = MockEventNetworkUtilization::get_committed("eth1");
286
const MockEventNetworkUtilization& ppp0_event = MockEventNetworkUtilization::get_committed("ppp0");
288
EXPECT_EQ(40, eth0_event.readRate);
289
EXPECT_EQ(0, eth0_event.writeRate);
290
EXPECT_STREQ("eth0", eth0_event.iface.c_str());
292
EXPECT_EQ(400, eth1_event.readRate);
293
EXPECT_EQ(0, eth1_event.writeRate);
294
EXPECT_STREQ("eth1", eth1_event.iface.c_str());
296
EXPECT_EQ(0, ppp0_event.readRate);
297
EXPECT_EQ(200, ppp0_event.writeRate);
298
EXPECT_STREQ("ppp0", ppp0_event.iface.c_str());
301
TEST_VM_F(JfrTestNetworkUtilization, InterfaceRemoved) {
302
MockNetworkInterface& eth0 = MockJfrOSInterface::add_interface("eth0", ++id);
303
MockNetworkInterface& eth1 = MockJfrOSInterface::add_interface("eth1", ++id);
304
JfrNetworkUtilization::send_events();
305
ASSERT_EQ(0u, MockEventNetworkUtilization::committed.size());
309
MockFastUnorderedElapsedCounterSource::current_ticks += 2 * NANOSECS_PER_SEC;
311
JfrNetworkUtilization::send_events();
312
ASSERT_EQ(2u, MockEventNetworkUtilization::committed.size());
313
const MockEventNetworkUtilization& eth0_event = MockEventNetworkUtilization::get_committed("eth0");
314
const MockEventNetworkUtilization& eth1_event = MockEventNetworkUtilization::get_committed("eth1");
316
EXPECT_EQ(40, eth0_event.readRate);
317
EXPECT_EQ(0, eth0_event.writeRate);
318
EXPECT_STREQ("eth0", eth0_event.iface.c_str());
320
EXPECT_EQ(80, eth1_event.readRate);
321
EXPECT_EQ(0, eth1_event.writeRate);
322
EXPECT_STREQ("eth1", eth1_event.iface.c_str());
324
MockJfrOSInterface::remove_interface(eth0);
325
MockEventNetworkUtilization::committed.clear();
328
MockFastUnorderedElapsedCounterSource::current_ticks += 2 * NANOSECS_PER_SEC;
329
JfrNetworkUtilization::send_events();
330
ASSERT_EQ(1u, MockEventNetworkUtilization::committed.size());
331
const MockEventNetworkUtilization& eth1_event_v2 = MockEventNetworkUtilization::get_committed("eth1");
333
EXPECT_EQ(40, eth1_event_v2.readRate);
334
EXPECT_EQ(0, eth1_event_v2.writeRate);
335
EXPECT_STREQ("eth1", eth1_event_v2.iface.c_str());
338
TEST_VM_F(JfrTestNetworkUtilization, InterfaceReset) {
339
MockNetworkInterface& eth0 = MockJfrOSInterface::add_interface("eth0", ++id);
340
JfrNetworkUtilization::send_events();
341
ASSERT_EQ(0u, MockEventNetworkUtilization::committed.size());
344
MockFastUnorderedElapsedCounterSource::current_ticks += 2 * NANOSECS_PER_SEC;
346
JfrNetworkUtilization::send_events();
347
ASSERT_EQ(1u, MockEventNetworkUtilization::committed.size());
348
const MockEventNetworkUtilization& event = MockEventNetworkUtilization::committed[0];
349
EXPECT_EQ(40, event.readRate);
350
EXPECT_EQ(0, event.writeRate);
351
EXPECT_STREQ("eth0", event.iface.c_str());
354
MockFastUnorderedElapsedCounterSource::current_ticks += 2 * NANOSECS_PER_SEC;
355
MockEventNetworkUtilization::committed.clear();
357
JfrNetworkUtilization::send_events();
358
ASSERT_EQ(0u, MockEventNetworkUtilization::committed.size());
361
MockFastUnorderedElapsedCounterSource::current_ticks += 2 * NANOSECS_PER_SEC;
363
JfrNetworkUtilization::send_events();
364
ASSERT_EQ(1u, MockEventNetworkUtilization::committed.size());
365
const MockEventNetworkUtilization& event_v2 = MockEventNetworkUtilization::committed[0];
366
EXPECT_EQ(40, event_v2.readRate);
367
EXPECT_EQ(0, event_v2.writeRate);
368
EXPECT_STREQ("eth0", event_v2.iface.c_str());