Search in sources :

Example 6 with DatabaseManager

use of com.microsoft.appcenter.utils.storage.DatabaseManager in project mobile-center-sdk-android by Microsoft.

the class DatabasePersistenceTest method getLogsWithCorruption.

@Test
public void getLogsWithCorruption() throws Exception {
    /* Mock instances. */
    int logCount = 3;
    DatabaseManager databaseManager = mock(DatabaseManager.class);
    whenNew(DatabaseManager.class).withAnyArguments().thenReturn(databaseManager);
    when(databaseManager.nextValues(any(Cursor.class))).thenCallRealMethod();
    /* Make 3 logs, the second one will be corrupted. */
    List<ContentValues> fieldValues = new ArrayList<>(logCount);
    {
        /* Valid record. */
        ContentValues contentValues = mock(ContentValues.class);
        when(contentValues.getAsLong(DatabaseManager.PRIMARY_KEY)).thenReturn(0L);
        when(contentValues.getAsString(DatabasePersistence.COLUMN_LOG)).thenReturn("first");
        fieldValues.add(contentValues);
    }
    {
        /* Empty record, "corrupted", cause identifier is null (and no other field either). */
        ContentValues contentValues = mock(ContentValues.class);
        when(contentValues.getAsLong(DatabaseManager.PRIMARY_KEY)).thenReturn(null);
        fieldValues.add(contentValues);
    }
    {
        /* Valid record. */
        ContentValues contentValues = mock(ContentValues.class);
        when(contentValues.getAsLong(DatabaseManager.PRIMARY_KEY)).thenReturn(2L);
        when(contentValues.getAsString(DatabasePersistence.COLUMN_LOG)).thenReturn("last");
        fieldValues.add(contentValues);
    }
    /* Mock log sequence retrieved from cursor. */
    MockCursor mockCursor = new MockCursor(fieldValues);
    mockCursor.mockBuildValues(databaseManager);
    when(databaseManager.getCursor(any(SQLiteQueryBuilder.class), isNull(String[].class), any(String[].class), anyString())).thenReturn(mockCursor);
    /* Mock second cursor with identifiers only. */
    List<ContentValues> idValues = new ArrayList<>(logCount);
    for (long i = 0; i < logCount; i++) {
        ContentValues contentValues = mock(ContentValues.class);
        when(contentValues.getAsLong(DatabaseManager.PRIMARY_KEY)).thenReturn(i);
        idValues.add(contentValues);
    }
    MockCursor mockIdCursor = new MockCursor(idValues);
    mockIdCursor.mockBuildValues(databaseManager);
    when(databaseManager.getCursor(any(SQLiteQueryBuilder.class), isNotNull(String[].class), any(String[].class), anyString())).thenReturn(mockIdCursor);
    /* Mock serializer and eventually the database. */
    LogSerializer logSerializer = mock(LogSerializer.class);
    when(logSerializer.deserializeLog(anyString(), anyString())).thenAnswer(new Answer<Log>() {

        @Override
        public Log answer(InvocationOnMock invocation) {
            /* Hack serializer to return type = payload to simplify checking. */
            Log log = mock(Log.class);
            when(log.getType()).thenReturn((String) invocation.getArguments()[0]);
            return log;
        }
    });
    DatabasePersistence persistence = new DatabasePersistence(mock(Context.class));
    persistence.setLogSerializer(logSerializer);
    /* Get logs and verify we get only non corrupted logs. */
    ArrayList<Log> outLogs = new ArrayList<>();
    persistence.getLogs("mock", Collections.<String>emptyList(), 50, outLogs);
    assertEquals(logCount - 1, outLogs.size());
    assertEquals("first", outLogs.get(0).getType());
    assertEquals("last", outLogs.get(1).getType());
    /* Verify we detected and deleted the corrupted log, the second one. */
    verify(databaseManager).delete(1);
    /* Verify next call is empty logs as they are pending. */
    outLogs = new ArrayList<>();
    persistence.getLogs("mock", Collections.<String>emptyList(), 50, outLogs);
    assertEquals(0, outLogs.size());
    /*
         * Add new logs with corruption again. First 2 logs are still there.
         * Also this time the corrupted log will not even return its identifier when scanning
         * with only id fields, to test that the delete fails gracefully and that we can still
         * work with other logs.
         */
    logCount = 4;
    fieldValues = new ArrayList<>(logCount);
    {
        /* Valid record. */
        ContentValues contentValues = mock(ContentValues.class);
        when(contentValues.getAsLong(DatabaseManager.PRIMARY_KEY)).thenReturn(0L);
        when(contentValues.getAsString(DatabasePersistence.COLUMN_LOG)).thenReturn("first");
        fieldValues.add(contentValues);
    }
    {
        /* Valid record. */
        ContentValues contentValues = mock(ContentValues.class);
        when(contentValues.getAsLong(DatabaseManager.PRIMARY_KEY)).thenReturn(2L);
        when(contentValues.getAsString(DatabasePersistence.COLUMN_LOG)).thenReturn("last");
        fieldValues.add(contentValues);
    }
    {
        /* New corrupted record. */
        ContentValues contentValues = mock(ContentValues.class);
        when(contentValues.getAsLong(DatabaseManager.PRIMARY_KEY)).thenReturn(null);
        fieldValues.add(contentValues);
    }
    {
        /* Valid new record. */
        ContentValues contentValues = mock(ContentValues.class);
        when(contentValues.getAsLong(DatabaseManager.PRIMARY_KEY)).thenReturn(4L);
        when(contentValues.getAsString(DatabasePersistence.COLUMN_LOG)).thenReturn("true last");
        fieldValues.add(contentValues);
    }
    mockCursor = new MockCursor(fieldValues) {

        @Override
        public void close() {
            /* It should be ignored. */
            throw new RuntimeException();
        }
    };
    mockCursor.mockBuildValues(databaseManager);
    when(databaseManager.getCursor(any(SQLiteQueryBuilder.class), isNull(String[].class), any(String[].class), anyString())).thenReturn(mockCursor);
    idValues = new ArrayList<>(4);
    /* Here the id cursor will also skip the new corrupted log which id would be 3. */
    for (long i = 0; i < logCount; i += 2) {
        ContentValues contentValues = mock(ContentValues.class);
        when(contentValues.getAsLong(DatabaseManager.PRIMARY_KEY)).thenReturn(i);
        idValues.add(contentValues);
    }
    mockIdCursor = new MockCursor(idValues) {

        @Override
        public void close() {
            /* It should be ignored. */
            throw new RuntimeException();
        }
    };
    mockIdCursor.mockBuildValues(databaseManager);
    when(databaseManager.getCursor(any(SQLiteQueryBuilder.class), isNotNull(String[].class), any(String[].class), anyString())).thenReturn(mockIdCursor);
    /* Verify next call is only the new valid log as others are marked pending. */
    outLogs = new ArrayList<>();
    persistence.getLogs("mock", Collections.<String>emptyList(), 50, outLogs);
    assertEquals(1, outLogs.size());
    assertEquals("true last", outLogs.get(0).getType());
    /* Verify that the only log we deleted in the entire test was the one from previous test (id=1). */
    verify(databaseManager).delete(anyLong());
}
Also used : ContentValues(android.content.ContentValues) Context(android.content.Context) DatabaseManager(com.microsoft.appcenter.utils.storage.DatabaseManager) AppCenterLog(com.microsoft.appcenter.utils.AppCenterLog) Log(com.microsoft.appcenter.ingestion.models.Log) ArrayList(java.util.ArrayList) LogSerializer(com.microsoft.appcenter.ingestion.models.json.LogSerializer) Matchers.anyString(org.mockito.Matchers.anyString) Cursor(android.database.Cursor) InvocationOnMock(org.mockito.invocation.InvocationOnMock) SQLiteQueryBuilder(android.database.sqlite.SQLiteQueryBuilder) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest) Test(org.junit.Test)

