Search in sources :

Example 6 with Log

use of com.microsoft.appcenter.ingestion.models.Log in project mobile-center-sdk-android by Microsoft.

the class SessionTrackerTest method pastSessions.

@Test
public void pastSessions() {
    /* Get a current session. */
    UUID firstSid, currentSid;
    long firstSessionTime = mMockTime;
    {
        Log log = newEvent();
        mSessionTracker.onEnqueuingLog(log, TEST_GROUP);
        assertNotNull(log.getSid());
        currentSid = firstSid = log.getSid();
    }
    /* Verify session reused for second log. */
    {
        Log log = newEvent();
        mSessionTracker.onEnqueuingLog(log, TEST_GROUP);
        assertEquals(currentSid, log.getSid());
    }
    /* Past log: correlation will fail and thus use no session. */
    {
        Log log = newEvent();
        log.setTimestamp(new Date(123L));
        mSessionTracker.onEnqueuingLog(log, TEST_GROUP);
        assertNull(log.getSid());
    }
    /* No usage from background for a long time, should produce a new session but we'll correlate, correlation does not trigger a new session. */
    {
        spendTime(30000);
        Log log = newEvent();
        log.setTimestamp(new Date(firstSessionTime + 1));
        mSessionTracker.onEnqueuingLog(log, TEST_GROUP);
        assertEquals(currentSid, log.getSid());
        Set<String> sessions = StorageHelper.PreferencesStorage.getStringSet("sessions");
        assertNotNull(sessions);
        assertEquals(1, sessions.size());
    }
    /* Trigger a second session. */
    {
        Log log = newEvent();
        mSessionTracker.onEnqueuingLog(log, TEST_GROUP);
        assertNotEquals(currentSid, log.getSid());
        Set<String> sessions = StorageHelper.PreferencesStorage.getStringSet("sessions");
        assertNotNull(sessions);
        assertEquals(2, sessions.size());
    }
    /* Correlate log to previous. */
    {
        spendTime(30000);
        Log log = newEvent();
        log.setTimestamp(new Date(firstSessionTime + 1));
        mSessionTracker.onEnqueuingLog(log, TEST_GROUP);
        assertEquals(firstSid, log.getSid());
        Set<String> sessions = StorageHelper.PreferencesStorage.getStringSet("sessions");
        assertNotNull(sessions);
        assertEquals(2, sessions.size());
    }
    /* Re-test with persistence now, no current session but same correlation will work and no session will be triggered on the new instance. */
    mSessionTracker = new SessionTracker(mChannel, TEST_GROUP);
    {
        Log log = newEvent();
        log.setTimestamp(new Date(firstSessionTime + 1));
        mSessionTracker.onEnqueuingLog(log, TEST_GROUP);
        assertEquals(firstSid, log.getSid());
        Set<String> sessions = StorageHelper.PreferencesStorage.getStringSet("sessions");
        assertNotNull(sessions);
        assertEquals(2, sessions.size());
    }
    /* Failed correlation without an active session will not start a new session. */
    {
        Log log = newEvent();
        log.setTimestamp(new Date(1));
        mSessionTracker.onEnqueuingLog(log, TEST_GROUP);
        assertNull(log.getSid());
        Set<String> sessions = StorageHelper.PreferencesStorage.getStringSet("sessions");
        assertNotNull(sessions);
        assertEquals(2, sessions.size());
    }
    /* Clear sessions. */
    mSessionTracker.clearSessions();
    verifyStatic();
    StorageHelper.PreferencesStorage.remove("sessions");
}
Also used : LinkedHashSet(java.util.LinkedHashSet) Set(java.util.Set) StartSessionLog(com.microsoft.appcenter.analytics.ingestion.models.StartSessionLog) StartServiceLog(com.microsoft.appcenter.ingestion.models.StartServiceLog) EventLog(com.microsoft.appcenter.analytics.ingestion.models.EventLog) Log(com.microsoft.appcenter.ingestion.models.Log) UUID(java.util.UUID) Date(java.util.Date) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest) Test(org.junit.Test)

