test/hotspot/gtest/jfr/test_networkUtilization.cpp
changeset 58863 c16ac7a2eba4
parent 53026 7d4397b43fa3
equal deleted inserted replaced
58861:2c3cc4b01880 58863:c16ac7a2eba4
     1 /*
     1 /*
     2  * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
    49 #include <map>
    49 #include <map>
    50 
    50 
    51 namespace {
    51 namespace {
    52 
    52 
    53   class MockFastUnorderedElapsedCounterSource : public ::FastUnorderedElapsedCounterSource {
    53   class MockFastUnorderedElapsedCounterSource : public ::FastUnorderedElapsedCounterSource {
    54   public:
    54    public:
    55     static jlong current_ticks;
    55     static jlong current_ticks;
    56     static Type now() {
    56     static Type now() {
    57       return current_ticks;
    57       return current_ticks;
    58     }
    58     }
    59     static uint64_t nanoseconds(Type value) {
    59     static uint64_t nanoseconds(Type value) {
    63 
    63 
    64   typedef TimeInstant<CounterRepresentation, MockFastUnorderedElapsedCounterSource> MockJfrTicks;
    64   typedef TimeInstant<CounterRepresentation, MockFastUnorderedElapsedCounterSource> MockJfrTicks;
    65   typedef TimeInterval<CounterRepresentation, MockFastUnorderedElapsedCounterSource> MockJfrTickspan;
    65   typedef TimeInterval<CounterRepresentation, MockFastUnorderedElapsedCounterSource> MockJfrTickspan;
    66 
    66 
    67   class MockJfrCheckpointWriter {
    67   class MockJfrCheckpointWriter {
    68   public:
    68    public:
    69     traceid current;
    69     traceid current;
    70     std::map<traceid, std::string> ids;
    70     std::map<traceid, std::string> ids;
    71 
    71 
    72     const JfrCheckpointContext context() const {
    72     const JfrCheckpointContext context() const {
    73       return JfrCheckpointContext();
    73       return JfrCheckpointContext();
    76       return 0;
    76       return 0;
    77     }
    77     }
    78     void write_key(traceid id) {
    78     void write_key(traceid id) {
    79       current = id;
    79       current = id;
    80     }
    80     }
    81     void write(const char* data) {
    81     void write_type(JfrTypeId id) {}
    82       ids[current] = data;
    82     MockJfrCheckpointWriter() {}
    83     }
    83     void write(const char* data) {}
    84     void set_context(const JfrCheckpointContext ctx) { }
    84     void set_context(const JfrCheckpointContext ctx) { }
    85     void write_count(u4 nof_entries, jlong offset) { }
    85     void write_count(u4 nof_entries) { }
    86   };
    86   };
    87 
    87 
    88   class MockJfrSerializer {
    88   class MockJfrSerializer {
    89   public:
    89    public:
    90     static MockJfrSerializer* current;
    90     static bool register_serializer(JfrTypeId id, bool permit_cache, MockJfrSerializer* serializer) {
    91 
       
    92     static bool register_serializer(JfrTypeId id, bool require_safepoint, bool permit_cache, MockJfrSerializer* serializer) {
       
    93       current = serializer;
       
    94       return true;
    91       return true;
    95     }
    92     }
    96 
    93     virtual void on_rotation() {}
    97     virtual void serialize(MockJfrCheckpointWriter& writer) = 0;
    94     virtual void serialize(MockJfrCheckpointWriter& writer) {}
    98   };
    95   };
    99 
    96 
   100   MockJfrSerializer* MockJfrSerializer::current;
    97   struct MockNetworkInterface {
   101 
    98     std::string name;
   102   class MockEventNetworkUtilization : public ::EventNetworkUtilization
    99     uint64_t bytes_in;
   103   {
   100     uint64_t bytes_out;
   104   public:
   101     traceid id;
       
   102     MockNetworkInterface(std::string name, uint64_t bytes_in, uint64_t bytes_out, traceid id) :
       
   103       name(name), bytes_in(bytes_in), bytes_out(bytes_out), id(id) {}
       
   104 
       
   105     bool operator==(const MockNetworkInterface& rhs) const {
       
   106       return name == rhs.name;
       
   107     }
       
   108   };
       
   109 
       
   110   class NetworkInterface : public ::NetworkInterface {
       
   111    public:
       
   112     NetworkInterface(const char* name, uint64_t bytes_in, uint64_t bytes_out, NetworkInterface* next) :
       
   113       ::NetworkInterface(name, bytes_in, bytes_out, next) {}
       
   114     NetworkInterface* next(void) const {
       
   115       return reinterpret_cast<NetworkInterface*>(::NetworkInterface::next());
       
   116     }
       
   117   };
       
   118 
       
   119   class MockJfrOSInterface {
       
   120     static std::list<MockNetworkInterface> _interfaces;
       
   121    public:
       
   122     MockJfrOSInterface() {}
       
   123     static int network_utilization(NetworkInterface** network_interfaces) {
       
   124       *network_interfaces = NULL;
       
   125       for (std::list<MockNetworkInterface>::const_iterator i = _interfaces.begin();
       
   126            i != _interfaces.end();
       
   127            ++i) {
       
   128         NetworkInterface* cur = new NetworkInterface(i->name.c_str(), i->bytes_in, i->bytes_out, *network_interfaces);
       
   129         *network_interfaces = cur;
       
   130       }
       
   131       return OS_OK;
       
   132     }
       
   133     static MockNetworkInterface& add_interface(const std::string& name, traceid id) {
       
   134       MockNetworkInterface iface(name, 0, 0, id);
       
   135       _interfaces.push_front(iface);
       
   136       return _interfaces.front();
       
   137     }
       
   138     static void remove_interface(const MockNetworkInterface& iface) {
       
   139       _interfaces.remove(iface);
       
   140     }
       
   141     static void clear_interfaces() {
       
   142       _interfaces.clear();
       
   143     }
       
   144     static const MockNetworkInterface& get_interface(traceid id) {
       
   145       std::list<MockNetworkInterface>::const_iterator i = _interfaces.begin();
       
   146       for (; i != _interfaces.end(); ++i) {
       
   147         if (i->id == id) {
       
   148           break;
       
   149         }
       
   150       }
       
   151       return *i;
       
   152     }
       
   153   };
       
   154 
       
   155   std::list<MockNetworkInterface> MockJfrOSInterface::_interfaces;
       
   156 
       
   157   class MockEventNetworkUtilization : public ::EventNetworkUtilization {
       
   158    public:
   105     std::string iface;
   159     std::string iface;
   106     s8 readRate;
   160     s8 readRate;
   107     s8 writeRate;
   161     s8 writeRate;
   108     static std::vector<MockEventNetworkUtilization> committed;
   162     static std::vector<MockEventNetworkUtilization> committed;
   109     MockJfrCheckpointWriter writer;
   163     MockJfrCheckpointWriter writer;
   110 
   164 
   111   public:
   165    public:
   112     MockEventNetworkUtilization(EventStartTime timing=TIMED) :
   166     MockEventNetworkUtilization(EventStartTime timing=TIMED) :
   113     ::EventNetworkUtilization(timing) {
   167     ::EventNetworkUtilization(timing) {}
   114     }
       
   115 
   168 
   116     void set_networkInterface(traceid new_value) {
   169     void set_networkInterface(traceid new_value) {
   117       MockJfrSerializer::current->serialize(writer);
   170       const MockNetworkInterface& entry  = MockJfrOSInterface::get_interface(new_value);
   118       iface = writer.ids[new_value];
   171       iface = entry.name;
   119     }
   172     }
   120     void set_readRate(s8 new_value) {
   173     void set_readRate(s8 new_value) {
   121       readRate = new_value;
   174       readRate = new_value;
   122     }
   175     }
   123     void set_writeRate(s8 new_value) {
   176     void set_writeRate(s8 new_value) {
   127     void commit() {
   180     void commit() {
   128       committed.push_back(*this);
   181       committed.push_back(*this);
   129     }
   182     }
   130 
   183 
   131     void set_starttime(const MockJfrTicks& time) {}
   184     void set_starttime(const MockJfrTicks& time) {}
   132 
       
   133     void set_endtime(const MockJfrTicks& time) {}
   185     void set_endtime(const MockJfrTicks& time) {}
   134 
   186 
   135     static const MockEventNetworkUtilization& get_committed(const std::string& name) {
   187     static const MockEventNetworkUtilization& get_committed(const std::string& name) {
   136       static MockEventNetworkUtilization placeholder;
   188       static MockEventNetworkUtilization placeholder;
   137       for (std::vector<MockEventNetworkUtilization>::const_iterator i = committed.begin();
   189       for (std::vector<MockEventNetworkUtilization>::const_iterator i = committed.begin();
   147 
   199 
   148   std::vector<MockEventNetworkUtilization> MockEventNetworkUtilization::committed;
   200   std::vector<MockEventNetworkUtilization> MockEventNetworkUtilization::committed;
   149 
   201 
   150   jlong MockFastUnorderedElapsedCounterSource::current_ticks;
   202   jlong MockFastUnorderedElapsedCounterSource::current_ticks;
   151 
   203 
   152   struct MockNetworkInterface {
       
   153     std::string name;
       
   154     uint64_t bytes_in;
       
   155     uint64_t bytes_out;
       
   156     MockNetworkInterface(std::string name, uint64_t bytes_in, uint64_t bytes_out)
       
   157     : name(name),
       
   158     bytes_in(bytes_in),
       
   159     bytes_out(bytes_out) {
       
   160 
       
   161     }
       
   162     bool operator==(const MockNetworkInterface& rhs) const {
       
   163       return name == rhs.name;
       
   164     }
       
   165   };
       
   166 
       
   167   class NetworkInterface : public ::NetworkInterface {
       
   168   public:
       
   169     NetworkInterface(const char* name, uint64_t bytes_in, uint64_t bytes_out, NetworkInterface* next)
       
   170     : ::NetworkInterface(name, bytes_in, bytes_out, next) {
       
   171     }
       
   172     NetworkInterface* next(void) const {
       
   173       return reinterpret_cast<NetworkInterface*>(::NetworkInterface::next());
       
   174     }
       
   175   };
       
   176 
       
   177   class MockJfrOSInterface {
       
   178     static std::list<MockNetworkInterface> _interfaces;
       
   179 
       
   180   public:
       
   181     MockJfrOSInterface() {
       
   182     }
       
   183     static int network_utilization(NetworkInterface** network_interfaces) {
       
   184       *network_interfaces = NULL;
       
   185       for (std::list<MockNetworkInterface>::const_iterator i = _interfaces.begin();
       
   186            i != _interfaces.end();
       
   187            ++i) {
       
   188         NetworkInterface* cur = new NetworkInterface(i->name.c_str(), i->bytes_in, i->bytes_out, *network_interfaces);
       
   189         *network_interfaces = cur;
       
   190       }
       
   191       return OS_OK;
       
   192     }
       
   193     static MockNetworkInterface& add_interface(const std::string& name) {
       
   194       MockNetworkInterface iface(name, 0, 0);
       
   195       _interfaces.push_back(iface);
       
   196       return _interfaces.back();
       
   197     }
       
   198     static void remove_interface(const MockNetworkInterface& iface) {
       
   199       _interfaces.remove(iface);
       
   200     }
       
   201     static void clear_interfaces() {
       
   202       _interfaces.clear();
       
   203     }
       
   204   };
       
   205 
       
   206   std::list<MockNetworkInterface> MockJfrOSInterface::_interfaces;
       
   207 
       
   208 // Reincluding source files in the anonymous namespace unfortunately seems to
   204 // Reincluding source files in the anonymous namespace unfortunately seems to
   209 // behave strangely with precompiled headers (only when using gcc though)
   205 // behave strangely with precompiled headers (only when using gcc though)
   210 #ifndef DONT_USE_PRECOMPILED_HEADER
   206 #ifndef DONT_USE_PRECOMPILED_HEADER
   211 #define DONT_USE_PRECOMPILED_HEADER
   207 #define DONT_USE_PRECOMPILED_HEADER
   212 #endif
   208 #endif
   246   }
   242   }
   247 };
   243 };
   248 
   244 
   249 TEST_VM_F(JfrTestNetworkUtilization, RequestFunctionBasic) {
   245 TEST_VM_F(JfrTestNetworkUtilization, RequestFunctionBasic) {
   250 
   246 
   251   MockNetworkInterface& eth0 = MockJfrOSInterface::add_interface("eth0");
   247   MockNetworkInterface& eth0 = MockJfrOSInterface::add_interface("eth0", 1);
   252   JfrNetworkUtilization::send_events();
   248   JfrNetworkUtilization::send_events();
   253   ASSERT_EQ(0u, MockEventNetworkUtilization::committed.size());
   249   ASSERT_EQ(0u, MockEventNetworkUtilization::committed.size());
   254 
   250 
   255   eth0.bytes_in += 10;
   251   eth0.bytes_in += 10;
   256   MockFastUnorderedElapsedCounterSource::current_ticks += 2 * NANOSECS_PER_SEC;
   252   MockFastUnorderedElapsedCounterSource::current_ticks += 2 * NANOSECS_PER_SEC;
   263   EXPECT_STREQ("eth0", e.iface.c_str());
   259   EXPECT_STREQ("eth0", e.iface.c_str());
   264 }
   260 }
   265 
   261 
   266 TEST_VM_F(JfrTestNetworkUtilization, RequestFunctionMultiple) {
   262 TEST_VM_F(JfrTestNetworkUtilization, RequestFunctionMultiple) {
   267 
   263 
   268   MockNetworkInterface& eth0 = MockJfrOSInterface::add_interface("eth0");
   264   MockNetworkInterface& eth0 = MockJfrOSInterface::add_interface("eth0", 2);
   269   MockNetworkInterface& eth1 = MockJfrOSInterface::add_interface("eth1");
   265   MockNetworkInterface& eth1 = MockJfrOSInterface::add_interface("eth1", 3);
   270   MockNetworkInterface& ppp0 = MockJfrOSInterface::add_interface("ppp0");
   266   MockNetworkInterface& ppp0 = MockJfrOSInterface::add_interface("ppp0", 4);
   271   JfrNetworkUtilization::send_events();
   267   JfrNetworkUtilization::send_events();
   272   ASSERT_EQ(0u, MockEventNetworkUtilization::committed.size());
   268   ASSERT_EQ(0u, MockEventNetworkUtilization::committed.size());
   273 
   269 
   274   eth0.bytes_in += 10;
   270   eth0.bytes_in += 10;
   275   eth1.bytes_in += 100;
   271   eth1.bytes_in += 100;
   294   EXPECT_EQ(200, ppp0_event.writeRate);
   290   EXPECT_EQ(200, ppp0_event.writeRate);
   295   EXPECT_STREQ("ppp0", ppp0_event.iface.c_str());
   291   EXPECT_STREQ("ppp0", ppp0_event.iface.c_str());
   296 }
   292 }
   297 
   293 
   298 TEST_VM_F(JfrTestNetworkUtilization, InterfaceRemoved) {
   294 TEST_VM_F(JfrTestNetworkUtilization, InterfaceRemoved) {
   299   MockNetworkInterface& eth0 = MockJfrOSInterface::add_interface("eth0");
   295   MockNetworkInterface& eth0 = MockJfrOSInterface::add_interface("eth0", 5);
   300   MockNetworkInterface& eth1 = MockJfrOSInterface::add_interface("eth1");
   296   MockNetworkInterface& eth1 = MockJfrOSInterface::add_interface("eth1", 6);
   301   JfrNetworkUtilization::send_events();
   297   JfrNetworkUtilization::send_events();
   302   ASSERT_EQ(0u, MockEventNetworkUtilization::committed.size());
   298   ASSERT_EQ(0u, MockEventNetworkUtilization::committed.size());
   303 
   299 
   304   eth0.bytes_in += 10;
   300   eth0.bytes_in += 10;
   305   eth1.bytes_in += 20;
   301   eth1.bytes_in += 20;
   331   EXPECT_EQ(0, eth1_event_v2.writeRate);
   327   EXPECT_EQ(0, eth1_event_v2.writeRate);
   332   EXPECT_STREQ("eth1", eth1_event_v2.iface.c_str());
   328   EXPECT_STREQ("eth1", eth1_event_v2.iface.c_str());
   333 }
   329 }
   334 
   330 
   335 TEST_VM_F(JfrTestNetworkUtilization, InterfaceReset) {
   331 TEST_VM_F(JfrTestNetworkUtilization, InterfaceReset) {
   336   MockNetworkInterface& eth0 = MockJfrOSInterface::add_interface("eth0");
   332   MockNetworkInterface& eth0 = MockJfrOSInterface::add_interface("eth0", 7);
   337   JfrNetworkUtilization::send_events();
   333   JfrNetworkUtilization::send_events();
   338   ASSERT_EQ(0u, MockEventNetworkUtilization::committed.size());
   334   ASSERT_EQ(0u, MockEventNetworkUtilization::committed.size());
   339 
   335 
   340   eth0.bytes_in += 10;
   336   eth0.bytes_in += 10;
   341   MockFastUnorderedElapsedCounterSource::current_ticks += 2 * NANOSECS_PER_SEC;
   337   MockFastUnorderedElapsedCounterSource::current_ticks += 2 * NANOSECS_PER_SEC;