SOLR-9500: Add LogLevel annotation for test-specific logging changes

This commit is contained in:
Alan Woodward 2016-09-26 09:14:49 +01:00
parent 65439e261e
commit c809cd4f0a
4 changed files with 183 additions and 11 deletions

View File

@ -190,6 +190,9 @@ Other Changes
* SOLR-9551: Add JSONWriter constructor variant, JSONWriterTest.testConstantsUnchanged test. * SOLR-9551: Add JSONWriter constructor variant, JSONWriterTest.testConstantsUnchanged test.
(Jonny Marks, Christine Poerschke) (Jonny Marks, Christine Poerschke)
* SOLR-9500: Add a LogLevel annotation to set log levels on specific tests (Alan
Woodward)
================== 6.2.1 ================== ================== 6.2.1 ==================
Bug Fixes Bug Fixes

View File

@ -31,6 +31,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles;
import java.lang.reflect.Method;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.nio.charset.Charset; import java.nio.charset.Charset;
@ -50,7 +51,6 @@ import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.logging.Level;
import com.carrotsearch.randomizedtesting.RandomizedContext; import com.carrotsearch.randomizedtesting.RandomizedContext;
import com.carrotsearch.randomizedtesting.annotations.ThreadLeakFilters; 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.LuceneTestCase.SuppressSysoutChecks;
import org.apache.lucene.util.QuickPatchThreadsFilter; import org.apache.lucene.util.QuickPatchThreadsFilter;
import org.apache.lucene.util.TestUtil; 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.embedded.JettyConfig;
import org.apache.solr.client.solrj.impl.CloudSolrClient; import org.apache.solr.client.solrj.impl.CloudSolrClient;
import org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrClient; 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;
import org.apache.solr.client.solrj.impl.HttpSolrClient.Builder; import org.apache.solr.client.solrj.impl.HttpSolrClient.Builder;
import org.apache.solr.client.solrj.impl.LBHttpSolrClient; 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.client.solrj.util.ClientUtils;
import org.apache.solr.cloud.IpTables; import org.apache.solr.cloud.IpTables;
import org.apache.solr.common.SolrDocument; 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.ModifiableSolrParams;
import org.apache.solr.common.params.SolrParams; import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.util.ObjectReleaseTracker; 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.common.util.XML;
import org.apache.solr.core.CoreContainer; import org.apache.solr.core.CoreContainer;
import org.apache.solr.core.CoresLocator; 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.search.SolrIndexSearcher;
import org.apache.solr.servlet.DirectSolrConnection; import org.apache.solr.servlet.DirectSolrConnection;
import org.apache.solr.util.AbstractSolrTestCase; import org.apache.solr.util.AbstractSolrTestCase;
import org.apache.solr.util.LogLevel;
import org.apache.solr.util.RandomizeSSL; import org.apache.solr.util.RandomizeSSL;
import org.apache.solr.util.RandomizeSSL.SSLRandomizer; import org.apache.solr.util.RandomizeSSL.SSLRandomizer;
import org.apache.solr.util.RefCounted; 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.TestHarness;
import org.apache.solr.util.TestInjection; import org.apache.solr.util.TestInjection;
import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.KeeperException;
import org.junit.After;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.ClassRule; import org.junit.ClassRule;
import org.junit.Rule; import org.junit.Rule;
@ -220,8 +222,10 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
@BeforeClass @BeforeClass
public static void setupTestCases() { 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.err.println("Creating dataDir: " + initCoreDataDir.getAbsolutePath());
System.setProperty("zookeeper.forceSync", "no"); System.setProperty("zookeeper.forceSync", "no");
@ -287,6 +291,40 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
} }
IpTables.unblockAllPorts(); 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() { protected static boolean isSSLMode() {
@ -413,13 +451,6 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
super.tearDown(); 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. /** Call initCore in @BeforeClass to instantiate a solr core in your test class.
* deleteCore will be called for you via SolrTestCaseJ4 @AfterClass */ * deleteCore will be called for you via SolrTestCaseJ4 @AfterClass */
public static void initCore(String config, String schema) throws Exception { public static void initCore(String config, String schema) throws Exception {

View File

@ -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;
}
}
}

View File

@ -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());
}
}