Example 7 with DatabaseManager

use of com.microsoft.appcenter.utils.storage.DatabaseManager in project mobile-center-sdk-android by Microsoft.

the class DatabasePersistenceTest method getLogsWithMoveNextException.

@Test
public void getLogsWithMoveNextException() throws Exception {
    /* Mock instances. */
    mockStatic(AppCenterLog.class);
    DatabaseManager databaseManager = mock(DatabaseManager.class);
    whenNew(DatabaseManager.class).withAnyArguments().thenReturn(databaseManager);
    when(databaseManager.nextValues(any(Cursor.class))).thenCallRealMethod();
    Cursor mockCursor = mock(Cursor.class);
    when(mockCursor.moveToNext()).thenThrow(new RuntimeException());
    when(databaseManager.getCursor(any(SQLiteQueryBuilder.class), any(String[].class), any(String[].class), anyString())).thenReturn(mockCursor);
    DatabasePersistence persistence = new DatabasePersistence(mock(Context.class), 1, DatabasePersistence.SCHEMA);
    /* Try to get logs. */
    ArrayList<Log> outLogs = new ArrayList<>();
    persistence.getLogs("mock", Collections.<String>emptyList(), 50, outLogs);
    assertEquals(0, outLogs.size());
    /* There is an error log. */
    verifyStatic();
    AppCenterLog.error(eq(AppCenter.LOG_TAG), anyString(), any(RuntimeException.class));
}
Also used : Context(android.content.Context) DatabaseManager(com.microsoft.appcenter.utils.storage.DatabaseManager) AppCenterLog(com.microsoft.appcenter.utils.AppCenterLog) Log(com.microsoft.appcenter.ingestion.models.Log) ArrayList(java.util.ArrayList) Cursor(android.database.Cursor) SQLiteQueryBuilder(android.database.sqlite.SQLiteQueryBuilder) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest) Test(org.junit.Test)

Example 8 with DatabaseManager

use of com.microsoft.appcenter.utils.storage.DatabaseManager in project mobile-center-sdk-android by Microsoft.

the class DatabasePersistenceTest method countLogsWithGetCountException.

@Test
public void countLogsWithGetCountException() throws Exception {
    /* Mock instances. */
    mockStatic(AppCenterLog.class);
    DatabaseManager mockDatabaseManager = mock(DatabaseManager.class);
    whenNew(DatabaseManager.class).withAnyArguments().thenReturn(mockDatabaseManager);
    Cursor mockCursor = mock(Cursor.class);
    when(mockCursor.moveToNext()).thenThrow(new RuntimeException());
    when(mockDatabaseManager.getCursor(any(SQLiteQueryBuilder.class), any(String[].class), any(String[].class), anyString())).thenReturn(mockCursor);
    DatabasePersistence persistence = new DatabasePersistence(mock(Context.class), 1, DatabasePersistence.SCHEMA);
    // noinspection TryFinallyCanBeTryWithResources
    try {
        assertEquals(0, persistence.countLogs("test-p1"));
    } finally {
        /* Close. */
        persistence.close();
    }
    /* There is an error log. */
    verifyStatic();
    AppCenterLog.error(eq(AppCenter.LOG_TAG), anyString(), any(RuntimeException.class));
}
Also used : Context(android.content.Context) DatabaseManager(com.microsoft.appcenter.utils.storage.DatabaseManager) Cursor(android.database.Cursor) SQLiteQueryBuilder(android.database.sqlite.SQLiteQueryBuilder) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest) Test(org.junit.Test)

Example 9 with DatabaseManager

use of com.microsoft.appcenter.utils.storage.DatabaseManager in project mobile-center-sdk-android by Microsoft.

