Path: blob/master/test/hotspot/gtest/jfr/test_networkUtilization.cpp
41144 views
/*1* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"2526// This test performs mocking of certain JVM functionality. This works by27// including the source file under test inside an anonymous namespace (which28// prevents linking conflicts) with the mocked symbols redefined.2930// The include list should mirror the one found in the included source file -31// with the ones that should pick up the mocks removed. Those should be included32// later after the mocks have been defined.3334#include "logging/log.hpp"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 "runtime/os_perf.hpp"41#include "utilities/globalDefinitions.hpp"42#include "utilities/growableArray.hpp"4344#include "unittest.hpp"4546#include <vector>47#include <list>48#include <map>4950namespace {5152class MockFastUnorderedElapsedCounterSource : public ::FastUnorderedElapsedCounterSource {53public:54static jlong current_ticks;55static Type now() {56return current_ticks;57}58static uint64_t nanoseconds(Type value) {59return value;60}61};6263typedef TimeInstant<CounterRepresentation, MockFastUnorderedElapsedCounterSource> MockJfrTicks;64typedef TimeInterval<CounterRepresentation, MockFastUnorderedElapsedCounterSource> MockJfrTickspan;6566class MockJfrCheckpointWriter {67public:68traceid current;69std::map<traceid, std::string> ids;7071const JfrCheckpointContext context() const {72return JfrCheckpointContext();73}74intptr_t reserve(size_t size) {75return 0;76}77void write_key(traceid id) {78current = id;79}80void write_type(JfrTypeId id) {}81MockJfrCheckpointWriter() {}82void write(const char* data) {}83void set_context(const JfrCheckpointContext ctx) { }84void write_count(u4 nof_entries) { }85};8687class MockJfrSerializer {88public:89static bool register_serializer(JfrTypeId id, bool permit_cache, MockJfrSerializer* serializer) {90return true;91}92virtual void on_rotation() {}93virtual void serialize(MockJfrCheckpointWriter& writer) {}94};9596struct MockNetworkInterface {97std::string name;98uint64_t bytes_in;99uint64_t bytes_out;100traceid id;101MockNetworkInterface(std::string name, uint64_t bytes_in, uint64_t bytes_out, traceid id) :102name(name), bytes_in(bytes_in), bytes_out(bytes_out), id(id) {}103104bool operator==(const MockNetworkInterface& rhs) const {105return name == rhs.name;106}107};108109class NetworkInterface : public ::NetworkInterface {110public:111NetworkInterface(const char* name, uint64_t bytes_in, uint64_t bytes_out, NetworkInterface* next) :112::NetworkInterface(name, bytes_in, bytes_out, next) {}113NetworkInterface* next(void) const {114return reinterpret_cast<NetworkInterface*>(::NetworkInterface::next());115}116};117118class MockJfrOSInterface {119static std::list<MockNetworkInterface> _interfaces;120public:121MockJfrOSInterface() {}122static int network_utilization(NetworkInterface** network_interfaces) {123*network_interfaces = NULL;124for (std::list<MockNetworkInterface>::const_iterator i = _interfaces.begin();125i != _interfaces.end();126++i) {127NetworkInterface* cur = new NetworkInterface(i->name.c_str(), i->bytes_in, i->bytes_out, *network_interfaces);128*network_interfaces = cur;129}130return OS_OK;131}132static MockNetworkInterface& add_interface(const std::string& name, traceid id) {133MockNetworkInterface iface(name, 0, 0, id);134_interfaces.push_front(iface);135return _interfaces.front();136}137static void remove_interface(const MockNetworkInterface& iface) {138_interfaces.remove(iface);139}140static void clear_interfaces() {141_interfaces.clear();142}143static const MockNetworkInterface& get_interface(traceid id) {144std::list<MockNetworkInterface>::const_iterator i = _interfaces.begin();145for (; i != _interfaces.end(); ++i) {146if (i->id == id) {147break;148}149}150return *i;151}152};153154std::list<MockNetworkInterface> MockJfrOSInterface::_interfaces;155156class MockEventNetworkUtilization : public ::EventNetworkUtilization {157public:158std::string iface;159s8 readRate;160s8 writeRate;161static std::vector<MockEventNetworkUtilization> committed;162MockJfrCheckpointWriter writer;163164public:165MockEventNetworkUtilization(EventStartTime timing=TIMED) :166::EventNetworkUtilization(timing) {}167168void set_networkInterface(traceid new_value) {169const MockNetworkInterface& entry = MockJfrOSInterface::get_interface(new_value);170iface = entry.name;171}172void set_readRate(s8 new_value) {173readRate = new_value;174}175void set_writeRate(s8 new_value) {176writeRate = new_value;177}178179void commit() {180committed.push_back(*this);181}182183void set_starttime(const MockJfrTicks& time) {}184void set_endtime(const MockJfrTicks& time) {}185186static const MockEventNetworkUtilization& get_committed(const std::string& name) {187static MockEventNetworkUtilization placeholder;188for (std::vector<MockEventNetworkUtilization>::const_iterator i = committed.begin();189i != committed.end();190++i) {191if (name == i->iface) {192return *i;193}194}195return placeholder;196}197};198199std::vector<MockEventNetworkUtilization> MockEventNetworkUtilization::committed;200201jlong MockFastUnorderedElapsedCounterSource::current_ticks;202203// Reincluding source files in the anonymous namespace unfortunately seems to204// behave strangely with precompiled headers (only when using gcc though)205#ifndef DONT_USE_PRECOMPILED_HEADER206#define DONT_USE_PRECOMPILED_HEADER207#endif208209#define EventNetworkUtilization MockEventNetworkUtilization210#define FastUnorderedElapsedCounterSource MockFastUnorderedElapsedCounterSource211#define JfrOSInterface MockJfrOSInterface212#define JfrSerializer MockJfrSerializer213#define JfrCheckpointWriter MockJfrCheckpointWriter214#define JfrTicks MockJfrTicks215#define JfrTickspan MockJfrTickspan216217#include "jfr/periodic/jfrNetworkUtilization.hpp"218#include "jfr/periodic/jfrNetworkUtilization.cpp"219220#undef EventNetworkUtilization221#undef FastUnorderedElapsedCounterSource222#undef JfrOSInterface223#undef JfrSerializer224#undef JfrCheckpointWriter225#undef JfrTicks226#undef JfrTickspan227228} // anonymous namespace229230class JfrTestNetworkUtilization : public ::testing::Test {231protected:232void SetUp() {233MockEventNetworkUtilization::committed.clear();234MockJfrOSInterface::clear_interfaces();235// Ensure that tests are separated in time236MockFastUnorderedElapsedCounterSource::current_ticks += 1 * NANOSECS_PER_SEC;237}238239void TearDown() {240JfrNetworkUtilization::destroy();241}242};243244static traceid id = 0;245246TEST_VM_F(JfrTestNetworkUtilization, RequestFunctionBasic) {247248MockNetworkInterface& eth0 = MockJfrOSInterface::add_interface("eth0", ++id);249JfrNetworkUtilization::send_events();250ASSERT_EQ(0u, MockEventNetworkUtilization::committed.size());251252eth0.bytes_in += 10;253MockFastUnorderedElapsedCounterSource::current_ticks += 2 * NANOSECS_PER_SEC;254255JfrNetworkUtilization::send_events();256ASSERT_EQ(1u, MockEventNetworkUtilization::committed.size());257MockEventNetworkUtilization& e = MockEventNetworkUtilization::committed[0];258EXPECT_EQ(40, e.readRate);259EXPECT_EQ(0, e.writeRate);260EXPECT_STREQ("eth0", e.iface.c_str());261}262263TEST_VM_F(JfrTestNetworkUtilization, RequestFunctionMultiple) {264265MockNetworkInterface& eth0 = MockJfrOSInterface::add_interface("eth0", ++id);266MockNetworkInterface& eth1 = MockJfrOSInterface::add_interface("eth1", ++id);267MockNetworkInterface& ppp0 = MockJfrOSInterface::add_interface("ppp0", ++id);268JfrNetworkUtilization::send_events();269ASSERT_EQ(0u, MockEventNetworkUtilization::committed.size());270271eth0.bytes_in += 10;272eth1.bytes_in += 100;273ppp0.bytes_out += 50;274MockFastUnorderedElapsedCounterSource::current_ticks += 2 * NANOSECS_PER_SEC;275276JfrNetworkUtilization::send_events();277ASSERT_EQ(3u, MockEventNetworkUtilization::committed.size());278const MockEventNetworkUtilization& eth0_event = MockEventNetworkUtilization::get_committed("eth0");279const MockEventNetworkUtilization& eth1_event = MockEventNetworkUtilization::get_committed("eth1");280const MockEventNetworkUtilization& ppp0_event = MockEventNetworkUtilization::get_committed("ppp0");281282EXPECT_EQ(40, eth0_event.readRate);283EXPECT_EQ(0, eth0_event.writeRate);284EXPECT_STREQ("eth0", eth0_event.iface.c_str());285286EXPECT_EQ(400, eth1_event.readRate);287EXPECT_EQ(0, eth1_event.writeRate);288EXPECT_STREQ("eth1", eth1_event.iface.c_str());289290EXPECT_EQ(0, ppp0_event.readRate);291EXPECT_EQ(200, ppp0_event.writeRate);292EXPECT_STREQ("ppp0", ppp0_event.iface.c_str());293}294295TEST_VM_F(JfrTestNetworkUtilization, InterfaceRemoved) {296MockNetworkInterface& eth0 = MockJfrOSInterface::add_interface("eth0", ++id);297MockNetworkInterface& eth1 = MockJfrOSInterface::add_interface("eth1", ++id);298JfrNetworkUtilization::send_events();299ASSERT_EQ(0u, MockEventNetworkUtilization::committed.size());300301eth0.bytes_in += 10;302eth1.bytes_in += 20;303MockFastUnorderedElapsedCounterSource::current_ticks += 2 * NANOSECS_PER_SEC;304305JfrNetworkUtilization::send_events();306ASSERT_EQ(2u, MockEventNetworkUtilization::committed.size());307const MockEventNetworkUtilization& eth0_event = MockEventNetworkUtilization::get_committed("eth0");308const MockEventNetworkUtilization& eth1_event = MockEventNetworkUtilization::get_committed("eth1");309310EXPECT_EQ(40, eth0_event.readRate);311EXPECT_EQ(0, eth0_event.writeRate);312EXPECT_STREQ("eth0", eth0_event.iface.c_str());313314EXPECT_EQ(80, eth1_event.readRate);315EXPECT_EQ(0, eth1_event.writeRate);316EXPECT_STREQ("eth1", eth1_event.iface.c_str());317318MockJfrOSInterface::remove_interface(eth0);319MockEventNetworkUtilization::committed.clear();320321eth1.bytes_in += 10;322MockFastUnorderedElapsedCounterSource::current_ticks += 2 * NANOSECS_PER_SEC;323JfrNetworkUtilization::send_events();324ASSERT_EQ(1u, MockEventNetworkUtilization::committed.size());325const MockEventNetworkUtilization& eth1_event_v2 = MockEventNetworkUtilization::get_committed("eth1");326327EXPECT_EQ(40, eth1_event_v2.readRate);328EXPECT_EQ(0, eth1_event_v2.writeRate);329EXPECT_STREQ("eth1", eth1_event_v2.iface.c_str());330}331332TEST_VM_F(JfrTestNetworkUtilization, InterfaceReset) {333MockNetworkInterface& eth0 = MockJfrOSInterface::add_interface("eth0", ++id);334JfrNetworkUtilization::send_events();335ASSERT_EQ(0u, MockEventNetworkUtilization::committed.size());336337eth0.bytes_in += 10;338MockFastUnorderedElapsedCounterSource::current_ticks += 2 * NANOSECS_PER_SEC;339340JfrNetworkUtilization::send_events();341ASSERT_EQ(1u, MockEventNetworkUtilization::committed.size());342const MockEventNetworkUtilization& event = MockEventNetworkUtilization::committed[0];343EXPECT_EQ(40, event.readRate);344EXPECT_EQ(0, event.writeRate);345EXPECT_STREQ("eth0", event.iface.c_str());346347eth0.bytes_in = 0;348MockFastUnorderedElapsedCounterSource::current_ticks += 2 * NANOSECS_PER_SEC;349MockEventNetworkUtilization::committed.clear();350351JfrNetworkUtilization::send_events();352ASSERT_EQ(0u, MockEventNetworkUtilization::committed.size());353354eth0.bytes_in = 10;355MockFastUnorderedElapsedCounterSource::current_ticks += 2 * NANOSECS_PER_SEC;356357JfrNetworkUtilization::send_events();358ASSERT_EQ(1u, MockEventNetworkUtilization::committed.size());359const MockEventNetworkUtilization& event_v2 = MockEventNetworkUtilization::committed[0];360EXPECT_EQ(40, event_v2.readRate);361EXPECT_EQ(0, event_v2.writeRate);362EXPECT_STREQ("eth0", event_v2.iface.c_str());363}364365366