From 9dbc4680e40f2976e2de9994f07c04f8531dd99a Mon Sep 17 00:00:00 2001 From: Arvid Ihrig <ihrig@fhi-berlin.mpg.de> Date: Mon, 23 Jul 2018 15:47:34 +0200 Subject: [PATCH] Integrated Pipeline: refactored logging end-to-end tests, now use an extra log appender to a ByteArrayOutputStream --- .../LoggingTestAsyncWrapper.scala | 19 +++++++ .../UnderDevelopment.scala | 23 +++----- .../package.scala | 2 +- .../helpers/LoggingTestBase.scala | 52 +++++++++++++++++++ 4 files changed, 79 insertions(+), 17 deletions(-) create mode 100644 integrated-pipeline/src/test/scala/eu/nomad_lab/integrated_pipeline_end_to_end_tests/LoggingTestAsyncWrapper.scala create mode 100644 integrated-pipeline/src/test/scala/eu/nomad_lab/integrated_pipeline_tests/helpers/LoggingTestBase.scala diff --git a/integrated-pipeline/src/test/scala/eu/nomad_lab/integrated_pipeline_end_to_end_tests/LoggingTestAsyncWrapper.scala b/integrated-pipeline/src/test/scala/eu/nomad_lab/integrated_pipeline_end_to_end_tests/LoggingTestAsyncWrapper.scala new file mode 100644 index 00000000..421d21d0 --- /dev/null +++ b/integrated-pipeline/src/test/scala/eu/nomad_lab/integrated_pipeline_end_to_end_tests/LoggingTestAsyncWrapper.scala @@ -0,0 +1,19 @@ +package eu.nomad_lab.integrated_pipeline_end_to_end_tests + +import eu.nomad_lab.integrated_pipeline_tests.helpers.LoggingTestBase +import org.scalatest.{ FutureOutcome, fixture } + +trait LoggingTestAsyncWrapper extends fixture.AsyncWordSpec with LoggingTestBase { + + override protected[this] val appenderName: String = "ParsingModule-EndToEndTests" + + def withFixture(test: OneArgAsyncTest): FutureOutcome = { + val logMessages = addAppender() + complete { + withFixture(test.toNoArgAsyncTest(logMessages)) + } lastly { + purgeConfiguration() + } + } + +} diff --git a/integrated-pipeline/src/test/scala/eu/nomad_lab/integrated_pipeline_end_to_end_tests/UnderDevelopment.scala b/integrated-pipeline/src/test/scala/eu/nomad_lab/integrated_pipeline_end_to_end_tests/UnderDevelopment.scala index c017e0b2..093d10d0 100644 --- a/integrated-pipeline/src/test/scala/eu/nomad_lab/integrated_pipeline_end_to_end_tests/UnderDevelopment.scala +++ b/integrated-pipeline/src/test/scala/eu/nomad_lab/integrated_pipeline_end_to_end_tests/UnderDevelopment.scala @@ -1,13 +1,9 @@ package eu.nomad_lab.integrated_pipeline_end_to_end_tests -import java.io.ByteArrayOutputStream - import eu.nomad_lab.TreeType import eu.nomad_lab.integrated_pipeline.{ Main, OutputType } -import org.scalatest.{ AsyncWordSpec, Matchers } import eu.nomad_lab.integrated_pipeline_tests.{ EndToEnd, PendingEndToEnd } - -import scala.util.Properties +import org.scalatest.Matchers /** * This Test Suite contains the End-to-End tests for the Integrated Pipeline that are not yet @@ -16,21 +12,16 @@ import scala.util.Properties * These tests validate some basic assumptions on the generated output, but the queries made are * simple enough to assume that the tests are independent of the parser versions. */ -class UnderDevelopment extends AsyncWordSpec with Matchers { +class UnderDevelopment extends LoggingTestAsyncWrapper with Matchers { "The Integrated Pipeline" when { "invoked in console mode" should { - "skip parse requests for non-existent file tree and log a warning" taggedAs (EndToEnd, PendingEndToEnd) in { + "skip parse requests for non-existent file tree and log a warning" taggedAs (EndToEnd, PendingEndToEnd) in { log => val f = new NonExistingTreeFixture(TreeType.Directory, OutputType.Json) - val output = new ByteArrayOutputStream() - Console.withOut(output) { - val finished = Main.mainWithFuture(f.generateConsoleArgumentList(Some(info))) - finished.map { _ => - //TODO: is it worth the effort to have a streaming implementation here? - val lines = output.toString.split(Properties.lineSeparator) - atLeast(1, lines) should (include("purely-imaginary") and include("not exist") - and include("skipping file tree")) - } + val finished = Main.mainWithFuture(f.generateConsoleArgumentList(Some(info))) + finished.map { _ => + atLeast(1, log.getLogMessages()) should (include("purely-imaginary") + and include("not exist") and include("skipping file tree")) } } } diff --git a/integrated-pipeline/src/test/scala/eu/nomad_lab/integrated_pipeline_end_to_end_tests/package.scala b/integrated-pipeline/src/test/scala/eu/nomad_lab/integrated_pipeline_end_to_end_tests/package.scala index 2460353e..2881e6c1 100644 --- a/integrated-pipeline/src/test/scala/eu/nomad_lab/integrated_pipeline_end_to_end_tests/package.scala +++ b/integrated-pipeline/src/test/scala/eu/nomad_lab/integrated_pipeline_end_to_end_tests/package.scala @@ -1,6 +1,6 @@ package eu.nomad_lab -import java.nio.file.{ Path, Paths } +import java.nio.file.Path import eu.nomad_lab.JsonSupport.formats import eu.nomad_lab.TreeType.TreeType diff --git a/integrated-pipeline/src/test/scala/eu/nomad_lab/integrated_pipeline_tests/helpers/LoggingTestBase.scala b/integrated-pipeline/src/test/scala/eu/nomad_lab/integrated_pipeline_tests/helpers/LoggingTestBase.scala new file mode 100644 index 00000000..c3f6219b --- /dev/null +++ b/integrated-pipeline/src/test/scala/eu/nomad_lab/integrated_pipeline_tests/helpers/LoggingTestBase.scala @@ -0,0 +1,52 @@ +package eu.nomad_lab.integrated_pipeline_tests.helpers + +import java.io.{ ByteArrayOutputStream, OutputStream } + +import org.apache.logging.log4j.core.LoggerContext +import org.apache.logging.log4j.core.appender.OutputStreamAppender +import org.apache.logging.log4j.core.layout.PatternLayout + +import scala.util.Properties + +/** + * Helper trait for testing log4j2 based logging implementations, the functions provided here can + * be used to append the logged messages to a ByteArray for inspection after the test code ran. + * This is an isolated trait because we have to provide this functionality both for synchronous + * and asynchronous ScalaTest suites. + */ +trait LoggingTestBase { + + //TODO: consider a streaming implementation if the logging volume becomes significant + + type FixtureParam = LoggingOutput + + protected[this] val appenderName: String + + def addAppender(): LoggingOutput = { + val rawBytes = new ByteArrayOutputStream() + val context = LoggerContext.getContext(false) + val config = context.getConfiguration + val layout = PatternLayout.newBuilder().withPattern("%d{HH:mm:ss.SSS} %-5level - %msg%n").build() + val appender = OutputStreamAppender.createAppender(layout, null, rawBytes, appenderName, false, true) + appender.start() + config.addAppender(appender) + val loggerConfig = config.getLoggerConfig("eu.nomad_lab") + val (level, filter) = (null, null) + loggerConfig.addAppender(appender, level, filter) + new LoggingOutput(rawBytes) + } + + def purgeConfiguration(): Unit = { + val context = LoggerContext.getContext(false) + context.reconfigure() + } + + class LoggingOutput(private val byteStream: ByteArrayOutputStream) { + + def getLogMessages(): Seq[String] = { + val output = byteStream.toString + byteStream.reset() + output.split(Properties.lineSeparator) + } + } +} -- GitLab