blob: 2487b657e916a6f1009a95a0a8f2eef1fcc9c1c7 [file] [log] [blame]
package org.apache.logging.log4j.layout.json.template;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.assertj.core.api.Assertions;
import org.awaitility.Awaitility;
import org.junit.Test;
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.time.Duration;
public class JsonTemplateLayoutNullEventDelimiterTest {
// Set the configuration.
static {
System.setProperty(
"log4j.configurationFile",
"nullEventDelimitedJsonTemplateLayoutLogging.xml");
}
// Note that this port is hardcoded in the configuration file too!
private static final int PORT = 50514;
@Test
public void test() throws Exception {
// Set the expected bytes.
final byte[] expectedBytes = {
'"', 'f', 'o', 'o', '"', '\0',
'"', 'b', 'a', 'r', '"', '\0'
};
// Start the TCP server.
try (final TcpServer server = new TcpServer(PORT)) {
// Produce log events.
final Logger logger = LogManager.getLogger(JsonTemplateLayoutNullEventDelimiterTest.class);
logger.log(Level.INFO, "foo");
logger.log(Level.INFO, "bar");
// Wait for the log events.
Awaitility
.await()
.atMost(Duration.ofSeconds(10))
.pollDelay(Duration.ofSeconds(2))
.until(() -> server.getTotalReadByteCount() >= expectedBytes.length);
// Verify the received log events.
final byte[] actualBytes = server.getReceivedBytes();
Assertions.assertThat(actualBytes).startsWith(expectedBytes);
}
}
private static final class TcpServer extends Thread implements AutoCloseable {
private final ServerSocket serverSocket;
private final ByteArrayOutputStream outputStream;
private volatile int totalReadByteCount = 0;
private volatile boolean closed = false;
private TcpServer(final int port) throws IOException {
this.serverSocket = new ServerSocket(port);
this.outputStream = new ByteArrayOutputStream();
serverSocket.setReuseAddress(true);
serverSocket.setSoTimeout(5_000);
setDaemon(true);
start();
}
@Override
public void run() {
try {
try (final Socket socket = serverSocket.accept()) {
final InputStream inputStream = socket.getInputStream();
final byte[] buffer = new byte[1024];
// noinspection InfiniteLoopStatement
while (true) {
final int readByteCount = inputStream.read(buffer);
if (readByteCount > 0) {
synchronized (this) {
totalReadByteCount += readByteCount;
outputStream.write(buffer, 0, readByteCount);
}
}
}
}
} catch (final EOFException ignored) {
// Socket is closed.
} catch (final Exception error) {
if (!closed) {
throw new RuntimeException(error);
}
}
}
public synchronized byte[] getReceivedBytes() {
return outputStream.toByteArray();
}
public synchronized int getTotalReadByteCount() {
return totalReadByteCount;
}
@Override
public synchronized void close() throws InterruptedException {
if (closed) {
throw new IllegalStateException("shutdown has already been invoked");
}
closed = true;
interrupt();
join(3_000L);
}
}
}