<commit_before>package net.kencochrane.raven.log4j2;

import net.kencochrane.raven.Raven;
import net.kencochrane.raven.RavenFactory;
import net.kencochrane.raven.dsn.Dsn;
import net.kencochrane.raven.event.Event;
import net.kencochrane.raven.event.EventBuilder;
import net.kencochrane.raven.event.interfaces.ExceptionInterface;
import net.kencochrane.raven.event.interfaces.MessageInterface;
import net.kencochrane.raven.event.interfaces.StackTraceInterface;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.MarkerManager;
import org.apache.logging.log4j.ThreadContext;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.appender.DefaultErrorHandler;
import org.apache.logging.log4j.core.impl.Log4jLogEvent;
import org.apache.logging.log4j.message.FormattedMessage;
import org.apache.logging.log4j.message.SimpleMessage;
import org.apache.logging.log4j.spi.DefaultThreadContextStack;
import org.hamcrest.Matchers;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.runners.MockitoJUnitRunner;
import org.mockito.stubbing.Answer;

import java.util.*;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.*;

@RunWith(MockitoJUnitRunner.class)
public class SentryAppenderTest {
    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
    private Raven mockRaven;
    @Mock
    private DefaultErrorHandler mockErrorHandler;
    private SentryAppender sentryAppender;

    @Before
    public void setUp() throws Exception {
        sentryAppender = new SentryAppender(mockRaven);
        setMockErrorHandlerOnAppender(sentryAppender);
    }

    private void setMockErrorHandlerOnAppender(final SentryAppender sentryAppender){
        sentryAppender.setHandler(mockErrorHandler);

        Answer<Void> answer = new Answer<Void>() {
            private final DefaultErrorHandler actualErrorHandler = new DefaultErrorHandler(sentryAppender);

            @Override
            public Void answer(InvocationOnMock invocation) throws Throwable {
                invocation.getMethod().invoke(actualErrorHandler, invocation.getArguments());
                return null;
            }
        };
        doAnswer(answer).when(mockErrorHandler).error(anyString());
        doAnswer(answer).when(mockErrorHandler).error(anyString(), any(Throwable.class));
        doAnswer(answer).when(mockErrorHandler).error(anyString(), any(LogEvent.class), any(Throwable.class));
    }

    @Test
    public void testSimpleMessageLogging() throws Exception {
        String messageContent = UUID.randomUUID().toString();
        String loggerName = UUID.randomUUID().toString();
        String threadName = UUID.randomUUID().toString();
        Date date = new Date(1373883196416L);
        ArgumentCaptor<Event> eventCaptor = ArgumentCaptor.forClass(Event.class);
        Event event;

        sentryAppender.append(new Log4jLogEvent(loggerName, null, null, Level.INFO, new SimpleMessage(messageContent),
                null, null, null, threadName, null, date.getTime()));

        verify(mockRaven).runBuilderHelpers(any(EventBuilder.class));
        verify(mockRaven).sendEvent(eventCaptor.capture());
        event = eventCaptor.getValue();
        assertThat(event.getMessage(), is(messageContent));
        assertThat(event.getLogger(), is(loggerName));
        assertThat(event.getExtra(), Matchers.<String, Object>hasEntry(SentryAppender.THREAD_NAME, threadName));
        assertThat(event.getTimestamp(), is(date));

        assertNoErrors();
    }

    @Test
    public void testLogLevelConversions() throws Exception {
        assertLevelConverted(Event.Level.DEBUG, Level.TRACE);
        assertLevelConverted(Event.Level.DEBUG, Level.DEBUG);
        assertLevelConverted(Event.Level.INFO, Level.INFO);
        assertLevelConverted(Event.Level.WARNING, Level.WARN);
        assertLevelConverted(Event.Level.ERROR, Level.ERROR);
        assertLevelConverted(Event.Level.FATAL, Level.FATAL);
    }

    private void assertLevelConverted(Event.Level expectedLevel, Level level) {
        ArgumentCaptor<Event> eventCaptor = ArgumentCaptor.forClass(Event.class);

        sentryAppender.append(new Log4jLogEvent(null, null, null, level, new SimpleMessage(""), null));

        verify(mockRaven).sendEvent(eventCaptor.capture());
        assertThat(eventCaptor.getValue().getLevel(), is(expectedLevel));
        assertNoErrors();
        reset(mockRaven);
    }

    @Test
    public void testExceptionLogging() throws Exception {
        Exception exception = new Exception();
        ArgumentCaptor<Event> eventCaptor = ArgumentCaptor.forClass(Event.class);

        sentryAppender.append(new Log4jLogEvent(null, null, null, Level.ERROR, new SimpleMessage(""), exception));

        verify(mockRaven).sendEvent(eventCaptor.capture());
        ExceptionInterface exceptionInterface = (ExceptionInterface) eventCaptor.getValue().getSentryInterfaces()
                .get(ExceptionInterface.EXCEPTION_INTERFACE);
        Throwable capturedException = exceptionInterface.getThrowable();

        assertThat(capturedException.getMessage(), is(exception.getMessage()));
        assertThat(capturedException.getStackTrace(), is(exception.getStackTrace()));
        assertNoErrors();
    }

    @Test
    public void testLogParametrisedMessage() throws Exception {
        String messagePattern = "Formatted message {} {} {}";
        Object[] parameters = {"first parameter", new Object[0], null};
        ArgumentCaptor<Event> eventCaptor = ArgumentCaptor.forClass(Event.class);

        sentryAppender.append(new Log4jLogEvent(null, null, null, Level.INFO,
                new FormattedMessage(messagePattern, parameters), null));

        verify(mockRaven).sendEvent(eventCaptor.capture());
        MessageInterface messageInterface = (MessageInterface) eventCaptor.getValue().getSentryInterfaces()
                .get(MessageInterface.MESSAGE_INTERFACE);

        assertThat(eventCaptor.getValue().getMessage(), is("Formatted message first parameter [] null"));
        assertThat(messageInterface.getMessage(), is(messagePattern));
        assertThat(messageInterface.getParameters(),
                is(Arrays.asList(parameters[0].toString(), parameters[1].toString(), null)));
        assertNoErrors();
    }

    @Test
    public void testMarkerAddedToTag() throws Exception {
        String markerName = UUID.randomUUID().toString();
        ArgumentCaptor<Event> eventCaptor = ArgumentCaptor.forClass(Event.class);

        sentryAppender.append(new Log4jLogEvent(null, MarkerManager.getMarker(markerName), null,
                Level.INFO, new SimpleMessage(""), null));

        verify(mockRaven).sendEvent(eventCaptor.capture());
        assertThat(eventCaptor.getValue().getTags(),
                Matchers.<String, Object>hasEntry(SentryAppender.LOG4J_MARKER, markerName));
        assertNoErrors();
    }

    @Test
    public void testMdcAddedToExtra() throws Exception {
        String extraKey = UUID.randomUUID().toString();
        String extraValue = UUID.randomUUID().toString();
        ArgumentCaptor<Event> eventCaptor = ArgumentCaptor.forClass(Event.class);

        ThreadContext.put(extraKey, extraValue);
        sentryAppender.append(new Log4jLogEvent(null, null, null, Level.INFO, new SimpleMessage(""), null,
                Collections.singletonMap(extraKey, extraValue), null, null, null, 0));

        verify(mockRaven).sendEvent(eventCaptor.capture());
        assertThat(eventCaptor.getValue().getExtra(), Matchers.<String, Object>hasEntry(extraKey, extraValue));
        assertNoErrors();
    }

