jdk

Форк
0
/
test_networkUtilization.cpp 
369 строк · 12.8 Кб
1
/*
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.
4
 *
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.
8
 *
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).
14
 *
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.
18
 *
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
21
 * questions.
22
 *
23
 */
24

25
#include "precompiled.hpp"
26

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.
30

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.
34

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"
44

45
#include "utilities/vmassert_uninstall.hpp"
46
#include <vector>
47
#include <list>
48
#include <map>
49
#include "utilities/vmassert_reinstall.hpp"
50

51
#include "unittest.hpp"
52

53
namespace {
54

55
  class MockFastUnorderedElapsedCounterSource : public ::FastUnorderedElapsedCounterSource {
56
   public:
57
    static jlong current_ticks;
58
    static Type now() {
59
      return current_ticks;
60
    }
61
    static uint64_t nanoseconds(Type value) {
62
      return value;
63
    }
64
  };
65

66
  typedef TimeInstant<CounterRepresentation, MockFastUnorderedElapsedCounterSource> MockJfrTicks;
67
  typedef TimeInterval<CounterRepresentation, MockFastUnorderedElapsedCounterSource> MockJfrTickspan;
68

69
  class MockJfrCheckpointWriter {
70
   public:
71
    traceid current;
72
    std::map<traceid, std::string> ids;
73

74
    const JfrCheckpointContext context() const {
75
      return JfrCheckpointContext();
76
    }
77
    intptr_t reserve(size_t size) {
78
      return 0;
79
    }
80
    void write_key(traceid id) {
81
      current = id;
82
    }
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) { }
88
  };
89

90
  class MockJfrSerializer {
91
   public:
92
    static bool register_serializer(JfrTypeId id, bool permit_cache, MockJfrSerializer* serializer) {
93
      return true;
94
    }
95
    virtual void on_rotation() {}
96
    virtual void serialize(MockJfrCheckpointWriter& writer) {}
97
  };
98

99
  struct MockNetworkInterface {
100
    std::string name;
101
    uint64_t bytes_in;
102
    uint64_t bytes_out;
103
    traceid id;
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) {}
106

107
    bool operator==(const MockNetworkInterface& rhs) const {
108
      return name == rhs.name;
109
    }
110
  };
111

112
  class NetworkInterface : public ::NetworkInterface {
113
   public:
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());
118
    }
119
  };
120

121
  class MockJfrOSInterface {
122
    static std::list<MockNetworkInterface> _interfaces;
123
   public:
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();
129
           ++i) {
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;
135
      }
136
      return OS_OK;
137
    }
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();
142
    }
143
    static void remove_interface(const MockNetworkInterface& iface) {
144
      _interfaces.remove(iface);
145
    }
146
    static void clear_interfaces() {
147
      _interfaces.clear();
148
    }
149
    static const MockNetworkInterface& get_interface(traceid id) {
150
      std::list<MockNetworkInterface>::const_iterator i = _interfaces.begin();
151
      for (; i != _interfaces.end(); ++i) {
152
        if (i->id == id) {
153
          break;
154
        }
155
      }
156
      return *i;
157
    }
158
  };
159

160
  std::list<MockNetworkInterface> MockJfrOSInterface::_interfaces;
161

162
  class MockEventNetworkUtilization : public ::EventNetworkUtilization {
163
   public:
164
    std::string iface;
165
    s8 readRate;
166
    s8 writeRate;
167
    static std::vector<MockEventNetworkUtilization> committed;
168
    MockJfrCheckpointWriter writer;
169

170
   public:
171
    MockEventNetworkUtilization(EventStartTime timing=TIMED) :
172
    ::EventNetworkUtilization(timing) {}
173

174
    void set_networkInterface(traceid new_value) {
175
      const MockNetworkInterface& entry  = MockJfrOSInterface::get_interface(new_value);
176
      iface = entry.name;
177
    }
178
    void set_readRate(s8 new_value) {
179
      readRate = new_value;
180
    }
181
    void set_writeRate(s8 new_value) {
182
      writeRate = new_value;
183
    }
184

185
    void commit() {
186
      committed.push_back(*this);
187
    }
188

189
    void set_starttime(const MockJfrTicks& time) {}
190
    void set_endtime(const MockJfrTicks& time) {}
191

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();
196
           ++i) {
197
        if (name == i->iface) {
198
          return *i;
199
        }
200
      }
201
      return placeholder;
202
    }
203
  };
204

