mirror of https://github.com/apache/lucene.git
SOLR-9500: Add LogLevel annotation for test-specific logging changes
This commit is contained in:
parent
65439e261e
commit
c809cd4f0a
|
@ -190,6 +190,9 @@ Other Changes
|
|||
* SOLR-9551: Add JSONWriter constructor variant, JSONWriterTest.testConstantsUnchanged test.
|
||||
(Jonny Marks, Christine Poerschke)
|
||||
|
||||
* SOLR-9500: Add a LogLevel annotation to set log levels on specific tests (Alan
|
||||
Woodward)
|
||||
|
||||
================== 6.2.1 ==================
|
||||
|
||||
Bug Fixes
|
||||
|
|
|
@ -31,6 +31,7 @@ import java.lang.annotation.Retention;
|
|||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.Charset;
|
||||
|
@ -50,7 +51,6 @@ import java.util.List;
|
|||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import com.carrotsearch.randomizedtesting.RandomizedContext;
|
||||
import com.carrotsearch.randomizedtesting.annotations.ThreadLeakFilters;
|
||||
|
@ -67,6 +67,7 @@ import org.apache.lucene.util.LuceneTestCase.SuppressFileSystems;
|
|||
import org.apache.lucene.util.LuceneTestCase.SuppressSysoutChecks;
|
||||
import org.apache.lucene.util.QuickPatchThreadsFilter;
|
||||
import org.apache.lucene.util.TestUtil;
|
||||
import org.apache.solr.client.solrj.ResponseParser;
|
||||
import org.apache.solr.client.solrj.embedded.JettyConfig;
|
||||
import org.apache.solr.client.solrj.impl.CloudSolrClient;
|
||||
import org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrClient;
|
||||
|
@ -74,7 +75,6 @@ import org.apache.solr.client.solrj.impl.HttpClientUtil;
|
|||
import org.apache.solr.client.solrj.impl.HttpSolrClient;
|
||||
import org.apache.solr.client.solrj.impl.HttpSolrClient.Builder;
|
||||
import org.apache.solr.client.solrj.impl.LBHttpSolrClient;
|
||||
import org.apache.solr.client.solrj.ResponseParser;
|
||||
import org.apache.solr.client.solrj.util.ClientUtils;
|
||||
import org.apache.solr.cloud.IpTables;
|
||||
import org.apache.solr.common.SolrDocument;
|
||||
|
@ -86,7 +86,6 @@ import org.apache.solr.common.params.CommonParams;
|
|||
import org.apache.solr.common.params.ModifiableSolrParams;
|
||||
import org.apache.solr.common.params.SolrParams;
|
||||
import org.apache.solr.common.util.ObjectReleaseTracker;
|
||||
import org.apache.solr.common.util.SuppressForbidden;
|
||||
import org.apache.solr.common.util.XML;
|
||||
import org.apache.solr.core.CoreContainer;
|
||||
import org.apache.solr.core.CoresLocator;
|
||||
|
@ -104,6 +103,7 @@ import org.apache.solr.schema.SchemaField;
|
|||
import org.apache.solr.search.SolrIndexSearcher;
|
||||
import org.apache.solr.servlet.DirectSolrConnection;
|
||||
import org.apache.solr.util.AbstractSolrTestCase;
|
||||
import org.apache.solr.util.LogLevel;
|
||||
import org.apache.solr.util.RandomizeSSL;
|
||||
import org.apache.solr.util.RandomizeSSL.SSLRandomizer;
|
||||
import org.apache.solr.util.RefCounted;
|
||||
|
@ -112,7 +112,9 @@ import org.apache.solr.util.SSLTestConfig;
|
|||
import org.apache.solr.util.TestHarness;
|
||||
import org.apache.solr.util.TestInjection;
|
||||
import org.apache.zookeeper.KeeperException;
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Rule;
|
||||
|
@ -220,8 +222,10 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
|
|||
|
||||
@BeforeClass
|
||||
public static void setupTestCases() {
|
||||
initCoreDataDir = createTempDir("init-core-data").toFile();
|
||||
|
||||
initClassLogLevels();
|
||||
|
||||
initCoreDataDir = createTempDir("init-core-data").toFile();
|
||||
System.err.println("Creating dataDir: " + initCoreDataDir.getAbsolutePath());
|
||||
|
||||
System.setProperty("zookeeper.forceSync", "no");
|
||||
|
@ -287,6 +291,40 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
|
|||
}
|
||||
|
||||
IpTables.unblockAllPorts();
|
||||
|
||||
LogLevel.Configurer.restoreLogLevels(savedClassLogLevels);
|
||||
savedClassLogLevels.clear();
|
||||
}
|
||||
|
||||
private static Map<String, String> savedClassLogLevels = new HashMap<>();
|
||||
|
||||
public static void initClassLogLevels() {
|
||||
Class currentClass = RandomizedContext.current().getTargetClass();
|
||||
LogLevel annotation = (LogLevel) currentClass.getAnnotation(LogLevel.class);
|
||||
if (annotation == null) {
|
||||
return;
|
||||
}
|
||||
Map<String, String> previousLevels = LogLevel.Configurer.setLevels(annotation.value());
|
||||
savedClassLogLevels.putAll(previousLevels);
|
||||
}
|
||||
|
||||
private Map<String, String> savedMethodLogLevels = new HashMap<>();
|
||||
|
||||
@Before
|
||||
public void initMethodLogLevels() {
|
||||
Method method = RandomizedContext.current().getTargetMethod();
|
||||
LogLevel annotation = method.getAnnotation(LogLevel.class);
|
||||
if (annotation == null) {
|
||||
return;
|
||||
}
|
||||
Map<String, String> previousLevels = LogLevel.Configurer.setLevels(annotation.value());
|
||||
savedMethodLogLevels.putAll(previousLevels);
|
||||
}
|
||||
|
||||
@After
|
||||
public void restoreMethodLogLevels() {
|
||||
LogLevel.Configurer.restoreLogLevels(savedMethodLogLevels);
|
||||
savedMethodLogLevels.clear();
|
||||
}
|
||||
|
||||
protected static boolean isSSLMode() {
|
||||
|
@ -413,13 +451,6 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
|
|||
super.tearDown();
|
||||
}
|
||||
|
||||
@SuppressForbidden(reason = "method is specific to java.util.logging and highly suspect!")
|
||||
public static void setLoggingLevel(Level level) {
|
||||
java.util.logging.Logger logger = java.util.logging.Logger.getLogger("");
|
||||
logger.setLevel(level);
|
||||
}
|
||||
|
||||
|
||||
/** Call initCore in @BeforeClass to instantiate a solr core in your test class.
|
||||
* deleteCore will be called for you via SolrTestCaseJ4 @AfterClass */
|
||||
public static void initCore(String config, String schema) throws Exception {
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* 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.solr.util;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.log4j.Level;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.solr.common.util.SuppressForbidden;
|
||||
|
||||
/**
|
||||
* Annotation specifying the log level for a particular test case or method
|
||||
*
|
||||
* Log levels are set for different classes by passing a configuration string
|
||||
* to the annotation, like this:
|
||||
* <code>
|
||||
* {@literal @}LogLevel("org.apache.solr=DEBUG;org.apache.solr.core=INFO")
|
||||
* </code>
|
||||
*/
|
||||
@Documented
|
||||
@Inherited
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.TYPE, ElementType.METHOD})
|
||||
public @interface LogLevel {
|
||||
|
||||
/**
|
||||
* A log-level definition string
|
||||
*/
|
||||
public String value();
|
||||
|
||||
@SuppressForbidden(reason="Specific to Log4J")
|
||||
public static class Configurer {
|
||||
|
||||
private static Map<String, Level> parseFrom(String input) {
|
||||
Map<String, Level> testlevels = new HashMap<>();
|
||||
for (String levelSetting : input.split(";")) {
|
||||
String[] parts = levelSetting.split("=");
|
||||
testlevels.put(parts[0], Level.toLevel(parts[1]));
|
||||
}
|
||||
return testlevels;
|
||||
}
|
||||
|
||||
private static String levelAsString(Level level) {
|
||||
return level == null ? null : level.toString();
|
||||
}
|
||||
|
||||
private static Level parseLevel(String level) {
|
||||
return level == null ? null : Level.toLevel(level);
|
||||
}
|
||||
|
||||
public static void restoreLogLevels(Map<String, String> savedLogLevels) {
|
||||
savedLogLevels.forEach((name, level) -> {
|
||||
Logger logger = Logger.getLogger(name);
|
||||
logger.setLevel(parseLevel(level));
|
||||
});
|
||||
}
|
||||
|
||||
public static Map<String, String> setLevels(String value) {
|
||||
Map<String, String> oldLevels = new HashMap<>();
|
||||
parseFrom(value).forEach((name, level) -> {
|
||||
Logger logger = Logger.getLogger(name);
|
||||
oldLevels.put(name, levelAsString(logger.getLevel()));
|
||||
logger.setLevel(level);
|
||||
});
|
||||
return oldLevels;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* 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.solr;
|
||||
|
||||
import org.apache.log4j.Level;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.solr.common.util.SuppressForbidden;
|
||||
import org.apache.solr.util.LogLevel;
|
||||
import org.junit.Test;
|
||||
|
||||
@SuppressForbidden(reason="We need to use log4J classes to access the log levels")
|
||||
@LogLevel("org.apache.solr.ClassLogLevel=error;org.apache.solr.MethodLogLevel=warn")
|
||||
public class TestLogLevelAnnotations extends SolrTestCaseJ4 {
|
||||
|
||||
@Test
|
||||
public void testClassLogLevels() {
|
||||
Logger classLogLevel = Logger.getLogger("org.apache.solr.ClassLogLevel");
|
||||
assertEquals(Level.ERROR, classLogLevel.getLevel());
|
||||
Logger methodLogLevel = Logger.getLogger("org.apache.solr.MethodLogLevel");
|
||||
assertEquals(Level.WARN, methodLogLevel.getLevel());
|
||||
}
|
||||
|
||||
@Test
|
||||
@LogLevel("org.apache.solr.MethodLogLevel=debug")
|
||||
public void testMethodLogLevels() {
|
||||
Logger classLogLevel = Logger.getLogger("org.apache.solr.ClassLogLevel");
|
||||
assertEquals(Level.ERROR, classLogLevel.getLevel());
|
||||
Logger methodLogLevel = Logger.getLogger("org.apache.solr.MethodLogLevel");
|
||||
assertEquals(Level.DEBUG, methodLogLevel.getLevel());
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue