23 * questions. |
23 * questions. |
24 */ |
24 */ |
25 |
25 |
26 package jdk.jfr.event.runtime; |
26 package jdk.jfr.event.runtime; |
27 |
27 |
|
28 import java.net.DatagramPacket; |
|
29 import java.net.DatagramSocket; |
|
30 import java.net.InetAddress; |
|
31 import java.util.HashSet; |
|
32 import java.util.List; |
|
33 import java.util.Set; |
|
34 |
28 import jdk.jfr.Recording; |
35 import jdk.jfr.Recording; |
29 import jdk.jfr.consumer.RecordedEvent; |
36 import jdk.jfr.consumer.RecordedEvent; |
30 import jdk.test.lib.Asserts; |
37 import jdk.test.lib.Asserts; |
31 import jdk.test.lib.Platform; |
38 import jdk.test.lib.Platform; |
32 import jdk.test.lib.jfr.EventNames; |
39 import jdk.test.lib.jfr.EventNames; |
33 import jdk.test.lib.jfr.Events; |
40 import jdk.test.lib.jfr.Events; |
34 |
|
35 import java.net.DatagramPacket; |
|
36 import java.net.DatagramSocket; |
|
37 import java.net.InetAddress; |
|
38 import java.time.Duration; |
|
39 import java.time.Instant; |
|
40 import java.util.List; |
|
41 import java.util.Map; |
|
42 |
|
43 import static java.util.stream.Collectors.averagingLong; |
|
44 import static java.util.stream.Collectors.groupingBy; |
|
45 |
41 |
46 /** |
42 /** |
47 * @test |
43 * @test |
48 * @key jfr |
44 * @key jfr |
49 * @requires vm.hasJFR |
45 * @requires vm.hasJFR |
54 public class TestNetworkUtilizationEvent { |
50 public class TestNetworkUtilizationEvent { |
55 |
51 |
56 private static final long packetSendCount = 100; |
52 private static final long packetSendCount = 100; |
57 |
53 |
58 public static void main(String[] args) throws Throwable { |
54 public static void main(String[] args) throws Throwable { |
59 testSimple(); |
|
60 } |
|
61 |
55 |
62 static void testSimple() throws Throwable { |
|
63 |
|
64 Instant start = Instant.now(); |
|
65 Recording recording = new Recording(); |
56 Recording recording = new Recording(); |
66 recording.enable(EventNames.NetworkUtilization); |
57 recording.enable(EventNames.NetworkUtilization).with("period", "endChunk"); |
67 recording.start(); |
58 recording.start(); |
68 |
59 |
69 DatagramSocket socket = new DatagramSocket(); |
60 DatagramSocket socket = new DatagramSocket(); |
70 String msg = "hello!"; |
61 String msg = "hello!"; |
71 byte[] buf = msg.getBytes(); |
62 byte[] buf = msg.getBytes(); |
72 |
63 forceEndChunk(); |
73 // Send a few packets both to the loopback address as well to an external |
64 // Send a few packets both to the loopback address as well to an |
|
65 // external |
74 DatagramPacket packet = new DatagramPacket(buf, buf.length, InetAddress.getLoopbackAddress(), 12345); |
66 DatagramPacket packet = new DatagramPacket(buf, buf.length, InetAddress.getLoopbackAddress(), 12345); |
75 for (int i = 0; i < packetSendCount; ++i) { |
67 for (int i = 0; i < packetSendCount; ++i) { |
76 socket.send(packet); |
68 socket.send(packet); |
77 } |
69 } |
78 packet = new DatagramPacket(buf, buf.length, InetAddress.getByName("10.0.0.0"), 12345); |
70 packet = new DatagramPacket(buf, buf.length, InetAddress.getByName("10.0.0.0"), 12345); |
79 for (int i = 0; i < packetSendCount; ++i) { |
71 for (int i = 0; i < packetSendCount; ++i) { |
80 socket.send(packet); |
72 socket.send(packet); |
81 } |
73 } |
|
74 forceEndChunk(); |
|
75 socket.close(); |
|
76 // Now there should have been traffic on at least two different |
|
77 // interfaces |
|
78 recording.stop(); |
82 |
79 |
83 // Now there should have been traffic on at least two different interfaces |
80 Set<String> networkInterfaces = new HashSet<>(); |
84 recording.stop(); |
|
85 Duration runtime = Duration.between(start, Instant.now()); |
|
86 List<RecordedEvent> events = Events.fromRecording(recording); |
81 List<RecordedEvent> events = Events.fromRecording(recording); |
87 |
82 Events.hasEvents(events); |
88 // Calculate the average write rate for each interface |
83 for (RecordedEvent event : events) { |
89 Map<String, Double> writeRates = events.stream() |
84 System.out.println(event); |
90 .collect(groupingBy(e -> Events.assertField(e, "networkInterface").getValue(), |
85 Events.assertField(event, "writeRate").atLeast(0L).atMost(1000L * Integer.MAX_VALUE); |
91 averagingLong(e -> Events.assertField(e, "writeRate").getValue()))); |
86 Events.assertField(event, "readRate").atLeast(0L).atMost(1000L * Integer.MAX_VALUE); |
92 |
87 Events.assertField(event, "networkInterface").notNull(); |
93 // Our test packets should have generated at least this much traffic per second |
88 if (event.getLong("writeRate") > 0) { |
94 long expectedTraffic = (buf.length * packetSendCount) / Math.max(1, runtime.toSeconds()); |
89 networkInterfaces.add(event.getString("networkInterface")); |
95 |
90 } |
96 // Count the number of interfaces that have seen at least our test traffic |
91 } |
97 long interfacesWithTraffic = writeRates.values().stream() |
|
98 .filter(d -> d >= expectedTraffic) |
|
99 .count(); |
|
100 |
92 |
101 if (Platform.isWindows() || Platform.isSolaris()) { |
93 if (Platform.isWindows() || Platform.isSolaris()) { |
102 // Windows and Solaris do not track statistics for the loopback interface |
94 // Windows and Solaris do not track statistics for the loopback |
103 Asserts.assertGreaterThanOrEqual(writeRates.size(), 1); |
95 // interface |
104 Asserts.assertGreaterThanOrEqual(interfacesWithTraffic, Long.valueOf(1)); |
96 Asserts.assertGreaterThanOrEqual(networkInterfaces.size(), 1); |
105 } else { |
97 } else { |
106 Asserts.assertGreaterThanOrEqual(writeRates.size(), 2); |
98 Asserts.assertGreaterThanOrEqual(networkInterfaces.size(), 2); |
107 Asserts.assertGreaterThanOrEqual(interfacesWithTraffic, Long.valueOf(2)); |
|
108 } |
99 } |
109 } |
100 } |
|
101 |
|
102 private static void forceEndChunk() { |
|
103 try(Recording r = new Recording()) { |
|
104 r.start(); |
|
105 r.stop(); |
|
106 } |
|
107 } |
110 } |
108 } |