the class DatabasePersistenceTest method putLogWithJSONException.

@Test(expected = PersistenceException.class)
public void putLogWithJSONException() throws Exception {
    DatabaseManager databaseManager = mock(DatabaseManager.class);
    whenNew(DatabaseManager.class).withAnyArguments().thenReturn(databaseManager);
    DatabasePersistence persistence = new DatabasePersistence(mock(Context.class));
    /* Set a mock log serializer. */
    LogSerializer logSerializer = mock(LogSerializer.class);
    when(logSerializer.serializeLog(any(Log.class))).thenThrow(new JSONException("JSON exception"));
    persistence.setLogSerializer(logSerializer);
    /* Persist a log. */
    persistence.putLog(mock(Log.class), "test-p1", NORMAL);
}
Also used : Context(android.content.Context) DatabaseManager(com.microsoft.appcenter.utils.storage.DatabaseManager) AppCenterLog(com.microsoft.appcenter.utils.AppCenterLog) Log(com.microsoft.appcenter.ingestion.models.Log) JSONException(org.json.JSONException) LogSerializer(com.microsoft.appcenter.ingestion.models.json.LogSerializer) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest) Test(org.junit.Test)

Example 10 with DatabaseManager

use of com.microsoft.appcenter.utils.storage.DatabaseManager in project mobile-center-sdk-android by Microsoft.

the class DatabasePersistenceTest method putLogWithOpenDatabaseException.

@Test(expected = PersistenceException.class)
public void putLogWithOpenDatabaseException() throws Exception {
    DatabaseManager databaseManager = mock(DatabaseManager.class);
    whenNew(DatabaseManager.class).withAnyArguments().thenReturn(databaseManager);
    when(databaseManager.getMaxSize()).thenReturn(-1L);
    DatabasePersistence persistence = new DatabasePersistence(mock(Context.class));
    /* Set a mock log serializer. */
    LogSerializer logSerializer = mock(LogSerializer.class);
    when(logSerializer.serializeLog(any(Log.class))).thenReturn("mock");
    persistence.setLogSerializer(logSerializer);
    /* Persist a log. */
    persistence.putLog(mock(Log.class), "test-p1", NORMAL);
}
Also used : Context(android.content.Context) DatabaseManager(com.microsoft.appcenter.utils.storage.DatabaseManager) AppCenterLog(com.microsoft.appcenter.utils.AppCenterLog) Log(com.microsoft.appcenter.ingestion.models.Log) LogSerializer(com.microsoft.appcenter.ingestion.models.json.LogSerializer) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest) Test(org.junit.Test)

Aggregations

DatabaseManager (com.microsoft.appcenter.utils.storage.DatabaseManager)11 Context (android.content.Context)10 Test (org.junit.Test)10 PrepareForTest (org.powermock.core.classloader.annotations.PrepareForTest)9 Cursor (android.database.Cursor)8 SQLiteQueryBuilder (android.database.sqlite.SQLiteQueryBuilder)8 Log (com.microsoft.appcenter.ingestion.models.Log)8 AppCenterLog (com.microsoft.appcenter.utils.AppCenterLog)7 ArrayList (java.util.ArrayList)6 LogSerializer (com.microsoft.appcenter.ingestion.models.json.LogSerializer)5 ContentValues (android.content.ContentValues)4 Matchers.anyString (org.mockito.Matchers.anyString)3 InvocationOnMock (org.mockito.invocation.InvocationOnMock)2 ApplicationInfo (android.content.pm.ApplicationInfo)1 SQLiteDiskIOException (android.database.sqlite.SQLiteDiskIOException)1 Handler (android.os.Handler)1 HandlerThread (android.os.HandlerThread)1 Looper (android.os.Looper)1 MediumTest (androidx.test.filters.MediumTest)1 DefaultLogSerializer (com.microsoft.appcenter.ingestion.models.json.DefaultLogSerializer)1