com.thoughtworks.go.util.ProcessWrapperTest.java Source code

Java tutorial

Introduction

Here is the source code for com.thoughtworks.go.util.ProcessWrapperTest.java

Source

/*************************GO-LICENSE-START*********************************
 * Copyright 2014 ThoughtWorks, Inc.
 *
 * 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.
 *************************GO-LICENSE-END***********************************/

package com.thoughtworks.go.util;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import com.thoughtworks.go.util.command.CommandLine;
import com.thoughtworks.go.util.command.CommandLineException;
import com.thoughtworks.go.util.command.ConsoleResult;
import com.thoughtworks.go.util.command.EnvironmentVariableContext;
import com.thoughtworks.go.util.command.InMemoryStreamConsumer;
import com.thoughtworks.go.util.command.ProcessOutputStreamConsumer;
import com.thoughtworks.go.util.command.SecretString;
import org.apache.commons.io.FileUtils;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import static com.thoughtworks.go.util.command.ProcessOutputStreamConsumer.inMemoryConsumer;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class ProcessWrapperTest {
    private File tempFolder;

    @Before
    public void setUp() throws Exception {
        tempFolder = FileUtil.createTempFolder();
        assertThat(tempFolder.exists(), is(true));
    }

    @After
    public void teardown() throws Exception {
        FileUtils.deleteQuietly(tempFolder);
    }

    @Test
    public void shouldReturnTrueWhenAProcessIsRunning() {
        Process process = getMockedProcess(mock(OutputStream.class));
        when(process.exitValue()).thenThrow(new IllegalThreadStateException());
        ProcessWrapper processWrapper = new ProcessWrapper(process, "", "", inMemoryConsumer(), null, null);
        assertThat(processWrapper.isRunning(), is(true));
    }

    @Test
    public void shouldReturnFalseWhenAProcessHasExited() {
        Process process = getMockedProcess(mock(OutputStream.class));
        when(process.exitValue()).thenReturn(1);
        ProcessWrapper processWrapper = new ProcessWrapper(process, "", "", inMemoryConsumer(), null, null);
        assertThat(processWrapper.isRunning(), is(false));
    }

    @Test
    public void shouldTypeInputToConsole() {
        OutputStream processInputStream = new ByteArrayOutputStream();// mock(OutputStream.class);
        Process process = getMockedProcess(processInputStream);
        ProcessWrapper processWrapper = new ProcessWrapper(process, "", "", inMemoryConsumer(), null, null);
        ArrayList<String> inputs = new ArrayList<String>();
        inputs.add("input1");
        inputs.add("input2");
        processWrapper.typeInputToConsole(inputs);

        String input = processInputStream.toString();
        String[] parts = input.split("\\r?\\n");
        assertThat(parts[0], is("input1"));
        assertThat(parts[1], is("input2"));
    }

    @Test
    public void shouldThrowExceptionWhenExecutableDoesNotExist() throws IOException {
        CommandLine line = CommandLine.createCommandLine("doesnotexist");
        try {
            ProcessOutputStreamConsumer outputStreamConsumer = inMemoryConsumer();
            line.execute(outputStreamConsumer, new EnvironmentVariableContext(), null);
            fail("Expected exception");
        } catch (CommandLineException e) {
            assertThat(e.getMessage(), containsString("Make sure this command can execute manually."));
            assertThat(e.getMessage(), containsString("doesnotexist"));
            assertThat(e.getResult(), notNullValue());
        }
    }

    @Test
    public void shouldTryCommandWithTimeout() throws IOException {
        CommandLine line = CommandLine.createCommandLine("doesnotexist");
        try {
            line.waitForSuccess(100);
            fail("Expected Exception");
        } catch (Exception e) {
            assertThat(e.getMessage(),
                    containsString("Timeout after 0.1 seconds waiting for command 'doesnotexist'"));
        }
    }

    @Test
    public void shouldCollectOutput() throws Exception {
        String output = "SYSOUT: Hello World!";
        String error = "SYSERR: Some error happened!";
        CommandLine line = CommandLine.createCommandLine("ruby").withArgs(script("echo"), output, error);
        ConsoleResult result = run(line);

        assertThat("Errors: " + result.errorAsString(), result.returnValue(), is(0));
        assertThat(result.output(), contains(output));
        assertThat(result.error(), contains(error));
    }

    private String script(final String name) {
        return "../util/test-resources/executables/" + name + ".rb";
    }

    @Test
    public void shouldAcceptInputString() throws Exception {
        String input = "SYSIN: Hello World!";
        CommandLine line = CommandLine.createCommandLine("ruby").withArgs(script("echo-input"));
        ConsoleResult result = run(line, input);
        assertThat(result.output(), contains(input));
        assertThat(result.error().size(), is(0));
    }

    @Test
    public void shouldBeAbleToCompleteInput() throws Exception {
        String input1 = "SYSIN: Line 1!";
        String input2 = "SYSIN: Line 2!";
        CommandLine line = CommandLine.createCommandLine("ruby").withArgs(script("echo-all-input"));
        ConsoleResult result = run(line, input1, input2);
        assertThat(result.returnValue(), is(0));
        assertThat(result.output(), contains("You said: " + input1));
        assertThat(result.output(), contains("You said: " + input2));
        assertThat(result.error().size(), is(0));
    }

    @Test
    public void shouldReportReturnValueIfProcessFails() {
        CommandLine line = CommandLine.createCommandLine("ruby").withArgs(script("nonexistent-script"));
        ConsoleResult result = run(line);
        assertThat(result.returnValue(), is(1));
    }

    @Test
    public void shouldSetGoServerVariablesIfTheyExist() {
        System.setProperty("GO_DEPENDENCY_LABEL_PIPELINE_NAME", "999");
        CommandLine line = CommandLine.createCommandLine("ruby").withArgs(script("dump-environment"));
        ConsoleResult result = run(line);
        assertThat("Errors: " + result.errorAsString(), result.returnValue(), is(0));
        assertThat(result.output(), contains("GO_DEPENDENCY_LABEL_PIPELINE_NAME=999"));
    }

    private ConsoleResult run(CommandLine line, String... inputs) {
        InMemoryStreamConsumer outputStreamConsumer = inMemoryConsumer();

        EnvironmentVariableContext environmentVariableContext = new EnvironmentVariableContext();
        environmentVariableContext.setProperty("GO_DEPENDENCY_LABEL_PIPELINE_NAME", "999", false);
        line.addInput(inputs);
        ProcessWrapper processWrapper = line.execute(outputStreamConsumer, environmentVariableContext, null);
        return new ConsoleResult(processWrapper.waitForExit(), outputStreamConsumer.getStdLines(),
                outputStreamConsumer.getErrLines(), line.getArguments(), new ArrayList<SecretString>());
    }

    private Matcher<List<String>> contains(final String output) {
        return new TypeSafeMatcher<List<String>>() {
            public boolean matchesSafely(List<String> lines) {
                for (String line : lines) {
                    if (line.contains(output)) {
                        return true;
                    }
                }
                return false;
            }

            public void describeTo(Description description) {
                description.appendText("to contain " + output);
            }
        };
    }

    private Process getMockedProcess(OutputStream outputStream) {
        Process process = mock(Process.class);
        when(process.getErrorStream()).thenReturn(mock(InputStream.class));
        when(process.getInputStream()).thenReturn(mock(InputStream.class));
        when(process.getOutputStream()).thenReturn(outputStream);
        return process;
    }

}