package net.hockeyapp.android; import android.support.test.InstrumentationRegistry; import android.support.test.runner.AndroidJUnit4; import android.test.InstrumentationTestCase; import net.hockeyapp.android.objects.CrashDetails; import net.hockeyapp.android.util.StacktraceFilenameFilter; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import java.io.File; @RunWith(AndroidJUnit4.class) public class CrashManagerTest extends InstrumentationTestCase { private static final String DUMMY_APP_IDENTIFIER = "12345678901234567890123456789012"; private static final StacktraceFilenameFilter STACK_TRACE_FILTER = new StacktraceFilenameFilter(); private static void cleanupReportsDir() { assertNotNull(Constants.FILES_PATH); File reportsDir = new File(Constants.FILES_PATH); for (File f : reportsDir.listFiles(STACK_TRACE_FILTER)) { f.delete(); } } private static void fakeCrashReport() { Throwable tr = new RuntimeException("Just a test exception"); ExceptionHandler.saveException(tr, Thread.currentThread(), null); } private static void fakeXamarinCrashReport() { Throwable tr = new RuntimeException("That's the Java exception"); Throwable xamaTr = new RuntimeException("Outer Exception", new RuntimeException("Inner Exception")); ExceptionHandler.saveNativeException(tr, xamaTr.toString(), Thread.currentThread(), null); } private static File lastCrashReportFile() { assertNotNull(Constants.FILES_PATH); File reportsDir = new File(Constants.FILES_PATH); long modifiedReference = 0; File lastReportsFile = null; for (File f : reportsDir.listFiles(STACK_TRACE_FILTER)) { if (f.lastModified() > modifiedReference) { modifiedReference = f.lastModified(); lastReportsFile = f; } } return lastReportsFile; } @Before public void setUp() throws Exception { super.setUp(); injectInstrumentation(InstrumentationRegistry.getInstrumentation()); if (Constants.FILES_PATH == null) { Constants.loadFromContext(getInstrumentation().getTargetContext()); } } @Test public void registerCrashManagerWorks() { // verify that registering the Crash Manager works (e.g. it's not throwing any exception) CrashManager.register(getInstrumentation().getTargetContext(), DUMMY_APP_IDENTIFIER); // verify that there were no crashes in the last session assertFalse(CrashManager.didCrashInLastSession()); } @Test public void crashInLastSessionRecognized() { fakeCrashReport(); assertNotNull(Constants.FILES_PATH); CrashManager.register(getInstrumentation().getTargetContext(), DUMMY_APP_IDENTIFIER); assertTrue(CrashManager.didCrashInLastSession()); assertNotNull(CrashManager.getLastCrashDetails()); } @Test public void crashDetailsInLastSessionCorrect() { assertNotNull(Constants.FILES_PATH); cleanupReportsDir(); fakeCrashReport(); CrashManager.register(getInstrumentation().getTargetContext(), DUMMY_APP_IDENTIFIER); CrashDetails crashDetails = CrashManager.getLastCrashDetails(); assertNotNull(crashDetails); File lastStackTrace = lastCrashReportFile(); assertNotNull(lastStackTrace); assertEquals(lastStackTrace.getName().substring(0, lastStackTrace.getName().indexOf(".stacktrace")), crashDetails.getCrashIdentifier()); assertEquals(Constants.CRASH_IDENTIFIER, crashDetails.getReporterKey()); fakeCrashReport(); fakeCrashReport(); fakeCrashReport(); crashDetails = CrashManager.getLastCrashDetails(); assertNotNull(crashDetails); lastStackTrace = lastCrashReportFile(); assertNotNull(lastStackTrace); assertEquals(lastStackTrace.getName().substring(0, lastStackTrace.getName().indexOf(".stacktrace")), crashDetails.getCrashIdentifier()); } @Test public void xamarinCrashCorrect() { cleanupReportsDir(); fakeXamarinCrashReport(); CrashManager.register(getInstrumentation().getTargetContext(), DUMMY_APP_IDENTIFIER); fakeXamarinCrashReport(); CrashDetails crashDetails = CrashManager.getLastCrashDetails(); assertNotNull(crashDetails); assertEquals(crashDetails.getFormat(), "Xamarin"); String throwableStackTrace = crashDetails.getThrowableStackTrace(); Boolean containsCausedByXamarin = throwableStackTrace.contains("Xamarin caused by:"); assertTrue(containsCausedByXamarin); } }