/* * 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. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.intellij.execution.process; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.text.StringUtil; import com.intellij.testFramework.PlatformTestUtil; import com.intellij.util.io.BaseOutputReader; import org.jetbrains.annotations.NotNull; import org.junit.Test; import java.io.File; import java.io.IOException; import java.net.URISyntaxException; import java.net.URL; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.*; public class BinaryOSProcessHandlerTest { @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 { String className = Runner.class.getName(); URL url = Runner.class.getClassLoader().getResource(className.replace('.', '/') + ".class"); assertNotNull(url); File dir = new File(url.toURI()); for (int i = 0; i < StringUtil.countChars(className, '.') + 1; i++) dir = dir.getParentFile(); String[] cmd = {PlatformTestUtil.getJavaExe(), "-cp", dir.getPath(), className}; return new ProcessBuilder(cmd).redirectErrorStream(false).start(); } private static class TestBinaryOSProcessHandler extends BinaryOSProcessHandler { private final StringBuilder stdErr = new StringBuilder(); private final boolean blocking; private int exitCode = -1; 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 public void notifyTextAvailable(String text, Key outputType) { if (outputType != ProcessOutputTypes.SYSTEM) { stdErr.append(text); } } @Override protected void notifyProcessTerminated(int exitCode) { super.notifyProcessTerminated(exitCode); this.exitCode = exitCode; } } 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; @SuppressWarnings("BusyWait") public static void main(String[] args) throws IOException, InterruptedException { System.err.print(TEXT); 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); } } } }