205
  std::vector<MockEventNetworkUtilization> MockEventNetworkUtilization::committed;
206

207
  jlong MockFastUnorderedElapsedCounterSource::current_ticks;
208

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
213
#endif
214

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
222

223
#include "jfr/periodic/jfrNetworkUtilization.hpp"
224
#include "jfr/periodic/jfrNetworkUtilization.cpp"
225

226
#undef EventNetworkUtilization
227
#undef FastUnorderedElapsedCounterSource
228
#undef JfrOSInterface
229
#undef JfrSerializer
230
#undef JfrCheckpointWriter
231
#undef JfrTicks
232
#undef JfrTickspan
233

234
} // anonymous namespace
235

236
class JfrTestNetworkUtilization : public ::testing::Test {
237
protected:
238
  void SetUp() {
239
    MockEventNetworkUtilization::committed.clear();
240
    MockJfrOSInterface::clear_interfaces();
241
    // Ensure that tests are separated in time
242
    MockFastUnorderedElapsedCounterSource::current_ticks += 1 * NANOSECS_PER_SEC;
243
  }
244

245
  void TearDown() {
246
    JfrNetworkUtilization::destroy();
247
  }
248
};
249

250
static traceid id = 0;
251

252
TEST_VM_F(JfrTestNetworkUtilization, RequestFunctionBasic) {
253

254
  MockNetworkInterface& eth0 = MockJfrOSInterface::add_interface("eth0", ++id);
255
  JfrNetworkUtilization::send_events();
256
  ASSERT_EQ(0u, MockEventNetworkUtilization::committed.size());
257

258
  eth0.bytes_in += 10;
259
  MockFastUnorderedElapsedCounterSource::current_ticks += 2 * NANOSECS_PER_SEC;
260

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());
267
}
268

269
TEST_VM_F(JfrTestNetworkUtilization, RequestFunctionMultiple) {
270

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());
276

277
  eth0.bytes_in += 10;
278
  eth1.bytes_in += 100;
279
  ppp0.bytes_out += 50;
280
  MockFastUnorderedElapsedCounterSource::current_ticks += 2 * NANOSECS_PER_SEC;
281

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");
287

288
  EXPECT_EQ(40, eth0_event.readRate);
289
  EXPECT_EQ(0, eth0_event.writeRate);
290
  EXPECT_STREQ("eth0", eth0_event.iface.c_str());
291

292
  EXPECT_EQ(400, eth1_event.readRate);
293
  EXPECT_EQ(0, eth1_event.writeRate);
294
  EXPECT_STREQ("eth1", eth1_event.iface.c_str());
295

296
  EXPECT_EQ(0, ppp0_event.readRate);
297
  EXPECT_EQ(200, ppp0_event.writeRate);
298
  EXPECT_STREQ("ppp0", ppp0_event.iface.c_str());
299
}
300

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());
306

307
  eth0.bytes_in += 10;
308
  eth1.bytes_in += 20;
309
  MockFastUnorderedElapsedCounterSource::current_ticks += 2 * NANOSECS_PER_SEC;
310

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");
315

316
  EXPECT_EQ(40, eth0_event.readRate);
317
  EXPECT_EQ(0, eth0_event.writeRate);
318
  EXPECT_STREQ("eth0", eth0_event.iface.c_str());
319

320
  EXPECT_EQ(80, eth1_event.readRate);
321
  EXPECT_EQ(0, eth1_event.writeRate);
322
  EXPECT_STREQ("eth1", eth1_event.iface.c_str());
323

324
  MockJfrOSInterface::remove_interface(eth0);
325
  MockEventNetworkUtilization::committed.clear();
326

327
  eth1.bytes_in += 10;
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");
332

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());
336
}
337

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());
342

343
  eth0.bytes_in += 10;
344
  MockFastUnorderedElapsedCounterSource::current_ticks += 2 * NANOSECS_PER_SEC;
345

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());
352

353
  eth0.bytes_in = 0;
354
  MockFastUnorderedElapsedCounterSource::current_ticks += 2 * NANOSECS_PER_SEC;
355
  MockEventNetworkUtilization::committed.clear();
356

357
  JfrNetworkUtilization::send_events();
358
  ASSERT_EQ(0u, MockEventNetworkUtilization::committed.size());
359

360
  eth0.bytes_in = 10;
361
  MockFastUnorderedElapsedCounterSource::current_ticks += 2 * NANOSECS_PER_SEC;
362

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());
369
}
370

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.