Skip to content

Commit

Permalink
Tap System.out with System Lambda (#123)
Browse files Browse the repository at this point in the history
Improve readability. Also System Lambda is more precise because it taps
the output of a single statement only.
  • Loading branch information
stefanbirkner authored Jul 9, 2020
1 parent 6a646af commit a5175dd
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 75 deletions.
6 changes: 6 additions & 0 deletions plugin-management-cli/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@
<artifactId>snakeyaml</artifactId>
<version>1.24</version>
</dependency>
<dependency>
<groupId>com.github.stefanbirkner</groupId>
<artifactId>system-lambda</artifactId>
<version>1.0.0</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,14 @@
import io.jenkins.tools.pluginmanager.config.Settings;
import io.jenkins.tools.pluginmanager.impl.Plugin;
import io.jenkins.tools.pluginmanager.impl.PluginDependencyStrategyException;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import org.apache.commons.io.FileUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
Expand All @@ -26,6 +23,7 @@
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import static com.github.stefanbirkner.systemlambda.SystemLambda.tapSystemOutNormalized;
import static java.util.Arrays.asList;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
Expand All @@ -44,8 +42,6 @@ public class CliOptionsTest {
private CliOptions options;
private CmdLineParser parser;
List<Plugin> txtRequestedPlugins;
private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
private final PrintStream originalOut = System.out;

@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();
Expand Down Expand Up @@ -73,8 +69,6 @@ public void createParser() throws CmdLineException {
"http://ftp-chi.osuosl.org/pub/jenkins/plugins/credentials/2.2.0/credentials.hpi", null),
new Plugin("blueocean", "latest", null, null)
);

System.setOut(new PrintStream(outContent));
}

@Test
Expand Down Expand Up @@ -299,21 +293,16 @@ public void showVersionTest() throws Exception {
whenNew(Properties.class).withNoArguments().thenReturn(properties);
when(properties.getProperty(any(String.class))).thenReturn(version);

options.showVersion();
assertEquals(version, outContent.toString().trim());

ByteArrayOutputStream aliasVersionOut = new ByteArrayOutputStream();
System.setOut(new PrintStream(aliasVersionOut));
String output = tapSystemOutNormalized(options::showVersion);
assertEquals("testVersion\n", output);

parser.parseArgument("-v");
options.showVersion();
assertEquals(version, aliasVersionOut.toString().trim());
String aliasOutput = tapSystemOutNormalized(options::showVersion);
assertEquals("testVersion\n", aliasOutput);
}

