package com.example.badlog; import com.google.common.io.Files; import io.dropwizard.Configuration; import io.dropwizard.testing.ConfigOverride; import io.dropwizard.testing.DropwizardTestSupport; import io.dropwizard.testing.ResourceHelpers; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.PrintStream; import static java.nio.charset.StandardCharsets.UTF_8; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; public class BadLogTest { private static final Logger LOGGER = LoggerFactory.getLogger(BadLogTest.class); private static ByteArrayOutputStream out; private static ByteArrayOutputStream err; private static PrintStream oldOut = System.out; private static PrintStream oldErr = System.err; @Rule public TemporaryFolder folder = new TemporaryFolder(); @Before public void setup() throws Exception { out = new ByteArrayOutputStream(); err = new ByteArrayOutputStream(); System.setOut(new PrintStream(out)); System.setErr(new PrintStream(err)); } @After public void teardown() { System.setOut(oldOut); System.setErr(oldErr); } @Test public void thatLoggingIsntBrokenOnCleanup() throws Exception { BadLogApp.runMe(new String[]{"server"}); LOGGER.info("I'm after the test"); Thread.sleep(100); assertThat(new String(out.toByteArray(), UTF_8)) .contains("Mayday we're going down") .contains("I'm after the test"); assertThat(new String(err.toByteArray(), UTF_8)) .contains("I'm a bad app"); } @Test public void testSupportShouldResetLogging() throws Exception { final File logFile = folder.newFile("example.log"); // Clear out the log file Files.write(new byte[]{}, logFile); final String configPath = ResourceHelpers.resourceFilePath("badlog/config.yaml"); final DropwizardTestSupport<Configuration> app = new DropwizardTestSupport<>(BadLogApp.class, configPath, ConfigOverride.config("logging.appenders[0].currentLogFilename", logFile.getAbsolutePath())); assertThatThrownBy(app::before).hasMessage("I'm a bad app"); // Explicitly run the command so that the fatal error function runs app.getApplication().run("server", configPath); app.after(); // Since our dropwizard app is only using the file appender, the console // appender should not contain our logging statements assertThat(new String(out.toByteArray(), UTF_8)) .doesNotContain("Mayday we're going down"); out.reset(); // and the file should have our logging statements final String contents = Files.toString(logFile, UTF_8); assertThat(contents).contains("Mayday we're going down"); // Clear out the log file Files.write(new byte[]{}, logFile); final DropwizardTestSupport<Configuration> app2 = new DropwizardTestSupport<>(BadLogApp.class, new Configuration()); assertThatThrownBy(app2::before).hasMessage("I'm a bad app"); // Explicitly run the command so that the fatal error function runs app2.getApplication().run("server"); app2.after(); // Now the console appender will see the fatal error assertThat(new String(out.toByteArray(), UTF_8)) .contains("Mayday we're going down"); out.reset(); // and the old log file shouldn't final String contents2 = Files.toString(logFile, UTF_8); assertThat(contents2).doesNotContain("Mayday we're going down"); // And for the final set of assertions will make sure that going back to the app // that logs to a file is still behaviorally correct. // Clear out the log file Files.write(new byte[]{}, logFile); final DropwizardTestSupport<Configuration> app3 = new DropwizardTestSupport<>(BadLogApp.class, configPath, ConfigOverride.config("logging.appenders[0].currentLogFilename", logFile.getAbsolutePath())); assertThatThrownBy(app3::before).hasMessage("I'm a bad app"); // Explicitly run the command so that the fatal error function runs app3.getApplication().run("server", configPath); app3.after(); // Since our dropwizard app is only using the file appender, the console // appender should not contain our logging statements assertThat(new String(out.toByteArray(), UTF_8)) .doesNotContain("Mayday we're going down"); // and the file should have our logging statements final String contents3 = Files.toString(logFile, UTF_8); assertThat(contents3).contains("Mayday we're going down"); } }