Skip to content

Commit

Permalink
Merge branch 'fix/backport-log4j3-api' into 2.x-ppkarwasz
Browse files Browse the repository at this point in the history
  • Loading branch information
ppkarwasz committed Mar 18, 2024
2 parents 2666940 + e23a405 commit f526601
Show file tree
Hide file tree
Showing 39 changed files with 1,044 additions and 774 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* 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.logging.log4j.test.junit;

/**
* A set of tags for JUnit 5 tests.
*/
public final class Tags {

/**
* Marks tests that don't modify the global environment.
* <p>
* These tests can safely be run in parallel.
* </p>
*/
public static final String PARALLEL = "parallel";

private Tags() {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@
*/
public class TestProvider extends Provider {
public TestProvider() {
super(0, "2.6.0", TestLoggerContextFactory.class);
super(5, CURRENT_VERSION, TestLoggerContextFactory.class);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@
import static org.junit.jupiter.api.Assertions.fail;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import org.apache.logging.log4j.util.ReadOnlyStringMap;
import org.apache.logging.log4j.util.TriConsumer;
import org.junit.jupiter.api.Test;

Expand Down Expand Up @@ -238,32 +240,18 @@ public void testEqualsWhenOneValueDiffers() {

@Test
public void testForEachBiConsumer_JavaUtil() {
UnmodifiableArrayBackedMap map = UnmodifiableArrayBackedMap.EMPTY_MAP.copyAndPutAll(getTestParameters());
Set<String> keys = new HashSet<>();
java.util.function.BiConsumer<String, String> java_util_action =
new java.util.function.BiConsumer<String, String>() {
@Override
public void accept(String key, String value) {
keys.add(key);
}
};
map.forEach(java_util_action);
final Map<String, String> map = UnmodifiableArrayBackedMap.EMPTY_MAP.copyAndPutAll(getTestParameters());
final Collection<String> keys = new HashSet<>();
map.forEach((key, value) -> keys.add(key));
assertEquals(map.keySet(), keys);
}

@Test
public void testForEachBiConsumer_Log4jUtil() {
UnmodifiableArrayBackedMap map = UnmodifiableArrayBackedMap.EMPTY_MAP.copyAndPutAll(getTestParameters());
Set<String> keys = new HashSet<>();
org.apache.logging.log4j.util.BiConsumer<String, String> log4j_util_action =
new org.apache.logging.log4j.util.BiConsumer<String, String>() {
@Override
public void accept(String key, String value) {
keys.add(key);
}
};
map.forEach(log4j_util_action);
assertEquals(map.keySet(), keys);
final ReadOnlyStringMap map = UnmodifiableArrayBackedMap.EMPTY_MAP.copyAndPutAll(getTestParameters());
final Collection<String> keys = new HashSet<>();
map.forEach((key, value) -> keys.add(key));
assertEquals(map.toMap().keySet(), keys);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,8 @@

import java.util.HashMap;
import java.util.Map;
import org.apache.logging.log4j.test.junit.InitializesThreadContext;
import org.apache.logging.log4j.test.junit.SetTestProperty;
import org.apache.logging.log4j.test.junit.UsingThreadContextMap;
import org.junit.jupiter.api.Test;
import org.junitpioneer.jupiter.ClearSystemProperty;

/**
* Tests the {@code DefaultThreadContextMap} class.
Expand Down Expand Up @@ -217,26 +214,4 @@ public void testToStringShowsMapContext() {
map.put("key2", "value2");
assertEquals("{key2=value2}", map.toString());
}

@Test
@ClearSystemProperty(key = DefaultThreadContextMap.INHERITABLE_MAP)
@InitializesThreadContext
public void testThreadLocalNotInheritableByDefault() {
ThreadContextMapFactory.init();
final ThreadLocal<Map<String, String>> threadLocal = DefaultThreadContextMap.createThreadLocalMap(true);
assertFalse(threadLocal instanceof InheritableThreadLocal<?>);
}

@Test
@SetTestProperty(key = DefaultThreadContextMap.INHERITABLE_MAP, value = "true")
@InitializesThreadContext
public void testThreadLocalInheritableIfConfigured() {
ThreadContextMapFactory.init();
try {
final ThreadLocal<Map<String, String>> threadLocal = DefaultThreadContextMap.createThreadLocalMap(true);
assertTrue(threadLocal instanceof InheritableThreadLocal<?>);
} finally {
System.clearProperty(DefaultThreadContextMap.INHERITABLE_MAP);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* 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.logging.log4j.spi;

import static org.assertj.core.api.Assertions.assertThat;

import java.time.Duration;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Stream;
import org.apache.logging.log4j.util.PropertiesUtil;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;

class ThreadContextMapTest {

static Stream<ThreadContextMap> defaultMaps() {
return Stream.of(
new DefaultThreadContextMap(),
new CopyOnWriteSortedArrayThreadContextMap(),
new GarbageFreeSortedArrayThreadContextMap());
}

static Stream<ThreadContextMap> inheritableMaps() {
final Properties props = new Properties();
props.setProperty("log4j2.isThreadContextMapInheritable", "true");
final PropertiesUtil util = new PropertiesUtil(props);
return Stream.of(
new DefaultThreadContextMap(true, util),
new CopyOnWriteSortedArrayThreadContextMap(util),
new GarbageFreeSortedArrayThreadContextMap(util));
}

@ParameterizedTest
@MethodSource("defaultMaps")
void threadLocalNotInheritableByDefault(final ThreadContextMap contextMap) {
contextMap.put("key", "threadLocalNotInheritableByDefault");
final ExecutorService executorService = Executors.newSingleThreadExecutor();
try {
assertThat(executorService.submit(() -> contextMap.get("key")))
.succeedsWithin(Duration.ofSeconds(1))
.isEqualTo(null);
} finally {
executorService.shutdown();
}
}

@ParameterizedTest
@MethodSource("inheritableMaps")
void threadLocalInheritableIfConfigured(final ThreadContextMap contextMap) {
contextMap.put("key", "threadLocalInheritableIfConfigured");
final ExecutorService executorService = Executors.newSingleThreadExecutor();
try {
assertThat(executorService.submit(() -> contextMap.get("key")))
.succeedsWithin(Duration.ofSeconds(1))
.isEqualTo("threadLocalInheritableIfConfigured");
} finally {
executorService.shutdown();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,36 +16,61 @@
*/
package org.apache.logging.log4j.util;

import static org.junit.jupiter.api.Assertions.assertTrue;

import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.spi.LoggerContext;
import org.apache.logging.log4j.test.TestLoggerContext;
import static org.assertj.core.api.Assertions.assertThat;

import java.util.Properties;
import org.apache.logging.log4j.TestProvider;
import org.apache.logging.log4j.test.TestLoggerContextFactory;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.parallel.Execution;
import org.junit.jupiter.api.parallel.ExecutionMode;

@Execution(ExecutionMode.CONCURRENT)
class ProviderUtilTest {

public class ProviderUtilTest {
/*
* Force initialization of ProviderUtil#PROVIDERS
*/
static {
ProviderUtil.lazyInit();
}

@Test
void should_select_provider_with_highest_priority() {
final PropertiesUtil properties = new PropertiesUtil(new Properties());
assertThat(ProviderUtil.selectProvider(properties))
.as("check selected provider")
.isInstanceOf(TestProvider.class);
}

@Test
void should_recognize_log4j_provider_property() {
final Properties map = new Properties();
map.setProperty("log4j.provider", LocalProvider.class.getName());
final PropertiesUtil properties = new PropertiesUtil(map);
assertThat(ProviderUtil.selectProvider(properties))
.as("check selected provider")
.isInstanceOf(LocalProvider.class);
}

@Test
public void complexTest() throws Exception {
final File file = new File("target/classes");
final ClassLoader classLoader =
new URLClassLoader(new URL[] {file.toURI().toURL()});
final Worker worker = new Worker();
worker.setContextClassLoader(classLoader);
worker.start();
worker.join();
assertTrue(worker.context instanceof TestLoggerContext, "Incorrect LoggerContext");
void should_recognize_log4j_factory_property() {
final Properties map = new Properties();
map.setProperty("log4j2.loggerContextFactory", LocalLoggerContextFactory.class.getName());
final PropertiesUtil properties = new PropertiesUtil(map);
assertThat(ProviderUtil.selectProvider(properties).getLoggerContextFactory())
.as("check selected logger context factory")
.isInstanceOf(LocalLoggerContextFactory.class);
}

private static class Worker extends Thread {
LoggerContext context = null;
public static class LocalLoggerContextFactory extends TestLoggerContextFactory {}

@Override
public void run() {
context = LogManager.getContext(false);
/**
* A provider with a smaller priority than {@link org.apache.logging.log4j.TestProvider}.
*/
public static class LocalProvider extends org.apache.logging.log4j.spi.Provider {
public LocalProvider() {
super(0, CURRENT_VERSION, LocalLoggerContextFactory.class);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;

import java.lang.invoke.MethodHandles;
import java.util.ArrayList;
import java.util.List;
import java.util.ServiceConfigurationError;
import java.util.ServiceLoader;
import java.util.stream.Collectors;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.status.StatusData;
import org.apache.logging.log4j.status.StatusLogger;
import org.apache.logging.log4j.test.BetterService;
import org.apache.logging.log4j.test.ListStatusListener;
import org.apache.logging.log4j.test.Service;
Expand All @@ -35,14 +37,26 @@

public class ServiceLoaderUtilTest {

private static final Logger LOGGER = StatusLogger.getLogger();

@Test
public void testServiceResolution() {
final List<Object> services = new ArrayList<>();
assertDoesNotThrow(() -> ServiceLoaderUtil.loadServices(BetterService.class, MethodHandles.lookup(), false)
ServiceLoaderUtil.safeStream(
BetterService.class,
ServiceLoader.load(BetterService.class, getClass().getClassLoader()),
LOGGER);
assertDoesNotThrow(() -> ServiceLoaderUtil.safeStream(
BetterService.class,
ServiceLoader.load(BetterService.class, getClass().getClassLoader()),
LOGGER)
.forEach(services::add));
assertThat(services).hasSize(1);
services.clear();
assertDoesNotThrow(() -> ServiceLoaderUtil.loadServices(PropertySource.class, MethodHandles.lookup(), false)
assertDoesNotThrow(() -> ServiceLoaderUtil.safeStream(
PropertySource.class,
ServiceLoader.load(PropertySource.class, getClass().getClassLoader()),
LOGGER)
.forEach(services::add));
assertThat(services).hasSize(3);
}
Expand All @@ -51,7 +65,10 @@ public void testServiceResolution() {
@UsingStatusListener
public void testBrokenServiceFile(final ListStatusListener listener) {
final List<Service> services = new ArrayList<>();
assertDoesNotThrow(() -> ServiceLoaderUtil.loadServices(Service.class, MethodHandles.lookup(), false)
assertDoesNotThrow(() -> ServiceLoaderUtil.safeStream(
Service.class,
ServiceLoader.load(Service.class, getClass().getClassLoader()),
LOGGER)
.forEach(services::add));
assertEquals(2, services.size());
// A warning for each broken service
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
org.apache.logging.log4j.TestProvider
org.apache.logging.log4j.TestProvider
org.apache.logging.log4j.util.ProviderUtilTest.LocalProvider
Loading

0 comments on commit f526601

Please sign in to comment.