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 0000000000000000000000000000000000000000..421d21d0dbda5703c32a5aa246d663d12692d1cb --- /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 c017e0b271c2bfc515a712126391dff476d2a837..093d10d07d497a97831bb1f401826f77e1b11a6d 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 2460353e31d7bea6d2ea844b3648392e762f9fe6..2881e6c144d3610ba0dc60fafc7d26c4ba2cc1c8 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 0000000000000000000000000000000000000000..c3f6219b2b63d888ab5881c0dd2304ee2b70a3a3 --- /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) + } + } +}