This commit is contained in:
2024-11-30 19:03:49 +08:00
commit 1e6763c160
3806 changed files with 737676 additions and 0 deletions

View File

@@ -0,0 +1,136 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.juli;
import java.io.File;
import java.util.Collections;
import java.util.Random;
import java.util.logging.LogManager;
import java.util.logging.Logger;
import org.junit.Assert;
import org.junit.Test;
/**
* Test cases for {@link ClassLoaderLogManager}.
*/
public class TestClassLoaderLogManager {
@Test
public void testReplace() {
ClassLoaderLogManager logManager = new ClassLoaderLogManager();
Assert.assertEquals("", logManager.replace(""));
Assert.assertEquals("${", logManager.replace("${"));
Assert.assertEquals("${undefinedproperty}", logManager.replace("${undefinedproperty}"));
Assert.assertEquals(
System.lineSeparator() + File.pathSeparator + File.separator,
logManager.replace("${line.separator}${path.separator}${file.separator}"));
Assert.assertEquals(
"foo" + File.separator + "bar" + System.lineSeparator() + File.pathSeparator + "baz",
logManager.replace("foo${file.separator}bar${line.separator}${path.separator}baz"));
// BZ 51249
Assert.assertEquals(
"%{file.separator}" + File.separator,
logManager.replace("%{file.separator}${file.separator}"));
Assert.assertEquals(
File.separator + "${undefinedproperty}" + File.separator,
logManager.replace("${file.separator}${undefinedproperty}${file.separator}"));
Assert.assertEquals("${}" + File.pathSeparator, logManager.replace("${}${path.separator}"));
}
@Test
public void testBug56082() {
ClassLoaderLogManager logManager = new ClassLoaderLogManager();
LoggerCreateThread[] createThreads = new LoggerCreateThread[10];
for (int i = 0; i < createThreads.length; i ++) {
createThreads[i] = new LoggerCreateThread(logManager);
createThreads[i].setName("LoggerCreate-" + i);
createThreads[i].start();
}
LoggerListThread listThread = new LoggerListThread(logManager);
listThread.setName("LoggerList");
listThread.start();
try {
listThread.join(2000);
} catch (InterruptedException e) {
// Ignore
}
for (int i = 0; i < createThreads.length; i ++) {
createThreads[i].setRunning(false);
}
Assert.assertTrue(listThread.isRunning());
listThread.setRunning(false);
}
private static class LoggerCreateThread extends Thread {
private final LogManager logManager;
private volatile boolean running = true;
public LoggerCreateThread(LogManager logManager) {
this.logManager = logManager;
}
@Override
public void run() {
Random r = new Random();
while (running) {
Logger logger = Logger.getLogger("Bug56082-" + r.nextInt(100000));
logManager.addLogger(logger);
}
}
public void setRunning(boolean running) {
this.running = running;
}
}
private static class LoggerListThread extends Thread {
private final LogManager logManager;
private volatile boolean running = true;
public LoggerListThread(LogManager logManager) {
this.logManager = logManager;
}
@Override
public void run() {
while (running) {
try {
Collections.list(logManager.getLoggerNames());
} catch (Exception e) {
e.printStackTrace();
running = false;
}
}
}
public boolean isRunning() {
return running;
}
public void setRunning(boolean running) {
this.running = running;
}
}
}

View File