@Test
public void showVersionErrorTest() throws CmdLineException {
ByteArrayOutputStream nullPropertiesOut = new ByteArrayOutputStream();
System.setOut(new PrintStream(nullPropertiesOut));
CliOptions cliOptionsSpy = spy(options);
parser.parseArgument("--version");
doReturn(null).when(cliOptionsSpy).getPropertiesInputStream(any(String.class));
Expand Down Expand Up @@ -369,9 +358,4 @@ public void useLatestSpecifiedAndLatestAllTest() throws CmdLineException {

assertThrows(PluginDependencyStrategyException.class, options::setup);
}

@After
public void restoreStream() {
System.setOut(originalOut);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@
import hudson.util.VersionNumber;
import io.jenkins.tools.pluginmanager.config.Config;
import io.jenkins.tools.pluginmanager.config.Settings;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.net.URI;
import java.net.URL;
import java.nio.charset.Charset;
Expand Down Expand Up @@ -36,7 +34,6 @@
import org.apache.http.impl.client.HttpClients;
import org.json.JSONArray;
import org.json.JSONObject;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
Expand All @@ -46,6 +43,7 @@
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import static com.github.stefanbirkner.systemlambda.SystemLambda.tapSystemOutNormalized;
import static io.jenkins.tools.pluginmanager.util.PluginManagerUtils.dirName;
import static java.util.Collections.singletonList;
import static org.hamcrest.CoreMatchers.is;
Expand All @@ -72,7 +70,6 @@
public class PluginManagerTest {
private PluginManager pm;
private Config cfg;
private final PrintStream originalOut = System.out;
private List<Plugin> directDependencyExpectedPlugins;

@Before
Expand Down Expand Up @@ -187,7 +184,7 @@ public void findEffectivePluginsTest() {
}

@Test
public void listPluginsNoOutputTest() throws IOException {
public void listPluginsNoOutputTest() throws Exception {
Config config = Config.builder()
.withJenkinsWar(Settings.DEFAULT_WAR)
.withPluginDir(Files.createTempDirectory("plugins").toFile())
Expand All @@ -196,18 +193,16 @@ public void listPluginsNoOutputTest() throws IOException {

PluginManager pluginManager = new PluginManager(config);

ByteArrayOutputStream expectedNoOutput = new ByteArrayOutputStream();
System.setOut(new PrintStream(expectedNoOutput));
String output = tapSystemOutNormalized(
pluginManager::listPlugins);

pluginManager.listPlugins();

assertEquals("", expectedNoOutput.toString().trim());
assertEquals("", output);
}



@Test
public void listPluginsOutputTest() throws IOException {
public void listPluginsOutputTest() throws Exception {
Config config = Config.builder()
.withJenkinsWar(Settings.DEFAULT_WAR)
.withPluginDir(Files.createTempDirectory("plugins").toFile())
Expand Down Expand Up @@ -285,11 +280,10 @@ public void listPluginsOutputTest() throws IOException {
"plugin1 1.0\n" +
"plugin2 2.0\n";

ByteArrayOutputStream outContent = new ByteArrayOutputStream();
System.setOut(new PrintStream(outContent));
pluginManager.listPlugins();
String output = tapSystemOutNormalized(
pluginManager::listPlugins);

assertEquals(expectedOutput.trim(), outContent.toString().replaceAll("\\r\\n?", "\n").trim());
assertEquals(expectedOutput, output);
}

@Test
Expand Down Expand Up @@ -564,7 +558,7 @@ public void warningExistsTest() {
}

@Test
public void checkVersionCompatibilityNullTest() {
public void checkVersionCompatibilityNullTest() throws Exception {
pm.setJenkinsVersion(null);

Plugin plugin1 = new Plugin("plugin1", "1.0", null, null);
Expand Down Expand Up @@ -609,7 +603,7 @@ public void checkVersionCompatibilityPassTest() {
}

@Test
public void showAvailableUpdatesNoOutputTest() throws IOException {
public void showAvailableUpdatesNoOutputTest() throws Exception {
Config config = Config.builder()
.withJenkinsWar(Settings.DEFAULT_WAR)
.withPluginDir(Files.createTempDirectory("tmpplugins").toFile())
Expand All @@ -623,16 +617,14 @@ public void showAvailableUpdatesNoOutputTest() throws IOException {
new Plugin("ant", "1.8", null, null),
new Plugin("amazon-ecs", "1.15", null, null));

ByteArrayOutputStream expectedNoOutput = new ByteArrayOutputStream();
System.setOut(new PrintStream(expectedNoOutput));

pluginManager.showAvailableUpdates(plugins);
String output = tapSystemOutNormalized(
() -> pluginManager.showAvailableUpdates(plugins));

assertEquals("", expectedNoOutput.toString().trim());
assertEquals("", output);
}

@Test
public void showAvailableUpdates() throws IOException {
public void showAvailableUpdates() throws Exception {
Config config = Config.builder()
.withJenkinsWar(Settings.DEFAULT_WAR)
.withPluginDir(Files.createTempDirectory("tmpplugins").toFile())
Expand All @@ -651,16 +643,14 @@ public void showAvailableUpdates() throws IOException {
doReturn(new VersionNumber("1.20")).when(pluginManagerSpy).getLatestPluginVersion("amazon-ecs");
doReturn(new VersionNumber("2.4")).when(pluginManagerSpy).getLatestPluginVersion("maven-invoker-plugin");

ByteArrayOutputStream output = new ByteArrayOutputStream();
System.setOut(new PrintStream(output));

pluginManagerSpy.showAvailableUpdates(plugins);
String output = tapSystemOutNormalized(
() -> pluginManagerSpy.showAvailableUpdates(plugins));

String expectedOutput = "\nAvailable updates:\n" +
"ant (1.8) has an available update: 1.9\n" +
"amazon-ecs (1.15) has an available update: 1.20\n";

assertEquals(expectedOutput, output.toString().replaceAll("\\r\\n?", "\n"));
assertEquals(expectedOutput, output);
}

@Test
Expand Down Expand Up @@ -768,7 +758,7 @@ public void checkVersionSpecificUpdateCenterTest() throws Exception {
}

@Test
public void outputPluginReplacementInfoTest() throws IOException {
public void outputPluginReplacementInfoTest() throws Exception {
Config config = Config.builder()
.withJenkinsWar(Settings.DEFAULT_WAR)
.withPluginDir(Files.createTempDirectory("tmpplugins").toFile())
Expand All @@ -784,14 +774,12 @@ public void outputPluginReplacementInfoTest() throws IOException {
higherVersion.setParent(highVersionParent);

String expected = "Version of plugin1 (1.0) required by plugin1parent1 (1.0.0) is lower than the version " +
"required (2.0) by plugin1parent2 (2.0.0), upgrading required plugin version";
"required (2.0) by plugin1parent2 (2.0.0), upgrading required plugin version\n";

ByteArrayOutputStream output = new ByteArrayOutputStream();
System.setOut(new PrintStream(output));
String output = tapSystemOutNormalized(
() -> pluginManager.outputPluginReplacementInfo(lowerVersion, higherVersion));

pluginManager.outputPluginReplacementInfo(lowerVersion, higherVersion);

assertEquals(expected, output.toString().trim());
assertEquals(expected, output);
}

@Test
Expand Down Expand Up @@ -1465,7 +1453,7 @@ public void getAttributeFromManifestTest() throws Exception {
assertEquals(value, pm.getAttributeFromManifest(testJpi, "key"));
}

public void showAllSecurityWarningsNoOutput() throws IOException {
public void showAllSecurityWarningsNoOutput() throws Exception {
Config config = Config.builder()
.withJenkinsWar(Settings.DEFAULT_WAR)
.withPluginDir(Files.createTempDirectory("plugins").toFile())
Expand All @@ -1474,16 +1462,14 @@ public void showAllSecurityWarningsNoOutput() throws IOException {

PluginManager pluginManager = new PluginManager(config);

ByteArrayOutputStream expectedNoOutput = new ByteArrayOutputStream();
System.setOut(new PrintStream(expectedNoOutput));

pluginManager.showAllSecurityWarnings();
String output = tapSystemOutNormalized(
pluginManager::showAllSecurityWarnings);

assertEquals("", expectedNoOutput.toString().trim());
assertEquals("", output);
}


public void showAllSecurityWarnings() throws IOException {
public void showAllSecurityWarnings() throws Exception {
Config config = Config.builder()
.withJenkinsWar(Settings.DEFAULT_WAR)
.withPluginDir(Files.createTempDirectory("plugins").toFile())
Expand All @@ -1494,19 +1480,15 @@ public void showAllSecurityWarnings() throws IOException {

pluginManager.setLatestUcJson(setTestUcJson());



ByteArrayOutputStream actualOutput = new ByteArrayOutputStream();
System.setOut(new PrintStream(actualOutput));

pluginManager.showAllSecurityWarnings();
String output = tapSystemOutNormalized(
pluginManager::showAllSecurityWarnings);

String expectedOutput = "google-login - Authentication bypass vulnerability\n" +
"cucumber-reports - Plugin disables Content-Security-Policy for files served by Jenkins\n" +
"pipeline-maven - Arbitrary files from Jenkins master available in Pipeline by using the withMaven step\n" +
"pipeline-maven - XML External Entity processing vulnerability\n";

assertEquals(expectedOutput.trim(), actualOutput.toString().trim());
assertEquals(expectedOutput, output);
}


Expand Down Expand Up @@ -1763,9 +1745,4 @@ private List<String> convertPluginsToStrings(List<Plugin> pluginList) {
Collections.sort(stringList);
return stringList;
}

@After
public void restoreStream() {
System.setOut(originalOut);
}
}

0 comments on commit a5175dd

Please sign in to comment.