Example 7 with Log

use of com.microsoft.appcenter.ingestion.models.Log in project mobile-center-sdk-android by Microsoft.

the class SessionTrackerTest method sdkConfiguredBetweenPauseAndResume.

@Test
public void sdkConfiguredBetweenPauseAndResume() {
    /* Pause application before we saw the first resume event (integration problem). We are handling that gracefully though. */
    mSessionTracker.onActivityPaused();
    /* Application is in background, send a log, verify decoration. */
    UUID expectedSid;
    StartSessionLog expectedStartSessionLog = new StartSessionLog();
    {
        Log log = newEvent();
        mSessionTracker.onEnqueuingLog(log, TEST_GROUP);
        mSessionTracker.onEnqueuingLog(expectedStartSessionLog, TEST_GROUP);
        assertNotNull(log.getSid());
        expectedSid = log.getSid();
        expectedStartSessionLog.setSid(expectedSid);
        verify(mChannel).enqueue(expectedStartSessionLog, TEST_GROUP);
    }
    /* Verify session reused for second log. */
    {
        Log log = newEvent();
        mSessionTracker.onEnqueuingLog(log, TEST_GROUP);
        mSessionTracker.onEnqueuingLog(expectedStartSessionLog, TEST_GROUP);
        assertEquals(expectedSid, log.getSid());
        verify(mChannel).enqueue(expectedStartSessionLog, TEST_GROUP);
    }
    /* No usage from background for a long time: new session. */
    {
        spendTime(30000);
        Log log = newEvent();
        mSessionTracker.onEnqueuingLog(log, TEST_GROUP);
        mSessionTracker.onEnqueuingLog(expectedStartSessionLog, TEST_GROUP);
        assertNotEquals(expectedSid, log.getSid());
        expectedSid = log.getSid();
        expectedStartSessionLog.setSid(expectedSid);
        verify(mChannel).enqueue(expectedStartSessionLog, TEST_GROUP);
    }
    /* App comes to foreground and sends a log, we were in background for a long time but we sent a log recently, still session. */
    {
        mSessionTracker.onActivityResumed();
        Log log = newEvent();
        mSessionTracker.onEnqueuingLog(log, TEST_GROUP);
        mSessionTracker.onEnqueuingLog(expectedStartSessionLog, TEST_GROUP);
        assertEquals(expectedSid, log.getSid());
        verify(mChannel).enqueue(expectedStartSessionLog, TEST_GROUP);
    }
    /* We are in foreground, even after timeout a log is still in session. */
    {
        spendTime(30000);
        Log log = newEvent();
        mSessionTracker.onEnqueuingLog(log, TEST_GROUP);
        mSessionTracker.onEnqueuingLog(expectedStartSessionLog, TEST_GROUP);
        assertEquals(expectedSid, log.getSid());
        verify(mChannel).enqueue(expectedStartSessionLog, TEST_GROUP);
    }
}
Also used : StartSessionLog(com.microsoft.appcenter.analytics.ingestion.models.StartSessionLog) StartSessionLog(com.microsoft.appcenter.analytics.ingestion.models.StartSessionLog) StartServiceLog(com.microsoft.appcenter.ingestion.models.StartServiceLog) EventLog(com.microsoft.appcenter.analytics.ingestion.models.EventLog) Log(com.microsoft.appcenter.ingestion.models.Log) UUID(java.util.UUID) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest) Test(org.junit.Test)

Example 8 with Log

use of com.microsoft.appcenter.ingestion.models.Log in project mobile-center-sdk-android by Microsoft.

the class SessionTrackerTest method longSessionStartingFromBackground.

