diff options
Diffstat (limited to 'container-core/src/test/java/com/yahoo/container/logging/LogFileHandlerTestCase.java')
-rw-r--r-- | container-core/src/test/java/com/yahoo/container/logging/LogFileHandlerTestCase.java | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/container-core/src/test/java/com/yahoo/container/logging/LogFileHandlerTestCase.java b/container-core/src/test/java/com/yahoo/container/logging/LogFileHandlerTestCase.java new file mode 100644 index 00000000000..dad8f5e3f90 --- /dev/null +++ b/container-core/src/test/java/com/yahoo/container/logging/LogFileHandlerTestCase.java @@ -0,0 +1,208 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.container.logging; + +import com.yahoo.compress.ZstdCompressor; +import com.yahoo.container.logging.LogFileHandler.Compression; +import com.yahoo.io.IOUtils; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.function.BiFunction; +import java.util.logging.Formatter; +import java.util.logging.Level; +import java.util.logging.LogRecord; +import java.util.zip.GZIPInputStream; + +import static com.yahoo.yolean.Exceptions.uncheck; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertNotEquals; + +/** + * @author Bob Travis + * @author bjorncs + */ +public class LogFileHandlerTestCase { + + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); + + @Test + public void testIt() throws IOException { + File root = temporaryFolder.newFolder("logfilehandlertest"); + + String pattern = root.getAbsolutePath() + "/logfilehandlertest.%Y%m%d%H%M%S"; + long[] rTimes = {1000, 2000, 10000}; + LogFileHandler<String> h = new LogFileHandler<>(Compression.NONE, pattern, rTimes, null, 2048, "thread-name", new StringLogWriter()); + long now = System.currentTimeMillis(); + long millisPerDay = 60*60*24*1000; + long tomorrowDays = (now / millisPerDay) +1; + long tomorrowMillis = tomorrowDays * millisPerDay; + + assertThat(tomorrowMillis+1000).isEqualTo(h.logThread.getNextRotationTime(tomorrowMillis)); + assertThat(tomorrowMillis+10000).isEqualTo(h.logThread.getNextRotationTime(tomorrowMillis+3000)); + String message = "test"; + h.publish(message); + h.publish( "another test"); + h.rotateNow(); + h.publish(message); + h.flush(); + h.shutdown(); + } + + @Test + public void testSimpleLogging() throws IOException { + File logFile = temporaryFolder.newFile("testLogFileG1.txt"); + + //create logfilehandler + LogFileHandler<String> h = new LogFileHandler<>(Compression.NONE, logFile.getAbsolutePath(), "0 5 ...", null, 2048, "thread-name", new StringLogWriter()); + + //write log + h.publish("testDeleteFileFirst1"); + h.flush(); + h.shutdown(); + } + + @Test + public void testDeleteFileDuringLogging() throws IOException { + File logFile = temporaryFolder.newFile("testLogFileG2.txt"); + + //create logfilehandler + LogFileHandler<String> h = new LogFileHandler<>(Compression.NONE, logFile.getAbsolutePath(), "0 5 ...", null, 2048, "thread-name", new StringLogWriter()); + + //write log + h.publish("testDeleteFileDuringLogging1"); + h.flush(); + + //delete log file + logFile.delete(); + + //write log again + h.publish("testDeleteFileDuringLogging2"); + h.flush(); + h.shutdown(); + } + + @Test(timeout = /*5 minutes*/300_000) + public void testSymlink() throws IOException, InterruptedException { + File root = temporaryFolder.newFolder("testlogforsymlinkchecking"); + Formatter formatter = new Formatter() { + public String format(LogRecord r) { + DateFormat df = new SimpleDateFormat("yyyy.MM.dd:HH:mm:ss.SSS"); + String timeStamp = df.format(new Date(r.getMillis())); + return ("[" + timeStamp + "]" + " " + formatMessage(r)); + } + }; + LogFileHandler<String> handler = new LogFileHandler<>( + Compression.NONE, root.getAbsolutePath() + "/logfilehandlertest.%Y%m%d%H%M%S%s", new long[]{0}, "symlink", 2048, "thread-name", new StringLogWriter()); + + String message = formatter.format(new LogRecord(Level.INFO, "test")); + handler.publishAndWait(message); + String firstFile = handler.getFileName(); + handler.rotateNow(); + String secondFileName = handler.getFileName(); + assertNotEquals(firstFile, secondFileName); + + String longMessage = formatter.format(new LogRecord(Level.INFO, "string which is way longer than the word test")); + handler.publish(longMessage); + handler.flush(); + assertThat(Files.size(Paths.get(firstFile))).isEqualTo(31); + final long expectedSecondFileLength = 72; + + long symlinkFileLength = Files.size(root.toPath().resolve("symlink")); + assertThat(symlinkFileLength).isEqualTo(expectedSecondFileLength); + handler.shutdown(); + } + + @Test(timeout = /*5 minutes*/300_000) + public void compresses_previous_log_file() throws InterruptedException, IOException { + File root = temporaryFolder.newFolder("compressespreviouslogfile"); + LogFileHandler<String> firstHandler = new LogFileHandler<>( + Compression.ZSTD, root.getAbsolutePath() + "/compressespreviouslogfile.%Y%m%d%H%M%S%s", new long[]{0}, "symlink", 2048, "thread-name", new StringLogWriter()); + firstHandler.publishAndWait("test"); + firstHandler.shutdown(); + + assertThat(Files.size(Paths.get(firstHandler.getFileName()))).isEqualTo(5); + assertThat(root.toPath().resolve("symlink").toRealPath().toString()).isEqualTo(firstHandler.getFileName()); + + LogFileHandler<String> secondHandler = new LogFileHandler<>( + Compression.ZSTD, root.getAbsolutePath() + "/compressespreviouslogfile.%Y%m%d%H%M%S%s", new long[]{0}, "symlink", 2048, "thread-name", new StringLogWriter()); + secondHandler.publishAndWait("test"); + secondHandler.rotateNow(); + + assertThat(root.toPath().resolve("symlink").toRealPath().toString()).isEqualTo(secondHandler.getFileName()); + + while (Files.exists(root.toPath().resolve(firstHandler.getFileName()))) Thread.sleep(1); + + assertThat(Files.exists(Paths.get(firstHandler.getFileName() + ".zst"))).isTrue(); + secondHandler.shutdown(); + } + + @Test(timeout = /*5 minutes*/300_000) + public void testcompression_gzip() throws InterruptedException, IOException { + testcompression( + Compression.GZIP, "gz", + (compressedFile, __) -> uncheck(() -> new String(new GZIPInputStream(Files.newInputStream(compressedFile)).readAllBytes()))); + } + + @Test(timeout = /*5 minutes*/300_000) + public void testcompression_zstd() throws InterruptedException, IOException { + testcompression( + Compression.ZSTD, "zst", + (compressedFile, uncompressedSize) -> uncheck(() -> { + ZstdCompressor zstdCompressor = new ZstdCompressor(); + byte[] uncompressedBytes = new byte[uncompressedSize]; + byte[] compressedBytes = Files.readAllBytes(compressedFile); + zstdCompressor.decompress(compressedBytes, 0, compressedBytes.length, uncompressedBytes, 0, uncompressedBytes.length); + return new String(uncompressedBytes); + })); + } + + private void testcompression(Compression compression, + String fileExtension, + BiFunction<Path, Integer, String> decompressor) throws IOException, InterruptedException { + File root = temporaryFolder.newFolder("testcompression" + compression.name()); + + LogFileHandler<String> h = new LogFileHandler<>( + compression, root.getAbsolutePath() + "/logfilehandlertest.%Y%m%d%H%M%S%s", new long[]{0}, null, 2048, "thread-name", new StringLogWriter()); + int logEntries = 10000; + for (int i = 0; i < logEntries; i++) { + h.publish("test"); + } + h.flush(); + String f1 = h.getFileName(); + assertThat(f1).startsWith(root.getAbsolutePath() + "/logfilehandlertest."); + File uncompressed = new File(f1); + File compressed = new File(f1 + "." + fileExtension); + assertThat(uncompressed).exists(); + assertThat(compressed).doesNotExist(); + String content = IOUtils.readFile(uncompressed); + assertThat(content).hasLineCount(logEntries); + h.rotateNow(); + while (uncompressed.exists()) { + Thread.sleep(1); + } + assertThat(compressed).exists(); + String uncompressedContent = decompressor.apply(compressed.toPath(), content.getBytes().length); + assertThat(uncompressedContent).isEqualTo(content); + h.shutdown(); + } + + static class StringLogWriter implements LogWriter<String> { + + @Override + public void write(String record, OutputStream outputStream) throws IOException { + outputStream.write(record.getBytes(StandardCharsets.UTF_8)); + } + } +} |