blob: 4ee71f2452d2141827ed8b814da7731498d667a2 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010, 2011 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.osgi.tests.bundles;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.List;
import junit.framework.AssertionFailedError;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.eclipse.core.internal.runtime.RuntimeLog;
import org.eclipse.core.runtime.ILog;
import org.eclipse.core.runtime.ILogListener;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.equinox.log.ExtendedLogEntry;
import org.eclipse.equinox.log.ExtendedLogReaderService;
import org.eclipse.equinox.log.ExtendedLogService;
import org.eclipse.equinox.log.LogFilter;
import org.eclipse.equinox.log.Logger;
import org.eclipse.osgi.framework.log.FrameworkLog;
import org.eclipse.osgi.framework.log.FrameworkLogEntry;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventAdmin;
import org.osgi.service.event.EventConstants;
import org.osgi.service.event.EventHandler;
import org.osgi.service.log.LogEntry;
import org.osgi.service.log.LogListener;
import org.osgi.service.log.LogService;
public class LoggingTests extends AbstractBundleTests {
static final String EQUINOX_LOGGER = "org.eclipse.equinox.logger";
public static Test suite() {
return new TestSuite(LoggingTests.class);
}
class LogServiceReference {
private final ServiceReference logRef;
final ExtendedLogService logService;
private final ServiceReference readerRef;
final ExtendedLogReaderService readerService;
private final ServiceReference fwkLogRef;
final FrameworkLog fwkLog;
public LogServiceReference(ServiceReference logRef, ExtendedLogService logService, ServiceReference readerRef, ExtendedLogReaderService readerService, ServiceReference fwkLogRef, FrameworkLog fwkLog) {
this.logRef = logRef;
this.logService = logService;
this.readerRef = readerRef;
this.readerService = readerService;
this.fwkLogRef = fwkLogRef;
this.fwkLog = fwkLog;
}
public void unget(BundleContext bc) {
bc.ungetService(logRef);
bc.ungetService(readerRef);
bc.ungetService(fwkLogRef);
}
}
class ILogEntry {
final IStatus status;
final String plugin;
ILogEntry(IStatus status, String plugin) {
this.status = status;
this.plugin = plugin;
}
}
class TestListener {
final List context;
boolean found = false;
TestListener(List context) {
this.context = context;
}
synchronized boolean waitforContext() {
if (context.size() > 0)
try {
wait(5000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return context.size() == 0;
}
synchronized void checkContext(IStatus check) {
if (check == null)
return;
if (context.size() > 0) {
IStatus expected = (IStatus) context.get(0);
try {
assertEquals(expected.getSeverity(), check.getSeverity());
assertEquals(expected.getCode(), check.getCode());
assertEquals(expected.getMessage(), check.getMessage());
assertEquals(expected.getPlugin(), check.getPlugin());
} catch (AssertionFailedError e) {
return;
}
context.remove(0);
if (context.size() == 0)
notifyAll();
}
}
synchronized void addContext(List moreContext) {
context.addAll(moreContext);
}
}
class TestILogListener extends TestListener implements ILogListener {
TestILogListener(List context) {
super(context);
}
public void logging(IStatus status, String plugin) {
checkContext(status);
}
}
class TestLogListener extends TestListener implements LogListener, LogFilter {
TestLogListener(List context) {
super(context);
}
List entries = new ArrayList();
public void logged(LogEntry entry) {
entries.add(entry);
Object check = ((ExtendedLogEntry) entry).getContext();
if (check instanceof FrameworkLogEntry)
check = ((FrameworkLogEntry) check).getContext();
if (check instanceof IStatus)
checkContext((IStatus) check);
}
List getEntries() {
return entries;
}
public boolean isLoggable(Bundle bundle, String loggerName, int logLevel) {
return EQUINOX_LOGGER.equals(loggerName);
}
}
private LogServiceReference getLogService(BundleContext bc) {
ServiceReference logRef = bc.getServiceReference(ExtendedLogService.class.getName());
assertNotNull("log service ref is null", logRef);
ServiceReference readerRef = bc.getServiceReference(ExtendedLogReaderService.class.getName());
assertNotNull("log reader ref is null", readerRef);
ServiceReference fwkLogRef = bc.getServiceReference(FrameworkLog.class.getName());
assertNotNull("framework log ref is null", fwkLogRef);
ExtendedLogService logService = (ExtendedLogService) bc.getService(logRef);
assertNotNull("log service is null", logService);
ExtendedLogReaderService readerService = (ExtendedLogReaderService) bc.getService(readerRef);
assertNotNull("reader service is null", readerService);
FrameworkLog fwkLog = (FrameworkLog) bc.getService(fwkLogRef);
assertNotNull("framework log is null", fwkLog);
return new LogServiceReference(logRef, logService, readerRef, readerService, fwkLogRef, fwkLog);
}
public void testLogService() throws BundleException {
// Tests listeners at all levels when logged with the LogService
Bundle testBundle = installer.installBundle("test.logging.a"); //$NON-NLS-1$
testBundle.start();
BundleContext bc = testBundle.getBundleContext();
LogServiceReference logRef = getLogService(bc);
IStatus a = new Status(IStatus.ERROR, testBundle.getSymbolicName(), getName());
List context = new ArrayList();
context.add(a);
TestILogListener iLogListener1 = new TestILogListener(new ArrayList(context));
TestILogListener iLogListener2 = new TestILogListener(new ArrayList(context));
TestLogListener logListener = new TestLogListener(new ArrayList(context));
ILog testLog = Platform.getLog(testBundle);
testLog.addLogListener(iLogListener1);
Platform.addLogListener(iLogListener2);
logRef.readerService.addLogListener(logListener, logListener);
try {
ExtendedLogService logService = logRef.logService;
Logger logger = logService.getLogger(testBundle, EQUINOX_LOGGER);
logger.log(a, LogService.LOG_ERROR, a.getMessage());
assertTrue("Missing context", iLogListener1.waitforContext());
assertTrue("Missing context", iLogListener2.waitforContext());
assertTrue("Missing context", logListener.waitforContext());
iLogListener1.addContext(new ArrayList(context));
iLogListener2.addContext(new ArrayList(context));
logListener.addContext(new ArrayList(context));
logger.log(new FrameworkLogEntry(a, testBundle.getSymbolicName(), a.getSeverity(), a.getCode(), a.getMessage(), 0, null, null), LogService.LOG_ERROR, a.getMessage());
assertTrue("Missing context", iLogListener1.waitforContext());
assertTrue("Missing context", iLogListener2.waitforContext());
assertTrue("Missing context", logListener.waitforContext());
iLogListener1.addContext(new ArrayList(context));
iLogListener2.addContext(new ArrayList(context));
logListener.addContext(new ArrayList(context));
logListener.entries.clear();
logger.log(LogService.LOG_ERROR, a.getMessage());
assertTrue("Missing context", iLogListener1.waitforContext());
assertTrue("Missing context", iLogListener2.waitforContext());
// there is no status here
assertFalse("Missing context", logListener.waitforContext());
// but we should have received one log entry
assertEquals("Wrong number of entries", 1, logListener.entries.size());
} finally {
testLog.removeLogListener(iLogListener1);
Platform.removeLogListener(iLogListener2);
logRef.readerService.removeLogListener(logListener);
logRef.unget(bc);
}
}
public void testPluginILog() throws BundleException {
// Tests listeners at all levels when logged with a plugin ILog
Bundle testBundle = installer.installBundle("test.logging.a"); //$NON-NLS-1$
testBundle.start();
BundleContext bc = testBundle.getBundleContext();
LogServiceReference logRef = getLogService(bc);
IStatus a = new Status(IStatus.ERROR, testBundle.getSymbolicName(), getName());
List context = new ArrayList();
context.add(a);
TestILogListener iLogListener1 = new TestILogListener(new ArrayList(context));
TestILogListener iLogListener2 = new TestILogListener(new ArrayList(context));
TestLogListener logListener = new TestLogListener(new ArrayList(context));
ILog testLog = Platform.getLog(testBundle);
testLog.addLogListener(iLogListener1);
Platform.addLogListener(iLogListener2);
logRef.readerService.addLogListener(logListener, logListener);
try {
testLog.log(a);
assertTrue("Missing context", iLogListener1.waitforContext());
assertTrue("Missing context", iLogListener2.waitforContext());
assertTrue("Missing context", logListener.waitforContext());
iLogListener1.addContext(new ArrayList(context));
iLogListener2.addContext(new ArrayList(context));
logListener.addContext(new ArrayList(context));
testLog.log(a);
assertTrue("Missing context", iLogListener1.waitforContext());
assertTrue("Missing context", iLogListener2.waitforContext());
assertTrue("Missing context", logListener.waitforContext());
} finally {
testLog.removeLogListener(iLogListener1);
Platform.removeLogListener(iLogListener2);
logRef.readerService.removeLogListener(logListener);
logRef.unget(bc);
}
}
public void testRuntimeLog() throws BundleException {
// Tests listeners at all levels when logged with the RuntimeLog
Bundle testBundle = installer.installBundle("test.logging.a"); //$NON-NLS-1$
testBundle.start();
BundleContext bc = testBundle.getBundleContext();
LogServiceReference logRef = getLogService(bc);
IStatus a = new Status(IStatus.ERROR, testBundle.getSymbolicName(), getName());
List context = new ArrayList();
context.add(a);
TestILogListener iLogListener1 = new TestILogListener(new ArrayList(context));
TestILogListener iLogListener2 = new TestILogListener(new ArrayList(context));
TestLogListener logListener = new TestLogListener(new ArrayList(context));
ILog testLog = Platform.getLog(testBundle);
testLog.addLogListener(iLogListener1);
Platform.addLogListener(iLogListener2);
logRef.readerService.addLogListener(logListener, logListener);
try {
RuntimeLog.log(a);
assertTrue("Missing context", iLogListener1.waitforContext());
assertTrue("Missing context", iLogListener2.waitforContext());
assertTrue("Missing context", logListener.waitforContext());
iLogListener1.addContext(new ArrayList(context));
iLogListener2.addContext(new ArrayList(context));
logListener.addContext(new ArrayList(context));
RuntimeLog.log(a);
assertTrue("Missing context", iLogListener1.waitforContext());
assertTrue("Missing context", iLogListener2.waitforContext());
assertTrue("Missing context", logListener.waitforContext());
} finally {
testLog.removeLogListener(iLogListener1);
Platform.removeLogListener(iLogListener2);
logRef.readerService.removeLogListener(logListener);
logRef.unget(bc);
}
}
public void testFrameworkLog() throws BundleException {
// Tests listeners at all levels when logged with the FrameworkLog
Bundle testBundle = installer.installBundle("test.logging.a"); //$NON-NLS-1$
testBundle.start();
BundleContext bc = testBundle.getBundleContext();
LogServiceReference logRef = getLogService(bc);
IStatus a = new Status(IStatus.ERROR, testBundle.getSymbolicName(), getName());
List context = new ArrayList();
context.add(a);
TestILogListener iLogListener1 = new TestILogListener(new ArrayList(context));
TestILogListener iLogListener2 = new TestILogListener(new ArrayList(context));
TestLogListener logListener = new TestLogListener(new ArrayList(context));
ILog testLog = Platform.getLog(testBundle);
testLog.addLogListener(iLogListener1);
Platform.addLogListener(iLogListener2);
logRef.readerService.addLogListener(logListener, logListener);
try {
FrameworkLogEntry fwkLogEntry = new FrameworkLogEntry(a, testBundle.getSymbolicName(), a.getSeverity(), a.getCode(), a.getMessage(), 0, null, null);
logRef.fwkLog.log(fwkLogEntry);
assertTrue("Missing context", iLogListener1.waitforContext());
assertTrue("Missing context", iLogListener2.waitforContext());
assertTrue("Missing context", logListener.waitforContext());
iLogListener1.addContext(new ArrayList(context));
iLogListener2.addContext(new ArrayList(context));
logListener.addContext(new ArrayList(context));
logRef.fwkLog.log(fwkLogEntry);
assertTrue("Missing context", iLogListener1.waitforContext());
assertTrue("Missing context", iLogListener2.waitforContext());
assertTrue("Missing context", logListener.waitforContext());
iLogListener1.addContext(new ArrayList(context));
iLogListener2.addContext(new ArrayList(context));
logListener.addContext(new ArrayList(context));
logListener.entries.clear();
logRef.fwkLog.log(new FrameworkLogEntry(testBundle.getSymbolicName(), a.getSeverity(), a.getCode(), a.getMessage(), 0, null, null));
assertTrue("Missing context", iLogListener1.waitforContext());
assertTrue("Missing context", iLogListener2.waitforContext());
// there is no status here
assertFalse("Missing context", logListener.waitforContext());
// but we should have received one log entry
assertEquals("Wrong number of entries", 1, logListener.entries.size());
} finally {
testLog.removeLogListener(iLogListener1);
Platform.removeLogListener(iLogListener2);
logRef.readerService.removeLogListener(logListener);
logRef.unget(bc);
}
}
public void testEventAdminAdapter1() {
ServiceReference eventRef = getContext().getServiceReference(EventAdmin.class.getName());
assertNotNull("No eventAdmin.", eventRef);
LogServiceReference logRef = getLogService(getContext());
final List events = new ArrayList();
EventHandler testHandler = new EventHandler() {
public void handleEvent(Event event) {
synchronized (events) {
events.add(event);
events.notifyAll();
}
}
};
Dictionary props = new Hashtable();
props.put(EventConstants.EVENT_TOPIC, "org/osgi/service/log/LogEntry/*");
ServiceRegistration handlerReg = getContext().registerService(EventHandler.class.getName(), testHandler, props);
try {
logRef.logService.log(LogService.LOG_ERROR, getName());
Event testEvent = null;
synchronized (events) {
if (events.size() == 0)
try {
events.wait(5000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
if (events.size() > 0)
testEvent = (Event) events.get(0);
}
assertNotNull("No event fired", testEvent);
assertEquals("Wrong message", getName(), testEvent.getProperty("message"));
} finally {
handlerReg.unregister();
logRef.unget(getContext());
}
}
public void testEventAdminAdapter2() {
ServiceReference eventRef = getContext().getServiceReference(EventAdmin.class.getName());
assertNotNull("No eventAdmin.", eventRef);
LogServiceReference logRef = getLogService(getContext());
final List events = new ArrayList();
EventHandler testHandler = new EventHandler() {
public void handleEvent(Event event) {
synchronized (events) {
events.add(event);
events.notifyAll();
}
throw new NullPointerException();
}
};
Dictionary props = new Hashtable();
props.put(EventConstants.EVENT_TOPIC, "org/osgi/service/log/LogEntry/*");
ServiceRegistration handlerReg = getContext().registerService(EventHandler.class.getName(), testHandler, props);
try {
logRef.logService.log(LogService.LOG_ERROR, getName());
int size = 0;
synchronized (events) {
for (int i = 0; i < 3 && events.size() < 3; i++)
try {
events.wait(5000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
size = events.size();
}
assertEquals("Should only get one event from bad handler", 2, size);
} finally {
handlerReg.unregister();
logRef.unget(getContext());
}
}
public void testBug347183() throws BundleException {
// test recursive logging
final Bundle testBundle = installer.installBundle("test.logging.a"); //$NON-NLS-1$
testBundle.start();
LogServiceReference logRef = getLogService(getContext());
ILogListener recurseLog = new ILogListener() {
public void logging(IStatus status, String plugin) {
Platform.getLog(testBundle).log(status);
}
};
Platform.addLogListener(recurseLog);
try {
logRef.fwkLog.log(new FrameworkLogEntry(getContext().getBundle().getSymbolicName(), FrameworkLogEntry.ERROR, 0, "Test message", 0, null, null));
// prime the log so we don't have to create it in the logging call
Platform.getLog(testBundle);
logRef.fwkLog.log(new FrameworkLogEntry(getContext().getBundle().getSymbolicName(), FrameworkLogEntry.ERROR, 0, "Test message", 0, null, null));
} finally {
Platform.removeLogListener(recurseLog);
}
}
}