blob: 776266495958ba4e4504262bc764cd969ca4b1fa [file] [log] [blame]
/*
* 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.sling.commons.log.logback.integration;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.List;
import javax.inject.Inject;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.Appender;
import ch.qos.logback.core.AppenderBase;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.ops4j.pax.exam.Option;
import org.ops4j.pax.exam.junit.PaxExam;
import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
import org.ops4j.pax.exam.spi.reactors.PerClass;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventAdmin;
import org.slf4j.LoggerFactory;
import static org.apache.sling.commons.log.logback.integration.ITConfigFragments.RESET_EVENT_TOPIC;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.ops4j.pax.exam.CoreOptions.composite;
import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
@RunWith(PaxExam.class)
@ExamReactorStrategy(PerClass.class)
public class ITAppenderServices extends LogTestBase {
@Inject
private BundleContext bundleContext;
@Inject
private ConfigurationAdmin ca;
private ServiceRegistration sr;
@Inject
private EventAdmin eventAdmin;
static {
// uncomment to enable debugging of this test class
// paxRunnerVmOption = DEBUG_VM_OPTION;
}
@Override
protected Option addExtraOptions() {
return composite(
configAdmin(), mavenBundle("commons-io", "commons-io").versionAsInProject(),
mavenBundle("org.apache.felix", "org.apache.felix.eventadmin").versionAsInProject()
);
}
@Test
public void testAppenderService() throws Exception {
TestAppender ta = registerAppender("foo.bar", "foo.baz");
delay();
Logger bar = (Logger)LoggerFactory.getLogger("foo.bar");
bar.setLevel(Level.DEBUG);
Logger baz = (Logger)LoggerFactory.getLogger("foo.baz");
baz.setLevel(Level.INFO);
bar.debug("Test message");
baz.debug("Test message"); // Would not be logged
// One event should be logged.
assertEquals(1, ta.events.size());
}
@Test
public void testRootAppenderService() throws Exception {
TestAppender ta = registerAppender("ROOT");
delay();
Logger root = (Logger)LoggerFactory.getLogger("ROOT");
root.setLevel(Level.DEBUG);
Logger foobar = (Logger)LoggerFactory.getLogger("foo.bar");
foobar.setLevel(Level.INFO);
root.debug("one");
foobar.debug("two");
foobar.info("three");
assertEquals(2, ta.events.size());
}
@Test
public void testAppenderServiceModified() throws Exception {
TestAppender ta = registerAppender("foo.bar", "foo.baz");
delay();
Logger bar = (Logger)LoggerFactory.getLogger("foo.bar");
bar.setLevel(Level.DEBUG);
Logger baz = (Logger)LoggerFactory.getLogger("foo.baz");
baz.setLevel(Level.INFO);
bar.debug("Test message");
baz.debug("Test message"); // Would not be logged
// One event should be logged.
assertEquals(1, ta.events.size());
ta.reset();
Dictionary<String, Object> props = new Hashtable<String, Object>();
props.put("loggers", new String[]{"foo.bar2"});
sr.setProperties(props);
delay();
LoggerFactory.getLogger("foo.bar2").info("foo.bar2");
LoggerFactory.getLogger("foo.baz").info("foo.baz");
assertEquals(1, ta.msgs.size());
assertTrue(ta.msgs.contains("foo.bar2"));
assertFalse(ta.msgs.contains("foo.baz"));
}
@Test
public void testOsgiAppenderRef() throws Exception {
Configuration config = ca.getConfiguration(ITConfigAdminSupport.PID, null);
Dictionary<String, Object> p = new Hashtable<String, Object>();
p.put(ITConfigAdminSupport.LOG_LEVEL, "INFO");
p.put(ITConfigAdminSupport.LOGBACK_FILE,absolutePath("test-osg-appender-ref-config.xml"));
config.update(p);
delay();
Logger ref = (Logger)LoggerFactory.getLogger("foo.ref.osgi");
assertTrue(ref.isDebugEnabled());
TestAppender ta = registerAppender("foo.bar", "foo.baz");
delay();
Logger bar = (Logger)LoggerFactory.getLogger("foo.bar");
bar.setLevel(Level.DEBUG);
Logger baz = (Logger)LoggerFactory.getLogger("foo.baz");
baz.setLevel(Level.INFO);
bar.debug("Test message");
baz.debug("Test message"); // Would not be logged
ref.debug("Test message ref");
// One event should be logged.
assertEquals(2, ta.events.size());
}
@Test
public void appenderRestartPostReset() throws Exception{
final TestAppender ta = registerAppender("ROOT");
delay();
assertTrue(ta.isStarted());
final int stopCount = ta.stopCount;
final int startCount = ta.startCount;
eventAdmin.sendEvent(new Event(RESET_EVENT_TOPIC, (Dictionary)null));
new RetryLoop(new RetryLoop.Condition() {
@Override
public String getDescription() {
return "Stopcount not increased";
}
@Override
public boolean isTrue() throws Exception {
return ta.stopCount > stopCount && ta.startCount > startCount;
}
}, 10, 100);
assertTrue(ta.isStarted());
}
@After
public void unregisterAppender(){
sr.unregister();
}
private TestAppender registerAppender(String... loggers){
TestAppender ta = new TestAppender();
Dictionary<String, Object> props = new Hashtable<String, Object>();
props.put("loggers", loggers);
sr = bundleContext.registerService(Appender.class.getName(), ta, props);
delay();
return ta;
}
private static class TestAppender extends AppenderBase<ILoggingEvent> {
final List<ILoggingEvent> events = new ArrayList<ILoggingEvent>();
final List<String> msgs = new ArrayList<String>();
int stopCount;
int startCount;
@Override
protected void append(ILoggingEvent eventObject) {
events.add(eventObject);
msgs.add(eventObject.getFormattedMessage());
}
@Override
public String getName() {
return "TestAppender";
}
public void reset(){
events.clear();
msgs.clear();
}
@Override
public void stop() {
super.stop();
stopCount++;
}
@Override
public void start() {
super.start();
startCount++;
}
}
}