@Override public Void answer(InvocationOnMock invocation) { Object[] args = invocation.getArguments(); if (AppCenter.isEnabled().get()) { ((Runnable) args[0]).run(); } else if (args[1] instanceof Runnable) { ((Runnable) args[1]).run(); } return null; } }).when(mAppCenterHandler).post(any(Runnable.class), any(Runnable.class));
@Test public void getLastSessionCrashReportWithMultipleListenersAndResultIsNullBeforeInit() { mockStatic(ErrorLogHelper.class); when(ErrorLogHelper.getLastErrorLogFile()).thenReturn(null); when(ErrorLogHelper.getStoredErrorLogFiles()).thenReturn(new File[0]); when(ErrorLogHelper.getNewMinidumpFiles()).thenReturn(new File[0]); @SuppressWarnings("unchecked") AppCenterConsumer<ErrorReport> callback = (AppCenterConsumer<ErrorReport>) mock(AppCenterConsumer.class); /* Call twice for multiple callbacks before initialize. */ Crashes.getLastSessionCrashReport().thenAccept(callback); Crashes.getLastSessionCrashReport().thenAccept(callback); Crashes.getInstance().onStarted(mock(Context.class), mock(Channel.class), "", null, true); assertFalse(Crashes.hasCrashedInLastSession().get()); verify(callback, times(2)).accept(null); }
@Test public void configureValidStorageSizeFromApp() { /* Set up storage to succeed resize. */ when(mChannel.setMaxStorageSize(anyLong())).thenReturn(true); /* Configure before start. */ AppCenterFuture<Boolean> future = AppCenter.setMaxStorageSize(AppCenter.MINIMUM_STORAGE_SIZE); /* Verify the operation is still pending. */ assertFalse(future.isDone()); /* Since the call is registered, we cannot change our mind anymore. */ assertFalse(AppCenter.setMaxStorageSize(AppCenter.MINIMUM_STORAGE_SIZE + 1).get()); /* Start AppCenter. */ AppCenter.start(mApplication, DUMMY_APP_SECRET, DummyService.class); /* Verify storage size applied. */ verify(mChannel).setMaxStorageSize(AppCenter.MINIMUM_STORAGE_SIZE); /* And result returned to developer. */ assertTrue(future.get()); }
isInstanceEnabledAsync().thenAccept(new AppCenterConsumer<Boolean>() {
@Test public void resumeWhileStartingAndDisableWhileRunningBrowserCodeOnUI() throws InterruptedException { final AtomicReference<Runnable> runnable = new AtomicReference<>(); doAnswer(new Answer<Void>() { @Override public Void answer(InvocationOnMock invocation) { runnable.set((Runnable) invocation.getArguments()[0]); return null; } }).when(HandlerUtils.class); HandlerUtils.runOnUiThread(any(Runnable.class)); Distribute.getInstance().onStarting(mAppCenterHandler); Distribute.getInstance().onActivityResumed(mActivity); Distribute.getInstance().onStarted(mContext, mock(Channel.class), "a", null, true); /* Disable and test async behavior of setEnabled. */ final CountDownLatch latch = new CountDownLatch(1); Distribute.setEnabled(false).thenAccept(new AppCenterConsumer<Void>() { @Override public void accept(Void aVoid) { latch.countDown(); } }); runnable.get().run(); assertTrue(latch.await(0, TimeUnit.MILLISECONDS)); verifyStatic(never()); BrowserUtils.openBrowser(anyString(), any(Activity.class)); }
@Test public void getInstallId() { assertNull(AppCenter.getInstallId().get()); SharedPreferencesManager.initialize(mApplication); SharedPreferencesManager.remove(PrefStorageConstants.KEY_INSTALL_ID); AppCenter.start(mApplication, UUIDUtils.randomUUID().toString(), DummyService.class); UUID installId = AppCenter.getInstallId().get(); assertNotNull(installId); assertEquals(installId, AppCenter.getInstallId().get()); assertEquals(installId, DummyService.getInstallId().get()); SharedPreferencesManager.remove(PrefStorageConstants.KEY_INSTALL_ID); final UUID installId2 = AppCenter.getInstallId().get(); assertNotNull(installId2); assertNotEquals(installId2, installId); final Semaphore lock = new Semaphore(0); final AtomicReference<UUID> asyncUUID = new AtomicReference<>(); AppCenter.getInstallId().thenAccept(new AppCenterConsumer<UUID>() { @Override public void accept(UUID uuid) { asyncUUID.set(uuid); lock.release(); } }); lock.acquireUninterruptibly(); assertEquals(installId2, asyncUUID.get()); AppCenter.setEnabled(false); assertNull(AppCenter.getInstallId().get()); }
/** * Save uncaught exception to disk. * * @param thread thread where exception occurred. * @param throwable Java exception as is, can be null for non Java exceptions. * @param modelException model exception, supports any language. * @return error log identifier. * @throws JSONException if an error occurred during JSON serialization of modelException. * @throws IOException if an error occurred while accessing the file system. */ UUID saveUncaughtException(Thread thread, Throwable throwable, com.microsoft.appcenter.crashes.ingestion.models.Exception modelException) throws JSONException, IOException { /* Ignore call if Crash is disabled. */ if (!Crashes.isEnabled().get()) { return null; } /* * Save only 1 crash. This is needed for example in Xamarin * where we save as a Xamarin crash before Java handler is called. */ if (mSavedUncaughtException) { return null; } mSavedUncaughtException = true; /* Save error log. */ ManagedErrorLog errorLog = ErrorLogHelper.createErrorLog(mContext, thread, modelException, Thread.getAllStackTraces(), mInitializeTimestamp, true); return saveErrorLogFiles(throwable, errorLog); }
assertFalse(Crashes.hasCrashedInLastSession().get()); assertFalse(Crashes.isEnabled().get()); assertFalse(Crashes.hasCrashedInLastSession().get()); Crashes.getLastSessionCrashReport().thenAccept(beforeCallback); verify(beforeCallback).accept(null); assertTrue(Crashes.isEnabled().get()); assertTrue(Crashes.hasCrashedInLastSession().get()); AppCenterConsumer<ErrorReport> afterCallback = (AppCenterConsumer<ErrorReport>) mock(AppCenterConsumer.class); AppCenterFuture<ErrorReport> future = Crashes.getLastSessionCrashReport(); future.thenAccept(afterCallback); future.thenAccept(afterCallback); ArgumentCaptor<ErrorReport> errorReportCaptor = ArgumentCaptor.forClass(ErrorReport.class); verify(afterCallback, times(2)).accept(errorReportCaptor.capture());
@Override public synchronized void onStarted(@NonNull Context context, @NonNull Channel channel, String appSecret, String transmissionTargetToken, boolean startedFromApp) { super.onStarted(context, channel, appSecret, transmissionTargetToken, startedFromApp); /* Check no dead lock if we do that. */ mInstallId = AppCenter.getInstallId().get(); } }
assertFalse(Crashes.hasCrashedInLastSession().get()); android.util.Log.i(TAG, "Process 1"); Thread.UncaughtExceptionHandler uncaughtExceptionHandler = mock(Thread.UncaughtExceptionHandler.class); Crashes.getLastSessionCrashReport().thenAccept(new AppCenterConsumer<ErrorReport>() { assertTrue(Crashes.hasCrashedInLastSession().get()); assertTrue(Crashes.isEnabled().get()); ArgumentCaptor<ManagedErrorLog> log = ArgumentCaptor.forClass(ManagedErrorLog.class); verify(mChannel).enqueue(log.capture(), anyString(), eq(PERSISTENCE_CRITICAL)); assertFalse(Crashes.hasCrashedInLastSession().get()); assertNull(Crashes.getLastSessionCrashReport().get());
@After public void tearDown() { AppCenter.setEnabled(true).get(); }
assertFalse(Push.isEnabled().get()); verifyStatic(); AppCenterLog.error(anyString(), anyString()); start(push, channel); verify(channel).removeGroup(eq(push.getGroupName())); assertTrue(Push.isEnabled().get()); verify(mFirebaseInstanceId).getToken(); ArgumentCaptor<PushInstallationLog> log = ArgumentCaptor.forClass(PushInstallationLog.class); assertTrue(Push.isEnabled().get()); Push.setEnabled(false).get(); assertFalse(Push.isEnabled().get()); verify(channel).clear(push.getGroupName()); verify(channel, times(2)).removeGroup(eq(push.getGroupName())); Push.setEnabled(false).thenAccept(new AppCenterConsumer<Void>() {
@Test public void useBrowserUpdateSetupIfAppIsTesterApp() throws Exception { /* Setup mock. */ UUID requestId = UUID.randomUUID(); when(UUIDUtils.randomUUID()).thenReturn(requestId); when(SharedPreferencesManager.getString(PREFERENCE_KEY_REQUEST_ID)).thenReturn(requestId.toString()); when(mPackageManager.getPackageInfo(DistributeUtils.TESTER_APP_PACKAGE_NAME, 0)).thenReturn(mock(PackageInfo.class)); when(mContext.getPackageName()).thenReturn(DistributeUtils.TESTER_APP_PACKAGE_NAME); /* Mock install id from AppCenter. */ UUID installId = UUID.randomUUID(); when(mAppCenterFuture.get()).thenReturn(installId); when(AppCenter.getInstallId()).thenReturn(mAppCenterFuture); /* Start and resume: open browser. */ start(); Distribute.getInstance().onActivityResumed(mActivity); verifyStatic(); BrowserUtils.openBrowser(anyString(), any(Activity.class)); }
assertFalse(Analytics.isEnabled().get()); Analytics.setEnabled(false); assertFalse(Analytics.isEnabled().get()); assertTrue(Analytics.isEnabled().get()); Analytics.setEnabled(false).get(); assertFalse(Analytics.isEnabled().get()); verify(channel).removeListener(isA(SessionTracker.class)); verify(channel).removeListener(isA(AnalyticsValidator.class)); Analytics.setEnabled(true).thenAccept(new AppCenterConsumer<Void>() { assertTrue(Analytics.isEnabled().get()); assertTrue(Analytics.isEnabled().get()); Analytics.trackEvent("test"); target.trackEvent("test"); assertFalse(Analytics.isEnabled().get()); Analytics.trackEvent("test"); Analytics.trackPage("test");
@Test public void unknownKeyTest() { String secret = DUMMY_APP_SECRET + PAIR_DELIMITER + DUMMY_TARGET_TOKEN_STRING + PAIR_DELIMITER + "unknown" + KEY_VALUE_DELIMITER + "value"; AppCenter.start(mApplication, secret, DummyService.class); assertTrue(AppCenter.isEnabled().get()); verify(DummyService.getInstance()).onStarted(any(Context.class), any(Channel.class), eq(DUMMY_APP_SECRET), eq(DUMMY_TRANSMISSION_TARGET_TOKEN), eq(true)); }
@Test public void registerWithoutFirebaseOrSenderId() { IllegalStateException exception = new IllegalStateException(); when(FirebaseInstanceId.getInstance()).thenThrow(exception); Resources resources = mock(Resources.class); when(mContext.getString(0)).thenThrow(new Resources.NotFoundException()); when(mContext.getResources()).thenReturn(resources); start(Push.getInstance(), mock(Channel.class)); assertTrue(Push.isEnabled().get()); verify(mContext, never()).startService(any(Intent.class)); }
@Test public void crashInLastSessionCorrupted() throws IOException { mockStatic(ErrorLogHelper.class); File file = errorStorageDirectory.newFile("last-error-log.json"); new FileWriter(file).append("fake_data").close(); when(ErrorLogHelper.getStoredErrorLogFiles()).thenReturn(new File[]{file}); when(ErrorLogHelper.getNewMinidumpFiles()).thenReturn(new File[0]); when(ErrorLogHelper.getLastErrorLogFile()).thenReturn(file); Crashes.getInstance().onStarted(mock(Context.class), mock(Channel.class), "", null, true); assertFalse(Crashes.hasCrashedInLastSession().get()); assertNull(Crashes.getLastSessionCrashReport().get()); }
@Test public void registerWithoutFirebaseButUseGoogleServicesStringForSenderId() { IllegalStateException exception = new IllegalStateException(); when(FirebaseInstanceId.getInstance()).thenThrow(exception); when(mContext.getPackageName()).thenReturn("com.contoso"); Resources resources = mock(Resources.class); when(resources.getIdentifier("gcm_defaultSenderId", "string", "com.contoso")).thenReturn(42); when(mContext.getString(42)).thenReturn("4567"); when(mContext.getResources()).thenReturn(resources); start(Push.getInstance(), mock(Channel.class)); assertTrue(Push.isEnabled().get()); verify(mContext).startService(any(Intent.class)); }