Skip to content

Commit

Permalink
Fix tests
Browse files Browse the repository at this point in the history
  • Loading branch information
MatkovIvan committed Oct 26, 2018
1 parent bc992de commit 8a74659
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 120 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
public ContentValues nextValues(Cursor cursor) {
try {
if (cursor.moveToNext()) {
return buildValues(cursor, mSchema);
return buildValues(cursor);
}
} catch (RuntimeException e) {
AppCenterLog.error(LOG_TAG, "Failed to get next cursor value: ", e);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.microsoft.appcenter;

import android.app.Application;
import android.content.ContentValues;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.database.Cursor;
import android.database.sqlite.SQLiteQueryBuilder;
import android.os.Bundle;
import android.os.Handler;
Expand All @@ -23,7 +23,6 @@
import com.microsoft.appcenter.utils.storage.DatabaseManager;
import com.microsoft.appcenter.utils.storage.FileManager;
import com.microsoft.appcenter.utils.storage.SharedPreferencesManager;
import com.microsoft.appcenter.utils.storage.FileManager;

import org.junit.After;
import org.junit.Before;
Expand All @@ -36,15 +35,12 @@
import org.powermock.modules.junit4.rule.PowerMockRule;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import static com.microsoft.appcenter.AppCenter.KEY_VALUE_DELIMITER;
import static com.microsoft.appcenter.AppCenter.TRANSMISSION_TARGET_TOKEN_KEY;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyCollectionOf;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
Expand Down Expand Up @@ -82,9 +78,6 @@ public class AbstractAppCenterTest {
@Rule
public PowerMockRule mPowerMockRule = new PowerMockRule();

@Mock
private Iterator<ContentValues> mDataBaseScannerIterator;

@Mock
DefaultChannel mChannel;

Expand Down Expand Up @@ -167,9 +160,8 @@ public Void answer(InvocationOnMock invocation) {
/* Mock empty database. */
DatabaseManager databaseManager = mock(DatabaseManager.class);
whenNew(DatabaseManager.class).withAnyArguments().thenReturn(databaseManager);
DatabaseManager.Scanner databaseScanner = mock(DatabaseManager.Scanner.class);
when(databaseManager.getScanner(any(SQLiteQueryBuilder.class), any(String[].class), anyBoolean())).thenReturn(databaseScanner);
when(databaseScanner.iterator()).thenReturn(mDataBaseScannerIterator);
when(databaseManager.getCursor(any(SQLiteQueryBuilder.class), any(String[].class), anyBoolean()))
.thenReturn(mock(Cursor.class));

/* Mock network state helper. */
when(NetworkStateHelper.getSharedInstance(any(Context.class))).thenReturn(mNetworkStateHelper);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.CursorWrapper;
import android.database.sqlite.SQLiteQueryBuilder;

import com.microsoft.appcenter.AppCenter;
Expand All @@ -10,7 +12,6 @@
import com.microsoft.appcenter.ingestion.models.json.LogSerializer;
import com.microsoft.appcenter.utils.AppCenterLog;
import com.microsoft.appcenter.utils.storage.DatabaseManager;
import com.microsoft.appcenter.utils.storage.SQLiteUtils;

import org.json.JSONException;
import org.junit.Rule;
Expand All @@ -21,20 +22,15 @@
import org.powermock.modules.junit4.rule.PowerMockRule;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import static com.microsoft.appcenter.persistence.DatabasePersistence.COLUMN_GROUP;
import static com.microsoft.appcenter.persistence.DatabasePersistence.COLUMN_TARGET_KEY;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyCollectionOf;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doReturn;
Expand Down Expand Up @@ -103,11 +99,13 @@ public void clearPendingLogState() throws Exception {
/* Mock instances. */
DatabaseManager mockDatabaseManager = mock(DatabaseManager.class);
whenNew(DatabaseManager.class).withAnyArguments().thenReturn(mockDatabaseManager);
when(mockDatabaseManager.nextValues(any(Cursor.class))).thenCallRealMethod();

for (int i = 0; i < groupCount; i++) {
DatabaseManager.Scanner mockDatabaseScanner = mock(DatabaseManager.Scanner.class);
when(mockDatabaseScanner.iterator()).thenReturn(list.get(i).iterator());
when(mockDatabaseManager.getScanner(any(SQLiteQueryBuilder.class), eq(new String[]{String.valueOf(i)}), eq(false))).thenReturn(mockDatabaseScanner);
MockCursor mockCursor = new MockCursor(list.get(i));
mockCursor.mockBuildValues(mockDatabaseManager);
when(mockDatabaseManager.getCursor(any(SQLiteQueryBuilder.class), eq(new String[]{String.valueOf(i)}), eq(false)))
.thenReturn(mockCursor);
}

LogSerializer mockLogSerializer = mock(LogSerializer.class);
Expand Down Expand Up @@ -139,9 +137,10 @@ public void getLogsWithCorruption() throws Exception {
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. */
Collection<ContentValues> fieldValues = new ArrayList<>(logCount);
List<ContentValues> fieldValues = new ArrayList<>(logCount);
{
/* Valid record. */
ContentValues contentValues = mock(ContentValues.class);
Expand All @@ -164,20 +163,20 @@ public void getLogsWithCorruption() throws Exception {
}

/* Mock log sequence retrieved from scanner. */
DatabaseManager.Scanner databaseScanner = mock(DatabaseManager.Scanner.class);
when(databaseManager.getScanner(any(SQLiteQueryBuilder.class), any(String[].class), eq(false))).thenReturn(databaseScanner);
when(databaseScanner.iterator()).thenReturn(fieldValues.iterator());
MockCursor mockCursor = new MockCursor(fieldValues);
mockCursor.mockBuildValues(databaseManager);
when(databaseManager.getCursor(any(SQLiteQueryBuilder.class), any(String[].class), eq(false))).thenReturn(mockCursor);

/* Mock second scanner with identifiers only. */
Collection<ContentValues> idValues = new ArrayList<>(logCount);
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);
}
DatabaseManager.Scanner idDatabaseScanner = mock(DatabaseManager.Scanner.class);
when(databaseManager.getScanner(any(SQLiteQueryBuilder.class), any(String[].class), eq(true))).thenReturn(idDatabaseScanner);
when(idDatabaseScanner.iterator()).thenReturn(idValues.iterator());
MockCursor mockIdCursor = new MockCursor(idValues);
mockIdCursor.mockBuildValues(databaseManager);
when(databaseManager.getCursor(any(SQLiteQueryBuilder.class), any(String[].class), eq(true))).thenReturn(mockIdCursor);

/* Mock serializer and eventually the database. */
LogSerializer logSerializer = mock(LogSerializer.class);
Expand Down Expand Up @@ -245,7 +244,9 @@ public Log answer(InvocationOnMock invocation) {
when(contentValues.getAsString(DatabasePersistence.COLUMN_LOG)).thenReturn("true last");
fieldValues.add(contentValues);
}
when(databaseScanner.iterator()).thenReturn(fieldValues.iterator());
mockCursor = new MockCursor(fieldValues);
mockCursor.mockBuildValues(databaseManager);
when(databaseManager.getCursor(any(SQLiteQueryBuilder.class), any(String[].class), eq(false))).thenReturn(mockCursor);
idValues = new ArrayList<>(4);

/* Here the id scanner will also skip the new corrupted log which id would be 3. */
Expand All @@ -254,7 +255,9 @@ public Log answer(InvocationOnMock invocation) {
when(contentValues.getAsLong(DatabaseManager.PRIMARY_KEY)).thenReturn(i);
idValues.add(contentValues);
}
when(idDatabaseScanner.iterator()).thenReturn(idValues.iterator());
mockIdCursor = new MockCursor(idValues);
mockIdCursor.mockBuildValues(databaseManager);
when(databaseManager.getCursor(any(SQLiteQueryBuilder.class), any(String[].class), eq(true))).thenReturn(mockIdCursor);

/* Verify next call is only the new valid log as others are marked pending. */
outLogs = new ArrayList<>();
Expand All @@ -272,13 +275,40 @@ public void checkSetStorageSizeForwarding() throws Exception {
/* The real Android test for checking size is in DatabaseManagerAndroidTest. */
DatabaseManager databaseManager = mock(DatabaseManager.class);
whenNew(DatabaseManager.class).withAnyArguments().thenReturn(databaseManager);
DatabaseManager.Scanner databaseScanner = mock(DatabaseManager.Scanner.class);
when(databaseManager.getScanner(any(SQLiteQueryBuilder.class), any(String[].class), anyBoolean())).thenReturn(databaseScanner);
when(databaseManager.getCursor(any(SQLiteQueryBuilder.class), any(String[].class), anyBoolean()))
.thenReturn(mock(Cursor.class));
when(databaseManager.setMaxSize(anyLong())).thenReturn(true).thenReturn(false);

/* Just checks calls are forwarded to the low level database layer. */
DatabasePersistence persistence = new DatabasePersistence(mock(Context.class));
assertTrue(persistence.setMaxStorageSize(20480));
assertFalse(persistence.setMaxStorageSize(2));
}

private static class MockCursor extends CursorWrapper {

private final List<ContentValues> mList;

private int mIndex = -1;

private MockCursor(List<ContentValues> list) {
super(null);
mList = list;
}

@Override
public boolean moveToNext() {
return ++mIndex < mList.size();
}

private void mockBuildValues(DatabaseManager databaseManager) {
when(databaseManager.buildValues(eq(this))).then(new Answer<ContentValues>() {

@Override
public ContentValues answer(InvocationOnMock invocation) {
return mList.get(mIndex);
}
});
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,10 @@
import java.util.Arrays;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
Expand Down Expand Up @@ -123,91 +121,6 @@ public void rowCountFailed() {
AppCenterLog.error(eq(AppCenter.LOG_TAG), anyString(), any(RuntimeException.class));
}

@Test
public void scannerIteratorFailed() {
mockStatic(AppCenterLog.class);
DatabaseManager databaseManagerMock;
databaseManagerMock = getDatabaseManagerMock();
databaseManagerMock.getScanner().iterator();
verifyStatic();
AppCenterLog.error(eq(AppCenter.LOG_TAG), anyString(), any(RuntimeException.class));
}

@Test
public void scannerCountFailed() {
mockStatic(AppCenterLog.class);
DatabaseManager databaseManagerMock;
databaseManagerMock = getDatabaseManagerMock();
databaseManagerMock.getScanner().getCount();
verifyStatic();
AppCenterLog.error(eq(AppCenter.LOG_TAG), anyString(), any(RuntimeException.class));
}

@Test
public void scannerNextFailedButClosingWorks() {
mockStatic(AppCenterLog.class);
DatabaseManager databaseManagerMock;

/* Cursor next failing but closing working. */
databaseManagerMock = spy(new DatabaseManager(null, "database", "table", 1, null, null));
when(databaseManagerMock.getDatabase()).thenReturn(mock(SQLiteDatabase.class));
mockStatic(SQLiteUtils.class);
Cursor cursor = mock(Cursor.class);
SQLiteQueryBuilder sqLiteQueryBuilder = mock(SQLiteQueryBuilder.class, new Returns(cursor));
when(SQLiteUtils.newSQLiteQueryBuilder()).thenReturn(sqLiteQueryBuilder);
when(cursor.moveToNext()).thenThrow(new RuntimeException());
DatabaseManager.Scanner scanner = databaseManagerMock.getScanner();
assertFalse(scanner.iterator().hasNext());
verifyStatic(never());
AppCenterLog.error(eq(AppCenter.LOG_TAG), anyString(), any(RuntimeException.class));

/* Verify closing failed. */
verifyStatic(never());
AppCenterLog.warn(eq(AppCenter.LOG_TAG), anyString(), any(RuntimeException.class));
}

@Test
public void scannerNextFailedAndClosingFails() {
mockStatic(AppCenterLog.class);
DatabaseManager databaseManagerMock;

/* Cursor next failing and closing failing. */
databaseManagerMock = spy(new DatabaseManager(null, "database", "table", 1, null, null));
when(databaseManagerMock.getDatabase()).thenReturn(mock(SQLiteDatabase.class));
mockStatic(SQLiteUtils.class);
Cursor cursor = mock(Cursor.class);
SQLiteQueryBuilder sqLiteQueryBuilder = mock(SQLiteQueryBuilder.class, new Returns(cursor));
when(SQLiteUtils.newSQLiteQueryBuilder()).thenReturn(sqLiteQueryBuilder);
when(cursor.moveToNext()).thenThrow(new RuntimeException());
doThrow(new RuntimeException()).when(cursor).close();
DatabaseManager.Scanner scanner = databaseManagerMock.getScanner();
assertFalse(scanner.iterator().hasNext());
verifyStatic(never());
AppCenterLog.error(eq(AppCenter.LOG_TAG), anyString(), any(RuntimeException.class));

/* Verify closing failed. */
verifyStatic();
AppCenterLog.warn(eq(AppCenter.LOG_TAG), anyString(), any(RuntimeException.class));
}

@Test
public void cursorCloseFailed() {
mockStatic(AppCenterLog.class);
DatabaseManager databaseManagerMock;
databaseManagerMock = spy(new DatabaseManager(null, "database", "table", 1, null, null));
when(databaseManagerMock.getDatabase()).thenReturn(mock(SQLiteDatabase.class));
mockStatic(SQLiteUtils.class);
Cursor cursor = mock(Cursor.class);
SQLiteQueryBuilder sqLiteQueryBuilder = mock(SQLiteQueryBuilder.class, new Returns(cursor));
when(SQLiteUtils.newSQLiteQueryBuilder()).thenReturn(sqLiteQueryBuilder);
doThrow(new RuntimeException()).when(cursor).close();
DatabaseManager.Scanner scanner = databaseManagerMock.getScanner();
assertFalse(scanner.iterator().hasNext());
scanner.close();
verifyStatic();
AppCenterLog.error(eq(AppCenter.LOG_TAG), anyString(), any(RuntimeException.class));
}

@Test
public void getDatabaseFailedOnce() {

Expand Down

0 comments on commit 8a74659

Please sign in to comment.