Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve LogBackTester interface #620

Merged
merged 9 commits into from
Nov 29, 2023
49 changes: 48 additions & 1 deletion src/test/java/emissary/test/core/junit5/LogbackTester.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,20 @@
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.spi.IThrowableProxy;
import ch.qos.logback.core.read.ListAppender;
import org.apache.commons.lang3.Validate;
import org.slf4j.LoggerFactory;

import java.io.Closeable;
import java.io.IOException;
import java.util.List;
import java.util.Optional;
import javax.annotation.Nullable;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;

public class LogbackTester implements Closeable {
public final String name;
Expand All @@ -30,6 +36,34 @@ public LogbackTester(final String name) {
logger.setAdditive(false);
}

public void checkLogList(List<SimplifiedLogEvent> events) {
Validate.notNull(events, "Required: events != null");

assertEquals(events.size(), appender.list.size(), "Expected event count does not match actual event count");

for (int i = 0; i < appender.list.size(); i++) {
final ILoggingEvent item = appender.list.get(i);
final SimplifiedLogEvent event = events.get(i);
assertEquals(event.level, item.getLevel(), "Levels not equal for element " + i);
assertEquals(event.message, item.getFormattedMessage(), "Messages not equal for element " + i);
if (event.throwable.isEmpty()) {
assertNull(item.getThrowableProxy(), "Expected no exception for element " + i);
} else {
assertNotNull(item.getThrowableProxy(), "Expected an exception for element " + i);
Throwable expected = event.throwable.get();
IThrowableProxy proxy = item.getThrowableProxy();
assertEquals(expected.getClass().getName(), proxy.getClassName(), "Exception class name not equal for element " + i);
assertEquals(expected.getLocalizedMessage(), proxy.getMessage(), "Exception message not equal for element " + i);
}

}
}


/**
* @deprecated Consider using the {@link #checkLogList(List)} overload instead of this version
*/
@Deprecated
public void checkLogList(final Level[] levels, final String[] messages, final boolean[] throwables) {
nixon124 marked this conversation as resolved.
Show resolved Hide resolved
Validate.notNull(levels, "Required: levels != null");
Validate.notNull(messages, "Required: messages != null");
Expand All @@ -44,12 +78,25 @@ public void checkLogList(final Level[] levels, final String[] messages, final bo

assertEquals(levels[i], item.getLevel(), "Levels not equal for element " + i);
assertEquals(messages[i], item.getFormattedMessage(), "Messages not equal for element " + i);
assertEquals(throwables[i], item.getThrowableProxy() != null, "Throwables not equal for elmeent " + i);
assertEquals(throwables[i], item.getThrowableProxy() != null, "Throwables not equal for element " + i);
}
}

@Override
public void close() throws IOException {
logger.detachAndStopAllAppenders();
}

public static class SimplifiedLogEvent {
public final Level level;
public final String message;
public final Optional<? extends Throwable> throwable;

public SimplifiedLogEvent(Level level, String message, @Nullable Throwable throwable) {
this.level = level;
this.message = message;
this.throwable = Optional.ofNullable(throwable);
}
}

}
102 changes: 102 additions & 0 deletions src/test/java/emissary/test/core/junit5/LogbackTesterTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package emissary.test.core.junit5;

import ch.qos.logback.classic.Level;
import org.junit.jupiter.api.Test;
import org.opentest4j.AssertionFailedError;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;

import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class LogbackTesterTest extends UnitTest {
protected Logger logger = LoggerFactory.getLogger("TESTY");

@Test
void canCreateTester() {
LogbackTester logBackTester = new LogbackTester(logger.getName());
assertNotNull(logBackTester);
}

@Test
void canCheckSingleEvent() {
LogbackTester logBackTester = new LogbackTester(logger.getName());
assertNotNull(logBackTester);
List<LogbackTester.SimplifiedLogEvent> events = new ArrayList<>();
LogbackTester.SimplifiedLogEvent event2 = new LogbackTester.SimplifiedLogEvent(Level.WARN, "Not good news.", new Exception("worse news"));
events.add(event2);
logger.warn("Not good news.", new Exception("worse news"));
assertDoesNotThrow(() -> logBackTester.checkLogList(events));
}

@Test
void canDetectWrongMessage() {
LogbackTester logBackTester = new LogbackTester(logger.getName());
assertNotNull(logBackTester, "Expected tester to not be null.");
List<LogbackTester.SimplifiedLogEvent> events = new ArrayList<>();
LogbackTester.SimplifiedLogEvent event2 = new LogbackTester.SimplifiedLogEvent(Level.WARN, "Wrong Message.", new Exception("worse news"));
events.add(event2);
logger.warn("Not good news.", new Exception("worse news"));
AssertionFailedError thrownException =
assertThrows(AssertionFailedError.class, () -> logBackTester.checkLogList(events), "Expected an exception.");
assertTrue(thrownException.getMessage().startsWith("Messages not equal"));
}

@Test
void canDetectWrongLevel() {
LogbackTester logBackTester = new LogbackTester(logger.getName());
assertNotNull(logBackTester, "Expected tester to not be null.");
List<LogbackTester.SimplifiedLogEvent> events = new ArrayList<>();
LogbackTester.SimplifiedLogEvent event3 = new LogbackTester.SimplifiedLogEvent(Level.INFO, "Not good news.", new Exception("worse news"));
events.add(event3);
logger.warn("Not good news.", new Exception("worse news"));
AssertionFailedError thrownException =
assertThrows(AssertionFailedError.class, () -> logBackTester.checkLogList(events), "Expected an exception.");
assertTrue(thrownException.getMessage().startsWith("Levels not equal"));
}

@Test
void canDetectWrongThrowable() {
LogbackTester logBackTester = new LogbackTester(logger.getName());
assertNotNull(logBackTester, "Expected tester to not be null.");
List<LogbackTester.SimplifiedLogEvent> events = new ArrayList<>();
LogbackTester.SimplifiedLogEvent event4 = new LogbackTester.SimplifiedLogEvent(Level.WARN, "Not good news.", new Exception("something"));
events.add(event4);
logger.warn("Not good news.", new Throwable("worse news"));
AssertionFailedError thrownException =
assertThrows(AssertionFailedError.class, () -> logBackTester.checkLogList(events), "Expected an exception.");
assertTrue(thrownException.getMessage().startsWith("Exception class name not"));
}

@Test
void canDetectWrongThrowableMessage() {
LogbackTester logBackTester = new LogbackTester(logger.getName());
assertNotNull(logBackTester, "Expected tester to not be null.");
List<LogbackTester.SimplifiedLogEvent> events = new ArrayList<>();
LogbackTester.SimplifiedLogEvent event4 = new LogbackTester.SimplifiedLogEvent(Level.WARN, "Not good news.", new Exception("something"));
events.add(event4);
logger.warn("Not good news.", new Exception("worse news"));
AssertionFailedError thrownException =
assertThrows(AssertionFailedError.class, () -> logBackTester.checkLogList(events), "Expected an exception.");
assertTrue(thrownException.getMessage().startsWith("Exception message not equal for"), thrownException.getMessage());
}

@Test
void canCheckOneEvent() {
LogbackTester logBackTester = new LogbackTester(logger.getName());
assertNotNull(logBackTester);
boolean[] throwing = new boolean[1];
String[] messages = new String[1];
Level[] levels = new Level[1];
levels[0] = Level.WARN;
messages[0] = "Not good news.";
throwing[0] = false;
logger.warn("Not good news.");
logBackTester.checkLogList(levels, messages, throwing);
}
}