diff --git a/backtrace-library/build.gradle b/backtrace-library/build.gradle index 06ba03ce..dd106aba 100644 --- a/backtrace-library/build.gradle +++ b/backtrace-library/build.gradle @@ -82,6 +82,7 @@ dependencies { implementation 'com.squareup:tape:1.2.3' testImplementation 'junit:junit:4.13.2' testImplementation "org.mockito:mockito-core:5.12.0" + testImplementation 'org.json:json:20240303' androidTestImplementation "org.mockito:mockito-android:5.12.0" androidTestImplementation 'net.jodah:concurrentunit:0.4.4' androidTestImplementation 'androidx.test.ext:junit:1.2.1' @@ -90,6 +91,7 @@ dependencies { androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1' androidTestImplementation 'org.mockito:mockito-core:5.2.0' androidTestImplementation "org.mockito:mockito-android:2.28.2" + testImplementation "com.google.guava:guava:33.3.1-jre" } apply from: 'publish.gradle' diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientAttachmentsTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientAttachmentsTest.java index 230b5565..d9f54ec2 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientAttachmentsTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientAttachmentsTest.java @@ -61,7 +61,7 @@ public void sendBacktraceExceptionAttachments() { RequestHandler rh = new RequestHandler() { @Override public BacktraceResult onRequest(BacktraceData data) { - return new BacktraceResult(data.getReport(), data.report.exception.getMessage(), + return new BacktraceResult(data.getReport(), data.getReport().exception.getMessage(), BacktraceResultStatus.Ok); } }; @@ -104,7 +104,7 @@ public void sendBacktraceExceptionNoAttachments() { RequestHandler rh = new RequestHandler() { @Override public BacktraceResult onRequest(BacktraceData data) { - return new BacktraceResult(data.getReport(), data.report.exception.getMessage(), + return new BacktraceResult(data.getReport(), data.getReport().exception.getMessage(), BacktraceResultStatus.Ok); } }; diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientAttributeTests.java b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientAttributeTests.java index e096856b..de643774 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientAttributeTests.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientAttributeTests.java @@ -11,6 +11,7 @@ import net.jodah.concurrentunit.Waiter; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -30,11 +31,19 @@ public class BacktraceClientAttributeTests { private BacktraceCredentials credentials; private BacktraceDatabase database; + private BacktraceClient backtraceClient; + @Before public void setUp() { context = InstrumentationRegistry.getInstrumentation().getContext(); credentials = new BacktraceCredentials("https://example-endpoint.com/", ""); database = new BacktraceDatabase(context, context.getFilesDir().getAbsolutePath()); + backtraceClient = new BacktraceClient(context, credentials, database); + } + + @After + public void cleanUp() { + database.clear(); } @Test @@ -42,7 +51,6 @@ public void shouldAddASingleAttribute() { // GIVEN final String attributeKey = "test-attribute"; final String attributeValue = "test-value"; - final BacktraceClient backtraceClient = new BacktraceClient(context, credentials, database); // WHEN backtraceClient.addAttribute(attributeKey, attributeValue); @@ -66,7 +74,6 @@ public void shouldAddMultipleAttributesAtOnce() { attributes.put(String.format("%s %d", attributeKey, attributeIteration), attributeValue); } // WHEN - final BacktraceClient backtraceClient = new BacktraceClient(context, credentials, database); backtraceClient.addAttribute(attributes); // THEN @@ -85,7 +92,6 @@ public void shouldReplaceExistingAttribute() { final String newAttributeValue = "test-value-new"; // WHEN - final BacktraceClient backtraceClient = new BacktraceClient(context, credentials, database); backtraceClient.addAttribute(attributeKey, oldAttributeValue); backtraceClient.addAttribute(attributeKey, newAttributeValue); @@ -129,14 +135,14 @@ public void attributesShouldBeAvailableInReport() { final String errorMessage = "error message"; final String attributeKey = "test-attribute"; final String attributeValue = "test-value"; - final BacktraceClient backtraceClient = new BacktraceClient(context, credentials, database); + backtraceClient.addAttribute(attributeKey, attributeValue); RequestHandler rh = data -> { // THEN - Object value = data.attributes.get(attributeKey); + Object value = data.getAttributes().get(attributeKey); assertNotNull(value); assertEquals(value, attributeValue); - return new BacktraceResult(data.getReport(), data.report.exception.getMessage(), + return new BacktraceResult(data.getReport(), data.getReport().exception.getMessage(), BacktraceResultStatus.Ok); }; backtraceClient.setOnRequestHandler(rh); diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientBreadcrumbsTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientBreadcrumbsTest.java index c3452c9f..03626655 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientBreadcrumbsTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientBreadcrumbsTest.java @@ -73,7 +73,7 @@ public void sendBacktraceExceptionBreadcrumbs() { RequestHandler rh = new RequestHandler() { @Override public BacktraceResult onRequest(BacktraceData data) { - return new BacktraceResult(data.getReport(), data.report.exception.getMessage(), + return new BacktraceResult(data.getReport(), data.getReport().exception.getMessage(), BacktraceResultStatus.Ok); } }; @@ -122,7 +122,7 @@ public void sendBacktraceExceptionBreadcrumbsAddBreadcrumb() { RequestHandler rh = new RequestHandler() { @Override public BacktraceResult onRequest(BacktraceData data) { - return new BacktraceResult(data.getReport(), data.report.exception.getMessage(), + return new BacktraceResult(data.getReport(), data.getReport().exception.getMessage(), BacktraceResultStatus.Ok); } }; @@ -276,7 +276,7 @@ public void sendBacktraceExceptionNoBreadcrumbs() { RequestHandler rh = new RequestHandler() { @Override public BacktraceResult onRequest(BacktraceData data) { - return new BacktraceResult(data.report, data.report.exception.getMessage(), + return new BacktraceResult(data.getReport(), data.getReport().exception.getMessage(), BacktraceResultStatus.Ok); } }; diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientEventsTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientEventsTest.java index 536fd73b..3dd7f716 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientEventsTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientEventsTest.java @@ -86,7 +86,7 @@ public void useBeforeSendAndRequestHandler() { RequestHandler rh = new RequestHandler() { @Override public BacktraceResult onRequest(BacktraceData data) { - return new BacktraceResult(null, data.attributes.get(attributeKey), + return new BacktraceResult(null, data.getAttributes().get(attributeKey), BacktraceResultStatus.Ok); } }; @@ -95,7 +95,7 @@ public BacktraceResult onRequest(BacktraceData data) { backtraceClient.setOnBeforeSendEventListener(new OnBeforeSendEventListener() { @Override public BacktraceData onEvent(BacktraceData data) { - data.attributes.put(attributeKey, resultMessage); + data.getAttributes().put(attributeKey, resultMessage); return data; } }); diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientProguardTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientProguardTest.java index 0c8672da..ec382eaa 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientProguardTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientProguardTest.java @@ -58,7 +58,7 @@ public void sendBacktraceReportWithStringAndAttributesProguard() { RequestHandler rh = new RequestHandler() { @Override public BacktraceResult onRequest(BacktraceData data) { - assertEquals("proguard", data.symbolication); + assertEquals("proguard", data.getSymbolication()); return new BacktraceResult(data.getReport(), data.getReport().message, BacktraceResultStatus.Ok); } @@ -97,7 +97,7 @@ public void sendBacktraceReportWithStringAndAttributesNoProguard() { RequestHandler rh = new RequestHandler() { @Override public BacktraceResult onRequest(BacktraceData data) { - assertNull(data.symbolication); + assertNull(data.getSymbolication()); return new BacktraceResult(data.getReport(), data.getReport().message, BacktraceResultStatus.Ok); } @@ -138,7 +138,7 @@ public void sendBacktraceReportWithExceptionAndAttributesProguard() { RequestHandler rh = new RequestHandler() { @Override public BacktraceResult onRequest(BacktraceData data) { - assertEquals("proguard", data.symbolication); + assertEquals("proguard", data.getSymbolication()); return new BacktraceResult(data.getReport(), data.getReport().exception.getMessage(), BacktraceResultStatus.Ok); } @@ -180,7 +180,7 @@ public void sendBacktraceReportWithExceptionAndAttributesNoProguard() { RequestHandler rh = new RequestHandler() { @Override public BacktraceResult onRequest(BacktraceData data) { - assertNull(data.symbolication); + assertNull(data.getSymbolication()); return new BacktraceResult(data.getReport(), data.getReport().exception.getMessage(), BacktraceResultStatus.Ok); } @@ -224,7 +224,7 @@ public void sendBacktraceExceptionProguard() { RequestHandler rh = new RequestHandler() { @Override public BacktraceResult onRequest(BacktraceData data) { - assertEquals("proguard", data.symbolication); + assertEquals("proguard", data.getSymbolication()); return new BacktraceResult(data.getReport(), data.getReport().exception.getMessage(), BacktraceResultStatus.Ok); } @@ -266,7 +266,7 @@ public void sendBacktraceExceptionNoProguard() { RequestHandler rh = new RequestHandler() { @Override public BacktraceResult onRequest(BacktraceData data) { - assertNull(data.symbolication); + assertNull(data.getSymbolication()); return new BacktraceResult(data.getReport(), data.getReport().exception.getMessage(), BacktraceResultStatus.Ok); } @@ -309,7 +309,7 @@ public void sendBacktraceStringProguard() { RequestHandler rh = new RequestHandler() { @Override public BacktraceResult onRequest(BacktraceData data) { - assertEquals("proguard", data.symbolication); + assertEquals("proguard", data.getSymbolication()); return new BacktraceResult(data.getReport(), data.getReport().message, BacktraceResultStatus.Ok); } @@ -351,7 +351,7 @@ public void sendBacktraceStringNoProguard() { RequestHandler rh = new RequestHandler() { @Override public BacktraceResult onRequest(BacktraceData data) { - assertNull(data.symbolication); + assertNull(data.getSymbolication()); return new BacktraceResult(data.getReport(), data.getReport().message, BacktraceResultStatus.Ok); } diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientSendTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientSendTest.java index 078df08f..7b1a642d 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientSendTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientSendTest.java @@ -110,7 +110,7 @@ public void sendExceptionWithManyCause() { fail(e.getMessage()); } - return new BacktraceResult(data.getReport(), data.report.message, + return new BacktraceResult(data.getReport(), data.getReport().message, BacktraceResultStatus.Ok); }; backtraceClient.setOnRequestHandler(rh); diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/SettingAttributesTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/SettingAttributesTest.java index fa60e787..b5af4c45 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/SettingAttributesTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/SettingAttributesTest.java @@ -29,6 +29,7 @@ import backtraceio.library.models.BacktraceResult; import backtraceio.library.models.database.BacktraceDatabaseSettings; import backtraceio.library.models.json.BacktraceAttributes; +import backtraceio.library.models.json.BacktraceReport; import backtraceio.library.models.types.BacktraceResultStatus; @@ -176,10 +177,13 @@ public void run() { @Override public BacktraceResult onRequest(BacktraceData data) { // THEN - waiter.assertTrue(data.getReport().attributes.containsKey(customClientAttributeKey)); - waiter.assertEquals(customClientAttributeValue, data.getReport().attributes.get(customClientAttributeKey)); + + final BacktraceReport dataReport = data.getReport(); + waiter.assertTrue(dataReport.attributes.containsKey(customClientAttributeKey)); + waiter.assertEquals(customClientAttributeValue, dataReport.attributes.get(customClientAttributeKey)); waiter.assertEquals(exceptionMessage, data.getReport().exception.getMessage()); - waiter.assertEquals(data.getReport().attributes.get(BacktraceAttributeConsts.ErrorType), BacktraceAttributeConsts.UnhandledExceptionAttributeType); + waiter.assertEquals(dataReport.attributes.get(BacktraceAttributeConsts.ErrorType), BacktraceAttributeConsts.UnhandledExceptionAttributeType); + waiter.resume(); return new BacktraceResult(data.getReport(), "", BacktraceResultStatus.Ok); } diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseContextTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseContextTest.java index ffe85e29..67092948 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseContextTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseContextTest.java @@ -38,15 +38,13 @@ public void setUp() { this.context = InstrumentationRegistry.getInstrumentation().getContext(); this.dbPath = this.context.getFilesDir().getAbsolutePath(); this.databaseSettings = new BacktraceDatabaseSettings(this.dbPath, RetryOrder.Queue); - this.databaseContext = new BacktraceDatabaseContext(this.context, this.databaseSettings); + this.databaseContext = new BacktraceDatabaseContext(this.databaseSettings); } - @After public void after() { this.databaseContext.clear(); } - @Test public void firstFromDatabaseContextQueue() { // GIVEN @@ -79,7 +77,7 @@ public void lastFromDatabaseContextQueue() { public void firstFromDatabaseContextStack() { // GIVEN BacktraceDatabaseSettings settings = new BacktraceDatabaseSettings(this.dbPath, RetryOrder.Stack); - this.databaseContext = new BacktraceDatabaseContext(this.context, settings); + this.databaseContext = new BacktraceDatabaseContext(settings); List records = fillDatabase(); // WHEN @@ -94,7 +92,7 @@ public void firstFromDatabaseContextStack() { public void lastFromDatabaseContextStack() { // GIVEN BacktraceDatabaseSettings settings = new BacktraceDatabaseSettings(this.dbPath, RetryOrder.Stack); - this.databaseContext = new BacktraceDatabaseContext(this.context, settings); + this.databaseContext = new BacktraceDatabaseContext(settings); List records = fillDatabase(); // WHEN @@ -147,7 +145,7 @@ public void notContainsInDatabaseContext() { // GIVEN fillDatabase(); BacktraceReport report = new BacktraceReport(this.testMessage); - BacktraceData data = new BacktraceData(this.context, report, null); + BacktraceData data = new BacktraceData.Builder(report).setAttributes(this.context, null).build(); BacktraceDatabaseRecord record = new BacktraceDatabaseRecord(data, this.dbPath); // WHEN @@ -236,7 +234,7 @@ public void tryDeleteNotExistingRecordFromDatabaseContext() { // GIVEN fillDatabase(); BacktraceReport report = new BacktraceReport(this.testMessage); - BacktraceData data = new BacktraceData(this.context, report, null); + BacktraceData data = new BacktraceData.Builder(report).setAttributes(this.context, null).build(); BacktraceDatabaseRecord record = new BacktraceDatabaseRecord(data, this.dbPath); // WHEN @@ -261,9 +259,9 @@ private List fillDatabase() { BacktraceReport report = new BacktraceReport(this.testMessage); BacktraceReport report2 = new BacktraceReport(this.testMessage); BacktraceReport report3 = new BacktraceReport(this.testMessage); - BacktraceData data = new BacktraceData(this.context, report, null); - BacktraceData data2 = new BacktraceData(this.context, report2, null); - BacktraceData data3 = new BacktraceData(this.context, report3, null); + BacktraceData data = new BacktraceData.Builder(report).setAttributes(this.context, null).build(); + BacktraceData data2 = new BacktraceData.Builder(report2).setAttributes(this.context, null).build(); + BacktraceData data3 = new BacktraceData.Builder(report3).setAttributes(this.context, null).build(); result.add(databaseContext.add(data)); result.add(databaseContext.add(data2)); result.add(databaseContext.add(data3)); diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseFileContextTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseFileContextTest.java index 471e462d..3c3dc2ab 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseFileContextTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseFileContextTest.java @@ -41,7 +41,7 @@ public void setUp() { this.context = InstrumentationRegistry.getInstrumentation().getContext(); this.dbPath = this.context.getFilesDir().getAbsolutePath(); this.databaseSettings = new BacktraceDatabaseSettings(this.dbPath, RetryOrder.Queue); - this.databaseContext = new BacktraceDatabaseContext(this.context, this.databaseSettings); + this.databaseContext = new BacktraceDatabaseContext(this.databaseSettings); this.databaseFileContext = new BacktraceDatabaseFileContext(this.dbPath, this.databaseSettings.getMaxDatabaseSize(), this.databaseSettings.getMaxRecordCount()); this.databaseContext.clear(); this.databaseFileContext.clear(); @@ -57,7 +57,7 @@ public void after() { public void getFilesAfterAddOne() { // GIVEN BacktraceReport report = new BacktraceReport(testMessage); - this.databaseContext.add(new BacktraceData(this.context, report, null)); + this.databaseContext.add(new BacktraceData.Builder(report).setAttributes(this.context, null).build()); // WHEN int files = countAllFiles(); @@ -73,9 +73,9 @@ public void getFilesAfterAddThree() { BacktraceReport report2 = new BacktraceReport(testMessage); BacktraceReport report3 = new BacktraceReport(testMessage); - this.databaseContext.add(new BacktraceData(this.context, report, null)); - this.databaseContext.add(new BacktraceData(this.context, report2, null)); - this.databaseContext.add(new BacktraceData(this.context, report3, null)); + this.databaseContext.add(new BacktraceData.Builder(report).setAttributes(this.context, null).build()); + this.databaseContext.add(new BacktraceData.Builder(report2).setAttributes(this.context, null).build()); + this.databaseContext.add(new BacktraceData.Builder(report3).setAttributes(this.context, null).build()); // WHEN int files = countAllFiles(); @@ -91,9 +91,9 @@ public void getRecords() { BacktraceReport report2 = new BacktraceReport(testMessage); BacktraceReport report3 = new BacktraceReport(testMessage); - this.databaseContext.add(new BacktraceData(this.context, report, null)); - this.databaseContext.add(new BacktraceData(this.context, report2, null)); - this.databaseContext.add(new BacktraceData(this.context, report3, null)); + this.databaseContext.add(new BacktraceData.Builder(report).setAttributes(this.context, null).build()); + this.databaseContext.add(new BacktraceData.Builder(report2).setAttributes(this.context, null).build()); + this.databaseContext.add(new BacktraceData.Builder(report3).setAttributes(this.context, null).build()); // WHEN int files = countRecords(); @@ -109,8 +109,8 @@ public void clear() { BacktraceReport report = new BacktraceReport(testMessage); BacktraceReport report2 = new BacktraceReport(testMessage); - this.databaseContext.add(new BacktraceData(this.context, report, null)); - this.databaseContext.add(new BacktraceData(this.context, report2, null)); + this.databaseContext.add(new BacktraceData.Builder(report).setAttributes(this.context, null).build()); + this.databaseContext.add(new BacktraceData.Builder(report2).setAttributes(this.context, null).build()); // WHEN int filesAfterAdd = countAllFiles(); @@ -129,8 +129,8 @@ public void filesConsistency() { BacktraceReport report = new BacktraceReport(testMessage); BacktraceReport report2 = new BacktraceReport(testMessage); - this.databaseContext.add(new BacktraceData(this.context, report, null)); - this.databaseContext.add(new BacktraceData(this.context, report2, null)); + this.databaseContext.add(new BacktraceData.Builder(report).setAttributes(this.context, null).build()); + this.databaseContext.add(new BacktraceData.Builder(report2).setAttributes(this.context, null).build()); // WHEN boolean result = this.databaseFileContext.validFileConsistency(); @@ -144,13 +144,13 @@ public void forceInconsistencyMaxRecordCount() { // GIVEN this.databaseSettings.setMaxRecordCount(1); this.databaseFileContext = new BacktraceDatabaseFileContext(this.dbPath, this.databaseSettings.getMaxDatabaseSize(), this.databaseSettings.getMaxRecordCount()); - this.databaseContext = new BacktraceDatabaseContext(this.context, this.databaseSettings); + this.databaseContext = new BacktraceDatabaseContext(this.databaseSettings); BacktraceReport report = new BacktraceReport(testMessage); BacktraceReport report2 = new BacktraceReport(testMessage); - this.databaseContext.add(new BacktraceData(this.context, report, null)); - this.databaseContext.add(new BacktraceData(this.context, report2, null)); + this.databaseContext.add(new BacktraceData.Builder(report).setAttributes(this.context, null).build()); + this.databaseContext.add(new BacktraceData.Builder(report2).setAttributes(this.context, null).build()); // WHEN boolean result = this.databaseFileContext.validFileConsistency(); @@ -167,8 +167,8 @@ public void forceInconsistencyMaxDatabaseSize() { BacktraceReport report = new BacktraceReport(testMessage); BacktraceReport report2 = new BacktraceReport(testMessage); - this.databaseContext.add(new BacktraceData(this.context, report, null)); - this.databaseContext.add(new BacktraceData(this.context, report2, null)); + this.databaseContext.add(new BacktraceData.Builder(report).setAttributes(this.context, null).build()); + this.databaseContext.add(new BacktraceData.Builder(report2).setAttributes(this.context, null).build()); // WHEN boolean result = this.databaseFileContext.validFileConsistency(); @@ -183,8 +183,8 @@ public void removeOrphanedFiles() { BacktraceReport report = new BacktraceReport(testMessage); BacktraceReport report2 = new BacktraceReport(testMessage); - final BacktraceDatabaseRecord record = this.databaseContext.add(new BacktraceData(this.context, report, null)); - this.databaseContext.add(new BacktraceData(this.context, report2, null)); + final BacktraceDatabaseRecord record = this.databaseContext.add(new BacktraceData.Builder(report).setAttributes(this.context, null).build()); + this.databaseContext.add(new BacktraceData.Builder(report2).setAttributes(this.context, null).build()); // WHEN int countRecords = countRecords(); diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseProguardTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseProguardTest.java index 5e9e80ae..f3ed97ac 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseProguardTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseProguardTest.java @@ -49,9 +49,9 @@ public void addSingleRecordNoProguard() { database.add(report, null); // THEN - assertEquals(report, database.get().iterator().next().getBacktraceData(context).getReport()); - assertNull(database.get().iterator().next().getBacktraceData(context).symbolication); - assertEquals(testMessage, database.get().iterator().next().getBacktraceData(context).getReport().message); + assertEquals(report, database.get().iterator().next().getBacktraceData().getReport()); + assertNull(database.get().iterator().next().getBacktraceData().symbolication); + assertEquals(testMessage, database.get().iterator().next().getBacktraceData().getReport().message); assertEquals(1, database.count()); } @@ -67,9 +67,9 @@ public void addSingleRecordProguard() { database.add(report, null, true); // THEN - assertEquals(report, database.get().iterator().next().getBacktraceData(context).getReport()); - assertEquals("proguard", database.get().iterator().next().getBacktraceData(context).symbolication); - assertEquals(testMessage, database.get().iterator().next().getBacktraceData(context).getReport().message); + assertEquals(report, database.get().iterator().next().getBacktraceData().getReport()); + assertEquals("proguard", database.get().iterator().next().getBacktraceData().symbolication); + assertEquals(testMessage, database.get().iterator().next().getBacktraceData().getReport().message); assertEquals(1, database.count()); } } \ No newline at end of file diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseRecordTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseRecordTest.java index 303c2907..bb903dba 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseRecordTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseRecordTest.java @@ -22,6 +22,7 @@ import backtraceio.library.BacktraceDatabase; import backtraceio.library.enums.database.RetryOrder; import backtraceio.library.models.BacktraceData; +import backtraceio.library.models.BacktraceDataAttachmentsFileHelper; import backtraceio.library.models.database.BacktraceDatabaseRecord; import backtraceio.library.models.database.BacktraceDatabaseSettings; import backtraceio.library.models.json.BacktraceReport; @@ -30,17 +31,15 @@ @RunWith(AndroidJUnit4.class) public class BacktraceDatabaseRecordTest { private Context context; - private String dbPath; - private BacktraceDatabaseSettings databaseSettings; private BacktraceDatabase database; private final String testMessage = "Example test string"; @Before public void setUp() { this.context = InstrumentationRegistry.getInstrumentation().getContext(); - this.dbPath = this.context.getFilesDir().getAbsolutePath(); - this.databaseSettings = new BacktraceDatabaseSettings(this.dbPath, RetryOrder.Queue); - this.database = new BacktraceDatabase(this.context, dbPath); + String dbPath = this.context.getFilesDir().getAbsolutePath(); + BacktraceDatabaseSettings databaseSettings = new BacktraceDatabaseSettings(dbPath, RetryOrder.Queue); + this.database = new BacktraceDatabase(this.context, databaseSettings); } @After @@ -51,16 +50,16 @@ public void after() { @Test public void saveAndGetRecord() { // GIVEN - BacktraceReport report = new BacktraceReport(testMessage); - BacktraceData data = new BacktraceData(this.context, report, null); - BacktraceDatabaseRecord record = new BacktraceDatabaseRecord(data, this.dbPath); + final BacktraceReport report = new BacktraceReport(testMessage); + final BacktraceData data = new BacktraceData.Builder(report).setAttributes(this.context, null).build(); + final BacktraceDatabaseRecord record = new BacktraceDatabaseRecord(data, this.database.getSettings().getDatabasePath()); // WHEN - boolean saveResult = record.save(); - boolean validResult = record.valid(); + final boolean saveResult = record.save(); + final boolean validResult = record.valid(); record.close(); - BacktraceData loadedData = record.getBacktraceData(context); + final BacktraceData loadedData = record.getBacktraceData(); // THEN assertTrue(saveResult); @@ -73,7 +72,7 @@ public void saveAndGetRecordWithAttachments() { // GIVEN final String attachment0 = context.getFilesDir() + "/someFile.log"; final String attachment1 = context.getFilesDir() + "/someOtherFile.log"; - List attachments = new ArrayList() {{ + final List attachments = new ArrayList() {{ add(attachment0); add(attachment1); }}; @@ -85,31 +84,31 @@ public void saveAndGetRecordWithAttachments() { fail(ex.getMessage()); } - BacktraceReport report = new BacktraceReport(testMessage, attachments); - BacktraceData data = new BacktraceData(this.context, report, null); - BacktraceDatabaseRecord record = new BacktraceDatabaseRecord(data, this.dbPath); + final BacktraceReport report = new BacktraceReport(testMessage, attachments); + final BacktraceData data = new BacktraceData.Builder(report).setAttributes(this.context, null).build(); + final BacktraceDatabaseRecord record = new BacktraceDatabaseRecord(data, this.database.getSettings().getDatabasePath()); // WHEN - boolean saveResult = record.save(); - boolean validResult = record.valid(); + final boolean saveResult = record.save(); + final boolean validResult = record.valid(); record.close(); - BacktraceData loadedData = record.getBacktraceData(context); - + final BacktraceData loadedData = record.getBacktraceData(); + final List existingFiles = BacktraceDataAttachmentsFileHelper.getValidAttachments(context, loadedData); // THEN assertTrue(saveResult); assertTrue(validResult); assertEquals(data.getReport().message, loadedData.getReport().message); - assertTrue(loadedData.getAttachments().contains(attachment0)); - assertTrue(loadedData.getAttachments().contains(attachment1)); + assertTrue(existingFiles.contains(attachment0)); + assertTrue(existingFiles.contains(attachment1)); } @Test public void deleteFileDiagnosticPathToCorruptRecord() { // GIVEN BacktraceReport report = new BacktraceReport(testMessage); - BacktraceData data = new BacktraceData(this.context, report, null); - BacktraceDatabaseRecord record = new BacktraceDatabaseRecord(data, this.dbPath); + BacktraceData data = new BacktraceData.Builder(report).setAttributes(this.context, null).build(); + BacktraceDatabaseRecord record = new BacktraceDatabaseRecord(data, this.database.getSettings().getDatabasePath()); // WHEN boolean saveResult = record.save(); @@ -126,8 +125,8 @@ public void deleteFileDiagnosticPathToCorruptRecord() { public void deleteFileReportPathToCorruptRecord() { // GIVEN BacktraceReport report = new BacktraceReport(testMessage); - BacktraceData data = new BacktraceData(this.context, report, null); - BacktraceDatabaseRecord record = new BacktraceDatabaseRecord(data, this.dbPath); + BacktraceData data = new BacktraceData.Builder(report).setAttributes(this.context, null).build(); + BacktraceDatabaseRecord record = new BacktraceDatabaseRecord(data, this.database.getSettings().getDatabasePath()); // WHEN boolean saveResult = record.save(); @@ -144,15 +143,15 @@ public void deleteFileReportPathToCorruptRecord() { public void createAndDeleteRecordFiles() { // GIVEN BacktraceReport report = new BacktraceReport(testMessage); - BacktraceData data = new BacktraceData(this.context, report, null); - BacktraceDatabaseRecord record = new BacktraceDatabaseRecord(data, this.dbPath); + BacktraceData data = new BacktraceData.Builder(report).setAttributes(this.context, null).build(); + BacktraceDatabaseRecord record = new BacktraceDatabaseRecord(data, this.database.getSettings().getDatabasePath()); // WHEN boolean saveResult = record.save(); - int numberOfFilesAfterSave = new File(this.dbPath).listFiles().length; + int numberOfFilesAfterSave = new File(this.database.getSettings().getDatabasePath()).listFiles().length; record.delete(); - int numberOfFilesAfterDelete = new File(this.dbPath).listFiles().length; + int numberOfFilesAfterDelete = new File(this.database.getSettings().getDatabasePath()).listFiles().length; // THEN assertTrue(saveResult); @@ -163,14 +162,14 @@ public void createAndDeleteRecordFiles() { @Test public void readFileAndDeserialize() { // GIVEN - BacktraceReport report = new BacktraceReport(testMessage); - BacktraceData data = new BacktraceData(this.context, report, null); - BacktraceDatabaseRecord record = new BacktraceDatabaseRecord(data, this.dbPath); + final BacktraceReport report = new BacktraceReport(testMessage); + final BacktraceData data = new BacktraceData.Builder(report).setAttributes(this.context, null).build(); + final BacktraceDatabaseRecord record = new BacktraceDatabaseRecord(data, this.database.getSettings().getDatabasePath()); record.save(); // WHEN - BacktraceDatabaseRecord recordFromFile = BacktraceDatabaseRecord.readFromFile(new File(record.getRecordPath())); - BacktraceData dataFromFile = recordFromFile.getBacktraceData(context); + final BacktraceDatabaseRecord recordFromFile = BacktraceDatabaseRecord.readFromFile(new File(record.getRecordPath())); + final BacktraceData dataFromFile = recordFromFile.getBacktraceData(); // THEN assertEquals(data.getReport().message, dataFromFile.getReport().message); diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseTest.java index 226d433e..0136a23c 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseTest.java @@ -100,50 +100,50 @@ public void addSingleRecord() { assertEquals(0, database.count()); // GIVEN - BacktraceReport report = new BacktraceReport(testMessage); + final BacktraceReport report = new BacktraceReport(testMessage); // WHEN database.add(report, null); // THEN - assertEquals(report, database.get().iterator().next().getBacktraceData(context).getReport()); - assertEquals(testMessage, database.get().iterator().next().getBacktraceData(context).getReport().message); + assertEquals(report, database.get().iterator().next().getBacktraceData().getReport()); + assertEquals(testMessage, database.get().iterator().next().getBacktraceData().getReport().message); assertEquals(1, database.count()); } @Test public void addWithAttributes() { // GIVEN - String key = "Example key"; - String value = "Example value"; - BacktraceReport report = new BacktraceReport(testMessage); - Map attributes = new HashMap<>(); + final String key = "Example key"; + final String value = "Example value"; + final BacktraceReport report = new BacktraceReport(testMessage); + final Map attributes = new HashMap<>(); attributes.put(key, value); // WHEN - BacktraceDatabaseRecord record = database.add(report, attributes); - BacktraceData dataFromDatabase = record.getBacktraceData(context); + final BacktraceDatabaseRecord record = database.add(report, attributes); + final BacktraceData dataFromDatabase = record.getBacktraceData(); // THEN - assertEquals(value, dataFromDatabase.attributes.get(key)); + assertEquals(value, dataFromDatabase.getAttributes().get(key)); } @Test public void deleteSingleRecord() { - BacktraceReport report = new BacktraceReport(testMessage); - BacktraceReport report2 = new BacktraceReport(new Exception("Example exception")); + final BacktraceReport report = new BacktraceReport(testMessage); + final BacktraceReport report2 = new BacktraceReport(new Exception("Example exception")); - BacktraceDatabaseRecord record = database.add(report, null); - BacktraceDatabaseRecord record2 = database.add(report2, null); + final BacktraceDatabaseRecord record = database.add(report, null); + final BacktraceDatabaseRecord record2 = database.add(report2, null); assertEquals(2, database.count()); database.delete(record); assertEquals(1, database.count()); - BacktraceDatabaseRecord recordFromDatabase = database.get().iterator().next(); + final BacktraceDatabaseRecord recordFromDatabase = database.get().iterator().next(); assertEquals(record2, recordFromDatabase); - assertEquals(report2, recordFromDatabase.getBacktraceData(context).getReport()); - assertEquals(report2.exception.getMessage(), recordFromDatabase.getBacktraceData(context).getReport().exception.getMessage()); + assertEquals(report2, recordFromDatabase.getBacktraceData().getReport()); + assertEquals(report2.exception.getMessage(), recordFromDatabase.getBacktraceData().getReport().exception.getMessage()); } @@ -235,7 +235,7 @@ public void recordLimit() { // THEN assertEquals(1, database.count()); - assertEquals(report2.message, database.get().iterator().next().getBacktraceData(context).getReport().message); + assertEquals(report2.message, database.get().iterator().next().getBacktraceData().getReport().message); } @Test diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/models/BacktraceDataTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/models/BacktraceDataTest.java index 031cdb5e..2c2ed334 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/models/BacktraceDataTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/models/BacktraceDataTest.java @@ -1,6 +1,8 @@ package backtraceio.library.models; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import android.content.Context; @@ -11,7 +13,10 @@ import org.junit.Test; import org.junit.runner.RunWith; +import java.util.Arrays; import java.util.HashMap; +import java.util.List; +import java.util.Map; import backtraceio.library.models.json.BacktraceReport; @@ -27,14 +32,70 @@ public void setUp() { @Test public void createBacktraceDataTest() { // GIVEN - BacktraceReport report = new BacktraceReport(new IllegalAccessException("test-message")); + List attachmentsPath = Arrays.asList("one", "two", "three"); + BacktraceReport report = new BacktraceReport(new IllegalAccessException("test-message"), attachmentsPath); + Map clientAttributes = new HashMap<>(); + clientAttributes.put("attr-1", 1); + clientAttributes.put("attr-2", true); + clientAttributes.put("attr-3", "test"); // WHEN - BacktraceData backtraceData = new BacktraceData(context, report, new HashMap<>()); + BacktraceData backtraceData = new BacktraceData.Builder(report).setAttributes(context, clientAttributes).build(); // THEN - assertEquals(backtraceData.classifiers, new String[]{"java.lang.IllegalAccessException"}); - assertEquals(backtraceData.getReport(), report); - assertEquals(backtraceData.attributes.get("classifier"), "java.lang.IllegalAccessException"); + assertArrayEquals( new String[]{"java.lang.IllegalAccessException"} , backtraceData.getClassifiers()); + assertEquals(report, backtraceData.getReport()); + assertEquals("java.lang.IllegalAccessException", backtraceData.getAttributes().get("classifier")); + assertEquals("backtrace-android", backtraceData.getAgent()); + assertEquals(backtraceio.library.BuildConfig.VERSION_NAME, backtraceData.getAgentVersion()); + assertEquals("java", backtraceData.getLang()); + assertEquals("0", backtraceData.getLangVersion()); + assertEquals("", backtraceData.getSymbolication()); + assertEquals(report.timestamp, backtraceData.getTimestamp()); + assertEquals(report.uuid.toString(), backtraceData.getUuid()); + assertEquals(43, backtraceData.getAttributes().size()); + assertEquals(3, backtraceData.getAnnotations().size()); + assertEquals("instr: androidx.test.runner.androidjunitrunner", backtraceData.getMainThread()); + assertEquals(34, backtraceData.getSourceCode().size()); + assertTrue(!backtraceData.getThreadInformationMap().isEmpty()); + assertEquals(3, backtraceData.getAttachmentPaths().size()); + assertEquals("1", backtraceData.getAttributes().get("attr-1")); + assertEquals("true", backtraceData.getAttributes().get("attr-2")); + assertEquals("test", backtraceData.getAttributes().get("attr-3")); + } + @Test + public void testBacktraceDataConstructor() { + // GIVEN + List attachmentsPath = Arrays.asList("one", "two", "three"); + BacktraceReport report = new BacktraceReport(new IllegalAccessException("test-message"), attachmentsPath); + + Map clientAttributes = new HashMap<>(); + clientAttributes.put("attr-1", 1); + clientAttributes.put("attr-2", true); + clientAttributes.put("attr-3", "test"); + + // WHEN + BacktraceData backtraceData = new BacktraceData(context, report, clientAttributes); + + // THEN + assertArrayEquals( new String[]{"java.lang.IllegalAccessException"}, backtraceData.getClassifiers()); + assertEquals(report, backtraceData.getReport()); + assertEquals("java.lang.IllegalAccessException", backtraceData.getAttributes().get("classifier")); + assertEquals("backtrace-android", backtraceData.getAgent()); + assertEquals(backtraceio.library.BuildConfig.VERSION_NAME, backtraceData.getAgentVersion()); + assertEquals("java", backtraceData.getLang()); + assertEquals("0", backtraceData.getLangVersion()); + assertEquals("", backtraceData.getSymbolication()); + assertEquals(report.timestamp, backtraceData.getTimestamp()); + assertEquals(report.uuid.toString(), backtraceData.getUuid()); + assertEquals(43, backtraceData.getAttributes().size()); + assertEquals(3, backtraceData.getAnnotations().size()); + assertEquals("instr: androidx.test.runner.androidjunitrunner", backtraceData.getMainThread()); + assertEquals(34, backtraceData.getSourceCode().size()); + assertTrue(!backtraceData.getThreadInformationMap().isEmpty()); + assertEquals(3, backtraceData.getAttachmentPaths().size()); + assertEquals("1", backtraceData.getAttributes().get("attr-1")); + assertEquals("true", backtraceData.getAttributes().get("attr-2")); + assertEquals("test", backtraceData.getAttributes().get("attr-3")); } } diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/watchdog/BacktraceWatchdogSharedTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/watchdog/BacktraceWatchdogSharedTest.java index 45d3a074..26e17c30 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/watchdog/BacktraceWatchdogSharedTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/watchdog/BacktraceWatchdogSharedTest.java @@ -62,7 +62,7 @@ public void checkAnrBreadcrumb() { String breadcrumbPath = data.getReport().attachmentPaths.get(0); assertTrue(breadcrumbPath.contains("bt-breadcrumbs")); - assertEquals(data.attributes.get("error.type"), AnrAttributeType); + assertEquals(data.getAttributes().get("error.type"), AnrAttributeType); assertEquals("ANR detected - thread is blocked", getANRBreadcrumb()); waiter.resume(); diff --git a/backtrace-library/src/main/java/backtraceio/library/BacktraceDatabase.java b/backtrace-library/src/main/java/backtraceio/library/BacktraceDatabase.java index 1b5aca6a..61332962 100644 --- a/backtrace-library/src/main/java/backtraceio/library/BacktraceDatabase.java +++ b/backtrace-library/src/main/java/backtraceio/library/BacktraceDatabase.java @@ -53,9 +53,7 @@ public class BacktraceDatabase implements Database { private BacktraceDatabaseSettings databaseSettings; private boolean _enable = false; private Breadcrumbs breadcrumbs; - private CrashHandlerConfiguration crashHandlerConfiguration; - private boolean _enabledNativeIntegration = false; private NativeCommunication nativeCommunication = new BacktraceCrashHandlerWrapper(); @@ -113,8 +111,7 @@ public BacktraceDatabase(Context context, BacktraceDatabaseSettings databaseSett this._applicationContext = context; this.databaseSettings = databaseSettings; - this.backtraceDatabaseContext = new BacktraceDatabaseContext(this._applicationContext, - databaseSettings); + this.backtraceDatabaseContext = new BacktraceDatabaseContext(databaseSettings); this.backtraceDatabaseFileContext = new BacktraceDatabaseFileContext(this.getDatabasePath(), this.databaseSettings.getMaxDatabaseSize(), this.databaseSettings .getMaxRecordCount()); @@ -318,7 +315,7 @@ public void run() { BacktraceDatabaseRecord record = backtraceDatabaseContext.first(); while (record != null) { final CountDownLatch threadWaiter = new CountDownLatch(1); - BacktraceData backtraceData = record.getBacktraceData(_applicationContext); + BacktraceData backtraceData = record.getBacktraceData(); if (backtraceData == null || backtraceData.getReport() == null) { BacktraceLogger.d(LOG_TAG, "Timer - backtrace data or report is null - " + "deleting record"); @@ -368,7 +365,7 @@ public void flush() { BacktraceDatabaseRecord record = backtraceDatabaseContext.first(); while (record != null) { - BacktraceData backtraceData = record.getBacktraceData(this._applicationContext); + BacktraceData backtraceData = record.getBacktraceData(); this.delete(record); if (backtraceData != null) { BacktraceApi.send(backtraceData, null); diff --git a/backtrace-library/src/main/java/backtraceio/library/base/BacktraceBase.java b/backtrace-library/src/main/java/backtraceio/library/base/BacktraceBase.java index 4890637b..bc524ffc 100644 --- a/backtrace-library/src/main/java/backtraceio/library/base/BacktraceBase.java +++ b/backtrace-library/src/main/java/backtraceio/library/base/BacktraceBase.java @@ -235,7 +235,7 @@ public BacktraceBase(Context context, BacktraceCredentials credentials, Database this.attributes = CollectionUtils.copyMap(attributes); this.attachments = CollectionUtils.copyList(attachments); this.database = database != null ? database : new BacktraceDatabase(); - this.setBacktraceApi(new BacktraceApi(credentials)); + this.setBacktraceApi(new BacktraceApi(this.context, credentials)); this.database.start(); this.metrics = new BacktraceMetrics(context, this.attributes, backtraceApi, credentials); } @@ -583,8 +583,8 @@ public void send(BacktraceReport report, final OnServerResponseEventListener cal } addReportAttachments(report); - BacktraceData backtraceData = new BacktraceData(this.context, report, this.attributes); - backtraceData.symbolication = this.isProguardEnabled ? "proguard" : null; + String symbolication = this.isProguardEnabled ? "proguard" : null; + BacktraceData backtraceData = new BacktraceData.Builder(report).setAttributes(context, this.attributes).setSymbolication(symbolication).build(); final BacktraceDatabaseRecord record = this.database.add(report, this.attributes, this.isProguardEnabled); diff --git a/backtrace-library/src/main/java/backtraceio/library/common/BacktraceSerializeHelper.java b/backtrace-library/src/main/java/backtraceio/library/common/BacktraceSerializeHelper.java index a94bbd46..ad3a9ee4 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/BacktraceSerializeHelper.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/BacktraceSerializeHelper.java @@ -31,4 +31,4 @@ public static T fromJson(Gson gson, String json, Class type) { return gson.fromJson(json, type); } -} +} \ No newline at end of file diff --git a/backtrace-library/src/main/java/backtraceio/library/common/DeviceAttributesHelper.java b/backtrace-library/src/main/java/backtraceio/library/common/DeviceAttributesHelper.java index 046c6651..34e5b40d 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/DeviceAttributesHelper.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/DeviceAttributesHelper.java @@ -194,7 +194,6 @@ private WifiStatus getWifiStatus() { * * @return is power saving mode activated */ - // TODO: replace bool to enum private boolean isPowerSavingMode() { if (Build.VERSION.SDK_INT < 21) { return false; diff --git a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceApiResult.java b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceApiResult.java new file mode 100644 index 00000000..68aea851 --- /dev/null +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceApiResult.java @@ -0,0 +1,34 @@ +package backtraceio.library.models; + +import com.google.gson.annotations.SerializedName; + +/** + * Coroner API response + */ +public class BacktraceApiResult { + + /** + * Object identifier + */ + @SerializedName("_rxid") + public String rxId; + + /** + * Result status eg. server error, ok + */ + @SerializedName("response") + public String response; + + public BacktraceApiResult(String rxId, String response) { + this.rxId = rxId; + this.response = response; + } + + public String getRxId() { + return rxId; + } + + public String getResponse() { + return response; + } +} \ No newline at end of file diff --git a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java index cd3eceb3..bbdcc46d 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java @@ -8,7 +8,6 @@ import java.util.Map; import backtraceio.library.BacktraceClient; -import backtraceio.library.common.FileHelper; import backtraceio.library.logger.BacktraceLogger; import backtraceio.library.models.json.Annotations; import backtraceio.library.models.json.BacktraceAttributes; @@ -23,6 +22,13 @@ */ public class BacktraceData { + /** + * 16 bytes of randomness in human readable UUID format + * server will reject request if uuid is already found + */ + @SerializedName("uuid") + public String uuid; + private static final transient String LOG_TAG = BacktraceData.class.getSimpleName(); /** * Name of programming language/environment this error comes from. @@ -43,13 +49,6 @@ public class BacktraceData { @SerializedName("symbolication") public String symbolication; - /** - * 16 bytes of randomness in human readable UUID format - * server will reject request if uuid is already found - */ - @SerializedName("uuid") - public String uuid; - /** * UTC timestamp in seconds */ @@ -98,12 +97,7 @@ public class BacktraceData { /** * Current BacktraceReport */ - public transient BacktraceReport report; - - /** - * Current application context - */ - public transient Context context; + public transient BacktraceReport report; // TODO: verify if we need it /** * Application thread details @@ -111,24 +105,50 @@ public class BacktraceData { @SerializedName("threads") Map threadInformationMap; + /** - * Create instance of report data - * - * @param context current application context - * @param report current report - * @param clientAttributes attributes which should be added to BacktraceData object - */ - public BacktraceData(Context context, BacktraceReport report, Map - clientAttributes) { - if (report == null) { - return; - } - this.context = context; - this.report = report; + * Create new instance of BacktraceData + * @deprecated + * This method is no longer way of creating new BacktraceData instance and will be removed soon + */ + @Deprecated + public BacktraceData(Context context, BacktraceReport report, Map clientAttributes) { + BacktraceData obj = new Builder(report) + .setAttributes(context, clientAttributes) + .setSymbolication("") + .build(); - setReportInformation(); - setThreadsInformation(); - setAttributes(clientAttributes); + this.uuid = obj.uuid; + this.symbolication = obj.symbolication; + this.timestamp = obj.timestamp; + this.langVersion = obj.langVersion; + this.agentVersion = obj.agentVersion; + this.attributes = obj.attributes; + this.mainThread = obj.mainThread; + this.report = obj.report; + this.classifiers = obj.classifiers; + this.annotations = obj.annotations; + this.sourceCode = obj.sourceCode; + this.threadInformationMap = obj.threadInformationMap; + } + + public BacktraceData(String uuid, String symbolication, long timestamp, String langVersion, + String agentVersion, Map attributes, String mainThread, + String[] classifiers, BacktraceReport report, Map annotations, + Map sourceCode, + Map threadInformationMap) { + this.uuid = uuid; + this.symbolication = symbolication; + this.timestamp = timestamp; + this.langVersion = langVersion; + this.agentVersion = agentVersion; + this.attributes = attributes; + this.mainThread = mainThread; + this.report = report; + this.classifiers = classifiers; + this.annotations = annotations; + this.sourceCode = sourceCode; + this.threadInformationMap = threadInformationMap; } /** @@ -136,65 +156,179 @@ public BacktraceData(Context context, BacktraceReport report, Map getAttachmentPaths() { + return report.attachmentPaths; + } + + /** + * Get paths to report attachments + * + * @deprecated + * Please use {@link #getAttachmentPaths()} instead. + * + * @return paths to attachments + */ + @Deprecated public List getAttachments() { - return FileHelper.filterOutFiles(this.context, report.attachmentPaths); + return this.getAttachmentPaths(); } + public Map getThreadInformationMap() { + return threadInformationMap; + } - public BacktraceReport getReport() { - return report; + public String getUuid() { + return uuid; } - /*** - * Set annotations object - * @param complexAttributes - */ - private void setAnnotations(Map complexAttributes) { - BacktraceLogger.d(LOG_TAG, "Setting annotations"); - Object exceptionMessage = null; + public String getLang() { + return lang; + } - if (this.attributes != null && - this.attributes.containsKey("error.message")) { - exceptionMessage = this.attributes.get("error.message"); - } - this.annotations = Annotations.getAnnotations(exceptionMessage, complexAttributes); + public String getAgent() { + return agent; } - /** - * Set attributes and add complex attributes to annotations - * - * @param clientAttributes - */ - private void setAttributes(Map clientAttributes) { - BacktraceLogger.d(LOG_TAG, "Setting attributes"); - BacktraceAttributes backtraceAttributes = new BacktraceAttributes(this.context, this.report, - clientAttributes); - this.attributes = backtraceAttributes.attributes; + public String getSymbolication() { + return symbolication; + } - setAnnotations(backtraceAttributes.getComplexAttributes()); + public long getTimestamp() { + return timestamp; } - /** - * Set report information such as report identifier (UUID), timestamp, classifier - */ - private void setReportInformation() { - BacktraceLogger.d(LOG_TAG, "Setting report information"); - uuid = report.uuid.toString(); - timestamp = report.timestamp; - classifiers = report.exceptionTypeReport ? new String[]{report.classifier} : null; - langVersion = System.getProperty("java.version"); //TODO: Fix problem with read Java version - agentVersion = BacktraceClient.version; + public String getLangVersion() { + return langVersion; } - /** - * Set information about all threads - */ - private void setThreadsInformation() { - BacktraceLogger.d(LOG_TAG, "Setting threads information"); - ThreadData threadData = new ThreadData(report.diagnosticStack); - this.mainThread = threadData.getMainThread(); - this.threadInformationMap = threadData.threadInformation; - SourceCodeData sourceCodeData = new SourceCodeData(report.diagnosticStack); - this.sourceCode = sourceCodeData.data.isEmpty() ? null : sourceCodeData.data; + public String getAgentVersion() { + return agentVersion; + } + + public Map getAttributes() { + return attributes; + } + + public String getMainThread() { + return mainThread; + } + + public String[] getClassifiers() { + return classifiers; + } + + public Map getAnnotations() { + return annotations; + } + + public Map getSourceCode() { + return sourceCode; + } + + public BacktraceReport getReport() { + return report; + } + + + public static class Builder { + private final BacktraceReport report; + + private String symbolication = ""; + + private String uuid; + + private long timestamp; + + private String[] classifiers; + + private String langVersion; + + private String agentVersion; + + private Map annotations; + private Map sourceCode; + private Map threadInformationMap; + private Map attributes; + private String mainThread; + + public Builder(BacktraceReport report) { + this.report = report; + + this.setDefaultReportInformation(this.report); + this.setDefaultThreadsInformation(); + } + + public BacktraceData build() { + return new BacktraceData( + this.uuid, + this.symbolication, + this.timestamp, + this.langVersion, + this.agentVersion, + this.attributes, + this.mainThread, + this.classifiers, + this.report, + this.annotations, + this.sourceCode, + this.threadInformationMap + ); + } + + public Builder setSymbolication(String symbolication) { + this.symbolication = symbolication; + return this; + } + + /** + * Set report information such as report identifier (UUID), timestamp, classifier + */ + private Builder setDefaultReportInformation(BacktraceReport report) { + this.uuid = report.uuid.toString(); + this.timestamp = report.timestamp; + this.classifiers = report.exceptionTypeReport ? new String[]{report.classifier} : null; + this.langVersion = System.getProperty("java.version"); + this.agentVersion = BacktraceClient.version; + return this; + } + + /** + * Set information about all threads + */ + private Builder setDefaultThreadsInformation() { + BacktraceLogger.d(LOG_TAG, "Setting threads information"); + + ThreadData threadData = new ThreadData(report.diagnosticStack); + SourceCodeData sourceCodeData = new SourceCodeData(report.diagnosticStack); + + this.mainThread = threadData.getMainThread(); + this.threadInformationMap = threadData.threadInformation; + this.sourceCode = sourceCodeData.data.isEmpty() ? null : sourceCodeData.data; + return this; + } + + public Builder setAttributes(Context context, Map clientAttributes) { + BacktraceLogger.d(LOG_TAG, "Setting attributes"); + BacktraceAttributes backtraceAttributes = new BacktraceAttributes( + context, + this.report, + clientAttributes); + this.attributes = backtraceAttributes.attributes; + + setAnnotations(backtraceAttributes.getComplexAttributes()); + return this; + } + + private Builder setAnnotations(Map complexAttributes) { + BacktraceLogger.d(LOG_TAG, "Setting annotations"); + Object exceptionMessage = null; + + if (this.attributes != null && + this.attributes.containsKey("error.message")) { + exceptionMessage = this.attributes.get("error.message"); + } + this.annotations = Annotations.getAnnotations(exceptionMessage, complexAttributes); + return this; + } } } \ No newline at end of file diff --git a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceDataAttachmentsFileHelper.java b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceDataAttachmentsFileHelper.java new file mode 100644 index 00000000..59927d0c --- /dev/null +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceDataAttachmentsFileHelper.java @@ -0,0 +1,14 @@ +package backtraceio.library.models; + +import android.content.Context; + +import java.util.List; + +import backtraceio.library.common.FileHelper; + +public class BacktraceDataAttachmentsFileHelper { + + public static List getValidAttachments(Context context, BacktraceData backtraceData) { + return FileHelper.filterOutFiles(context, backtraceData.getAttachmentPaths()); + } +} diff --git a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceResult.java b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceResult.java index 371146f9..8e8924df 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceResult.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceResult.java @@ -14,7 +14,6 @@ public class BacktraceResult { * Object identifier */ @SerializedName("_rxid") - @SuppressWarnings({"UnusedDeclaration"}) public String rxId; /** @@ -36,7 +35,14 @@ public class BacktraceResult { * Create new instance of BacktraceResult */ public BacktraceResult() { + } + + public BacktraceResult(BacktraceApiResult apiResult) { + this(apiResult.rxId, apiResult.getResponse()); + } + public BacktraceResult(String rxId, String status) { + this(null, rxId, null, BacktraceResultStatus.enumOf(status)); } /** @@ -47,9 +53,34 @@ public BacktraceResult() { * @param status result status eg. ok, server error */ public BacktraceResult(BacktraceReport report, String message, BacktraceResultStatus status) { - setBacktraceReport(report); + this(report, null, message, status); + } + + /** + * Create new instance of BacktraceResult + * + * @param report executed report + * @param message message + * @param status result status eg. ok, server error + */ + public BacktraceResult(BacktraceReport report, String rxId, String message, BacktraceResultStatus status) { + this.rxId = rxId; this.message = message; this.status = status; + + setBacktraceReport(report); + } + + public String getRxId() { + return rxId; + } + + public String getMessage() { + return message; + } + + public BacktraceResultStatus getStatus() { + return status; } /** diff --git a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceStackFrame.java b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceStackFrame.java index eeddc80f..bed1f1d9 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceStackFrame.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceStackFrame.java @@ -1,5 +1,6 @@ package backtraceio.library.models; + import com.google.gson.annotations.SerializedName; import java.util.UUID; @@ -38,9 +39,30 @@ public class BacktraceStackFrame { /** * Create new instance of BacktraceStackFrame + * + * @deprecated + * Use {@link #fromStackTraceElement(StackTraceElement frame)} instead. */ @SuppressWarnings({"UnusedDeclaration"}) - public BacktraceStackFrame() { + @Deprecated + public BacktraceStackFrame() {} + + /** + * Create new instance of BacktraceStackFrame + * + * @deprecated + * Use {@link #fromStackTraceElement(StackTraceElement frame)} instead. + */ + @Deprecated + public BacktraceStackFrame(StackTraceElement frame) { + BacktraceStackFrame obj = BacktraceStackFrame.fromStackTraceElement(frame); + if (obj == null) { + throw new IllegalArgumentException("Wrong stacktrace element frame - can`t be null"); + } + this.functionName = obj.functionName; + this.sourceCodeFileName = obj.sourceCodeFileName; + this.sourceCode = obj.sourceCode; + this.line = obj.line; } /** @@ -48,14 +70,25 @@ public BacktraceStackFrame() { * * @param frame single stacktrace element */ - public BacktraceStackFrame(StackTraceElement frame) { + public static BacktraceStackFrame fromStackTraceElement(StackTraceElement frame) { if (frame == null || frame.getMethodName() == null) { - BacktraceLogger.w(LOG_TAG, "Frame or method name is null"); - return; + BacktraceLogger.e(LOG_TAG, "Frame or method name is null"); + throw new IllegalArgumentException("Frame or method name is null"); } - this.functionName = frame.getClassName() + "." + frame.getMethodName(); - this.sourceCodeFileName = frame.getFileName(); - this.sourceCode = UUID.randomUUID().toString(); - this.line = frame.getLineNumber() > 0 ? frame.getLineNumber() : null; + final String functionName = frame.getClassName() + "." + frame.getMethodName(); + final String fileName = frame.getFileName(); + final Integer line = frame.getLineNumber() > 0 ? frame.getLineNumber() : null; + return new BacktraceStackFrame(functionName, fileName, line); + } + + public BacktraceStackFrame(String functionName, String sourceCodeFileName, Integer line) { + this(functionName, sourceCodeFileName, line, UUID.randomUUID().toString()); + } + + public BacktraceStackFrame(String functionName, String sourceCodeFileName, Integer line, String sourceCodeUuid) { + this.functionName = functionName; + this.sourceCodeFileName = sourceCodeFileName; + this.sourceCode = sourceCodeUuid; + this.line = line; } } \ No newline at end of file diff --git a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceStackTrace.java b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceStackTrace.java index 16cb1217..91a1b9a5 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceStackTrace.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceStackTrace.java @@ -61,7 +61,7 @@ private void setStacktraceInformation(StackTraceElement[] frames) { BacktraceLogger.d(LOG_TAG, "Skipping frame because it comes from inside the Backtrace library"); continue; } - BacktraceStackFrame backtraceStackFrame = new BacktraceStackFrame(frame); + BacktraceStackFrame backtraceStackFrame = BacktraceStackFrame.fromStackTraceElement(frame); this.stackFrames.add(backtraceStackFrame); } } diff --git a/backtrace-library/src/main/java/backtraceio/library/models/database/BacktraceDatabaseRecord.java b/backtrace-library/src/main/java/backtraceio/library/models/database/BacktraceDatabaseRecord.java index 46ad8db6..3ffd7415 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/database/BacktraceDatabaseRecord.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/database/BacktraceDatabaseRecord.java @@ -23,13 +23,13 @@ public class BacktraceDatabaseRecord { /** * Path to database directory */ - private transient final String _path; + private final transient String path; /** * Id */ @SerializedName("Id") - public UUID id = UUID.randomUUID(); + public UUID id; /** * Check if current record is in use @@ -39,7 +39,8 @@ public class BacktraceDatabaseRecord { /** * record writer */ - transient DatabaseRecordWriter RecordWriter; + private final transient DatabaseRecordWriter recordWriter; + /** * Path to json stored all information about current record @@ -70,17 +71,28 @@ public class BacktraceDatabaseRecord { */ private transient BacktraceData record; - BacktraceDatabaseRecord() { - this._path = ""; - this.recordPath = String.format("%s-record.json", this.id); - this.diagnosticDataPath = String.format("%s-attachment", this.id); - } - public BacktraceDatabaseRecord(BacktraceData data, String path) { - this.id = UUID.fromString(data.uuid); + this.id = UUID.fromString(data.getUuid()); this.record = data; - this._path = path; - RecordWriter = new BacktraceDatabaseRecordWriter(path); + this.path = path; + this.recordWriter = new BacktraceDatabaseRecordWriter(path); + } + + public BacktraceDatabaseRecord(String id, + String path, + String recordPath, + String diagnosticDataPath, + String reportPath, + long size) { + this.id = UUID.fromString(id); + this.recordPath = recordPath; + this.diagnosticDataPath = diagnosticDataPath; + this.reportPath = reportPath; + this.path = path; + this.size = size; + this.recordWriter = new BacktraceDatabaseRecordWriter(path); + + this.record = getBacktraceData(); } /** @@ -115,17 +127,25 @@ public long getSize() { return size; } - public void setSize(long size) { - this.size = size; + /** + * Get BacktraceData object related to db record + * @deprecated The {@code context} parameter is no longer used and this method will be removed in future versions. + * Please use {@link #getBacktraceData()} instead. + * + *

The {@code context} parameter has no effect on the behavior of this method.

+ * + * @param context The unused context parameter. + * @return The BacktraceData object related to db record + */ + @Deprecated + public BacktraceData getBacktraceData(Context context) { + return getBacktraceData(); } - /** * Get valid BacktraceData from current record - * - * @param context * @return valid BacktraceData object */ - public BacktraceData getBacktraceData(Context context) { + public BacktraceData getBacktraceData() { if (this.record != null) { return this.record; } @@ -150,8 +170,6 @@ public BacktraceData getBacktraceData(Context context) { // diagnostic data to API diagnosticData.report = BacktraceSerializeHelper.fromJson(jsonReport, BacktraceReport.class); - // Serialized data loses the context, give context again when deserializing - diagnosticData.context = context; return diagnosticData; } catch (Exception ex) { BacktraceLogger.e(LOG_TAG, "Exception occurs on deserialization of diagnostic data", ex); @@ -170,13 +188,13 @@ public boolean save() { this.diagnosticDataPath = save(record, String.format("%s-attachment", id)); this.reportPath = save(record.getReport(), String.format("%s-report", id)); - this.recordPath = new File(this._path, + this.recordPath = new File(this.path, String.format("%s-record.json", this.id)).getAbsolutePath(); String json = BacktraceSerializeHelper.toJson(this); byte[] file = json.getBytes(StandardCharsets.UTF_8); this.size += file.length; - RecordWriter.write(this, String.format("%s-record", this.id)); + recordWriter.write(this, String.format("%s-record", this.id)); BacktraceLogger.d(LOG_TAG, "Saving data to internal app storage successful"); return true; } catch (Exception ex) { @@ -201,7 +219,7 @@ private String save(Object data, String prefix) { String json = BacktraceSerializeHelper.toJson(data); byte[] file = json.getBytes(StandardCharsets.UTF_8); this.size += file.length; - return RecordWriter.write(file, prefix); + return recordWriter.write(file, prefix); } catch (Exception ex) { BacktraceLogger.e(LOG_TAG, "Received IOException while saving data to database", ex); return ""; // TODO: consider a better solution diff --git a/backtrace-library/src/main/java/backtraceio/library/models/json/Annotations.java b/backtrace-library/src/main/java/backtraceio/library/models/json/Annotations.java index c77fa8e3..d8a315db 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/json/Annotations.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/json/Annotations.java @@ -21,13 +21,15 @@ public static Map getAnnotations(Object exceptionMessage, Map diagnosticStack; + public List diagnosticStack; /** * Create new instance of Backtrace report to send a report with custom client message @@ -188,12 +188,23 @@ public BacktraceReport( this.setDefaultErrorTypeAttribute(); } - public String getExceptionClassifier(Exception exception) { - if (exception instanceof UnhandledThrowableWrapper) { - return ((UnhandledThrowableWrapper) exception).getClassifier(); - } - return exception.getClass().getCanonicalName(); + public BacktraceReport(UUID uuid, long timestamp, + boolean exceptionTypeReport, String classifier, + Map attributes, + String message, Exception exception, + List attachmentPaths, + List diagnosticStack) { + this.uuid = uuid; + this.timestamp = timestamp; + this.exceptionTypeReport = exceptionTypeReport; + this.classifier = classifier; + this.attributes = attributes; + this.message = message; + this.exception = exception; + this.attachmentPaths = attachmentPaths; + this.diagnosticStack = diagnosticStack; } + /** * To avoid serialization issues with custom exceptions, our goal is to always * prepare exception in a way potential serialization won't break it @@ -210,6 +221,13 @@ private Exception prepareException(Exception exception) { return reportException; } + public String getExceptionClassifier(Exception exception) { + if (exception instanceof UnhandledThrowableWrapper) { + return ((UnhandledThrowableWrapper) exception).getClassifier(); + } + return exception.getClass().getCanonicalName(); + } + /** * Sets error.type attribute depends on the type of the report */ @@ -236,7 +254,7 @@ private void setDefaultErrorTypeAttribute() { public static Map concatAttributes( BacktraceReport report, Map attributes) { Map reportAttributes = report.attributes != null ? report.attributes : - new HashMap(); + new HashMap<>(); if (attributes == null) { return reportAttributes; } @@ -249,8 +267,7 @@ public BacktraceData toBacktraceData(Context context, Map client } public BacktraceData toBacktraceData(Context context, Map clientAttributes, boolean isProguardEnabled) { - BacktraceData backtraceData = new BacktraceData(context, this, clientAttributes); - backtraceData.symbolication = isProguardEnabled ? "proguard" : null; - return backtraceData; + final String symbolication = isProguardEnabled ? "proguard" : null; + return new BacktraceData.Builder(this).setAttributes(context, clientAttributes).setSymbolication(symbolication).build(); } } \ No newline at end of file diff --git a/backtrace-library/src/main/java/backtraceio/library/models/json/SourceCode.java b/backtrace-library/src/main/java/backtraceio/library/models/json/SourceCode.java index 991b14eb..7ff04dce 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/json/SourceCode.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/json/SourceCode.java @@ -22,7 +22,19 @@ public class SourceCode { public SourceCode(BacktraceStackFrame stackFrame) { - this.sourceCodeFileName = stackFrame.sourceCodeFileName; - this.startLine = stackFrame.line; + this(stackFrame.line, stackFrame.sourceCodeFileName); + } + + public SourceCode(Integer line, String sourceCodeFileName) { + this.startLine = line; + this.sourceCodeFileName = sourceCodeFileName; + } + + public Integer getStartLine() { + return startLine; + } + + public String getSourceCodeFileName() { + return sourceCodeFileName; } } diff --git a/backtrace-library/src/main/java/backtraceio/library/models/json/SourceCodeData.java b/backtrace-library/src/main/java/backtraceio/library/models/json/SourceCodeData.java index bc9e101b..640a7188 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/json/SourceCodeData.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/json/SourceCodeData.java @@ -1,7 +1,7 @@ package backtraceio.library.models.json; -import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import backtraceio.library.logger.BacktraceLogger; @@ -16,9 +16,9 @@ public class SourceCodeData { /** * Source code information about current executed program */ - public Map data = new HashMap<>(); + public final Map data = new HashMap<>(); - public SourceCodeData(ArrayList exceptionStack) { + public SourceCodeData(List exceptionStack) { BacktraceLogger.d(LOG_TAG, "Initialization source code data"); if (exceptionStack == null || exceptionStack.size() == 0) { BacktraceLogger.w(LOG_TAG, "Exception stack is null or empty"); diff --git a/backtrace-library/src/main/java/backtraceio/library/models/json/ThreadData.java b/backtrace-library/src/main/java/backtraceio/library/models/json/ThreadData.java index baad3b04..14d9064f 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/json/ThreadData.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/json/ThreadData.java @@ -2,6 +2,7 @@ import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import backtraceio.library.models.BacktraceStackFrame; @@ -14,7 +15,7 @@ public class ThreadData { /** * All collected application threads information */ - public HashMap threadInformation = new HashMap<>(); + public Map threadInformation = new HashMap<>(); /** * Application Id for current thread. @@ -27,7 +28,7 @@ public class ThreadData { * * @param exceptionStack current BacktraceReport exception stack */ - public ThreadData(ArrayList exceptionStack) { + public ThreadData(List exceptionStack) { generateCurrentThreadInformation(exceptionStack); processThreads(); } @@ -46,7 +47,7 @@ public String getMainThread() { * * @param exceptionStack current BacktraceReport exception stack */ - private void generateCurrentThreadInformation(ArrayList exceptionStack) { + private void generateCurrentThreadInformation(List exceptionStack) { Thread currThread = Thread.currentThread(); mainThread = currThread.getName().toLowerCase(); this.threadInformation.put(mainThread, @@ -73,7 +74,7 @@ private void processThreads() { } if (stack != null && stack.length != 0) { for (StackTraceElement stackTraceElement : stack) { - stackFrame.add(new BacktraceStackFrame(stackTraceElement)); + stackFrame.add(BacktraceStackFrame.fromStackTraceElement(stackTraceElement)); } } this.threadInformation.put(threadName, new ThreadInformation(thread, stackFrame, diff --git a/backtrace-library/src/main/java/backtraceio/library/models/json/ThreadInformation.java b/backtrace-library/src/main/java/backtraceio/library/models/json/ThreadInformation.java index 2fea63a3..8dbf1944 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/json/ThreadInformation.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/json/ThreadInformation.java @@ -3,6 +3,7 @@ import com.google.gson.annotations.SerializedName; import java.util.ArrayList; +import java.util.List; import backtraceio.library.models.BacktraceStackFrame; @@ -28,7 +29,7 @@ public class ThreadInformation { */ @SerializedName("stack") @SuppressWarnings({"UnusedDeclaration"}) - private final ArrayList stack; + private final List stack; /** * Create new instance of ThreadInformation @@ -37,9 +38,9 @@ public class ThreadInformation { * @param fault denotes whether a thread is a faulting thread - in most cases main thread * @param stack exception stack information */ - private ThreadInformation(String threadName, Boolean fault, ArrayList + public ThreadInformation(String threadName, Boolean fault, List stack) { - this.stack = stack == null ? new ArrayList() : stack; + this.stack = stack == null ? new ArrayList<>() : stack; this.name = threadName; this.fault = fault; } @@ -51,7 +52,19 @@ private ThreadInformation(String threadName, Boolean fault, ArrayList stack, Boolean currentThread) { + ThreadInformation(Thread thread, List stack, Boolean currentThread) { this(thread.getName().toLowerCase(), currentThread, stack); } + + public String getName() { + return name; + } + + public Boolean getFault() { + return fault; + } + + public List getStack() { + return stack; + } } diff --git a/backtrace-library/src/main/java/backtraceio/library/models/types/BacktraceResultStatus.java b/backtrace-library/src/main/java/backtraceio/library/models/types/BacktraceResultStatus.java index 40d8e18b..dd570907 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/types/BacktraceResultStatus.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/types/BacktraceResultStatus.java @@ -12,5 +12,18 @@ public enum BacktraceResultStatus { /** * Set when data were send to API */ - Ok, + Ok; + + public static BacktraceResultStatus enumOf(String val) { + switch (val.toLowerCase()) { + case "ok": + return BacktraceResultStatus.Ok; + + case "servererror": + return BacktraceResultStatus.ServerError; + + default: + throw new IllegalArgumentException("Invalid BacktraceResultStatus enum value"); + } + } } \ No newline at end of file diff --git a/backtrace-library/src/main/java/backtraceio/library/services/BacktraceApi.java b/backtrace-library/src/main/java/backtraceio/library/services/BacktraceApi.java index 0bd48290..4e3bc608 100644 --- a/backtrace-library/src/main/java/backtraceio/library/services/BacktraceApi.java +++ b/backtrace-library/src/main/java/backtraceio/library/services/BacktraceApi.java @@ -1,5 +1,7 @@ package backtraceio.library.services; +import android.content.Context; + import backtraceio.library.BacktraceCredentials; import backtraceio.library.events.EventsOnServerResponseEventListener; import backtraceio.library.events.EventsRequestHandler; @@ -19,6 +21,7 @@ public class BacktraceApi implements Api { private final static transient String LOG_TAG = BacktraceApi.class.getSimpleName(); + private final transient BacktraceHandlerThread threadSender; /** @@ -61,7 +64,7 @@ public class BacktraceApi implements Api { * * @param credentials API credentials */ - public BacktraceApi(BacktraceCredentials credentials) { + public BacktraceApi(Context context, BacktraceCredentials credentials) { if (credentials == null) { BacktraceLogger.e(LOG_TAG, "BacktraceCredentials parameter passed to BacktraceApi " + "constructor is null"); @@ -69,7 +72,7 @@ public BacktraceApi(BacktraceCredentials credentials) { } this.reportSubmissionUrl = credentials.getSubmissionUrl().toString(); - threadSender = new BacktraceHandlerThread(BacktraceHandlerThread.class.getSimpleName(), + threadSender = new BacktraceHandlerThread(context, BacktraceHandlerThread.class.getSimpleName(), this.reportSubmissionUrl); } diff --git a/backtrace-library/src/main/java/backtraceio/library/services/BacktraceDatabaseContext.java b/backtrace-library/src/main/java/backtraceio/library/services/BacktraceDatabaseContext.java index bebd2bbe..d2d17675 100644 --- a/backtrace-library/src/main/java/backtraceio/library/services/BacktraceDatabaseContext.java +++ b/backtrace-library/src/main/java/backtraceio/library/services/BacktraceDatabaseContext.java @@ -30,10 +30,6 @@ public class BacktraceDatabaseContext implements DatabaseContext { */ private final int _retryNumber; - /** - * Application context - */ - private final Context _applicationContext; /** * Database cache @@ -55,13 +51,28 @@ public class BacktraceDatabaseContext implements DatabaseContext { */ private final RetryOrder retryOrder; + /** + * @deprecated This constructor will be removed in future versions. + * The {@code context} parameter is no longer used. + * Please use the constructor without the {@code context} parameter. + * + *

Use {@link #BacktraceDatabaseContext(BacktraceDatabaseSettings)} instead.

+ * + * @param context The unused Android context parameter. + * @param settings The database settings. + */ + @Deprecated + public BacktraceDatabaseContext(Context context, BacktraceDatabaseSettings settings) { + this(settings); + } + /** * Initialize new instance of Backtrace Database Context * * @param settings database settings */ - public BacktraceDatabaseContext(Context context, BacktraceDatabaseSettings settings) { - this(context, settings.getDatabasePath(), settings.getRetryLimit(), settings.getRetryOrder()); + public BacktraceDatabaseContext(BacktraceDatabaseSettings settings) { + this(settings.getDatabasePath(), settings.getRetryLimit(), settings.getRetryOrder()); } /** @@ -71,8 +82,7 @@ public BacktraceDatabaseContext(Context context, BacktraceDatabaseSettings setti * @param retryNumber total number of retries * @param retryOrder record order */ - private BacktraceDatabaseContext(Context context, String path, int retryNumber, RetryOrder retryOrder) { - this._applicationContext = context; + private BacktraceDatabaseContext(String path, int retryNumber, RetryOrder retryOrder) { this._path = path; this._retryNumber = retryNumber; this.retryOrder = retryOrder; @@ -88,7 +98,7 @@ private void setupBatch() { } for (int i = 0; i < _retryNumber; i++) { - this.batchRetry.put(i, new ArrayList()); + this.batchRetry.put(i, new ArrayList<>()); } } diff --git a/backtrace-library/src/main/java/backtraceio/library/services/BacktraceDatabaseFileContext.java b/backtrace-library/src/main/java/backtraceio/library/services/BacktraceDatabaseFileContext.java index 95059b8a..8b10dbe2 100644 --- a/backtrace-library/src/main/java/backtraceio/library/services/BacktraceDatabaseFileContext.java +++ b/backtrace-library/src/main/java/backtraceio/library/services/BacktraceDatabaseFileContext.java @@ -1,7 +1,6 @@ package backtraceio.library.services; import java.io.File; -import java.io.FileFilter; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -52,12 +51,7 @@ public Iterable getAll() { public Iterable getRecords() { BacktraceLogger.d(LOG_TAG, "Getting files from file context"); final Pattern p = Pattern.compile(this.recordFilterRegex); - File[] pagesTemplates = this._databaseDirectory.listFiles(new FileFilter() { - @Override - public boolean accept(File f) { - return p.matcher(f.getName()).matches(); - } - }); + File[] pagesTemplates = this._databaseDirectory.listFiles(f -> p.matcher(f.getName()).matches()); if (pagesTemplates == null) { return Collections.emptyList(); } diff --git a/backtrace-library/src/main/java/backtraceio/library/services/BacktraceHandlerThread.java b/backtrace-library/src/main/java/backtraceio/library/services/BacktraceHandlerThread.java index eb4afaa4..900959a9 100644 --- a/backtrace-library/src/main/java/backtraceio/library/services/BacktraceHandlerThread.java +++ b/backtrace-library/src/main/java/backtraceio/library/services/BacktraceHandlerThread.java @@ -1,5 +1,6 @@ package backtraceio.library.services; +import android.content.Context; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; @@ -10,20 +11,23 @@ import backtraceio.library.common.BacktraceSerializeHelper; import backtraceio.library.interfaces.Api; import backtraceio.library.logger.BacktraceLogger; +import backtraceio.library.models.BacktraceDataAttachmentsFileHelper; import backtraceio.library.models.BacktraceResult; public class BacktraceHandlerThread extends HandlerThread { private static final transient String LOG_TAG = BacktraceHandlerThread.class.getSimpleName(); + private final transient Context context; private BacktraceHandler mHandler; private final String url; private UniqueEventsHandler mUniqueEventsHandler; private SummedEventsHandler mSummedEventsHandler; - BacktraceHandlerThread(String name, String url) { + BacktraceHandlerThread(Context context, String name, String url) { super(name); this.url = url; + this.context = context; this.start(); } @@ -41,7 +45,7 @@ SummedEventsHandler createSummedEventsHandler(BacktraceMetrics backtraceMetrics, protected void onLooperPrepared() { super.onLooperPrepared(); if (mHandler == null) { - mHandler = new BacktraceHandler(this.getLooper(), this.url); + mHandler = new BacktraceHandler(this.context, this.getLooper(), this.url); } } @@ -55,7 +59,7 @@ void sendReport(BacktraceHandlerInputReport data) { // Sometimes, sendReport gets called before the Looper is ready. // getLooper will wait for the Looper to be ready: https://stackoverflow.com/questions/30300555/android-what-happens-after-a-handlerthread-is-started if (mHandler == null) { - mHandler = new BacktraceHandler(this.getLooper(), this.url); + mHandler = new BacktraceHandler(this.context, this.getLooper(), this.url); } mHandler.sendMessage(createMessage(data)); } @@ -70,10 +74,13 @@ void sendSummedEvents(BacktraceHandlerInputEvents data) { private class BacktraceHandler extends Handler { private final transient String LOG_TAG = BacktraceHandler.class.getSimpleName(); + + private final transient Context context; String url; - private BacktraceHandler(Looper looper, String url) { + private BacktraceHandler(Context context, Looper looper, String url) { super(looper); + this.context = context; this.url = url; } @@ -87,8 +94,8 @@ public void handleMessage(Message msg) { } else { BacktraceLogger.d(LOG_TAG, "Sending report using default request handler"); String json = BacktraceSerializeHelper.toJson(mInput.data); - List attachments = mInput.data.getAttachments(); - result = BacktraceReportSender.sendReport(url, json, attachments, mInput.data.report, + List attachments = BacktraceDataAttachmentsFileHelper.getValidAttachments(this.context, mInput.data); + result = BacktraceReportSender.sendReport(url, json, attachments, mInput.data.getReport(), mInput.serverErrorEventListener); } diff --git a/backtrace-library/src/main/java/backtraceio/library/services/BacktraceReportSender.java b/backtrace-library/src/main/java/backtraceio/library/services/BacktraceReportSender.java index fb2c11c5..3049f0db 100644 --- a/backtrace-library/src/main/java/backtraceio/library/services/BacktraceReportSender.java +++ b/backtrace-library/src/main/java/backtraceio/library/services/BacktraceReportSender.java @@ -12,6 +12,7 @@ import backtraceio.library.events.OnServerErrorEventListener; import backtraceio.library.http.HttpHelper; import backtraceio.library.logger.BacktraceLogger; +import backtraceio.library.models.BacktraceApiResult; import backtraceio.library.models.BacktraceResult; import backtraceio.library.models.json.BacktraceReport; import backtraceio.library.models.metrics.EventsPayload; @@ -73,9 +74,10 @@ static BacktraceResult sendReport(String serverUrl, String json, List at BacktraceLogger.d(LOG_TAG, "Received response status from Backtrace API for HTTP request is: " + statusCode); if (statusCode == HttpURLConnection.HTTP_OK) { - result = BacktraceSerializeHelper.fromJson( - HttpHelper.getResponseMessage(urlConnection), BacktraceResult.class - ); + final String responseJson = HttpHelper.getResponseMessage(urlConnection); + final BacktraceApiResult apiResult = BacktraceSerializeHelper.fromJson(responseJson, BacktraceApiResult.class); + + result = new BacktraceResult(apiResult); result.setBacktraceReport(report); } else { String message = HttpHelper.getResponseMessage(urlConnection); diff --git a/backtrace-library/src/test/java/backtraceio/library/ConcatAttributesUnitTest.java b/backtrace-library/src/test/java/backtraceio/library/ConcatAttributesUnitTest.java index 5a4de571..b56d3d1f 100644 --- a/backtrace-library/src/test/java/backtraceio/library/ConcatAttributesUnitTest.java +++ b/backtrace-library/src/test/java/backtraceio/library/ConcatAttributesUnitTest.java @@ -12,22 +12,25 @@ public class ConcatAttributesUnitTest { - private Map attributesReport = new HashMap() {{ + private final Map attributesReport = new HashMap() {{ put("1", "1"); put("2", "2"); }}; - private Map attributes = new HashMap() {{ + private final Map attributes = new HashMap() {{ put("3", "3"); put("4", "4"); }}; @Test public void concatAttributes_isCorrect() { + // GIVEN // 1 - backtraceReport by default adds error.type attribute - int expectedAttributesSize = 1 + attributes.size() + attributesReport.size(); - BacktraceReport report = new BacktraceReport("test", attributesReport, null); - Map result = BacktraceReport.concatAttributes(report, attributes); + final int expectedAttributesSize = 1 + attributes.size() + attributesReport.size(); + final BacktraceReport report = new BacktraceReport("test", attributesReport, null); + // WHEN + final Map result = BacktraceReport.concatAttributes(report, attributes); + // THEN assertEquals(expectedAttributesSize, result.size()); assertEquals(result.get("2"), "2"); assertEquals(result.get("4"), "4"); @@ -35,21 +38,26 @@ public void concatAttributes_isCorrect() { @Test public void concatAttributesNullParam_isCorrect() { + // GIVEN // 1 - backtraceReport by default adds error.type attribute int expectedAttributesSize = 1 + attributesReport.size(); - BacktraceReport report = new BacktraceReport("test", attributesReport, null); - Map result = BacktraceReport.concatAttributes(report, null); + final BacktraceReport report = new BacktraceReport("test", attributesReport, null); + // WHEN + final Map result = BacktraceReport.concatAttributes(report, null); + // THEN assertEquals(expectedAttributesSize, result.size()); assertEquals(result.get("2"), "2"); } @Test public void concatAttributesNullAttributes_isCorrect() { - + // GIVEN // 1 - backtraceReport by default adds error.type attribute - int expectedAttributesSize = 1 + attributes.size(); - BacktraceReport report = new BacktraceReport("test", null, null); - Map result = BacktraceReport.concatAttributes(report, attributes); + final int expectedAttributesSize = 1 + attributes.size(); + final BacktraceReport report = new BacktraceReport("test", null, null); + // WHEN + final Map result = BacktraceReport.concatAttributes(report, attributes); + // THEN assertEquals(expectedAttributesSize, result.size()); assertEquals(result.get("4"), "4"); } diff --git a/backtrace-library/src/test/java/backtraceio/library/TestUtils.java b/backtrace-library/src/test/java/backtraceio/library/TestUtils.java new file mode 100644 index 00000000..737d7e08 --- /dev/null +++ b/backtrace-library/src/test/java/backtraceio/library/TestUtils.java @@ -0,0 +1,66 @@ +package backtraceio.library; + +import com.google.common.collect.MapDifference; +import com.google.common.collect.Maps; +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; +import com.google.gson.reflect.TypeToken; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.lang.reflect.Type; +import java.util.Map; + +public class TestUtils { + + public static String readFileAsString(Object obj, String fileName) { + ClassLoader classLoader = obj.getClass().getClassLoader(); + InputStream inputStream = classLoader.getResourceAsStream(fileName); + + if (inputStream != null) { + try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) { + StringBuilder jsonStringBuilder = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + jsonStringBuilder.append(line); + } + return jsonStringBuilder.toString(); + + } catch (IOException e) { + e.printStackTrace(); + } + } + return null; + } + + public static String minifyJsonString(String json) throws JSONException { + JSONObject jsonObject = new JSONObject(json); + return jsonObject.toString(); + } + + public static boolean compareJson(String json1, String json2) { + + final JsonParser parser = new JsonParser(); + final JsonElement o1 = parser.parse(json1); + final JsonElement o2 = parser.parse(json2); + final boolean compareResult = o1.equals(o2); + + if (!compareResult) { + Gson g = new Gson(); + Type mapType = new TypeToken>(){}.getType(); + Map json1Map = g.fromJson(json1, mapType); + Map json2Map = g.fromJson(json2, mapType); + MapDifference x = Maps.difference(json1Map, json2Map); + + System.out.println(Maps.difference(json1Map, json2Map)); + return false; + } + return true; + } +} diff --git a/backtrace-library/src/test/java/backtraceio/library/database/BacktraceDatabaseRecordTest.java b/backtrace-library/src/test/java/backtraceio/library/database/BacktraceDatabaseRecordTest.java new file mode 100644 index 00000000..e2a0064d --- /dev/null +++ b/backtrace-library/src/test/java/backtraceio/library/database/BacktraceDatabaseRecordTest.java @@ -0,0 +1,73 @@ +package backtraceio.library.database; + +import static junit.framework.TestCase.assertEquals; +import static org.junit.Assert.assertNull; + +import org.junit.Test; + +import backtraceio.library.TestUtils; +import backtraceio.library.common.BacktraceSerializeHelper; +import backtraceio.library.models.database.BacktraceDatabaseRecord; + +public class BacktraceDatabaseRecordTest { + private final String JSON_FILE = "backtraceDatabaseRecord.json"; + private final String uuid = "ecdf418b-3e22-4c7c-8011-c85dc2b4386f"; + private final String dbPath = "/data/user/0/backtraceio.library.test/files/"; + + private final int expectedSize = 25362; + @Test + public void serialize() { + // GIVEN + final BacktraceDatabaseRecord obj = new BacktraceDatabaseRecord( + uuid, + dbPath + uuid + "-report.json", + dbPath + uuid + "-record.json", + dbPath+ uuid + "-attachment.json", + dbPath + uuid + "-report.json", + expectedSize + ); + + // WHEN + String json = BacktraceSerializeHelper.toJson(obj); + + // THEN + String expectedJson = TestUtils.readFileAsString(this, JSON_FILE); + assertEquals(expectedJson, json); + } + + @Test + public void deserialize() { + // GIVEN + String json = TestUtils.readFileAsString(this, JSON_FILE); + // WHEN + final BacktraceDatabaseRecord obj = BacktraceSerializeHelper.fromJson(json, BacktraceDatabaseRecord.class); + // THEN + assertEquals(dbPath + uuid + "-record.json", obj.getRecordPath()); + assertEquals(expectedSize, obj.getSize()); + assertEquals(dbPath+ uuid + "-attachment.json", obj.getDiagnosticDataPath()); + assertNull(obj.getBacktraceData()); + } + + @Test + public void serializeAndDeserialize() { + // GIVEN + final BacktraceDatabaseRecord obj = new BacktraceDatabaseRecord( + uuid, + dbPath + uuid + "-report.json", + dbPath + uuid + "-record.json", + dbPath+ uuid + "-attachment.json", + dbPath + uuid + "-report.json", + expectedSize + ); + String json = BacktraceSerializeHelper.toJson(obj); + + // WHEN + final BacktraceDatabaseRecord output = BacktraceSerializeHelper.fromJson(json, BacktraceDatabaseRecord.class); + + // THEN + assertEquals(dbPath + uuid + "-record.json", output.getRecordPath()); + assertEquals(expectedSize, output.getSize()); + assertEquals(dbPath+ uuid + "-attachment.json", output.getDiagnosticDataPath()); + assertNull(output.getBacktraceData()); + } +} diff --git a/backtrace-library/src/test/java/backtraceio/library/models/BacktraceApiResultTest.java b/backtrace-library/src/test/java/backtraceio/library/models/BacktraceApiResultTest.java new file mode 100644 index 00000000..608676bc --- /dev/null +++ b/backtrace-library/src/test/java/backtraceio/library/models/BacktraceApiResultTest.java @@ -0,0 +1,48 @@ +package backtraceio.library.models; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import org.junit.Test; + +import backtraceio.library.TestUtils; +import backtraceio.library.common.BacktraceSerializeHelper; + +public class BacktraceApiResultTest { + + @Test + public void serialize() { + // GIVEN + BacktraceApiResult example = new BacktraceApiResult("95000000-eb43-390b-0000-000000000000", "ok"); + // WHEN + String result = BacktraceSerializeHelper.toJson(example); + // THEN + String expectedJson = TestUtils.readFileAsString(this, "backtraceApiResult.json"); + assertEquals(expectedJson, result); + } + + @Test + public void deserialize() { + // GIVEN + String json = TestUtils.readFileAsString(this, "backtraceApiResult.json"); + // WHEN + BacktraceApiResult result = BacktraceSerializeHelper.fromJson(json, BacktraceApiResult.class); + // THEN + assertNotNull(result); + assertEquals("95000000-eb43-390b-0000-000000000000", result.getRxId()); + assertEquals("ok", result.getResponse()); + } + + @Test + public void serializeAndDeserialize() { + // GIVEN + BacktraceApiResult example = new BacktraceApiResult("95000000-eb43-390b-0000-000000000000", "ok"); + // WHEN + String json = BacktraceSerializeHelper.toJson(example); + BacktraceApiResult result = BacktraceSerializeHelper.fromJson(json, BacktraceApiResult.class); + // THEN + assertNotNull(result); + assertEquals(example.getRxId(), result.getRxId()); + assertEquals(example.getResponse(), result.getResponse()); + } +} diff --git a/backtrace-library/src/test/java/backtraceio/library/models/BacktraceDataJsonTest.java b/backtrace-library/src/test/java/backtraceio/library/models/BacktraceDataJsonTest.java new file mode 100644 index 00000000..3b9411c8 --- /dev/null +++ b/backtrace-library/src/test/java/backtraceio/library/models/BacktraceDataJsonTest.java @@ -0,0 +1,192 @@ +package backtraceio.library.models; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import androidx.annotation.NonNull; + +import com.google.common.collect.ImmutableMap; + +import org.junit.Test; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import backtraceio.library.TestUtils; +import backtraceio.library.common.BacktraceSerializeHelper; +import backtraceio.library.models.json.SourceCode; +import backtraceio.library.models.json.ThreadInformation; + +public class BacktraceDataJsonTest { + private final String JSON_FILE = "backtraceData.json"; + @Test + public void serialize() { + // GIVEN + final BacktraceData backtraceData = createTestBacktraceDataObject(); + + // WHEN + String json = BacktraceSerializeHelper.toJson(backtraceData); + + // THEN + String expectedJson = TestUtils.readFileAsString(this, JSON_FILE); + + assertTrue(TestUtils.compareJson(json, expectedJson)); + } + + @NonNull + private static BacktraceData createTestBacktraceDataObject() { + final Map attributes = ImmutableMap.of("application.session", "4b965773-539e-4dd3-be1b-f8ab017c2c9f"); + + // GIVEN annotations + final Map annotations = ImmutableMap.of( + "Environment Variables", ImmutableMap.of("SYSTEMSERVERCLASSPATH", "/system/framework/com.android.location.provider.jar:/system/framework/services.jar:/system/framework/ethernet-service.jar:/apex/com.android.permission/javalib/service-permission.jar:/apex/com.android.wifi/javalib/service-wifi.jar:/apex/com.android.ipsec/javalib/android.net.ipsec.ike.jar"), + "Exception", ImmutableMap.of("message", "Example test string") + ); + // GIVEN other + final Map sourceCode = ImmutableMap.of( + "8751bea6-d6f6-48f4-9f96-1355c3408a9a", new SourceCode(null, "VMStack.java"), + "27948842-7c2b-4898-a74a-ba3ca4afe814", new SourceCode(17, "InvokeMethod.java") + ); + + final Map threadInformationMap = new HashMap<>(); + + threadInformationMap.put("profile saver", new ThreadInformation("profile saver", false, new ArrayList<>())); + threadInformationMap.put("main", new ThreadInformation("main", false, new ArrayList() {{ + add(new BacktraceStackFrame("android.os.MessageQueue.nativePollOnce", null, null, "b1a3d84a-fcf3-4d10-90d5-994f1e397607" )); + add(new BacktraceStackFrame("android.os.MessageQueue.next", null, 335, "868c2d50-b00a-42a5-9aa0-e82cdea07bcd")); + }})); + + // GIVEN BacktraceData + return new BacktraceData( + "ecdf418b-3e22-4c7c-8011-c85dc2b4386f", + null, + 1720419610, + "0", + "3.8.3", + attributes, + "instr: androidx.test.runner.androidjunitrunner", + null, + null, + annotations, + sourceCode, + threadInformationMap + ); + } + + @Test + public void deserialize() { + // GIVEN + String json = TestUtils.readFileAsString(this, JSON_FILE); + + // WHEN + final BacktraceData obj = BacktraceSerializeHelper.fromJson(json, BacktraceData.class); + + // THEN + assertNotNull(obj); + assertEquals("ecdf418b-3e22-4c7c-8011-c85dc2b4386f", obj.getUuid()); + assertEquals(null, obj.getSymbolication()); + assertEquals(1720419610, obj.getTimestamp()); + assertEquals("0", obj.getLangVersion()); + assertEquals("java", obj.getLang()); + assertEquals("3.8.3", obj.getAgentVersion()); + assertEquals("backtrace-android", obj.getAgent()); + assertEquals("instr: androidx.test.runner.androidjunitrunner", obj.getMainThread()); + assertNull(obj.classifiers); + assertEquals(2, obj.getAnnotations().size()); + assertEquals("/system/framework/com.android.location.provider.jar:/system/framework/services.jar:/system/framework/ethernet-service.jar:/apex/com.android.permission/javalib/service-permission.jar:/apex/com.android.wifi/javalib/service-wifi.jar:/apex/com.android.ipsec/javalib/android.net.ipsec.ike.jar", ((Map)obj.getAnnotations().get("Environment Variables")).get("SYSTEMSERVERCLASSPATH")); + assertEquals("Example test string", ((Map)obj.getAnnotations().get("Exception")).get("message")); + assertEquals(1, obj.getAttributes().size()); + assertEquals("4b965773-539e-4dd3-be1b-f8ab017c2c9f", obj.getAttributes().get("application.session")); + assertNull(obj.getReport()); + + // THEN source-code + assertEquals(2, obj.getSourceCode().size()); + assertNull(obj.getSourceCode().get("8751bea6-d6f6-48f4-9f96-1355c3408a9a").getStartLine()); + assertEquals("VMStack.java", obj.getSourceCode().get("8751bea6-d6f6-48f4-9f96-1355c3408a9a").getSourceCodeFileName()); + assertEquals(new Integer(17), obj.getSourceCode().get("27948842-7c2b-4898-a74a-ba3ca4afe814").getStartLine()); + assertEquals("InvokeMethod.java", obj.getSourceCode().get("27948842-7c2b-4898-a74a-ba3ca4afe814").getSourceCodeFileName()); + assertEquals(2, obj.getThreadInformationMap().size()); + + // THEN 'profile saver' thread + ThreadInformation resultProfileSaverThread = obj.getThreadInformationMap().get("profile saver"); + assertEquals(false, resultProfileSaverThread.getFault()); + assertEquals("profile saver", resultProfileSaverThread.getName()); + assertEquals(0, resultProfileSaverThread.getStack().size()); + + // THEN 'main' thread + ThreadInformation resultMainThread = obj.getThreadInformationMap().get("main"); + assertEquals(false,resultMainThread.getFault()); + assertEquals("main", resultMainThread.getName()); + assertEquals(2, resultMainThread.getStack().size()); + assertEquals(null, resultMainThread.getStack().get(0).sourceCodeFileName); + assertEquals(null, resultMainThread.getStack().get(0).line); + assertEquals("b1a3d84a-fcf3-4d10-90d5-994f1e397607", resultMainThread.getStack().get(0).sourceCode); + assertEquals("android.os.MessageQueue.nativePollOnce", resultMainThread.getStack().get(0).functionName); + + assertEquals(null, resultMainThread.getStack().get(1).sourceCodeFileName); + assertEquals(new Integer(335), resultMainThread.getStack().get(1).line); + assertEquals("868c2d50-b00a-42a5-9aa0-e82cdea07bcd", resultMainThread.getStack().get(1).sourceCode); + assertEquals("android.os.MessageQueue.next", resultMainThread.getStack().get(1).functionName); + } + + + @Test + public void serializeAndDeserialize() { + // GIVEN + final BacktraceData backtraceData = createTestBacktraceDataObject(); + + // WHEN + String json = BacktraceSerializeHelper.toJson(backtraceData); + final BacktraceData obj = BacktraceSerializeHelper.fromJson(json, BacktraceData.class); + + // THEN + assertNotNull(obj); + assertEquals("ecdf418b-3e22-4c7c-8011-c85dc2b4386f", obj.getUuid()); + assertEquals(null, obj.getSymbolication()); + assertEquals(1720419610, obj.getTimestamp()); + assertEquals("0", obj.getLangVersion()); + assertEquals("java", obj.getLang()); + assertEquals("3.8.3", obj.getAgentVersion()); + assertEquals("backtrace-android", obj.getAgent()); + assertEquals("instr: androidx.test.runner.androidjunitrunner", obj.getMainThread()); + assertNull(obj.classifiers); + assertEquals(2, obj.getAnnotations().size()); + assertEquals("/system/framework/com.android.location.provider.jar:/system/framework/services.jar:/system/framework/ethernet-service.jar:/apex/com.android.permission/javalib/service-permission.jar:/apex/com.android.wifi/javalib/service-wifi.jar:/apex/com.android.ipsec/javalib/android.net.ipsec.ike.jar", ((Map)obj.getAnnotations().get("Environment Variables")).get("SYSTEMSERVERCLASSPATH")); + assertEquals("Example test string", ((Map)obj.getAnnotations().get("Exception")).get("message")); + assertEquals(1, obj.getAttributes().size()); + assertEquals("4b965773-539e-4dd3-be1b-f8ab017c2c9f", obj.getAttributes().get("application.session")); + assertNull(obj.getReport()); + + // THEN source-code + assertEquals(2, obj.getSourceCode().size()); + assertNull(obj.getSourceCode().get("8751bea6-d6f6-48f4-9f96-1355c3408a9a").getStartLine()); + assertEquals("VMStack.java", obj.getSourceCode().get("8751bea6-d6f6-48f4-9f96-1355c3408a9a").getSourceCodeFileName()); + assertEquals(new Integer(17), obj.getSourceCode().get("27948842-7c2b-4898-a74a-ba3ca4afe814").getStartLine()); + assertEquals("InvokeMethod.java", obj.getSourceCode().get("27948842-7c2b-4898-a74a-ba3ca4afe814").getSourceCodeFileName()); + assertEquals(2, obj.getThreadInformationMap().size()); + + // THEN 'profile saver' thread + ThreadInformation resultProfileSaverThread = obj.getThreadInformationMap().get("profile saver"); + assertEquals(false, resultProfileSaverThread.getFault()); + assertEquals("profile saver", resultProfileSaverThread.getName()); + assertEquals(0, resultProfileSaverThread.getStack().size()); + + // THEN 'main' thread + ThreadInformation resultMainThread = obj.getThreadInformationMap().get("main"); + assertEquals(false,resultMainThread.getFault()); + assertEquals("main", resultMainThread.getName()); + assertEquals(2, resultMainThread.getStack().size()); + assertEquals(null, resultMainThread.getStack().get(0).sourceCodeFileName); + assertEquals(null, resultMainThread.getStack().get(0).line); + assertEquals("b1a3d84a-fcf3-4d10-90d5-994f1e397607", resultMainThread.getStack().get(0).sourceCode); + assertEquals("android.os.MessageQueue.nativePollOnce", resultMainThread.getStack().get(0).functionName); + + assertEquals(null, resultMainThread.getStack().get(1).sourceCodeFileName); + assertEquals(new Integer(335), resultMainThread.getStack().get(1).line); + assertEquals("868c2d50-b00a-42a5-9aa0-e82cdea07bcd", resultMainThread.getStack().get(1).sourceCode); + assertEquals("android.os.MessageQueue.next", resultMainThread.getStack().get(1).functionName); + } +} diff --git a/backtrace-library/src/test/java/backtraceio/library/models/BacktraceResultTest.java b/backtrace-library/src/test/java/backtraceio/library/models/BacktraceResultTest.java new file mode 100644 index 00000000..aae1262f --- /dev/null +++ b/backtrace-library/src/test/java/backtraceio/library/models/BacktraceResultTest.java @@ -0,0 +1,92 @@ +package backtraceio.library.models; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import org.junit.Test; + +import backtraceio.library.TestUtils; +import backtraceio.library.common.BacktraceSerializeHelper; +import backtraceio.library.models.json.BacktraceReport; +import backtraceio.library.models.types.BacktraceResultStatus; + +public class BacktraceResultTest { + + @Test + public void createFromBacktraceApiResult() { + // GIVEN + BacktraceApiResult example = new BacktraceApiResult("95000000-eb43-390b-0000-000000000000", "Ok"); + // WHEN + BacktraceResult result = new BacktraceResult(example); + // THEN + assertEquals(example.getRxId(), result.getRxId()); + assertEquals(BacktraceResultStatus.Ok, result.getStatus()); + } + + @Test + public void createFromBacktraceApiResultStatusLowercase() { + // GIVEN + BacktraceApiResult example = new BacktraceApiResult("95000000-eb43-390b-0000-000000000000", "ok"); + // WHEN + BacktraceResult result = new BacktraceResult(example); + // THEN + assertEquals(example.getRxId(), result.getRxId()); + assertEquals(BacktraceResultStatus.Ok, result.getStatus()); + } + + @Test + public void serialize() { + // GIVEN + BacktraceResult example = new BacktraceResult("95000000-eb43-390b-0000-000000000000", "Ok"); + // WHEN + String result = BacktraceSerializeHelper.toJson(example); + // THEN + String expectedJson = TestUtils.readFileAsString(this, "backtraceResult.json"); + assertEquals(expectedJson, result); + } + + @Test + public void deserialize() { + // GIVEN + String json = TestUtils.readFileAsString(this, "backtraceResult.json"); + // WHEN + BacktraceResult result = BacktraceSerializeHelper.fromJson(json, BacktraceResult.class); + // THEN + assertNotNull(result); + assertNull(result.getBacktraceReport()); + assertEquals("95000000-eb43-390b-0000-000000000000", result.getRxId()); + assertEquals(BacktraceResultStatus.Ok, result.getStatus()); + assertNull(result.getMessage()); + } + + @Test + public void serializeAndDeserialize() { + // GIVEN + BacktraceResult example = new BacktraceResult("95000000-eb43-390b-0000-000000000000", "Ok"); + // WHEN + String json = BacktraceSerializeHelper.toJson(example); + BacktraceResult result = BacktraceSerializeHelper.fromJson(json, BacktraceResult.class); + // THEN + assertNotNull(result); + assertEquals(example.getRxId(), result.getRxId()); + assertEquals(example.getMessage(), result.getMessage()); + } + + @Test + public void testOnErrorCreation() { + // GIVEN + Exception exception = new Exception("test-1"); + BacktraceReport report = new BacktraceReport("test-report"); + + // WHEN + BacktraceResult result = BacktraceResult.OnError(new BacktraceReport("test-report"), new Exception("test-1")); + + // THEN + assertEquals(null, result.getRxId()); + assertEquals(BacktraceResultStatus.ServerError, result.getStatus()); + assertNotNull(result.getBacktraceReport()); + assertEquals(exception.getMessage(), result.getMessage()); + assertEquals(report.message, result.getBacktraceReport().message); + } +} diff --git a/backtrace-library/src/test/java/backtraceio/library/models/BacktraceStackFrameTest.java b/backtrace-library/src/test/java/backtraceio/library/models/BacktraceStackFrameTest.java new file mode 100644 index 00000000..6639cc14 --- /dev/null +++ b/backtrace-library/src/test/java/backtraceio/library/models/BacktraceStackFrameTest.java @@ -0,0 +1,80 @@ +package backtraceio.library.models; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import org.json.JSONException; +import org.junit.Before; +import org.junit.Test; + +import backtraceio.library.TestUtils; +import backtraceio.library.common.BacktraceSerializeHelper; +import backtraceio.library.logger.BacktraceLogger; +import backtraceio.library.logger.BacktraceMockLogger; + +public class BacktraceStackFrameTest { + @Before + public void setUp() { + BacktraceLogger.setLogger(new BacktraceMockLogger()); + } + private final String JSON_FILE = "backtraceStackFrame.json"; + @Test + public void serialize() throws JSONException { + // GIVEN + BacktraceStackFrame obj = new BacktraceStackFrame("java.util.TimerThread.run", "TimerThread", 512, "85c0915f-3b99-4942-91c8-221e23846ded"); + // WHEN + String json = TestUtils.minifyJsonString(BacktraceSerializeHelper.toJson(obj)); + // THEN + String expectedJson = TestUtils.minifyJsonString(TestUtils.readFileAsString(this, JSON_FILE)); + + assertEquals(expectedJson, json); + } + + @Test + public void serializeFromStackTraceElement() throws JSONException { + // GIVEN + String sourceCodeUuid = "85c0915f-3b99-4942-91c8-221e23846ded"; + BacktraceStackFrame obj = BacktraceStackFrame.fromStackTraceElement(new StackTraceElement("java.util.TimerThread", "run", "", 512)); + // WHEN + String json = TestUtils.minifyJsonString(BacktraceSerializeHelper.toJson(obj)); + // THEN + String expectedJson = TestUtils.minifyJsonString(TestUtils.readFileAsString(this, JSON_FILE)). + replace(sourceCodeUuid, obj.sourceCode); + + assertEquals(expectedJson, json); + } + + @Test(expected = IllegalArgumentException.class) + public void createFromNullStackTraceElement() { + // GIVEN + BacktraceStackFrame.fromStackTraceElement(null); + } + + @Test + public void deserialize() throws JSONException { + // GIVEN + String json = TestUtils.minifyJsonString(TestUtils.readFileAsString(this, JSON_FILE)); + // WHEN + BacktraceStackFrame obj = BacktraceSerializeHelper.fromJson(json, BacktraceStackFrame.class); + // THEN + assertEquals(512, obj.line.intValue()); + assertEquals("85c0915f-3b99-4942-91c8-221e23846ded", obj.sourceCode); + assertEquals("java.util.TimerThread.run", obj.functionName); + assertNull(obj.sourceCodeFileName); + } + + @Test + public void serializeAndDeserialize() { + // GIVEN + BacktraceStackFrame obj = new BacktraceStackFrame("java.util.TimerThread.run", "TimerThread", 512, "85c0915f-3b99-4942-91c8-221e23846ded"); + // WHEN + String json = BacktraceSerializeHelper.toJson(obj); + BacktraceStackFrame result = BacktraceSerializeHelper.fromJson(json, BacktraceStackFrame.class); + + // THEN + assertEquals(512, result.line.intValue()); + assertEquals("85c0915f-3b99-4942-91c8-221e23846ded", result.sourceCode); + assertEquals("java.util.TimerThread.run", result.functionName); + assertNull(result.sourceCodeFileName); + } +} diff --git a/backtrace-library/src/test/java/backtraceio/library/models/json/BacktraceReportTest.java b/backtrace-library/src/test/java/backtraceio/library/models/json/BacktraceReportTest.java new file mode 100644 index 00000000..49d769f7 --- /dev/null +++ b/backtrace-library/src/test/java/backtraceio/library/models/json/BacktraceReportTest.java @@ -0,0 +1,141 @@ +package backtraceio.library.models.json; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import org.json.JSONException; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.lang.StackTraceElement; +import backtraceio.library.TestUtils; +import backtraceio.library.common.BacktraceSerializeHelper; +import backtraceio.library.models.BacktraceStackFrame; + +public class BacktraceReportTest { + private final String JSON_FILE = "backtraceReport.json"; + @Test + public void serialize() throws JSONException { + // GIVEN + final List diagnosticStack = new ArrayList<>(); + + diagnosticStack.add(new BacktraceStackFrame("backtraceio.library.SettingAttributesTest.tmpGsonTest", null, 75, "c37b9ae3-eab1-4928-9533-f1c14b6149f5")); + diagnosticStack.add(new BacktraceStackFrame("java.lang.reflect.Method.invoke", null, null, "6f280747-feee-4f4b-9eff-dda0d8eaa535")); + final Exception exception = new IllegalAccessException(); + final StackTraceElement[] stackTraceElements = new StackTraceElement[1]; + stackTraceElements[0] = new StackTraceElement("backtraceio.library.SettingAttributesTest", "tmpGsonTest", "SettingAttributesTest.java", 75); + + exception.setStackTrace(stackTraceElements); + + final Map attributes = new HashMap<>(); + attributes.put("error.type", "Exception"); + final BacktraceReport report = new BacktraceReport(UUID.fromString("a62a533a-a7b8-415c-9a99-253c51f00827"), 1709680251, true, "java.lang.IllegalAccessException", attributes, null, exception, new ArrayList() {{ add("abc.txt"); }}, diagnosticStack); + + // WHEN + String json = BacktraceSerializeHelper.toJson(report); + + // THEN + String expectedJson = TestUtils.minifyJsonString( + TestUtils.readFileAsString(this, JSON_FILE) + ); + + assertTrue(TestUtils.compareJson(json, expectedJson)); + } + + @Test + public void deserialize() { + // GIVEN + String json = TestUtils.readFileAsString(this, JSON_FILE); + + // WHEN + final BacktraceReport obj = BacktraceSerializeHelper.fromJson(json, BacktraceReport.class); + + // THEN + assertNotNull(obj); + assertEquals("a62a533a-a7b8-415c-9a99-253c51f00827", obj.uuid.toString()); + assertEquals(1709680251, obj.timestamp); + assertEquals(true, obj.exceptionTypeReport); + + assertEquals("java.lang.IllegalAccessException", obj.classifier); + assertEquals(1, obj.attributes.size()); + assertEquals("Exception", obj.attributes.get("error.type")); + assertNull(obj.message); + assertNotNull(obj.exception); + assertEquals(1, obj.exception.getStackTrace().length); + assertEquals(1, obj.attachmentPaths.size()); + assertEquals("abc.txt", obj.attachmentPaths.get(0)); + + + // THEN diagnostic stack + assertNotNull(obj.diagnosticStack); + assertEquals(2, obj.diagnosticStack.size()); + + assertEquals("backtraceio.library.SettingAttributesTest.tmpGsonTest", obj.diagnosticStack.get(0).functionName); + assertEquals(75, obj.diagnosticStack.get(0).line.intValue()); + assertEquals("c37b9ae3-eab1-4928-9533-f1c14b6149f5", obj.diagnosticStack.get(0).sourceCode); + assertNull(obj.diagnosticStack.get(0).sourceCodeFileName); + + assertEquals("java.lang.reflect.Method.invoke", obj.diagnosticStack.get(1).functionName); + assertNull(obj.diagnosticStack.get(1).line); + assertEquals("6f280747-feee-4f4b-9eff-dda0d8eaa535", obj.diagnosticStack.get(1).sourceCode); + assertNull(obj.diagnosticStack.get(1).sourceCodeFileName); + } + + @Test + public void serializeAndDeserialize() { + // GIVEN + final List diagnosticStack = new ArrayList<>(); + + diagnosticStack.add(new BacktraceStackFrame("backtraceio.library.SettingAttributesTest.tmpGsonTest", null, 75, "c37b9ae3-eab1-4928-9533-f1c14b6149f5")); + diagnosticStack.add(new BacktraceStackFrame("java.lang.reflect.Method.invoke", null, null, "6f280747-feee-4f4b-9eff-dda0d8eaa535")); + final Exception exception = new IllegalAccessException(); + final StackTraceElement[] stackTraceElements = new StackTraceElement[1]; + stackTraceElements[0] = new StackTraceElement("backtraceio.library.SettingAttributesTest", "tmpGsonTest", "SettingAttributesTest.java", 75); + + exception.setStackTrace(stackTraceElements); + + final Map attributes = new HashMap<>(); + attributes.put("error.type", "Exception"); + final BacktraceReport report = new BacktraceReport(UUID.fromString("a62a533a-a7b8-415c-9a99-253c51f00827"), 1709680251, true, "java.lang.IllegalAccessException", attributes, null, exception, new ArrayList() {{ add("abc.txt"); }}, diagnosticStack); + + // WHEN + String json = BacktraceSerializeHelper.toJson(report); + final BacktraceReport obj = BacktraceSerializeHelper.fromJson(json, BacktraceReport.class); + + // THEN + assertNotNull(obj); + assertEquals("a62a533a-a7b8-415c-9a99-253c51f00827", obj.uuid.toString()); + assertEquals(1709680251, obj.timestamp); + assertEquals(true, obj.exceptionTypeReport); + + assertEquals("java.lang.IllegalAccessException", obj.classifier); + assertEquals(1, obj.attributes.size()); + assertEquals("Exception", obj.attributes.get("error.type")); + assertNull(obj.message); + assertNotNull(obj.exception); + assertEquals(1, obj.exception.getStackTrace().length); + assertEquals(1, obj.attachmentPaths.size()); + assertEquals("abc.txt", obj.attachmentPaths.get(0)); + + + // THEN diagnostic stack + assertNotNull(obj.diagnosticStack); + assertEquals(2, obj.diagnosticStack.size()); + + assertEquals("backtraceio.library.SettingAttributesTest.tmpGsonTest", obj.diagnosticStack.get(0).functionName); + assertEquals(75, obj.diagnosticStack.get(0).line.intValue()); + assertEquals("c37b9ae3-eab1-4928-9533-f1c14b6149f5", obj.diagnosticStack.get(0).sourceCode); + assertNull(obj.diagnosticStack.get(0).sourceCodeFileName); + + assertEquals("java.lang.reflect.Method.invoke", obj.diagnosticStack.get(1).functionName); + assertNull(obj.diagnosticStack.get(1).line); + assertEquals("6f280747-feee-4f4b-9eff-dda0d8eaa535", obj.diagnosticStack.get(1).sourceCode); + assertNull(obj.diagnosticStack.get(1).sourceCodeFileName); + } +} diff --git a/backtrace-library/src/test/java/backtraceio/library/models/json/SourceCodeDataTest.java b/backtrace-library/src/test/java/backtraceio/library/models/json/SourceCodeDataTest.java new file mode 100644 index 00000000..6c695a1d --- /dev/null +++ b/backtrace-library/src/test/java/backtraceio/library/models/json/SourceCodeDataTest.java @@ -0,0 +1,74 @@ +package backtraceio.library.models.json; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import org.json.JSONException; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; + +import backtraceio.library.TestUtils; +import backtraceio.library.common.BacktraceSerializeHelper; +import backtraceio.library.models.BacktraceStackFrame; + +public class SourceCodeDataTest { + private final String JSON_FILE = "sourceCodeData.json"; + @Test + public void serialize() throws JSONException { + // GIVEN + List frames = new ArrayList() {{ + add(new BacktraceStackFrame(null, "VMStack.java", null, "8751bea6-d6f6-48f4-9f96-1355c3408a9a")); + add(new BacktraceStackFrame(null, "InvokeMethod.java", 17, "27948842-7c2b-4898-a74a-ba3ca4afe814")); + }}; + + SourceCodeData obj = new SourceCodeData(frames); + // WHEN + String json = TestUtils.minifyJsonString(BacktraceSerializeHelper.toJson(obj)); + + // THEN + String expectedJson = TestUtils.minifyJsonString( + TestUtils.readFileAsString(this, JSON_FILE) + ); + + assertEquals(expectedJson, json); + } + + @Test + public void deserialize() { + // GIVEN + String json = TestUtils.readFileAsString(this, JSON_FILE); + // WHEN + final SourceCodeData obj = BacktraceSerializeHelper.fromJson(json, SourceCodeData.class); + // THEN + assertEquals(2, obj.data.size()); + assertEquals("VMStack.java", obj.data.get("8751bea6-d6f6-48f4-9f96-1355c3408a9a").getSourceCodeFileName()); + assertNull(obj.data.get("8751bea6-d6f6-48f4-9f96-1355c3408a9a").getStartLine()); + assertEquals("InvokeMethod.java", obj.data.get("27948842-7c2b-4898-a74a-ba3ca4afe814").getSourceCodeFileName()); + assertEquals(17, obj.data.get("27948842-7c2b-4898-a74a-ba3ca4afe814").getStartLine().intValue()); + } + + @Test + public void serializeAndDeserialize() { + // GIVEN + List frames = new ArrayList() {{ + add(new BacktraceStackFrame(null, "VMStack.java", null, "8751bea6-d6f6-48f4-9f96-1355c3408a9a")); + add(new BacktraceStackFrame(null, "InvokeMethod.java", 17, "27948842-7c2b-4898-a74a-ba3ca4afe814")); + }}; + + SourceCodeData obj = new SourceCodeData(frames); + // WHEN + String json = BacktraceSerializeHelper.toJson(obj); + + SourceCodeData result = BacktraceSerializeHelper.fromJson(json, SourceCodeData.class); + + // THEN + assertEquals(2, result.data.size()); + + assertEquals("VMStack.java", result.data.get("8751bea6-d6f6-48f4-9f96-1355c3408a9a").getSourceCodeFileName()); + assertNull(result.data.get("8751bea6-d6f6-48f4-9f96-1355c3408a9a").getStartLine()); + assertEquals("InvokeMethod.java", result.data.get("27948842-7c2b-4898-a74a-ba3ca4afe814").getSourceCodeFileName()); + assertEquals(17, result.data.get("27948842-7c2b-4898-a74a-ba3ca4afe814").getStartLine().intValue()); + } +} diff --git a/backtrace-library/src/test/java/backtraceio/library/models/json/SourceCodeTest.java b/backtrace-library/src/test/java/backtraceio/library/models/json/SourceCodeTest.java new file mode 100644 index 00000000..30c3edab --- /dev/null +++ b/backtrace-library/src/test/java/backtraceio/library/models/json/SourceCodeTest.java @@ -0,0 +1,54 @@ +package backtraceio.library.models.json; + +import static org.junit.Assert.assertEquals; + +import org.json.JSONException; +import org.junit.Test; + +import backtraceio.library.TestUtils; +import backtraceio.library.common.BacktraceSerializeHelper; + +public class SourceCodeTest { + + private final String JSON_FILE = "sourceCode.json"; + @Test + public void serialize() throws JSONException { + // GIVEN + SourceCode obj = new SourceCode(17, "InvokeMethod.java"); + + // WHEN + String json = TestUtils.minifyJsonString(BacktraceSerializeHelper.toJson(obj)); + + // THEN + String expectedJson = TestUtils.minifyJsonString( + TestUtils.readFileAsString(this, JSON_FILE) + ); + + assertEquals(expectedJson, json); + } + + @Test + public void deserialize() { + // GIVEN + String json = TestUtils.readFileAsString(this, JSON_FILE); + // WHEN + SourceCode result = BacktraceSerializeHelper.fromJson(json, SourceCode.class); + // THEN + assertEquals("InvokeMethod.java", result.getSourceCodeFileName()); + assertEquals(17, result.getStartLine().intValue()); + } + + @Test + public void serializeAndDeserialize() { + // GIVEN + SourceCode obj = new SourceCode(17, "InvokeMethod.java"); + + // WHEN + String json = BacktraceSerializeHelper.toJson(obj); + + // WHEN + SourceCode result = BacktraceSerializeHelper.fromJson(json, SourceCode.class); + assertEquals(obj.getSourceCodeFileName(), result.getSourceCodeFileName()); + assertEquals(obj.getStartLine(), result.getStartLine()); + } +} diff --git a/backtrace-library/src/test/java/backtraceio/library/models/json/ThreadInformationTest.java b/backtrace-library/src/test/java/backtraceio/library/models/json/ThreadInformationTest.java new file mode 100644 index 00000000..a31a24cb --- /dev/null +++ b/backtrace-library/src/test/java/backtraceio/library/models/json/ThreadInformationTest.java @@ -0,0 +1,96 @@ +package backtraceio.library.models.json; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import org.json.JSONException; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; + +import backtraceio.library.TestUtils; +import backtraceio.library.common.BacktraceSerializeHelper; +import backtraceio.library.models.BacktraceStackFrame; + +public class ThreadInformationTest { + + @Test + public void serialize() throws JSONException { + // GIVEN + List frames = new ArrayList<>(); + frames.add(new BacktraceStackFrame("backtraceio.backtraceio.MainActivity.handledException", null, 150, "cde23509-3dcc-494d-af1f-4b4e2af4cc5e")); + frames.add(new BacktraceStackFrame("java.lang.reflect.Method.invoke", null, null, "7fc374ec-e276-46da-8d1a-05b37425927e")); + ThreadInformation obj = new ThreadInformation("main", true, frames); + + // WHEN + String json = TestUtils.minifyJsonString(BacktraceSerializeHelper.toJson(obj)); + + // THEN + String expectedJson = TestUtils.minifyJsonString( + TestUtils.readFileAsString(this, "threadInformation.json") + ); + + assertEquals(expectedJson, json); + } + + @Test + public void deserialize() { + // GIVEN + String json = TestUtils.readFileAsString(this, "threadInformation.json"); + // WHEN + ThreadInformation result = BacktraceSerializeHelper.fromJson(json, ThreadInformation.class); + // THEN + assertNotNull(result); + assertEquals("main", result.getName()); + assertTrue(result.getFault()); + assertNotNull(result.getStack()); + assertEquals(2, result.getStack().size()); + + // THEN Frame 1 + assertEquals(Integer.valueOf(150), result.getStack().get(0).line); + assertEquals("backtraceio.backtraceio.MainActivity.handledException", result.getStack().get(0).functionName); + assertEquals("cde23509-3dcc-494d-af1f-4b4e2af4cc5e", result.getStack().get(0).sourceCode); + assertNull(result.getStack().get(0).sourceCodeFileName); + + // THEN Frame 2 + assertNull(result.getStack().get(1).line); + assertEquals("java.lang.reflect.Method.invoke", result.getStack().get(1).functionName); + assertEquals("7fc374ec-e276-46da-8d1a-05b37425927e", result.getStack().get(1).sourceCode); + assertNull(result.getStack().get(1).sourceCodeFileName); + } + + @Test + public void serializeAndDeserialize() { + List frames = new ArrayList<>(); + frames.add(new BacktraceStackFrame("backtraceio.backtraceio.MainActivity.handledException", null, 150, "cde23509-3dcc-494d-af1f-4b4e2af4cc5e")); + frames.add(new BacktraceStackFrame("java.lang.reflect.Method.invoke", null, null, "7fc374ec-e276-46da-8d1a-05b37425927e")); + ThreadInformation obj = new ThreadInformation("main", true, frames); + + // WHEN + String json = BacktraceSerializeHelper.toJson(obj); + + // WHEN + ThreadInformation result = BacktraceSerializeHelper.fromJson(json, ThreadInformation.class); + // THEN + assertNotNull(result); + assertEquals("main", result.getName()); + assertTrue(result.getFault()); + assertNotNull(result.getStack()); + assertEquals(2, result.getStack().size()); + + // THEN Frame 1 + assertEquals(Integer.valueOf(150), result.getStack().get(0).line); + assertEquals("backtraceio.backtraceio.MainActivity.handledException", result.getStack().get(0).functionName); + assertEquals("cde23509-3dcc-494d-af1f-4b4e2af4cc5e", result.getStack().get(0).sourceCode); + assertNull(result.getStack().get(0).sourceCodeFileName); + + // THEN Frame 2 + assertNull(result.getStack().get(1).line); + assertEquals("java.lang.reflect.Method.invoke", result.getStack().get(1).functionName); + assertEquals("7fc374ec-e276-46da-8d1a-05b37425927e", result.getStack().get(1).sourceCode); + assertNull(result.getStack().get(1).sourceCodeFileName); + } +} diff --git a/backtrace-library/src/test/java/backtraceio/library/models/types/BacktraceResultStatusTest.java b/backtrace-library/src/test/java/backtraceio/library/models/types/BacktraceResultStatusTest.java new file mode 100644 index 00000000..850523c2 --- /dev/null +++ b/backtrace-library/src/test/java/backtraceio/library/models/types/BacktraceResultStatusTest.java @@ -0,0 +1,53 @@ +package backtraceio.library.models.types; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.junit.experimental.runners.Enclosed; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import java.util.Arrays; +import java.util.Collection; + +@RunWith(Enclosed.class) +public class BacktraceResultStatusTest { + @RunWith(Parameterized.class) + public static class BacktraceResultStatusParametrizedTests { + private final String apiStatus; + private final BacktraceResultStatus expectedApiStatusEnum; + + public BacktraceResultStatusParametrizedTests(String apiStatus, BacktraceResultStatus expectedApiStatusEnum) { + this.apiStatus = apiStatus; + this.expectedApiStatusEnum = expectedApiStatusEnum; + } + + @Parameterized.Parameters + public static Collection apiStringStatus() { + return Arrays.asList(new Object[][]{ + {"ok", BacktraceResultStatus.Ok}, + {"Ok", BacktraceResultStatus.Ok}, + {"OK", BacktraceResultStatus.Ok}, + {"oK", BacktraceResultStatus.Ok}, + {"servererror", BacktraceResultStatus.ServerError}, + {"serverError", BacktraceResultStatus.ServerError}, + {"ServerError", BacktraceResultStatus.ServerError}, + {"SERVERERROR", BacktraceResultStatus.ServerError} + }); + } + + @Test + public void testMappingStatusStringToEnum() { + assertEquals(this.expectedApiStatusEnum, + BacktraceResultStatus.enumOf(this.apiStatus)); + } + + } + public static class BacktraceResultStatusSingleTests { + + @Test(expected = IllegalArgumentException.class) + public void testWrongStatusValue() { + BacktraceResultStatus.enumOf("unsupported-value"); + } + } +} diff --git a/backtrace-library/src/test/resources/backtraceApiResult.error.json b/backtrace-library/src/test/resources/backtraceApiResult.error.json new file mode 100644 index 00000000..9928ff97 --- /dev/null +++ b/backtrace-library/src/test/resources/backtraceApiResult.error.json @@ -0,0 +1 @@ +{"error":{"code":32768, "message":"no root object supplied"}} \ No newline at end of file diff --git a/backtrace-library/src/test/resources/backtraceApiResult.json b/backtrace-library/src/test/resources/backtraceApiResult.json new file mode 100644 index 00000000..9ef4b2d6 --- /dev/null +++ b/backtrace-library/src/test/resources/backtraceApiResult.json @@ -0,0 +1 @@ +{"_rxid":"95000000-eb43-390b-0000-000000000000","response":"ok"} \ No newline at end of file diff --git a/backtrace-library/src/test/resources/backtraceData.json b/backtrace-library/src/test/resources/backtraceData.json new file mode 100644 index 00000000..09e18113 --- /dev/null +++ b/backtrace-library/src/test/resources/backtraceData.json @@ -0,0 +1,51 @@ +{ + "agent": "backtrace-android", + "agentVersion": "3.8.3", + "annotations": { + "Environment Variables": { + "SYSTEMSERVERCLASSPATH": "/system/framework/com.android.location.provider.jar:/system/framework/services.jar:/system/framework/ethernet-service.jar:/apex/com.android.permission/javalib/service-permission.jar:/apex/com.android.wifi/javalib/service-wifi.jar:/apex/com.android.ipsec/javalib/android.net.ipsec.ike.jar" + }, + "Exception": { + "message": "Example test string" + } + }, + "attributes": { + "application.session": "4b965773-539e-4dd3-be1b-f8ab017c2c9f" + }, + "lang": "java", + "langVersion": "0", + "mainThread": "instr: androidx.test.runner.androidjunitrunner", + "sourceCode": { + "8751bea6-d6f6-48f4-9f96-1355c3408a9a": { + "path": "VMStack.java" + }, + "27948842-7c2b-4898-a74a-ba3ca4afe814": { + "path": "InvokeMethod.java", + "startLine": 17 + } + }, + "threads": { + "profile saver": { + "fault": false, + "name": "profile saver", + "stack": [] + }, + "main": { + "fault": false, + "name": "main", + "stack": [ + { + "funcName": "android.os.MessageQueue.nativePollOnce", + "sourceCode": "b1a3d84a-fcf3-4d10-90d5-994f1e397607" + }, + { + "funcName": "android.os.MessageQueue.next", + "line": 335, + "sourceCode": "868c2d50-b00a-42a5-9aa0-e82cdea07bcd" + } + ] + } + }, + "timestamp": 1720419610, + "uuid": "ecdf418b-3e22-4c7c-8011-c85dc2b4386f" +} \ No newline at end of file diff --git a/backtrace-library/src/test/resources/backtraceDatabaseRecord.json b/backtrace-library/src/test/resources/backtraceDatabaseRecord.json new file mode 100644 index 00000000..afdccdeb --- /dev/null +++ b/backtrace-library/src/test/resources/backtraceDatabaseRecord.json @@ -0,0 +1 @@ +{"Id":"ecdf418b-3e22-4c7c-8011-c85dc2b4386f","RecordName":"/data/user/0/backtraceio.library.test/files/ecdf418b-3e22-4c7c-8011-c85dc2b4386f-record.json","DataPath":"/data/user/0/backtraceio.library.test/files/ecdf418b-3e22-4c7c-8011-c85dc2b4386f-attachment.json","ReportPath":"/data/user/0/backtraceio.library.test/files/ecdf418b-3e22-4c7c-8011-c85dc2b4386f-report.json","Size":25362} \ No newline at end of file diff --git a/backtrace-library/src/test/resources/backtraceReport-tmp.json b/backtrace-library/src/test/resources/backtraceReport-tmp.json new file mode 100644 index 00000000..0213f828 --- /dev/null +++ b/backtrace-library/src/test/resources/backtraceReport-tmp.json @@ -0,0 +1,238 @@ +{ + "attachment-paths": [ + "abc.txt" + ], + "attributes": { + "error.type": "Exception" + }, + "classifier": "java.lang.IllegalAccessException", + "diagnostic-stack": [ + { + "funcName": "backtraceio.library.SettingAttributesTest.tmpGsonTest", + "line": 75, + "sourceCode": "c37b9ae3-eab1-4928-9533-f1c14b6149f5" + }, + { + "funcName": "java.lang.reflect.Method.invoke", + "sourceCode": "6f280747-feee-4f4b-9eff-dda0d8eaa535" + } + ], + "exception": { + "stack-trace": [ + { + "declaring-class": "backtraceio.library.SettingAttributesTest", + "file-name": "SettingAttributesTest.java", + "line-number": 75, + "method-name": "tmpGsonTest" + }, + { + "declaring-class": "java.lang.reflect.Method", + "file-name": "Method.java", + "line-number": -2, + "method-name": "invoke" + }, + { + "declaring-class": "org.junit.runners.model.FrameworkMethod$1", + "file-name": "FrameworkMethod.java", + "line-number": 59, + "method-name": "runReflectiveCall" + }, + { + "declaring-class": "org.junit.internal.runners.model.ReflectiveCallable", + "file-name": "ReflectiveCallable.java", + "line-number": 12, + "method-name": "run" + }, + { + "declaring-class": "org.junit.runners.model.FrameworkMethod", + "file-name": "FrameworkMethod.java", + "line-number": 56, + "method-name": "invokeExplosively" + }, + { + "declaring-class": "org.junit.internal.runners.statements.InvokeMethod", + "file-name": "InvokeMethod.java", + "line-number": 17, + "method-name": "evaluate" + }, + { + "declaring-class": "androidx.test.internal.runner.junit4.statement.RunBefores", + "file-name": "RunBefores.java", + "line-number": 80, + "method-name": "evaluate" + }, + { + "declaring-class": "org.junit.runners.ParentRunner$3", + "file-name": "ParentRunner.java", + "line-number": 306, + "method-name": "evaluate" + }, + { + "declaring-class": "org.junit.runners.BlockJUnit4ClassRunner$1", + "file-name": "BlockJUnit4ClassRunner.java", + "line-number": 100, + "method-name": "evaluate" + }, + { + "declaring-class": "org.junit.runners.ParentRunner", + "file-name": "ParentRunner.java", + "line-number": 366, + "method-name": "runLeaf" + }, + { + "declaring-class": "org.junit.runners.BlockJUnit4ClassRunner", + "file-name": "BlockJUnit4ClassRunner.java", + "line-number": 103, + "method-name": "runChild" + }, + { + "declaring-class": "org.junit.runners.BlockJUnit4ClassRunner", + "file-name": "BlockJUnit4ClassRunner.java", + "line-number": 63, + "method-name": "runChild" + }, + { + "declaring-class": "org.junit.runners.ParentRunner$4", + "file-name": "ParentRunner.java", + "line-number": 331, + "method-name": "run" + }, + { + "declaring-class": "org.junit.runners.ParentRunner$1", + "file-name": "ParentRunner.java", + "line-number": 79, + "method-name": "schedule" + }, + { + "declaring-class": "org.junit.runners.ParentRunner", + "file-name": "ParentRunner.java", + "line-number": 329, + "method-name": "runChildren" + }, + { + "declaring-class": "org.junit.runners.ParentRunner", + "file-name": "ParentRunner.java", + "line-number": 66, + "method-name": "access$100" + }, + { + "declaring-class": "org.junit.runners.ParentRunner$2", + "file-name": "ParentRunner.java", + "line-number": 293, + "method-name": "evaluate" + }, + { + "declaring-class": "org.junit.runners.ParentRunner$3", + "file-name": "ParentRunner.java", + "line-number": 306, + "method-name": "evaluate" + }, + { + "declaring-class": "org.junit.runners.ParentRunner", + "file-name": "ParentRunner.java", + "line-number": 413, + "method-name": "run" + }, + { + "declaring-class": "androidx.test.ext.junit.runners.AndroidJUnit4", + "file-name": "AndroidJUnit4.java", + "line-number": 162, + "method-name": "run" + }, + { + "declaring-class": "org.junit.runners.Suite", + "file-name": "Suite.java", + "line-number": 128, + "method-name": "runChild" + }, + { + "declaring-class": "org.junit.runners.Suite", + "file-name": "Suite.java", + "line-number": 27, + "method-name": "runChild" + }, + { + "declaring-class": "org.junit.runners.ParentRunner$4", + "file-name": "ParentRunner.java", + "line-number": 331, + "method-name": "run" + }, + { + "declaring-class": "org.junit.runners.ParentRunner$1", + "file-name": "ParentRunner.java", + "line-number": 79, + "method-name": "schedule" + }, + { + "declaring-class": "org.junit.runners.ParentRunner", + "file-name": "ParentRunner.java", + "line-number": 329, + "method-name": "runChildren" + }, + { + "declaring-class": "org.junit.runners.ParentRunner", + "file-name": "ParentRunner.java", + "line-number": 66, + "method-name": "access$100" + }, + { + "declaring-class": "org.junit.runners.ParentRunner$2", + "file-name": "ParentRunner.java", + "line-number": 293, + "method-name": "evaluate" + }, + { + "declaring-class": "org.junit.runners.ParentRunner$3", + "file-name": "ParentRunner.java", + "line-number": 306, + "method-name": "evaluate" + }, + { + "declaring-class": "org.junit.runners.ParentRunner", + "file-name": "ParentRunner.java", + "line-number": 413, + "method-name": "run" + }, + { + "declaring-class": "org.junit.runner.JUnitCore", + "file-name": "JUnitCore.java", + "line-number": 137, + "method-name": "run" + }, + { + "declaring-class": "org.junit.runner.JUnitCore", + "file-name": "JUnitCore.java", + "line-number": 115, + "method-name": "run" + }, + { + "declaring-class": "androidx.test.internal.runner.TestExecutor", + "file-name": "TestExecutor.java", + "line-number": 67, + "method-name": "execute" + }, + { + "declaring-class": "androidx.test.internal.runner.TestExecutor", + "file-name": "TestExecutor.java", + "line-number": 58, + "method-name": "execute" + }, + { + "declaring-class": "androidx.test.runner.AndroidJUnitRunner", + "file-name": "AndroidJUnitRunner.java", + "line-number": 446, + "method-name": "onStart" + }, + { + "declaring-class": "android.app.Instrumentation$InstrumentationThread", + "file-name": "Instrumentation.java", + "line-number": 2205, + "method-name": "run" + } + ], + "suppressed-exceptions": [] + }, + "exception-type-report": true, + "timestamp": 1709680251, + "uuid": "a62a533a-a7b8-415c-9a99-253c51f00827" +} \ No newline at end of file diff --git a/backtrace-library/src/test/resources/backtraceReport.json b/backtrace-library/src/test/resources/backtraceReport.json new file mode 100644 index 00000000..6a96fcff --- /dev/null +++ b/backtrace-library/src/test/resources/backtraceReport.json @@ -0,0 +1,35 @@ +{ + "attachment-paths": [ + "abc.txt" + ], + "attributes": { + "error.type": "Exception" + }, + "classifier": "java.lang.IllegalAccessException", + "diagnostic-stack": [ + { + "funcName": "backtraceio.library.SettingAttributesTest.tmpGsonTest", + "line": 75, + "sourceCode": "c37b9ae3-eab1-4928-9533-f1c14b6149f5" + }, + { + "funcName": "java.lang.reflect.Method.invoke", + "sourceCode": "6f280747-feee-4f4b-9eff-dda0d8eaa535" + } + ], + "exception": { + "stack-trace": [ + { + "declaring-class": "backtraceio.library.SettingAttributesTest", + "file-name": "SettingAttributesTest.java", + "line-number": 75, + "method-name": "tmpGsonTest", + "format": 0 + } + ], + "suppressed-exceptions": [] + }, + "exception-type-report": true, + "timestamp": 1709680251, + "uuid": "a62a533a-a7b8-415c-9a99-253c51f00827" +} \ No newline at end of file diff --git a/backtrace-library/src/test/resources/backtraceResult.json b/backtrace-library/src/test/resources/backtraceResult.json new file mode 100644 index 00000000..041811cc --- /dev/null +++ b/backtrace-library/src/test/resources/backtraceResult.json @@ -0,0 +1 @@ +{"_rxid":"95000000-eb43-390b-0000-000000000000","status":"Ok"} \ No newline at end of file diff --git a/backtrace-library/src/test/resources/backtraceStackFrame.json b/backtrace-library/src/test/resources/backtraceStackFrame.json new file mode 100644 index 00000000..1031ca57 --- /dev/null +++ b/backtrace-library/src/test/resources/backtraceStackFrame.json @@ -0,0 +1,5 @@ +{ + "funcName": "java.util.TimerThread.run", + "line": 512, + "sourceCode": "85c0915f-3b99-4942-91c8-221e23846ded" +} \ No newline at end of file diff --git a/backtrace-library/src/test/resources/sourceCode.json b/backtrace-library/src/test/resources/sourceCode.json new file mode 100644 index 00000000..a543e644 --- /dev/null +++ b/backtrace-library/src/test/resources/sourceCode.json @@ -0,0 +1,4 @@ +{ + "startLine": 17, + "path": "InvokeMethod.java" +} \ No newline at end of file diff --git a/backtrace-library/src/test/resources/sourceCodeData.json b/backtrace-library/src/test/resources/sourceCodeData.json new file mode 100644 index 00000000..5b1f3d75 --- /dev/null +++ b/backtrace-library/src/test/resources/sourceCodeData.json @@ -0,0 +1,11 @@ +{ + "data": { + "8751bea6-d6f6-48f4-9f96-1355c3408a9a": { + "path": "VMStack.java" + }, + "27948842-7c2b-4898-a74a-ba3ca4afe814": { + "startLine": 17, + "path": "InvokeMethod.java" + } + } +} \ No newline at end of file diff --git a/backtrace-library/src/test/resources/threadInformation.json b/backtrace-library/src/test/resources/threadInformation.json new file mode 100644 index 00000000..ac02fb0a --- /dev/null +++ b/backtrace-library/src/test/resources/threadInformation.json @@ -0,0 +1,15 @@ +{ + "name": "main", + "fault": true, + "stack": [ + { + "funcName": "backtraceio.backtraceio.MainActivity.handledException", + "line": 150, + "sourceCode": "cde23509-3dcc-494d-af1f-4b4e2af4cc5e" + }, + { + "funcName": "java.lang.reflect.Method.invoke", + "sourceCode": "7fc374ec-e276-46da-8d1a-05b37425927e" + } + ] +} \ No newline at end of file diff --git a/example-app/src/main/java/backtraceio/backtraceio/MainActivity.java b/example-app/src/main/java/backtraceio/backtraceio/MainActivity.java index f0c3f1cb..75fc7c02 100644 --- a/example-app/src/main/java/backtraceio/backtraceio/MainActivity.java +++ b/example-app/src/main/java/backtraceio/backtraceio/MainActivity.java @@ -51,7 +51,7 @@ public void setOnServerResponseEventListener(OnServerResponseEventListener e) { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); - + backtraceClient = initializeBacktrace(BuildConfig.BACKTRACE_SUBMISSION_URL); symlinkAndWriteFile(); @@ -75,7 +75,6 @@ private void symlinkAndWriteFile() { private BacktraceClient initializeBacktrace(final String submissionUrl) { BacktraceCredentials credentials = new BacktraceCredentials(submissionUrl); - Context context = getApplicationContext(); String dbPath = context.getFilesDir().getAbsolutePath();