test/hotspot/gtest/jfr/test_networkUtilization.cpp
branchJEP-349-branch
changeset 58154 060d9d139109
parent 58076 ca625d28c580
equal deleted inserted replaced
58101:84b0544833c4 58154:060d9d139109
    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();
    78     void write_key(traceid id) {
    78     void write_key(traceid id) {
    79       current = id;
    79       current = id;
    80     }
    80     }
    81     void write_type(JfrTypeId id) {}
    81     void write_type(JfrTypeId id) {}
    82     MockJfrCheckpointWriter() {}
    82     MockJfrCheckpointWriter() {}
    83     MockJfrCheckpointWriter(bool dummy1, bool dummy2, void* dummy3) {}
    83     void write(const char* data) {}
    84     void write(const char* data) {
       
    85       ids[current] = data;
       
    86     }
       
    87     void set_context(const JfrCheckpointContext ctx) { }
    84     void set_context(const JfrCheckpointContext ctx) { }
    88     void write_count(u4 nof_entries, jlong offset) { }
    85     void write_count(u4 nof_entries) { }
    89   };
    86   };
    90 
    87 
    91   class MockJfrSerializer {
    88   class MockJfrSerializer {
    92   public:
    89    public:
    93     static MockJfrSerializer* current;
       
    94 
       
    95     static bool register_serializer(JfrTypeId id, bool permit_cache, MockJfrSerializer* serializer) {
    90     static bool register_serializer(JfrTypeId id, bool permit_cache, MockJfrSerializer* serializer) {
    96       current = serializer;
       
    97       return true;
    91       return true;
    98     }
    92     }
    99 
    93     virtual void on_rotation() {}
   100     virtual void serialize(MockJfrCheckpointWriter& writer) {}
    94     virtual void serialize(MockJfrCheckpointWriter& writer) {}
   101   };
    95   };
   102 
    96 
   103   MockJfrSerializer* MockJfrSerializer::current;
    97   struct MockNetworkInterface {
   104 
    98     std::string name;
   105   class MockEventNetworkUtilization : public ::EventNetworkUtilization
    99     uint64_t bytes_in;
   106   {
   100     uint64_t bytes_out;
   107   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:
   108     std::string iface;
   159     std::string iface;
   109     s8 readRate;
   160     s8 readRate;
   110     s8 writeRate;
   161     s8 writeRate;
   111     static std::vector<MockEventNetworkUtilization> committed;
   162     static std::vector<MockEventNetworkUtilization> committed;
   112     MockJfrCheckpointWriter writer;
   163     MockJfrCheckpointWriter writer;
   113 
   164 
   114   public:
   165    public:
   115     MockEventNetworkUtilization(EventStartTime timing=TIMED) :
   166     MockEventNetworkUtilization(EventStartTime timing=TIMED) :
   116     ::EventNetworkUtilization(timing) {
   167     ::EventNetworkUtilization(timing) {}
   117     }
       
   118 
   168 
   119     void set_networkInterface(traceid new_value) {
   169     void set_networkInterface(traceid new_value) {
   120       MockJfrSerializer::current->serialize(writer);
   170       const MockNetworkInterface& entry  = MockJfrOSInterface::get_interface(new_value);
   121       iface = writer.ids[new_value];
   171       iface = entry.name;
   122     }
   172     }
   123     void set_readRate(s8 new_value) {
   173     void set_readRate(s8 new_value) {
   124       readRate = new_value;
   174       readRate = new_value;
   125     }
   175     }
   126     void set_writeRate(s8 new_value) {
   176     void set_writeRate(s8 new_value) {
   130     void commit() {
   180     void commit() {
   131       committed.push_back(*this);
   181       committed.push_back(*this);
   132     }
   182     }
   133 
   183 
   134     void set_starttime(const MockJfrTicks& time) {}
   184     void set_starttime(const MockJfrTicks& time) {}
   135 
       
   136     void set_endtime(const MockJfrTicks& time) {}
   185     void set_endtime(const MockJfrTicks& time) {}
   137 
   186 
   138     static const MockEventNetworkUtilization& get_committed(const std::string& name) {
   187     static const MockEventNetworkUtilization& get_committed(const std::string& name) {
   139       static MockEventNetworkUtilization placeholder;
   188       static MockEventNetworkUtilization placeholder;
   140       for (std::vector<MockEventNetworkUtilization>::const_iterator i = committed.begin();
   189       for (std::vector<MockEventNetworkUtilization>::const_iterator i = committed.begin();
   150 
   199 
   151   std::vector<MockEventNetworkUtilization> MockEventNetworkUtilization::committed;
   200   std::vector<MockEventNetworkUtilization> MockEventNetworkUtilization::committed;
   152 
   201 
   153   jlong MockFastUnorderedElapsedCounterSource::current_ticks;
   202   jlong MockFastUnorderedElapsedCounterSource::current_ticks;
   154 
   203 
   155   struct MockNetworkInterface {
       
   156     std::string name;
       
   157     uint64_t bytes_in;
       
   158     uint64_t bytes_out;
       
   159     MockNetworkInterface(std::string name, uint64_t bytes_in, uint64_t bytes_out)
       
   160     : name(name),
       
   161     bytes_in(bytes_in),
       
   162     bytes_out(bytes_out) {
       
   163 
       
   164     }
       
   165     bool operator==(const MockNetworkInterface& rhs) const {
       
   166       return name == rhs.name;
       
   167     }
       
   168   };
       
   169 
       
   170   class NetworkInterface : public ::NetworkInterface {
       
   171   public:
       
   172     NetworkInterface(const char* name, uint64_t bytes_in, uint64_t bytes_out, NetworkInterface* next)
       
   173     : ::NetworkInterface(name, bytes_in, bytes_out, next) {
       
   174     }
       
   175     NetworkInterface* next(void) const {
       
   176       return reinterpret_cast<NetworkInterface*>(::NetworkInterface::next());
       
   177     }
       
   178   };
       
   179 
       
   180   class MockJfrOSInterface {
       
   181     static std::list<MockNetworkInterface> _interfaces;
       
   182 
       
   183   public:
       
   184     MockJfrOSInterface() {
       
   185     }
       
   186     static int network_utilization(NetworkInterface** network_interfaces) {
       
   187       *network_interfaces = NULL;
       
   188       for (std::list<MockNetworkInterface>::const_iterator i = _interfaces.begin();
       
   189            i != _interfaces.end();
       
   190            ++i) {
       
   191         NetworkInterface* cur = new NetworkInterface(i->name.c_str(), i->bytes_in, i->bytes_out, *network_interfaces);
       
   192         *network_interfaces = cur;
       
   193       }
       
   194       return OS_OK;
       
   195     }
       
   196     static MockNetworkInterface& add_interface(const std::string& name) {
       
   197       MockNetworkInterface iface(name, 0, 0);
       
   198       _interfaces.push_back(iface);
       
   199       return _interfaces.back();
       
   200     }
       
   201     static void remove_interface(const MockNetworkInterface& iface) {
       
   202       _interfaces.remove(iface);
       
   203     }
       
   204     static void clear_interfaces() {
       
   205       _interfaces.clear();
       
   206     }
       
   207   };
       
   208 
       
   209   std::list<MockNetworkInterface> MockJfrOSInterface::_interfaces;
       
   210 
       
   211 // Reincluding source files in the anonymous namespace unfortunately seems to
   204 // Reincluding source files in the anonymous namespace unfortunately seems to
   212 // behave strangely with precompiled headers (only when using gcc though)
   205 // behave strangely with precompiled headers (only when using gcc though)
   213 #ifndef DONT_USE_PRECOMPILED_HEADER
   206 #ifndef DONT_USE_PRECOMPILED_HEADER
   214 #define DONT_USE_PRECOMPILED_HEADER
   207 #define DONT_USE_PRECOMPILED_HEADER
   215 #endif
   208 #endif
   249   }
   242   }
   250 };
   243 };
   251 
   244 
   252 TEST_VM_F(JfrTestNetworkUtilization, RequestFunctionBasic) {
   245 TEST_VM_F(JfrTestNetworkUtilization, RequestFunctionBasic) {
   253 
   246 
   254   MockNetworkInterface& eth0 = MockJfrOSInterface::add_interface("eth0");
   247   MockNetworkInterface& eth0 = MockJfrOSInterface::add_interface("eth0", 1);
   255   JfrNetworkUtilization::send_events();
   248   JfrNetworkUtilization::send_events();
   256   ASSERT_EQ(0u, MockEventNetworkUtilization::committed.size());
   249   ASSERT_EQ(0u, MockEventNetworkUtilization::committed.size());
   257 
   250 
   258   eth0.bytes_in += 10;
   251   eth0.bytes_in += 10;
   259   MockFastUnorderedElapsedCounterSource::current_ticks += 2 * NANOSECS_PER_SEC;
   252   MockFastUnorderedElapsedCounterSource::current_ticks += 2 * NANOSECS_PER_SEC;
   266   EXPECT_STREQ("eth0", e.iface.c_str());
   259   EXPECT_STREQ("eth0", e.iface.c_str());
   267 }
   260 }
   268 
   261 
   269 TEST_VM_F(JfrTestNetworkUtilization, RequestFunctionMultiple) {
   262 TEST_VM_F(JfrTestNetworkUtilization, RequestFunctionMultiple) {
   270 
   263 
   271   MockNetworkInterface& eth0 = MockJfrOSInterface::add_interface("eth0");
   264   MockNetworkInterface& eth0 = MockJfrOSInterface::add_interface("eth0", 2);
   272   MockNetworkInterface& eth1 = MockJfrOSInterface::add_interface("eth1");
   265   MockNetworkInterface& eth1 = MockJfrOSInterface::add_interface("eth1", 3);
   273   MockNetworkInterface& ppp0 = MockJfrOSInterface::add_interface("ppp0");
   266   MockNetworkInterface& ppp0 = MockJfrOSInterface::add_interface("ppp0", 4);
   274   JfrNetworkUtilization::send_events();
   267   JfrNetworkUtilization::send_events();
   275   ASSERT_EQ(0u, MockEventNetworkUtilization::committed.size());
   268   ASSERT_EQ(0u, MockEventNetworkUtilization::committed.size());
   276 
   269 
   277   eth0.bytes_in += 10;
   270   eth0.bytes_in += 10;
   278   eth1.bytes_in += 100;
   271   eth1.bytes_in += 100;
   297   EXPECT_EQ(200, ppp0_event.writeRate);
   290   EXPECT_EQ(200, ppp0_event.writeRate);
   298   EXPECT_STREQ("ppp0", ppp0_event.iface.c_str());
   291   EXPECT_STREQ("ppp0", ppp0_event.iface.c_str());
   299 }
   292 }
   300 
   293 
   301 TEST_VM_F(JfrTestNetworkUtilization, InterfaceRemoved) {
   294 TEST_VM_F(JfrTestNetworkUtilization, InterfaceRemoved) {
   302   MockNetworkInterface& eth0 = MockJfrOSInterface::add_interface("eth0");
   295   MockNetworkInterface& eth0 = MockJfrOSInterface::add_interface("eth0", 5);
   303   MockNetworkInterface& eth1 = MockJfrOSInterface::add_interface("eth1");
   296   MockNetworkInterface& eth1 = MockJfrOSInterface::add_interface("eth1", 6);
   304   JfrNetworkUtilization::send_events();
   297   JfrNetworkUtilization::send_events();
   305   ASSERT_EQ(0u, MockEventNetworkUtilization::committed.size());
   298   ASSERT_EQ(0u, MockEventNetworkUtilization::committed.size());
   306 
   299 
   307   eth0.bytes_in += 10;
   300   eth0.bytes_in += 10;
   308   eth1.bytes_in += 20;
   301   eth1.bytes_in += 20;
   334   EXPECT_EQ(0, eth1_event_v2.writeRate);
   327   EXPECT_EQ(0, eth1_event_v2.writeRate);
   335   EXPECT_STREQ("eth1", eth1_event_v2.iface.c_str());
   328   EXPECT_STREQ("eth1", eth1_event_v2.iface.c_str());
   336 }
   329 }
   337 
   330 
   338 TEST_VM_F(JfrTestNetworkUtilization, InterfaceReset) {
   331 TEST_VM_F(JfrTestNetworkUtilization, InterfaceReset) {
   339   MockNetworkInterface& eth0 = MockJfrOSInterface::add_interface("eth0");
   332   MockNetworkInterface& eth0 = MockJfrOSInterface::add_interface("eth0", 7);
   340   JfrNetworkUtilization::send_events();
   333   JfrNetworkUtilization::send_events();
   341   ASSERT_EQ(0u, MockEventNetworkUtilization::committed.size());
   334   ASSERT_EQ(0u, MockEventNetworkUtilization::committed.size());
   342 
   335 
   343   eth0.bytes_in += 10;
   336   eth0.bytes_in += 10;
   344   MockFastUnorderedElapsedCounterSource::current_ticks += 2 * NANOSECS_PER_SEC;
   337   MockFastUnorderedElapsedCounterSource::current_ticks += 2 * NANOSECS_PER_SEC;