diff --git a/src/integrationTest/java/org/opensearch/security/http/JwtAuthenticationTests.java b/src/integrationTest/java/org/opensearch/security/http/JwtAuthenticationTests.java
index 7f5d21ea58..bf8af72854 100644
--- a/src/integrationTest/java/org/opensearch/security/http/JwtAuthenticationTests.java
+++ b/src/integrationTest/java/org/opensearch/security/http/JwtAuthenticationTests.java
@@ -39,6 +39,7 @@
import org.opensearch.test.framework.cluster.TestRestClient.HttpResponse;
import org.opensearch.test.framework.log.LogsRule;
+import static java.nio.charset.StandardCharsets.US_ASCII;
import static org.apache.http.HttpHeaders.AUTHORIZATION;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsInAnyOrder;
@@ -89,7 +90,7 @@ public class JwtAuthenticationTests {
public static final String QA_SONG_INDEX_NAME = String.format("song_lyrics_%s", QA_DEPARTMENT);
private static final KeyPair KEY_PAIR = Keys.keyPairFor(SignatureAlgorithm.RS256);
- private static final String PUBLIC_KEY = new String(Base64.getEncoder().encode(KEY_PAIR.getPublic().getEncoded()));
+ private static final String PUBLIC_KEY = new String(Base64.getEncoder().encode(KEY_PAIR.getPublic().getEncoded()), US_ASCII);
static final TestSecurityConfig.User ADMIN_USER = new TestSecurityConfig.User("admin").roles(ALL_ACCESS);
@@ -186,7 +187,7 @@ public void shouldAuthenticateWithJwtToken_failureIncorrectFormatOfToken() {
HttpResponse response = client.getAuthInfo();
response.assertStatusCode(401);
- logsRule.assertThatContain(String.format("No JWT token found in '%s' header.", JWT_AUTH_HEADER));
+ logsRule.assertThatContain(String.format("No JWT token found in '%s' header header", JWT_AUTH_HEADER));
}
}
diff --git a/src/integrationTest/java/org/opensearch/test/framework/log/LogCapturingAppender.java b/src/integrationTest/java/org/opensearch/test/framework/log/LogCapturingAppender.java
index 83baf031c7..11a59f470d 100644
--- a/src/integrationTest/java/org/opensearch/test/framework/log/LogCapturingAppender.java
+++ b/src/integrationTest/java/org/opensearch/test/framework/log/LogCapturingAppender.java
@@ -33,24 +33,53 @@
import static org.opensearch.test.framework.log.LogCapturingAppender.PLUGIN_NAME;
+/**
+*
The class acts as Log4j2 appender with a special purpose. The appender is used to capture logs which are generated during tests and
+* then test can examine logs. To use the appender it is necessary to:
+*
+* - Add package with appender to log4j2 package scan in Log4j2 configuration file
+* - Create appender in log4j2 configuration
+* - Assign required loggers to appender
+* - Enable appender for certain classes with method {@link #enable(String...)}. Each test can enable appender for distinct classes
+*
+*/
@Plugin(name = PLUGIN_NAME, category = Core.CATEGORY_NAME, elementType = Appender.ELEMENT_TYPE, printObject = true)
public class LogCapturingAppender extends AbstractAppender {
public final static String PLUGIN_NAME = "LogCapturingAppender";
+ /**
+ * Appender stores only last MAX_SIZE
messages to avoid excessive RAM memory usage.
+ */
public static final int MAX_SIZE = 100;
+
+ /**
+ * Buffer for captured log messages
+ */
private static final Buffer messages = BufferUtils.synchronizedBuffer(new CircularFifoBuffer(MAX_SIZE));
+ /**
+ * Log messages are stored in buffer {@link #messages} only for classes which are added to the {@link #activeLoggers} set.
+ */
private static final Set activeLoggers = Collections.synchronizedSet(new HashSet<>());
protected LogCapturingAppender(String name, Filter filter, Layout extends Serializable> layout, boolean ignoreExceptions, Property[] properties) {
super(name, filter, layout, ignoreExceptions, properties);
}
+ /**
+ * Method used by Log4j2 to create appender
+ * @param name appender name from Log4j2 configuration
+ * @return newly created appender
+ */
@PluginFactory
public static LogCapturingAppender createAppender(@PluginAttribute(value = "name", defaultString = "logCapturingAppender") String name) {
return new LogCapturingAppender(name, null, null, true, Property.EMPTY_ARRAY);
}
+ /**
+ * Method invoked by Log4j2 to append log events
+ * @param event The LogEvent, represents log message.
+ */
@Override
public void append(LogEvent event) {
String loggerName = event.getLoggerName();
@@ -60,16 +89,27 @@ public void append(LogEvent event) {
}
}
+ /**
+ * To collect log messages form given logger the logger name must be passed to {@link #enable(String...)} method.
+ * @param loggerNames logger names
+ */
public static void enable(String...loggerNames) {
disable();
activeLoggers.addAll(Arrays.asList(loggerNames));
}
+ /**
+ * Invocation cause that appender stops collecting log messages. Additionally, memory used by collected messages so far is released.
+ */
public static void disable() {
activeLoggers.clear();
messages.clear();
}
+ /**
+ * Is used to obtain gathered log messages
+ * @return Log messages
+ */
public static List getLogMessages() {
return new ArrayList<>(messages);
}
diff --git a/src/integrationTest/java/org/opensearch/test/framework/log/LogsRule.java b/src/integrationTest/java/org/opensearch/test/framework/log/LogsRule.java
index 4a0b35dd36..34fe6f4455 100644
--- a/src/integrationTest/java/org/opensearch/test/framework/log/LogsRule.java
+++ b/src/integrationTest/java/org/opensearch/test/framework/log/LogsRule.java
@@ -18,10 +18,20 @@
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasItem;
+/**
+* The class is a JUnit 4 rule and enables developers to write assertion related to log messages generated in the course of test. To use
+* {@link LogsRule} appender {@link LogCapturingAppender} must be properly configured. The rule also manages {@link LogCapturingAppender}
+* so that memory occupied by gathered log messages is released after each test.
+*/
public class LogsRule extends ExternalResource {
private final String[] loggerNames;
+ /**
+ * Constructor used to start gathering log messages from certain loggers
+ * @param loggerNames Loggers names. Log messages are collected only if the log message is associated with the logger with a name which
+ * is present in loggerNames
parameter.
+ */
public LogsRule(String...loggerNames) {
this.loggerNames = Objects.requireNonNull(loggerNames, "Logger names are required");
}
@@ -36,6 +46,10 @@ protected void after() {
LogCapturingAppender.disable();
}
+ /**
+ * Check if during the tests certain log message was logged
+ * @param expectedLogMessage expected log message
+ */
public void assertThatContain(String expectedLogMessage) {
List messages = LogCapturingAppender.getLogMessages();
String reason = reasonMessage(expectedLogMessage, messages);