@@ -0,0 +1,109 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.juli;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
import org.junit.Assert;
import org.junit.Test;
public class TestDateFormatCache {
// Note that there is a similar test:
// org.apache.catalina.valves.TestAccessLogValve.testBug54044()
@Test
public void testBug54044() throws Exception {
final String timeFormat = "dd-MMM-yyyy HH:mm:ss";
final int cacheSize = 10;
SimpleDateFormat sdf = new SimpleDateFormat(timeFormat, Locale.US);
sdf.setTimeZone(TimeZone.getDefault());
DateFormatCache dfc = new DateFormatCache(cacheSize, timeFormat, null);
// Get dfc.cache.cache field
Object dfcCache;
Field dfcCacheArray;
Field dfcCacheField = dfc.getClass().getDeclaredField("cache");
dfcCacheField.setAccessible(true);
dfcCache = dfcCacheField.get(dfc);
dfcCacheArray = dfcCache.getClass().getDeclaredField("cache");
dfcCacheArray.setAccessible(true);
// Create an array to hold the expected values
String[] expected = new String[cacheSize];
// Fill the cache & populate the expected values
for (int secs = 0; secs < (cacheSize); secs++) {
dfc.getFormat(secs * 1000);
expected[secs] = generateExpected(sdf, secs);
}
Assert.assertArrayEquals(expected,
(String[]) dfcCacheArray.get(dfcCache));
// Cause the cache to roll-around by one and then confirm
dfc.getFormat(cacheSize * 1000);
expected[0] = generateExpected(sdf, cacheSize);
Assert.assertArrayEquals(expected,
(String[]) dfcCacheArray.get(dfcCache));
// Jump 2 ahead and then confirm (skipped value should be null)
dfc.getFormat((cacheSize + 2) * 1000);
expected[1] = null;
expected[2] = generateExpected(sdf, cacheSize + 2);
Assert.assertArrayEquals(expected,
(String[]) dfcCacheArray.get(dfcCache));
// Back 1 to fill in the gap
dfc.getFormat((cacheSize + 1) * 1000);
expected[1] = generateExpected(sdf, cacheSize + 1);
Assert.assertArrayEquals(expected,
(String[]) dfcCacheArray.get(dfcCache));
// Return to 1 and confirm skipped value is null
dfc.getFormat(1 * 1000);
expected[1] = generateExpected(sdf, 1);
expected[2] = null;
Assert.assertArrayEquals(expected,
(String[]) dfcCacheArray.get(dfcCache));
// Go back one further
dfc.getFormat(0);
expected[0] = generateExpected(sdf, 0);
Assert.assertArrayEquals(expected,
(String[]) dfcCacheArray.get(dfcCache));
// Jump ahead far enough that the entire cache will need to be cleared
dfc.getFormat(42 * 1000);
for (int i = 0; i < cacheSize; i++) {
expected[i] = null;
}
expected[0] = generateExpected(sdf, 42);
Assert.assertArrayEquals(expected,
(String[]) dfcCacheArray.get(dfcCache));
}
private String generateExpected(SimpleDateFormat sdf, long secs) {
return sdf.format(new Date(secs * 1000));
}
}

View File

