/**
* Copyright (c) Codice Foundation
* <p>
* This is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser
* General Public License as published by the Free Software Foundation, either version 3 of the
* License, or any later version.
* <p>
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details. A copy of the GNU Lesser General Public License
* is distributed along with this program and can be found at
* <http://www.gnu.org/licenses/lgpl.html>.
*/
package org.codice.ddf.platform.logging;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import javax.management.MBeanServer;
import org.apache.log4j.Priority;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.ops4j.pax.logging.spi.PaxLevel;
import org.ops4j.pax.logging.spi.PaxLoggingEvent;
@RunWith(MockitoJUnitRunner.class)
public class LoggingServiceTest {
private static final String BUNDLE_NAME_KEY = "bundle.name";
private static final String BUNDLE_VERSION_KEY = "bundle.version";
private static final int MAX_LOG_EVENTS_LIMIT = 5000;
@Mock
private MBeanServer mockMBeanServer;
@Test
public void testRetrieveLogEvents() throws Exception {
// Setup
List<PaxLoggingEvent> mockPaxLoggingEvents = getMockPaxLoggingEventsTimestampOrderSmallestToLargest(3);
List<LogEvent> expectedLogEvents = getExpectedLogEvents(mockPaxLoggingEvents);
LoggingService loggingServiceBean = getLoggingService();
appendLogs(loggingServiceBean, mockPaxLoggingEvents);
// Perform Test
List<LogEvent> actualLogEvents = loggingServiceBean.retrieveLogEvents();
// Verify
assertThat(actualLogEvents,
contains(expectedLogEvents.toArray(new LogEvent[expectedLogEvents.size()])));
}
@Test
public void testResizeMaxLogEventsKeepsAppropriateLogEvents() throws Exception {
// Setup
List<PaxLoggingEvent> mockPaxLoggingEvents = getMockPaxLoggingEventsTimestampOrderSmallestToLargest(3);
LogEvent expectedLogEventAfterResize = getExpectedLogEvent(mockPaxLoggingEvents.get(2));
LoggingService loggingServiceBean = getLoggingService();
appendLogs(loggingServiceBean, mockPaxLoggingEvents);
// Perform Test
loggingServiceBean.setMaxLogEvents(1);
// Verify
List<LogEvent> actualLogEvents = loggingServiceBean.retrieveLogEvents();
assertThat(actualLogEvents, contains(expectedLogEventAfterResize));
}
@Test(expected = IllegalArgumentException.class)
public void testSetMaxLogEventsTo0() throws Exception {
// Setup
LoggingService loggingServiceBean = getLoggingService();
// Perform Test
loggingServiceBean.setMaxLogEvents(0);
}
@Test(expected = IllegalArgumentException.class)
public void testSetMaxLogEventsToExceedLimit() throws Exception {
// Setup
LoggingService loggingServiceBean = getLoggingService();
// Perform Test
loggingServiceBean.setMaxLogEvents(MAX_LOG_EVENTS_LIMIT + 1);
}
/**
* Verify oldest log events are evicted when queue is full.
*/
@Test
public void testDoAppendWhenLoggingQueueIsFull() throws Exception {
// Setup
List<PaxLoggingEvent> mockPaxLoggingEvents = getMockPaxLoggingEventsTimestampOrderSmallestToLargest(6);
List<LogEvent> expectedLogEvents = getExpectedLogEvents(mockPaxLoggingEvents).subList(3,
mockPaxLoggingEvents.size());
LoggingService loggingServiceBean = getLoggingService();
loggingServiceBean.setMaxLogEvents(3);
appendLogs(loggingServiceBean, mockPaxLoggingEvents.subList(0, 3));
// Perform Test
appendLogs(loggingServiceBean, mockPaxLoggingEvents.subList(3, mockPaxLoggingEvents.size()));
// Verify
List<LogEvent> actualLogEvents = loggingServiceBean.retrieveLogEvents();
assertThat(actualLogEvents,
contains(expectedLogEvents.toArray(new LogEvent[expectedLogEvents.size()])));
}
@Test
public void testDestroy() throws Exception {
LoggingService loggingServiceBean = getLoggingService();
loggingServiceBean.destroy();
}
private PaxLevel getMockPaxLevel(String level) {
PaxLevel mockPaxLevel = new PaxLevel() {
@Override
public String toString() {
return level;
}
@Override
public boolean isGreaterOrEqual(PaxLevel r) {
return false;
}
@Override
public int toInt() {
switch (level) {
case "ERROR":
return Priority.ERROR_INT;
case "WARN":
return Priority.WARN_INT;
case "INFO":
return Priority.INFO_INT;
case "DEBUG":
return Priority.DEBUG_INT;
case "TRACE":
return org.apache.log4j.Level.TRACE_INT;
default:
return -1;
}
}
@Override
public int getSyslogEquivalent() {
return 0;
}
};
return mockPaxLevel;
}
private List<PaxLoggingEvent> getMockPaxLoggingEventsTimestampOrderSmallestToLargest(
int numberOfLoggingEvents) {
String baseMessage = "message ";
String baseBundleName = "my-bundle-name-";
List<PaxLoggingEvent> mockPaxLoggingEvents = new ArrayList<>(3);
for (int i = 0; i < numberOfLoggingEvents; i++) {
PaxLoggingEvent mockPaxLoggingEvent = getMockPaxLoggingEvent(i, "INFO",
baseMessage + i, baseBundleName + i, "1.2.3");
mockPaxLoggingEvents.add(mockPaxLoggingEvent);
}
return mockPaxLoggingEvents;
}
private List<LogEvent> getExpectedLogEvents(List<PaxLoggingEvent> mockPaxLoggingEvents) {
List<LogEvent> expectedLogEvents = new ArrayList<>(mockPaxLoggingEvents.size());
for (PaxLoggingEvent mockPaxLoggingEvent : mockPaxLoggingEvents) {
expectedLogEvents.add(getExpectedLogEvent(mockPaxLoggingEvent));
}
return expectedLogEvents;
}
private LogEvent getExpectedLogEvent(PaxLoggingEvent mockPaxLoggingEvent) {
return new LogEvent(mockPaxLoggingEvent);
}
private void addBundleNameProperty(Properties properties, String bundleName) {
properties.put(BUNDLE_NAME_KEY, bundleName);
}
private void addBundleVersionProperty(Properties properties, String bundleVersion) {
properties.put(BUNDLE_VERSION_KEY, bundleVersion);
}
private Properties getLoggingProperties(String bundleName, String bundleVersion) {
Properties properties = new Properties();
addBundleNameProperty(properties, bundleName);
addBundleVersionProperty(properties, bundleVersion);
return properties;
}
private PaxLoggingEvent getMockPaxLoggingEvent(long timestamp, String level, String message,
String bundleName, String bundleVersion) {
PaxLoggingEvent mockPaxLoggingEvent = mock(PaxLoggingEvent.class);
when(mockPaxLoggingEvent.getTimeStamp()).thenReturn(timestamp);
when(mockPaxLoggingEvent.getLevel()).thenReturn(getMockPaxLevel(level));
when(mockPaxLoggingEvent.getMessage()).thenReturn(message);
when(mockPaxLoggingEvent.getProperties()).thenReturn(
getLoggingProperties(bundleName, bundleVersion));
return mockPaxLoggingEvent;
}
private void appendLogs(LoggingService loggingServiceBean,
List<PaxLoggingEvent> mockPaxLoggingEvents) {
for (PaxLoggingEvent mockPaxLoggingEvent : mockPaxLoggingEvents) {
loggingServiceBean.doAppend(mockPaxLoggingEvent);
}
}
private LoggingService getLoggingService() throws Exception {
LoggingService loggingServiceBean = new LoggingService(mockMBeanServer);
loggingServiceBean.init();
return loggingServiceBean;
}
}