diff --git a/platform/platform-tests/testSrc/com/intellij/execution/process/BinaryOSProcessHandlerTest.java b/platform/platform-tests/testSrc/com/intellij/execution/process/BinaryOSProcessHandlerTest.java index 38dc5cdb98ba..4a417082ba82 100644 --- a/platform/platform-tests/testSrc/com/intellij/execution/process/BinaryOSProcessHandlerTest.java +++ b/platform/platform-tests/testSrc/com/intellij/execution/process/BinaryOSProcessHandlerTest.java @@ -18,6 +18,8 @@ package com.intellij.execution.process; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.io.BaseOutputReader; +import org.jetbrains.annotations.NotNull; import org.junit.Test; import java.io.File; @@ -29,14 +31,21 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.*; public class BinaryOSProcessHandlerTest { - @Test - public void test() throws Exception { - TestBinaryOSProcessHandler handler = new TestBinaryOSProcessHandler(launchTest()); - handler.startNotify(); - assertTrue(handler.waitFor(60 * 1000)); - assertEquals(0, handler.exitCode); - assertThat(handler.stdErr.toString()).isEqualTo(Runner.TEXT); - assertThat(handler.getOutput()).containsExactly(Runner.BYTES); + @Test public void testBlocking() { doTest(true); } + @Test public void testNonBlocking() { doTest(false); } + + private static void doTest(boolean blocking) { + try { + TestBinaryOSProcessHandler handler = new TestBinaryOSProcessHandler(launchTest(), blocking); + handler.startNotify(); + assertTrue(handler.waitFor(60 * 1000)); + assertEquals(0, handler.exitCode); + assertThat(handler.stdErr.toString()).isEqualTo(Runner.TEXT); + assertThat(handler.getOutput()).containsExactly(Runner.BYTES); + } + catch (URISyntaxException | IOException e) { + throw new RuntimeException(e); + } } private static Process launchTest() throws URISyntaxException, IOException { @@ -54,10 +63,18 @@ public class BinaryOSProcessHandlerTest { private static class TestBinaryOSProcessHandler extends BinaryOSProcessHandler { private final StringBuilder stdErr = new StringBuilder(); + private final boolean blocking; private int exitCode = -1; - public TestBinaryOSProcessHandler(Process process) { + public TestBinaryOSProcessHandler(Process process, boolean blocking) { super(process, "test", null); + this.blocking = blocking; + } + + @NotNull + @Override + protected BaseOutputReader.Options readerOptions() { + return blocking ? BaseOutputReader.Options.BLOCKING : BaseOutputReader.Options.NON_BLOCKING; } @Override @@ -77,10 +94,18 @@ public class BinaryOSProcessHandlerTest { public static class Runner { private static final String TEXT = "some\ntext"; private static final byte[] BYTES = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + private static final int PACKET_SIZE = 4; + private static final int SEND_TIMEOUT = 500; - public static void main(String[] args) throws IOException { + @SuppressWarnings("BusyWait") + public static void main(String[] args) throws IOException, InterruptedException { System.err.print(TEXT); - System.out.write(BYTES); + + for (int offset = 0; offset < BYTES.length; offset += PACKET_SIZE) { + int n = Math.min(PACKET_SIZE, BYTES.length - offset); + System.out.write(BYTES, offset, n); + Thread.sleep(SEND_TIMEOUT); + } } } } \ No newline at end of file diff --git a/platform/util/src/com/intellij/util/io/BinaryOutputReader.java b/platform/util/src/com/intellij/util/io/BinaryOutputReader.java index 58a55366bc32..1e61b91d0676 100644 --- a/platform/util/src/com/intellij/util/io/BinaryOutputReader.java +++ b/platform/util/src/com/intellij/util/io/BinaryOutputReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,31 +35,31 @@ public abstract class BinaryOutputReader extends BaseDataReader { @Override protected boolean readAvailableNonBlocking() throws IOException { byte[] buffer = myBuffer; - boolean read = false; - while (myStream.available() > 0) { - int n = myStream.read(buffer); - if (n <= 0) break; - read = true; - onBinaryAvailable(buffer, n); + int n; + while (myStream.available() > 0 && (n = myStream.read(buffer)) >= 0) { + if (n > 0) { + read = true; + onBinaryAvailable(buffer, n); + } } return read; } + @Override protected final boolean readAvailableBlocking() throws IOException { + byte[] buffer = myBuffer; boolean read = false; - byte[] buffer = myBuffer; - - int n; - while ((n = myStream.read(buffer)) >= 0) { - if (n > 0) { - read = true; - onBinaryAvailable(buffer, n); - } + int n; + while ((n = myStream.read(buffer)) >= 0) { + if (n > 0) { + read = true; + onBinaryAvailable(buffer, n); } + } return read; } @@ -70,4 +70,4 @@ public abstract class BinaryOutputReader extends BaseDataReader { protected void close() throws IOException { myStream.close(); } -} +} \ No newline at end of file