@Test
public void longSessionStartingFromBackground() {
    /* Application is in background, send a log, verify decoration. */
    UUID firstSid;
    long firstSessionTime = mMockTime;
    UUID expectedSid;
    StartSessionLog expectedStartSessionLog = new StartSessionLog();
    {
        Log log = newEvent();
        mSessionTracker.onEnqueuingLog(log, TEST_GROUP);
        mSessionTracker.onEnqueuingLog(expectedStartSessionLog, TEST_GROUP);
        assertNotNull(log.getSid());
        firstSid = expectedSid = log.getSid();
        expectedStartSessionLog.setSid(expectedSid);
        verify(mChannel).enqueue(expectedStartSessionLog, TEST_GROUP);
    }
    /* Verify session reused for second log. */
    {
        Log log = newEvent();
        mSessionTracker.onEnqueuingLog(log, TEST_GROUP);
        mSessionTracker.onEnqueuingLog(expectedStartSessionLog, TEST_GROUP);
        assertEquals(expectedSid, log.getSid());
        verify(mChannel).enqueue(expectedStartSessionLog, TEST_GROUP);
    }
    /* No usage from background for a long time: new session. */
    {
        spendTime(30000);
        Log log = newEvent();
        mSessionTracker.onEnqueuingLog(log, TEST_GROUP);
        mSessionTracker.onEnqueuingLog(expectedStartSessionLog, TEST_GROUP);
        assertNotEquals(expectedSid, log.getSid());
        expectedSid = log.getSid();
        expectedStartSessionLog.setSid(expectedSid);
        verify(mChannel).enqueue(expectedStartSessionLog, TEST_GROUP);
    }
    /* App comes to foreground and sends a log, still session. */
    {
        mSessionTracker.onActivityResumed();
        Log log = newEvent();
        mSessionTracker.onEnqueuingLog(log, TEST_GROUP);
        mSessionTracker.onEnqueuingLog(expectedStartSessionLog, TEST_GROUP);
        assertEquals(expectedSid, log.getSid());
        verify(mChannel).enqueue(expectedStartSessionLog, TEST_GROUP);
    }
    /* We are in foreground, even after timeout a log is still in session. */
    {
        spendTime(30000);
        Log log = newEvent();
        mSessionTracker.onEnqueuingLog(log, TEST_GROUP);
        mSessionTracker.onEnqueuingLog(expectedStartSessionLog, TEST_GROUP);
        assertEquals(expectedSid, log.getSid());
        verify(mChannel).enqueue(expectedStartSessionLog, TEST_GROUP);
    }
    /* Switch to another activity and send a log, still session. */
    {
        spendTime(2);
        mSessionTracker.onActivityPaused();
        spendTime(2);
        mSessionTracker.onActivityResumed();
        Log log = newEvent();
        mSessionTracker.onEnqueuingLog(log, TEST_GROUP);
        mSessionTracker.onEnqueuingLog(expectedStartSessionLog, TEST_GROUP);
        assertEquals(expectedSid, log.getSid());
        verify(mChannel).enqueue(expectedStartSessionLog, TEST_GROUP);
    }
    /* We are in foreground, even after timeout a log is still in session. */
    {
        spendTime(30000);
        Log log = newEvent();
        mSessionTracker.onEnqueuingLog(log, TEST_GROUP);
        mSessionTracker.onEnqueuingLog(expectedStartSessionLog, TEST_GROUP);
        assertEquals(expectedSid, log.getSid());
        verify(mChannel).enqueue(expectedStartSessionLog, TEST_GROUP);
    }
    /* Background for a short time and send log: still in session. */
    {
        spendTime(2);
        mSessionTracker.onActivityPaused();
        spendTime(2);
        Log log = newEvent();
        mSessionTracker.onEnqueuingLog(log, TEST_GROUP);
        mSessionTracker.onEnqueuingLog(expectedStartSessionLog, TEST_GROUP);
        assertEquals(expectedSid, log.getSid());
        verify(mChannel).enqueue(expectedStartSessionLog, TEST_GROUP);
    }
    /* Background for a long time but correlating a log to first session: should not trigger new session. */
    {
        Log log = newEvent();
        log.setTimestamp(new Date(firstSessionTime + 20));
        mSessionTracker.onEnqueuingLog(log, TEST_GROUP);
        mSessionTracker.onEnqueuingLog(expectedStartSessionLog, TEST_GROUP);
        assertEquals(firstSid, log.getSid());
        verify(mChannel).enqueue(expectedStartSessionLog, TEST_GROUP);
    }
    /* Background for a long time and coming back to foreground: new session. */
    {
        spendTime(30000);
        mSessionTracker.onActivityResumed();
        Log log = newEvent();
        mSessionTracker.onEnqueuingLog(log, TEST_GROUP);
        mSessionTracker.onEnqueuingLog(expectedStartSessionLog, TEST_GROUP);
        assertNotEquals(expectedSid, log.getSid());
        expectedSid = log.getSid();
        expectedStartSessionLog.setSid(expectedSid);
        verify(mChannel).enqueue(expectedStartSessionLog, TEST_GROUP);
    }
    /* Background for a long time sending a log: new session. */
    {
        mSessionTracker.onActivityPaused();
        spendTime(30000);
        Log log = newEvent();
        mSessionTracker.onEnqueuingLog(log, TEST_GROUP);
        mSessionTracker.onEnqueuingLog(expectedStartSessionLog, TEST_GROUP);
        assertNotEquals(expectedSid, log.getSid());
        expectedSid = log.getSid();
        expectedStartSessionLog.setSid(expectedSid);
        verify(mChannel).enqueue(expectedStartSessionLog, TEST_GROUP);
    }
}
Also used : StartSessionLog(com.microsoft.appcenter.analytics.ingestion.models.StartSessionLog) StartSessionLog(com.microsoft.appcenter.analytics.ingestion.models.StartSessionLog) StartServiceLog(com.microsoft.appcenter.ingestion.models.StartServiceLog) EventLog(com.microsoft.appcenter.analytics.ingestion.models.EventLog) Log(com.microsoft.appcenter.ingestion.models.Log) UUID(java.util.UUID) Date(java.util.Date) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest) Test(org.junit.Test)

