From 5b7fec6033806d17b9565af378ca1a8290f9ad22 Mon Sep 17 00:00:00 2001 From: Mark Nellemann Date: Tue, 18 Jul 2023 15:21:52 +0200 Subject: [PATCH] Add some tests of conversion and client-server comm. --- .../biz/nellemann/jnetperf/Statistics.java | 20 +++--- .../biz/nellemann/jnetperf/TcpClient.java | 5 ++ .../biz/nellemann/jnetperf/TcpServer.java | 16 +++-- .../jnetperf/TimeSuffixConverter.java | 3 +- .../biz/nellemann/jnetperf/UdpClient.java | 6 +- .../biz/nellemann/jnetperf/UdpServer.java | 18 +++-- .../jnetperf/UnitSuffixConverter.java | 12 ++-- .../nellemann/jnetperf/ApplicationTest.groovy | 11 --- .../jnetperf/TcpClientServerTest.groovy | 45 ++++++++++++ .../jnetperf/TimeSuffixConverterTest.groovy | 38 ++++++++++ .../jnetperf/UdpClientServerTest.groovy | 45 ++++++++++++ .../jnetperf/UnitSuffixConverterTest.groovy | 71 +++++++++++++++++++ 12 files changed, 253 insertions(+), 37 deletions(-) delete mode 100644 src/test/groovy/biz/nellemann/jnetperf/ApplicationTest.groovy create mode 100644 src/test/groovy/biz/nellemann/jnetperf/TcpClientServerTest.groovy create mode 100644 src/test/groovy/biz/nellemann/jnetperf/TimeSuffixConverterTest.groovy create mode 100644 src/test/groovy/biz/nellemann/jnetperf/UdpClientServerTest.groovy create mode 100644 src/test/groovy/biz/nellemann/jnetperf/UnitSuffixConverterTest.groovy diff --git a/src/main/java/biz/nellemann/jnetperf/Statistics.java b/src/main/java/biz/nellemann/jnetperf/Statistics.java index d5629bd..7a2c0b2 100644 --- a/src/main/java/biz/nellemann/jnetperf/Statistics.java +++ b/src/main/java/biz/nellemann/jnetperf/Statistics.java @@ -25,12 +25,13 @@ public class Statistics { private final int MAX_TICKS_AVG = 300; private final int LOG_AVG_MODULO = 30; private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.systemDefault()); - private long packetsTransferred, packetsTransferredTotal = 0; + private long packetsTransferred; + private long packetsTransferredTotal = 0; private long bytesTransferred, bytesTransferredTotal = 0; private long bytesPerSec; private long packetsPerSec; private long packetsUnacked = 0; - private int tickItererations = 0; + private int tickIterations = 0; private int tickTotal = 0; private final long[] bytesPerSecAvgTmp = new long[MAX_TICKS_AVG]; @@ -52,8 +53,8 @@ public class Statistics { // Because we do this every second ... bytesPerSec = bytesTransferred; packetsPerSec = packetsTransferred; - bytesPerSecAvgTmp[tickItererations] = bytesTransferred; - packetsPerSecAvgTmp[tickItererations] = packetsTransferred; + bytesPerSecAvgTmp[tickIterations] = bytesTransferred; + packetsPerSecAvgTmp[tickIterations] = packetsTransferred; timestamp1 = timestamp2; printStatus(); @@ -61,11 +62,11 @@ public class Statistics { bytesTransferred = 0; packetsTransferred = 0; - if(++tickItererations >= MAX_TICKS_AVG) { - tickItererations = 0; + if(++tickIterations >= MAX_TICKS_AVG) { + tickIterations = 0; } - if(tickItererations % LOG_AVG_MODULO == 0) { + if(tickIterations % LOG_AVG_MODULO == 0) { printAverage(); } tickTotal++; @@ -78,7 +79,6 @@ public class Statistics { public void printStatus() { System.out.printf("%-19s - Status: %10d pkt/s %14d B/s %12d KB/s %8d MB/s\n", formatter.format(Instant.now()), packetsPerSec, bytesPerSec, bytesPerSec/1_000, bytesPerSec/1_000_000); - } @@ -122,6 +122,9 @@ public class Statistics { return packetsTransferredTotal; } + public long getBytesTransferredTotal() { + return bytesTransferredTotal; + } public int getRuntime() { return tickTotal; @@ -157,5 +160,4 @@ public class Statistics { return avg; } - } diff --git a/src/main/java/biz/nellemann/jnetperf/TcpClient.java b/src/main/java/biz/nellemann/jnetperf/TcpClient.java index 5fbd797..917f97a 100644 --- a/src/main/java/biz/nellemann/jnetperf/TcpClient.java +++ b/src/main/java/biz/nellemann/jnetperf/TcpClient.java @@ -122,4 +122,9 @@ public class TcpClient { statistics.printSummary(); } + + public Statistics getStatistics() { + return statistics; + } + } diff --git a/src/main/java/biz/nellemann/jnetperf/TcpServer.java b/src/main/java/biz/nellemann/jnetperf/TcpServer.java index 40d328c..c3f323b 100644 --- a/src/main/java/biz/nellemann/jnetperf/TcpServer.java +++ b/src/main/java/biz/nellemann/jnetperf/TcpServer.java @@ -17,6 +17,8 @@ public class TcpServer extends Thread { private DataInputStream in; private DataOutputStream out; private byte[] inBuffer; + private boolean runThread = true; + private boolean runSession = true; public TcpServer(int port) throws IOException { @@ -28,7 +30,7 @@ public class TcpServer extends Thread { public void run() { try { - while (true) { + while (runThread) { socket = new ServerSocket(port); socket.setSoTimeout(0); // Wait indefinitely inBuffer = new byte[Payload.DEFAULT_LENGTH]; @@ -45,8 +47,8 @@ public class TcpServer extends Thread { public void session() throws IOException { Statistics statistics = new Statistics(); - boolean running = true; boolean ackEnd = false; + runSession = true; Socket server = socket.accept(); InetAddress address = socket.getInetAddress(); @@ -54,7 +56,7 @@ public class TcpServer extends Thread { in = new DataInputStream(server.getInputStream()); out = new DataOutputStream(server.getOutputStream()); - while (running) { + while (runSession) { Payload payload = receive(); statistics.transferPacket(); @@ -78,7 +80,7 @@ public class TcpServer extends Thread { statistics.tick(); if(ackEnd) { - running = false; + runSession = false; statistics.printAverage(); statistics.printSummary(); } @@ -97,4 +99,10 @@ public class TcpServer extends Thread { return new Payload(inBuffer); } + + public void finish() { + runThread = false; + runSession = false; + } + } diff --git a/src/main/java/biz/nellemann/jnetperf/TimeSuffixConverter.java b/src/main/java/biz/nellemann/jnetperf/TimeSuffixConverter.java index d518d04..33f5c62 100644 --- a/src/main/java/biz/nellemann/jnetperf/TimeSuffixConverter.java +++ b/src/main/java/biz/nellemann/jnetperf/TimeSuffixConverter.java @@ -29,8 +29,7 @@ public class TimeSuffixConverter implements CommandLine.ITypeConverter seconds = number * 60 * 60; break; default: - System.err.println("Unknown suffix: " + suffix); - seconds = number; + throw new IllegalArgumentException("Unknown suffix: " + suffix); } } else { seconds = number; diff --git a/src/main/java/biz/nellemann/jnetperf/UdpClient.java b/src/main/java/biz/nellemann/jnetperf/UdpClient.java index 08ee081..72bf203 100644 --- a/src/main/java/biz/nellemann/jnetperf/UdpClient.java +++ b/src/main/java/biz/nellemann/jnetperf/UdpClient.java @@ -118,7 +118,6 @@ public class UdpClient { // Send end - //Thread.sleep(100); payload = new Payload(PayloadType.END.getValue(), length, sequence++, packets); send(payload); payload = receive(); @@ -134,4 +133,9 @@ public class UdpClient { statistics.printSummary(); } + + public Statistics getStatistics() { + return statistics; + } + } diff --git a/src/main/java/biz/nellemann/jnetperf/UdpServer.java b/src/main/java/biz/nellemann/jnetperf/UdpServer.java index 4febd26..5826676 100644 --- a/src/main/java/biz/nellemann/jnetperf/UdpServer.java +++ b/src/main/java/biz/nellemann/jnetperf/UdpServer.java @@ -32,6 +32,9 @@ public class UdpServer extends Thread { private DatagramSocket socket; private byte[] inBuffer; + private boolean runThread = true; + private boolean runSession = true; + public UdpServer(int port) { log.info("UdpServer()"); @@ -41,7 +44,7 @@ public class UdpServer extends Thread { public void run() { try { - while (true) { + while (runThread) { inBuffer = new byte[Payload.DEFAULT_LENGTH]; socket = new DatagramSocket(port); session(); @@ -57,10 +60,10 @@ public class UdpServer extends Thread { public void session() throws IOException { Statistics statistics = new Statistics(); - boolean running = true; boolean ackEnd = false; + runSession = true; - while (running) { + while (runSession) { DatagramPacket packet = new DatagramPacket(inBuffer, inBuffer.length); socket.receive(packet); @@ -91,7 +94,7 @@ public class UdpServer extends Thread { statistics.tick(); if(ackEnd) { - running = false; + runSession = false; statistics.printAverage(); statistics.printSummary(); } @@ -101,4 +104,11 @@ public class UdpServer extends Thread { } + + public void finish() { + runThread = false; + runSession = false; + } + + } diff --git a/src/main/java/biz/nellemann/jnetperf/UnitSuffixConverter.java b/src/main/java/biz/nellemann/jnetperf/UnitSuffixConverter.java index f117433..127e9f4 100644 --- a/src/main/java/biz/nellemann/jnetperf/UnitSuffixConverter.java +++ b/src/main/java/biz/nellemann/jnetperf/UnitSuffixConverter.java @@ -6,16 +6,17 @@ import java.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; -public class UnitSuffixConverter implements CommandLine.ITypeConverter { +public class UnitSuffixConverter implements CommandLine.ITypeConverter { final private Pattern pattern = Pattern.compile("(\\d+)([kmg])?b?", Pattern.CASE_INSENSITIVE); - public Integer convert(String value) { - int bytes = 0; + public Long convert(String value) { + + long bytes = 0L; Matcher matcher = pattern.matcher(value); if (matcher.find()) { - int number = Integer.parseInt(matcher.group(1)); + long number = Long.parseLong(matcher.group(1)); if(matcher.group(2) != null) { // We got the kilo, mega og giga suffix String suffix = matcher.group(2); switch (suffix.toLowerCase(Locale.ROOT)) { @@ -29,8 +30,7 @@ public class UnitSuffixConverter implements CommandLine.ITypeConverter bytes = number * 1024 * 1024 * 1024; break; default: - System.err.println("Unknown suffix: " + suffix); - bytes = number; + throw new IllegalArgumentException("Unknown suffix: " + suffix); } } else { bytes = number; diff --git a/src/test/groovy/biz/nellemann/jnetperf/ApplicationTest.groovy b/src/test/groovy/biz/nellemann/jnetperf/ApplicationTest.groovy deleted file mode 100644 index 7b74a28..0000000 --- a/src/test/groovy/biz/nellemann/jnetperf/ApplicationTest.groovy +++ /dev/null @@ -1,11 +0,0 @@ -/* - * This Spock specification was generated by the Gradle 'init' task. - */ -package biz.nellemann.jnetperf - -import spock.lang.Specification - -class ApplicationTest extends Specification { - - -} diff --git a/src/test/groovy/biz/nellemann/jnetperf/TcpClientServerTest.groovy b/src/test/groovy/biz/nellemann/jnetperf/TcpClientServerTest.groovy new file mode 100644 index 0000000..841acd4 --- /dev/null +++ b/src/test/groovy/biz/nellemann/jnetperf/TcpClientServerTest.groovy @@ -0,0 +1,45 @@ +package biz.nellemann.jnetperf + +import spock.lang.Shared +import spock.lang.Specification + +class TcpClientServerTest extends Specification { + + static final int port = 9876; + + @Shared + TcpServer tcpServer = new TcpServer(port) + + // run before every feature method + def setup() { + tcpServer.start(); + + } + + // run after every feature method + def cleanup() { + tcpServer.finish() + } + + // run before the first feature method + def setupSpec() { + } + + // run after the last feature method + def cleanupSpec() { + } + + + def "test client to server communication"() { + setup: + TcpClient client = new TcpClient("localhost", port, 512, 100, 60) + + when: + client.start() + + then: + client.getStatistics().getPacketsTransferredTotal() == 102 // packets + handshake + end + client.getStatistics().getBytesTransferredTotal() == 52224 + } + +} diff --git a/src/test/groovy/biz/nellemann/jnetperf/TimeSuffixConverterTest.groovy b/src/test/groovy/biz/nellemann/jnetperf/TimeSuffixConverterTest.groovy new file mode 100644 index 0000000..6b4ba64 --- /dev/null +++ b/src/test/groovy/biz/nellemann/jnetperf/TimeSuffixConverterTest.groovy @@ -0,0 +1,38 @@ +package biz.nellemann.jnetperf + +import spock.lang.Shared +import spock.lang.Specification + +class TimeSuffixConverterTest extends Specification { + + @Shared + TimeSuffixConverter timeSuffixConverter = new TimeSuffixConverter(); + + + def "test second to seconds"() { + when: + int seconds = timeSuffixConverter.convert("12s") + + then: + seconds == 12; + } + + + def "test minute to seconds"() { + when: + int seconds = timeSuffixConverter.convert("120m") + + then: + seconds == 7200; + } + + + def "test hour to seconds"() { + when: + int seconds = timeSuffixConverter.convert("48h") + + then: + seconds == 172800; + } + +} diff --git a/src/test/groovy/biz/nellemann/jnetperf/UdpClientServerTest.groovy b/src/test/groovy/biz/nellemann/jnetperf/UdpClientServerTest.groovy new file mode 100644 index 0000000..9764199 --- /dev/null +++ b/src/test/groovy/biz/nellemann/jnetperf/UdpClientServerTest.groovy @@ -0,0 +1,45 @@ +package biz.nellemann.jnetperf + +import spock.lang.Shared +import spock.lang.Specification + +class UdpClientServerTest extends Specification { + + static final int port = 9876; + + @Shared + UdpServer udpServer = new UdpServer(port) + + // run before every feature method + def setup() { + udpServer.start(); + + } + + // run after every feature method + def cleanup() { + udpServer.finish() + } + + // run before the first feature method + def setupSpec() { + } + + // run after the last feature method + def cleanupSpec() { + } + + + def "test client to server communication"() { + setup: + UdpClient client = new UdpClient("localhost", port, 512, 100, 60) + + when: + client.start() + + then: + client.getStatistics().getPacketsTransferredTotal() == 102 // packets + handshake + end + client.getStatistics().getBytesTransferredTotal() == 53144 // TODO: Why is this larger than the TCP test ? + } + +} diff --git a/src/test/groovy/biz/nellemann/jnetperf/UnitSuffixConverterTest.groovy b/src/test/groovy/biz/nellemann/jnetperf/UnitSuffixConverterTest.groovy new file mode 100644 index 0000000..91921ce --- /dev/null +++ b/src/test/groovy/biz/nellemann/jnetperf/UnitSuffixConverterTest.groovy @@ -0,0 +1,71 @@ +package biz.nellemann.jnetperf + +import spock.lang.Shared +import spock.lang.Specification + +class UnitSuffixConverterTest extends Specification { + + @Shared + UnitSuffixConverter unitSuffixConverter = new UnitSuffixConverter(); + + + def "test byte (b) to bytes"() { + when: + long bytes = unitSuffixConverter.convert("16b") + + then: + bytes == 16; + } + + + def "test kilo (k) to bytes"() { + when: + long bytes = unitSuffixConverter.convert("2048k") + + then: + bytes == 2097152; + } + + def "test kilo (kb) to bytes"() { + when: + long bytes = unitSuffixConverter.convert("2048kb") + + then: + bytes == 2097152; + } + + def "test mega (m) to bytes"() { + when: + long bytes = unitSuffixConverter.convert("2m") + + then: + bytes == 2097152; + } + + def "test mega (mb) to bytes"() { + when: + long bytes = unitSuffixConverter.convert("2mb") + + then: + bytes == 2097152; + } + + + def "test giga (g) to bytes"() { + when: + long bytes = unitSuffixConverter.convert("1g") + + then: + bytes == 1073741824; + } + + + def "test giga (gb) to bytes"() { + when: + long bytes = unitSuffixConverter.convert("1gb") + + then: + bytes == 1073741824; + } + +}