/* * Copyright 2016 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. */ package com.thoughtworks.go.buildsession; import com.googlecode.junit.ext.JunitExtRunner; import com.googlecode.junit.ext.RunIf; import com.googlecode.junit.ext.checkers.OSChecker; import com.thoughtworks.go.domain.BuildCommand; import com.thoughtworks.go.junitext.EnhancedOSChecker; import com.thoughtworks.go.util.ArrayUtil; import com.thoughtworks.go.util.LogFixture; import com.thoughtworks.go.util.SystemUtil; import org.apache.log4j.Level; import org.junit.Test; import org.junit.runner.RunWith; import java.io.IOException; import static com.thoughtworks.go.domain.BuildCommand.*; import static com.thoughtworks.go.domain.JobResult.Failed; import static com.thoughtworks.go.domain.JobResult.Passed; import static com.thoughtworks.go.junitext.EnhancedOSChecker.DO_NOT_RUN_ON; import static com.thoughtworks.go.junitext.EnhancedOSChecker.WINDOWS; import static com.thoughtworks.go.matchers.ConsoleOutMatcher.printedAppsMissingInfoOnUnix; import static com.thoughtworks.go.matchers.ConsoleOutMatcher.printedAppsMissingInfoOnWindows; import static com.thoughtworks.go.util.LogFixture.logFixtureFor; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.not; import static org.hamcrest.core.Is.is; @RunWith(JunitExtRunner.class) public class ExecCommandExecutorTest extends BuildSessionBasedTestCase { @Test public void execExecuteExternalCommandAndConnectOutputToBuildConsole() { runBuild(exec("echo", "foo"), Passed); assertThat(console.lastLine(), is("foo")); } @Test public void execShouldFailIfWorkingDirectoryNotExists() { runBuild(exec("echo", "should not show").setWorkingDirectory("not-exists"), Failed); assertThat(console.lineCount(), is(1)); assertThat(console.firstLine(), containsString("not-exists\" is not a directory!")); } @Test public void execUseSystemEnvironmentVariables() { runBuild(execEchoEnv(pathSystemEnvName()), Passed); assertThat(console.output(), is(System.getenv(pathSystemEnvName()))); } @Test public void execUsePresetEnvs() { BuildSession buildSession = newBuildSession(); buildSession.setEnv("GO_SERVER_URL", "https://far.far.away/go"); runBuild(buildSession, execEchoEnv("GO_SERVER_URL"), Passed); assertThat(console.output(), is("https://far.far.away/go")); } @Test public void execUseExportedEnv() throws IOException { runBuild(compose( export("foo", "bar", false), execEchoEnv("foo")), Passed); assertThat(console.lastLine(), is("bar")); } @Test public void execUseExportedEnvWithOverridden() throws Exception { runBuild(compose( export("answer", "2", false), export("answer", "42", false), execEchoEnv("answer")), Passed); assertThat(console.lastLine(), is("42")); } @Test public void execUseOverriddenSystemEnvValue() throws Exception { runBuild(compose( export(pathSystemEnvName(), "/foo/bar", false), execEchoEnv(pathSystemEnvName())), Passed); assertThat(console.lastLine(), is("/foo/bar")); } @Test @RunIf(value = EnhancedOSChecker.class, arguments = {DO_NOT_RUN_ON, WINDOWS}) public void execExecuteNotExistExternalCommandOnUnix() { runBuild(exec("not-not-not-exist"), Failed); assertThat(console.output(), printedAppsMissingInfoOnUnix("not-not-not-exist")); } @Test @RunIf(value = EnhancedOSChecker.class, arguments = {EnhancedOSChecker.WINDOWS}) public void execExecuteNotExistExternalCommandOnWindows() { runBuild(exec("not-not-not-exist"), Failed); assertThat(console.output(), printedAppsMissingInfoOnWindows("not-not-not-exist")); } @Test @RunIf(value = EnhancedOSChecker.class, arguments = {DO_NOT_RUN_ON, OSChecker.WINDOWS}) public void shouldNotLeakSecretsToConsoleLog() { runBuild(compose(secret("topsecret"), exec("not-not-not-exist", "topsecret")), Failed); assertThat(console.output(), containsString("not-not-not-exist ******")); assertThat(console.output(), not(containsString("topsecret"))); } @Test @RunIf(value = EnhancedOSChecker.class, arguments = {DO_NOT_RUN_ON, OSChecker.WINDOWS}) public void shouldNotLeakSecretsToLog() { try (LogFixture logFixture = logFixtureFor(ExecCommandExecutor.class, Level.DEBUG)) { runBuild(compose(secret("topsecret"), exec("not-not-not-exist", "topsecret")), Failed); String logs = ArrayUtil.join(logFixture.getMessages()); assertThat(logs, containsString("not-not-not-exist ******")); assertThat(logs, not(containsString("topsecret"))); } } private BuildCommand execEchoEnv(final String envname) { if (SystemUtil.isWindows()) { return exec("echo", "%" + envname + "%"); } else { return exec("/bin/sh", "-c", String.format("echo ${%s}", envname)); } } }