Example 9 with Log

use of com.microsoft.appcenter.ingestion.models.Log in project mobile-center-sdk-android by Microsoft.

the class SessionTrackerTest method ignoreStartService.

@Test
public void ignoreStartService() {
    Log startServiceLog = spy(new StartServiceLog());
    mSessionTracker.onEnqueuingLog(startServiceLog, TEST_GROUP);
    verify(mChannel, never()).enqueue(any(Log.class), anyString());
    verify(startServiceLog, never()).setSid(any(UUID.class));
}
Also used : StartSessionLog(com.microsoft.appcenter.analytics.ingestion.models.StartSessionLog) StartServiceLog(com.microsoft.appcenter.ingestion.models.StartServiceLog) EventLog(com.microsoft.appcenter.analytics.ingestion.models.EventLog) Log(com.microsoft.appcenter.ingestion.models.Log) StartServiceLog(com.microsoft.appcenter.ingestion.models.StartServiceLog) UUID(java.util.UUID) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest) Test(org.junit.Test)

Example 10 with Log

use of com.microsoft.appcenter.ingestion.models.Log in project mobile-center-sdk-android by Microsoft.

the class CrashesAndroidTest method testNoDuplicateCallbacksOrSending.

@Test
public void testNoDuplicateCallbacksOrSending() throws Exception {
    /* Crash on 1st process. */
    assertFalse(Crashes.hasCrashedInLastSession().get());
    android.util.Log.i(TAG, "Process 1");
    Thread.UncaughtExceptionHandler uncaughtExceptionHandler = mock(Thread.UncaughtExceptionHandler.class);
    Thread.setDefaultUncaughtExceptionHandler(uncaughtExceptionHandler);
    CrashesListener crashesListener = mock(CrashesListener.class);
    /* While testing should process, call methods that require the handler to test we avoid a dead lock and run directly. */
    when(crashesListener.shouldProcess(any(ErrorReport.class))).thenAnswer(new Answer<Boolean>() {

        @Override
        public Boolean answer(InvocationOnMock invocationOnMock) throws Throwable {
            assertNotNull(AppCenter.getInstallId().get());
            return AppCenter.isEnabled().get() && Crashes.isEnabled().get();
        }
    });
    when(crashesListener.shouldAwaitUserConfirmation()).thenReturn(true);
    startFresh(crashesListener);
    final Error exception = generateStackOverflowError();
    assertTrue(exception.getStackTrace().length > ErrorLogHelper.FRAME_LIMIT);
    final Thread thread = new Thread() {

        @Override
        public void run() {
            throw exception;
        }
    };
    thread.start();
    thread.join();
    assertEquals(ErrorLogHelper.FRAME_LIMIT, exception.getStackTrace().length);
    verify(uncaughtExceptionHandler).uncaughtException(thread, exception);
    assertEquals(2, ErrorLogHelper.getErrorStorageDirectory().listFiles(mMinidumpFilter).length);
    verifyZeroInteractions(crashesListener);
    /* Second process: enqueue log but network is down... */
    android.util.Log.i(TAG, "Process 2");
    startFresh(crashesListener);
    /* Check last session error report. */
    Crashes.getLastSessionCrashReport().thenAccept(new AppCenterConsumer<ErrorReport>() {

        @Override
        public void accept(ErrorReport errorReport) {
            assertNotNull(errorReport);
            Throwable lastThrowable = errorReport.getThrowable();
            assertTrue(lastThrowable instanceof StackOverflowError);
            assertEquals(ErrorLogHelper.FRAME_LIMIT, lastThrowable.getStackTrace().length);
        }
    });
    assertTrue(Crashes.hasCrashedInLastSession().get());
    /* Wait U.I. thread callback (shouldAwaitUserConfirmation). */
    final Semaphore semaphore = new Semaphore(0);
    HandlerUtils.runOnUiThread(new Runnable() {

        @Override
        public void run() {
            semaphore.release();
        }
    });
    semaphore.acquire();
    /* Waiting user confirmation so no log sent yet. */
    ArgumentMatcher<Log> matchCrashLog = new ArgumentMatcher<Log>() {

        @Override
        public boolean matches(Object o) {
            return o instanceof ManagedErrorLog;
        }
    };
    verify(mChannel, never()).enqueue(argThat(matchCrashLog), anyString());
    assertEquals(2, ErrorLogHelper.getErrorStorageDirectory().listFiles(mMinidumpFilter).length);
    verify(crashesListener).shouldProcess(any(ErrorReport.class));
    verify(crashesListener).shouldAwaitUserConfirmation();
    verifyNoMoreInteractions(crashesListener);
    /* Confirm to resume processing. */
    final AtomicReference<Log> log = new AtomicReference<>();
    doAnswer(new Answer() {

        @Override
        public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
            log.set((Log) invocationOnMock.getArguments()[0]);
            return null;
        }
    }).when(mChannel).enqueue(argThat(matchCrashLog), anyString());
    Crashes.notifyUserConfirmation(Crashes.ALWAYS_SEND);
    assertTrue(Crashes.isEnabled().get());
    verify(mChannel).enqueue(argThat(matchCrashLog), anyString());
    assertNotNull(log.get());
    assertEquals(1, ErrorLogHelper.getErrorStorageDirectory().listFiles(mMinidumpFilter).length);
    verify(crashesListener).getErrorAttachments(any(ErrorReport.class));
    verifyNoMoreInteractions(crashesListener);
    /* Third process: sending succeeds. */
    android.util.Log.i(TAG, "Process 3");
    mChannel = mock(Channel.class);
    ArgumentCaptor<Channel.GroupListener> groupListener = ArgumentCaptor.forClass(Channel.GroupListener.class);
    startFresh(crashesListener);
    verify(mChannel).addGroup(anyString(), anyInt(), anyInt(), anyInt(), groupListener.capture());
    groupListener.getValue().onBeforeSending(log.get());
    groupListener.getValue().onSuccess(log.get());
    /* Wait callback to be processed in background thread (file manipulations) then called back in UI. */
    /*
         * Wait background thread to process the 2 previous commands,
         * to do we check if crashed in last session, since we restarted process again after crash,
         * it's false even if we couldn't send the log yet.
         */
    assertFalse(Crashes.hasCrashedInLastSession().get());
    assertNull(Crashes.getLastSessionCrashReport().get());
    /* Wait U.I. thread callbacks. */
    HandlerUtils.runOnUiThread(new Runnable() {

        @Override
        public void run() {
            semaphore.release();
        }
    });
    semaphore.acquire();
    assertEquals(0, ErrorLogHelper.getErrorStorageDirectory().listFiles(mMinidumpFilter).length);
    verify(mChannel, never()).enqueue(argThat(matchCrashLog), anyString());
    verify(crashesListener).onBeforeSending(any(ErrorReport.class));
    verify(crashesListener).onSendingSucceeded(any(ErrorReport.class));
    verifyNoMoreInteractions(crashesListener);
    /* Verify log was truncated to 256 frames. */
    assertTrue(log.get() instanceof ManagedErrorLog);
    ManagedErrorLog errorLog = (ManagedErrorLog) log.get();
    assertNotNull(errorLog.getException());
    assertNotNull(errorLog.getException().getFrames());
    assertEquals(ErrorLogHelper.FRAME_LIMIT, errorLog.getException().getFrames().size());
}
Also used : Semaphore(java.util.concurrent.Semaphore) ErrorReport(com.microsoft.appcenter.crashes.model.ErrorReport) ManagedErrorLog(com.microsoft.appcenter.crashes.ingestion.models.ManagedErrorLog) ArgumentMatcher(org.mockito.ArgumentMatcher) ErrorAttachmentLog(com.microsoft.appcenter.crashes.ingestion.models.ErrorAttachmentLog) ManagedErrorLog(com.microsoft.appcenter.crashes.ingestion.models.ManagedErrorLog) Log(com.microsoft.appcenter.ingestion.models.Log) Channel(com.microsoft.appcenter.channel.Channel) AtomicReference(java.util.concurrent.atomic.AtomicReference) Answer(org.mockito.stubbing.Answer) Mockito.doAnswer(org.mockito.Mockito.doAnswer) InvocationOnMock(org.mockito.invocation.InvocationOnMock) Test(org.junit.Test)