    @Test
    @SuppressWarnings("unchecked")
    public void testNdcAddedToExtra() throws Exception {
        ArgumentCaptor<Event> eventCaptor = ArgumentCaptor.forClass(Event.class);
        ThreadContext.ContextStack contextStack = new DefaultThreadContextStack(true);

        contextStack.push(UUID.randomUUID().toString());
        contextStack.push(UUID.randomUUID().toString());
        contextStack.push(UUID.randomUUID().toString());
        sentryAppender.append(new Log4jLogEvent(null, null, null, Level.INFO, new SimpleMessage(""), null,
                null, contextStack, null, null, 0));<commit_msg>Format code and remove unused statements<commit_after>package net.kencochrane.raven.log4j2;

import net.kencochrane.raven.Raven;
import net.kencochrane.raven.RavenFactory;
import net.kencochrane.raven.dsn.Dsn;
import net.kencochrane.raven.event.Event;
import net.kencochrane.raven.event.EventBuilder;
import net.kencochrane.raven.event.interfaces.ExceptionInterface;
import net.kencochrane.raven.event.interfaces.MessageInterface;
import net.kencochrane.raven.event.interfaces.StackTraceInterface;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.MarkerManager;
import org.apache.logging.log4j.ThreadContext;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.appender.DefaultErrorHandler;
import org.apache.logging.log4j.core.impl.Log4jLogEvent;
import org.apache.logging.log4j.message.FormattedMessage;
import org.apache.logging.log4j.message.SimpleMessage;
import org.apache.logging.log4j.spi.DefaultThreadContextStack;
import org.hamcrest.Matchers;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.runners.MockitoJUnitRunner;
import org.mockito.stubbing.Answer;

import java.util.*;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.*;

@RunWith(MockitoJUnitRunner.class)
public class SentryAppenderTest {
    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
    private Raven mockRaven;
    @Mock
    private DefaultErrorHandler mockErrorHandler;
    private SentryAppender sentryAppender;

    @Before
    public void setUp() throws Exception {
        sentryAppender = new SentryAppender(mockRaven);
        setMockErrorHandlerOnAppender(sentryAppender);
    }

    private void setMockErrorHandlerOnAppender(final SentryAppender sentryAppender) {
        sentryAppender.setHandler(mockErrorHandler);

        Answer<Void> answer = new Answer<Void>() {
            private final DefaultErrorHandler actualErrorHandler = new DefaultErrorHandler(sentryAppender);

            @Override
            public Void answer(InvocationOnMock invocation) throws Throwable {
                invocation.getMethod().invoke(actualErrorHandler, invocation.getArguments());
                return null;
            }
        };
        doAnswer(answer).when(mockErrorHandler).error(anyString());
        doAnswer(answer).when(mockErrorHandler).error(anyString(), any(Throwable.class));
        doAnswer(answer).when(mockErrorHandler).error(anyString(), any(LogEvent.class), any(Throwable.class));
    }

    @Test
    public void testSimpleMessageLogging() throws Exception {
        String messageContent = UUID.randomUUID().toString();
        String loggerName = UUID.randomUUID().toString();
        String threadName = UUID.randomUUID().toString();
        Date date = new Date(1373883196416L);
        ArgumentCaptor<Event> eventCaptor = ArgumentCaptor.forClass(Event.class);
        Event event;

        sentryAppender.append(new Log4jLogEvent(loggerName, null, null, Level.INFO, new SimpleMessage(messageContent),
                null, null, null, threadName, null, date.getTime()));

        verify(mockRaven).runBuilderHelpers(any(EventBuilder.class));
        verify(mockRaven).sendEvent(eventCaptor.capture());
        event = eventCaptor.getValue();
        assertThat(event.getMessage(), is(messageContent));
        assertThat(event.getLogger(), is(loggerName));
        assertThat(event.getExtra(), Matchers.<String, Object>hasEntry(SentryAppender.THREAD_NAME, threadName));
        assertThat(event.getTimestamp(), is(date));

        assertNoErrors();
    }

    @Test
    public void testLogLevelConversions() throws Exception {
        assertLevelConverted(Event.Level.DEBUG, Level.TRACE);
        assertLevelConverted(Event.Level.DEBUG, Level.DEBUG);
        assertLevelConverted(Event.Level.INFO, Level.INFO);
        assertLevelConverted(Event.Level.WARNING, Level.WARN);
        assertLevelConverted(Event.Level.ERROR, Level.ERROR);
        assertLevelConverted(Event.Level.FATAL, Level.FATAL);
    }

    private void assertLevelConverted(Event.Level expectedLevel, Level level) {
        ArgumentCaptor<Event> eventCaptor = ArgumentCaptor.forClass(Event.class);

        sentryAppender.append(new Log4jLogEvent(null, null, null, level, new SimpleMessage(""), null));

        verify(mockRaven).sendEvent(eventCaptor.capture());
        assertThat(eventCaptor.getValue().getLevel(), is(expectedLevel));
        assertNoErrors();
        reset(mockRaven);
    }

    @Test
    public void testExceptionLogging() throws Exception {
        Exception exception = new Exception();
        ArgumentCaptor<Event> eventCaptor = ArgumentCaptor.forClass(Event.class);

        sentryAppender.append(new Log4jLogEvent(null, null, null, Level.ERROR, new SimpleMessage(""), exception));

        verify(mockRaven).sendEvent(eventCaptor.capture());
        ExceptionInterface exceptionInterface = (ExceptionInterface) eventCaptor.getValue().getSentryInterfaces()
                .get(ExceptionInterface.EXCEPTION_INTERFACE);
        Throwable capturedException = exceptionInterface.getThrowable();

        assertThat(capturedException.getMessage(), is(exception.getMessage()));
        assertThat(capturedException.getStackTrace(), is(exception.getStackTrace()));
        assertNoErrors();
    }

    @Test
    public void testLogParametrisedMessage() throws Exception {
        String messagePattern = "Formatted message {} {} {}";
        Object[] parameters = {"first parameter", new Object[0], null};
        ArgumentCaptor<Event> eventCaptor = ArgumentCaptor.forClass(Event.class);

        sentryAppender.append(new Log4jLogEvent(null, null, null, Level.INFO,
                new FormattedMessage(messagePattern, parameters), null));

        verify(mockRaven).sendEvent(eventCaptor.capture());
        MessageInterface messageInterface = (MessageInterface) eventCaptor.getValue().getSentryInterfaces()
                .get(MessageInterface.MESSAGE_INTERFACE);

        assertThat(eventCaptor.getValue().getMessage(), is("Formatted message first parameter [] null"));
        assertThat(messageInterface.getMessage(), is(messagePattern));
        assertThat(messageInterface.getParameters(),
                is(Arrays.asList(parameters[0].toString(), parameters[1].toString(), null)));
        assertNoErrors();
    }

    @Test
    public void testMarkerAddedToTag() throws Exception {
        String markerName = UUID.randomUUID().toString();
        ArgumentCaptor<Event> eventCaptor = ArgumentCaptor.forClass(Event.class);

        sentryAppender.append(new Log4jLogEvent(null, MarkerManager.getMarker(markerName), null,
                Level.INFO, new SimpleMessage(""), null));

        verify(mockRaven).sendEvent(eventCaptor.capture());
        assertThat(eventCaptor.getValue().getTags(),
                Matchers.<String, Object>hasEntry(SentryAppender.LOG4J_MARKER, markerName));
        assertNoErrors();
    }

    @Test
    public void testMdcAddedToExtra() throws Exception {
        String extraKey = UUID.randomUUID().toString();
        String extraValue = UUID.randomUUID().toString();
        ArgumentCaptor<Event> eventCaptor = ArgumentCaptor.forClass(Event.class);

        sentryAppender.append(new Log4jLogEvent(null, null, null, Level.INFO, new SimpleMessage(""), null,
                Collections.singletonMap(extraKey, extraValue), null, null, null, 0));

        verify(mockRaven).sendEvent(eventCaptor.capture());
        assertThat(eventCaptor.getValue().getExtra(), Matchers.<String, Object>hasEntry(extraKey, extraValue));
        assertNoErrors();
    }

    @Test
    @SuppressWarnings("unchecked")
    public void testNdcAddedToExtra() throws Exception {
        ArgumentCaptor<Event> eventCaptor = ArgumentCaptor.forClass(Event.class);
        ThreadContext.ContextStack contextStack = new DefaultThreadContextStack(true);

        contextStack.push(UUID.randomUUID().toString());
        contextStack.push(UUID.randomUUID().toString());
        contextStack.push(UUID.randomUUID().toString());
        sentryAppender.append(new Log4jLogEvent(null, null, null, Level.INFO, new SimpleMessage(""), null,
                null, contextStack, null, null, 0));
{'fraction_non_alphanumeric': 0.11147870266438235, 'fraction_numerical': 0.004489868257812961, 'mean_word_length': 4.032104637336504, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6892404', 'n_tokens_mistral': 4730, 'n_tokens_neox': 4641, 'n_words': 796}