use of com.microsoft.appcenter.ingestion.models.Log in project mobile-center-sdk-android by Microsoft.
the class DatabasePersistenceTest method clearPendingLogState.
@Test
public void clearPendingLogState() throws JSONException {
/* groupCount should be <= 9. */
final int groupCount = 4;
final int logCount = 10;
/* Mock logs. */
List<List<ContentValues>> list = new ArrayList<>();
for (int i = 0; i < groupCount; i++) {
List<ContentValues> iterator = new ArrayList<>();
for (long l = 1; l <= logCount; l++) {
ContentValues values = mock(ContentValues.class);
when(values.getAsLong(DatabaseManager.PRIMARY_KEY)).thenReturn(l + i * logCount);
when(values.getAsString(DatabasePersistence.COLUMN_LOG)).thenReturn("{}");
iterator.add(values);
}
list.add(iterator);
}
/* Mock instances. */
mockStatic(StorageHelper.DatabaseStorage.class);
StorageHelper.DatabaseStorage mockDatabaseStorage = mock(StorageHelper.DatabaseStorage.class);
when(StorageHelper.DatabaseStorage.getDatabaseStorage(anyString(), anyString(), anyInt(), any(ContentValues.class), anyInt(), any(StorageHelper.DatabaseStorage.DatabaseErrorListener.class))).thenReturn(mockDatabaseStorage);
for (int i = 0; i < groupCount; i++) {
StorageHelper.DatabaseStorage.DatabaseScanner mockDatabaseScanner = mock(StorageHelper.DatabaseStorage.DatabaseScanner.class);
when(mockDatabaseScanner.iterator()).thenReturn(list.get(i).iterator());
when(mockDatabaseStorage.getScanner(COLUMN_GROUP, String.valueOf(i))).thenReturn(mockDatabaseScanner);
}
LogSerializer mockLogSerializer = mock(LogSerializer.class);
when(mockLogSerializer.deserializeLog(anyString())).thenReturn(mock(Log.class));
/* Instantiate Database Persistence. */
DatabasePersistence persistence = new DatabasePersistence();
persistence.setLogSerializer(mockLogSerializer);
/* Get logs. */
for (int i = 0; i < groupCount; i++) {
persistence.getLogs(String.valueOf(i), logCount, new ArrayList<Log>());
}
/* Verify there are 4 pending groups. */
assertEquals(groupCount, persistence.mPendingDbIdentifiersGroups.size());
assertEquals(groupCount * logCount, persistence.mPendingDbIdentifiers.size());
/* Clear all pending groups and verify. */
persistence.clearPendingLogState();
assertEquals(0, persistence.mPendingDbIdentifiersGroups.size());
assertEquals(0, persistence.mPendingDbIdentifiers.size());
}
use of com.microsoft.appcenter.ingestion.models.Log in project mobile-center-sdk-android by Microsoft.
the class DatabasePersistenceTest method getLogsWithCorruption.
@Test
public void getLogsWithCorruption() throws JSONException {
/* Mock instances. */
int logCount = 3;
mockStatic(StorageHelper.DatabaseStorage.class);
StorageHelper.DatabaseStorage databaseStorage = mock(StorageHelper.DatabaseStorage.class);
when(StorageHelper.DatabaseStorage.getDatabaseStorage(anyString(), anyString(), anyInt(), any(ContentValues.class), anyInt(), any(StorageHelper.DatabaseStorage.DatabaseErrorListener.class))).thenReturn(databaseStorage);
/* Make 3 logs, the second one will be corrupted. */
Collection<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 scanner. */
StorageHelper.DatabaseStorage.DatabaseScanner databaseScanner = mock(StorageHelper.DatabaseStorage.DatabaseScanner.class);
when(databaseStorage.getScanner(anyString(), anyString())).thenReturn(databaseScanner);
when(databaseStorage.getScanner(anyString(), anyString(), eq(false))).thenReturn(databaseScanner);
when(databaseScanner.iterator()).thenReturn(fieldValues.iterator());
/* Mock second scanner with identifiers only. */
Collection<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);
}
StorageHelper.DatabaseStorage.DatabaseScanner idDatabaseScanner = mock(StorageHelper.DatabaseStorage.DatabaseScanner.class);
when(databaseStorage.getScanner(anyString(), anyString(), eq(true))).thenReturn(idDatabaseScanner);
when(idDatabaseScanner.iterator()).thenReturn(idValues.iterator());
/* Mock serializer and eventually the database. */
LogSerializer logSerializer = mock(LogSerializer.class);
when(logSerializer.deserializeLog(anyString())).thenAnswer(new Answer<Log>() {
@Override
public Log answer(InvocationOnMock invocation) throws Throwable {
/* 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();
persistence.setLogSerializer(logSerializer);
/* Get logs and verify we get only non corrupted logs. */
ArrayList<Log> outLogs = new ArrayList<>();
persistence.getLogs("mock", 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(databaseStorage).delete(1);
/* Verify next call is empty logs as they are pending. */
outLogs = new ArrayList<>();
persistence.getLogs("mock", 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);
}
when(databaseScanner.iterator()).thenReturn(fieldValues.iterator());
idValues = new ArrayList<>(4);
/* Here the id scanner 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);
}
when(idDatabaseScanner.iterator()).thenReturn(idValues.iterator());
/* Verify next call is only the new valid log as others are marked pending. */
outLogs = new ArrayList<>();
persistence.getLogs("mock", 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(databaseStorage).delete(anyLong());
}
use of com.microsoft.appcenter.ingestion.models.Log in project mobile-center-sdk-android by Microsoft.
the class EventFilter method applyEnabledState.
@Override
protected synchronized void applyEnabledState(boolean enabled) {
/* Enable filtering logs when this module is enabled. */
if (enabled) {
mChannelListener = new AbstractChannelListener() {
@Override
public boolean shouldFilter(@NonNull Log log) {
/* Filter out events. */
if (log instanceof EventLog) {
AppCenterLog.info(LOG_TAG, "Filtered an event out.");
return true;
}
return false;
}
};
mChannel.addListener(mChannelListener);
} else /* On applying disabled state, let's make sure we remove listener. */
if (mChannel != null) {
mChannel.removeListener(mChannelListener);
}
}
use of com.microsoft.appcenter.ingestion.models.Log in project mobile-center-sdk-android by Microsoft.
the class AnalyticsTest method setEnabled.
@Test
public void setEnabled() throws InterruptedException {
/* Before start it does not work to change state, it's disabled. */
Analytics analytics = Analytics.getInstance();
Analytics.setEnabled(true);
assertFalse(Analytics.isEnabled().get());
Analytics.setEnabled(false);
assertFalse(Analytics.isEnabled().get());
/* Start. */
Channel channel = mock(Channel.class);
analytics.onStarting(mAppCenterHandler);
analytics.onStarted(mock(Context.class), "", channel);
verify(channel).removeGroup(eq(analytics.getGroupName()));
verify(channel).addGroup(eq(analytics.getGroupName()), anyInt(), anyLong(), anyInt(), any(Channel.GroupListener.class));
verify(channel).addListener(any(Channel.Listener.class));
/* Now we can see the service enabled. */
assertTrue(Analytics.isEnabled().get());
/* Disable. Testing to wait setEnabled to finish while we are at it. */
Analytics.setEnabled(false).get();
assertFalse(Analytics.isEnabled().get());
verify(channel).removeListener(any(SessionTracker.class));
verify(channel, times(2)).removeGroup(analytics.getGroupName());
verify(channel).clear(analytics.getGroupName());
verifyStatic();
StorageHelper.PreferencesStorage.remove("sessions");
Analytics.trackEvent("test");
Analytics.trackPage("test");
analytics.onActivityResumed(new Activity());
analytics.onActivityPaused(new Activity());
verify(channel, never()).enqueue(any(Log.class), eq(analytics.getGroupName()));
/* Enable again, verify the async behavior of setEnabled with the callback. */
final CountDownLatch latch = new CountDownLatch(1);
Analytics.setEnabled(true).thenAccept(new AppCenterConsumer<Void>() {
@Override
public void accept(Void aVoid) {
latch.countDown();
}
});
assertTrue(latch.await(0, TimeUnit.MILLISECONDS));
assertTrue(Analytics.isEnabled().get());
/* Test double call to setEnabled true. */
Analytics.setEnabled(true);
assertTrue(Analytics.isEnabled().get());
Analytics.trackEvent("test");
Analytics.trackPage("test");
verify(channel, times(2)).enqueue(any(Log.class), eq(analytics.getGroupName()));
/* Disable again. */
Analytics.setEnabled(false);
assertFalse(Analytics.isEnabled().get());
Analytics.trackEvent("test");
Analytics.trackPage("test");
analytics.onActivityResumed(new Activity());
analytics.onActivityPaused(new Activity());
/* No more log enqueued. */
verify(channel, times(2)).enqueue(any(Log.class), eq(analytics.getGroupName()));
}
use of com.microsoft.appcenter.ingestion.models.Log in project mobile-center-sdk-android by Microsoft.
the class AnalyticsTest method startSessionAfterUserApproval.
@Test
public void startSessionAfterUserApproval() {
/*
* Disable analytics while in background to set up the initial condition
* simulating the opt-in use case.
*/
Analytics analytics = Analytics.getInstance();
Channel channel = mock(Channel.class);
analytics.onStarting(mAppCenterHandler);
analytics.onStarted(mock(Context.class), "", channel);
Analytics.setEnabled(false);
/* App in foreground: no log yet, we are disabled. */
analytics.onActivityResumed(new Activity());
verify(channel, never()).enqueue(any(Log.class), eq(analytics.getGroupName()));
/* Enable: start session sent retroactively. */
Analytics.setEnabled(true);
verify(channel).enqueue(argThat(new ArgumentMatcher<Log>() {
@Override
public boolean matches(Object argument) {
return argument instanceof StartSessionLog;
}
}), eq(analytics.getGroupName()));
verify(channel).enqueue(argThat(new ArgumentMatcher<Log>() {
@Override
public boolean matches(Object argument) {
return argument instanceof PageLog;
}
}), eq(analytics.getGroupName()));
/* Go background. */
analytics.onActivityPaused(new Activity());
/* Disable/enable: nothing happens on background. */
Analytics.setEnabled(false);
Analytics.setEnabled(true);
/* No additional log. */
verify(channel, times(2)).enqueue(any(Log.class), eq(analytics.getGroupName()));
}
Aggregations