Aggregations

Log (com.microsoft.appcenter.ingestion.models.Log)64 Test (org.junit.Test)50 ArrayList (java.util.ArrayList)27 AppCenterLog (com.microsoft.appcenter.utils.AppCenterLog)25 Context (android.content.Context)24 UUID (java.util.UUID)23 PrepareForTest (org.powermock.core.classloader.annotations.PrepareForTest)22 LogSerializer (com.microsoft.appcenter.ingestion.models.json.LogSerializer)20 EventLog (com.microsoft.appcenter.analytics.ingestion.models.EventLog)15 DefaultLogSerializer (com.microsoft.appcenter.ingestion.models.json.DefaultLogSerializer)15 StartSessionLog (com.microsoft.appcenter.analytics.ingestion.models.StartSessionLog)14 LogContainer (com.microsoft.appcenter.ingestion.models.LogContainer)14 Channel (com.microsoft.appcenter.channel.Channel)12 Persistence (com.microsoft.appcenter.persistence.Persistence)12 HashMap (java.util.HashMap)11 Matchers.anyString (org.mockito.Matchers.anyString)11 InvocationOnMock (org.mockito.invocation.InvocationOnMock)11 Date (java.util.Date)10 MediumTest (android.support.test.filters.MediumTest)9 IngestionHttp (com.microsoft.appcenter.ingestion.IngestionHttp)9