From baadf220d261a6c610920d749a2b9c19f864ba96 Mon Sep 17 00:00:00 2001 From: wuyan Date: Sat, 11 Sep 2021 10:07:53 +0800 Subject: [PATCH 20/23] 8202142: jfr/event/io/TestInstrumentation is unstable Summary: : JDK-8202142: jfr/event/io/TestInstrumentation is unstable LLT: jdk/test/jdk/jfr/event/io/TestInstrumentation.java Patch Type: backport Bug url: https://bugs.openjdk.java.net/browse/JDK-8202142 --- jdk/test/jdk/jfr/event/io/IOEvent.java | 9 +- jdk/test/jdk/jfr/event/io/IOHelper.java | 8 +- .../jdk/jfr/event/io/TestDisabledEvents.java | 33 +-- .../jfr/event/io/TestFileChannelEvents.java | 138 +++++------ .../jdk/jfr/event/io/TestFileReadOnly.java | 77 +++--- .../jfr/event/io/TestFileStreamEvents.java | 69 +++--- .../jdk/jfr/event/io/TestInstrumentation.java | 4 +- .../event/io/TestRandomAccessFileEvents.java | 115 ++++----- .../event/io/TestRandomAccessFileThread.java | 222 +++++++++--------- .../jfr/event/io/TestSocketChannelEvents.java | 122 +++++----- .../jdk/jfr/event/io/TestSocketEvents.java | 104 ++++---- 11 files changed, 455 insertions(+), 446 deletions(-) diff --git a/jdk/test/jdk/jfr/event/io/IOEvent.java b/jdk/test/jdk/jfr/event/io/IOEvent.java index e3939fbf8..dcf70ccc3 100644 --- a/jdk/test/jdk/jfr/event/io/IOEvent.java +++ b/jdk/test/jdk/jfr/event/io/IOEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -197,14 +197,11 @@ public class IOEvent { } return canonical_path; } else { - return String.format("%s/%s:%d", - event.getValue("host"), - event.getValue("address"), - event.getValue("port")); + return event.getValue("address") + ":" + event.getValue("port"); } } private static String getAddress(Socket s) { - return s.getInetAddress().toString() + ":" + s.getPort(); + return s.getInetAddress().getHostAddress() + ":" + s.getPort(); } } diff --git a/jdk/test/jdk/jfr/event/io/IOHelper.java b/jdk/test/jdk/jfr/event/io/IOHelper.java index f1f205529..23e61f59a 100644 --- a/jdk/test/jdk/jfr/event/io/IOHelper.java +++ b/jdk/test/jdk/jfr/event/io/IOHelper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,8 @@ package jdk.jfr.event.io; import static jdk.test.lib.Asserts.assertEquals; import static jdk.test.lib.Asserts.assertTrue; +import java.util.Collections; +import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; @@ -41,6 +43,7 @@ import jdk.test.lib.jfr.Events; public class IOHelper { public static void verifyEqualsInOrder(List events, List expectedEvents) throws Throwable { + Collections.sort(events, Comparator.comparing(RecordedEvent::getStartTime)); List actualEvents = getTestEvents(events, expectedEvents); try { assertEquals(actualEvents.size(), expectedEvents.size(), "Wrong number of events."); @@ -48,6 +51,9 @@ public class IOHelper { assertEquals(actualEvents.get(i), expectedEvents.get(i), "Wrong event at pos " + i); } } catch (Throwable t) { + for (RecordedEvent e: events) { + System.out.println(e); + } logEvents(actualEvents, expectedEvents); throw t; } diff --git a/jdk/test/jdk/jfr/event/io/TestDisabledEvents.java b/jdk/test/jdk/jfr/event/io/TestDisabledEvents.java index aad1b217f..d80304cf0 100644 --- a/jdk/test/jdk/jfr/event/io/TestDisabledEvents.java +++ b/jdk/test/jdk/jfr/event/io/TestDisabledEvents.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -57,21 +57,22 @@ public class TestDisabledEvents { public static void main(String[] args) throws Throwable { File tmp = File.createTempFile("TestDisabledEvents", ".tmp", new File(".")); tmp.deleteOnExit(); - Recording recording = new Recording(); - recording.disable(IOEvent.EVENT_FILE_READ); - recording.disable(IOEvent.EVENT_FILE_WRITE); - recording.start(); - - useRandomAccessFile(tmp); - useFileStreams(tmp); - useFileChannel(tmp); - - recording.stop(); - for (RecordedEvent event : Events.fromRecording(recording)) { - final String eventName = event.getEventType().getName(); - System.out.println("Got eventName:" + eventName); - assertNotEquals(eventName, IOEvent.EVENT_FILE_READ, "Got disabled read event"); - assertNotEquals(eventName, IOEvent.EVENT_FILE_WRITE, "Got disabled write event"); + try (Recording recording = new Recording()) { + recording.disable(IOEvent.EVENT_FILE_READ); + recording.disable(IOEvent.EVENT_FILE_WRITE); + recording.start(); + + useRandomAccessFile(tmp); + useFileStreams(tmp); + useFileChannel(tmp); + + recording.stop(); + for (RecordedEvent event : Events.fromRecording(recording)) { + final String eventName = event.getEventType().getName(); + System.out.println("Got eventName:" + eventName); + assertNotEquals(eventName, IOEvent.EVENT_FILE_READ, "Got disabled read event"); + assertNotEquals(eventName, IOEvent.EVENT_FILE_WRITE, "Got disabled write event"); + } } } diff --git a/jdk/test/jdk/jfr/event/io/TestFileChannelEvents.java b/jdk/test/jdk/jfr/event/io/TestFileChannelEvents.java index cb90bc54f..632fcaba3 100644 --- a/jdk/test/jdk/jfr/event/io/TestFileChannelEvents.java +++ b/jdk/test/jdk/jfr/event/io/TestFileChannelEvents.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,74 +50,74 @@ public class TestFileChannelEvents { public static void main(String[] args) throws Throwable { File tmp = File.createTempFile("TestFileChannelEvents", ".tmp", new File(".")); tmp.deleteOnExit(); - Recording recording = new Recording(); - List expectedEvents = new ArrayList<>(); - - try (RandomAccessFile rf = new RandomAccessFile(tmp, "rw"); FileChannel ch = rf.getChannel();) { - recording.enable(IOEvent.EVENT_FILE_FORCE).withThreshold(Duration.ofMillis(0)); - recording.enable(IOEvent.EVENT_FILE_READ).withThreshold(Duration.ofMillis(0)); - recording.enable(IOEvent.EVENT_FILE_WRITE).withThreshold(Duration.ofMillis(0)); - recording.start(); - - ByteBuffer bufA = ByteBuffer.allocateDirect(10); - ByteBuffer bufB = ByteBuffer.allocateDirect(20); - bufA.put("1234567890".getBytes()); - bufB.put("1234567890".getBytes()); - - // test write(ByteBuffer) - bufA.flip(); - long size = ch.write(bufA); - expectedEvents.add(IOEvent.createFileWriteEvent(size, tmp)); - - // test write(ByteBuffer, long) - bufA.flip(); - size = ch.write(bufA, bufA.capacity() / 2); - expectedEvents.add(IOEvent.createFileWriteEvent(size, tmp)); - - // test write(ByteBuffer[]) - bufA.flip(); - bufA.limit(5); - bufB.flip(); - bufB.limit(5); - size = ch.write(new ByteBuffer[] { bufA, bufB }); - expectedEvents.add(IOEvent.createFileWriteEvent(size, tmp)); - - // test force(boolean) - ch.force(true); - expectedEvents.add(IOEvent.createFileForceEvent(tmp)); - - // reset file - ch.position(0); - - // test read(ByteBuffer) - bufA.clear(); - size = ch.read(bufA); - expectedEvents.add(IOEvent.createFileReadEvent(size, tmp)); - - // test read(ByteBuffer, long) - bufA.clear(); - size = ch.read(bufA, bufA.capacity() / 2); - expectedEvents.add(IOEvent.createFileReadEvent(size, tmp)); - - // test read(ByteBuffer[]) - bufA.clear(); - bufA.limit(5); - bufB.clear(); - bufB.limit(5); - size = ch.read(new ByteBuffer[] { bufA, bufB }); - expectedEvents.add(IOEvent.createFileReadEvent(size, tmp)); - - // Read at EOF. Should get size -1 in event. - ch.position(ch.size()); - bufA.clear(); - size = ch.read(bufA); - assertEquals(size, -1L, "Expected size -1 when read at EOF"); - expectedEvents.add(IOEvent.createFileReadEvent(size, tmp)); - - ch.close(); - recording.stop(); - List events = Events.fromRecording(recording); - IOHelper.verifyEqualsInOrder(events, expectedEvents); + try (Recording recording = new Recording()) { + List expectedEvents = new ArrayList<>(); + try (RandomAccessFile rf = new RandomAccessFile(tmp, "rw"); FileChannel ch = rf.getChannel();) { + recording.enable(IOEvent.EVENT_FILE_FORCE).withThreshold(Duration.ofMillis(0)); + recording.enable(IOEvent.EVENT_FILE_READ).withThreshold(Duration.ofMillis(0)); + recording.enable(IOEvent.EVENT_FILE_WRITE).withThreshold(Duration.ofMillis(0)); + recording.start(); + + ByteBuffer bufA = ByteBuffer.allocateDirect(10); + ByteBuffer bufB = ByteBuffer.allocateDirect(20); + bufA.put("1234567890".getBytes()); + bufB.put("1234567890".getBytes()); + + // test write(ByteBuffer) + bufA.flip(); + long size = ch.write(bufA); + expectedEvents.add(IOEvent.createFileWriteEvent(size, tmp)); + + // test write(ByteBuffer, long) + bufA.flip(); + size = ch.write(bufA, bufA.capacity() / 2); + expectedEvents.add(IOEvent.createFileWriteEvent(size, tmp)); + + // test write(ByteBuffer[]) + bufA.flip(); + bufA.limit(5); + bufB.flip(); + bufB.limit(5); + size = ch.write(new ByteBuffer[] { bufA, bufB }); + expectedEvents.add(IOEvent.createFileWriteEvent(size, tmp)); + + // test force(boolean) + ch.force(true); + expectedEvents.add(IOEvent.createFileForceEvent(tmp)); + + // reset file + ch.position(0); + + // test read(ByteBuffer) + bufA.clear(); + size = ch.read(bufA); + expectedEvents.add(IOEvent.createFileReadEvent(size, tmp)); + + // test read(ByteBuffer, long) + bufA.clear(); + size = ch.read(bufA, bufA.capacity() / 2); + expectedEvents.add(IOEvent.createFileReadEvent(size, tmp)); + + // test read(ByteBuffer[]) + bufA.clear(); + bufA.limit(5); + bufB.clear(); + bufB.limit(5); + size = ch.read(new ByteBuffer[] { bufA, bufB }); + expectedEvents.add(IOEvent.createFileReadEvent(size, tmp)); + + // Read at EOF. Should get size -1 in event. + ch.position(ch.size()); + bufA.clear(); + size = ch.read(bufA); + assertEquals(size, -1L, "Expected size -1 when read at EOF"); + expectedEvents.add(IOEvent.createFileReadEvent(size, tmp)); + + ch.close(); + recording.stop(); + List events = Events.fromRecording(recording); + IOHelper.verifyEqualsInOrder(events, expectedEvents); + } } } } diff --git a/jdk/test/jdk/jfr/event/io/TestFileReadOnly.java b/jdk/test/jdk/jfr/event/io/TestFileReadOnly.java index 065ebadc3..b7e20d0ef 100644 --- a/jdk/test/jdk/jfr/event/io/TestFileReadOnly.java +++ b/jdk/test/jdk/jfr/event/io/TestFileReadOnly.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,50 +52,51 @@ public class TestFileReadOnly { public static void main(String[] args) throws Throwable { File tmp = File.createTempFile("TestFileReadOnly", ".tmp", new File(".")); tmp.deleteOnExit(); - Recording recording = new Recording(); - List expectedEvents = new ArrayList<>(); + try(Recording recording = new Recording()) { + List expectedEvents = new ArrayList<>(); - recording.enable(IOEvent.EVENT_FILE_READ).withThreshold(Duration.ofMillis(0)); - recording.enable(IOEvent.EVENT_FILE_WRITE).withThreshold(Duration.ofMillis(0)); - recording.start(); + recording.enable(IOEvent.EVENT_FILE_READ).withThreshold(Duration.ofMillis(0)); + recording.enable(IOEvent.EVENT_FILE_WRITE).withThreshold(Duration.ofMillis(0)); + recording.start(); - final byte[] buf = { 1, 2, 3 }; + final byte[] buf = { 1, 2, 3 }; - // Create the file. - try (RandomAccessFile f = new RandomAccessFile(tmp, "rw")) { - f.write(buf); - expectedEvents.add(IOEvent.createFileWriteEvent(buf.length, tmp)); - } - - // Reopen the file as ReadOnly and try to write to it. - // Should generate an event with bytesWritten = -1. - try (RandomAccessFile f = new RandomAccessFile(tmp, "r")) { - try { + // Create the file. + try (RandomAccessFile f = new RandomAccessFile(tmp, "rw")) { f.write(buf); - fail("No exception for ReadOnly File"); - } catch (IOException e) { - // Expected exception - expectedEvents.add(IOEvent.createFileWriteEvent(-1, tmp)); + expectedEvents.add(IOEvent.createFileWriteEvent(buf.length, tmp)); } - } - // Try to write to read-only FileChannel. - try (RandomAccessFile f = new RandomAccessFile(tmp, "r"); FileChannel ch = f.getChannel()) { - ByteBuffer writeBuf = ByteBuffer.allocateDirect(buf.length); - writeBuf.put(buf); - writeBuf.flip(); - ch.position(0); - try { - ch.write(writeBuf); - fail("No exception for ReadOnly FileChannel"); - } catch (java.nio.channels.NonWritableChannelException e) { - // Expected exception - expectedEvents.add(IOEvent.createFileWriteEvent(-1, tmp)); + // Reopen the file as ReadOnly and try to write to it. + // Should generate an event with bytesWritten = -1. + try (RandomAccessFile f = new RandomAccessFile(tmp, "r")) { + try { + f.write(buf); + fail("No exception for ReadOnly File"); + } catch (IOException e) { + // Expected exception + expectedEvents.add(IOEvent.createFileWriteEvent(-1, tmp)); + } } - } - recording.stop(); - List events = Events.fromRecording(recording); - IOHelper.verifyEqualsInOrder(events, expectedEvents); + // Try to write to read-only FileChannel. + try (RandomAccessFile f = new RandomAccessFile(tmp, "r"); FileChannel ch = f.getChannel()) { + ByteBuffer writeBuf = ByteBuffer.allocateDirect(buf.length); + writeBuf.put(buf); + writeBuf.flip(); + ch.position(0); + try { + ch.write(writeBuf); + fail("No exception for ReadOnly FileChannel"); + } catch (java.nio.channels.NonWritableChannelException e) { + // Expected exception + expectedEvents.add(IOEvent.createFileWriteEvent(-1, tmp)); + } + } + + recording.stop(); + List events = Events.fromRecording(recording); + IOHelper.verifyEqualsInOrder(events, expectedEvents); + } } } diff --git a/jdk/test/jdk/jfr/event/io/TestFileStreamEvents.java b/jdk/test/jdk/jfr/event/io/TestFileStreamEvents.java index 46c7b80f3..0bddf5a6c 100644 --- a/jdk/test/jdk/jfr/event/io/TestFileStreamEvents.java +++ b/jdk/test/jdk/jfr/event/io/TestFileStreamEvents.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,47 +50,48 @@ public class TestFileStreamEvents { public static void main(String[] args) throws Throwable { File tmp = File.createTempFile("TestFileStreamEvents", ".tmp", new File(".")); tmp.deleteOnExit(); - Recording recording = new Recording(); - List expectedEvents = new ArrayList<>(); + try (Recording recording = new Recording()) { + List expectedEvents = new ArrayList<>(); - try(FileOutputStream fos = new FileOutputStream(tmp); FileInputStream fis = new FileInputStream(tmp);) { - recording.enable(IOEvent.EVENT_FILE_READ).withThreshold(Duration.ofMillis(0)); - recording.enable(IOEvent.EVENT_FILE_WRITE).withThreshold(Duration.ofMillis(0)); - recording.start(); + try(FileOutputStream fos = new FileOutputStream(tmp); FileInputStream fis = new FileInputStream(tmp);) { + recording.enable(IOEvent.EVENT_FILE_READ).withThreshold(Duration.ofMillis(0)); + recording.enable(IOEvent.EVENT_FILE_WRITE).withThreshold(Duration.ofMillis(0)); + recording.start(); - int writeByte = 47; - byte[] writeBuf = {11, 12, 13, 14}; + int writeByte = 47; + byte[] writeBuf = {11, 12, 13, 14}; - // Write - fos.write(writeByte); - expectedEvents.add(IOEvent.createFileWriteEvent(1, tmp)); - fos.write(writeBuf); - expectedEvents.add(IOEvent.createFileWriteEvent(writeBuf.length, tmp)); - fos.write(writeBuf, 0, 2); - expectedEvents.add(IOEvent.createFileWriteEvent(2, tmp)); + // Write + fos.write(writeByte); + expectedEvents.add(IOEvent.createFileWriteEvent(1, tmp)); + fos.write(writeBuf); + expectedEvents.add(IOEvent.createFileWriteEvent(writeBuf.length, tmp)); + fos.write(writeBuf, 0, 2); + expectedEvents.add(IOEvent.createFileWriteEvent(2, tmp)); - // Read - int readByte = fis.read(); - assertEquals(readByte, writeByte, "Wrong byte read"); - expectedEvents.add(IOEvent.createFileReadEvent(1, tmp)); + // Read + int readByte = fis.read(); + assertEquals(readByte, writeByte, "Wrong byte read"); + expectedEvents.add(IOEvent.createFileReadEvent(1, tmp)); - byte[] readBuf = new byte[writeBuf.length]; - long size = fis.read(readBuf); - assertEquals(size, (long)writeBuf.length, "Wrong size when reading byte[]"); - expectedEvents.add(IOEvent.createFileReadEvent(size, tmp)); + byte[] readBuf = new byte[writeBuf.length]; + long size = fis.read(readBuf); + assertEquals(size, (long)writeBuf.length, "Wrong size when reading byte[]"); + expectedEvents.add(IOEvent.createFileReadEvent(size, tmp)); - size = fis.read(readBuf, 0, 2); - assertEquals(size, 2L, "Wrong size when reading 2 bytes"); - expectedEvents.add(IOEvent.createFileReadEvent(size, tmp)); + size = fis.read(readBuf, 0, 2); + assertEquals(size, 2L, "Wrong size when reading 2 bytes"); + expectedEvents.add(IOEvent.createFileReadEvent(size, tmp)); - // We are at EOF. Read more and verify we get size -1. - size = fis.read(readBuf); - assertEquals(size, -1L, "Size should be -1 at EOF"); - expectedEvents.add(IOEvent.createFileReadEvent(size, tmp)); + // We are at EOF. Read more and verify we get size -1. + size = fis.read(readBuf); + assertEquals(size, -1L, "Size should be -1 at EOF"); + expectedEvents.add(IOEvent.createFileReadEvent(size, tmp)); - recording.stop(); - List events = Events.fromRecording(recording); - IOHelper.verifyEqualsInOrder(events, expectedEvents); + recording.stop(); + List events = Events.fromRecording(recording); + IOHelper.verifyEqualsInOrder(events, expectedEvents); + } } } } diff --git a/jdk/test/jdk/jfr/event/io/TestInstrumentation.java b/jdk/test/jdk/jfr/event/io/TestInstrumentation.java index d5430e6c6..19fe5a6da 100644 --- a/jdk/test/jdk/jfr/event/io/TestInstrumentation.java +++ b/jdk/test/jdk/jfr/event/io/TestInstrumentation.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -104,11 +104,9 @@ public class TestInstrumentation implements ClassFileTransformer { "java/io/FileOutputStream::write::([B)V", "java/io/FileOutputStream::write::([BII)V", "java/net/SocketInputStream::read::()I", - "java/net/SocketInputStream::read::([B)I", "java/net/SocketInputStream::read::([BII)I", "java/net/SocketInputStream::close::()V", "java/net/SocketOutputStream::write::(I)V", - "java/net/SocketOutputStream::write::([B)V", "java/net/SocketOutputStream::write::([BII)V", "java/net/SocketOutputStream::close::()V", "java/nio/channels/FileChannel::read::([Ljava/nio/ByteBuffer;)J", diff --git a/jdk/test/jdk/jfr/event/io/TestRandomAccessFileEvents.java b/jdk/test/jdk/jfr/event/io/TestRandomAccessFileEvents.java index 959ed4d22..9c28231c5 100644 --- a/jdk/test/jdk/jfr/event/io/TestRandomAccessFileEvents.java +++ b/jdk/test/jdk/jfr/event/io/TestRandomAccessFileEvents.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,62 +49,63 @@ public class TestRandomAccessFileEvents { public static void main(String[] args) throws Throwable { File tmp = File.createTempFile("TestRandomAccessFileEvents", ".tmp", new File(".")); tmp.deleteOnExit(); - Recording recording = new Recording(); - List expectedEvents = new ArrayList<>(); - - recording.enable(IOEvent.EVENT_FILE_WRITE).withThreshold(Duration.ofMillis(0)); - recording.enable(IOEvent.EVENT_FILE_READ).withThreshold(Duration.ofMillis(0)); - recording.start(); - - RandomAccessFile ras = new RandomAccessFile(tmp, "rw"); - int writeInt = 47; - byte[] writeBuffer = {10,11,12,13}; - - // Write an int and a buffer. - ras.write(writeInt); - expectedEvents.add(IOEvent.createFileWriteEvent(1, tmp)); - ras.write(writeBuffer); - expectedEvents.add(IOEvent.createFileWriteEvent(writeBuffer.length, tmp)); - - ras.seek(0); - - // Read int and buffer - int readInt = ras.read(); - assertEquals(readInt, writeInt, "wrong int read"); - expectedEvents.add(IOEvent.createFileReadEvent(1, tmp)); - byte[] readBuffer = new byte [writeBuffer.length]; - int size = ras.read(readBuffer); - verifyBufferEquals(readBuffer, writeBuffer); - expectedEvents.add(IOEvent.createFileReadEvent(readBuffer.length, tmp)); - - // Read beyond EOF - readInt = ras.read(); - assertEquals(-1, readInt, "wrong read after EOF"); - expectedEvents.add(IOEvent.createFileReadEvent(-1, tmp)); - - // Seek to beginning and verify we can read after EOF. - ras.seek(0); - readInt = ras.read(); - assertEquals(readInt, writeInt, "wrong int read after seek(0)"); - expectedEvents.add(IOEvent.createFileReadEvent(1, tmp)); - - // seek beyond EOF and verify we get EOF when reading. - ras.seek(10); - readInt = ras.read(); - assertEquals(-1, readInt, "wrong read after seek beyond EOF"); - expectedEvents.add(IOEvent.createFileReadEvent(-1, tmp)); - - // Read partial buffer. - int partialSize = writeBuffer.length - 2; - ras.seek(ras.length()-partialSize); - size = ras.read(readBuffer); - assertEquals(size, partialSize, "Wrong size partial buffer read"); - expectedEvents.add(IOEvent.createFileReadEvent(size, tmp)); - - ras.close(); - recording.stop(); - List events = Events.fromRecording(recording); - IOHelper.verifyEqualsInOrder(events, expectedEvents); + try (Recording recording = new Recording()) { + List expectedEvents = new ArrayList<>(); + + recording.enable(IOEvent.EVENT_FILE_WRITE).withThreshold(Duration.ofMillis(0)); + recording.enable(IOEvent.EVENT_FILE_READ).withThreshold(Duration.ofMillis(0)); + recording.start(); + + RandomAccessFile ras = new RandomAccessFile(tmp, "rw"); + int writeInt = 47; + byte[] writeBuffer = {10,11,12,13}; + + // Write an int and a buffer. + ras.write(writeInt); + expectedEvents.add(IOEvent.createFileWriteEvent(1, tmp)); + ras.write(writeBuffer); + expectedEvents.add(IOEvent.createFileWriteEvent(writeBuffer.length, tmp)); + + ras.seek(0); + + // Read int and buffer + int readInt = ras.read(); + assertEquals(readInt, writeInt, "wrong int read"); + expectedEvents.add(IOEvent.createFileReadEvent(1, tmp)); + byte[] readBuffer = new byte [writeBuffer.length]; + int size = ras.read(readBuffer); + verifyBufferEquals(readBuffer, writeBuffer); + expectedEvents.add(IOEvent.createFileReadEvent(readBuffer.length, tmp)); + + // Read beyond EOF + readInt = ras.read(); + assertEquals(-1, readInt, "wrong read after EOF"); + expectedEvents.add(IOEvent.createFileReadEvent(-1, tmp)); + + // Seek to beginning and verify we can read after EOF. + ras.seek(0); + readInt = ras.read(); + assertEquals(readInt, writeInt, "wrong int read after seek(0)"); + expectedEvents.add(IOEvent.createFileReadEvent(1, tmp)); + + // seek beyond EOF and verify we get EOF when reading. + ras.seek(10); + readInt = ras.read(); + assertEquals(-1, readInt, "wrong read after seek beyond EOF"); + expectedEvents.add(IOEvent.createFileReadEvent(-1, tmp)); + + // Read partial buffer. + int partialSize = writeBuffer.length - 2; + ras.seek(ras.length()-partialSize); + size = ras.read(readBuffer); + assertEquals(size, partialSize, "Wrong size partial buffer read"); + expectedEvents.add(IOEvent.createFileReadEvent(size, tmp)); + + ras.close(); + recording.stop(); + List events = Events.fromRecording(recording); + IOHelper.verifyEqualsInOrder(events, expectedEvents); + } } private static void verifyBufferEquals(byte[] a, byte[] b) { diff --git a/jdk/test/jdk/jfr/event/io/TestRandomAccessFileThread.java b/jdk/test/jdk/jfr/event/io/TestRandomAccessFileThread.java index b6200fd66..539759c6f 100644 --- a/jdk/test/jdk/jfr/event/io/TestRandomAccessFileThread.java +++ b/jdk/test/jdk/jfr/event/io/TestRandomAccessFileThread.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -64,43 +64,42 @@ public class TestRandomAccessFileThread { public static void main(String[] args) throws Throwable { File tmp = File.createTempFile("TestRandomAccessFileThread", ".tmp", new File(".")); tmp.deleteOnExit(); - - Recording recording = new Recording(); - recording.enable(IOEvent.EVENT_FILE_READ).withThreshold(Duration.ofMillis(0)); - recording.enable(IOEvent.EVENT_FILE_WRITE).withThreshold(Duration.ofMillis(0)); - recording.start(); - - TestThread writerThread = new TestThread(new XRun() { - @Override - public void xrun() throws IOException { - final byte[] buf = new byte[OP_COUNT]; - for (int i = 0; i < buf.length; ++i) { - buf[i] = (byte)((i + 'a') % 255); - } - try (RandomAccessFile raf = new RandomAccessFile(tmp, "rwd")) { - for(int i = 0; i < OP_COUNT; ++i) { - raf.write(buf, 0, i + 1); - writeCount++; + try (Recording recording = new Recording()) { + recording.enable(IOEvent.EVENT_FILE_READ).withThreshold(Duration.ofMillis(0)); + recording.enable(IOEvent.EVENT_FILE_WRITE).withThreshold(Duration.ofMillis(0)); + recording.start(); + + TestThread writerThread = new TestThread(new XRun() { + @Override + public void xrun() throws IOException { + final byte[] buf = new byte[OP_COUNT]; + for (int i = 0; i < buf.length; ++i) { + buf[i] = (byte)((i + 'a') % 255); } - } - }}, "TestWriterThread"); + try (RandomAccessFile raf = new RandomAccessFile(tmp, "rwd")) { + for(int i = 0; i < OP_COUNT; ++i) { + raf.write(buf, 0, i + 1); + writeCount++; + } + } + }}, "TestWriterThread"); TestThread readerThread = new TestThread(new XRun() { - @Override - public void xrun() throws IOException { - try (RandomAccessFile raf = new RandomAccessFile(tmp, "r")) { - byte[] buf = new byte[OP_COUNT]; - for(int i = 0; i < OP_COUNT; ++i) { - while (writeCount <= i) { - // No more data to read. Wait for writer thread. - Thread.yield(); + @Override + public void xrun() throws IOException { + try (RandomAccessFile raf = new RandomAccessFile(tmp, "r")) { + byte[] buf = new byte[OP_COUNT]; + for(int i = 0; i < OP_COUNT; ++i) { + while (writeCount <= i) { + // No more data to read. Wait for writer thread. + Thread.yield(); + } + int expectedSize = i + 1; + int actualSize = raf.read(buf, 0, expectedSize); + Asserts.assertEquals(actualSize, expectedSize, "Wrong read size. Probably test error."); } - int expectedSize = i + 1; - int actualSize = raf.read(buf, 0, expectedSize); - Asserts.assertEquals(actualSize, expectedSize, "Wrong read size. Probably test error."); } - } - }}, "TestReaderThread"); + }}, "TestReaderThread"); readerThread.start(); writerThread.start(); @@ -118,7 +117,7 @@ public class TestRandomAccessFileThread { continue; } logEventSummary(event); - if (Events.isEventType(event,IOEvent.EVENT_FILE_READ)) { + if (Events.isEventType(event, IOEvent.EVENT_FILE_READ)) { readEvents.add(event); } else { writeEvents.add(event); @@ -136,91 +135,92 @@ public class TestRandomAccessFileThread { Asserts.assertEquals(readEvents.size(), OP_COUNT, "Wrong number of read events"); Asserts.assertEquals(writeEvents.size(), OP_COUNT, "Wrong number of write events"); } - - private static void logEventSummary(RecordedEvent event) { - boolean isRead = Events.isEventType(event, IOEvent.EVENT_FILE_READ); - String name = isRead ? "read " : "write"; - String bytesField = isRead ? "bytesRead" : "bytesWritten"; - long bytes = Events.assertField(event, bytesField).getValue(); - long commit = Events.assertField(event, "startTime").getValue(); - Instant start = event.getStartTime(); - Instant end = event.getEndTime(); - System.out.printf("%s: bytes=%d, commit=%d, start=%s, end=%s%n", name, bytes, commit, start, end); - } - - private static void verifyThread(List events, Thread thread) { - events.stream().forEach(e -> Events.assertEventThread(e, thread)); - } - - private static void verifyBytes(List events, String fieldName) { - long expectedBytes = 0; - for (RecordedEvent event : events) { - Events.assertField(event, fieldName).equal(++expectedBytes); - } + } + + private static void logEventSummary(RecordedEvent event) { + boolean isRead = Events.isEventType(event, IOEvent.EVENT_FILE_READ); + String name = isRead ? "read " : "write"; + String bytesField = isRead ? "bytesRead" : "bytesWritten"; + long bytes = Events.assertField(event, bytesField).getValue(); + long commit = Events.assertField(event, "startTime").getValue(); + Instant start = event.getStartTime(); + Instant end = event.getEndTime(); + System.out.printf("%s: bytes=%d, commit=%d, start=%s, end=%s%n", name, bytes, commit, start, end); + } + + private static void verifyThread(List events, Thread thread) { + events.stream().forEach(e -> Events.assertEventThread(e, thread)); + } + + private static void verifyBytes(List events, String fieldName) { + long expectedBytes = 0; + for (RecordedEvent event : events) { + Events.assertField(event, fieldName).equal(++expectedBytes); } - - // Verify that all times are increasing - private static void verifyTimes(List events) { - RecordedEvent prev = null; - for (RecordedEvent curr : events) { - if (prev != null) { - try { - Asserts.assertGreaterThanOrEqual(curr.getStartTime(), prev.getStartTime(), "Wrong startTime"); - Asserts.assertGreaterThanOrEqual(curr.getEndTime(), prev.getEndTime(), "Wrong endTime"); - long commitPrev = Events.assertField(prev, "startTime").getValue(); - long commitCurr = Events.assertField(curr, "startTime").getValue(); - Asserts.assertGreaterThanOrEqual(commitCurr, commitPrev, "Wrong commitTime"); - } catch (Exception e) { - System.out.println("Error: " + e.getMessage()); - System.out.println("Prev Event: " + prev); - System.out.println("Curr Event: " + curr); - throw e; - } + } + + // Verify that all times are increasing + private static void verifyTimes(List events) { + RecordedEvent prev = null; + for (RecordedEvent curr : events) { + if (prev != null) { + try { + Asserts.assertGreaterThanOrEqual(curr.getStartTime(), prev.getStartTime(), "Wrong startTime"); + Asserts.assertGreaterThanOrEqual(curr.getEndTime(), prev.getEndTime(), "Wrong endTime"); + long commitPrev = Events.assertField(prev, "startTime").getValue(); + long commitCurr = Events.assertField(curr, "startTime").getValue(); + Asserts.assertGreaterThanOrEqual(commitCurr, commitPrev, "Wrong commitTime"); + } catch (Exception e) { + System.out.println("Error: " + e.getMessage()); + System.out.println("Prev Event: " + prev); + System.out.println("Curr Event: " + curr); + throw e; } - prev = curr; } + prev = curr; } - - // Verify that all times are increasing - private static void verifyReadWriteTimes(List readEvents, List writeEvents) { - List events = new ArrayList<>(); - events.addAll(readEvents); - events.addAll(writeEvents); - events.sort(new EventComparator()); - - int countRead = 0; - int countWrite = 0; - for (RecordedEvent event : events) { - if (Events.isEventType(event, IOEvent.EVENT_FILE_READ)) { - ++countRead; - } else { - ++countWrite; - } - // We can not read from the file before it has been written. - // This check verifies that times of different threads are correct. - // Since the read and write are from different threads, it is possible that the read - // is committed before the same write. - // But read operation may only be 1 step ahead of the write operation. - Asserts.assertLessThanOrEqual(countRead, countWrite + 1, "read must be after write"); + } + + // Verify that all times are increasing + private static void verifyReadWriteTimes(List readEvents, List writeEvents) { + List events = new ArrayList<>(); + events.addAll(readEvents); + events.addAll(writeEvents); + events.sort(new EventComparator()); + + int countRead = 0; + int countWrite = 0; + for (RecordedEvent event : events) { + if (Events.isEventType(event, IOEvent.EVENT_FILE_READ)) { + ++countRead; + } else { + ++countWrite; } + // We can not read from the file before it has been written. + // This check verifies that times of different threads are correct. + // Since the read and write are from different threads, it is possible that the read + // is committed before the same write. + // But read operation may only be 1 step ahead of the write operation. + Asserts.assertLessThanOrEqual(countRead, countWrite + 1, "read must be after write"); } + } - private static boolean isOurEvent(RecordedEvent event, File file) { - if (!Events.isEventType(event, IOEvent.EVENT_FILE_READ) && - !Events.isEventType(event, IOEvent.EVENT_FILE_WRITE)) { - return false; - } - String path = Events.assertField(event, "path").getValue(); - return file.getPath().equals(path); + private static boolean isOurEvent(RecordedEvent event, File file) { + if (!Events.isEventType(event, IOEvent.EVENT_FILE_READ) && + !Events.isEventType(event, IOEvent.EVENT_FILE_WRITE)) { + return false; } - - private static class EventComparator implements Comparator { - @Override - public int compare(RecordedEvent a, RecordedEvent b) { - long commitA = Events.assertField(a, "startTime").getValue(); - long commitB = Events.assertField(b, "startTime").getValue(); - return Long.compare(commitA, commitB); - } + String path = Events.assertField(event, "path").getValue(); + return file.getPath().equals(path); + } + + private static class EventComparator implements Comparator { + @Override + public int compare(RecordedEvent a, RecordedEvent b) { + long commitA = Events.assertField(a, "startTime").getValue(); + long commitB = Events.assertField(b, "startTime").getValue(); + return Long.compare(commitA, commitB); } + } } diff --git a/jdk/test/jdk/jfr/event/io/TestSocketChannelEvents.java b/jdk/test/jdk/jfr/event/io/TestSocketChannelEvents.java index dbd43adbf..23b692a31 100644 --- a/jdk/test/jdk/jfr/event/io/TestSocketChannelEvents.java +++ b/jdk/test/jdk/jfr/event/io/TestSocketChannelEvents.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,6 +53,7 @@ public class TestSocketChannelEvents { private static final int bufSizeB = 20; private List expectedEvents = new ArrayList<>(); + private synchronized void addExpectedEvent(IOEvent event) { expectedEvents.add(event); } @@ -62,69 +63,70 @@ public class TestSocketChannelEvents { } public void test() throws Throwable { - Recording recording = new Recording(); - - try (ServerSocketChannel ss = ServerSocketChannel.open()) { - recording.enable(IOEvent.EVENT_SOCKET_READ).withThreshold(Duration.ofMillis(0)); - recording.enable(IOEvent.EVENT_SOCKET_WRITE).withThreshold(Duration.ofMillis(0)); - recording.start(); - - ss.socket().setReuseAddress(true); - ss.socket().bind(null); - - TestThread readerThread = new TestThread(new XRun() { - @Override - public void xrun() throws IOException { - ByteBuffer bufA = ByteBuffer.allocate(bufSizeA); - ByteBuffer bufB = ByteBuffer.allocate(bufSizeB); - try (SocketChannel sc = ss.accept()) { - int readSize = sc.read(bufA); - assertEquals(readSize, bufSizeA, "Wrong readSize bufA"); - addExpectedEvent(IOEvent.createSocketReadEvent(bufSizeA, sc.socket())); - - bufA.clear(); - bufA.limit(1); - readSize = (int)sc.read(new ByteBuffer[] { bufA, bufB }); - assertEquals(readSize, 1 + bufSizeB, "Wrong readSize 1+bufB"); - addExpectedEvent(IOEvent.createSocketReadEvent(readSize, sc.socket())); - - // We try to read, but client have closed. Should get EOF. - bufA.clear(); - bufA.limit(1); - readSize = sc.read(bufA); - assertEquals(readSize, -1, "Wrong readSize at EOF"); - addExpectedEvent(IOEvent.createSocketReadEvent(-1, sc.socket())); + try (Recording recording = new Recording()) { + try (ServerSocketChannel ss = ServerSocketChannel.open()) { + recording.enable(IOEvent.EVENT_SOCKET_READ).withThreshold(Duration.ofMillis(0)); + recording.enable(IOEvent.EVENT_SOCKET_WRITE).withThreshold(Duration.ofMillis(0)); + recording.start(); + + ss.socket().setReuseAddress(true); + ss.socket().bind(null); + + TestThread readerThread = new TestThread(new XRun() { + @Override + public void xrun() throws IOException { + ByteBuffer bufA = ByteBuffer.allocate(bufSizeA); + ByteBuffer bufB = ByteBuffer.allocate(bufSizeB); + try (SocketChannel sc = ss.accept()) { + int readSize = sc.read(bufA); + assertEquals(readSize, bufSizeA, "Wrong readSize bufA"); + addExpectedEvent(IOEvent.createSocketReadEvent(bufSizeA, sc.socket())); + + bufA.clear(); + bufA.limit(1); + readSize = (int) sc.read(new ByteBuffer[] { bufA, bufB }); + assertEquals(readSize, 1 + bufSizeB, "Wrong readSize 1+bufB"); + addExpectedEvent(IOEvent.createSocketReadEvent(readSize, sc.socket())); + + // We try to read, but client have closed. Should + // get EOF. + bufA.clear(); + bufA.limit(1); + readSize = sc.read(bufA); + assertEquals(readSize, -1, "Wrong readSize at EOF"); + addExpectedEvent(IOEvent.createSocketReadEvent(-1, sc.socket())); + } } - } - }); - readerThread.start(); - - try (SocketChannel sc = SocketChannel.open(ss.socket().getLocalSocketAddress())) { - ByteBuffer bufA = ByteBuffer.allocateDirect(bufSizeA); - ByteBuffer bufB = ByteBuffer.allocateDirect(bufSizeB); - for (int i = 0; i < bufSizeA; ++i) { - bufA.put((byte)('a' + (i % 20))); - } - for (int i = 0; i < bufSizeB; ++i) { - bufB.put((byte)('A' + (i % 20))); - } - bufA.flip(); - bufB.flip(); + }); + readerThread.start(); + + try (SocketChannel sc = SocketChannel.open(ss.socket().getLocalSocketAddress())) { + ByteBuffer bufA = ByteBuffer.allocateDirect(bufSizeA); + ByteBuffer bufB = ByteBuffer.allocateDirect(bufSizeB); + for (int i = 0; i < bufSizeA; ++i) { + bufA.put((byte) ('a' + (i % 20))); + } + for (int i = 0; i < bufSizeB; ++i) { + bufB.put((byte) ('A' + (i % 20))); + } + bufA.flip(); + bufB.flip(); - sc.write(bufA); - addExpectedEvent(IOEvent.createSocketWriteEvent(bufSizeA, sc.socket())); + sc.write(bufA); + addExpectedEvent(IOEvent.createSocketWriteEvent(bufSizeA, sc.socket())); - bufA.clear(); - bufA.limit(1); - int bytesWritten = (int)sc.write(new ByteBuffer[] { bufA, bufB }); - assertEquals(bytesWritten, 1 + bufSizeB, "Wrong bytesWritten 1+bufB"); - addExpectedEvent(IOEvent.createSocketWriteEvent(bytesWritten, sc.socket())); - } + bufA.clear(); + bufA.limit(1); + int bytesWritten = (int) sc.write(new ByteBuffer[] { bufA, bufB }); + assertEquals(bytesWritten, 1 + bufSizeB, "Wrong bytesWritten 1+bufB"); + addExpectedEvent(IOEvent.createSocketWriteEvent(bytesWritten, sc.socket())); + } - readerThread.joinAndThrow(); - recording.stop(); - List events= Events.fromRecording(recording); - IOHelper.verifyEquals(events, expectedEvents); + readerThread.joinAndThrow(); + recording.stop(); + List events = Events.fromRecording(recording); + IOHelper.verifyEquals(events, expectedEvents); + } } } } diff --git a/jdk/test/jdk/jfr/event/io/TestSocketEvents.java b/jdk/test/jdk/jfr/event/io/TestSocketEvents.java index c0b64aa7d..5b544cc7e 100644 --- a/jdk/test/jdk/jfr/event/io/TestSocketEvents.java +++ b/jdk/test/jdk/jfr/event/io/TestSocketEvents.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,6 +55,7 @@ public class TestSocketEvents { private static final byte[] writeBuf = { 'B', 'C', 'D', 'E' }; private List expectedEvents = new ArrayList<>(); + private synchronized void addExpectedEvent(IOEvent event) { expectedEvents.add(event); } @@ -64,58 +65,59 @@ public class TestSocketEvents { } private void test() throws Throwable { - Recording recording = new Recording(); - - try (ServerSocket ss = new ServerSocket()) { - recording.enable(IOEvent.EVENT_SOCKET_READ).withThreshold(Duration.ofMillis(0)); - recording.enable(IOEvent.EVENT_SOCKET_WRITE).withThreshold(Duration.ofMillis(0)); - recording.start(); - - ss.setReuseAddress(true); - ss.bind(null); - - TestThread readerThread = new TestThread(new XRun() { - @Override - public void xrun() throws IOException { - byte[] bs = new byte[4]; - try (Socket s = ss.accept(); InputStream is = s.getInputStream()) { - int readInt = is.read(); - assertEquals(readInt, writeInt, "Wrong readInt"); - addExpectedEvent(IOEvent.createSocketReadEvent(1, s)); - - int bytesRead = is.read(bs, 0, 3); - assertEquals(bytesRead, 3, "Wrong bytesRead partial buffer"); - addExpectedEvent(IOEvent.createSocketReadEvent(bytesRead, s)); - - bytesRead = is.read(bs); - assertEquals(bytesRead, writeBuf.length, "Wrong bytesRead full buffer"); - addExpectedEvent(IOEvent.createSocketReadEvent(bytesRead, s)); - - // Try to read more, but writer have closed. Should get EOF. - readInt = is.read(); - assertEquals(readInt, -1, "Wrong readInt at EOF"); - addExpectedEvent(IOEvent.createSocketReadEvent(-1, s)); - } - } - }); - readerThread.start(); - - try (Socket s = new Socket()) { - s.connect(ss.getLocalSocketAddress()); - try (OutputStream os = s.getOutputStream()) { - os.write(writeInt); - addExpectedEvent(IOEvent.createSocketWriteEvent(1, s)); - os.write(writeBuf, 0, 3); - addExpectedEvent(IOEvent.createSocketWriteEvent(3, s)); - os.write(writeBuf); - addExpectedEvent(IOEvent.createSocketWriteEvent(writeBuf.length, s)); + try (Recording recording = new Recording()) { + try (ServerSocket ss = new ServerSocket()) { + recording.enable(IOEvent.EVENT_SOCKET_READ).withThreshold(Duration.ofMillis(0)); + recording.enable(IOEvent.EVENT_SOCKET_WRITE).withThreshold(Duration.ofMillis(0)); + recording.start(); + + ss.setReuseAddress(true); + ss.bind(null); + + TestThread readerThread = new TestThread(new XRun() { + @Override + public void xrun() throws IOException { + byte[] bs = new byte[4]; + try (Socket s = ss.accept(); InputStream is = s.getInputStream()) { + int readInt = is.read(); + assertEquals(readInt, writeInt, "Wrong readInt"); + addExpectedEvent(IOEvent.createSocketReadEvent(1, s)); + + int bytesRead = is.read(bs, 0, 3); + assertEquals(bytesRead, 3, "Wrong bytesRead partial buffer"); + addExpectedEvent(IOEvent.createSocketReadEvent(bytesRead, s)); + + bytesRead = is.read(bs); + assertEquals(bytesRead, writeBuf.length, "Wrong bytesRead full buffer"); + addExpectedEvent(IOEvent.createSocketReadEvent(bytesRead, s)); + + // Try to read more, but writer have closed. Should + // get EOF. + readInt = is.read(); + assertEquals(readInt, -1, "Wrong readInt at EOF"); + addExpectedEvent(IOEvent.createSocketReadEvent(-1, s)); + } + } + }); + readerThread.start(); + + try (Socket s = new Socket()) { + s.connect(ss.getLocalSocketAddress()); + try (OutputStream os = s.getOutputStream()) { + os.write(writeInt); + addExpectedEvent(IOEvent.createSocketWriteEvent(1, s)); + os.write(writeBuf, 0, 3); + addExpectedEvent(IOEvent.createSocketWriteEvent(3, s)); + os.write(writeBuf); + addExpectedEvent(IOEvent.createSocketWriteEvent(writeBuf.length, s)); + } } - } - readerThread.joinAndThrow(); - recording.stop(); - List events = Events.fromRecording(recording); - IOHelper.verifyEquals(events, expectedEvents); + readerThread.joinAndThrow(); + recording.stop(); + List events = Events.fromRecording(recording); + IOHelper.verifyEquals(events, expectedEvents); + } } } } -- 2.22.0