/* * Licensed 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.dnlock.log4jna.nt.test; import static org.junit.Assert.*; import java.io.Serializable; import java.nio.file.Path; import java.nio.file.Paths; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.core.Filter; import org.apache.logging.log4j.core.Layout; import org.apache.logging.log4j.core.LogEvent; import org.apache.logging.log4j.core.impl.Log4jLogEvent; import org.apache.logging.log4j.core.layout.PatternLayout; import org.apache.logging.log4j.message.SimpleMessage; import org.dblock.log4jna.nt.Win32EventLogAppender; import org.junit.Before; import org.junit.Test; import com.sun.jna.platform.win32.Advapi32Util; import com.sun.jna.platform.win32.Advapi32Util.EventLogIterator; import com.sun.jna.platform.win32.Advapi32Util.EventLogRecord; import com.sun.jna.platform.win32.Advapi32Util.EventLogType; import com.sun.jna.platform.win32.Kernel32; import com.sun.jna.platform.win32.WinNT; import com.sun.jna.platform.win32.WinReg; /** * Test case for {@link Win32EventLogAppender}. * * @author Curt Arnold * @author <a href="mailto:dblock@dblock.org">Daniel Doubrovkine</a> * @author <a href="mailto:tony@niemira.com">Tony Niemira</a> * @author <a href="mailto:claudio.trajtenberg@cgtca.ca">Claudio Trajtenberg</a> * */ public class Win32EventLogAppenderTest { /** * This must exist in the windows registry. * <p> * Key: * </p> * <p> * <code>HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\Application\Log4jnaTest</code> * </p> * <p> * With entries: * </p> * * <pre> * Name: <code>TypesSupported</code> * Type: <code>REG_DWORD</code> * Data: <code>0x7</code> * * Name: <code>CategoryCount</code> * Type: <code>REG_DWORD</code> * Data: <code>0x6</code> * </pre> */ private static final String TEST_LOGGER_NAME = "Log4jnaTest"; /** * The dll file location from the <code>src/test/resources</code> folder. */ private static String _eventLogAppenderDLL = Paths.get("src/test/resources/Win32EventlogAppender.dll") .toAbsolutePath().toString(); /** * Class under test */ private Win32EventLogAppender _eventLogAppender = null; /** * */ @Before public void setUp() { String source = null; String log = getClass().getName(); Layout<? extends Serializable> layout = PatternLayout.newBuilder() .withPattern(PatternLayout.TTCC_CONVERSION_PATTERN).build(); Filter filter = null; _eventLogAppender = Win32EventLogAppender.createAppender("appenderName", null, source, log, _eventLogAppenderDLL, _eventLogAppenderDLL, layout, filter); _eventLogAppender.setSource(TEST_LOGGER_NAME); _eventLogAppender.setApplication("Application"); // _eventLogAppender.setCategoryMessageFile(_eventLogAppenderDLL); // _eventLogAppender.setEventMessageFile(_eventLogAppenderDLL); } /** * Test case for {@link Win32EventLogAppender#append(LogEvent)} with debug * level. */ @Test public void testDebugEvent() { String message = "log4jna debug message @ " + Kernel32.INSTANCE.GetTickCount(); _eventLogAppender.append(asLogEvent(message, Level.DEBUG)); expectEvent(message, Level.DEBUG, EventLogType.Informational); } /** * Test case for {@link Win32EventLogAppender#append(LogEvent)} with info * level. */ @Test public void testInfoEvent() { String message = "log4jna info message @ " + Kernel32.INSTANCE.GetTickCount(); _eventLogAppender.append(asLogEvent(message, Level.INFO)); expectEvent(message, Level.INFO, EventLogType.Informational); } /** * Test case for {@link Win32EventLogAppender#append(LogEvent)} with warn * level. */ @Test public void testWarnEvent() { String message = "log4jna warn message @ " + Kernel32.INSTANCE.GetTickCount(); _eventLogAppender.append(asLogEvent(message, Level.WARN)); expectEvent(message, Level.WARN, EventLogType.Warning); } /** * Test case for {@link Win32EventLogAppender#append(LogEvent)} with fatal level. */ @Test public void testFatalEvent() { String message = "log4jna fatal message @ " + Kernel32.INSTANCE.GetTickCount(); _eventLogAppender.append(asLogEvent(message, Level.FATAL)); expectEvent(message, Level.FATAL, EventLogType.Error); } public void donttestRegistryValues() { String eventSourceKeyPath = "SYSTEM\\CurrentControlSet\\Services\\EventLog\\" + _eventLogAppender.getApplication() + "\\" + _eventLogAppender.getSource(); String eventMessageFileInRegistry = Advapi32Util.registryGetStringValue(WinReg.HKEY_LOCAL_MACHINE, eventSourceKeyPath, "EventMessageFile"); Path eventMessageFileGiven = Paths.get(_eventLogAppenderDLL); assertEquals(eventMessageFileInRegistry, eventMessageFileGiven.toString()); String categoryMessageFileInRegistry = Advapi32Util.registryGetStringValue(WinReg.HKEY_LOCAL_MACHINE, eventSourceKeyPath, "CategoryMessageFile"); Path categoryMessageFileGiven = Paths.get(_eventLogAppenderDLL); assertEquals(categoryMessageFileInRegistry, categoryMessageFileGiven.toString()); } private LogEvent asLogEvent(String message, Level level) { return new Log4jLogEvent.Builder().setLoggerName(TEST_LOGGER_NAME).setMarker(null) .setLoggerFqcn(_eventLogAppender.getClass().getName()).setLevel(level) .setMessage(new SimpleMessage(message)).setTimeMillis(System.currentTimeMillis()).build(); } /* * public void testException() { String message = * "log4jna exception message @ " + Kernel32.INSTANCE.GetTickCount(); * _logger.debug(message, new Exception("testing exception")); * expectEvent(message, Level.DEBUG, EventLogType.Informational); } */ private void expectEvent(String message, Level level, EventLogType eventLogType) { EventLogIterator iter = new EventLogIterator(null, TEST_LOGGER_NAME, WinNT.EVENTLOG_BACKWARDS_READ); try { assertTrue(iter.hasNext()); EventLogRecord record = iter.next(); assertEquals(TEST_LOGGER_NAME, record.getSource()); assertEquals(eventLogType, record.getType()); assertEquals(1, record.getRecord().NumStrings.intValue()); assertNull(record.getData()); // The full message includes a level and the full class name String fullMessage = level + " " + TEST_LOGGER_NAME + " " + "[]" + " - " + message; // The event message has the location tacked on the front StringBuilder eventMessage = new StringBuilder(); for (int i = 0; i < record.getStrings().length; i++) { eventMessage.append(record.getStrings()[i].trim()); } int levelMarker = eventMessage.indexOf(level.toString()); assertTrue("missing level marker in '" + eventMessage + "'", levelMarker >= 0); String eventMessageWithoutLocation = eventMessage.substring(levelMarker); assertEquals(fullMessage, eventMessageWithoutLocation); } finally { iter.close(); } } }