@@ -0,0 +1,135 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.juli;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class TestFileHandler {
private static final String PREFIX_1 = "localhost.";
private static final String PREFIX_2 = "test.";
private static final String PREFIX_3 = "";
private static final String PREFIX_4 = "localhost1";
private static final String SUFIX_1 = ".log";
private static final String SUFIX_2 = ".txt";
private File logsDir;
@Before
public void setUp() throws Exception {
File logsBase = new File(System.getProperty("tomcat.test.temp", "output/tmp"));
if (!logsBase.mkdirs() && !logsBase.isDirectory()) {
Assert.fail("Unable to create logs directory.");
}
Path logsBasePath = FileSystems.getDefault().getPath(logsBase.getAbsolutePath());
logsDir = Files.createTempDirectory(logsBasePath, "test").toFile();
generateLogFiles(logsDir, PREFIX_1, SUFIX_2, 3);
generateLogFiles(logsDir, PREFIX_2, SUFIX_1, 3);
generateLogFiles(logsDir, PREFIX_3, SUFIX_1, 3);
generateLogFiles(logsDir, PREFIX_4, SUFIX_1, 3);
Calendar date = Calendar.getInstance();
date.add(Calendar.DAY_OF_MONTH, -3);
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH-mm-ss.SSS");
File file = new File(logsDir, PREFIX_1 + formatter.format(date.getTime()) + SUFIX_1);
if (!file.createNewFile()) {
Assert.fail("Unable to create " + file.getAbsolutePath());
}
}
@After
public void tearDown() {
File[] files = logsDir.listFiles();
if (files != null) {
for (File file : files) {
Assert.assertTrue("Failed to delete [" + file + "]", file.delete());
}
Assert.assertTrue("Failed to create [" + logsDir + "]", logsDir.delete());
}
}
@Test
public void testCleanOnInitOneHandler() throws Exception {
generateLogFiles(logsDir, PREFIX_1, SUFIX_1, 3);
FileHandler fh1 = new FileHandler(logsDir.getAbsolutePath(), PREFIX_1, SUFIX_1, 2);
Thread.sleep(1000);
Assert.assertTrue(logsDir.list().length == 16);
fh1.close();
}
@Test
public void testCleanOnInitMultipleHandlers() throws Exception {
generateLogFiles(logsDir, PREFIX_1, SUFIX_1, 3);
FileHandler fh1 = new FileHandler(logsDir.getAbsolutePath(), PREFIX_1, SUFIX_1, 2);
FileHandler fh2 = new FileHandler(logsDir.getAbsolutePath(), PREFIX_1, SUFIX_2, 2);
FileHandler fh3 = new FileHandler(logsDir.getAbsolutePath(), PREFIX_2, SUFIX_1, 2);
FileHandler fh4 = new FileHandler(logsDir.getAbsolutePath(), PREFIX_3, SUFIX_1, 2);
Thread.sleep(1000);
Assert.assertTrue(logsDir.list().length == 16);
fh1.close();
fh2.close();
fh3.close();
fh4.close();
}
@Test
public void testCleanDisabled() throws Exception {
generateLogFiles(logsDir, PREFIX_1, SUFIX_1, 3);
FileHandler fh1 = new FileHandler(logsDir.getAbsolutePath(), PREFIX_1, SUFIX_1, -1);
Thread.sleep(1000);
Assert.assertTrue(logsDir.list().length == 17);
fh1.close();
}
private void generateLogFiles(File dir, String prefix, String sufix, int amount)
throws IOException {
Calendar cal = Calendar.getInstance();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
for (int i = 0; i < amount; i++) {
cal.add(Calendar.DAY_OF_MONTH, -1);
File file = new File(dir, prefix + formatter.format(cal.getTime()) + sufix);
if (!file.createNewFile()) {
Assert.fail("Unable to create " + file.getAbsolutePath());
}
}
}
}

View File

@@ -0,0 +1,80 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.juli;
import java.io.File;
import java.net.URLDecoder;
import org.junit.After;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.apache.catalina.startup.LoggingBaseTest;
public class TestFileHandlerNonRotatable extends LoggingBaseTest {
private FileHandler testHandler;
@BeforeClass
public static void setUpPerTestClass() throws Exception {
LoggingBaseTest.setUpPerTestClass();
System.setProperty("java.util.logging.manager",
"org.apache.juli.ClassLoaderLogManager");
String configLoggingPath = TestFileHandlerNonRotatable.class
.getResource("logging-non-rotatable.properties")
.getFile();
System.setProperty("java.util.logging.config.file",
URLDecoder.decode(configLoggingPath, java.nio.charset.StandardCharsets.UTF_8.toString()));
}
@Override
@After
public void tearDown() throws Exception {
if (testHandler != null) {
testHandler.close();
}
super.tearDown();
}
@Test
public void testBug61232() throws Exception {
testHandler = new FileHandler(this.getTemporaryDirectory().toString(),
"juli.", ".log");
File logFile = new File(this.getTemporaryDirectory(), "juli.log");
Assert.assertTrue(logFile.exists());
}
@Test
public void testCustomSuffixWithoutSeparator() throws Exception {
testHandler = new FileHandler(this.getTemporaryDirectory().toString(),
"juli.", "log");
File logFile = new File(this.getTemporaryDirectory(), "juli.log");
Assert.assertTrue(logFile.exists());
}
@Test
public void testCustomPrefixWithoutSeparator() throws Exception {
testHandler = new FileHandler(this.getTemporaryDirectory().toString(),
"juli", ".log");
File logFile = new File(this.getTemporaryDirectory(), "juli.log");
Assert.assertTrue(logFile.exists());
}
}

View File

@@ -0,0 +1,16 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
org.apache.juli.FileHandler.rotatable = false