From 809a69b537f1606bb7f9e5190b1ae01a300c248b Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Thu, 10 Aug 2023 22:18:56 +0200 Subject: [PATCH 001/100] Org.json serializer --- .../common/BacktraceDataSerializerTest.java | 48 +++++ .../serializers/BacktraceDataSerializer.java | 203 ++++++++++++++++++ .../library/models/BacktraceData.java | 4 + .../library/models/json/Annotations.java | 10 +- .../models/json/ThreadInformation.java | 12 ++ 5 files changed, 273 insertions(+), 4 deletions(-) create mode 100644 backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java create mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java new file mode 100644 index 00000000..de69f0e9 --- /dev/null +++ b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java @@ -0,0 +1,48 @@ +package backtraceio.library.common; + +import static org.junit.Assert.assertEquals; + +import android.content.Context; + +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; + +import org.json.JSONException; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import backtraceio.library.common.serializers.BacktraceDataSerializer; +import backtraceio.library.models.BacktraceData; +import backtraceio.library.models.json.BacktraceReport; + +@RunWith(AndroidJUnit4.class) +public class BacktraceDataSerializerTest { + + @Test + public void testGsonSerializer() throws JSONException, IllegalAccessException { // TODO: fix name + // GIVEN + final Context context = InstrumentationRegistry.getInstrumentation().getContext(); + final Exception exception = new Exception("test-error"); + final Map attributes = new HashMap(); + attributes.put("string-key", "string-value"); + attributes.put("string-key2", exception); + + final List attachments = new ArrayList<>(); + attachments.add("test-path"); + attachments.add("test-path2"); + final BacktraceReport report = new BacktraceReport(exception, attributes, attachments); + final BacktraceData data = new BacktraceData(context, report, null); + + // WHEN + final String jsonFromGson = BacktraceSerializeHelper.toJson(data); + final String jsonFromOrgJson = BacktraceDataSerializer.toJson(data); + + // THEN + assertEquals(jsonFromOrgJson, jsonFromGson); + } +} diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java new file mode 100644 index 00000000..9760a9e3 --- /dev/null +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java @@ -0,0 +1,203 @@ +package backtraceio.library.common.serializers; + +import androidx.annotation.NonNull; + +import com.google.gson.JsonArray; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.lang.reflect.Field; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import backtraceio.library.models.BacktraceData; +import backtraceio.library.models.BacktraceStackFrame; +import backtraceio.library.models.json.SourceCode; +import backtraceio.library.models.json.ThreadInformation; + +public class BacktraceDataSerializer { + + public static Object serialize(Object obj) throws IllegalAccessException, JSONException { + if (obj == null) { + return new JSONObject(); + } + + // TODO: check if all of the types + if (obj instanceof String || obj instanceof Boolean || obj instanceof Number) { + return obj; + } + + if (obj instanceof Collection) { + return serializeCollection((Collection) obj); + } + + if (obj instanceof Map) { + return serializeMap((Map) obj); + } + + JSONObject jsonObject = new JSONObject(); + Class clazz = obj.getClass(); + List fields = getAllFields(clazz, obj); + + for (Field field : fields) { + String fieldName = field.getName(); + Object fieldValue = field.get(obj); + jsonObject.put(fieldName, fieldValue); + } + + return jsonObject; + } + + private static List getAllFields(Class klass, Object obj) throws IllegalAccessException { + // TODO: improve naming + Map fields = new HashMap<>(); +// List fields = new ArrayList<>(); + for (Class k = klass; k != null; k = k.getSuperclass()) { + for (Field f: k.getDeclaredFields()){ + try { + fields.put(f.getName(), serialize(f.get(obj))); + } + catch (Exception e) { + System.out.println(e); + } + } +// fields.addAll(Arrays.asList(k.getDeclaredFields())); + } + return null; + } + + private static JSONArray serializeCollection(Collection collection) throws IllegalAccessException, JSONException { + JSONArray jsonArray = new JSONArray(); + for (Object item : collection) { + jsonArray.put(serialize(item)); + } + return jsonArray; + } + + private static JSONObject serializeMap(Map map) throws IllegalAccessException, JSONException { + JSONObject jsonObject = new JSONObject(); + for (Map.Entry entry : map.entrySet()) { + String key = String.valueOf(entry.getKey()); + Object value = entry.getValue(); + jsonObject.put(key, serialize(value)); + } + return jsonObject; + } + + public static String toJson(BacktraceData data) throws JSONException, IllegalAccessException { + { + JSONObject json = new JSONObject(); + + // Serialize simple fields + json.put("lang", data.lang); + json.put("agent", data.agent); + json.put("symbolication", data.symbolication); + json.put("uuid", data.uuid); + json.put("timestamp", data.timestamp); + json.put("langVersion", data.langVersion); + json.put("agentVersion", data.agentVersion); + json.put("mainThread", data.mainThread); + + if (data.classifiers != null) { + final JsonArray classifiers = new JsonArray(); + + for (String classifier : data.classifiers) { + classifiers.add(classifier); + } + json.put("classifiers", classifiers); + } + + + if (data.attributes != null) { + json.put("attributes", serializeAttributes(data.attributes)); + } + + if(data.annotations != null) { + json.put("annotations", serializeAnnotations(data.annotations)); + } + + if (data.sourceCode != null) { + json.put("sourceCode", serializeSourceCode(data.sourceCode)); + } + + // Serialize threadInformationMap + if (data.getThreadInformationMap() != null) { + JSONObject threadInformationJson = serializeThreadInformation(data.getThreadInformationMap()); + json.put("threads", threadInformationJson); + } + + return json.toString(); + } + } + + @NonNull + private static JSONObject serializeThreadInformation(Map threadInformationMap) throws JSONException { + JSONObject threadInformationJson = new JSONObject(); + for (Map.Entry entry : threadInformationMap.entrySet()) { + ThreadInformation threadInfo = entry.getValue(); + JSONObject threadInfoObj = new JSONObject(); + threadInfoObj.put("name", threadInfo.getName()); + threadInfoObj.put("fault", threadInfo.getFault()); + if(threadInfo.getStack() != null) { + JSONArray stackArray = serializeStackList(threadInfo.getStack()); + threadInfoObj.put("stack", stackArray); + } + threadInformationJson.put(entry.getKey(), threadInfoObj); + } + return threadInformationJson; + } + + @NonNull + private static JSONArray serializeStackList(ArrayList stack) throws JSONException { + JSONArray stackArray = new JSONArray(); + + for (BacktraceStackFrame stackFrame : stack) { + JSONObject stackFrameObj = new JSONObject(); + stackFrameObj.put("funcName", stackFrame.functionName); + stackFrameObj.put("line", stackFrame.line); + stackFrameObj.put("sourceCode", stackFrame.sourceCode); + stackArray.put(stackFrameObj); + } + + return stackArray; + } + + @NonNull + private static JSONObject serializeSourceCode(Map sourceCodeMap) throws JSONException { + JSONObject sourceCodeJson = new JSONObject(); + for (Map.Entry entry : sourceCodeMap.entrySet()) { + SourceCode sourceCode = entry.getValue(); + JSONObject sourceCodeObj = new JSONObject(); + sourceCodeObj.put("startLine", sourceCode.startLine); + sourceCodeObj.put("path", sourceCode.sourceCodeFileName); + sourceCodeJson.put(entry.getKey(), sourceCodeObj); + } + return sourceCodeJson; + } + + private static JSONObject serializeAnnotations(Map annotations) throws JSONException, IllegalAccessException { + JSONObject annotationsJson = new JSONObject(); + for (Map.Entry entry : annotations.entrySet()) { + annotationsJson.put(entry.getKey(), serialize(entry.getValue())); + } + return annotationsJson; + } + + private static JSONObject serializeAttributes(Map attributes) throws JSONException { + JSONObject attributesJson = new JSONObject(); + + for (Map.Entry entry : attributes.entrySet()) { + attributesJson.put(entry.getKey(), entry.getValue()); + } + + return attributesJson; + } +} 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 7b74ab67..49f1dcbb 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java @@ -140,6 +140,10 @@ public List getAttachments() { return FileHelper.filterOutFiles(this.context, report.attachmentPaths); } + public Map getThreadInformationMap() { + return threadInformationMap; + } + /*** * Set annotations object * @param complexAttributes 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 stack, Boolean currentThread) { this(thread.getName().toLowerCase(), currentThread, stack); } + + public String getName() { + return name; + } + + public Boolean getFault() { + return fault; + } + + public ArrayList getStack() { + return stack; + } } From 50b5a7b9267f3202082337eb9940149c285dbbd4 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Mon, 21 Aug 2023 22:26:04 +0200 Subject: [PATCH 002/100] Performance tests --- .../common/BacktraceDataSerializerTest.java | 50 ++++++++++++++ .../serializers/BacktraceDataSerializer.java | 65 ++++++++++++++++--- 2 files changed, 106 insertions(+), 9 deletions(-) diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java index de69f0e9..1434c7dc 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java @@ -8,6 +8,7 @@ import androidx.test.platform.app.InstrumentationRegistry; import org.json.JSONException; +import org.json.JSONObject; import org.junit.Test; import org.junit.runner.RunWith; @@ -29,6 +30,7 @@ public void testGsonSerializer() throws JSONException, IllegalAccessException { final Context context = InstrumentationRegistry.getInstrumentation().getContext(); final Exception exception = new Exception("test-error"); final Map attributes = new HashMap(); + attributes.put("string-key", "string-value"); attributes.put("string-key2", exception); @@ -45,4 +47,52 @@ public void testGsonSerializer() throws JSONException, IllegalAccessException { // THEN assertEquals(jsonFromOrgJson, jsonFromGson); } + + + @Test + public void testGsonPerformanceSerializer() throws JSONException, IllegalAccessException { // TODO: fix name + // GIVEN + final Context context = InstrumentationRegistry.getInstrumentation().getContext(); + long timeGson = 0; + long timeOrgJson = 0; + final int iterations = 5000; + for (int i = 0; i < iterations; i++) { + // INIT SAMPLE + final Exception exception = new Exception(Integer.toString(i)); + + final Map attributes = new HashMap(); + + attributes.put("string-key", Integer.toString(i)); + attributes.put("string-key2", exception.getMessage()); + + final List attachments = new ArrayList<>(); + attachments.add(Integer.toString(i)); + attachments.add(Integer.toString(i * 10)); + final BacktraceReport report = new BacktraceReport(exception, attributes, attachments); + final BacktraceData data = new BacktraceData(context, report, null); + + // GSON + long startTime = System.currentTimeMillis(); + BacktraceSerializeHelper.toJson(data); + long endTime = System.currentTimeMillis(); + timeGson += endTime - startTime; + + + // ORG JSON + long startTimeOrg = System.currentTimeMillis(); + BacktraceDataSerializer.toJson(data); + long endTimeOrg = System.currentTimeMillis(); + timeOrgJson += endTimeOrg - startTimeOrg; + } + + System.out.println("[GSON] Total execution time: " + timeGson + " milliseconds"); + System.out.println("[Org.json] total execution time: " + timeOrgJson + " milliseconds"); + + double averageExecutionTimeGson = (double) timeGson / iterations; + double averageExecutionTimeOrgJson = (double) timeOrgJson / iterations; + + System.out.println("[GSON] Average execution time: " + averageExecutionTimeGson + " milliseconds"); + System.out.println("[Org.json] Average execution time: " + averageExecutionTimeOrgJson + " milliseconds"); + + } } diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java index 9760a9e3..78072019 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java @@ -1,5 +1,7 @@ package backtraceio.library.common.serializers; +import android.os.Build; + import androidx.annotation.NonNull; import com.google.gson.JsonArray; @@ -9,6 +11,7 @@ import org.json.JSONObject; import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.math.BigDecimal; import java.math.BigInteger; import java.util.ArrayList; @@ -45,24 +48,34 @@ public static Object serialize(Object obj) throws IllegalAccessException, JSONEx JSONObject jsonObject = new JSONObject(); Class clazz = obj.getClass(); - List fields = getAllFields(clazz, obj); - - for (Field field : fields) { - String fieldName = field.getName(); - Object fieldValue = field.get(obj); - jsonObject.put(fieldName, fieldValue); - } +// List fields = getAllFields(clazz, obj); + Map getters = executeAndGetMethods(obj); +// Map fields = getAllFields(obj.getClass(), obj); +// for (Field field : fields) { +// String fieldName = field.getName(); +// Object fieldValue = field.get(obj); +// jsonObject.put(fieldName, fieldValue); +// } return jsonObject; } - private static List getAllFields(Class klass, Object obj) throws IllegalAccessException { + public static String decapitalizeString(String string) { + return string == null || string.isEmpty() ? "" : Character.toLowerCase(string.charAt(0)) + string.substring(1); + } + + private static Map getAllFields(Class klass, Object obj) throws IllegalAccessException { // TODO: improve naming Map fields = new HashMap<>(); // List fields = new ArrayList<>(); for (Class k = klass; k != null; k = k.getSuperclass()) { for (Field f: k.getDeclaredFields()){ try { + f.setAccessible(true); + Object val = f.get(obj); + if(val == null) { + continue; + } fields.put(f.getName(), serialize(f.get(obj))); } catch (Exception e) { @@ -71,9 +84,43 @@ private static List getAllFields(Class klass, Object obj) throws Illeg } // fields.addAll(Arrays.asList(k.getDeclaredFields())); } - return null; + + for (Field f: klass.getDeclaredFields()) { + try { + fields.put(f.getName(), serialize(f.get(obj))); + } catch (JSONException e) { + throw new RuntimeException(e); + } + } + + return fields; } + public static Map executeAndGetMethods(Object obj) { + Class clazz = obj.getClass(); + Map fields = new HashMap<>(); + Method[] methods = clazz.getMethods(); + + for (Method method : methods) { + String methodName = method.getName(); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // TODO: check if needed + if (methodName.startsWith("get") && method.getParameterCount() == 0) { + try { + Object result = method.invoke(obj); + String propertyName = methodName.substring(3); // Remove 'get' prefix + System.out.println(propertyName + ": " + result); + fields.put(decapitalizeString(propertyName), result); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + return fields; + } + + private static JSONArray serializeCollection(Collection collection) throws IllegalAccessException, JSONException { JSONArray jsonArray = new JSONArray(); for (Object item : collection) { From 24680bb97bf28435432c3ef94cdcbef33fc628fa Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Sat, 26 Aug 2023 14:47:41 +0200 Subject: [PATCH 003/100] Tmp serialization --- .../common/BacktraceDataSerializerTest.java | 3 +- .../serializers/BacktraceDataSerializer.java | 180 ++++++++++-------- .../common/serializers/SerializerHelper.java | 111 +++++++++++ 3 files changed, 211 insertions(+), 83 deletions(-) create mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java index 1434c7dc..ee215823 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java @@ -55,7 +55,7 @@ public void testGsonPerformanceSerializer() throws JSONException, IllegalAccessE final Context context = InstrumentationRegistry.getInstrumentation().getContext(); long timeGson = 0; long timeOrgJson = 0; - final int iterations = 5000; + final int iterations = 1; for (int i = 0; i < iterations; i++) { // INIT SAMPLE final Exception exception = new Exception(Integer.toString(i)); @@ -93,6 +93,5 @@ public void testGsonPerformanceSerializer() throws JSONException, IllegalAccessE System.out.println("[GSON] Average execution time: " + averageExecutionTimeGson + " milliseconds"); System.out.println("[Org.json] Average execution time: " + averageExecutionTimeOrgJson + " milliseconds"); - } } diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java index 78072019..ef24adf3 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java @@ -1,5 +1,8 @@ package backtraceio.library.common.serializers; +import static backtraceio.library.common.serializers.SerializerHelper.decapitalizeString; +import static backtraceio.library.common.serializers.SerializerHelper.serialize; + import android.os.Build; import androidx.annotation.NonNull; @@ -28,73 +31,88 @@ public class BacktraceDataSerializer { - public static Object serialize(Object obj) throws IllegalAccessException, JSONException { - if (obj == null) { - return new JSONObject(); - } - - // TODO: check if all of the types - if (obj instanceof String || obj instanceof Boolean || obj instanceof Number) { - return obj; - } - - if (obj instanceof Collection) { - return serializeCollection((Collection) obj); - } - - if (obj instanceof Map) { - return serializeMap((Map) obj); - } - JSONObject jsonObject = new JSONObject(); - Class clazz = obj.getClass(); +// public static Object serialize(Object obj) throws IllegalAccessException, JSONException { +// if (obj == null) { +// return new JSONObject(); +// } +// +// // TODO: check if all of the types +// if (SerializerHelper.isPrimitiveType(obj)) { +// return obj; +// } +// +// if (obj instanceof Collection) { +// return serializeCollection((Collection) obj); +// } +// +// if (obj instanceof Map) { +// return serializeMap((Map) obj); +// } +// +// JSONObject jsonObject = new JSONObject(); +// Class clazz = obj.getClass(); // List fields = getAllFields(clazz, obj); - Map getters = executeAndGetMethods(obj); -// Map fields = getAllFields(obj.getClass(), obj); -// for (Field field : fields) { -// String fieldName = field.getName(); -// Object fieldValue = field.get(obj); -// jsonObject.put(fieldName, fieldValue); +//// Map getters = executeAndGetMethods(obj); +//// Map fields = getAllFields(obj.getClass(), obj); +//// for (Field field : fields) { +//// String fieldName = field.getName(); +//// Object fieldValue = field.get(obj); +//// jsonObject.put(fieldName, fieldValue); +//// } +// +// return jsonObject; +// } + +// public static String decapitalizeString(String string) { +// return string == null || string.isEmpty() ? "" : Character.toLowerCase(string.charAt(0)) + string.substring(1); +// } + +// private static List getAllFields(Class klass, Object obj) throws IllegalAccessException { +// // TODO: improve naming +// +// List fields = new ArrayList(); +// for (Class c = klass; c != null; c = c.getSuperclass()) { +// fields.addAll(Arrays.asList(c.getDeclaredFields())); // } - - return jsonObject; - } - - public static String decapitalizeString(String string) { - return string == null || string.isEmpty() ? "" : Character.toLowerCase(string.charAt(0)) + string.substring(1); - } - - private static Map getAllFields(Class klass, Object obj) throws IllegalAccessException { - // TODO: improve naming - Map fields = new HashMap<>(); -// List fields = new ArrayList<>(); - for (Class k = klass; k != null; k = k.getSuperclass()) { - for (Field f: k.getDeclaredFields()){ - try { - f.setAccessible(true); - Object val = f.get(obj); - if(val == null) { - continue; - } - fields.put(f.getName(), serialize(f.get(obj))); - } - catch (Exception e) { - System.out.println(e); - } - } -// fields.addAll(Arrays.asList(k.getDeclaredFields())); - } - - for (Field f: klass.getDeclaredFields()) { - try { - fields.put(f.getName(), serialize(f.get(obj))); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - return fields; - } +// +// for (Field f: fields) { +// f.setAccessible(true); +// if (!java.lang.reflect.Modifier.isStatic(f.getModifiers())) { +// System.out.println(f.getName() + " " + f.get(obj)); +// } +// +// } +//// return fields; +//// Map fields = new HashMap<>(); +////// List fields = new ArrayList<>(); +//// for (Class k = klass; k != null; k = k.getSuperclass()) { +//// for (Field f: k.getDeclaredFields()){ +//// try { +//// f.setAccessible(true); +//// Object val = f.get(obj); +//// if(val == null) { +//// continue; +//// } +//// fields.put(f.getName(), serialize(f.get(obj))); +//// } +//// catch (Exception e) { +//// System.out.println(e); +//// } +//// } +////// fields.addAll(Arrays.asList(k.getDeclaredFields())); +//// } +//// +//// for (Field f: klass.getDeclaredFields()) { +//// try { +//// fields.put(f.getName(), serialize(f.get(obj))); +//// } catch (JSONException e) { +//// throw new RuntimeException(e); +//// } +//// } +// +// return fields; +// } public static Map executeAndGetMethods(Object obj) { Class clazz = obj.getClass(); @@ -121,23 +139,23 @@ public static Map executeAndGetMethods(Object obj) { } - private static JSONArray serializeCollection(Collection collection) throws IllegalAccessException, JSONException { - JSONArray jsonArray = new JSONArray(); - for (Object item : collection) { - jsonArray.put(serialize(item)); - } - return jsonArray; - } - - private static JSONObject serializeMap(Map map) throws IllegalAccessException, JSONException { - JSONObject jsonObject = new JSONObject(); - for (Map.Entry entry : map.entrySet()) { - String key = String.valueOf(entry.getKey()); - Object value = entry.getValue(); - jsonObject.put(key, serialize(value)); - } - return jsonObject; - } +// private static JSONArray serializeCollection(Collection collection) throws IllegalAccessException, JSONException { +// JSONArray jsonArray = new JSONArray(); +// for (Object item : collection) { +// jsonArray.put(serialize(item)); +// } +// return jsonArray; +// } +// +// private static JSONObject serializeMap(Map map) throws IllegalAccessException, JSONException { +// JSONObject jsonObject = new JSONObject(); +// for (Map.Entry entry : map.entrySet()) { +// String key = String.valueOf(entry.getKey()); +// Object value = entry.getValue(); +// jsonObject.put(key, serialize(value)); +// } +// return jsonObject; +// } public static String toJson(BacktraceData data) throws JSONException, IllegalAccessException { { diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java new file mode 100644 index 00000000..9a645fd6 --- /dev/null +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java @@ -0,0 +1,111 @@ +package backtraceio.library.common.serializers; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class SerializerHelper { + public static int MAX_SERIALIZATION_LEVEL = 5; + private static final Map, Class> WRAPPER_TYPE_MAP; + static { + WRAPPER_TYPE_MAP = new HashMap<>(); + WRAPPER_TYPE_MAP.put(Integer.class, int.class); + WRAPPER_TYPE_MAP.put(Byte.class, byte.class); + WRAPPER_TYPE_MAP.put(Character.class, char.class); + WRAPPER_TYPE_MAP.put(Boolean.class, boolean.class); + WRAPPER_TYPE_MAP.put(Double.class, double.class); + WRAPPER_TYPE_MAP.put(Float.class, float.class); + WRAPPER_TYPE_MAP.put(Long.class, long.class); + WRAPPER_TYPE_MAP.put(Short.class, short.class); + WRAPPER_TYPE_MAP.put(Void.class, void.class); + } + + public static boolean isPrimitiveType(Object source) { + return WRAPPER_TYPE_MAP.containsKey(source.getClass()); + } + + public static String decapitalizeString(String string) { + return string == null || string.isEmpty() ? "" : Character.toLowerCase(string.charAt(0)) + string.substring(1); + } + + private static JSONArray serializeCollection(Collection collection) throws IllegalAccessException, JSONException { + JSONArray jsonArray = new JSONArray(); + for (Object item : collection) { + jsonArray.put(serialize(item)); + } + return jsonArray; + } + + private static List getAllFields(Class klass, Object obj) throws IllegalAccessException { + // TODO: improve naming + + List fields = new ArrayList<>(); + for (Class c = klass; c != null; c = c.getSuperclass()) { + fields.addAll(Arrays.asList(c.getDeclaredFields())); + } + + for (Field f: fields) { + f.setAccessible(true); + if (!java.lang.reflect.Modifier.isStatic(f.getModifiers())) { + System.out.println(f.getName() + " " + f.get(obj)); + } + + } + + return fields; + } + + private static JSONObject serializeMap(Map map) throws IllegalAccessException, JSONException { + JSONObject jsonObject = new JSONObject(); + for (Map.Entry entry : map.entrySet()) { + String key = String.valueOf(entry.getKey()); + Object value = entry.getValue(); + jsonObject.put(key, serialize(value)); + } + return jsonObject; + } + + public static Object serialize(Object obj, int serializationDepth) throws IllegalAccessException, JSONException { + + } + + public static Object serialize(Object obj) throws IllegalAccessException, JSONException { + if (obj == null) { + return new JSONObject(); + } + + // TODO: check if all of the types + if (SerializerHelper.isPrimitiveType(obj)) { + return obj; + } + + if (obj instanceof Collection) { + return serializeCollection((Collection) obj); + } + + if (obj instanceof Map) { + return serializeMap((Map) obj); + } + + JSONObject jsonObject = new JSONObject(); + Class clazz = obj.getClass(); + List fields = getAllFields(clazz, obj); +// Map getters = executeAndGetMethods(obj); +// Map fields = getAllFields(obj.getClass(), obj); +// for (Field field : fields) { +// String fieldName = field.getName(); +// Object fieldValue = field.get(obj); +// jsonObject.put(fieldName, fieldValue); +// } + + return jsonObject; + } +} From feb8ee35056964b0d0a223a0655bff073b727f6e Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 30 Aug 2023 18:40:31 +0200 Subject: [PATCH 004/100] Improve serializer --- .../common/BacktraceDataSerializerTest.java | 20 ++++- .../serializers/BacktraceDataSerializer.java | 19 ++-- .../common/serializers/SerializerHelper.java | 89 ++++++++++++++----- 3 files changed, 93 insertions(+), 35 deletions(-) diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java index ee215823..27fd8b61 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java @@ -18,6 +18,7 @@ import java.util.Map; import backtraceio.library.common.serializers.BacktraceDataSerializer; +import backtraceio.library.common.serializers.SerializerHelper; import backtraceio.library.models.BacktraceData; import backtraceio.library.models.json.BacktraceReport; @@ -48,6 +49,23 @@ public void testGsonSerializer() throws JSONException, IllegalAccessException { assertEquals(jsonFromOrgJson, jsonFromGson); } + @Test + public void temp() throws JSONException { +// try { + +// } catch (Exception e) { + try{ + BacktraceReport r = null; + r.toString(); + } + catch (Exception e) { + Object result2 = SerializerHelper.serialize(e); + System.out.println(result2); + } + Object result = SerializerHelper.serialize(new BacktraceReport("test")); + System.out.println(result); +// } + } @Test public void testGsonPerformanceSerializer() throws JSONException, IllegalAccessException { // TODO: fix name @@ -55,7 +73,7 @@ public void testGsonPerformanceSerializer() throws JSONException, IllegalAccessE final Context context = InstrumentationRegistry.getInstrumentation().getContext(); long timeGson = 0; long timeOrgJson = 0; - final int iterations = 1; + final int iterations = 5000; for (int i = 0; i < iterations; i++) { // INIT SAMPLE final Exception exception = new Exception(Integer.toString(i)); diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java index ef24adf3..70076f1e 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java @@ -13,15 +13,9 @@ import org.json.JSONException; import org.json.JSONObject; -import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.math.BigDecimal; -import java.math.BigInteger; import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; import java.util.HashMap; -import java.util.List; import java.util.Map; import backtraceio.library.models.BacktraceData; @@ -123,12 +117,17 @@ public static Map executeAndGetMethods(Object obj) { String methodName = method.getName(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // TODO: check if needed + + if (methodName.equals("getClass")) { + continue; + } + if (methodName.startsWith("get") && method.getParameterCount() == 0) { try { Object result = method.invoke(obj); String propertyName = methodName.substring(3); // Remove 'get' prefix - System.out.println(propertyName + ": " + result); - fields.put(decapitalizeString(propertyName), result); +// System.out.println(propertyName + ": " + result); + fields.put(decapitalizeString(propertyName), serialize(result)); } catch (Exception e) { e.printStackTrace(); } @@ -185,7 +184,7 @@ public static String toJson(BacktraceData data) throws JSONException, IllegalAcc json.put("attributes", serializeAttributes(data.attributes)); } - if(data.annotations != null) { + if (data.annotations != null) { json.put("annotations", serializeAnnotations(data.annotations)); } @@ -211,7 +210,7 @@ private static JSONObject serializeThreadInformation(Map, Class> WRAPPER_TYPE_MAP; + static { WRAPPER_TYPE_MAP = new HashMap<>(); WRAPPER_TYPE_MAP.put(Integer.class, int.class); @@ -29,22 +32,33 @@ public class SerializerHelper { } public static boolean isPrimitiveType(Object source) { - return WRAPPER_TYPE_MAP.containsKey(source.getClass()); + return WRAPPER_TYPE_MAP.containsKey(source.getClass()) || source instanceof String || source instanceof Number; } public static String decapitalizeString(String string) { return string == null || string.isEmpty() ? "" : Character.toLowerCase(string.charAt(0)) + string.substring(1); } - private static JSONArray serializeCollection(Collection collection) throws IllegalAccessException, JSONException { + private static JSONArray serializeCollection(Collection collection) throws JSONException { + return serializeCollection(collection, 0); + } + + private static JSONArray serializeArray(Object[] array, int serializationDepth) throws JSONException { + JSONArray jsonArray = new JSONArray(); + for (Object item : array) { + jsonArray.put(serialize(item, serializationDepth)); + } + return jsonArray; + } + private static JSONArray serializeCollection(Collection collection, int serializationDepth) throws JSONException { JSONArray jsonArray = new JSONArray(); for (Object item : collection) { - jsonArray.put(serialize(item)); + jsonArray.put(serialize(item, serializationDepth)); } return jsonArray; } - private static List getAllFields(Class klass, Object obj) throws IllegalAccessException { + private static JSONObject getAllFields(Class klass, Object obj, int serializationDepth) { // TODO: improve naming List fields = new ArrayList<>(); @@ -52,33 +66,55 @@ private static List getAllFields(Class klass, Object obj) throws Illeg fields.addAll(Arrays.asList(c.getDeclaredFields())); } - for (Field f: fields) { + JSONObject result = new JSONObject(); + for (Field f : fields) { f.setAccessible(true); if (!java.lang.reflect.Modifier.isStatic(f.getModifiers())) { - System.out.println(f.getName() + " " + f.get(obj)); + try { + Object value = f.get(obj); + if (value == obj) { + continue; + } + result.put(f.getName(), serialize(value, serializationDepth)); + } catch (Exception ex) { + + } + } } - return fields; + return result; } - private static JSONObject serializeMap(Map map) throws IllegalAccessException, JSONException { + private static JSONObject serializeMap(Map map) throws JSONException { + return serializeMap(map, 0); + } + + private static JSONObject serializeMap(Map map, int serializationDepth) throws JSONException { JSONObject jsonObject = new JSONObject(); for (Map.Entry entry : map.entrySet()) { String key = String.valueOf(entry.getKey()); Object value = entry.getValue(); - jsonObject.put(key, serialize(value)); + jsonObject.put(key, serialize(value, serializationDepth)); } return jsonObject; } - public static Object serialize(Object obj, int serializationDepth) throws IllegalAccessException, JSONException { +// public static Object serialize(Object obj, int serializationDepth) throws IllegalAccessException, JSONException { +// +// } + public static Object serialize(Object obj) throws JSONException { + return serialize(obj, 0); } - public static Object serialize(Object obj) throws IllegalAccessException, JSONException { + public static Object serialize(Object obj, int serializationDepth) throws JSONException { if (obj == null) { + return null; + } + + if (serializationDepth > MAX_SERIALIZATION_LEVEL) { return new JSONObject(); } @@ -87,24 +123,29 @@ public static Object serialize(Object obj) throws IllegalAccessException, JSONEx return obj; } - if (obj instanceof Collection) { - return serializeCollection((Collection) obj); - } + serializationDepth++; if (obj instanceof Map) { - return serializeMap((Map) obj); + return serializeMap((Map) obj, serializationDepth); + } + + + if (obj.getClass().isArray()) { + return serializeArray((Object[]) obj, serializationDepth); + } + + if (obj instanceof Collection) { + return serializeCollection((Collection) obj, serializationDepth); } - JSONObject jsonObject = new JSONObject(); Class clazz = obj.getClass(); - List fields = getAllFields(clazz, obj); -// Map getters = executeAndGetMethods(obj); -// Map fields = getAllFields(obj.getClass(), obj); -// for (Field field : fields) { -// String fieldName = field.getName(); -// Object fieldValue = field.get(obj); -// jsonObject.put(fieldName, fieldValue); -// } + JSONObject jsonObject = getAllFields(clazz, obj, serializationDepth); + Map getters = executeAndGetMethods(obj); + + for (Map.Entry entry: getters.entrySet()) { + jsonObject.put(entry.getKey(), entry.getValue()); + jsonObject.put(entry.getKey(), entry.getValue()); // TODO: remove + } return jsonObject; } From ec1921162130f4c781eb09e88f04447937e9eea4 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 30 Aug 2023 18:41:53 +0200 Subject: [PATCH 005/100] Remove unused code --- .../serializers/BacktraceDataSerializer.java | 104 ------------------ .../common/serializers/SerializerHelper.java | 4 - 2 files changed, 108 deletions(-) diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java index 70076f1e..a0eab680 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java @@ -25,89 +25,6 @@ public class BacktraceDataSerializer { - -// public static Object serialize(Object obj) throws IllegalAccessException, JSONException { -// if (obj == null) { -// return new JSONObject(); -// } -// -// // TODO: check if all of the types -// if (SerializerHelper.isPrimitiveType(obj)) { -// return obj; -// } -// -// if (obj instanceof Collection) { -// return serializeCollection((Collection) obj); -// } -// -// if (obj instanceof Map) { -// return serializeMap((Map) obj); -// } -// -// JSONObject jsonObject = new JSONObject(); -// Class clazz = obj.getClass(); -// List fields = getAllFields(clazz, obj); -//// Map getters = executeAndGetMethods(obj); -//// Map fields = getAllFields(obj.getClass(), obj); -//// for (Field field : fields) { -//// String fieldName = field.getName(); -//// Object fieldValue = field.get(obj); -//// jsonObject.put(fieldName, fieldValue); -//// } -// -// return jsonObject; -// } - -// public static String decapitalizeString(String string) { -// return string == null || string.isEmpty() ? "" : Character.toLowerCase(string.charAt(0)) + string.substring(1); -// } - -// private static List getAllFields(Class klass, Object obj) throws IllegalAccessException { -// // TODO: improve naming -// -// List fields = new ArrayList(); -// for (Class c = klass; c != null; c = c.getSuperclass()) { -// fields.addAll(Arrays.asList(c.getDeclaredFields())); -// } -// -// for (Field f: fields) { -// f.setAccessible(true); -// if (!java.lang.reflect.Modifier.isStatic(f.getModifiers())) { -// System.out.println(f.getName() + " " + f.get(obj)); -// } -// -// } -//// return fields; -//// Map fields = new HashMap<>(); -////// List fields = new ArrayList<>(); -//// for (Class k = klass; k != null; k = k.getSuperclass()) { -//// for (Field f: k.getDeclaredFields()){ -//// try { -//// f.setAccessible(true); -//// Object val = f.get(obj); -//// if(val == null) { -//// continue; -//// } -//// fields.put(f.getName(), serialize(f.get(obj))); -//// } -//// catch (Exception e) { -//// System.out.println(e); -//// } -//// } -////// fields.addAll(Arrays.asList(k.getDeclaredFields())); -//// } -//// -//// for (Field f: klass.getDeclaredFields()) { -//// try { -//// fields.put(f.getName(), serialize(f.get(obj))); -//// } catch (JSONException e) { -//// throw new RuntimeException(e); -//// } -//// } -// -// return fields; -// } - public static Map executeAndGetMethods(Object obj) { Class clazz = obj.getClass(); Map fields = new HashMap<>(); @@ -126,7 +43,6 @@ public static Map executeAndGetMethods(Object obj) { try { Object result = method.invoke(obj); String propertyName = methodName.substring(3); // Remove 'get' prefix -// System.out.println(propertyName + ": " + result); fields.put(decapitalizeString(propertyName), serialize(result)); } catch (Exception e) { e.printStackTrace(); @@ -137,25 +53,6 @@ public static Map executeAndGetMethods(Object obj) { return fields; } - -// private static JSONArray serializeCollection(Collection collection) throws IllegalAccessException, JSONException { -// JSONArray jsonArray = new JSONArray(); -// for (Object item : collection) { -// jsonArray.put(serialize(item)); -// } -// return jsonArray; -// } -// -// private static JSONObject serializeMap(Map map) throws IllegalAccessException, JSONException { -// JSONObject jsonObject = new JSONObject(); -// for (Map.Entry entry : map.entrySet()) { -// String key = String.valueOf(entry.getKey()); -// Object value = entry.getValue(); -// jsonObject.put(key, serialize(value)); -// } -// return jsonObject; -// } - public static String toJson(BacktraceData data) throws JSONException, IllegalAccessException { { JSONObject json = new JSONObject(); @@ -192,7 +89,6 @@ public static String toJson(BacktraceData data) throws JSONException, IllegalAcc json.put("sourceCode", serializeSourceCode(data.sourceCode)); } - // Serialize threadInformationMap if (data.getThreadInformationMap() != null) { JSONObject threadInformationJson = serializeThreadInformation(data.getThreadInformationMap()); json.put("threads", threadInformationJson); diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java index 4ba5eb5b..c4cf5a92 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java @@ -101,10 +101,6 @@ private static JSONObject serializeMap(Map map, int serializationDepth) th return jsonObject; } -// public static Object serialize(Object obj, int serializationDepth) throws IllegalAccessException, JSONException { -// -// } - public static Object serialize(Object obj) throws JSONException { return serialize(obj, 0); } From 88d2df812bfeb253888628339bc244f1d53a1d42 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 30 Aug 2023 18:42:36 +0200 Subject: [PATCH 006/100] Remove unused code --- .../backtraceio/library/common/serializers/SerializerHelper.java | 1 - 1 file changed, 1 deletion(-) diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java index c4cf5a92..0be85980 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java @@ -140,7 +140,6 @@ public static Object serialize(Object obj, int serializationDepth) throws JSONEx for (Map.Entry entry: getters.entrySet()) { jsonObject.put(entry.getKey(), entry.getValue()); - jsonObject.put(entry.getKey(), entry.getValue()); // TODO: remove } return jsonObject; From 0c8c1e82084c0319a7fa524da0c67b4fbf11769b Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 30 Aug 2023 23:10:20 +0200 Subject: [PATCH 007/100] Deserializer --- .../common/BacktraceDataDeserializerTest.java | 42 ++++ .../common/BacktraceDataSerializerTest.java | 2 +- .../src/androidTest/resources/sample.json | 0 .../BacktraceDataDeserializer.java | 225 ++++++++++++++++++ .../serializers/BacktraceDataSerializer.java | 8 +- .../common/serializers/SerializerHelper.java | 11 +- .../library/models/BacktraceData.java | 45 +++- 7 files changed, 305 insertions(+), 28 deletions(-) create mode 100644 backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java create mode 100644 backtrace-library/src/androidTest/resources/sample.json create mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataDeserializer.java diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java new file mode 100644 index 00000000..b78f908b --- /dev/null +++ b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java @@ -0,0 +1,42 @@ +package backtraceio.library.common; + +import static org.junit.Assert.assertEquals; + +import android.content.Context; + +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; + +import org.json.JSONException; +import org.json.JSONObject; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import backtraceio.library.common.serializers.BacktraceDataDeserializer; +import backtraceio.library.common.serializers.BacktraceDataSerializer; +import backtraceio.library.common.serializers.SerializerHelper; +import backtraceio.library.models.BacktraceData; +import backtraceio.library.models.json.BacktraceReport; + +@RunWith(AndroidJUnit4.class) +public class BacktraceDataDeserializerTest { + + @Test + public void fromJson() throws JSONException, IllegalAccessException { + // GIVEN + String path = "src/test/resources/"; + String jsonPath = path + "sample.json"; + String json = FileHelper.readFile(new File(jsonPath)); + // WHEN + JSONObject jsonObj = new JSONObject(json); + + // THEN +// BacktraceData backtraceData = BacktraceDataDeserializer. + } +} diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java index 27fd8b61..47611768 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java @@ -73,7 +73,7 @@ public void testGsonPerformanceSerializer() throws JSONException, IllegalAccessE final Context context = InstrumentationRegistry.getInstrumentation().getContext(); long timeGson = 0; long timeOrgJson = 0; - final int iterations = 5000; + final int iterations = 1; for (int i = 0; i < iterations; i++) { // INIT SAMPLE final Exception exception = new Exception(Integer.toString(i)); diff --git a/backtrace-library/src/androidTest/resources/sample.json b/backtrace-library/src/androidTest/resources/sample.json new file mode 100644 index 00000000..e69de29b diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataDeserializer.java new file mode 100644 index 00000000..3b218677 --- /dev/null +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataDeserializer.java @@ -0,0 +1,225 @@ +package backtraceio.library.common.serializers; + +import android.content.Context; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.UUID; + +import backtraceio.library.models.BacktraceData; +import backtraceio.library.models.BacktraceStackFrame; +import backtraceio.library.models.json.BacktraceReport; +import backtraceio.library.models.json.SourceCode; +import backtraceio.library.models.json.ThreadInformation; + +public class BacktraceDataDeserializer { + + public static BacktraceData deserialize(JSONObject obj) throws JSONException { + BacktraceData backtraceData = new BacktraceData(null, null, null); // todo: fix + + backtraceData.symbolication = obj.optString("symbolication"); + backtraceData.uuid = obj.optString("uuid"); + backtraceData.timestamp = obj.optLong("timestamp"); + backtraceData.langVersion = obj.optString("langVersion"); + backtraceData.agentVersion = obj.optString("agentVersion"); + backtraceData.mainThread = obj.optString("mainThread"); + + JSONArray classifiersArray = obj.optJSONArray("classifiers"); + if (classifiersArray != null) { + backtraceData.classifiers = new String[classifiersArray.length()]; + for (int i = 0; i < classifiersArray.length(); i++) { + backtraceData.classifiers[i] = classifiersArray.optString(i); + } + } + + JSONObject attributesObj = obj.optJSONObject("attributes"); + if (attributesObj != null) { + backtraceData.attributes = new HashMap<>(); + Iterator attributesKeys = attributesObj.keys(); + while (attributesKeys.hasNext()) { + String key = attributesKeys.next(); + backtraceData.attributes.put(key, attributesObj.optString(key)); + } + } + + JSONObject annotationsObj = obj.optJSONObject("annotations"); + if (annotationsObj != null) { + backtraceData.annotations = new HashMap<>(); + Iterator annotationsKeys = annotationsObj.keys(); + while (annotationsKeys.hasNext()) { + String key = annotationsKeys.next(); + backtraceData.annotations.put(key, annotationsObj.opt(key)); + } + } + + JSONObject sourceCodeObj = obj.optJSONObject("sourceCode"); + if (sourceCodeObj != null) { + backtraceData.sourceCode = new HashMap<>(); + Iterator sourceCodeKeys = sourceCodeObj.keys(); + while (sourceCodeKeys.hasNext()) { + String key = sourceCodeKeys.next(); + JSONObject sourceCodeItem = sourceCodeObj.optJSONObject(key); + if (sourceCodeItem != null) { +// SourceCode sourceCode = new SourceCode(); +// sourceCode.startLine = sourceCodeItem.optInt("startLine"); +// sourceCode.sourceCodeFileName = sourceCodeItem.optString("path"); +// backtraceData.sourceCode.put(key, sourceCode); + } + } + } + +// JSONObject threadInformationMapObj = obj.optJSONObject("threads"); +// if (threadInformationMapObj != null) { +// backtraceData.threadInformationMap = new HashMap<>(); +// Iterator threadKeys = threadInformationMapObj.keys(); +// while (threadKeys.hasNext()) { +// String threadKey = threadKeys.next(); +// JSONObject threadInfoObj = threadInformationMapObj.optJSONObject(threadKey); +// if (threadInfoObj != null) { +// ThreadInformation threadInformation = new ThreadInformation(); +// threadInformation.name = threadInfoObj.optString("name"); +// JSONArray stackArray = threadInfoObj.optJSONArray("stack"); +// if (stackArray != null) { +// threadInformation.stack = new ArrayList<>(); +// for (int i = 0; i < stackArray.length(); i++) { +// JSONObject stackItem = stackArray.optJSONObject(i); +// if (stackItem != null) { +// BacktraceStackFrame stackFrame = new BacktraceStackFrame(); +// stackFrame.functionName = stackItem.optString("funcName"); +// stackFrame.line = stackItem.optInt("line"); +// stackFrame.sourceCode = stackItem.optString("sourceCode"); +// threadInformation.stack.add(stackFrame); +// } +// } +// } +// backtraceData.threadInformationMap.put(threadKey, threadInformation); +// } +// } +// } + + // Deserialize BacktraceReport + JSONObject reportObj = obj.optJSONObject("report"); + if (reportObj != null) { + BacktraceReport report = new BacktraceReport(""); // todo: fix + report.uuid = UUID.fromString(reportObj.optString("uuid")); + report.timestamp = reportObj.optLong("timestamp"); + report.exceptionTypeReport = reportObj.optBoolean("exceptionTypeReport"); + report.classifier = reportObj.optString("classifier"); + + JSONArray attachmentPathsArray = reportObj.optJSONArray("attachmentPaths"); + if (attachmentPathsArray != null) { + report.attachmentPaths = new ArrayList<>(); + for (int i = 0; i < attachmentPathsArray.length(); i++) { + report.attachmentPaths.add(attachmentPathsArray.optString(i)); + } + } + + report.message = reportObj.optString("message"); + + // Deserialize exception field if needed + + JSONArray diagnosticStackArray = reportObj.optJSONArray("diagnosticStack"); + if (diagnosticStackArray != null) { + report.diagnosticStack = new ArrayList<>(); + for (int i = 0; i < diagnosticStackArray.length(); i++) { + JSONObject stackItem = diagnosticStackArray.optJSONObject(i); + if (stackItem != null) { + BacktraceStackFrame stackFrame = new BacktraceStackFrame(); + stackFrame.functionName = stackItem.optString("funcName"); + stackFrame.line = stackItem.optInt("line"); + stackFrame.sourceCode = stackItem.optString("sourceCode"); + report.diagnosticStack.add(stackFrame); + } + } + } + + // You would similarly handle other fields of BacktraceReport here + + backtraceData.report = report; + } + + return backtraceData; + } + + + public static BacktraceData deserialize(Context context, JSONObject obj) throws JSONException { + BacktraceData backtraceData = new BacktraceData(context, null, null); // todo fix + + // ... (Deserialization logic for other fields) ... + + // Deserialize BacktraceReport + JSONObject reportObj = obj.optJSONObject("report"); + if (reportObj != null) { + BacktraceReport report = new BacktraceReport(""); + report.uuid = UUID.fromString(reportObj.optString("uuid")); + report.timestamp = reportObj.optLong("timestamp"); + report.exceptionTypeReport = reportObj.optBoolean("exceptionTypeReport"); + report.classifier = reportObj.optString("classifier"); + + JSONArray attachmentPathsArray = reportObj.optJSONArray("attachmentPaths"); + if (attachmentPathsArray != null) { + report.attachmentPaths = new ArrayList<>(); + for (int i = 0; i < attachmentPathsArray.length(); i++) { + report.attachmentPaths.add(attachmentPathsArray.optString(i)); + } + } + + report.message = reportObj.optString("message"); + + // Deserialize exception field + JSONObject exceptionObj = reportObj.optJSONObject("exception"); + if (exceptionObj != null) { + String exceptionClassName = exceptionObj.optString("className"); + String exceptionMessage = exceptionObj.optString("message"); + Exception exception = new Exception(exceptionMessage); + exception.setStackTrace(parseStackFrames(exceptionObj.optJSONArray("stackTrace"))); + report.exception = exception; + } + + JSONArray diagnosticStackArray = reportObj.optJSONArray("diagnosticStack"); + if (diagnosticStackArray != null) { + report.diagnosticStack = new ArrayList<>(); + for (int i = 0; i < diagnosticStackArray.length(); i++) { + JSONObject stackItem = diagnosticStackArray.optJSONObject(i); + if (stackItem != null) { + BacktraceStackFrame stackFrame = new BacktraceStackFrame(); + stackFrame.functionName = stackItem.optString("funcName"); + stackFrame.line = stackItem.optInt("line"); + stackFrame.sourceCode = stackItem.optString("sourceCode"); + report.diagnosticStack.add(stackFrame); + } + } + } + + // ... (Other deserialization for BacktraceReport fields) ... + + backtraceData.report = report; + } + + return backtraceData; + } + + private static StackTraceElement[] parseStackFrames(JSONArray stackTraceArray) { + if (stackTraceArray == null) { + return new StackTraceElement[0]; + } + StackTraceElement[] stackTrace = new StackTraceElement[stackTraceArray.length()]; + for (int i = 0; i < stackTraceArray.length(); i++) { + JSONObject stackItem = stackTraceArray.optJSONObject(i); + if (stackItem != null) { + String className = stackItem.optString("className"); + String methodName = stackItem.optString("methodName"); + String fileName = stackItem.optString("fileName"); + int lineNumber = stackItem.optInt("lineNumber"); + stackTrace[i] = new StackTraceElement(className, methodName, fileName, lineNumber); + } + } + return stackTrace; + } + +} \ No newline at end of file diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java index a0eab680..a25924aa 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java @@ -30,10 +30,9 @@ public static Map executeAndGetMethods(Object obj) { Map fields = new HashMap<>(); Method[] methods = clazz.getMethods(); - for (Method method : methods) { - String methodName = method.getName(); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // TODO: check if needed + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // TODO: check if needed + for (Method method : methods) { + String methodName = method.getName(); if (methodName.equals("getClass")) { continue; @@ -76,7 +75,6 @@ public static String toJson(BacktraceData data) throws JSONException, IllegalAcc json.put("classifiers", classifiers); } - if (data.attributes != null) { json.put("attributes", serializeAttributes(data.attributes)); } diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java index 0be85980..13872097 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java @@ -39,10 +39,6 @@ public static String decapitalizeString(String string) { return string == null || string.isEmpty() ? "" : Character.toLowerCase(string.charAt(0)) + string.substring(1); } - private static JSONArray serializeCollection(Collection collection) throws JSONException { - return serializeCollection(collection, 0); - } - private static JSONArray serializeArray(Object[] array, int serializationDepth) throws JSONException { JSONArray jsonArray = new JSONArray(); for (Object item : array) { @@ -77,7 +73,7 @@ private static JSONObject getAllFields(Class klass, Object obj, int serializa } result.put(f.getName(), serialize(value, serializationDepth)); } catch (Exception ex) { - +// ex.printStackTrace(); } } @@ -87,10 +83,6 @@ private static JSONObject getAllFields(Class klass, Object obj, int serializa return result; } - private static JSONObject serializeMap(Map map) throws JSONException { - return serializeMap(map, 0); - } - private static JSONObject serializeMap(Map map, int serializationDepth) throws JSONException { JSONObject jsonObject = new JSONObject(); for (Map.Entry entry : map.entrySet()) { @@ -125,7 +117,6 @@ public static Object serialize(Object obj, int serializationDepth) throws JSONEx return serializeMap((Map) obj, serializationDepth); } - if (obj.getClass().isArray()) { return serializeArray((Object[]) obj, serializationDepth); } 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 49f1dcbb..e91a6746 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java @@ -118,6 +118,7 @@ public class BacktraceData { * @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) { @@ -126,8 +127,8 @@ public BacktraceData(Context context, BacktraceReport report, Map clientAttributes) { /** * Set report information such as report identifier (UUID), timestamp, classifier */ - private void setReportInformation() { + private void setDefaultReportInformation() { + this.setReportInformation( + report.uuid.toString(), + report.timestamp, + report.exceptionTypeReport ? new String[]{report.classifier} : null, + System.getProperty("java.version"), //TODO: Fix problem with read Java version, + BacktraceClient.version + ); + } + + public void setReportInformation(String uuid, long timestamp, String [] classifiers, String langVersion, String agentVersion) { 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; + this.uuid = uuid; + this.timestamp = timestamp; + this.classifiers = classifiers; + this.langVersion = langVersion; + this.agentVersion = agentVersion; } /** * Set information about all threads */ - private void setThreadsInformation() { + private void setDefaultThreadsInformation() { 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; + + this.setThreadsInformation( + threadData.getMainThread(), + threadData.threadInformation, + sourceCodeData.data.isEmpty() ? null : sourceCodeData.data + ); + } + + public void setThreadsInformation(String mainThreadName, Map threadInformationMap, Map sourceCodeData) { + this.mainThread = mainThreadName; + this.threadInformationMap = threadInformationMap; + this.sourceCode = sourceCodeData; } } \ No newline at end of file From 3f67d7343c08db3b5fadd67205f68806ba60b2a1 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Sun, 17 Sep 2023 20:34:57 +0200 Subject: [PATCH 008/100] Deserialization unit tests --- .../java/backtraceio/library/TestUtils.java | 29 +++++++ .../common/BacktraceDataDeserializerTest.java | 23 ++++- .../src/androidTest/resources/sample.json | 3 + .../BacktraceDataDeserializer.java | 84 ++++++++++--------- 4 files changed, 97 insertions(+), 42 deletions(-) create mode 100644 backtrace-library/src/androidTest/java/backtraceio/library/TestUtils.java diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/TestUtils.java b/backtrace-library/src/androidTest/java/backtraceio/library/TestUtils.java new file mode 100644 index 00000000..c20aed4f --- /dev/null +++ b/backtrace-library/src/androidTest/java/backtraceio/library/TestUtils.java @@ -0,0 +1,29 @@ +package backtraceio.library; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +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; + } +} diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java index b78f908b..c4298190 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java @@ -2,6 +2,8 @@ import static org.junit.Assert.assertEquals; +import static backtraceio.library.TestUtils.readFileAsString; + import android.content.Context; import androidx.test.ext.junit.runners.AndroidJUnit4; @@ -12,12 +14,18 @@ import org.junit.Test; import org.junit.runner.RunWith; +import java.io.BufferedReader; import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import backtraceio.library.R; import backtraceio.library.common.serializers.BacktraceDataDeserializer; import backtraceio.library.common.serializers.BacktraceDataSerializer; import backtraceio.library.common.serializers.SerializerHelper; @@ -30,13 +38,20 @@ public class BacktraceDataDeserializerTest { @Test public void fromJson() throws JSONException, IllegalAccessException { // GIVEN - String path = "src/test/resources/"; + final Context context = InstrumentationRegistry.getInstrumentation().getContext(); + + String fileName = "sample.json"; + + String path = "resources/"; String jsonPath = path + "sample.json"; - String json = FileHelper.readFile(new File(jsonPath)); + // WHEN - JSONObject jsonObj = new JSONObject(json); + + String content = readFileAsString(this, fileName); +// File x = getFileFromPath(this, "resources/sample.json"); + JSONObject jsonObj = new JSONObject(content); // THEN -// BacktraceData backtraceData = BacktraceDataDeserializer. + BacktraceData backtraceData = BacktraceDataDeserializer.deserialize(context, jsonObj); } } diff --git a/backtrace-library/src/androidTest/resources/sample.json b/backtrace-library/src/androidTest/resources/sample.json index e69de29b..a3c76f22 100644 --- a/backtrace-library/src/androidTest/resources/sample.json +++ b/backtrace-library/src/androidTest/resources/sample.json @@ -0,0 +1,3 @@ +{ + "abc": 123 +} \ No newline at end of file diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataDeserializer.java index 3b218677..1aa81d3a 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataDeserializer.java @@ -19,8 +19,9 @@ public class BacktraceDataDeserializer { - public static BacktraceData deserialize(JSONObject obj) throws JSONException { - BacktraceData backtraceData = new BacktraceData(null, null, null); // todo: fix + public static BacktraceData deserialize(Context context, JSONObject obj) throws JSONException { + BacktraceReport report = BacktraceDataDeserializer.deserializeReport(context, obj.optJSONObject("report")); + BacktraceData backtraceData = new BacktraceData(context, report, new HashMap<>()); // todo: fix backtraceData.symbolication = obj.optString("symbolication"); backtraceData.uuid = obj.optString("uuid"); @@ -102,52 +103,59 @@ public static BacktraceData deserialize(JSONObject obj) throws JSONException { // } // } - // Deserialize BacktraceReport - JSONObject reportObj = obj.optJSONObject("report"); - if (reportObj != null) { - BacktraceReport report = new BacktraceReport(""); // todo: fix - report.uuid = UUID.fromString(reportObj.optString("uuid")); - report.timestamp = reportObj.optLong("timestamp"); - report.exceptionTypeReport = reportObj.optBoolean("exceptionTypeReport"); - report.classifier = reportObj.optString("classifier"); + return backtraceData; + } + public static BacktraceReport deserializeReport(Context context, JSONObject obj) throws JSONException { + if (obj == null ){ + return null; + } - JSONArray attachmentPathsArray = reportObj.optJSONArray("attachmentPaths"); - if (attachmentPathsArray != null) { - report.attachmentPaths = new ArrayList<>(); - for (int i = 0; i < attachmentPathsArray.length(); i++) { - report.attachmentPaths.add(attachmentPathsArray.optString(i)); - } + BacktraceReport report = new BacktraceReport(""); // todo: fix + report.uuid = UUID.fromString(obj.optString("uuid")); + report.timestamp = obj.optLong("timestamp"); + report.exceptionTypeReport = obj.optBoolean("exceptionTypeReport"); + report.classifier = obj.optString("classifier"); + + JSONArray attachmentPathsArray = obj.optJSONArray("attachmentPaths"); + if (attachmentPathsArray != null) { + report.attachmentPaths = new ArrayList<>(); + for (int i = 0; i < attachmentPathsArray.length(); i++) { + report.attachmentPaths.add(attachmentPathsArray.optString(i)); } + } - report.message = reportObj.optString("message"); - - // Deserialize exception field if needed - - JSONArray diagnosticStackArray = reportObj.optJSONArray("diagnosticStack"); - if (diagnosticStackArray != null) { - report.diagnosticStack = new ArrayList<>(); - for (int i = 0; i < diagnosticStackArray.length(); i++) { - JSONObject stackItem = diagnosticStackArray.optJSONObject(i); - if (stackItem != null) { - BacktraceStackFrame stackFrame = new BacktraceStackFrame(); - stackFrame.functionName = stackItem.optString("funcName"); - stackFrame.line = stackItem.optInt("line"); - stackFrame.sourceCode = stackItem.optString("sourceCode"); - report.diagnosticStack.add(stackFrame); - } + report.message = obj.optString("message"); + + // Deserialize exception field if needed + + JSONArray diagnosticStackArray = obj.optJSONArray("diagnosticStack"); + if (diagnosticStackArray != null) { + report.diagnosticStack = new ArrayList<>(); + for (int i = 0; i < diagnosticStackArray.length(); i++) { + JSONObject stackItem = diagnosticStackArray.optJSONObject(i); + if (stackItem != null) { + BacktraceStackFrame stackFrame = new BacktraceStackFrame(); + stackFrame.functionName = stackItem.optString("funcName"); + stackFrame.line = stackItem.optInt("line"); + stackFrame.sourceCode = stackItem.optString("sourceCode"); + report.diagnosticStack.add(stackFrame); } } + } - // You would similarly handle other fields of BacktraceReport here - - backtraceData.report = report; + JSONObject exceptionObj = obj.optJSONObject("exception"); + if (exceptionObj != null) { + String exceptionClassName = exceptionObj.optString("className"); + String exceptionMessage = exceptionObj.optString("message"); + Exception exception = new Exception(exceptionMessage); + exception.setStackTrace(parseStackFrames(exceptionObj.optJSONArray("stackTrace"))); + report.exception = exception; } - return backtraceData; + return report; } - - public static BacktraceData deserialize(Context context, JSONObject obj) throws JSONException { + public static BacktraceData deserializeReportXYZ(Context context, JSONObject obj) throws JSONException { BacktraceData backtraceData = new BacktraceData(context, null, null); // todo fix // ... (Deserialization logic for other fields) ... From e4fe04bd6cb6af17edd02ac4affc4efd886abdca Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Mon, 18 Sep 2023 22:38:29 +0200 Subject: [PATCH 009/100] Add sample json --- .../common/BacktraceDataDeserializerTest.java | 7 +- .../common/BacktraceDataSerializerTest.java | 2 + .../src/androidTest/resources/sample.json | 1015 ++++++++++++++++- 3 files changed, 1021 insertions(+), 3 deletions(-) diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java index c4298190..f1c0dc88 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java @@ -44,14 +44,17 @@ public void fromJson() throws JSONException, IllegalAccessException { String path = "resources/"; String jsonPath = path + "sample.json"; - + // WHEN String content = readFileAsString(this, fileName); // File x = getFileFromPath(this, "resources/sample.json"); JSONObject jsonObj = new JSONObject(content); - // THEN BacktraceData backtraceData = BacktraceDataDeserializer.deserialize(context, jsonObj); + + System.out.println(backtraceData.report); + // THEN +// assertEquals(backtraceData.report.message, ); } } diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java index 47611768..2b821d5a 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java @@ -43,6 +43,8 @@ public void testGsonSerializer() throws JSONException, IllegalAccessException { // WHEN final String jsonFromGson = BacktraceSerializeHelper.toJson(data); + + final BacktraceData dataGson = BacktraceSerializeHelper.fromJson(jsonFromGson, BacktraceData.class); final String jsonFromOrgJson = BacktraceDataSerializer.toJson(data); // THEN diff --git a/backtrace-library/src/androidTest/resources/sample.json b/backtrace-library/src/androidTest/resources/sample.json index a3c76f22..b23fc1eb 100644 --- a/backtrace-library/src/androidTest/resources/sample.json +++ b/backtrace-library/src/androidTest/resources/sample.json @@ -1,3 +1,1016 @@ { - "abc": 123 + "agent": "backtrace-android", + "agentVersion": "3.7.7-8-3f67d73-org-json-serializer", + "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", + "PATH": "/product/bin:/apex/com.android.runtime/bin:/apex/com.android.art/bin:/system_ext/bin:/system/bin:/system/xbin:/odm/bin:/vendor/bin:/vendor/xbin", + "ANDROID_SOCKET_zygote": "17", + "ANDROID_I18N_ROOT": "/apex/com.android.i18n", + "ANDROID_DATA": "/data", + "ASEC_MOUNTPOINT": "/mnt/asec", + "ANDROID_TZDATA_ROOT": "/apex/com.android.tzdata", + "EXTERNAL_STORAGE": "/sdcard", + "ANDROID_BOOTLOGO": "1", + "ANDROID_ASSETS": "/system/app", + "ANDROID_STORAGE": "/storage", + "DEX2OATBOOTCLASSPATH": "/apex/com.android.art/javalib/core-oj.jar:/apex/com.android.art/javalib/core-libart.jar:/apex/com.android.art/javalib/core-icu4j.jar:/apex/com.android.art/javalib/okhttp.jar:/apex/com.android.art/javalib/bouncycastle.jar:/apex/com.android.art/javalib/apache-xml.jar:/system/framework/framework.jar:/system/framework/ext.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/framework-atb-backward-compatibility.jar", + "ANDROID_ART_ROOT": "/apex/com.android.art", + "ANDROID_ROOT": "/system", + "DOWNLOAD_CACHE": "/data/cache", + "BOOTCLASSPATH": "/apex/com.android.art/javalib/core-oj.jar:/apex/com.android.art/javalib/core-libart.jar:/apex/com.android.art/javalib/core-icu4j.jar:/apex/com.android.art/javalib/okhttp.jar:/apex/com.android.art/javalib/bouncycastle.jar:/apex/com.android.art/javalib/apache-xml.jar:/system/framework/framework.jar:/system/framework/ext.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/framework-atb-backward-compatibility.jar:/apex/com.android.conscrypt/javalib/conscrypt.jar:/apex/com.android.media/javalib/updatable-media.jar:/apex/com.android.mediaprovider/javalib/framework-mediaprovider.jar:/apex/com.android.os.statsd/javalib/framework-statsd.jar:/apex/com.android.permission/javalib/framework-permission.jar:/apex/com.android.sdkext/javalib/framework-sdkextensions.jar:/apex/com.android.wifi/javalib/framework-wifi.jar:/apex/com.android.tethering/javalib/framework-tethering.jar", + "ANDROID_SOCKET_usap_pool_primary": "21" + }, + "string-key2": { + "detail-message": "test-error", + "stack-trace": [ + { + "declaring-class": "backtraceio.library.common.BacktraceDataSerializerTest", + "file-name": "BacktraceDataSerializerTest.java", + "line-number": 32, + "method-name": "testGsonSerializer" + }, + { + "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": "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 properties": { + "detail-message": "test-error", + "stack-trace": [ + { + "declaring-class": "backtraceio.library.common.BacktraceDataSerializerTest", + "file-name": "BacktraceDataSerializerTest.java", + "line-number": 32, + "method-name": "testGsonSerializer" + }, + { + "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": "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": { + "message": "test-error" + } + }, + "attributes": { + "device.nfc.status": "NotAvailable", + "device.cpu.temperature": "0.0", + "string-key": "string-value", + "system.memory.active": "1051795456", + "device.wifi.status": "Enabled", + "screen.height": "1834", + "uname.machine": "i686", + "screen.dpi": "288", + "device.bluetooth_status": "NotPermitted", + "device.airplane_mode": "false", + "classifier": "java.lang.Exception", + "system.memory.total": "2077347840", + "device.sdk": "30", + "device.brand": "google", + "uname.sysname": "Android", + "cpu.boottime": "1694978533765", + "device.os_version": "5.4.61-android11-0-00791-gbad091cc4bf3-ab6833933", + "device.gps.enabled": "Enabled", + "application.package": "backtraceio.library.test", + "uname.version": "11", + "backtrace.version": "3.7.7-8-3f67d73-org-json-serializer", + "device.is_power_saving_mode": "false", + "screen.orientation": "Portrait", + "device.manufacturer": "Google", + "system.memory.free": "1025556480", + "battery.state": "Unplugged", + "error.type": "Exception", + "device.location": "Enabled", + "application": "backtraceio.library.test", + "error.message": "test-error", + "culture": "English", + "device.model": "sdk_gphone_x86", + "screen.width": "1080", + "build.type": "Debug", + "device.product": "sdk_gphone_x86", + "guid": "e4c57699-0dc9-35e2-b4a0-2ffff1925ca7", + "app.storage_used": "2925368", + "battery.level": "1.0", + "screen.brightness": "102" + }, + "classifiers": [ + "java.lang.Exception" + ], + "lang": "java", + "langVersion": "0", + "mainThread": "instr: androidx.test.runner.androidjunitrunner", + "sourceCode": { + "def0b244-b5c3-4c68-9e4b-b5421888eee1": { + "path": "ParentRunner.java", + "startLine": 306 + }, + "8d478559-5a6f-412b-b854-3000e9adc98f": { + "path": "Suite.java", + "startLine": 128 + }, + "448f66cf-becf-4c83-9687-37eb9369a359": { + "path": "BlockJUnit4ClassRunner.java", + "startLine": 100 + }, + "bd559fdd-bd6f-44b6-a9b9-a14d865961d7": { + "path": "ParentRunner.java", + "startLine": 366 + }, + "e0eeb7ad-1024-4789-9fbe-4becb39e8420": { + "path": "ParentRunner.java", + "startLine": 413 + }, + "4e282390-371b-4af4-b117-29398510be3a": { + "path": "FrameworkMethod.java", + "startLine": 59 + }, + "0ca32861-e9bb-4dd2-a38b-76bdb0be09e8": { + "path": "ParentRunner.java", + "startLine": 293 + }, + "7aaec2ac-a43e-444b-b9ae-ad41ced28f33": { + "path": "ParentRunner.java", + "startLine": 413 + }, + "cb3283d2-d08f-4851-96fb-ec54aac63fd2": { + "path": "JUnitCore.java", + "startLine": 115 + }, + "d3a587b8-9d2c-4e70-9a0a-5a8257917d2d": { + "path": "Method.java" + }, + "4585edd4-5bf7-45e4-bb46-3f557b096852": { + "path": "FrameworkMethod.java", + "startLine": 56 + }, + "3e26748a-3965-4814-95a4-c474a701a15b": { + "path": "ParentRunner.java", + "startLine": 331 + }, + "d6321483-6dc8-4ae5-95e8-c34ca2bfb660": { + "path": "AndroidJUnit4.java", + "startLine": 162 + }, + "b8437309-6989-4316-ab70-925d6fbc5135": { + "path": "Instrumentation.java", + "startLine": 2205 + }, + "da3b40ad-d417-4f05-ae95-a7203478961d": { + "path": "ParentRunner.java", + "startLine": 329 + }, + "04520e56-5648-402d-99b5-434a8375e1b5": { + "path": "ParentRunner.java", + "startLine": 306 + }, + "dc715057-f108-4cc2-b4e8-f21aa2c4a75e": { + "path": "ParentRunner.java", + "startLine": 79 + }, + "ef921e3c-bbc6-4d1f-a8ac-e9dfcc2b3d90": { + "path": "ParentRunner.java", + "startLine": 79 + }, + "2068f2a4-9f0f-4854-bee9-cb398b7fd37f": { + "path": "ParentRunner.java", + "startLine": 331 + }, + "5e310bf1-ef77-449e-b523-bfb56d96cbc7": { + "path": "ParentRunner.java", + "startLine": 66 + }, + "3d9dcb46-6ac9-423e-8920-d0b5ec9c0f6d": { + "path": "BlockJUnit4ClassRunner.java", + "startLine": 63 + }, + "b47a8dd1-9c31-4793-805c-e33f9c77c818": { + "path": "Suite.java", + "startLine": 27 + }, + "2517e7f8-fcec-44eb-a37c-c144fd441837": { + "path": "AndroidJUnitRunner.java", + "startLine": 446 + }, + "2bf04cc1-bb1e-47e2-a11b-c4bdea625413": { + "path": "JUnitCore.java", + "startLine": 137 + }, + "295ccd27-4db2-487c-82f0-f255120cf593": { + "path": "ParentRunner.java", + "startLine": 306 + }, + "1ecb4287-1ad2-45a6-8450-af401cdbe17f": { + "path": "ReflectiveCallable.java", + "startLine": 12 + }, + "8ff34e56-9e08-4520-a87e-d7789785f013": { + "path": "TestExecutor.java", + "startLine": 67 + }, + "1549004b-d478-4341-87a2-4dea50ad031d": { + "path": "ParentRunner.java", + "startLine": 329 + }, + "5e3e29f7-7f77-4d4c-ae54-7a41caac90f4": { + "path": "ParentRunner.java", + "startLine": 293 + }, + "e9b5bfe9-f501-49c9-9621-02019e307488": { + "path": "InvokeMethod.java", + "startLine": 17 + }, + "a03637b1-a324-48e1-9b6f-06f030e2f3ba": { + "path": "ParentRunner.java", + "startLine": 66 + }, + "c6cf7f65-6407-4b51-91f0-76f223c36c62": { + "path": "BlockJUnit4ClassRunner.java", + "startLine": 103 + }, + "19b8ca48-b129-4503-99bc-da54738d3108": { + "path": "TestExecutor.java", + "startLine": 58 + } + }, + "threads": { + "profile saver": { + "fault": false, + "name": "profile saver", + "stack": [] + }, + "signal catcher": { + "fault": false, + "name": "signal catcher", + "stack": [] + }, + "finalizerwatchdogdaemon": { + "fault": false, + "name": "finalizerwatchdogdaemon", + "stack": [ + { + "funcName": "java.lang.Object.wait", + "sourceCode": "d71a2769-7f9d-48d2-bb69-f8a99742219a" + }, + { + "funcName": "java.lang.Object.wait", + "line": 442, + "sourceCode": "0710ca43-967f-4c85-865a-3ce24337a4d1" + }, + { + "funcName": "java.lang.Object.wait", + "line": 568, + "sourceCode": "38e624a4-5cce-4bc5-92bb-bf684f18792b" + }, + { + "funcName": "java.lang.Daemons$FinalizerWatchdogDaemon.sleepUntilNeeded", + "line": 341, + "sourceCode": "2b916c9d-3558-45bd-9bb0-b4436311451b" + }, + { + "funcName": "java.lang.Daemons$FinalizerWatchdogDaemon.runInternal", + "line": 321, + "sourceCode": "c35386b7-781a-4185-8817-eef78da6c429" + }, + { + "funcName": "java.lang.Daemons$Daemon.run", + "line": 139, + "sourceCode": "c9386136-04a8-485a-b8b9-95215d027013" + }, + { + "funcName": "java.lang.Thread.run", + "line": 923, + "sourceCode": "caea3885-ba11-4852-ad74-8585e064bb31" + } + ] + }, + "main": { + "fault": false, + "name": "main", + "stack": [ + { + "funcName": "android.os.MessageQueue.nativePollOnce", + "sourceCode": "00b5be47-8513-4f2e-a5d4-c711a58ce8ab" + }, + { + "funcName": "android.os.MessageQueue.next", + "line": 335, + "sourceCode": "caa8a790-c72a-479e-bc67-54139e01bdbe" + }, + { + "funcName": "android.os.Looper.loop", + "line": 183, + "sourceCode": "9f06bcf3-579d-4856-90f6-530eaeb97aed" + }, + { + "funcName": "android.app.ActivityThread.main", + "line": 7656, + "sourceCode": "6604ff49-6071-46ac-8f54-7b47f817b365" + }, + { + "funcName": "java.lang.reflect.Method.invoke", + "sourceCode": "c13bba6c-f9f1-4e43-84c6-a6cd6ab76bb4" + }, + { + "funcName": "com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run", + "line": 592, + "sourceCode": "c7255d95-3f41-422e-b491-19a60aa3f9db" + }, + { + "funcName": "com.android.internal.os.ZygoteInit.main", + "line": 947, + "sourceCode": "20e6b724-4a53-46ba-b949-979200eb2ec9" + } + ] + }, + "binder:11143_1": { + "fault": false, + "name": "binder:11143_1", + "stack": [] + }, + "binder:11143_2": { + "fault": false, + "name": "binder:11143_2", + "stack": [] + }, + "binder:11143_3": { + "fault": false, + "name": "binder:11143_3", + "stack": [] + }, + "finalizerdaemon": { + "fault": false, + "name": "finalizerdaemon", + "stack": [ + { + "funcName": "java.lang.Object.wait", + "sourceCode": "9632b2af-8ce2-4c58-855b-f9b308538457" + }, + { + "funcName": "java.lang.Object.wait", + "line": 442, + "sourceCode": "98bd4205-4ea6-4904-ac80-36c6b30ec1fe" + }, + { + "funcName": "java.lang.ref.ReferenceQueue.remove", + "line": 190, + "sourceCode": "779a86d7-754b-45a2-b75c-8095a1a8a92a" + }, + { + "funcName": "java.lang.ref.ReferenceQueue.remove", + "line": 211, + "sourceCode": "33d2d142-27da-4703-ae72-3064cbc5296c" + }, + { + "funcName": "java.lang.Daemons$FinalizerDaemon.runInternal", + "line": 273, + "sourceCode": "da999508-073c-4575-8564-d5b28643a4ff" + }, + { + "funcName": "java.lang.Daemons$Daemon.run", + "line": 139, + "sourceCode": "2c8faa9d-544a-4f03-8add-844f72ce88cc" + }, + { + "funcName": "java.lang.Thread.run", + "line": 923, + "sourceCode": "7f1d95d6-4c9d-493d-952c-1f3214ec6f13" + } + ] + }, + "referencequeuedaemon": { + "fault": false, + "name": "referencequeuedaemon", + "stack": [ + { + "funcName": "java.lang.Object.wait", + "sourceCode": "26071830-c698-441a-8658-ca585739125a" + }, + { + "funcName": "java.lang.Object.wait", + "line": 442, + "sourceCode": "be01c017-528d-4d0e-9ddb-304a6dabb97d" + }, + { + "funcName": "java.lang.Object.wait", + "line": 568, + "sourceCode": "b8074c19-2f7e-4b14-9440-d353a52e1a33" + }, + { + "funcName": "java.lang.Daemons$ReferenceQueueDaemon.runInternal", + "line": 217, + "sourceCode": "8038e8d8-b863-44e7-96be-86578bf7b81c" + }, + { + "funcName": "java.lang.Daemons$Daemon.run", + "line": 139, + "sourceCode": "48686825-013f-4cb8-8fff-95040fd7b184" + }, + { + "funcName": "java.lang.Thread.run", + "line": 923, + "sourceCode": "4c4e61d0-34c1-4011-9ddb-26fe16b66501" + } + ] + }, + "instrumentationconnectionthread": { + "fault": false, + "name": "instrumentationconnectionthread", + "stack": [ + { + "funcName": "android.os.MessageQueue.nativePollOnce", + "sourceCode": "1ba44e13-1bcd-4831-b880-a62f46085890" + }, + { + "funcName": "android.os.MessageQueue.next", + "line": 335, + "sourceCode": "f0ca2009-f11a-4976-a1f2-3ceb9ef6ce95" + }, + { + "funcName": "android.os.Looper.loop", + "line": 183, + "sourceCode": "1f3f81c7-2f6c-402b-8001-d1328c049ff4" + }, + { + "funcName": "android.os.HandlerThread.run", + "line": 67, + "sourceCode": "d2161b2c-5baf-47ec-a9b0-2e957704aab7" + } + ] + }, + "jit thread pool worker thread 0": { + "fault": false, + "name": "jit thread pool worker thread 0", + "stack": [] + }, + "instr: androidx.test.runner.androidjunitrunner": { + "fault": true, + "name": "instr: androidx.test.runner.androidjunitrunner", + "stack": [ + { + "funcName": "java.lang.reflect.Method.invoke", + "sourceCode": "d3a587b8-9d2c-4e70-9a0a-5a8257917d2d" + }, + { + "funcName": "org.junit.runners.model.FrameworkMethod$1.runReflectiveCall", + "line": 59, + "sourceCode": "4e282390-371b-4af4-b117-29398510be3a" + }, + { + "funcName": "org.junit.internal.runners.model.ReflectiveCallable.run", + "line": 12, + "sourceCode": "1ecb4287-1ad2-45a6-8450-af401cdbe17f" + }, + { + "funcName": "org.junit.runners.model.FrameworkMethod.invokeExplosively", + "line": 56, + "sourceCode": "4585edd4-5bf7-45e4-bb46-3f557b096852" + }, + { + "funcName": "org.junit.internal.runners.statements.InvokeMethod.evaluate", + "line": 17, + "sourceCode": "e9b5bfe9-f501-49c9-9621-02019e307488" + }, + { + "funcName": "org.junit.runners.ParentRunner$3.evaluate", + "line": 306, + "sourceCode": "def0b244-b5c3-4c68-9e4b-b5421888eee1" + }, + { + "funcName": "org.junit.runners.BlockJUnit4ClassRunner$1.evaluate", + "line": 100, + "sourceCode": "448f66cf-becf-4c83-9687-37eb9369a359" + }, + { + "funcName": "org.junit.runners.ParentRunner.runLeaf", + "line": 366, + "sourceCode": "bd559fdd-bd6f-44b6-a9b9-a14d865961d7" + }, + { + "funcName": "org.junit.runners.BlockJUnit4ClassRunner.runChild", + "line": 103, + "sourceCode": "c6cf7f65-6407-4b51-91f0-76f223c36c62" + }, + { + "funcName": "org.junit.runners.BlockJUnit4ClassRunner.runChild", + "line": 63, + "sourceCode": "3d9dcb46-6ac9-423e-8920-d0b5ec9c0f6d" + }, + { + "funcName": "org.junit.runners.ParentRunner$4.run", + "line": 331, + "sourceCode": "3e26748a-3965-4814-95a4-c474a701a15b" + }, + { + "funcName": "org.junit.runners.ParentRunner$1.schedule", + "line": 79, + "sourceCode": "dc715057-f108-4cc2-b4e8-f21aa2c4a75e" + }, + { + "funcName": "org.junit.runners.ParentRunner.runChildren", + "line": 329, + "sourceCode": "da3b40ad-d417-4f05-ae95-a7203478961d" + }, + { + "funcName": "org.junit.runners.ParentRunner.access$100", + "line": 66, + "sourceCode": "5e310bf1-ef77-449e-b523-bfb56d96cbc7" + }, + { + "funcName": "org.junit.runners.ParentRunner$2.evaluate", + "line": 293, + "sourceCode": "0ca32861-e9bb-4dd2-a38b-76bdb0be09e8" + }, + { + "funcName": "org.junit.runners.ParentRunner$3.evaluate", + "line": 306, + "sourceCode": "04520e56-5648-402d-99b5-434a8375e1b5" + }, + { + "funcName": "org.junit.runners.ParentRunner.run", + "line": 413, + "sourceCode": "e0eeb7ad-1024-4789-9fbe-4becb39e8420" + }, + { + "funcName": "androidx.test.ext.junit.runners.AndroidJUnit4.run", + "line": 162, + "sourceCode": "d6321483-6dc8-4ae5-95e8-c34ca2bfb660" + }, + { + "funcName": "org.junit.runners.Suite.runChild", + "line": 128, + "sourceCode": "8d478559-5a6f-412b-b854-3000e9adc98f" + }, + { + "funcName": "org.junit.runners.Suite.runChild", + "line": 27, + "sourceCode": "b47a8dd1-9c31-4793-805c-e33f9c77c818" + }, + { + "funcName": "org.junit.runners.ParentRunner$4.run", + "line": 331, + "sourceCode": "2068f2a4-9f0f-4854-bee9-cb398b7fd37f" + }, + { + "funcName": "org.junit.runners.ParentRunner$1.schedule", + "line": 79, + "sourceCode": "ef921e3c-bbc6-4d1f-a8ac-e9dfcc2b3d90" + }, + { + "funcName": "org.junit.runners.ParentRunner.runChildren", + "line": 329, + "sourceCode": "1549004b-d478-4341-87a2-4dea50ad031d" + }, + { + "funcName": "org.junit.runners.ParentRunner.access$100", + "line": 66, + "sourceCode": "a03637b1-a324-48e1-9b6f-06f030e2f3ba" + }, + { + "funcName": "org.junit.runners.ParentRunner$2.evaluate", + "line": 293, + "sourceCode": "5e3e29f7-7f77-4d4c-ae54-7a41caac90f4" + }, + { + "funcName": "org.junit.runners.ParentRunner$3.evaluate", + "line": 306, + "sourceCode": "295ccd27-4db2-487c-82f0-f255120cf593" + }, + { + "funcName": "org.junit.runners.ParentRunner.run", + "line": 413, + "sourceCode": "7aaec2ac-a43e-444b-b9ae-ad41ced28f33" + }, + { + "funcName": "org.junit.runner.JUnitCore.run", + "line": 137, + "sourceCode": "2bf04cc1-bb1e-47e2-a11b-c4bdea625413" + }, + { + "funcName": "org.junit.runner.JUnitCore.run", + "line": 115, + "sourceCode": "cb3283d2-d08f-4851-96fb-ec54aac63fd2" + }, + { + "funcName": "androidx.test.internal.runner.TestExecutor.execute", + "line": 67, + "sourceCode": "8ff34e56-9e08-4520-a87e-d7789785f013" + }, + { + "funcName": "androidx.test.internal.runner.TestExecutor.execute", + "line": 58, + "sourceCode": "19b8ca48-b129-4503-99bc-da54738d3108" + }, + { + "funcName": "androidx.test.runner.AndroidJUnitRunner.onStart", + "line": 446, + "sourceCode": "2517e7f8-fcec-44eb-a37c-c144fd441837" + }, + { + "funcName": "android.app.Instrumentation$InstrumentationThread.run", + "line": 2205, + "sourceCode": "b8437309-6989-4316-ab70-925d6fbc5135" + } + ] + }, + "heaptaskdaemon": { + "fault": false, + "name": "heaptaskdaemon", + "stack": [] + } + }, + "timestamp": 1694983723, + "uuid": "079e41e2-bef1-4062-9e20-f2e1b3a93582" } \ No newline at end of file From 79c1f08ae1e7a8aa36b932df01a7775e06450bfc Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Thu, 28 Sep 2023 23:23:53 +0200 Subject: [PATCH 010/100] Add naming converter to allow different casing on serialization --- .../common/BacktraceDataSerializerTest.java | 20 +++-- .../serializers/BacktraceDataSerializer.java | 45 +++-------- .../common/serializers/SerializerHelper.java | 77 ++++++++++++++----- .../naming/LowerCaseWithDashConverter.java | 11 +++ .../models/json/naming/NamingConverter.java | 5 ++ .../models/json/naming/NamingPolicy.java | 18 +++++ .../models/json/naming/NamingUtils.java | 15 ++++ 7 files changed, 135 insertions(+), 56 deletions(-) create mode 100644 backtrace-library/src/main/java/backtraceio/library/models/json/naming/LowerCaseWithDashConverter.java create mode 100644 backtrace-library/src/main/java/backtraceio/library/models/json/naming/NamingConverter.java create mode 100644 backtrace-library/src/main/java/backtraceio/library/models/json/naming/NamingPolicy.java create mode 100644 backtrace-library/src/main/java/backtraceio/library/models/json/naming/NamingUtils.java diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java index 2b821d5a..a734c76d 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java @@ -20,7 +20,13 @@ import backtraceio.library.common.serializers.BacktraceDataSerializer; import backtraceio.library.common.serializers.SerializerHelper; import backtraceio.library.models.BacktraceData; +import backtraceio.library.models.BacktraceResult; +import backtraceio.library.models.BacktraceStackFrame; import backtraceio.library.models.json.BacktraceReport; +import backtraceio.library.models.json.SourceCode; +import backtraceio.library.models.json.naming.LowerCaseWithDashConverter; +import backtraceio.library.models.json.naming.NamingPolicy; +import backtraceio.library.models.types.BacktraceResultStatus; @RunWith(AndroidJUnit4.class) public class BacktraceDataSerializerTest { @@ -33,7 +39,9 @@ public void testGsonSerializer() throws JSONException, IllegalAccessException { final Map attributes = new HashMap(); attributes.put("string-key", "string-value"); - attributes.put("string-key2", exception); + attributes.put("string-key-exception", exception); +// attributes.put("complex-obj-value", new BacktraceResult(null, "sample-msg", BacktraceResultStatus.Ok)); + attributes.put("complex-obj-source-cd", new StackTraceElement("sample.class", "some.method", "file",123)); final List attachments = new ArrayList<>(); attachments.add("test-path"); @@ -45,7 +53,8 @@ public void testGsonSerializer() throws JSONException, IllegalAccessException { final String jsonFromGson = BacktraceSerializeHelper.toJson(data); final BacktraceData dataGson = BacktraceSerializeHelper.fromJson(jsonFromGson, BacktraceData.class); - final String jsonFromOrgJson = BacktraceDataSerializer.toJson(data); + BacktraceDataSerializer serializer = new BacktraceDataSerializer(new NamingPolicy()); + final String jsonFromOrgJson = serializer.toJson(data); // THEN assertEquals(jsonFromOrgJson, jsonFromGson); @@ -61,10 +70,10 @@ public void temp() throws JSONException { r.toString(); } catch (Exception e) { - Object result2 = SerializerHelper.serialize(e); + Object result2 = SerializerHelper.serialize(null, e); System.out.println(result2); } - Object result = SerializerHelper.serialize(new BacktraceReport("test")); + Object result = SerializerHelper.serialize(null, new BacktraceReport("test")); System.out.println(result); // } } @@ -100,7 +109,8 @@ public void testGsonPerformanceSerializer() throws JSONException, IllegalAccessE // ORG JSON long startTimeOrg = System.currentTimeMillis(); - BacktraceDataSerializer.toJson(data); + BacktraceDataSerializer serializer = new BacktraceDataSerializer(new NamingPolicy()); + serializer.toJson( data); long endTimeOrg = System.currentTimeMillis(); timeOrgJson += endTimeOrg - startTimeOrg; } diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java index a25924aa..e4292344 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java @@ -22,37 +22,16 @@ import backtraceio.library.models.BacktraceStackFrame; import backtraceio.library.models.json.SourceCode; import backtraceio.library.models.json.ThreadInformation; +import backtraceio.library.models.json.naming.NamingPolicy; public class BacktraceDataSerializer { - - public static Map executeAndGetMethods(Object obj) { - Class clazz = obj.getClass(); - Map fields = new HashMap<>(); - Method[] methods = clazz.getMethods(); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // TODO: check if needed - for (Method method : methods) { - String methodName = method.getName(); - - if (methodName.equals("getClass")) { - continue; - } - - if (methodName.startsWith("get") && method.getParameterCount() == 0) { - try { - Object result = method.invoke(obj); - String propertyName = methodName.substring(3); // Remove 'get' prefix - fields.put(decapitalizeString(propertyName), serialize(result)); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - } - return fields; + NamingPolicy namingPolicy; + public BacktraceDataSerializer(NamingPolicy policy) { + namingPolicy = policy; } - public static String toJson(BacktraceData data) throws JSONException, IllegalAccessException { + + public String toJson(BacktraceData data) throws JSONException, IllegalAccessException { { JSONObject json = new JSONObject(); @@ -97,7 +76,7 @@ public static String toJson(BacktraceData data) throws JSONException, IllegalAcc } @NonNull - private static JSONObject serializeThreadInformation(Map threadInformationMap) throws JSONException { + private JSONObject serializeThreadInformation(Map threadInformationMap) throws JSONException { JSONObject threadInformationJson = new JSONObject(); for (Map.Entry entry : threadInformationMap.entrySet()) { ThreadInformation threadInfo = entry.getValue(); @@ -114,7 +93,7 @@ private static JSONObject serializeThreadInformation(Map stack) throws JSONException { + private JSONArray serializeStackList(ArrayList stack) throws JSONException { JSONArray stackArray = new JSONArray(); for (BacktraceStackFrame stackFrame : stack) { @@ -129,7 +108,7 @@ private static JSONArray serializeStackList(ArrayList stack } @NonNull - private static JSONObject serializeSourceCode(Map sourceCodeMap) throws JSONException { + private JSONObject serializeSourceCode(Map sourceCodeMap) throws JSONException { JSONObject sourceCodeJson = new JSONObject(); for (Map.Entry entry : sourceCodeMap.entrySet()) { SourceCode sourceCode = entry.getValue(); @@ -141,15 +120,15 @@ private static JSONObject serializeSourceCode(Map sourceCode return sourceCodeJson; } - private static JSONObject serializeAnnotations(Map annotations) throws JSONException, IllegalAccessException { + private JSONObject serializeAnnotations(Map annotations) throws JSONException, IllegalAccessException { JSONObject annotationsJson = new JSONObject(); for (Map.Entry entry : annotations.entrySet()) { - annotationsJson.put(entry.getKey(), serialize(entry.getValue())); + annotationsJson.put(entry.getKey(), serialize(this.namingPolicy, entry.getValue())); } return annotationsJson; } - private static JSONObject serializeAttributes(Map attributes) throws JSONException { + private JSONObject serializeAttributes(Map attributes) throws JSONException { JSONObject attributesJson = new JSONObject(); for (Map.Entry entry : attributes.entrySet()) { diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java index 13872097..d8cd55b4 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java @@ -1,12 +1,13 @@ package backtraceio.library.common.serializers; -import static backtraceio.library.common.serializers.BacktraceDataSerializer.executeAndGetMethods; +import android.os.Build; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -14,6 +15,8 @@ import java.util.List; import java.util.Map; +import backtraceio.library.models.json.naming.NamingPolicy; + public class SerializerHelper { public static int MAX_SERIALIZATION_LEVEL = 5; private static final Map, Class> WRAPPER_TYPE_MAP; @@ -39,22 +42,29 @@ public static String decapitalizeString(String string) { return string == null || string.isEmpty() ? "" : Character.toLowerCase(string.charAt(0)) + string.substring(1); } - private static JSONArray serializeArray(Object[] array, int serializationDepth) throws JSONException { + private static JSONArray serializeArray(NamingPolicy namingPolicy, Object[] array, int serializationDepth) throws JSONException { JSONArray jsonArray = new JSONArray(); for (Object item : array) { - jsonArray.put(serialize(item, serializationDepth)); + jsonArray.put(serialize(namingPolicy, item, serializationDepth)); } return jsonArray; } - private static JSONArray serializeCollection(Collection collection, int serializationDepth) throws JSONException { + private static JSONArray serializeCollection(NamingPolicy namingPolicy, Collection collection, int serializationDepth) throws JSONException { JSONArray jsonArray = new JSONArray(); for (Object item : collection) { - jsonArray.put(serialize(item, serializationDepth)); + jsonArray.put(serialize(namingPolicy, item, serializationDepth)); } return jsonArray; } - private static JSONObject getAllFields(Class klass, Object obj, int serializationDepth) { + private static JSONObject serializeException(Exception exception) { + JSONObject obj = new JSONObject(); + +// obj.put(); + return obj; + } + + private static JSONObject getAllFields(NamingPolicy namingPolicy, Class klass, Object obj, int serializationDepth) { // TODO: improve naming List fields = new ArrayList<>(); @@ -71,7 +81,7 @@ private static JSONObject getAllFields(Class klass, Object obj, int serializa if (value == obj) { continue; } - result.put(f.getName(), serialize(value, serializationDepth)); + result.put(namingPolicy.convert(f.getName()), serialize(namingPolicy, value, serializationDepth)); } catch (Exception ex) { // ex.printStackTrace(); } @@ -83,21 +93,48 @@ private static JSONObject getAllFields(Class klass, Object obj, int serializa return result; } - private static JSONObject serializeMap(Map map, int serializationDepth) throws JSONException { + private static JSONObject serializeMap(NamingPolicy namingPolicy, Map map, int serializationDepth) throws JSONException { JSONObject jsonObject = new JSONObject(); for (Map.Entry entry : map.entrySet()) { String key = String.valueOf(entry.getKey()); Object value = entry.getValue(); - jsonObject.put(key, serialize(value, serializationDepth)); + jsonObject.put(key, serialize(namingPolicy, value, serializationDepth)); } return jsonObject; } - public static Object serialize(Object obj) throws JSONException { - return serialize(obj, 0); + public static Object serialize(NamingPolicy namingPolicy, Object obj) throws JSONException { + return serialize(namingPolicy, obj, 0); } - public static Object serialize(Object obj, int serializationDepth) throws JSONException { + public static Map executeAndGetMethods(NamingPolicy namingPolicy, Object obj) { + Class clazz = obj.getClass(); + Map fields = new HashMap<>(); + Method[] methods = clazz.getMethods(); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // TODO: check if needed + for (Method method : methods) { + String methodName = method.getName(); + + if (methodName.equals("getClass") || methodName.equals("getClassName")) { + continue; + } + + if (methodName.startsWith("get") && method.getParameterCount() == 0) { + try { + Object result = method.invoke(obj); + String propertyName = methodName.substring(3); // Remove 'get' prefix + fields.put(namingPolicy.convert(propertyName), serialize(namingPolicy, result)); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + return fields; + } + + public static Object serialize(NamingPolicy namingPolicy, Object obj, int serializationDepth) throws JSONException { if (obj == null) { return null; } @@ -114,23 +151,27 @@ public static Object serialize(Object obj, int serializationDepth) throws JSONEx serializationDepth++; if (obj instanceof Map) { - return serializeMap((Map) obj, serializationDepth); + return serializeMap(namingPolicy, (Map) obj, serializationDepth); } if (obj.getClass().isArray()) { - return serializeArray((Object[]) obj, serializationDepth); + return serializeArray(namingPolicy, (Object[]) obj, serializationDepth); } if (obj instanceof Collection) { - return serializeCollection((Collection) obj, serializationDepth); + return serializeCollection(namingPolicy, (Collection) obj, serializationDepth); + } + + if (obj instanceof Exception) { +// return serializeException((Exception) obj); } Class clazz = obj.getClass(); - JSONObject jsonObject = getAllFields(clazz, obj, serializationDepth); - Map getters = executeAndGetMethods(obj); + JSONObject jsonObject = getAllFields(namingPolicy, clazz, obj, serializationDepth); + Map getters = executeAndGetMethods(namingPolicy, obj); for (Map.Entry entry: getters.entrySet()) { - jsonObject.put(entry.getKey(), entry.getValue()); + jsonObject.put(namingPolicy.convert(entry.getKey()), entry.getValue()); } return jsonObject; diff --git a/backtrace-library/src/main/java/backtraceio/library/models/json/naming/LowerCaseWithDashConverter.java b/backtrace-library/src/main/java/backtraceio/library/models/json/naming/LowerCaseWithDashConverter.java new file mode 100644 index 00000000..dc4b0858 --- /dev/null +++ b/backtrace-library/src/main/java/backtraceio/library/models/json/naming/LowerCaseWithDashConverter.java @@ -0,0 +1,11 @@ +package backtraceio.library.models.json.naming; + +import static backtraceio.library.models.json.naming.NamingUtils.separateCamelCase; + +import java.util.Locale; + +public class LowerCaseWithDashConverter implements NamingConverter { + public String convert(String value) { + return separateCamelCase(value, '-').toLowerCase(Locale.ENGLISH); + } +} diff --git a/backtrace-library/src/main/java/backtraceio/library/models/json/naming/NamingConverter.java b/backtrace-library/src/main/java/backtraceio/library/models/json/naming/NamingConverter.java new file mode 100644 index 00000000..467856f3 --- /dev/null +++ b/backtrace-library/src/main/java/backtraceio/library/models/json/naming/NamingConverter.java @@ -0,0 +1,5 @@ +package backtraceio.library.models.json.naming; + +public interface NamingConverter { + String convert(String value); +} diff --git a/backtrace-library/src/main/java/backtraceio/library/models/json/naming/NamingPolicy.java b/backtrace-library/src/main/java/backtraceio/library/models/json/naming/NamingPolicy.java new file mode 100644 index 00000000..36b721f1 --- /dev/null +++ b/backtrace-library/src/main/java/backtraceio/library/models/json/naming/NamingPolicy.java @@ -0,0 +1,18 @@ +package backtraceio.library.models.json.naming; + +public class NamingPolicy implements NamingConverter { + NamingConverter instance; + + public NamingPolicy() { + this(new LowerCaseWithDashConverter()); + } + + public NamingPolicy(NamingConverter namingConverter) { + this.instance = namingConverter; + } + + @Override + public String convert(String value) { + return instance.convert(value); + } +} diff --git a/backtrace-library/src/main/java/backtraceio/library/models/json/naming/NamingUtils.java b/backtrace-library/src/main/java/backtraceio/library/models/json/naming/NamingUtils.java new file mode 100644 index 00000000..0541b25c --- /dev/null +++ b/backtrace-library/src/main/java/backtraceio/library/models/json/naming/NamingUtils.java @@ -0,0 +1,15 @@ +package backtraceio.library.models.json.naming; + +public class NamingUtils { + static String separateCamelCase(String name, char separator) { + StringBuilder translation = new StringBuilder(); + for (int i = 0, length = name.length(); i < length; i++) { + char character = name.charAt(i); + if (Character.isUpperCase(character) && translation.length() != 0) { + translation.append(separator); + } + translation.append(character); + } + return translation.toString(); + } +} From 3943c3246c13b9846e2e3ef840c00ef43ee2fd79 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 4 Oct 2023 23:43:57 +0200 Subject: [PATCH 011/100] Fix gson differences --- .../common/BacktraceDataSerializerTest.java | 10 ++++++--- .../common/BacktraceSerializationUtils.java | 14 ++++++++++++ .../serializers/BacktraceDataSerializer.java | 6 ++--- .../common/serializers/SerializerHelper.java | 22 ++++++++++++++++--- 4 files changed, 43 insertions(+), 9 deletions(-) create mode 100644 backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceSerializationUtils.java diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java index a734c76d..858f1001 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java @@ -1,6 +1,9 @@ package backtraceio.library.common; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import static backtraceio.library.common.BacktraceSerializationUtils.jsonEquals; import android.content.Context; @@ -42,7 +45,7 @@ public void testGsonSerializer() throws JSONException, IllegalAccessException { attributes.put("string-key-exception", exception); // attributes.put("complex-obj-value", new BacktraceResult(null, "sample-msg", BacktraceResultStatus.Ok)); attributes.put("complex-obj-source-cd", new StackTraceElement("sample.class", "some.method", "file",123)); - +//exception.getSuppressed() final List attachments = new ArrayList<>(); attachments.add("test-path"); attachments.add("test-path2"); @@ -57,7 +60,8 @@ public void testGsonSerializer() throws JSONException, IllegalAccessException { final String jsonFromOrgJson = serializer.toJson(data); // THEN - assertEquals(jsonFromOrgJson, jsonFromGson); + assertTrue(jsonEquals(jsonFromOrgJson, jsonFromGson)); +// assertEquals(jsonFromOrgJson, jsonFromGson); } @Test @@ -84,7 +88,7 @@ public void testGsonPerformanceSerializer() throws JSONException, IllegalAccessE final Context context = InstrumentationRegistry.getInstrumentation().getContext(); long timeGson = 0; long timeOrgJson = 0; - final int iterations = 1; + final int iterations = 1000; for (int i = 0; i < iterations; i++) { // INIT SAMPLE final Exception exception = new Exception(Integer.toString(i)); diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceSerializationUtils.java b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceSerializationUtils.java new file mode 100644 index 00000000..620df0e6 --- /dev/null +++ b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceSerializationUtils.java @@ -0,0 +1,14 @@ +package backtraceio.library.common; + +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; + +public class BacktraceSerializationUtils { + + public static boolean jsonEquals(String json1, String json2) { + JsonParser parser = new JsonParser(); + JsonElement o1 = parser.parse(json1); + JsonElement o2 = parser.parse(json2); + return o1.equals(o2); + } +} diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java index e4292344..d14037f6 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java @@ -7,6 +7,7 @@ import androidx.annotation.NonNull; + import com.google.gson.JsonArray; import org.json.JSONArray; @@ -46,10 +47,9 @@ public String toJson(BacktraceData data) throws JSONException, IllegalAccessExce json.put("mainThread", data.mainThread); if (data.classifiers != null) { - final JsonArray classifiers = new JsonArray(); - + final JSONArray classifiers = new JSONArray(); for (String classifier : data.classifiers) { - classifiers.add(classifier); + classifiers.put(classifier); } json.put("classifiers", classifiers); } diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java index d8cd55b4..04e24882 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java @@ -43,6 +43,10 @@ public static String decapitalizeString(String string) { } private static JSONArray serializeArray(NamingPolicy namingPolicy, Object[] array, int serializationDepth) throws JSONException { + if (array == null) { + return null; + } + JSONArray jsonArray = new JSONArray(); for (Object item : array) { jsonArray.put(serialize(namingPolicy, item, serializationDepth)); @@ -50,6 +54,10 @@ private static JSONArray serializeArray(NamingPolicy namingPolicy, Object[] arra return jsonArray; } private static JSONArray serializeCollection(NamingPolicy namingPolicy, Collection collection, int serializationDepth) throws JSONException { + if (collection == null) { + return null; + } + JSONArray jsonArray = new JSONArray(); for (Object item : collection) { jsonArray.put(serialize(namingPolicy, item, serializationDepth)); @@ -57,11 +65,18 @@ private static JSONArray serializeCollection(NamingPolicy namingPolicy, Collecti return jsonArray; } - private static JSONObject serializeException(Exception exception) { - JSONObject obj = new JSONObject(); + private static Object serializeException(NamingPolicy namingPolicy, Exception exception) { +// JSONObject obj = new JSONObject(); + try { + return getAllFields(namingPolicy, exception.getClass(), exception, 2); +// return serialize(namingPolicy, exception.getCause()); + } + catch (Exception e) { + return null; + } // obj.put(); - return obj; +// return obj; } private static JSONObject getAllFields(NamingPolicy namingPolicy, Class klass, Object obj, int serializationDepth) { @@ -163,6 +178,7 @@ public static Object serialize(NamingPolicy namingPolicy, Object obj, int serial } if (obj instanceof Exception) { + return serializeException(namingPolicy, (Exception) obj); // return serializeException((Exception) obj); } From 5af11bdfeb45fedbaa1cec8761ef7092dea8278c Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Mon, 9 Oct 2023 23:20:34 +0200 Subject: [PATCH 012/100] Json org serializer tests --- .../common/BacktraceDataSerializerTest.java | 11 +-- .../library/common/SerializerHelperTest.java | 76 +++++++++++++++++++ .../serializers/BacktraceDataSerializer.java | 9 +-- .../common/serializers/SerializerHelper.java | 2 +- .../naming/LowerCaseWithDashConverter.java | 4 +- .../serializers}/naming/NamingConverter.java | 2 +- .../serializers}/naming/NamingPolicy.java | 2 +- .../serializers}/naming/NamingUtils.java | 2 +- 8 files changed, 85 insertions(+), 23 deletions(-) create mode 100644 backtrace-library/src/androidTest/java/backtraceio/library/common/SerializerHelperTest.java rename backtrace-library/src/main/java/backtraceio/library/{models/json => common/serializers}/naming/LowerCaseWithDashConverter.java (60%) rename backtrace-library/src/main/java/backtraceio/library/{models/json => common/serializers}/naming/NamingConverter.java (56%) rename backtrace-library/src/main/java/backtraceio/library/{models/json => common/serializers}/naming/NamingPolicy.java (87%) rename backtrace-library/src/main/java/backtraceio/library/{models/json => common/serializers}/naming/NamingUtils.java (90%) diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java index 858f1001..d8ee85f8 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java @@ -11,7 +11,6 @@ import androidx.test.platform.app.InstrumentationRegistry; import org.json.JSONException; -import org.json.JSONObject; import org.junit.Test; import org.junit.runner.RunWith; @@ -23,13 +22,8 @@ import backtraceio.library.common.serializers.BacktraceDataSerializer; import backtraceio.library.common.serializers.SerializerHelper; import backtraceio.library.models.BacktraceData; -import backtraceio.library.models.BacktraceResult; -import backtraceio.library.models.BacktraceStackFrame; import backtraceio.library.models.json.BacktraceReport; -import backtraceio.library.models.json.SourceCode; -import backtraceio.library.models.json.naming.LowerCaseWithDashConverter; -import backtraceio.library.models.json.naming.NamingPolicy; -import backtraceio.library.models.types.BacktraceResultStatus; +import backtraceio.library.common.serializers.naming.NamingPolicy; @RunWith(AndroidJUnit4.class) public class BacktraceDataSerializerTest { @@ -45,7 +39,7 @@ public void testGsonSerializer() throws JSONException, IllegalAccessException { attributes.put("string-key-exception", exception); // attributes.put("complex-obj-value", new BacktraceResult(null, "sample-msg", BacktraceResultStatus.Ok)); attributes.put("complex-obj-source-cd", new StackTraceElement("sample.class", "some.method", "file",123)); -//exception.getSuppressed() + final List attachments = new ArrayList<>(); attachments.add("test-path"); attachments.add("test-path2"); @@ -61,7 +55,6 @@ public void testGsonSerializer() throws JSONException, IllegalAccessException { // THEN assertTrue(jsonEquals(jsonFromOrgJson, jsonFromGson)); -// assertEquals(jsonFromOrgJson, jsonFromGson); } @Test diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/common/SerializerHelperTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/common/SerializerHelperTest.java new file mode 100644 index 00000000..dbc09f5d --- /dev/null +++ b/backtrace-library/src/androidTest/java/backtraceio/library/common/SerializerHelperTest.java @@ -0,0 +1,76 @@ +package backtraceio.library.common; + +import static junit.framework.TestCase.assertEquals; +import static junit.framework.TestCase.assertNotNull; + +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.json.JSONException; +import org.json.JSONObject; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.ArrayList; +import java.util.List; + +import backtraceio.library.common.serializers.SerializerHelper; +import backtraceio.library.common.serializers.naming.NamingPolicy; + +@RunWith(AndroidJUnit4.class) +public class SerializerHelperTest { + public final static NamingPolicy namingPolicy = new NamingPolicy(); + + @Test + public void serializeList() throws JSONException { + // GIVEN + final List list = new ArrayList() {{ + add(1); + add(2); + add(3); + }}; + // WHEN + JSONObject result = (JSONObject) SerializerHelper.serialize(namingPolicy, list); + + // THEN + assertEquals(result.length(), 3); + assertEquals(result.length(), 3); + + } + + public void serializeObjectList() { + + } + + public void serializeJSONObject() { + + } + + public void testIsPrimitiveType() { + + } + + public void testDecapitalizeString () { + + } + + public void serializeMap() { + + } + + public void serializeObject() { + + } + + public void serializeException() throws JSONException { + // GIVEN + final ArrayIndexOutOfBoundsException exception = new ArrayIndexOutOfBoundsException("test"); + + // WHEN + JSONObject result = (JSONObject) SerializerHelper.serialize(namingPolicy, exception); + + // THEN + assertNotNull(result); + + assertEquals(result.get("message"), "test"); + } +} diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java index d14037f6..285328f0 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java @@ -1,29 +1,22 @@ package backtraceio.library.common.serializers; -import static backtraceio.library.common.serializers.SerializerHelper.decapitalizeString; import static backtraceio.library.common.serializers.SerializerHelper.serialize; -import android.os.Build; - import androidx.annotation.NonNull; -import com.google.gson.JsonArray; - import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; -import java.lang.reflect.Method; import java.util.ArrayList; -import java.util.HashMap; import java.util.Map; import backtraceio.library.models.BacktraceData; import backtraceio.library.models.BacktraceStackFrame; import backtraceio.library.models.json.SourceCode; import backtraceio.library.models.json.ThreadInformation; -import backtraceio.library.models.json.naming.NamingPolicy; +import backtraceio.library.common.serializers.naming.NamingPolicy; public class BacktraceDataSerializer { NamingPolicy namingPolicy; diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java index 04e24882..3488457e 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java @@ -15,7 +15,7 @@ import java.util.List; import java.util.Map; -import backtraceio.library.models.json.naming.NamingPolicy; +import backtraceio.library.common.serializers.naming.NamingPolicy; public class SerializerHelper { public static int MAX_SERIALIZATION_LEVEL = 5; diff --git a/backtrace-library/src/main/java/backtraceio/library/models/json/naming/LowerCaseWithDashConverter.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/naming/LowerCaseWithDashConverter.java similarity index 60% rename from backtrace-library/src/main/java/backtraceio/library/models/json/naming/LowerCaseWithDashConverter.java rename to backtrace-library/src/main/java/backtraceio/library/common/serializers/naming/LowerCaseWithDashConverter.java index dc4b0858..65ca47dd 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/json/naming/LowerCaseWithDashConverter.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/naming/LowerCaseWithDashConverter.java @@ -1,6 +1,6 @@ -package backtraceio.library.models.json.naming; +package backtraceio.library.common.serializers.naming; -import static backtraceio.library.models.json.naming.NamingUtils.separateCamelCase; +import static backtraceio.library.common.serializers.naming.NamingUtils.separateCamelCase; import java.util.Locale; diff --git a/backtrace-library/src/main/java/backtraceio/library/models/json/naming/NamingConverter.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/naming/NamingConverter.java similarity index 56% rename from backtrace-library/src/main/java/backtraceio/library/models/json/naming/NamingConverter.java rename to backtrace-library/src/main/java/backtraceio/library/common/serializers/naming/NamingConverter.java index 467856f3..fc179285 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/json/naming/NamingConverter.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/naming/NamingConverter.java @@ -1,4 +1,4 @@ -package backtraceio.library.models.json.naming; +package backtraceio.library.common.serializers.naming; public interface NamingConverter { String convert(String value); diff --git a/backtrace-library/src/main/java/backtraceio/library/models/json/naming/NamingPolicy.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/naming/NamingPolicy.java similarity index 87% rename from backtrace-library/src/main/java/backtraceio/library/models/json/naming/NamingPolicy.java rename to backtrace-library/src/main/java/backtraceio/library/common/serializers/naming/NamingPolicy.java index 36b721f1..44dcd8a3 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/json/naming/NamingPolicy.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/naming/NamingPolicy.java @@ -1,4 +1,4 @@ -package backtraceio.library.models.json.naming; +package backtraceio.library.common.serializers.naming; public class NamingPolicy implements NamingConverter { NamingConverter instance; diff --git a/backtrace-library/src/main/java/backtraceio/library/models/json/naming/NamingUtils.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/naming/NamingUtils.java similarity index 90% rename from backtrace-library/src/main/java/backtraceio/library/models/json/naming/NamingUtils.java rename to backtrace-library/src/main/java/backtraceio/library/common/serializers/naming/NamingUtils.java index 0541b25c..fea736dc 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/json/naming/NamingUtils.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/naming/NamingUtils.java @@ -1,4 +1,4 @@ -package backtraceio.library.models.json.naming; +package backtraceio.library.common.serializers.naming; public class NamingUtils { static String separateCamelCase(String name, char separator) { From 9aa36f238f28f387e36e0dfec57e21802215308c Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Tue, 17 Oct 2023 21:36:15 +0200 Subject: [PATCH 013/100] Add unit tests, code refactor --- .../PrimitiveTypeSerializerHelperTest.java | 50 +++++++++++++++++++ .../library/common/SerializerHelperTest.java | 46 +++++++++++++---- .../common/serializers/SerializerHelper.java | 10 ---- 3 files changed, 85 insertions(+), 21 deletions(-) create mode 100644 backtrace-library/src/androidTest/java/backtraceio/library/common/PrimitiveTypeSerializerHelperTest.java diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/common/PrimitiveTypeSerializerHelperTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/common/PrimitiveTypeSerializerHelperTest.java new file mode 100644 index 00000000..5fdcf202 --- /dev/null +++ b/backtrace-library/src/androidTest/java/backtraceio/library/common/PrimitiveTypeSerializerHelperTest.java @@ -0,0 +1,50 @@ +package backtraceio.library.common; + +import static junit.framework.TestCase.assertEquals; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; + +import backtraceio.library.common.serializers.SerializerHelper; + +@RunWith(Parameterized.class) +public class PrimitiveTypeSerializerHelperTest { + private Object testedObj; + private boolean expectedResult; + + // Constructor for the parameterized test + public PrimitiveTypeSerializerHelperTest(Object testedObj, boolean expectedResult) { + this.testedObj = testedObj; + this.expectedResult = expectedResult; + } + + @Parameterized.Parameters + public static Collection data() { + return Arrays.asList(new Object[][]{ + {1, true}, // int + {1L, true}, // long + {1.0f, true}, // float + {'c', true}, // char + {"test", true}, // string + {1.5, true}, // double + {new Object(), false}, // object + {new Exception("test"), false}, // object exception + {new ArrayList<>(), false}, // array list + {new HashMap<>(), false} // hash map + }); + } + @Test + public void testIsPrimitiveType() { + // WHEN + boolean result = SerializerHelper.isPrimitiveType(testedObj); + + // THEN + assertEquals(expectedResult, result); + } +} diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/common/SerializerHelperTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/common/SerializerHelperTest.java index dbc09f5d..5c960b20 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/common/SerializerHelperTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/common/SerializerHelperTest.java @@ -5,6 +5,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; +import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.junit.Test; @@ -15,11 +16,15 @@ import backtraceio.library.common.serializers.SerializerHelper; import backtraceio.library.common.serializers.naming.NamingPolicy; +import backtraceio.library.models.BacktraceStackFrame; +import backtraceio.library.models.json.SourceCode; @RunWith(AndroidJUnit4.class) public class SerializerHelperTest { public final static NamingPolicy namingPolicy = new NamingPolicy(); + + @Test public void serializeList() throws JSONException { // GIVEN @@ -29,29 +34,47 @@ public void serializeList() throws JSONException { add(3); }}; // WHEN - JSONObject result = (JSONObject) SerializerHelper.serialize(namingPolicy, list); + JSONArray result = (JSONArray) SerializerHelper.serialize(namingPolicy, list); // THEN + assertEquals("[1,2,3]", result.toString()); assertEquals(result.length(), 3); - assertEquals(result.length(), 3); - } - public void serializeObjectList() { - - } + @Test + public void serializeObjectList() throws JSONException { + // GIVEN + final SourceCode sourceCode = new SourceCode(new BacktraceStackFrame(new StackTraceElement("sample-class", "sample-method", "sample-file", 123))); - public void serializeJSONObject() { + // WHEN + JSONObject jsonObject = (JSONObject) SerializerHelper.serialize(namingPolicy, sourceCode); + // THEN + assertEquals("{\"startLine\": 123, \"path\": \"sample-file\" }", jsonObject.toString()); } - public void testIsPrimitiveType() { + @Test + public void serializeJSONObject() throws JSONException { + // GIVEN + final JSONObject jsonObject = new JSONObject(); + jsonObject.put("sample-int", 1); + jsonObject.put("sample-boolean", true); + jsonObject.put("sample-string", "example"); + jsonObject.put("sample-array", new ArrayList(){{ + add("1"); + add("2"); + add("3"); + }}); + jsonObject.put("sample-exception", new Exception("msg")); + + // WHEN + final JSONObject result = (JSONObject) SerializerHelper.serialize(namingPolicy, jsonObject); + // THEN + assertEquals("", result.toString()); // TODO: } - public void testDecapitalizeString () { - } public void serializeMap() { @@ -71,6 +94,7 @@ public void serializeException() throws JSONException { // THEN assertNotNull(result); - assertEquals(result.get("message"), "test"); + assertEquals("test", result.get("message")); + assertEquals("\"message\":\"test\"", result.toString()); } } diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java index 3488457e..dfb6ab05 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java @@ -38,10 +38,6 @@ public static boolean isPrimitiveType(Object source) { return WRAPPER_TYPE_MAP.containsKey(source.getClass()) || source instanceof String || source instanceof Number; } - public static String decapitalizeString(String string) { - return string == null || string.isEmpty() ? "" : Character.toLowerCase(string.charAt(0)) + string.substring(1); - } - private static JSONArray serializeArray(NamingPolicy namingPolicy, Object[] array, int serializationDepth) throws JSONException { if (array == null) { return null; @@ -66,17 +62,12 @@ private static JSONArray serializeCollection(NamingPolicy namingPolicy, Collecti } private static Object serializeException(NamingPolicy namingPolicy, Exception exception) { -// JSONObject obj = new JSONObject(); try { - return getAllFields(namingPolicy, exception.getClass(), exception, 2); -// return serialize(namingPolicy, exception.getCause()); } catch (Exception e) { return null; } -// obj.put(); -// return obj; } private static JSONObject getAllFields(NamingPolicy namingPolicy, Class klass, Object obj, int serializationDepth) { @@ -179,7 +170,6 @@ public static Object serialize(NamingPolicy namingPolicy, Object obj, int serial if (obj instanceof Exception) { return serializeException(namingPolicy, (Exception) obj); -// return serializeException((Exception) obj); } Class clazz = obj.getClass(); From 78fcdc068d2cea35ed5ee271db741397d2d1560b Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Tue, 17 Oct 2023 23:32:00 +0200 Subject: [PATCH 014/100] Add unit tests for naming converter --- .../library/common/SerializerHelperTest.java | 35 ++++++++-- .../LowerCaseWithDashConverterTest.java | 64 +++++++++++++++++++ .../serializers/naming/NamingUtilsTest.java | 54 ++++++++++++++++ .../common/serializers/SerializerHelper.java | 14 +++- .../naming/LowerCaseWithDashConverter.java | 3 + .../serializers/naming/NamingUtils.java | 3 + 6 files changed, 165 insertions(+), 8 deletions(-) create mode 100644 backtrace-library/src/androidTest/java/backtraceio/library/common/serializers/naming/LowerCaseWithDashConverterTest.java create mode 100644 backtrace-library/src/androidTest/java/backtraceio/library/common/serializers/naming/NamingUtilsTest.java diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/common/SerializerHelperTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/common/SerializerHelperTest.java index 5c960b20..d006b024 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/common/SerializerHelperTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/common/SerializerHelperTest.java @@ -12,7 +12,9 @@ import org.junit.runner.RunWith; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import backtraceio.library.common.serializers.SerializerHelper; import backtraceio.library.common.serializers.naming.NamingPolicy; @@ -23,8 +25,6 @@ public class SerializerHelperTest { public final static NamingPolicy namingPolicy = new NamingPolicy(); - - @Test public void serializeList() throws JSONException { // GIVEN @@ -42,7 +42,7 @@ public void serializeList() throws JSONException { } @Test - public void serializeObjectList() throws JSONException { + public void serializeObject() throws JSONException { // GIVEN final SourceCode sourceCode = new SourceCode(new BacktraceStackFrame(new StackTraceElement("sample-class", "sample-method", "sample-file", 123))); @@ -50,7 +50,7 @@ public void serializeObjectList() throws JSONException { JSONObject jsonObject = (JSONObject) SerializerHelper.serialize(namingPolicy, sourceCode); // THEN - assertEquals("{\"startLine\": 123, \"path\": \"sample-file\" }", jsonObject.toString()); + assertEquals("{\"path\":\"sample-file\",\"startLine\":123}", jsonObject.toString()); } @Test @@ -71,17 +71,38 @@ public void serializeJSONObject() throws JSONException { final JSONObject result = (JSONObject) SerializerHelper.serialize(namingPolicy, jsonObject); // THEN - assertEquals("", result.toString()); // TODO: + final String expectedJson = "{\"name-value-pairs\":{\"sample-int\":1,\"sample-boolean\":true,\"sample-string\":\"example\",\"sample-array\":[\"1\",\"2\",\"3\"],\"sample-exception\":{\"detail-message\":\"msg\",\"stack-trace\":[],\"suppressed-exceptions\":[]}}}"; + assertEquals(expectedJson, result.toString()); // TODO: } - public void serializeMap() { + public void serializeMap() throws JSONException { + // GIVEN + Map object = new HashMap<>(); + object.put("string-value", "123"); + object.put("int-value", 123); + object.put("boolean-value", false); + object.put("exception-value", new Exception("test")); + + // WHEN + final JSONObject result = (JSONObject) SerializerHelper.serialize(namingPolicy, object); + // THEN + assertEquals("", result.toString()); } - public void serializeObject() { + public void serializeObjectList() throws JSONException { + // GIVEN + List objList = new ArrayList<>(); + objList.add(new Exception("1")); + objList.add(new Exception("2")); + objList.add(new Exception("3")); + // WHEN + final JSONObject result = (JSONObject) SerializerHelper.serialize(namingPolicy, objList); + // THEN + assertEquals("", result.toString()); } public void serializeException() throws JSONException { diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/common/serializers/naming/LowerCaseWithDashConverterTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/common/serializers/naming/LowerCaseWithDashConverterTest.java new file mode 100644 index 00000000..f817b266 --- /dev/null +++ b/backtrace-library/src/androidTest/java/backtraceio/library/common/serializers/naming/LowerCaseWithDashConverterTest.java @@ -0,0 +1,64 @@ +package backtraceio.library.common.serializers.naming; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import java.util.Arrays; +import java.util.Collection; + +import backtraceio.library.common.serializers.naming.LowerCaseWithDashConverter; + +@RunWith(Parameterized.class) +public class LowerCaseWithDashConverterTest { + private final String input; + private final String expectedOutput; + + public LowerCaseWithDashConverterTest(String input, String expectedOutput) { + this.input = input; + this.expectedOutput = expectedOutput; + } + + @Parameterized.Parameters + public static Collection data() { + return Arrays.asList(new Object[][]{ + {"camelCaseInput", "camel-case-input"}, + {"UpperCaseInput", "upper-case-input"}, + {"snake_case_input", "snake_case_input"}, + {"mixedCASEInput", "mixed-c-a-s-e-input"}, + {"some-dashed-input", "some-dashed-input"}, + {"kebab-Case-Input", "kebab--case--input"}, + {"Space Separated Input", "space -separated -input"}, + {"123NumericInput", "123-numeric-input"}, + {"!@#$%^SpecialChars", "!@#$%^-special-chars"}, + {"", ""} + }); + } + + @Test + public void convertShouldConvertToLowerCaseWithDash() { + // GIVEN + LowerCaseWithDashConverter converter = new LowerCaseWithDashConverter(); + + // WHEN + String actualOutput = converter.convert(input); + + // THEN + assertEquals(expectedOutput, actualOutput); + } + + @Test + public void convertShouldConvertNullToLowerCaseWithDash() { + // GIVEN + LowerCaseWithDashConverter converter = new LowerCaseWithDashConverter(); + + // WHEN + String actualOutput = converter.convert(null); + + // THEN + assertNull(actualOutput); + } +} diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/common/serializers/naming/NamingUtilsTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/common/serializers/naming/NamingUtilsTest.java new file mode 100644 index 00000000..a6cb7185 --- /dev/null +++ b/backtrace-library/src/androidTest/java/backtraceio/library/common/serializers/naming/NamingUtilsTest.java @@ -0,0 +1,54 @@ +package backtraceio.library.common.serializers.naming; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import java.util.Arrays; +import java.util.Collection; + +import static org.junit.Assert.assertEquals; + +import backtraceio.library.common.serializers.naming.NamingUtils; + +@RunWith(Parameterized.class) +public class NamingUtilsTest { + + private final String input; + private final char separator; + private final String expectedOutput; + + public NamingUtilsTest(String input, char separator, String expectedOutput) { + this.input = input; + this.separator = separator; + this.expectedOutput = expectedOutput; + } + + @Parameterized.Parameters + public static Collection data() { + return Arrays.asList(new Object[][]{ + {"camelCaseInput", '-', "camel-Case-Input"}, + {"camelcaseinput", '-', "camelcaseinput"}, + {"Camelcaseinput", '-', "Camelcaseinput"}, + {"UpperCaseInput", '_', "Upper_Case_Input"}, + {"snake_case_input", '*', "snake_case_input"}, + {"mixedCASEInput", '.', "mixed.C.A.S.E.Input"}, + {"some-dashed-input", '|', "some-dashed-input"}, + {"kebabCaseInput", ':', "kebab:Case:Input"}, + {"Space Separated Input", '+', "Space +Separated +Input"}, + {"123NumericInput", '_', "123_Numeric_Input"}, + {"!@#$%^SpecialChars", '!', "!@#$%^!Special!Chars"}, + {"", '*', ""}, + {null, '-', null} + }); + } + + @Test + public void separateCamelCase_shouldSeparateCamelCase() { + // Arrange + String actualOutput = NamingUtils.separateCamelCase(input, separator); + + // Assert + assertEquals(expectedOutput, actualOutput); + } +} \ No newline at end of file diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java index dfb6ab05..b11d0ba6 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java @@ -2,6 +2,8 @@ import android.os.Build; +import com.google.gson.annotations.SerializedName; + import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -83,11 +85,12 @@ private static JSONObject getAllFields(NamingPolicy namingPolicy, Class klass f.setAccessible(true); if (!java.lang.reflect.Modifier.isStatic(f.getModifiers())) { try { + Object value = f.get(obj); if (value == obj) { continue; } - result.put(namingPolicy.convert(f.getName()), serialize(namingPolicy, value, serializationDepth)); + result.put(getFieldName(namingPolicy, f), serialize(namingPolicy, value, serializationDepth)); } catch (Exception ex) { // ex.printStackTrace(); } @@ -99,6 +102,15 @@ private static JSONObject getAllFields(NamingPolicy namingPolicy, Class klass return result; } + private static String getFieldName(NamingPolicy namingPolicy, Field field) { + if (field.isAnnotationPresent(SerializedName.class)) { + // Get the SerializedName value + SerializedName annotation = field.getAnnotation(SerializedName.class); + return annotation.value(); + } + return namingPolicy.convert(field.getName()); + } + private static JSONObject serializeMap(NamingPolicy namingPolicy, Map map, int serializationDepth) throws JSONException { JSONObject jsonObject = new JSONObject(); for (Map.Entry entry : map.entrySet()) { diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/naming/LowerCaseWithDashConverter.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/naming/LowerCaseWithDashConverter.java index 65ca47dd..57a718db 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/naming/LowerCaseWithDashConverter.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/naming/LowerCaseWithDashConverter.java @@ -6,6 +6,9 @@ public class LowerCaseWithDashConverter implements NamingConverter { public String convert(String value) { + if (value == null){ + return null; + } return separateCamelCase(value, '-').toLowerCase(Locale.ENGLISH); } } diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/naming/NamingUtils.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/naming/NamingUtils.java index fea736dc..c66804d2 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/naming/NamingUtils.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/naming/NamingUtils.java @@ -3,6 +3,9 @@ public class NamingUtils { static String separateCamelCase(String name, char separator) { StringBuilder translation = new StringBuilder(); + if (name == null) { + return null; + } for (int i = 0, length = name.length(); i < length; i++) { char character = name.charAt(i); if (Character.isUpperCase(character) && translation.length() != 0) { From 0f673a9637da9aa010014fa716a8fc0872517579 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 18 Oct 2023 19:42:09 +0200 Subject: [PATCH 015/100] Replace gson serializer --- .../common/BacktraceDataSerializerTest.java | 2 +- .../common/BacktraceSerializeHelper.java | 11 ++----- .../serializers/BacktraceDataSerializer.java | 8 +++-- .../BacktraceOrgJsonSerializer.java | 33 +++++++++++++++++++ 4 files changed, 43 insertions(+), 11 deletions(-) create mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceOrgJsonSerializer.java diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java index d8ee85f8..c6b5c858 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java @@ -51,7 +51,7 @@ public void testGsonSerializer() throws JSONException, IllegalAccessException { final BacktraceData dataGson = BacktraceSerializeHelper.fromJson(jsonFromGson, BacktraceData.class); BacktraceDataSerializer serializer = new BacktraceDataSerializer(new NamingPolicy()); - final String jsonFromOrgJson = serializer.toJson(data); + final String jsonFromOrgJson = serializer.toJson(data).toString(); // THEN assertTrue(jsonEquals(jsonFromOrgJson, jsonFromGson)); 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 d87babc5..8274f389 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/BacktraceSerializeHelper.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/BacktraceSerializeHelper.java @@ -1,11 +1,10 @@ package backtraceio.library.common; -import com.google.gson.FieldNamingPolicy; import com.google.gson.Gson; -import com.google.gson.GsonBuilder; + import backtraceio.library.common.serialization.BacktraceGsonBuilder; -import backtraceio.library.models.BacktraceResult; +import backtraceio.library.common.serializers.BacktraceOrgJsonSerializer; /** * Helper class for serialize and deserialize objects @@ -19,17 +18,13 @@ public class BacktraceSerializeHelper { * @return serialized object in JSON string format */ public static String toJson(Object object) { - return BacktraceSerializeHelper.toJson(new BacktraceGsonBuilder().buildGson(), object); + return BacktraceOrgJsonSerializer.toJson(object); } public static T fromJson(String json, Class type) { return BacktraceSerializeHelper.fromJson(new BacktraceGsonBuilder().buildGson(), json, type); } - public static String toJson(Gson gson, Object object) { - return gson.toJson(object); - } - public static T fromJson(Gson gson, String json, Class type) { return gson.fromJson(json, type); } diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java index 285328f0..9a1a20a1 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java @@ -25,8 +25,12 @@ public BacktraceDataSerializer(NamingPolicy policy) { } - public String toJson(BacktraceData data) throws JSONException, IllegalAccessException { + public JSONObject toJson(BacktraceData data) throws JSONException, IllegalAccessException { { + if (data == null) { + return null; + } + JSONObject json = new JSONObject(); // Serialize simple fields @@ -64,7 +68,7 @@ public String toJson(BacktraceData data) throws JSONException, IllegalAccessExce json.put("threads", threadInformationJson); } - return json.toString(); + return json; } } diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceOrgJsonSerializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceOrgJsonSerializer.java new file mode 100644 index 00000000..c780164c --- /dev/null +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceOrgJsonSerializer.java @@ -0,0 +1,33 @@ +package backtraceio.library.common.serializers; + +import org.json.JSONException; + +import backtraceio.library.common.serializers.BacktraceDataSerializer; +import backtraceio.library.common.serializers.SerializerHelper; +import backtraceio.library.common.serializers.naming.NamingPolicy; +import backtraceio.library.models.BacktraceData; + +public class BacktraceOrgJsonSerializer { + + public static String toJson(Object object) { // TODO: remove IllegalAccessException + if (object == null) { + return null; + } + + try { + NamingPolicy namingPolicy = new NamingPolicy(); + Class clazz = object.getClass(); + + if (clazz.equals(BacktraceData.class)) { + BacktraceDataSerializer dataSerializer = new BacktraceDataSerializer(namingPolicy); + return dataSerializer.toJson((BacktraceData) object).toString(); + } + + return SerializerHelper.serialize(namingPolicy, object).toString(); + } + catch (Exception ex) { // TODO: improve error handling + ex.printStackTrace(); + return null; + } + } +} From 312a57d15f54436cca35dfcdb99b4b91d019c3ee Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 18 Oct 2023 22:23:20 +0200 Subject: [PATCH 016/100] Fix unit tests --- .../common/BacktraceSerializeHelper.java | 1 + .../common/serializers/SerializerHelper.java | 28 +++++++++++-------- 2 files changed, 18 insertions(+), 11 deletions(-) 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 8274f389..d2b4de33 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/BacktraceSerializeHelper.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/BacktraceSerializeHelper.java @@ -18,6 +18,7 @@ public class BacktraceSerializeHelper { * @return serialized object in JSON string format */ public static String toJson(Object object) { +// return new BacktraceGsonBuilder().buildGson().toJson(object); return BacktraceOrgJsonSerializer.toJson(object); } diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java index b11d0ba6..0955c641 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java @@ -16,6 +16,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.UUID; import backtraceio.library.common.serializers.naming.NamingPolicy; @@ -83,20 +84,21 @@ private static JSONObject getAllFields(NamingPolicy namingPolicy, Class klass JSONObject result = new JSONObject(); for (Field f : fields) { f.setAccessible(true); - if (!java.lang.reflect.Modifier.isStatic(f.getModifiers())) { - try { - - Object value = f.get(obj); - if (value == obj) { - continue; - } - result.put(getFieldName(namingPolicy, f), serialize(namingPolicy, value, serializationDepth)); - } catch (Exception ex) { -// ex.printStackTrace(); - } + if (java.lang.reflect.Modifier.isTransient(f.getModifiers()) || + java.lang.reflect.Modifier.isStatic(f.getModifiers())) { + continue; } + try { + Object value = f.get(obj); + if (value == obj) { + continue; + } + result.put(getFieldName(namingPolicy, f), serialize(namingPolicy, value, serializationDepth)); + } catch (Exception ex) { +// ex.printStackTrace(); + } } return result; @@ -168,6 +170,10 @@ public static Object serialize(NamingPolicy namingPolicy, Object obj, int serial serializationDepth++; + if (obj instanceof UUID) { + return obj.toString(); + } + if (obj instanceof Map) { return serializeMap(namingPolicy, (Map) obj, serializationDepth); } From fb0a2616e4eb75b4dde9c4054591ce1ba6f70b57 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 1 Nov 2023 21:58:26 +0100 Subject: [PATCH 017/100] Add tmp deserializer --- .../common/BacktraceDataDeserializerTest.java | 26 ++++++++++++ .../BacktraceOrgJsonDeserializer.java | 42 +++++++++++++++++++ .../library/models/BacktraceData.java | 4 ++ 3 files changed, 72 insertions(+) create mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceOrgJsonDeserializer.java diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java index f1c0dc88..227fdf2f 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java @@ -28,6 +28,7 @@ import backtraceio.library.R; import backtraceio.library.common.serializers.BacktraceDataDeserializer; import backtraceio.library.common.serializers.BacktraceDataSerializer; +import backtraceio.library.common.serializers.BacktraceOrgJsonDeserializer; import backtraceio.library.common.serializers.SerializerHelper; import backtraceio.library.models.BacktraceData; import backtraceio.library.models.json.BacktraceReport; @@ -35,6 +36,31 @@ @RunWith(AndroidJUnit4.class) public class BacktraceDataDeserializerTest { + @Test + public void fromJson2() throws JSONException, IllegalAccessException { + // GIVEN + final Context context = InstrumentationRegistry.getInstrumentation().getContext(); + + String fileName = "sample.json"; + + String path = "resources/"; + String jsonPath = path + "sample.json"; + + // WHEN + + String content = readFileAsString(this, fileName); +// File x = getFileFromPath(this, "resources/sample.json"); + JSONObject jsonObj = new JSONObject(content); + + BacktraceData dataJson = BacktraceOrgJsonDeserializer.deserialize(content, BacktraceData.class); + + BacktraceData backtraceData = BacktraceDataDeserializer.deserialize(context, jsonObj); + + System.out.println(backtraceData.report); + // THEN +// assertEquals(backtraceData.report.message, ); + } + @Test public void fromJson() throws JSONException, IllegalAccessException { // GIVEN diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceOrgJsonDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceOrgJsonDeserializer.java new file mode 100644 index 00000000..83a6c532 --- /dev/null +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceOrgJsonDeserializer.java @@ -0,0 +1,42 @@ +package backtraceio.library.common.serializers; + +import org.json.JSONException; +import org.json.JSONObject; + +public class BacktraceOrgJsonDeserializer { + + public static T deserialize(String jsonString, Class clazz) throws JSONException { + JSONObject jsonObject = new JSONObject(jsonString); + return deserialize(jsonObject, clazz); + } + + public static T deserialize(JSONObject jsonObject, Class clazz) { + try { + T instance = clazz.newInstance(); + // Assuming that the class has a default (no-argument) constructor + + // Iterate through the fields of the class + for (java.lang.reflect.Field field : clazz.getDeclaredFields()) { + // Make the field accessible (public, private, etc.) + field.setAccessible(true); + + // Get the field name + String fieldName = field.getName(); + + // Check if the JSON object has a key with the field name + if (jsonObject.has(fieldName)) { + // Set the field value using reflection + field.set(instance, jsonObject.get(fieldName)); + } + } + + return instance; + } catch (InstantiationException | IllegalAccessException e) { + e.printStackTrace(); // Handle the exception appropriately + } catch (JSONException e) { + throw new RuntimeException(e); + } + + return null; + } +} 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 e91a6746..88bb5276 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java @@ -111,6 +111,10 @@ public class BacktraceData { @SerializedName("threads") Map threadInformationMap; + + public BacktraceData() { + + } /** * Create instance of report data * From 6f52f471cdb0653e3a529114052feddc5ef4a54c Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Mon, 11 Dec 2023 17:51:19 +0100 Subject: [PATCH 018/100] Add custom serializer annotation --- .../common/BacktraceDataDeserializerTest.java | 38 +++++++++++++++++++ .../common/BacktraceSerializeHelper.java | 1 - .../BacktraceOrgJsonDeserializer.java | 12 ++++++ .../common/serializers/SerializedName.java | 27 +++++++++++++ .../library/models/BacktraceResult.java | 3 +- .../database/BacktraceDatabaseRecord.java | 2 +- .../backtraceio/backtraceio/MainActivity.java | 3 +- 7 files changed, 81 insertions(+), 5 deletions(-) create mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializedName.java diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java index 227fdf2f..82903da4 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java @@ -1,6 +1,9 @@ package backtraceio.library.common; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static backtraceio.library.TestUtils.readFileAsString; @@ -31,11 +34,46 @@ import backtraceio.library.common.serializers.BacktraceOrgJsonDeserializer; import backtraceio.library.common.serializers.SerializerHelper; import backtraceio.library.models.BacktraceData; +import backtraceio.library.models.BacktraceResult; +import backtraceio.library.models.database.BacktraceDatabaseRecord; import backtraceio.library.models.json.BacktraceReport; +import backtraceio.library.models.types.BacktraceResultStatus; @RunWith(AndroidJUnit4.class) public class BacktraceDataDeserializerTest { + @Test + public void deserializeCoronerJsonResponse() throws JSONException { + // GIVEN + String json = "{\"response\":\"ok\",\"_rxid\":\"01000000-5360-240b-0000-000000000000\"}"; + + // WHEN + BacktraceResult result = BacktraceOrgJsonDeserializer.deserialize(json, BacktraceResult.class); + + // THEN + assertNotNull(result); + assertNull(result.getBacktraceReport()); + assertNull(result.message); + assertEquals(BacktraceResultStatus.Ok, result.status); + assertEquals("01000000-5360-240b-0000-000000000000", result.rxId); + } + + @Test + public void deserializeDatabaseRecord() throws JSONException { + // GIVEN + String json = "{\"DataPath\":\"\\/data\\/user\\/0\\/backtraceio.backtraceio\\/files\\/8fbde28b-aa64-4e2f-83d8-493a98446fc8-attachment.json\",\"Id\":\"8fbde28b-aa64-4e2f-83d8-493a98446fc8\",\"RecordName\":\"\\/data\\/user\\/0\\/backtraceio.backtraceio\\/files\\/8fbde28b-aa64-4e2f-83d8-493a98446fc8-record.json\",\"ReportPath\":\"\\/data\\/user\\/0\\/backtraceio.backtraceio\\/files\\/8fbde28b-aa64-4e2f-83d8-493a98446fc8-report.json\",\"Size\":16996,\"size\":16996,\"record-path\":\"\\/data\\/user\\/0\\/backtraceio.backtraceio\\/files\\/8fbde28b-aa64-4e2f-83d8-493a98446fc8-record.json\",\"report-path\":\"\\/data\\/user\\/0\\/backtraceio.backtraceio\\/files\\/8fbde28b-aa64-4e2f-83d8-493a98446fc8-report.json\",\"diagnostic-data-path\":\"\\/data\\/user\\/0\\/backtraceio.backtraceio\\/files\\/8fbde28b-aa64-4e2f-83d8-493a98446fc8-attachment.json\"}"; + + // WHEN + BacktraceDatabaseRecord result = BacktraceOrgJsonDeserializer.deserialize(json, BacktraceDatabaseRecord.class); + + // THEN + assertNotNull(result); + assertEquals(16996, result.getSize()); + assertFalse(result.locked); + assertEquals("/data/user/0/backtraceio.backtraceio/files/8fbde28b-aa64-4e2f-83d8-493a98446fc8-attachment.json", result.getDiagnosticDataPath()); + assertEquals("/data/user/0/backtraceio.backtraceio/files/8fbde28b-aa64-4e2f-83d8-493a98446fc8-record.json", result.getRecordPath()); + assertEquals("/data/user/0/backtraceio.backtraceio/files/8fbde28b-aa64-4e2f-83d8-493a98446fc8-report.json", result.getReportPath()); + } @Test public void fromJson2() throws JSONException, IllegalAccessException { // GIVEN 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 d2b4de33..8274f389 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/BacktraceSerializeHelper.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/BacktraceSerializeHelper.java @@ -18,7 +18,6 @@ public class BacktraceSerializeHelper { * @return serialized object in JSON string format */ public static String toJson(Object object) { -// return new BacktraceGsonBuilder().buildGson().toJson(object); return BacktraceOrgJsonSerializer.toJson(object); } diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceOrgJsonDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceOrgJsonDeserializer.java index 83a6c532..2acdc944 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceOrgJsonDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceOrgJsonDeserializer.java @@ -27,6 +27,18 @@ public static T deserialize(JSONObject jsonObject, Class clazz) { if (jsonObject.has(fieldName)) { // Set the field value using reflection field.set(instance, jsonObject.get(fieldName)); + continue; + } + + + if (field.isAnnotationPresent(SerializedName.class)) { + SerializedName annotation = field.getAnnotation(SerializedName.class); + if (annotation != null) { + String customName = annotation.value(); + field.set(instance, jsonObject.get(customName)); + continue; + } + } } diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializedName.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializedName.java new file mode 100644 index 00000000..1f5de375 --- /dev/null +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializedName.java @@ -0,0 +1,27 @@ +package backtraceio.library.common.serializers; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD, ElementType.METHOD}) +public @interface SerializedName { + + /** + * The desired name of the field when it is serialized or deserialized. + * + * @return the desired name of the field when it is serialized or deserialized + */ + String value(); + + /** + * The alternative names of the field when it is deserialized + * + * @return the alternative names of the field when it is deserialized + */ + String[] alternate() default {}; +} \ No newline at end of file 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..5948a197 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceResult.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceResult.java @@ -1,7 +1,6 @@ package backtraceio.library.models; -import com.google.gson.annotations.SerializedName; - +import backtraceio.library.common.serializers.SerializedName; import backtraceio.library.models.json.BacktraceReport; import backtraceio.library.models.types.BacktraceResultStatus; 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 5e39510c..146d3bbe 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 @@ -70,7 +70,7 @@ public class BacktraceDatabaseRecord { */ private transient BacktraceData record; - BacktraceDatabaseRecord() { + public BacktraceDatabaseRecord() { this._path = ""; this.recordPath = String.format("%s-record.json", this.id); this.diagnosticDataPath = String.format("%s-attachment", this.id); diff --git a/example-app/src/main/java/backtraceio/backtraceio/MainActivity.java b/example-app/src/main/java/backtraceio/backtraceio/MainActivity.java index 714d5371..d7c3d59f 100644 --- a/example-app/src/main/java/backtraceio/backtraceio/MainActivity.java +++ b/example-app/src/main/java/backtraceio/backtraceio/MainActivity.java @@ -75,7 +75,8 @@ private void symlinkAndWriteFile() { } private BacktraceClient initializeBacktrace(final String submissionUrl) { - BacktraceCredentials credentials = new BacktraceCredentials(submissionUrl); + BacktraceCredentials credentials = new BacktraceCredentials("https://yolo.sp.backtrace.io:6098/", + "2dd86e8e779d1fc7e22e7b19a9489abeedec3b1426abe7e2209888e92362fba4"); Context context = getApplicationContext(); String dbPath = context.getFilesDir().getAbsolutePath(); From 91d74b52854cdb30c7a5b53744f50337e55eca1e Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Sun, 31 Dec 2023 16:33:52 +0100 Subject: [PATCH 019/100] Deserialize refactor --- backtrace-library/build.gradle | 1 + .../BacktraceClientSerializationTest.java | 2 +- .../common/BacktraceDataDeserializerTest.java | 11 +++ .../resources/backtraceResult.error.json | 1 + .../resources/backtraceResult.json | 1 + .../serializers/BacktraceDeserializer.java | 41 +++++++++ .../BacktraceOrgJsonDeserializer.java | 85 +++++++++---------- .../common/serializers/SerializerHelper.java | 1 - .../BacktraceDataDeserializer.java | 15 ++++ .../BacktraceDatabaseRecordDeserializer.java | 14 +++ .../BacktraceReportDeserializer.java | 15 ++++ .../BacktraceResultDeserializer.java | 14 +++ .../deserializers/Deserializable.java | 8 ++ .../deserializers/ExceptionDeserializer.java | 11 +++ .../deserializers/ReflectionDeserializer.java | 54 ++++++++++++ .../library/models/BacktraceData.java | 2 +- .../library/models/BacktraceResult.java | 5 ++ .../library/models/BacktraceStackFrame.java | 2 +- .../database/BacktraceDatabaseRecord.java | 2 +- .../library/models/json/SourceCode.java | 2 +- .../models/json/ThreadInformation.java | 2 +- .../library/models/metrics/Event.java | 2 +- .../models/metrics/EventsMetadata.java | 2 +- .../library/models/metrics/EventsPayload.java | 2 +- .../library/models/metrics/SummedEvent.java | 2 +- .../models/metrics/SummedEventsPayload.java | 2 +- .../library/models/metrics/UniqueEvent.java | 2 +- .../models/metrics/UniqueEventsPayload.java | 2 +- coroner-client/build.gradle | 2 +- .../CoronerResponseGroupDeserializerTest.java | 2 - 30 files changed, 247 insertions(+), 60 deletions(-) create mode 100644 backtrace-library/src/androidTest/resources/backtraceResult.error.json create mode 100644 backtrace-library/src/androidTest/resources/backtraceResult.json create mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDeserializer.java create mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDataDeserializer.java create mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDatabaseRecordDeserializer.java create mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceReportDeserializer.java create mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceResultDeserializer.java create mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/Deserializable.java create mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ExceptionDeserializer.java create mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ReflectionDeserializer.java diff --git a/backtrace-library/build.gradle b/backtrace-library/build.gradle index c948e84d..bb2b38fc 100644 --- a/backtrace-library/build.gradle +++ b/backtrace-library/build.gradle @@ -71,6 +71,7 @@ dependencies { implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'com.squareup:tape:1.2.3' testImplementation 'junit:junit:4.13.2' + testImplementation 'com.google.code.gson:gson:2.10.1' androidTestImplementation 'net.jodah:concurrentunit:0.4.4' androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test:rules:1.5.0' diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientSerializationTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientSerializationTest.java index 9f9c6e48..000b6a4e 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientSerializationTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientSerializationTest.java @@ -6,7 +6,7 @@ import android.content.Context; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.platform.app.InstrumentationRegistry; -import com.google.gson.annotations.SerializedName; +import backtraceio.library.common.serializers.SerializedName; import net.jodah.concurrentunit.Waiter; import org.junit.Before; import org.junit.Test; diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java index 82903da4..47953220 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java @@ -74,6 +74,17 @@ public void deserializeDatabaseRecord() throws JSONException { assertEquals("/data/user/0/backtraceio.backtraceio/files/8fbde28b-aa64-4e2f-83d8-493a98446fc8-record.json", result.getRecordPath()); assertEquals("/data/user/0/backtraceio.backtraceio/files/8fbde28b-aa64-4e2f-83d8-493a98446fc8-report.json", result.getReportPath()); } + + @Test + public void deserializeBacktraceApiResult() throws JSONException { + // GIVEN + + // WHEN + + // THEN + + } + @Test public void fromJson2() throws JSONException, IllegalAccessException { // GIVEN diff --git a/backtrace-library/src/androidTest/resources/backtraceResult.error.json b/backtrace-library/src/androidTest/resources/backtraceResult.error.json new file mode 100644 index 00000000..9928ff97 --- /dev/null +++ b/backtrace-library/src/androidTest/resources/backtraceResult.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/androidTest/resources/backtraceResult.json b/backtrace-library/src/androidTest/resources/backtraceResult.json new file mode 100644 index 00000000..1174a076 --- /dev/null +++ b/backtrace-library/src/androidTest/resources/backtraceResult.json @@ -0,0 +1 @@ +{"response":"ok","_rxid":"95000000-eb43-390b-0000-000000000000"} \ No newline at end of file diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDeserializer.java new file mode 100644 index 00000000..87a1a13e --- /dev/null +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDeserializer.java @@ -0,0 +1,41 @@ +package backtraceio.library.common.serializers; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.HashMap; + +import backtraceio.library.common.serializers.deserializers.BacktraceDataDeserializer; +import backtraceio.library.common.serializers.deserializers.BacktraceDatabaseRecordDeserializer; +import backtraceio.library.common.serializers.deserializers.BacktraceReportDeserializer; +import backtraceio.library.common.serializers.deserializers.BacktraceResultDeserializer; +import backtraceio.library.common.serializers.deserializers.Deserializable; +import backtraceio.library.common.serializers.deserializers.ExceptionDeserializer; +import backtraceio.library.common.serializers.deserializers.ReflectionDeserializer; +import backtraceio.library.models.BacktraceData; +import backtraceio.library.models.BacktraceResult; +import backtraceio.library.models.json.BacktraceReport; + +public class BacktraceDeserializer { + + public final static Deserializable DEFAULT_DESERIALIZER = new ReflectionDeserializer(); + public static HashMap deserializers = new HashMap() {{ + put(BacktraceResult.class, new BacktraceResultDeserializer()); + put(BacktraceReport.class, new BacktraceReportDeserializer()); + put(BacktraceData.class, new BacktraceDataDeserializer()); + put(Exception.class, new ExceptionDeserializer()); + put(BacktraceDatabaseRecordDeserializer.class, new BacktraceDatabaseRecordDeserializer()) + }}; + + public static void registerDeserializer(Class clazz, Deserializable obj) { + deserializers.put(clazz, obj); + } + + public static T deserialize(JSONObject obj, Class clazz) throws JSONException { + if (deserializers.containsKey(clazz)) { + return deserializers.get(clazz).deserialize(obj); + } + + return DEFAULT_DESERIALIZER.deserialize(obj); + } +} diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceOrgJsonDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceOrgJsonDeserializer.java index 2acdc944..e11d925b 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceOrgJsonDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceOrgJsonDeserializer.java @@ -6,49 +6,48 @@ public class BacktraceOrgJsonDeserializer { public static T deserialize(String jsonString, Class clazz) throws JSONException { - JSONObject jsonObject = new JSONObject(jsonString); - return deserialize(jsonObject, clazz); + return BacktraceDeserializer.deserialize(new JSONObject(jsonString), clazz); } - public static T deserialize(JSONObject jsonObject, Class clazz) { - try { - T instance = clazz.newInstance(); - // Assuming that the class has a default (no-argument) constructor - - // Iterate through the fields of the class - for (java.lang.reflect.Field field : clazz.getDeclaredFields()) { - // Make the field accessible (public, private, etc.) - field.setAccessible(true); - - // Get the field name - String fieldName = field.getName(); - - // Check if the JSON object has a key with the field name - if (jsonObject.has(fieldName)) { - // Set the field value using reflection - field.set(instance, jsonObject.get(fieldName)); - continue; - } - - - if (field.isAnnotationPresent(SerializedName.class)) { - SerializedName annotation = field.getAnnotation(SerializedName.class); - if (annotation != null) { - String customName = annotation.value(); - field.set(instance, jsonObject.get(customName)); - continue; - } - - } - } - - return instance; - } catch (InstantiationException | IllegalAccessException e) { - e.printStackTrace(); // Handle the exception appropriately - } catch (JSONException e) { - throw new RuntimeException(e); - } - - return null; - } +// public static T deserialize(JSONObject jsonObject, Class clazz) { +// try { +// T instance = clazz.newInstance(); +// // Assuming that the class has a default (no-argument) constructor +// +// // Iterate through the fields of the class +// for (java.lang.reflect.Field field : clazz.getDeclaredFields()) { +// // Make the field accessible (public, private, etc.) +// field.setAccessible(true); +// +// // Get the field name +// String fieldName = field.getName(); +// +// // Check if the JSON object has a key with the field name +// if (jsonObject.has(fieldName)) { +// // Set the field value using reflection +// field.set(instance, jsonObject.get(fieldName)); +// continue; +// } +// +// +// if (field.isAnnotationPresent(SerializedName.class)) { +// SerializedName annotation = field.getAnnotation(SerializedName.class); +// if (annotation != null) { +// String customName = annotation.value(); +// field.set(instance, jsonObject.get(customName)); +// continue; +// } +// +// } +// } +// +// return instance; +// } catch (InstantiationException | IllegalAccessException e) { +// e.printStackTrace(); // Handle the exception appropriately +// } catch (JSONException e) { +// throw new RuntimeException(e); +// } +// +// return null; +// } } diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java index 0955c641..3bcdf920 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java @@ -2,7 +2,6 @@ import android.os.Build; -import com.google.gson.annotations.SerializedName; import org.json.JSONArray; import org.json.JSONException; diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDataDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDataDeserializer.java new file mode 100644 index 00000000..fbae1d9e --- /dev/null +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDataDeserializer.java @@ -0,0 +1,15 @@ +package backtraceio.library.common.serializers.deserializers; + +import org.json.JSONException; +import org.json.JSONObject; + +import backtraceio.library.models.BacktraceData; +import backtraceio.library.models.BacktraceResult; +import backtraceio.library.models.types.BacktraceResultStatus; + +public class BacktraceDataDeserializer implements Deserializable{ + + public BacktraceData deserialize(JSONObject obj) throws JSONException { + return new BacktraceData(); // TODO + } +} diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDatabaseRecordDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDatabaseRecordDeserializer.java new file mode 100644 index 00000000..1a313c7c --- /dev/null +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDatabaseRecordDeserializer.java @@ -0,0 +1,14 @@ +package backtraceio.library.common.serializers.deserializers; + +import org.json.JSONException; +import org.json.JSONObject; + +import backtraceio.library.models.BacktraceData; +import backtraceio.library.models.database.BacktraceDatabaseRecord; + +public class BacktraceDatabaseRecordDeserializer implements Deserializable{ + + public BacktraceDatabaseRecord deserialize(JSONObject obj) throws JSONException { + return new BacktraceDatabaseRecord(); // TODO + } +} diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceReportDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceReportDeserializer.java new file mode 100644 index 00000000..60401680 --- /dev/null +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceReportDeserializer.java @@ -0,0 +1,15 @@ +package backtraceio.library.common.serializers.deserializers; + +import org.json.JSONException; +import org.json.JSONObject; + +import backtraceio.library.models.database.BacktraceDatabaseRecord; +import backtraceio.library.models.json.BacktraceReport; + +public class BacktraceReportDeserializer implements Deserializable{ + + public BacktraceReport deserialize(JSONObject obj) throws JSONException { +// return new BacktraceReport(); // TODO + return null; // TODO: + } +} diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceResultDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceResultDeserializer.java new file mode 100644 index 00000000..48ecd4ce --- /dev/null +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceResultDeserializer.java @@ -0,0 +1,14 @@ +package backtraceio.library.common.serializers.deserializers; + +import org.json.JSONException; +import org.json.JSONObject; + +import backtraceio.library.models.BacktraceResult; +import backtraceio.library.models.types.BacktraceResultStatus; + +public class BacktraceResultDeserializer implements Deserializable{ + + public BacktraceResult deserialize(JSONObject obj) throws JSONException { + return new BacktraceResult(obj.optString("_rxid", null), obj.optString("response", BacktraceResultStatus.Ok.toString())); + } +} diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/Deserializable.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/Deserializable.java new file mode 100644 index 00000000..8b2f0177 --- /dev/null +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/Deserializable.java @@ -0,0 +1,8 @@ +package backtraceio.library.common.serializers.deserializers; + +import org.json.JSONException; +import org.json.JSONObject; + +public interface Deserializable { + public T deserialize(JSONObject jsonObj) throws JSONException; +} diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ExceptionDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ExceptionDeserializer.java new file mode 100644 index 00000000..d9f1c155 --- /dev/null +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ExceptionDeserializer.java @@ -0,0 +1,11 @@ +package backtraceio.library.common.serializers.deserializers; + +import org.json.JSONException; +import org.json.JSONObject; + +public class ExceptionDeserializer implements Deserializable { + @Override + public Exception deserialize(JSONObject obj) throws JSONException { + return null; // TODO: fix + } +} diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ReflectionDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ReflectionDeserializer.java new file mode 100644 index 00000000..7b17894b --- /dev/null +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ReflectionDeserializer.java @@ -0,0 +1,54 @@ +package backtraceio.library.common.serializers.deserializers; + +import org.json.JSONException; +import org.json.JSONObject; + +import backtraceio.library.common.serializers.SerializedName; +import backtraceio.library.models.BacktraceResult; + +public class ReflectionDeserializer implements Deserializable { + + + @Override + public T1 deserialize(JSONObject jsonObj, Class clazz) throws JSONException { + try { + T instance = clazz.newInstance(); + // Assuming that the class has a default (no-argument) constructor + + // Iterate through the fields of the class + for (java.lang.reflect.Field field : clazz.getDeclaredFields()) { + // Make the field accessible (public, private, etc.) + field.setAccessible(true); + + // Get the field name + String fieldName = field.getName(); + + // Check if the JSON object has a key with the field name + if (jsonObject.has(fieldName)) { + // Set the field value using reflection + field.set(instance, jsonObject.get(fieldName)); + continue; + } + + + if (field.isAnnotationPresent(SerializedName.class)) { + SerializedName annotation = field.getAnnotation(SerializedName.class); + if (annotation != null) { + String customName = annotation.value(); + field.set(instance, jsonObject.get(customName)); + continue; + } + + } + } + + return instance; + } catch (InstantiationException | IllegalAccessException e) { + e.printStackTrace(); // Handle the exception appropriately + } catch (JSONException e) { + throw new RuntimeException(e); + } + + return null; + } +} 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 88bb5276..97039c35 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java @@ -2,7 +2,7 @@ import android.content.Context; -import com.google.gson.annotations.SerializedName; +import backtraceio.library.common.serializers.SerializedName; import java.util.List; import java.util.Map; 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 5948a197..7b964064 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceResult.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceResult.java @@ -38,6 +38,11 @@ public BacktraceResult() { } + public BacktraceResult(String rxId, String status) { + this.rxId = rxId; + this.status = BacktraceResultStatus.valueOf(status); + } + /** * Create new instance of BacktraceResult * 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..fbc48433 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceStackFrame.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceStackFrame.java @@ -1,9 +1,9 @@ package backtraceio.library.models; -import com.google.gson.annotations.SerializedName; import java.util.UUID; +import backtraceio.library.common.serializers.SerializedName; import backtraceio.library.logger.BacktraceLogger; /** 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 146d3bbe..5327f0a9 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 @@ -2,7 +2,7 @@ import android.content.Context; -import com.google.gson.annotations.SerializedName; +import backtraceio.library.common.serializers.SerializedName; import java.io.File; import java.nio.charset.StandardCharsets; 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..55740cad 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 @@ -1,6 +1,6 @@ package backtraceio.library.models.json; -import com.google.gson.annotations.SerializedName; +import backtraceio.library.common.serializers.SerializedName; import backtraceio.library.models.BacktraceStackFrame; 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 2d6bfb84..6f960597 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 @@ -1,6 +1,6 @@ package backtraceio.library.models.json; -import com.google.gson.annotations.SerializedName; +import backtraceio.library.common.serializers.SerializedName; import java.util.ArrayList; diff --git a/backtrace-library/src/main/java/backtraceio/library/models/metrics/Event.java b/backtrace-library/src/main/java/backtraceio/library/models/metrics/Event.java index fce15e6e..9f3d18b6 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/metrics/Event.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/metrics/Event.java @@ -1,6 +1,6 @@ package backtraceio.library.models.metrics; -import com.google.gson.annotations.SerializedName; +import backtraceio.library.common.serializers.SerializedName; import java.util.HashMap; import java.util.Map; diff --git a/backtrace-library/src/main/java/backtraceio/library/models/metrics/EventsMetadata.java b/backtrace-library/src/main/java/backtraceio/library/models/metrics/EventsMetadata.java index f0284138..10a293e2 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/metrics/EventsMetadata.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/metrics/EventsMetadata.java @@ -1,6 +1,6 @@ package backtraceio.library.models.metrics; -import com.google.gson.annotations.SerializedName; +import backtraceio.library.common.serializers.SerializedName; public class EventsMetadata { diff --git a/backtrace-library/src/main/java/backtraceio/library/models/metrics/EventsPayload.java b/backtrace-library/src/main/java/backtraceio/library/models/metrics/EventsPayload.java index 05198c75..0a0177b8 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/metrics/EventsPayload.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/metrics/EventsPayload.java @@ -1,6 +1,6 @@ package backtraceio.library.models.metrics; -import com.google.gson.annotations.SerializedName; +import backtraceio.library.common.serializers.SerializedName; import java.util.concurrent.ConcurrentLinkedDeque; diff --git a/backtrace-library/src/main/java/backtraceio/library/models/metrics/SummedEvent.java b/backtrace-library/src/main/java/backtraceio/library/models/metrics/SummedEvent.java index b9665f01..eea49c9f 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/metrics/SummedEvent.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/metrics/SummedEvent.java @@ -1,6 +1,6 @@ package backtraceio.library.models.metrics; -import com.google.gson.annotations.SerializedName; +import backtraceio.library.common.serializers.SerializedName; import java.util.HashMap; import java.util.Map; diff --git a/backtrace-library/src/main/java/backtraceio/library/models/metrics/SummedEventsPayload.java b/backtrace-library/src/main/java/backtraceio/library/models/metrics/SummedEventsPayload.java index fe483803..f89ed28e 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/metrics/SummedEventsPayload.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/metrics/SummedEventsPayload.java @@ -1,6 +1,6 @@ package backtraceio.library.models.metrics; -import com.google.gson.annotations.SerializedName; +import backtraceio.library.common.serializers.SerializedName; import java.util.concurrent.ConcurrentLinkedDeque; diff --git a/backtrace-library/src/main/java/backtraceio/library/models/metrics/UniqueEvent.java b/backtrace-library/src/main/java/backtraceio/library/models/metrics/UniqueEvent.java index 789b9825..d252122f 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/metrics/UniqueEvent.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/metrics/UniqueEvent.java @@ -1,6 +1,6 @@ package backtraceio.library.models.metrics; -import com.google.gson.annotations.SerializedName; +import backtraceio.library.common.serializers.SerializedName; import java.util.ArrayList; import java.util.HashMap; diff --git a/backtrace-library/src/main/java/backtraceio/library/models/metrics/UniqueEventsPayload.java b/backtrace-library/src/main/java/backtraceio/library/models/metrics/UniqueEventsPayload.java index 1f1b06ef..1d27bea4 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/metrics/UniqueEventsPayload.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/metrics/UniqueEventsPayload.java @@ -1,6 +1,6 @@ package backtraceio.library.models.metrics; -import com.google.gson.annotations.SerializedName; +import backtraceio.library.common.serializers.SerializedName; import java.util.concurrent.ConcurrentLinkedDeque; diff --git a/coroner-client/build.gradle b/coroner-client/build.gradle index 79ded59f..a458782c 100644 --- a/coroner-client/build.gradle +++ b/coroner-client/build.gradle @@ -9,7 +9,7 @@ java { dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation 'com.google.code.gson:gson:2.10' + implementation 'com.google.code.gson:gson:2.10.1' testImplementation 'junit:junit:4.13.2' testImplementation group: 'org.mockito', name: 'mockito-core', version: '5.2.0' } \ No newline at end of file diff --git a/coroner-client/src/test/java/backtraceio/coroner/serialization/CoronerResponseGroupDeserializerTest.java b/coroner-client/src/test/java/backtraceio/coroner/serialization/CoronerResponseGroupDeserializerTest.java index 147a81b6..165e7a16 100644 --- a/coroner-client/src/test/java/backtraceio/coroner/serialization/CoronerResponseGroupDeserializerTest.java +++ b/coroner-client/src/test/java/backtraceio/coroner/serialization/CoronerResponseGroupDeserializerTest.java @@ -1,7 +1,5 @@ package backtraceio.coroner.serialization; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import com.google.gson.JsonElement; From 8dff878cca3e72f1779ad5cc62415f99a8c0c9d9 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Sun, 31 Dec 2023 16:34:15 +0100 Subject: [PATCH 020/100] Fix --- .../src/main/java/backtraceio/backtraceio/MainActivity.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/example-app/src/main/java/backtraceio/backtraceio/MainActivity.java b/example-app/src/main/java/backtraceio/backtraceio/MainActivity.java index d7c3d59f..714d5371 100644 --- a/example-app/src/main/java/backtraceio/backtraceio/MainActivity.java +++ b/example-app/src/main/java/backtraceio/backtraceio/MainActivity.java @@ -75,8 +75,7 @@ private void symlinkAndWriteFile() { } private BacktraceClient initializeBacktrace(final String submissionUrl) { - BacktraceCredentials credentials = new BacktraceCredentials("https://yolo.sp.backtrace.io:6098/", - "2dd86e8e779d1fc7e22e7b19a9489abeedec3b1426abe7e2209888e92362fba4"); + BacktraceCredentials credentials = new BacktraceCredentials(submissionUrl); Context context = getApplicationContext(); String dbPath = context.getFilesDir().getAbsolutePath(); From 9ffd261d4a5e60a8875c18afb6c2cd83346b501a Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Tue, 2 Jan 2024 23:54:16 +0100 Subject: [PATCH 021/100] Code refactor --- .../serializers/BacktraceDeserializer.java | 9 ++++-- .../BacktraceReportDeserializer.java | 6 ++-- .../deserializers/Deserializable.java | 2 +- .../deserializers/ReflectionDeserializer.java | 29 +++++++++++++++---- 4 files changed, 34 insertions(+), 12 deletions(-) diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDeserializer.java index 87a1a13e..397f71e7 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDeserializer.java @@ -24,18 +24,21 @@ public class BacktraceDeserializer { put(BacktraceReport.class, new BacktraceReportDeserializer()); put(BacktraceData.class, new BacktraceDataDeserializer()); put(Exception.class, new ExceptionDeserializer()); - put(BacktraceDatabaseRecordDeserializer.class, new BacktraceDatabaseRecordDeserializer()) + put(BacktraceDatabaseRecordDeserializer.class, new BacktraceDatabaseRecordDeserializer()); }}; + public static void registerDeserializer(Class clazz, Deserializable obj) { deserializers.put(clazz, obj); } + + @SuppressWarnings("unchecked") public static T deserialize(JSONObject obj, Class clazz) throws JSONException { if (deserializers.containsKey(clazz)) { - return deserializers.get(clazz).deserialize(obj); + return (T) deserializers.get(clazz).deserialize(obj); } - return DEFAULT_DESERIALIZER.deserialize(obj); + return (T) DEFAULT_DESERIALIZER.deserialize(obj); } } diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceReportDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceReportDeserializer.java index 60401680..8717b74f 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceReportDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceReportDeserializer.java @@ -8,8 +8,10 @@ public class BacktraceReportDeserializer implements Deserializable{ + + @Override public BacktraceReport deserialize(JSONObject obj) throws JSONException { -// return new BacktraceReport(); // TODO - return null; // TODO: + return this.deserialize(obj); +// return null; // TODO: } } diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/Deserializable.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/Deserializable.java index 8b2f0177..9b7bae19 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/Deserializable.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/Deserializable.java @@ -4,5 +4,5 @@ import org.json.JSONObject; public interface Deserializable { - public T deserialize(JSONObject jsonObj) throws JSONException; + T deserialize(JSONObject obj) throws JSONException; } diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ReflectionDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ReflectionDeserializer.java index 7b17894b..7b743dcb 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ReflectionDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ReflectionDeserializer.java @@ -3,16 +3,27 @@ import org.json.JSONException; import org.json.JSONObject; +import java.lang.reflect.InvocationTargetException; + import backtraceio.library.common.serializers.SerializedName; import backtraceio.library.models.BacktraceResult; -public class ReflectionDeserializer implements Deserializable { +public final class ReflectionDeserializer implements Deserializable { @Override - public T1 deserialize(JSONObject jsonObj, Class clazz) throws JSONException { + public Object deserialize(JSONObject obj) throws JSONException { try { - T instance = clazz.newInstance(); + Class clazz = Object.class; + + // Get the class type from the JSON object if available + if (obj.has("classType")) { + String className = obj.getString("classType"); + clazz = Class.forName(className); + } + + // Create an instance of the class using reflection + Object instance = clazz.getDeclaredConstructor().newInstance(); // Assuming that the class has a default (no-argument) constructor // Iterate through the fields of the class @@ -24,9 +35,9 @@ public T1 deserialize(JSONObject jsonObj, Class clazz) throws JSONExcept String fieldName = field.getName(); // Check if the JSON object has a key with the field name - if (jsonObject.has(fieldName)) { + if (obj.has(fieldName)) { // Set the field value using reflection - field.set(instance, jsonObject.get(fieldName)); + field.set(instance, obj.get(fieldName)); continue; } @@ -35,7 +46,7 @@ public T1 deserialize(JSONObject jsonObj, Class clazz) throws JSONExcept SerializedName annotation = field.getAnnotation(SerializedName.class); if (annotation != null) { String customName = annotation.value(); - field.set(instance, jsonObject.get(customName)); + field.set(instance, obj.get(customName)); continue; } @@ -47,6 +58,12 @@ public T1 deserialize(JSONObject jsonObj, Class clazz) throws JSONExcept e.printStackTrace(); // Handle the exception appropriately } catch (JSONException e) { throw new RuntimeException(e); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + throw new RuntimeException(e); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); } return null; From b9a63d91c285c392a70206cd287744fb822dc5a1 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 10 Jan 2024 17:46:30 +0100 Subject: [PATCH 022/100] Unit tests deserializer --- backtrace-library/build.gradle | 1 + .../common/BacktraceSerializeHelper.java | 3 +- .../serializers/BacktraceDataSerializer.java | 3 +- .../BacktraceReportDeserializer.java | 64 +++++++++++++++++-- .../BacktraceResultDeserializer.java | 6 +- .../library/models/json/BacktraceReport.java | 19 +++++- .../library/models/json/SourceCodeData.java | 3 +- .../library/models/json/ThreadData.java | 7 +- .../models/json/ThreadInformation.java | 11 ++-- .../BacktraceReportDeserializerTest.java | 51 +++++++++++++++ .../BacktraceResultDeserializerTest.java | 36 +++++++++++ 11 files changed, 186 insertions(+), 18 deletions(-) create mode 100644 backtrace-library/src/test/java/backtraceio/library/BacktraceReportDeserializerTest.java create mode 100644 backtrace-library/src/test/java/backtraceio/library/BacktraceResultDeserializerTest.java diff --git a/backtrace-library/build.gradle b/backtrace-library/build.gradle index bb2b38fc..eae7bf18 100644 --- a/backtrace-library/build.gradle +++ b/backtrace-library/build.gradle @@ -71,6 +71,7 @@ dependencies { implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'com.squareup:tape:1.2.3' testImplementation 'junit:junit:4.13.2' + testImplementation 'org.json:json:20231013' testImplementation 'com.google.code.gson:gson:2.10.1' androidTestImplementation 'net.jodah:concurrentunit:0.4.4' androidTestImplementation 'androidx.test.ext:junit:1.1.5' 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 8274f389..367100ec 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/BacktraceSerializeHelper.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/BacktraceSerializeHelper.java @@ -18,7 +18,8 @@ public class BacktraceSerializeHelper { * @return serialized object in JSON string format */ public static String toJson(Object object) { - return BacktraceOrgJsonSerializer.toJson(object); + return new BacktraceGsonBuilder().buildGson().toJson(object); +// return BacktraceOrgJsonSerializer.toJson(object); } public static T fromJson(String json, Class type) { diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java index 9a1a20a1..92433166 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java @@ -10,6 +10,7 @@ import org.json.JSONObject; import java.util.ArrayList; +import java.util.List; import java.util.Map; import backtraceio.library.models.BacktraceData; @@ -90,7 +91,7 @@ private JSONObject serializeThreadInformation(Map thr } @NonNull - private JSONArray serializeStackList(ArrayList stack) throws JSONException { + private JSONArray serializeStackList(List stack) throws JSONException { JSONArray stackArray = new JSONArray(); for (BacktraceStackFrame stackFrame : stack) { diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceReportDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceReportDeserializer.java index 8717b74f..82e048f2 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceReportDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceReportDeserializer.java @@ -1,17 +1,73 @@ package backtraceio.library.common.serializers.deserializers; +import static backtraceio.library.common.BacktraceStringHelper.isNullOrEmpty; + +import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; -import backtraceio.library.models.database.BacktraceDatabaseRecord; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import backtraceio.library.models.BacktraceStackFrame; import backtraceio.library.models.json.BacktraceReport; -public class BacktraceReportDeserializer implements Deserializable{ +public class BacktraceReportDeserializer implements Deserializable { @Override + // TODO: fix all null warnings public BacktraceReport deserialize(JSONObject obj) throws JSONException { - return this.deserialize(obj); -// return null; // TODO: + final String uuid = obj.optString("uuid", null); + final long timestamp = obj.optLong("timestamp", 0); + final String message = obj.optString("message", null); // TODO fix + final String classifier = obj.optString("classifier", null); + final boolean exceptionTypeReport = obj.optBoolean("exception-type-report"); + final Exception exception = getException(obj.optJSONObject("exception")); // TODO: fix + final Map attributes = new HashMap<>(); // TODO: fix + + final List attachmentPaths = this.getAttachmentList(obj.optJSONArray("attachmentPaths")); + final List diagnosticStack = this.getBacktraceStackFrame(); + + return new BacktraceReport( + !isNullOrEmpty(uuid)? UUID.fromString(uuid) : null, + timestamp, + exceptionTypeReport, + classifier, + attributes, + message, + exception, + attachmentPaths, + diagnosticStack + ); + } + + public Exception getException(JSONObject obj) { + return null; // TODO: + } + + public Map getAttributes(JSONObject obj) { + return null; // TODO: + } + + public List getAttachmentList(JSONArray array) { + if (array == null) { + return null; + } + + List result = new ArrayList<>(); + + for (int i = 0; i < array.length(); i++) { + result.add(array.optString(i)); + } + + return result; + } + + public List getBacktraceStackFrame() { + return null; // TODO } } diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceResultDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceResultDeserializer.java index 48ecd4ce..8d45cd0e 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceResultDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceResultDeserializer.java @@ -6,9 +6,11 @@ import backtraceio.library.models.BacktraceResult; import backtraceio.library.models.types.BacktraceResultStatus; -public class BacktraceResultDeserializer implements Deserializable{ +public class BacktraceResultDeserializer implements Deserializable { public BacktraceResult deserialize(JSONObject obj) throws JSONException { - return new BacktraceResult(obj.optString("_rxid", null), obj.optString("response", BacktraceResultStatus.Ok.toString())); + return new BacktraceResult(obj.optString("_rxid", null), + obj.optString("response", BacktraceResultStatus.Ok.toString()) + ); } } diff --git a/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceReport.java b/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceReport.java index d47358a7..084592e8 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceReport.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceReport.java @@ -63,7 +63,7 @@ public class BacktraceReport { /** * Current report exception stack */ - public ArrayList diagnosticStack; + public List diagnosticStack; /** * Create new instance of Backtrace report to send a report with custom client message @@ -187,6 +187,23 @@ public BacktraceReport( this.setDefaultErrorTypeAttribute(); } + 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 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..e348a13b 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 @@ -2,6 +2,7 @@ import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import backtraceio.library.logger.BacktraceLogger; @@ -18,7 +19,7 @@ public class SourceCodeData { */ public 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..806e3857 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, 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 6f960597..9ee1648d 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 backtraceio.library.common.serializers.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 + private 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,7 @@ private ThreadInformation(String threadName, Boolean fault, ArrayList stack, Boolean currentThread) { + ThreadInformation(Thread thread, List stack, Boolean currentThread) { this(thread.getName().toLowerCase(), currentThread, stack); } @@ -63,7 +64,7 @@ public Boolean getFault() { return fault; } - public ArrayList getStack() { + public List getStack() { return stack; } } diff --git a/backtrace-library/src/test/java/backtraceio/library/BacktraceReportDeserializerTest.java b/backtrace-library/src/test/java/backtraceio/library/BacktraceReportDeserializerTest.java new file mode 100644 index 00000000..309867bd --- /dev/null +++ b/backtrace-library/src/test/java/backtraceio/library/BacktraceReportDeserializerTest.java @@ -0,0 +1,51 @@ +package backtraceio.library; + +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 com.google.gson.GsonBuilder; + +import org.json.JSONException; +import org.json.JSONObject; +import org.junit.Test; + +import java.util.HashMap; + +import backtraceio.library.common.BacktraceSerializeHelper; +import backtraceio.library.common.serialization.BacktraceGsonBuilder; +import backtraceio.library.common.serializers.deserializers.BacktraceReportDeserializer; +import backtraceio.library.common.serializers.deserializers.BacktraceResultDeserializer; +import backtraceio.library.models.BacktraceResult; +import backtraceio.library.models.json.BacktraceReport; +import backtraceio.library.models.types.BacktraceResultStatus; + +// TODO: move to standard unit tests not instrumented +public class BacktraceReportDeserializerTest { + @Test + public void deserializeCoronerApiJsonResponse() throws JSONException { + // GIVEN + String json3 = "{\"response\":\"Ok\",\"_rxid\":\"01000000-5360-240b-0000-000000000000\"}"; + String json = "{\"uuid\":\"39407c49-0999-438b-bfac-140c83d2521b\",\"timestamp\":1704901251,\"exception-type-report\":true,\"classifier\":\"java.lang.Exception\",\"attributes\":{\"error.type\":\"Exception\",\"test\":{\"detail-message\":\"123\",\"stack-trace\":[],\"suppressed-exceptions\":[]}},\"exception\":{\"detail-message\":\"test\",\"stack-trace\":[{\"class-loader-name\":\"app\",\"declaring-class\":\"backtraceio.library.BacktraceReportDeserializerTest\",\"method-name\":\"deserializeCoronerApiJsonResponse\",\"file-name\":\"BacktraceReportDeserializerTest.java\",\"line-number\":28,\"format\":1},{\"module-name\":\"java.base\",\"module-version\":\"11.0.15\",\"declaring-class\":\"jdk.internal.reflect.NativeMethodAccessorImpl\",\"method-name\":\"invoke0\",\"file-name\":\"NativeMethodAccessorImpl.java\",\"line-number\":-2,\"format\":2},{\"module-name\":\"java.base\",\"module-version\":\"11.0.15\",\"declaring-class\":\"jdk.internal.reflect.NativeMethodAccessorImpl\",\"method-name\":\"invoke\",\"file-name\":\"NativeMethodAccessorImpl.java\",\"line-number\":62,\"format\":2},{\"module-name\":\"java.base\",\"module-version\":\"11.0.15\",\"declaring-class\":\"jdk.internal.reflect.DelegatingMethodAccessorImpl\",\"method-name\":\"invoke\",\"file-name\":\"DelegatingMethodAccessorImpl.java\",\"line-number\":43,\"format\":2},{\"module-name\":\"java.base\",\"module-version\":\"11.0.15\",\"declaring-class\":\"java.lang.reflect.Method\",\"method-name\":\"invoke\",\"file-name\":\"Method.java\",\"line-number\":566,\"format\":2},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.model.FrameworkMethod$1\",\"method-name\":\"runReflectiveCall\",\"file-name\":\"FrameworkMethod.java\",\"line-number\":59,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.internal.runners.model.ReflectiveCallable\",\"method-name\":\"run\",\"file-name\":\"ReflectiveCallable.java\",\"line-number\":12,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.model.FrameworkMethod\",\"method-name\":\"invokeExplosively\",\"file-name\":\"FrameworkMethod.java\",\"line-number\":56,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.internal.runners.statements.InvokeMethod\",\"method-name\":\"evaluate\",\"file-name\":\"InvokeMethod.java\",\"line-number\":17,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.ParentRunner$3\",\"method-name\":\"evaluate\",\"file-name\":\"ParentRunner.java\",\"line-number\":306,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.BlockJUnit4ClassRunner$1\",\"method-name\":\"evaluate\",\"file-name\":\"BlockJUnit4ClassRunner.java\",\"line-number\":100,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.ParentRunner\",\"method-name\":\"runLeaf\",\"file-name\":\"ParentRunner.java\",\"line-number\":366,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.BlockJUnit4ClassRunner\",\"method-name\":\"runChild\",\"file-name\":\"BlockJUnit4ClassRunner.java\",\"line-number\":103,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.BlockJUnit4ClassRunner\",\"method-name\":\"runChild\",\"file-name\":\"BlockJUnit4ClassRunner.java\",\"line-number\":63,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.ParentRunner$4\",\"method-name\":\"run\",\"file-name\":\"ParentRunner.java\",\"line-number\":331,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.ParentRunner$1\",\"method-name\":\"schedule\",\"file-name\":\"ParentRunner.java\",\"line-number\":79,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.ParentRunner\",\"method-name\":\"runChildren\",\"file-name\":\"ParentRunner.java\",\"line-number\":329,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.ParentRunner\",\"method-name\":\"access$100\",\"file-name\":\"ParentRunner.java\",\"line-number\":66,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.ParentRunner$2\",\"method-name\":\"evaluate\",\"file-name\":\"ParentRunner.java\",\"line-number\":293,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.ParentRunner$3\",\"method-name\":\"evaluate\",\"file-name\":\"ParentRunner.java\",\"line-number\":306,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.ParentRunner\",\"method-name\":\"run\",\"file-name\":\"ParentRunner.java\",\"line-number\":413,\"format\":1},{\"declaring-class\":\"org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor\",\"method-name\":\"runTestClass\",\"file-name\":\"JUnitTestClassExecutor.java\",\"line-number\":110,\"format\":0},{\"declaring-class\":\"org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor\",\"method-name\":\"execute\",\"file-name\":\"JUnitTestClassExecutor.java\",\"line-number\":58,\"format\":0},{\"declaring-class\":\"org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor\",\"method-name\":\"execute\",\"file-name\":\"JUnitTestClassExecutor.java\",\"line-number\":38,\"format\":0},{\"declaring-class\":\"org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor\",\"method-name\":\"processTestClass\",\"file-name\":\"AbstractJUnitTestClassProcessor.java\",\"line-number\":62,\"format\":0},{\"declaring-class\":\"org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor\",\"method-name\":\"processTestClass\",\"file-name\":\"SuiteTestClassProcessor.java\",\"line-number\":51,\"format\":0},{\"module-name\":\"java.base\",\"module-version\":\"11.0.15\",\"declaring-class\":\"jdk.internal.reflect.NativeMethodAccessorImpl\",\"method-name\":\"invoke0\",\"file-name\":\"NativeMethodAccessorImpl.java\",\"line-number\":-2,\"format\":2},{\"module-name\":\"java.base\",\"module-version\":\"11.0.15\",\"declaring-class\":\"jdk.internal.reflect.NativeMethodAccessorImpl\",\"method-name\":\"invoke\",\"file-name\":\"NativeMethodAccessorImpl.java\",\"line-number\":62,\"format\":2},{\"module-name\":\"java.base\",\"module-version\":\"11.0.15\",\"declaring-class\":\"jdk.internal.reflect.DelegatingMethodAccessorImpl\",\"method-name\":\"invoke\",\"file-name\":\"DelegatingMethodAccessorImpl.java\",\"line-number\":43,\"format\":2},{\"module-name\":\"java.base\",\"module-version\":\"11.0.15\",\"declaring-class\":\"java.lang.reflect.Method\",\"method-name\":\"invoke\",\"file-name\":\"Method.java\",\"line-number\":566,\"format\":2},{\"declaring-class\":\"org.gradle.internal.dispatch.ReflectionDispatch\",\"method-name\":\"dispatch\",\"file-name\":\"ReflectionDispatch.java\",\"line-number\":36,\"format\":0},{\"declaring-class\":\"org.gradle.internal.dispatch.ReflectionDispatch\",\"method-name\":\"dispatch\",\"file-name\":\"ReflectionDispatch.java\",\"line-number\":24,\"format\":0},{\"declaring-class\":\"org.gradle.internal.dispatch.ContextClassLoaderDispatch\",\"method-name\":\"dispatch\",\"file-name\":\"ContextClassLoaderDispatch.java\",\"line-number\":33,\"format\":0},{\"declaring-class\":\"org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler\",\"method-name\":\"invoke\",\"file-name\":\"ProxyDispatchAdapter.java\",\"line-number\":94,\"format\":0},{\"declaring-class\":\"com.sun.proxy.$Proxy5\",\"method-name\":\"processTestClass\",\"line-number\":-1,\"format\":0},{\"declaring-class\":\"org.gradle.api.internal.tasks.testing.worker.TestWorker$2\",\"method-name\":\"run\",\"file-name\":\"TestWorker.java\",\"line-number\":176,\"format\":0},{\"declaring-class\":\"org.gradle.api.internal.tasks.testing.worker.TestWorker\",\"method-name\":\"executeAndMaintainThreadName\",\"file-name\":\"TestWorker.java\",\"line-number\":129,\"format\":0},{\"declaring-class\":\"org.gradle.api.internal.tasks.testing.worker.TestWorker\",\"method-name\":\"execute\",\"file-name\":\"TestWorker.java\",\"line-number\":100,\"format\":0},{\"declaring-class\":\"org.gradle.api.internal.tasks.testing.worker.TestWorker\",\"method-name\":\"execute\",\"file-name\":\"TestWorker.java\",\"line-number\":60,\"format\":0},{\"declaring-class\":\"org.gradle.process.internal.worker.child.ActionExecutionWorker\",\"method-name\":\"execute\",\"file-name\":\"ActionExecutionWorker.java\",\"line-number\":56,\"format\":0},{\"declaring-class\":\"org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker\",\"method-name\":\"call\",\"file-name\":\"SystemApplicationClassLoaderWorker.java\",\"line-number\":133,\"format\":0},{\"declaring-class\":\"org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker\",\"method-name\":\"call\",\"file-name\":\"SystemApplicationClassLoaderWorker.java\",\"line-number\":71,\"format\":0},{\"class-loader-name\":\"app\",\"declaring-class\":\"worker.org.gradle.process.internal.worker.GradleWorkerMain\",\"method-name\":\"run\",\"file-name\":\"GradleWorkerMain.java\",\"line-number\":69,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"worker.org.gradle.process.internal.worker.GradleWorkerMain\",\"method-name\":\"main\",\"file-name\":\"GradleWorkerMain.java\",\"line-number\":74,\"format\":1}],\"suppressed-exceptions\":[]},\"attachment-paths\":[],\"diagnostic-stack\":[{\"function-name\":\"jdk.internal.reflect.NativeMethodAccessorImpl.invoke0\",\"source-code\":\"09abddfa-f0b4-4c7b-8d4d-b5974b63ddbe\"},{\"function-name\":\"jdk.internal.reflect.NativeMethodAccessorImpl.invoke\",\"line\":62,\"source-code\":\"0e1d692e-c09d-4fc4-b79e-a10d5a2f1784\"},{\"function-name\":\"jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke\",\"line\":43,\"source-code\":\"f10bf34f-ebc9-448f-923c-d8d95d1e902c\"},{\"function-name\":\"java.lang.reflect.Method.invoke\",\"line\":566,\"source-code\":\"9dd50221-77de-4390-8e58-dd80d4e3d334\"},{\"function-name\":\"org.junit.runners.model.FrameworkMethod$1.runReflectiveCall\",\"line\":59,\"source-code\":\"6dfc62ec-cacb-4b1f-bd10-910d302b17d9\"},{\"function-name\":\"org.junit.internal.runners.model.ReflectiveCallable.run\",\"line\":12,\"source-code\":\"bfee006e-e2fc-4495-a9af-918b1d2a0b21\"},{\"function-name\":\"org.junit.runners.model.FrameworkMethod.invokeExplosively\",\"line\":56,\"source-code\":\"2c93a559-ce6a-4198-b0d5-f8eaf3e7d9e7\"},{\"function-name\":\"org.junit.internal.runners.statements.InvokeMethod.evaluate\",\"line\":17,\"source-code\":\"51bb3a68-0fa8-4fb6-892b-31814389a6e8\"},{\"function-name\":\"org.junit.runners.ParentRunner$3.evaluate\",\"line\":306,\"source-code\":\"25d86bea-22d1-4860-80b9-7c9bcc57fbbc\"},{\"function-name\":\"org.junit.runners.BlockJUnit4ClassRunner$1.evaluate\",\"line\":100,\"source-code\":\"02809e4b-14d7-4e59-a294-a96a4faef2f9\"},{\"function-name\":\"org.junit.runners.ParentRunner.runLeaf\",\"line\":366,\"source-code\":\"bafc405c-f6ed-4f43-8488-21ee7c69ceb9\"},{\"function-name\":\"org.junit.runners.BlockJUnit4ClassRunner.runChild\",\"line\":103,\"source-code\":\"c58d0aa9-62ad-4299-8917-ac03f08968da\"},{\"function-name\":\"org.junit.runners.BlockJUnit4ClassRunner.runChild\",\"line\":63,\"source-code\":\"784c5ee6-5705-4160-8f2f-4130af14b07f\"},{\"function-name\":\"org.junit.runners.ParentRunner$4.run\",\"line\":331,\"source-code\":\"d196c71a-5d5d-4c2f-9971-1ecf09c7c249\"},{\"function-name\":\"org.junit.runners.ParentRunner$1.schedule\",\"line\":79,\"source-code\":\"90fb8c3f-d9cf-4c51-b64f-4a0fb2828c5a\"},{\"function-name\":\"org.junit.runners.ParentRunner.runChildren\",\"line\":329,\"source-code\":\"d57386c0-c987-4e9e-84a6-5392be9c05fa\"},{\"function-name\":\"org.junit.runners.ParentRunner.access$100\",\"line\":66,\"source-code\":\"def6f727-70d7-40a8-945d-ad1200ab902f\"},{\"function-name\":\"org.junit.runners.ParentRunner$2.evaluate\",\"line\":293,\"source-code\":\"1715c216-399a-4149-812b-e4df6a84383a\"},{\"function-name\":\"org.junit.runners.ParentRunner$3.evaluate\",\"line\":306,\"source-code\":\"b944ea20-59e7-4a27-b04c-f6d0bbd56641\"},{\"function-name\":\"org.junit.runners.ParentRunner.run\",\"line\":413,\"source-code\":\"8fd59a49-370a-4037-aa3b-897d9f23cbd7\"},{\"function-name\":\"org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass\",\"line\":110,\"source-code\":\"ffff8d16-dbd9-46d9-a66d-66ea9ea09b2e\"},{\"function-name\":\"org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute\",\"line\":58,\"source-code\":\"2d51c1ef-31b9-4cb6-8e7a-fd532655374c\"},{\"function-name\":\"org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute\",\"line\":38,\"source-code\":\"838bf886-e97d-4e86-a4f3-519399c47d45\"},{\"function-name\":\"org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass\",\"line\":62,\"source-code\":\"c53e74a7-7461-43a3-943c-2f30b76c12fb\"},{\"function-name\":\"org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass\",\"line\":51,\"source-code\":\"c7c1f43b-bd91-49e2-b037-cfff36d704be\"},{\"function-name\":\"jdk.internal.reflect.NativeMethodAccessorImpl.invoke0\",\"source-code\":\"64223e3c-e9f1-4e10-bdb6-3017c6065c0d\"},{\"function-name\":\"jdk.internal.reflect.NativeMethodAccessorImpl.invoke\",\"line\":62,\"source-code\":\"30077941-0ca3-4262-910b-e247ddddc536\"},{\"function-name\":\"jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke\",\"line\":43,\"source-code\":\"7c553ce5-9c83-4c15-8371-e1e2888b551a\"},{\"function-name\":\"java.lang.reflect.Method.invoke\",\"line\":566,\"source-code\":\"95e942c1-39e2-4a8c-8a6d-bfdeb5ccd769\"},{\"function-name\":\"org.gradle.internal.dispatch.ReflectionDispatch.dispatch\",\"line\":36,\"source-code\":\"4148f823-3c5c-4cd9-8581-164da1674e76\"},{\"function-name\":\"org.gradle.internal.dispatch.ReflectionDispatch.dispatch\",\"line\":24,\"source-code\":\"d3d0bc8d-b044-4dc0-8005-02d0dcb4c696\"},{\"function-name\":\"org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch\",\"line\":33,\"source-code\":\"700c3d9c-9a29-4187-bfbe-75aee9bba6cd\"},{\"function-name\":\"org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke\",\"line\":94,\"source-code\":\"8ba21c2a-6ad1-4aff-8109-4f67c0155b5f\"},{\"function-name\":\"com.sun.proxy.$Proxy5.processTestClass\",\"source-code\":\"ccab4c45-b9d0-4165-93f0-17515e650f82\"},{\"function-name\":\"org.gradle.api.internal.tasks.testing.worker.TestWorker$2.run\",\"line\":176,\"source-code\":\"1be123e0-0320-4900-a22e-103e541b2e6a\"},{\"function-name\":\"org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName\",\"line\":129,\"source-code\":\"25e0fa54-6be5-402f-9fff-f1270d9af06d\"},{\"function-name\":\"org.gradle.api.internal.tasks.testing.worker.TestWorker.execute\",\"line\":100,\"source-code\":\"e987481f-feac-4e56-96ec-1cfd615b58dc\"},{\"function-name\":\"org.gradle.api.internal.tasks.testing.worker.TestWorker.execute\",\"line\":60,\"source-code\":\"395d0d24-420b-471f-92aa-4f1e066b08f9\"},{\"function-name\":\"org.gradle.process.internal.worker.child.ActionExecutionWorker.execute\",\"line\":56,\"source-code\":\"9a5a94f7-bb4d-45e9-98ef-db9bf4d29daf\"},{\"function-name\":\"org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call\",\"line\":133,\"source-code\":\"99a8df6d-5ce1-4831-a7b8-b999e28791fa\"},{\"function-name\":\"org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call\",\"line\":71,\"source-code\":\"8c1c5455-ef76-4bf9-b96b-2c7e551cd172\"},{\"function-name\":\"worker.org.gradle.process.internal.worker.GradleWorkerMain.run\",\"line\":69,\"source-code\":\"ba96ce9d-e712-4c87-a54e-86d1de170962\"},{\"function-name\":\"worker.org.gradle.process.internal.worker.GradleWorkerMain.main\",\"line\":74,\"source-code\":\"519557ac-72b3-4fc9-b6eb-6f3a201aeb0c\"}]}"; + // WHEN + String json2 = BacktraceSerializeHelper.toJson(new BacktraceReport(new Exception("test"), new HashMap() {{ put("test", new Exception("123")); }} )); + BacktraceReportDeserializer deserializer = new BacktraceReportDeserializer(); + BacktraceReport result2 = BacktraceSerializeHelper.fromJson(new BacktraceGsonBuilder().buildGson(), json, BacktraceReport.class); + BacktraceReport result = deserializer.deserialize(new JSONObject(json)); + + // THEN + assertNotNull(result); + assertEquals("39407c49-0999-438b-bfac-140c83d2521b", result.uuid.toString()); + assertEquals(1704901251, result.timestamp); + assertTrue(result.exceptionTypeReport); + assertEquals("java.lang.Exception", result.classifier); + assertNull(result.message); +// assertNull(result.getBacktraceReport()); +// assertNull(result.message); +// assertEquals(BacktraceResultStatus.Ok, result.status); +// assertEquals("01000000-5360-240b-0000-000000000000", result.rxId); + } + + // TODO: Add test case with another response e.g. server error +} diff --git a/backtrace-library/src/test/java/backtraceio/library/BacktraceResultDeserializerTest.java b/backtrace-library/src/test/java/backtraceio/library/BacktraceResultDeserializerTest.java new file mode 100644 index 00000000..ea7b9852 --- /dev/null +++ b/backtrace-library/src/test/java/backtraceio/library/BacktraceResultDeserializerTest.java @@ -0,0 +1,36 @@ +package backtraceio.library; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + + +import org.json.JSONException; +import org.json.JSONObject; +import org.junit.Test; + +import backtraceio.library.common.serializers.deserializers.BacktraceResultDeserializer; +import backtraceio.library.models.BacktraceResult; +import backtraceio.library.models.types.BacktraceResultStatus; + +// TODO: move to standard unit tests not instrumented +public class BacktraceResultDeserializerTest { + @Test + public void deserializeCoronerApiJsonResponse() throws JSONException { + // GIVEN + String json = "{\"response\":\"Ok\",\"_rxid\":\"01000000-5360-240b-0000-000000000000\"}"; + + // WHEN + BacktraceResultDeserializer deserializer = new BacktraceResultDeserializer(); + BacktraceResult result = deserializer.deserialize(new JSONObject(json)); + + // THEN + assertNotNull(result); + assertNull(result.getBacktraceReport()); + assertNull(result.message); + assertEquals(BacktraceResultStatus.Ok, result.status); + assertEquals("01000000-5360-240b-0000-000000000000", result.rxId); + } + + // TODO: Add test case with another response e.g. server error +} From 3686709bdd9676f7546a6baa0f2cbcc6341c3432 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Tue, 6 Feb 2024 17:58:36 +0100 Subject: [PATCH 023/100] Serialize exception --- .../BacktraceReportDeserializer.java | 54 +++++++++++++++---- .../deserializers/ExceptionDeserializer.java | 40 +++++++++++++- .../BacktraceReportDeserializerTest.java | 22 ++++---- 3 files changed, 91 insertions(+), 25 deletions(-) diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceReportDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceReportDeserializer.java index 82e048f2..e8332e9a 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceReportDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceReportDeserializer.java @@ -8,6 +8,7 @@ import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.UUID; @@ -17,20 +18,23 @@ public class BacktraceReportDeserializer implements Deserializable { - + ExceptionDeserializer exceptionDeserializer; + public BacktraceReportDeserializer() { + this.exceptionDeserializer = new ExceptionDeserializer(); + } @Override // TODO: fix all null warnings public BacktraceReport deserialize(JSONObject obj) throws JSONException { final String uuid = obj.optString("uuid", null); final long timestamp = obj.optLong("timestamp", 0); - final String message = obj.optString("message", null); // TODO fix - final String classifier = obj.optString("classifier", null); + final String message = obj.optString("message", null); + final String classifier = obj.optString("classifier", ""); final boolean exceptionTypeReport = obj.optBoolean("exception-type-report"); - final Exception exception = getException(obj.optJSONObject("exception")); // TODO: fix - final Map attributes = new HashMap<>(); // TODO: fix + final Exception exception = getException(obj.optJSONObject("exception")); + final Map attributes = this.getAttributes(obj.optJSONObject("attributes")); // TODO: fix final List attachmentPaths = this.getAttachmentList(obj.optJSONArray("attachmentPaths")); - final List diagnosticStack = this.getBacktraceStackFrame(); + final List diagnosticStack = this.getDiagnosticStack(obj.optJSONArray("diagnostic-stack")); // todo fix diagnostic-stack name return new BacktraceReport( !isNullOrEmpty(uuid)? UUID.fromString(uuid) : null, @@ -46,16 +50,28 @@ public BacktraceReport deserialize(JSONObject obj) throws JSONException { } public Exception getException(JSONObject obj) { - return null; // TODO: + return this.exceptionDeserializer.deserialize(obj); // TODO: fix usage } public Map getAttributes(JSONObject obj) { - return null; // TODO: + if (obj == null) { + return null; + } + + Map result = new HashMap<>(); + + Iterator attributesKeys = obj.keys(); + while (attributesKeys.hasNext()) { + String key = attributesKeys.next(); + result.put(key, obj.optString(key)); + } + + return result; } public List getAttachmentList(JSONArray array) { if (array == null) { - return null; + return new ArrayList<>(); } List result = new ArrayList<>(); @@ -67,7 +83,23 @@ public List getAttachmentList(JSONArray array) { return result; } - public List getBacktraceStackFrame() { - return null; // TODO + public List getDiagnosticStack(JSONArray obj) { + if (obj == null) { + return null; + } + + List result = new ArrayList<>(); + for (int i = 0; i < obj.length(); i++) { + JSONObject stackItem = obj.optJSONObject(i); + if (stackItem != null) { + BacktraceStackFrame stackFrame = new BacktraceStackFrame(); + stackFrame.functionName = stackItem.optString("function-name"); + stackFrame.line = stackItem.optInt("line"); // todo: should be null in case of empty + stackFrame.sourceCode = stackItem.optString("source-code"); + result.add(stackFrame); + } + } + + return result; } } diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ExceptionDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ExceptionDeserializer.java index d9f1c155..4ed24db0 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ExceptionDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ExceptionDeserializer.java @@ -1,11 +1,47 @@ package backtraceio.library.common.serializers.deserializers; +import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import java.util.ArrayList; +import java.util.List; + public class ExceptionDeserializer implements Deserializable { @Override - public Exception deserialize(JSONObject obj) throws JSONException { - return null; // TODO: fix + public Exception deserialize(JSONObject obj) { + final String message = obj.optString("detail-message", ""); + + final Exception exception = new Exception(message); + + try { + exception.setStackTrace(getStacktrace(obj.optJSONArray("stack-trace"))); + } + catch (JSONException jsonException) { + //TODO: handle + System.out.println(jsonException.toString()); + } + return exception; + } + + public StackTraceElement[] getStacktrace(JSONArray array) throws JSONException { + if (array == null || array.length() == 0) { + // TODO: + return null; + } + + StackTraceElement[] result = new StackTraceElement[array.length()]; + + for(int idx = 0; idx < array.length(); idx++) { + JSONObject obj = (JSONObject) array.get(idx); + result[idx] = new StackTraceElement( + obj.optString("declaring-class"), // make something to not hardcode in this way + obj.getString("method-name"), // make something to not hardcode in this way + obj.optString("file-name"), // make something to not hardcode in this way + obj.getInt("line-number") // make something to not hardcode in this way + ); + } + + return result; } } diff --git a/backtrace-library/src/test/java/backtraceio/library/BacktraceReportDeserializerTest.java b/backtrace-library/src/test/java/backtraceio/library/BacktraceReportDeserializerTest.java index 309867bd..2bb686f7 100644 --- a/backtrace-library/src/test/java/backtraceio/library/BacktraceReportDeserializerTest.java +++ b/backtrace-library/src/test/java/backtraceio/library/BacktraceReportDeserializerTest.java @@ -27,25 +27,23 @@ public class BacktraceReportDeserializerTest { public void deserializeCoronerApiJsonResponse() throws JSONException { // GIVEN String json3 = "{\"response\":\"Ok\",\"_rxid\":\"01000000-5360-240b-0000-000000000000\"}"; - String json = "{\"uuid\":\"39407c49-0999-438b-bfac-140c83d2521b\",\"timestamp\":1704901251,\"exception-type-report\":true,\"classifier\":\"java.lang.Exception\",\"attributes\":{\"error.type\":\"Exception\",\"test\":{\"detail-message\":\"123\",\"stack-trace\":[],\"suppressed-exceptions\":[]}},\"exception\":{\"detail-message\":\"test\",\"stack-trace\":[{\"class-loader-name\":\"app\",\"declaring-class\":\"backtraceio.library.BacktraceReportDeserializerTest\",\"method-name\":\"deserializeCoronerApiJsonResponse\",\"file-name\":\"BacktraceReportDeserializerTest.java\",\"line-number\":28,\"format\":1},{\"module-name\":\"java.base\",\"module-version\":\"11.0.15\",\"declaring-class\":\"jdk.internal.reflect.NativeMethodAccessorImpl\",\"method-name\":\"invoke0\",\"file-name\":\"NativeMethodAccessorImpl.java\",\"line-number\":-2,\"format\":2},{\"module-name\":\"java.base\",\"module-version\":\"11.0.15\",\"declaring-class\":\"jdk.internal.reflect.NativeMethodAccessorImpl\",\"method-name\":\"invoke\",\"file-name\":\"NativeMethodAccessorImpl.java\",\"line-number\":62,\"format\":2},{\"module-name\":\"java.base\",\"module-version\":\"11.0.15\",\"declaring-class\":\"jdk.internal.reflect.DelegatingMethodAccessorImpl\",\"method-name\":\"invoke\",\"file-name\":\"DelegatingMethodAccessorImpl.java\",\"line-number\":43,\"format\":2},{\"module-name\":\"java.base\",\"module-version\":\"11.0.15\",\"declaring-class\":\"java.lang.reflect.Method\",\"method-name\":\"invoke\",\"file-name\":\"Method.java\",\"line-number\":566,\"format\":2},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.model.FrameworkMethod$1\",\"method-name\":\"runReflectiveCall\",\"file-name\":\"FrameworkMethod.java\",\"line-number\":59,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.internal.runners.model.ReflectiveCallable\",\"method-name\":\"run\",\"file-name\":\"ReflectiveCallable.java\",\"line-number\":12,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.model.FrameworkMethod\",\"method-name\":\"invokeExplosively\",\"file-name\":\"FrameworkMethod.java\",\"line-number\":56,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.internal.runners.statements.InvokeMethod\",\"method-name\":\"evaluate\",\"file-name\":\"InvokeMethod.java\",\"line-number\":17,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.ParentRunner$3\",\"method-name\":\"evaluate\",\"file-name\":\"ParentRunner.java\",\"line-number\":306,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.BlockJUnit4ClassRunner$1\",\"method-name\":\"evaluate\",\"file-name\":\"BlockJUnit4ClassRunner.java\",\"line-number\":100,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.ParentRunner\",\"method-name\":\"runLeaf\",\"file-name\":\"ParentRunner.java\",\"line-number\":366,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.BlockJUnit4ClassRunner\",\"method-name\":\"runChild\",\"file-name\":\"BlockJUnit4ClassRunner.java\",\"line-number\":103,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.BlockJUnit4ClassRunner\",\"method-name\":\"runChild\",\"file-name\":\"BlockJUnit4ClassRunner.java\",\"line-number\":63,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.ParentRunner$4\",\"method-name\":\"run\",\"file-name\":\"ParentRunner.java\",\"line-number\":331,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.ParentRunner$1\",\"method-name\":\"schedule\",\"file-name\":\"ParentRunner.java\",\"line-number\":79,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.ParentRunner\",\"method-name\":\"runChildren\",\"file-name\":\"ParentRunner.java\",\"line-number\":329,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.ParentRunner\",\"method-name\":\"access$100\",\"file-name\":\"ParentRunner.java\",\"line-number\":66,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.ParentRunner$2\",\"method-name\":\"evaluate\",\"file-name\":\"ParentRunner.java\",\"line-number\":293,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.ParentRunner$3\",\"method-name\":\"evaluate\",\"file-name\":\"ParentRunner.java\",\"line-number\":306,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.ParentRunner\",\"method-name\":\"run\",\"file-name\":\"ParentRunner.java\",\"line-number\":413,\"format\":1},{\"declaring-class\":\"org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor\",\"method-name\":\"runTestClass\",\"file-name\":\"JUnitTestClassExecutor.java\",\"line-number\":110,\"format\":0},{\"declaring-class\":\"org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor\",\"method-name\":\"execute\",\"file-name\":\"JUnitTestClassExecutor.java\",\"line-number\":58,\"format\":0},{\"declaring-class\":\"org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor\",\"method-name\":\"execute\",\"file-name\":\"JUnitTestClassExecutor.java\",\"line-number\":38,\"format\":0},{\"declaring-class\":\"org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor\",\"method-name\":\"processTestClass\",\"file-name\":\"AbstractJUnitTestClassProcessor.java\",\"line-number\":62,\"format\":0},{\"declaring-class\":\"org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor\",\"method-name\":\"processTestClass\",\"file-name\":\"SuiteTestClassProcessor.java\",\"line-number\":51,\"format\":0},{\"module-name\":\"java.base\",\"module-version\":\"11.0.15\",\"declaring-class\":\"jdk.internal.reflect.NativeMethodAccessorImpl\",\"method-name\":\"invoke0\",\"file-name\":\"NativeMethodAccessorImpl.java\",\"line-number\":-2,\"format\":2},{\"module-name\":\"java.base\",\"module-version\":\"11.0.15\",\"declaring-class\":\"jdk.internal.reflect.NativeMethodAccessorImpl\",\"method-name\":\"invoke\",\"file-name\":\"NativeMethodAccessorImpl.java\",\"line-number\":62,\"format\":2},{\"module-name\":\"java.base\",\"module-version\":\"11.0.15\",\"declaring-class\":\"jdk.internal.reflect.DelegatingMethodAccessorImpl\",\"method-name\":\"invoke\",\"file-name\":\"DelegatingMethodAccessorImpl.java\",\"line-number\":43,\"format\":2},{\"module-name\":\"java.base\",\"module-version\":\"11.0.15\",\"declaring-class\":\"java.lang.reflect.Method\",\"method-name\":\"invoke\",\"file-name\":\"Method.java\",\"line-number\":566,\"format\":2},{\"declaring-class\":\"org.gradle.internal.dispatch.ReflectionDispatch\",\"method-name\":\"dispatch\",\"file-name\":\"ReflectionDispatch.java\",\"line-number\":36,\"format\":0},{\"declaring-class\":\"org.gradle.internal.dispatch.ReflectionDispatch\",\"method-name\":\"dispatch\",\"file-name\":\"ReflectionDispatch.java\",\"line-number\":24,\"format\":0},{\"declaring-class\":\"org.gradle.internal.dispatch.ContextClassLoaderDispatch\",\"method-name\":\"dispatch\",\"file-name\":\"ContextClassLoaderDispatch.java\",\"line-number\":33,\"format\":0},{\"declaring-class\":\"org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler\",\"method-name\":\"invoke\",\"file-name\":\"ProxyDispatchAdapter.java\",\"line-number\":94,\"format\":0},{\"declaring-class\":\"com.sun.proxy.$Proxy5\",\"method-name\":\"processTestClass\",\"line-number\":-1,\"format\":0},{\"declaring-class\":\"org.gradle.api.internal.tasks.testing.worker.TestWorker$2\",\"method-name\":\"run\",\"file-name\":\"TestWorker.java\",\"line-number\":176,\"format\":0},{\"declaring-class\":\"org.gradle.api.internal.tasks.testing.worker.TestWorker\",\"method-name\":\"executeAndMaintainThreadName\",\"file-name\":\"TestWorker.java\",\"line-number\":129,\"format\":0},{\"declaring-class\":\"org.gradle.api.internal.tasks.testing.worker.TestWorker\",\"method-name\":\"execute\",\"file-name\":\"TestWorker.java\",\"line-number\":100,\"format\":0},{\"declaring-class\":\"org.gradle.api.internal.tasks.testing.worker.TestWorker\",\"method-name\":\"execute\",\"file-name\":\"TestWorker.java\",\"line-number\":60,\"format\":0},{\"declaring-class\":\"org.gradle.process.internal.worker.child.ActionExecutionWorker\",\"method-name\":\"execute\",\"file-name\":\"ActionExecutionWorker.java\",\"line-number\":56,\"format\":0},{\"declaring-class\":\"org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker\",\"method-name\":\"call\",\"file-name\":\"SystemApplicationClassLoaderWorker.java\",\"line-number\":133,\"format\":0},{\"declaring-class\":\"org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker\",\"method-name\":\"call\",\"file-name\":\"SystemApplicationClassLoaderWorker.java\",\"line-number\":71,\"format\":0},{\"class-loader-name\":\"app\",\"declaring-class\":\"worker.org.gradle.process.internal.worker.GradleWorkerMain\",\"method-name\":\"run\",\"file-name\":\"GradleWorkerMain.java\",\"line-number\":69,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"worker.org.gradle.process.internal.worker.GradleWorkerMain\",\"method-name\":\"main\",\"file-name\":\"GradleWorkerMain.java\",\"line-number\":74,\"format\":1}],\"suppressed-exceptions\":[]},\"attachment-paths\":[],\"diagnostic-stack\":[{\"function-name\":\"jdk.internal.reflect.NativeMethodAccessorImpl.invoke0\",\"source-code\":\"09abddfa-f0b4-4c7b-8d4d-b5974b63ddbe\"},{\"function-name\":\"jdk.internal.reflect.NativeMethodAccessorImpl.invoke\",\"line\":62,\"source-code\":\"0e1d692e-c09d-4fc4-b79e-a10d5a2f1784\"},{\"function-name\":\"jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke\",\"line\":43,\"source-code\":\"f10bf34f-ebc9-448f-923c-d8d95d1e902c\"},{\"function-name\":\"java.lang.reflect.Method.invoke\",\"line\":566,\"source-code\":\"9dd50221-77de-4390-8e58-dd80d4e3d334\"},{\"function-name\":\"org.junit.runners.model.FrameworkMethod$1.runReflectiveCall\",\"line\":59,\"source-code\":\"6dfc62ec-cacb-4b1f-bd10-910d302b17d9\"},{\"function-name\":\"org.junit.internal.runners.model.ReflectiveCallable.run\",\"line\":12,\"source-code\":\"bfee006e-e2fc-4495-a9af-918b1d2a0b21\"},{\"function-name\":\"org.junit.runners.model.FrameworkMethod.invokeExplosively\",\"line\":56,\"source-code\":\"2c93a559-ce6a-4198-b0d5-f8eaf3e7d9e7\"},{\"function-name\":\"org.junit.internal.runners.statements.InvokeMethod.evaluate\",\"line\":17,\"source-code\":\"51bb3a68-0fa8-4fb6-892b-31814389a6e8\"},{\"function-name\":\"org.junit.runners.ParentRunner$3.evaluate\",\"line\":306,\"source-code\":\"25d86bea-22d1-4860-80b9-7c9bcc57fbbc\"},{\"function-name\":\"org.junit.runners.BlockJUnit4ClassRunner$1.evaluate\",\"line\":100,\"source-code\":\"02809e4b-14d7-4e59-a294-a96a4faef2f9\"},{\"function-name\":\"org.junit.runners.ParentRunner.runLeaf\",\"line\":366,\"source-code\":\"bafc405c-f6ed-4f43-8488-21ee7c69ceb9\"},{\"function-name\":\"org.junit.runners.BlockJUnit4ClassRunner.runChild\",\"line\":103,\"source-code\":\"c58d0aa9-62ad-4299-8917-ac03f08968da\"},{\"function-name\":\"org.junit.runners.BlockJUnit4ClassRunner.runChild\",\"line\":63,\"source-code\":\"784c5ee6-5705-4160-8f2f-4130af14b07f\"},{\"function-name\":\"org.junit.runners.ParentRunner$4.run\",\"line\":331,\"source-code\":\"d196c71a-5d5d-4c2f-9971-1ecf09c7c249\"},{\"function-name\":\"org.junit.runners.ParentRunner$1.schedule\",\"line\":79,\"source-code\":\"90fb8c3f-d9cf-4c51-b64f-4a0fb2828c5a\"},{\"function-name\":\"org.junit.runners.ParentRunner.runChildren\",\"line\":329,\"source-code\":\"d57386c0-c987-4e9e-84a6-5392be9c05fa\"},{\"function-name\":\"org.junit.runners.ParentRunner.access$100\",\"line\":66,\"source-code\":\"def6f727-70d7-40a8-945d-ad1200ab902f\"},{\"function-name\":\"org.junit.runners.ParentRunner$2.evaluate\",\"line\":293,\"source-code\":\"1715c216-399a-4149-812b-e4df6a84383a\"},{\"function-name\":\"org.junit.runners.ParentRunner$3.evaluate\",\"line\":306,\"source-code\":\"b944ea20-59e7-4a27-b04c-f6d0bbd56641\"},{\"function-name\":\"org.junit.runners.ParentRunner.run\",\"line\":413,\"source-code\":\"8fd59a49-370a-4037-aa3b-897d9f23cbd7\"},{\"function-name\":\"org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass\",\"line\":110,\"source-code\":\"ffff8d16-dbd9-46d9-a66d-66ea9ea09b2e\"},{\"function-name\":\"org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute\",\"line\":58,\"source-code\":\"2d51c1ef-31b9-4cb6-8e7a-fd532655374c\"},{\"function-name\":\"org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute\",\"line\":38,\"source-code\":\"838bf886-e97d-4e86-a4f3-519399c47d45\"},{\"function-name\":\"org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass\",\"line\":62,\"source-code\":\"c53e74a7-7461-43a3-943c-2f30b76c12fb\"},{\"function-name\":\"org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass\",\"line\":51,\"source-code\":\"c7c1f43b-bd91-49e2-b037-cfff36d704be\"},{\"function-name\":\"jdk.internal.reflect.NativeMethodAccessorImpl.invoke0\",\"source-code\":\"64223e3c-e9f1-4e10-bdb6-3017c6065c0d\"},{\"function-name\":\"jdk.internal.reflect.NativeMethodAccessorImpl.invoke\",\"line\":62,\"source-code\":\"30077941-0ca3-4262-910b-e247ddddc536\"},{\"function-name\":\"jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke\",\"line\":43,\"source-code\":\"7c553ce5-9c83-4c15-8371-e1e2888b551a\"},{\"function-name\":\"java.lang.reflect.Method.invoke\",\"line\":566,\"source-code\":\"95e942c1-39e2-4a8c-8a6d-bfdeb5ccd769\"},{\"function-name\":\"org.gradle.internal.dispatch.ReflectionDispatch.dispatch\",\"line\":36,\"source-code\":\"4148f823-3c5c-4cd9-8581-164da1674e76\"},{\"function-name\":\"org.gradle.internal.dispatch.ReflectionDispatch.dispatch\",\"line\":24,\"source-code\":\"d3d0bc8d-b044-4dc0-8005-02d0dcb4c696\"},{\"function-name\":\"org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch\",\"line\":33,\"source-code\":\"700c3d9c-9a29-4187-bfbe-75aee9bba6cd\"},{\"function-name\":\"org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke\",\"line\":94,\"source-code\":\"8ba21c2a-6ad1-4aff-8109-4f67c0155b5f\"},{\"function-name\":\"com.sun.proxy.$Proxy5.processTestClass\",\"source-code\":\"ccab4c45-b9d0-4165-93f0-17515e650f82\"},{\"function-name\":\"org.gradle.api.internal.tasks.testing.worker.TestWorker$2.run\",\"line\":176,\"source-code\":\"1be123e0-0320-4900-a22e-103e541b2e6a\"},{\"function-name\":\"org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName\",\"line\":129,\"source-code\":\"25e0fa54-6be5-402f-9fff-f1270d9af06d\"},{\"function-name\":\"org.gradle.api.internal.tasks.testing.worker.TestWorker.execute\",\"line\":100,\"source-code\":\"e987481f-feac-4e56-96ec-1cfd615b58dc\"},{\"function-name\":\"org.gradle.api.internal.tasks.testing.worker.TestWorker.execute\",\"line\":60,\"source-code\":\"395d0d24-420b-471f-92aa-4f1e066b08f9\"},{\"function-name\":\"org.gradle.process.internal.worker.child.ActionExecutionWorker.execute\",\"line\":56,\"source-code\":\"9a5a94f7-bb4d-45e9-98ef-db9bf4d29daf\"},{\"function-name\":\"org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call\",\"line\":133,\"source-code\":\"99a8df6d-5ce1-4831-a7b8-b999e28791fa\"},{\"function-name\":\"org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call\",\"line\":71,\"source-code\":\"8c1c5455-ef76-4bf9-b96b-2c7e551cd172\"},{\"function-name\":\"worker.org.gradle.process.internal.worker.GradleWorkerMain.run\",\"line\":69,\"source-code\":\"ba96ce9d-e712-4c87-a54e-86d1de170962\"},{\"function-name\":\"worker.org.gradle.process.internal.worker.GradleWorkerMain.main\",\"line\":74,\"source-code\":\"519557ac-72b3-4fc9-b6eb-6f3a201aeb0c\"}]}"; + String json = "{\"uuid\":\"444d7674-378c-48fd-9b51-d961c3bba3ab\",\"timestamp\":1704905258,\"exception-type-report\":true,\"classifier\":\"java.lang.IllegalAccessException\",\"attributes\":{\"error.type\":\"Exception\",\"test\":{\"detail-message\":\"123\",\"stack-trace\":[],\"suppressed-exceptions\":[]}},\"exception\":{\"detail-message\":\"test\",\"stack-trace\":[{\"class-loader-name\":\"app\",\"declaring-class\":\"backtraceio.library.BacktraceReportDeserializerTest\",\"method-name\":\"deserializeCoronerApiJsonResponse\",\"file-name\":\"BacktraceReportDeserializerTest.java\",\"line-number\":32,\"format\":1},{\"module-name\":\"java.base\",\"module-version\":\"11.0.15\",\"declaring-class\":\"jdk.internal.reflect.NativeMethodAccessorImpl\",\"method-name\":\"invoke0\",\"file-name\":\"NativeMethodAccessorImpl.java\",\"line-number\":-2,\"format\":2},{\"module-name\":\"java.base\",\"module-version\":\"11.0.15\",\"declaring-class\":\"jdk.internal.reflect.NativeMethodAccessorImpl\",\"method-name\":\"invoke\",\"file-name\":\"NativeMethodAccessorImpl.java\",\"line-number\":62,\"format\":2},{\"module-name\":\"java.base\",\"module-version\":\"11.0.15\",\"declaring-class\":\"jdk.internal.reflect.DelegatingMethodAccessorImpl\",\"method-name\":\"invoke\",\"file-name\":\"DelegatingMethodAccessorImpl.java\",\"line-number\":43,\"format\":2},{\"module-name\":\"java.base\",\"module-version\":\"11.0.15\",\"declaring-class\":\"java.lang.reflect.Method\",\"method-name\":\"invoke\",\"file-name\":\"Method.java\",\"line-number\":566,\"format\":2},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.model.FrameworkMethod$1\",\"method-name\":\"runReflectiveCall\",\"file-name\":\"FrameworkMethod.java\",\"line-number\":59,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.internal.runners.model.ReflectiveCallable\",\"method-name\":\"run\",\"file-name\":\"ReflectiveCallable.java\",\"line-number\":12,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.model.FrameworkMethod\",\"method-name\":\"invokeExplosively\",\"file-name\":\"FrameworkMethod.java\",\"line-number\":56,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.internal.runners.statements.InvokeMethod\",\"method-name\":\"evaluate\",\"file-name\":\"InvokeMethod.java\",\"line-number\":17,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.ParentRunner$3\",\"method-name\":\"evaluate\",\"file-name\":\"ParentRunner.java\",\"line-number\":306,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.BlockJUnit4ClassRunner$1\",\"method-name\":\"evaluate\",\"file-name\":\"BlockJUnit4ClassRunner.java\",\"line-number\":100,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.ParentRunner\",\"method-name\":\"runLeaf\",\"file-name\":\"ParentRunner.java\",\"line-number\":366,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.BlockJUnit4ClassRunner\",\"method-name\":\"runChild\",\"file-name\":\"BlockJUnit4ClassRunner.java\",\"line-number\":103,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.BlockJUnit4ClassRunner\",\"method-name\":\"runChild\",\"file-name\":\"BlockJUnit4ClassRunner.java\",\"line-number\":63,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.ParentRunner$4\",\"method-name\":\"run\",\"file-name\":\"ParentRunner.java\",\"line-number\":331,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.ParentRunner$1\",\"method-name\":\"schedule\",\"file-name\":\"ParentRunner.java\",\"line-number\":79,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.ParentRunner\",\"method-name\":\"runChildren\",\"file-name\":\"ParentRunner.java\",\"line-number\":329,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.ParentRunner\",\"method-name\":\"access$100\",\"file-name\":\"ParentRunner.java\",\"line-number\":66,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.ParentRunner$2\",\"method-name\":\"evaluate\",\"file-name\":\"ParentRunner.java\",\"line-number\":293,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.ParentRunner$3\",\"method-name\":\"evaluate\",\"file-name\":\"ParentRunner.java\",\"line-number\":306,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.ParentRunner\",\"method-name\":\"run\",\"file-name\":\"ParentRunner.java\",\"line-number\":413,\"format\":1},{\"declaring-class\":\"org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor\",\"method-name\":\"runTestClass\",\"file-name\":\"JUnitTestClassExecutor.java\",\"line-number\":110,\"format\":0},{\"declaring-class\":\"org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor\",\"method-name\":\"execute\",\"file-name\":\"JUnitTestClassExecutor.java\",\"line-number\":58,\"format\":0},{\"declaring-class\":\"org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor\",\"method-name\":\"execute\",\"file-name\":\"JUnitTestClassExecutor.java\",\"line-number\":38,\"format\":0},{\"declaring-class\":\"org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor\",\"method-name\":\"processTestClass\",\"file-name\":\"AbstractJUnitTestClassProcessor.java\",\"line-number\":62,\"format\":0},{\"declaring-class\":\"org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor\",\"method-name\":\"processTestClass\",\"file-name\":\"SuiteTestClassProcessor.java\",\"line-number\":51,\"format\":0},{\"module-name\":\"java.base\",\"module-version\":\"11.0.15\",\"declaring-class\":\"jdk.internal.reflect.NativeMethodAccessorImpl\",\"method-name\":\"invoke0\",\"file-name\":\"NativeMethodAccessorImpl.java\",\"line-number\":-2,\"format\":2},{\"module-name\":\"java.base\",\"module-version\":\"11.0.15\",\"declaring-class\":\"jdk.internal.reflect.NativeMethodAccessorImpl\",\"method-name\":\"invoke\",\"file-name\":\"NativeMethodAccessorImpl.java\",\"line-number\":62,\"format\":2},{\"module-name\":\"java.base\",\"module-version\":\"11.0.15\",\"declaring-class\":\"jdk.internal.reflect.DelegatingMethodAccessorImpl\",\"method-name\":\"invoke\",\"file-name\":\"DelegatingMethodAccessorImpl.java\",\"line-number\":43,\"format\":2},{\"module-name\":\"java.base\",\"module-version\":\"11.0.15\",\"declaring-class\":\"java.lang.reflect.Method\",\"method-name\":\"invoke\",\"file-name\":\"Method.java\",\"line-number\":566,\"format\":2},{\"declaring-class\":\"org.gradle.internal.dispatch.ReflectionDispatch\",\"method-name\":\"dispatch\",\"file-name\":\"ReflectionDispatch.java\",\"line-number\":36,\"format\":0},{\"declaring-class\":\"org.gradle.internal.dispatch.ReflectionDispatch\",\"method-name\":\"dispatch\",\"file-name\":\"ReflectionDispatch.java\",\"line-number\":24,\"format\":0},{\"declaring-class\":\"org.gradle.internal.dispatch.ContextClassLoaderDispatch\",\"method-name\":\"dispatch\",\"file-name\":\"ContextClassLoaderDispatch.java\",\"line-number\":33,\"format\":0},{\"declaring-class\":\"org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler\",\"method-name\":\"invoke\",\"file-name\":\"ProxyDispatchAdapter.java\",\"line-number\":94,\"format\":0},{\"declaring-class\":\"com.sun.proxy.$Proxy5\",\"method-name\":\"processTestClass\",\"line-number\":-1,\"format\":0},{\"declaring-class\":\"org.gradle.api.internal.tasks.testing.worker.TestWorker$2\",\"method-name\":\"run\",\"file-name\":\"TestWorker.java\",\"line-number\":176,\"format\":0},{\"declaring-class\":\"org.gradle.api.internal.tasks.testing.worker.TestWorker\",\"method-name\":\"executeAndMaintainThreadName\",\"file-name\":\"TestWorker.java\",\"line-number\":129,\"format\":0},{\"declaring-class\":\"org.gradle.api.internal.tasks.testing.worker.TestWorker\",\"method-name\":\"execute\",\"file-name\":\"TestWorker.java\",\"line-number\":100,\"format\":0},{\"declaring-class\":\"org.gradle.api.internal.tasks.testing.worker.TestWorker\",\"method-name\":\"execute\",\"file-name\":\"TestWorker.java\",\"line-number\":60,\"format\":0},{\"declaring-class\":\"org.gradle.process.internal.worker.child.ActionExecutionWorker\",\"method-name\":\"execute\",\"file-name\":\"ActionExecutionWorker.java\",\"line-number\":56,\"format\":0},{\"declaring-class\":\"org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker\",\"method-name\":\"call\",\"file-name\":\"SystemApplicationClassLoaderWorker.java\",\"line-number\":133,\"format\":0},{\"declaring-class\":\"org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker\",\"method-name\":\"call\",\"file-name\":\"SystemApplicationClassLoaderWorker.java\",\"line-number\":71,\"format\":0},{\"class-loader-name\":\"app\",\"declaring-class\":\"worker.org.gradle.process.internal.worker.GradleWorkerMain\",\"method-name\":\"run\",\"file-name\":\"GradleWorkerMain.java\",\"line-number\":69,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"worker.org.gradle.process.internal.worker.GradleWorkerMain\",\"method-name\":\"main\",\"file-name\":\"GradleWorkerMain.java\",\"line-number\":74,\"format\":1}],\"suppressed-exceptions\":[]},\"attachment-paths\":[],\"diagnostic-stack\":[{\"function-name\":\"jdk.internal.reflect.NativeMethodAccessorImpl.invoke0\",\"source-code\":\"4cb41569-1b17-4a69-8b48-37582c95f87a\"},{\"function-name\":\"jdk.internal.reflect.NativeMethodAccessorImpl.invoke\",\"line\":62,\"source-code\":\"792b5fee-8fd0-4686-9715-78bdcc01df34\"},{\"function-name\":\"jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke\",\"line\":43,\"source-code\":\"2356b394-c780-4c9c-9eeb-3d33de2929b8\"},{\"function-name\":\"java.lang.reflect.Method.invoke\",\"line\":566,\"source-code\":\"7bb5feae-2be1-4c9a-a173-def2dbb5224e\"},{\"function-name\":\"org.junit.runners.model.FrameworkMethod$1.runReflectiveCall\",\"line\":59,\"source-code\":\"6fc4926b-58a9-4d54-a154-660d521ab5d0\"},{\"function-name\":\"org.junit.internal.runners.model.ReflectiveCallable.run\",\"line\":12,\"source-code\":\"32e57bb6-e81c-427a-8ba3-e6982c4b157b\"},{\"function-name\":\"org.junit.runners.model.FrameworkMethod.invokeExplosively\",\"line\":56,\"source-code\":\"75f22f28-7cb4-47f8-99e5-a48d73aafe12\"},{\"function-name\":\"org.junit.internal.runners.statements.InvokeMethod.evaluate\",\"line\":17,\"source-code\":\"cbe15b23-a13d-4779-94ff-1e41edba94f3\"},{\"function-name\":\"org.junit.runners.ParentRunner$3.evaluate\",\"line\":306,\"source-code\":\"a7805b15-c619-4033-b8db-3f7f6bd17df6\"},{\"function-name\":\"org.junit.runners.BlockJUnit4ClassRunner$1.evaluate\",\"line\":100,\"source-code\":\"9a3b6b5f-9f13-44c0-9578-51606d1909c3\"},{\"function-name\":\"org.junit.runners.ParentRunner.runLeaf\",\"line\":366,\"source-code\":\"c249c6c4-fd10-44c3-975d-d3fbb592de81\"},{\"function-name\":\"org.junit.runners.BlockJUnit4ClassRunner.runChild\",\"line\":103,\"source-code\":\"37e1c09b-3130-4442-ae81-80d2b40893e0\"},{\"function-name\":\"org.junit.runners.BlockJUnit4ClassRunner.runChild\",\"line\":63,\"source-code\":\"691a9153-27ad-494c-8e97-28cf9c596431\"},{\"function-name\":\"org.junit.runners.ParentRunner$4.run\",\"line\":331,\"source-code\":\"aed30d5c-2c23-4da7-984e-9b853c0f82e1\"},{\"function-name\":\"org.junit.runners.ParentRunner$1.schedule\",\"line\":79,\"source-code\":\"ac1bf646-f881-4009-a1a9-cd8b943e3433\"},{\"function-name\":\"org.junit.runners.ParentRunner.runChildren\",\"line\":329,\"source-code\":\"dd1bad0a-521e-4b6c-9f5d-8f913817b831\"},{\"function-name\":\"org.junit.runners.ParentRunner.access$100\",\"line\":66,\"source-code\":\"0aa5b966-b70c-43f1-a644-25bad713d2b4\"},{\"function-name\":\"org.junit.runners.ParentRunner$2.evaluate\",\"line\":293,\"source-code\":\"64a86c43-bac6-4868-aa7c-f3572952a4f8\"},{\"function-name\":\"org.junit.runners.ParentRunner$3.evaluate\",\"line\":306,\"source-code\":\"3615e845-9d23-473e-bf14-273a9a9bb138\"},{\"function-name\":\"org.junit.runners.ParentRunner.run\",\"line\":413,\"source-code\":\"f6a03f68-151e-4111-8723-0652f3371ea0\"},{\"function-name\":\"org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass\",\"line\":110,\"source-code\":\"b1d4e3d3-dca9-4c3f-9d26-f399f3bf7923\"},{\"function-name\":\"org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute\",\"line\":58,\"source-code\":\"aa1069c3-0bf4-4479-ad33-5a4053135e59\"},{\"function-name\":\"org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute\",\"line\":38,\"source-code\":\"114a456e-88a3-4888-be52-7102794a7038\"},{\"function-name\":\"org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass\",\"line\":62,\"source-code\":\"8f10c785-6aa9-4236-bcb1-3e2bf93c524a\"},{\"function-name\":\"org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass\",\"line\":51,\"source-code\":\"4e80f634-abf6-415c-9cce-1619dd67fc23\"},{\"function-name\":\"jdk.internal.reflect.NativeMethodAccessorImpl.invoke0\",\"source-code\":\"7c0d6267-d9f3-413c-84e2-23722e1bb223\"},{\"function-name\":\"jdk.internal.reflect.NativeMethodAccessorImpl.invoke\",\"line\":62,\"source-code\":\"3f740a13-ee55-4428-a6dd-bb803138e660\"},{\"function-name\":\"jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke\",\"line\":43,\"source-code\":\"11eb9575-b019-4484-ba11-29fc194fed49\"},{\"function-name\":\"java.lang.reflect.Method.invoke\",\"line\":566,\"source-code\":\"65afbae6-c443-4f3b-9390-6124e24f95e1\"},{\"function-name\":\"org.gradle.internal.dispatch.ReflectionDispatch.dispatch\",\"line\":36,\"source-code\":\"362cd836-732c-4c1e-af25-4f1e294253f2\"},{\"function-name\":\"org.gradle.internal.dispatch.ReflectionDispatch.dispatch\",\"line\":24,\"source-code\":\"4b005a51-0d16-426d-a367-b83dc37c13ab\"},{\"function-name\":\"org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch\",\"line\":33,\"source-code\":\"ca109cad-f9ee-41d6-8029-379f4f01f5a8\"},{\"function-name\":\"org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke\",\"line\":94,\"source-code\":\"599b1cdc-1b45-4126-848c-c0e56e8ce8d4\"},{\"function-name\":\"com.sun.proxy.$Proxy5.processTestClass\",\"source-code\":\"f2814221-e618-4aa0-9315-60003596f658\"},{\"function-name\":\"org.gradle.api.internal.tasks.testing.worker.TestWorker$2.run\",\"line\":176,\"source-code\":\"51f5c2d0-b9cc-4176-b36b-d97a20463d3e\"},{\"function-name\":\"org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName\",\"line\":129,\"source-code\":\"d104a0f1-6da3-41b1-b442-b80373bcb1b5\"},{\"function-name\":\"org.gradle.api.internal.tasks.testing.worker.TestWorker.execute\",\"line\":100,\"source-code\":\"120f38d5-525d-4ac4-a507-442455140ce9\"},{\"function-name\":\"org.gradle.api.internal.tasks.testing.worker.TestWorker.execute\",\"line\":60,\"source-code\":\"d9d1bdb6-042b-4465-9737-2d65668632c0\"},{\"function-name\":\"org.gradle.process.internal.worker.child.ActionExecutionWorker.execute\",\"line\":56,\"source-code\":\"d4806ec1-0dab-48df-8b5d-834804fe5c43\"},{\"function-name\":\"org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call\",\"line\":133,\"source-code\":\"d0f083ba-6a43-4e9c-8e2b-e0cdf8638a88\"},{\"function-name\":\"org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call\",\"line\":71,\"source-code\":\"24c83e74-20eb-4a28-866c-a641dee9d245\"},{\"function-name\":\"worker.org.gradle.process.internal.worker.GradleWorkerMain.run\",\"line\":69,\"source-code\":\"fa90688b-00e1-4a2e-b5f9-038de2f3dd4f\"},{\"function-name\":\"worker.org.gradle.process.internal.worker.GradleWorkerMain.main\",\"line\":74,\"source-code\":\"88b732b6-b058-469b-8549-578818de4138\"}]}"; // WHEN - String json2 = BacktraceSerializeHelper.toJson(new BacktraceReport(new Exception("test"), new HashMap() {{ put("test", new Exception("123")); }} )); + String json2 = BacktraceSerializeHelper.toJson(new BacktraceReport(new IllegalAccessException("test"), new HashMap() {{ put("test", new Exception("123")); }} )); BacktraceReportDeserializer deserializer = new BacktraceReportDeserializer(); - BacktraceReport result2 = BacktraceSerializeHelper.fromJson(new BacktraceGsonBuilder().buildGson(), json, BacktraceReport.class); - BacktraceReport result = deserializer.deserialize(new JSONObject(json)); + BacktraceReport resultGson = BacktraceSerializeHelper.fromJson(new BacktraceGsonBuilder().buildGson(), json, BacktraceReport.class); + BacktraceReport resultCustom = deserializer.deserialize(new JSONObject(json)); // THEN - assertNotNull(result); - assertEquals("39407c49-0999-438b-bfac-140c83d2521b", result.uuid.toString()); - assertEquals(1704901251, result.timestamp); - assertTrue(result.exceptionTypeReport); - assertEquals("java.lang.Exception", result.classifier); - assertNull(result.message); + assertNotNull(resultCustom); + assertEquals("39407c49-0999-438b-bfac-140c83d2521b", resultCustom.uuid.toString()); + assertEquals(1704901251, resultCustom.timestamp); + assertTrue(resultCustom.exceptionTypeReport); + assertEquals("java.lang.Exception", resultCustom.classifier); + assertNull(resultCustom.message); // assertNull(result.getBacktraceReport()); // assertNull(result.message); // assertEquals(BacktraceResultStatus.Ok, result.status); // assertEquals("01000000-5360-240b-0000-000000000000", result.rxId); } - - // TODO: Add test case with another response e.g. server error } From b8e01b4c2c0af96e4a0990005eebdb9e26be9983 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Tue, 6 Feb 2024 22:19:56 +0100 Subject: [PATCH 024/100] Prepare unit test for backtrace data --- .../BacktraceDataDeserializer.java | 1 + .../BacktraceDataDeserializerTest.java | 39 +++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 backtrace-library/src/test/java/backtraceio/library/BacktraceDataDeserializerTest.java diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDataDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDataDeserializer.java index fbae1d9e..448b035c 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDataDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDataDeserializer.java @@ -10,6 +10,7 @@ public class BacktraceDataDeserializer implements Deserializable{ public BacktraceData deserialize(JSONObject obj) throws JSONException { + return new BacktraceData(); // TODO } } diff --git a/backtrace-library/src/test/java/backtraceio/library/BacktraceDataDeserializerTest.java b/backtrace-library/src/test/java/backtraceio/library/BacktraceDataDeserializerTest.java new file mode 100644 index 00000000..12eaaf14 --- /dev/null +++ b/backtrace-library/src/test/java/backtraceio/library/BacktraceDataDeserializerTest.java @@ -0,0 +1,39 @@ +package backtraceio.library; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import org.json.JSONException; +import org.json.JSONObject; +import org.junit.Test; + +import backtraceio.library.common.serializers.BacktraceDeserializer; +import backtraceio.library.models.BacktraceData; + +public class BacktraceDataDeserializerTest { + + @Test + public void deserializeBacktraceData() throws JSONException { + // GIVEN + final String backtraceDataJson = "{\"agent\":\"backtrace-android\",\"agent-version\":\"3.7.12-8-3686709-org-json-serializer\",\"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\",\"PATH\":\"/product/bin:/apex/com.android.runtime/bin:/apex/com.android.art/bin:/system_ext/bin:/system/bin:/system/xbin:/odm/bin:/vendor/bin:/vendor/xbin\",\"ANDROID_SOCKET_zygote\":\"17\",\"ANDROID_I18N_ROOT\":\"/apex/com.android.i18n\",\"ANDROID_DATA\":\"/data\",\"ASEC_MOUNTPOINT\":\"/mnt/asec\",\"ANDROID_TZDATA_ROOT\":\"/apex/com.android.tzdata\",\"EXTERNAL_STORAGE\":\"/sdcard\",\"ANDROID_BOOTLOGO\":\"1\",\"ANDROID_ASSETS\":\"/system/app\",\"ANDROID_STORAGE\":\"/storage\",\"DEX2OATBOOTCLASSPATH\":\"/apex/com.android.art/javalib/core-oj.jar:/apex/com.android.art/javalib/core-libart.jar:/apex/com.android.art/javalib/core-icu4j.jar:/apex/com.android.art/javalib/okhttp.jar:/apex/com.android.art/javalib/bouncycastle.jar:/apex/com.android.art/javalib/apache-xml.jar:/system/framework/framework.jar:/system/framework/ext.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/framework-atb-backward-compatibility.jar\",\"ANDROID_ART_ROOT\":\"/apex/com.android.art\",\"ANDROID_ROOT\":\"/system\",\"DOWNLOAD_CACHE\":\"/data/cache\",\"BOOTCLASSPATH\":\"/apex/com.android.art/javalib/core-oj.jar:/apex/com.android.art/javalib/core-libart.jar:/apex/com.android.art/javalib/core-icu4j.jar:/apex/com.android.art/javalib/okhttp.jar:/apex/com.android.art/javalib/bouncycastle.jar:/apex/com.android.art/javalib/apache-xml.jar:/system/framework/framework.jar:/system/framework/ext.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/framework-atb-backward-compatibility.jar:/apex/com.android.conscrypt/javalib/conscrypt.jar:/apex/com.android.media/javalib/updatable-media.jar:/apex/com.android.mediaprovider/javalib/framework-mediaprovider.jar:/apex/com.android.os.statsd/javalib/framework-statsd.jar:/apex/com.android.permission/javalib/framework-permission.jar:/apex/com.android.sdkext/javalib/framework-sdkextensions.jar:/apex/com.android.wifi/javalib/framework-wifi.jar:/apex/com.android.tethering/javalib/framework-tethering.jar\",\"ANDROID_SOCKET_usap_pool_primary\":\"21\"},\"Exception\":{\"message\":\"Example test string\"}},\"attributes\":{\"application.session\":\"fd86372a-457d-4347-b1af-34779f86f520\",\"device.nfc.status\":\"NotAvailable\",\"device.cpu.temperature\":\"0.0\",\"system.memory.active\":\"1094905856\",\"device.wifi.status\":\"Enabled\",\"screen.height\":\"1834\",\"uname.machine\":\"i686\",\"screen.dpi\":\"288\",\"device.bluetooth_status\":\"NotPermitted\",\"device.airplane_mode\":\"false\",\"system.memory.total\":\"2077347840\",\"device.sdk\":\"30\",\"device.brand\":\"google\",\"uname.sysname\":\"Android\",\"cpu.boottime\":\"1707253373829\",\"device.os_version\":\"5.4.61-android11-0-00791-gbad091cc4bf3-ab6833933\",\"device.gps.enabled\":\"Enabled\",\"application.package\":\"backtraceio.library.test\",\"uname.version\":\"11\",\"backtrace.version\":\"3.7.12-8-3686709-org-json-serializer\",\"device.is_power_saving_mode\":\"false\",\"screen.orientation\":\"Portrait\",\"device.manufacturer\":\"Google\",\"system.memory.free\":\"982441984\",\"battery.state\":\"Unplugged\",\"backtrace.agent\":\"backtrace-android\",\"error.type\":\"Message\",\"device.location\":\"Enabled\",\"application\":\"backtraceio.library.test\",\"error.message\":\"Example test string\",\"culture\":\"English\",\"device.model\":\"sdk_gphone_x86\",\"screen.width\":\"1080\",\"build.type\":\"Debug\",\"device.product\":\"sdk_gphone_x86\",\"guid\":\"e4c57699-0dc9-35e2-b4a0-2ffff1925ca7\",\"app.storage_used\":\"2974528\",\"battery.level\":\"1.0\",\"screen.brightness\":\"102\"},\"lang\":\"java\",\"lang-version\":\"0\",\"main-thread\":\"instr: androidx.test.runner.androidjunitrunner\",\"source-code\":{\"5ad3ea57-08bc-42b9-a0af-4c0b63abd5d7\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":331},\"e1c31c4a-9f5f-4aae-8f74-29c5f7398e4d\":{\"source-code-file-name\":\"AndroidJUnit4.java\",\"start-line\":162},\"0a88f8a1-60c0-41a0-a95c-d75de5a4c82d\":{\"source-code-file-name\":\"JUnitCore.java\",\"start-line\":137},\"b1cc1675-df0c-4bda-9ec2-cc50d02b7497\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":66},\"6237d391-f50f-49b7-a029-dc8533521a39\":{\"source-code-file-name\":\"BlockJUnit4ClassRunner.java\",\"start-line\":100},\"24d96335-14d8-45d8-a07d-fc24bc56d4db\":{\"source-code-file-name\":\"Suite.java\",\"start-line\":128},\"9b765b76-8714-4dc2-8584-c58e57d0b97d\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":79},\"0952a91a-0c4b-45f2-93c7-e744a7e64ded\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":306},\"86deee3a-0e5f-495b-af66-5b2f36964ca2\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":79},\"bbf3d67c-a184-49ee-b0d5-b02188e3fa30\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":293},\"a70079ba-1646-4dda-ae17-7a92bf584c69\":{\"source-code-file-name\":\"ReflectiveCallable.java\",\"start-line\":12},\"61876082-acce-458e-8248-bfb03dc2b340\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":306},\"cfe92970-ae80-45b4-9dd4-8099919a1c26\":{\"source-code-file-name\":\"Suite.java\",\"start-line\":27},\"a4ef001f-1238-4b6e-9e57-aaa3dc1717ce\":{\"source-code-file-name\":\"AndroidJUnitRunner.java\",\"start-line\":446},\"6e8a4d01-3519-4742-be84-34da0dac2460\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":413},\"42aefc9a-50aa-40e9-ac4e-483c279cd9dc\":{\"source-code-file-name\":\"Method.java\"},\"56847938-10cc-4e20-98e2-521ce93ebe70\":{\"source-code-file-name\":\"VMStack.java\"},\"86086e43-f1de-49c0-aeda-3ae2be530407\":{\"source-code-file-name\":\"FrameworkMethod.java\",\"start-line\":59},\"ecc0e91a-52b3-48e7-b509-a850f49652c1\":{\"source-code-file-name\":\"RunBefores.java\",\"start-line\":80},\"673561af-72d1-4294-8f73-cca30446e70e\":{\"source-code-file-name\":\"BlockJUnit4ClassRunner.java\",\"start-line\":103},\"88ac7e2c-c331-4249-910d-519a6d25363f\":{\"source-code-file-name\":\"BlockJUnit4ClassRunner.java\",\"start-line\":63},\"ea2aa6d0-8e27-402d-8836-9ede35629ac9\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":66},\"4d79837a-1751-47e1-a134-d883871a9cec\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":413},\"7787b022-3043-4976-9dde-990443b50b24\":{\"source-code-file-name\":\"FrameworkMethod.java\",\"start-line\":56},\"5ed2c2aa-38a0-42ed-8f05-9131c4c72e90\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":366},\"e7bd36c2-dd6a-4bb3-bac5-e5e606490c71\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":329},\"ddf80aac-8ae4-42cc-9d35-5dae41fbf626\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":329},\"2980dbe3-ee88-486c-8442-9b6816dfe07a\":{\"source-code-file-name\":\"RunAfters.java\",\"start-line\":61},\"351d6b15-5d61-4a8a-9a06-5b14bf071945\":{\"source-code-file-name\":\"JUnitCore.java\",\"start-line\":115},\"2172b7fe-e8cf-4ffa-936b-c6efb52694bb\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":331},\"9ae72a6b-31be-435f-8a52-461f043b492b\":{\"source-code-file-name\":\"TestExecutor.java\",\"start-line\":58},\"a67eccc1-bd1c-4207-93a5-db20e09b79aa\":{\"source-code-file-name\":\"Instrumentation.java\",\"start-line\":2205},\"76276ba5-69ae-4815-8a9c-77525b526cb1\":{\"source-code-file-name\":\"TestExecutor.java\",\"start-line\":67},\"23444a66-f715-444f-afcb-f367a6f72689\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":293},\"1cfc3859-cf21-4d84-ba61-d73d9ee73c41\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":306},\"653bad70-8157-49d4-8894-8bb089f76722\":{\"source-code-file-name\":\"Thread.java\",\"start-line\":1736},\"84649fde-1055-4085-a52e-52c35811cbde\":{\"source-code-file-name\":\"InvokeMethod.java\",\"start-line\":17}},\"thread-information-map\":{\"profile saver\":{\"fault\":false,\"name\":\"profile saver\",\"stack\":[]},\"finalizerwatchdogdaemon\":{\"fault\":false,\"name\":\"finalizerwatchdogdaemon\",\"stack\":[{\"function-name\":\"java.lang.Object.wait\",\"source-code\":\"b778a593-508f-444d-ab62-77d1ea5506c5\"},{\"function-name\":\"java.lang.Object.wait\",\"line\":442,\"source-code\":\"567b0437-8d29-4cc2-9274-819c056179a9\"},{\"function-name\":\"java.lang.Object.wait\",\"line\":568,\"source-code\":\"d07089b6-e586-4cde-ab31-3d0d1740ae25\"},{\"function-name\":\"java.lang.Daemons$FinalizerWatchdogDaemon.sleepUntilNeeded\",\"line\":341,\"source-code\":\"5aa512c3-e353-4309-9613-f3175bc05c56\"},{\"function-name\":\"java.lang.Daemons$FinalizerWatchdogDaemon.runInternal\",\"line\":321,\"source-code\":\"a8fb461e-e7b9-4259-b16f-8e9610884d2a\"},{\"function-name\":\"java.lang.Daemons$Daemon.run\",\"line\":139,\"source-code\":\"100f945a-c9ed-42d4-a396-bfb1c9c09e32\"},{\"function-name\":\"java.lang.Thread.run\",\"line\":923,\"source-code\":\"ba65711d-9470-4cdc-a06a-32db7ce84db9\"}]},\"signal catcher\":{\"fault\":false,\"name\":\"signal catcher\",\"stack\":[]},\"timer-0\":{\"fault\":false,\"name\":\"timer-0\",\"stack\":[{\"function-name\":\"java.lang.Object.wait\",\"source-code\":\"dbfe3cc6-8ac5-4a8c-b4c2-3c4073e563c7\"},{\"function-name\":\"java.lang.Object.wait\",\"line\":442,\"source-code\":\"ce872d4e-20a7-4991-9ae6-b0c09ff728f1\"},{\"function-name\":\"java.util.TimerThread.mainLoop\",\"line\":559,\"source-code\":\"507a2ca3-1e70-492a-9a75-cb95073c44a0\"},{\"function-name\":\"java.util.TimerThread.run\",\"line\":512,\"source-code\":\"06908da9-ce73-4835-b1e3-5fb732fcf82e\"}]},\"main\":{\"fault\":false,\"name\":\"main\",\"stack\":[{\"function-name\":\"android.os.MessageQueue.nativePollOnce\",\"source-code\":\"30ad9a05-28af-4db8-8ee6-35d55cc85ca5\"},{\"function-name\":\"android.os.MessageQueue.next\",\"line\":335,\"source-code\":\"58e043c1-b6f0-47ee-a5ea-af64153bd38b\"},{\"function-name\":\"android.os.Looper.loop\",\"line\":183,\"source-code\":\"9718f15f-0010-4e8f-8012-a5c48b554a9f\"},{\"function-name\":\"android.app.ActivityThread.main\",\"line\":7656,\"source-code\":\"4cc5b61d-3403-4a03-8a69-63adbcc55511\"},{\"function-name\":\"java.lang.reflect.Method.invoke\",\"source-code\":\"23078e7a-df17-4655-bad5-48b90baedba9\"},{\"function-name\":\"com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run\",\"line\":592,\"source-code\":\"cc45db4a-ec38-49d9-b5f6-14b804362ccd\"},{\"function-name\":\"com.android.internal.os.ZygoteInit.main\",\"line\":947,\"source-code\":\"406194e7-76b8-4b8f-977c-21756313f648\"}]},\"finalizerdaemon\":{\"fault\":false,\"name\":\"finalizerdaemon\",\"stack\":[{\"function-name\":\"java.lang.Object.wait\",\"source-code\":\"daff552e-1ac1-4417-9b77-fd91b3a664fc\"},{\"function-name\":\"java.lang.Object.wait\",\"line\":442,\"source-code\":\"d1445680-d522-46d4-ae3a-b2daeda6de3d\"},{\"function-name\":\"java.lang.ref.ReferenceQueue.remove\",\"line\":190,\"source-code\":\"260f72cf-3b32-48ff-9722-af6280876415\"},{\"function-name\":\"java.lang.ref.ReferenceQueue.remove\",\"line\":211,\"source-code\":\"e951fdfd-cde7-49f2-926b-4e131544d4d4\"},{\"function-name\":\"java.lang.Daemons$FinalizerDaemon.runInternal\",\"line\":273,\"source-code\":\"4f2ac4ed-051c-4a1c-a94d-999809f38ea6\"},{\"function-name\":\"java.lang.Daemons$Daemon.run\",\"line\":139,\"source-code\":\"d2d21d80-5047-4c37-abe5-cb0e854c555a\"},{\"function-name\":\"java.lang.Thread.run\",\"line\":923,\"source-code\":\"ceeb7b8e-7b5c-4d65-9c80-7c8e02a12202\"}]},\"referencequeuedaemon\":{\"fault\":false,\"name\":\"referencequeuedaemon\",\"stack\":[{\"function-name\":\"java.lang.Object.wait\",\"source-code\":\"d569fd77-fec0-4abd-b746-1e43394a8ca1\"},{\"function-name\":\"java.lang.Object.wait\",\"line\":442,\"source-code\":\"29bee7cd-cda4-4cd0-b7b6-1b21c40f3ee5\"},{\"function-name\":\"java.lang.Object.wait\",\"line\":568,\"source-code\":\"4b73fe34-9a92-4b11-a391-fa60086a62b4\"},{\"function-name\":\"java.lang.Daemons$ReferenceQueueDaemon.runInternal\",\"line\":217,\"source-code\":\"e76abece-43e7-48a0-a429-f13b75282fdd\"},{\"function-name\":\"java.lang.Daemons$Daemon.run\",\"line\":139,\"source-code\":\"08d8fd2b-8d9e-4317-ad68-3031de5f429f\"},{\"function-name\":\"java.lang.Thread.run\",\"line\":923,\"source-code\":\"8509b640-6470-4894-a896-7794e917c270\"}]},\"binder:8909_3\":{\"fault\":false,\"name\":\"binder:8909_3\",\"stack\":[]},\"jit thread pool worker thread 0\":{\"fault\":false,\"name\":\"jit thread pool worker thread 0\",\"stack\":[]},\"instrumentationconnectionthread\":{\"fault\":false,\"name\":\"instrumentationconnectionthread\",\"stack\":[{\"function-name\":\"android.os.MessageQueue.nativePollOnce\",\"source-code\":\"2699757c-16bd-4853-8d48-ad23aeebf5ad\"},{\"function-name\":\"android.os.MessageQueue.next\",\"line\":335,\"source-code\":\"bf1a4cc2-55ee-43c3-83a0-8780eeece1ce\"},{\"function-name\":\"android.os.Looper.loop\",\"line\":183,\"source-code\":\"2e0184c2-dd7e-41b6-946a-a646896cb880\"},{\"function-name\":\"android.os.HandlerThread.run\",\"line\":67,\"source-code\":\"209e3b61-b3f2-4de5-b8e3-6d832e969ce9\"}]},\"instr: androidx.test.runner.androidjunitrunner\":{\"fault\":true,\"name\":\"instr: androidx.test.runner.androidjunitrunner\",\"stack\":[{\"function-name\":\"dalvik.system.VMStack.getThreadStackTrace\",\"source-code\":\"56847938-10cc-4e20-98e2-521ce93ebe70\"},{\"function-name\":\"java.lang.Thread.getStackTrace\",\"line\":1736,\"source-code\":\"653bad70-8157-49d4-8894-8bb089f76722\"},{\"function-name\":\"java.lang.reflect.Method.invoke\",\"source-code\":\"42aefc9a-50aa-40e9-ac4e-483c279cd9dc\"},{\"function-name\":\"org.junit.runners.model.FrameworkMethod$1.runReflectiveCall\",\"line\":59,\"source-code\":\"86086e43-f1de-49c0-aeda-3ae2be530407\"},{\"function-name\":\"org.junit.internal.runners.model.ReflectiveCallable.run\",\"line\":12,\"source-code\":\"a70079ba-1646-4dda-ae17-7a92bf584c69\"},{\"function-name\":\"org.junit.runners.model.FrameworkMethod.invokeExplosively\",\"line\":56,\"source-code\":\"7787b022-3043-4976-9dde-990443b50b24\"},{\"function-name\":\"org.junit.internal.runners.statements.InvokeMethod.evaluate\",\"line\":17,\"source-code\":\"84649fde-1055-4085-a52e-52c35811cbde\"},{\"function-name\":\"androidx.test.internal.runner.junit4.statement.RunBefores.evaluate\",\"line\":80,\"source-code\":\"ecc0e91a-52b3-48e7-b509-a850f49652c1\"},{\"function-name\":\"androidx.test.internal.runner.junit4.statement.RunAfters.evaluate\",\"line\":61,\"source-code\":\"2980dbe3-ee88-486c-8442-9b6816dfe07a\"},{\"function-name\":\"org.junit.runners.ParentRunner$3.evaluate\",\"line\":306,\"source-code\":\"1cfc3859-cf21-4d84-ba61-d73d9ee73c41\"},{\"function-name\":\"org.junit.runners.BlockJUnit4ClassRunner$1.evaluate\",\"line\":100,\"source-code\":\"6237d391-f50f-49b7-a029-dc8533521a39\"},{\"function-name\":\"org.junit.runners.ParentRunner.runLeaf\",\"line\":366,\"source-code\":\"5ed2c2aa-38a0-42ed-8f05-9131c4c72e90\"},{\"function-name\":\"org.junit.runners.BlockJUnit4ClassRunner.runChild\",\"line\":103,\"source-code\":\"673561af-72d1-4294-8f73-cca30446e70e\"},{\"function-name\":\"org.junit.runners.BlockJUnit4ClassRunner.runChild\",\"line\":63,\"source-code\":\"88ac7e2c-c331-4249-910d-519a6d25363f\"},{\"function-name\":\"org.junit.runners.ParentRunner$4.run\",\"line\":331,\"source-code\":\"2172b7fe-e8cf-4ffa-936b-c6efb52694bb\"},{\"function-name\":\"org.junit.runners.ParentRunner$1.schedule\",\"line\":79,\"source-code\":\"86deee3a-0e5f-495b-af66-5b2f36964ca2\"},{\"function-name\":\"org.junit.runners.ParentRunner.runChildren\",\"line\":329,\"source-code\":\"e7bd36c2-dd6a-4bb3-bac5-e5e606490c71\"},{\"function-name\":\"org.junit.runners.ParentRunner.access$100\",\"line\":66,\"source-code\":\"ea2aa6d0-8e27-402d-8836-9ede35629ac9\"},{\"function-name\":\"org.junit.runners.ParentRunner$2.evaluate\",\"line\":293,\"source-code\":\"23444a66-f715-444f-afcb-f367a6f72689\"},{\"function-name\":\"org.junit.runners.ParentRunner$3.evaluate\",\"line\":306,\"source-code\":\"0952a91a-0c4b-45f2-93c7-e744a7e64ded\"},{\"function-name\":\"org.junit.runners.ParentRunner.run\",\"line\":413,\"source-code\":\"6e8a4d01-3519-4742-be84-34da0dac2460\"},{\"function-name\":\"androidx.test.ext.junit.runners.AndroidJUnit4.run\",\"line\":162,\"source-code\":\"e1c31c4a-9f5f-4aae-8f74-29c5f7398e4d\"},{\"function-name\":\"org.junit.runners.Suite.runChild\",\"line\":128,\"source-code\":\"24d96335-14d8-45d8-a07d-fc24bc56d4db\"},{\"function-name\":\"org.junit.runners.Suite.runChild\",\"line\":27,\"source-code\":\"cfe92970-ae80-45b4-9dd4-8099919a1c26\"},{\"function-name\":\"org.junit.runners.ParentRunner$4.run\",\"line\":331,\"source-code\":\"5ad3ea57-08bc-42b9-a0af-4c0b63abd5d7\"},{\"function-name\":\"org.junit.runners.ParentRunner$1.schedule\",\"line\":79,\"source-code\":\"9b765b76-8714-4dc2-8584-c58e57d0b97d\"},{\"function-name\":\"org.junit.runners.ParentRunner.runChildren\",\"line\":329,\"source-code\":\"ddf80aac-8ae4-42cc-9d35-5dae41fbf626\"},{\"function-name\":\"org.junit.runners.ParentRunner.access$100\",\"line\":66,\"source-code\":\"b1cc1675-df0c-4bda-9ec2-cc50d02b7497\"},{\"function-name\":\"org.junit.runners.ParentRunner$2.evaluate\",\"line\":293,\"source-code\":\"bbf3d67c-a184-49ee-b0d5-b02188e3fa30\"},{\"function-name\":\"org.junit.runners.ParentRunner$3.evaluate\",\"line\":306,\"source-code\":\"61876082-acce-458e-8248-bfb03dc2b340\"},{\"function-name\":\"org.junit.runners.ParentRunner.run\",\"line\":413,\"source-code\":\"4d79837a-1751-47e1-a134-d883871a9cec\"},{\"function-name\":\"org.junit.runner.JUnitCore.run\",\"line\":137,\"source-code\":\"0a88f8a1-60c0-41a0-a95c-d75de5a4c82d\"},{\"function-name\":\"org.junit.runner.JUnitCore.run\",\"line\":115,\"source-code\":\"351d6b15-5d61-4a8a-9a06-5b14bf071945\"},{\"function-name\":\"androidx.test.internal.runner.TestExecutor.execute\",\"line\":67,\"source-code\":\"76276ba5-69ae-4815-8a9c-77525b526cb1\"},{\"function-name\":\"androidx.test.internal.runner.TestExecutor.execute\",\"line\":58,\"source-code\":\"9ae72a6b-31be-435f-8a52-461f043b492b\"},{\"function-name\":\"androidx.test.runner.AndroidJUnitRunner.onStart\",\"line\":446,\"source-code\":\"a4ef001f-1238-4b6e-9e57-aaa3dc1717ce\"},{\"function-name\":\"android.app.Instrumentation$InstrumentationThread.run\",\"line\":2205,\"source-code\":\"a67eccc1-bd1c-4207-93a5-db20e09b79aa\"}]},\"binder:8909_1\":{\"fault\":false,\"name\":\"binder:8909_1\",\"stack\":[]},\"heaptaskdaemon\":{\"fault\":false,\"name\":\"heaptaskdaemon\",\"stack\":[]},\"binder:8909_2\":{\"fault\":false,\"name\":\"binder:8909_2\",\"stack\":[]}},\"timestamp\":1707253867,\"uuid\":\"8e68b676-21cb-4cc8-ac2e-32a60e8d29c1\"}"; + + // WHEN + final BacktraceData result = BacktraceDeserializer.deserialize(new JSONObject(backtraceDataJson), BacktraceData.class); + + // THEN + assertNotNull(result); + assertEquals("8e68b676-21cb-4cc8-ac2e-32a60e8d29c1", result.uuid); + assertEquals("backtrace-android", result.agent); + assertEquals("3.7.12-8-3686709-org-json-serializer", result.agentVersion); + assertEquals("java", result.lang); + assertEquals("0", result.langVersion); + assertEquals(1707253867, result.timestamp); + assertEquals("instr: androidx.test.runner.androidjunitrunner", result.mainThread); + + // TODO: +// assertEquals("", result.annotations); +// assertEquals("", result.attributes); +// assertEquals("", result.sourceCode); +// assertEquals("", result.getThreadInformationMap()); + } +} From f89ec68e30bf6fc98a412ba8be023e9e036f451f Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 7 Feb 2024 22:10:24 +0100 Subject: [PATCH 025/100] Deserializer database record --- .../common/BacktraceDataDeserializerTest.java | 8 +- .../common/BacktraceDataSerializerTest.java | 6 +- .../BacktraceDatabaseContextTest.java | 10 +- .../BacktraceDatabaseFileContextTest.java | 34 +- .../BacktraceDatabaseProguardTest.java | 12 +- .../database/BacktraceDatabaseRecordTest.java | 49 +- .../database/BacktraceDatabaseTest.java | 34 +- .../library/models/BacktraceDataTest.java | 2 +- .../library/BacktraceDatabase.java | 4 +- .../library/base/BacktraceBase.java | 6 +- .../common/BacktraceSerializeHelper.java | 4 +- .../BacktraceDataDeserializer.java | 417 +++++++++--------- .../BacktraceDataDeserializer.java | 16 +- .../BacktraceDatabaseRecordDeserializer.java | 9 +- .../library/models/BacktraceData.java | 261 +++++++---- .../BacktraceDataAttachmentsFileHelper.java | 14 + .../database/BacktraceDatabaseRecord.java | 52 ++- .../library/models/json/BacktraceReport.java | 5 +- .../library/services/BacktraceApi.java | 7 +- .../services/BacktraceHandlerThread.java | 17 +- 20 files changed, 555 insertions(+), 412 deletions(-) create mode 100644 backtrace-library/src/main/java/backtraceio/library/models/BacktraceDataAttachmentsFileHelper.java diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java index 47953220..b150f04b 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java @@ -103,9 +103,9 @@ public void fromJson2() throws JSONException, IllegalAccessException { BacktraceData dataJson = BacktraceOrgJsonDeserializer.deserialize(content, BacktraceData.class); - BacktraceData backtraceData = BacktraceDataDeserializer.deserialize(context, jsonObj); +// BacktraceData backtraceData = BacktraceDataDeserializer.deserialize(context, jsonObj); - System.out.println(backtraceData.report); +// System.out.println(backtraceData.report); // THEN // assertEquals(backtraceData.report.message, ); } @@ -126,9 +126,9 @@ public void fromJson() throws JSONException, IllegalAccessException { // File x = getFileFromPath(this, "resources/sample.json"); JSONObject jsonObj = new JSONObject(content); - BacktraceData backtraceData = BacktraceDataDeserializer.deserialize(context, jsonObj); +// BacktraceData backtraceData = BacktraceDataDeserializer.deserialize(context, jsonObj); - System.out.println(backtraceData.report); +// System.out.println(backtraceData.report); // THEN // assertEquals(backtraceData.report.message, ); } diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java index c6b5c858..15f9090e 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java @@ -44,7 +44,7 @@ public void testGsonSerializer() throws JSONException, IllegalAccessException { attachments.add("test-path"); attachments.add("test-path2"); final BacktraceReport report = new BacktraceReport(exception, attributes, attachments); - final BacktraceData data = new BacktraceData(context, report, null); + final BacktraceData data = new BacktraceData.Builder(context, report, null).build(); // WHEN final String jsonFromGson = BacktraceSerializeHelper.toJson(data); @@ -95,7 +95,7 @@ public void testGsonPerformanceSerializer() throws JSONException, IllegalAccessE attachments.add(Integer.toString(i)); attachments.add(Integer.toString(i * 10)); final BacktraceReport report = new BacktraceReport(exception, attributes, attachments); - final BacktraceData data = new BacktraceData(context, report, null); + final BacktraceData data = new BacktraceData.Builder(context, report, null).build(); // GSON long startTime = System.currentTimeMillis(); @@ -107,7 +107,7 @@ public void testGsonPerformanceSerializer() throws JSONException, IllegalAccessE // ORG JSON long startTimeOrg = System.currentTimeMillis(); BacktraceDataSerializer serializer = new BacktraceDataSerializer(new NamingPolicy()); - serializer.toJson( data); + serializer.toJson(data); long endTimeOrg = System.currentTimeMillis(); timeOrgJson += endTimeOrg - startTimeOrg; } 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 a05ce0b3..db75d12f 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseContextTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseContextTest.java @@ -146,7 +146,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(this.context, report, null).build(); BacktraceDatabaseRecord record = new BacktraceDatabaseRecord(data, this.dbPath); // WHEN @@ -219,7 +219,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(this.context, report, null).build(); BacktraceDatabaseRecord record = new BacktraceDatabaseRecord(data, this.dbPath); // WHEN @@ -244,9 +244,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(this.context, report, null).build(); + BacktraceData data2 = new BacktraceData.Builder(this.context, report2, null).build(); + BacktraceData data3 = new BacktraceData.Builder(this.context, report3, 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 e165cb60..89523ae4 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseFileContextTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseFileContextTest.java @@ -56,7 +56,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(this.context, report, null).build()); // WHEN int files = countAllFiles(); @@ -72,9 +72,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(this.context, report, null).build()); + this.databaseContext.add(new BacktraceData.Builder(this.context, report2, null).build()); + this.databaseContext.add(new BacktraceData.Builder(this.context, report3, null).build()); // WHEN int files = countAllFiles(); @@ -90,9 +90,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(this.context, report, null).build()); + this.databaseContext.add(new BacktraceData.Builder(this.context, report2, null).build()); + this.databaseContext.add(new BacktraceData.Builder(this.context, report3, null).build()); // WHEN int files = countRecords(); @@ -108,8 +108,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(this.context, report, null).build()); + this.databaseContext.add(new BacktraceData.Builder(this.context, report2, null).build()); // WHEN int filesAfterAdd = countAllFiles(); @@ -128,8 +128,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(this.context, report, null).build()); + this.databaseContext.add(new BacktraceData.Builder(this.context, report2, null).build()); // WHEN boolean result = this.databaseFileContext.validFileConsistency(); @@ -148,8 +148,8 @@ public void forceInconsistencyMaxRecordCount() { 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(this.context, report, null).build()); + this.databaseContext.add(new BacktraceData.Builder(this.context, report2, null).build()); // WHEN boolean result = this.databaseFileContext.validFileConsistency(); @@ -166,8 +166,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(this.context, report, null).build()); + this.databaseContext.add(new BacktraceData.Builder(this.context, report2, null).build()); // WHEN boolean result = this.databaseFileContext.validFileConsistency(); @@ -182,8 +182,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(this.context, report, null).build()); + this.databaseContext.add(new BacktraceData.Builder(this.context, report2, 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 722f7cde..d37414de 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseProguardTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseProguardTest.java @@ -48,9 +48,9 @@ public void addSingleRecordNoProguard() { database.add(report, null); // THEN - assertEquals(report, database.get().iterator().next().getBacktraceData(context).report); - assertNull(database.get().iterator().next().getBacktraceData(context).symbolication); - assertEquals(testMessage, database.get().iterator().next().getBacktraceData(context).report.message); + assertEquals(report, database.get().iterator().next().getBacktraceData().report); + assertNull(database.get().iterator().next().getBacktraceData().symbolication); + assertEquals(testMessage, database.get().iterator().next().getBacktraceData().report.message); assertEquals(1, database.count()); } @@ -66,9 +66,9 @@ public void addSingleRecordProguard() { database.add(report, null, true); // THEN - assertEquals(report, database.get().iterator().next().getBacktraceData(context).report); - assertEquals("proguard", database.get().iterator().next().getBacktraceData(context).symbolication); - assertEquals(testMessage, database.get().iterator().next().getBacktraceData(context).report.message); + assertEquals(report, database.get().iterator().next().getBacktraceData().report); + assertEquals("proguard", database.get().iterator().next().getBacktraceData().symbolication); + assertEquals(testMessage, database.get().iterator().next().getBacktraceData().report.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 55e27f43..e5c06684 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseRecordTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseRecordTest.java @@ -21,6 +21,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; @@ -50,16 +51,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(this.context, report, null).build(); + final BacktraceDatabaseRecord record = new BacktraceDatabaseRecord(data, this.dbPath); // 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); @@ -72,7 +73,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); }}; @@ -84,30 +85,30 @@ 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(this.context, report, null).build(); + final BacktraceDatabaseRecord record = new BacktraceDatabaseRecord(data, this.dbPath); // 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.getExistingFiles(context, loadedData); // THEN assertTrue(saveResult); assertTrue(validResult); assertEquals(data.report.message, loadedData.report.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); + BacktraceData data = new BacktraceData.Builder(this.context, report, null).build(); BacktraceDatabaseRecord record = new BacktraceDatabaseRecord(data, this.dbPath); // WHEN @@ -125,7 +126,7 @@ public void deleteFileDiagnosticPathToCorruptRecord() { public void deleteFileReportPathToCorruptRecord() { // GIVEN BacktraceReport report = new BacktraceReport(testMessage); - BacktraceData data = new BacktraceData(this.context, report, null); + BacktraceData data = new BacktraceData.Builder(this.context, report, null).build(); BacktraceDatabaseRecord record = new BacktraceDatabaseRecord(data, this.dbPath); // WHEN @@ -143,7 +144,7 @@ public void deleteFileReportPathToCorruptRecord() { public void createAndDeleteRecordFiles() { // GIVEN BacktraceReport report = new BacktraceReport(testMessage); - BacktraceData data = new BacktraceData(this.context, report, null); + BacktraceData data = new BacktraceData.Builder(this.context, report, null).build(); BacktraceDatabaseRecord record = new BacktraceDatabaseRecord(data, this.dbPath); // WHEN @@ -162,14 +163,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(this.context, report, null).build(); + final BacktraceDatabaseRecord record = new BacktraceDatabaseRecord(data, this.dbPath); 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.report.message, dataFromFile.report.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 27645fe7..e69cd474 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseTest.java @@ -65,29 +65,29 @@ 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).report); - assertEquals(testMessage, database.get().iterator().next().getBacktraceData(context).report.message); + assertEquals(report, database.get().iterator().next().getBacktraceData().report); + assertEquals(testMessage, database.get().iterator().next().getBacktraceData().report.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)); @@ -95,20 +95,20 @@ public void addWithAttributes() { @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).report); - assertEquals(report2.exception.getMessage(), recordFromDatabase.getBacktraceData(context).report.exception.getMessage()); + assertEquals(report2, recordFromDatabase.getBacktraceData().report); + assertEquals(report2.exception.getMessage(), recordFromDatabase.getBacktraceData().report.exception.getMessage()); } @@ -195,7 +195,7 @@ public void recordLimit() { // THEN assertEquals(1, database.count()); - assertEquals(report2.message, database.get().iterator().next().getBacktraceData(context).report.message); + assertEquals(report2.message, database.get().iterator().next().getBacktraceData().report.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 c686c966..167d1206 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/models/BacktraceDataTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/models/BacktraceDataTest.java @@ -30,7 +30,7 @@ public void createBacktraceDataTest() { BacktraceReport report = new BacktraceReport(new IllegalAccessException("test-message")); // WHEN - BacktraceData backtraceData = new BacktraceData(context, report, new HashMap<>()); + BacktraceData backtraceData = new BacktraceData.Builder(context, report, new HashMap<>()).build(); // THEN assertEquals(backtraceData.classifiers, new String[]{"java.lang.IllegalAccessException"}); diff --git a/backtrace-library/src/main/java/backtraceio/library/BacktraceDatabase.java b/backtrace-library/src/main/java/backtraceio/library/BacktraceDatabase.java index 04f9837e..701ee594 100644 --- a/backtrace-library/src/main/java/backtraceio/library/BacktraceDatabase.java +++ b/backtrace-library/src/main/java/backtraceio/library/BacktraceDatabase.java @@ -299,7 +299,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.report == null) { BacktraceLogger.d(LOG_TAG, "Timer - backtrace data or report is null - " + "deleting record"); @@ -349,7 +349,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 89ee462c..46dd6d35 100644 --- a/backtrace-library/src/main/java/backtraceio/library/base/BacktraceBase.java +++ b/backtrace-library/src/main/java/backtraceio/library/base/BacktraceBase.java @@ -236,7 +236,7 @@ public BacktraceBase(Context context, BacktraceCredentials credentials, Database this.attributes = attributes != null ? attributes : new HashMap(); this.attachments = attachments != null ? attachments : new ArrayList(); 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, attributes, backtraceApi, credentials); } @@ -551,8 +551,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(context, report, symbolication, this.attributes).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 367100ec..d2b4de33 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/BacktraceSerializeHelper.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/BacktraceSerializeHelper.java @@ -18,8 +18,8 @@ public class BacktraceSerializeHelper { * @return serialized object in JSON string format */ public static String toJson(Object object) { - return new BacktraceGsonBuilder().buildGson().toJson(object); -// return BacktraceOrgJsonSerializer.toJson(object); +// return new BacktraceGsonBuilder().buildGson().toJson(object); + return BacktraceOrgJsonSerializer.toJson(object); } public static T fromJson(String json, Class type) { diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataDeserializer.java index 1aa81d3a..2c5e703c 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataDeserializer.java @@ -18,216 +18,217 @@ import backtraceio.library.models.json.ThreadInformation; public class BacktraceDataDeserializer { - - public static BacktraceData deserialize(Context context, JSONObject obj) throws JSONException { - BacktraceReport report = BacktraceDataDeserializer.deserializeReport(context, obj.optJSONObject("report")); - BacktraceData backtraceData = new BacktraceData(context, report, new HashMap<>()); // todo: fix - - backtraceData.symbolication = obj.optString("symbolication"); - backtraceData.uuid = obj.optString("uuid"); - backtraceData.timestamp = obj.optLong("timestamp"); - backtraceData.langVersion = obj.optString("langVersion"); - backtraceData.agentVersion = obj.optString("agentVersion"); - backtraceData.mainThread = obj.optString("mainThread"); - - JSONArray classifiersArray = obj.optJSONArray("classifiers"); - if (classifiersArray != null) { - backtraceData.classifiers = new String[classifiersArray.length()]; - for (int i = 0; i < classifiersArray.length(); i++) { - backtraceData.classifiers[i] = classifiersArray.optString(i); - } - } - - JSONObject attributesObj = obj.optJSONObject("attributes"); - if (attributesObj != null) { - backtraceData.attributes = new HashMap<>(); - Iterator attributesKeys = attributesObj.keys(); - while (attributesKeys.hasNext()) { - String key = attributesKeys.next(); - backtraceData.attributes.put(key, attributesObj.optString(key)); - } - } - - JSONObject annotationsObj = obj.optJSONObject("annotations"); - if (annotationsObj != null) { - backtraceData.annotations = new HashMap<>(); - Iterator annotationsKeys = annotationsObj.keys(); - while (annotationsKeys.hasNext()) { - String key = annotationsKeys.next(); - backtraceData.annotations.put(key, annotationsObj.opt(key)); - } - } - - JSONObject sourceCodeObj = obj.optJSONObject("sourceCode"); - if (sourceCodeObj != null) { - backtraceData.sourceCode = new HashMap<>(); - Iterator sourceCodeKeys = sourceCodeObj.keys(); - while (sourceCodeKeys.hasNext()) { - String key = sourceCodeKeys.next(); - JSONObject sourceCodeItem = sourceCodeObj.optJSONObject(key); - if (sourceCodeItem != null) { -// SourceCode sourceCode = new SourceCode(); -// sourceCode.startLine = sourceCodeItem.optInt("startLine"); -// sourceCode.sourceCodeFileName = sourceCodeItem.optString("path"); -// backtraceData.sourceCode.put(key, sourceCode); - } - } - } - -// JSONObject threadInformationMapObj = obj.optJSONObject("threads"); -// if (threadInformationMapObj != null) { -// backtraceData.threadInformationMap = new HashMap<>(); -// Iterator threadKeys = threadInformationMapObj.keys(); -// while (threadKeys.hasNext()) { -// String threadKey = threadKeys.next(); -// JSONObject threadInfoObj = threadInformationMapObj.optJSONObject(threadKey); -// if (threadInfoObj != null) { -// ThreadInformation threadInformation = new ThreadInformation(); -// threadInformation.name = threadInfoObj.optString("name"); -// JSONArray stackArray = threadInfoObj.optJSONArray("stack"); -// if (stackArray != null) { -// threadInformation.stack = new ArrayList<>(); -// for (int i = 0; i < stackArray.length(); i++) { -// JSONObject stackItem = stackArray.optJSONObject(i); -// if (stackItem != null) { -// BacktraceStackFrame stackFrame = new BacktraceStackFrame(); -// stackFrame.functionName = stackItem.optString("funcName"); -// stackFrame.line = stackItem.optInt("line"); -// stackFrame.sourceCode = stackItem.optString("sourceCode"); -// threadInformation.stack.add(stackFrame); -// } -// } -// } -// backtraceData.threadInformationMap.put(threadKey, threadInformation); +// +// public static BacktraceData deserialize(Context context, JSONObject obj) throws JSONException { +// BacktraceReport report = BacktraceDataDeserializer.deserializeReport(context, obj.optJSONObject("report")); +// BacktraceData backtraceData = new BacktraceData.Builder(context, report, new HashMap<>()).build(); // todo: fix ??? +// +// backtraceData.symbolication = obj.optString("symbolication"); +// backtraceData.uuid = obj.optString("uuid"); +// backtraceData.timestamp = obj.optLong("timestamp"); +// backtraceData.langVersion = obj.optString("langVersion"); +// backtraceData.agentVersion = obj.optString("agentVersion"); +// backtraceData.mainThread = obj.optString("mainThread"); +// +// JSONArray classifiersArray = obj.optJSONArray("classifiers"); +// if (classifiersArray != null) { +// backtraceData.classifiers = new String[classifiersArray.length()]; +// for (int i = 0; i < classifiersArray.length(); i++) { +// backtraceData.classifiers[i] = classifiersArray.optString(i); +// } +// } +// +// JSONObject attributesObj = obj.optJSONObject("attributes"); +// if (attributesObj != null) { +// backtraceData.attributes = new HashMap<>(); +// Iterator attributesKeys = attributesObj.keys(); +// while (attributesKeys.hasNext()) { +// String key = attributesKeys.next(); +// backtraceData.attributes.put(key, attributesObj.optString(key)); +// } +// } +// +// JSONObject annotationsObj = obj.optJSONObject("annotations"); +// if (annotationsObj != null) { +// backtraceData.annotations = new HashMap<>(); +// Iterator annotationsKeys = annotationsObj.keys(); +// while (annotationsKeys.hasNext()) { +// String key = annotationsKeys.next(); +// backtraceData.annotations.put(key, annotationsObj.opt(key)); +// } +// } +// +// JSONObject sourceCodeObj = obj.optJSONObject("sourceCode"); +// if (sourceCodeObj != null) { +// backtraceData.sourceCode = new HashMap<>(); +// Iterator sourceCodeKeys = sourceCodeObj.keys(); +// while (sourceCodeKeys.hasNext()) { +// String key = sourceCodeKeys.next(); +// JSONObject sourceCodeItem = sourceCodeObj.optJSONObject(key); +// if (sourceCodeItem != null) { +//// SourceCode sourceCode = new SourceCode(); +//// sourceCode.startLine = sourceCodeItem.optInt("startLine"); +//// sourceCode.sourceCodeFileName = sourceCodeItem.optString("path"); +//// backtraceData.sourceCode.put(key, sourceCode); // } // } // } - - return backtraceData; - } - public static BacktraceReport deserializeReport(Context context, JSONObject obj) throws JSONException { - if (obj == null ){ - return null; - } - - BacktraceReport report = new BacktraceReport(""); // todo: fix - report.uuid = UUID.fromString(obj.optString("uuid")); - report.timestamp = obj.optLong("timestamp"); - report.exceptionTypeReport = obj.optBoolean("exceptionTypeReport"); - report.classifier = obj.optString("classifier"); - - JSONArray attachmentPathsArray = obj.optJSONArray("attachmentPaths"); - if (attachmentPathsArray != null) { - report.attachmentPaths = new ArrayList<>(); - for (int i = 0; i < attachmentPathsArray.length(); i++) { - report.attachmentPaths.add(attachmentPathsArray.optString(i)); - } - } - - report.message = obj.optString("message"); - - // Deserialize exception field if needed - - JSONArray diagnosticStackArray = obj.optJSONArray("diagnosticStack"); - if (diagnosticStackArray != null) { - report.diagnosticStack = new ArrayList<>(); - for (int i = 0; i < diagnosticStackArray.length(); i++) { - JSONObject stackItem = diagnosticStackArray.optJSONObject(i); - if (stackItem != null) { - BacktraceStackFrame stackFrame = new BacktraceStackFrame(); - stackFrame.functionName = stackItem.optString("funcName"); - stackFrame.line = stackItem.optInt("line"); - stackFrame.sourceCode = stackItem.optString("sourceCode"); - report.diagnosticStack.add(stackFrame); - } - } - } - - JSONObject exceptionObj = obj.optJSONObject("exception"); - if (exceptionObj != null) { - String exceptionClassName = exceptionObj.optString("className"); - String exceptionMessage = exceptionObj.optString("message"); - Exception exception = new Exception(exceptionMessage); - exception.setStackTrace(parseStackFrames(exceptionObj.optJSONArray("stackTrace"))); - report.exception = exception; - } - - return report; - } - - public static BacktraceData deserializeReportXYZ(Context context, JSONObject obj) throws JSONException { - BacktraceData backtraceData = new BacktraceData(context, null, null); // todo fix - - // ... (Deserialization logic for other fields) ... - - // Deserialize BacktraceReport - JSONObject reportObj = obj.optJSONObject("report"); - if (reportObj != null) { - BacktraceReport report = new BacktraceReport(""); - report.uuid = UUID.fromString(reportObj.optString("uuid")); - report.timestamp = reportObj.optLong("timestamp"); - report.exceptionTypeReport = reportObj.optBoolean("exceptionTypeReport"); - report.classifier = reportObj.optString("classifier"); - - JSONArray attachmentPathsArray = reportObj.optJSONArray("attachmentPaths"); - if (attachmentPathsArray != null) { - report.attachmentPaths = new ArrayList<>(); - for (int i = 0; i < attachmentPathsArray.length(); i++) { - report.attachmentPaths.add(attachmentPathsArray.optString(i)); - } - } - - report.message = reportObj.optString("message"); - - // Deserialize exception field - JSONObject exceptionObj = reportObj.optJSONObject("exception"); - if (exceptionObj != null) { - String exceptionClassName = exceptionObj.optString("className"); - String exceptionMessage = exceptionObj.optString("message"); - Exception exception = new Exception(exceptionMessage); - exception.setStackTrace(parseStackFrames(exceptionObj.optJSONArray("stackTrace"))); - report.exception = exception; - } - - JSONArray diagnosticStackArray = reportObj.optJSONArray("diagnosticStack"); - if (diagnosticStackArray != null) { - report.diagnosticStack = new ArrayList<>(); - for (int i = 0; i < diagnosticStackArray.length(); i++) { - JSONObject stackItem = diagnosticStackArray.optJSONObject(i); - if (stackItem != null) { - BacktraceStackFrame stackFrame = new BacktraceStackFrame(); - stackFrame.functionName = stackItem.optString("funcName"); - stackFrame.line = stackItem.optInt("line"); - stackFrame.sourceCode = stackItem.optString("sourceCode"); - report.diagnosticStack.add(stackFrame); - } - } - } - - // ... (Other deserialization for BacktraceReport fields) ... - - backtraceData.report = report; - } - - return backtraceData; - } - - private static StackTraceElement[] parseStackFrames(JSONArray stackTraceArray) { - if (stackTraceArray == null) { - return new StackTraceElement[0]; - } - StackTraceElement[] stackTrace = new StackTraceElement[stackTraceArray.length()]; - for (int i = 0; i < stackTraceArray.length(); i++) { - JSONObject stackItem = stackTraceArray.optJSONObject(i); - if (stackItem != null) { - String className = stackItem.optString("className"); - String methodName = stackItem.optString("methodName"); - String fileName = stackItem.optString("fileName"); - int lineNumber = stackItem.optInt("lineNumber"); - stackTrace[i] = new StackTraceElement(className, methodName, fileName, lineNumber); - } - } - return stackTrace; - } +// +//// JSONObject threadInformationMapObj = obj.optJSONObject("threads"); +//// if (threadInformationMapObj != null) { +//// backtraceData.threadInformationMap = new HashMap<>(); +//// Iterator threadKeys = threadInformationMapObj.keys(); +//// while (threadKeys.hasNext()) { +//// String threadKey = threadKeys.next(); +//// JSONObject threadInfoObj = threadInformationMapObj.optJSONObject(threadKey); +//// if (threadInfoObj != null) { +//// ThreadInformation threadInformation = new ThreadInformation(); +//// threadInformation.name = threadInfoObj.optString("name"); +//// JSONArray stackArray = threadInfoObj.optJSONArray("stack"); +//// if (stackArray != null) { +//// threadInformation.stack = new ArrayList<>(); +//// for (int i = 0; i < stackArray.length(); i++) { +//// JSONObject stackItem = stackArray.optJSONObject(i); +//// if (stackItem != null) { +//// BacktraceStackFrame stackFrame = new BacktraceStackFrame(); +//// stackFrame.functionName = stackItem.optString("funcName"); +//// stackFrame.line = stackItem.optInt("line"); +//// stackFrame.sourceCode = stackItem.optString("sourceCode"); +//// threadInformation.stack.add(stackFrame); +//// } +//// } +//// } +//// backtraceData.threadInformationMap.put(threadKey, threadInformation); +//// } +//// } +//// } +// +// return backtraceData; +// } +// public static BacktraceReport deserializeReport(Context context, JSONObject obj) throws JSONException { +// if (obj == null ){ +// return null; +// } +// +// BacktraceReport report = new BacktraceReport(""); // todo: fix +// report.uuid = UUID.fromString(obj.optString("uuid")); +// report.timestamp = obj.optLong("timestamp"); +// report.exceptionTypeReport = obj.optBoolean("exceptionTypeReport"); +// report.classifier = obj.optString("classifier"); +// +// JSONArray attachmentPathsArray = obj.optJSONArray("attachmentPaths"); +// if (attachmentPathsArray != null) { +// report.attachmentPaths = new ArrayList<>(); +// for (int i = 0; i < attachmentPathsArray.length(); i++) { +// report.attachmentPaths.add(attachmentPathsArray.optString(i)); +// } +// } +// +// report.message = obj.optString("message"); +// +// // Deserialize exception field if needed +// +// JSONArray diagnosticStackArray = obj.optJSONArray("diagnosticStack"); +// if (diagnosticStackArray != null) { +// report.diagnosticStack = new ArrayList<>(); +// for (int i = 0; i < diagnosticStackArray.length(); i++) { +// JSONObject stackItem = diagnosticStackArray.optJSONObject(i); +// if (stackItem != null) { +// BacktraceStackFrame stackFrame = new BacktraceStackFrame(); +// stackFrame.functionName = stackItem.optString("funcName"); +// stackFrame.line = stackItem.optInt("line"); +// stackFrame.sourceCode = stackItem.optString("sourceCode"); +// report.diagnosticStack.add(stackFrame); +// } +// } +// } +// +// JSONObject exceptionObj = obj.optJSONObject("exception"); +// if (exceptionObj != null) { +// String exceptionClassName = exceptionObj.optString("className"); +// String exceptionMessage = exceptionObj.optString("message"); +// Exception exception = new Exception(exceptionMessage); +// exception.setStackTrace(parseStackFrames(exceptionObj.optJSONArray("stackTrace"))); +// report.exception = exception; +// } +// +// return report; +// } +// +// public static BacktraceData deserializeReportXYZ(Context context, JSONObject obj) throws JSONException { +// return null; // BL: Do we need below code? +//// BacktraceData backtraceData = new BacktraceData(context, null, null); // todo fix +// +// // ... (Deserialization logic for other fields) ... +// +// // Deserialize BacktraceReport +//// JSONObject reportObj = obj.optJSONObject("report"); +//// if (reportObj != null) { +//// BacktraceReport report = new BacktraceReport(""); +//// report.uuid = UUID.fromString(reportObj.optString("uuid")); +//// report.timestamp = reportObj.optLong("timestamp"); +//// report.exceptionTypeReport = reportObj.optBoolean("exceptionTypeReport"); +//// report.classifier = reportObj.optString("classifier"); +//// +//// JSONArray attachmentPathsArray = reportObj.optJSONArray("attachmentPaths"); +//// if (attachmentPathsArray != null) { +//// report.attachmentPaths = new ArrayList<>(); +//// for (int i = 0; i < attachmentPathsArray.length(); i++) { +//// report.attachmentPaths.add(attachmentPathsArray.optString(i)); +//// } +//// } +//// +//// report.message = reportObj.optString("message"); +//// +//// // Deserialize exception field +//// JSONObject exceptionObj = reportObj.optJSONObject("exception"); +//// if (exceptionObj != null) { +//// String exceptionClassName = exceptionObj.optString("className"); +//// String exceptionMessage = exceptionObj.optString("message"); +//// Exception exception = new Exception(exceptionMessage); +//// exception.setStackTrace(parseStackFrames(exceptionObj.optJSONArray("stackTrace"))); +//// report.exception = exception; +//// } +//// +//// JSONArray diagnosticStackArray = reportObj.optJSONArray("diagnosticStack"); +//// if (diagnosticStackArray != null) { +//// report.diagnosticStack = new ArrayList<>(); +//// for (int i = 0; i < diagnosticStackArray.length(); i++) { +//// JSONObject stackItem = diagnosticStackArray.optJSONObject(i); +//// if (stackItem != null) { +//// BacktraceStackFrame stackFrame = new BacktraceStackFrame(); +//// stackFrame.functionName = stackItem.optString("funcName"); +//// stackFrame.line = stackItem.optInt("line"); +//// stackFrame.sourceCode = stackItem.optString("sourceCode"); +//// report.diagnosticStack.add(stackFrame); +//// } +//// } +//// } +// +// // ... (Other deserialization for BacktraceReport fields) ... +// +//// backtraceData.report = report; +// } +// +//// return backtraceData; +// } +// +// private static StackTraceElement[] parseStackFrames(JSONArray stackTraceArray) { +// if (stackTraceArray == null) { +// return new StackTraceElement[0]; +// } +// StackTraceElement[] stackTrace = new StackTraceElement[stackTraceArray.length()]; +// for (int i = 0; i < stackTraceArray.length(); i++) { +// JSONObject stackItem = stackTraceArray.optJSONObject(i); +// if (stackItem != null) { +// String className = stackItem.optString("className"); +// String methodName = stackItem.optString("methodName"); +// String fileName = stackItem.optString("fileName"); +// int lineNumber = stackItem.optInt("lineNumber"); +// stackTrace[i] = new StackTraceElement(className, methodName, fileName, lineNumber); +// } +// } +// return stackTrace; +// } } \ No newline at end of file diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDataDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDataDeserializer.java index 448b035c..a632f469 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDataDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDataDeserializer.java @@ -11,6 +11,20 @@ public class BacktraceDataDeserializer implements Deserializable{ public BacktraceData deserialize(JSONObject obj) throws JSONException { - return new BacktraceData(); // TODO + return new BacktraceData( + obj.optString("uuid"), + obj.optString("symbolication"), + obj.optLong("timestamp"), + obj.optString("lang-version"), // TODO: fix or improve casing should get from annotation + obj.optString("agent-version"), // TODO: fix or improve casing should get from annotation + // TODO: fix all below + null, + obj.optString("main-thread"), + null, + null, + null, + null, + null + ); // TODO } } diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDatabaseRecordDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDatabaseRecordDeserializer.java index 1a313c7c..7ce68f09 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDatabaseRecordDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDatabaseRecordDeserializer.java @@ -9,6 +9,13 @@ public class BacktraceDatabaseRecordDeserializer implements Deserializable{ public BacktraceDatabaseRecord deserialize(JSONObject obj) throws JSONException { - return new BacktraceDatabaseRecord(); // TODO + return new BacktraceDatabaseRecord( + obj.optString("Id"), + obj.optString("path"), + obj.optString("RecordName"), + obj.optString("DataPath"), + obj.optString("ReportPath"), + obj.optLong("size")// TODO: use all from fields or annotation + ); } } 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 97039c35..69d0b43f 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java @@ -2,13 +2,11 @@ import android.content.Context; -import backtraceio.library.common.serializers.SerializedName; - import java.util.List; import java.util.Map; import backtraceio.library.BacktraceClient; -import backtraceio.library.common.FileHelper; +import backtraceio.library.common.serializers.SerializedName; import backtraceio.library.logger.BacktraceLogger; import backtraceio.library.models.json.Annotations; import backtraceio.library.models.json.BacktraceAttributes; @@ -98,12 +96,7 @@ public class BacktraceData { /** * Current BacktraceReport */ - public transient BacktraceReport report; - - /** - * Current application context - */ - public transient Context context; + public transient BacktraceReport report; // Think if we need it /** * Application thread details @@ -115,25 +108,24 @@ public class BacktraceData { public BacktraceData() { } - /** - * 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; + 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.symbolication = symbolication; + this.uuid = uuid; + this.timestamp = timestamp; + this.langVersion = langVersion; + this.agentVersion = agentVersion; + this.attributes = attributes; + this.mainThread = mainThread; this.report = report; - - setDefaultReportInformation(); - setDefaultThreadsInformation(); - setAttributes(clientAttributes); + this.classifiers = classifiers; + this.annotations = annotations; + this.sourceCode = sourceCode; + this.threadInformationMap = threadInformationMap; } /** @@ -141,84 +133,175 @@ public BacktraceData(Context context, BacktraceReport report, Map getAttachments() { - return FileHelper.filterOutFiles(this.context, report.attachmentPaths); + public List getAttachmentPaths() { + return report.attachmentPaths; } public Map getThreadInformationMap() { return threadInformationMap; } - /*** - * Set annotations object - * @param complexAttributes - */ - private void setAnnotations(Map complexAttributes) { - BacktraceLogger.d(LOG_TAG, "Setting annotations"); - Object exceptionMessage = null; +// /*** +// * Set annotations object +// * @param complexAttributes +// */ +// private void 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); +// } + +// /** +// * Set attributes and add complex attributes to annotations +// * +// * @param context // TODO: +// * @param clientAttributes +// */ + + +// /** +// * Set report information such as report identifier (UUID), timestamp, classifier +// */ +// private void setDefaultReportInformation() { +// this.setReportInformation( +// report.uuid.toString(), +// report.timestamp, +// report.exceptionTypeReport ? new String[]{report.classifier} : null, +// System.getProperty("java.version"), //TODO: Fix problem with read Java version, +// BacktraceClient.version +// ); +// } + +// public void setReportInformation(String uuid, long timestamp, String [] classifiers, String langVersion, String agentVersion) { +// BacktraceLogger.d(LOG_TAG, "Setting report information"); +// this.uuid = uuid; +// this.timestamp = timestamp; +// this.classifiers = classifiers; +// this.langVersion = langVersion; +// this.agentVersion = agentVersion; +// } + +// /** +// * Set information about all threads +// */ +// private void setDefaultThreadsInformation() { +// BacktraceLogger.d(LOG_TAG, "Setting threads information"); +// +// ThreadData threadData = new ThreadData(report.diagnosticStack); +// SourceCodeData sourceCodeData = new SourceCodeData(report.diagnosticStack); +// +// this.setThreadsInformation( +// threadData.getMainThread(), +// threadData.threadInformation, +// sourceCodeData.data.isEmpty() ? null : sourceCodeData.data +// ); +// } +// +// public void setThreadsInformation(String mainThreadName, Map threadInformationMap, Map sourceCodeData) { +// this.mainThread = mainThreadName; +// this.threadInformationMap = threadInformationMap; +// this.sourceCode = sourceCodeData; +// } + + //Builder Class + public static class Builder { + final BacktraceReport report; + + final String symbolication; + + String uuid; + + long timestamp; + + String[] classifiers; + + String langVersion; + + String agentVersion; + + Map annotations; + Map sourceCode; + Map threadInformationMap; + Map attributes; + String mainThread; + + public Builder(Context context, BacktraceReport report, Map + clientAttributes) { + this(context, report, "", clientAttributes); + } + public Builder(Context context, BacktraceReport report, String symbolication, Map + clientAttributes) { + this.report = report; + this.symbolication = symbolication; + + this.setDefaultReportInformation(this.report); + this.setDefaultThreadsInformation(); + this.setAttributes(context, clientAttributes); + } - if (this.attributes != null && - this.attributes.containsKey("error.message")) { - exceptionMessage = this.attributes.get("error.message"); + public BacktraceData build() { + BacktraceData backtraceData = 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 + ); + + return backtraceData; } - this.annotations = Annotations.getAnnotations(exceptionMessage, complexAttributes); - } - /** - * 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; + private void 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; + } - setAnnotations(backtraceAttributes.getComplexAttributes()); - } + private void setDefaultThreadsInformation() { + BacktraceLogger.d(LOG_TAG, "Setting threads information"); - /** - * Set report information such as report identifier (UUID), timestamp, classifier - */ - private void setDefaultReportInformation() { - this.setReportInformation( - report.uuid.toString(), - report.timestamp, - report.exceptionTypeReport ? new String[]{report.classifier} : null, - System.getProperty("java.version"), //TODO: Fix problem with read Java version, - BacktraceClient.version - ); - } + ThreadData threadData = new ThreadData(report.diagnosticStack); + SourceCodeData sourceCodeData = new SourceCodeData(report.diagnosticStack); - public void setReportInformation(String uuid, long timestamp, String [] classifiers, String langVersion, String agentVersion) { - BacktraceLogger.d(LOG_TAG, "Setting report information"); - this.uuid = uuid; - this.timestamp = timestamp; - this.classifiers = classifiers; - this.langVersion = langVersion; - this.agentVersion = agentVersion; - } + this.mainThread = threadData.getMainThread(); + this.threadInformationMap = threadData.threadInformation; + this.sourceCode = sourceCodeData.data.isEmpty() ? null : sourceCodeData.data; + } - /** - * Set information about all threads - */ - private void setDefaultThreadsInformation() { - BacktraceLogger.d(LOG_TAG, "Setting threads information"); + public void setAttributes(Context context, Map clientAttributes) { + BacktraceLogger.d(LOG_TAG, "Setting attributes"); + BacktraceAttributes backtraceAttributes = new BacktraceAttributes( + context, + this.report, + clientAttributes); + this.attributes = backtraceAttributes.attributes; - ThreadData threadData = new ThreadData(report.diagnosticStack); - SourceCodeData sourceCodeData = new SourceCodeData(report.diagnosticStack); + setAnnotations(backtraceAttributes.getComplexAttributes()); + } - this.setThreadsInformation( - threadData.getMainThread(), - threadData.threadInformation, - sourceCodeData.data.isEmpty() ? null : sourceCodeData.data - ); - } + private void setAnnotations(Map complexAttributes) { + BacktraceLogger.d(LOG_TAG, "Setting annotations"); + Object exceptionMessage = null; - public void setThreadsInformation(String mainThreadName, Map threadInformationMap, Map sourceCodeData) { - this.mainThread = mainThreadName; - this.threadInformationMap = threadInformationMap; - this.sourceCode = sourceCodeData; + if (this.attributes != null && + this.attributes.containsKey("error.message")) { + exceptionMessage = this.attributes.get("error.message"); + } + this.annotations = Annotations.getAnnotations(exceptionMessage, complexAttributes); + } } } \ 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..49a0423e --- /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 getExistingFiles (Context context, BacktraceData backtraceData) { // TODO: fix name + return FileHelper.filterOutFiles(context, backtraceData.getAttachmentPaths()); + } +} 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 5327f0a9..5b1c34a2 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 String path; /** * Id */ @SerializedName("Id") - public UUID id = UUID.randomUUID(); + public UUID id;// = UUID.randomUUID(); /** * Check if current record is in use @@ -39,7 +39,8 @@ public class BacktraceDatabaseRecord { /** * record writer */ - transient DatabaseRecordWriter RecordWriter; + private transient DatabaseRecordWriter recordWriter; + /** * Path to json stored all information about current record @@ -70,17 +71,34 @@ public class BacktraceDatabaseRecord { */ private transient BacktraceData record; - public BacktraceDatabaseRecord() { - this._path = ""; - this.recordPath = String.format("%s-record.json", this.id); - this.diagnosticDataPath = String.format("%s-attachment", this.id); - } +// public 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.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 +133,13 @@ public long getSize() { return size; } - public void setSize(long size) { - this.size = size; - } - /** * Get valid BacktraceData from current record * * @param context * @return valid BacktraceData object */ - public BacktraceData getBacktraceData(Context context) { + public BacktraceData getBacktraceData() { // TODO: check if we still need it if (this.record != null) { return this.record; } @@ -151,7 +165,7 @@ public BacktraceData getBacktraceData(Context context) { diagnosticData.report = BacktraceSerializeHelper.fromJson(jsonReport, BacktraceReport.class); // Serialized data loses the context, give context again when deserializing - diagnosticData.context = context; +// diagnosticData.context = context; // TODO: check if we still need it return diagnosticData; } catch (Exception ex) { BacktraceLogger.e(LOG_TAG, "Exception occurs on deserialization of diagnostic data", ex); @@ -170,13 +184,13 @@ public boolean save() { this.diagnosticDataPath = save(record, String.format("%s-attachment", id)); this.reportPath = save(record.report, 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 +215,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/BacktraceReport.java b/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceReport.java index 084592e8..ade58bf9 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceReport.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceReport.java @@ -259,8 +259,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(context, this, symbolication, clientAttributes).build(); } } \ 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/BacktraceHandlerThread.java b/backtrace-library/src/main/java/backtraceio/library/services/BacktraceHandlerThread.java index eb4afaa4..01c4c5bb 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,7 +94,7 @@ 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(); + List attachments = BacktraceDataAttachmentsFileHelper.getExistingFiles(this.context, mInput.data); result = BacktraceReportSender.sendReport(url, json, attachments, mInput.data.report, mInput.serverErrorEventListener); } From fb1ff11ff8c836abde2a7947d1bcf4ebf32af320 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Thu, 8 Feb 2024 23:38:57 +0100 Subject: [PATCH 026/100] Add field name cache and annotation reader --- .../common/BacktraceDataDeserializerTest.java | 4 ++- .../serializers/BacktraceDeserializer.java | 5 +-- .../BacktraceDataDeserializer.java | 1 + .../BacktraceDatabaseRecordDeserializer.java | 26 ++++++++++---- .../BacktraceResultDeserializer.java | 10 ++++-- .../deserializers/ExceptionDeserializer.java | 8 ++--- .../deserializers/FieldNameCache.java | 36 +++++++++++++++++++ .../deserializers/FieldNameLoader.java | 13 +++++++ .../library/models/BacktraceData.java | 1 + .../library/models/BacktraceResult.java | 1 + .../database/BacktraceDatabaseRecord.java | 2 +- 11 files changed, 90 insertions(+), 17 deletions(-) create mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/FieldNameCache.java create mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/FieldNameLoader.java diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java index b150f04b..da18930c 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java @@ -27,6 +27,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.UUID; import backtraceio.library.R; import backtraceio.library.common.serializers.BacktraceDataDeserializer; @@ -61,7 +62,7 @@ public void deserializeCoronerJsonResponse() throws JSONException { @Test public void deserializeDatabaseRecord() throws JSONException { // GIVEN - String json = "{\"DataPath\":\"\\/data\\/user\\/0\\/backtraceio.backtraceio\\/files\\/8fbde28b-aa64-4e2f-83d8-493a98446fc8-attachment.json\",\"Id\":\"8fbde28b-aa64-4e2f-83d8-493a98446fc8\",\"RecordName\":\"\\/data\\/user\\/0\\/backtraceio.backtraceio\\/files\\/8fbde28b-aa64-4e2f-83d8-493a98446fc8-record.json\",\"ReportPath\":\"\\/data\\/user\\/0\\/backtraceio.backtraceio\\/files\\/8fbde28b-aa64-4e2f-83d8-493a98446fc8-report.json\",\"Size\":16996,\"size\":16996,\"record-path\":\"\\/data\\/user\\/0\\/backtraceio.backtraceio\\/files\\/8fbde28b-aa64-4e2f-83d8-493a98446fc8-record.json\",\"report-path\":\"\\/data\\/user\\/0\\/backtraceio.backtraceio\\/files\\/8fbde28b-aa64-4e2f-83d8-493a98446fc8-report.json\",\"diagnostic-data-path\":\"\\/data\\/user\\/0\\/backtraceio.backtraceio\\/files\\/8fbde28b-aa64-4e2f-83d8-493a98446fc8-attachment.json\"}"; + String json = "{\"DataPath\":\"\\/data\\/user\\/0\\/backtraceio.backtraceio\\/files\\/8fbde28b-aa64-4e2f-83d8-493a98446fc8-attachment.json\",\"Id\":\"8fbde28b-aa64-4e2f-83d8-493a98446fc8\",\"RecordName\":\"\\/data\\/user\\/0\\/backtraceio.backtraceio\\/files\\/8fbde28b-aa64-4e2f-83d8-493a98446fc8-record.json\",\"ReportPath\":\"\\/data\\/user\\/0\\/backtraceio.backtraceio\\/files\\/8fbde28b-aa64-4e2f-83d8-493a98446fc8-report.json\",\"Size\":16996,\"size\":16996,\"record-path\":\"\\/data\\/user\\/0\\/backtraceio.backtraceio\\/files\\/8fbde28b-aa64-4e2f-83d8-493a98446fc8-record.json\",\"report-path\":\"\\/data\\/user\\/0\\/backtraceio.backtraceio\\/files\\/8fbde28b-aa64-4e2f-83d8-493a98446fc8-report.json\",\"diagnostic-data-path\":\"\\/data\\/user\\/0\\/backtraceio.backtraceio\\/files\\/8fbde28b-aa64-4e2f-83d8-493a98446fc8-attachment.json\"}"; // todo: incorrect json duplicated entries // WHEN BacktraceDatabaseRecord result = BacktraceOrgJsonDeserializer.deserialize(json, BacktraceDatabaseRecord.class); @@ -70,6 +71,7 @@ public void deserializeDatabaseRecord() throws JSONException { assertNotNull(result); assertEquals(16996, result.getSize()); assertFalse(result.locked); + assertEquals(UUID.fromString("8fbde28b-aa64-4e2f-83d8-493a98446fc8"), result.id); assertEquals("/data/user/0/backtraceio.backtraceio/files/8fbde28b-aa64-4e2f-83d8-493a98446fc8-attachment.json", result.getDiagnosticDataPath()); assertEquals("/data/user/0/backtraceio.backtraceio/files/8fbde28b-aa64-4e2f-83d8-493a98446fc8-record.json", result.getRecordPath()); assertEquals("/data/user/0/backtraceio.backtraceio/files/8fbde28b-aa64-4e2f-83d8-493a98446fc8-report.json", result.getReportPath()); diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDeserializer.java index 397f71e7..8d512853 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDeserializer.java @@ -14,6 +14,7 @@ import backtraceio.library.common.serializers.deserializers.ReflectionDeserializer; import backtraceio.library.models.BacktraceData; import backtraceio.library.models.BacktraceResult; +import backtraceio.library.models.database.BacktraceDatabaseRecord; import backtraceio.library.models.json.BacktraceReport; public class BacktraceDeserializer { @@ -24,7 +25,7 @@ public class BacktraceDeserializer { put(BacktraceReport.class, new BacktraceReportDeserializer()); put(BacktraceData.class, new BacktraceDataDeserializer()); put(Exception.class, new ExceptionDeserializer()); - put(BacktraceDatabaseRecordDeserializer.class, new BacktraceDatabaseRecordDeserializer()); + put(BacktraceDatabaseRecord.class, new BacktraceDatabaseRecordDeserializer()); }}; @@ -38,7 +39,7 @@ public static T deserialize(JSONObject obj, Class clazz) throws JSONExcep if (deserializers.containsKey(clazz)) { return (T) deserializers.get(clazz).deserialize(obj); } - + // todo: maybe return unsupported return (T) DEFAULT_DESERIALIZER.deserialize(obj); } } diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDataDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDataDeserializer.java index a632f469..608744af 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDataDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDataDeserializer.java @@ -20,6 +20,7 @@ public BacktraceData deserialize(JSONObject obj) throws JSONException { // TODO: fix all below null, obj.optString("main-thread"), + // TODO: deserialize all of below null, null, null, diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDatabaseRecordDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDatabaseRecordDeserializer.java index 7ce68f09..cfb61f7f 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDatabaseRecordDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDatabaseRecordDeserializer.java @@ -3,19 +3,31 @@ import org.json.JSONException; import org.json.JSONObject; +import java.util.UUID; + import backtraceio.library.models.BacktraceData; import backtraceio.library.models.database.BacktraceDatabaseRecord; -public class BacktraceDatabaseRecordDeserializer implements Deserializable{ +public class BacktraceDatabaseRecordDeserializer implements Deserializable { + + private final FieldNameLoader fieldNameLoader = new FieldNameLoader(BacktraceDatabaseRecord.class); // TODO: maybe we can reuse it + static class Fields { + final static String id = "id"; + final static String path = "path"; + final static String recordPath = "recordPath"; + final static String diagnosticDataPath = "diagnosticDataPath"; + final static String reportPath = "reportPath"; + final static String size = "size"; + } public BacktraceDatabaseRecord deserialize(JSONObject obj) throws JSONException { return new BacktraceDatabaseRecord( - obj.optString("Id"), - obj.optString("path"), - obj.optString("RecordName"), - obj.optString("DataPath"), - obj.optString("ReportPath"), - obj.optLong("size")// TODO: use all from fields or annotation + obj.optString(fieldNameLoader.get(Fields.id)), + obj.optString(fieldNameLoader.get(Fields.path)), + obj.optString(fieldNameLoader.get(Fields.recordPath)), + obj.optString(fieldNameLoader.get(Fields.diagnosticDataPath)), + obj.optString(fieldNameLoader.get(Fields.reportPath)), + obj.optLong(fieldNameLoader.get(Fields.size)) ); } } diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceResultDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceResultDeserializer.java index 8d45cd0e..1693656a 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceResultDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceResultDeserializer.java @@ -8,9 +8,15 @@ public class BacktraceResultDeserializer implements Deserializable { + private final FieldNameLoader fieldNameLoader = new FieldNameLoader(BacktraceResult.class); // TODO: maybe we can reuse it + + static class Fields { + final static String rxId = "rxId"; + final static String status = "response"; + } public BacktraceResult deserialize(JSONObject obj) throws JSONException { - return new BacktraceResult(obj.optString("_rxid", null), - obj.optString("response", BacktraceResultStatus.Ok.toString()) + return new BacktraceResult(obj.optString(fieldNameLoader.get(Fields.rxId), null), // TODO: check fallback warning + obj.optString(fieldNameLoader.get(Fields.status), BacktraceResultStatus.Ok.toString()) ); } } diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ExceptionDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ExceptionDeserializer.java index 4ed24db0..bbf383ca 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ExceptionDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ExceptionDeserializer.java @@ -35,10 +35,10 @@ public StackTraceElement[] getStacktrace(JSONArray array) throws JSONException { for(int idx = 0; idx < array.length(); idx++) { JSONObject obj = (JSONObject) array.get(idx); result[idx] = new StackTraceElement( - obj.optString("declaring-class"), // make something to not hardcode in this way - obj.getString("method-name"), // make something to not hardcode in this way - obj.optString("file-name"), // make something to not hardcode in this way - obj.getInt("line-number") // make something to not hardcode in this way + obj.optString("declaring-class"), // TODO: make something to not hardcode in this way + obj.getString("method-name"), // TODO: make something to not hardcode in this way + obj.optString("file-name"), // TODO: make something to not hardcode in this way + obj.getInt("line-number") // TODO: make something to not hardcode in this way ); } diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/FieldNameCache.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/FieldNameCache.java new file mode 100644 index 00000000..778d28cf --- /dev/null +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/FieldNameCache.java @@ -0,0 +1,36 @@ +package backtraceio.library.common.serializers.deserializers; + +import androidx.annotation.NonNull; + +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; + +import backtraceio.library.common.serializers.SerializedName; + +public class FieldNameCache { + // Map to store annotation information + private static Map fieldNameMap = new HashMap<>(); + + // Method to get annotation for a given class and field + public static String getAnnotation(Class clazz, @NonNull String fieldName) { + // Generate a unique key for the class and field combination + String key = clazz.getName() + "_" + fieldName; + + // Check if the annotation is already cached + String cachedFieldName = fieldNameMap.get(key); + if (cachedFieldName == null) { + // If not cached, retrieve the annotation and store it in the map + try { + Field field = clazz.getDeclaredField(fieldName); + if (field.isAnnotationPresent(SerializedName.class)) { + cachedFieldName = field.getAnnotation(SerializedName.class).value(); + fieldNameMap.put(key, cachedFieldName); + } + } catch (NoSuchFieldException e) { + e.printStackTrace(); + } + } + return cachedFieldName; + } + } diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/FieldNameLoader.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/FieldNameLoader.java new file mode 100644 index 00000000..d6c93e63 --- /dev/null +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/FieldNameLoader.java @@ -0,0 +1,13 @@ +package backtraceio.library.common.serializers.deserializers; + +public class FieldNameLoader { + private final Class clazz; + + public FieldNameLoader(Class clazz) { + this.clazz = clazz; + } + + public String get(String fieldName) { + return FieldNameCache.getAnnotation(clazz, fieldName); + } +} 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 69d0b43f..7e9c1ed0 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java @@ -21,6 +21,7 @@ */ public class BacktraceData { + private static final transient String LOG_TAG = BacktraceData.class.getSimpleName(); /** * Name of programming language/environment this error comes from. 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 7b964064..2a22bd57 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceResult.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceResult.java @@ -24,6 +24,7 @@ public class BacktraceResult { /** * Result status eg. server error, ok */ + @SerializedName("response") // TODO: check if status or response public BacktraceResultStatus status = BacktraceResultStatus.Ok; /** 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 5b1c34a2..d5f6cc43 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 @@ -29,7 +29,7 @@ public class BacktraceDatabaseRecord { * Id */ @SerializedName("Id") - public UUID id;// = UUID.randomUUID(); + public UUID id; /** * Check if current record is in use From c9d5074a6ee7531b777fd41c3fd9b300985c0739 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Sat, 10 Feb 2024 09:51:31 +0100 Subject: [PATCH 027/100] Refactor Backtrace result api --- .../serializers/BacktraceDeserializer.java | 7 ++--- .../BacktraceApiResultDeserializer.java | 25 +++++++++++++++++ .../BacktraceResultDeserializer.java | 22 --------------- .../library/models/BacktraceApiResult.java | 28 +++++++++++++++++++ .../library/models/BacktraceResult.java | 9 +++--- .../services/BacktraceReportSender.java | 8 ++++-- .../BacktraceReportDeserializerTest.java | 5 ---- .../BacktraceResultDeserializerTest.java | 4 +-- 8 files changed, 67 insertions(+), 41 deletions(-) create mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceApiResultDeserializer.java delete mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceResultDeserializer.java create mode 100644 backtrace-library/src/main/java/backtraceio/library/models/BacktraceApiResult.java diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDeserializer.java index 8d512853..5e43d519 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDeserializer.java @@ -8,10 +8,11 @@ import backtraceio.library.common.serializers.deserializers.BacktraceDataDeserializer; import backtraceio.library.common.serializers.deserializers.BacktraceDatabaseRecordDeserializer; import backtraceio.library.common.serializers.deserializers.BacktraceReportDeserializer; -import backtraceio.library.common.serializers.deserializers.BacktraceResultDeserializer; +import backtraceio.library.common.serializers.deserializers.BacktraceApiResultDeserializer; import backtraceio.library.common.serializers.deserializers.Deserializable; import backtraceio.library.common.serializers.deserializers.ExceptionDeserializer; import backtraceio.library.common.serializers.deserializers.ReflectionDeserializer; +import backtraceio.library.models.BacktraceApiResult; import backtraceio.library.models.BacktraceData; import backtraceio.library.models.BacktraceResult; import backtraceio.library.models.database.BacktraceDatabaseRecord; @@ -21,19 +22,17 @@ public class BacktraceDeserializer { public final static Deserializable DEFAULT_DESERIALIZER = new ReflectionDeserializer(); public static HashMap deserializers = new HashMap() {{ - put(BacktraceResult.class, new BacktraceResultDeserializer()); + put(BacktraceApiResult.class, new BacktraceApiResultDeserializer()); put(BacktraceReport.class, new BacktraceReportDeserializer()); put(BacktraceData.class, new BacktraceDataDeserializer()); put(Exception.class, new ExceptionDeserializer()); put(BacktraceDatabaseRecord.class, new BacktraceDatabaseRecordDeserializer()); }}; - public static void registerDeserializer(Class clazz, Deserializable obj) { deserializers.put(clazz, obj); } - @SuppressWarnings("unchecked") public static T deserialize(JSONObject obj, Class clazz) throws JSONException { if (deserializers.containsKey(clazz)) { diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceApiResultDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceApiResultDeserializer.java new file mode 100644 index 00000000..9abc8f6d --- /dev/null +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceApiResultDeserializer.java @@ -0,0 +1,25 @@ +package backtraceio.library.common.serializers.deserializers; + +import org.json.JSONException; +import org.json.JSONObject; + +import backtraceio.library.models.BacktraceApiResult; +import backtraceio.library.models.BacktraceResult; +import backtraceio.library.models.types.BacktraceResultStatus; + +public class BacktraceApiResultDeserializer implements Deserializable { + + private final FieldNameLoader fieldNameLoader = new FieldNameLoader(BacktraceApiResult.class); // TODO: maybe we can reuse it + + static class Fields { + final static String rxId = "rxId"; + final static String response = "response"; + } + public BacktraceApiResult deserialize(JSONObject obj) throws JSONException { + return new BacktraceApiResult( + obj.optString(fieldNameLoader.get(Fields.rxId), null), // TODO: check fallback warning + obj.optString(fieldNameLoader.get(Fields.response), BacktraceResultStatus.Ok.toString() + ) + ); + } +} diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceResultDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceResultDeserializer.java deleted file mode 100644 index 1693656a..00000000 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceResultDeserializer.java +++ /dev/null @@ -1,22 +0,0 @@ -package backtraceio.library.common.serializers.deserializers; - -import org.json.JSONException; -import org.json.JSONObject; - -import backtraceio.library.models.BacktraceResult; -import backtraceio.library.models.types.BacktraceResultStatus; - -public class BacktraceResultDeserializer implements Deserializable { - - private final FieldNameLoader fieldNameLoader = new FieldNameLoader(BacktraceResult.class); // TODO: maybe we can reuse it - - static class Fields { - final static String rxId = "rxId"; - final static String status = "response"; - } - public BacktraceResult deserialize(JSONObject obj) throws JSONException { - return new BacktraceResult(obj.optString(fieldNameLoader.get(Fields.rxId), null), // TODO: check fallback warning - obj.optString(fieldNameLoader.get(Fields.status), BacktraceResultStatus.Ok.toString()) - ); - } -} 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..829c437a --- /dev/null +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceApiResult.java @@ -0,0 +1,28 @@ +package backtraceio.library.models; + +import backtraceio.library.common.serializers.SerializedName; +import backtraceio.library.models.json.BacktraceReport; +import backtraceio.library.models.types.BacktraceResultStatus; + +/** + * Send method result + */ +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; + } +} \ No newline at end of file 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 2a22bd57..52ff63b3 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceResult.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceResult.java @@ -12,8 +12,6 @@ public class BacktraceResult { /** * Object identifier */ - @SerializedName("_rxid") - @SuppressWarnings({"UnusedDeclaration"}) public String rxId; /** @@ -24,7 +22,6 @@ public class BacktraceResult { /** * Result status eg. server error, ok */ - @SerializedName("response") // TODO: check if status or response public BacktraceResultStatus status = BacktraceResultStatus.Ok; /** @@ -36,12 +33,14 @@ public class BacktraceResult { * Create new instance of BacktraceResult */ public BacktraceResult() { + } + public BacktraceResult(BacktraceApiResult apiResult) { + this(apiResult.rxId, apiResult.response); } public BacktraceResult(String rxId, String status) { - this.rxId = rxId; - this.status = BacktraceResultStatus.valueOf(status); + this(null, rxId, BacktraceResultStatus.valueOf(status)); } /** 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/BacktraceReportDeserializerTest.java b/backtrace-library/src/test/java/backtraceio/library/BacktraceReportDeserializerTest.java index 2bb686f7..372bc502 100644 --- a/backtrace-library/src/test/java/backtraceio/library/BacktraceReportDeserializerTest.java +++ b/backtrace-library/src/test/java/backtraceio/library/BacktraceReportDeserializerTest.java @@ -5,8 +5,6 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -import com.google.gson.GsonBuilder; - import org.json.JSONException; import org.json.JSONObject; import org.junit.Test; @@ -16,10 +14,7 @@ import backtraceio.library.common.BacktraceSerializeHelper; import backtraceio.library.common.serialization.BacktraceGsonBuilder; import backtraceio.library.common.serializers.deserializers.BacktraceReportDeserializer; -import backtraceio.library.common.serializers.deserializers.BacktraceResultDeserializer; -import backtraceio.library.models.BacktraceResult; import backtraceio.library.models.json.BacktraceReport; -import backtraceio.library.models.types.BacktraceResultStatus; // TODO: move to standard unit tests not instrumented public class BacktraceReportDeserializerTest { diff --git a/backtrace-library/src/test/java/backtraceio/library/BacktraceResultDeserializerTest.java b/backtrace-library/src/test/java/backtraceio/library/BacktraceResultDeserializerTest.java index ea7b9852..7c897da7 100644 --- a/backtrace-library/src/test/java/backtraceio/library/BacktraceResultDeserializerTest.java +++ b/backtrace-library/src/test/java/backtraceio/library/BacktraceResultDeserializerTest.java @@ -9,7 +9,7 @@ import org.json.JSONObject; import org.junit.Test; -import backtraceio.library.common.serializers.deserializers.BacktraceResultDeserializer; +import backtraceio.library.common.serializers.deserializers.BacktraceApiResultDeserializer; import backtraceio.library.models.BacktraceResult; import backtraceio.library.models.types.BacktraceResultStatus; @@ -21,7 +21,7 @@ public void deserializeCoronerApiJsonResponse() throws JSONException { String json = "{\"response\":\"Ok\",\"_rxid\":\"01000000-5360-240b-0000-000000000000\"}"; // WHEN - BacktraceResultDeserializer deserializer = new BacktraceResultDeserializer(); + BacktraceApiResultDeserializer deserializer = new BacktraceApiResultDeserializer(); BacktraceResult result = deserializer.deserialize(new JSONObject(json)); // THEN From 3f21f87bd3822a508a30d1bc7691965a03f551d7 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Sun, 11 Feb 2024 11:34:08 +0100 Subject: [PATCH 028/100] Implementation of next deserialization methods of Backtrace Data obj --- .../BacktraceDataDeserializer.java | 87 +++++++++++++++++-- ...> BacktraceApiResultDeserializerTest.java} | 12 +-- 2 files changed, 84 insertions(+), 15 deletions(-) rename backtrace-library/src/test/java/backtraceio/library/{BacktraceResultDeserializerTest.java => BacktraceApiResultDeserializerTest.java} (73%) diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDataDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDataDeserializer.java index 608744af..9db4507c 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDataDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDataDeserializer.java @@ -1,16 +1,22 @@ package backtraceio.library.common.serializers.deserializers; +import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + import backtraceio.library.models.BacktraceData; -import backtraceio.library.models.BacktraceResult; -import backtraceio.library.models.types.BacktraceResultStatus; +import backtraceio.library.models.json.BacktraceReport; +import backtraceio.library.models.json.SourceCode; +import backtraceio.library.models.json.ThreadInformation; +// TODO: check if methods should be private public class BacktraceDataDeserializer implements Deserializable{ public BacktraceData deserialize(JSONObject obj) throws JSONException { - return new BacktraceData( obj.optString("uuid"), obj.optString("symbolication"), @@ -18,14 +24,77 @@ public BacktraceData deserialize(JSONObject obj) throws JSONException { obj.optString("lang-version"), // TODO: fix or improve casing should get from annotation obj.optString("agent-version"), // TODO: fix or improve casing should get from annotation // TODO: fix all below - null, + getAttributes(obj.optJSONObject("attributes")), obj.optString("main-thread"), // TODO: deserialize all of below - null, - null, - null, - null, - null + getClassifiers(obj.optJSONArray("classifiers")), + getBacktraceReport(obj.optJSONObject("report")), + getAnnotations(obj.optJSONObject("annotations")), + getSourceCode(obj.optJSONObject("sourceCode")), + + getThreadInformation(obj.optJSONObject("threads")) ); // TODO } + + public BacktraceReport getBacktraceReport(JSONObject obj) { + // TODO: implement + return null; + } + + public Map getAnnotations(JSONObject obj) { + // TODO: implement + return null; + } + + public Map getSourceCode(JSONObject obj) { + // TODO: implement + return null; + } + + public Map getThreadInformation(JSONObject obj) { + // TODO: implement + return null; + } + + public String [] getClassifiers(JSONArray jsonArray) { + + if (jsonArray == null) { + return new String[0]; + } + + String[] result = new String[jsonArray.length()]; + + for(int i = 0; i < jsonArray.length(); i++){ + try { + Object object = jsonArray.get(i); + result[i] = object.toString(); + } + catch (JSONException exception) { + // todo: error handling + } + } + + return result; + } + + public Map getAttributes(JSONObject obj) { + Map result = new HashMap<>(); + + if (obj == null) { + return result; + } + + Iterator keys = obj.keys(); + + while(keys.hasNext()) { + String key = keys.next(); + try { + result.put(key, obj.get(key).toString()); + } catch (JSONException e) { + // TODO: error handling + } + } + + return result; + } } diff --git a/backtrace-library/src/test/java/backtraceio/library/BacktraceResultDeserializerTest.java b/backtrace-library/src/test/java/backtraceio/library/BacktraceApiResultDeserializerTest.java similarity index 73% rename from backtrace-library/src/test/java/backtraceio/library/BacktraceResultDeserializerTest.java rename to backtrace-library/src/test/java/backtraceio/library/BacktraceApiResultDeserializerTest.java index 7c897da7..a8cf0b0b 100644 --- a/backtrace-library/src/test/java/backtraceio/library/BacktraceResultDeserializerTest.java +++ b/backtrace-library/src/test/java/backtraceio/library/BacktraceApiResultDeserializerTest.java @@ -10,11 +10,11 @@ import org.junit.Test; import backtraceio.library.common.serializers.deserializers.BacktraceApiResultDeserializer; -import backtraceio.library.models.BacktraceResult; +import backtraceio.library.models.BacktraceApiResult; import backtraceio.library.models.types.BacktraceResultStatus; // TODO: move to standard unit tests not instrumented -public class BacktraceResultDeserializerTest { +public class BacktraceApiResultDeserializerTest { @Test public void deserializeCoronerApiJsonResponse() throws JSONException { // GIVEN @@ -22,13 +22,13 @@ public void deserializeCoronerApiJsonResponse() throws JSONException { // WHEN BacktraceApiResultDeserializer deserializer = new BacktraceApiResultDeserializer(); - BacktraceResult result = deserializer.deserialize(new JSONObject(json)); + BacktraceApiResult result = deserializer.deserialize(new JSONObject(json)); // THEN assertNotNull(result); - assertNull(result.getBacktraceReport()); - assertNull(result.message); - assertEquals(BacktraceResultStatus.Ok, result.status); +// assertNull(result.getBacktraceReport()); +// assertNull(result.message); + assertEquals(BacktraceResultStatus.Ok, result.response); assertEquals("01000000-5360-240b-0000-000000000000", result.rxId); } From 9817c7b3c9c09bcc185d3cbf7bc93df4db28003d Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Sat, 17 Feb 2024 17:31:55 +0100 Subject: [PATCH 029/100] Add next deserializers --- .../library/common/SerializerHelperTest.java | 2 +- .../BacktraceDataDeserializer.java | 50 +++++++++++++++---- .../BacktraceStackFrameDeserializer.java | 27 ++++++++++ .../deserializers/SourceCodeDeserializer.java | 22 ++++++++ .../ThreadInformationDeserializer.java | 48 ++++++++++++++++++ .../library/models/BacktraceStackFrame.java | 17 +++++-- .../library/models/json/SourceCode.java | 8 ++- .../library/models/json/ThreadData.java | 2 +- .../models/json/ThreadInformation.java | 2 +- 9 files changed, 158 insertions(+), 20 deletions(-) create mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceStackFrameDeserializer.java create mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/SourceCodeDeserializer.java create mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ThreadInformationDeserializer.java diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/common/SerializerHelperTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/common/SerializerHelperTest.java index d006b024..765c9578 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/common/SerializerHelperTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/common/SerializerHelperTest.java @@ -44,7 +44,7 @@ public void serializeList() throws JSONException { @Test public void serializeObject() throws JSONException { // GIVEN - final SourceCode sourceCode = new SourceCode(new BacktraceStackFrame(new StackTraceElement("sample-class", "sample-method", "sample-file", 123))); + final SourceCode sourceCode = new SourceCode(BacktraceStackFrame.fromStackTraceElement(new StackTraceElement("sample-class", "sample-method", "sample-file", 123))); // WHEN JSONObject jsonObject = (JSONObject) SerializerHelper.serialize(namingPolicy, sourceCode); diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDataDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDataDeserializer.java index 9db4507c..85e96bc6 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDataDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDataDeserializer.java @@ -4,6 +4,7 @@ import org.json.JSONException; import org.json.JSONObject; +import java.security.InvalidAlgorithmParameterException; import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -23,22 +24,21 @@ public BacktraceData deserialize(JSONObject obj) throws JSONException { obj.optLong("timestamp"), obj.optString("lang-version"), // TODO: fix or improve casing should get from annotation obj.optString("agent-version"), // TODO: fix or improve casing should get from annotation - // TODO: fix all below + // TODO: fix all below and maybe add fallback getAttributes(obj.optJSONObject("attributes")), obj.optString("main-thread"), - // TODO: deserialize all of below getClassifiers(obj.optJSONArray("classifiers")), getBacktraceReport(obj.optJSONObject("report")), getAnnotations(obj.optJSONObject("annotations")), getSourceCode(obj.optJSONObject("sourceCode")), - getThreadInformation(obj.optJSONObject("threads")) ); // TODO } - public BacktraceReport getBacktraceReport(JSONObject obj) { - // TODO: implement - return null; + public BacktraceReport getBacktraceReport(JSONObject obj) throws JSONException { + // TODO: reuse deserializer ? + BacktraceReportDeserializer deserializer = new BacktraceReportDeserializer(); + return deserializer.deserialize(obj); } public Map getAnnotations(JSONObject obj) { @@ -46,14 +46,44 @@ public Map getAnnotations(JSONObject obj) { return null; } - public Map getSourceCode(JSONObject obj) { - // TODO: implement - return null; + public Map getSourceCode(JSONObject obj) { + SourceCodeDeserializer deserializer = new SourceCodeDeserializer(); + + Map result = new HashMap<>(); + + Iterator keys = obj.keys(); + + while(keys.hasNext()) { + String key = keys.next(); + try { + if (obj.get(key) instanceof JSONObject) { + result.put(key, deserializer.deserialize(obj)); + } + } catch (JSONException e) { + // TODO: + } + } + return result; } public Map getThreadInformation(JSONObject obj) { // TODO: implement - return null; + // TODO: what if obj == null + Map result = new HashMap<>(); + final ThreadInformationDeserializer deserializer = new ThreadInformationDeserializer(); + Iterator keys = obj.keys(); + + while(keys.hasNext()) { + String key = keys.next(); + try { + if (obj.get(key) instanceof JSONObject) { + result.put(key, deserializer.deserialize(obj)); + } + } catch (JSONException e) { + // TODO: + } + } + return result; } public String [] getClassifiers(JSONArray jsonArray) { diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceStackFrameDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceStackFrameDeserializer.java new file mode 100644 index 00000000..5f9fd106 --- /dev/null +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceStackFrameDeserializer.java @@ -0,0 +1,27 @@ +package backtraceio.library.common.serializers.deserializers; + +import org.json.JSONException; +import org.json.JSONObject; + +import backtraceio.library.models.BacktraceApiResult; +import backtraceio.library.models.BacktraceStackFrame; +import backtraceio.library.models.types.BacktraceResultStatus; + +public class BacktraceStackFrameDeserializer implements Deserializable { + + private final FieldNameLoader fieldNameLoader = new FieldNameLoader(BacktraceStackFrame.class); // TODO: maybe we can reuse it + + static class Fields { + final static String functionName = "functionName"; + final static String line = "line"; + final static String sourceCode = "sourceCode"; + } + public BacktraceStackFrame deserialize(JSONObject obj) throws JSONException { + return new BacktraceStackFrame( + obj.optString(fieldNameLoader.get(Fields.functionName), null), // TODO: check fallback warning + obj.optString(fieldNameLoader.get(Fields.line), null), // TODO: check fallback warning + obj.optInt(fieldNameLoader.get(Fields.sourceCode)) // TODO: check fallback warning + ); + } +} + diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/SourceCodeDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/SourceCodeDeserializer.java new file mode 100644 index 00000000..c0f53088 --- /dev/null +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/SourceCodeDeserializer.java @@ -0,0 +1,22 @@ +package backtraceio.library.common.serializers.deserializers; + +import org.json.JSONException; +import org.json.JSONObject; + +import backtraceio.library.models.BacktraceStackFrame; +import backtraceio.library.models.json.SourceCode; + +public class SourceCodeDeserializer implements Deserializable { + private final FieldNameLoader fieldNameLoader = new FieldNameLoader(SourceCode.class); // TODO: maybe we can reuse it + + static class Fields { + final static String startLine = "startLine"; + final static String sourceCodeFileName = "sourceCodeFileName"; + } + public SourceCode deserialize(JSONObject obj) throws JSONException { + return new SourceCode( + obj.optInt(fieldNameLoader.get(Fields.startLine)), + obj.optString(fieldNameLoader.get(Fields.sourceCodeFileName)) + ); + } +} diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ThreadInformationDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ThreadInformationDeserializer.java new file mode 100644 index 00000000..2efa1338 --- /dev/null +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ThreadInformationDeserializer.java @@ -0,0 +1,48 @@ +package backtraceio.library.common.serializers.deserializers; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.List; + +import backtraceio.library.models.BacktraceStackFrame; +import backtraceio.library.models.json.ThreadInformation; + +public class ThreadInformationDeserializer implements Deserializable { + + private final FieldNameLoader fieldNameLoader = new FieldNameLoader(ThreadInformation.class); // TODO: maybe we can reuse it + + static class Fields { + final static String name = "name"; + final static String fault = "fault"; + final static String stack = "stack"; + } + + public ThreadInformation deserialize(JSONObject obj) throws JSONException { + return new ThreadInformation( + obj.optString(Fields.name, null), // TODO: fallback warning + obj.optBoolean(Fields.fault, false), + getBacktraceStackFrameList(obj.optJSONArray(Fields.stack)) + ); + } + + public List getBacktraceStackFrameList(JSONArray jsonArray) { + final List result = new ArrayList<>(); + +// StackTraceElement[] result = new StackTraceElement[array.length()]; + final BacktraceStackFrameDeserializer deserializer = new BacktraceStackFrameDeserializer(); // TODO: check how to resolve it + for(int idx = 0; idx < jsonArray.length(); idx++) { + try { + JSONObject obj = (JSONObject) jsonArray.get(idx); + result.add(deserializer.deserialize(obj)); + } + catch (Exception ex) { + // TODO: handle + } + } + + return result; + } +} 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 fbc48433..03f15cfe 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceStackFrame.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceStackFrame.java @@ -48,14 +48,21 @@ 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; + return null; } - this.functionName = frame.getClassName() + "." + frame.getMethodName(); - this.sourceCodeFileName = frame.getFileName(); + 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 = functionName; + this.sourceCodeFileName = sourceCodeFileName; this.sourceCode = UUID.randomUUID().toString(); - this.line = frame.getLineNumber() > 0 ? frame.getLineNumber() : null; + this.line = line; } } \ 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 55740cad..7843c460 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,11 @@ 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 } } 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 806e3857..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 @@ -74,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 9ee1648d..3e44e35e 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 @@ -38,7 +38,7 @@ 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, List + public ThreadInformation(String threadName, Boolean fault, List stack) { this.stack = stack == null ? new ArrayList<>() : stack; this.name = threadName; From 8cc35d6db4a1fb585e79f832bede99cb5469d837 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Sat, 17 Feb 2024 18:27:41 +0100 Subject: [PATCH 030/100] Deserializers implementation --- .../BacktraceDataDeserializer.java | 41 +++++++++++++------ .../BacktraceReportDeserializer.java | 37 ++++++++++++----- .../ThreadInformationDeserializer.java | 6 +-- .../library/models/BacktraceData.java | 15 ++++--- .../library/models/json/BacktraceReport.java | 3 ++ .../library/models/json/SourceCode.java | 2 +- 6 files changed, 69 insertions(+), 35 deletions(-) diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDataDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDataDeserializer.java index 85e96bc6..94721f14 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDataDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDataDeserializer.java @@ -10,6 +10,7 @@ import java.util.Map; import backtraceio.library.models.BacktraceData; +import backtraceio.library.models.database.BacktraceDatabaseRecord; import backtraceio.library.models.json.BacktraceReport; import backtraceio.library.models.json.SourceCode; import backtraceio.library.models.json.ThreadInformation; @@ -17,21 +18,37 @@ // TODO: check if methods should be private public class BacktraceDataDeserializer implements Deserializable{ + private final FieldNameLoader fieldNameLoader = new FieldNameLoader(BacktraceData.class); // TODO: maybe we can reuse it + static class Fields { + final static String uuid = "uuid"; + final static String symbolication = "symbolication"; + final static String timestamp = "timestamp"; + final static String langVersion = "langVersion"; + final static String agentVersion = "agentVersion"; + final static String attributes = "attributes"; + final static String mainThread = "mainThread"; + final static String classifiers = "classifiers"; + final static String annotations = "annotations"; + final static String sourceCode = "sourceCode"; + final static String report = "report"; + final static String threadInformationMap = "threadInformationMap"; + + } public BacktraceData deserialize(JSONObject obj) throws JSONException { return new BacktraceData( - obj.optString("uuid"), - obj.optString("symbolication"), - obj.optLong("timestamp"), - obj.optString("lang-version"), // TODO: fix or improve casing should get from annotation - obj.optString("agent-version"), // TODO: fix or improve casing should get from annotation + obj.optString(fieldNameLoader.get(Fields.uuid)), + obj.optString(fieldNameLoader.get(Fields.symbolication)), + obj.optLong(fieldNameLoader.get(Fields.timestamp)), + obj.optString(fieldNameLoader.get(Fields.langVersion)), // TODO: fix or improve casing should get from annotation + obj.optString(fieldNameLoader.get(Fields.agentVersion)), // TODO: fix or improve casing should get from annotation // TODO: fix all below and maybe add fallback - getAttributes(obj.optJSONObject("attributes")), - obj.optString("main-thread"), - getClassifiers(obj.optJSONArray("classifiers")), - getBacktraceReport(obj.optJSONObject("report")), - getAnnotations(obj.optJSONObject("annotations")), - getSourceCode(obj.optJSONObject("sourceCode")), - getThreadInformation(obj.optJSONObject("threads")) + getAttributes(obj.optJSONObject(fieldNameLoader.get(Fields.attributes))), + obj.optString(fieldNameLoader.get(Fields.mainThread)), + getClassifiers(obj.optJSONArray(fieldNameLoader.get(Fields.classifiers))), + getBacktraceReport(obj.optJSONObject(fieldNameLoader.get(Fields.report))), + getAnnotations(obj.optJSONObject(fieldNameLoader.get(Fields.annotations))), + getSourceCode(obj.optJSONObject(fieldNameLoader.get(Fields.sourceCode))), + getThreadInformation(obj.optJSONObject(fieldNameLoader.get(Fields.threadInformationMap))) ); // TODO } diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceReportDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceReportDeserializer.java index e8332e9a..a799da55 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceReportDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceReportDeserializer.java @@ -13,28 +13,43 @@ import java.util.Map; import java.util.UUID; +import backtraceio.library.models.BacktraceApiResult; import backtraceio.library.models.BacktraceStackFrame; import backtraceio.library.models.json.BacktraceReport; public class BacktraceReportDeserializer implements Deserializable { - ExceptionDeserializer exceptionDeserializer; + private final FieldNameLoader fieldNameLoader = new FieldNameLoader(BacktraceReport.class); // TODO: maybe we can reuse it + final ExceptionDeserializer exceptionDeserializer; + + static class Fields { + final static String uuid = "rxId"; + final static String timestamp = "timestamp"; + final static String exceptionTypeReport = "exceptionTypeReport"; + final static String attributes = "attributes"; + final static String classifier = "classifier"; + final static String message = "message"; + final static String exception = "exception"; + final static String attachmentPaths = "attachmentPaths"; + final static String diagnosticStack = "diagnosticStack"; + } + public BacktraceReportDeserializer() { this.exceptionDeserializer = new ExceptionDeserializer(); } @Override // TODO: fix all null warnings public BacktraceReport deserialize(JSONObject obj) throws JSONException { - final String uuid = obj.optString("uuid", null); - final long timestamp = obj.optLong("timestamp", 0); - final String message = obj.optString("message", null); - final String classifier = obj.optString("classifier", ""); - final boolean exceptionTypeReport = obj.optBoolean("exception-type-report"); - final Exception exception = getException(obj.optJSONObject("exception")); - final Map attributes = this.getAttributes(obj.optJSONObject("attributes")); // TODO: fix - - final List attachmentPaths = this.getAttachmentList(obj.optJSONArray("attachmentPaths")); - final List diagnosticStack = this.getDiagnosticStack(obj.optJSONArray("diagnostic-stack")); // todo fix diagnostic-stack name + final String uuid = obj.optString(fieldNameLoader.get(Fields.uuid), null); + final long timestamp = obj.optLong(fieldNameLoader.get(Fields.timestamp), 0); + final String message = obj.optString(fieldNameLoader.get(Fields.message), null); + final String classifier = obj.optString(fieldNameLoader.get(Fields.classifier), ""); + final boolean exceptionTypeReport = obj.optBoolean(fieldNameLoader.get(Fields.exceptionTypeReport)); + final Exception exception = getException(obj.optJSONObject(fieldNameLoader.get(Fields.exception))); + final Map attributes = this.getAttributes(obj.optJSONObject(fieldNameLoader.get(Fields.attributes))); + + final List attachmentPaths = this.getAttachmentList(obj.optJSONArray(fieldNameLoader.get(Fields.attachmentPaths))); + final List diagnosticStack = this.getDiagnosticStack(obj.optJSONArray(fieldNameLoader.get(Fields.diagnosticStack))); return new BacktraceReport( !isNullOrEmpty(uuid)? UUID.fromString(uuid) : null, diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ThreadInformationDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ThreadInformationDeserializer.java index 2efa1338..ccb67912 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ThreadInformationDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ThreadInformationDeserializer.java @@ -22,9 +22,9 @@ static class Fields { public ThreadInformation deserialize(JSONObject obj) throws JSONException { return new ThreadInformation( - obj.optString(Fields.name, null), // TODO: fallback warning - obj.optBoolean(Fields.fault, false), - getBacktraceStackFrameList(obj.optJSONArray(Fields.stack)) + obj.optString(fieldNameLoader.get(Fields.name), null), // TODO: fallback warning + obj.optBoolean(fieldNameLoader.get(Fields.fault), false), + getBacktraceStackFrameList(obj.optJSONArray(fieldNameLoader.get(Fields.stack))) ); } 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 7e9c1ed0..69d2a054 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java @@ -21,6 +21,12 @@ */ 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(); /** @@ -42,13 +48,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 */ @@ -115,8 +114,8 @@ public BacktraceData(String uuid, String symbolication, long timestamp, String l String[] classifiers, BacktraceReport report, Map annotations, Map sourceCode, Map threadInformationMap) { - this.symbolication = symbolication; this.uuid = uuid; + this.symbolication = symbolication; this.timestamp = timestamp; this.langVersion = langVersion; this.agentVersion = agentVersion; diff --git a/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceReport.java b/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceReport.java index ade58bf9..d8cfccb9 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceReport.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceReport.java @@ -9,6 +9,7 @@ import java.util.UUID; import backtraceio.library.common.BacktraceTimeHelper; +import backtraceio.library.common.serializers.SerializedName; import backtraceio.library.models.BacktraceAttributeConsts; import backtraceio.library.models.BacktraceData; import backtraceio.library.models.BacktraceStackFrame; @@ -33,6 +34,7 @@ public class BacktraceReport { /** * Get information about report type. If value is true the BacktraceReport has an error */ + @SerializedName("exception-type-report") public Boolean exceptionTypeReport = false; /** @@ -63,6 +65,7 @@ public class BacktraceReport { /** * Current report exception stack */ + @SerializedName("diagnostic-stack") public List diagnosticStack; /** 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 7843c460..47bb11dd 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 @@ -27,6 +27,6 @@ public SourceCode(BacktraceStackFrame stackFrame) { public SourceCode(Integer line, String sourceCodeFileName) { this.startLine = line; - this.sourceCodeFileName = sourceCodeFileName + this.sourceCodeFileName = sourceCodeFileName; } } From 3c21c68b1ce1d8408ac6be2fae31bfb7dd568f45 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 28 Feb 2024 19:05:04 +0100 Subject: [PATCH 031/100] Deserialize backtrace data annotation, add unit test checks --- .../common/BacktraceDataDeserializerTest.java | 51 ++++++++----------- .../serializers/BacktraceDeserializer.java | 6 +++ .../BacktraceApiResultDeserializer.java | 5 +- .../BacktraceDataDeserializer.java | 38 +++++++------- .../BacktraceDatabaseRecordDeserializer.java | 4 +- .../BacktraceReportDeserializer.java | 17 +++++-- .../BacktraceStackFrameDeserializer.java | 8 ++- .../deserializers/ExceptionDeserializer.java | 5 +- .../deserializers/MapDeserializer.java | 42 +++++++++++++++ .../deserializers/SourceCodeDeserializer.java | 2 +- .../ThreadInformationDeserializer.java | 13 ++--- .../{ => cache}/FieldNameCache.java | 6 ++- .../{ => cache}/FieldNameLoader.java | 2 +- .../library/models/BacktraceStackTrace.java | 2 +- 14 files changed, 127 insertions(+), 74 deletions(-) create mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/MapDeserializer.java rename backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/{ => cache}/FieldNameCache.java (84%) rename backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/{ => cache}/FieldNameLoader.java (78%) diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java index da18930c..16abf3ff 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java @@ -12,6 +12,10 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.platform.app.InstrumentationRegistry; +import com.google.gson.FieldNamingPolicy; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + import org.json.JSONException; import org.json.JSONObject; import org.junit.Test; @@ -90,47 +94,32 @@ public void deserializeBacktraceApiResult() throws JSONException { @Test public void fromJson2() throws JSONException, IllegalAccessException { // GIVEN - final Context context = InstrumentationRegistry.getInstrumentation().getContext(); - String fileName = "sample.json"; - - String path = "resources/"; - String jsonPath = path + "sample.json"; - - // WHEN - String content = readFileAsString(this, fileName); -// File x = getFileFromPath(this, "resources/sample.json"); - JSONObject jsonObj = new JSONObject(content); + // WHEN BacktraceData dataJson = BacktraceOrgJsonDeserializer.deserialize(content, BacktraceData.class); -// BacktraceData backtraceData = BacktraceDataDeserializer.deserialize(context, jsonObj); - -// System.out.println(backtraceData.report); - // THEN -// assertEquals(backtraceData.report.message, ); - } - - @Test - public void fromJson() throws JSONException, IllegalAccessException { - // GIVEN - final Context context = InstrumentationRegistry.getInstrumentation().getContext(); - - String fileName = "sample.json"; + BacktraceData gsonDataJson = (new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_DASHES)).create().fromJson(content, BacktraceData.class); // GSON backup - String path = "resources/"; - String jsonPath = path + "sample.json"; + assertEquals(dataJson.uuid, "079e41e2-bef1-4062-9e20-f2e1b3a93582"); + assertEquals(dataJson.report, null); + assertEquals(dataJson.lang, "java"); + assertEquals(dataJson.agent, "backtrace-android"); + assertEquals(dataJson.langVersion, "0"); + assertEquals(dataJson.agentVersion, "3.7.7-8-3f67d73-org-json-serializer"); + assertEquals(dataJson.mainThread, "instr: androidx.test.runner.androidjunitrunner"); + assertEquals(dataJson.timestamp, 1694983723); +// assertEquals(dataJson.); - // WHEN - - String content = readFileAsString(this, fileName); -// File x = getFileFromPath(this, "resources/sample.json"); - JSONObject jsonObj = new JSONObject(content); +// assertEquals(dataJson.symbolication, ""); +// assertEquals(dataJson.classifiers, ""); +// assertEquals(dataJson.sourceCode, ""); +// assertEquals(dataJson.annotations, ""); // BacktraceData backtraceData = BacktraceDataDeserializer.deserialize(context, jsonObj); -// System.out.println(backtraceData.report); + System.out.println(dataJson.report); // THEN // assertEquals(backtraceData.report.message, ); } diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDeserializer.java index 5e43d519..8df87544 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDeserializer.java @@ -35,7 +35,13 @@ public static void registerDeserializer(Class clazz, Deserializable obj) { @SuppressWarnings("unchecked") public static T deserialize(JSONObject obj, Class clazz) throws JSONException { + if (obj == null) { +// LOGG + // TODO: Add logging + return null; + } if (deserializers.containsKey(clazz)) { + // TODO: check if deserializers.get(clazz) is not null return (T) deserializers.get(clazz).deserialize(obj); } // todo: maybe return unsupported diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceApiResultDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceApiResultDeserializer.java index 9abc8f6d..7d4858fb 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceApiResultDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceApiResultDeserializer.java @@ -3,8 +3,8 @@ import org.json.JSONException; import org.json.JSONObject; +import backtraceio.library.common.serializers.deserializers.cache.FieldNameLoader; import backtraceio.library.models.BacktraceApiResult; -import backtraceio.library.models.BacktraceResult; import backtraceio.library.models.types.BacktraceResultStatus; public class BacktraceApiResultDeserializer implements Deserializable { @@ -18,8 +18,7 @@ static class Fields { public BacktraceApiResult deserialize(JSONObject obj) throws JSONException { return new BacktraceApiResult( obj.optString(fieldNameLoader.get(Fields.rxId), null), // TODO: check fallback warning - obj.optString(fieldNameLoader.get(Fields.response), BacktraceResultStatus.Ok.toString() - ) + obj.optString(fieldNameLoader.get(Fields.response), BacktraceResultStatus.Ok.toString()) ); } } diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDataDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDataDeserializer.java index 94721f14..987a44ad 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDataDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDataDeserializer.java @@ -4,21 +4,21 @@ import org.json.JSONException; import org.json.JSONObject; -import java.security.InvalidAlgorithmParameterException; import java.util.HashMap; import java.util.Iterator; import java.util.Map; +import backtraceio.library.common.serializers.deserializers.cache.FieldNameLoader; import backtraceio.library.models.BacktraceData; -import backtraceio.library.models.database.BacktraceDatabaseRecord; import backtraceio.library.models.json.BacktraceReport; import backtraceio.library.models.json.SourceCode; import backtraceio.library.models.json.ThreadInformation; // TODO: check if methods should be private -public class BacktraceDataDeserializer implements Deserializable{ +public class BacktraceDataDeserializer implements Deserializable { private final FieldNameLoader fieldNameLoader = new FieldNameLoader(BacktraceData.class); // TODO: maybe we can reuse it + static class Fields { final static String uuid = "uuid"; final static String symbolication = "symbolication"; @@ -34,9 +34,10 @@ static class Fields { final static String threadInformationMap = "threadInformationMap"; } + public BacktraceData deserialize(JSONObject obj) throws JSONException { return new BacktraceData( - obj.optString(fieldNameLoader.get(Fields.uuid)), + obj.optString(fieldNameLoader.get(Fields.uuid)), obj.optString(fieldNameLoader.get(Fields.symbolication)), obj.optLong(fieldNameLoader.get(Fields.timestamp)), obj.optString(fieldNameLoader.get(Fields.langVersion)), // TODO: fix or improve casing should get from annotation @@ -58,19 +59,22 @@ public BacktraceReport getBacktraceReport(JSONObject obj) throws JSONException { return deserializer.deserialize(obj); } - public Map getAnnotations(JSONObject obj) { - // TODO: implement - return null; + public Map getAnnotations(JSONObject obj) throws JSONException { + // TODO: Fix: throwing exception + return MapDeserializer.toMap(obj); } - public Map getSourceCode(JSONObject obj) { + public Map getSourceCode(JSONObject obj) { + if (obj == null) { + return null; + } SourceCodeDeserializer deserializer = new SourceCodeDeserializer(); Map result = new HashMap<>(); Iterator keys = obj.keys(); - while(keys.hasNext()) { + while (keys.hasNext()) { String key = keys.next(); try { if (obj.get(key) instanceof JSONObject) { @@ -84,13 +88,15 @@ public Map getSourceCode(JSONObject obj) { } public Map getThreadInformation(JSONObject obj) { - // TODO: implement // TODO: what if obj == null + if (obj == null) { + return null; + } Map result = new HashMap<>(); final ThreadInformationDeserializer deserializer = new ThreadInformationDeserializer(); Iterator keys = obj.keys(); - while(keys.hasNext()) { + while (keys.hasNext()) { String key = keys.next(); try { if (obj.get(key) instanceof JSONObject) { @@ -103,20 +109,18 @@ public Map getThreadInformation(JSONObject obj) { return result; } - public String [] getClassifiers(JSONArray jsonArray) { - + public String[] getClassifiers(JSONArray jsonArray) { if (jsonArray == null) { return new String[0]; } String[] result = new String[jsonArray.length()]; - for(int i = 0; i < jsonArray.length(); i++){ + for (int i = 0; i < jsonArray.length(); i++) { try { Object object = jsonArray.get(i); result[i] = object.toString(); - } - catch (JSONException exception) { + } catch (JSONException exception) { // todo: error handling } } @@ -133,7 +137,7 @@ public Map getAttributes(JSONObject obj) { Iterator keys = obj.keys(); - while(keys.hasNext()) { + while (keys.hasNext()) { String key = keys.next(); try { result.put(key, obj.get(key).toString()); diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDatabaseRecordDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDatabaseRecordDeserializer.java index cfb61f7f..8e6d69e0 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDatabaseRecordDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDatabaseRecordDeserializer.java @@ -3,9 +3,7 @@ import org.json.JSONException; import org.json.JSONObject; -import java.util.UUID; - -import backtraceio.library.models.BacktraceData; +import backtraceio.library.common.serializers.deserializers.cache.FieldNameLoader; import backtraceio.library.models.database.BacktraceDatabaseRecord; public class BacktraceDatabaseRecordDeserializer implements Deserializable { diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceReportDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceReportDeserializer.java index a799da55..7bc8aaed 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceReportDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceReportDeserializer.java @@ -13,7 +13,7 @@ import java.util.Map; import java.util.UUID; -import backtraceio.library.models.BacktraceApiResult; +import backtraceio.library.common.serializers.deserializers.cache.FieldNameLoader; import backtraceio.library.models.BacktraceStackFrame; import backtraceio.library.models.json.BacktraceReport; @@ -22,8 +22,10 @@ public class BacktraceReportDeserializer implements Deserializable getDiagnosticStack(JSONArray obj) { for (int i = 0; i < obj.length(); i++) { JSONObject stackItem = obj.optJSONObject(i); if (stackItem != null) { + try { + result.add(this.stackFrameDeserializer.deserialize(stackItem)); + } catch (Exception e) { + // TODO: handle + } BacktraceStackFrame stackFrame = new BacktraceStackFrame(); stackFrame.functionName = stackItem.optString("function-name"); - stackFrame.line = stackItem.optInt("line"); // todo: should be null in case of empty + stackFrame.line = stackItem.optInt("line"); stackFrame.sourceCode = stackItem.optString("source-code"); result.add(stackFrame); } diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceStackFrameDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceStackFrameDeserializer.java index 5f9fd106..9e6bab5f 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceStackFrameDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceStackFrameDeserializer.java @@ -3,9 +3,8 @@ import org.json.JSONException; import org.json.JSONObject; -import backtraceio.library.models.BacktraceApiResult; +import backtraceio.library.common.serializers.deserializers.cache.FieldNameLoader; import backtraceio.library.models.BacktraceStackFrame; -import backtraceio.library.models.types.BacktraceResultStatus; public class BacktraceStackFrameDeserializer implements Deserializable { @@ -19,9 +18,8 @@ static class Fields { public BacktraceStackFrame deserialize(JSONObject obj) throws JSONException { return new BacktraceStackFrame( obj.optString(fieldNameLoader.get(Fields.functionName), null), // TODO: check fallback warning - obj.optString(fieldNameLoader.get(Fields.line), null), // TODO: check fallback warning - obj.optInt(fieldNameLoader.get(Fields.sourceCode)) // TODO: check fallback warning - ); + obj.optString(fieldNameLoader.get(Fields.line), null), // TODO: check fallback warning // todo: should be null in case of empty + obj.optInt(fieldNameLoader.get(Fields.sourceCode))); // TODO: check fallback warning } } diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ExceptionDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ExceptionDeserializer.java index bbf383ca..72fcea97 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ExceptionDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ExceptionDeserializer.java @@ -8,6 +8,10 @@ import java.util.List; public class ExceptionDeserializer implements Deserializable { + static class Fields { + final static String startLine = "startLine"; + final static String sourceCodeFileName = "sourceCodeFileName"; + } @Override public Exception deserialize(JSONObject obj) { final String message = obj.optString("detail-message", ""); @@ -31,7 +35,6 @@ public StackTraceElement[] getStacktrace(JSONArray array) throws JSONException { } StackTraceElement[] result = new StackTraceElement[array.length()]; - for(int idx = 0; idx < array.length(); idx++) { JSONObject obj = (JSONObject) array.get(idx); result[idx] = new StackTraceElement( diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/MapDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/MapDeserializer.java new file mode 100644 index 00000000..b7725174 --- /dev/null +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/MapDeserializer.java @@ -0,0 +1,42 @@ +package backtraceio.library.common.serializers.deserializers; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +public class MapDeserializer { + public static Map toMap(JSONObject jsonObj) throws JSONException { + Map map = new HashMap<>(); + Iterator keys = jsonObj.keys(); + while(keys.hasNext()) { + String key = keys.next(); + Object value = jsonObj.get(key); + if (value instanceof JSONArray) { + value = toList((JSONArray) value); + } else if (value instanceof JSONObject) { + value = toMap((JSONObject) value); + } + map.put(key, value); + } return map; + } + + public static List toList(JSONArray array) throws JSONException { + List list = new ArrayList<>(); + for(int i = 0; i < array.length(); i++) { + Object value = array.get(i); + if (value instanceof JSONArray) { + value = toList((JSONArray) value); + } + else if (value instanceof JSONObject) { + value = toMap((JSONObject) value); + } + list.add(value); + } return list; + } +} diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/SourceCodeDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/SourceCodeDeserializer.java index c0f53088..7a9e1ae5 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/SourceCodeDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/SourceCodeDeserializer.java @@ -3,7 +3,7 @@ import org.json.JSONException; import org.json.JSONObject; -import backtraceio.library.models.BacktraceStackFrame; +import backtraceio.library.common.serializers.deserializers.cache.FieldNameLoader; import backtraceio.library.models.json.SourceCode; public class SourceCodeDeserializer implements Deserializable { diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ThreadInformationDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ThreadInformationDeserializer.java index ccb67912..3639c1fd 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ThreadInformationDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ThreadInformationDeserializer.java @@ -7,6 +7,7 @@ import java.util.ArrayList; import java.util.List; +import backtraceio.library.common.serializers.deserializers.cache.FieldNameLoader; import backtraceio.library.models.BacktraceStackFrame; import backtraceio.library.models.json.ThreadInformation; @@ -24,21 +25,21 @@ public ThreadInformation deserialize(JSONObject obj) throws JSONException { return new ThreadInformation( obj.optString(fieldNameLoader.get(Fields.name), null), // TODO: fallback warning obj.optBoolean(fieldNameLoader.get(Fields.fault), false), - getBacktraceStackFrameList(obj.optJSONArray(fieldNameLoader.get(Fields.stack))) - ); + getBacktraceStackFrameList(obj.optJSONArray(fieldNameLoader.get(Fields.stack)))); } public List getBacktraceStackFrameList(JSONArray jsonArray) { + if (jsonArray == null) { + return null; // todo: Check if we should return empty or null + } final List result = new ArrayList<>(); -// StackTraceElement[] result = new StackTraceElement[array.length()]; final BacktraceStackFrameDeserializer deserializer = new BacktraceStackFrameDeserializer(); // TODO: check how to resolve it - for(int idx = 0; idx < jsonArray.length(); idx++) { + for (int idx = 0; idx < jsonArray.length(); idx++) { try { JSONObject obj = (JSONObject) jsonArray.get(idx); result.add(deserializer.deserialize(obj)); - } - catch (Exception ex) { + } catch (Exception ex) { // TODO: handle } } diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/FieldNameCache.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/cache/FieldNameCache.java similarity index 84% rename from backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/FieldNameCache.java rename to backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/cache/FieldNameCache.java index 778d28cf..dfae1688 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/FieldNameCache.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/cache/FieldNameCache.java @@ -1,4 +1,4 @@ -package backtraceio.library.common.serializers.deserializers; +package backtraceio.library.common.serializers.deserializers.cache; import androidx.annotation.NonNull; @@ -10,7 +10,7 @@ public class FieldNameCache { // Map to store annotation information - private static Map fieldNameMap = new HashMap<>(); + private final static Map fieldNameMap = new HashMap<>(); // Method to get annotation for a given class and field public static String getAnnotation(Class clazz, @NonNull String fieldName) { @@ -26,6 +26,8 @@ public static String getAnnotation(Class clazz, @NonNull String fieldName) { if (field.isAnnotationPresent(SerializedName.class)) { cachedFieldName = field.getAnnotation(SerializedName.class).value(); fieldNameMap.put(key, cachedFieldName); + } else { + cachedFieldName = field.getName(); } } catch (NoSuchFieldException e) { e.printStackTrace(); diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/FieldNameLoader.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/cache/FieldNameLoader.java similarity index 78% rename from backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/FieldNameLoader.java rename to backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/cache/FieldNameLoader.java index d6c93e63..6cb5c6f5 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/FieldNameLoader.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/cache/FieldNameLoader.java @@ -1,4 +1,4 @@ -package backtraceio.library.common.serializers.deserializers; +package backtraceio.library.common.serializers.deserializers.cache; public class FieldNameLoader { private final Class clazz; 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); } } From a9d8f51db65d5aecb783741de489ff1b6a0f8e88 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 6 Mar 2024 00:01:32 +0100 Subject: [PATCH 032/100] Add next tests --- .../library/models/BacktraceDataTest.java | 1 + .../androidTest/resources/backtraceData.json | 1 + .../BacktraceReportDeserializer.java | 36 +++------------ .../GenericListDeserializer.java | 26 +++++++++++ .../ThreadInformationDeserializer.java | 24 ++++------ .../BacktraceDataDeserializerTest.java | 44 +++++++++++++++---- .../library/ConcatAttributesUnitTest.java | 30 ++++++++----- 7 files changed, 97 insertions(+), 65 deletions(-) create mode 100644 backtrace-library/src/androidTest/resources/backtraceData.json create mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/GenericListDeserializer.java 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 167d1206..159bf8d8 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/models/BacktraceDataTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/models/BacktraceDataTest.java @@ -36,5 +36,6 @@ public void createBacktraceDataTest() { assertEquals(backtraceData.classifiers, new String[]{"java.lang.IllegalAccessException"}); assertEquals(backtraceData.report, report); assertEquals(backtraceData.attributes.get("classifier"), "java.lang.IllegalAccessException"); + // TODO: add next checks } } diff --git a/backtrace-library/src/androidTest/resources/backtraceData.json b/backtrace-library/src/androidTest/resources/backtraceData.json new file mode 100644 index 00000000..c4d29bf4 --- /dev/null +++ b/backtrace-library/src/androidTest/resources/backtraceData.json @@ -0,0 +1 @@ +{"agent":"backtrace-android","agent-version":"3.7.12-8-3686709-org-json-serializer","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","PATH":"/product/bin:/apex/com.android.runtime/bin:/apex/com.android.art/bin:/system_ext/bin:/system/bin:/system/xbin:/odm/bin:/vendor/bin:/vendor/xbin","ANDROID_SOCKET_zygote":"17","ANDROID_I18N_ROOT":"/apex/com.android.i18n","ANDROID_DATA":"/data","ASEC_MOUNTPOINT":"/mnt/asec","ANDROID_TZDATA_ROOT":"/apex/com.android.tzdata","EXTERNAL_STORAGE":"/sdcard","ANDROID_BOOTLOGO":"1","ANDROID_ASSETS":"/system/app","ANDROID_STORAGE":"/storage","DEX2OATBOOTCLASSPATH":"/apex/com.android.art/javalib/core-oj.jar:/apex/com.android.art/javalib/core-libart.jar:/apex/com.android.art/javalib/core-icu4j.jar:/apex/com.android.art/javalib/okhttp.jar:/apex/com.android.art/javalib/bouncycastle.jar:/apex/com.android.art/javalib/apache-xml.jar:/system/framework/framework.jar:/system/framework/ext.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/framework-atb-backward-compatibility.jar","ANDROID_ART_ROOT":"/apex/com.android.art","ANDROID_ROOT":"/system","DOWNLOAD_CACHE":"/data/cache","BOOTCLASSPATH":"/apex/com.android.art/javalib/core-oj.jar:/apex/com.android.art/javalib/core-libart.jar:/apex/com.android.art/javalib/core-icu4j.jar:/apex/com.android.art/javalib/okhttp.jar:/apex/com.android.art/javalib/bouncycastle.jar:/apex/com.android.art/javalib/apache-xml.jar:/system/framework/framework.jar:/system/framework/ext.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/framework-atb-backward-compatibility.jar:/apex/com.android.conscrypt/javalib/conscrypt.jar:/apex/com.android.media/javalib/updatable-media.jar:/apex/com.android.mediaprovider/javalib/framework-mediaprovider.jar:/apex/com.android.os.statsd/javalib/framework-statsd.jar:/apex/com.android.permission/javalib/framework-permission.jar:/apex/com.android.sdkext/javalib/framework-sdkextensions.jar:/apex/com.android.wifi/javalib/framework-wifi.jar:/apex/com.android.tethering/javalib/framework-tethering.jar","ANDROID_SOCKET_usap_pool_primary":"21"},"Exception":{"message":"Example test string"}},"attributes":{"application.session":"fd86372a-457d-4347-b1af-34779f86f520","device.nfc.status":"NotAvailable","device.cpu.temperature":"0.0","system.memory.active":"1094905856","device.wifi.status":"Enabled","screen.height":"1834","uname.machine":"i686","screen.dpi":"288","device.bluetooth_status":"NotPermitted","device.airplane_mode":"false","system.memory.total":"2077347840","device.sdk":"30","device.brand":"google","uname.sysname":"Android","cpu.boottime":"1707253373829","device.os_version":"5.4.61-android11-0-00791-gbad091cc4bf3-ab6833933","device.gps.enabled":"Enabled","application.package":"backtraceio.library.test","uname.version":"11","backtrace.version":"3.7.12-8-3686709-org-json-serializer","device.is_power_saving_mode":"false","screen.orientation":"Portrait","device.manufacturer":"Google","system.memory.free":"982441984","battery.state":"Unplugged","backtrace.agent":"backtrace-android","error.type":"Message","device.location":"Enabled","application":"backtraceio.library.test","error.message":"Example test string","culture":"English","device.model":"sdk_gphone_x86","screen.width":"1080","build.type":"Debug","device.product":"sdk_gphone_x86","guid":"e4c57699-0dc9-35e2-b4a0-2ffff1925ca7","app.storage_used":"2974528","battery.level":"1.0","screen.brightness":"102"},"lang":"java","lang-version":"0","main-thread":"instr: androidx.test.runner.androidjunitrunner","source-code":{"5ad3ea57-08bc-42b9-a0af-4c0b63abd5d7":{"source-code-file-name":"ParentRunner.java","start-line":331},"e1c31c4a-9f5f-4aae-8f74-29c5f7398e4d":{"source-code-file-name":"AndroidJUnit4.java","start-line":162},"0a88f8a1-60c0-41a0-a95c-d75de5a4c82d":{"source-code-file-name":"JUnitCore.java","start-line":137},"b1cc1675-df0c-4bda-9ec2-cc50d02b7497":{"source-code-file-name":"ParentRunner.java","start-line":66},"6237d391-f50f-49b7-a029-dc8533521a39":{"source-code-file-name":"BlockJUnit4ClassRunner.java","start-line":100},"24d96335-14d8-45d8-a07d-fc24bc56d4db":{"source-code-file-name":"Suite.java","start-line":128},"9b765b76-8714-4dc2-8584-c58e57d0b97d":{"source-code-file-name":"ParentRunner.java","start-line":79},"0952a91a-0c4b-45f2-93c7-e744a7e64ded":{"source-code-file-name":"ParentRunner.java","start-line":306},"86deee3a-0e5f-495b-af66-5b2f36964ca2":{"source-code-file-name":"ParentRunner.java","start-line":79},"bbf3d67c-a184-49ee-b0d5-b02188e3fa30":{"source-code-file-name":"ParentRunner.java","start-line":293},"a70079ba-1646-4dda-ae17-7a92bf584c69":{"source-code-file-name":"ReflectiveCallable.java","start-line":12},"61876082-acce-458e-8248-bfb03dc2b340":{"source-code-file-name":"ParentRunner.java","start-line":306},"cfe92970-ae80-45b4-9dd4-8099919a1c26":{"source-code-file-name":"Suite.java","start-line":27},"a4ef001f-1238-4b6e-9e57-aaa3dc1717ce":{"source-code-file-name":"AndroidJUnitRunner.java","start-line":446},"6e8a4d01-3519-4742-be84-34da0dac2460":{"source-code-file-name":"ParentRunner.java","start-line":413},"42aefc9a-50aa-40e9-ac4e-483c279cd9dc":{"source-code-file-name":"Method.java"},"56847938-10cc-4e20-98e2-521ce93ebe70":{"source-code-file-name":"VMStack.java"},"86086e43-f1de-49c0-aeda-3ae2be530407":{"source-code-file-name":"FrameworkMethod.java","start-line":59},"ecc0e91a-52b3-48e7-b509-a850f49652c1":{"source-code-file-name":"RunBefores.java","start-line":80},"673561af-72d1-4294-8f73-cca30446e70e":{"source-code-file-name":"BlockJUnit4ClassRunner.java","start-line":103},"88ac7e2c-c331-4249-910d-519a6d25363f":{"source-code-file-name":"BlockJUnit4ClassRunner.java","start-line":63},"ea2aa6d0-8e27-402d-8836-9ede35629ac9":{"source-code-file-name":"ParentRunner.java","start-line":66},"4d79837a-1751-47e1-a134-d883871a9cec":{"source-code-file-name":"ParentRunner.java","start-line":413},"7787b022-3043-4976-9dde-990443b50b24":{"source-code-file-name":"FrameworkMethod.java","start-line":56},"5ed2c2aa-38a0-42ed-8f05-9131c4c72e90":{"source-code-file-name":"ParentRunner.java","start-line":366},"e7bd36c2-dd6a-4bb3-bac5-e5e606490c71":{"source-code-file-name":"ParentRunner.java","start-line":329},"ddf80aac-8ae4-42cc-9d35-5dae41fbf626":{"source-code-file-name":"ParentRunner.java","start-line":329},"2980dbe3-ee88-486c-8442-9b6816dfe07a":{"source-code-file-name":"RunAfters.java","start-line":61},"351d6b15-5d61-4a8a-9a06-5b14bf071945":{"source-code-file-name":"JUnitCore.java","start-line":115},"2172b7fe-e8cf-4ffa-936b-c6efb52694bb":{"source-code-file-name":"ParentRunner.java","start-line":331},"9ae72a6b-31be-435f-8a52-461f043b492b":{"source-code-file-name":"TestExecutor.java","start-line":58},"a67eccc1-bd1c-4207-93a5-db20e09b79aa":{"source-code-file-name":"Instrumentation.java","start-line":2205},"76276ba5-69ae-4815-8a9c-77525b526cb1":{"source-code-file-name":"TestExecutor.java","start-line":67},"23444a66-f715-444f-afcb-f367a6f72689":{"source-code-file-name":"ParentRunner.java","start-line":293},"1cfc3859-cf21-4d84-ba61-d73d9ee73c41":{"source-code-file-name":"ParentRunner.java","start-line":306},"653bad70-8157-49d4-8894-8bb089f76722":{"source-code-file-name":"Thread.java","start-line":1736},"84649fde-1055-4085-a52e-52c35811cbde":{"source-code-file-name":"InvokeMethod.java","start-line":17}},"thread-information-map":{"profile saver":{"fault":false,"name":"profile saver","stack":[]},"finalizerwatchdogdaemon":{"fault":false,"name":"finalizerwatchdogdaemon","stack":[{"function-name":"java.lang.Object.wait","source-code":"b778a593-508f-444d-ab62-77d1ea5506c5"},{"function-name":"java.lang.Object.wait","line":442,"source-code":"567b0437-8d29-4cc2-9274-819c056179a9"},{"function-name":"java.lang.Object.wait","line":568,"source-code":"d07089b6-e586-4cde-ab31-3d0d1740ae25"},{"function-name":"java.lang.Daemons$FinalizerWatchdogDaemon.sleepUntilNeeded","line":341,"source-code":"5aa512c3-e353-4309-9613-f3175bc05c56"},{"function-name":"java.lang.Daemons$FinalizerWatchdogDaemon.runInternal","line":321,"source-code":"a8fb461e-e7b9-4259-b16f-8e9610884d2a"},{"function-name":"java.lang.Daemons$Daemon.run","line":139,"source-code":"100f945a-c9ed-42d4-a396-bfb1c9c09e32"},{"function-name":"java.lang.Thread.run","line":923,"source-code":"ba65711d-9470-4cdc-a06a-32db7ce84db9"}]},"signal catcher":{"fault":false,"name":"signal catcher","stack":[]},"timer-0":{"fault":false,"name":"timer-0","stack":[{"function-name":"java.lang.Object.wait","source-code":"dbfe3cc6-8ac5-4a8c-b4c2-3c4073e563c7"},{"function-name":"java.lang.Object.wait","line":442,"source-code":"ce872d4e-20a7-4991-9ae6-b0c09ff728f1"},{"function-name":"java.util.TimerThread.mainLoop","line":559,"source-code":"507a2ca3-1e70-492a-9a75-cb95073c44a0"},{"function-name":"java.util.TimerThread.run","line":512,"source-code":"06908da9-ce73-4835-b1e3-5fb732fcf82e"}]},"main":{"fault":false,"name":"main","stack":[{"function-name":"android.os.MessageQueue.nativePollOnce","source-code":"30ad9a05-28af-4db8-8ee6-35d55cc85ca5"},{"function-name":"android.os.MessageQueue.next","line":335,"source-code":"58e043c1-b6f0-47ee-a5ea-af64153bd38b"},{"function-name":"android.os.Looper.loop","line":183,"source-code":"9718f15f-0010-4e8f-8012-a5c48b554a9f"},{"function-name":"android.app.ActivityThread.main","line":7656,"source-code":"4cc5b61d-3403-4a03-8a69-63adbcc55511"},{"function-name":"java.lang.reflect.Method.invoke","source-code":"23078e7a-df17-4655-bad5-48b90baedba9"},{"function-name":"com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run","line":592,"source-code":"cc45db4a-ec38-49d9-b5f6-14b804362ccd"},{"function-name":"com.android.internal.os.ZygoteInit.main","line":947,"source-code":"406194e7-76b8-4b8f-977c-21756313f648"}]},"finalizerdaemon":{"fault":false,"name":"finalizerdaemon","stack":[{"function-name":"java.lang.Object.wait","source-code":"daff552e-1ac1-4417-9b77-fd91b3a664fc"},{"function-name":"java.lang.Object.wait","line":442,"source-code":"d1445680-d522-46d4-ae3a-b2daeda6de3d"},{"function-name":"java.lang.ref.ReferenceQueue.remove","line":190,"source-code":"260f72cf-3b32-48ff-9722-af6280876415"},{"function-name":"java.lang.ref.ReferenceQueue.remove","line":211,"source-code":"e951fdfd-cde7-49f2-926b-4e131544d4d4"},{"function-name":"java.lang.Daemons$FinalizerDaemon.runInternal","line":273,"source-code":"4f2ac4ed-051c-4a1c-a94d-999809f38ea6"},{"function-name":"java.lang.Daemons$Daemon.run","line":139,"source-code":"d2d21d80-5047-4c37-abe5-cb0e854c555a"},{"function-name":"java.lang.Thread.run","line":923,"source-code":"ceeb7b8e-7b5c-4d65-9c80-7c8e02a12202"}]},"referencequeuedaemon":{"fault":false,"name":"referencequeuedaemon","stack":[{"function-name":"java.lang.Object.wait","source-code":"d569fd77-fec0-4abd-b746-1e43394a8ca1"},{"function-name":"java.lang.Object.wait","line":442,"source-code":"29bee7cd-cda4-4cd0-b7b6-1b21c40f3ee5"},{"function-name":"java.lang.Object.wait","line":568,"source-code":"4b73fe34-9a92-4b11-a391-fa60086a62b4"},{"function-name":"java.lang.Daemons$ReferenceQueueDaemon.runInternal","line":217,"source-code":"e76abece-43e7-48a0-a429-f13b75282fdd"},{"function-name":"java.lang.Daemons$Daemon.run","line":139,"source-code":"08d8fd2b-8d9e-4317-ad68-3031de5f429f"},{"function-name":"java.lang.Thread.run","line":923,"source-code":"8509b640-6470-4894-a896-7794e917c270"}]},"binder:8909_3":{"fault":false,"name":"binder:8909_3","stack":[]},"jit thread pool worker thread 0":{"fault":false,"name":"jit thread pool worker thread 0","stack":[]},"instrumentationconnectionthread":{"fault":false,"name":"instrumentationconnectionthread","stack":[{"function-name":"android.os.MessageQueue.nativePollOnce","source-code":"2699757c-16bd-4853-8d48-ad23aeebf5ad"},{"function-name":"android.os.MessageQueue.next","line":335,"source-code":"bf1a4cc2-55ee-43c3-83a0-8780eeece1ce"},{"function-name":"android.os.Looper.loop","line":183,"source-code":"2e0184c2-dd7e-41b6-946a-a646896cb880"},{"function-name":"android.os.HandlerThread.run","line":67,"source-code":"209e3b61-b3f2-4de5-b8e3-6d832e969ce9"}]},"instr: androidx.test.runner.androidjunitrunner":{"fault":true,"name":"instr: androidx.test.runner.androidjunitrunner","stack":[{"function-name":"dalvik.system.VMStack.getThreadStackTrace","source-code":"56847938-10cc-4e20-98e2-521ce93ebe70"},{"function-name":"java.lang.Thread.getStackTrace","line":1736,"source-code":"653bad70-8157-49d4-8894-8bb089f76722"},{"function-name":"java.lang.reflect.Method.invoke","source-code":"42aefc9a-50aa-40e9-ac4e-483c279cd9dc"},{"function-name":"org.junit.runners.model.FrameworkMethod$1.runReflectiveCall","line":59,"source-code":"86086e43-f1de-49c0-aeda-3ae2be530407"},{"function-name":"org.junit.internal.runners.model.ReflectiveCallable.run","line":12,"source-code":"a70079ba-1646-4dda-ae17-7a92bf584c69"},{"function-name":"org.junit.runners.model.FrameworkMethod.invokeExplosively","line":56,"source-code":"7787b022-3043-4976-9dde-990443b50b24"},{"function-name":"org.junit.internal.runners.statements.InvokeMethod.evaluate","line":17,"source-code":"84649fde-1055-4085-a52e-52c35811cbde"},{"function-name":"androidx.test.internal.runner.junit4.statement.RunBefores.evaluate","line":80,"source-code":"ecc0e91a-52b3-48e7-b509-a850f49652c1"},{"function-name":"androidx.test.internal.runner.junit4.statement.RunAfters.evaluate","line":61,"source-code":"2980dbe3-ee88-486c-8442-9b6816dfe07a"},{"function-name":"org.junit.runners.ParentRunner$3.evaluate","line":306,"source-code":"1cfc3859-cf21-4d84-ba61-d73d9ee73c41"},{"function-name":"org.junit.runners.BlockJUnit4ClassRunner$1.evaluate","line":100,"source-code":"6237d391-f50f-49b7-a029-dc8533521a39"},{"function-name":"org.junit.runners.ParentRunner.runLeaf","line":366,"source-code":"5ed2c2aa-38a0-42ed-8f05-9131c4c72e90"},{"function-name":"org.junit.runners.BlockJUnit4ClassRunner.runChild","line":103,"source-code":"673561af-72d1-4294-8f73-cca30446e70e"},{"function-name":"org.junit.runners.BlockJUnit4ClassRunner.runChild","line":63,"source-code":"88ac7e2c-c331-4249-910d-519a6d25363f"},{"function-name":"org.junit.runners.ParentRunner$4.run","line":331,"source-code":"2172b7fe-e8cf-4ffa-936b-c6efb52694bb"},{"function-name":"org.junit.runners.ParentRunner$1.schedule","line":79,"source-code":"86deee3a-0e5f-495b-af66-5b2f36964ca2"},{"function-name":"org.junit.runners.ParentRunner.runChildren","line":329,"source-code":"e7bd36c2-dd6a-4bb3-bac5-e5e606490c71"},{"function-name":"org.junit.runners.ParentRunner.access$100","line":66,"source-code":"ea2aa6d0-8e27-402d-8836-9ede35629ac9"},{"function-name":"org.junit.runners.ParentRunner$2.evaluate","line":293,"source-code":"23444a66-f715-444f-afcb-f367a6f72689"},{"function-name":"org.junit.runners.ParentRunner$3.evaluate","line":306,"source-code":"0952a91a-0c4b-45f2-93c7-e744a7e64ded"},{"function-name":"org.junit.runners.ParentRunner.run","line":413,"source-code":"6e8a4d01-3519-4742-be84-34da0dac2460"},{"function-name":"androidx.test.ext.junit.runners.AndroidJUnit4.run","line":162,"source-code":"e1c31c4a-9f5f-4aae-8f74-29c5f7398e4d"},{"function-name":"org.junit.runners.Suite.runChild","line":128,"source-code":"24d96335-14d8-45d8-a07d-fc24bc56d4db"},{"function-name":"org.junit.runners.Suite.runChild","line":27,"source-code":"cfe92970-ae80-45b4-9dd4-8099919a1c26"},{"function-name":"org.junit.runners.ParentRunner$4.run","line":331,"source-code":"5ad3ea57-08bc-42b9-a0af-4c0b63abd5d7"},{"function-name":"org.junit.runners.ParentRunner$1.schedule","line":79,"source-code":"9b765b76-8714-4dc2-8584-c58e57d0b97d"},{"function-name":"org.junit.runners.ParentRunner.runChildren","line":329,"source-code":"ddf80aac-8ae4-42cc-9d35-5dae41fbf626"},{"function-name":"org.junit.runners.ParentRunner.access$100","line":66,"source-code":"b1cc1675-df0c-4bda-9ec2-cc50d02b7497"},{"function-name":"org.junit.runners.ParentRunner$2.evaluate","line":293,"source-code":"bbf3d67c-a184-49ee-b0d5-b02188e3fa30"},{"function-name":"org.junit.runners.ParentRunner$3.evaluate","line":306,"source-code":"61876082-acce-458e-8248-bfb03dc2b340"},{"function-name":"org.junit.runners.ParentRunner.run","line":413,"source-code":"4d79837a-1751-47e1-a134-d883871a9cec"},{"function-name":"org.junit.runner.JUnitCore.run","line":137,"source-code":"0a88f8a1-60c0-41a0-a95c-d75de5a4c82d"},{"function-name":"org.junit.runner.JUnitCore.run","line":115,"source-code":"351d6b15-5d61-4a8a-9a06-5b14bf071945"},{"function-name":"androidx.test.internal.runner.TestExecutor.execute","line":67,"source-code":"76276ba5-69ae-4815-8a9c-77525b526cb1"},{"function-name":"androidx.test.internal.runner.TestExecutor.execute","line":58,"source-code":"9ae72a6b-31be-435f-8a52-461f043b492b"},{"function-name":"androidx.test.runner.AndroidJUnitRunner.onStart","line":446,"source-code":"a4ef001f-1238-4b6e-9e57-aaa3dc1717ce"},{"function-name":"android.app.Instrumentation$InstrumentationThread.run","line":2205,"source-code":"a67eccc1-bd1c-4207-93a5-db20e09b79aa"}]},"binder:8909_1":{"fault":false,"name":"binder:8909_1","stack":[]},"heaptaskdaemon":{"fault":false,"name":"heaptaskdaemon","stack":[]},"binder:8909_2":{"fault":false,"name":"binder:8909_2","stack":[]}},"timestamp":1707253867,"uuid":"8e68b676-21cb-4cc8-ac2e-32a60e8d29c1"} \ No newline at end of file diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceReportDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceReportDeserializer.java index 7bc8aaed..617fd3f7 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceReportDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceReportDeserializer.java @@ -74,20 +74,12 @@ public Exception getException(JSONObject obj) { return this.exceptionDeserializer.deserialize(obj); // TODO: fix usage } - public Map getAttributes(JSONObject obj) { + public Map getAttributes(JSONObject obj) throws JSONException { if (obj == null) { return null; } - Map result = new HashMap<>(); - - Iterator attributesKeys = obj.keys(); - while (attributesKeys.hasNext()) { - String key = attributesKeys.next(); - result.put(key, obj.optString(key)); - } - - return result; + return MapDeserializer.toMap(obj); // TODO: check exception } public List getAttachmentList(JSONArray array) { @@ -104,28 +96,12 @@ public List getAttachmentList(JSONArray array) { return result; } - public List getDiagnosticStack(JSONArray obj) { - if (obj == null) { + public List getDiagnosticStack(JSONArray array) { + if (array == null) { return null; } - List result = new ArrayList<>(); - for (int i = 0; i < obj.length(); i++) { - JSONObject stackItem = obj.optJSONObject(i); - if (stackItem != null) { - try { - result.add(this.stackFrameDeserializer.deserialize(stackItem)); - } catch (Exception e) { - // TODO: handle - } - BacktraceStackFrame stackFrame = new BacktraceStackFrame(); - stackFrame.functionName = stackItem.optString("function-name"); - stackFrame.line = stackItem.optInt("line"); - stackFrame.sourceCode = stackItem.optString("source-code"); - result.add(stackFrame); - } - } - - return result; + GenericListDeserializer deserializer = new GenericListDeserializer<>(); + return deserializer.deserialize(array, this.stackFrameDeserializer); } } diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/GenericListDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/GenericListDeserializer.java new file mode 100644 index 00000000..edc42192 --- /dev/null +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/GenericListDeserializer.java @@ -0,0 +1,26 @@ +package backtraceio.library.common.serializers.deserializers; + +import org.json.JSONArray; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.List; + +import backtraceio.library.models.BacktraceStackFrame; + +public class GenericListDeserializer { + List deserialize(JSONArray array, Deserializable deserializer) { + List result = new ArrayList(); + for (int i = 0; i < array.length(); i++) { + JSONObject obj = array.optJSONObject(i); + if (obj != null) { + try { + result.add(deserializer.deserialize(obj)); + } catch (Exception e) { + // TODO: handle + } + } + } + return result; + } +} diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ThreadInformationDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ThreadInformationDeserializer.java index 3639c1fd..84f67fab 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ThreadInformationDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ThreadInformationDeserializer.java @@ -14,13 +14,17 @@ public class ThreadInformationDeserializer implements Deserializable { private final FieldNameLoader fieldNameLoader = new FieldNameLoader(ThreadInformation.class); // TODO: maybe we can reuse it - + final BacktraceStackFrameDeserializer stackFrameDeserializer; static class Fields { final static String name = "name"; final static String fault = "fault"; final static String stack = "stack"; } + public ThreadInformationDeserializer() { + this.stackFrameDeserializer = new BacktraceStackFrameDeserializer(); + } + public ThreadInformation deserialize(JSONObject obj) throws JSONException { return new ThreadInformation( obj.optString(fieldNameLoader.get(Fields.name), null), // TODO: fallback warning @@ -28,22 +32,12 @@ public ThreadInformation deserialize(JSONObject obj) throws JSONException { getBacktraceStackFrameList(obj.optJSONArray(fieldNameLoader.get(Fields.stack)))); } - public List getBacktraceStackFrameList(JSONArray jsonArray) { - if (jsonArray == null) { + public List getBacktraceStackFrameList(JSONArray array) { + if (array == null) { return null; // todo: Check if we should return empty or null } - final List result = new ArrayList<>(); - - final BacktraceStackFrameDeserializer deserializer = new BacktraceStackFrameDeserializer(); // TODO: check how to resolve it - for (int idx = 0; idx < jsonArray.length(); idx++) { - try { - JSONObject obj = (JSONObject) jsonArray.get(idx); - result.add(deserializer.deserialize(obj)); - } catch (Exception ex) { - // TODO: handle - } - } - return result; + GenericListDeserializer deserializer = new GenericListDeserializer<>(); + return deserializer.deserialize(array, this.stackFrameDeserializer); } } diff --git a/backtrace-library/src/test/java/backtraceio/library/BacktraceDataDeserializerTest.java b/backtrace-library/src/test/java/backtraceio/library/BacktraceDataDeserializerTest.java index 12eaaf14..337a0a87 100644 --- a/backtrace-library/src/test/java/backtraceio/library/BacktraceDataDeserializerTest.java +++ b/backtrace-library/src/test/java/backtraceio/library/BacktraceDataDeserializerTest.java @@ -2,20 +2,26 @@ 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.json.JSONObject; import org.junit.Test; +import java.util.Map; + import backtraceio.library.common.serializers.BacktraceDeserializer; import backtraceio.library.models.BacktraceData; +import backtraceio.library.models.json.SourceCode; +import backtraceio.library.models.json.ThreadInformation; public class BacktraceDataDeserializerTest { @Test public void deserializeBacktraceData() throws JSONException { // GIVEN - final String backtraceDataJson = "{\"agent\":\"backtrace-android\",\"agent-version\":\"3.7.12-8-3686709-org-json-serializer\",\"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\",\"PATH\":\"/product/bin:/apex/com.android.runtime/bin:/apex/com.android.art/bin:/system_ext/bin:/system/bin:/system/xbin:/odm/bin:/vendor/bin:/vendor/xbin\",\"ANDROID_SOCKET_zygote\":\"17\",\"ANDROID_I18N_ROOT\":\"/apex/com.android.i18n\",\"ANDROID_DATA\":\"/data\",\"ASEC_MOUNTPOINT\":\"/mnt/asec\",\"ANDROID_TZDATA_ROOT\":\"/apex/com.android.tzdata\",\"EXTERNAL_STORAGE\":\"/sdcard\",\"ANDROID_BOOTLOGO\":\"1\",\"ANDROID_ASSETS\":\"/system/app\",\"ANDROID_STORAGE\":\"/storage\",\"DEX2OATBOOTCLASSPATH\":\"/apex/com.android.art/javalib/core-oj.jar:/apex/com.android.art/javalib/core-libart.jar:/apex/com.android.art/javalib/core-icu4j.jar:/apex/com.android.art/javalib/okhttp.jar:/apex/com.android.art/javalib/bouncycastle.jar:/apex/com.android.art/javalib/apache-xml.jar:/system/framework/framework.jar:/system/framework/ext.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/framework-atb-backward-compatibility.jar\",\"ANDROID_ART_ROOT\":\"/apex/com.android.art\",\"ANDROID_ROOT\":\"/system\",\"DOWNLOAD_CACHE\":\"/data/cache\",\"BOOTCLASSPATH\":\"/apex/com.android.art/javalib/core-oj.jar:/apex/com.android.art/javalib/core-libart.jar:/apex/com.android.art/javalib/core-icu4j.jar:/apex/com.android.art/javalib/okhttp.jar:/apex/com.android.art/javalib/bouncycastle.jar:/apex/com.android.art/javalib/apache-xml.jar:/system/framework/framework.jar:/system/framework/ext.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/framework-atb-backward-compatibility.jar:/apex/com.android.conscrypt/javalib/conscrypt.jar:/apex/com.android.media/javalib/updatable-media.jar:/apex/com.android.mediaprovider/javalib/framework-mediaprovider.jar:/apex/com.android.os.statsd/javalib/framework-statsd.jar:/apex/com.android.permission/javalib/framework-permission.jar:/apex/com.android.sdkext/javalib/framework-sdkextensions.jar:/apex/com.android.wifi/javalib/framework-wifi.jar:/apex/com.android.tethering/javalib/framework-tethering.jar\",\"ANDROID_SOCKET_usap_pool_primary\":\"21\"},\"Exception\":{\"message\":\"Example test string\"}},\"attributes\":{\"application.session\":\"fd86372a-457d-4347-b1af-34779f86f520\",\"device.nfc.status\":\"NotAvailable\",\"device.cpu.temperature\":\"0.0\",\"system.memory.active\":\"1094905856\",\"device.wifi.status\":\"Enabled\",\"screen.height\":\"1834\",\"uname.machine\":\"i686\",\"screen.dpi\":\"288\",\"device.bluetooth_status\":\"NotPermitted\",\"device.airplane_mode\":\"false\",\"system.memory.total\":\"2077347840\",\"device.sdk\":\"30\",\"device.brand\":\"google\",\"uname.sysname\":\"Android\",\"cpu.boottime\":\"1707253373829\",\"device.os_version\":\"5.4.61-android11-0-00791-gbad091cc4bf3-ab6833933\",\"device.gps.enabled\":\"Enabled\",\"application.package\":\"backtraceio.library.test\",\"uname.version\":\"11\",\"backtrace.version\":\"3.7.12-8-3686709-org-json-serializer\",\"device.is_power_saving_mode\":\"false\",\"screen.orientation\":\"Portrait\",\"device.manufacturer\":\"Google\",\"system.memory.free\":\"982441984\",\"battery.state\":\"Unplugged\",\"backtrace.agent\":\"backtrace-android\",\"error.type\":\"Message\",\"device.location\":\"Enabled\",\"application\":\"backtraceio.library.test\",\"error.message\":\"Example test string\",\"culture\":\"English\",\"device.model\":\"sdk_gphone_x86\",\"screen.width\":\"1080\",\"build.type\":\"Debug\",\"device.product\":\"sdk_gphone_x86\",\"guid\":\"e4c57699-0dc9-35e2-b4a0-2ffff1925ca7\",\"app.storage_used\":\"2974528\",\"battery.level\":\"1.0\",\"screen.brightness\":\"102\"},\"lang\":\"java\",\"lang-version\":\"0\",\"main-thread\":\"instr: androidx.test.runner.androidjunitrunner\",\"source-code\":{\"5ad3ea57-08bc-42b9-a0af-4c0b63abd5d7\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":331},\"e1c31c4a-9f5f-4aae-8f74-29c5f7398e4d\":{\"source-code-file-name\":\"AndroidJUnit4.java\",\"start-line\":162},\"0a88f8a1-60c0-41a0-a95c-d75de5a4c82d\":{\"source-code-file-name\":\"JUnitCore.java\",\"start-line\":137},\"b1cc1675-df0c-4bda-9ec2-cc50d02b7497\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":66},\"6237d391-f50f-49b7-a029-dc8533521a39\":{\"source-code-file-name\":\"BlockJUnit4ClassRunner.java\",\"start-line\":100},\"24d96335-14d8-45d8-a07d-fc24bc56d4db\":{\"source-code-file-name\":\"Suite.java\",\"start-line\":128},\"9b765b76-8714-4dc2-8584-c58e57d0b97d\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":79},\"0952a91a-0c4b-45f2-93c7-e744a7e64ded\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":306},\"86deee3a-0e5f-495b-af66-5b2f36964ca2\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":79},\"bbf3d67c-a184-49ee-b0d5-b02188e3fa30\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":293},\"a70079ba-1646-4dda-ae17-7a92bf584c69\":{\"source-code-file-name\":\"ReflectiveCallable.java\",\"start-line\":12},\"61876082-acce-458e-8248-bfb03dc2b340\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":306},\"cfe92970-ae80-45b4-9dd4-8099919a1c26\":{\"source-code-file-name\":\"Suite.java\",\"start-line\":27},\"a4ef001f-1238-4b6e-9e57-aaa3dc1717ce\":{\"source-code-file-name\":\"AndroidJUnitRunner.java\",\"start-line\":446},\"6e8a4d01-3519-4742-be84-34da0dac2460\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":413},\"42aefc9a-50aa-40e9-ac4e-483c279cd9dc\":{\"source-code-file-name\":\"Method.java\"},\"56847938-10cc-4e20-98e2-521ce93ebe70\":{\"source-code-file-name\":\"VMStack.java\"},\"86086e43-f1de-49c0-aeda-3ae2be530407\":{\"source-code-file-name\":\"FrameworkMethod.java\",\"start-line\":59},\"ecc0e91a-52b3-48e7-b509-a850f49652c1\":{\"source-code-file-name\":\"RunBefores.java\",\"start-line\":80},\"673561af-72d1-4294-8f73-cca30446e70e\":{\"source-code-file-name\":\"BlockJUnit4ClassRunner.java\",\"start-line\":103},\"88ac7e2c-c331-4249-910d-519a6d25363f\":{\"source-code-file-name\":\"BlockJUnit4ClassRunner.java\",\"start-line\":63},\"ea2aa6d0-8e27-402d-8836-9ede35629ac9\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":66},\"4d79837a-1751-47e1-a134-d883871a9cec\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":413},\"7787b022-3043-4976-9dde-990443b50b24\":{\"source-code-file-name\":\"FrameworkMethod.java\",\"start-line\":56},\"5ed2c2aa-38a0-42ed-8f05-9131c4c72e90\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":366},\"e7bd36c2-dd6a-4bb3-bac5-e5e606490c71\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":329},\"ddf80aac-8ae4-42cc-9d35-5dae41fbf626\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":329},\"2980dbe3-ee88-486c-8442-9b6816dfe07a\":{\"source-code-file-name\":\"RunAfters.java\",\"start-line\":61},\"351d6b15-5d61-4a8a-9a06-5b14bf071945\":{\"source-code-file-name\":\"JUnitCore.java\",\"start-line\":115},\"2172b7fe-e8cf-4ffa-936b-c6efb52694bb\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":331},\"9ae72a6b-31be-435f-8a52-461f043b492b\":{\"source-code-file-name\":\"TestExecutor.java\",\"start-line\":58},\"a67eccc1-bd1c-4207-93a5-db20e09b79aa\":{\"source-code-file-name\":\"Instrumentation.java\",\"start-line\":2205},\"76276ba5-69ae-4815-8a9c-77525b526cb1\":{\"source-code-file-name\":\"TestExecutor.java\",\"start-line\":67},\"23444a66-f715-444f-afcb-f367a6f72689\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":293},\"1cfc3859-cf21-4d84-ba61-d73d9ee73c41\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":306},\"653bad70-8157-49d4-8894-8bb089f76722\":{\"source-code-file-name\":\"Thread.java\",\"start-line\":1736},\"84649fde-1055-4085-a52e-52c35811cbde\":{\"source-code-file-name\":\"InvokeMethod.java\",\"start-line\":17}},\"thread-information-map\":{\"profile saver\":{\"fault\":false,\"name\":\"profile saver\",\"stack\":[]},\"finalizerwatchdogdaemon\":{\"fault\":false,\"name\":\"finalizerwatchdogdaemon\",\"stack\":[{\"function-name\":\"java.lang.Object.wait\",\"source-code\":\"b778a593-508f-444d-ab62-77d1ea5506c5\"},{\"function-name\":\"java.lang.Object.wait\",\"line\":442,\"source-code\":\"567b0437-8d29-4cc2-9274-819c056179a9\"},{\"function-name\":\"java.lang.Object.wait\",\"line\":568,\"source-code\":\"d07089b6-e586-4cde-ab31-3d0d1740ae25\"},{\"function-name\":\"java.lang.Daemons$FinalizerWatchdogDaemon.sleepUntilNeeded\",\"line\":341,\"source-code\":\"5aa512c3-e353-4309-9613-f3175bc05c56\"},{\"function-name\":\"java.lang.Daemons$FinalizerWatchdogDaemon.runInternal\",\"line\":321,\"source-code\":\"a8fb461e-e7b9-4259-b16f-8e9610884d2a\"},{\"function-name\":\"java.lang.Daemons$Daemon.run\",\"line\":139,\"source-code\":\"100f945a-c9ed-42d4-a396-bfb1c9c09e32\"},{\"function-name\":\"java.lang.Thread.run\",\"line\":923,\"source-code\":\"ba65711d-9470-4cdc-a06a-32db7ce84db9\"}]},\"signal catcher\":{\"fault\":false,\"name\":\"signal catcher\",\"stack\":[]},\"timer-0\":{\"fault\":false,\"name\":\"timer-0\",\"stack\":[{\"function-name\":\"java.lang.Object.wait\",\"source-code\":\"dbfe3cc6-8ac5-4a8c-b4c2-3c4073e563c7\"},{\"function-name\":\"java.lang.Object.wait\",\"line\":442,\"source-code\":\"ce872d4e-20a7-4991-9ae6-b0c09ff728f1\"},{\"function-name\":\"java.util.TimerThread.mainLoop\",\"line\":559,\"source-code\":\"507a2ca3-1e70-492a-9a75-cb95073c44a0\"},{\"function-name\":\"java.util.TimerThread.run\",\"line\":512,\"source-code\":\"06908da9-ce73-4835-b1e3-5fb732fcf82e\"}]},\"main\":{\"fault\":false,\"name\":\"main\",\"stack\":[{\"function-name\":\"android.os.MessageQueue.nativePollOnce\",\"source-code\":\"30ad9a05-28af-4db8-8ee6-35d55cc85ca5\"},{\"function-name\":\"android.os.MessageQueue.next\",\"line\":335,\"source-code\":\"58e043c1-b6f0-47ee-a5ea-af64153bd38b\"},{\"function-name\":\"android.os.Looper.loop\",\"line\":183,\"source-code\":\"9718f15f-0010-4e8f-8012-a5c48b554a9f\"},{\"function-name\":\"android.app.ActivityThread.main\",\"line\":7656,\"source-code\":\"4cc5b61d-3403-4a03-8a69-63adbcc55511\"},{\"function-name\":\"java.lang.reflect.Method.invoke\",\"source-code\":\"23078e7a-df17-4655-bad5-48b90baedba9\"},{\"function-name\":\"com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run\",\"line\":592,\"source-code\":\"cc45db4a-ec38-49d9-b5f6-14b804362ccd\"},{\"function-name\":\"com.android.internal.os.ZygoteInit.main\",\"line\":947,\"source-code\":\"406194e7-76b8-4b8f-977c-21756313f648\"}]},\"finalizerdaemon\":{\"fault\":false,\"name\":\"finalizerdaemon\",\"stack\":[{\"function-name\":\"java.lang.Object.wait\",\"source-code\":\"daff552e-1ac1-4417-9b77-fd91b3a664fc\"},{\"function-name\":\"java.lang.Object.wait\",\"line\":442,\"source-code\":\"d1445680-d522-46d4-ae3a-b2daeda6de3d\"},{\"function-name\":\"java.lang.ref.ReferenceQueue.remove\",\"line\":190,\"source-code\":\"260f72cf-3b32-48ff-9722-af6280876415\"},{\"function-name\":\"java.lang.ref.ReferenceQueue.remove\",\"line\":211,\"source-code\":\"e951fdfd-cde7-49f2-926b-4e131544d4d4\"},{\"function-name\":\"java.lang.Daemons$FinalizerDaemon.runInternal\",\"line\":273,\"source-code\":\"4f2ac4ed-051c-4a1c-a94d-999809f38ea6\"},{\"function-name\":\"java.lang.Daemons$Daemon.run\",\"line\":139,\"source-code\":\"d2d21d80-5047-4c37-abe5-cb0e854c555a\"},{\"function-name\":\"java.lang.Thread.run\",\"line\":923,\"source-code\":\"ceeb7b8e-7b5c-4d65-9c80-7c8e02a12202\"}]},\"referencequeuedaemon\":{\"fault\":false,\"name\":\"referencequeuedaemon\",\"stack\":[{\"function-name\":\"java.lang.Object.wait\",\"source-code\":\"d569fd77-fec0-4abd-b746-1e43394a8ca1\"},{\"function-name\":\"java.lang.Object.wait\",\"line\":442,\"source-code\":\"29bee7cd-cda4-4cd0-b7b6-1b21c40f3ee5\"},{\"function-name\":\"java.lang.Object.wait\",\"line\":568,\"source-code\":\"4b73fe34-9a92-4b11-a391-fa60086a62b4\"},{\"function-name\":\"java.lang.Daemons$ReferenceQueueDaemon.runInternal\",\"line\":217,\"source-code\":\"e76abece-43e7-48a0-a429-f13b75282fdd\"},{\"function-name\":\"java.lang.Daemons$Daemon.run\",\"line\":139,\"source-code\":\"08d8fd2b-8d9e-4317-ad68-3031de5f429f\"},{\"function-name\":\"java.lang.Thread.run\",\"line\":923,\"source-code\":\"8509b640-6470-4894-a896-7794e917c270\"}]},\"binder:8909_3\":{\"fault\":false,\"name\":\"binder:8909_3\",\"stack\":[]},\"jit thread pool worker thread 0\":{\"fault\":false,\"name\":\"jit thread pool worker thread 0\",\"stack\":[]},\"instrumentationconnectionthread\":{\"fault\":false,\"name\":\"instrumentationconnectionthread\",\"stack\":[{\"function-name\":\"android.os.MessageQueue.nativePollOnce\",\"source-code\":\"2699757c-16bd-4853-8d48-ad23aeebf5ad\"},{\"function-name\":\"android.os.MessageQueue.next\",\"line\":335,\"source-code\":\"bf1a4cc2-55ee-43c3-83a0-8780eeece1ce\"},{\"function-name\":\"android.os.Looper.loop\",\"line\":183,\"source-code\":\"2e0184c2-dd7e-41b6-946a-a646896cb880\"},{\"function-name\":\"android.os.HandlerThread.run\",\"line\":67,\"source-code\":\"209e3b61-b3f2-4de5-b8e3-6d832e969ce9\"}]},\"instr: androidx.test.runner.androidjunitrunner\":{\"fault\":true,\"name\":\"instr: androidx.test.runner.androidjunitrunner\",\"stack\":[{\"function-name\":\"dalvik.system.VMStack.getThreadStackTrace\",\"source-code\":\"56847938-10cc-4e20-98e2-521ce93ebe70\"},{\"function-name\":\"java.lang.Thread.getStackTrace\",\"line\":1736,\"source-code\":\"653bad70-8157-49d4-8894-8bb089f76722\"},{\"function-name\":\"java.lang.reflect.Method.invoke\",\"source-code\":\"42aefc9a-50aa-40e9-ac4e-483c279cd9dc\"},{\"function-name\":\"org.junit.runners.model.FrameworkMethod$1.runReflectiveCall\",\"line\":59,\"source-code\":\"86086e43-f1de-49c0-aeda-3ae2be530407\"},{\"function-name\":\"org.junit.internal.runners.model.ReflectiveCallable.run\",\"line\":12,\"source-code\":\"a70079ba-1646-4dda-ae17-7a92bf584c69\"},{\"function-name\":\"org.junit.runners.model.FrameworkMethod.invokeExplosively\",\"line\":56,\"source-code\":\"7787b022-3043-4976-9dde-990443b50b24\"},{\"function-name\":\"org.junit.internal.runners.statements.InvokeMethod.evaluate\",\"line\":17,\"source-code\":\"84649fde-1055-4085-a52e-52c35811cbde\"},{\"function-name\":\"androidx.test.internal.runner.junit4.statement.RunBefores.evaluate\",\"line\":80,\"source-code\":\"ecc0e91a-52b3-48e7-b509-a850f49652c1\"},{\"function-name\":\"androidx.test.internal.runner.junit4.statement.RunAfters.evaluate\",\"line\":61,\"source-code\":\"2980dbe3-ee88-486c-8442-9b6816dfe07a\"},{\"function-name\":\"org.junit.runners.ParentRunner$3.evaluate\",\"line\":306,\"source-code\":\"1cfc3859-cf21-4d84-ba61-d73d9ee73c41\"},{\"function-name\":\"org.junit.runners.BlockJUnit4ClassRunner$1.evaluate\",\"line\":100,\"source-code\":\"6237d391-f50f-49b7-a029-dc8533521a39\"},{\"function-name\":\"org.junit.runners.ParentRunner.runLeaf\",\"line\":366,\"source-code\":\"5ed2c2aa-38a0-42ed-8f05-9131c4c72e90\"},{\"function-name\":\"org.junit.runners.BlockJUnit4ClassRunner.runChild\",\"line\":103,\"source-code\":\"673561af-72d1-4294-8f73-cca30446e70e\"},{\"function-name\":\"org.junit.runners.BlockJUnit4ClassRunner.runChild\",\"line\":63,\"source-code\":\"88ac7e2c-c331-4249-910d-519a6d25363f\"},{\"function-name\":\"org.junit.runners.ParentRunner$4.run\",\"line\":331,\"source-code\":\"2172b7fe-e8cf-4ffa-936b-c6efb52694bb\"},{\"function-name\":\"org.junit.runners.ParentRunner$1.schedule\",\"line\":79,\"source-code\":\"86deee3a-0e5f-495b-af66-5b2f36964ca2\"},{\"function-name\":\"org.junit.runners.ParentRunner.runChildren\",\"line\":329,\"source-code\":\"e7bd36c2-dd6a-4bb3-bac5-e5e606490c71\"},{\"function-name\":\"org.junit.runners.ParentRunner.access$100\",\"line\":66,\"source-code\":\"ea2aa6d0-8e27-402d-8836-9ede35629ac9\"},{\"function-name\":\"org.junit.runners.ParentRunner$2.evaluate\",\"line\":293,\"source-code\":\"23444a66-f715-444f-afcb-f367a6f72689\"},{\"function-name\":\"org.junit.runners.ParentRunner$3.evaluate\",\"line\":306,\"source-code\":\"0952a91a-0c4b-45f2-93c7-e744a7e64ded\"},{\"function-name\":\"org.junit.runners.ParentRunner.run\",\"line\":413,\"source-code\":\"6e8a4d01-3519-4742-be84-34da0dac2460\"},{\"function-name\":\"androidx.test.ext.junit.runners.AndroidJUnit4.run\",\"line\":162,\"source-code\":\"e1c31c4a-9f5f-4aae-8f74-29c5f7398e4d\"},{\"function-name\":\"org.junit.runners.Suite.runChild\",\"line\":128,\"source-code\":\"24d96335-14d8-45d8-a07d-fc24bc56d4db\"},{\"function-name\":\"org.junit.runners.Suite.runChild\",\"line\":27,\"source-code\":\"cfe92970-ae80-45b4-9dd4-8099919a1c26\"},{\"function-name\":\"org.junit.runners.ParentRunner$4.run\",\"line\":331,\"source-code\":\"5ad3ea57-08bc-42b9-a0af-4c0b63abd5d7\"},{\"function-name\":\"org.junit.runners.ParentRunner$1.schedule\",\"line\":79,\"source-code\":\"9b765b76-8714-4dc2-8584-c58e57d0b97d\"},{\"function-name\":\"org.junit.runners.ParentRunner.runChildren\",\"line\":329,\"source-code\":\"ddf80aac-8ae4-42cc-9d35-5dae41fbf626\"},{\"function-name\":\"org.junit.runners.ParentRunner.access$100\",\"line\":66,\"source-code\":\"b1cc1675-df0c-4bda-9ec2-cc50d02b7497\"},{\"function-name\":\"org.junit.runners.ParentRunner$2.evaluate\",\"line\":293,\"source-code\":\"bbf3d67c-a184-49ee-b0d5-b02188e3fa30\"},{\"function-name\":\"org.junit.runners.ParentRunner$3.evaluate\",\"line\":306,\"source-code\":\"61876082-acce-458e-8248-bfb03dc2b340\"},{\"function-name\":\"org.junit.runners.ParentRunner.run\",\"line\":413,\"source-code\":\"4d79837a-1751-47e1-a134-d883871a9cec\"},{\"function-name\":\"org.junit.runner.JUnitCore.run\",\"line\":137,\"source-code\":\"0a88f8a1-60c0-41a0-a95c-d75de5a4c82d\"},{\"function-name\":\"org.junit.runner.JUnitCore.run\",\"line\":115,\"source-code\":\"351d6b15-5d61-4a8a-9a06-5b14bf071945\"},{\"function-name\":\"androidx.test.internal.runner.TestExecutor.execute\",\"line\":67,\"source-code\":\"76276ba5-69ae-4815-8a9c-77525b526cb1\"},{\"function-name\":\"androidx.test.internal.runner.TestExecutor.execute\",\"line\":58,\"source-code\":\"9ae72a6b-31be-435f-8a52-461f043b492b\"},{\"function-name\":\"androidx.test.runner.AndroidJUnitRunner.onStart\",\"line\":446,\"source-code\":\"a4ef001f-1238-4b6e-9e57-aaa3dc1717ce\"},{\"function-name\":\"android.app.Instrumentation$InstrumentationThread.run\",\"line\":2205,\"source-code\":\"a67eccc1-bd1c-4207-93a5-db20e09b79aa\"}]},\"binder:8909_1\":{\"fault\":false,\"name\":\"binder:8909_1\",\"stack\":[]},\"heaptaskdaemon\":{\"fault\":false,\"name\":\"heaptaskdaemon\",\"stack\":[]},\"binder:8909_2\":{\"fault\":false,\"name\":\"binder:8909_2\",\"stack\":[]}},\"timestamp\":1707253867,\"uuid\":\"8e68b676-21cb-4cc8-ac2e-32a60e8d29c1\"}"; + final String backtraceDataJson = "{\"agent\":\"backtrace-android\",\"agentVersion\":\"3.7.12-8-3686709-org-json-serializer\",\"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\",\"PATH\":\"/product/bin:/apex/com.android.runtime/bin:/apex/com.android.art/bin:/system_ext/bin:/system/bin:/system/xbin:/odm/bin:/vendor/bin:/vendor/xbin\",\"ANDROID_SOCKET_zygote\":\"17\",\"ANDROID_I18N_ROOT\":\"/apex/com.android.i18n\",\"ANDROID_DATA\":\"/data\",\"ASEC_MOUNTPOINT\":\"/mnt/asec\",\"ANDROID_TZDATA_ROOT\":\"/apex/com.android.tzdata\",\"EXTERNAL_STORAGE\":\"/sdcard\",\"ANDROID_BOOTLOGO\":\"1\",\"ANDROID_ASSETS\":\"/system/app\",\"ANDROID_STORAGE\":\"/storage\",\"DEX2OATBOOTCLASSPATH\":\"/apex/com.android.art/javalib/core-oj.jar:/apex/com.android.art/javalib/core-libart.jar:/apex/com.android.art/javalib/core-icu4j.jar:/apex/com.android.art/javalib/okhttp.jar:/apex/com.android.art/javalib/bouncycastle.jar:/apex/com.android.art/javalib/apache-xml.jar:/system/framework/framework.jar:/system/framework/ext.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/framework-atb-backward-compatibility.jar\",\"ANDROID_ART_ROOT\":\"/apex/com.android.art\",\"ANDROID_ROOT\":\"/system\",\"DOWNLOAD_CACHE\":\"/data/cache\",\"BOOTCLASSPATH\":\"/apex/com.android.art/javalib/core-oj.jar:/apex/com.android.art/javalib/core-libart.jar:/apex/com.android.art/javalib/core-icu4j.jar:/apex/com.android.art/javalib/okhttp.jar:/apex/com.android.art/javalib/bouncycastle.jar:/apex/com.android.art/javalib/apache-xml.jar:/system/framework/framework.jar:/system/framework/ext.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/framework-atb-backward-compatibility.jar:/apex/com.android.conscrypt/javalib/conscrypt.jar:/apex/com.android.media/javalib/updatable-media.jar:/apex/com.android.mediaprovider/javalib/framework-mediaprovider.jar:/apex/com.android.os.statsd/javalib/framework-statsd.jar:/apex/com.android.permission/javalib/framework-permission.jar:/apex/com.android.sdkext/javalib/framework-sdkextensions.jar:/apex/com.android.wifi/javalib/framework-wifi.jar:/apex/com.android.tethering/javalib/framework-tethering.jar\",\"ANDROID_SOCKET_usap_pool_primary\":\"21\"},\"Exception\":{\"message\":\"Example test string\"}},\"attributes\":{\"application.session\":\"fd86372a-457d-4347-b1af-34779f86f520\",\"device.nfc.status\":\"NotAvailable\",\"device.cpu.temperature\":\"0.0\",\"system.memory.active\":\"1094905856\",\"device.wifi.status\":\"Enabled\",\"screen.height\":\"1834\",\"uname.machine\":\"i686\",\"screen.dpi\":\"288\",\"device.bluetooth_status\":\"NotPermitted\",\"device.airplane_mode\":\"false\",\"system.memory.total\":\"2077347840\",\"device.sdk\":\"30\",\"device.brand\":\"google\",\"uname.sysname\":\"Android\",\"cpu.boottime\":\"1707253373829\",\"device.os_version\":\"5.4.61-android11-0-00791-gbad091cc4bf3-ab6833933\",\"device.gps.enabled\":\"Enabled\",\"application.package\":\"backtraceio.library.test\",\"uname.version\":\"11\",\"backtrace.version\":\"3.7.12-8-3686709-org-json-serializer\",\"device.is_power_saving_mode\":\"false\",\"screen.orientation\":\"Portrait\",\"device.manufacturer\":\"Google\",\"system.memory.free\":\"982441984\",\"battery.state\":\"Unplugged\",\"backtrace.agent\":\"backtrace-android\",\"error.type\":\"Message\",\"device.location\":\"Enabled\",\"application\":\"backtraceio.library.test\",\"error.message\":\"Example test string\",\"culture\":\"English\",\"device.model\":\"sdk_gphone_x86\",\"screen.width\":\"1080\",\"build.type\":\"Debug\",\"device.product\":\"sdk_gphone_x86\",\"guid\":\"e4c57699-0dc9-35e2-b4a0-2ffff1925ca7\",\"app.storage_used\":\"2974528\",\"battery.level\":\"1.0\",\"screen.brightness\":\"102\"},\"lang\":\"java\",\"langVersion\":\"0\",\"mainThread\":\"instr: androidx.test.runner.androidjunitrunner\",\"sourceCode\":{\"5ad3ea57-08bc-42b9-a0af-4c0b63abd5d7\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":331},\"e1c31c4a-9f5f-4aae-8f74-29c5f7398e4d\":{\"source-code-file-name\":\"AndroidJUnit4.java\",\"start-line\":162},\"0a88f8a1-60c0-41a0-a95c-d75de5a4c82d\":{\"source-code-file-name\":\"JUnitCore.java\",\"start-line\":137},\"b1cc1675-df0c-4bda-9ec2-cc50d02b7497\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":66},\"6237d391-f50f-49b7-a029-dc8533521a39\":{\"source-code-file-name\":\"BlockJUnit4ClassRunner.java\",\"start-line\":100},\"24d96335-14d8-45d8-a07d-fc24bc56d4db\":{\"source-code-file-name\":\"Suite.java\",\"start-line\":128},\"9b765b76-8714-4dc2-8584-c58e57d0b97d\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":79},\"0952a91a-0c4b-45f2-93c7-e744a7e64ded\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":306},\"86deee3a-0e5f-495b-af66-5b2f36964ca2\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":79},\"bbf3d67c-a184-49ee-b0d5-b02188e3fa30\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":293},\"a70079ba-1646-4dda-ae17-7a92bf584c69\":{\"source-code-file-name\":\"ReflectiveCallable.java\",\"start-line\":12},\"61876082-acce-458e-8248-bfb03dc2b340\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":306},\"cfe92970-ae80-45b4-9dd4-8099919a1c26\":{\"source-code-file-name\":\"Suite.java\",\"start-line\":27},\"a4ef001f-1238-4b6e-9e57-aaa3dc1717ce\":{\"source-code-file-name\":\"AndroidJUnitRunner.java\",\"start-line\":446},\"6e8a4d01-3519-4742-be84-34da0dac2460\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":413},\"42aefc9a-50aa-40e9-ac4e-483c279cd9dc\":{\"source-code-file-name\":\"Method.java\"},\"56847938-10cc-4e20-98e2-521ce93ebe70\":{\"source-code-file-name\":\"VMStack.java\"},\"86086e43-f1de-49c0-aeda-3ae2be530407\":{\"source-code-file-name\":\"FrameworkMethod.java\",\"start-line\":59},\"ecc0e91a-52b3-48e7-b509-a850f49652c1\":{\"source-code-file-name\":\"RunBefores.java\",\"start-line\":80},\"673561af-72d1-4294-8f73-cca30446e70e\":{\"source-code-file-name\":\"BlockJUnit4ClassRunner.java\",\"start-line\":103},\"88ac7e2c-c331-4249-910d-519a6d25363f\":{\"source-code-file-name\":\"BlockJUnit4ClassRunner.java\",\"start-line\":63},\"ea2aa6d0-8e27-402d-8836-9ede35629ac9\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":66},\"4d79837a-1751-47e1-a134-d883871a9cec\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":413},\"7787b022-3043-4976-9dde-990443b50b24\":{\"source-code-file-name\":\"FrameworkMethod.java\",\"start-line\":56},\"5ed2c2aa-38a0-42ed-8f05-9131c4c72e90\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":366},\"e7bd36c2-dd6a-4bb3-bac5-e5e606490c71\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":329},\"ddf80aac-8ae4-42cc-9d35-5dae41fbf626\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":329},\"2980dbe3-ee88-486c-8442-9b6816dfe07a\":{\"source-code-file-name\":\"RunAfters.java\",\"start-line\":61},\"351d6b15-5d61-4a8a-9a06-5b14bf071945\":{\"source-code-file-name\":\"JUnitCore.java\",\"start-line\":115},\"2172b7fe-e8cf-4ffa-936b-c6efb52694bb\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":331},\"9ae72a6b-31be-435f-8a52-461f043b492b\":{\"source-code-file-name\":\"TestExecutor.java\",\"start-line\":58},\"a67eccc1-bd1c-4207-93a5-db20e09b79aa\":{\"source-code-file-name\":\"Instrumentation.java\",\"start-line\":2205},\"76276ba5-69ae-4815-8a9c-77525b526cb1\":{\"source-code-file-name\":\"TestExecutor.java\",\"start-line\":67},\"23444a66-f715-444f-afcb-f367a6f72689\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":293},\"1cfc3859-cf21-4d84-ba61-d73d9ee73c41\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":306},\"653bad70-8157-49d4-8894-8bb089f76722\":{\"source-code-file-name\":\"Thread.java\",\"start-line\":1736},\"84649fde-1055-4085-a52e-52c35811cbde\":{\"source-code-file-name\":\"InvokeMethod.java\",\"start-line\":17}},\"threadInformation-map\":{\"profile saver\":{\"fault\":false,\"name\":\"profile saver\",\"stack\":[]},\"finalizerwatchdogdaemon\":{\"fault\":false,\"name\":\"finalizerwatchdogdaemon\",\"stack\":[{\"function-name\":\"java.lang.Object.wait\",\"source-code\":\"b778a593-508f-444d-ab62-77d1ea5506c5\"},{\"function-name\":\"java.lang.Object.wait\",\"line\":442,\"source-code\":\"567b0437-8d29-4cc2-9274-819c056179a9\"},{\"function-name\":\"java.lang.Object.wait\",\"line\":568,\"source-code\":\"d07089b6-e586-4cde-ab31-3d0d1740ae25\"},{\"function-name\":\"java.lang.Daemons$FinalizerWatchdogDaemon.sleepUntilNeeded\",\"line\":341,\"source-code\":\"5aa512c3-e353-4309-9613-f3175bc05c56\"},{\"function-name\":\"java.lang.Daemons$FinalizerWatchdogDaemon.runInternal\",\"line\":321,\"source-code\":\"a8fb461e-e7b9-4259-b16f-8e9610884d2a\"},{\"function-name\":\"java.lang.Daemons$Daemon.run\",\"line\":139,\"source-code\":\"100f945a-c9ed-42d4-a396-bfb1c9c09e32\"},{\"function-name\":\"java.lang.Thread.run\",\"line\":923,\"source-code\":\"ba65711d-9470-4cdc-a06a-32db7ce84db9\"}]},\"signal catcher\":{\"fault\":false,\"name\":\"signal catcher\",\"stack\":[]},\"timer-0\":{\"fault\":false,\"name\":\"timer-0\",\"stack\":[{\"function-name\":\"java.lang.Object.wait\",\"source-code\":\"dbfe3cc6-8ac5-4a8c-b4c2-3c4073e563c7\"},{\"function-name\":\"java.lang.Object.wait\",\"line\":442,\"source-code\":\"ce872d4e-20a7-4991-9ae6-b0c09ff728f1\"},{\"function-name\":\"java.util.TimerThread.mainLoop\",\"line\":559,\"source-code\":\"507a2ca3-1e70-492a-9a75-cb95073c44a0\"},{\"function-name\":\"java.util.TimerThread.run\",\"line\":512,\"source-code\":\"06908da9-ce73-4835-b1e3-5fb732fcf82e\"}]},\"main\":{\"fault\":false,\"name\":\"main\",\"stack\":[{\"function-name\":\"android.os.MessageQueue.nativePollOnce\",\"source-code\":\"30ad9a05-28af-4db8-8ee6-35d55cc85ca5\"},{\"function-name\":\"android.os.MessageQueue.next\",\"line\":335,\"source-code\":\"58e043c1-b6f0-47ee-a5ea-af64153bd38b\"},{\"function-name\":\"android.os.Looper.loop\",\"line\":183,\"source-code\":\"9718f15f-0010-4e8f-8012-a5c48b554a9f\"},{\"function-name\":\"android.app.ActivityThread.main\",\"line\":7656,\"source-code\":\"4cc5b61d-3403-4a03-8a69-63adbcc55511\"},{\"function-name\":\"java.lang.reflect.Method.invoke\",\"source-code\":\"23078e7a-df17-4655-bad5-48b90baedba9\"},{\"function-name\":\"com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run\",\"line\":592,\"source-code\":\"cc45db4a-ec38-49d9-b5f6-14b804362ccd\"},{\"function-name\":\"com.android.internal.os.ZygoteInit.main\",\"line\":947,\"source-code\":\"406194e7-76b8-4b8f-977c-21756313f648\"}]},\"finalizerdaemon\":{\"fault\":false,\"name\":\"finalizerdaemon\",\"stack\":[{\"function-name\":\"java.lang.Object.wait\",\"source-code\":\"daff552e-1ac1-4417-9b77-fd91b3a664fc\"},{\"function-name\":\"java.lang.Object.wait\",\"line\":442,\"source-code\":\"d1445680-d522-46d4-ae3a-b2daeda6de3d\"},{\"function-name\":\"java.lang.ref.ReferenceQueue.remove\",\"line\":190,\"source-code\":\"260f72cf-3b32-48ff-9722-af6280876415\"},{\"function-name\":\"java.lang.ref.ReferenceQueue.remove\",\"line\":211,\"source-code\":\"e951fdfd-cde7-49f2-926b-4e131544d4d4\"},{\"function-name\":\"java.lang.Daemons$FinalizerDaemon.runInternal\",\"line\":273,\"source-code\":\"4f2ac4ed-051c-4a1c-a94d-999809f38ea6\"},{\"function-name\":\"java.lang.Daemons$Daemon.run\",\"line\":139,\"source-code\":\"d2d21d80-5047-4c37-abe5-cb0e854c555a\"},{\"function-name\":\"java.lang.Thread.run\",\"line\":923,\"source-code\":\"ceeb7b8e-7b5c-4d65-9c80-7c8e02a12202\"}]},\"referencequeuedaemon\":{\"fault\":false,\"name\":\"referencequeuedaemon\",\"stack\":[{\"function-name\":\"java.lang.Object.wait\",\"source-code\":\"d569fd77-fec0-4abd-b746-1e43394a8ca1\"},{\"function-name\":\"java.lang.Object.wait\",\"line\":442,\"source-code\":\"29bee7cd-cda4-4cd0-b7b6-1b21c40f3ee5\"},{\"function-name\":\"java.lang.Object.wait\",\"line\":568,\"source-code\":\"4b73fe34-9a92-4b11-a391-fa60086a62b4\"},{\"function-name\":\"java.lang.Daemons$ReferenceQueueDaemon.runInternal\",\"line\":217,\"source-code\":\"e76abece-43e7-48a0-a429-f13b75282fdd\"},{\"function-name\":\"java.lang.Daemons$Daemon.run\",\"line\":139,\"source-code\":\"08d8fd2b-8d9e-4317-ad68-3031de5f429f\"},{\"function-name\":\"java.lang.Thread.run\",\"line\":923,\"source-code\":\"8509b640-6470-4894-a896-7794e917c270\"}]},\"binder:8909_3\":{\"fault\":false,\"name\":\"binder:8909_3\",\"stack\":[]},\"jit thread pool worker thread 0\":{\"fault\":false,\"name\":\"jit thread pool worker thread 0\",\"stack\":[]},\"instrumentationconnectionthread\":{\"fault\":false,\"name\":\"instrumentationconnectionthread\",\"stack\":[{\"function-name\":\"android.os.MessageQueue.nativePollOnce\",\"source-code\":\"2699757c-16bd-4853-8d48-ad23aeebf5ad\"},{\"function-name\":\"android.os.MessageQueue.next\",\"line\":335,\"source-code\":\"bf1a4cc2-55ee-43c3-83a0-8780eeece1ce\"},{\"function-name\":\"android.os.Looper.loop\",\"line\":183,\"source-code\":\"2e0184c2-dd7e-41b6-946a-a646896cb880\"},{\"function-name\":\"android.os.HandlerThread.run\",\"line\":67,\"source-code\":\"209e3b61-b3f2-4de5-b8e3-6d832e969ce9\"}]},\"instr: androidx.test.runner.androidjunitrunner\":{\"fault\":true,\"name\":\"instr: androidx.test.runner.androidjunitrunner\",\"stack\":[{\"function-name\":\"dalvik.system.VMStack.getThreadStackTrace\",\"source-code\":\"56847938-10cc-4e20-98e2-521ce93ebe70\"},{\"function-name\":\"java.lang.Thread.getStackTrace\",\"line\":1736,\"source-code\":\"653bad70-8157-49d4-8894-8bb089f76722\"},{\"function-name\":\"java.lang.reflect.Method.invoke\",\"source-code\":\"42aefc9a-50aa-40e9-ac4e-483c279cd9dc\"},{\"function-name\":\"org.junit.runners.model.FrameworkMethod$1.runReflectiveCall\",\"line\":59,\"source-code\":\"86086e43-f1de-49c0-aeda-3ae2be530407\"},{\"function-name\":\"org.junit.internal.runners.model.ReflectiveCallable.run\",\"line\":12,\"source-code\":\"a70079ba-1646-4dda-ae17-7a92bf584c69\"},{\"function-name\":\"org.junit.runners.model.FrameworkMethod.invokeExplosively\",\"line\":56,\"source-code\":\"7787b022-3043-4976-9dde-990443b50b24\"},{\"function-name\":\"org.junit.internal.runners.statements.InvokeMethod.evaluate\",\"line\":17,\"source-code\":\"84649fde-1055-4085-a52e-52c35811cbde\"},{\"function-name\":\"androidx.test.internal.runner.junit4.statement.RunBefores.evaluate\",\"line\":80,\"source-code\":\"ecc0e91a-52b3-48e7-b509-a850f49652c1\"},{\"function-name\":\"androidx.test.internal.runner.junit4.statement.RunAfters.evaluate\",\"line\":61,\"source-code\":\"2980dbe3-ee88-486c-8442-9b6816dfe07a\"},{\"function-name\":\"org.junit.runners.ParentRunner$3.evaluate\",\"line\":306,\"source-code\":\"1cfc3859-cf21-4d84-ba61-d73d9ee73c41\"},{\"function-name\":\"org.junit.runners.BlockJUnit4ClassRunner$1.evaluate\",\"line\":100,\"source-code\":\"6237d391-f50f-49b7-a029-dc8533521a39\"},{\"function-name\":\"org.junit.runners.ParentRunner.runLeaf\",\"line\":366,\"source-code\":\"5ed2c2aa-38a0-42ed-8f05-9131c4c72e90\"},{\"function-name\":\"org.junit.runners.BlockJUnit4ClassRunner.runChild\",\"line\":103,\"source-code\":\"673561af-72d1-4294-8f73-cca30446e70e\"},{\"function-name\":\"org.junit.runners.BlockJUnit4ClassRunner.runChild\",\"line\":63,\"source-code\":\"88ac7e2c-c331-4249-910d-519a6d25363f\"},{\"function-name\":\"org.junit.runners.ParentRunner$4.run\",\"line\":331,\"source-code\":\"2172b7fe-e8cf-4ffa-936b-c6efb52694bb\"},{\"function-name\":\"org.junit.runners.ParentRunner$1.schedule\",\"line\":79,\"source-code\":\"86deee3a-0e5f-495b-af66-5b2f36964ca2\"},{\"function-name\":\"org.junit.runners.ParentRunner.runChildren\",\"line\":329,\"source-code\":\"e7bd36c2-dd6a-4bb3-bac5-e5e606490c71\"},{\"function-name\":\"org.junit.runners.ParentRunner.access$100\",\"line\":66,\"source-code\":\"ea2aa6d0-8e27-402d-8836-9ede35629ac9\"},{\"function-name\":\"org.junit.runners.ParentRunner$2.evaluate\",\"line\":293,\"source-code\":\"23444a66-f715-444f-afcb-f367a6f72689\"},{\"function-name\":\"org.junit.runners.ParentRunner$3.evaluate\",\"line\":306,\"source-code\":\"0952a91a-0c4b-45f2-93c7-e744a7e64ded\"},{\"function-name\":\"org.junit.runners.ParentRunner.run\",\"line\":413,\"source-code\":\"6e8a4d01-3519-4742-be84-34da0dac2460\"},{\"function-name\":\"androidx.test.ext.junit.runners.AndroidJUnit4.run\",\"line\":162,\"source-code\":\"e1c31c4a-9f5f-4aae-8f74-29c5f7398e4d\"},{\"function-name\":\"org.junit.runners.Suite.runChild\",\"line\":128,\"source-code\":\"24d96335-14d8-45d8-a07d-fc24bc56d4db\"},{\"function-name\":\"org.junit.runners.Suite.runChild\",\"line\":27,\"source-code\":\"cfe92970-ae80-45b4-9dd4-8099919a1c26\"},{\"function-name\":\"org.junit.runners.ParentRunner$4.run\",\"line\":331,\"source-code\":\"5ad3ea57-08bc-42b9-a0af-4c0b63abd5d7\"},{\"function-name\":\"org.junit.runners.ParentRunner$1.schedule\",\"line\":79,\"source-code\":\"9b765b76-8714-4dc2-8584-c58e57d0b97d\"},{\"function-name\":\"org.junit.runners.ParentRunner.runChildren\",\"line\":329,\"source-code\":\"ddf80aac-8ae4-42cc-9d35-5dae41fbf626\"},{\"function-name\":\"org.junit.runners.ParentRunner.access$100\",\"line\":66,\"source-code\":\"b1cc1675-df0c-4bda-9ec2-cc50d02b7497\"},{\"function-name\":\"org.junit.runners.ParentRunner$2.evaluate\",\"line\":293,\"source-code\":\"bbf3d67c-a184-49ee-b0d5-b02188e3fa30\"},{\"function-name\":\"org.junit.runners.ParentRunner$3.evaluate\",\"line\":306,\"source-code\":\"61876082-acce-458e-8248-bfb03dc2b340\"},{\"function-name\":\"org.junit.runners.ParentRunner.run\",\"line\":413,\"source-code\":\"4d79837a-1751-47e1-a134-d883871a9cec\"},{\"function-name\":\"org.junit.runner.JUnitCore.run\",\"line\":137,\"source-code\":\"0a88f8a1-60c0-41a0-a95c-d75de5a4c82d\"},{\"function-name\":\"org.junit.runner.JUnitCore.run\",\"line\":115,\"source-code\":\"351d6b15-5d61-4a8a-9a06-5b14bf071945\"},{\"function-name\":\"androidx.test.internal.runner.TestExecutor.execute\",\"line\":67,\"source-code\":\"76276ba5-69ae-4815-8a9c-77525b526cb1\"},{\"function-name\":\"androidx.test.internal.runner.TestExecutor.execute\",\"line\":58,\"source-code\":\"9ae72a6b-31be-435f-8a52-461f043b492b\"},{\"function-name\":\"androidx.test.runner.AndroidJUnitRunner.onStart\",\"line\":446,\"source-code\":\"a4ef001f-1238-4b6e-9e57-aaa3dc1717ce\"},{\"function-name\":\"android.app.Instrumentation$InstrumentationThread.run\",\"line\":2205,\"source-code\":\"a67eccc1-bd1c-4207-93a5-db20e09b79aa\"}]},\"binder:8909_1\":{\"fault\":false,\"name\":\"binder:8909_1\",\"stack\":[]},\"heaptaskdaemon\":{\"fault\":false,\"name\":\"heaptaskdaemon\",\"stack\":[]},\"binder:8909_2\":{\"fault\":false,\"name\":\"binder:8909_2\",\"stack\":[]}},\"timestamp\":1707253867,\"uuid\":\"8e68b676-21cb-4cc8-ac2e-32a60e8d29c1\"}"; // WHEN final BacktraceData result = BacktraceDeserializer.deserialize(new JSONObject(backtraceDataJson), BacktraceData.class); @@ -23,17 +29,37 @@ public void deserializeBacktraceData() throws JSONException { // THEN assertNotNull(result); assertEquals("8e68b676-21cb-4cc8-ac2e-32a60e8d29c1", result.uuid); - assertEquals("backtrace-android", result.agent); - assertEquals("3.7.12-8-3686709-org-json-serializer", result.agentVersion); assertEquals("java", result.lang); - assertEquals("0", result.langVersion); + assertEquals("backtrace-android", result.agent); + assertEquals("", result.symbolication); // TODO: check assertEquals(1707253867, result.timestamp); + assertEquals("0", result.langVersion); + assertEquals("3.7.12-8-3686709-org-json-serializer", result.agentVersion); assertEquals("instr: androidx.test.runner.androidjunitrunner", result.mainThread); + assertEquals(0, result.classifiers.length); + assertNull(result.report); + // THEN Attributes + assertEquals(result.attributes.size(), 39); + assertEquals(result.attributes.get("application"), "backtraceio.library.test"); + assertEquals(result.attributes.get("error.type"), "Message"); + // THEN Annotations + assertEquals(2, result.annotations.size()); + assertEquals("Example test string", ((Map) result.annotations.get("Exception")).get("message")); + assertNotNull(result.annotations.get("Environment Variables")); + // THEN Source Code + assertEquals(result.sourceCode.size(), 37); + SourceCode firstSourceCode = result.sourceCode.get("5ad3ea57-08bc-42b9-a0af-4c0b63abd5d7"); + + assertEquals(firstSourceCode.sourceCodeFileName, "ParentRunner.java"); + assertEquals(firstSourceCode.startLine.intValue(), 331); - // TODO: -// assertEquals("", result.annotations); -// assertEquals("", result.attributes); -// assertEquals("", result.sourceCode); -// assertEquals("", result.getThreadInformationMap()); + assertEquals(result.sourceCode.get(0), 37); +// assertEquals(); + // THEN Thread informations + assertEquals(result.getThreadInformationMap().size(), 14); + ThreadInformation threadInformation = result.getThreadInformationMap().get(13); + assertEquals(threadInformation.getFault(), ""); + assertEquals(threadInformation.getName(), ""); + assertEquals(threadInformation.getStack(), ""); } } diff --git a/backtrace-library/src/test/java/backtraceio/library/ConcatAttributesUnitTest.java b/backtrace-library/src/test/java/backtraceio/library/ConcatAttributesUnitTest.java index 9c19b6b9..36b8f1bb 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"); } From 83781e81bf70d4ee5d402ead0fbd0875d8d84d0e Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 6 Mar 2024 00:55:38 +0100 Subject: [PATCH 033/100] Fix backtrace data deserialization --- .../androidTest/resources/backtraceData.json | 1 - .../src/androidTest/resources/sample.json | 1016 ----------------- .../BacktraceDataDeserializer.java | 4 +- .../BacktraceStackFrameDeserializer.java | 4 +- .../library/models/BacktraceStackFrame.java | 4 +- .../BacktraceDataDeserializerTest.java | 50 +- .../java/backtraceio/library/TestUtils.java | 29 + .../src/test/resources/backtraceData.json | 1 + .../src/test/resources/backtraceReport.json | 1 + .../resources/backtraceResult.error.json | 0 .../resources/backtraceResult.json | 0 11 files changed, 66 insertions(+), 1044 deletions(-) delete mode 100644 backtrace-library/src/androidTest/resources/backtraceData.json delete mode 100644 backtrace-library/src/androidTest/resources/sample.json create mode 100644 backtrace-library/src/test/java/backtraceio/library/TestUtils.java create mode 100644 backtrace-library/src/test/resources/backtraceData.json create mode 100644 backtrace-library/src/test/resources/backtraceReport.json rename backtrace-library/src/{androidTest => test}/resources/backtraceResult.error.json (100%) rename backtrace-library/src/{androidTest => test}/resources/backtraceResult.json (100%) diff --git a/backtrace-library/src/androidTest/resources/backtraceData.json b/backtrace-library/src/androidTest/resources/backtraceData.json deleted file mode 100644 index c4d29bf4..00000000 --- a/backtrace-library/src/androidTest/resources/backtraceData.json +++ /dev/null @@ -1 +0,0 @@ -{"agent":"backtrace-android","agent-version":"3.7.12-8-3686709-org-json-serializer","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","PATH":"/product/bin:/apex/com.android.runtime/bin:/apex/com.android.art/bin:/system_ext/bin:/system/bin:/system/xbin:/odm/bin:/vendor/bin:/vendor/xbin","ANDROID_SOCKET_zygote":"17","ANDROID_I18N_ROOT":"/apex/com.android.i18n","ANDROID_DATA":"/data","ASEC_MOUNTPOINT":"/mnt/asec","ANDROID_TZDATA_ROOT":"/apex/com.android.tzdata","EXTERNAL_STORAGE":"/sdcard","ANDROID_BOOTLOGO":"1","ANDROID_ASSETS":"/system/app","ANDROID_STORAGE":"/storage","DEX2OATBOOTCLASSPATH":"/apex/com.android.art/javalib/core-oj.jar:/apex/com.android.art/javalib/core-libart.jar:/apex/com.android.art/javalib/core-icu4j.jar:/apex/com.android.art/javalib/okhttp.jar:/apex/com.android.art/javalib/bouncycastle.jar:/apex/com.android.art/javalib/apache-xml.jar:/system/framework/framework.jar:/system/framework/ext.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/framework-atb-backward-compatibility.jar","ANDROID_ART_ROOT":"/apex/com.android.art","ANDROID_ROOT":"/system","DOWNLOAD_CACHE":"/data/cache","BOOTCLASSPATH":"/apex/com.android.art/javalib/core-oj.jar:/apex/com.android.art/javalib/core-libart.jar:/apex/com.android.art/javalib/core-icu4j.jar:/apex/com.android.art/javalib/okhttp.jar:/apex/com.android.art/javalib/bouncycastle.jar:/apex/com.android.art/javalib/apache-xml.jar:/system/framework/framework.jar:/system/framework/ext.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/framework-atb-backward-compatibility.jar:/apex/com.android.conscrypt/javalib/conscrypt.jar:/apex/com.android.media/javalib/updatable-media.jar:/apex/com.android.mediaprovider/javalib/framework-mediaprovider.jar:/apex/com.android.os.statsd/javalib/framework-statsd.jar:/apex/com.android.permission/javalib/framework-permission.jar:/apex/com.android.sdkext/javalib/framework-sdkextensions.jar:/apex/com.android.wifi/javalib/framework-wifi.jar:/apex/com.android.tethering/javalib/framework-tethering.jar","ANDROID_SOCKET_usap_pool_primary":"21"},"Exception":{"message":"Example test string"}},"attributes":{"application.session":"fd86372a-457d-4347-b1af-34779f86f520","device.nfc.status":"NotAvailable","device.cpu.temperature":"0.0","system.memory.active":"1094905856","device.wifi.status":"Enabled","screen.height":"1834","uname.machine":"i686","screen.dpi":"288","device.bluetooth_status":"NotPermitted","device.airplane_mode":"false","system.memory.total":"2077347840","device.sdk":"30","device.brand":"google","uname.sysname":"Android","cpu.boottime":"1707253373829","device.os_version":"5.4.61-android11-0-00791-gbad091cc4bf3-ab6833933","device.gps.enabled":"Enabled","application.package":"backtraceio.library.test","uname.version":"11","backtrace.version":"3.7.12-8-3686709-org-json-serializer","device.is_power_saving_mode":"false","screen.orientation":"Portrait","device.manufacturer":"Google","system.memory.free":"982441984","battery.state":"Unplugged","backtrace.agent":"backtrace-android","error.type":"Message","device.location":"Enabled","application":"backtraceio.library.test","error.message":"Example test string","culture":"English","device.model":"sdk_gphone_x86","screen.width":"1080","build.type":"Debug","device.product":"sdk_gphone_x86","guid":"e4c57699-0dc9-35e2-b4a0-2ffff1925ca7","app.storage_used":"2974528","battery.level":"1.0","screen.brightness":"102"},"lang":"java","lang-version":"0","main-thread":"instr: androidx.test.runner.androidjunitrunner","source-code":{"5ad3ea57-08bc-42b9-a0af-4c0b63abd5d7":{"source-code-file-name":"ParentRunner.java","start-line":331},"e1c31c4a-9f5f-4aae-8f74-29c5f7398e4d":{"source-code-file-name":"AndroidJUnit4.java","start-line":162},"0a88f8a1-60c0-41a0-a95c-d75de5a4c82d":{"source-code-file-name":"JUnitCore.java","start-line":137},"b1cc1675-df0c-4bda-9ec2-cc50d02b7497":{"source-code-file-name":"ParentRunner.java","start-line":66},"6237d391-f50f-49b7-a029-dc8533521a39":{"source-code-file-name":"BlockJUnit4ClassRunner.java","start-line":100},"24d96335-14d8-45d8-a07d-fc24bc56d4db":{"source-code-file-name":"Suite.java","start-line":128},"9b765b76-8714-4dc2-8584-c58e57d0b97d":{"source-code-file-name":"ParentRunner.java","start-line":79},"0952a91a-0c4b-45f2-93c7-e744a7e64ded":{"source-code-file-name":"ParentRunner.java","start-line":306},"86deee3a-0e5f-495b-af66-5b2f36964ca2":{"source-code-file-name":"ParentRunner.java","start-line":79},"bbf3d67c-a184-49ee-b0d5-b02188e3fa30":{"source-code-file-name":"ParentRunner.java","start-line":293},"a70079ba-1646-4dda-ae17-7a92bf584c69":{"source-code-file-name":"ReflectiveCallable.java","start-line":12},"61876082-acce-458e-8248-bfb03dc2b340":{"source-code-file-name":"ParentRunner.java","start-line":306},"cfe92970-ae80-45b4-9dd4-8099919a1c26":{"source-code-file-name":"Suite.java","start-line":27},"a4ef001f-1238-4b6e-9e57-aaa3dc1717ce":{"source-code-file-name":"AndroidJUnitRunner.java","start-line":446},"6e8a4d01-3519-4742-be84-34da0dac2460":{"source-code-file-name":"ParentRunner.java","start-line":413},"42aefc9a-50aa-40e9-ac4e-483c279cd9dc":{"source-code-file-name":"Method.java"},"56847938-10cc-4e20-98e2-521ce93ebe70":{"source-code-file-name":"VMStack.java"},"86086e43-f1de-49c0-aeda-3ae2be530407":{"source-code-file-name":"FrameworkMethod.java","start-line":59},"ecc0e91a-52b3-48e7-b509-a850f49652c1":{"source-code-file-name":"RunBefores.java","start-line":80},"673561af-72d1-4294-8f73-cca30446e70e":{"source-code-file-name":"BlockJUnit4ClassRunner.java","start-line":103},"88ac7e2c-c331-4249-910d-519a6d25363f":{"source-code-file-name":"BlockJUnit4ClassRunner.java","start-line":63},"ea2aa6d0-8e27-402d-8836-9ede35629ac9":{"source-code-file-name":"ParentRunner.java","start-line":66},"4d79837a-1751-47e1-a134-d883871a9cec":{"source-code-file-name":"ParentRunner.java","start-line":413},"7787b022-3043-4976-9dde-990443b50b24":{"source-code-file-name":"FrameworkMethod.java","start-line":56},"5ed2c2aa-38a0-42ed-8f05-9131c4c72e90":{"source-code-file-name":"ParentRunner.java","start-line":366},"e7bd36c2-dd6a-4bb3-bac5-e5e606490c71":{"source-code-file-name":"ParentRunner.java","start-line":329},"ddf80aac-8ae4-42cc-9d35-5dae41fbf626":{"source-code-file-name":"ParentRunner.java","start-line":329},"2980dbe3-ee88-486c-8442-9b6816dfe07a":{"source-code-file-name":"RunAfters.java","start-line":61},"351d6b15-5d61-4a8a-9a06-5b14bf071945":{"source-code-file-name":"JUnitCore.java","start-line":115},"2172b7fe-e8cf-4ffa-936b-c6efb52694bb":{"source-code-file-name":"ParentRunner.java","start-line":331},"9ae72a6b-31be-435f-8a52-461f043b492b":{"source-code-file-name":"TestExecutor.java","start-line":58},"a67eccc1-bd1c-4207-93a5-db20e09b79aa":{"source-code-file-name":"Instrumentation.java","start-line":2205},"76276ba5-69ae-4815-8a9c-77525b526cb1":{"source-code-file-name":"TestExecutor.java","start-line":67},"23444a66-f715-444f-afcb-f367a6f72689":{"source-code-file-name":"ParentRunner.java","start-line":293},"1cfc3859-cf21-4d84-ba61-d73d9ee73c41":{"source-code-file-name":"ParentRunner.java","start-line":306},"653bad70-8157-49d4-8894-8bb089f76722":{"source-code-file-name":"Thread.java","start-line":1736},"84649fde-1055-4085-a52e-52c35811cbde":{"source-code-file-name":"InvokeMethod.java","start-line":17}},"thread-information-map":{"profile saver":{"fault":false,"name":"profile saver","stack":[]},"finalizerwatchdogdaemon":{"fault":false,"name":"finalizerwatchdogdaemon","stack":[{"function-name":"java.lang.Object.wait","source-code":"b778a593-508f-444d-ab62-77d1ea5506c5"},{"function-name":"java.lang.Object.wait","line":442,"source-code":"567b0437-8d29-4cc2-9274-819c056179a9"},{"function-name":"java.lang.Object.wait","line":568,"source-code":"d07089b6-e586-4cde-ab31-3d0d1740ae25"},{"function-name":"java.lang.Daemons$FinalizerWatchdogDaemon.sleepUntilNeeded","line":341,"source-code":"5aa512c3-e353-4309-9613-f3175bc05c56"},{"function-name":"java.lang.Daemons$FinalizerWatchdogDaemon.runInternal","line":321,"source-code":"a8fb461e-e7b9-4259-b16f-8e9610884d2a"},{"function-name":"java.lang.Daemons$Daemon.run","line":139,"source-code":"100f945a-c9ed-42d4-a396-bfb1c9c09e32"},{"function-name":"java.lang.Thread.run","line":923,"source-code":"ba65711d-9470-4cdc-a06a-32db7ce84db9"}]},"signal catcher":{"fault":false,"name":"signal catcher","stack":[]},"timer-0":{"fault":false,"name":"timer-0","stack":[{"function-name":"java.lang.Object.wait","source-code":"dbfe3cc6-8ac5-4a8c-b4c2-3c4073e563c7"},{"function-name":"java.lang.Object.wait","line":442,"source-code":"ce872d4e-20a7-4991-9ae6-b0c09ff728f1"},{"function-name":"java.util.TimerThread.mainLoop","line":559,"source-code":"507a2ca3-1e70-492a-9a75-cb95073c44a0"},{"function-name":"java.util.TimerThread.run","line":512,"source-code":"06908da9-ce73-4835-b1e3-5fb732fcf82e"}]},"main":{"fault":false,"name":"main","stack":[{"function-name":"android.os.MessageQueue.nativePollOnce","source-code":"30ad9a05-28af-4db8-8ee6-35d55cc85ca5"},{"function-name":"android.os.MessageQueue.next","line":335,"source-code":"58e043c1-b6f0-47ee-a5ea-af64153bd38b"},{"function-name":"android.os.Looper.loop","line":183,"source-code":"9718f15f-0010-4e8f-8012-a5c48b554a9f"},{"function-name":"android.app.ActivityThread.main","line":7656,"source-code":"4cc5b61d-3403-4a03-8a69-63adbcc55511"},{"function-name":"java.lang.reflect.Method.invoke","source-code":"23078e7a-df17-4655-bad5-48b90baedba9"},{"function-name":"com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run","line":592,"source-code":"cc45db4a-ec38-49d9-b5f6-14b804362ccd"},{"function-name":"com.android.internal.os.ZygoteInit.main","line":947,"source-code":"406194e7-76b8-4b8f-977c-21756313f648"}]},"finalizerdaemon":{"fault":false,"name":"finalizerdaemon","stack":[{"function-name":"java.lang.Object.wait","source-code":"daff552e-1ac1-4417-9b77-fd91b3a664fc"},{"function-name":"java.lang.Object.wait","line":442,"source-code":"d1445680-d522-46d4-ae3a-b2daeda6de3d"},{"function-name":"java.lang.ref.ReferenceQueue.remove","line":190,"source-code":"260f72cf-3b32-48ff-9722-af6280876415"},{"function-name":"java.lang.ref.ReferenceQueue.remove","line":211,"source-code":"e951fdfd-cde7-49f2-926b-4e131544d4d4"},{"function-name":"java.lang.Daemons$FinalizerDaemon.runInternal","line":273,"source-code":"4f2ac4ed-051c-4a1c-a94d-999809f38ea6"},{"function-name":"java.lang.Daemons$Daemon.run","line":139,"source-code":"d2d21d80-5047-4c37-abe5-cb0e854c555a"},{"function-name":"java.lang.Thread.run","line":923,"source-code":"ceeb7b8e-7b5c-4d65-9c80-7c8e02a12202"}]},"referencequeuedaemon":{"fault":false,"name":"referencequeuedaemon","stack":[{"function-name":"java.lang.Object.wait","source-code":"d569fd77-fec0-4abd-b746-1e43394a8ca1"},{"function-name":"java.lang.Object.wait","line":442,"source-code":"29bee7cd-cda4-4cd0-b7b6-1b21c40f3ee5"},{"function-name":"java.lang.Object.wait","line":568,"source-code":"4b73fe34-9a92-4b11-a391-fa60086a62b4"},{"function-name":"java.lang.Daemons$ReferenceQueueDaemon.runInternal","line":217,"source-code":"e76abece-43e7-48a0-a429-f13b75282fdd"},{"function-name":"java.lang.Daemons$Daemon.run","line":139,"source-code":"08d8fd2b-8d9e-4317-ad68-3031de5f429f"},{"function-name":"java.lang.Thread.run","line":923,"source-code":"8509b640-6470-4894-a896-7794e917c270"}]},"binder:8909_3":{"fault":false,"name":"binder:8909_3","stack":[]},"jit thread pool worker thread 0":{"fault":false,"name":"jit thread pool worker thread 0","stack":[]},"instrumentationconnectionthread":{"fault":false,"name":"instrumentationconnectionthread","stack":[{"function-name":"android.os.MessageQueue.nativePollOnce","source-code":"2699757c-16bd-4853-8d48-ad23aeebf5ad"},{"function-name":"android.os.MessageQueue.next","line":335,"source-code":"bf1a4cc2-55ee-43c3-83a0-8780eeece1ce"},{"function-name":"android.os.Looper.loop","line":183,"source-code":"2e0184c2-dd7e-41b6-946a-a646896cb880"},{"function-name":"android.os.HandlerThread.run","line":67,"source-code":"209e3b61-b3f2-4de5-b8e3-6d832e969ce9"}]},"instr: androidx.test.runner.androidjunitrunner":{"fault":true,"name":"instr: androidx.test.runner.androidjunitrunner","stack":[{"function-name":"dalvik.system.VMStack.getThreadStackTrace","source-code":"56847938-10cc-4e20-98e2-521ce93ebe70"},{"function-name":"java.lang.Thread.getStackTrace","line":1736,"source-code":"653bad70-8157-49d4-8894-8bb089f76722"},{"function-name":"java.lang.reflect.Method.invoke","source-code":"42aefc9a-50aa-40e9-ac4e-483c279cd9dc"},{"function-name":"org.junit.runners.model.FrameworkMethod$1.runReflectiveCall","line":59,"source-code":"86086e43-f1de-49c0-aeda-3ae2be530407"},{"function-name":"org.junit.internal.runners.model.ReflectiveCallable.run","line":12,"source-code":"a70079ba-1646-4dda-ae17-7a92bf584c69"},{"function-name":"org.junit.runners.model.FrameworkMethod.invokeExplosively","line":56,"source-code":"7787b022-3043-4976-9dde-990443b50b24"},{"function-name":"org.junit.internal.runners.statements.InvokeMethod.evaluate","line":17,"source-code":"84649fde-1055-4085-a52e-52c35811cbde"},{"function-name":"androidx.test.internal.runner.junit4.statement.RunBefores.evaluate","line":80,"source-code":"ecc0e91a-52b3-48e7-b509-a850f49652c1"},{"function-name":"androidx.test.internal.runner.junit4.statement.RunAfters.evaluate","line":61,"source-code":"2980dbe3-ee88-486c-8442-9b6816dfe07a"},{"function-name":"org.junit.runners.ParentRunner$3.evaluate","line":306,"source-code":"1cfc3859-cf21-4d84-ba61-d73d9ee73c41"},{"function-name":"org.junit.runners.BlockJUnit4ClassRunner$1.evaluate","line":100,"source-code":"6237d391-f50f-49b7-a029-dc8533521a39"},{"function-name":"org.junit.runners.ParentRunner.runLeaf","line":366,"source-code":"5ed2c2aa-38a0-42ed-8f05-9131c4c72e90"},{"function-name":"org.junit.runners.BlockJUnit4ClassRunner.runChild","line":103,"source-code":"673561af-72d1-4294-8f73-cca30446e70e"},{"function-name":"org.junit.runners.BlockJUnit4ClassRunner.runChild","line":63,"source-code":"88ac7e2c-c331-4249-910d-519a6d25363f"},{"function-name":"org.junit.runners.ParentRunner$4.run","line":331,"source-code":"2172b7fe-e8cf-4ffa-936b-c6efb52694bb"},{"function-name":"org.junit.runners.ParentRunner$1.schedule","line":79,"source-code":"86deee3a-0e5f-495b-af66-5b2f36964ca2"},{"function-name":"org.junit.runners.ParentRunner.runChildren","line":329,"source-code":"e7bd36c2-dd6a-4bb3-bac5-e5e606490c71"},{"function-name":"org.junit.runners.ParentRunner.access$100","line":66,"source-code":"ea2aa6d0-8e27-402d-8836-9ede35629ac9"},{"function-name":"org.junit.runners.ParentRunner$2.evaluate","line":293,"source-code":"23444a66-f715-444f-afcb-f367a6f72689"},{"function-name":"org.junit.runners.ParentRunner$3.evaluate","line":306,"source-code":"0952a91a-0c4b-45f2-93c7-e744a7e64ded"},{"function-name":"org.junit.runners.ParentRunner.run","line":413,"source-code":"6e8a4d01-3519-4742-be84-34da0dac2460"},{"function-name":"androidx.test.ext.junit.runners.AndroidJUnit4.run","line":162,"source-code":"e1c31c4a-9f5f-4aae-8f74-29c5f7398e4d"},{"function-name":"org.junit.runners.Suite.runChild","line":128,"source-code":"24d96335-14d8-45d8-a07d-fc24bc56d4db"},{"function-name":"org.junit.runners.Suite.runChild","line":27,"source-code":"cfe92970-ae80-45b4-9dd4-8099919a1c26"},{"function-name":"org.junit.runners.ParentRunner$4.run","line":331,"source-code":"5ad3ea57-08bc-42b9-a0af-4c0b63abd5d7"},{"function-name":"org.junit.runners.ParentRunner$1.schedule","line":79,"source-code":"9b765b76-8714-4dc2-8584-c58e57d0b97d"},{"function-name":"org.junit.runners.ParentRunner.runChildren","line":329,"source-code":"ddf80aac-8ae4-42cc-9d35-5dae41fbf626"},{"function-name":"org.junit.runners.ParentRunner.access$100","line":66,"source-code":"b1cc1675-df0c-4bda-9ec2-cc50d02b7497"},{"function-name":"org.junit.runners.ParentRunner$2.evaluate","line":293,"source-code":"bbf3d67c-a184-49ee-b0d5-b02188e3fa30"},{"function-name":"org.junit.runners.ParentRunner$3.evaluate","line":306,"source-code":"61876082-acce-458e-8248-bfb03dc2b340"},{"function-name":"org.junit.runners.ParentRunner.run","line":413,"source-code":"4d79837a-1751-47e1-a134-d883871a9cec"},{"function-name":"org.junit.runner.JUnitCore.run","line":137,"source-code":"0a88f8a1-60c0-41a0-a95c-d75de5a4c82d"},{"function-name":"org.junit.runner.JUnitCore.run","line":115,"source-code":"351d6b15-5d61-4a8a-9a06-5b14bf071945"},{"function-name":"androidx.test.internal.runner.TestExecutor.execute","line":67,"source-code":"76276ba5-69ae-4815-8a9c-77525b526cb1"},{"function-name":"androidx.test.internal.runner.TestExecutor.execute","line":58,"source-code":"9ae72a6b-31be-435f-8a52-461f043b492b"},{"function-name":"androidx.test.runner.AndroidJUnitRunner.onStart","line":446,"source-code":"a4ef001f-1238-4b6e-9e57-aaa3dc1717ce"},{"function-name":"android.app.Instrumentation$InstrumentationThread.run","line":2205,"source-code":"a67eccc1-bd1c-4207-93a5-db20e09b79aa"}]},"binder:8909_1":{"fault":false,"name":"binder:8909_1","stack":[]},"heaptaskdaemon":{"fault":false,"name":"heaptaskdaemon","stack":[]},"binder:8909_2":{"fault":false,"name":"binder:8909_2","stack":[]}},"timestamp":1707253867,"uuid":"8e68b676-21cb-4cc8-ac2e-32a60e8d29c1"} \ No newline at end of file diff --git a/backtrace-library/src/androidTest/resources/sample.json b/backtrace-library/src/androidTest/resources/sample.json deleted file mode 100644 index b23fc1eb..00000000 --- a/backtrace-library/src/androidTest/resources/sample.json +++ /dev/null @@ -1,1016 +0,0 @@ -{ - "agent": "backtrace-android", - "agentVersion": "3.7.7-8-3f67d73-org-json-serializer", - "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", - "PATH": "/product/bin:/apex/com.android.runtime/bin:/apex/com.android.art/bin:/system_ext/bin:/system/bin:/system/xbin:/odm/bin:/vendor/bin:/vendor/xbin", - "ANDROID_SOCKET_zygote": "17", - "ANDROID_I18N_ROOT": "/apex/com.android.i18n", - "ANDROID_DATA": "/data", - "ASEC_MOUNTPOINT": "/mnt/asec", - "ANDROID_TZDATA_ROOT": "/apex/com.android.tzdata", - "EXTERNAL_STORAGE": "/sdcard", - "ANDROID_BOOTLOGO": "1", - "ANDROID_ASSETS": "/system/app", - "ANDROID_STORAGE": "/storage", - "DEX2OATBOOTCLASSPATH": "/apex/com.android.art/javalib/core-oj.jar:/apex/com.android.art/javalib/core-libart.jar:/apex/com.android.art/javalib/core-icu4j.jar:/apex/com.android.art/javalib/okhttp.jar:/apex/com.android.art/javalib/bouncycastle.jar:/apex/com.android.art/javalib/apache-xml.jar:/system/framework/framework.jar:/system/framework/ext.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/framework-atb-backward-compatibility.jar", - "ANDROID_ART_ROOT": "/apex/com.android.art", - "ANDROID_ROOT": "/system", - "DOWNLOAD_CACHE": "/data/cache", - "BOOTCLASSPATH": "/apex/com.android.art/javalib/core-oj.jar:/apex/com.android.art/javalib/core-libart.jar:/apex/com.android.art/javalib/core-icu4j.jar:/apex/com.android.art/javalib/okhttp.jar:/apex/com.android.art/javalib/bouncycastle.jar:/apex/com.android.art/javalib/apache-xml.jar:/system/framework/framework.jar:/system/framework/ext.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/framework-atb-backward-compatibility.jar:/apex/com.android.conscrypt/javalib/conscrypt.jar:/apex/com.android.media/javalib/updatable-media.jar:/apex/com.android.mediaprovider/javalib/framework-mediaprovider.jar:/apex/com.android.os.statsd/javalib/framework-statsd.jar:/apex/com.android.permission/javalib/framework-permission.jar:/apex/com.android.sdkext/javalib/framework-sdkextensions.jar:/apex/com.android.wifi/javalib/framework-wifi.jar:/apex/com.android.tethering/javalib/framework-tethering.jar", - "ANDROID_SOCKET_usap_pool_primary": "21" - }, - "string-key2": { - "detail-message": "test-error", - "stack-trace": [ - { - "declaring-class": "backtraceio.library.common.BacktraceDataSerializerTest", - "file-name": "BacktraceDataSerializerTest.java", - "line-number": 32, - "method-name": "testGsonSerializer" - }, - { - "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": "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 properties": { - "detail-message": "test-error", - "stack-trace": [ - { - "declaring-class": "backtraceio.library.common.BacktraceDataSerializerTest", - "file-name": "BacktraceDataSerializerTest.java", - "line-number": 32, - "method-name": "testGsonSerializer" - }, - { - "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": "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": { - "message": "test-error" - } - }, - "attributes": { - "device.nfc.status": "NotAvailable", - "device.cpu.temperature": "0.0", - "string-key": "string-value", - "system.memory.active": "1051795456", - "device.wifi.status": "Enabled", - "screen.height": "1834", - "uname.machine": "i686", - "screen.dpi": "288", - "device.bluetooth_status": "NotPermitted", - "device.airplane_mode": "false", - "classifier": "java.lang.Exception", - "system.memory.total": "2077347840", - "device.sdk": "30", - "device.brand": "google", - "uname.sysname": "Android", - "cpu.boottime": "1694978533765", - "device.os_version": "5.4.61-android11-0-00791-gbad091cc4bf3-ab6833933", - "device.gps.enabled": "Enabled", - "application.package": "backtraceio.library.test", - "uname.version": "11", - "backtrace.version": "3.7.7-8-3f67d73-org-json-serializer", - "device.is_power_saving_mode": "false", - "screen.orientation": "Portrait", - "device.manufacturer": "Google", - "system.memory.free": "1025556480", - "battery.state": "Unplugged", - "error.type": "Exception", - "device.location": "Enabled", - "application": "backtraceio.library.test", - "error.message": "test-error", - "culture": "English", - "device.model": "sdk_gphone_x86", - "screen.width": "1080", - "build.type": "Debug", - "device.product": "sdk_gphone_x86", - "guid": "e4c57699-0dc9-35e2-b4a0-2ffff1925ca7", - "app.storage_used": "2925368", - "battery.level": "1.0", - "screen.brightness": "102" - }, - "classifiers": [ - "java.lang.Exception" - ], - "lang": "java", - "langVersion": "0", - "mainThread": "instr: androidx.test.runner.androidjunitrunner", - "sourceCode": { - "def0b244-b5c3-4c68-9e4b-b5421888eee1": { - "path": "ParentRunner.java", - "startLine": 306 - }, - "8d478559-5a6f-412b-b854-3000e9adc98f": { - "path": "Suite.java", - "startLine": 128 - }, - "448f66cf-becf-4c83-9687-37eb9369a359": { - "path": "BlockJUnit4ClassRunner.java", - "startLine": 100 - }, - "bd559fdd-bd6f-44b6-a9b9-a14d865961d7": { - "path": "ParentRunner.java", - "startLine": 366 - }, - "e0eeb7ad-1024-4789-9fbe-4becb39e8420": { - "path": "ParentRunner.java", - "startLine": 413 - }, - "4e282390-371b-4af4-b117-29398510be3a": { - "path": "FrameworkMethod.java", - "startLine": 59 - }, - "0ca32861-e9bb-4dd2-a38b-76bdb0be09e8": { - "path": "ParentRunner.java", - "startLine": 293 - }, - "7aaec2ac-a43e-444b-b9ae-ad41ced28f33": { - "path": "ParentRunner.java", - "startLine": 413 - }, - "cb3283d2-d08f-4851-96fb-ec54aac63fd2": { - "path": "JUnitCore.java", - "startLine": 115 - }, - "d3a587b8-9d2c-4e70-9a0a-5a8257917d2d": { - "path": "Method.java" - }, - "4585edd4-5bf7-45e4-bb46-3f557b096852": { - "path": "FrameworkMethod.java", - "startLine": 56 - }, - "3e26748a-3965-4814-95a4-c474a701a15b": { - "path": "ParentRunner.java", - "startLine": 331 - }, - "d6321483-6dc8-4ae5-95e8-c34ca2bfb660": { - "path": "AndroidJUnit4.java", - "startLine": 162 - }, - "b8437309-6989-4316-ab70-925d6fbc5135": { - "path": "Instrumentation.java", - "startLine": 2205 - }, - "da3b40ad-d417-4f05-ae95-a7203478961d": { - "path": "ParentRunner.java", - "startLine": 329 - }, - "04520e56-5648-402d-99b5-434a8375e1b5": { - "path": "ParentRunner.java", - "startLine": 306 - }, - "dc715057-f108-4cc2-b4e8-f21aa2c4a75e": { - "path": "ParentRunner.java", - "startLine": 79 - }, - "ef921e3c-bbc6-4d1f-a8ac-e9dfcc2b3d90": { - "path": "ParentRunner.java", - "startLine": 79 - }, - "2068f2a4-9f0f-4854-bee9-cb398b7fd37f": { - "path": "ParentRunner.java", - "startLine": 331 - }, - "5e310bf1-ef77-449e-b523-bfb56d96cbc7": { - "path": "ParentRunner.java", - "startLine": 66 - }, - "3d9dcb46-6ac9-423e-8920-d0b5ec9c0f6d": { - "path": "BlockJUnit4ClassRunner.java", - "startLine": 63 - }, - "b47a8dd1-9c31-4793-805c-e33f9c77c818": { - "path": "Suite.java", - "startLine": 27 - }, - "2517e7f8-fcec-44eb-a37c-c144fd441837": { - "path": "AndroidJUnitRunner.java", - "startLine": 446 - }, - "2bf04cc1-bb1e-47e2-a11b-c4bdea625413": { - "path": "JUnitCore.java", - "startLine": 137 - }, - "295ccd27-4db2-487c-82f0-f255120cf593": { - "path": "ParentRunner.java", - "startLine": 306 - }, - "1ecb4287-1ad2-45a6-8450-af401cdbe17f": { - "path": "ReflectiveCallable.java", - "startLine": 12 - }, - "8ff34e56-9e08-4520-a87e-d7789785f013": { - "path": "TestExecutor.java", - "startLine": 67 - }, - "1549004b-d478-4341-87a2-4dea50ad031d": { - "path": "ParentRunner.java", - "startLine": 329 - }, - "5e3e29f7-7f77-4d4c-ae54-7a41caac90f4": { - "path": "ParentRunner.java", - "startLine": 293 - }, - "e9b5bfe9-f501-49c9-9621-02019e307488": { - "path": "InvokeMethod.java", - "startLine": 17 - }, - "a03637b1-a324-48e1-9b6f-06f030e2f3ba": { - "path": "ParentRunner.java", - "startLine": 66 - }, - "c6cf7f65-6407-4b51-91f0-76f223c36c62": { - "path": "BlockJUnit4ClassRunner.java", - "startLine": 103 - }, - "19b8ca48-b129-4503-99bc-da54738d3108": { - "path": "TestExecutor.java", - "startLine": 58 - } - }, - "threads": { - "profile saver": { - "fault": false, - "name": "profile saver", - "stack": [] - }, - "signal catcher": { - "fault": false, - "name": "signal catcher", - "stack": [] - }, - "finalizerwatchdogdaemon": { - "fault": false, - "name": "finalizerwatchdogdaemon", - "stack": [ - { - "funcName": "java.lang.Object.wait", - "sourceCode": "d71a2769-7f9d-48d2-bb69-f8a99742219a" - }, - { - "funcName": "java.lang.Object.wait", - "line": 442, - "sourceCode": "0710ca43-967f-4c85-865a-3ce24337a4d1" - }, - { - "funcName": "java.lang.Object.wait", - "line": 568, - "sourceCode": "38e624a4-5cce-4bc5-92bb-bf684f18792b" - }, - { - "funcName": "java.lang.Daemons$FinalizerWatchdogDaemon.sleepUntilNeeded", - "line": 341, - "sourceCode": "2b916c9d-3558-45bd-9bb0-b4436311451b" - }, - { - "funcName": "java.lang.Daemons$FinalizerWatchdogDaemon.runInternal", - "line": 321, - "sourceCode": "c35386b7-781a-4185-8817-eef78da6c429" - }, - { - "funcName": "java.lang.Daemons$Daemon.run", - "line": 139, - "sourceCode": "c9386136-04a8-485a-b8b9-95215d027013" - }, - { - "funcName": "java.lang.Thread.run", - "line": 923, - "sourceCode": "caea3885-ba11-4852-ad74-8585e064bb31" - } - ] - }, - "main": { - "fault": false, - "name": "main", - "stack": [ - { - "funcName": "android.os.MessageQueue.nativePollOnce", - "sourceCode": "00b5be47-8513-4f2e-a5d4-c711a58ce8ab" - }, - { - "funcName": "android.os.MessageQueue.next", - "line": 335, - "sourceCode": "caa8a790-c72a-479e-bc67-54139e01bdbe" - }, - { - "funcName": "android.os.Looper.loop", - "line": 183, - "sourceCode": "9f06bcf3-579d-4856-90f6-530eaeb97aed" - }, - { - "funcName": "android.app.ActivityThread.main", - "line": 7656, - "sourceCode": "6604ff49-6071-46ac-8f54-7b47f817b365" - }, - { - "funcName": "java.lang.reflect.Method.invoke", - "sourceCode": "c13bba6c-f9f1-4e43-84c6-a6cd6ab76bb4" - }, - { - "funcName": "com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run", - "line": 592, - "sourceCode": "c7255d95-3f41-422e-b491-19a60aa3f9db" - }, - { - "funcName": "com.android.internal.os.ZygoteInit.main", - "line": 947, - "sourceCode": "20e6b724-4a53-46ba-b949-979200eb2ec9" - } - ] - }, - "binder:11143_1": { - "fault": false, - "name": "binder:11143_1", - "stack": [] - }, - "binder:11143_2": { - "fault": false, - "name": "binder:11143_2", - "stack": [] - }, - "binder:11143_3": { - "fault": false, - "name": "binder:11143_3", - "stack": [] - }, - "finalizerdaemon": { - "fault": false, - "name": "finalizerdaemon", - "stack": [ - { - "funcName": "java.lang.Object.wait", - "sourceCode": "9632b2af-8ce2-4c58-855b-f9b308538457" - }, - { - "funcName": "java.lang.Object.wait", - "line": 442, - "sourceCode": "98bd4205-4ea6-4904-ac80-36c6b30ec1fe" - }, - { - "funcName": "java.lang.ref.ReferenceQueue.remove", - "line": 190, - "sourceCode": "779a86d7-754b-45a2-b75c-8095a1a8a92a" - }, - { - "funcName": "java.lang.ref.ReferenceQueue.remove", - "line": 211, - "sourceCode": "33d2d142-27da-4703-ae72-3064cbc5296c" - }, - { - "funcName": "java.lang.Daemons$FinalizerDaemon.runInternal", - "line": 273, - "sourceCode": "da999508-073c-4575-8564-d5b28643a4ff" - }, - { - "funcName": "java.lang.Daemons$Daemon.run", - "line": 139, - "sourceCode": "2c8faa9d-544a-4f03-8add-844f72ce88cc" - }, - { - "funcName": "java.lang.Thread.run", - "line": 923, - "sourceCode": "7f1d95d6-4c9d-493d-952c-1f3214ec6f13" - } - ] - }, - "referencequeuedaemon": { - "fault": false, - "name": "referencequeuedaemon", - "stack": [ - { - "funcName": "java.lang.Object.wait", - "sourceCode": "26071830-c698-441a-8658-ca585739125a" - }, - { - "funcName": "java.lang.Object.wait", - "line": 442, - "sourceCode": "be01c017-528d-4d0e-9ddb-304a6dabb97d" - }, - { - "funcName": "java.lang.Object.wait", - "line": 568, - "sourceCode": "b8074c19-2f7e-4b14-9440-d353a52e1a33" - }, - { - "funcName": "java.lang.Daemons$ReferenceQueueDaemon.runInternal", - "line": 217, - "sourceCode": "8038e8d8-b863-44e7-96be-86578bf7b81c" - }, - { - "funcName": "java.lang.Daemons$Daemon.run", - "line": 139, - "sourceCode": "48686825-013f-4cb8-8fff-95040fd7b184" - }, - { - "funcName": "java.lang.Thread.run", - "line": 923, - "sourceCode": "4c4e61d0-34c1-4011-9ddb-26fe16b66501" - } - ] - }, - "instrumentationconnectionthread": { - "fault": false, - "name": "instrumentationconnectionthread", - "stack": [ - { - "funcName": "android.os.MessageQueue.nativePollOnce", - "sourceCode": "1ba44e13-1bcd-4831-b880-a62f46085890" - }, - { - "funcName": "android.os.MessageQueue.next", - "line": 335, - "sourceCode": "f0ca2009-f11a-4976-a1f2-3ceb9ef6ce95" - }, - { - "funcName": "android.os.Looper.loop", - "line": 183, - "sourceCode": "1f3f81c7-2f6c-402b-8001-d1328c049ff4" - }, - { - "funcName": "android.os.HandlerThread.run", - "line": 67, - "sourceCode": "d2161b2c-5baf-47ec-a9b0-2e957704aab7" - } - ] - }, - "jit thread pool worker thread 0": { - "fault": false, - "name": "jit thread pool worker thread 0", - "stack": [] - }, - "instr: androidx.test.runner.androidjunitrunner": { - "fault": true, - "name": "instr: androidx.test.runner.androidjunitrunner", - "stack": [ - { - "funcName": "java.lang.reflect.Method.invoke", - "sourceCode": "d3a587b8-9d2c-4e70-9a0a-5a8257917d2d" - }, - { - "funcName": "org.junit.runners.model.FrameworkMethod$1.runReflectiveCall", - "line": 59, - "sourceCode": "4e282390-371b-4af4-b117-29398510be3a" - }, - { - "funcName": "org.junit.internal.runners.model.ReflectiveCallable.run", - "line": 12, - "sourceCode": "1ecb4287-1ad2-45a6-8450-af401cdbe17f" - }, - { - "funcName": "org.junit.runners.model.FrameworkMethod.invokeExplosively", - "line": 56, - "sourceCode": "4585edd4-5bf7-45e4-bb46-3f557b096852" - }, - { - "funcName": "org.junit.internal.runners.statements.InvokeMethod.evaluate", - "line": 17, - "sourceCode": "e9b5bfe9-f501-49c9-9621-02019e307488" - }, - { - "funcName": "org.junit.runners.ParentRunner$3.evaluate", - "line": 306, - "sourceCode": "def0b244-b5c3-4c68-9e4b-b5421888eee1" - }, - { - "funcName": "org.junit.runners.BlockJUnit4ClassRunner$1.evaluate", - "line": 100, - "sourceCode": "448f66cf-becf-4c83-9687-37eb9369a359" - }, - { - "funcName": "org.junit.runners.ParentRunner.runLeaf", - "line": 366, - "sourceCode": "bd559fdd-bd6f-44b6-a9b9-a14d865961d7" - }, - { - "funcName": "org.junit.runners.BlockJUnit4ClassRunner.runChild", - "line": 103, - "sourceCode": "c6cf7f65-6407-4b51-91f0-76f223c36c62" - }, - { - "funcName": "org.junit.runners.BlockJUnit4ClassRunner.runChild", - "line": 63, - "sourceCode": "3d9dcb46-6ac9-423e-8920-d0b5ec9c0f6d" - }, - { - "funcName": "org.junit.runners.ParentRunner$4.run", - "line": 331, - "sourceCode": "3e26748a-3965-4814-95a4-c474a701a15b" - }, - { - "funcName": "org.junit.runners.ParentRunner$1.schedule", - "line": 79, - "sourceCode": "dc715057-f108-4cc2-b4e8-f21aa2c4a75e" - }, - { - "funcName": "org.junit.runners.ParentRunner.runChildren", - "line": 329, - "sourceCode": "da3b40ad-d417-4f05-ae95-a7203478961d" - }, - { - "funcName": "org.junit.runners.ParentRunner.access$100", - "line": 66, - "sourceCode": "5e310bf1-ef77-449e-b523-bfb56d96cbc7" - }, - { - "funcName": "org.junit.runners.ParentRunner$2.evaluate", - "line": 293, - "sourceCode": "0ca32861-e9bb-4dd2-a38b-76bdb0be09e8" - }, - { - "funcName": "org.junit.runners.ParentRunner$3.evaluate", - "line": 306, - "sourceCode": "04520e56-5648-402d-99b5-434a8375e1b5" - }, - { - "funcName": "org.junit.runners.ParentRunner.run", - "line": 413, - "sourceCode": "e0eeb7ad-1024-4789-9fbe-4becb39e8420" - }, - { - "funcName": "androidx.test.ext.junit.runners.AndroidJUnit4.run", - "line": 162, - "sourceCode": "d6321483-6dc8-4ae5-95e8-c34ca2bfb660" - }, - { - "funcName": "org.junit.runners.Suite.runChild", - "line": 128, - "sourceCode": "8d478559-5a6f-412b-b854-3000e9adc98f" - }, - { - "funcName": "org.junit.runners.Suite.runChild", - "line": 27, - "sourceCode": "b47a8dd1-9c31-4793-805c-e33f9c77c818" - }, - { - "funcName": "org.junit.runners.ParentRunner$4.run", - "line": 331, - "sourceCode": "2068f2a4-9f0f-4854-bee9-cb398b7fd37f" - }, - { - "funcName": "org.junit.runners.ParentRunner$1.schedule", - "line": 79, - "sourceCode": "ef921e3c-bbc6-4d1f-a8ac-e9dfcc2b3d90" - }, - { - "funcName": "org.junit.runners.ParentRunner.runChildren", - "line": 329, - "sourceCode": "1549004b-d478-4341-87a2-4dea50ad031d" - }, - { - "funcName": "org.junit.runners.ParentRunner.access$100", - "line": 66, - "sourceCode": "a03637b1-a324-48e1-9b6f-06f030e2f3ba" - }, - { - "funcName": "org.junit.runners.ParentRunner$2.evaluate", - "line": 293, - "sourceCode": "5e3e29f7-7f77-4d4c-ae54-7a41caac90f4" - }, - { - "funcName": "org.junit.runners.ParentRunner$3.evaluate", - "line": 306, - "sourceCode": "295ccd27-4db2-487c-82f0-f255120cf593" - }, - { - "funcName": "org.junit.runners.ParentRunner.run", - "line": 413, - "sourceCode": "7aaec2ac-a43e-444b-b9ae-ad41ced28f33" - }, - { - "funcName": "org.junit.runner.JUnitCore.run", - "line": 137, - "sourceCode": "2bf04cc1-bb1e-47e2-a11b-c4bdea625413" - }, - { - "funcName": "org.junit.runner.JUnitCore.run", - "line": 115, - "sourceCode": "cb3283d2-d08f-4851-96fb-ec54aac63fd2" - }, - { - "funcName": "androidx.test.internal.runner.TestExecutor.execute", - "line": 67, - "sourceCode": "8ff34e56-9e08-4520-a87e-d7789785f013" - }, - { - "funcName": "androidx.test.internal.runner.TestExecutor.execute", - "line": 58, - "sourceCode": "19b8ca48-b129-4503-99bc-da54738d3108" - }, - { - "funcName": "androidx.test.runner.AndroidJUnitRunner.onStart", - "line": 446, - "sourceCode": "2517e7f8-fcec-44eb-a37c-c144fd441837" - }, - { - "funcName": "android.app.Instrumentation$InstrumentationThread.run", - "line": 2205, - "sourceCode": "b8437309-6989-4316-ab70-925d6fbc5135" - } - ] - }, - "heaptaskdaemon": { - "fault": false, - "name": "heaptaskdaemon", - "stack": [] - } - }, - "timestamp": 1694983723, - "uuid": "079e41e2-bef1-4062-9e20-f2e1b3a93582" -} \ No newline at end of file diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDataDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDataDeserializer.java index 987a44ad..5d76ddcb 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDataDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDataDeserializer.java @@ -78,7 +78,7 @@ public Map getSourceCode(JSONObject obj) { String key = keys.next(); try { if (obj.get(key) instanceof JSONObject) { - result.put(key, deserializer.deserialize(obj)); + result.put(key, deserializer.deserialize((JSONObject) obj.get(key))); } } catch (JSONException e) { // TODO: @@ -100,7 +100,7 @@ public Map getThreadInformation(JSONObject obj) { String key = keys.next(); try { if (obj.get(key) instanceof JSONObject) { - result.put(key, deserializer.deserialize(obj)); + result.put(key, deserializer.deserialize((JSONObject) obj.get(key))); } } catch (JSONException e) { // TODO: diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceStackFrameDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceStackFrameDeserializer.java index 9e6bab5f..624bf81f 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceStackFrameDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceStackFrameDeserializer.java @@ -18,8 +18,8 @@ static class Fields { public BacktraceStackFrame deserialize(JSONObject obj) throws JSONException { return new BacktraceStackFrame( obj.optString(fieldNameLoader.get(Fields.functionName), null), // TODO: check fallback warning - obj.optString(fieldNameLoader.get(Fields.line), null), // TODO: check fallback warning // todo: should be null in case of empty - obj.optInt(fieldNameLoader.get(Fields.sourceCode))); // TODO: check fallback warning + obj.optString(fieldNameLoader.get(Fields.sourceCode), null), // TODO: check fallback warning // todo: should be null in case of empty + obj.optInt(fieldNameLoader.get(Fields.line))); // TODO: check fallback warning } } 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 03f15cfe..ed051cc7 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceStackFrame.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceStackFrame.java @@ -34,7 +34,7 @@ public class BacktraceStackFrame { /** * Source code file name where exception occurs */ - public transient String sourceCodeFileName; + public transient String sourceCodeFileName; // why transient /** * Create new instance of BacktraceStackFrame @@ -61,7 +61,7 @@ public static BacktraceStackFrame fromStackTraceElement(StackTraceElement frame) public BacktraceStackFrame(String functionName, String sourceCodeFileName, Integer line) { this.functionName = functionName; - this.sourceCodeFileName = sourceCodeFileName; + this.sourceCodeFileName = sourceCodeFileName; // why this.sourceCode = UUID.randomUUID().toString(); this.line = line; } diff --git a/backtrace-library/src/test/java/backtraceio/library/BacktraceDataDeserializerTest.java b/backtrace-library/src/test/java/backtraceio/library/BacktraceDataDeserializerTest.java index 337a0a87..b411ccb5 100644 --- a/backtrace-library/src/test/java/backtraceio/library/BacktraceDataDeserializerTest.java +++ b/backtrace-library/src/test/java/backtraceio/library/BacktraceDataDeserializerTest.java @@ -5,6 +5,8 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static backtraceio.library.TestUtils.readFileAsString; + import org.json.JSONException; import org.json.JSONObject; import org.junit.Test; @@ -21,45 +23,51 @@ public class BacktraceDataDeserializerTest { @Test public void deserializeBacktraceData() throws JSONException { // GIVEN - final String backtraceDataJson = "{\"agent\":\"backtrace-android\",\"agentVersion\":\"3.7.12-8-3686709-org-json-serializer\",\"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\",\"PATH\":\"/product/bin:/apex/com.android.runtime/bin:/apex/com.android.art/bin:/system_ext/bin:/system/bin:/system/xbin:/odm/bin:/vendor/bin:/vendor/xbin\",\"ANDROID_SOCKET_zygote\":\"17\",\"ANDROID_I18N_ROOT\":\"/apex/com.android.i18n\",\"ANDROID_DATA\":\"/data\",\"ASEC_MOUNTPOINT\":\"/mnt/asec\",\"ANDROID_TZDATA_ROOT\":\"/apex/com.android.tzdata\",\"EXTERNAL_STORAGE\":\"/sdcard\",\"ANDROID_BOOTLOGO\":\"1\",\"ANDROID_ASSETS\":\"/system/app\",\"ANDROID_STORAGE\":\"/storage\",\"DEX2OATBOOTCLASSPATH\":\"/apex/com.android.art/javalib/core-oj.jar:/apex/com.android.art/javalib/core-libart.jar:/apex/com.android.art/javalib/core-icu4j.jar:/apex/com.android.art/javalib/okhttp.jar:/apex/com.android.art/javalib/bouncycastle.jar:/apex/com.android.art/javalib/apache-xml.jar:/system/framework/framework.jar:/system/framework/ext.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/framework-atb-backward-compatibility.jar\",\"ANDROID_ART_ROOT\":\"/apex/com.android.art\",\"ANDROID_ROOT\":\"/system\",\"DOWNLOAD_CACHE\":\"/data/cache\",\"BOOTCLASSPATH\":\"/apex/com.android.art/javalib/core-oj.jar:/apex/com.android.art/javalib/core-libart.jar:/apex/com.android.art/javalib/core-icu4j.jar:/apex/com.android.art/javalib/okhttp.jar:/apex/com.android.art/javalib/bouncycastle.jar:/apex/com.android.art/javalib/apache-xml.jar:/system/framework/framework.jar:/system/framework/ext.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/framework-atb-backward-compatibility.jar:/apex/com.android.conscrypt/javalib/conscrypt.jar:/apex/com.android.media/javalib/updatable-media.jar:/apex/com.android.mediaprovider/javalib/framework-mediaprovider.jar:/apex/com.android.os.statsd/javalib/framework-statsd.jar:/apex/com.android.permission/javalib/framework-permission.jar:/apex/com.android.sdkext/javalib/framework-sdkextensions.jar:/apex/com.android.wifi/javalib/framework-wifi.jar:/apex/com.android.tethering/javalib/framework-tethering.jar\",\"ANDROID_SOCKET_usap_pool_primary\":\"21\"},\"Exception\":{\"message\":\"Example test string\"}},\"attributes\":{\"application.session\":\"fd86372a-457d-4347-b1af-34779f86f520\",\"device.nfc.status\":\"NotAvailable\",\"device.cpu.temperature\":\"0.0\",\"system.memory.active\":\"1094905856\",\"device.wifi.status\":\"Enabled\",\"screen.height\":\"1834\",\"uname.machine\":\"i686\",\"screen.dpi\":\"288\",\"device.bluetooth_status\":\"NotPermitted\",\"device.airplane_mode\":\"false\",\"system.memory.total\":\"2077347840\",\"device.sdk\":\"30\",\"device.brand\":\"google\",\"uname.sysname\":\"Android\",\"cpu.boottime\":\"1707253373829\",\"device.os_version\":\"5.4.61-android11-0-00791-gbad091cc4bf3-ab6833933\",\"device.gps.enabled\":\"Enabled\",\"application.package\":\"backtraceio.library.test\",\"uname.version\":\"11\",\"backtrace.version\":\"3.7.12-8-3686709-org-json-serializer\",\"device.is_power_saving_mode\":\"false\",\"screen.orientation\":\"Portrait\",\"device.manufacturer\":\"Google\",\"system.memory.free\":\"982441984\",\"battery.state\":\"Unplugged\",\"backtrace.agent\":\"backtrace-android\",\"error.type\":\"Message\",\"device.location\":\"Enabled\",\"application\":\"backtraceio.library.test\",\"error.message\":\"Example test string\",\"culture\":\"English\",\"device.model\":\"sdk_gphone_x86\",\"screen.width\":\"1080\",\"build.type\":\"Debug\",\"device.product\":\"sdk_gphone_x86\",\"guid\":\"e4c57699-0dc9-35e2-b4a0-2ffff1925ca7\",\"app.storage_used\":\"2974528\",\"battery.level\":\"1.0\",\"screen.brightness\":\"102\"},\"lang\":\"java\",\"langVersion\":\"0\",\"mainThread\":\"instr: androidx.test.runner.androidjunitrunner\",\"sourceCode\":{\"5ad3ea57-08bc-42b9-a0af-4c0b63abd5d7\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":331},\"e1c31c4a-9f5f-4aae-8f74-29c5f7398e4d\":{\"source-code-file-name\":\"AndroidJUnit4.java\",\"start-line\":162},\"0a88f8a1-60c0-41a0-a95c-d75de5a4c82d\":{\"source-code-file-name\":\"JUnitCore.java\",\"start-line\":137},\"b1cc1675-df0c-4bda-9ec2-cc50d02b7497\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":66},\"6237d391-f50f-49b7-a029-dc8533521a39\":{\"source-code-file-name\":\"BlockJUnit4ClassRunner.java\",\"start-line\":100},\"24d96335-14d8-45d8-a07d-fc24bc56d4db\":{\"source-code-file-name\":\"Suite.java\",\"start-line\":128},\"9b765b76-8714-4dc2-8584-c58e57d0b97d\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":79},\"0952a91a-0c4b-45f2-93c7-e744a7e64ded\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":306},\"86deee3a-0e5f-495b-af66-5b2f36964ca2\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":79},\"bbf3d67c-a184-49ee-b0d5-b02188e3fa30\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":293},\"a70079ba-1646-4dda-ae17-7a92bf584c69\":{\"source-code-file-name\":\"ReflectiveCallable.java\",\"start-line\":12},\"61876082-acce-458e-8248-bfb03dc2b340\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":306},\"cfe92970-ae80-45b4-9dd4-8099919a1c26\":{\"source-code-file-name\":\"Suite.java\",\"start-line\":27},\"a4ef001f-1238-4b6e-9e57-aaa3dc1717ce\":{\"source-code-file-name\":\"AndroidJUnitRunner.java\",\"start-line\":446},\"6e8a4d01-3519-4742-be84-34da0dac2460\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":413},\"42aefc9a-50aa-40e9-ac4e-483c279cd9dc\":{\"source-code-file-name\":\"Method.java\"},\"56847938-10cc-4e20-98e2-521ce93ebe70\":{\"source-code-file-name\":\"VMStack.java\"},\"86086e43-f1de-49c0-aeda-3ae2be530407\":{\"source-code-file-name\":\"FrameworkMethod.java\",\"start-line\":59},\"ecc0e91a-52b3-48e7-b509-a850f49652c1\":{\"source-code-file-name\":\"RunBefores.java\",\"start-line\":80},\"673561af-72d1-4294-8f73-cca30446e70e\":{\"source-code-file-name\":\"BlockJUnit4ClassRunner.java\",\"start-line\":103},\"88ac7e2c-c331-4249-910d-519a6d25363f\":{\"source-code-file-name\":\"BlockJUnit4ClassRunner.java\",\"start-line\":63},\"ea2aa6d0-8e27-402d-8836-9ede35629ac9\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":66},\"4d79837a-1751-47e1-a134-d883871a9cec\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":413},\"7787b022-3043-4976-9dde-990443b50b24\":{\"source-code-file-name\":\"FrameworkMethod.java\",\"start-line\":56},\"5ed2c2aa-38a0-42ed-8f05-9131c4c72e90\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":366},\"e7bd36c2-dd6a-4bb3-bac5-e5e606490c71\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":329},\"ddf80aac-8ae4-42cc-9d35-5dae41fbf626\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":329},\"2980dbe3-ee88-486c-8442-9b6816dfe07a\":{\"source-code-file-name\":\"RunAfters.java\",\"start-line\":61},\"351d6b15-5d61-4a8a-9a06-5b14bf071945\":{\"source-code-file-name\":\"JUnitCore.java\",\"start-line\":115},\"2172b7fe-e8cf-4ffa-936b-c6efb52694bb\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":331},\"9ae72a6b-31be-435f-8a52-461f043b492b\":{\"source-code-file-name\":\"TestExecutor.java\",\"start-line\":58},\"a67eccc1-bd1c-4207-93a5-db20e09b79aa\":{\"source-code-file-name\":\"Instrumentation.java\",\"start-line\":2205},\"76276ba5-69ae-4815-8a9c-77525b526cb1\":{\"source-code-file-name\":\"TestExecutor.java\",\"start-line\":67},\"23444a66-f715-444f-afcb-f367a6f72689\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":293},\"1cfc3859-cf21-4d84-ba61-d73d9ee73c41\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":306},\"653bad70-8157-49d4-8894-8bb089f76722\":{\"source-code-file-name\":\"Thread.java\",\"start-line\":1736},\"84649fde-1055-4085-a52e-52c35811cbde\":{\"source-code-file-name\":\"InvokeMethod.java\",\"start-line\":17}},\"threadInformation-map\":{\"profile saver\":{\"fault\":false,\"name\":\"profile saver\",\"stack\":[]},\"finalizerwatchdogdaemon\":{\"fault\":false,\"name\":\"finalizerwatchdogdaemon\",\"stack\":[{\"function-name\":\"java.lang.Object.wait\",\"source-code\":\"b778a593-508f-444d-ab62-77d1ea5506c5\"},{\"function-name\":\"java.lang.Object.wait\",\"line\":442,\"source-code\":\"567b0437-8d29-4cc2-9274-819c056179a9\"},{\"function-name\":\"java.lang.Object.wait\",\"line\":568,\"source-code\":\"d07089b6-e586-4cde-ab31-3d0d1740ae25\"},{\"function-name\":\"java.lang.Daemons$FinalizerWatchdogDaemon.sleepUntilNeeded\",\"line\":341,\"source-code\":\"5aa512c3-e353-4309-9613-f3175bc05c56\"},{\"function-name\":\"java.lang.Daemons$FinalizerWatchdogDaemon.runInternal\",\"line\":321,\"source-code\":\"a8fb461e-e7b9-4259-b16f-8e9610884d2a\"},{\"function-name\":\"java.lang.Daemons$Daemon.run\",\"line\":139,\"source-code\":\"100f945a-c9ed-42d4-a396-bfb1c9c09e32\"},{\"function-name\":\"java.lang.Thread.run\",\"line\":923,\"source-code\":\"ba65711d-9470-4cdc-a06a-32db7ce84db9\"}]},\"signal catcher\":{\"fault\":false,\"name\":\"signal catcher\",\"stack\":[]},\"timer-0\":{\"fault\":false,\"name\":\"timer-0\",\"stack\":[{\"function-name\":\"java.lang.Object.wait\",\"source-code\":\"dbfe3cc6-8ac5-4a8c-b4c2-3c4073e563c7\"},{\"function-name\":\"java.lang.Object.wait\",\"line\":442,\"source-code\":\"ce872d4e-20a7-4991-9ae6-b0c09ff728f1\"},{\"function-name\":\"java.util.TimerThread.mainLoop\",\"line\":559,\"source-code\":\"507a2ca3-1e70-492a-9a75-cb95073c44a0\"},{\"function-name\":\"java.util.TimerThread.run\",\"line\":512,\"source-code\":\"06908da9-ce73-4835-b1e3-5fb732fcf82e\"}]},\"main\":{\"fault\":false,\"name\":\"main\",\"stack\":[{\"function-name\":\"android.os.MessageQueue.nativePollOnce\",\"source-code\":\"30ad9a05-28af-4db8-8ee6-35d55cc85ca5\"},{\"function-name\":\"android.os.MessageQueue.next\",\"line\":335,\"source-code\":\"58e043c1-b6f0-47ee-a5ea-af64153bd38b\"},{\"function-name\":\"android.os.Looper.loop\",\"line\":183,\"source-code\":\"9718f15f-0010-4e8f-8012-a5c48b554a9f\"},{\"function-name\":\"android.app.ActivityThread.main\",\"line\":7656,\"source-code\":\"4cc5b61d-3403-4a03-8a69-63adbcc55511\"},{\"function-name\":\"java.lang.reflect.Method.invoke\",\"source-code\":\"23078e7a-df17-4655-bad5-48b90baedba9\"},{\"function-name\":\"com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run\",\"line\":592,\"source-code\":\"cc45db4a-ec38-49d9-b5f6-14b804362ccd\"},{\"function-name\":\"com.android.internal.os.ZygoteInit.main\",\"line\":947,\"source-code\":\"406194e7-76b8-4b8f-977c-21756313f648\"}]},\"finalizerdaemon\":{\"fault\":false,\"name\":\"finalizerdaemon\",\"stack\":[{\"function-name\":\"java.lang.Object.wait\",\"source-code\":\"daff552e-1ac1-4417-9b77-fd91b3a664fc\"},{\"function-name\":\"java.lang.Object.wait\",\"line\":442,\"source-code\":\"d1445680-d522-46d4-ae3a-b2daeda6de3d\"},{\"function-name\":\"java.lang.ref.ReferenceQueue.remove\",\"line\":190,\"source-code\":\"260f72cf-3b32-48ff-9722-af6280876415\"},{\"function-name\":\"java.lang.ref.ReferenceQueue.remove\",\"line\":211,\"source-code\":\"e951fdfd-cde7-49f2-926b-4e131544d4d4\"},{\"function-name\":\"java.lang.Daemons$FinalizerDaemon.runInternal\",\"line\":273,\"source-code\":\"4f2ac4ed-051c-4a1c-a94d-999809f38ea6\"},{\"function-name\":\"java.lang.Daemons$Daemon.run\",\"line\":139,\"source-code\":\"d2d21d80-5047-4c37-abe5-cb0e854c555a\"},{\"function-name\":\"java.lang.Thread.run\",\"line\":923,\"source-code\":\"ceeb7b8e-7b5c-4d65-9c80-7c8e02a12202\"}]},\"referencequeuedaemon\":{\"fault\":false,\"name\":\"referencequeuedaemon\",\"stack\":[{\"function-name\":\"java.lang.Object.wait\",\"source-code\":\"d569fd77-fec0-4abd-b746-1e43394a8ca1\"},{\"function-name\":\"java.lang.Object.wait\",\"line\":442,\"source-code\":\"29bee7cd-cda4-4cd0-b7b6-1b21c40f3ee5\"},{\"function-name\":\"java.lang.Object.wait\",\"line\":568,\"source-code\":\"4b73fe34-9a92-4b11-a391-fa60086a62b4\"},{\"function-name\":\"java.lang.Daemons$ReferenceQueueDaemon.runInternal\",\"line\":217,\"source-code\":\"e76abece-43e7-48a0-a429-f13b75282fdd\"},{\"function-name\":\"java.lang.Daemons$Daemon.run\",\"line\":139,\"source-code\":\"08d8fd2b-8d9e-4317-ad68-3031de5f429f\"},{\"function-name\":\"java.lang.Thread.run\",\"line\":923,\"source-code\":\"8509b640-6470-4894-a896-7794e917c270\"}]},\"binder:8909_3\":{\"fault\":false,\"name\":\"binder:8909_3\",\"stack\":[]},\"jit thread pool worker thread 0\":{\"fault\":false,\"name\":\"jit thread pool worker thread 0\",\"stack\":[]},\"instrumentationconnectionthread\":{\"fault\":false,\"name\":\"instrumentationconnectionthread\",\"stack\":[{\"function-name\":\"android.os.MessageQueue.nativePollOnce\",\"source-code\":\"2699757c-16bd-4853-8d48-ad23aeebf5ad\"},{\"function-name\":\"android.os.MessageQueue.next\",\"line\":335,\"source-code\":\"bf1a4cc2-55ee-43c3-83a0-8780eeece1ce\"},{\"function-name\":\"android.os.Looper.loop\",\"line\":183,\"source-code\":\"2e0184c2-dd7e-41b6-946a-a646896cb880\"},{\"function-name\":\"android.os.HandlerThread.run\",\"line\":67,\"source-code\":\"209e3b61-b3f2-4de5-b8e3-6d832e969ce9\"}]},\"instr: androidx.test.runner.androidjunitrunner\":{\"fault\":true,\"name\":\"instr: androidx.test.runner.androidjunitrunner\",\"stack\":[{\"function-name\":\"dalvik.system.VMStack.getThreadStackTrace\",\"source-code\":\"56847938-10cc-4e20-98e2-521ce93ebe70\"},{\"function-name\":\"java.lang.Thread.getStackTrace\",\"line\":1736,\"source-code\":\"653bad70-8157-49d4-8894-8bb089f76722\"},{\"function-name\":\"java.lang.reflect.Method.invoke\",\"source-code\":\"42aefc9a-50aa-40e9-ac4e-483c279cd9dc\"},{\"function-name\":\"org.junit.runners.model.FrameworkMethod$1.runReflectiveCall\",\"line\":59,\"source-code\":\"86086e43-f1de-49c0-aeda-3ae2be530407\"},{\"function-name\":\"org.junit.internal.runners.model.ReflectiveCallable.run\",\"line\":12,\"source-code\":\"a70079ba-1646-4dda-ae17-7a92bf584c69\"},{\"function-name\":\"org.junit.runners.model.FrameworkMethod.invokeExplosively\",\"line\":56,\"source-code\":\"7787b022-3043-4976-9dde-990443b50b24\"},{\"function-name\":\"org.junit.internal.runners.statements.InvokeMethod.evaluate\",\"line\":17,\"source-code\":\"84649fde-1055-4085-a52e-52c35811cbde\"},{\"function-name\":\"androidx.test.internal.runner.junit4.statement.RunBefores.evaluate\",\"line\":80,\"source-code\":\"ecc0e91a-52b3-48e7-b509-a850f49652c1\"},{\"function-name\":\"androidx.test.internal.runner.junit4.statement.RunAfters.evaluate\",\"line\":61,\"source-code\":\"2980dbe3-ee88-486c-8442-9b6816dfe07a\"},{\"function-name\":\"org.junit.runners.ParentRunner$3.evaluate\",\"line\":306,\"source-code\":\"1cfc3859-cf21-4d84-ba61-d73d9ee73c41\"},{\"function-name\":\"org.junit.runners.BlockJUnit4ClassRunner$1.evaluate\",\"line\":100,\"source-code\":\"6237d391-f50f-49b7-a029-dc8533521a39\"},{\"function-name\":\"org.junit.runners.ParentRunner.runLeaf\",\"line\":366,\"source-code\":\"5ed2c2aa-38a0-42ed-8f05-9131c4c72e90\"},{\"function-name\":\"org.junit.runners.BlockJUnit4ClassRunner.runChild\",\"line\":103,\"source-code\":\"673561af-72d1-4294-8f73-cca30446e70e\"},{\"function-name\":\"org.junit.runners.BlockJUnit4ClassRunner.runChild\",\"line\":63,\"source-code\":\"88ac7e2c-c331-4249-910d-519a6d25363f\"},{\"function-name\":\"org.junit.runners.ParentRunner$4.run\",\"line\":331,\"source-code\":\"2172b7fe-e8cf-4ffa-936b-c6efb52694bb\"},{\"function-name\":\"org.junit.runners.ParentRunner$1.schedule\",\"line\":79,\"source-code\":\"86deee3a-0e5f-495b-af66-5b2f36964ca2\"},{\"function-name\":\"org.junit.runners.ParentRunner.runChildren\",\"line\":329,\"source-code\":\"e7bd36c2-dd6a-4bb3-bac5-e5e606490c71\"},{\"function-name\":\"org.junit.runners.ParentRunner.access$100\",\"line\":66,\"source-code\":\"ea2aa6d0-8e27-402d-8836-9ede35629ac9\"},{\"function-name\":\"org.junit.runners.ParentRunner$2.evaluate\",\"line\":293,\"source-code\":\"23444a66-f715-444f-afcb-f367a6f72689\"},{\"function-name\":\"org.junit.runners.ParentRunner$3.evaluate\",\"line\":306,\"source-code\":\"0952a91a-0c4b-45f2-93c7-e744a7e64ded\"},{\"function-name\":\"org.junit.runners.ParentRunner.run\",\"line\":413,\"source-code\":\"6e8a4d01-3519-4742-be84-34da0dac2460\"},{\"function-name\":\"androidx.test.ext.junit.runners.AndroidJUnit4.run\",\"line\":162,\"source-code\":\"e1c31c4a-9f5f-4aae-8f74-29c5f7398e4d\"},{\"function-name\":\"org.junit.runners.Suite.runChild\",\"line\":128,\"source-code\":\"24d96335-14d8-45d8-a07d-fc24bc56d4db\"},{\"function-name\":\"org.junit.runners.Suite.runChild\",\"line\":27,\"source-code\":\"cfe92970-ae80-45b4-9dd4-8099919a1c26\"},{\"function-name\":\"org.junit.runners.ParentRunner$4.run\",\"line\":331,\"source-code\":\"5ad3ea57-08bc-42b9-a0af-4c0b63abd5d7\"},{\"function-name\":\"org.junit.runners.ParentRunner$1.schedule\",\"line\":79,\"source-code\":\"9b765b76-8714-4dc2-8584-c58e57d0b97d\"},{\"function-name\":\"org.junit.runners.ParentRunner.runChildren\",\"line\":329,\"source-code\":\"ddf80aac-8ae4-42cc-9d35-5dae41fbf626\"},{\"function-name\":\"org.junit.runners.ParentRunner.access$100\",\"line\":66,\"source-code\":\"b1cc1675-df0c-4bda-9ec2-cc50d02b7497\"},{\"function-name\":\"org.junit.runners.ParentRunner$2.evaluate\",\"line\":293,\"source-code\":\"bbf3d67c-a184-49ee-b0d5-b02188e3fa30\"},{\"function-name\":\"org.junit.runners.ParentRunner$3.evaluate\",\"line\":306,\"source-code\":\"61876082-acce-458e-8248-bfb03dc2b340\"},{\"function-name\":\"org.junit.runners.ParentRunner.run\",\"line\":413,\"source-code\":\"4d79837a-1751-47e1-a134-d883871a9cec\"},{\"function-name\":\"org.junit.runner.JUnitCore.run\",\"line\":137,\"source-code\":\"0a88f8a1-60c0-41a0-a95c-d75de5a4c82d\"},{\"function-name\":\"org.junit.runner.JUnitCore.run\",\"line\":115,\"source-code\":\"351d6b15-5d61-4a8a-9a06-5b14bf071945\"},{\"function-name\":\"androidx.test.internal.runner.TestExecutor.execute\",\"line\":67,\"source-code\":\"76276ba5-69ae-4815-8a9c-77525b526cb1\"},{\"function-name\":\"androidx.test.internal.runner.TestExecutor.execute\",\"line\":58,\"source-code\":\"9ae72a6b-31be-435f-8a52-461f043b492b\"},{\"function-name\":\"androidx.test.runner.AndroidJUnitRunner.onStart\",\"line\":446,\"source-code\":\"a4ef001f-1238-4b6e-9e57-aaa3dc1717ce\"},{\"function-name\":\"android.app.Instrumentation$InstrumentationThread.run\",\"line\":2205,\"source-code\":\"a67eccc1-bd1c-4207-93a5-db20e09b79aa\"}]},\"binder:8909_1\":{\"fault\":false,\"name\":\"binder:8909_1\",\"stack\":[]},\"heaptaskdaemon\":{\"fault\":false,\"name\":\"heaptaskdaemon\",\"stack\":[]},\"binder:8909_2\":{\"fault\":false,\"name\":\"binder:8909_2\",\"stack\":[]}},\"timestamp\":1707253867,\"uuid\":\"8e68b676-21cb-4cc8-ac2e-32a60e8d29c1\"}"; - +// final String backtraceDataJson = "{\"agent\":\"backtrace-android\",\"agentVersion\":\"3.7.12-8-3686709-org-json-serializer\",\"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\",\"PATH\":\"/product/bin:/apex/com.android.runtime/bin:/apex/com.android.art/bin:/system_ext/bin:/system/bin:/system/xbin:/odm/bin:/vendor/bin:/vendor/xbin\",\"ANDROID_SOCKET_zygote\":\"17\",\"ANDROID_I18N_ROOT\":\"/apex/com.android.i18n\",\"ANDROID_DATA\":\"/data\",\"ASEC_MOUNTPOINT\":\"/mnt/asec\",\"ANDROID_TZDATA_ROOT\":\"/apex/com.android.tzdata\",\"EXTERNAL_STORAGE\":\"/sdcard\",\"ANDROID_BOOTLOGO\":\"1\",\"ANDROID_ASSETS\":\"/system/app\",\"ANDROID_STORAGE\":\"/storage\",\"DEX2OATBOOTCLASSPATH\":\"/apex/com.android.art/javalib/core-oj.jar:/apex/com.android.art/javalib/core-libart.jar:/apex/com.android.art/javalib/core-icu4j.jar:/apex/com.android.art/javalib/okhttp.jar:/apex/com.android.art/javalib/bouncycastle.jar:/apex/com.android.art/javalib/apache-xml.jar:/system/framework/framework.jar:/system/framework/ext.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/framework-atb-backward-compatibility.jar\",\"ANDROID_ART_ROOT\":\"/apex/com.android.art\",\"ANDROID_ROOT\":\"/system\",\"DOWNLOAD_CACHE\":\"/data/cache\",\"BOOTCLASSPATH\":\"/apex/com.android.art/javalib/core-oj.jar:/apex/com.android.art/javalib/core-libart.jar:/apex/com.android.art/javalib/core-icu4j.jar:/apex/com.android.art/javalib/okhttp.jar:/apex/com.android.art/javalib/bouncycastle.jar:/apex/com.android.art/javalib/apache-xml.jar:/system/framework/framework.jar:/system/framework/ext.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/framework-atb-backward-compatibility.jar:/apex/com.android.conscrypt/javalib/conscrypt.jar:/apex/com.android.media/javalib/updatable-media.jar:/apex/com.android.mediaprovider/javalib/framework-mediaprovider.jar:/apex/com.android.os.statsd/javalib/framework-statsd.jar:/apex/com.android.permission/javalib/framework-permission.jar:/apex/com.android.sdkext/javalib/framework-sdkextensions.jar:/apex/com.android.wifi/javalib/framework-wifi.jar:/apex/com.android.tethering/javalib/framework-tethering.jar\",\"ANDROID_SOCKET_usap_pool_primary\":\"21\"},\"Exception\":{\"message\":\"Example test string\"}},\"attributes\":{\"application.session\":\"fd86372a-457d-4347-b1af-34779f86f520\",\"device.nfc.status\":\"NotAvailable\",\"device.cpu.temperature\":\"0.0\",\"system.memory.active\":\"1094905856\",\"device.wifi.status\":\"Enabled\",\"screen.height\":\"1834\",\"uname.machine\":\"i686\",\"screen.dpi\":\"288\",\"device.bluetooth_status\":\"NotPermitted\",\"device.airplane_mode\":\"false\",\"system.memory.total\":\"2077347840\",\"device.sdk\":\"30\",\"device.brand\":\"google\",\"uname.sysname\":\"Android\",\"cpu.boottime\":\"1707253373829\",\"device.os_version\":\"5.4.61-android11-0-00791-gbad091cc4bf3-ab6833933\",\"device.gps.enabled\":\"Enabled\",\"application.package\":\"backtraceio.library.test\",\"uname.version\":\"11\",\"backtrace.version\":\"3.7.12-8-3686709-org-json-serializer\",\"device.is_power_saving_mode\":\"false\",\"screen.orientation\":\"Portrait\",\"device.manufacturer\":\"Google\",\"system.memory.free\":\"982441984\",\"battery.state\":\"Unplugged\",\"backtrace.agent\":\"backtrace-android\",\"error.type\":\"Message\",\"device.location\":\"Enabled\",\"application\":\"backtraceio.library.test\",\"error.message\":\"Example test string\",\"culture\":\"English\",\"device.model\":\"sdk_gphone_x86\",\"screen.width\":\"1080\",\"build.type\":\"Debug\",\"device.product\":\"sdk_gphone_x86\",\"guid\":\"e4c57699-0dc9-35e2-b4a0-2ffff1925ca7\",\"app.storage_used\":\"2974528\",\"battery.level\":\"1.0\",\"screen.brightness\":\"102\"},\"lang\":\"java\",\"langVersion\":\"0\",\"mainThread\":\"instr: androidx.test.runner.androidjunitrunner\",\"sourceCode\":{\"5ad3ea57-08bc-42b9-a0af-4c0b63abd5d7\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":331},\"e1c31c4a-9f5f-4aae-8f74-29c5f7398e4d\":{\"source-code-file-name\":\"AndroidJUnit4.java\",\"start-line\":162},\"0a88f8a1-60c0-41a0-a95c-d75de5a4c82d\":{\"source-code-file-name\":\"JUnitCore.java\",\"start-line\":137},\"b1cc1675-df0c-4bda-9ec2-cc50d02b7497\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":66},\"6237d391-f50f-49b7-a029-dc8533521a39\":{\"source-code-file-name\":\"BlockJUnit4ClassRunner.java\",\"start-line\":100},\"24d96335-14d8-45d8-a07d-fc24bc56d4db\":{\"source-code-file-name\":\"Suite.java\",\"start-line\":128},\"9b765b76-8714-4dc2-8584-c58e57d0b97d\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":79},\"0952a91a-0c4b-45f2-93c7-e744a7e64ded\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":306},\"86deee3a-0e5f-495b-af66-5b2f36964ca2\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":79},\"bbf3d67c-a184-49ee-b0d5-b02188e3fa30\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":293},\"a70079ba-1646-4dda-ae17-7a92bf584c69\":{\"source-code-file-name\":\"ReflectiveCallable.java\",\"start-line\":12},\"61876082-acce-458e-8248-bfb03dc2b340\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":306},\"cfe92970-ae80-45b4-9dd4-8099919a1c26\":{\"source-code-file-name\":\"Suite.java\",\"start-line\":27},\"a4ef001f-1238-4b6e-9e57-aaa3dc1717ce\":{\"source-code-file-name\":\"AndroidJUnitRunner.java\",\"start-line\":446},\"6e8a4d01-3519-4742-be84-34da0dac2460\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":413},\"42aefc9a-50aa-40e9-ac4e-483c279cd9dc\":{\"source-code-file-name\":\"Method.java\"},\"56847938-10cc-4e20-98e2-521ce93ebe70\":{\"source-code-file-name\":\"VMStack.java\"},\"86086e43-f1de-49c0-aeda-3ae2be530407\":{\"source-code-file-name\":\"FrameworkMethod.java\",\"start-line\":59},\"ecc0e91a-52b3-48e7-b509-a850f49652c1\":{\"source-code-file-name\":\"RunBefores.java\",\"start-line\":80},\"673561af-72d1-4294-8f73-cca30446e70e\":{\"source-code-file-name\":\"BlockJUnit4ClassRunner.java\",\"start-line\":103},\"88ac7e2c-c331-4249-910d-519a6d25363f\":{\"source-code-file-name\":\"BlockJUnit4ClassRunner.java\",\"start-line\":63},\"ea2aa6d0-8e27-402d-8836-9ede35629ac9\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":66},\"4d79837a-1751-47e1-a134-d883871a9cec\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":413},\"7787b022-3043-4976-9dde-990443b50b24\":{\"source-code-file-name\":\"FrameworkMethod.java\",\"start-line\":56},\"5ed2c2aa-38a0-42ed-8f05-9131c4c72e90\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":366},\"e7bd36c2-dd6a-4bb3-bac5-e5e606490c71\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":329},\"ddf80aac-8ae4-42cc-9d35-5dae41fbf626\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":329},\"2980dbe3-ee88-486c-8442-9b6816dfe07a\":{\"source-code-file-name\":\"RunAfters.java\",\"start-line\":61},\"351d6b15-5d61-4a8a-9a06-5b14bf071945\":{\"source-code-file-name\":\"JUnitCore.java\",\"start-line\":115},\"2172b7fe-e8cf-4ffa-936b-c6efb52694bb\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":331},\"9ae72a6b-31be-435f-8a52-461f043b492b\":{\"source-code-file-name\":\"TestExecutor.java\",\"start-line\":58},\"a67eccc1-bd1c-4207-93a5-db20e09b79aa\":{\"source-code-file-name\":\"Instrumentation.java\",\"start-line\":2205},\"76276ba5-69ae-4815-8a9c-77525b526cb1\":{\"source-code-file-name\":\"TestExecutor.java\",\"start-line\":67},\"23444a66-f715-444f-afcb-f367a6f72689\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":293},\"1cfc3859-cf21-4d84-ba61-d73d9ee73c41\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":306},\"653bad70-8157-49d4-8894-8bb089f76722\":{\"source-code-file-name\":\"Thread.java\",\"start-line\":1736},\"84649fde-1055-4085-a52e-52c35811cbde\":{\"source-code-file-name\":\"InvokeMethod.java\",\"start-line\":17}},\"threadInformation-map\":{\"profile saver\":{\"fault\":false,\"name\":\"profile saver\",\"stack\":[]},\"finalizerwatchdogdaemon\":{\"fault\":false,\"name\":\"finalizerwatchdogdaemon\",\"stack\":[{\"function-name\":\"java.lang.Object.wait\",\"source-code\":\"b778a593-508f-444d-ab62-77d1ea5506c5\"},{\"function-name\":\"java.lang.Object.wait\",\"line\":442,\"source-code\":\"567b0437-8d29-4cc2-9274-819c056179a9\"},{\"function-name\":\"java.lang.Object.wait\",\"line\":568,\"source-code\":\"d07089b6-e586-4cde-ab31-3d0d1740ae25\"},{\"function-name\":\"java.lang.Daemons$FinalizerWatchdogDaemon.sleepUntilNeeded\",\"line\":341,\"source-code\":\"5aa512c3-e353-4309-9613-f3175bc05c56\"},{\"function-name\":\"java.lang.Daemons$FinalizerWatchdogDaemon.runInternal\",\"line\":321,\"source-code\":\"a8fb461e-e7b9-4259-b16f-8e9610884d2a\"},{\"function-name\":\"java.lang.Daemons$Daemon.run\",\"line\":139,\"source-code\":\"100f945a-c9ed-42d4-a396-bfb1c9c09e32\"},{\"function-name\":\"java.lang.Thread.run\",\"line\":923,\"source-code\":\"ba65711d-9470-4cdc-a06a-32db7ce84db9\"}]},\"signal catcher\":{\"fault\":false,\"name\":\"signal catcher\",\"stack\":[]},\"timer-0\":{\"fault\":false,\"name\":\"timer-0\",\"stack\":[{\"function-name\":\"java.lang.Object.wait\",\"source-code\":\"dbfe3cc6-8ac5-4a8c-b4c2-3c4073e563c7\"},{\"function-name\":\"java.lang.Object.wait\",\"line\":442,\"source-code\":\"ce872d4e-20a7-4991-9ae6-b0c09ff728f1\"},{\"function-name\":\"java.util.TimerThread.mainLoop\",\"line\":559,\"source-code\":\"507a2ca3-1e70-492a-9a75-cb95073c44a0\"},{\"function-name\":\"java.util.TimerThread.run\",\"line\":512,\"source-code\":\"06908da9-ce73-4835-b1e3-5fb732fcf82e\"}]},\"main\":{\"fault\":false,\"name\":\"main\",\"stack\":[{\"function-name\":\"android.os.MessageQueue.nativePollOnce\",\"source-code\":\"30ad9a05-28af-4db8-8ee6-35d55cc85ca5\"},{\"function-name\":\"android.os.MessageQueue.next\",\"line\":335,\"source-code\":\"58e043c1-b6f0-47ee-a5ea-af64153bd38b\"},{\"function-name\":\"android.os.Looper.loop\",\"line\":183,\"source-code\":\"9718f15f-0010-4e8f-8012-a5c48b554a9f\"},{\"function-name\":\"android.app.ActivityThread.main\",\"line\":7656,\"source-code\":\"4cc5b61d-3403-4a03-8a69-63adbcc55511\"},{\"function-name\":\"java.lang.reflect.Method.invoke\",\"source-code\":\"23078e7a-df17-4655-bad5-48b90baedba9\"},{\"function-name\":\"com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run\",\"line\":592,\"source-code\":\"cc45db4a-ec38-49d9-b5f6-14b804362ccd\"},{\"function-name\":\"com.android.internal.os.ZygoteInit.main\",\"line\":947,\"source-code\":\"406194e7-76b8-4b8f-977c-21756313f648\"}]},\"finalizerdaemon\":{\"fault\":false,\"name\":\"finalizerdaemon\",\"stack\":[{\"function-name\":\"java.lang.Object.wait\",\"source-code\":\"daff552e-1ac1-4417-9b77-fd91b3a664fc\"},{\"function-name\":\"java.lang.Object.wait\",\"line\":442,\"source-code\":\"d1445680-d522-46d4-ae3a-b2daeda6de3d\"},{\"function-name\":\"java.lang.ref.ReferenceQueue.remove\",\"line\":190,\"source-code\":\"260f72cf-3b32-48ff-9722-af6280876415\"},{\"function-name\":\"java.lang.ref.ReferenceQueue.remove\",\"line\":211,\"source-code\":\"e951fdfd-cde7-49f2-926b-4e131544d4d4\"},{\"function-name\":\"java.lang.Daemons$FinalizerDaemon.runInternal\",\"line\":273,\"source-code\":\"4f2ac4ed-051c-4a1c-a94d-999809f38ea6\"},{\"function-name\":\"java.lang.Daemons$Daemon.run\",\"line\":139,\"source-code\":\"d2d21d80-5047-4c37-abe5-cb0e854c555a\"},{\"function-name\":\"java.lang.Thread.run\",\"line\":923,\"source-code\":\"ceeb7b8e-7b5c-4d65-9c80-7c8e02a12202\"}]},\"referencequeuedaemon\":{\"fault\":false,\"name\":\"referencequeuedaemon\",\"stack\":[{\"function-name\":\"java.lang.Object.wait\",\"source-code\":\"d569fd77-fec0-4abd-b746-1e43394a8ca1\"},{\"function-name\":\"java.lang.Object.wait\",\"line\":442,\"source-code\":\"29bee7cd-cda4-4cd0-b7b6-1b21c40f3ee5\"},{\"function-name\":\"java.lang.Object.wait\",\"line\":568,\"source-code\":\"4b73fe34-9a92-4b11-a391-fa60086a62b4\"},{\"function-name\":\"java.lang.Daemons$ReferenceQueueDaemon.runInternal\",\"line\":217,\"source-code\":\"e76abece-43e7-48a0-a429-f13b75282fdd\"},{\"function-name\":\"java.lang.Daemons$Daemon.run\",\"line\":139,\"source-code\":\"08d8fd2b-8d9e-4317-ad68-3031de5f429f\"},{\"function-name\":\"java.lang.Thread.run\",\"line\":923,\"source-code\":\"8509b640-6470-4894-a896-7794e917c270\"}]},\"binder:8909_3\":{\"fault\":false,\"name\":\"binder:8909_3\",\"stack\":[]},\"jit thread pool worker thread 0\":{\"fault\":false,\"name\":\"jit thread pool worker thread 0\",\"stack\":[]},\"instrumentationconnectionthread\":{\"fault\":false,\"name\":\"instrumentationconnectionthread\",\"stack\":[{\"function-name\":\"android.os.MessageQueue.nativePollOnce\",\"source-code\":\"2699757c-16bd-4853-8d48-ad23aeebf5ad\"},{\"function-name\":\"android.os.MessageQueue.next\",\"line\":335,\"source-code\":\"bf1a4cc2-55ee-43c3-83a0-8780eeece1ce\"},{\"function-name\":\"android.os.Looper.loop\",\"line\":183,\"source-code\":\"2e0184c2-dd7e-41b6-946a-a646896cb880\"},{\"function-name\":\"android.os.HandlerThread.run\",\"line\":67,\"source-code\":\"209e3b61-b3f2-4de5-b8e3-6d832e969ce9\"}]},\"instr: androidx.test.runner.androidjunitrunner\":{\"fault\":true,\"name\":\"instr: androidx.test.runner.androidjunitrunner\",\"stack\":[{\"function-name\":\"dalvik.system.VMStack.getThreadStackTrace\",\"source-code\":\"56847938-10cc-4e20-98e2-521ce93ebe70\"},{\"function-name\":\"java.lang.Thread.getStackTrace\",\"line\":1736,\"source-code\":\"653bad70-8157-49d4-8894-8bb089f76722\"},{\"function-name\":\"java.lang.reflect.Method.invoke\",\"source-code\":\"42aefc9a-50aa-40e9-ac4e-483c279cd9dc\"},{\"function-name\":\"org.junit.runners.model.FrameworkMethod$1.runReflectiveCall\",\"line\":59,\"source-code\":\"86086e43-f1de-49c0-aeda-3ae2be530407\"},{\"function-name\":\"org.junit.internal.runners.model.ReflectiveCallable.run\",\"line\":12,\"source-code\":\"a70079ba-1646-4dda-ae17-7a92bf584c69\"},{\"function-name\":\"org.junit.runners.model.FrameworkMethod.invokeExplosively\",\"line\":56,\"source-code\":\"7787b022-3043-4976-9dde-990443b50b24\"},{\"function-name\":\"org.junit.internal.runners.statements.InvokeMethod.evaluate\",\"line\":17,\"source-code\":\"84649fde-1055-4085-a52e-52c35811cbde\"},{\"function-name\":\"androidx.test.internal.runner.junit4.statement.RunBefores.evaluate\",\"line\":80,\"source-code\":\"ecc0e91a-52b3-48e7-b509-a850f49652c1\"},{\"function-name\":\"androidx.test.internal.runner.junit4.statement.RunAfters.evaluate\",\"line\":61,\"source-code\":\"2980dbe3-ee88-486c-8442-9b6816dfe07a\"},{\"function-name\":\"org.junit.runners.ParentRunner$3.evaluate\",\"line\":306,\"source-code\":\"1cfc3859-cf21-4d84-ba61-d73d9ee73c41\"},{\"function-name\":\"org.junit.runners.BlockJUnit4ClassRunner$1.evaluate\",\"line\":100,\"source-code\":\"6237d391-f50f-49b7-a029-dc8533521a39\"},{\"function-name\":\"org.junit.runners.ParentRunner.runLeaf\",\"line\":366,\"source-code\":\"5ed2c2aa-38a0-42ed-8f05-9131c4c72e90\"},{\"function-name\":\"org.junit.runners.BlockJUnit4ClassRunner.runChild\",\"line\":103,\"source-code\":\"673561af-72d1-4294-8f73-cca30446e70e\"},{\"function-name\":\"org.junit.runners.BlockJUnit4ClassRunner.runChild\",\"line\":63,\"source-code\":\"88ac7e2c-c331-4249-910d-519a6d25363f\"},{\"function-name\":\"org.junit.runners.ParentRunner$4.run\",\"line\":331,\"source-code\":\"2172b7fe-e8cf-4ffa-936b-c6efb52694bb\"},{\"function-name\":\"org.junit.runners.ParentRunner$1.schedule\",\"line\":79,\"source-code\":\"86deee3a-0e5f-495b-af66-5b2f36964ca2\"},{\"function-name\":\"org.junit.runners.ParentRunner.runChildren\",\"line\":329,\"source-code\":\"e7bd36c2-dd6a-4bb3-bac5-e5e606490c71\"},{\"function-name\":\"org.junit.runners.ParentRunner.access$100\",\"line\":66,\"source-code\":\"ea2aa6d0-8e27-402d-8836-9ede35629ac9\"},{\"function-name\":\"org.junit.runners.ParentRunner$2.evaluate\",\"line\":293,\"source-code\":\"23444a66-f715-444f-afcb-f367a6f72689\"},{\"function-name\":\"org.junit.runners.ParentRunner$3.evaluate\",\"line\":306,\"source-code\":\"0952a91a-0c4b-45f2-93c7-e744a7e64ded\"},{\"function-name\":\"org.junit.runners.ParentRunner.run\",\"line\":413,\"source-code\":\"6e8a4d01-3519-4742-be84-34da0dac2460\"},{\"function-name\":\"androidx.test.ext.junit.runners.AndroidJUnit4.run\",\"line\":162,\"source-code\":\"e1c31c4a-9f5f-4aae-8f74-29c5f7398e4d\"},{\"function-name\":\"org.junit.runners.Suite.runChild\",\"line\":128,\"source-code\":\"24d96335-14d8-45d8-a07d-fc24bc56d4db\"},{\"function-name\":\"org.junit.runners.Suite.runChild\",\"line\":27,\"source-code\":\"cfe92970-ae80-45b4-9dd4-8099919a1c26\"},{\"function-name\":\"org.junit.runners.ParentRunner$4.run\",\"line\":331,\"source-code\":\"5ad3ea57-08bc-42b9-a0af-4c0b63abd5d7\"},{\"function-name\":\"org.junit.runners.ParentRunner$1.schedule\",\"line\":79,\"source-code\":\"9b765b76-8714-4dc2-8584-c58e57d0b97d\"},{\"function-name\":\"org.junit.runners.ParentRunner.runChildren\",\"line\":329,\"source-code\":\"ddf80aac-8ae4-42cc-9d35-5dae41fbf626\"},{\"function-name\":\"org.junit.runners.ParentRunner.access$100\",\"line\":66,\"source-code\":\"b1cc1675-df0c-4bda-9ec2-cc50d02b7497\"},{\"function-name\":\"org.junit.runners.ParentRunner$2.evaluate\",\"line\":293,\"source-code\":\"bbf3d67c-a184-49ee-b0d5-b02188e3fa30\"},{\"function-name\":\"org.junit.runners.ParentRunner$3.evaluate\",\"line\":306,\"source-code\":\"61876082-acce-458e-8248-bfb03dc2b340\"},{\"function-name\":\"org.junit.runners.ParentRunner.run\",\"line\":413,\"source-code\":\"4d79837a-1751-47e1-a134-d883871a9cec\"},{\"function-name\":\"org.junit.runner.JUnitCore.run\",\"line\":137,\"source-code\":\"0a88f8a1-60c0-41a0-a95c-d75de5a4c82d\"},{\"function-name\":\"org.junit.runner.JUnitCore.run\",\"line\":115,\"source-code\":\"351d6b15-5d61-4a8a-9a06-5b14bf071945\"},{\"function-name\":\"androidx.test.internal.runner.TestExecutor.execute\",\"line\":67,\"source-code\":\"76276ba5-69ae-4815-8a9c-77525b526cb1\"},{\"function-name\":\"androidx.test.internal.runner.TestExecutor.execute\",\"line\":58,\"source-code\":\"9ae72a6b-31be-435f-8a52-461f043b492b\"},{\"function-name\":\"androidx.test.runner.AndroidJUnitRunner.onStart\",\"line\":446,\"source-code\":\"a4ef001f-1238-4b6e-9e57-aaa3dc1717ce\"},{\"function-name\":\"android.app.Instrumentation$InstrumentationThread.run\",\"line\":2205,\"source-code\":\"a67eccc1-bd1c-4207-93a5-db20e09b79aa\"}]},\"binder:8909_1\":{\"fault\":false,\"name\":\"binder:8909_1\",\"stack\":[]},\"heaptaskdaemon\":{\"fault\":false,\"name\":\"heaptaskdaemon\",\"stack\":[]},\"binder:8909_2\":{\"fault\":false,\"name\":\"binder:8909_2\",\"stack\":[]}},\"timestamp\":1707253867,\"uuid\":\"8e68b676-21cb-4cc8-ac2e-32a60e8d29c1\"}"; + String backtraceDataJson = readFileAsString(this, "backtraceData.json"); // WHEN final BacktraceData result = BacktraceDeserializer.deserialize(new JSONObject(backtraceDataJson), BacktraceData.class); // THEN assertNotNull(result); - assertEquals("8e68b676-21cb-4cc8-ac2e-32a60e8d29c1", result.uuid); + assertEquals("398dad51-7c39-4d64-941c-854de56f5f2b", result.uuid); assertEquals("java", result.lang); assertEquals("backtrace-android", result.agent); assertEquals("", result.symbolication); // TODO: check - assertEquals(1707253867, result.timestamp); + assertEquals(1709680075, result.timestamp); assertEquals("0", result.langVersion); - assertEquals("3.7.12-8-3686709-org-json-serializer", result.agentVersion); + assertEquals("3.7.14-1-931f45d", result.agentVersion); assertEquals("instr: androidx.test.runner.androidjunitrunner", result.mainThread); - assertEquals(0, result.classifiers.length); + assertEquals(1, result.classifiers.length); + assertEquals("java.lang.IllegalAccessException", result.classifiers[0]); assertNull(result.report); // THEN Attributes - assertEquals(result.attributes.size(), 39); + assertEquals(result.attributes.size(), 41); assertEquals(result.attributes.get("application"), "backtraceio.library.test"); - assertEquals(result.attributes.get("error.type"), "Message"); + assertEquals(result.attributes.get("error.type"), "Exception"); // THEN Annotations - assertEquals(2, result.annotations.size()); - assertEquals("Example test string", ((Map) result.annotations.get("Exception")).get("message")); - assertNotNull(result.annotations.get("Environment Variables")); + assertEquals(5, result.annotations.size()); + assertEquals("Test", ((Map) result.annotations.get("Exception")).get("message")); + assertNotNull(result.annotations.get("Exception properties")); + assertEquals("Test", ((Map) result.annotations.get("Exception properties")).get("detail-message")); + assertNotNull(result.annotations.get("1")); + assertNotNull(result.annotations.get("123")); // THEN Source Code - assertEquals(result.sourceCode.size(), 37); - SourceCode firstSourceCode = result.sourceCode.get("5ad3ea57-08bc-42b9-a0af-4c0b63abd5d7"); + assertEquals(result.sourceCode.size(), 35); + SourceCode firstSourceCode = result.sourceCode.get("ca0a50a1-d553-4479-8fe2-28c3f527743b"); assertEquals(firstSourceCode.sourceCodeFileName, "ParentRunner.java"); - assertEquals(firstSourceCode.startLine.intValue(), 331); - - assertEquals(result.sourceCode.get(0), 37); + assertEquals(firstSourceCode.startLine.intValue(), 306); // assertEquals(); // THEN Thread informations - assertEquals(result.getThreadInformationMap().size(), 14); - ThreadInformation threadInformation = result.getThreadInformationMap().get(13); - assertEquals(threadInformation.getFault(), ""); - assertEquals(threadInformation.getName(), ""); - assertEquals(threadInformation.getStack(), ""); + assertEquals(result.getThreadInformationMap().size(), 13); + ThreadInformation threadInformation = result.getThreadInformationMap().get("finalizerwatchdogdaemon"); + assertEquals(threadInformation.getFault(), false); + assertEquals(threadInformation.getName(), "finalizerwatchdogdaemon"); + assertNotNull(threadInformation.getStack()); + assertEquals(threadInformation.getStack().get(1).sourceCode, "4f359140-a606-4f5d-ba67-adb387383d43"); + assertEquals(threadInformation.getStack().get(1).sourceCodeFileName, null); + assertEquals(threadInformation.getStack().get(1).functionName, "java.lang.Object.wait"); + assertEquals(threadInformation.getStack().get(1).line.intValue(), 442); } } 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..c20aed4f --- /dev/null +++ b/backtrace-library/src/test/java/backtraceio/library/TestUtils.java @@ -0,0 +1,29 @@ +package backtraceio.library; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +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; + } +} diff --git a/backtrace-library/src/test/resources/backtraceData.json b/backtrace-library/src/test/resources/backtraceData.json new file mode 100644 index 00000000..742cf483 --- /dev/null +++ b/backtrace-library/src/test/resources/backtraceData.json @@ -0,0 +1 @@ +{"agent":"backtrace-android","agentVersion":"3.7.14-1-931f45d","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","PATH":"/product/bin:/apex/com.android.runtime/bin:/apex/com.android.art/bin:/system_ext/bin:/system/bin:/system/xbin:/odm/bin:/vendor/bin:/vendor/xbin","ANDROID_SOCKET_zygote":"17","ANDROID_I18N_ROOT":"/apex/com.android.i18n","ANDROID_DATA":"/data","ASEC_MOUNTPOINT":"/mnt/asec","ANDROID_TZDATA_ROOT":"/apex/com.android.tzdata","EXTERNAL_STORAGE":"/sdcard","ANDROID_BOOTLOGO":"1","ANDROID_ASSETS":"/system/app","ANDROID_STORAGE":"/storage","DEX2OATBOOTCLASSPATH":"/apex/com.android.art/javalib/core-oj.jar:/apex/com.android.art/javalib/core-libart.jar:/apex/com.android.art/javalib/core-icu4j.jar:/apex/com.android.art/javalib/okhttp.jar:/apex/com.android.art/javalib/bouncycastle.jar:/apex/com.android.art/javalib/apache-xml.jar:/system/framework/framework.jar:/system/framework/ext.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/framework-atb-backward-compatibility.jar","ANDROID_ART_ROOT":"/apex/com.android.art","ANDROID_ROOT":"/system","DOWNLOAD_CACHE":"/data/cache","BOOTCLASSPATH":"/apex/com.android.art/javalib/core-oj.jar:/apex/com.android.art/javalib/core-libart.jar:/apex/com.android.art/javalib/core-icu4j.jar:/apex/com.android.art/javalib/okhttp.jar:/apex/com.android.art/javalib/bouncycastle.jar:/apex/com.android.art/javalib/apache-xml.jar:/system/framework/framework.jar:/system/framework/ext.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/framework-atb-backward-compatibility.jar:/apex/com.android.conscrypt/javalib/conscrypt.jar:/apex/com.android.media/javalib/updatable-media.jar:/apex/com.android.mediaprovider/javalib/framework-mediaprovider.jar:/apex/com.android.os.statsd/javalib/framework-statsd.jar:/apex/com.android.permission/javalib/framework-permission.jar:/apex/com.android.sdkext/javalib/framework-sdkextensions.jar:/apex/com.android.wifi/javalib/framework-wifi.jar:/apex/com.android.tethering/javalib/framework-tethering.jar","ANDROID_SOCKET_usap_pool_primary":"22"},"1":{"detail-message":"Test-message","stack-trace":[],"suppressed-exceptions":[]},"123":{"detail-message":"Another exception","stack-trace":[],"suppressed-exceptions":[]},"Exception properties":{"detail-message":"Test","stack-trace":[{"declaring-class":"backtraceio.library.SettingAttributesTest","file-name":"SettingAttributesTest.java","line-number":61,"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":{"message":"Test"}},"attributes":{"application.session":"8a834365-a1f7-4fb0-937c-fe1ca84f041b","device.nfc.status":"NotAvailable","device.cpu.temperature":"0.0","system.memory.active":"981274624","device.wifi.status":"Disabled","screen.height":"1834","uname.machine":"i686","screen.dpi":"288","device.bluetooth_status":"NotPermitted","device.airplane_mode":"false","classifier":"java.lang.IllegalAccessException","system.memory.total":"2077347840","device.sdk":"30","key":"false","device.brand":"google","uname.sysname":"Android","cpu.boottime":"1709621937678","device.os_version":"5.4.61-android11-0-00791-gbad091cc4bf3-ab6833933","device.gps.enabled":"Enabled","application.package":"backtraceio.library.test","uname.version":"11","backtrace.version":"3.7.14-1-931f45d","device.is_power_saving_mode":"false","screen.orientation":"Portrait","device.manufacturer":"Google","system.memory.free":"1096073216","battery.state":"Unplugged","backtrace.agent":"backtrace-android","error.type":"Exception","device.location":"Enabled","application":"backtraceio.library.test","error.message":"Test","culture":"English","device.model":"sdk_gphone_x86","screen.width":"1080","build.type":"Debug","device.product":"sdk_gphone_x86","guid":"e4c57699-0dc9-35e2-b4a0-2ffff1925ca7","app.storage_used":"2990720","battery.level":"1.0","screen.brightness":"102"},"classifiers":["java.lang.IllegalAccessException"],"lang":"java","langVersion":"0","mainThread":"instr: androidx.test.runner.androidjunitrunner","sourceCode":{"0d619b24-4484-47ce-a83a-f2922671a47a":{"path":"Method.java"},"ca0a50a1-d553-4479-8fe2-28c3f527743b":{"path":"ParentRunner.java","startLine":306},"49f16751-a846-4e09-8f8c-c6b5755b5e9b":{"path":"InvokeMethod.java","startLine":17},"510905e8-d411-4f4f-bc31-1e385f298781":{"path":"AndroidJUnitRunner.java","startLine":446},"f1c89597-b75a-43de-bd06-48c3222c6b1f":{"path":"TestExecutor.java","startLine":67},"a18a7ea7-4145-428e-9dc1-54cca9903051":{"path":"ParentRunner.java","startLine":329},"5c63fbbd-3a0e-4088-803e-f93c237c1f45":{"path":"ParentRunner.java","startLine":293},"d80839b2-8f5c-4a59-aac7-7590429fbb72":{"path":"ParentRunner.java","startLine":293},"cd3260f0-44a8-4f26-a2e8-039f25aab865":{"path":"BlockJUnit4ClassRunner.java","startLine":100},"a9c0ee95-83b2-47a5-b65e-025663c33589":{"path":"Suite.java","startLine":27},"c90e3f7b-afc6-486c-abb7-5d25dcdc6d58":{"path":"ParentRunner.java","startLine":306},"acf17580-69f3-4b97-a500-7a988f674086":{"path":"SettingAttributesTest.java","startLine":61},"ef1c9c6c-f3e2-444b-b471-c50b55e2f13d":{"path":"BlockJUnit4ClassRunner.java","startLine":103},"2b21aa76-a40b-4b90-910f-483723440468":{"path":"AndroidJUnit4.java","startLine":162},"07cc53cb-1ff0-4e3a-8d5b-d51a6bd36a82":{"path":"ParentRunner.java","startLine":366},"1290819f-6bbf-4db3-9946-0ce3208cc227":{"path":"ParentRunner.java","startLine":79},"380123bc-73c0-4ea1-ab07-36b3d9edb476":{"path":"ReflectiveCallable.java","startLine":12},"e844e0cf-4dac-476e-a67e-ae13a49e114a":{"path":"FrameworkMethod.java","startLine":59},"8f6f57da-218e-4744-b395-2e960ce0909f":{"path":"BlockJUnit4ClassRunner.java","startLine":63},"f5aa1c63-708c-4ebd-92ff-2d5b7bbabc76":{"path":"ParentRunner.java","startLine":413},"ac094d10-223d-4a3a-9e34-554b4ffe9d68":{"path":"ParentRunner.java","startLine":66},"a1e94af3-b1f1-42d3-8698-c79c7bfffb5c":{"path":"ParentRunner.java","startLine":413},"ef7e55ae-72f5-48fd-a1d7-d0456a5665c5":{"path":"FrameworkMethod.java","startLine":56},"5f4c9e78-a835-4e0e-b3ce-764fd54bbbcb":{"path":"JUnitCore.java","startLine":115},"bc1e3d86-1605-4a6d-934f-139b616fdfd1":{"path":"ParentRunner.java","startLine":331},"bd092922-6269-46ea-b8b3-9fe19150cf12":{"path":"RunBefores.java","startLine":80},"c50ee7ea-1fd9-404b-8575-2b0f9ec02be8":{"path":"JUnitCore.java","startLine":137},"99ca899d-f0ea-42c2-a493-04812ca559cb":{"path":"TestExecutor.java","startLine":58},"918fe7f4-b0ec-45bf-95a8-01e4df8cc689":{"path":"ParentRunner.java","startLine":306},"0266df08-f20b-4987-b3e1-3c9ea87e52c3":{"path":"Suite.java","startLine":128},"ef83875d-d036-4f0b-9ba1-3412c645e01b":{"path":"ParentRunner.java","startLine":79},"d7fcfa69-4904-423e-85f5-28008daf9396":{"path":"Instrumentation.java","startLine":2205},"49c97f9a-8ae0-496b-a94b-ff3d83abea63":{"path":"ParentRunner.java","startLine":66},"f9ec00bd-802c-4c36-8863-b90c29991a59":{"path":"ParentRunner.java","startLine":331},"af73d037-6118-41d6-8c5e-68909c5b4cae":{"path":"ParentRunner.java","startLine":329}},"threads":{"profile saver":{"fault":false,"name":"profile saver","stack":[]},"binder:4109_3":{"fault":false,"name":"binder:4109_3","stack":[]},"signal catcher":{"fault":false,"name":"signal catcher","stack":[]},"binder:4109_1":{"fault":false,"name":"binder:4109_1","stack":[]},"finalizerwatchdogdaemon":{"fault":false,"name":"finalizerwatchdogdaemon","stack":[{"funcName":"java.lang.Object.wait","sourceCode":"223a0637-b9f7-45b1-a075-e9c76e087c68"},{"funcName":"java.lang.Object.wait","line":442,"sourceCode":"4f359140-a606-4f5d-ba67-adb387383d43"},{"funcName":"java.lang.Object.wait","line":568,"sourceCode":"6b046834-2148-4fff-9b6c-98dba736fbfc"},{"funcName":"java.lang.Daemons$FinalizerWatchdogDaemon.sleepUntilNeeded","line":341,"sourceCode":"e0742ba8-99ab-4f9d-8f8b-f1a2ca4ae53e"},{"funcName":"java.lang.Daemons$FinalizerWatchdogDaemon.runInternal","line":321,"sourceCode":"b379b271-8b33-4ae7-b79f-71c56bfbfa2f"},{"funcName":"java.lang.Daemons$Daemon.run","line":139,"sourceCode":"50fbe298-fa92-43b1-a5a1-08589e673e5a"},{"funcName":"java.lang.Thread.run","line":923,"sourceCode":"554c09ea-a4b8-4809-bb69-a7df21e4c0af"}]},"binder:4109_2":{"fault":false,"name":"binder:4109_2","stack":[]},"main":{"fault":false,"name":"main","stack":[{"funcName":"android.os.MessageQueue.nativePollOnce","sourceCode":"758ec023-78db-42d7-a4a7-c6c291059a56"},{"funcName":"android.os.MessageQueue.next","line":335,"sourceCode":"fed2a4a5-0b0a-4dd1-a96f-51fa1121cdf4"},{"funcName":"android.os.Looper.loop","line":183,"sourceCode":"4782b0d3-8800-4897-92c6-64cf17e67b8f"},{"funcName":"android.app.ActivityThread.main","line":7656,"sourceCode":"a5e47b8f-e331-49c1-8179-80ae517b263e"},{"funcName":"java.lang.reflect.Method.invoke","sourceCode":"fc72e5f5-0f14-4ee5-91e6-73570c271530"},{"funcName":"com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run","line":592,"sourceCode":"37013d3c-f962-4cb8-919e-553bc43d2577"},{"funcName":"com.android.internal.os.ZygoteInit.main","line":947,"sourceCode":"07ed3f99-e7c0-40f0-a398-1d1aff7231e2"}]},"finalizerdaemon":{"fault":false,"name":"finalizerdaemon","stack":[{"funcName":"java.lang.Object.wait","sourceCode":"52c14a22-0f24-49aa-a49d-725dab99e41c"},{"funcName":"java.lang.Object.wait","line":442,"sourceCode":"3c86cb0f-e6f3-4bda-a0cc-a6b5a5069fa1"},{"funcName":"java.lang.ref.ReferenceQueue.remove","line":190,"sourceCode":"d5b11d05-3eb5-4585-8672-c6c957323d38"},{"funcName":"java.lang.ref.ReferenceQueue.remove","line":211,"sourceCode":"bc76dd76-62b6-4752-b726-4a6a4c3a710f"},{"funcName":"java.lang.Daemons$FinalizerDaemon.runInternal","line":273,"sourceCode":"d6897d2a-32f7-4f7b-b70e-ed817a7cb6ef"},{"funcName":"java.lang.Daemons$Daemon.run","line":139,"sourceCode":"0821f15f-d9d6-4fa6-aee1-cdb2513ba039"},{"funcName":"java.lang.Thread.run","line":923,"sourceCode":"b1d6f758-2bf1-47f4-a71a-8b20db2e3c9c"}]},"referencequeuedaemon":{"fault":false,"name":"referencequeuedaemon","stack":[{"funcName":"java.lang.Object.wait","sourceCode":"13098981-5d81-46e9-b20c-a97775b9809d"},{"funcName":"java.lang.Object.wait","line":442,"sourceCode":"9f3c26ab-3dbc-435a-a611-756bcd7ed185"},{"funcName":"java.lang.Object.wait","line":568,"sourceCode":"699421b6-e827-46b0-8125-621eb1d0550b"},{"funcName":"java.lang.Daemons$ReferenceQueueDaemon.runInternal","line":217,"sourceCode":"bf83f06c-c088-4cea-ac7b-ca8294940c17"},{"funcName":"java.lang.Daemons$Daemon.run","line":139,"sourceCode":"5c6ef27e-3694-47bb-82a8-b942f562edae"},{"funcName":"java.lang.Thread.run","line":923,"sourceCode":"b0dd03ce-ecbd-4cdb-87b9-dcd72391eea8"}]},"instrumentationconnectionthread":{"fault":false,"name":"instrumentationconnectionthread","stack":[{"funcName":"android.os.MessageQueue.nativePollOnce","sourceCode":"a3ad1195-620f-47e2-bbcf-5ad5d7896320"},{"funcName":"android.os.MessageQueue.next","line":335,"sourceCode":"bc0095ba-5087-4af6-b461-1a03536a14d5"},{"funcName":"android.os.Looper.loop","line":183,"sourceCode":"e35c39fc-5edf-400e-9c11-78fbd744cb33"},{"funcName":"android.os.HandlerThread.run","line":67,"sourceCode":"d8cdab8e-f8ba-46b6-89e5-254708edbb53"}]},"jit thread pool worker thread 0":{"fault":false,"name":"jit thread pool worker thread 0","stack":[]},"instr: androidx.test.runner.androidjunitrunner":{"fault":true,"name":"instr: androidx.test.runner.androidjunitrunner","stack":[{"funcName":"backtraceio.library.SettingAttributesTest.tmpGsonTest","line":61,"sourceCode":"acf17580-69f3-4b97-a500-7a988f674086"},{"funcName":"java.lang.reflect.Method.invoke","sourceCode":"0d619b24-4484-47ce-a83a-f2922671a47a"},{"funcName":"org.junit.runners.model.FrameworkMethod$1.runReflectiveCall","line":59,"sourceCode":"e844e0cf-4dac-476e-a67e-ae13a49e114a"},{"funcName":"org.junit.internal.runners.model.ReflectiveCallable.run","line":12,"sourceCode":"380123bc-73c0-4ea1-ab07-36b3d9edb476"},{"funcName":"org.junit.runners.model.FrameworkMethod.invokeExplosively","line":56,"sourceCode":"ef7e55ae-72f5-48fd-a1d7-d0456a5665c5"},{"funcName":"org.junit.internal.runners.statements.InvokeMethod.evaluate","line":17,"sourceCode":"49f16751-a846-4e09-8f8c-c6b5755b5e9b"},{"funcName":"androidx.test.internal.runner.junit4.statement.RunBefores.evaluate","line":80,"sourceCode":"bd092922-6269-46ea-b8b3-9fe19150cf12"},{"funcName":"org.junit.runners.ParentRunner$3.evaluate","line":306,"sourceCode":"c90e3f7b-afc6-486c-abb7-5d25dcdc6d58"},{"funcName":"org.junit.runners.BlockJUnit4ClassRunner$1.evaluate","line":100,"sourceCode":"cd3260f0-44a8-4f26-a2e8-039f25aab865"},{"funcName":"org.junit.runners.ParentRunner.runLeaf","line":366,"sourceCode":"07cc53cb-1ff0-4e3a-8d5b-d51a6bd36a82"},{"funcName":"org.junit.runners.BlockJUnit4ClassRunner.runChild","line":103,"sourceCode":"ef1c9c6c-f3e2-444b-b471-c50b55e2f13d"},{"funcName":"org.junit.runners.BlockJUnit4ClassRunner.runChild","line":63,"sourceCode":"8f6f57da-218e-4744-b395-2e960ce0909f"},{"funcName":"org.junit.runners.ParentRunner$4.run","line":331,"sourceCode":"f9ec00bd-802c-4c36-8863-b90c29991a59"},{"funcName":"org.junit.runners.ParentRunner$1.schedule","line":79,"sourceCode":"ef83875d-d036-4f0b-9ba1-3412c645e01b"},{"funcName":"org.junit.runners.ParentRunner.runChildren","line":329,"sourceCode":"a18a7ea7-4145-428e-9dc1-54cca9903051"},{"funcName":"org.junit.runners.ParentRunner.access$100","line":66,"sourceCode":"ac094d10-223d-4a3a-9e34-554b4ffe9d68"},{"funcName":"org.junit.runners.ParentRunner$2.evaluate","line":293,"sourceCode":"d80839b2-8f5c-4a59-aac7-7590429fbb72"},{"funcName":"org.junit.runners.ParentRunner$3.evaluate","line":306,"sourceCode":"918fe7f4-b0ec-45bf-95a8-01e4df8cc689"},{"funcName":"org.junit.runners.ParentRunner.run","line":413,"sourceCode":"f5aa1c63-708c-4ebd-92ff-2d5b7bbabc76"},{"funcName":"androidx.test.ext.junit.runners.AndroidJUnit4.run","line":162,"sourceCode":"2b21aa76-a40b-4b90-910f-483723440468"},{"funcName":"org.junit.runners.Suite.runChild","line":128,"sourceCode":"0266df08-f20b-4987-b3e1-3c9ea87e52c3"},{"funcName":"org.junit.runners.Suite.runChild","line":27,"sourceCode":"a9c0ee95-83b2-47a5-b65e-025663c33589"},{"funcName":"org.junit.runners.ParentRunner$4.run","line":331,"sourceCode":"bc1e3d86-1605-4a6d-934f-139b616fdfd1"},{"funcName":"org.junit.runners.ParentRunner$1.schedule","line":79,"sourceCode":"1290819f-6bbf-4db3-9946-0ce3208cc227"},{"funcName":"org.junit.runners.ParentRunner.runChildren","line":329,"sourceCode":"af73d037-6118-41d6-8c5e-68909c5b4cae"},{"funcName":"org.junit.runners.ParentRunner.access$100","line":66,"sourceCode":"49c97f9a-8ae0-496b-a94b-ff3d83abea63"},{"funcName":"org.junit.runners.ParentRunner$2.evaluate","line":293,"sourceCode":"5c63fbbd-3a0e-4088-803e-f93c237c1f45"},{"funcName":"org.junit.runners.ParentRunner$3.evaluate","line":306,"sourceCode":"ca0a50a1-d553-4479-8fe2-28c3f527743b"},{"funcName":"org.junit.runners.ParentRunner.run","line":413,"sourceCode":"a1e94af3-b1f1-42d3-8698-c79c7bfffb5c"},{"funcName":"org.junit.runner.JUnitCore.run","line":137,"sourceCode":"c50ee7ea-1fd9-404b-8575-2b0f9ec02be8"},{"funcName":"org.junit.runner.JUnitCore.run","line":115,"sourceCode":"5f4c9e78-a835-4e0e-b3ce-764fd54bbbcb"},{"funcName":"androidx.test.internal.runner.TestExecutor.execute","line":67,"sourceCode":"f1c89597-b75a-43de-bd06-48c3222c6b1f"},{"funcName":"androidx.test.internal.runner.TestExecutor.execute","line":58,"sourceCode":"99ca899d-f0ea-42c2-a493-04812ca559cb"},{"funcName":"androidx.test.runner.AndroidJUnitRunner.onStart","line":446,"sourceCode":"510905e8-d411-4f4f-bc31-1e385f298781"},{"funcName":"android.app.Instrumentation$InstrumentationThread.run","line":2205,"sourceCode":"d7fcfa69-4904-423e-85f5-28008daf9396"}]},"heaptaskdaemon":{"fault":false,"name":"heaptaskdaemon","stack":[]}},"timestamp":1709680075,"uuid":"398dad51-7c39-4d64-941c-854de56f5f2b"} \ 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..3f6a28ce --- /dev/null +++ b/backtrace-library/src/test/resources/backtraceReport.json @@ -0,0 +1 @@ +{"attachment-paths":[],"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"},{"funcName":"org.junit.runners.model.FrameworkMethod$1.runReflectiveCall","line":59,"sourceCode":"bd149fbf-b1c5-43af-a53e-18d613140f4d"},{"funcName":"org.junit.internal.runners.model.ReflectiveCallable.run","line":12,"sourceCode":"183d6033-e096-4fd8-a190-d8947354aaa9"},{"funcName":"org.junit.runners.model.FrameworkMethod.invokeExplosively","line":56,"sourceCode":"bf114ba5-c2f5-41b2-a7c2-80d4f30eacdc"},{"funcName":"org.junit.internal.runners.statements.InvokeMethod.evaluate","line":17,"sourceCode":"8d499ef4-7bf9-49f7-a06e-9c34ba4ccc69"},{"funcName":"androidx.test.internal.runner.junit4.statement.RunBefores.evaluate","line":80,"sourceCode":"8c80c122-14e9-4ee5-bc48-8da38ec9d0a9"},{"funcName":"org.junit.runners.ParentRunner$3.evaluate","line":306,"sourceCode":"174e6e74-76c5-4d08-a58c-64c24aaf6ea0"},{"funcName":"org.junit.runners.BlockJUnit4ClassRunner$1.evaluate","line":100,"sourceCode":"4a45c684-03cb-4d07-93ce-04cb6ae4dd00"},{"funcName":"org.junit.runners.ParentRunner.runLeaf","line":366,"sourceCode":"3105e506-3104-489f-ad24-1b3cbe610e32"},{"funcName":"org.junit.runners.BlockJUnit4ClassRunner.runChild","line":103,"sourceCode":"dd7ba2ca-f129-4806-894d-e8e8e61290c2"},{"funcName":"org.junit.runners.BlockJUnit4ClassRunner.runChild","line":63,"sourceCode":"ab513a09-13b2-4ae5-8e1b-2be51b8e6df1"},{"funcName":"org.junit.runners.ParentRunner$4.run","line":331,"sourceCode":"8fa6d1d6-adc9-47e4-8db5-bf8ae79e1791"},{"funcName":"org.junit.runners.ParentRunner$1.schedule","line":79,"sourceCode":"03cefd46-7ebf-4713-a438-2534757338b3"},{"funcName":"org.junit.runners.ParentRunner.runChildren","line":329,"sourceCode":"c6b95075-3b03-4acb-ac84-6b64ef8dc8c4"},{"funcName":"org.junit.runners.ParentRunner.access$100","line":66,"sourceCode":"83631ebc-436d-4218-871b-cdda0be927cc"},{"funcName":"org.junit.runners.ParentRunner$2.evaluate","line":293,"sourceCode":"bd0ebabf-dff6-4662-a7ce-4d2f8882b610"},{"funcName":"org.junit.runners.ParentRunner$3.evaluate","line":306,"sourceCode":"e6eb219d-8698-449e-989f-fe265086791d"},{"funcName":"org.junit.runners.ParentRunner.run","line":413,"sourceCode":"dea0b948-ce57-4b5c-b0f9-aaf59c9e982e"},{"funcName":"androidx.test.ext.junit.runners.AndroidJUnit4.run","line":162,"sourceCode":"300e5627-ccde-4d88-ad18-af12acf4b314"},{"funcName":"org.junit.runners.Suite.runChild","line":128,"sourceCode":"c934c1cb-f20f-4da2-8d1e-9cac80e3f29b"},{"funcName":"org.junit.runners.Suite.runChild","line":27,"sourceCode":"ccd786d2-f763-4cc3-982a-493f8cb0a0e8"},{"funcName":"org.junit.runners.ParentRunner$4.run","line":331,"sourceCode":"fd16c8e6-7ac7-470a-990e-1703b301bfbb"},{"funcName":"org.junit.runners.ParentRunner$1.schedule","line":79,"sourceCode":"9a4d6c39-c233-4823-b632-73cd764996f3"},{"funcName":"org.junit.runners.ParentRunner.runChildren","line":329,"sourceCode":"f02dd76d-8093-4a34-81a0-4e79b383f13e"},{"funcName":"org.junit.runners.ParentRunner.access$100","line":66,"sourceCode":"8c34280e-fa49-451e-bd26-27cb76f9a836"},{"funcName":"org.junit.runners.ParentRunner$2.evaluate","line":293,"sourceCode":"457c3c30-cbf1-474b-8ac5-b0a12a2a98fc"},{"funcName":"org.junit.runners.ParentRunner$3.evaluate","line":306,"sourceCode":"d0ca0f81-5018-4ecc-b890-bd4c561c3d34"},{"funcName":"org.junit.runners.ParentRunner.run","line":413,"sourceCode":"35799925-5686-4d9c-b4e9-2644043ecd29"},{"funcName":"org.junit.runner.JUnitCore.run","line":137,"sourceCode":"a3872d95-0550-4931-b31c-9707cd89a5a5"},{"funcName":"org.junit.runner.JUnitCore.run","line":115,"sourceCode":"4d8f9dac-7bcf-4c7c-adbd-231daca51a53"},{"funcName":"androidx.test.internal.runner.TestExecutor.execute","line":67,"sourceCode":"612fc16a-f056-4d49-8e45-82d25d05dfb7"},{"funcName":"androidx.test.internal.runner.TestExecutor.execute","line":58,"sourceCode":"37fd34c2-0c59-4567-8145-b4cadc9a5a9f"},{"funcName":"androidx.test.runner.AndroidJUnitRunner.onStart","line":446,"sourceCode":"c03ef402-39c5-47d3-8871-4367dec69712"},{"funcName":"android.app.Instrumentation$InstrumentationThread.run","line":2205,"sourceCode":"dfead18b-f0de-4c9f-9812-627322b44860"}],"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/androidTest/resources/backtraceResult.error.json b/backtrace-library/src/test/resources/backtraceResult.error.json similarity index 100% rename from backtrace-library/src/androidTest/resources/backtraceResult.error.json rename to backtrace-library/src/test/resources/backtraceResult.error.json diff --git a/backtrace-library/src/androidTest/resources/backtraceResult.json b/backtrace-library/src/test/resources/backtraceResult.json similarity index 100% rename from backtrace-library/src/androidTest/resources/backtraceResult.json rename to backtrace-library/src/test/resources/backtraceResult.json From 6daa876d51e62e36ded10518d16f34b9dd43ec15 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 3 Apr 2024 19:45:49 +0200 Subject: [PATCH 034/100] Remove unused file --- .../BacktraceDataDeserializer.java | 234 ------------------ 1 file changed, 234 deletions(-) delete mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataDeserializer.java diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataDeserializer.java deleted file mode 100644 index 2c5e703c..00000000 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataDeserializer.java +++ /dev/null @@ -1,234 +0,0 @@ -package backtraceio.library.common.serializers; - -import android.content.Context; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.UUID; - -import backtraceio.library.models.BacktraceData; -import backtraceio.library.models.BacktraceStackFrame; -import backtraceio.library.models.json.BacktraceReport; -import backtraceio.library.models.json.SourceCode; -import backtraceio.library.models.json.ThreadInformation; - -public class BacktraceDataDeserializer { -// -// public static BacktraceData deserialize(Context context, JSONObject obj) throws JSONException { -// BacktraceReport report = BacktraceDataDeserializer.deserializeReport(context, obj.optJSONObject("report")); -// BacktraceData backtraceData = new BacktraceData.Builder(context, report, new HashMap<>()).build(); // todo: fix ??? -// -// backtraceData.symbolication = obj.optString("symbolication"); -// backtraceData.uuid = obj.optString("uuid"); -// backtraceData.timestamp = obj.optLong("timestamp"); -// backtraceData.langVersion = obj.optString("langVersion"); -// backtraceData.agentVersion = obj.optString("agentVersion"); -// backtraceData.mainThread = obj.optString("mainThread"); -// -// JSONArray classifiersArray = obj.optJSONArray("classifiers"); -// if (classifiersArray != null) { -// backtraceData.classifiers = new String[classifiersArray.length()]; -// for (int i = 0; i < classifiersArray.length(); i++) { -// backtraceData.classifiers[i] = classifiersArray.optString(i); -// } -// } -// -// JSONObject attributesObj = obj.optJSONObject("attributes"); -// if (attributesObj != null) { -// backtraceData.attributes = new HashMap<>(); -// Iterator attributesKeys = attributesObj.keys(); -// while (attributesKeys.hasNext()) { -// String key = attributesKeys.next(); -// backtraceData.attributes.put(key, attributesObj.optString(key)); -// } -// } -// -// JSONObject annotationsObj = obj.optJSONObject("annotations"); -// if (annotationsObj != null) { -// backtraceData.annotations = new HashMap<>(); -// Iterator annotationsKeys = annotationsObj.keys(); -// while (annotationsKeys.hasNext()) { -// String key = annotationsKeys.next(); -// backtraceData.annotations.put(key, annotationsObj.opt(key)); -// } -// } -// -// JSONObject sourceCodeObj = obj.optJSONObject("sourceCode"); -// if (sourceCodeObj != null) { -// backtraceData.sourceCode = new HashMap<>(); -// Iterator sourceCodeKeys = sourceCodeObj.keys(); -// while (sourceCodeKeys.hasNext()) { -// String key = sourceCodeKeys.next(); -// JSONObject sourceCodeItem = sourceCodeObj.optJSONObject(key); -// if (sourceCodeItem != null) { -//// SourceCode sourceCode = new SourceCode(); -//// sourceCode.startLine = sourceCodeItem.optInt("startLine"); -//// sourceCode.sourceCodeFileName = sourceCodeItem.optString("path"); -//// backtraceData.sourceCode.put(key, sourceCode); -// } -// } -// } -// -//// JSONObject threadInformationMapObj = obj.optJSONObject("threads"); -//// if (threadInformationMapObj != null) { -//// backtraceData.threadInformationMap = new HashMap<>(); -//// Iterator threadKeys = threadInformationMapObj.keys(); -//// while (threadKeys.hasNext()) { -//// String threadKey = threadKeys.next(); -//// JSONObject threadInfoObj = threadInformationMapObj.optJSONObject(threadKey); -//// if (threadInfoObj != null) { -//// ThreadInformation threadInformation = new ThreadInformation(); -//// threadInformation.name = threadInfoObj.optString("name"); -//// JSONArray stackArray = threadInfoObj.optJSONArray("stack"); -//// if (stackArray != null) { -//// threadInformation.stack = new ArrayList<>(); -//// for (int i = 0; i < stackArray.length(); i++) { -//// JSONObject stackItem = stackArray.optJSONObject(i); -//// if (stackItem != null) { -//// BacktraceStackFrame stackFrame = new BacktraceStackFrame(); -//// stackFrame.functionName = stackItem.optString("funcName"); -//// stackFrame.line = stackItem.optInt("line"); -//// stackFrame.sourceCode = stackItem.optString("sourceCode"); -//// threadInformation.stack.add(stackFrame); -//// } -//// } -//// } -//// backtraceData.threadInformationMap.put(threadKey, threadInformation); -//// } -//// } -//// } -// -// return backtraceData; -// } -// public static BacktraceReport deserializeReport(Context context, JSONObject obj) throws JSONException { -// if (obj == null ){ -// return null; -// } -// -// BacktraceReport report = new BacktraceReport(""); // todo: fix -// report.uuid = UUID.fromString(obj.optString("uuid")); -// report.timestamp = obj.optLong("timestamp"); -// report.exceptionTypeReport = obj.optBoolean("exceptionTypeReport"); -// report.classifier = obj.optString("classifier"); -// -// JSONArray attachmentPathsArray = obj.optJSONArray("attachmentPaths"); -// if (attachmentPathsArray != null) { -// report.attachmentPaths = new ArrayList<>(); -// for (int i = 0; i < attachmentPathsArray.length(); i++) { -// report.attachmentPaths.add(attachmentPathsArray.optString(i)); -// } -// } -// -// report.message = obj.optString("message"); -// -// // Deserialize exception field if needed -// -// JSONArray diagnosticStackArray = obj.optJSONArray("diagnosticStack"); -// if (diagnosticStackArray != null) { -// report.diagnosticStack = new ArrayList<>(); -// for (int i = 0; i < diagnosticStackArray.length(); i++) { -// JSONObject stackItem = diagnosticStackArray.optJSONObject(i); -// if (stackItem != null) { -// BacktraceStackFrame stackFrame = new BacktraceStackFrame(); -// stackFrame.functionName = stackItem.optString("funcName"); -// stackFrame.line = stackItem.optInt("line"); -// stackFrame.sourceCode = stackItem.optString("sourceCode"); -// report.diagnosticStack.add(stackFrame); -// } -// } -// } -// -// JSONObject exceptionObj = obj.optJSONObject("exception"); -// if (exceptionObj != null) { -// String exceptionClassName = exceptionObj.optString("className"); -// String exceptionMessage = exceptionObj.optString("message"); -// Exception exception = new Exception(exceptionMessage); -// exception.setStackTrace(parseStackFrames(exceptionObj.optJSONArray("stackTrace"))); -// report.exception = exception; -// } -// -// return report; -// } -// -// public static BacktraceData deserializeReportXYZ(Context context, JSONObject obj) throws JSONException { -// return null; // BL: Do we need below code? -//// BacktraceData backtraceData = new BacktraceData(context, null, null); // todo fix -// -// // ... (Deserialization logic for other fields) ... -// -// // Deserialize BacktraceReport -//// JSONObject reportObj = obj.optJSONObject("report"); -//// if (reportObj != null) { -//// BacktraceReport report = new BacktraceReport(""); -//// report.uuid = UUID.fromString(reportObj.optString("uuid")); -//// report.timestamp = reportObj.optLong("timestamp"); -//// report.exceptionTypeReport = reportObj.optBoolean("exceptionTypeReport"); -//// report.classifier = reportObj.optString("classifier"); -//// -//// JSONArray attachmentPathsArray = reportObj.optJSONArray("attachmentPaths"); -//// if (attachmentPathsArray != null) { -//// report.attachmentPaths = new ArrayList<>(); -//// for (int i = 0; i < attachmentPathsArray.length(); i++) { -//// report.attachmentPaths.add(attachmentPathsArray.optString(i)); -//// } -//// } -//// -//// report.message = reportObj.optString("message"); -//// -//// // Deserialize exception field -//// JSONObject exceptionObj = reportObj.optJSONObject("exception"); -//// if (exceptionObj != null) { -//// String exceptionClassName = exceptionObj.optString("className"); -//// String exceptionMessage = exceptionObj.optString("message"); -//// Exception exception = new Exception(exceptionMessage); -//// exception.setStackTrace(parseStackFrames(exceptionObj.optJSONArray("stackTrace"))); -//// report.exception = exception; -//// } -//// -//// JSONArray diagnosticStackArray = reportObj.optJSONArray("diagnosticStack"); -//// if (diagnosticStackArray != null) { -//// report.diagnosticStack = new ArrayList<>(); -//// for (int i = 0; i < diagnosticStackArray.length(); i++) { -//// JSONObject stackItem = diagnosticStackArray.optJSONObject(i); -//// if (stackItem != null) { -//// BacktraceStackFrame stackFrame = new BacktraceStackFrame(); -//// stackFrame.functionName = stackItem.optString("funcName"); -//// stackFrame.line = stackItem.optInt("line"); -//// stackFrame.sourceCode = stackItem.optString("sourceCode"); -//// report.diagnosticStack.add(stackFrame); -//// } -//// } -//// } -// -// // ... (Other deserialization for BacktraceReport fields) ... -// -//// backtraceData.report = report; -// } -// -//// return backtraceData; -// } -// -// private static StackTraceElement[] parseStackFrames(JSONArray stackTraceArray) { -// if (stackTraceArray == null) { -// return new StackTraceElement[0]; -// } -// StackTraceElement[] stackTrace = new StackTraceElement[stackTraceArray.length()]; -// for (int i = 0; i < stackTraceArray.length(); i++) { -// JSONObject stackItem = stackTraceArray.optJSONObject(i); -// if (stackItem != null) { -// String className = stackItem.optString("className"); -// String methodName = stackItem.optString("methodName"); -// String fileName = stackItem.optString("fileName"); -// int lineNumber = stackItem.optInt("lineNumber"); -// stackTrace[i] = new StackTraceElement(className, methodName, fileName, lineNumber); -// } -// } -// return stackTrace; -// } - -} \ No newline at end of file From 7c693fc5a10f224ec000d25f2cf6bb62bd4addf1 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 3 Apr 2024 19:55:11 +0200 Subject: [PATCH 035/100] Fix doc --- .../java/backtraceio/library/models/BacktraceApiResult.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceApiResult.java b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceApiResult.java index 829c437a..ae6a3438 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceApiResult.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceApiResult.java @@ -5,7 +5,7 @@ import backtraceio.library.models.types.BacktraceResultStatus; /** - * Send method result + * Coroner API response */ public class BacktraceApiResult { From 546968fdc864d040d9f2b270bdaed88a75e7a63b Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 3 Apr 2024 19:58:28 +0200 Subject: [PATCH 036/100] Code cleanup --- .../library/models/BacktraceData.java | 77 +++---------------- 1 file changed, 9 insertions(+), 68 deletions(-) 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 69d2a054..9a8e4eb4 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java @@ -16,6 +16,9 @@ import backtraceio.library.models.json.ThreadData; import backtraceio.library.models.json.ThreadInformation; + +// TODO: replace direct access with getters + /** * Serializable Backtrace API data object */ @@ -141,74 +144,6 @@ public Map getThreadInformationMap() { return threadInformationMap; } -// /*** -// * Set annotations object -// * @param complexAttributes -// */ -// private void 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); -// } - -// /** -// * Set attributes and add complex attributes to annotations -// * -// * @param context // TODO: -// * @param clientAttributes -// */ - - -// /** -// * Set report information such as report identifier (UUID), timestamp, classifier -// */ -// private void setDefaultReportInformation() { -// this.setReportInformation( -// report.uuid.toString(), -// report.timestamp, -// report.exceptionTypeReport ? new String[]{report.classifier} : null, -// System.getProperty("java.version"), //TODO: Fix problem with read Java version, -// BacktraceClient.version -// ); -// } - -// public void setReportInformation(String uuid, long timestamp, String [] classifiers, String langVersion, String agentVersion) { -// BacktraceLogger.d(LOG_TAG, "Setting report information"); -// this.uuid = uuid; -// this.timestamp = timestamp; -// this.classifiers = classifiers; -// this.langVersion = langVersion; -// this.agentVersion = agentVersion; -// } - -// /** -// * Set information about all threads -// */ -// private void setDefaultThreadsInformation() { -// BacktraceLogger.d(LOG_TAG, "Setting threads information"); -// -// ThreadData threadData = new ThreadData(report.diagnosticStack); -// SourceCodeData sourceCodeData = new SourceCodeData(report.diagnosticStack); -// -// this.setThreadsInformation( -// threadData.getMainThread(), -// threadData.threadInformation, -// sourceCodeData.data.isEmpty() ? null : sourceCodeData.data -// ); -// } -// -// public void setThreadsInformation(String mainThreadName, Map threadInformationMap, Map sourceCodeData) { -// this.mainThread = mainThreadName; -// this.threadInformationMap = threadInformationMap; -// this.sourceCode = sourceCodeData; -// } - - //Builder Class public static class Builder { final BacktraceReport report; @@ -263,6 +198,9 @@ public BacktraceData build() { return backtraceData; } + /** + * Set report information such as report identifier (UUID), timestamp, classifier + */ private void setDefaultReportInformation(BacktraceReport report) { this.uuid = report.uuid.toString(); this.timestamp = report.timestamp; @@ -271,6 +209,9 @@ private void setDefaultReportInformation(BacktraceReport report) { this.agentVersion = BacktraceClient.version; } + /** + * Set information about all threads + */ private void setDefaultThreadsInformation() { BacktraceLogger.d(LOG_TAG, "Setting threads information"); From c42e6c828c767101341f8f948f92afc2aeda174a Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 3 Apr 2024 20:06:02 +0200 Subject: [PATCH 037/100] Remove unused code --- .../BacktraceOrgJsonDeserializer.java | 48 ++----------------- 1 file changed, 3 insertions(+), 45 deletions(-) diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceOrgJsonDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceOrgJsonDeserializer.java index e11d925b..5c34a45c 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceOrgJsonDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceOrgJsonDeserializer.java @@ -5,49 +5,7 @@ public class BacktraceOrgJsonDeserializer { - public static T deserialize(String jsonString, Class clazz) throws JSONException { - return BacktraceDeserializer.deserialize(new JSONObject(jsonString), clazz); - } - -// public static T deserialize(JSONObject jsonObject, Class clazz) { -// try { -// T instance = clazz.newInstance(); -// // Assuming that the class has a default (no-argument) constructor -// -// // Iterate through the fields of the class -// for (java.lang.reflect.Field field : clazz.getDeclaredFields()) { -// // Make the field accessible (public, private, etc.) -// field.setAccessible(true); -// -// // Get the field name -// String fieldName = field.getName(); -// -// // Check if the JSON object has a key with the field name -// if (jsonObject.has(fieldName)) { -// // Set the field value using reflection -// field.set(instance, jsonObject.get(fieldName)); -// continue; -// } -// -// -// if (field.isAnnotationPresent(SerializedName.class)) { -// SerializedName annotation = field.getAnnotation(SerializedName.class); -// if (annotation != null) { -// String customName = annotation.value(); -// field.set(instance, jsonObject.get(customName)); -// continue; -// } -// -// } -// } -// -// return instance; -// } catch (InstantiationException | IllegalAccessException e) { -// e.printStackTrace(); // Handle the exception appropriately -// } catch (JSONException e) { -// throw new RuntimeException(e); -// } -// -// return null; -// } + public static T deserialize(String jsonString, Class clazz) throws JSONException { + return BacktraceDeserializer.deserialize(new JSONObject(jsonString), clazz); + } } From 6b6db45c2e27cbdb96583e2cf3d96cbc18bf2c78 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 3 Apr 2024 20:06:48 +0200 Subject: [PATCH 038/100] Optimize imports --- .../common/BacktraceDataDeserializerTest.java | 20 ------------------- .../common/BacktraceSerializeHelper.java | 1 - .../serializers/BacktraceDataSerializer.java | 4 +--- .../serializers/BacktraceDeserializer.java | 3 +-- .../BacktraceOrgJsonSerializer.java | 4 ---- .../common/serializers/SerializerHelper.java | 1 - .../BacktraceReportDeserializer.java | 2 -- .../deserializers/ExceptionDeserializer.java | 3 --- .../GenericListDeserializer.java | 2 -- .../deserializers/ReflectionDeserializer.java | 1 - .../ThreadInformationDeserializer.java | 1 - .../library/models/BacktraceApiResult.java | 2 -- .../library/models/BacktraceResult.java | 1 - .../database/BacktraceDatabaseRecord.java | 5 +---- .../library/models/json/SourceCode.java | 1 - .../library/models/json/SourceCodeData.java | 1 - .../models/json/ThreadInformation.java | 3 +-- .../library/models/metrics/Event.java | 3 +-- .../library/models/metrics/EventsPayload.java | 4 ++-- .../library/models/metrics/SummedEvent.java | 3 +-- .../models/metrics/SummedEventsPayload.java | 4 ++-- .../library/models/metrics/UniqueEvent.java | 3 +-- .../models/metrics/UniqueEventsPayload.java | 4 ++-- .../watchdog/BacktraceWatchdogShared.java | 1 - .../BacktraceApiResultDeserializerTest.java | 2 -- .../BacktraceDataDeserializerTest.java | 2 -- .../library/BacktraceSerializeHelperTest.java | 3 --- .../library/BacktraceStackTraceTest.java | 8 ++++---- .../library/ConcatAttributesUnitTest.java | 4 ++-- 29 files changed, 19 insertions(+), 77 deletions(-) diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java index 16abf3ff..589b58a0 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java @@ -7,41 +7,21 @@ import static backtraceio.library.TestUtils.readFileAsString; -import android.content.Context; - import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.platform.app.InstrumentationRegistry; import com.google.gson.FieldNamingPolicy; -import com.google.gson.Gson; import com.google.gson.GsonBuilder; import org.json.JSONException; -import org.json.JSONObject; import org.junit.Test; import org.junit.runner.RunWith; -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.URL; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; import java.util.UUID; -import backtraceio.library.R; -import backtraceio.library.common.serializers.BacktraceDataDeserializer; -import backtraceio.library.common.serializers.BacktraceDataSerializer; import backtraceio.library.common.serializers.BacktraceOrgJsonDeserializer; -import backtraceio.library.common.serializers.SerializerHelper; import backtraceio.library.models.BacktraceData; import backtraceio.library.models.BacktraceResult; import backtraceio.library.models.database.BacktraceDatabaseRecord; -import backtraceio.library.models.json.BacktraceReport; import backtraceio.library.models.types.BacktraceResultStatus; @RunWith(AndroidJUnit4.class) 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 d2b4de33..e4676801 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/BacktraceSerializeHelper.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/BacktraceSerializeHelper.java @@ -2,7 +2,6 @@ import com.google.gson.Gson; - import backtraceio.library.common.serialization.BacktraceGsonBuilder; import backtraceio.library.common.serializers.BacktraceOrgJsonSerializer; diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java index 92433166..3b05c6e1 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java @@ -4,20 +4,18 @@ import androidx.annotation.NonNull; - import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; -import java.util.ArrayList; import java.util.List; import java.util.Map; +import backtraceio.library.common.serializers.naming.NamingPolicy; import backtraceio.library.models.BacktraceData; import backtraceio.library.models.BacktraceStackFrame; import backtraceio.library.models.json.SourceCode; import backtraceio.library.models.json.ThreadInformation; -import backtraceio.library.common.serializers.naming.NamingPolicy; public class BacktraceDataSerializer { NamingPolicy namingPolicy; diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDeserializer.java index 8df87544..5fcfeebc 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDeserializer.java @@ -5,16 +5,15 @@ import java.util.HashMap; +import backtraceio.library.common.serializers.deserializers.BacktraceApiResultDeserializer; import backtraceio.library.common.serializers.deserializers.BacktraceDataDeserializer; import backtraceio.library.common.serializers.deserializers.BacktraceDatabaseRecordDeserializer; import backtraceio.library.common.serializers.deserializers.BacktraceReportDeserializer; -import backtraceio.library.common.serializers.deserializers.BacktraceApiResultDeserializer; import backtraceio.library.common.serializers.deserializers.Deserializable; import backtraceio.library.common.serializers.deserializers.ExceptionDeserializer; import backtraceio.library.common.serializers.deserializers.ReflectionDeserializer; import backtraceio.library.models.BacktraceApiResult; import backtraceio.library.models.BacktraceData; -import backtraceio.library.models.BacktraceResult; import backtraceio.library.models.database.BacktraceDatabaseRecord; import backtraceio.library.models.json.BacktraceReport; diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceOrgJsonSerializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceOrgJsonSerializer.java index c780164c..03a95371 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceOrgJsonSerializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceOrgJsonSerializer.java @@ -1,9 +1,5 @@ package backtraceio.library.common.serializers; -import org.json.JSONException; - -import backtraceio.library.common.serializers.BacktraceDataSerializer; -import backtraceio.library.common.serializers.SerializerHelper; import backtraceio.library.common.serializers.naming.NamingPolicy; import backtraceio.library.models.BacktraceData; diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java index 3bcdf920..2c1cd7f4 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java @@ -2,7 +2,6 @@ import android.os.Build; - import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceReportDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceReportDeserializer.java index 617fd3f7..d7589b2a 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceReportDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceReportDeserializer.java @@ -7,8 +7,6 @@ import org.json.JSONObject; import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.UUID; diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ExceptionDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ExceptionDeserializer.java index 72fcea97..96d6291d 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ExceptionDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ExceptionDeserializer.java @@ -4,9 +4,6 @@ import org.json.JSONException; import org.json.JSONObject; -import java.util.ArrayList; -import java.util.List; - public class ExceptionDeserializer implements Deserializable { static class Fields { final static String startLine = "startLine"; diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/GenericListDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/GenericListDeserializer.java index edc42192..46ec0b1b 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/GenericListDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/GenericListDeserializer.java @@ -6,8 +6,6 @@ import java.util.ArrayList; import java.util.List; -import backtraceio.library.models.BacktraceStackFrame; - public class GenericListDeserializer { List deserialize(JSONArray array, Deserializable deserializer) { List result = new ArrayList(); diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ReflectionDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ReflectionDeserializer.java index 7b743dcb..a499d9c0 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ReflectionDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ReflectionDeserializer.java @@ -6,7 +6,6 @@ import java.lang.reflect.InvocationTargetException; import backtraceio.library.common.serializers.SerializedName; -import backtraceio.library.models.BacktraceResult; public final class ReflectionDeserializer implements Deserializable { diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ThreadInformationDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ThreadInformationDeserializer.java index 84f67fab..1507e7fa 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ThreadInformationDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ThreadInformationDeserializer.java @@ -4,7 +4,6 @@ import org.json.JSONException; import org.json.JSONObject; -import java.util.ArrayList; import java.util.List; import backtraceio.library.common.serializers.deserializers.cache.FieldNameLoader; diff --git a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceApiResult.java b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceApiResult.java index ae6a3438..aefc2ea7 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceApiResult.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceApiResult.java @@ -1,8 +1,6 @@ package backtraceio.library.models; import backtraceio.library.common.serializers.SerializedName; -import backtraceio.library.models.json.BacktraceReport; -import backtraceio.library.models.types.BacktraceResultStatus; /** * Coroner API response 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 52ff63b3..9a436416 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceResult.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceResult.java @@ -1,6 +1,5 @@ package backtraceio.library.models; -import backtraceio.library.common.serializers.SerializedName; import backtraceio.library.models.json.BacktraceReport; import backtraceio.library.models.types.BacktraceResultStatus; 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 d5f6cc43..ab9dfd77 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 @@ -1,9 +1,5 @@ package backtraceio.library.models.database; -import android.content.Context; - -import backtraceio.library.common.serializers.SerializedName; - import java.io.File; import java.nio.charset.StandardCharsets; import java.util.UUID; @@ -11,6 +7,7 @@ import backtraceio.library.common.BacktraceSerializeHelper; import backtraceio.library.common.BacktraceStringHelper; import backtraceio.library.common.FileHelper; +import backtraceio.library.common.serializers.SerializedName; import backtraceio.library.interfaces.DatabaseRecordWriter; import backtraceio.library.logger.BacktraceLogger; import backtraceio.library.models.BacktraceData; 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 47bb11dd..ae367239 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 @@ -1,7 +1,6 @@ package backtraceio.library.models.json; import backtraceio.library.common.serializers.SerializedName; - import backtraceio.library.models.BacktraceStackFrame; /** 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 e348a13b..3a957ec5 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,6 +1,5 @@ package backtraceio.library.models.json; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; 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 3e44e35e..6cb9112e 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 @@ -1,10 +1,9 @@ package backtraceio.library.models.json; -import backtraceio.library.common.serializers.SerializedName; - import java.util.ArrayList; import java.util.List; +import backtraceio.library.common.serializers.SerializedName; import backtraceio.library.models.BacktraceStackFrame; /** diff --git a/backtrace-library/src/main/java/backtraceio/library/models/metrics/Event.java b/backtrace-library/src/main/java/backtraceio/library/models/metrics/Event.java index 9f3d18b6..516668e5 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/metrics/Event.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/metrics/Event.java @@ -1,11 +1,10 @@ package backtraceio.library.models.metrics; -import backtraceio.library.common.serializers.SerializedName; - import java.util.HashMap; import java.util.Map; import backtraceio.library.common.BacktraceStringHelper; +import backtraceio.library.common.serializers.SerializedName; public abstract class Event { diff --git a/backtrace-library/src/main/java/backtraceio/library/models/metrics/EventsPayload.java b/backtrace-library/src/main/java/backtraceio/library/models/metrics/EventsPayload.java index 0a0177b8..9bd06762 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/metrics/EventsPayload.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/metrics/EventsPayload.java @@ -1,9 +1,9 @@ package backtraceio.library.models.metrics; -import backtraceio.library.common.serializers.SerializedName; - import java.util.concurrent.ConcurrentLinkedDeque; +import backtraceio.library.common.serializers.SerializedName; + public abstract class EventsPayload { private static final transient String LOG_TAG = EventsPayload.class.getSimpleName(); diff --git a/backtrace-library/src/main/java/backtraceio/library/models/metrics/SummedEvent.java b/backtrace-library/src/main/java/backtraceio/library/models/metrics/SummedEvent.java index eea49c9f..534e847a 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/metrics/SummedEvent.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/metrics/SummedEvent.java @@ -1,11 +1,10 @@ package backtraceio.library.models.metrics; -import backtraceio.library.common.serializers.SerializedName; - import java.util.HashMap; import java.util.Map; import backtraceio.library.common.BacktraceTimeHelper; +import backtraceio.library.common.serializers.SerializedName; public final class SummedEvent extends Event { diff --git a/backtrace-library/src/main/java/backtraceio/library/models/metrics/SummedEventsPayload.java b/backtrace-library/src/main/java/backtraceio/library/models/metrics/SummedEventsPayload.java index f89ed28e..ecca24d2 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/metrics/SummedEventsPayload.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/metrics/SummedEventsPayload.java @@ -1,9 +1,9 @@ package backtraceio.library.models.metrics; -import backtraceio.library.common.serializers.SerializedName; - import java.util.concurrent.ConcurrentLinkedDeque; +import backtraceio.library.common.serializers.SerializedName; + public class SummedEventsPayload extends EventsPayload { @SerializedName("summed_events") private final ConcurrentLinkedDeque summedEvents; diff --git a/backtrace-library/src/main/java/backtraceio/library/models/metrics/UniqueEvent.java b/backtrace-library/src/main/java/backtraceio/library/models/metrics/UniqueEvent.java index d252122f..ed3d7034 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/metrics/UniqueEvent.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/metrics/UniqueEvent.java @@ -1,7 +1,5 @@ package backtraceio.library.models.metrics; -import backtraceio.library.common.serializers.SerializedName; - import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -9,6 +7,7 @@ import backtraceio.library.common.BacktraceStringHelper; import backtraceio.library.common.BacktraceTimeHelper; +import backtraceio.library.common.serializers.SerializedName; import backtraceio.library.logger.BacktraceLogger; public class UniqueEvent extends Event { diff --git a/backtrace-library/src/main/java/backtraceio/library/models/metrics/UniqueEventsPayload.java b/backtrace-library/src/main/java/backtraceio/library/models/metrics/UniqueEventsPayload.java index 1d27bea4..978d1fd3 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/metrics/UniqueEventsPayload.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/metrics/UniqueEventsPayload.java @@ -1,9 +1,9 @@ package backtraceio.library.models.metrics; -import backtraceio.library.common.serializers.SerializedName; - import java.util.concurrent.ConcurrentLinkedDeque; +import backtraceio.library.common.serializers.SerializedName; + public final class UniqueEventsPayload extends EventsPayload { @SerializedName("unique_events") private final ConcurrentLinkedDeque uniqueEvents; diff --git a/backtrace-library/src/main/java/backtraceio/library/watchdog/BacktraceWatchdogShared.java b/backtrace-library/src/main/java/backtraceio/library/watchdog/BacktraceWatchdogShared.java index 7aaa4c2c..3c30051b 100644 --- a/backtrace-library/src/main/java/backtraceio/library/watchdog/BacktraceWatchdogShared.java +++ b/backtrace-library/src/main/java/backtraceio/library/watchdog/BacktraceWatchdogShared.java @@ -1,7 +1,6 @@ package backtraceio.library.watchdog; import java.util.HashMap; -import java.util.Map; import backtraceio.library.BacktraceClient; import backtraceio.library.logger.BacktraceLogger; diff --git a/backtrace-library/src/test/java/backtraceio/library/BacktraceApiResultDeserializerTest.java b/backtrace-library/src/test/java/backtraceio/library/BacktraceApiResultDeserializerTest.java index a8cf0b0b..97d5abf1 100644 --- a/backtrace-library/src/test/java/backtraceio/library/BacktraceApiResultDeserializerTest.java +++ b/backtrace-library/src/test/java/backtraceio/library/BacktraceApiResultDeserializerTest.java @@ -2,8 +2,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; - import org.json.JSONException; import org.json.JSONObject; diff --git a/backtrace-library/src/test/java/backtraceio/library/BacktraceDataDeserializerTest.java b/backtrace-library/src/test/java/backtraceio/library/BacktraceDataDeserializerTest.java index b411ccb5..4768bd60 100644 --- a/backtrace-library/src/test/java/backtraceio/library/BacktraceDataDeserializerTest.java +++ b/backtrace-library/src/test/java/backtraceio/library/BacktraceDataDeserializerTest.java @@ -3,8 +3,6 @@ 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 static backtraceio.library.TestUtils.readFileAsString; import org.json.JSONException; diff --git a/backtrace-library/src/test/java/backtraceio/library/BacktraceSerializeHelperTest.java b/backtrace-library/src/test/java/backtraceio/library/BacktraceSerializeHelperTest.java index 15b11e0d..868e1c83 100644 --- a/backtrace-library/src/test/java/backtraceio/library/BacktraceSerializeHelperTest.java +++ b/backtrace-library/src/test/java/backtraceio/library/BacktraceSerializeHelperTest.java @@ -4,13 +4,10 @@ import static junit.framework.TestCase.assertNotNull; import static junit.framework.TestCase.assertNull; -import junit.framework.Assert; - import org.junit.Test; import backtraceio.library.common.BacktraceSerializeHelper; import backtraceio.library.models.BacktraceResult; -import backtraceio.library.models.json.BacktraceReport; import backtraceio.library.models.types.BacktraceResultStatus; public class BacktraceSerializeHelperTest { diff --git a/backtrace-library/src/test/java/backtraceio/library/BacktraceStackTraceTest.java b/backtrace-library/src/test/java/backtraceio/library/BacktraceStackTraceTest.java index 02515e13..82dec57f 100644 --- a/backtrace-library/src/test/java/backtraceio/library/BacktraceStackTraceTest.java +++ b/backtrace-library/src/test/java/backtraceio/library/BacktraceStackTraceTest.java @@ -1,13 +1,13 @@ package backtraceio.library; -import org.junit.Test; - -import backtraceio.library.models.BacktraceStackTrace; - 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.models.BacktraceStackTrace; + public class BacktraceStackTraceTest { @Test diff --git a/backtrace-library/src/test/java/backtraceio/library/ConcatAttributesUnitTest.java b/backtrace-library/src/test/java/backtraceio/library/ConcatAttributesUnitTest.java index 36b8f1bb..b56d3d1f 100644 --- a/backtrace-library/src/test/java/backtraceio/library/ConcatAttributesUnitTest.java +++ b/backtrace-library/src/test/java/backtraceio/library/ConcatAttributesUnitTest.java @@ -1,5 +1,7 @@ package backtraceio.library; +import static org.junit.Assert.assertEquals; + import org.junit.Test; import java.util.HashMap; @@ -7,8 +9,6 @@ import backtraceio.library.models.json.BacktraceReport; -import static org.junit.Assert.assertEquals; - public class ConcatAttributesUnitTest { From fd8a6d5b51f83ceb56f3f1d2aa130bf59f5c8149 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 3 Apr 2024 23:34:56 +0200 Subject: [PATCH 039/100] Fixes and unit tests --- .../common/BacktraceDataDeserializerTest.java | 14 ---- .../BacktraceResultDeserializerTest.java | 56 ++++++++++++++ .../BacktraceDatabaseContextTest.java | 8 +- .../BacktraceDatabaseFileContextTest.java | 4 +- .../library/models/BacktraceDataTest.java | 18 ++++- .../library/BacktraceDatabase.java | 3 +- .../common/BacktraceSerializeHelper.java | 17 ++++- .../BacktraceApiResultDeserializer.java | 2 +- .../BacktraceReportDeserializer.java | 3 + .../library/models/BacktraceApiResult.java | 8 ++ .../services/BacktraceDatabaseContext.java | 15 +--- .../BacktraceDatabaseFileContext.java | 7 +- .../BacktraceApiResultDeserializerTest.java | 34 --------- .../BacktraceDataDeserializerTest.java | 71 ------------------ .../library/BacktraceDataTest.java | 73 +++++++++++++++++++ .../BacktraceApiResultDeserializerTest.java | 63 ++++++++++++++++ .../backtraceio/backtraceio/MainActivity.java | 7 +- 17 files changed, 250 insertions(+), 153 deletions(-) create mode 100644 backtrace-library/src/androidTest/java/backtraceio/library/common/deserializers/BacktraceResultDeserializerTest.java delete mode 100644 backtrace-library/src/test/java/backtraceio/library/BacktraceApiResultDeserializerTest.java delete mode 100644 backtrace-library/src/test/java/backtraceio/library/BacktraceDataDeserializerTest.java create mode 100644 backtrace-library/src/test/java/backtraceio/library/BacktraceDataTest.java create mode 100644 backtrace-library/src/test/java/backtraceio/library/deserializers/BacktraceApiResultDeserializerTest.java diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java index 589b58a0..59508872 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java @@ -27,21 +27,7 @@ @RunWith(AndroidJUnit4.class) public class BacktraceDataDeserializerTest { - @Test - public void deserializeCoronerJsonResponse() throws JSONException { - // GIVEN - String json = "{\"response\":\"ok\",\"_rxid\":\"01000000-5360-240b-0000-000000000000\"}"; - - // WHEN - BacktraceResult result = BacktraceOrgJsonDeserializer.deserialize(json, BacktraceResult.class); - // THEN - assertNotNull(result); - assertNull(result.getBacktraceReport()); - assertNull(result.message); - assertEquals(BacktraceResultStatus.Ok, result.status); - assertEquals("01000000-5360-240b-0000-000000000000", result.rxId); - } @Test public void deserializeDatabaseRecord() throws JSONException { diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/common/deserializers/BacktraceResultDeserializerTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/common/deserializers/BacktraceResultDeserializerTest.java new file mode 100644 index 00000000..f284cc85 --- /dev/null +++ b/backtrace-library/src/androidTest/java/backtraceio/library/common/deserializers/BacktraceResultDeserializerTest.java @@ -0,0 +1,56 @@ +package backtraceio.library.common.deserializers; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.json.JSONException; +import org.junit.Test; +import org.junit.runner.RunWith; + +import backtraceio.library.common.serializers.BacktraceOrgJsonDeserializer; +import backtraceio.library.common.serializers.deserializers.BacktraceApiResultDeserializer; +import backtraceio.library.models.BacktraceResult; +import backtraceio.library.models.types.BacktraceResultStatus; + +@RunWith(AndroidJUnit4.class) +public class BacktraceResultDeserializerTest { + + private final String JSON_1 ="{\"response\":\"ok\",\"_rxid\":\"01000000-5360-240b-0000-000000000000\"}"; + + @Test + public void deserializeCoronerJsonResponse() throws JSONException { + // GIVEN + String json = JSON_1; + + // WHEN + BacktraceResult result = BacktraceOrgJsonDeserializer.deserialize(json, BacktraceResult.class); + + // THEN + assertNotNull(result); + assertNull(result.getBacktraceReport()); + assertNull(result.message); + assertEquals(BacktraceResultStatus.Ok, result.status); + assertEquals("01000000-5360-240b-0000-000000000000", result.rxId); + } + + @Test + public void deserializeCoronerAPIJsonResponse() throws JSONException { + // GIVEN + BacktraceApiResultDeserializer deserializer = new BacktraceApiResultDeserializer(); + String json = JSON_1; + + // WHEN + BacktraceResult result = BacktraceOrgJsonDeserializer.deserialize(json, BacktraceResult.class); + + // THEN + assertNotNull(result); + assertNull(result.getBacktraceReport()); + assertNull(result.message); + assertEquals(BacktraceResultStatus.Ok, result.status); + assertEquals("01000000-5360-240b-0000-000000000000", result.rxId); + } + +} 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 db75d12f..3be52201 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseContextTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseContextTest.java @@ -37,15 +37,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 @@ -78,7 +76,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 @@ -93,7 +91,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 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 89523ae4..5f67ef73 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseFileContextTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseFileContextTest.java @@ -40,7 +40,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(); @@ -143,7 +143,7 @@ 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); 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 159bf8d8..d16a3e03 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,9 @@ package backtraceio.library.models; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import android.content.Context; @@ -33,9 +36,20 @@ public void createBacktraceDataTest() { BacktraceData backtraceData = new BacktraceData.Builder(context, report, new HashMap<>()).build(); // THEN - assertEquals(backtraceData.classifiers, new String[]{"java.lang.IllegalAccessException"}); + assertArrayEquals(backtraceData.classifiers, new String[]{"java.lang.IllegalAccessException"}); assertEquals(backtraceData.report, report); assertEquals(backtraceData.attributes.get("classifier"), "java.lang.IllegalAccessException"); - // TODO: add next checks + assertEquals(backtraceData.agent, "backtrace-android"); + assertEquals(backtraceData.agentVersion, "3.8.0-6-6b6db45-backtrace-data-refactor"); + assertEquals(backtraceData.lang, "java"); + assertEquals(backtraceData.langVersion, "0"); + assertEquals(backtraceData.symbolication, ""); + assertEquals(backtraceData.timestamp, report.timestamp); + assertEquals(backtraceData.uuid, report.uuid.toString()); + assertEquals(backtraceData.attributes.size(), 40); + assertEquals(backtraceData.annotations.size(), 3); + assertEquals(backtraceData.mainThread, "instr: androidx.test.runner.androidjunitrunner"); + assertEquals(backtraceData.sourceCode.size(), 34); + assertEquals(backtraceData.getThreadInformationMap().size(), 13); } } diff --git a/backtrace-library/src/main/java/backtraceio/library/BacktraceDatabase.java b/backtrace-library/src/main/java/backtraceio/library/BacktraceDatabase.java index 87f3f077..3f726998 100644 --- a/backtrace-library/src/main/java/backtraceio/library/BacktraceDatabase.java +++ b/backtrace-library/src/main/java/backtraceio/library/BacktraceDatabase.java @@ -124,8 +124,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()); 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 e4676801..d608ea86 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/BacktraceSerializeHelper.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/BacktraceSerializeHelper.java @@ -3,6 +3,7 @@ import com.google.gson.Gson; import backtraceio.library.common.serialization.BacktraceGsonBuilder; +import backtraceio.library.common.serializers.BacktraceOrgJsonDeserializer; import backtraceio.library.common.serializers.BacktraceOrgJsonSerializer; /** @@ -22,11 +23,23 @@ public static String toJson(Object object) { } public static T fromJson(String json, Class type) { - return BacktraceSerializeHelper.fromJson(new BacktraceGsonBuilder().buildGson(), json, type); + try { + return BacktraceOrgJsonDeserializer.deserialize(json, type); + } catch (Exception e) { + //TODO: remove this try-catch + return null; + } +// return BacktraceSerializeHelper.fromJson(new BacktraceGsonBuilder().buildGson(), json, type); } public static T fromJson(Gson gson, String json, Class type) { - return gson.fromJson(json, type); + try { + return BacktraceOrgJsonDeserializer.deserialize(json, type); + } catch (Exception e) { + //TODO: remove this try-catch + return null; + } +// return gson.fromJson(json, type); } } diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceApiResultDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceApiResultDeserializer.java index 7d4858fb..abf954eb 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceApiResultDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceApiResultDeserializer.java @@ -18,7 +18,7 @@ static class Fields { public BacktraceApiResult deserialize(JSONObject obj) throws JSONException { return new BacktraceApiResult( obj.optString(fieldNameLoader.get(Fields.rxId), null), // TODO: check fallback warning - obj.optString(fieldNameLoader.get(Fields.response), BacktraceResultStatus.Ok.toString()) + obj.optString(fieldNameLoader.get(Fields.response), BacktraceResultStatus.ServerError.toString()) ); } } diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceReportDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceReportDeserializer.java index d7589b2a..b24f4174 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceReportDeserializer.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceReportDeserializer.java @@ -69,6 +69,9 @@ public BacktraceReport deserialize(JSONObject obj) throws JSONException { } public Exception getException(JSONObject obj) { + if (obj == null) { + return null; + } return this.exceptionDeserializer.deserialize(obj); // TODO: fix usage } diff --git a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceApiResult.java b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceApiResult.java index aefc2ea7..2776821f 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceApiResult.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceApiResult.java @@ -23,4 +23,12 @@ 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/services/BacktraceDatabaseContext.java b/backtrace-library/src/main/java/backtraceio/library/services/BacktraceDatabaseContext.java index e8274e69..df966a0d 100644 --- a/backtrace-library/src/main/java/backtraceio/library/services/BacktraceDatabaseContext.java +++ b/backtrace-library/src/main/java/backtraceio/library/services/BacktraceDatabaseContext.java @@ -1,7 +1,5 @@ package backtraceio.library.services; -import android.content.Context; - import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -29,10 +27,6 @@ public class BacktraceDatabaseContext implements DatabaseContext { */ private final int _retryNumber; - /** - * Application context - */ - private final Context _applicationContext; /** * Database cache @@ -59,8 +53,8 @@ public class BacktraceDatabaseContext implements DatabaseContext { * * @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()); } /** @@ -70,8 +64,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; @@ -87,7 +80,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..05946fc0 100644 --- a/backtrace-library/src/main/java/backtraceio/library/services/BacktraceDatabaseFileContext.java +++ b/backtrace-library/src/main/java/backtraceio/library/services/BacktraceDatabaseFileContext.java @@ -52,12 +52,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/test/java/backtraceio/library/BacktraceApiResultDeserializerTest.java b/backtrace-library/src/test/java/backtraceio/library/BacktraceApiResultDeserializerTest.java deleted file mode 100644 index 97d5abf1..00000000 --- a/backtrace-library/src/test/java/backtraceio/library/BacktraceApiResultDeserializerTest.java +++ /dev/null @@ -1,34 +0,0 @@ -package backtraceio.library; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Test; - -import backtraceio.library.common.serializers.deserializers.BacktraceApiResultDeserializer; -import backtraceio.library.models.BacktraceApiResult; -import backtraceio.library.models.types.BacktraceResultStatus; - -// TODO: move to standard unit tests not instrumented -public class BacktraceApiResultDeserializerTest { - @Test - public void deserializeCoronerApiJsonResponse() throws JSONException { - // GIVEN - String json = "{\"response\":\"Ok\",\"_rxid\":\"01000000-5360-240b-0000-000000000000\"}"; - - // WHEN - BacktraceApiResultDeserializer deserializer = new BacktraceApiResultDeserializer(); - BacktraceApiResult result = deserializer.deserialize(new JSONObject(json)); - - // THEN - assertNotNull(result); -// assertNull(result.getBacktraceReport()); -// assertNull(result.message); - assertEquals(BacktraceResultStatus.Ok, result.response); - assertEquals("01000000-5360-240b-0000-000000000000", result.rxId); - } - - // TODO: Add test case with another response e.g. server error -} diff --git a/backtrace-library/src/test/java/backtraceio/library/BacktraceDataDeserializerTest.java b/backtrace-library/src/test/java/backtraceio/library/BacktraceDataDeserializerTest.java deleted file mode 100644 index 4768bd60..00000000 --- a/backtrace-library/src/test/java/backtraceio/library/BacktraceDataDeserializerTest.java +++ /dev/null @@ -1,71 +0,0 @@ -package backtraceio.library; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static backtraceio.library.TestUtils.readFileAsString; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Test; - -import java.util.Map; - -import backtraceio.library.common.serializers.BacktraceDeserializer; -import backtraceio.library.models.BacktraceData; -import backtraceio.library.models.json.SourceCode; -import backtraceio.library.models.json.ThreadInformation; - -public class BacktraceDataDeserializerTest { - - @Test - public void deserializeBacktraceData() throws JSONException { - // GIVEN -// final String backtraceDataJson = "{\"agent\":\"backtrace-android\",\"agentVersion\":\"3.7.12-8-3686709-org-json-serializer\",\"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\",\"PATH\":\"/product/bin:/apex/com.android.runtime/bin:/apex/com.android.art/bin:/system_ext/bin:/system/bin:/system/xbin:/odm/bin:/vendor/bin:/vendor/xbin\",\"ANDROID_SOCKET_zygote\":\"17\",\"ANDROID_I18N_ROOT\":\"/apex/com.android.i18n\",\"ANDROID_DATA\":\"/data\",\"ASEC_MOUNTPOINT\":\"/mnt/asec\",\"ANDROID_TZDATA_ROOT\":\"/apex/com.android.tzdata\",\"EXTERNAL_STORAGE\":\"/sdcard\",\"ANDROID_BOOTLOGO\":\"1\",\"ANDROID_ASSETS\":\"/system/app\",\"ANDROID_STORAGE\":\"/storage\",\"DEX2OATBOOTCLASSPATH\":\"/apex/com.android.art/javalib/core-oj.jar:/apex/com.android.art/javalib/core-libart.jar:/apex/com.android.art/javalib/core-icu4j.jar:/apex/com.android.art/javalib/okhttp.jar:/apex/com.android.art/javalib/bouncycastle.jar:/apex/com.android.art/javalib/apache-xml.jar:/system/framework/framework.jar:/system/framework/ext.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/framework-atb-backward-compatibility.jar\",\"ANDROID_ART_ROOT\":\"/apex/com.android.art\",\"ANDROID_ROOT\":\"/system\",\"DOWNLOAD_CACHE\":\"/data/cache\",\"BOOTCLASSPATH\":\"/apex/com.android.art/javalib/core-oj.jar:/apex/com.android.art/javalib/core-libart.jar:/apex/com.android.art/javalib/core-icu4j.jar:/apex/com.android.art/javalib/okhttp.jar:/apex/com.android.art/javalib/bouncycastle.jar:/apex/com.android.art/javalib/apache-xml.jar:/system/framework/framework.jar:/system/framework/ext.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/framework-atb-backward-compatibility.jar:/apex/com.android.conscrypt/javalib/conscrypt.jar:/apex/com.android.media/javalib/updatable-media.jar:/apex/com.android.mediaprovider/javalib/framework-mediaprovider.jar:/apex/com.android.os.statsd/javalib/framework-statsd.jar:/apex/com.android.permission/javalib/framework-permission.jar:/apex/com.android.sdkext/javalib/framework-sdkextensions.jar:/apex/com.android.wifi/javalib/framework-wifi.jar:/apex/com.android.tethering/javalib/framework-tethering.jar\",\"ANDROID_SOCKET_usap_pool_primary\":\"21\"},\"Exception\":{\"message\":\"Example test string\"}},\"attributes\":{\"application.session\":\"fd86372a-457d-4347-b1af-34779f86f520\",\"device.nfc.status\":\"NotAvailable\",\"device.cpu.temperature\":\"0.0\",\"system.memory.active\":\"1094905856\",\"device.wifi.status\":\"Enabled\",\"screen.height\":\"1834\",\"uname.machine\":\"i686\",\"screen.dpi\":\"288\",\"device.bluetooth_status\":\"NotPermitted\",\"device.airplane_mode\":\"false\",\"system.memory.total\":\"2077347840\",\"device.sdk\":\"30\",\"device.brand\":\"google\",\"uname.sysname\":\"Android\",\"cpu.boottime\":\"1707253373829\",\"device.os_version\":\"5.4.61-android11-0-00791-gbad091cc4bf3-ab6833933\",\"device.gps.enabled\":\"Enabled\",\"application.package\":\"backtraceio.library.test\",\"uname.version\":\"11\",\"backtrace.version\":\"3.7.12-8-3686709-org-json-serializer\",\"device.is_power_saving_mode\":\"false\",\"screen.orientation\":\"Portrait\",\"device.manufacturer\":\"Google\",\"system.memory.free\":\"982441984\",\"battery.state\":\"Unplugged\",\"backtrace.agent\":\"backtrace-android\",\"error.type\":\"Message\",\"device.location\":\"Enabled\",\"application\":\"backtraceio.library.test\",\"error.message\":\"Example test string\",\"culture\":\"English\",\"device.model\":\"sdk_gphone_x86\",\"screen.width\":\"1080\",\"build.type\":\"Debug\",\"device.product\":\"sdk_gphone_x86\",\"guid\":\"e4c57699-0dc9-35e2-b4a0-2ffff1925ca7\",\"app.storage_used\":\"2974528\",\"battery.level\":\"1.0\",\"screen.brightness\":\"102\"},\"lang\":\"java\",\"langVersion\":\"0\",\"mainThread\":\"instr: androidx.test.runner.androidjunitrunner\",\"sourceCode\":{\"5ad3ea57-08bc-42b9-a0af-4c0b63abd5d7\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":331},\"e1c31c4a-9f5f-4aae-8f74-29c5f7398e4d\":{\"source-code-file-name\":\"AndroidJUnit4.java\",\"start-line\":162},\"0a88f8a1-60c0-41a0-a95c-d75de5a4c82d\":{\"source-code-file-name\":\"JUnitCore.java\",\"start-line\":137},\"b1cc1675-df0c-4bda-9ec2-cc50d02b7497\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":66},\"6237d391-f50f-49b7-a029-dc8533521a39\":{\"source-code-file-name\":\"BlockJUnit4ClassRunner.java\",\"start-line\":100},\"24d96335-14d8-45d8-a07d-fc24bc56d4db\":{\"source-code-file-name\":\"Suite.java\",\"start-line\":128},\"9b765b76-8714-4dc2-8584-c58e57d0b97d\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":79},\"0952a91a-0c4b-45f2-93c7-e744a7e64ded\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":306},\"86deee3a-0e5f-495b-af66-5b2f36964ca2\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":79},\"bbf3d67c-a184-49ee-b0d5-b02188e3fa30\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":293},\"a70079ba-1646-4dda-ae17-7a92bf584c69\":{\"source-code-file-name\":\"ReflectiveCallable.java\",\"start-line\":12},\"61876082-acce-458e-8248-bfb03dc2b340\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":306},\"cfe92970-ae80-45b4-9dd4-8099919a1c26\":{\"source-code-file-name\":\"Suite.java\",\"start-line\":27},\"a4ef001f-1238-4b6e-9e57-aaa3dc1717ce\":{\"source-code-file-name\":\"AndroidJUnitRunner.java\",\"start-line\":446},\"6e8a4d01-3519-4742-be84-34da0dac2460\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":413},\"42aefc9a-50aa-40e9-ac4e-483c279cd9dc\":{\"source-code-file-name\":\"Method.java\"},\"56847938-10cc-4e20-98e2-521ce93ebe70\":{\"source-code-file-name\":\"VMStack.java\"},\"86086e43-f1de-49c0-aeda-3ae2be530407\":{\"source-code-file-name\":\"FrameworkMethod.java\",\"start-line\":59},\"ecc0e91a-52b3-48e7-b509-a850f49652c1\":{\"source-code-file-name\":\"RunBefores.java\",\"start-line\":80},\"673561af-72d1-4294-8f73-cca30446e70e\":{\"source-code-file-name\":\"BlockJUnit4ClassRunner.java\",\"start-line\":103},\"88ac7e2c-c331-4249-910d-519a6d25363f\":{\"source-code-file-name\":\"BlockJUnit4ClassRunner.java\",\"start-line\":63},\"ea2aa6d0-8e27-402d-8836-9ede35629ac9\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":66},\"4d79837a-1751-47e1-a134-d883871a9cec\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":413},\"7787b022-3043-4976-9dde-990443b50b24\":{\"source-code-file-name\":\"FrameworkMethod.java\",\"start-line\":56},\"5ed2c2aa-38a0-42ed-8f05-9131c4c72e90\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":366},\"e7bd36c2-dd6a-4bb3-bac5-e5e606490c71\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":329},\"ddf80aac-8ae4-42cc-9d35-5dae41fbf626\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":329},\"2980dbe3-ee88-486c-8442-9b6816dfe07a\":{\"source-code-file-name\":\"RunAfters.java\",\"start-line\":61},\"351d6b15-5d61-4a8a-9a06-5b14bf071945\":{\"source-code-file-name\":\"JUnitCore.java\",\"start-line\":115},\"2172b7fe-e8cf-4ffa-936b-c6efb52694bb\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":331},\"9ae72a6b-31be-435f-8a52-461f043b492b\":{\"source-code-file-name\":\"TestExecutor.java\",\"start-line\":58},\"a67eccc1-bd1c-4207-93a5-db20e09b79aa\":{\"source-code-file-name\":\"Instrumentation.java\",\"start-line\":2205},\"76276ba5-69ae-4815-8a9c-77525b526cb1\":{\"source-code-file-name\":\"TestExecutor.java\",\"start-line\":67},\"23444a66-f715-444f-afcb-f367a6f72689\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":293},\"1cfc3859-cf21-4d84-ba61-d73d9ee73c41\":{\"source-code-file-name\":\"ParentRunner.java\",\"start-line\":306},\"653bad70-8157-49d4-8894-8bb089f76722\":{\"source-code-file-name\":\"Thread.java\",\"start-line\":1736},\"84649fde-1055-4085-a52e-52c35811cbde\":{\"source-code-file-name\":\"InvokeMethod.java\",\"start-line\":17}},\"threadInformation-map\":{\"profile saver\":{\"fault\":false,\"name\":\"profile saver\",\"stack\":[]},\"finalizerwatchdogdaemon\":{\"fault\":false,\"name\":\"finalizerwatchdogdaemon\",\"stack\":[{\"function-name\":\"java.lang.Object.wait\",\"source-code\":\"b778a593-508f-444d-ab62-77d1ea5506c5\"},{\"function-name\":\"java.lang.Object.wait\",\"line\":442,\"source-code\":\"567b0437-8d29-4cc2-9274-819c056179a9\"},{\"function-name\":\"java.lang.Object.wait\",\"line\":568,\"source-code\":\"d07089b6-e586-4cde-ab31-3d0d1740ae25\"},{\"function-name\":\"java.lang.Daemons$FinalizerWatchdogDaemon.sleepUntilNeeded\",\"line\":341,\"source-code\":\"5aa512c3-e353-4309-9613-f3175bc05c56\"},{\"function-name\":\"java.lang.Daemons$FinalizerWatchdogDaemon.runInternal\",\"line\":321,\"source-code\":\"a8fb461e-e7b9-4259-b16f-8e9610884d2a\"},{\"function-name\":\"java.lang.Daemons$Daemon.run\",\"line\":139,\"source-code\":\"100f945a-c9ed-42d4-a396-bfb1c9c09e32\"},{\"function-name\":\"java.lang.Thread.run\",\"line\":923,\"source-code\":\"ba65711d-9470-4cdc-a06a-32db7ce84db9\"}]},\"signal catcher\":{\"fault\":false,\"name\":\"signal catcher\",\"stack\":[]},\"timer-0\":{\"fault\":false,\"name\":\"timer-0\",\"stack\":[{\"function-name\":\"java.lang.Object.wait\",\"source-code\":\"dbfe3cc6-8ac5-4a8c-b4c2-3c4073e563c7\"},{\"function-name\":\"java.lang.Object.wait\",\"line\":442,\"source-code\":\"ce872d4e-20a7-4991-9ae6-b0c09ff728f1\"},{\"function-name\":\"java.util.TimerThread.mainLoop\",\"line\":559,\"source-code\":\"507a2ca3-1e70-492a-9a75-cb95073c44a0\"},{\"function-name\":\"java.util.TimerThread.run\",\"line\":512,\"source-code\":\"06908da9-ce73-4835-b1e3-5fb732fcf82e\"}]},\"main\":{\"fault\":false,\"name\":\"main\",\"stack\":[{\"function-name\":\"android.os.MessageQueue.nativePollOnce\",\"source-code\":\"30ad9a05-28af-4db8-8ee6-35d55cc85ca5\"},{\"function-name\":\"android.os.MessageQueue.next\",\"line\":335,\"source-code\":\"58e043c1-b6f0-47ee-a5ea-af64153bd38b\"},{\"function-name\":\"android.os.Looper.loop\",\"line\":183,\"source-code\":\"9718f15f-0010-4e8f-8012-a5c48b554a9f\"},{\"function-name\":\"android.app.ActivityThread.main\",\"line\":7656,\"source-code\":\"4cc5b61d-3403-4a03-8a69-63adbcc55511\"},{\"function-name\":\"java.lang.reflect.Method.invoke\",\"source-code\":\"23078e7a-df17-4655-bad5-48b90baedba9\"},{\"function-name\":\"com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run\",\"line\":592,\"source-code\":\"cc45db4a-ec38-49d9-b5f6-14b804362ccd\"},{\"function-name\":\"com.android.internal.os.ZygoteInit.main\",\"line\":947,\"source-code\":\"406194e7-76b8-4b8f-977c-21756313f648\"}]},\"finalizerdaemon\":{\"fault\":false,\"name\":\"finalizerdaemon\",\"stack\":[{\"function-name\":\"java.lang.Object.wait\",\"source-code\":\"daff552e-1ac1-4417-9b77-fd91b3a664fc\"},{\"function-name\":\"java.lang.Object.wait\",\"line\":442,\"source-code\":\"d1445680-d522-46d4-ae3a-b2daeda6de3d\"},{\"function-name\":\"java.lang.ref.ReferenceQueue.remove\",\"line\":190,\"source-code\":\"260f72cf-3b32-48ff-9722-af6280876415\"},{\"function-name\":\"java.lang.ref.ReferenceQueue.remove\",\"line\":211,\"source-code\":\"e951fdfd-cde7-49f2-926b-4e131544d4d4\"},{\"function-name\":\"java.lang.Daemons$FinalizerDaemon.runInternal\",\"line\":273,\"source-code\":\"4f2ac4ed-051c-4a1c-a94d-999809f38ea6\"},{\"function-name\":\"java.lang.Daemons$Daemon.run\",\"line\":139,\"source-code\":\"d2d21d80-5047-4c37-abe5-cb0e854c555a\"},{\"function-name\":\"java.lang.Thread.run\",\"line\":923,\"source-code\":\"ceeb7b8e-7b5c-4d65-9c80-7c8e02a12202\"}]},\"referencequeuedaemon\":{\"fault\":false,\"name\":\"referencequeuedaemon\",\"stack\":[{\"function-name\":\"java.lang.Object.wait\",\"source-code\":\"d569fd77-fec0-4abd-b746-1e43394a8ca1\"},{\"function-name\":\"java.lang.Object.wait\",\"line\":442,\"source-code\":\"29bee7cd-cda4-4cd0-b7b6-1b21c40f3ee5\"},{\"function-name\":\"java.lang.Object.wait\",\"line\":568,\"source-code\":\"4b73fe34-9a92-4b11-a391-fa60086a62b4\"},{\"function-name\":\"java.lang.Daemons$ReferenceQueueDaemon.runInternal\",\"line\":217,\"source-code\":\"e76abece-43e7-48a0-a429-f13b75282fdd\"},{\"function-name\":\"java.lang.Daemons$Daemon.run\",\"line\":139,\"source-code\":\"08d8fd2b-8d9e-4317-ad68-3031de5f429f\"},{\"function-name\":\"java.lang.Thread.run\",\"line\":923,\"source-code\":\"8509b640-6470-4894-a896-7794e917c270\"}]},\"binder:8909_3\":{\"fault\":false,\"name\":\"binder:8909_3\",\"stack\":[]},\"jit thread pool worker thread 0\":{\"fault\":false,\"name\":\"jit thread pool worker thread 0\",\"stack\":[]},\"instrumentationconnectionthread\":{\"fault\":false,\"name\":\"instrumentationconnectionthread\",\"stack\":[{\"function-name\":\"android.os.MessageQueue.nativePollOnce\",\"source-code\":\"2699757c-16bd-4853-8d48-ad23aeebf5ad\"},{\"function-name\":\"android.os.MessageQueue.next\",\"line\":335,\"source-code\":\"bf1a4cc2-55ee-43c3-83a0-8780eeece1ce\"},{\"function-name\":\"android.os.Looper.loop\",\"line\":183,\"source-code\":\"2e0184c2-dd7e-41b6-946a-a646896cb880\"},{\"function-name\":\"android.os.HandlerThread.run\",\"line\":67,\"source-code\":\"209e3b61-b3f2-4de5-b8e3-6d832e969ce9\"}]},\"instr: androidx.test.runner.androidjunitrunner\":{\"fault\":true,\"name\":\"instr: androidx.test.runner.androidjunitrunner\",\"stack\":[{\"function-name\":\"dalvik.system.VMStack.getThreadStackTrace\",\"source-code\":\"56847938-10cc-4e20-98e2-521ce93ebe70\"},{\"function-name\":\"java.lang.Thread.getStackTrace\",\"line\":1736,\"source-code\":\"653bad70-8157-49d4-8894-8bb089f76722\"},{\"function-name\":\"java.lang.reflect.Method.invoke\",\"source-code\":\"42aefc9a-50aa-40e9-ac4e-483c279cd9dc\"},{\"function-name\":\"org.junit.runners.model.FrameworkMethod$1.runReflectiveCall\",\"line\":59,\"source-code\":\"86086e43-f1de-49c0-aeda-3ae2be530407\"},{\"function-name\":\"org.junit.internal.runners.model.ReflectiveCallable.run\",\"line\":12,\"source-code\":\"a70079ba-1646-4dda-ae17-7a92bf584c69\"},{\"function-name\":\"org.junit.runners.model.FrameworkMethod.invokeExplosively\",\"line\":56,\"source-code\":\"7787b022-3043-4976-9dde-990443b50b24\"},{\"function-name\":\"org.junit.internal.runners.statements.InvokeMethod.evaluate\",\"line\":17,\"source-code\":\"84649fde-1055-4085-a52e-52c35811cbde\"},{\"function-name\":\"androidx.test.internal.runner.junit4.statement.RunBefores.evaluate\",\"line\":80,\"source-code\":\"ecc0e91a-52b3-48e7-b509-a850f49652c1\"},{\"function-name\":\"androidx.test.internal.runner.junit4.statement.RunAfters.evaluate\",\"line\":61,\"source-code\":\"2980dbe3-ee88-486c-8442-9b6816dfe07a\"},{\"function-name\":\"org.junit.runners.ParentRunner$3.evaluate\",\"line\":306,\"source-code\":\"1cfc3859-cf21-4d84-ba61-d73d9ee73c41\"},{\"function-name\":\"org.junit.runners.BlockJUnit4ClassRunner$1.evaluate\",\"line\":100,\"source-code\":\"6237d391-f50f-49b7-a029-dc8533521a39\"},{\"function-name\":\"org.junit.runners.ParentRunner.runLeaf\",\"line\":366,\"source-code\":\"5ed2c2aa-38a0-42ed-8f05-9131c4c72e90\"},{\"function-name\":\"org.junit.runners.BlockJUnit4ClassRunner.runChild\",\"line\":103,\"source-code\":\"673561af-72d1-4294-8f73-cca30446e70e\"},{\"function-name\":\"org.junit.runners.BlockJUnit4ClassRunner.runChild\",\"line\":63,\"source-code\":\"88ac7e2c-c331-4249-910d-519a6d25363f\"},{\"function-name\":\"org.junit.runners.ParentRunner$4.run\",\"line\":331,\"source-code\":\"2172b7fe-e8cf-4ffa-936b-c6efb52694bb\"},{\"function-name\":\"org.junit.runners.ParentRunner$1.schedule\",\"line\":79,\"source-code\":\"86deee3a-0e5f-495b-af66-5b2f36964ca2\"},{\"function-name\":\"org.junit.runners.ParentRunner.runChildren\",\"line\":329,\"source-code\":\"e7bd36c2-dd6a-4bb3-bac5-e5e606490c71\"},{\"function-name\":\"org.junit.runners.ParentRunner.access$100\",\"line\":66,\"source-code\":\"ea2aa6d0-8e27-402d-8836-9ede35629ac9\"},{\"function-name\":\"org.junit.runners.ParentRunner$2.evaluate\",\"line\":293,\"source-code\":\"23444a66-f715-444f-afcb-f367a6f72689\"},{\"function-name\":\"org.junit.runners.ParentRunner$3.evaluate\",\"line\":306,\"source-code\":\"0952a91a-0c4b-45f2-93c7-e744a7e64ded\"},{\"function-name\":\"org.junit.runners.ParentRunner.run\",\"line\":413,\"source-code\":\"6e8a4d01-3519-4742-be84-34da0dac2460\"},{\"function-name\":\"androidx.test.ext.junit.runners.AndroidJUnit4.run\",\"line\":162,\"source-code\":\"e1c31c4a-9f5f-4aae-8f74-29c5f7398e4d\"},{\"function-name\":\"org.junit.runners.Suite.runChild\",\"line\":128,\"source-code\":\"24d96335-14d8-45d8-a07d-fc24bc56d4db\"},{\"function-name\":\"org.junit.runners.Suite.runChild\",\"line\":27,\"source-code\":\"cfe92970-ae80-45b4-9dd4-8099919a1c26\"},{\"function-name\":\"org.junit.runners.ParentRunner$4.run\",\"line\":331,\"source-code\":\"5ad3ea57-08bc-42b9-a0af-4c0b63abd5d7\"},{\"function-name\":\"org.junit.runners.ParentRunner$1.schedule\",\"line\":79,\"source-code\":\"9b765b76-8714-4dc2-8584-c58e57d0b97d\"},{\"function-name\":\"org.junit.runners.ParentRunner.runChildren\",\"line\":329,\"source-code\":\"ddf80aac-8ae4-42cc-9d35-5dae41fbf626\"},{\"function-name\":\"org.junit.runners.ParentRunner.access$100\",\"line\":66,\"source-code\":\"b1cc1675-df0c-4bda-9ec2-cc50d02b7497\"},{\"function-name\":\"org.junit.runners.ParentRunner$2.evaluate\",\"line\":293,\"source-code\":\"bbf3d67c-a184-49ee-b0d5-b02188e3fa30\"},{\"function-name\":\"org.junit.runners.ParentRunner$3.evaluate\",\"line\":306,\"source-code\":\"61876082-acce-458e-8248-bfb03dc2b340\"},{\"function-name\":\"org.junit.runners.ParentRunner.run\",\"line\":413,\"source-code\":\"4d79837a-1751-47e1-a134-d883871a9cec\"},{\"function-name\":\"org.junit.runner.JUnitCore.run\",\"line\":137,\"source-code\":\"0a88f8a1-60c0-41a0-a95c-d75de5a4c82d\"},{\"function-name\":\"org.junit.runner.JUnitCore.run\",\"line\":115,\"source-code\":\"351d6b15-5d61-4a8a-9a06-5b14bf071945\"},{\"function-name\":\"androidx.test.internal.runner.TestExecutor.execute\",\"line\":67,\"source-code\":\"76276ba5-69ae-4815-8a9c-77525b526cb1\"},{\"function-name\":\"androidx.test.internal.runner.TestExecutor.execute\",\"line\":58,\"source-code\":\"9ae72a6b-31be-435f-8a52-461f043b492b\"},{\"function-name\":\"androidx.test.runner.AndroidJUnitRunner.onStart\",\"line\":446,\"source-code\":\"a4ef001f-1238-4b6e-9e57-aaa3dc1717ce\"},{\"function-name\":\"android.app.Instrumentation$InstrumentationThread.run\",\"line\":2205,\"source-code\":\"a67eccc1-bd1c-4207-93a5-db20e09b79aa\"}]},\"binder:8909_1\":{\"fault\":false,\"name\":\"binder:8909_1\",\"stack\":[]},\"heaptaskdaemon\":{\"fault\":false,\"name\":\"heaptaskdaemon\",\"stack\":[]},\"binder:8909_2\":{\"fault\":false,\"name\":\"binder:8909_2\",\"stack\":[]}},\"timestamp\":1707253867,\"uuid\":\"8e68b676-21cb-4cc8-ac2e-32a60e8d29c1\"}"; - String backtraceDataJson = readFileAsString(this, "backtraceData.json"); - // WHEN - final BacktraceData result = BacktraceDeserializer.deserialize(new JSONObject(backtraceDataJson), BacktraceData.class); - - // THEN - assertNotNull(result); - assertEquals("398dad51-7c39-4d64-941c-854de56f5f2b", result.uuid); - assertEquals("java", result.lang); - assertEquals("backtrace-android", result.agent); - assertEquals("", result.symbolication); // TODO: check - assertEquals(1709680075, result.timestamp); - assertEquals("0", result.langVersion); - assertEquals("3.7.14-1-931f45d", result.agentVersion); - assertEquals("instr: androidx.test.runner.androidjunitrunner", result.mainThread); - assertEquals(1, result.classifiers.length); - assertEquals("java.lang.IllegalAccessException", result.classifiers[0]); - assertNull(result.report); - // THEN Attributes - assertEquals(result.attributes.size(), 41); - assertEquals(result.attributes.get("application"), "backtraceio.library.test"); - assertEquals(result.attributes.get("error.type"), "Exception"); - // THEN Annotations - assertEquals(5, result.annotations.size()); - assertEquals("Test", ((Map) result.annotations.get("Exception")).get("message")); - assertNotNull(result.annotations.get("Exception properties")); - assertEquals("Test", ((Map) result.annotations.get("Exception properties")).get("detail-message")); - assertNotNull(result.annotations.get("1")); - assertNotNull(result.annotations.get("123")); - // THEN Source Code - assertEquals(result.sourceCode.size(), 35); - SourceCode firstSourceCode = result.sourceCode.get("ca0a50a1-d553-4479-8fe2-28c3f527743b"); - - assertEquals(firstSourceCode.sourceCodeFileName, "ParentRunner.java"); - assertEquals(firstSourceCode.startLine.intValue(), 306); -// assertEquals(); - // THEN Thread informations - assertEquals(result.getThreadInformationMap().size(), 13); - ThreadInformation threadInformation = result.getThreadInformationMap().get("finalizerwatchdogdaemon"); - assertEquals(threadInformation.getFault(), false); - assertEquals(threadInformation.getName(), "finalizerwatchdogdaemon"); - assertNotNull(threadInformation.getStack()); - assertEquals(threadInformation.getStack().get(1).sourceCode, "4f359140-a606-4f5d-ba67-adb387383d43"); - assertEquals(threadInformation.getStack().get(1).sourceCodeFileName, null); - assertEquals(threadInformation.getStack().get(1).functionName, "java.lang.Object.wait"); - assertEquals(threadInformation.getStack().get(1).line.intValue(), 442); - } -} diff --git a/backtrace-library/src/test/java/backtraceio/library/BacktraceDataTest.java b/backtrace-library/src/test/java/backtraceio/library/BacktraceDataTest.java new file mode 100644 index 00000000..83cef953 --- /dev/null +++ b/backtrace-library/src/test/java/backtraceio/library/BacktraceDataTest.java @@ -0,0 +1,73 @@ +package backtraceio.library; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static backtraceio.library.TestUtils.readFileAsString; + +import org.json.JSONException; +import org.json.JSONObject; +import org.junit.Test; + +import java.util.Map; + +import backtraceio.library.common.serializers.BacktraceDeserializer; +import backtraceio.library.models.BacktraceData; +import backtraceio.library.models.json.SourceCode; +import backtraceio.library.models.json.ThreadInformation; + +public class BacktraceDataTest { + + @Test + public void deserializeBacktraceData() throws JSONException { + // GIVEN + String backtraceDataJson = readFileAsString(this, "backtraceData.json"); + // WHEN + final BacktraceData result = BacktraceDeserializer.deserialize(new JSONObject(backtraceDataJson), BacktraceData.class); + + // THEN + assertNotNull(result); + assertEquals("398dad51-7c39-4d64-941c-854de56f5f2b", result.uuid); + assertEquals("java", result.lang); + assertEquals("backtrace-android", result.agent); + assertEquals("", result.symbolication); // TODO: check + assertEquals(1709680075, result.timestamp); + assertEquals("0", result.langVersion); + assertEquals("3.7.14-1-931f45d", result.agentVersion); + assertEquals("instr: androidx.test.runner.androidjunitrunner", result.mainThread); + assertEquals(1, result.classifiers.length); + assertEquals("java.lang.IllegalAccessException", result.classifiers[0]); + assertNull(result.report); + + // THEN Attributes + assertEquals(result.attributes.size(), 41); + assertEquals(result.attributes.get("application"), "backtraceio.library.test"); + assertEquals(result.attributes.get("error.type"), "Exception"); + + // THEN Annotations + assertEquals(5, result.annotations.size()); + assertEquals("Test", ((Map) result.annotations.get("Exception")).get("message")); + assertNotNull(result.annotations.get("Exception properties")); + assertEquals("Test", ((Map) result.annotations.get("Exception properties")).get("detail-message")); + assertNotNull(result.annotations.get("1")); + assertNotNull(result.annotations.get("123")); + + // THEN Source Code + assertEquals(result.sourceCode.size(), 35); + SourceCode firstSourceCode = result.sourceCode.get("ca0a50a1-d553-4479-8fe2-28c3f527743b"); + + assertEquals(firstSourceCode.sourceCodeFileName, "ParentRunner.java"); + assertEquals(firstSourceCode.startLine.intValue(), 306); + + // THEN Thread information + assertEquals(result.getThreadInformationMap().size(), 13); + ThreadInformation threadInformation = result.getThreadInformationMap().get("finalizerwatchdogdaemon"); + assertEquals(threadInformation.getFault(), false); + assertEquals(threadInformation.getName(), "finalizerwatchdogdaemon"); + assertNotNull(threadInformation.getStack()); + assertEquals(threadInformation.getStack().get(1).sourceCode, "4f359140-a606-4f5d-ba67-adb387383d43"); + assertEquals(threadInformation.getStack().get(1).sourceCodeFileName, null); + assertEquals(threadInformation.getStack().get(1).functionName, "java.lang.Object.wait"); + assertEquals(threadInformation.getStack().get(1).line.intValue(), 442); + } +} diff --git a/backtrace-library/src/test/java/backtraceio/library/deserializers/BacktraceApiResultDeserializerTest.java b/backtrace-library/src/test/java/backtraceio/library/deserializers/BacktraceApiResultDeserializerTest.java new file mode 100644 index 00000000..e851f0a9 --- /dev/null +++ b/backtrace-library/src/test/java/backtraceio/library/deserializers/BacktraceApiResultDeserializerTest.java @@ -0,0 +1,63 @@ +package backtraceio.library.deserializers; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import org.json.JSONException; +import org.json.JSONObject; +import org.junit.Test; + +import backtraceio.library.common.serializers.BacktraceOrgJsonDeserializer; +import backtraceio.library.common.serializers.deserializers.BacktraceApiResultDeserializer; +import backtraceio.library.models.BacktraceApiResult; +import backtraceio.library.models.BacktraceResult; +import backtraceio.library.models.types.BacktraceResultStatus; + +// TODO: move to standard unit tests not instrumented +// TODO: use from resources +public class BacktraceApiResultDeserializerTest { + + private final String JSON_1 = "{\"response\":\"Ok\",\"_rxid\":\"01000000-5360-240b-0000-000000000000\"}"; + @Test + public void deserializeCoronerApiJsonResponse() throws JSONException { + // GIVEN + String json = JSON_1; + + // WHEN + BacktraceApiResultDeserializer deserializer = new BacktraceApiResultDeserializer(); + BacktraceApiResult result = deserializer.deserialize(new JSONObject(json)); + + // THEN + assertNotNull(result); + assertEquals(BacktraceResultStatus.Ok.toString(), result.getResponse()); + assertEquals("01000000-5360-240b-0000-000000000000", result.getRxId()); + } + + @Test + public void deserializeCoronerApiJsonResponseUsingOrgDeserializer() throws JSONException { + // GIVEN + String json = JSON_1; + + // WHEN + BacktraceApiResult result = BacktraceOrgJsonDeserializer.deserialize(json, BacktraceApiResult.class); + + // THEN + assertNotNull(result); + assertEquals(BacktraceResultStatus.Ok.toString(), result.getResponse()); + assertEquals("01000000-5360-240b-0000-000000000000", result.getRxId()); + } + + @Test + public void deserializeCoronerApiErrorResponse() throws JSONException { + String json = "{ \"error\": { \"code\": 6, \"message\": \"invalid token\" } }"; // TODO: add proper error json + + // WHEN + BacktraceApiResult result = BacktraceOrgJsonDeserializer.deserialize(json, BacktraceApiResult.class); + + // THEN + assertNotNull(result); + assertEquals(BacktraceResultStatus.ServerError.toString(), result.getResponse()); + assertNull(result.getRxId()); + } +} diff --git a/example-app/src/main/java/backtraceio/backtraceio/MainActivity.java b/example-app/src/main/java/backtraceio/backtraceio/MainActivity.java index 714d5371..ca5af705 100644 --- a/example-app/src/main/java/backtraceio/backtraceio/MainActivity.java +++ b/example-app/src/main/java/backtraceio/backtraceio/MainActivity.java @@ -41,7 +41,7 @@ public class MainActivity extends AppCompatActivity { // Used to load the 'native-lib' library on application startup. static { - System.loadLibrary("native-lib"); +// System.loadLibrary("native-lib"); } public void setOnServerResponseEventListener(OnServerResponseEventListener e) { @@ -75,8 +75,9 @@ private void symlinkAndWriteFile() { } private BacktraceClient initializeBacktrace(final String submissionUrl) { - BacktraceCredentials credentials = new BacktraceCredentials(submissionUrl); - +// BacktraceCredentials credentials = new BacktraceCredentials(submissionUrl); +BacktraceCredentials credentials = new BacktraceCredentials("https://yolo.sp.backtrace.io:6098/", + "2dd86e8e779d1fc7e22e7b19a9489abeedec3b1426abe7e2209888e92362fba4"); Context context = getApplicationContext(); String dbPath = context.getFilesDir().getAbsolutePath(); From f936667eaa97ec6a132bdc744bc620878876b759 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Tue, 21 May 2024 22:43:46 +0200 Subject: [PATCH 040/100] Fix unit tests --- .../deserializers/BacktraceResultDeserializerTest.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/common/deserializers/BacktraceResultDeserializerTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/common/deserializers/BacktraceResultDeserializerTest.java index f284cc85..4f227929 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/common/deserializers/BacktraceResultDeserializerTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/common/deserializers/BacktraceResultDeserializerTest.java @@ -7,11 +7,13 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; import org.json.JSONException; +import org.json.JSONObject; import org.junit.Test; import org.junit.runner.RunWith; import backtraceio.library.common.serializers.BacktraceOrgJsonDeserializer; import backtraceio.library.common.serializers.deserializers.BacktraceApiResultDeserializer; +import backtraceio.library.models.BacktraceApiResult; import backtraceio.library.models.BacktraceResult; import backtraceio.library.models.types.BacktraceResultStatus; @@ -43,14 +45,12 @@ public void deserializeCoronerAPIJsonResponse() throws JSONException { String json = JSON_1; // WHEN - BacktraceResult result = BacktraceOrgJsonDeserializer.deserialize(json, BacktraceResult.class); + BacktraceApiResult result = deserializer.deserialize(new JSONObject(json)); // THEN assertNotNull(result); - assertNull(result.getBacktraceReport()); - assertNull(result.message); - assertEquals(BacktraceResultStatus.Ok, result.status); - assertEquals("01000000-5360-240b-0000-000000000000", result.rxId); + assertEquals("ok", result.getResponse()); + assertEquals("01000000-5360-240b-0000-000000000000", result.getRxId()); } } From ec62127c2618094cd78c0e16c57d9acafb39bc33 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 22 May 2024 20:36:27 +0200 Subject: [PATCH 041/100] Add extra check --- .../backtraceio/library/models/BacktraceDataTest.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) 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 d16a3e03..0dc93394 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/models/BacktraceDataTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/models/BacktraceDataTest.java @@ -2,8 +2,6 @@ import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; import android.content.Context; @@ -14,7 +12,9 @@ import org.junit.Test; import org.junit.runner.RunWith; +import java.util.Arrays; import java.util.HashMap; +import java.util.List; import backtraceio.library.models.json.BacktraceReport; @@ -30,7 +30,8 @@ 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); // WHEN BacktraceData backtraceData = new BacktraceData.Builder(context, report, new HashMap<>()).build(); @@ -51,5 +52,6 @@ public void createBacktraceDataTest() { assertEquals(backtraceData.mainThread, "instr: androidx.test.runner.androidjunitrunner"); assertEquals(backtraceData.sourceCode.size(), 34); assertEquals(backtraceData.getThreadInformationMap().size(), 13); + assertEquals(backtraceData.getAttachmentPaths().size(), 2); } } From 77d0fb8ed8d69a02b49b6acc74639dc2c25a6410 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 22 May 2024 20:43:07 +0200 Subject: [PATCH 042/100] Remove commented code --- .../library/common/BacktraceSerializeHelper.java | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) 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 d608ea86..b5920afc 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/BacktraceSerializeHelper.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/BacktraceSerializeHelper.java @@ -2,7 +2,6 @@ import com.google.gson.Gson; -import backtraceio.library.common.serialization.BacktraceGsonBuilder; import backtraceio.library.common.serializers.BacktraceOrgJsonDeserializer; import backtraceio.library.common.serializers.BacktraceOrgJsonSerializer; @@ -18,18 +17,16 @@ public class BacktraceSerializeHelper { * @return serialized object in JSON string format */ public static String toJson(Object object) { -// return new BacktraceGsonBuilder().buildGson().toJson(object); return BacktraceOrgJsonSerializer.toJson(object); } public static T fromJson(String json, Class type) { try { - return BacktraceOrgJsonDeserializer.deserialize(json, type); - } catch (Exception e) { - //TODO: remove this try-catch + return BacktraceOrgJsonDeserializer.deserialize(json, type); + } catch (Exception e) { + //TODO: remove this try-catch return null; - } -// return BacktraceSerializeHelper.fromJson(new BacktraceGsonBuilder().buildGson(), json, type); + } } public static T fromJson(Gson gson, String json, Class type) { @@ -39,7 +36,6 @@ public static T fromJson(Gson gson, String json, Class type) { //TODO: remove this try-catch return null; } -// return gson.fromJson(json, type); } } From e0dd7a342fe616f9a52def511c7017a067d5d952 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 22 May 2024 21:00:25 +0200 Subject: [PATCH 043/100] Fix naming --- .../common/serializers/SerializerHelper.java | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java index 2c1cd7f4..44cedd96 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java @@ -71,30 +71,31 @@ private static Object serializeException(NamingPolicy namingPolicy, Exception ex } } - private static JSONObject getAllFields(NamingPolicy namingPolicy, Class klass, Object obj, int serializationDepth) { + private static JSONObject getAllFields(NamingPolicy namingPolicy, Class serializedClass, Object obj, int serializationDepth) { // TODO: improve naming List fields = new ArrayList<>(); - for (Class c = klass; c != null; c = c.getSuperclass()) { - fields.addAll(Arrays.asList(c.getDeclaredFields())); + for (Class clazz = serializedClass; clazz != null; clazz = clazz.getSuperclass()) { + fields.addAll(Arrays.asList(clazz.getDeclaredFields())); } JSONObject result = new JSONObject(); - for (Field f : fields) { - f.setAccessible(true); + for (Field field : fields) { + field.setAccessible(true); - if (java.lang.reflect.Modifier.isTransient(f.getModifiers()) || - java.lang.reflect.Modifier.isStatic(f.getModifiers())) { + if (java.lang.reflect.Modifier.isTransient(field.getModifiers()) || + java.lang.reflect.Modifier.isStatic(field.getModifiers())) { continue; } try { - Object value = f.get(obj); + Object value = field.get(obj); if (value == obj) { continue; } - result.put(getFieldName(namingPolicy, f), serialize(namingPolicy, value, serializationDepth)); + result.put(getFieldName(namingPolicy, field), serialize(namingPolicy, value, serializationDepth)); } catch (Exception ex) { + // TODO: error handling // ex.printStackTrace(); } } @@ -144,6 +145,7 @@ public static Map executeAndGetMethods(NamingPolicy namingPolicy String propertyName = methodName.substring(3); // Remove 'get' prefix fields.put(namingPolicy.convert(propertyName), serialize(namingPolicy, result)); } catch (Exception e) { + // TODO: error handling e.printStackTrace(); } } From f1c44a54107cc9a26a65ca49f4f36f14497c4ecb Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Mon, 27 May 2024 23:13:58 +0200 Subject: [PATCH 044/100] Revert custom serializer --- backtrace-library/build.gradle | 2 - .../BacktraceClientSerializationTest.java | 2 +- .../common/BacktraceSerializeHelper.java | 28 ++- .../serializers/BacktraceDataSerializer.java | 136 ------------ .../serializers/BacktraceDeserializer.java | 49 ----- .../BacktraceOrgJsonDeserializer.java | 11 - .../BacktraceOrgJsonSerializer.java | 29 --- .../common/serializers/SerializedName.java | 27 --- .../common/serializers/SerializerHelper.java | 203 ------------------ .../BacktraceApiResultDeserializer.java | 24 --- .../BacktraceDataDeserializer.java | 151 ------------- .../BacktraceDatabaseRecordDeserializer.java | 31 --- .../BacktraceReportDeserializer.java | 108 ---------- .../BacktraceStackFrameDeserializer.java | 25 --- .../deserializers/Deserializable.java | 8 - .../deserializers/ExceptionDeserializer.java | 47 ---- .../GenericListDeserializer.java | 24 --- .../deserializers/MapDeserializer.java | 42 ---- .../deserializers/ReflectionDeserializer.java | 70 ------ .../deserializers/SourceCodeDeserializer.java | 22 -- .../ThreadInformationDeserializer.java | 42 ---- .../deserializers/cache/FieldNameCache.java | 38 ---- .../deserializers/cache/FieldNameLoader.java | 13 -- .../naming/LowerCaseWithDashConverter.java | 14 -- .../serializers/naming/NamingConverter.java | 5 - .../serializers/naming/NamingPolicy.java | 18 -- .../serializers/naming/NamingUtils.java | 18 -- .../library/models/BacktraceApiResult.java | 2 +- .../library/models/BacktraceData.java | 2 +- .../library/models/BacktraceStackFrame.java | 2 +- .../database/BacktraceDatabaseRecord.java | 2 +- .../library/models/json/BacktraceReport.java | 2 +- .../library/models/json/SourceCode.java | 2 +- .../models/json/ThreadInformation.java | 2 +- .../library/models/metrics/Event.java | 2 +- .../models/metrics/EventsMetadata.java | 2 +- .../library/models/metrics/EventsPayload.java | 2 +- .../library/models/metrics/SummedEvent.java | 2 +- .../models/metrics/SummedEventsPayload.java | 2 +- .../library/models/metrics/UniqueEvent.java | 2 +- .../models/metrics/UniqueEventsPayload.java | 2 +- .../library/BacktraceDataTest.java | 73 ------- .../BacktraceReportDeserializerTest.java | 44 ---- .../library/BacktraceSerializeHelperTest.java | 39 ---- .../BacktraceApiResultDeserializerTest.java | 63 ------ .../src/test/resources/backtraceData.json | 1 - 46 files changed, 27 insertions(+), 1408 deletions(-) delete mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java delete mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDeserializer.java delete mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceOrgJsonDeserializer.java delete mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceOrgJsonSerializer.java delete mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializedName.java delete mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java delete mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceApiResultDeserializer.java delete mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDataDeserializer.java delete mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDatabaseRecordDeserializer.java delete mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceReportDeserializer.java delete mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceStackFrameDeserializer.java delete mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/Deserializable.java delete mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ExceptionDeserializer.java delete mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/GenericListDeserializer.java delete mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/MapDeserializer.java delete mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ReflectionDeserializer.java delete mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/SourceCodeDeserializer.java delete mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ThreadInformationDeserializer.java delete mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/cache/FieldNameCache.java delete mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/cache/FieldNameLoader.java delete mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/naming/LowerCaseWithDashConverter.java delete mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/naming/NamingConverter.java delete mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/naming/NamingPolicy.java delete mode 100644 backtrace-library/src/main/java/backtraceio/library/common/serializers/naming/NamingUtils.java delete mode 100644 backtrace-library/src/test/java/backtraceio/library/BacktraceDataTest.java delete mode 100644 backtrace-library/src/test/java/backtraceio/library/BacktraceReportDeserializerTest.java delete mode 100644 backtrace-library/src/test/java/backtraceio/library/BacktraceSerializeHelperTest.java delete mode 100644 backtrace-library/src/test/java/backtraceio/library/deserializers/BacktraceApiResultDeserializerTest.java delete mode 100644 backtrace-library/src/test/resources/backtraceData.json diff --git a/backtrace-library/build.gradle b/backtrace-library/build.gradle index 8e483050..583705b1 100644 --- a/backtrace-library/build.gradle +++ b/backtrace-library/build.gradle @@ -72,8 +72,6 @@ dependencies { implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'com.squareup:tape:1.2.3' testImplementation 'junit:junit:4.13.2' - testImplementation 'org.json:json:20231013' - testImplementation 'com.google.code.gson:gson:2.10.1' androidTestImplementation 'net.jodah:concurrentunit:0.4.4' androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test:rules:1.5.0' diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientSerializationTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientSerializationTest.java index 000b6a4e..9f9c6e48 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientSerializationTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientSerializationTest.java @@ -6,7 +6,7 @@ import android.content.Context; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.platform.app.InstrumentationRegistry; -import backtraceio.library.common.serializers.SerializedName; +import com.google.gson.annotations.SerializedName; import net.jodah.concurrentunit.Waiter; import org.junit.Before; import org.junit.Test; 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 b5920afc..3ab9b70a 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/BacktraceSerializeHelper.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/BacktraceSerializeHelper.java @@ -1,9 +1,11 @@ package backtraceio.library.common; +import com.google.gson.FieldNamingPolicy; import com.google.gson.Gson; +import com.google.gson.GsonBuilder; -import backtraceio.library.common.serializers.BacktraceOrgJsonDeserializer; -import backtraceio.library.common.serializers.BacktraceOrgJsonSerializer; +import backtraceio.library.common.serialization.BacktraceGsonBuilder; +import backtraceio.library.models.BacktraceResult; /** * Helper class for serialize and deserialize objects @@ -17,25 +19,19 @@ public class BacktraceSerializeHelper { * @return serialized object in JSON string format */ public static String toJson(Object object) { - return BacktraceOrgJsonSerializer.toJson(object); + return BacktraceSerializeHelper.toJson(new BacktraceGsonBuilder().buildGson(), object); } public static T fromJson(String json, Class type) { - try { - return BacktraceOrgJsonDeserializer.deserialize(json, type); - } catch (Exception e) { - //TODO: remove this try-catch - return null; - } + return BacktraceSerializeHelper.fromJson(new BacktraceGsonBuilder().buildGson(), json, type); + } + + public static String toJson(Gson gson, Object object) { + return gson.toJson(object); } public static T fromJson(Gson gson, String json, Class type) { - try { - return BacktraceOrgJsonDeserializer.deserialize(json, type); - } catch (Exception e) { - //TODO: remove this try-catch - return null; - } + return gson.fromJson(json, type); } -} +} \ No newline at end of file diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java deleted file mode 100644 index 3b05c6e1..00000000 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDataSerializer.java +++ /dev/null @@ -1,136 +0,0 @@ -package backtraceio.library.common.serializers; - -import static backtraceio.library.common.serializers.SerializerHelper.serialize; - -import androidx.annotation.NonNull; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.List; -import java.util.Map; - -import backtraceio.library.common.serializers.naming.NamingPolicy; -import backtraceio.library.models.BacktraceData; -import backtraceio.library.models.BacktraceStackFrame; -import backtraceio.library.models.json.SourceCode; -import backtraceio.library.models.json.ThreadInformation; - -public class BacktraceDataSerializer { - NamingPolicy namingPolicy; - public BacktraceDataSerializer(NamingPolicy policy) { - namingPolicy = policy; - } - - - public JSONObject toJson(BacktraceData data) throws JSONException, IllegalAccessException { - { - if (data == null) { - return null; - } - - JSONObject json = new JSONObject(); - - // Serialize simple fields - json.put("lang", data.lang); - json.put("agent", data.agent); - json.put("symbolication", data.symbolication); - json.put("uuid", data.uuid); - json.put("timestamp", data.timestamp); - json.put("langVersion", data.langVersion); - json.put("agentVersion", data.agentVersion); - json.put("mainThread", data.mainThread); - - if (data.classifiers != null) { - final JSONArray classifiers = new JSONArray(); - for (String classifier : data.classifiers) { - classifiers.put(classifier); - } - json.put("classifiers", classifiers); - } - - if (data.attributes != null) { - json.put("attributes", serializeAttributes(data.attributes)); - } - - if (data.annotations != null) { - json.put("annotations", serializeAnnotations(data.annotations)); - } - - if (data.sourceCode != null) { - json.put("sourceCode", serializeSourceCode(data.sourceCode)); - } - - if (data.getThreadInformationMap() != null) { - JSONObject threadInformationJson = serializeThreadInformation(data.getThreadInformationMap()); - json.put("threads", threadInformationJson); - } - - return json; - } - } - - @NonNull - private JSONObject serializeThreadInformation(Map threadInformationMap) throws JSONException { - JSONObject threadInformationJson = new JSONObject(); - for (Map.Entry entry : threadInformationMap.entrySet()) { - ThreadInformation threadInfo = entry.getValue(); - JSONObject threadInfoObj = new JSONObject(); - threadInfoObj.put("name", threadInfo.getName()); - threadInfoObj.put("fault", threadInfo.getFault()); - if (threadInfo.getStack() != null) { - JSONArray stackArray = serializeStackList(threadInfo.getStack()); - threadInfoObj.put("stack", stackArray); - } - threadInformationJson.put(entry.getKey(), threadInfoObj); - } - return threadInformationJson; - } - - @NonNull - private JSONArray serializeStackList(List stack) throws JSONException { - JSONArray stackArray = new JSONArray(); - - for (BacktraceStackFrame stackFrame : stack) { - JSONObject stackFrameObj = new JSONObject(); - stackFrameObj.put("funcName", stackFrame.functionName); - stackFrameObj.put("line", stackFrame.line); - stackFrameObj.put("sourceCode", stackFrame.sourceCode); - stackArray.put(stackFrameObj); - } - - return stackArray; - } - - @NonNull - private JSONObject serializeSourceCode(Map sourceCodeMap) throws JSONException { - JSONObject sourceCodeJson = new JSONObject(); - for (Map.Entry entry : sourceCodeMap.entrySet()) { - SourceCode sourceCode = entry.getValue(); - JSONObject sourceCodeObj = new JSONObject(); - sourceCodeObj.put("startLine", sourceCode.startLine); - sourceCodeObj.put("path", sourceCode.sourceCodeFileName); - sourceCodeJson.put(entry.getKey(), sourceCodeObj); - } - return sourceCodeJson; - } - - private JSONObject serializeAnnotations(Map annotations) throws JSONException, IllegalAccessException { - JSONObject annotationsJson = new JSONObject(); - for (Map.Entry entry : annotations.entrySet()) { - annotationsJson.put(entry.getKey(), serialize(this.namingPolicy, entry.getValue())); - } - return annotationsJson; - } - - private JSONObject serializeAttributes(Map attributes) throws JSONException { - JSONObject attributesJson = new JSONObject(); - - for (Map.Entry entry : attributes.entrySet()) { - attributesJson.put(entry.getKey(), entry.getValue()); - } - - return attributesJson; - } -} diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDeserializer.java deleted file mode 100644 index 5fcfeebc..00000000 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceDeserializer.java +++ /dev/null @@ -1,49 +0,0 @@ -package backtraceio.library.common.serializers; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.HashMap; - -import backtraceio.library.common.serializers.deserializers.BacktraceApiResultDeserializer; -import backtraceio.library.common.serializers.deserializers.BacktraceDataDeserializer; -import backtraceio.library.common.serializers.deserializers.BacktraceDatabaseRecordDeserializer; -import backtraceio.library.common.serializers.deserializers.BacktraceReportDeserializer; -import backtraceio.library.common.serializers.deserializers.Deserializable; -import backtraceio.library.common.serializers.deserializers.ExceptionDeserializer; -import backtraceio.library.common.serializers.deserializers.ReflectionDeserializer; -import backtraceio.library.models.BacktraceApiResult; -import backtraceio.library.models.BacktraceData; -import backtraceio.library.models.database.BacktraceDatabaseRecord; -import backtraceio.library.models.json.BacktraceReport; - -public class BacktraceDeserializer { - - public final static Deserializable DEFAULT_DESERIALIZER = new ReflectionDeserializer(); - public static HashMap deserializers = new HashMap() {{ - put(BacktraceApiResult.class, new BacktraceApiResultDeserializer()); - put(BacktraceReport.class, new BacktraceReportDeserializer()); - put(BacktraceData.class, new BacktraceDataDeserializer()); - put(Exception.class, new ExceptionDeserializer()); - put(BacktraceDatabaseRecord.class, new BacktraceDatabaseRecordDeserializer()); - }}; - - public static void registerDeserializer(Class clazz, Deserializable obj) { - deserializers.put(clazz, obj); - } - - @SuppressWarnings("unchecked") - public static T deserialize(JSONObject obj, Class clazz) throws JSONException { - if (obj == null) { -// LOGG - // TODO: Add logging - return null; - } - if (deserializers.containsKey(clazz)) { - // TODO: check if deserializers.get(clazz) is not null - return (T) deserializers.get(clazz).deserialize(obj); - } - // todo: maybe return unsupported - return (T) DEFAULT_DESERIALIZER.deserialize(obj); - } -} diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceOrgJsonDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceOrgJsonDeserializer.java deleted file mode 100644 index 5c34a45c..00000000 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceOrgJsonDeserializer.java +++ /dev/null @@ -1,11 +0,0 @@ -package backtraceio.library.common.serializers; - -import org.json.JSONException; -import org.json.JSONObject; - -public class BacktraceOrgJsonDeserializer { - - public static T deserialize(String jsonString, Class clazz) throws JSONException { - return BacktraceDeserializer.deserialize(new JSONObject(jsonString), clazz); - } -} diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceOrgJsonSerializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceOrgJsonSerializer.java deleted file mode 100644 index 03a95371..00000000 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/BacktraceOrgJsonSerializer.java +++ /dev/null @@ -1,29 +0,0 @@ -package backtraceio.library.common.serializers; - -import backtraceio.library.common.serializers.naming.NamingPolicy; -import backtraceio.library.models.BacktraceData; - -public class BacktraceOrgJsonSerializer { - - public static String toJson(Object object) { // TODO: remove IllegalAccessException - if (object == null) { - return null; - } - - try { - NamingPolicy namingPolicy = new NamingPolicy(); - Class clazz = object.getClass(); - - if (clazz.equals(BacktraceData.class)) { - BacktraceDataSerializer dataSerializer = new BacktraceDataSerializer(namingPolicy); - return dataSerializer.toJson((BacktraceData) object).toString(); - } - - return SerializerHelper.serialize(namingPolicy, object).toString(); - } - catch (Exception ex) { // TODO: improve error handling - ex.printStackTrace(); - return null; - } - } -} diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializedName.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializedName.java deleted file mode 100644 index 1f5de375..00000000 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializedName.java +++ /dev/null @@ -1,27 +0,0 @@ -package backtraceio.library.common.serializers; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Documented -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.FIELD, ElementType.METHOD}) -public @interface SerializedName { - - /** - * The desired name of the field when it is serialized or deserialized. - * - * @return the desired name of the field when it is serialized or deserialized - */ - String value(); - - /** - * The alternative names of the field when it is deserialized - * - * @return the alternative names of the field when it is deserialized - */ - String[] alternate() default {}; -} \ No newline at end of file diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java deleted file mode 100644 index 44cedd96..00000000 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/SerializerHelper.java +++ /dev/null @@ -1,203 +0,0 @@ -package backtraceio.library.common.serializers; - -import android.os.Build; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -import backtraceio.library.common.serializers.naming.NamingPolicy; - -public class SerializerHelper { - public static int MAX_SERIALIZATION_LEVEL = 5; - private static final Map, Class> WRAPPER_TYPE_MAP; - - static { - WRAPPER_TYPE_MAP = new HashMap<>(); - WRAPPER_TYPE_MAP.put(Integer.class, int.class); - WRAPPER_TYPE_MAP.put(Byte.class, byte.class); - WRAPPER_TYPE_MAP.put(Character.class, char.class); - WRAPPER_TYPE_MAP.put(Boolean.class, boolean.class); - WRAPPER_TYPE_MAP.put(Double.class, double.class); - WRAPPER_TYPE_MAP.put(Float.class, float.class); - WRAPPER_TYPE_MAP.put(Long.class, long.class); - WRAPPER_TYPE_MAP.put(Short.class, short.class); - WRAPPER_TYPE_MAP.put(Void.class, void.class); - } - - public static boolean isPrimitiveType(Object source) { - return WRAPPER_TYPE_MAP.containsKey(source.getClass()) || source instanceof String || source instanceof Number; - } - - private static JSONArray serializeArray(NamingPolicy namingPolicy, Object[] array, int serializationDepth) throws JSONException { - if (array == null) { - return null; - } - - JSONArray jsonArray = new JSONArray(); - for (Object item : array) { - jsonArray.put(serialize(namingPolicy, item, serializationDepth)); - } - return jsonArray; - } - private static JSONArray serializeCollection(NamingPolicy namingPolicy, Collection collection, int serializationDepth) throws JSONException { - if (collection == null) { - return null; - } - - JSONArray jsonArray = new JSONArray(); - for (Object item : collection) { - jsonArray.put(serialize(namingPolicy, item, serializationDepth)); - } - return jsonArray; - } - - private static Object serializeException(NamingPolicy namingPolicy, Exception exception) { - try { - return getAllFields(namingPolicy, exception.getClass(), exception, 2); - } - catch (Exception e) { - return null; - } - } - - private static JSONObject getAllFields(NamingPolicy namingPolicy, Class serializedClass, Object obj, int serializationDepth) { - // TODO: improve naming - - List fields = new ArrayList<>(); - for (Class clazz = serializedClass; clazz != null; clazz = clazz.getSuperclass()) { - fields.addAll(Arrays.asList(clazz.getDeclaredFields())); - } - - JSONObject result = new JSONObject(); - for (Field field : fields) { - field.setAccessible(true); - - if (java.lang.reflect.Modifier.isTransient(field.getModifiers()) || - java.lang.reflect.Modifier.isStatic(field.getModifiers())) { - continue; - } - - try { - Object value = field.get(obj); - if (value == obj) { - continue; - } - result.put(getFieldName(namingPolicy, field), serialize(namingPolicy, value, serializationDepth)); - } catch (Exception ex) { - // TODO: error handling -// ex.printStackTrace(); - } - } - - return result; - } - - private static String getFieldName(NamingPolicy namingPolicy, Field field) { - if (field.isAnnotationPresent(SerializedName.class)) { - // Get the SerializedName value - SerializedName annotation = field.getAnnotation(SerializedName.class); - return annotation.value(); - } - return namingPolicy.convert(field.getName()); - } - - private static JSONObject serializeMap(NamingPolicy namingPolicy, Map map, int serializationDepth) throws JSONException { - JSONObject jsonObject = new JSONObject(); - for (Map.Entry entry : map.entrySet()) { - String key = String.valueOf(entry.getKey()); - Object value = entry.getValue(); - jsonObject.put(key, serialize(namingPolicy, value, serializationDepth)); - } - return jsonObject; - } - - public static Object serialize(NamingPolicy namingPolicy, Object obj) throws JSONException { - return serialize(namingPolicy, obj, 0); - } - - public static Map executeAndGetMethods(NamingPolicy namingPolicy, Object obj) { - Class clazz = obj.getClass(); - Map fields = new HashMap<>(); - Method[] methods = clazz.getMethods(); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // TODO: check if needed - for (Method method : methods) { - String methodName = method.getName(); - - if (methodName.equals("getClass") || methodName.equals("getClassName")) { - continue; - } - - if (methodName.startsWith("get") && method.getParameterCount() == 0) { - try { - Object result = method.invoke(obj); - String propertyName = methodName.substring(3); // Remove 'get' prefix - fields.put(namingPolicy.convert(propertyName), serialize(namingPolicy, result)); - } catch (Exception e) { - // TODO: error handling - e.printStackTrace(); - } - } - } - } - return fields; - } - - public static Object serialize(NamingPolicy namingPolicy, Object obj, int serializationDepth) throws JSONException { - if (obj == null) { - return null; - } - - if (serializationDepth > MAX_SERIALIZATION_LEVEL) { - return new JSONObject(); - } - - // TODO: check if all of the types - if (SerializerHelper.isPrimitiveType(obj)) { - return obj; - } - - serializationDepth++; - - if (obj instanceof UUID) { - return obj.toString(); - } - - if (obj instanceof Map) { - return serializeMap(namingPolicy, (Map) obj, serializationDepth); - } - - if (obj.getClass().isArray()) { - return serializeArray(namingPolicy, (Object[]) obj, serializationDepth); - } - - if (obj instanceof Collection) { - return serializeCollection(namingPolicy, (Collection) obj, serializationDepth); - } - - if (obj instanceof Exception) { - return serializeException(namingPolicy, (Exception) obj); - } - - Class clazz = obj.getClass(); - JSONObject jsonObject = getAllFields(namingPolicy, clazz, obj, serializationDepth); - Map getters = executeAndGetMethods(namingPolicy, obj); - - for (Map.Entry entry: getters.entrySet()) { - jsonObject.put(namingPolicy.convert(entry.getKey()), entry.getValue()); - } - - return jsonObject; - } -} diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceApiResultDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceApiResultDeserializer.java deleted file mode 100644 index abf954eb..00000000 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceApiResultDeserializer.java +++ /dev/null @@ -1,24 +0,0 @@ -package backtraceio.library.common.serializers.deserializers; - -import org.json.JSONException; -import org.json.JSONObject; - -import backtraceio.library.common.serializers.deserializers.cache.FieldNameLoader; -import backtraceio.library.models.BacktraceApiResult; -import backtraceio.library.models.types.BacktraceResultStatus; - -public class BacktraceApiResultDeserializer implements Deserializable { - - private final FieldNameLoader fieldNameLoader = new FieldNameLoader(BacktraceApiResult.class); // TODO: maybe we can reuse it - - static class Fields { - final static String rxId = "rxId"; - final static String response = "response"; - } - public BacktraceApiResult deserialize(JSONObject obj) throws JSONException { - return new BacktraceApiResult( - obj.optString(fieldNameLoader.get(Fields.rxId), null), // TODO: check fallback warning - obj.optString(fieldNameLoader.get(Fields.response), BacktraceResultStatus.ServerError.toString()) - ); - } -} diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDataDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDataDeserializer.java deleted file mode 100644 index 5d76ddcb..00000000 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDataDeserializer.java +++ /dev/null @@ -1,151 +0,0 @@ -package backtraceio.library.common.serializers.deserializers; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -import backtraceio.library.common.serializers.deserializers.cache.FieldNameLoader; -import backtraceio.library.models.BacktraceData; -import backtraceio.library.models.json.BacktraceReport; -import backtraceio.library.models.json.SourceCode; -import backtraceio.library.models.json.ThreadInformation; - -// TODO: check if methods should be private -public class BacktraceDataDeserializer implements Deserializable { - - private final FieldNameLoader fieldNameLoader = new FieldNameLoader(BacktraceData.class); // TODO: maybe we can reuse it - - static class Fields { - final static String uuid = "uuid"; - final static String symbolication = "symbolication"; - final static String timestamp = "timestamp"; - final static String langVersion = "langVersion"; - final static String agentVersion = "agentVersion"; - final static String attributes = "attributes"; - final static String mainThread = "mainThread"; - final static String classifiers = "classifiers"; - final static String annotations = "annotations"; - final static String sourceCode = "sourceCode"; - final static String report = "report"; - final static String threadInformationMap = "threadInformationMap"; - - } - - public BacktraceData deserialize(JSONObject obj) throws JSONException { - return new BacktraceData( - obj.optString(fieldNameLoader.get(Fields.uuid)), - obj.optString(fieldNameLoader.get(Fields.symbolication)), - obj.optLong(fieldNameLoader.get(Fields.timestamp)), - obj.optString(fieldNameLoader.get(Fields.langVersion)), // TODO: fix or improve casing should get from annotation - obj.optString(fieldNameLoader.get(Fields.agentVersion)), // TODO: fix or improve casing should get from annotation - // TODO: fix all below and maybe add fallback - getAttributes(obj.optJSONObject(fieldNameLoader.get(Fields.attributes))), - obj.optString(fieldNameLoader.get(Fields.mainThread)), - getClassifiers(obj.optJSONArray(fieldNameLoader.get(Fields.classifiers))), - getBacktraceReport(obj.optJSONObject(fieldNameLoader.get(Fields.report))), - getAnnotations(obj.optJSONObject(fieldNameLoader.get(Fields.annotations))), - getSourceCode(obj.optJSONObject(fieldNameLoader.get(Fields.sourceCode))), - getThreadInformation(obj.optJSONObject(fieldNameLoader.get(Fields.threadInformationMap))) - ); // TODO - } - - public BacktraceReport getBacktraceReport(JSONObject obj) throws JSONException { - // TODO: reuse deserializer ? - BacktraceReportDeserializer deserializer = new BacktraceReportDeserializer(); - return deserializer.deserialize(obj); - } - - public Map getAnnotations(JSONObject obj) throws JSONException { - // TODO: Fix: throwing exception - return MapDeserializer.toMap(obj); - } - - public Map getSourceCode(JSONObject obj) { - if (obj == null) { - return null; - } - SourceCodeDeserializer deserializer = new SourceCodeDeserializer(); - - Map result = new HashMap<>(); - - Iterator keys = obj.keys(); - - while (keys.hasNext()) { - String key = keys.next(); - try { - if (obj.get(key) instanceof JSONObject) { - result.put(key, deserializer.deserialize((JSONObject) obj.get(key))); - } - } catch (JSONException e) { - // TODO: - } - } - return result; - } - - public Map getThreadInformation(JSONObject obj) { - // TODO: what if obj == null - if (obj == null) { - return null; - } - Map result = new HashMap<>(); - final ThreadInformationDeserializer deserializer = new ThreadInformationDeserializer(); - Iterator keys = obj.keys(); - - while (keys.hasNext()) { - String key = keys.next(); - try { - if (obj.get(key) instanceof JSONObject) { - result.put(key, deserializer.deserialize((JSONObject) obj.get(key))); - } - } catch (JSONException e) { - // TODO: - } - } - return result; - } - - public String[] getClassifiers(JSONArray jsonArray) { - if (jsonArray == null) { - return new String[0]; - } - - String[] result = new String[jsonArray.length()]; - - for (int i = 0; i < jsonArray.length(); i++) { - try { - Object object = jsonArray.get(i); - result[i] = object.toString(); - } catch (JSONException exception) { - // todo: error handling - } - } - - return result; - } - - public Map getAttributes(JSONObject obj) { - Map result = new HashMap<>(); - - if (obj == null) { - return result; - } - - Iterator keys = obj.keys(); - - while (keys.hasNext()) { - String key = keys.next(); - try { - result.put(key, obj.get(key).toString()); - } catch (JSONException e) { - // TODO: error handling - } - } - - return result; - } -} diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDatabaseRecordDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDatabaseRecordDeserializer.java deleted file mode 100644 index 8e6d69e0..00000000 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceDatabaseRecordDeserializer.java +++ /dev/null @@ -1,31 +0,0 @@ -package backtraceio.library.common.serializers.deserializers; - -import org.json.JSONException; -import org.json.JSONObject; - -import backtraceio.library.common.serializers.deserializers.cache.FieldNameLoader; -import backtraceio.library.models.database.BacktraceDatabaseRecord; - -public class BacktraceDatabaseRecordDeserializer implements Deserializable { - - private final FieldNameLoader fieldNameLoader = new FieldNameLoader(BacktraceDatabaseRecord.class); // TODO: maybe we can reuse it - static class Fields { - final static String id = "id"; - final static String path = "path"; - final static String recordPath = "recordPath"; - final static String diagnosticDataPath = "diagnosticDataPath"; - final static String reportPath = "reportPath"; - final static String size = "size"; - } - - public BacktraceDatabaseRecord deserialize(JSONObject obj) throws JSONException { - return new BacktraceDatabaseRecord( - obj.optString(fieldNameLoader.get(Fields.id)), - obj.optString(fieldNameLoader.get(Fields.path)), - obj.optString(fieldNameLoader.get(Fields.recordPath)), - obj.optString(fieldNameLoader.get(Fields.diagnosticDataPath)), - obj.optString(fieldNameLoader.get(Fields.reportPath)), - obj.optLong(fieldNameLoader.get(Fields.size)) - ); - } -} diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceReportDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceReportDeserializer.java deleted file mode 100644 index b24f4174..00000000 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceReportDeserializer.java +++ /dev/null @@ -1,108 +0,0 @@ -package backtraceio.library.common.serializers.deserializers; - -import static backtraceio.library.common.BacktraceStringHelper.isNullOrEmpty; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -import backtraceio.library.common.serializers.deserializers.cache.FieldNameLoader; -import backtraceio.library.models.BacktraceStackFrame; -import backtraceio.library.models.json.BacktraceReport; - -public class BacktraceReportDeserializer implements Deserializable { - - private final FieldNameLoader fieldNameLoader = new FieldNameLoader(BacktraceReport.class); // TODO: maybe we can reuse it - final ExceptionDeserializer exceptionDeserializer; - - final BacktraceStackFrameDeserializer stackFrameDeserializer; - - static class Fields { - final static String uuid = "uuid"; - final static String timestamp = "timestamp"; - final static String exceptionTypeReport = "exceptionTypeReport"; - final static String attributes = "attributes"; - final static String classifier = "classifier"; - final static String message = "message"; - final static String exception = "exception"; - final static String attachmentPaths = "attachmentPaths"; - final static String diagnosticStack = "diagnosticStack"; - } - - public BacktraceReportDeserializer() { - this.exceptionDeserializer = new ExceptionDeserializer(); - this.stackFrameDeserializer = new BacktraceStackFrameDeserializer(); - } - @Override - // TODO: fix all null warnings - public BacktraceReport deserialize(JSONObject obj) throws JSONException { - if (obj == null) { - return null; - } - final String uuid = obj.optString(fieldNameLoader.get(Fields.uuid), null); - final long timestamp = obj.optLong(fieldNameLoader.get(Fields.timestamp), 0); - final String message = obj.optString(fieldNameLoader.get(Fields.message), null); - final String classifier = obj.optString(fieldNameLoader.get(Fields.classifier), ""); - final boolean exceptionTypeReport = obj.optBoolean(fieldNameLoader.get(Fields.exceptionTypeReport)); - final Exception exception = getException(obj.optJSONObject(fieldNameLoader.get(Fields.exception))); - final Map attributes = this.getAttributes(obj.optJSONObject(fieldNameLoader.get(Fields.attributes))); - - final List attachmentPaths = this.getAttachmentList(obj.optJSONArray(fieldNameLoader.get(Fields.attachmentPaths))); - final List diagnosticStack = this.getDiagnosticStack(obj.optJSONArray(fieldNameLoader.get(Fields.diagnosticStack))); - - return new BacktraceReport( - !isNullOrEmpty(uuid)? UUID.fromString(uuid) : null, - timestamp, - exceptionTypeReport, - classifier, - attributes, - message, - exception, - attachmentPaths, - diagnosticStack - ); - } - - public Exception getException(JSONObject obj) { - if (obj == null) { - return null; - } - return this.exceptionDeserializer.deserialize(obj); // TODO: fix usage - } - - public Map getAttributes(JSONObject obj) throws JSONException { - if (obj == null) { - return null; - } - - return MapDeserializer.toMap(obj); // TODO: check exception - } - - public List getAttachmentList(JSONArray array) { - if (array == null) { - return new ArrayList<>(); - } - - List result = new ArrayList<>(); - - for (int i = 0; i < array.length(); i++) { - result.add(array.optString(i)); - } - - return result; - } - - public List getDiagnosticStack(JSONArray array) { - if (array == null) { - return null; - } - - GenericListDeserializer deserializer = new GenericListDeserializer<>(); - return deserializer.deserialize(array, this.stackFrameDeserializer); - } -} diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceStackFrameDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceStackFrameDeserializer.java deleted file mode 100644 index 624bf81f..00000000 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/BacktraceStackFrameDeserializer.java +++ /dev/null @@ -1,25 +0,0 @@ -package backtraceio.library.common.serializers.deserializers; - -import org.json.JSONException; -import org.json.JSONObject; - -import backtraceio.library.common.serializers.deserializers.cache.FieldNameLoader; -import backtraceio.library.models.BacktraceStackFrame; - -public class BacktraceStackFrameDeserializer implements Deserializable { - - private final FieldNameLoader fieldNameLoader = new FieldNameLoader(BacktraceStackFrame.class); // TODO: maybe we can reuse it - - static class Fields { - final static String functionName = "functionName"; - final static String line = "line"; - final static String sourceCode = "sourceCode"; - } - public BacktraceStackFrame deserialize(JSONObject obj) throws JSONException { - return new BacktraceStackFrame( - obj.optString(fieldNameLoader.get(Fields.functionName), null), // TODO: check fallback warning - obj.optString(fieldNameLoader.get(Fields.sourceCode), null), // TODO: check fallback warning // todo: should be null in case of empty - obj.optInt(fieldNameLoader.get(Fields.line))); // TODO: check fallback warning - } -} - diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/Deserializable.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/Deserializable.java deleted file mode 100644 index 9b7bae19..00000000 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/Deserializable.java +++ /dev/null @@ -1,8 +0,0 @@ -package backtraceio.library.common.serializers.deserializers; - -import org.json.JSONException; -import org.json.JSONObject; - -public interface Deserializable { - T deserialize(JSONObject obj) throws JSONException; -} diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ExceptionDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ExceptionDeserializer.java deleted file mode 100644 index 96d6291d..00000000 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ExceptionDeserializer.java +++ /dev/null @@ -1,47 +0,0 @@ -package backtraceio.library.common.serializers.deserializers; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -public class ExceptionDeserializer implements Deserializable { - static class Fields { - final static String startLine = "startLine"; - final static String sourceCodeFileName = "sourceCodeFileName"; - } - @Override - public Exception deserialize(JSONObject obj) { - final String message = obj.optString("detail-message", ""); - - final Exception exception = new Exception(message); - - try { - exception.setStackTrace(getStacktrace(obj.optJSONArray("stack-trace"))); - } - catch (JSONException jsonException) { - //TODO: handle - System.out.println(jsonException.toString()); - } - return exception; - } - - public StackTraceElement[] getStacktrace(JSONArray array) throws JSONException { - if (array == null || array.length() == 0) { - // TODO: - return null; - } - - StackTraceElement[] result = new StackTraceElement[array.length()]; - for(int idx = 0; idx < array.length(); idx++) { - JSONObject obj = (JSONObject) array.get(idx); - result[idx] = new StackTraceElement( - obj.optString("declaring-class"), // TODO: make something to not hardcode in this way - obj.getString("method-name"), // TODO: make something to not hardcode in this way - obj.optString("file-name"), // TODO: make something to not hardcode in this way - obj.getInt("line-number") // TODO: make something to not hardcode in this way - ); - } - - return result; - } -} diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/GenericListDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/GenericListDeserializer.java deleted file mode 100644 index 46ec0b1b..00000000 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/GenericListDeserializer.java +++ /dev/null @@ -1,24 +0,0 @@ -package backtraceio.library.common.serializers.deserializers; - -import org.json.JSONArray; -import org.json.JSONObject; - -import java.util.ArrayList; -import java.util.List; - -public class GenericListDeserializer { - List deserialize(JSONArray array, Deserializable deserializer) { - List result = new ArrayList(); - for (int i = 0; i < array.length(); i++) { - JSONObject obj = array.optJSONObject(i); - if (obj != null) { - try { - result.add(deserializer.deserialize(obj)); - } catch (Exception e) { - // TODO: handle - } - } - } - return result; - } -} diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/MapDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/MapDeserializer.java deleted file mode 100644 index b7725174..00000000 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/MapDeserializer.java +++ /dev/null @@ -1,42 +0,0 @@ -package backtraceio.library.common.serializers.deserializers; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -public class MapDeserializer { - public static Map toMap(JSONObject jsonObj) throws JSONException { - Map map = new HashMap<>(); - Iterator keys = jsonObj.keys(); - while(keys.hasNext()) { - String key = keys.next(); - Object value = jsonObj.get(key); - if (value instanceof JSONArray) { - value = toList((JSONArray) value); - } else if (value instanceof JSONObject) { - value = toMap((JSONObject) value); - } - map.put(key, value); - } return map; - } - - public static List toList(JSONArray array) throws JSONException { - List list = new ArrayList<>(); - for(int i = 0; i < array.length(); i++) { - Object value = array.get(i); - if (value instanceof JSONArray) { - value = toList((JSONArray) value); - } - else if (value instanceof JSONObject) { - value = toMap((JSONObject) value); - } - list.add(value); - } return list; - } -} diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ReflectionDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ReflectionDeserializer.java deleted file mode 100644 index a499d9c0..00000000 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ReflectionDeserializer.java +++ /dev/null @@ -1,70 +0,0 @@ -package backtraceio.library.common.serializers.deserializers; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.lang.reflect.InvocationTargetException; - -import backtraceio.library.common.serializers.SerializedName; - - -public final class ReflectionDeserializer implements Deserializable { - - @Override - public Object deserialize(JSONObject obj) throws JSONException { - try { - Class clazz = Object.class; - - // Get the class type from the JSON object if available - if (obj.has("classType")) { - String className = obj.getString("classType"); - clazz = Class.forName(className); - } - - // Create an instance of the class using reflection - Object instance = clazz.getDeclaredConstructor().newInstance(); - // Assuming that the class has a default (no-argument) constructor - - // Iterate through the fields of the class - for (java.lang.reflect.Field field : clazz.getDeclaredFields()) { - // Make the field accessible (public, private, etc.) - field.setAccessible(true); - - // Get the field name - String fieldName = field.getName(); - - // Check if the JSON object has a key with the field name - if (obj.has(fieldName)) { - // Set the field value using reflection - field.set(instance, obj.get(fieldName)); - continue; - } - - - if (field.isAnnotationPresent(SerializedName.class)) { - SerializedName annotation = field.getAnnotation(SerializedName.class); - if (annotation != null) { - String customName = annotation.value(); - field.set(instance, obj.get(customName)); - continue; - } - - } - } - - return instance; - } catch (InstantiationException | IllegalAccessException e) { - e.printStackTrace(); // Handle the exception appropriately - } catch (JSONException e) { - throw new RuntimeException(e); - } catch (ClassNotFoundException e) { - throw new RuntimeException(e); - } catch (InvocationTargetException e) { - throw new RuntimeException(e); - } catch (NoSuchMethodException e) { - throw new RuntimeException(e); - } - - return null; - } -} diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/SourceCodeDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/SourceCodeDeserializer.java deleted file mode 100644 index 7a9e1ae5..00000000 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/SourceCodeDeserializer.java +++ /dev/null @@ -1,22 +0,0 @@ -package backtraceio.library.common.serializers.deserializers; - -import org.json.JSONException; -import org.json.JSONObject; - -import backtraceio.library.common.serializers.deserializers.cache.FieldNameLoader; -import backtraceio.library.models.json.SourceCode; - -public class SourceCodeDeserializer implements Deserializable { - private final FieldNameLoader fieldNameLoader = new FieldNameLoader(SourceCode.class); // TODO: maybe we can reuse it - - static class Fields { - final static String startLine = "startLine"; - final static String sourceCodeFileName = "sourceCodeFileName"; - } - public SourceCode deserialize(JSONObject obj) throws JSONException { - return new SourceCode( - obj.optInt(fieldNameLoader.get(Fields.startLine)), - obj.optString(fieldNameLoader.get(Fields.sourceCodeFileName)) - ); - } -} diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ThreadInformationDeserializer.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ThreadInformationDeserializer.java deleted file mode 100644 index 1507e7fa..00000000 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/ThreadInformationDeserializer.java +++ /dev/null @@ -1,42 +0,0 @@ -package backtraceio.library.common.serializers.deserializers; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.List; - -import backtraceio.library.common.serializers.deserializers.cache.FieldNameLoader; -import backtraceio.library.models.BacktraceStackFrame; -import backtraceio.library.models.json.ThreadInformation; - -public class ThreadInformationDeserializer implements Deserializable { - - private final FieldNameLoader fieldNameLoader = new FieldNameLoader(ThreadInformation.class); // TODO: maybe we can reuse it - final BacktraceStackFrameDeserializer stackFrameDeserializer; - static class Fields { - final static String name = "name"; - final static String fault = "fault"; - final static String stack = "stack"; - } - - public ThreadInformationDeserializer() { - this.stackFrameDeserializer = new BacktraceStackFrameDeserializer(); - } - - public ThreadInformation deserialize(JSONObject obj) throws JSONException { - return new ThreadInformation( - obj.optString(fieldNameLoader.get(Fields.name), null), // TODO: fallback warning - obj.optBoolean(fieldNameLoader.get(Fields.fault), false), - getBacktraceStackFrameList(obj.optJSONArray(fieldNameLoader.get(Fields.stack)))); - } - - public List getBacktraceStackFrameList(JSONArray array) { - if (array == null) { - return null; // todo: Check if we should return empty or null - } - - GenericListDeserializer deserializer = new GenericListDeserializer<>(); - return deserializer.deserialize(array, this.stackFrameDeserializer); - } -} diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/cache/FieldNameCache.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/cache/FieldNameCache.java deleted file mode 100644 index dfae1688..00000000 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/cache/FieldNameCache.java +++ /dev/null @@ -1,38 +0,0 @@ -package backtraceio.library.common.serializers.deserializers.cache; - -import androidx.annotation.NonNull; - -import java.lang.reflect.Field; -import java.util.HashMap; -import java.util.Map; - -import backtraceio.library.common.serializers.SerializedName; - -public class FieldNameCache { - // Map to store annotation information - private final static Map fieldNameMap = new HashMap<>(); - - // Method to get annotation for a given class and field - public static String getAnnotation(Class clazz, @NonNull String fieldName) { - // Generate a unique key for the class and field combination - String key = clazz.getName() + "_" + fieldName; - - // Check if the annotation is already cached - String cachedFieldName = fieldNameMap.get(key); - if (cachedFieldName == null) { - // If not cached, retrieve the annotation and store it in the map - try { - Field field = clazz.getDeclaredField(fieldName); - if (field.isAnnotationPresent(SerializedName.class)) { - cachedFieldName = field.getAnnotation(SerializedName.class).value(); - fieldNameMap.put(key, cachedFieldName); - } else { - cachedFieldName = field.getName(); - } - } catch (NoSuchFieldException e) { - e.printStackTrace(); - } - } - return cachedFieldName; - } - } diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/cache/FieldNameLoader.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/cache/FieldNameLoader.java deleted file mode 100644 index 6cb5c6f5..00000000 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/deserializers/cache/FieldNameLoader.java +++ /dev/null @@ -1,13 +0,0 @@ -package backtraceio.library.common.serializers.deserializers.cache; - -public class FieldNameLoader { - private final Class clazz; - - public FieldNameLoader(Class clazz) { - this.clazz = clazz; - } - - public String get(String fieldName) { - return FieldNameCache.getAnnotation(clazz, fieldName); - } -} diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/naming/LowerCaseWithDashConverter.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/naming/LowerCaseWithDashConverter.java deleted file mode 100644 index 57a718db..00000000 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/naming/LowerCaseWithDashConverter.java +++ /dev/null @@ -1,14 +0,0 @@ -package backtraceio.library.common.serializers.naming; - -import static backtraceio.library.common.serializers.naming.NamingUtils.separateCamelCase; - -import java.util.Locale; - -public class LowerCaseWithDashConverter implements NamingConverter { - public String convert(String value) { - if (value == null){ - return null; - } - return separateCamelCase(value, '-').toLowerCase(Locale.ENGLISH); - } -} diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/naming/NamingConverter.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/naming/NamingConverter.java deleted file mode 100644 index fc179285..00000000 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/naming/NamingConverter.java +++ /dev/null @@ -1,5 +0,0 @@ -package backtraceio.library.common.serializers.naming; - -public interface NamingConverter { - String convert(String value); -} diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/naming/NamingPolicy.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/naming/NamingPolicy.java deleted file mode 100644 index 44dcd8a3..00000000 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/naming/NamingPolicy.java +++ /dev/null @@ -1,18 +0,0 @@ -package backtraceio.library.common.serializers.naming; - -public class NamingPolicy implements NamingConverter { - NamingConverter instance; - - public NamingPolicy() { - this(new LowerCaseWithDashConverter()); - } - - public NamingPolicy(NamingConverter namingConverter) { - this.instance = namingConverter; - } - - @Override - public String convert(String value) { - return instance.convert(value); - } -} diff --git a/backtrace-library/src/main/java/backtraceio/library/common/serializers/naming/NamingUtils.java b/backtrace-library/src/main/java/backtraceio/library/common/serializers/naming/NamingUtils.java deleted file mode 100644 index c66804d2..00000000 --- a/backtrace-library/src/main/java/backtraceio/library/common/serializers/naming/NamingUtils.java +++ /dev/null @@ -1,18 +0,0 @@ -package backtraceio.library.common.serializers.naming; - -public class NamingUtils { - static String separateCamelCase(String name, char separator) { - StringBuilder translation = new StringBuilder(); - if (name == null) { - return null; - } - for (int i = 0, length = name.length(); i < length; i++) { - char character = name.charAt(i); - if (Character.isUpperCase(character) && translation.length() != 0) { - translation.append(separator); - } - translation.append(character); - } - return translation.toString(); - } -} diff --git a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceApiResult.java b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceApiResult.java index 2776821f..68aea851 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceApiResult.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceApiResult.java @@ -1,6 +1,6 @@ package backtraceio.library.models; -import backtraceio.library.common.serializers.SerializedName; +import com.google.gson.annotations.SerializedName; /** * Coroner API response 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 9a8e4eb4..2094f2c8 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java @@ -6,7 +6,7 @@ import java.util.Map; import backtraceio.library.BacktraceClient; -import backtraceio.library.common.serializers.SerializedName; +import com.google.gson.annotations.SerializedName; import backtraceio.library.logger.BacktraceLogger; import backtraceio.library.models.json.Annotations; import backtraceio.library.models.json.BacktraceAttributes; 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 ed051cc7..555b6589 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceStackFrame.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceStackFrame.java @@ -3,7 +3,7 @@ import java.util.UUID; -import backtraceio.library.common.serializers.SerializedName; +import com.google.gson.annotations.SerializedName; import backtraceio.library.logger.BacktraceLogger; /** 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 ab9dfd77..e1deee40 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 @@ -7,7 +7,7 @@ import backtraceio.library.common.BacktraceSerializeHelper; import backtraceio.library.common.BacktraceStringHelper; import backtraceio.library.common.FileHelper; -import backtraceio.library.common.serializers.SerializedName; +import com.google.gson.annotations.SerializedName; import backtraceio.library.interfaces.DatabaseRecordWriter; import backtraceio.library.logger.BacktraceLogger; import backtraceio.library.models.BacktraceData; diff --git a/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceReport.java b/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceReport.java index db2011fe..2fccc96a 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceReport.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceReport.java @@ -9,7 +9,7 @@ import java.util.UUID; import backtraceio.library.common.BacktraceTimeHelper; -import backtraceio.library.common.serializers.SerializedName; +import com.google.gson.annotations.SerializedName; import backtraceio.library.models.BacktraceAttributeConsts; import backtraceio.library.models.BacktraceData; import backtraceio.library.models.BacktraceStackFrame; 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 ae367239..9e23eb59 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 @@ -1,6 +1,6 @@ package backtraceio.library.models.json; -import backtraceio.library.common.serializers.SerializedName; +import com.google.gson.annotations.SerializedName; import backtraceio.library.models.BacktraceStackFrame; /** 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 6cb9112e..d5c1757d 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,7 +3,7 @@ import java.util.ArrayList; import java.util.List; -import backtraceio.library.common.serializers.SerializedName; +import com.google.gson.annotations.SerializedName; import backtraceio.library.models.BacktraceStackFrame; /** diff --git a/backtrace-library/src/main/java/backtraceio/library/models/metrics/Event.java b/backtrace-library/src/main/java/backtraceio/library/models/metrics/Event.java index 516668e5..d0e59222 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/metrics/Event.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/metrics/Event.java @@ -4,7 +4,7 @@ import java.util.Map; import backtraceio.library.common.BacktraceStringHelper; -import backtraceio.library.common.serializers.SerializedName; +import com.google.gson.annotations.SerializedName; public abstract class Event { diff --git a/backtrace-library/src/main/java/backtraceio/library/models/metrics/EventsMetadata.java b/backtrace-library/src/main/java/backtraceio/library/models/metrics/EventsMetadata.java index 10a293e2..f0284138 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/metrics/EventsMetadata.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/metrics/EventsMetadata.java @@ -1,6 +1,6 @@ package backtraceio.library.models.metrics; -import backtraceio.library.common.serializers.SerializedName; +import com.google.gson.annotations.SerializedName; public class EventsMetadata { diff --git a/backtrace-library/src/main/java/backtraceio/library/models/metrics/EventsPayload.java b/backtrace-library/src/main/java/backtraceio/library/models/metrics/EventsPayload.java index 9bd06762..c0bc301f 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/metrics/EventsPayload.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/metrics/EventsPayload.java @@ -2,7 +2,7 @@ import java.util.concurrent.ConcurrentLinkedDeque; -import backtraceio.library.common.serializers.SerializedName; +import com.google.gson.annotations.SerializedName; public abstract class EventsPayload { diff --git a/backtrace-library/src/main/java/backtraceio/library/models/metrics/SummedEvent.java b/backtrace-library/src/main/java/backtraceio/library/models/metrics/SummedEvent.java index 534e847a..67bfc96c 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/metrics/SummedEvent.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/metrics/SummedEvent.java @@ -4,7 +4,7 @@ import java.util.Map; import backtraceio.library.common.BacktraceTimeHelper; -import backtraceio.library.common.serializers.SerializedName; +import com.google.gson.annotations.SerializedName; public final class SummedEvent extends Event { diff --git a/backtrace-library/src/main/java/backtraceio/library/models/metrics/SummedEventsPayload.java b/backtrace-library/src/main/java/backtraceio/library/models/metrics/SummedEventsPayload.java index ecca24d2..d32dbd00 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/metrics/SummedEventsPayload.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/metrics/SummedEventsPayload.java @@ -2,7 +2,7 @@ import java.util.concurrent.ConcurrentLinkedDeque; -import backtraceio.library.common.serializers.SerializedName; +import com.google.gson.annotations.SerializedName; public class SummedEventsPayload extends EventsPayload { @SerializedName("summed_events") diff --git a/backtrace-library/src/main/java/backtraceio/library/models/metrics/UniqueEvent.java b/backtrace-library/src/main/java/backtraceio/library/models/metrics/UniqueEvent.java index ed3d7034..d7fb99eb 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/metrics/UniqueEvent.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/metrics/UniqueEvent.java @@ -7,7 +7,7 @@ import backtraceio.library.common.BacktraceStringHelper; import backtraceio.library.common.BacktraceTimeHelper; -import backtraceio.library.common.serializers.SerializedName; +import com.google.gson.annotations.SerializedName; import backtraceio.library.logger.BacktraceLogger; public class UniqueEvent extends Event { diff --git a/backtrace-library/src/main/java/backtraceio/library/models/metrics/UniqueEventsPayload.java b/backtrace-library/src/main/java/backtraceio/library/models/metrics/UniqueEventsPayload.java index 978d1fd3..3f695168 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/metrics/UniqueEventsPayload.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/metrics/UniqueEventsPayload.java @@ -2,7 +2,7 @@ import java.util.concurrent.ConcurrentLinkedDeque; -import backtraceio.library.common.serializers.SerializedName; +import com.google.gson.annotations.SerializedName; public final class UniqueEventsPayload extends EventsPayload { @SerializedName("unique_events") diff --git a/backtrace-library/src/test/java/backtraceio/library/BacktraceDataTest.java b/backtrace-library/src/test/java/backtraceio/library/BacktraceDataTest.java deleted file mode 100644 index 83cef953..00000000 --- a/backtrace-library/src/test/java/backtraceio/library/BacktraceDataTest.java +++ /dev/null @@ -1,73 +0,0 @@ -package backtraceio.library; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static backtraceio.library.TestUtils.readFileAsString; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Test; - -import java.util.Map; - -import backtraceio.library.common.serializers.BacktraceDeserializer; -import backtraceio.library.models.BacktraceData; -import backtraceio.library.models.json.SourceCode; -import backtraceio.library.models.json.ThreadInformation; - -public class BacktraceDataTest { - - @Test - public void deserializeBacktraceData() throws JSONException { - // GIVEN - String backtraceDataJson = readFileAsString(this, "backtraceData.json"); - // WHEN - final BacktraceData result = BacktraceDeserializer.deserialize(new JSONObject(backtraceDataJson), BacktraceData.class); - - // THEN - assertNotNull(result); - assertEquals("398dad51-7c39-4d64-941c-854de56f5f2b", result.uuid); - assertEquals("java", result.lang); - assertEquals("backtrace-android", result.agent); - assertEquals("", result.symbolication); // TODO: check - assertEquals(1709680075, result.timestamp); - assertEquals("0", result.langVersion); - assertEquals("3.7.14-1-931f45d", result.agentVersion); - assertEquals("instr: androidx.test.runner.androidjunitrunner", result.mainThread); - assertEquals(1, result.classifiers.length); - assertEquals("java.lang.IllegalAccessException", result.classifiers[0]); - assertNull(result.report); - - // THEN Attributes - assertEquals(result.attributes.size(), 41); - assertEquals(result.attributes.get("application"), "backtraceio.library.test"); - assertEquals(result.attributes.get("error.type"), "Exception"); - - // THEN Annotations - assertEquals(5, result.annotations.size()); - assertEquals("Test", ((Map) result.annotations.get("Exception")).get("message")); - assertNotNull(result.annotations.get("Exception properties")); - assertEquals("Test", ((Map) result.annotations.get("Exception properties")).get("detail-message")); - assertNotNull(result.annotations.get("1")); - assertNotNull(result.annotations.get("123")); - - // THEN Source Code - assertEquals(result.sourceCode.size(), 35); - SourceCode firstSourceCode = result.sourceCode.get("ca0a50a1-d553-4479-8fe2-28c3f527743b"); - - assertEquals(firstSourceCode.sourceCodeFileName, "ParentRunner.java"); - assertEquals(firstSourceCode.startLine.intValue(), 306); - - // THEN Thread information - assertEquals(result.getThreadInformationMap().size(), 13); - ThreadInformation threadInformation = result.getThreadInformationMap().get("finalizerwatchdogdaemon"); - assertEquals(threadInformation.getFault(), false); - assertEquals(threadInformation.getName(), "finalizerwatchdogdaemon"); - assertNotNull(threadInformation.getStack()); - assertEquals(threadInformation.getStack().get(1).sourceCode, "4f359140-a606-4f5d-ba67-adb387383d43"); - assertEquals(threadInformation.getStack().get(1).sourceCodeFileName, null); - assertEquals(threadInformation.getStack().get(1).functionName, "java.lang.Object.wait"); - assertEquals(threadInformation.getStack().get(1).line.intValue(), 442); - } -} diff --git a/backtrace-library/src/test/java/backtraceio/library/BacktraceReportDeserializerTest.java b/backtrace-library/src/test/java/backtraceio/library/BacktraceReportDeserializerTest.java deleted file mode 100644 index 372bc502..00000000 --- a/backtrace-library/src/test/java/backtraceio/library/BacktraceReportDeserializerTest.java +++ /dev/null @@ -1,44 +0,0 @@ -package backtraceio.library; - -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.json.JSONObject; -import org.junit.Test; - -import java.util.HashMap; - -import backtraceio.library.common.BacktraceSerializeHelper; -import backtraceio.library.common.serialization.BacktraceGsonBuilder; -import backtraceio.library.common.serializers.deserializers.BacktraceReportDeserializer; -import backtraceio.library.models.json.BacktraceReport; - -// TODO: move to standard unit tests not instrumented -public class BacktraceReportDeserializerTest { - @Test - public void deserializeCoronerApiJsonResponse() throws JSONException { - // GIVEN - String json3 = "{\"response\":\"Ok\",\"_rxid\":\"01000000-5360-240b-0000-000000000000\"}"; - String json = "{\"uuid\":\"444d7674-378c-48fd-9b51-d961c3bba3ab\",\"timestamp\":1704905258,\"exception-type-report\":true,\"classifier\":\"java.lang.IllegalAccessException\",\"attributes\":{\"error.type\":\"Exception\",\"test\":{\"detail-message\":\"123\",\"stack-trace\":[],\"suppressed-exceptions\":[]}},\"exception\":{\"detail-message\":\"test\",\"stack-trace\":[{\"class-loader-name\":\"app\",\"declaring-class\":\"backtraceio.library.BacktraceReportDeserializerTest\",\"method-name\":\"deserializeCoronerApiJsonResponse\",\"file-name\":\"BacktraceReportDeserializerTest.java\",\"line-number\":32,\"format\":1},{\"module-name\":\"java.base\",\"module-version\":\"11.0.15\",\"declaring-class\":\"jdk.internal.reflect.NativeMethodAccessorImpl\",\"method-name\":\"invoke0\",\"file-name\":\"NativeMethodAccessorImpl.java\",\"line-number\":-2,\"format\":2},{\"module-name\":\"java.base\",\"module-version\":\"11.0.15\",\"declaring-class\":\"jdk.internal.reflect.NativeMethodAccessorImpl\",\"method-name\":\"invoke\",\"file-name\":\"NativeMethodAccessorImpl.java\",\"line-number\":62,\"format\":2},{\"module-name\":\"java.base\",\"module-version\":\"11.0.15\",\"declaring-class\":\"jdk.internal.reflect.DelegatingMethodAccessorImpl\",\"method-name\":\"invoke\",\"file-name\":\"DelegatingMethodAccessorImpl.java\",\"line-number\":43,\"format\":2},{\"module-name\":\"java.base\",\"module-version\":\"11.0.15\",\"declaring-class\":\"java.lang.reflect.Method\",\"method-name\":\"invoke\",\"file-name\":\"Method.java\",\"line-number\":566,\"format\":2},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.model.FrameworkMethod$1\",\"method-name\":\"runReflectiveCall\",\"file-name\":\"FrameworkMethod.java\",\"line-number\":59,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.internal.runners.model.ReflectiveCallable\",\"method-name\":\"run\",\"file-name\":\"ReflectiveCallable.java\",\"line-number\":12,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.model.FrameworkMethod\",\"method-name\":\"invokeExplosively\",\"file-name\":\"FrameworkMethod.java\",\"line-number\":56,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.internal.runners.statements.InvokeMethod\",\"method-name\":\"evaluate\",\"file-name\":\"InvokeMethod.java\",\"line-number\":17,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.ParentRunner$3\",\"method-name\":\"evaluate\",\"file-name\":\"ParentRunner.java\",\"line-number\":306,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.BlockJUnit4ClassRunner$1\",\"method-name\":\"evaluate\",\"file-name\":\"BlockJUnit4ClassRunner.java\",\"line-number\":100,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.ParentRunner\",\"method-name\":\"runLeaf\",\"file-name\":\"ParentRunner.java\",\"line-number\":366,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.BlockJUnit4ClassRunner\",\"method-name\":\"runChild\",\"file-name\":\"BlockJUnit4ClassRunner.java\",\"line-number\":103,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.BlockJUnit4ClassRunner\",\"method-name\":\"runChild\",\"file-name\":\"BlockJUnit4ClassRunner.java\",\"line-number\":63,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.ParentRunner$4\",\"method-name\":\"run\",\"file-name\":\"ParentRunner.java\",\"line-number\":331,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.ParentRunner$1\",\"method-name\":\"schedule\",\"file-name\":\"ParentRunner.java\",\"line-number\":79,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.ParentRunner\",\"method-name\":\"runChildren\",\"file-name\":\"ParentRunner.java\",\"line-number\":329,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.ParentRunner\",\"method-name\":\"access$100\",\"file-name\":\"ParentRunner.java\",\"line-number\":66,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.ParentRunner$2\",\"method-name\":\"evaluate\",\"file-name\":\"ParentRunner.java\",\"line-number\":293,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.ParentRunner$3\",\"method-name\":\"evaluate\",\"file-name\":\"ParentRunner.java\",\"line-number\":306,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"org.junit.runners.ParentRunner\",\"method-name\":\"run\",\"file-name\":\"ParentRunner.java\",\"line-number\":413,\"format\":1},{\"declaring-class\":\"org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor\",\"method-name\":\"runTestClass\",\"file-name\":\"JUnitTestClassExecutor.java\",\"line-number\":110,\"format\":0},{\"declaring-class\":\"org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor\",\"method-name\":\"execute\",\"file-name\":\"JUnitTestClassExecutor.java\",\"line-number\":58,\"format\":0},{\"declaring-class\":\"org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor\",\"method-name\":\"execute\",\"file-name\":\"JUnitTestClassExecutor.java\",\"line-number\":38,\"format\":0},{\"declaring-class\":\"org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor\",\"method-name\":\"processTestClass\",\"file-name\":\"AbstractJUnitTestClassProcessor.java\",\"line-number\":62,\"format\":0},{\"declaring-class\":\"org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor\",\"method-name\":\"processTestClass\",\"file-name\":\"SuiteTestClassProcessor.java\",\"line-number\":51,\"format\":0},{\"module-name\":\"java.base\",\"module-version\":\"11.0.15\",\"declaring-class\":\"jdk.internal.reflect.NativeMethodAccessorImpl\",\"method-name\":\"invoke0\",\"file-name\":\"NativeMethodAccessorImpl.java\",\"line-number\":-2,\"format\":2},{\"module-name\":\"java.base\",\"module-version\":\"11.0.15\",\"declaring-class\":\"jdk.internal.reflect.NativeMethodAccessorImpl\",\"method-name\":\"invoke\",\"file-name\":\"NativeMethodAccessorImpl.java\",\"line-number\":62,\"format\":2},{\"module-name\":\"java.base\",\"module-version\":\"11.0.15\",\"declaring-class\":\"jdk.internal.reflect.DelegatingMethodAccessorImpl\",\"method-name\":\"invoke\",\"file-name\":\"DelegatingMethodAccessorImpl.java\",\"line-number\":43,\"format\":2},{\"module-name\":\"java.base\",\"module-version\":\"11.0.15\",\"declaring-class\":\"java.lang.reflect.Method\",\"method-name\":\"invoke\",\"file-name\":\"Method.java\",\"line-number\":566,\"format\":2},{\"declaring-class\":\"org.gradle.internal.dispatch.ReflectionDispatch\",\"method-name\":\"dispatch\",\"file-name\":\"ReflectionDispatch.java\",\"line-number\":36,\"format\":0},{\"declaring-class\":\"org.gradle.internal.dispatch.ReflectionDispatch\",\"method-name\":\"dispatch\",\"file-name\":\"ReflectionDispatch.java\",\"line-number\":24,\"format\":0},{\"declaring-class\":\"org.gradle.internal.dispatch.ContextClassLoaderDispatch\",\"method-name\":\"dispatch\",\"file-name\":\"ContextClassLoaderDispatch.java\",\"line-number\":33,\"format\":0},{\"declaring-class\":\"org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler\",\"method-name\":\"invoke\",\"file-name\":\"ProxyDispatchAdapter.java\",\"line-number\":94,\"format\":0},{\"declaring-class\":\"com.sun.proxy.$Proxy5\",\"method-name\":\"processTestClass\",\"line-number\":-1,\"format\":0},{\"declaring-class\":\"org.gradle.api.internal.tasks.testing.worker.TestWorker$2\",\"method-name\":\"run\",\"file-name\":\"TestWorker.java\",\"line-number\":176,\"format\":0},{\"declaring-class\":\"org.gradle.api.internal.tasks.testing.worker.TestWorker\",\"method-name\":\"executeAndMaintainThreadName\",\"file-name\":\"TestWorker.java\",\"line-number\":129,\"format\":0},{\"declaring-class\":\"org.gradle.api.internal.tasks.testing.worker.TestWorker\",\"method-name\":\"execute\",\"file-name\":\"TestWorker.java\",\"line-number\":100,\"format\":0},{\"declaring-class\":\"org.gradle.api.internal.tasks.testing.worker.TestWorker\",\"method-name\":\"execute\",\"file-name\":\"TestWorker.java\",\"line-number\":60,\"format\":0},{\"declaring-class\":\"org.gradle.process.internal.worker.child.ActionExecutionWorker\",\"method-name\":\"execute\",\"file-name\":\"ActionExecutionWorker.java\",\"line-number\":56,\"format\":0},{\"declaring-class\":\"org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker\",\"method-name\":\"call\",\"file-name\":\"SystemApplicationClassLoaderWorker.java\",\"line-number\":133,\"format\":0},{\"declaring-class\":\"org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker\",\"method-name\":\"call\",\"file-name\":\"SystemApplicationClassLoaderWorker.java\",\"line-number\":71,\"format\":0},{\"class-loader-name\":\"app\",\"declaring-class\":\"worker.org.gradle.process.internal.worker.GradleWorkerMain\",\"method-name\":\"run\",\"file-name\":\"GradleWorkerMain.java\",\"line-number\":69,\"format\":1},{\"class-loader-name\":\"app\",\"declaring-class\":\"worker.org.gradle.process.internal.worker.GradleWorkerMain\",\"method-name\":\"main\",\"file-name\":\"GradleWorkerMain.java\",\"line-number\":74,\"format\":1}],\"suppressed-exceptions\":[]},\"attachment-paths\":[],\"diagnostic-stack\":[{\"function-name\":\"jdk.internal.reflect.NativeMethodAccessorImpl.invoke0\",\"source-code\":\"4cb41569-1b17-4a69-8b48-37582c95f87a\"},{\"function-name\":\"jdk.internal.reflect.NativeMethodAccessorImpl.invoke\",\"line\":62,\"source-code\":\"792b5fee-8fd0-4686-9715-78bdcc01df34\"},{\"function-name\":\"jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke\",\"line\":43,\"source-code\":\"2356b394-c780-4c9c-9eeb-3d33de2929b8\"},{\"function-name\":\"java.lang.reflect.Method.invoke\",\"line\":566,\"source-code\":\"7bb5feae-2be1-4c9a-a173-def2dbb5224e\"},{\"function-name\":\"org.junit.runners.model.FrameworkMethod$1.runReflectiveCall\",\"line\":59,\"source-code\":\"6fc4926b-58a9-4d54-a154-660d521ab5d0\"},{\"function-name\":\"org.junit.internal.runners.model.ReflectiveCallable.run\",\"line\":12,\"source-code\":\"32e57bb6-e81c-427a-8ba3-e6982c4b157b\"},{\"function-name\":\"org.junit.runners.model.FrameworkMethod.invokeExplosively\",\"line\":56,\"source-code\":\"75f22f28-7cb4-47f8-99e5-a48d73aafe12\"},{\"function-name\":\"org.junit.internal.runners.statements.InvokeMethod.evaluate\",\"line\":17,\"source-code\":\"cbe15b23-a13d-4779-94ff-1e41edba94f3\"},{\"function-name\":\"org.junit.runners.ParentRunner$3.evaluate\",\"line\":306,\"source-code\":\"a7805b15-c619-4033-b8db-3f7f6bd17df6\"},{\"function-name\":\"org.junit.runners.BlockJUnit4ClassRunner$1.evaluate\",\"line\":100,\"source-code\":\"9a3b6b5f-9f13-44c0-9578-51606d1909c3\"},{\"function-name\":\"org.junit.runners.ParentRunner.runLeaf\",\"line\":366,\"source-code\":\"c249c6c4-fd10-44c3-975d-d3fbb592de81\"},{\"function-name\":\"org.junit.runners.BlockJUnit4ClassRunner.runChild\",\"line\":103,\"source-code\":\"37e1c09b-3130-4442-ae81-80d2b40893e0\"},{\"function-name\":\"org.junit.runners.BlockJUnit4ClassRunner.runChild\",\"line\":63,\"source-code\":\"691a9153-27ad-494c-8e97-28cf9c596431\"},{\"function-name\":\"org.junit.runners.ParentRunner$4.run\",\"line\":331,\"source-code\":\"aed30d5c-2c23-4da7-984e-9b853c0f82e1\"},{\"function-name\":\"org.junit.runners.ParentRunner$1.schedule\",\"line\":79,\"source-code\":\"ac1bf646-f881-4009-a1a9-cd8b943e3433\"},{\"function-name\":\"org.junit.runners.ParentRunner.runChildren\",\"line\":329,\"source-code\":\"dd1bad0a-521e-4b6c-9f5d-8f913817b831\"},{\"function-name\":\"org.junit.runners.ParentRunner.access$100\",\"line\":66,\"source-code\":\"0aa5b966-b70c-43f1-a644-25bad713d2b4\"},{\"function-name\":\"org.junit.runners.ParentRunner$2.evaluate\",\"line\":293,\"source-code\":\"64a86c43-bac6-4868-aa7c-f3572952a4f8\"},{\"function-name\":\"org.junit.runners.ParentRunner$3.evaluate\",\"line\":306,\"source-code\":\"3615e845-9d23-473e-bf14-273a9a9bb138\"},{\"function-name\":\"org.junit.runners.ParentRunner.run\",\"line\":413,\"source-code\":\"f6a03f68-151e-4111-8723-0652f3371ea0\"},{\"function-name\":\"org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass\",\"line\":110,\"source-code\":\"b1d4e3d3-dca9-4c3f-9d26-f399f3bf7923\"},{\"function-name\":\"org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute\",\"line\":58,\"source-code\":\"aa1069c3-0bf4-4479-ad33-5a4053135e59\"},{\"function-name\":\"org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute\",\"line\":38,\"source-code\":\"114a456e-88a3-4888-be52-7102794a7038\"},{\"function-name\":\"org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass\",\"line\":62,\"source-code\":\"8f10c785-6aa9-4236-bcb1-3e2bf93c524a\"},{\"function-name\":\"org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass\",\"line\":51,\"source-code\":\"4e80f634-abf6-415c-9cce-1619dd67fc23\"},{\"function-name\":\"jdk.internal.reflect.NativeMethodAccessorImpl.invoke0\",\"source-code\":\"7c0d6267-d9f3-413c-84e2-23722e1bb223\"},{\"function-name\":\"jdk.internal.reflect.NativeMethodAccessorImpl.invoke\",\"line\":62,\"source-code\":\"3f740a13-ee55-4428-a6dd-bb803138e660\"},{\"function-name\":\"jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke\",\"line\":43,\"source-code\":\"11eb9575-b019-4484-ba11-29fc194fed49\"},{\"function-name\":\"java.lang.reflect.Method.invoke\",\"line\":566,\"source-code\":\"65afbae6-c443-4f3b-9390-6124e24f95e1\"},{\"function-name\":\"org.gradle.internal.dispatch.ReflectionDispatch.dispatch\",\"line\":36,\"source-code\":\"362cd836-732c-4c1e-af25-4f1e294253f2\"},{\"function-name\":\"org.gradle.internal.dispatch.ReflectionDispatch.dispatch\",\"line\":24,\"source-code\":\"4b005a51-0d16-426d-a367-b83dc37c13ab\"},{\"function-name\":\"org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch\",\"line\":33,\"source-code\":\"ca109cad-f9ee-41d6-8029-379f4f01f5a8\"},{\"function-name\":\"org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke\",\"line\":94,\"source-code\":\"599b1cdc-1b45-4126-848c-c0e56e8ce8d4\"},{\"function-name\":\"com.sun.proxy.$Proxy5.processTestClass\",\"source-code\":\"f2814221-e618-4aa0-9315-60003596f658\"},{\"function-name\":\"org.gradle.api.internal.tasks.testing.worker.TestWorker$2.run\",\"line\":176,\"source-code\":\"51f5c2d0-b9cc-4176-b36b-d97a20463d3e\"},{\"function-name\":\"org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName\",\"line\":129,\"source-code\":\"d104a0f1-6da3-41b1-b442-b80373bcb1b5\"},{\"function-name\":\"org.gradle.api.internal.tasks.testing.worker.TestWorker.execute\",\"line\":100,\"source-code\":\"120f38d5-525d-4ac4-a507-442455140ce9\"},{\"function-name\":\"org.gradle.api.internal.tasks.testing.worker.TestWorker.execute\",\"line\":60,\"source-code\":\"d9d1bdb6-042b-4465-9737-2d65668632c0\"},{\"function-name\":\"org.gradle.process.internal.worker.child.ActionExecutionWorker.execute\",\"line\":56,\"source-code\":\"d4806ec1-0dab-48df-8b5d-834804fe5c43\"},{\"function-name\":\"org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call\",\"line\":133,\"source-code\":\"d0f083ba-6a43-4e9c-8e2b-e0cdf8638a88\"},{\"function-name\":\"org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call\",\"line\":71,\"source-code\":\"24c83e74-20eb-4a28-866c-a641dee9d245\"},{\"function-name\":\"worker.org.gradle.process.internal.worker.GradleWorkerMain.run\",\"line\":69,\"source-code\":\"fa90688b-00e1-4a2e-b5f9-038de2f3dd4f\"},{\"function-name\":\"worker.org.gradle.process.internal.worker.GradleWorkerMain.main\",\"line\":74,\"source-code\":\"88b732b6-b058-469b-8549-578818de4138\"}]}"; - // WHEN - String json2 = BacktraceSerializeHelper.toJson(new BacktraceReport(new IllegalAccessException("test"), new HashMap() {{ put("test", new Exception("123")); }} )); - BacktraceReportDeserializer deserializer = new BacktraceReportDeserializer(); - BacktraceReport resultGson = BacktraceSerializeHelper.fromJson(new BacktraceGsonBuilder().buildGson(), json, BacktraceReport.class); - BacktraceReport resultCustom = deserializer.deserialize(new JSONObject(json)); - - // THEN - assertNotNull(resultCustom); - assertEquals("39407c49-0999-438b-bfac-140c83d2521b", resultCustom.uuid.toString()); - assertEquals(1704901251, resultCustom.timestamp); - assertTrue(resultCustom.exceptionTypeReport); - assertEquals("java.lang.Exception", resultCustom.classifier); - assertNull(resultCustom.message); -// assertNull(result.getBacktraceReport()); -// assertNull(result.message); -// assertEquals(BacktraceResultStatus.Ok, result.status); -// assertEquals("01000000-5360-240b-0000-000000000000", result.rxId); - } -} diff --git a/backtrace-library/src/test/java/backtraceio/library/BacktraceSerializeHelperTest.java b/backtrace-library/src/test/java/backtraceio/library/BacktraceSerializeHelperTest.java deleted file mode 100644 index 868e1c83..00000000 --- a/backtrace-library/src/test/java/backtraceio/library/BacktraceSerializeHelperTest.java +++ /dev/null @@ -1,39 +0,0 @@ -package backtraceio.library; - -import static junit.framework.TestCase.assertEquals; -import static junit.framework.TestCase.assertNotNull; -import static junit.framework.TestCase.assertNull; - -import org.junit.Test; - -import backtraceio.library.common.BacktraceSerializeHelper; -import backtraceio.library.models.BacktraceResult; -import backtraceio.library.models.types.BacktraceResultStatus; - -public class BacktraceSerializeHelperTest { - @Test - public void testSerialization() { - // GIVEN - BacktraceResult backtraceResult = new BacktraceResult(null, "result-message", BacktraceResultStatus.Ok); - // WHEN - String json = BacktraceSerializeHelper.toJson(backtraceResult); - // THEN - assertEquals("{\"message\":\"result-message\",\"status\":\"Ok\"}", json); - } - - @Test - public void testDeserialization() { - // GIVEN - String json = "{\"_rxid\": \"12345\", \"message\":\"result-message\",\"status\":\"Ok\"}"; - - // WHEN - BacktraceResult result = BacktraceSerializeHelper.fromJson(json ,BacktraceResult.class); - - // THEN - assertNotNull(result); - assertEquals("result-message", result.message); - assertEquals("12345", result.rxId); - assertEquals(BacktraceResultStatus.Ok, result.status); - assertNull(result.getBacktraceReport()); - } -} diff --git a/backtrace-library/src/test/java/backtraceio/library/deserializers/BacktraceApiResultDeserializerTest.java b/backtrace-library/src/test/java/backtraceio/library/deserializers/BacktraceApiResultDeserializerTest.java deleted file mode 100644 index e851f0a9..00000000 --- a/backtrace-library/src/test/java/backtraceio/library/deserializers/BacktraceApiResultDeserializerTest.java +++ /dev/null @@ -1,63 +0,0 @@ -package backtraceio.library.deserializers; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Test; - -import backtraceio.library.common.serializers.BacktraceOrgJsonDeserializer; -import backtraceio.library.common.serializers.deserializers.BacktraceApiResultDeserializer; -import backtraceio.library.models.BacktraceApiResult; -import backtraceio.library.models.BacktraceResult; -import backtraceio.library.models.types.BacktraceResultStatus; - -// TODO: move to standard unit tests not instrumented -// TODO: use from resources -public class BacktraceApiResultDeserializerTest { - - private final String JSON_1 = "{\"response\":\"Ok\",\"_rxid\":\"01000000-5360-240b-0000-000000000000\"}"; - @Test - public void deserializeCoronerApiJsonResponse() throws JSONException { - // GIVEN - String json = JSON_1; - - // WHEN - BacktraceApiResultDeserializer deserializer = new BacktraceApiResultDeserializer(); - BacktraceApiResult result = deserializer.deserialize(new JSONObject(json)); - - // THEN - assertNotNull(result); - assertEquals(BacktraceResultStatus.Ok.toString(), result.getResponse()); - assertEquals("01000000-5360-240b-0000-000000000000", result.getRxId()); - } - - @Test - public void deserializeCoronerApiJsonResponseUsingOrgDeserializer() throws JSONException { - // GIVEN - String json = JSON_1; - - // WHEN - BacktraceApiResult result = BacktraceOrgJsonDeserializer.deserialize(json, BacktraceApiResult.class); - - // THEN - assertNotNull(result); - assertEquals(BacktraceResultStatus.Ok.toString(), result.getResponse()); - assertEquals("01000000-5360-240b-0000-000000000000", result.getRxId()); - } - - @Test - public void deserializeCoronerApiErrorResponse() throws JSONException { - String json = "{ \"error\": { \"code\": 6, \"message\": \"invalid token\" } }"; // TODO: add proper error json - - // WHEN - BacktraceApiResult result = BacktraceOrgJsonDeserializer.deserialize(json, BacktraceApiResult.class); - - // THEN - assertNotNull(result); - assertEquals(BacktraceResultStatus.ServerError.toString(), result.getResponse()); - assertNull(result.getRxId()); - } -} diff --git a/backtrace-library/src/test/resources/backtraceData.json b/backtrace-library/src/test/resources/backtraceData.json deleted file mode 100644 index 742cf483..00000000 --- a/backtrace-library/src/test/resources/backtraceData.json +++ /dev/null @@ -1 +0,0 @@ -{"agent":"backtrace-android","agentVersion":"3.7.14-1-931f45d","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","PATH":"/product/bin:/apex/com.android.runtime/bin:/apex/com.android.art/bin:/system_ext/bin:/system/bin:/system/xbin:/odm/bin:/vendor/bin:/vendor/xbin","ANDROID_SOCKET_zygote":"17","ANDROID_I18N_ROOT":"/apex/com.android.i18n","ANDROID_DATA":"/data","ASEC_MOUNTPOINT":"/mnt/asec","ANDROID_TZDATA_ROOT":"/apex/com.android.tzdata","EXTERNAL_STORAGE":"/sdcard","ANDROID_BOOTLOGO":"1","ANDROID_ASSETS":"/system/app","ANDROID_STORAGE":"/storage","DEX2OATBOOTCLASSPATH":"/apex/com.android.art/javalib/core-oj.jar:/apex/com.android.art/javalib/core-libart.jar:/apex/com.android.art/javalib/core-icu4j.jar:/apex/com.android.art/javalib/okhttp.jar:/apex/com.android.art/javalib/bouncycastle.jar:/apex/com.android.art/javalib/apache-xml.jar:/system/framework/framework.jar:/system/framework/ext.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/framework-atb-backward-compatibility.jar","ANDROID_ART_ROOT":"/apex/com.android.art","ANDROID_ROOT":"/system","DOWNLOAD_CACHE":"/data/cache","BOOTCLASSPATH":"/apex/com.android.art/javalib/core-oj.jar:/apex/com.android.art/javalib/core-libart.jar:/apex/com.android.art/javalib/core-icu4j.jar:/apex/com.android.art/javalib/okhttp.jar:/apex/com.android.art/javalib/bouncycastle.jar:/apex/com.android.art/javalib/apache-xml.jar:/system/framework/framework.jar:/system/framework/ext.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/framework-atb-backward-compatibility.jar:/apex/com.android.conscrypt/javalib/conscrypt.jar:/apex/com.android.media/javalib/updatable-media.jar:/apex/com.android.mediaprovider/javalib/framework-mediaprovider.jar:/apex/com.android.os.statsd/javalib/framework-statsd.jar:/apex/com.android.permission/javalib/framework-permission.jar:/apex/com.android.sdkext/javalib/framework-sdkextensions.jar:/apex/com.android.wifi/javalib/framework-wifi.jar:/apex/com.android.tethering/javalib/framework-tethering.jar","ANDROID_SOCKET_usap_pool_primary":"22"},"1":{"detail-message":"Test-message","stack-trace":[],"suppressed-exceptions":[]},"123":{"detail-message":"Another exception","stack-trace":[],"suppressed-exceptions":[]},"Exception properties":{"detail-message":"Test","stack-trace":[{"declaring-class":"backtraceio.library.SettingAttributesTest","file-name":"SettingAttributesTest.java","line-number":61,"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":{"message":"Test"}},"attributes":{"application.session":"8a834365-a1f7-4fb0-937c-fe1ca84f041b","device.nfc.status":"NotAvailable","device.cpu.temperature":"0.0","system.memory.active":"981274624","device.wifi.status":"Disabled","screen.height":"1834","uname.machine":"i686","screen.dpi":"288","device.bluetooth_status":"NotPermitted","device.airplane_mode":"false","classifier":"java.lang.IllegalAccessException","system.memory.total":"2077347840","device.sdk":"30","key":"false","device.brand":"google","uname.sysname":"Android","cpu.boottime":"1709621937678","device.os_version":"5.4.61-android11-0-00791-gbad091cc4bf3-ab6833933","device.gps.enabled":"Enabled","application.package":"backtraceio.library.test","uname.version":"11","backtrace.version":"3.7.14-1-931f45d","device.is_power_saving_mode":"false","screen.orientation":"Portrait","device.manufacturer":"Google","system.memory.free":"1096073216","battery.state":"Unplugged","backtrace.agent":"backtrace-android","error.type":"Exception","device.location":"Enabled","application":"backtraceio.library.test","error.message":"Test","culture":"English","device.model":"sdk_gphone_x86","screen.width":"1080","build.type":"Debug","device.product":"sdk_gphone_x86","guid":"e4c57699-0dc9-35e2-b4a0-2ffff1925ca7","app.storage_used":"2990720","battery.level":"1.0","screen.brightness":"102"},"classifiers":["java.lang.IllegalAccessException"],"lang":"java","langVersion":"0","mainThread":"instr: androidx.test.runner.androidjunitrunner","sourceCode":{"0d619b24-4484-47ce-a83a-f2922671a47a":{"path":"Method.java"},"ca0a50a1-d553-4479-8fe2-28c3f527743b":{"path":"ParentRunner.java","startLine":306},"49f16751-a846-4e09-8f8c-c6b5755b5e9b":{"path":"InvokeMethod.java","startLine":17},"510905e8-d411-4f4f-bc31-1e385f298781":{"path":"AndroidJUnitRunner.java","startLine":446},"f1c89597-b75a-43de-bd06-48c3222c6b1f":{"path":"TestExecutor.java","startLine":67},"a18a7ea7-4145-428e-9dc1-54cca9903051":{"path":"ParentRunner.java","startLine":329},"5c63fbbd-3a0e-4088-803e-f93c237c1f45":{"path":"ParentRunner.java","startLine":293},"d80839b2-8f5c-4a59-aac7-7590429fbb72":{"path":"ParentRunner.java","startLine":293},"cd3260f0-44a8-4f26-a2e8-039f25aab865":{"path":"BlockJUnit4ClassRunner.java","startLine":100},"a9c0ee95-83b2-47a5-b65e-025663c33589":{"path":"Suite.java","startLine":27},"c90e3f7b-afc6-486c-abb7-5d25dcdc6d58":{"path":"ParentRunner.java","startLine":306},"acf17580-69f3-4b97-a500-7a988f674086":{"path":"SettingAttributesTest.java","startLine":61},"ef1c9c6c-f3e2-444b-b471-c50b55e2f13d":{"path":"BlockJUnit4ClassRunner.java","startLine":103},"2b21aa76-a40b-4b90-910f-483723440468":{"path":"AndroidJUnit4.java","startLine":162},"07cc53cb-1ff0-4e3a-8d5b-d51a6bd36a82":{"path":"ParentRunner.java","startLine":366},"1290819f-6bbf-4db3-9946-0ce3208cc227":{"path":"ParentRunner.java","startLine":79},"380123bc-73c0-4ea1-ab07-36b3d9edb476":{"path":"ReflectiveCallable.java","startLine":12},"e844e0cf-4dac-476e-a67e-ae13a49e114a":{"path":"FrameworkMethod.java","startLine":59},"8f6f57da-218e-4744-b395-2e960ce0909f":{"path":"BlockJUnit4ClassRunner.java","startLine":63},"f5aa1c63-708c-4ebd-92ff-2d5b7bbabc76":{"path":"ParentRunner.java","startLine":413},"ac094d10-223d-4a3a-9e34-554b4ffe9d68":{"path":"ParentRunner.java","startLine":66},"a1e94af3-b1f1-42d3-8698-c79c7bfffb5c":{"path":"ParentRunner.java","startLine":413},"ef7e55ae-72f5-48fd-a1d7-d0456a5665c5":{"path":"FrameworkMethod.java","startLine":56},"5f4c9e78-a835-4e0e-b3ce-764fd54bbbcb":{"path":"JUnitCore.java","startLine":115},"bc1e3d86-1605-4a6d-934f-139b616fdfd1":{"path":"ParentRunner.java","startLine":331},"bd092922-6269-46ea-b8b3-9fe19150cf12":{"path":"RunBefores.java","startLine":80},"c50ee7ea-1fd9-404b-8575-2b0f9ec02be8":{"path":"JUnitCore.java","startLine":137},"99ca899d-f0ea-42c2-a493-04812ca559cb":{"path":"TestExecutor.java","startLine":58},"918fe7f4-b0ec-45bf-95a8-01e4df8cc689":{"path":"ParentRunner.java","startLine":306},"0266df08-f20b-4987-b3e1-3c9ea87e52c3":{"path":"Suite.java","startLine":128},"ef83875d-d036-4f0b-9ba1-3412c645e01b":{"path":"ParentRunner.java","startLine":79},"d7fcfa69-4904-423e-85f5-28008daf9396":{"path":"Instrumentation.java","startLine":2205},"49c97f9a-8ae0-496b-a94b-ff3d83abea63":{"path":"ParentRunner.java","startLine":66},"f9ec00bd-802c-4c36-8863-b90c29991a59":{"path":"ParentRunner.java","startLine":331},"af73d037-6118-41d6-8c5e-68909c5b4cae":{"path":"ParentRunner.java","startLine":329}},"threads":{"profile saver":{"fault":false,"name":"profile saver","stack":[]},"binder:4109_3":{"fault":false,"name":"binder:4109_3","stack":[]},"signal catcher":{"fault":false,"name":"signal catcher","stack":[]},"binder:4109_1":{"fault":false,"name":"binder:4109_1","stack":[]},"finalizerwatchdogdaemon":{"fault":false,"name":"finalizerwatchdogdaemon","stack":[{"funcName":"java.lang.Object.wait","sourceCode":"223a0637-b9f7-45b1-a075-e9c76e087c68"},{"funcName":"java.lang.Object.wait","line":442,"sourceCode":"4f359140-a606-4f5d-ba67-adb387383d43"},{"funcName":"java.lang.Object.wait","line":568,"sourceCode":"6b046834-2148-4fff-9b6c-98dba736fbfc"},{"funcName":"java.lang.Daemons$FinalizerWatchdogDaemon.sleepUntilNeeded","line":341,"sourceCode":"e0742ba8-99ab-4f9d-8f8b-f1a2ca4ae53e"},{"funcName":"java.lang.Daemons$FinalizerWatchdogDaemon.runInternal","line":321,"sourceCode":"b379b271-8b33-4ae7-b79f-71c56bfbfa2f"},{"funcName":"java.lang.Daemons$Daemon.run","line":139,"sourceCode":"50fbe298-fa92-43b1-a5a1-08589e673e5a"},{"funcName":"java.lang.Thread.run","line":923,"sourceCode":"554c09ea-a4b8-4809-bb69-a7df21e4c0af"}]},"binder:4109_2":{"fault":false,"name":"binder:4109_2","stack":[]},"main":{"fault":false,"name":"main","stack":[{"funcName":"android.os.MessageQueue.nativePollOnce","sourceCode":"758ec023-78db-42d7-a4a7-c6c291059a56"},{"funcName":"android.os.MessageQueue.next","line":335,"sourceCode":"fed2a4a5-0b0a-4dd1-a96f-51fa1121cdf4"},{"funcName":"android.os.Looper.loop","line":183,"sourceCode":"4782b0d3-8800-4897-92c6-64cf17e67b8f"},{"funcName":"android.app.ActivityThread.main","line":7656,"sourceCode":"a5e47b8f-e331-49c1-8179-80ae517b263e"},{"funcName":"java.lang.reflect.Method.invoke","sourceCode":"fc72e5f5-0f14-4ee5-91e6-73570c271530"},{"funcName":"com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run","line":592,"sourceCode":"37013d3c-f962-4cb8-919e-553bc43d2577"},{"funcName":"com.android.internal.os.ZygoteInit.main","line":947,"sourceCode":"07ed3f99-e7c0-40f0-a398-1d1aff7231e2"}]},"finalizerdaemon":{"fault":false,"name":"finalizerdaemon","stack":[{"funcName":"java.lang.Object.wait","sourceCode":"52c14a22-0f24-49aa-a49d-725dab99e41c"},{"funcName":"java.lang.Object.wait","line":442,"sourceCode":"3c86cb0f-e6f3-4bda-a0cc-a6b5a5069fa1"},{"funcName":"java.lang.ref.ReferenceQueue.remove","line":190,"sourceCode":"d5b11d05-3eb5-4585-8672-c6c957323d38"},{"funcName":"java.lang.ref.ReferenceQueue.remove","line":211,"sourceCode":"bc76dd76-62b6-4752-b726-4a6a4c3a710f"},{"funcName":"java.lang.Daemons$FinalizerDaemon.runInternal","line":273,"sourceCode":"d6897d2a-32f7-4f7b-b70e-ed817a7cb6ef"},{"funcName":"java.lang.Daemons$Daemon.run","line":139,"sourceCode":"0821f15f-d9d6-4fa6-aee1-cdb2513ba039"},{"funcName":"java.lang.Thread.run","line":923,"sourceCode":"b1d6f758-2bf1-47f4-a71a-8b20db2e3c9c"}]},"referencequeuedaemon":{"fault":false,"name":"referencequeuedaemon","stack":[{"funcName":"java.lang.Object.wait","sourceCode":"13098981-5d81-46e9-b20c-a97775b9809d"},{"funcName":"java.lang.Object.wait","line":442,"sourceCode":"9f3c26ab-3dbc-435a-a611-756bcd7ed185"},{"funcName":"java.lang.Object.wait","line":568,"sourceCode":"699421b6-e827-46b0-8125-621eb1d0550b"},{"funcName":"java.lang.Daemons$ReferenceQueueDaemon.runInternal","line":217,"sourceCode":"bf83f06c-c088-4cea-ac7b-ca8294940c17"},{"funcName":"java.lang.Daemons$Daemon.run","line":139,"sourceCode":"5c6ef27e-3694-47bb-82a8-b942f562edae"},{"funcName":"java.lang.Thread.run","line":923,"sourceCode":"b0dd03ce-ecbd-4cdb-87b9-dcd72391eea8"}]},"instrumentationconnectionthread":{"fault":false,"name":"instrumentationconnectionthread","stack":[{"funcName":"android.os.MessageQueue.nativePollOnce","sourceCode":"a3ad1195-620f-47e2-bbcf-5ad5d7896320"},{"funcName":"android.os.MessageQueue.next","line":335,"sourceCode":"bc0095ba-5087-4af6-b461-1a03536a14d5"},{"funcName":"android.os.Looper.loop","line":183,"sourceCode":"e35c39fc-5edf-400e-9c11-78fbd744cb33"},{"funcName":"android.os.HandlerThread.run","line":67,"sourceCode":"d8cdab8e-f8ba-46b6-89e5-254708edbb53"}]},"jit thread pool worker thread 0":{"fault":false,"name":"jit thread pool worker thread 0","stack":[]},"instr: androidx.test.runner.androidjunitrunner":{"fault":true,"name":"instr: androidx.test.runner.androidjunitrunner","stack":[{"funcName":"backtraceio.library.SettingAttributesTest.tmpGsonTest","line":61,"sourceCode":"acf17580-69f3-4b97-a500-7a988f674086"},{"funcName":"java.lang.reflect.Method.invoke","sourceCode":"0d619b24-4484-47ce-a83a-f2922671a47a"},{"funcName":"org.junit.runners.model.FrameworkMethod$1.runReflectiveCall","line":59,"sourceCode":"e844e0cf-4dac-476e-a67e-ae13a49e114a"},{"funcName":"org.junit.internal.runners.model.ReflectiveCallable.run","line":12,"sourceCode":"380123bc-73c0-4ea1-ab07-36b3d9edb476"},{"funcName":"org.junit.runners.model.FrameworkMethod.invokeExplosively","line":56,"sourceCode":"ef7e55ae-72f5-48fd-a1d7-d0456a5665c5"},{"funcName":"org.junit.internal.runners.statements.InvokeMethod.evaluate","line":17,"sourceCode":"49f16751-a846-4e09-8f8c-c6b5755b5e9b"},{"funcName":"androidx.test.internal.runner.junit4.statement.RunBefores.evaluate","line":80,"sourceCode":"bd092922-6269-46ea-b8b3-9fe19150cf12"},{"funcName":"org.junit.runners.ParentRunner$3.evaluate","line":306,"sourceCode":"c90e3f7b-afc6-486c-abb7-5d25dcdc6d58"},{"funcName":"org.junit.runners.BlockJUnit4ClassRunner$1.evaluate","line":100,"sourceCode":"cd3260f0-44a8-4f26-a2e8-039f25aab865"},{"funcName":"org.junit.runners.ParentRunner.runLeaf","line":366,"sourceCode":"07cc53cb-1ff0-4e3a-8d5b-d51a6bd36a82"},{"funcName":"org.junit.runners.BlockJUnit4ClassRunner.runChild","line":103,"sourceCode":"ef1c9c6c-f3e2-444b-b471-c50b55e2f13d"},{"funcName":"org.junit.runners.BlockJUnit4ClassRunner.runChild","line":63,"sourceCode":"8f6f57da-218e-4744-b395-2e960ce0909f"},{"funcName":"org.junit.runners.ParentRunner$4.run","line":331,"sourceCode":"f9ec00bd-802c-4c36-8863-b90c29991a59"},{"funcName":"org.junit.runners.ParentRunner$1.schedule","line":79,"sourceCode":"ef83875d-d036-4f0b-9ba1-3412c645e01b"},{"funcName":"org.junit.runners.ParentRunner.runChildren","line":329,"sourceCode":"a18a7ea7-4145-428e-9dc1-54cca9903051"},{"funcName":"org.junit.runners.ParentRunner.access$100","line":66,"sourceCode":"ac094d10-223d-4a3a-9e34-554b4ffe9d68"},{"funcName":"org.junit.runners.ParentRunner$2.evaluate","line":293,"sourceCode":"d80839b2-8f5c-4a59-aac7-7590429fbb72"},{"funcName":"org.junit.runners.ParentRunner$3.evaluate","line":306,"sourceCode":"918fe7f4-b0ec-45bf-95a8-01e4df8cc689"},{"funcName":"org.junit.runners.ParentRunner.run","line":413,"sourceCode":"f5aa1c63-708c-4ebd-92ff-2d5b7bbabc76"},{"funcName":"androidx.test.ext.junit.runners.AndroidJUnit4.run","line":162,"sourceCode":"2b21aa76-a40b-4b90-910f-483723440468"},{"funcName":"org.junit.runners.Suite.runChild","line":128,"sourceCode":"0266df08-f20b-4987-b3e1-3c9ea87e52c3"},{"funcName":"org.junit.runners.Suite.runChild","line":27,"sourceCode":"a9c0ee95-83b2-47a5-b65e-025663c33589"},{"funcName":"org.junit.runners.ParentRunner$4.run","line":331,"sourceCode":"bc1e3d86-1605-4a6d-934f-139b616fdfd1"},{"funcName":"org.junit.runners.ParentRunner$1.schedule","line":79,"sourceCode":"1290819f-6bbf-4db3-9946-0ce3208cc227"},{"funcName":"org.junit.runners.ParentRunner.runChildren","line":329,"sourceCode":"af73d037-6118-41d6-8c5e-68909c5b4cae"},{"funcName":"org.junit.runners.ParentRunner.access$100","line":66,"sourceCode":"49c97f9a-8ae0-496b-a94b-ff3d83abea63"},{"funcName":"org.junit.runners.ParentRunner$2.evaluate","line":293,"sourceCode":"5c63fbbd-3a0e-4088-803e-f93c237c1f45"},{"funcName":"org.junit.runners.ParentRunner$3.evaluate","line":306,"sourceCode":"ca0a50a1-d553-4479-8fe2-28c3f527743b"},{"funcName":"org.junit.runners.ParentRunner.run","line":413,"sourceCode":"a1e94af3-b1f1-42d3-8698-c79c7bfffb5c"},{"funcName":"org.junit.runner.JUnitCore.run","line":137,"sourceCode":"c50ee7ea-1fd9-404b-8575-2b0f9ec02be8"},{"funcName":"org.junit.runner.JUnitCore.run","line":115,"sourceCode":"5f4c9e78-a835-4e0e-b3ce-764fd54bbbcb"},{"funcName":"androidx.test.internal.runner.TestExecutor.execute","line":67,"sourceCode":"f1c89597-b75a-43de-bd06-48c3222c6b1f"},{"funcName":"androidx.test.internal.runner.TestExecutor.execute","line":58,"sourceCode":"99ca899d-f0ea-42c2-a493-04812ca559cb"},{"funcName":"androidx.test.runner.AndroidJUnitRunner.onStart","line":446,"sourceCode":"510905e8-d411-4f4f-bc31-1e385f298781"},{"funcName":"android.app.Instrumentation$InstrumentationThread.run","line":2205,"sourceCode":"d7fcfa69-4904-423e-85f5-28008daf9396"}]},"heaptaskdaemon":{"fault":false,"name":"heaptaskdaemon","stack":[]}},"timestamp":1709680075,"uuid":"398dad51-7c39-4d64-941c-854de56f5f2b"} \ No newline at end of file From fb1b6f97b908e0d283c12aa96fb42dbc34834a9b Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Mon, 27 May 2024 23:16:15 +0200 Subject: [PATCH 045/100] Remove deserializer tests --- .../common/BacktraceDataDeserializerTest.java | 92 ------------- .../common/BacktraceDataSerializerTest.java | 124 ------------------ .../BacktraceResultDeserializerTest.java | 56 -------- .../LowerCaseWithDashConverterTest.java | 64 --------- .../serializers/naming/NamingUtilsTest.java | 54 -------- 5 files changed, 390 deletions(-) delete mode 100644 backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java delete mode 100644 backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java delete mode 100644 backtrace-library/src/androidTest/java/backtraceio/library/common/deserializers/BacktraceResultDeserializerTest.java delete mode 100644 backtrace-library/src/androidTest/java/backtraceio/library/common/serializers/naming/LowerCaseWithDashConverterTest.java delete mode 100644 backtrace-library/src/androidTest/java/backtraceio/library/common/serializers/naming/NamingUtilsTest.java diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java deleted file mode 100644 index 59508872..00000000 --- a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataDeserializerTest.java +++ /dev/null @@ -1,92 +0,0 @@ -package backtraceio.library.common; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; - -import static backtraceio.library.TestUtils.readFileAsString; - -import androidx.test.ext.junit.runners.AndroidJUnit4; - -import com.google.gson.FieldNamingPolicy; -import com.google.gson.GsonBuilder; - -import org.json.JSONException; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.util.UUID; - -import backtraceio.library.common.serializers.BacktraceOrgJsonDeserializer; -import backtraceio.library.models.BacktraceData; -import backtraceio.library.models.BacktraceResult; -import backtraceio.library.models.database.BacktraceDatabaseRecord; -import backtraceio.library.models.types.BacktraceResultStatus; - -@RunWith(AndroidJUnit4.class) -public class BacktraceDataDeserializerTest { - - - - @Test - public void deserializeDatabaseRecord() throws JSONException { - // GIVEN - String json = "{\"DataPath\":\"\\/data\\/user\\/0\\/backtraceio.backtraceio\\/files\\/8fbde28b-aa64-4e2f-83d8-493a98446fc8-attachment.json\",\"Id\":\"8fbde28b-aa64-4e2f-83d8-493a98446fc8\",\"RecordName\":\"\\/data\\/user\\/0\\/backtraceio.backtraceio\\/files\\/8fbde28b-aa64-4e2f-83d8-493a98446fc8-record.json\",\"ReportPath\":\"\\/data\\/user\\/0\\/backtraceio.backtraceio\\/files\\/8fbde28b-aa64-4e2f-83d8-493a98446fc8-report.json\",\"Size\":16996,\"size\":16996,\"record-path\":\"\\/data\\/user\\/0\\/backtraceio.backtraceio\\/files\\/8fbde28b-aa64-4e2f-83d8-493a98446fc8-record.json\",\"report-path\":\"\\/data\\/user\\/0\\/backtraceio.backtraceio\\/files\\/8fbde28b-aa64-4e2f-83d8-493a98446fc8-report.json\",\"diagnostic-data-path\":\"\\/data\\/user\\/0\\/backtraceio.backtraceio\\/files\\/8fbde28b-aa64-4e2f-83d8-493a98446fc8-attachment.json\"}"; // todo: incorrect json duplicated entries - - // WHEN - BacktraceDatabaseRecord result = BacktraceOrgJsonDeserializer.deserialize(json, BacktraceDatabaseRecord.class); - - // THEN - assertNotNull(result); - assertEquals(16996, result.getSize()); - assertFalse(result.locked); - assertEquals(UUID.fromString("8fbde28b-aa64-4e2f-83d8-493a98446fc8"), result.id); - assertEquals("/data/user/0/backtraceio.backtraceio/files/8fbde28b-aa64-4e2f-83d8-493a98446fc8-attachment.json", result.getDiagnosticDataPath()); - assertEquals("/data/user/0/backtraceio.backtraceio/files/8fbde28b-aa64-4e2f-83d8-493a98446fc8-record.json", result.getRecordPath()); - assertEquals("/data/user/0/backtraceio.backtraceio/files/8fbde28b-aa64-4e2f-83d8-493a98446fc8-report.json", result.getReportPath()); - } - - @Test - public void deserializeBacktraceApiResult() throws JSONException { - // GIVEN - - // WHEN - - // THEN - - } - - @Test - public void fromJson2() throws JSONException, IllegalAccessException { - // GIVEN - String fileName = "sample.json"; - String content = readFileAsString(this, fileName); - - // WHEN - BacktraceData dataJson = BacktraceOrgJsonDeserializer.deserialize(content, BacktraceData.class); - - BacktraceData gsonDataJson = (new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_DASHES)).create().fromJson(content, BacktraceData.class); // GSON backup - - assertEquals(dataJson.uuid, "079e41e2-bef1-4062-9e20-f2e1b3a93582"); - assertEquals(dataJson.report, null); - assertEquals(dataJson.lang, "java"); - assertEquals(dataJson.agent, "backtrace-android"); - assertEquals(dataJson.langVersion, "0"); - assertEquals(dataJson.agentVersion, "3.7.7-8-3f67d73-org-json-serializer"); - assertEquals(dataJson.mainThread, "instr: androidx.test.runner.androidjunitrunner"); - assertEquals(dataJson.timestamp, 1694983723); -// assertEquals(dataJson.); - -// assertEquals(dataJson.symbolication, ""); -// assertEquals(dataJson.classifiers, ""); -// assertEquals(dataJson.sourceCode, ""); -// assertEquals(dataJson.annotations, ""); - -// BacktraceData backtraceData = BacktraceDataDeserializer.deserialize(context, jsonObj); - - System.out.println(dataJson.report); - // THEN -// assertEquals(backtraceData.report.message, ); - } -} diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java deleted file mode 100644 index 15f9090e..00000000 --- a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceDataSerializerTest.java +++ /dev/null @@ -1,124 +0,0 @@ -package backtraceio.library.common; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import static backtraceio.library.common.BacktraceSerializationUtils.jsonEquals; - -import android.content.Context; - -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.platform.app.InstrumentationRegistry; - -import org.json.JSONException; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import backtraceio.library.common.serializers.BacktraceDataSerializer; -import backtraceio.library.common.serializers.SerializerHelper; -import backtraceio.library.models.BacktraceData; -import backtraceio.library.models.json.BacktraceReport; -import backtraceio.library.common.serializers.naming.NamingPolicy; - -@RunWith(AndroidJUnit4.class) -public class BacktraceDataSerializerTest { - - @Test - public void testGsonSerializer() throws JSONException, IllegalAccessException { // TODO: fix name - // GIVEN - final Context context = InstrumentationRegistry.getInstrumentation().getContext(); - final Exception exception = new Exception("test-error"); - final Map attributes = new HashMap(); - - attributes.put("string-key", "string-value"); - attributes.put("string-key-exception", exception); -// attributes.put("complex-obj-value", new BacktraceResult(null, "sample-msg", BacktraceResultStatus.Ok)); - attributes.put("complex-obj-source-cd", new StackTraceElement("sample.class", "some.method", "file",123)); - - final List attachments = new ArrayList<>(); - attachments.add("test-path"); - attachments.add("test-path2"); - final BacktraceReport report = new BacktraceReport(exception, attributes, attachments); - final BacktraceData data = new BacktraceData.Builder(context, report, null).build(); - - // WHEN - final String jsonFromGson = BacktraceSerializeHelper.toJson(data); - - final BacktraceData dataGson = BacktraceSerializeHelper.fromJson(jsonFromGson, BacktraceData.class); - BacktraceDataSerializer serializer = new BacktraceDataSerializer(new NamingPolicy()); - final String jsonFromOrgJson = serializer.toJson(data).toString(); - - // THEN - assertTrue(jsonEquals(jsonFromOrgJson, jsonFromGson)); - } - - @Test - public void temp() throws JSONException { -// try { - -// } catch (Exception e) { - try{ - BacktraceReport r = null; - r.toString(); - } - catch (Exception e) { - Object result2 = SerializerHelper.serialize(null, e); - System.out.println(result2); - } - Object result = SerializerHelper.serialize(null, new BacktraceReport("test")); - System.out.println(result); -// } - } - - @Test - public void testGsonPerformanceSerializer() throws JSONException, IllegalAccessException { // TODO: fix name - // GIVEN - final Context context = InstrumentationRegistry.getInstrumentation().getContext(); - long timeGson = 0; - long timeOrgJson = 0; - final int iterations = 1000; - for (int i = 0; i < iterations; i++) { - // INIT SAMPLE - final Exception exception = new Exception(Integer.toString(i)); - - final Map attributes = new HashMap(); - - attributes.put("string-key", Integer.toString(i)); - attributes.put("string-key2", exception.getMessage()); - - final List attachments = new ArrayList<>(); - attachments.add(Integer.toString(i)); - attachments.add(Integer.toString(i * 10)); - final BacktraceReport report = new BacktraceReport(exception, attributes, attachments); - final BacktraceData data = new BacktraceData.Builder(context, report, null).build(); - - // GSON - long startTime = System.currentTimeMillis(); - BacktraceSerializeHelper.toJson(data); - long endTime = System.currentTimeMillis(); - timeGson += endTime - startTime; - - - // ORG JSON - long startTimeOrg = System.currentTimeMillis(); - BacktraceDataSerializer serializer = new BacktraceDataSerializer(new NamingPolicy()); - serializer.toJson(data); - long endTimeOrg = System.currentTimeMillis(); - timeOrgJson += endTimeOrg - startTimeOrg; - } - - System.out.println("[GSON] Total execution time: " + timeGson + " milliseconds"); - System.out.println("[Org.json] total execution time: " + timeOrgJson + " milliseconds"); - - double averageExecutionTimeGson = (double) timeGson / iterations; - double averageExecutionTimeOrgJson = (double) timeOrgJson / iterations; - - System.out.println("[GSON] Average execution time: " + averageExecutionTimeGson + " milliseconds"); - System.out.println("[Org.json] Average execution time: " + averageExecutionTimeOrgJson + " milliseconds"); - } -} diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/common/deserializers/BacktraceResultDeserializerTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/common/deserializers/BacktraceResultDeserializerTest.java deleted file mode 100644 index 4f227929..00000000 --- a/backtrace-library/src/androidTest/java/backtraceio/library/common/deserializers/BacktraceResultDeserializerTest.java +++ /dev/null @@ -1,56 +0,0 @@ -package backtraceio.library.common.deserializers; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; - -import androidx.test.ext.junit.runners.AndroidJUnit4; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Test; -import org.junit.runner.RunWith; - -import backtraceio.library.common.serializers.BacktraceOrgJsonDeserializer; -import backtraceio.library.common.serializers.deserializers.BacktraceApiResultDeserializer; -import backtraceio.library.models.BacktraceApiResult; -import backtraceio.library.models.BacktraceResult; -import backtraceio.library.models.types.BacktraceResultStatus; - -@RunWith(AndroidJUnit4.class) -public class BacktraceResultDeserializerTest { - - private final String JSON_1 ="{\"response\":\"ok\",\"_rxid\":\"01000000-5360-240b-0000-000000000000\"}"; - - @Test - public void deserializeCoronerJsonResponse() throws JSONException { - // GIVEN - String json = JSON_1; - - // WHEN - BacktraceResult result = BacktraceOrgJsonDeserializer.deserialize(json, BacktraceResult.class); - - // THEN - assertNotNull(result); - assertNull(result.getBacktraceReport()); - assertNull(result.message); - assertEquals(BacktraceResultStatus.Ok, result.status); - assertEquals("01000000-5360-240b-0000-000000000000", result.rxId); - } - - @Test - public void deserializeCoronerAPIJsonResponse() throws JSONException { - // GIVEN - BacktraceApiResultDeserializer deserializer = new BacktraceApiResultDeserializer(); - String json = JSON_1; - - // WHEN - BacktraceApiResult result = deserializer.deserialize(new JSONObject(json)); - - // THEN - assertNotNull(result); - assertEquals("ok", result.getResponse()); - assertEquals("01000000-5360-240b-0000-000000000000", result.getRxId()); - } - -} diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/common/serializers/naming/LowerCaseWithDashConverterTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/common/serializers/naming/LowerCaseWithDashConverterTest.java deleted file mode 100644 index f817b266..00000000 --- a/backtrace-library/src/androidTest/java/backtraceio/library/common/serializers/naming/LowerCaseWithDashConverterTest.java +++ /dev/null @@ -1,64 +0,0 @@ -package backtraceio.library.common.serializers.naming; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; - -import java.util.Arrays; -import java.util.Collection; - -import backtraceio.library.common.serializers.naming.LowerCaseWithDashConverter; - -@RunWith(Parameterized.class) -public class LowerCaseWithDashConverterTest { - private final String input; - private final String expectedOutput; - - public LowerCaseWithDashConverterTest(String input, String expectedOutput) { - this.input = input; - this.expectedOutput = expectedOutput; - } - - @Parameterized.Parameters - public static Collection data() { - return Arrays.asList(new Object[][]{ - {"camelCaseInput", "camel-case-input"}, - {"UpperCaseInput", "upper-case-input"}, - {"snake_case_input", "snake_case_input"}, - {"mixedCASEInput", "mixed-c-a-s-e-input"}, - {"some-dashed-input", "some-dashed-input"}, - {"kebab-Case-Input", "kebab--case--input"}, - {"Space Separated Input", "space -separated -input"}, - {"123NumericInput", "123-numeric-input"}, - {"!@#$%^SpecialChars", "!@#$%^-special-chars"}, - {"", ""} - }); - } - - @Test - public void convertShouldConvertToLowerCaseWithDash() { - // GIVEN - LowerCaseWithDashConverter converter = new LowerCaseWithDashConverter(); - - // WHEN - String actualOutput = converter.convert(input); - - // THEN - assertEquals(expectedOutput, actualOutput); - } - - @Test - public void convertShouldConvertNullToLowerCaseWithDash() { - // GIVEN - LowerCaseWithDashConverter converter = new LowerCaseWithDashConverter(); - - // WHEN - String actualOutput = converter.convert(null); - - // THEN - assertNull(actualOutput); - } -} diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/common/serializers/naming/NamingUtilsTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/common/serializers/naming/NamingUtilsTest.java deleted file mode 100644 index a6cb7185..00000000 --- a/backtrace-library/src/androidTest/java/backtraceio/library/common/serializers/naming/NamingUtilsTest.java +++ /dev/null @@ -1,54 +0,0 @@ -package backtraceio.library.common.serializers.naming; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; - -import java.util.Arrays; -import java.util.Collection; - -import static org.junit.Assert.assertEquals; - -import backtraceio.library.common.serializers.naming.NamingUtils; - -@RunWith(Parameterized.class) -public class NamingUtilsTest { - - private final String input; - private final char separator; - private final String expectedOutput; - - public NamingUtilsTest(String input, char separator, String expectedOutput) { - this.input = input; - this.separator = separator; - this.expectedOutput = expectedOutput; - } - - @Parameterized.Parameters - public static Collection data() { - return Arrays.asList(new Object[][]{ - {"camelCaseInput", '-', "camel-Case-Input"}, - {"camelcaseinput", '-', "camelcaseinput"}, - {"Camelcaseinput", '-', "Camelcaseinput"}, - {"UpperCaseInput", '_', "Upper_Case_Input"}, - {"snake_case_input", '*', "snake_case_input"}, - {"mixedCASEInput", '.', "mixed.C.A.S.E.Input"}, - {"some-dashed-input", '|', "some-dashed-input"}, - {"kebabCaseInput", ':', "kebab:Case:Input"}, - {"Space Separated Input", '+', "Space +Separated +Input"}, - {"123NumericInput", '_', "123_Numeric_Input"}, - {"!@#$%^SpecialChars", '!', "!@#$%^!Special!Chars"}, - {"", '*', ""}, - {null, '-', null} - }); - } - - @Test - public void separateCamelCase_shouldSeparateCamelCase() { - // Arrange - String actualOutput = NamingUtils.separateCamelCase(input, separator); - - // Assert - assertEquals(expectedOutput, actualOutput); - } -} \ No newline at end of file From 71a00e7e8fff8fba0e5cb219a7505905b49c1801 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Mon, 27 May 2024 23:16:54 +0200 Subject: [PATCH 046/100] Remove unused file --- .../common/BacktraceSerializationUtils.java | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceSerializationUtils.java diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceSerializationUtils.java b/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceSerializationUtils.java deleted file mode 100644 index 620df0e6..00000000 --- a/backtrace-library/src/androidTest/java/backtraceio/library/common/BacktraceSerializationUtils.java +++ /dev/null @@ -1,14 +0,0 @@ -package backtraceio.library.common; - -import com.google.gson.JsonElement; -import com.google.gson.JsonParser; - -public class BacktraceSerializationUtils { - - public static boolean jsonEquals(String json1, String json2) { - JsonParser parser = new JsonParser(); - JsonElement o1 = parser.parse(json1); - JsonElement o2 = parser.parse(json2); - return o1.equals(o2); - } -} From b81b4cee6766bd164987f2dd968c13850727b39a Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Mon, 27 May 2024 23:21:44 +0200 Subject: [PATCH 047/100] Optimize imports --- .../BacktraceClientAttachmentsTest.java | 3 +- .../BacktraceClientAttributeTests.java | 2 - .../BacktraceClientBreadcrumbsTest.java | 2 +- .../library/BacktraceClientEventsTest.java | 3 +- .../library/BacktraceClientMetricsTest.java | 2 +- .../library/BacktraceClientProguardTest.java | 3 +- .../library/BacktraceClientSendTest.java | 3 +- .../BacktraceClientSerializationTest.java | 7 + .../BacktraceClientSummedEventTest.java | 3 +- .../BacktraceClientUniqueEventTest.java | 3 +- .../BacktraceErrorTypeAttributeTest.java | 3 +- .../library/BacktraceFileAttachments.java | 3 +- .../library/BacktraceUrlTests.java | 1 + .../library/SettingAttributesTest.java | 3 +- .../PrimitiveTypeSerializerHelperTest.java | 50 -------- .../library/common/SerializerHelperTest.java | 121 ------------------ .../BacktraceDatabaseContextTest.java | 3 +- .../BacktraceDatabaseFileContextTest.java | 3 +- .../BacktraceDatabaseProguardTest.java | 3 +- .../database/BacktraceDatabaseRecordTest.java | 3 +- .../BacktraceDatabaseRecordWriterTest.java | 3 +- .../database/BacktraceDatabaseTest.java | 4 +- .../library/metrics/BacktraceMetricsTest.java | 3 +- .../library/watchdog/BacktraceAnrTest.java | 3 +- .../watchdog/BacktraceWatchdogTest.java | 3 +- .../common/BacktraceSerializeHelper.java | 3 - .../library/models/BacktraceData.java | 3 +- .../library/models/BacktraceStackFrame.java | 3 +- .../database/BacktraceDatabaseRecord.java | 3 +- .../library/models/json/BacktraceReport.java | 3 +- .../library/models/json/SourceCode.java | 1 + .../models/json/ThreadInformation.java | 3 +- .../library/models/metrics/Event.java | 3 +- .../library/models/metrics/EventsPayload.java | 4 +- .../library/models/metrics/SummedEvent.java | 3 +- .../models/metrics/SummedEventsPayload.java | 4 +- .../library/models/metrics/UniqueEvent.java | 3 +- .../models/metrics/UniqueEventsPayload.java | 4 +- .../BacktraceDatabaseFileContext.java | 1 - 39 files changed, 67 insertions(+), 214 deletions(-) delete mode 100644 backtrace-library/src/androidTest/java/backtraceio/library/common/PrimitiveTypeSerializerHelperTest.java delete mode 100644 backtrace-library/src/androidTest/java/backtraceio/library/common/SerializerHelperTest.java diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientAttachmentsTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientAttachmentsTest.java index baf64834..fc9cebaa 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientAttachmentsTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientAttachmentsTest.java @@ -6,8 +6,9 @@ import static org.junit.Assert.assertNotNull; import android.content.Context; -import androidx.test.platform.app.InstrumentationRegistry; + import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; import net.jodah.concurrentunit.Waiter; diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientAttributeTests.java b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientAttributeTests.java index 1f25b2a2..9e94b704 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientAttributeTests.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientAttributeTests.java @@ -20,9 +20,7 @@ import java.util.Map; import java.util.concurrent.TimeUnit; -import backtraceio.library.events.OnServerResponseEventListener; import backtraceio.library.events.RequestHandler; -import backtraceio.library.models.BacktraceData; import backtraceio.library.models.BacktraceResult; import backtraceio.library.models.types.BacktraceResultStatus; diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientBreadcrumbsTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientBreadcrumbsTest.java index 903eeb36..1a17236e 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientBreadcrumbsTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientBreadcrumbsTest.java @@ -8,8 +8,8 @@ import android.content.Context; -import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; import junit.framework.TestCase; diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientEventsTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientEventsTest.java index 19bc833b..536fd73b 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientEventsTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientEventsTest.java @@ -5,8 +5,9 @@ import android.content.Context; import android.net.Uri; -import androidx.test.platform.app.InstrumentationRegistry; + import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; import net.jodah.concurrentunit.Waiter; diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientMetricsTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientMetricsTest.java index df887a19..4edd73f2 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientMetricsTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientMetricsTest.java @@ -10,8 +10,8 @@ import android.content.Context; -import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; import net.jodah.concurrentunit.Waiter; diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientProguardTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientProguardTest.java index ffd73386..e8aa78dc 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientProguardTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientProguardTest.java @@ -6,8 +6,9 @@ import static org.junit.Assert.assertNull; import android.content.Context; -import androidx.test.platform.app.InstrumentationRegistry; + import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; import net.jodah.concurrentunit.Waiter; diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientSendTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientSendTest.java index 4595adb1..9eeee5e1 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientSendTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientSendTest.java @@ -7,8 +7,9 @@ import static org.junit.Assert.assertTrue; import android.content.Context; -import androidx.test.platform.app.InstrumentationRegistry; + import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; import net.jodah.concurrentunit.Waiter; diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientSerializationTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientSerializationTest.java index 9f9c6e48..2e5ebc2b 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientSerializationTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientSerializationTest.java @@ -3,17 +3,24 @@ import static junit.framework.TestCase.fail; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; + import android.content.Context; + import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.platform.app.InstrumentationRegistry; + import com.google.gson.annotations.SerializedName; + import net.jodah.concurrentunit.Waiter; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; + import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; + import backtraceio.library.common.BacktraceSerializeHelper; import backtraceio.library.events.OnServerResponseEventListener; import backtraceio.library.events.RequestHandler; diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientSummedEventTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientSummedEventTest.java index 5ed1f69c..ab99b6fb 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientSummedEventTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientSummedEventTest.java @@ -7,8 +7,9 @@ import static org.junit.Assert.assertNotEquals; import android.content.Context; -import androidx.test.platform.app.InstrumentationRegistry; + import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; import net.jodah.concurrentunit.Waiter; diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientUniqueEventTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientUniqueEventTest.java index 63f5cf02..f2606528 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientUniqueEventTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientUniqueEventTest.java @@ -9,8 +9,9 @@ import static java.lang.Thread.sleep; import android.content.Context; -import androidx.test.platform.app.InstrumentationRegistry; + import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; import net.jodah.concurrentunit.Waiter; diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceErrorTypeAttributeTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceErrorTypeAttributeTest.java index 6c0cd1bf..82ca2300 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceErrorTypeAttributeTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceErrorTypeAttributeTest.java @@ -5,8 +5,9 @@ import static org.junit.Assert.assertEquals; import android.content.Context; -import androidx.test.platform.app.InstrumentationRegistry; + import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; import net.jodah.concurrentunit.Waiter; diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceFileAttachments.java b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceFileAttachments.java index 9eaf5cf1..ea31aae3 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceFileAttachments.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceFileAttachments.java @@ -5,9 +5,10 @@ import static org.junit.Assert.assertNotNull; import android.content.Context; + +import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.rule.GrantPermissionRule; -import androidx.test.ext.junit.runners.AndroidJUnit4; import net.jodah.concurrentunit.Waiter; diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceUrlTests.java b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceUrlTests.java index c454b2c7..1198d7ca 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceUrlTests.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceUrlTests.java @@ -1,6 +1,7 @@ package backtraceio.library; import android.net.Uri; + import androidx.test.ext.junit.runners.AndroidJUnit4; import org.junit.Assert; diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/SettingAttributesTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/SettingAttributesTest.java index 1016da21..689b3374 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/SettingAttributesTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/SettingAttributesTest.java @@ -6,8 +6,9 @@ import static org.junit.Assert.fail; import android.content.Context; -import androidx.test.platform.app.InstrumentationRegistry; + import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; import net.jodah.concurrentunit.Waiter; diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/common/PrimitiveTypeSerializerHelperTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/common/PrimitiveTypeSerializerHelperTest.java deleted file mode 100644 index 5fdcf202..00000000 --- a/backtrace-library/src/androidTest/java/backtraceio/library/common/PrimitiveTypeSerializerHelperTest.java +++ /dev/null @@ -1,50 +0,0 @@ -package backtraceio.library.common; - -import static junit.framework.TestCase.assertEquals; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; - -import backtraceio.library.common.serializers.SerializerHelper; - -@RunWith(Parameterized.class) -public class PrimitiveTypeSerializerHelperTest { - private Object testedObj; - private boolean expectedResult; - - // Constructor for the parameterized test - public PrimitiveTypeSerializerHelperTest(Object testedObj, boolean expectedResult) { - this.testedObj = testedObj; - this.expectedResult = expectedResult; - } - - @Parameterized.Parameters - public static Collection data() { - return Arrays.asList(new Object[][]{ - {1, true}, // int - {1L, true}, // long - {1.0f, true}, // float - {'c', true}, // char - {"test", true}, // string - {1.5, true}, // double - {new Object(), false}, // object - {new Exception("test"), false}, // object exception - {new ArrayList<>(), false}, // array list - {new HashMap<>(), false} // hash map - }); - } - @Test - public void testIsPrimitiveType() { - // WHEN - boolean result = SerializerHelper.isPrimitiveType(testedObj); - - // THEN - assertEquals(expectedResult, result); - } -} diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/common/SerializerHelperTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/common/SerializerHelperTest.java deleted file mode 100644 index 765c9578..00000000 --- a/backtrace-library/src/androidTest/java/backtraceio/library/common/SerializerHelperTest.java +++ /dev/null @@ -1,121 +0,0 @@ -package backtraceio.library.common; - -import static junit.framework.TestCase.assertEquals; -import static junit.framework.TestCase.assertNotNull; - -import androidx.test.ext.junit.runners.AndroidJUnit4; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import backtraceio.library.common.serializers.SerializerHelper; -import backtraceio.library.common.serializers.naming.NamingPolicy; -import backtraceio.library.models.BacktraceStackFrame; -import backtraceio.library.models.json.SourceCode; - -@RunWith(AndroidJUnit4.class) -public class SerializerHelperTest { - public final static NamingPolicy namingPolicy = new NamingPolicy(); - - @Test - public void serializeList() throws JSONException { - // GIVEN - final List list = new ArrayList() {{ - add(1); - add(2); - add(3); - }}; - // WHEN - JSONArray result = (JSONArray) SerializerHelper.serialize(namingPolicy, list); - - // THEN - assertEquals("[1,2,3]", result.toString()); - assertEquals(result.length(), 3); - } - - @Test - public void serializeObject() throws JSONException { - // GIVEN - final SourceCode sourceCode = new SourceCode(BacktraceStackFrame.fromStackTraceElement(new StackTraceElement("sample-class", "sample-method", "sample-file", 123))); - - // WHEN - JSONObject jsonObject = (JSONObject) SerializerHelper.serialize(namingPolicy, sourceCode); - - // THEN - assertEquals("{\"path\":\"sample-file\",\"startLine\":123}", jsonObject.toString()); - } - - @Test - public void serializeJSONObject() throws JSONException { - // GIVEN - final JSONObject jsonObject = new JSONObject(); - jsonObject.put("sample-int", 1); - jsonObject.put("sample-boolean", true); - jsonObject.put("sample-string", "example"); - jsonObject.put("sample-array", new ArrayList(){{ - add("1"); - add("2"); - add("3"); - }}); - jsonObject.put("sample-exception", new Exception("msg")); - - // WHEN - final JSONObject result = (JSONObject) SerializerHelper.serialize(namingPolicy, jsonObject); - - // THEN - final String expectedJson = "{\"name-value-pairs\":{\"sample-int\":1,\"sample-boolean\":true,\"sample-string\":\"example\",\"sample-array\":[\"1\",\"2\",\"3\"],\"sample-exception\":{\"detail-message\":\"msg\",\"stack-trace\":[],\"suppressed-exceptions\":[]}}}"; - assertEquals(expectedJson, result.toString()); // TODO: - } - - - - public void serializeMap() throws JSONException { - // GIVEN - Map object = new HashMap<>(); - object.put("string-value", "123"); - object.put("int-value", 123); - object.put("boolean-value", false); - object.put("exception-value", new Exception("test")); - - // WHEN - final JSONObject result = (JSONObject) SerializerHelper.serialize(namingPolicy, object); - - // THEN - assertEquals("", result.toString()); - } - - public void serializeObjectList() throws JSONException { - // GIVEN - List objList = new ArrayList<>(); - objList.add(new Exception("1")); - objList.add(new Exception("2")); - objList.add(new Exception("3")); - // WHEN - final JSONObject result = (JSONObject) SerializerHelper.serialize(namingPolicy, objList); - - // THEN - assertEquals("", result.toString()); - } - - public void serializeException() throws JSONException { - // GIVEN - final ArrayIndexOutOfBoundsException exception = new ArrayIndexOutOfBoundsException("test"); - - // WHEN - JSONObject result = (JSONObject) SerializerHelper.serialize(namingPolicy, exception); - - // THEN - assertNotNull(result); - - assertEquals("test", result.get("message")); - assertEquals("\"message\":\"test\"", result.toString()); - } -} 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 3be52201..d4c3959c 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseContextTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseContextTest.java @@ -6,8 +6,9 @@ import static org.junit.Assert.assertTrue; import android.content.Context; -import androidx.test.platform.app.InstrumentationRegistry; + import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; import org.junit.After; import org.junit.Before; 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 5f67ef73..1ba68e65 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseFileContextTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseFileContextTest.java @@ -5,8 +5,9 @@ import static org.junit.Assert.assertTrue; import android.content.Context; -import androidx.test.platform.app.InstrumentationRegistry; + import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; import org.junit.After; import org.junit.Before; 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 d37414de..e29d1116 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseProguardTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseProguardTest.java @@ -4,8 +4,9 @@ import static org.junit.Assert.assertNull; import android.content.Context; -import androidx.test.platform.app.InstrumentationRegistry; + import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; import org.junit.After; import org.junit.Before; 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 e5c06684..b30c5442 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseRecordTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseRecordTest.java @@ -6,8 +6,9 @@ import static junit.framework.TestCase.fail; import android.content.Context; -import androidx.test.platform.app.InstrumentationRegistry; + import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; import org.junit.After; import org.junit.Before; diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseRecordWriterTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseRecordWriterTest.java index ee76cfb2..0bf859e5 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseRecordWriterTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseRecordWriterTest.java @@ -2,8 +2,8 @@ import static junit.framework.TestCase.assertEquals; -import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; import org.junit.After; import org.junit.Before; @@ -12,7 +12,6 @@ import java.io.File; import java.io.IOException; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; 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 e3c54342..4d2121ac 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseTest.java @@ -3,10 +3,9 @@ import static org.junit.Assert.assertEquals; import android.content.Context; -import android.os.FileUtils; -import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; import net.jodah.concurrentunit.Waiter; @@ -18,7 +17,6 @@ import java.io.File; import java.io.FileFilter; import java.io.IOException; -import java.nio.file.FileSystems; import java.util.ArrayList; import java.util.HashMap; import java.util.List; diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/metrics/BacktraceMetricsTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/metrics/BacktraceMetricsTest.java index 0c69dc60..8f07a2bc 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/metrics/BacktraceMetricsTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/metrics/BacktraceMetricsTest.java @@ -3,8 +3,9 @@ import static org.junit.Assert.assertEquals; import android.content.Context; -import androidx.test.platform.app.InstrumentationRegistry; + import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; import junit.framework.TestCase; diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/watchdog/BacktraceAnrTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/watchdog/BacktraceAnrTest.java index fa958c28..0bf1f09e 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/watchdog/BacktraceAnrTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/watchdog/BacktraceAnrTest.java @@ -3,9 +3,10 @@ import static org.junit.Assert.fail; import android.content.Context; -import androidx.test.platform.app.InstrumentationRegistry; + import androidx.test.annotation.UiThreadTest; import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; import net.jodah.concurrentunit.Waiter; diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/watchdog/BacktraceWatchdogTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/watchdog/BacktraceWatchdogTest.java index 1f5b600e..3add03e0 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/watchdog/BacktraceWatchdogTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/watchdog/BacktraceWatchdogTest.java @@ -1,9 +1,10 @@ package backtraceio.library.watchdog; import android.content.Context; -import androidx.test.platform.app.InstrumentationRegistry; + import androidx.test.annotation.UiThreadTest; import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; import net.jodah.concurrentunit.Waiter; 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 3ab9b70a..ad3a9ee4 100644 --- a/backtrace-library/src/main/java/backtraceio/library/common/BacktraceSerializeHelper.java +++ b/backtrace-library/src/main/java/backtraceio/library/common/BacktraceSerializeHelper.java @@ -1,11 +1,8 @@ package backtraceio.library.common; -import com.google.gson.FieldNamingPolicy; import com.google.gson.Gson; -import com.google.gson.GsonBuilder; import backtraceio.library.common.serialization.BacktraceGsonBuilder; -import backtraceio.library.models.BacktraceResult; /** * Helper class for serialize and deserialize objects 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 2094f2c8..74f05d86 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java @@ -2,11 +2,12 @@ import android.content.Context; +import com.google.gson.annotations.SerializedName; + import java.util.List; import java.util.Map; import backtraceio.library.BacktraceClient; -import com.google.gson.annotations.SerializedName; import backtraceio.library.logger.BacktraceLogger; import backtraceio.library.models.json.Annotations; import backtraceio.library.models.json.BacktraceAttributes; 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 555b6589..2c619a8c 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceStackFrame.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceStackFrame.java @@ -1,9 +1,10 @@ package backtraceio.library.models; +import com.google.gson.annotations.SerializedName; + import java.util.UUID; -import com.google.gson.annotations.SerializedName; import backtraceio.library.logger.BacktraceLogger; /** 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 e1deee40..9dd8f196 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 @@ -1,5 +1,7 @@ package backtraceio.library.models.database; +import com.google.gson.annotations.SerializedName; + import java.io.File; import java.nio.charset.StandardCharsets; import java.util.UUID; @@ -7,7 +9,6 @@ import backtraceio.library.common.BacktraceSerializeHelper; import backtraceio.library.common.BacktraceStringHelper; import backtraceio.library.common.FileHelper; -import com.google.gson.annotations.SerializedName; import backtraceio.library.interfaces.DatabaseRecordWriter; import backtraceio.library.logger.BacktraceLogger; import backtraceio.library.models.BacktraceData; diff --git a/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceReport.java b/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceReport.java index 2fccc96a..6a45db4d 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceReport.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceReport.java @@ -2,6 +2,8 @@ import android.content.Context; +import com.google.gson.annotations.SerializedName; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -9,7 +11,6 @@ import java.util.UUID; import backtraceio.library.common.BacktraceTimeHelper; -import com.google.gson.annotations.SerializedName; import backtraceio.library.models.BacktraceAttributeConsts; import backtraceio.library.models.BacktraceData; import backtraceio.library.models.BacktraceStackFrame; 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 9e23eb59..9c6c0d72 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 @@ -1,6 +1,7 @@ package backtraceio.library.models.json; import com.google.gson.annotations.SerializedName; + import backtraceio.library.models.BacktraceStackFrame; /** 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 d5c1757d..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 @@ -1,9 +1,10 @@ package backtraceio.library.models.json; +import com.google.gson.annotations.SerializedName; + import java.util.ArrayList; import java.util.List; -import com.google.gson.annotations.SerializedName; import backtraceio.library.models.BacktraceStackFrame; /** diff --git a/backtrace-library/src/main/java/backtraceio/library/models/metrics/Event.java b/backtrace-library/src/main/java/backtraceio/library/models/metrics/Event.java index d0e59222..fce15e6e 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/metrics/Event.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/metrics/Event.java @@ -1,10 +1,11 @@ package backtraceio.library.models.metrics; +import com.google.gson.annotations.SerializedName; + import java.util.HashMap; import java.util.Map; import backtraceio.library.common.BacktraceStringHelper; -import com.google.gson.annotations.SerializedName; public abstract class Event { diff --git a/backtrace-library/src/main/java/backtraceio/library/models/metrics/EventsPayload.java b/backtrace-library/src/main/java/backtraceio/library/models/metrics/EventsPayload.java index c0bc301f..05198c75 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/metrics/EventsPayload.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/metrics/EventsPayload.java @@ -1,9 +1,9 @@ package backtraceio.library.models.metrics; -import java.util.concurrent.ConcurrentLinkedDeque; - import com.google.gson.annotations.SerializedName; +import java.util.concurrent.ConcurrentLinkedDeque; + public abstract class EventsPayload { private static final transient String LOG_TAG = EventsPayload.class.getSimpleName(); diff --git a/backtrace-library/src/main/java/backtraceio/library/models/metrics/SummedEvent.java b/backtrace-library/src/main/java/backtraceio/library/models/metrics/SummedEvent.java index 67bfc96c..b9665f01 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/metrics/SummedEvent.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/metrics/SummedEvent.java @@ -1,10 +1,11 @@ package backtraceio.library.models.metrics; +import com.google.gson.annotations.SerializedName; + import java.util.HashMap; import java.util.Map; import backtraceio.library.common.BacktraceTimeHelper; -import com.google.gson.annotations.SerializedName; public final class SummedEvent extends Event { diff --git a/backtrace-library/src/main/java/backtraceio/library/models/metrics/SummedEventsPayload.java b/backtrace-library/src/main/java/backtraceio/library/models/metrics/SummedEventsPayload.java index d32dbd00..fe483803 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/metrics/SummedEventsPayload.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/metrics/SummedEventsPayload.java @@ -1,9 +1,9 @@ package backtraceio.library.models.metrics; -import java.util.concurrent.ConcurrentLinkedDeque; - import com.google.gson.annotations.SerializedName; +import java.util.concurrent.ConcurrentLinkedDeque; + public class SummedEventsPayload extends EventsPayload { @SerializedName("summed_events") private final ConcurrentLinkedDeque summedEvents; diff --git a/backtrace-library/src/main/java/backtraceio/library/models/metrics/UniqueEvent.java b/backtrace-library/src/main/java/backtraceio/library/models/metrics/UniqueEvent.java index d7fb99eb..789b9825 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/metrics/UniqueEvent.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/metrics/UniqueEvent.java @@ -1,5 +1,7 @@ package backtraceio.library.models.metrics; +import com.google.gson.annotations.SerializedName; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -7,7 +9,6 @@ import backtraceio.library.common.BacktraceStringHelper; import backtraceio.library.common.BacktraceTimeHelper; -import com.google.gson.annotations.SerializedName; import backtraceio.library.logger.BacktraceLogger; public class UniqueEvent extends Event { diff --git a/backtrace-library/src/main/java/backtraceio/library/models/metrics/UniqueEventsPayload.java b/backtrace-library/src/main/java/backtraceio/library/models/metrics/UniqueEventsPayload.java index 3f695168..1f1b06ef 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/metrics/UniqueEventsPayload.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/metrics/UniqueEventsPayload.java @@ -1,9 +1,9 @@ package backtraceio.library.models.metrics; -import java.util.concurrent.ConcurrentLinkedDeque; - import com.google.gson.annotations.SerializedName; +import java.util.concurrent.ConcurrentLinkedDeque; + public final class UniqueEventsPayload extends EventsPayload { @SerializedName("unique_events") private final ConcurrentLinkedDeque uniqueEvents; 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 05946fc0..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; From 8bacf18c176ce5312bb2ffe82c9814e0e85497fa Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 29 May 2024 18:31:06 +0200 Subject: [PATCH 048/100] Use get report method --- .../BacktraceClientAttachmentsTest.java | 4 +- .../BacktraceClientAttributeTests.java | 2 +- .../BacktraceClientBreadcrumbsTest.java | 8 +- .../library/BacktraceClientProguardTest.java | 16 ++-- .../library/BacktraceClientSendTest.java | 14 ++-- .../BacktraceClientSerializationTest.java | 4 +- .../BacktraceErrorTypeAttributeTest.java | 2 +- .../library/SettingAttributesTest.java | 14 ++-- .../database/BacktraceDatabaseRecordTest.java | 6 +- .../library/models/BacktraceDataTest.java | 2 +- .../models/UncaughtExceptionHandlerTest.java | 26 +++--- .../watchdog/BacktraceWatchdogSharedTest.java | 2 +- .../library/BacktraceDatabase.java | 2 +- .../library/models/BacktraceData.java | 82 +++++++++++++++---- .../services/BacktraceHandlerThread.java | 2 +- 15 files changed, 119 insertions(+), 67 deletions(-) diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientAttachmentsTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientAttachmentsTest.java index fc9cebaa..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.report, 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.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/BacktraceClientAttributeTests.java b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientAttributeTests.java index 9e94b704..15161153 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientAttributeTests.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientAttributeTests.java @@ -136,7 +136,7 @@ public void attributesShouldBeAvailableInReport() { Object value = data.attributes.get(attributeKey); assertNotNull(value); assertEquals(value, attributeValue); - return new BacktraceResult(data.report, 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 1a17236e..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.report, 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.report, data.report.exception.getMessage(), + return new BacktraceResult(data.getReport(), data.getReport().exception.getMessage(), BacktraceResultStatus.Ok); } }; @@ -181,7 +181,7 @@ public void sendBacktraceExceptionBreadcrumbsClearBreadcrumb() { 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); } }; @@ -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/BacktraceClientProguardTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientProguardTest.java index e8aa78dc..0c8672da 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientProguardTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientProguardTest.java @@ -59,7 +59,7 @@ public void sendBacktraceReportWithStringAndAttributesProguard() { @Override public BacktraceResult onRequest(BacktraceData data) { assertEquals("proguard", data.symbolication); - return new BacktraceResult(data.report, data.report.message, + return new BacktraceResult(data.getReport(), data.getReport().message, BacktraceResultStatus.Ok); } }; @@ -98,7 +98,7 @@ public void sendBacktraceReportWithStringAndAttributesNoProguard() { @Override public BacktraceResult onRequest(BacktraceData data) { assertNull(data.symbolication); - return new BacktraceResult(data.report, data.report.message, + return new BacktraceResult(data.getReport(), data.getReport().message, BacktraceResultStatus.Ok); } }; @@ -139,7 +139,7 @@ public void sendBacktraceReportWithExceptionAndAttributesProguard() { @Override public BacktraceResult onRequest(BacktraceData data) { assertEquals("proguard", data.symbolication); - return new BacktraceResult(data.report, data.report.exception.getMessage(), + return new BacktraceResult(data.getReport(), data.getReport().exception.getMessage(), BacktraceResultStatus.Ok); } }; @@ -181,7 +181,7 @@ public void sendBacktraceReportWithExceptionAndAttributesNoProguard() { @Override public BacktraceResult onRequest(BacktraceData data) { assertNull(data.symbolication); - return new BacktraceResult(data.report, data.report.exception.getMessage(), + return new BacktraceResult(data.getReport(), data.getReport().exception.getMessage(), BacktraceResultStatus.Ok); } }; @@ -225,7 +225,7 @@ public void sendBacktraceExceptionProguard() { @Override public BacktraceResult onRequest(BacktraceData data) { assertEquals("proguard", data.symbolication); - return new BacktraceResult(data.report, data.report.exception.getMessage(), + return new BacktraceResult(data.getReport(), data.getReport().exception.getMessage(), BacktraceResultStatus.Ok); } }; @@ -267,7 +267,7 @@ public void sendBacktraceExceptionNoProguard() { @Override public BacktraceResult onRequest(BacktraceData data) { assertNull(data.symbolication); - return new BacktraceResult(data.report, data.report.exception.getMessage(), + return new BacktraceResult(data.getReport(), data.getReport().exception.getMessage(), BacktraceResultStatus.Ok); } }; @@ -310,7 +310,7 @@ public void sendBacktraceStringProguard() { @Override public BacktraceResult onRequest(BacktraceData data) { assertEquals("proguard", data.symbolication); - return new BacktraceResult(data.report, data.report.message, + return new BacktraceResult(data.getReport(), data.getReport().message, BacktraceResultStatus.Ok); } }; @@ -352,7 +352,7 @@ public void sendBacktraceStringNoProguard() { @Override public BacktraceResult onRequest(BacktraceData data) { assertNull(data.symbolication); - return new BacktraceResult(data.report, data.report.message, + 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 9eeee5e1..7b1a642d 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientSendTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientSendTest.java @@ -55,7 +55,7 @@ public void sendException() { RequestHandler rh = new RequestHandler() { @Override public BacktraceResult onRequest(BacktraceData data) { - return new BacktraceResult(null, data.report.exception.getMessage(), + return new BacktraceResult(null, data.getReport().exception.getMessage(), BacktraceResultStatus.ServerError); } }; @@ -110,7 +110,7 @@ public void sendExceptionWithManyCause() { fail(e.getMessage()); } - return new BacktraceResult(data.report, data.report.message, + return new BacktraceResult(data.getReport(), data.getReport().message, BacktraceResultStatus.Ok); }; backtraceClient.setOnRequestHandler(rh); @@ -136,7 +136,7 @@ public void sendBacktraceReportWithString() { RequestHandler rh = new RequestHandler() { @Override public BacktraceResult onRequest(BacktraceData data) { - return new BacktraceResult(data.report, data.report.message, + return new BacktraceResult(data.getReport(), data.getReport().message, BacktraceResultStatus.Ok); } }; @@ -171,7 +171,7 @@ public void sendBacktraceReportWithStringAndAttributes() { RequestHandler rh = new RequestHandler() { @Override public BacktraceResult onRequest(BacktraceData data) { - return new BacktraceResult(data.report, data.report.message, + return new BacktraceResult(data.getReport(), data.getReport().message, BacktraceResultStatus.Ok); } }; @@ -209,7 +209,7 @@ public void sendBacktraceReportWithException() { 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); } }; @@ -244,7 +244,7 @@ public void sendBacktraceReportWithExceptionAndAttributes() { 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); } }; @@ -287,7 +287,7 @@ public void sendMultipleReports() { 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/BacktraceClientSerializationTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientSerializationTest.java index 2e5ebc2b..53a58182 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientSerializationTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientSerializationTest.java @@ -75,11 +75,11 @@ public void sendReportWithTheSameJsonKeys() { public BacktraceResult onRequest(BacktraceData data) { String dataJson = BacktraceSerializeHelper.toJson(data); assertNotNull(dataJson); - String reportJson = BacktraceSerializeHelper.toJson(data.report); + String reportJson = BacktraceSerializeHelper.toJson(data.getReport()); assertNotNull(reportJson); - 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/BacktraceErrorTypeAttributeTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceErrorTypeAttributeTest.java index 82ca2300..e8ca3470 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceErrorTypeAttributeTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceErrorTypeAttributeTest.java @@ -62,7 +62,7 @@ public void sendBacktraceExceptionWithErrorType() { 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/SettingAttributesTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/SettingAttributesTest.java index 689b3374..63935f08 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; @@ -143,7 +144,7 @@ public BacktraceResult onRequest(BacktraceData data) { assertNotNull(data.attributes); assertTrue(data.attributes.containsKey(customClientAttributeKey)); assertEquals(data.attributes.get(customClientAttributeKey), customClientAttributeValue); - return new BacktraceResult(data.report, "", BacktraceResultStatus.Ok); + return new BacktraceResult(data.getReport(), "", BacktraceResultStatus.Ok); } }; backtraceClient.setOnRequestHandler(rh); @@ -176,12 +177,13 @@ public void run() { @Override public BacktraceResult onRequest(BacktraceData data) { // THEN - waiter.assertTrue(data.report.attributes.containsKey(customClientAttributeKey)); - waiter.assertEquals(customClientAttributeValue, data.report.attributes.get(customClientAttributeKey)); - waiter.assertEquals(exceptionMessage, data.report.exception.getMessage()); - waiter.assertEquals(data.report.attributes.get(BacktraceAttributeConsts.ErrorType), BacktraceAttributeConsts.UnhandledExceptionAttributeType); + 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(dataReport.attributes.get(BacktraceAttributeConsts.ErrorType), BacktraceAttributeConsts.UnhandledExceptionAttributeType); waiter.resume(); - return new BacktraceResult(data.report, "", BacktraceResultStatus.Ok); + return new BacktraceResult(data.getReport(), "", BacktraceResultStatus.Ok); } }); BacktraceExceptionHandler.enable(backtraceClient); 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 b30c5442..e8ab2f67 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseRecordTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseRecordTest.java @@ -66,7 +66,7 @@ public void saveAndGetRecord() { // THEN assertTrue(saveResult); assertTrue(validResult); - assertEquals(data.report.message, loadedData.report.message); + assertEquals(data.getReport().message, loadeddata.getReport().message); } @Test @@ -100,7 +100,7 @@ public void saveAndGetRecordWithAttachments() { // THEN assertTrue(saveResult); assertTrue(validResult); - assertEquals(data.report.message, loadedData.report.message); + assertEquals(data.getReport().message, loadeddata.getReport().message); assertTrue(existingFiles.contains(attachment0)); assertTrue(existingFiles.contains(attachment1)); } @@ -174,6 +174,6 @@ public void readFileAndDeserialize() { final BacktraceData dataFromFile = recordFromFile.getBacktraceData(); // THEN - assertEquals(data.report.message, dataFromFile.report.message); + assertEquals(data.getReport().message, dataFromFile.report.message); } } 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 0dc93394..7bce38e5 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/models/BacktraceDataTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/models/BacktraceDataTest.java @@ -38,7 +38,7 @@ public void createBacktraceDataTest() { // THEN assertArrayEquals(backtraceData.classifiers, new String[]{"java.lang.IllegalAccessException"}); - assertEquals(backtraceData.report, report); + assertEquals(backtracedata.getReport(), report); assertEquals(backtraceData.attributes.get("classifier"), "java.lang.IllegalAccessException"); assertEquals(backtraceData.agent, "backtrace-android"); assertEquals(backtraceData.agentVersion, "3.8.0-6-6b6db45-backtrace-data-refactor"); diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/models/UncaughtExceptionHandlerTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/models/UncaughtExceptionHandlerTest.java index b6ef0e38..90cddc89 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/models/UncaughtExceptionHandlerTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/models/UncaughtExceptionHandlerTest.java @@ -68,7 +68,7 @@ public void testUncaughtException() throws InvocationTargetException, NoSuchMeth client.setOnRequestHandler(data -> { testedAtomicReportData.set(data); waiter.resume(); - return new BacktraceResult(data.report, data.report.message, + return new BacktraceResult(data.getReport(), data.getReport().message, BacktraceResultStatus.Ok); }); @@ -87,12 +87,12 @@ public void testUncaughtException() throws InvocationTargetException, NoSuchMeth // THEN assertNotNull(testedAtomicReportData); final BacktraceData testedReportData = testedAtomicReportData.get(); - assertEquals("Test message", testedReportData.report.exception.getMessage()); - assertNull(testedReportData.report.message); - assertTrue(testedReportData.report.diagnosticStack.size() > 0); - assertEquals("java.lang.IllegalArgumentException", testedReportData.report.classifier); - assertEquals("Unhandled Exception", testedReportData.report.attributes.get("error.type")); - assertTrue(testedReportData.report.exceptionTypeReport); + assertEquals("Test message", testedReportdata.getReport().exception.getMessage()); + assertNull(testedReportdata.getReport().message); + assertTrue(testedReportdata.getReport().diagnosticStack.size() > 0); + assertEquals("java.lang.IllegalArgumentException", testedReportdata.getReport().classifier); + assertEquals("Unhandled Exception", testedReportdata.getReport().attributes.get("error.type")); + assertTrue(testedReportdata.getReport().exceptionTypeReport); } @Test @@ -106,7 +106,7 @@ public void testUncaughtError() throws InvocationTargetException, NoSuchMethodEx client.setOnRequestHandler(data -> { testedAtomicReportData.set(data); waiter.resume(); - return new BacktraceResult(data.report, data.report.message, + return new BacktraceResult(data.getReport(), data.getReport().message, BacktraceResultStatus.Ok); }); @@ -125,10 +125,10 @@ public void testUncaughtError() throws InvocationTargetException, NoSuchMethodEx // THEN assertNotNull(testedAtomicReportData); final BacktraceData testedReportData = testedAtomicReportData.get(); - assertNull(testedReportData.report.message); - assertTrue(testedReportData.report.diagnosticStack.size() > 0); - assertEquals("java.lang.OutOfMemoryError", testedReportData.report.classifier); - assertEquals("Unhandled Exception", testedReportData.report.attributes.get("error.type")); - assertTrue(testedReportData.report.exceptionTypeReport); + assertNull(testedReportdata.getReport().message); + assertTrue(testedReportdata.getReport().diagnosticStack.size() > 0); + assertEquals("java.lang.OutOfMemoryError", testedReportdata.getReport().classifier); + assertEquals("Unhandled Exception", testedReportdata.getReport().attributes.get("error.type")); + assertTrue(testedReportdata.getReport().exceptionTypeReport); } } 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 cd2cf10a..45d3a074 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/watchdog/BacktraceWatchdogSharedTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/watchdog/BacktraceWatchdogSharedTest.java @@ -59,7 +59,7 @@ public void checkAnrBreadcrumb() { backtraceClient.clearBreadcrumbs(); backtraceClient.setOnRequestHandler(data -> { - String breadcrumbPath = data.report.attachmentPaths.get(0); + String breadcrumbPath = data.getReport().attachmentPaths.get(0); assertTrue(breadcrumbPath.contains("bt-breadcrumbs")); assertEquals(data.attributes.get("error.type"), AnrAttributeType); diff --git a/backtrace-library/src/main/java/backtraceio/library/BacktraceDatabase.java b/backtrace-library/src/main/java/backtraceio/library/BacktraceDatabase.java index 3f726998..b5fcc901 100644 --- a/backtrace-library/src/main/java/backtraceio/library/BacktraceDatabase.java +++ b/backtrace-library/src/main/java/backtraceio/library/BacktraceDatabase.java @@ -317,7 +317,7 @@ public void run() { while (record != null) { final CountDownLatch threadWaiter = new CountDownLatch(1); BacktraceData backtraceData = record.getBacktraceData(); - if (backtraceData == null || backtraceData.report == null) { + if (backtraceData == null || backtracedata.getReport() == null) { BacktraceLogger.d(LOG_TAG, "Timer - backtrace data or report is null - " + "deleting record"); delete(record); 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 74f05d86..cb0b7d2d 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java @@ -97,6 +97,58 @@ public class BacktraceData { @SerializedName("sourceCode") public Map sourceCode; + public String getUuid() { + return uuid; + } + + public String getLang() { + return lang; + } + + public String getAgent() { + return agent; + } + + public String getSymbolication() { + return symbolication; + } + + public long getTimestamp() { + return timestamp; + } + + public String getLangVersion() { + return langVersion; + } + + 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; + } + /** * Current BacktraceReport */ @@ -146,25 +198,25 @@ public Map getThreadInformationMap() { } public static class Builder { - final BacktraceReport report; + private final BacktraceReport report; - final String symbolication; + private final String symbolication; - String uuid; + private String uuid; - long timestamp; + private long timestamp; - String[] classifiers; + private String[] classifiers; - String langVersion; + private String langVersion; - String agentVersion; + private String agentVersion; - Map annotations; - Map sourceCode; - Map threadInformationMap; - Map attributes; - String mainThread; + private Map annotations; + private Map sourceCode; + private Map threadInformationMap; + private Map attributes; + private String mainThread; public Builder(Context context, BacktraceReport report, Map clientAttributes) { @@ -181,7 +233,7 @@ public Builder(Context context, BacktraceReport report, String symbolication, Ma } public BacktraceData build() { - BacktraceData backtraceData = new BacktraceData( + return new BacktraceData( this.uuid, this.symbolication, this.timestamp, @@ -195,8 +247,6 @@ public BacktraceData build() { this.sourceCode, this.threadInformationMap ); - - return backtraceData; } /** @@ -224,7 +274,7 @@ private void setDefaultThreadsInformation() { this.sourceCode = sourceCodeData.data.isEmpty() ? null : sourceCodeData.data; } - public void setAttributes(Context context, Map clientAttributes) { + private void setAttributes(Context context, Map clientAttributes) { BacktraceLogger.d(LOG_TAG, "Setting attributes"); BacktraceAttributes backtraceAttributes = new BacktraceAttributes( context, 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 01c4c5bb..2f60fd54 100644 --- a/backtrace-library/src/main/java/backtraceio/library/services/BacktraceHandlerThread.java +++ b/backtrace-library/src/main/java/backtraceio/library/services/BacktraceHandlerThread.java @@ -95,7 +95,7 @@ public void handleMessage(Message msg) { BacktraceLogger.d(LOG_TAG, "Sending report using default request handler"); String json = BacktraceSerializeHelper.toJson(mInput.data); List attachments = BacktraceDataAttachmentsFileHelper.getExistingFiles(this.context, mInput.data); - result = BacktraceReportSender.sendReport(url, json, attachments, mInput.data.report, + result = BacktraceReportSender.sendReport(url, json, attachments, mInput.data.getReport(), mInput.serverErrorEventListener); } From 2759a60fa7258454c3bf023ca5ef81a605652d78 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 29 May 2024 18:32:19 +0200 Subject: [PATCH 049/100] Move getters below --- .../library/models/BacktraceData.java | 96 ++++++++++--------- 1 file changed, 49 insertions(+), 47 deletions(-) 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 cb0b7d2d..12affe81 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java @@ -97,6 +97,55 @@ public class BacktraceData { @SerializedName("sourceCode") public Map sourceCode; + /** + * Current BacktraceReport + */ + public transient BacktraceReport report; // Think if we need it + + /** + * Application thread details + */ + @SerializedName("threads") + Map threadInformationMap; + + + public BacktraceData() { + + } + + 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; + } + + /** + * Get absolute paths to report attachments + * + * @return paths to attachments + */ + public List getAttachmentPaths() { + return report.attachmentPaths; + } + + public Map getThreadInformationMap() { + return threadInformationMap; + } + + public String getUuid() { return uuid; } @@ -149,53 +198,6 @@ public BacktraceReport getReport() { return report; } - /** - * Current BacktraceReport - */ - public transient BacktraceReport report; // Think if we need it - - /** - * Application thread details - */ - @SerializedName("threads") - Map threadInformationMap; - - - public BacktraceData() { - - } - - 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; - } - - /** - * Get absolute paths to report attachments - * - * @return paths to attachments - */ - public List getAttachmentPaths() { - return report.attachmentPaths; - } - - public Map getThreadInformationMap() { - return threadInformationMap; - } public static class Builder { private final BacktraceReport report; From 8072dfd18fcbab554c1a87ab2ee99f7bab3c2a75 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 29 May 2024 18:34:27 +0200 Subject: [PATCH 050/100] Rename method --- .../library/database/BacktraceDatabaseRecordTest.java | 2 +- .../library/models/BacktraceDataAttachmentsFileHelper.java | 2 +- .../backtraceio/library/services/BacktraceHandlerThread.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) 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 e8ab2f67..57387c0b 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseRecordTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseRecordTest.java @@ -96,7 +96,7 @@ public void saveAndGetRecordWithAttachments() { record.close(); final BacktraceData loadedData = record.getBacktraceData(); - final List existingFiles = BacktraceDataAttachmentsFileHelper.getExistingFiles(context, loadedData); + final List existingFiles = BacktraceDataAttachmentsFileHelper.getValidAttachments(context, loadedData); // THEN assertTrue(saveResult); assertTrue(validResult); diff --git a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceDataAttachmentsFileHelper.java b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceDataAttachmentsFileHelper.java index 49a0423e..bf8ec99d 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceDataAttachmentsFileHelper.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceDataAttachmentsFileHelper.java @@ -8,7 +8,7 @@ public class BacktraceDataAttachmentsFileHelper { - public static List getExistingFiles (Context context, BacktraceData backtraceData) { // TODO: fix name + public static List getValidAttachments(Context context, BacktraceData backtraceData) { // TODO: fix name return FileHelper.filterOutFiles(context, backtraceData.getAttachmentPaths()); } } 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 2f60fd54..900959a9 100644 --- a/backtrace-library/src/main/java/backtraceio/library/services/BacktraceHandlerThread.java +++ b/backtrace-library/src/main/java/backtraceio/library/services/BacktraceHandlerThread.java @@ -94,7 +94,7 @@ public void handleMessage(Message msg) { } else { BacktraceLogger.d(LOG_TAG, "Sending report using default request handler"); String json = BacktraceSerializeHelper.toJson(mInput.data); - List attachments = BacktraceDataAttachmentsFileHelper.getExistingFiles(this.context, mInput.data); + List attachments = BacktraceDataAttachmentsFileHelper.getValidAttachments(this.context, mInput.data); result = BacktraceReportSender.sendReport(url, json, attachments, mInput.data.getReport(), mInput.serverErrorEventListener); } From e515faae3be47a5a8116bebcfca7ab9b81c3dd9a Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 29 May 2024 18:34:48 +0200 Subject: [PATCH 051/100] Remove todo --- .../library/models/BacktraceDataAttachmentsFileHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceDataAttachmentsFileHelper.java b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceDataAttachmentsFileHelper.java index bf8ec99d..59927d0c 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceDataAttachmentsFileHelper.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceDataAttachmentsFileHelper.java @@ -8,7 +8,7 @@ public class BacktraceDataAttachmentsFileHelper { - public static List getValidAttachments(Context context, BacktraceData backtraceData) { // TODO: fix name + public static List getValidAttachments(Context context, BacktraceData backtraceData) { return FileHelper.filterOutFiles(context, backtraceData.getAttachmentPaths()); } } From fd202773f029c9a755650a314179afb68b85596d Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 29 May 2024 18:36:11 +0200 Subject: [PATCH 052/100] Remove todo --- .../java/backtraceio/library/models/BacktraceStackFrame.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 2c619a8c..3c0324b6 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceStackFrame.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceStackFrame.java @@ -35,7 +35,7 @@ public class BacktraceStackFrame { /** * Source code file name where exception occurs */ - public transient String sourceCodeFileName; // why transient + public transient String sourceCodeFileName; /** * Create new instance of BacktraceStackFrame From 060299090c70339646ee9c466617adce89a215fb Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 29 May 2024 18:36:46 +0200 Subject: [PATCH 053/100] Remove todo --- .../java/backtraceio/library/models/BacktraceStackFrame.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 3c0324b6..0d94768c 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceStackFrame.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceStackFrame.java @@ -62,7 +62,7 @@ public static BacktraceStackFrame fromStackTraceElement(StackTraceElement frame) public BacktraceStackFrame(String functionName, String sourceCodeFileName, Integer line) { this.functionName = functionName; - this.sourceCodeFileName = sourceCodeFileName; // why + this.sourceCodeFileName = sourceCodeFileName; this.sourceCode = UUID.randomUUID().toString(); this.line = line; } From 8c8931633a5034e2234d2742303d3431b74d1bb7 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 29 May 2024 18:38:03 +0200 Subject: [PATCH 054/100] Remove unused code --- .../models/database/BacktraceDatabaseRecord.java | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) 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 9dd8f196..e04ee981 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 @@ -37,7 +37,7 @@ public class BacktraceDatabaseRecord { /** * record writer */ - private transient DatabaseRecordWriter recordWriter; + private final transient DatabaseRecordWriter recordWriter; /** @@ -68,13 +68,6 @@ public class BacktraceDatabaseRecord { * Stored record */ private transient BacktraceData record; - -// public 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.record = data; @@ -133,8 +126,6 @@ public long getSize() { /** * Get valid BacktraceData from current record - * - * @param context * @return valid BacktraceData object */ public BacktraceData getBacktraceData() { // TODO: check if we still need it From 804251c0ffd1275e4043ba606c5864efcba72fda Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 29 May 2024 18:40:40 +0200 Subject: [PATCH 055/100] Remove todo --- .../src/main/java/backtraceio/library/BacktraceDatabase.java | 2 +- .../library/models/database/BacktraceDatabaseRecord.java | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/backtrace-library/src/main/java/backtraceio/library/BacktraceDatabase.java b/backtrace-library/src/main/java/backtraceio/library/BacktraceDatabase.java index b5fcc901..5bb31f5d 100644 --- a/backtrace-library/src/main/java/backtraceio/library/BacktraceDatabase.java +++ b/backtrace-library/src/main/java/backtraceio/library/BacktraceDatabase.java @@ -317,7 +317,7 @@ public void run() { while (record != null) { final CountDownLatch threadWaiter = new CountDownLatch(1); BacktraceData backtraceData = record.getBacktraceData(); - if (backtraceData == null || backtracedata.getReport() == null) { + if (backtraceData == null || backtraceData.getReport() == null) { BacktraceLogger.d(LOG_TAG, "Timer - backtrace data or report is null - " + "deleting record"); delete(record); 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 e04ee981..afc49b6d 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 @@ -128,7 +128,7 @@ public long getSize() { * Get valid BacktraceData from current record * @return valid BacktraceData object */ - public BacktraceData getBacktraceData() { // TODO: check if we still need it + public BacktraceData getBacktraceData() { if (this.record != null) { return this.record; } @@ -153,8 +153,6 @@ public BacktraceData getBacktraceData() { // TODO: check if we still need it // diagnostic data to API diagnosticData.report = BacktraceSerializeHelper.fromJson(jsonReport, BacktraceReport.class); - // Serialized data loses the context, give context again when deserializing -// diagnosticData.context = context; // TODO: check if we still need it return diagnosticData; } catch (Exception ex) { BacktraceLogger.e(LOG_TAG, "Exception occurs on deserialization of diagnostic data", ex); From b68784dff4326a636ba7348f2fa064f243751373 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 29 May 2024 18:42:59 +0200 Subject: [PATCH 056/100] Improve backtrace-report model --- .../java/backtraceio/library/models/json/BacktraceReport.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceReport.java b/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceReport.java index 601d2802..079c52db 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceReport.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceReport.java @@ -2,13 +2,14 @@ import android.content.Context; +import com.google.gson.annotations.SerializedName; + import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; import backtraceio.library.common.BacktraceTimeHelper; -import backtraceio.library.common.serializers.SerializedName; import backtraceio.library.common.CollectionUtils; import backtraceio.library.models.BacktraceAttributeConsts; import backtraceio.library.models.BacktraceData; @@ -35,7 +36,6 @@ public class BacktraceReport { /** * Get information about report type. If value is true the BacktraceReport has an error */ - @SerializedName("exception-type-report") public Boolean exceptionTypeReport = false; /** From 9189726368644caaf5e7f72f97b428597226d263 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 29 May 2024 18:48:41 +0200 Subject: [PATCH 057/100] Remove unused files --- .../java/backtraceio/library/TestUtils.java | 29 ------------------- .../backtraceio/backtraceio/MainActivity.java | 6 ++-- 2 files changed, 2 insertions(+), 33 deletions(-) delete mode 100644 backtrace-library/src/androidTest/java/backtraceio/library/TestUtils.java diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/TestUtils.java b/backtrace-library/src/androidTest/java/backtraceio/library/TestUtils.java deleted file mode 100644 index c20aed4f..00000000 --- a/backtrace-library/src/androidTest/java/backtraceio/library/TestUtils.java +++ /dev/null @@ -1,29 +0,0 @@ -package backtraceio.library; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; - -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; - } -} diff --git a/example-app/src/main/java/backtraceio/backtraceio/MainActivity.java b/example-app/src/main/java/backtraceio/backtraceio/MainActivity.java index 142c626b..993940f9 100644 --- a/example-app/src/main/java/backtraceio/backtraceio/MainActivity.java +++ b/example-app/src/main/java/backtraceio/backtraceio/MainActivity.java @@ -40,7 +40,7 @@ public class MainActivity extends AppCompatActivity { // Used to load the 'native-lib' library on application startup. static { -// System.loadLibrary("native-lib"); + System.loadLibrary("native-lib"); } public void setOnServerResponseEventListener(OnServerResponseEventListener e) { @@ -74,9 +74,7 @@ private void symlinkAndWriteFile() { } private BacktraceClient initializeBacktrace(final String submissionUrl) { -// BacktraceCredentials credentials = new BacktraceCredentials(submissionUrl); -BacktraceCredentials credentials = new BacktraceCredentials("https://yolo.sp.backtrace.io:6098/", - "2dd86e8e779d1fc7e22e7b19a9489abeedec3b1426abe7e2209888e92362fba4"); + BacktraceCredentials credentials = new BacktraceCredentials(submissionUrl); Context context = getApplicationContext(); String dbPath = context.getFilesDir().getAbsolutePath(); From 0faf51c460e03f0970bc93c156364e5450923deb Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 29 May 2024 19:01:18 +0200 Subject: [PATCH 058/100] Use getters --- .../BacktraceClientAttributeTests.java | 16 +++++++---- .../library/BacktraceClientEventsTest.java | 4 +-- .../library/BacktraceClientProguardTest.java | 16 +++++------ .../database/BacktraceDatabaseTest.java | 2 +- .../library/models/BacktraceDataTest.java | 28 +++++++++---------- .../watchdog/BacktraceWatchdogSharedTest.java | 2 +- .../library/models/BacktraceData.java | 7 ++--- .../database/BacktraceDatabaseRecord.java | 2 +- 8 files changed, 40 insertions(+), 37 deletions(-) diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientAttributeTests.java b/backtrace-library/src/androidTest/java/backtraceio/library/BacktraceClientAttributeTests.java index 15161153..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,11 +135,11 @@ 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.getReport().exception.getMessage(), 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/database/BacktraceDatabaseTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseTest.java index 4d2121ac..9fc84eb8 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseTest.java @@ -125,7 +125,7 @@ public void addWithAttributes() { final BacktraceData dataFromDatabase = record.getBacktraceData(); // THEN - assertEquals(value, dataFromDatabase.attributes.get(key)); + assertEquals(value, dataFromDatabase.getAttributes().get(key)); } @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 7bce38e5..6a14fafe 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/models/BacktraceDataTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/models/BacktraceDataTest.java @@ -37,20 +37,20 @@ public void createBacktraceDataTest() { BacktraceData backtraceData = new BacktraceData.Builder(context, report, new HashMap<>()).build(); // THEN - assertArrayEquals(backtraceData.classifiers, new String[]{"java.lang.IllegalAccessException"}); - assertEquals(backtracedata.getReport(), report); - assertEquals(backtraceData.attributes.get("classifier"), "java.lang.IllegalAccessException"); - assertEquals(backtraceData.agent, "backtrace-android"); - assertEquals(backtraceData.agentVersion, "3.8.0-6-6b6db45-backtrace-data-refactor"); - assertEquals(backtraceData.lang, "java"); - assertEquals(backtraceData.langVersion, "0"); - assertEquals(backtraceData.symbolication, ""); - assertEquals(backtraceData.timestamp, report.timestamp); - assertEquals(backtraceData.uuid, report.uuid.toString()); - assertEquals(backtraceData.attributes.size(), 40); - assertEquals(backtraceData.annotations.size(), 3); - assertEquals(backtraceData.mainThread, "instr: androidx.test.runner.androidjunitrunner"); - assertEquals(backtraceData.sourceCode.size(), 34); + assertArrayEquals(backtraceData.getClassifiers(), new String[]{"java.lang.IllegalAccessException"}); + assertEquals(backtraceData.getReport(), report); + assertEquals(backtraceData.getAttributes().get("classifier"), "java.lang.IllegalAccessException"); + assertEquals(backtraceData.getAgent(), "backtrace-android"); + assertEquals(backtraceData.getAgentVersion(), "3.8.0-6-6b6db45-backtrace-data-refactor"); + assertEquals(backtraceData.getLang(), "java"); + assertEquals(backtraceData.getLangVersion(), "0"); + assertEquals(backtraceData.getSymbolication(), ""); + assertEquals(backtraceData.getTimestamp(), report.timestamp); + assertEquals(backtraceData.getUuid(), report.uuid.toString()); + assertEquals(backtraceData.getAttributes().size(), 40); + assertEquals(backtraceData.getAnnotations().size(), 3); + assertEquals(backtraceData.getMainThread(), "instr: androidx.test.runner.androidjunitrunner"); + assertEquals(backtraceData.getSourceCode().size(), 34); assertEquals(backtraceData.getThreadInformationMap().size(), 13); assertEquals(backtraceData.getAttachmentPaths().size(), 2); } 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/models/BacktraceData.java b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java index 12affe81..fa3bf603 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java @@ -107,11 +107,8 @@ public class BacktraceData { */ @SerializedName("threads") Map threadInformationMap; - - - public BacktraceData() { - - } + + public BacktraceData() { } public BacktraceData(String uuid, String symbolication, long timestamp, String langVersion, String agentVersion, Map attributes, String mainThread, 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 afc49b6d..1d818dc3 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 @@ -69,7 +69,7 @@ public class BacktraceDatabaseRecord { */ private transient BacktraceData record; public BacktraceDatabaseRecord(BacktraceData data, String path) { - this.id = UUID.fromString(data.uuid); + this.id = UUID.fromString(data.getUuid()); this.record = data; this.path = path; this.recordWriter = new BacktraceDatabaseRecordWriter(path); From 3e082d72c9b45986d4392a2592d78df61ba4351e Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 29 May 2024 20:13:55 +0200 Subject: [PATCH 059/100] Remove todo --- .../main/java/backtraceio/library/models/BacktraceData.java | 3 --- 1 file changed, 3 deletions(-) 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 fa3bf603..017cb54e 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java @@ -17,9 +17,6 @@ import backtraceio.library.models.json.ThreadData; import backtraceio.library.models.json.ThreadInformation; - -// TODO: replace direct access with getters - /** * Serializable Backtrace API data object */ From d253450ecf41ad7cc38e615ad9b8c06582d4050b Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 29 May 2024 20:18:39 +0200 Subject: [PATCH 060/100] Remove unnecessary annotation --- .../models/UncaughtExceptionHandlerTest.java | 22 +++++++++---------- .../library/models/json/BacktraceReport.java | 3 --- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/backtrace-library/src/androidTest/java/backtraceio/library/models/UncaughtExceptionHandlerTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/models/UncaughtExceptionHandlerTest.java index 90cddc89..a2024bf7 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/models/UncaughtExceptionHandlerTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/models/UncaughtExceptionHandlerTest.java @@ -87,12 +87,12 @@ public void testUncaughtException() throws InvocationTargetException, NoSuchMeth // THEN assertNotNull(testedAtomicReportData); final BacktraceData testedReportData = testedAtomicReportData.get(); - assertEquals("Test message", testedReportdata.getReport().exception.getMessage()); - assertNull(testedReportdata.getReport().message); - assertTrue(testedReportdata.getReport().diagnosticStack.size() > 0); - assertEquals("java.lang.IllegalArgumentException", testedReportdata.getReport().classifier); - assertEquals("Unhandled Exception", testedReportdata.getReport().attributes.get("error.type")); - assertTrue(testedReportdata.getReport().exceptionTypeReport); + assertEquals("Test message", testedReportData.getReport().exception.getMessage()); + assertNull(testedReportData.getReport().message); + assertTrue(testedReportData.getReport().diagnosticStack.size() > 0); + assertEquals("java.lang.IllegalArgumentException", testedReportData.getReport().classifier); + assertEquals("Unhandled Exception", testedReportData.getReport().attributes.get("error.type")); + assertTrue(testedReportData.getReport().exceptionTypeReport); } @Test @@ -125,10 +125,10 @@ public void testUncaughtError() throws InvocationTargetException, NoSuchMethodEx // THEN assertNotNull(testedAtomicReportData); final BacktraceData testedReportData = testedAtomicReportData.get(); - assertNull(testedReportdata.getReport().message); - assertTrue(testedReportdata.getReport().diagnosticStack.size() > 0); - assertEquals("java.lang.OutOfMemoryError", testedReportdata.getReport().classifier); - assertEquals("Unhandled Exception", testedReportdata.getReport().attributes.get("error.type")); - assertTrue(testedReportdata.getReport().exceptionTypeReport); + assertNull(testedReportData.getReport().message); + assertTrue(testedReportData.getReport().diagnosticStack.size() > 0); + assertEquals("java.lang.OutOfMemoryError", testedReportData.getReport().classifier); + assertEquals("Unhandled Exception", testedReportData.getReport().attributes.get("error.type")); + assertTrue(testedReportData.getReport().exceptionTypeReport); } } diff --git a/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceReport.java b/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceReport.java index 079c52db..2f7d2016 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceReport.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceReport.java @@ -2,8 +2,6 @@ import android.content.Context; -import com.google.gson.annotations.SerializedName; - import java.util.HashMap; import java.util.List; import java.util.Map; @@ -66,7 +64,6 @@ public class BacktraceReport { /** * Current report exception stack */ - @SerializedName("diagnostic-stack") public List diagnosticStack; /** From 98381cc1f26ef39a13a6d17dc592af0130686f97 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 12 Jun 2024 22:30:15 +0200 Subject: [PATCH 061/100] Add unit tests for BacktraceResult and BacktraceApiResult --- .../database/BacktraceDatabaseRecordTest.java | 4 +- .../library/models/BacktraceDataTest.java | 12 ++- .../library/models/BacktraceResult.java | 34 +++++++- .../models/BacktraceApiResultTest.java | 48 +++++++++++ .../library/models/BacktraceResultTest.java | 81 +++++++++++++++++++ ...ror.json => backtraceApiResult.error.json} | 0 .../test/resources/backtraceApiResult.json | 1 + .../src/test/resources/backtraceResult.json | 2 +- 8 files changed, 174 insertions(+), 8 deletions(-) create mode 100644 backtrace-library/src/test/java/backtraceio/library/models/BacktraceApiResultTest.java create mode 100644 backtrace-library/src/test/java/backtraceio/library/models/BacktraceResultTest.java rename backtrace-library/src/test/resources/{backtraceResult.error.json => backtraceApiResult.error.json} (100%) create mode 100644 backtrace-library/src/test/resources/backtraceApiResult.json 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 57387c0b..bd1fb672 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseRecordTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseRecordTest.java @@ -66,7 +66,7 @@ public void saveAndGetRecord() { // THEN assertTrue(saveResult); assertTrue(validResult); - assertEquals(data.getReport().message, loadeddata.getReport().message); + assertEquals(data.getReport().message, loadedData.getReport().message); } @Test @@ -100,7 +100,7 @@ public void saveAndGetRecordWithAttachments() { // THEN assertTrue(saveResult); assertTrue(validResult); - assertEquals(data.getReport().message, loadeddata.getReport().message); + assertEquals(data.getReport().message, loadedData.getReport().message); assertTrue(existingFiles.contains(attachment0)); assertTrue(existingFiles.contains(attachment1)); } 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 6a14fafe..ed575891 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/models/BacktraceDataTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/models/BacktraceDataTest.java @@ -15,6 +15,7 @@ import java.util.Arrays; import java.util.HashMap; import java.util.List; +import java.util.Map; import backtraceio.library.models.json.BacktraceReport; @@ -33,8 +34,12 @@ public void createBacktraceDataTest() { 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.Builder(context, report, new HashMap<>()).build(); + BacktraceData backtraceData = new BacktraceData.Builder(context, report, clientAttributes).build(); // THEN assertArrayEquals(backtraceData.getClassifiers(), new String[]{"java.lang.IllegalAccessException"}); @@ -47,11 +52,14 @@ public void createBacktraceDataTest() { assertEquals(backtraceData.getSymbolication(), ""); assertEquals(backtraceData.getTimestamp(), report.timestamp); assertEquals(backtraceData.getUuid(), report.uuid.toString()); - assertEquals(backtraceData.getAttributes().size(), 40); + assertEquals(backtraceData.getAttributes().size(), 43); assertEquals(backtraceData.getAnnotations().size(), 3); assertEquals(backtraceData.getMainThread(), "instr: androidx.test.runner.androidjunitrunner"); assertEquals(backtraceData.getSourceCode().size(), 34); assertEquals(backtraceData.getThreadInformationMap().size(), 13); assertEquals(backtraceData.getAttachmentPaths().size(), 2); + assertEquals(backtraceData.getAttributes().get("attr-2"), 1); + assertEquals(backtraceData.getAttributes().get("attr-2"), true); + assertEquals(backtraceData.getAttributes().get("attr-3"), "test"); } } 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 9a436416..d61c7df5 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceResult.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceResult.java @@ -1,5 +1,7 @@ package backtraceio.library.models; +import com.google.gson.annotations.SerializedName; + import backtraceio.library.models.json.BacktraceReport; import backtraceio.library.models.types.BacktraceResultStatus; @@ -11,6 +13,7 @@ public class BacktraceResult { /** * Object identifier */ + @SerializedName("_rxid") public String rxId; /** @@ -35,11 +38,11 @@ public BacktraceResult() { } public BacktraceResult(BacktraceApiResult apiResult) { - this(apiResult.rxId, apiResult.response); + this(apiResult.rxId, apiResult.getResponse()); } public BacktraceResult(String rxId, String status) { - this(null, rxId, BacktraceResultStatus.valueOf(status)); + this(null, rxId, null, BacktraceResultStatus.valueOf(status)); } /** @@ -50,9 +53,34 @@ public BacktraceResult(String rxId, String status) { * @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/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/BacktraceResultTest.java b/backtrace-library/src/test/java/backtraceio/library/models/BacktraceResultTest.java new file mode 100644 index 00000000..4c1efabc --- /dev/null +++ b/backtrace-library/src/test/java/backtraceio/library/models/BacktraceResultTest.java @@ -0,0 +1,81 @@ +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 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/resources/backtraceResult.error.json b/backtrace-library/src/test/resources/backtraceApiResult.error.json similarity index 100% rename from backtrace-library/src/test/resources/backtraceResult.error.json rename to backtrace-library/src/test/resources/backtraceApiResult.error.json 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/backtraceResult.json b/backtrace-library/src/test/resources/backtraceResult.json index 1174a076..041811cc 100644 --- a/backtrace-library/src/test/resources/backtraceResult.json +++ b/backtrace-library/src/test/resources/backtraceResult.json @@ -1 +1 @@ -{"response":"ok","_rxid":"95000000-eb43-390b-0000-000000000000"} \ No newline at end of file +{"_rxid":"95000000-eb43-390b-0000-000000000000","status":"Ok"} \ No newline at end of file From 9c4311ce39d0b83894c186014cf2e09357176afb Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Thu, 20 Jun 2024 00:27:11 +0200 Subject: [PATCH 062/100] Add Thread information tests --- .../library/models/BacktraceStackFrame.java | 6 +- .../models/json/ThreadInformationTest.java | 96 +++++++++++++++++++ .../src/test/resources/threadInformation.json | 15 +++ 3 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 backtrace-library/src/test/java/backtraceio/library/models/json/ThreadInformationTest.java create mode 100644 backtrace-library/src/test/resources/threadInformation.json 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 0d94768c..151c0dab 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceStackFrame.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceStackFrame.java @@ -61,9 +61,13 @@ public static BacktraceStackFrame fromStackTraceElement(StackTraceElement frame) } 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 = UUID.randomUUID().toString(); + this.sourceCode = sourceCodeUuid; this.line = line; } } \ No newline at end of file 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..fd860d8f --- /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.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() { + // 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 = BacktraceSerializeHelper.toJson(obj); + + // THEN + String expectedJson = TestUtils.readFileAsString(this, "threadInformation.json") + .replace("\n", "") + .replace(" ", "") + .replace("\t", ""); + + 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/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 From 8e87beea80e6a8f2f5a7241f30d0c8c3bd9d80ff Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Mon, 8 Jul 2024 07:21:33 +0200 Subject: [PATCH 063/100] Add test for backtrace stack frame --- .../java/backtraceio/library/TestUtils.java | 6 ++ .../models/BacktraceStackFrameTest.java | 74 +++++++++++++++++++ .../models/json/ThreadInformationTest.java | 2 +- .../test/resources/backtraceStackFrame.json | 5 ++ 4 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 backtrace-library/src/test/java/backtraceio/library/models/BacktraceStackFrameTest.java create mode 100644 backtrace-library/src/test/resources/backtraceStackFrame.json diff --git a/backtrace-library/src/test/java/backtraceio/library/TestUtils.java b/backtrace-library/src/test/java/backtraceio/library/TestUtils.java index c20aed4f..129cfc58 100644 --- a/backtrace-library/src/test/java/backtraceio/library/TestUtils.java +++ b/backtrace-library/src/test/java/backtraceio/library/TestUtils.java @@ -26,4 +26,10 @@ public static String readFileAsString(Object obj, String fileName) { } return null; } + + public static String unifyJsonString(String json) { + return json.replace("\n", "") + .replace(" ", "") + .replace("\t", ""); + } } 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..26c08d1f --- /dev/null +++ b/backtrace-library/src/test/java/backtraceio/library/models/BacktraceStackFrameTest.java @@ -0,0 +1,74 @@ +package backtraceio.library.models; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import org.junit.Test; + +import backtraceio.library.TestUtils; +import backtraceio.library.common.BacktraceSerializeHelper; + +public class BacktraceStackFrameTest { + private final String JSON_FILE = "backtraceStackFrame.json"; + @Test + public void serialize() { + // GIVEN + BacktraceStackFrame obj = new BacktraceStackFrame("java.util.TimerThread.run", "TimerThread", 512, "85c0915f-3b99-4942-91c8-221e23846ded"); + // WHEN + String json = BacktraceSerializeHelper.toJson(obj); + // THEN + String expectedJson = TestUtils.unifyJsonString(TestUtils.readFileAsString(this, JSON_FILE)); + + assertEquals(expectedJson, json); + } + + @Test + public void serializeFromStackTraceElement() { + // GIVEN + String sourceCodeUuid = "85c0915f-3b99-4942-91c8-221e23846ded"; + BacktraceStackFrame obj = BacktraceStackFrame.fromStackTraceElement(new StackTraceElement("java.util.TimerThread", "run", "", 512)); + // WHEN + String json = BacktraceSerializeHelper.toJson(obj); + // THEN + String expectedJson = TestUtils.unifyJsonString(TestUtils.readFileAsString(this, JSON_FILE)). + replace(sourceCodeUuid, obj.sourceCode); + + assertEquals(expectedJson, json); + } + + @Test + public void createFromNullStackTraceElement() { + // GIVEN + BacktraceStackFrame obj = BacktraceStackFrame.fromStackTraceElement(null); + // THEN + assertNull(obj); + } + + @Test + public void deserialize() { + // GIVEN + String json = TestUtils.unifyJsonString(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/ThreadInformationTest.java b/backtrace-library/src/test/java/backtraceio/library/models/json/ThreadInformationTest.java index fd860d8f..99d67839 100644 --- a/backtrace-library/src/test/java/backtraceio/library/models/json/ThreadInformationTest.java +++ b/backtrace-library/src/test/java/backtraceio/library/models/json/ThreadInformationTest.java @@ -33,7 +33,7 @@ public void serialize() { .replace(" ", "") .replace("\t", ""); - assertEquals(expectedJson,json); + assertEquals(expectedJson, json); } @Test 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 From 55e92f022663cae56ce1f7685ff7afcba78c9dc0 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Mon, 8 Jul 2024 07:41:07 +0200 Subject: [PATCH 064/100] Refactor db record test --- .../database/BacktraceDatabaseRecordTest.java | 39 ++++++++++++------- 1 file changed, 26 insertions(+), 13 deletions(-) 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 bd1fb672..7f69429c 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseRecordTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseRecordTest.java @@ -31,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 @@ -54,7 +52,7 @@ public void saveAndGetRecord() { // GIVEN final BacktraceReport report = new BacktraceReport(testMessage); final BacktraceData data = new BacktraceData.Builder(this.context, report, null).build(); - final BacktraceDatabaseRecord record = new BacktraceDatabaseRecord(data, this.dbPath); + final BacktraceDatabaseRecord record = new BacktraceDatabaseRecord(data, this.database.getSettings().getDatabasePath()); // WHEN final boolean saveResult = record.save(); @@ -88,7 +86,7 @@ public void saveAndGetRecordWithAttachments() { final BacktraceReport report = new BacktraceReport(testMessage, attachments); final BacktraceData data = new BacktraceData.Builder(this.context, report, null).build(); - final BacktraceDatabaseRecord record = new BacktraceDatabaseRecord(data, this.dbPath); + final BacktraceDatabaseRecord record = new BacktraceDatabaseRecord(data, this.database.getSettings().getDatabasePath()); // WHEN final boolean saveResult = record.save(); @@ -110,7 +108,7 @@ public void deleteFileDiagnosticPathToCorruptRecord() { // GIVEN BacktraceReport report = new BacktraceReport(testMessage); BacktraceData data = new BacktraceData.Builder(this.context, report, null).build(); - BacktraceDatabaseRecord record = new BacktraceDatabaseRecord(data, this.dbPath); + BacktraceDatabaseRecord record = new BacktraceDatabaseRecord(data, this.database.getSettings().getDatabasePath()); // WHEN boolean saveResult = record.save(); @@ -128,7 +126,7 @@ public void deleteFileReportPathToCorruptRecord() { // GIVEN BacktraceReport report = new BacktraceReport(testMessage); BacktraceData data = new BacktraceData.Builder(this.context, report, null).build(); - BacktraceDatabaseRecord record = new BacktraceDatabaseRecord(data, this.dbPath); + BacktraceDatabaseRecord record = new BacktraceDatabaseRecord(data, this.database.getSettings().getDatabasePath()); // WHEN boolean saveResult = record.save(); @@ -146,14 +144,14 @@ public void createAndDeleteRecordFiles() { // GIVEN BacktraceReport report = new BacktraceReport(testMessage); BacktraceData data = new BacktraceData.Builder(this.context, report, null).build(); - BacktraceDatabaseRecord record = new BacktraceDatabaseRecord(data, this.dbPath); + 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); @@ -166,7 +164,7 @@ public void readFileAndDeserialize() { // GIVEN final BacktraceReport report = new BacktraceReport(testMessage); final BacktraceData data = new BacktraceData.Builder(this.context, report, null).build(); - final BacktraceDatabaseRecord record = new BacktraceDatabaseRecord(data, this.dbPath); + final BacktraceDatabaseRecord record = new BacktraceDatabaseRecord(data, this.database.getSettings().getDatabasePath()); record.save(); // WHEN @@ -176,4 +174,19 @@ public void readFileAndDeserialize() { // THEN assertEquals(data.getReport().message, dataFromFile.report.message); } + + @Test + public void serialize() { + + } + + @Test + public void deserialize() { + + } + + @Test + public void serializeAndDeserialize() { + + } } From ad59a872b7d0a8d4e9405ea5fbb97e4c7adcd6f1 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Tue, 9 Jul 2024 23:04:03 +0200 Subject: [PATCH 065/100] Add unit tests --- .../database/BacktraceDatabaseRecordTest.java | 15 ---- .../database/BacktraceDatabaseRecord.java | 2 +- .../database/BacktraceDatabaseRecordTest.java | 73 +++++++++++++++++++ .../resources/backtraceDatabaseRecord.json | 1 + 4 files changed, 75 insertions(+), 16 deletions(-) create mode 100644 backtrace-library/src/test/java/backtraceio/library/database/BacktraceDatabaseRecordTest.java create mode 100644 backtrace-library/src/test/resources/backtraceDatabaseRecord.json 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 7f69429c..5c672395 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseRecordTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseRecordTest.java @@ -174,19 +174,4 @@ public void readFileAndDeserialize() { // THEN assertEquals(data.getReport().message, dataFromFile.report.message); } - - @Test - public void serialize() { - - } - - @Test - public void deserialize() { - - } - - @Test - public void serializeAndDeserialize() { - - } } 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 1d818dc3..5b8cf473 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 @@ -21,7 +21,7 @@ public class BacktraceDatabaseRecord { /** * Path to database directory */ - private final String path; + private final transient String path; /** * Id 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/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 From e9012b476c01d73f5815a0a450f474bcd4b379b6 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 10 Jul 2024 00:31:00 +0200 Subject: [PATCH 066/100] Add unit tests --- .../library/models/json/SourceCode.java | 8 ++ .../library/models/json/SourceCodeData.java | 2 +- .../models/json/SourceCodeDataTest.java | 73 +++++++++++++++++++ .../library/models/json/SourceCodeTest.java | 53 ++++++++++++++ .../models/json/ThreadInformationTest.java | 7 +- .../src/test/resources/sourceCode.json | 4 + .../src/test/resources/sourceCodeData.json | 11 +++ 7 files changed, 153 insertions(+), 5 deletions(-) create mode 100644 backtrace-library/src/test/java/backtraceio/library/models/json/SourceCodeDataTest.java create mode 100644 backtrace-library/src/test/java/backtraceio/library/models/json/SourceCodeTest.java create mode 100644 backtrace-library/src/test/resources/sourceCode.json create mode 100644 backtrace-library/src/test/resources/sourceCodeData.json 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 9c6c0d72..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 @@ -29,4 +29,12 @@ 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 3a957ec5..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 @@ -16,7 +16,7 @@ public class SourceCodeData { /** * Source code information about current executed program */ - public Map data = new HashMap<>(); + public final Map data = new HashMap<>(); public SourceCodeData(List exceptionStack) { BacktraceLogger.d(LOG_TAG, "Initialization source code data"); 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..c8567556 --- /dev/null +++ b/backtrace-library/src/test/java/backtraceio/library/models/json/SourceCodeDataTest.java @@ -0,0 +1,73 @@ +package backtraceio.library.models.json; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +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() { + // 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); + + // THEN + String expectedJson = TestUtils.unifyJsonString( + 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..91b9ad1c --- /dev/null +++ b/backtrace-library/src/test/java/backtraceio/library/models/json/SourceCodeTest.java @@ -0,0 +1,53 @@ +package backtraceio.library.models.json; + +import static org.junit.Assert.assertEquals; + +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() { + // GIVEN + SourceCode obj = new SourceCode(17, "InvokeMethod.java"); + + // WHEN + String json = BacktraceSerializeHelper.toJson(obj); + + // THEN + String expectedJson = TestUtils.unifyJsonString( + 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 index 99d67839..1f1e12e0 100644 --- a/backtrace-library/src/test/java/backtraceio/library/models/json/ThreadInformationTest.java +++ b/backtrace-library/src/test/java/backtraceio/library/models/json/ThreadInformationTest.java @@ -28,10 +28,9 @@ public void serialize() { String json = BacktraceSerializeHelper.toJson(obj); // THEN - String expectedJson = TestUtils.readFileAsString(this, "threadInformation.json") - .replace("\n", "") - .replace(" ", "") - .replace("\t", ""); + String expectedJson = TestUtils.unifyJsonString( + TestUtils.readFileAsString(this, "threadInformation.json") + ); assertEquals(expectedJson, json); } 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 From fb49d5963800099f77f6fbc92d8b3eef95fd3fc0 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Mon, 15 Jul 2024 19:48:17 +0200 Subject: [PATCH 067/100] Test backtrace report --- backtrace-library/build.gradle | 1 + .../java/backtraceio/library/TestUtils.java | 11 + .../models/json/BacktraceReportTest.java | 76 ++++++ .../test/resources/backtraceReport-tmp.json | 238 ++++++++++++++++++ .../src/test/resources/backtraceReport.json | 35 ++- 5 files changed, 360 insertions(+), 1 deletion(-) create mode 100644 backtrace-library/src/test/java/backtraceio/library/models/json/BacktraceReportTest.java create mode 100644 backtrace-library/src/test/resources/backtraceReport-tmp.json diff --git a/backtrace-library/build.gradle b/backtrace-library/build.gradle index 104c51e4..dda86818 100644 --- a/backtrace-library/build.gradle +++ b/backtrace-library/build.gradle @@ -88,6 +88,7 @@ dependencies { androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' androidTestImplementation 'org.mockito:mockito-core:2.28.2' androidTestImplementation "org.mockito:mockito-android:2.28.2" + testImplementation "com.google.guava:guava:33.2.1-jre" } apply from: 'publish.gradle' diff --git a/backtrace-library/src/test/java/backtraceio/library/TestUtils.java b/backtrace-library/src/test/java/backtraceio/library/TestUtils.java index 129cfc58..3f626eb4 100644 --- a/backtrace-library/src/test/java/backtraceio/library/TestUtils.java +++ b/backtrace-library/src/test/java/backtraceio/library/TestUtils.java @@ -1,5 +1,8 @@ package backtraceio.library; +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; + import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; @@ -32,4 +35,12 @@ public static String unifyJsonString(String json) { .replace(" ", "") .replace("\t", ""); } + + public static boolean compareJson(String json1, String json2) { + JsonParser parser = new JsonParser(); + JsonElement o1 = parser.parse(json1); + JsonElement o2 = parser.parse(json2); +// System.out.println(o1.equals(o2)); + return o1.equals(o2); + } } 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..66baf869 --- /dev/null +++ b/backtrace-library/src/test/java/backtraceio/library/models/json/BacktraceReportTest.java @@ -0,0 +1,76 @@ +package backtraceio.library.models.json; + +import com.google.common.collect.Maps; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; + +import org.junit.Test; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +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() { + // GIVEN +// public BacktraceReport(UUID uuid, long timestamp, +// boolean exceptionTypeReport, String classifier, +// Map attributes, +// String message, Exception exception, +// List attachmentPaths, +// List diagnosticStack) { +// +// } + 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")); + Exception exception = new IllegalAccessException(); +// exception. + StackTraceElement[] stackTraceElements = new StackTraceElement[1]; + stackTraceElements[0] = new StackTraceElement("backtraceio.library.SettingAttributesTest", "tmpGsonTest", "SettingAttributesTest.java", 75); + + exception.setStackTrace(stackTraceElements); + BacktraceReport report = new BacktraceReport(UUID.fromString("a62a533a-a7b8-415c-9a99-253c51f00827"), 1709680251, true, "java.lang.IllegalAccessException", null, null, exception, new ArrayList() {{ add("abc.txt"); }}, diagnosticStack); +// BacktraceReport report = new BacktraceReport(new IllegalAccessException(), null, new ArrayList() {{ add("abc.txt"); }}); + +// report.diagnosticStack. + + +// report.uuid + + // WHEN + String json = BacktraceSerializeHelper.toJson(report); + // THEN + + String expectedJson = TestUtils.unifyJsonString( + TestUtils.readFileAsString(this, JSON_FILE) + ); + +// assertTrue(TestUtils.compareJson(json, expectedJson)); + Gson g = new Gson(); + Type mapType = new TypeToken>(){}.getType(); + Map firstMap = g.fromJson(json, mapType); + Map secondMap = g.fromJson(expectedJson, mapType); + System.out.println(Maps.difference(firstMap, secondMap)); +// assertNotNull(json); + } + + @Test + public void deserialize() { + + } + + @Test + public void serializeAndDeserialize() { + + } +} 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 index 3f6a28ce..1502f33e 100644 --- a/backtrace-library/src/test/resources/backtraceReport.json +++ b/backtrace-library/src/test/resources/backtraceReport.json @@ -1 +1,34 @@ -{"attachment-paths":[],"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"},{"funcName":"org.junit.runners.model.FrameworkMethod$1.runReflectiveCall","line":59,"sourceCode":"bd149fbf-b1c5-43af-a53e-18d613140f4d"},{"funcName":"org.junit.internal.runners.model.ReflectiveCallable.run","line":12,"sourceCode":"183d6033-e096-4fd8-a190-d8947354aaa9"},{"funcName":"org.junit.runners.model.FrameworkMethod.invokeExplosively","line":56,"sourceCode":"bf114ba5-c2f5-41b2-a7c2-80d4f30eacdc"},{"funcName":"org.junit.internal.runners.statements.InvokeMethod.evaluate","line":17,"sourceCode":"8d499ef4-7bf9-49f7-a06e-9c34ba4ccc69"},{"funcName":"androidx.test.internal.runner.junit4.statement.RunBefores.evaluate","line":80,"sourceCode":"8c80c122-14e9-4ee5-bc48-8da38ec9d0a9"},{"funcName":"org.junit.runners.ParentRunner$3.evaluate","line":306,"sourceCode":"174e6e74-76c5-4d08-a58c-64c24aaf6ea0"},{"funcName":"org.junit.runners.BlockJUnit4ClassRunner$1.evaluate","line":100,"sourceCode":"4a45c684-03cb-4d07-93ce-04cb6ae4dd00"},{"funcName":"org.junit.runners.ParentRunner.runLeaf","line":366,"sourceCode":"3105e506-3104-489f-ad24-1b3cbe610e32"},{"funcName":"org.junit.runners.BlockJUnit4ClassRunner.runChild","line":103,"sourceCode":"dd7ba2ca-f129-4806-894d-e8e8e61290c2"},{"funcName":"org.junit.runners.BlockJUnit4ClassRunner.runChild","line":63,"sourceCode":"ab513a09-13b2-4ae5-8e1b-2be51b8e6df1"},{"funcName":"org.junit.runners.ParentRunner$4.run","line":331,"sourceCode":"8fa6d1d6-adc9-47e4-8db5-bf8ae79e1791"},{"funcName":"org.junit.runners.ParentRunner$1.schedule","line":79,"sourceCode":"03cefd46-7ebf-4713-a438-2534757338b3"},{"funcName":"org.junit.runners.ParentRunner.runChildren","line":329,"sourceCode":"c6b95075-3b03-4acb-ac84-6b64ef8dc8c4"},{"funcName":"org.junit.runners.ParentRunner.access$100","line":66,"sourceCode":"83631ebc-436d-4218-871b-cdda0be927cc"},{"funcName":"org.junit.runners.ParentRunner$2.evaluate","line":293,"sourceCode":"bd0ebabf-dff6-4662-a7ce-4d2f8882b610"},{"funcName":"org.junit.runners.ParentRunner$3.evaluate","line":306,"sourceCode":"e6eb219d-8698-449e-989f-fe265086791d"},{"funcName":"org.junit.runners.ParentRunner.run","line":413,"sourceCode":"dea0b948-ce57-4b5c-b0f9-aaf59c9e982e"},{"funcName":"androidx.test.ext.junit.runners.AndroidJUnit4.run","line":162,"sourceCode":"300e5627-ccde-4d88-ad18-af12acf4b314"},{"funcName":"org.junit.runners.Suite.runChild","line":128,"sourceCode":"c934c1cb-f20f-4da2-8d1e-9cac80e3f29b"},{"funcName":"org.junit.runners.Suite.runChild","line":27,"sourceCode":"ccd786d2-f763-4cc3-982a-493f8cb0a0e8"},{"funcName":"org.junit.runners.ParentRunner$4.run","line":331,"sourceCode":"fd16c8e6-7ac7-470a-990e-1703b301bfbb"},{"funcName":"org.junit.runners.ParentRunner$1.schedule","line":79,"sourceCode":"9a4d6c39-c233-4823-b632-73cd764996f3"},{"funcName":"org.junit.runners.ParentRunner.runChildren","line":329,"sourceCode":"f02dd76d-8093-4a34-81a0-4e79b383f13e"},{"funcName":"org.junit.runners.ParentRunner.access$100","line":66,"sourceCode":"8c34280e-fa49-451e-bd26-27cb76f9a836"},{"funcName":"org.junit.runners.ParentRunner$2.evaluate","line":293,"sourceCode":"457c3c30-cbf1-474b-8ac5-b0a12a2a98fc"},{"funcName":"org.junit.runners.ParentRunner$3.evaluate","line":306,"sourceCode":"d0ca0f81-5018-4ecc-b890-bd4c561c3d34"},{"funcName":"org.junit.runners.ParentRunner.run","line":413,"sourceCode":"35799925-5686-4d9c-b4e9-2644043ecd29"},{"funcName":"org.junit.runner.JUnitCore.run","line":137,"sourceCode":"a3872d95-0550-4931-b31c-9707cd89a5a5"},{"funcName":"org.junit.runner.JUnitCore.run","line":115,"sourceCode":"4d8f9dac-7bcf-4c7c-adbd-231daca51a53"},{"funcName":"androidx.test.internal.runner.TestExecutor.execute","line":67,"sourceCode":"612fc16a-f056-4d49-8e45-82d25d05dfb7"},{"funcName":"androidx.test.internal.runner.TestExecutor.execute","line":58,"sourceCode":"37fd34c2-0c59-4567-8145-b4cadc9a5a9f"},{"funcName":"androidx.test.runner.AndroidJUnitRunner.onStart","line":446,"sourceCode":"c03ef402-39c5-47d3-8871-4367dec69712"},{"funcName":"android.app.Instrumentation$InstrumentationThread.run","line":2205,"sourceCode":"dfead18b-f0de-4c9f-9812-627322b44860"}],"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 +{ + "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" + } + ], + "suppressed-exceptions": [] + }, + "exception-type-report": true, + "timestamp": 1709680251, + "uuid": "a62a533a-a7b8-415c-9a99-253c51f00827" +} \ No newline at end of file From 83d153bb2b6124d19a08b6bbde13ca99cef60a59 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Mon, 15 Jul 2024 23:41:24 +0200 Subject: [PATCH 068/100] Backtrace report unit tests --- .../library/models/json/BacktraceReport.java | 1 + .../java/backtraceio/library/TestUtils.java | 28 +++- .../models/json/BacktraceReportTest.java | 126 +++++++++++++----- .../src/test/resources/backtraceReport.json | 3 +- 4 files changed, 121 insertions(+), 37 deletions(-) diff --git a/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceReport.java b/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceReport.java index 2f7d2016..742c70d1 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceReport.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceReport.java @@ -6,6 +6,7 @@ import java.util.List; import java.util.Map; import java.util.UUID; +import java.lang.Exception; import backtraceio.library.common.BacktraceTimeHelper; import backtraceio.library.common.CollectionUtils; diff --git a/backtrace-library/src/test/java/backtraceio/library/TestUtils.java b/backtrace-library/src/test/java/backtraceio/library/TestUtils.java index 3f626eb4..6a0eb29d 100644 --- a/backtrace-library/src/test/java/backtraceio/library/TestUtils.java +++ b/backtrace-library/src/test/java/backtraceio/library/TestUtils.java @@ -1,12 +1,18 @@ 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 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 { @@ -37,10 +43,22 @@ public static String unifyJsonString(String json) { } public static boolean compareJson(String json1, String json2) { - JsonParser parser = new JsonParser(); - JsonElement o1 = parser.parse(json1); - JsonElement o2 = parser.parse(json2); -// System.out.println(o1.equals(o2)); - return o1.equals(o2); + + 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)); // TODO: improve print + return false; + } + return true; } } 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 index 66baf869..9f2f1f3b 100644 --- a/backtrace-library/src/test/java/backtraceio/library/models/json/BacktraceReportTest.java +++ b/backtrace-library/src/test/java/backtraceio/library/models/json/BacktraceReportTest.java @@ -1,17 +1,18 @@ package backtraceio.library.models.json; -import com.google.common.collect.Maps; -import com.google.gson.Gson; -import com.google.gson.reflect.TypeToken; +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.junit.Test; -import java.lang.reflect.Type; 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; @@ -21,56 +22,119 @@ public class BacktraceReportTest { @Test public void serialize() { // GIVEN -// public BacktraceReport(UUID uuid, long timestamp, -// boolean exceptionTypeReport, String classifier, -// Map attributes, -// String message, Exception exception, -// List attachmentPaths, -// List diagnosticStack) { -// -// } - List diagnosticStack = new ArrayList<>(); + 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")); - Exception exception = new IllegalAccessException(); -// exception. - StackTraceElement[] stackTraceElements = new StackTraceElement[1]; + 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); - BacktraceReport report = new BacktraceReport(UUID.fromString("a62a533a-a7b8-415c-9a99-253c51f00827"), 1709680251, true, "java.lang.IllegalAccessException", null, null, exception, new ArrayList() {{ add("abc.txt"); }}, diagnosticStack); -// BacktraceReport report = new BacktraceReport(new IllegalAccessException(), null, new ArrayList() {{ add("abc.txt"); }}); - -// report.diagnosticStack. - -// report.uuid + 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 + // THEN String expectedJson = TestUtils.unifyJsonString( TestUtils.readFileAsString(this, JSON_FILE) ); -// assertTrue(TestUtils.compareJson(json, expectedJson)); - Gson g = new Gson(); - Type mapType = new TypeToken>(){}.getType(); - Map firstMap = g.fromJson(json, mapType); - Map secondMap = g.fromJson(expectedJson, mapType); - System.out.println(Maps.difference(firstMap, secondMap)); -// assertNotNull(json); + 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/resources/backtraceReport.json b/backtrace-library/src/test/resources/backtraceReport.json index 1502f33e..6a96fcff 100644 --- a/backtrace-library/src/test/resources/backtraceReport.json +++ b/backtrace-library/src/test/resources/backtraceReport.json @@ -23,7 +23,8 @@ "declaring-class": "backtraceio.library.SettingAttributesTest", "file-name": "SettingAttributesTest.java", "line-number": 75, - "method-name": "tmpGsonTest" + "method-name": "tmpGsonTest", + "format": 0 } ], "suppressed-exceptions": [] From dbc6e583662b1c676712f569bbfdf9f14229ae2a Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 17 Jul 2024 00:41:43 +0200 Subject: [PATCH 069/100] Add BacktraceData unit tests --- .../library/models/BacktraceDataJsonTest.java | 140 ++++++++++++++++++ .../src/test/resources/backtraceData.json | 51 +++++++ 2 files changed, 191 insertions(+) create mode 100644 backtrace-library/src/test/java/backtraceio/library/models/BacktraceDataJsonTest.java create mode 100644 backtrace-library/src/test/resources/backtraceData.json 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..2e7092c1 --- /dev/null +++ b/backtrace-library/src/test/java/backtraceio/library/models/BacktraceDataJsonTest.java @@ -0,0 +1,140 @@ +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.AnnotationException; +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 +// 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) +// + // GIVEN attributes + 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 = new HashMap<>(); + attributes.put("application.session", "4b965773-539e-4dd3-be1b-f8ab017c2c9f"); + + // GIVEN annotations + final Map annotations = new HashMap() + {{ + put("Environment Variables", ImmutableMap.copyOf(new HashMap() {{ + put("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"); + }} + )); + put("Exception", new AnnotationException("Example test string")); + }}; + + // GIVEN other + final Map sourceCode = new HashMap<>(); + sourceCode.put("8751bea6-d6f6-48f4-9f96-1355c3408a9a", new SourceCode(null, "VMStack.java")); + sourceCode.put("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 + final BacktraceData backtraceData = new BacktraceData( + "ecdf418b-3e22-4c7c-8011-c85dc2b4386f", + null, + 1720419610, + "0", + "3.8.3", + attributes, + "instr: androidx.test.runner.androidjunitrunner", + null, + null, + annotations, + sourceCode, + threadInformationMap + ); + return backtraceData; + } + + @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); +// assertNull(obj.ge); + // TODO: more + } + + + @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); +// assertNull(obj.ge); + // TODO: more + } +} 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 From 0f20ef0be412c907cb5cb22fe0a0c7b629b6aaa6 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 17 Jul 2024 21:23:51 +0200 Subject: [PATCH 070/100] Add backtrace data unit tests --- .../library/models/BacktraceDataJsonTest.java | 74 ++++++++++++++++++- 1 file changed, 70 insertions(+), 4 deletions(-) diff --git a/backtrace-library/src/test/java/backtraceio/library/models/BacktraceDataJsonTest.java b/backtrace-library/src/test/java/backtraceio/library/models/BacktraceDataJsonTest.java index 2e7092c1..9b9b9cba 100644 --- a/backtrace-library/src/test/java/backtraceio/library/models/BacktraceDataJsonTest.java +++ b/backtrace-library/src/test/java/backtraceio/library/models/BacktraceDataJsonTest.java @@ -109,8 +109,41 @@ public void deserialize() { assertEquals("backtrace-android", obj.getAgent()); assertEquals("instr: androidx.test.runner.androidjunitrunner", obj.getMainThread()); assertNull(obj.classifiers); -// assertNull(obj.ge); - // TODO: more + 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); } @@ -134,7 +167,40 @@ public void serializeAndDeserialize() { assertEquals("backtrace-android", obj.getAgent()); assertEquals("instr: androidx.test.runner.androidjunitrunner", obj.getMainThread()); assertNull(obj.classifiers); -// assertNull(obj.ge); - // TODO: more + 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); } } From 93a4222b0b68bba09260a31bdbe6382596d5ab00 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 17 Jul 2024 21:31:20 +0200 Subject: [PATCH 071/100] Refactor unit-tests --- .../library/models/BacktraceDataJsonTest.java | 34 ++++++------------- 1 file changed, 10 insertions(+), 24 deletions(-) diff --git a/backtrace-library/src/test/java/backtraceio/library/models/BacktraceDataJsonTest.java b/backtrace-library/src/test/java/backtraceio/library/models/BacktraceDataJsonTest.java index 9b9b9cba..3b9411c8 100644 --- a/backtrace-library/src/test/java/backtraceio/library/models/BacktraceDataJsonTest.java +++ b/backtrace-library/src/test/java/backtraceio/library/models/BacktraceDataJsonTest.java @@ -17,7 +17,6 @@ import backtraceio.library.TestUtils; import backtraceio.library.common.BacktraceSerializeHelper; -import backtraceio.library.models.json.AnnotationException; import backtraceio.library.models.json.SourceCode; import backtraceio.library.models.json.ThreadInformation; @@ -26,13 +25,6 @@ public class BacktraceDataJsonTest { @Test public void serialize() { // GIVEN -// 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) -// - // GIVEN attributes final BacktraceData backtraceData = createTestBacktraceDataObject(); // WHEN @@ -46,23 +38,18 @@ public void serialize() { @NonNull private static BacktraceData createTestBacktraceDataObject() { - final Map attributes = new HashMap<>(); - attributes.put("application.session", "4b965773-539e-4dd3-be1b-f8ab017c2c9f"); + final Map attributes = ImmutableMap.of("application.session", "4b965773-539e-4dd3-be1b-f8ab017c2c9f"); // GIVEN annotations - final Map annotations = new HashMap() - {{ - put("Environment Variables", ImmutableMap.copyOf(new HashMap() {{ - put("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"); - }} - )); - put("Exception", new AnnotationException("Example test string")); - }}; - + 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 = new HashMap<>(); - sourceCode.put("8751bea6-d6f6-48f4-9f96-1355c3408a9a", new SourceCode(null, "VMStack.java")); - sourceCode.put("27948842-7c2b-4898-a74a-ba3ca4afe814", new SourceCode(17, "InvokeMethod.java")); + 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<>(); @@ -73,7 +60,7 @@ private static BacktraceData createTestBacktraceDataObject() { }})); // GIVEN BacktraceData - final BacktraceData backtraceData = new BacktraceData( + return new BacktraceData( "ecdf418b-3e22-4c7c-8011-c85dc2b4386f", null, 1720419610, @@ -87,7 +74,6 @@ private static BacktraceData createTestBacktraceDataObject() { sourceCode, threadInformationMap ); - return backtraceData; } @Test From 7174fbd3c611d39a748d9b13c7e16a11ff965ade Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 17 Jul 2024 21:42:53 +0200 Subject: [PATCH 072/100] Remove todo --- .../src/test/java/backtraceio/library/TestUtils.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backtrace-library/src/test/java/backtraceio/library/TestUtils.java b/backtrace-library/src/test/java/backtraceio/library/TestUtils.java index 6a0eb29d..5c31907e 100644 --- a/backtrace-library/src/test/java/backtraceio/library/TestUtils.java +++ b/backtrace-library/src/test/java/backtraceio/library/TestUtils.java @@ -55,8 +55,8 @@ public static boolean compareJson(String json1, String json2) { 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)); // TODO: improve print + + System.out.println(Maps.difference(json1Map, json2Map)); return false; } return true; From 72360ef89afde181cebecfc37b1b7dd7dce0ef90 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Tue, 20 Aug 2024 22:49:17 +0200 Subject: [PATCH 073/100] PR improvements --- .../main/java/backtraceio/library/models/BacktraceData.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) 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 fb4dc67f..3d2a991c 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java @@ -97,15 +97,14 @@ public class BacktraceData { /** * Current BacktraceReport */ - public transient BacktraceReport report; // Think if we need it + public transient BacktraceReport report; // TODO: verify if we need it /** * Application thread details */ @SerializedName("threads") Map threadInformationMap; - - public BacktraceData() { } + public BacktraceData(String uuid, String symbolication, long timestamp, String langVersion, String agentVersion, Map attributes, String mainThread, From 503db7845ad91583fba8541678ff619a365e097f Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 21 Aug 2024 19:01:02 +0200 Subject: [PATCH 074/100] Fix warnings --- .../library/models/json/BacktraceAttributes.java | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceAttributes.java b/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceAttributes.java index de9d247c..8a0a4506 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceAttributes.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceAttributes.java @@ -25,7 +25,7 @@ * Class instance to get a built-in attributes from current application */ public class BacktraceAttributes { - private static final transient String LOG_TAG = BacktraceAttributes.class.getSimpleName(); + private static final String LOG_TAG = BacktraceAttributes.class.getSimpleName(); /** * Get built-in primitive attributes @@ -42,15 +42,10 @@ public class BacktraceAttributes { */ private final Context context; - /** - * Are metrics enabled? - */ - private static boolean isMetricsEnabled = false; - /** * Metrics session ID */ - private static String sessionId = UUID.randomUUID().toString(); + private static final String sessionId = UUID.randomUUID().toString(); /** * Create instance of Backtrace Attribute @@ -136,7 +131,7 @@ private void setScreenInformation(Boolean includeDynamicAttributes) { this.attributes.put("screen.width", String.valueOf(metrics.widthPixels)); this.attributes.put("screen.height", String.valueOf(metrics.heightPixels)); this.attributes.put("screen.dpi", String.valueOf(metrics.densityDpi)); - if (includeDynamicAttributes == false) { + if (!includeDynamicAttributes) { return; } this.attributes.put("screen.orientation", getScreenOrientation().toString()); From f5a2e7424a5ed098759bfab670fe969fbf8f5acd Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 2 Oct 2024 21:23:00 +0200 Subject: [PATCH 075/100] Use getter for report --- .../database/BacktraceDatabaseProguardTest.java | 8 ++++---- .../library/database/BacktraceDatabaseRecordTest.java | 2 +- .../library/database/BacktraceDatabaseTest.java | 10 +++++----- 3 files changed, 10 insertions(+), 10 deletions(-) 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 e29d1116..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().report); + assertEquals(report, database.get().iterator().next().getBacktraceData().getReport()); assertNull(database.get().iterator().next().getBacktraceData().symbolication); - assertEquals(testMessage, database.get().iterator().next().getBacktraceData().report.message); + 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().report); + assertEquals(report, database.get().iterator().next().getBacktraceData().getReport()); assertEquals("proguard", database.get().iterator().next().getBacktraceData().symbolication); - assertEquals(testMessage, database.get().iterator().next().getBacktraceData().report.message); + 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 5c672395..6a38cf9a 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseRecordTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseRecordTest.java @@ -172,6 +172,6 @@ public void readFileAndDeserialize() { final BacktraceData dataFromFile = recordFromFile.getBacktraceData(); // THEN - assertEquals(data.getReport().message, dataFromFile.report.message); + 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 9fc84eb8..0136a23c 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseTest.java @@ -106,8 +106,8 @@ public void addSingleRecord() { database.add(report, null); // THEN - assertEquals(report, database.get().iterator().next().getBacktraceData().report); - assertEquals(testMessage, database.get().iterator().next().getBacktraceData().report.message); + assertEquals(report, database.get().iterator().next().getBacktraceData().getReport()); + assertEquals(testMessage, database.get().iterator().next().getBacktraceData().getReport().message); assertEquals(1, database.count()); } @@ -142,8 +142,8 @@ public void deleteSingleRecord() { final BacktraceDatabaseRecord recordFromDatabase = database.get().iterator().next(); assertEquals(record2, recordFromDatabase); - assertEquals(report2, recordFromDatabase.getBacktraceData().report); - assertEquals(report2.exception.getMessage(), recordFromDatabase.getBacktraceData().report.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().report.message); + assertEquals(report2.message, database.get().iterator().next().getBacktraceData().getReport().message); } @Test From bf20af14ef1daa39677a1b52080cba5cb8ec9292 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 2 Oct 2024 21:23:54 +0200 Subject: [PATCH 076/100] Bump guava version --- backtrace-library/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backtrace-library/build.gradle b/backtrace-library/build.gradle index dd06273e..e5e1ff1e 100644 --- a/backtrace-library/build.gradle +++ b/backtrace-library/build.gradle @@ -90,7 +90,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.2.1-jre" + testImplementation "com.google.guava:guava:33.3.1-jre" } apply from: 'publish.gradle' From 6af0b6a296695ec95b6af8490df6e657dc9ce016 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Mon, 7 Oct 2024 22:43:40 +0200 Subject: [PATCH 077/100] Add backward compatibility --- .../library/models/BacktraceStackFrame.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) 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 151c0dab..d68739a7 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceStackFrame.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceStackFrame.java @@ -41,7 +41,19 @@ public class BacktraceStackFrame { * Create new instance of BacktraceStackFrame */ @SuppressWarnings({"UnusedDeclaration"}) - public BacktraceStackFrame() { + public BacktraceStackFrame() {} + + + @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; } /** From 5cd32b217b3b6d61070ce156409b0d8c4cdf9420 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Mon, 7 Oct 2024 23:33:37 +0200 Subject: [PATCH 078/100] Add backward compatibility --- .../main/java/backtraceio/library/BacktraceDatabase.java | 2 -- .../library/models/database/BacktraceDatabaseRecord.java | 7 +++++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/backtrace-library/src/main/java/backtraceio/library/BacktraceDatabase.java b/backtrace-library/src/main/java/backtraceio/library/BacktraceDatabase.java index fb3a10b6..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(); 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 d53ac5d0..3d54ff6e 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 @@ -1,5 +1,7 @@ package backtraceio.library.models.database; +import android.content.Context; + import com.google.gson.annotations.SerializedName; import java.io.File; @@ -124,6 +126,11 @@ public long getSize() { return size; } + @Deprecated + // TODO: Add description + public BacktraceData getBacktraceData(Context context) { + return getBacktraceData(); + } /** * Get valid BacktraceData from current record * @return valid BacktraceData object From 6382adb29707712e1aef853d796d62cd7171feab Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 9 Oct 2024 21:02:58 +0200 Subject: [PATCH 079/100] Tmp --- .../models/database/BacktraceDatabaseRecord.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) 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 3d54ff6e..d6d768cf 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 @@ -70,6 +70,18 @@ public class BacktraceDatabaseRecord { * Stored record */ private transient BacktraceData record; + + public BacktraceDatabaseRecord() { + // TODO: to verify +// this.id = UUID.fromString(data.getUuid()); +// +// +// this._path = ""; +// this.recordPath = ; +// this.diagnosticDataPath = ; +// this(UUID.randomUUID(), "", String.format("%s-record.json", this.id), String.format("%s-attachment", this.id), 0) + + } public BacktraceDatabaseRecord(BacktraceData data, String path) { this.id = UUID.fromString(data.getUuid()); this.record = data; From 96ede960fc98c68623887d42ed73da9563ca36b2 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 9 Oct 2024 21:39:45 +0200 Subject: [PATCH 080/100] Add backward compatibility --- .../library/services/BacktraceDatabaseContext.java | 8 ++++++++ 1 file changed, 8 insertions(+) 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 55a35160..6875ab6a 100644 --- a/backtrace-library/src/main/java/backtraceio/library/services/BacktraceDatabaseContext.java +++ b/backtrace-library/src/main/java/backtraceio/library/services/BacktraceDatabaseContext.java @@ -1,5 +1,7 @@ package backtraceio.library.services; +import android.content.Context; + import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -49,6 +51,12 @@ public class BacktraceDatabaseContext implements DatabaseContext { */ private final RetryOrder retryOrder; + @Deprecated + // TODO: Add description Context not used + public BacktraceDatabaseContext(Context context, BacktraceDatabaseSettings settings) { + this(settings); + } + /** * Initialize new instance of Backtrace Database Context * From 2b91f661e829b92bcbb9ccb164aa567673f73d73 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 9 Oct 2024 21:50:48 +0200 Subject: [PATCH 081/100] Backward compatibility --- .../library/models/BacktraceData.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) 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 3d2a991c..43d109f0 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java @@ -105,6 +105,28 @@ public class BacktraceData { @SerializedName("threads") Map threadInformationMap; + @Deprecated + // TODO: Add description + public BacktraceData(Context context, BacktraceReport report, Map clientAttributes) { + BacktraceData obj = new Builder( + context, + report, + clientAttributes + ).build(); + + 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, From c93cfb32cff1072dbe6b26ac229aa39bf3d028cc Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Tue, 15 Oct 2024 19:34:08 +0200 Subject: [PATCH 082/100] Tmp change --- .../database/BacktraceDatabaseRecord.java | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) 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 d6d768cf..63885795 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 @@ -71,17 +71,18 @@ public class BacktraceDatabaseRecord { */ private transient BacktraceData record; - public BacktraceDatabaseRecord() { - // TODO: to verify -// this.id = UUID.fromString(data.getUuid()); +// public BacktraceDatabaseRecord() { +// // TODO: to verify +// this.path = ""; +//// this.id = UUID.fromString(data.getUuid()); +//// +//// +//// this._path = ""; +//// this.recordPath = ; +//// this.diagnosticDataPath = ; +//// this(UUID.randomUUID(), "", String.format("%s-record.json", this.id), String.format("%s-attachment", this.id), 0) // -// -// this._path = ""; -// this.recordPath = ; -// this.diagnosticDataPath = ; -// this(UUID.randomUUID(), "", String.format("%s-record.json", this.id), String.format("%s-attachment", this.id), 0) - - } +// } public BacktraceDatabaseRecord(BacktraceData data, String path) { this.id = UUID.fromString(data.getUuid()); this.record = data; From d1e9a402e2cf40aeb529a7405f4b9b0aa89214e3 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Tue, 15 Oct 2024 19:36:15 +0200 Subject: [PATCH 083/100] Remove unused code --- .../models/database/BacktraceDatabaseRecord.java | 12 ------------ 1 file changed, 12 deletions(-) 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 63885795..77aa6008 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 @@ -71,18 +71,6 @@ public class BacktraceDatabaseRecord { */ private transient BacktraceData record; -// public BacktraceDatabaseRecord() { -// // TODO: to verify -// this.path = ""; -//// this.id = UUID.fromString(data.getUuid()); -//// -//// -//// this._path = ""; -//// this.recordPath = ; -//// this.diagnosticDataPath = ; -//// this(UUID.randomUUID(), "", String.format("%s-record.json", this.id), String.format("%s-attachment", this.id), 0) -// -// } public BacktraceDatabaseRecord(BacktraceData data, String path) { this.id = UUID.fromString(data.getUuid()); this.record = data; From 4d9e1e61302adbbb1798540ea5ab943e32670d59 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Tue, 15 Oct 2024 20:11:39 +0200 Subject: [PATCH 084/100] Add doc --- .../java/backtraceio/library/models/BacktraceData.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) 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 43d109f0..d95f28bf 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java @@ -16,6 +16,7 @@ import backtraceio.library.models.json.SourceCodeData; import backtraceio.library.models.json.ThreadData; import backtraceio.library.models.json.ThreadInformation; +import backtraceio.library.services.BacktraceApi; /** * Serializable Backtrace API data object @@ -105,8 +106,13 @@ public class BacktraceData { @SerializedName("threads") Map threadInformationMap; + + /** + * Create new instance of BacktraceData + * @deprecated + * This method is no longer way of creating new BacktraceData instance and will be removed soon + */ @Deprecated - // TODO: Add description public BacktraceData(Context context, BacktraceReport report, Map clientAttributes) { BacktraceData obj = new Builder( context, From c51af927fd791516761c29a2b95b3d7abb753a59 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Mon, 21 Oct 2024 21:54:52 +0200 Subject: [PATCH 085/100] Resolve TODOs --- .../library/common/DeviceAttributesHelper.java | 1 - .../java/backtraceio/library/models/BacktraceData.java | 1 - .../library/models/database/BacktraceDatabaseRecord.java | 9 +++++++-- 3 files changed, 7 insertions(+), 4 deletions(-) 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/BacktraceData.java b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java index d95f28bf..7d8d0c63 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java @@ -16,7 +16,6 @@ import backtraceio.library.models.json.SourceCodeData; import backtraceio.library.models.json.ThreadData; import backtraceio.library.models.json.ThreadInformation; -import backtraceio.library.services.BacktraceApi; /** * Serializable Backtrace API data object 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 77aa6008..0ecb2a92 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 @@ -126,9 +126,14 @@ public String getReportPath() { public long getSize() { return size; } - + + /** + * Get BacktraceData object related to db record + * @deprecated Context param is not used, use getBacktraceData() method + * @param context Android context + * @return BacktraceData object related to db record + */ @Deprecated - // TODO: Add description public BacktraceData getBacktraceData(Context context) { return getBacktraceData(); } From eefc7a664cb851274bbce665d3792e323c15831e Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Mon, 21 Oct 2024 22:05:12 +0200 Subject: [PATCH 086/100] Update deprecated docs --- .../models/database/BacktraceDatabaseRecord.java | 12 ++++++++---- .../library/services/BacktraceDatabaseContext.java | 11 ++++++++++- 2 files changed, 18 insertions(+), 5 deletions(-) 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 0ecb2a92..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 @@ -126,12 +126,16 @@ public String getReportPath() { public long getSize() { return size; } - + /** * Get BacktraceData object related to db record - * @deprecated Context param is not used, use getBacktraceData() method - * @param context Android context - * @return 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) { 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 6875ab6a..d2d17675 100644 --- a/backtrace-library/src/main/java/backtraceio/library/services/BacktraceDatabaseContext.java +++ b/backtrace-library/src/main/java/backtraceio/library/services/BacktraceDatabaseContext.java @@ -51,8 +51,17 @@ 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 - // TODO: Add description Context not used public BacktraceDatabaseContext(Context context, BacktraceDatabaseSettings settings) { this(settings); } From f385467a9cb750b8b590ec3e5456759fa1efe959 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Tue, 22 Oct 2024 21:53:19 +0200 Subject: [PATCH 087/100] Fix enum issue with different status case --- .../library/models/BacktraceResult.java | 2 +- .../models/types/BacktraceResultStatus.java | 15 ++++++- .../library/models/BacktraceResultTest.java | 11 +++++ .../types/BacktraceResultStatusTest.java | 44 +++++++++++++++++++ .../backtraceio/backtraceio/MainActivity.java | 10 ++++- 5 files changed, 78 insertions(+), 4 deletions(-) create mode 100644 backtrace-library/src/test/java/backtraceio/library/models/types/BacktraceResultStatusTest.java 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 d61c7df5..8e8924df 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceResult.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceResult.java @@ -42,7 +42,7 @@ public BacktraceResult(BacktraceApiResult apiResult) { } public BacktraceResult(String rxId, String status) { - this(null, rxId, null, BacktraceResultStatus.valueOf(status)); + this(null, rxId, null, BacktraceResultStatus.enumOf(status)); } /** 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/test/java/backtraceio/library/models/BacktraceResultTest.java b/backtrace-library/src/test/java/backtraceio/library/models/BacktraceResultTest.java index 4c1efabc..aae1262f 100644 --- a/backtrace-library/src/test/java/backtraceio/library/models/BacktraceResultTest.java +++ b/backtrace-library/src/test/java/backtraceio/library/models/BacktraceResultTest.java @@ -24,6 +24,17 @@ public void createFromBacktraceApiResult() { 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 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..9d414849 --- /dev/null +++ b/backtrace-library/src/test/java/backtraceio/library/models/types/BacktraceResultStatusTest.java @@ -0,0 +1,44 @@ +package backtraceio.library.models.types; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import java.util.Arrays; +import java.util.Collection; + +@RunWith(Parameterized.class) +public class BacktraceResultStatusTest { + private String apiStatus; + private BacktraceResultStatus expectedApiStatusEnum; + + public BacktraceResultStatusTest(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)); + } + + @Test(expected = IllegalArgumentException.class) + public void testWrongStatusValue() { + BacktraceResultStatus.enumOf("unsupported-value"); + } +} diff --git a/example-app/src/main/java/backtraceio/backtraceio/MainActivity.java b/example-app/src/main/java/backtraceio/backtraceio/MainActivity.java index 993940f9..19534647 100644 --- a/example-app/src/main/java/backtraceio/backtraceio/MainActivity.java +++ b/example-app/src/main/java/backtraceio/backtraceio/MainActivity.java @@ -74,7 +74,8 @@ private void symlinkAndWriteFile() { } private BacktraceClient initializeBacktrace(final String submissionUrl) { - BacktraceCredentials credentials = new BacktraceCredentials(submissionUrl); + BacktraceCredentials credentials = new BacktraceCredentials("https://yolo.sp.backtrace.io:6098/", + "2dd86e8e779d1fc7e22e7b19a9489abeedec3b1426abe7e2209888e92362fba4"); Context context = getApplicationContext(); String dbPath = context.getFilesDir().getAbsolutePath(); @@ -149,7 +150,12 @@ public void handledException(View view) { throw new IndexOutOfBoundsException("Invalid index of selected element!"); } } catch (IndexOutOfBoundsException e) { - backtraceClient.send(new BacktraceReport(e), this.listener); + Map attr = new HashMap<>(); + attr.put("XYZ", "ATTR"); + String path = "/asdas.txt"; + List l = new ArrayList<>(); + l.add(path); + backtraceClient.send(new BacktraceReport(e, attr, l), this.listener); } } From f96cc52cc128c496b4c6e2fa488275dcb9065c39 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 23 Oct 2024 08:15:47 +0200 Subject: [PATCH 088/100] Add BacktraceResultStatus tests --- .../types/BacktraceResultStatusTest.java | 63 +++++++++++-------- 1 file changed, 36 insertions(+), 27 deletions(-) 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 index 9d414849..850523c2 100644 --- a/backtrace-library/src/test/java/backtraceio/library/models/types/BacktraceResultStatusTest.java +++ b/backtrace-library/src/test/java/backtraceio/library/models/types/BacktraceResultStatusTest.java @@ -3,42 +3,51 @@ 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(Parameterized.class) +@RunWith(Enclosed.class) public class BacktraceResultStatusTest { - private String apiStatus; - private BacktraceResultStatus expectedApiStatusEnum; + @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 BacktraceResultStatusTest(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"); + @Test(expected = IllegalArgumentException.class) + public void testWrongStatusValue() { + BacktraceResultStatus.enumOf("unsupported-value"); + } } } From e15ff054bf52a434dbb2088ac22d892d2b6c4511 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 23 Oct 2024 08:16:02 +0200 Subject: [PATCH 089/100] Mock logger in StackFrame tests --- .../library/models/BacktraceStackFrameTest.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/backtrace-library/src/test/java/backtraceio/library/models/BacktraceStackFrameTest.java b/backtrace-library/src/test/java/backtraceio/library/models/BacktraceStackFrameTest.java index 26c08d1f..da34e10e 100644 --- a/backtrace-library/src/test/java/backtraceio/library/models/BacktraceStackFrameTest.java +++ b/backtrace-library/src/test/java/backtraceio/library/models/BacktraceStackFrameTest.java @@ -3,12 +3,19 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; +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() { From 3a51ad1ef9ae5ba66910847153f6ffa0ed12c72f Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 23 Oct 2024 08:16:12 +0200 Subject: [PATCH 090/100] Fix BacktraceData tests --- .../backtraceio/library/models/BacktraceDataTest.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) 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 ed575891..8e4a2a8f 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/models/BacktraceDataTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/models/BacktraceDataTest.java @@ -46,7 +46,7 @@ public void createBacktraceDataTest() { assertEquals(backtraceData.getReport(), report); assertEquals(backtraceData.getAttributes().get("classifier"), "java.lang.IllegalAccessException"); assertEquals(backtraceData.getAgent(), "backtrace-android"); - assertEquals(backtraceData.getAgentVersion(), "3.8.0-6-6b6db45-backtrace-data-refactor"); + assertEquals(backtraceData.getAgentVersion(), backtraceio.library.BuildConfig.VERSION_NAME); assertEquals(backtraceData.getLang(), "java"); assertEquals(backtraceData.getLangVersion(), "0"); assertEquals(backtraceData.getSymbolication(), ""); @@ -57,9 +57,11 @@ public void createBacktraceDataTest() { assertEquals(backtraceData.getMainThread(), "instr: androidx.test.runner.androidjunitrunner"); assertEquals(backtraceData.getSourceCode().size(), 34); assertEquals(backtraceData.getThreadInformationMap().size(), 13); - assertEquals(backtraceData.getAttachmentPaths().size(), 2); - assertEquals(backtraceData.getAttributes().get("attr-2"), 1); - assertEquals(backtraceData.getAttributes().get("attr-2"), true); + assertEquals(backtraceData.getAttachmentPaths().size(), 3); + assertEquals(backtraceData.getAttributes().get("attr-1"), "1"); + assertEquals(backtraceData.getAttributes().get("attr-2"), "true"); assertEquals(backtraceData.getAttributes().get("attr-3"), "test"); } + + // TODO: Add test with BacktraceData constructor } From 2c2d3c277bcfd15e737db4f84a50ca6fcee31288 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 23 Oct 2024 17:35:28 +0200 Subject: [PATCH 091/100] Add BacktraceData constructor test --- .../library/models/BacktraceDataTest.java | 37 ++++++++++++++++++- 1 file changed, 35 insertions(+), 2 deletions(-) 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 8e4a2a8f..2a5ac57e 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/models/BacktraceDataTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/models/BacktraceDataTest.java @@ -56,12 +56,45 @@ public void createBacktraceDataTest() { assertEquals(backtraceData.getAnnotations().size(), 3); assertEquals(backtraceData.getMainThread(), "instr: androidx.test.runner.androidjunitrunner"); assertEquals(backtraceData.getSourceCode().size(), 34); - assertEquals(backtraceData.getThreadInformationMap().size(), 13); + assertEquals(backtraceData.getThreadInformationMap().size(), 15); assertEquals(backtraceData.getAttachmentPaths().size(), 3); assertEquals(backtraceData.getAttributes().get("attr-1"), "1"); assertEquals(backtraceData.getAttributes().get("attr-2"), "true"); assertEquals(backtraceData.getAttributes().get("attr-3"), "test"); } + @Test + public void testBacktraceDataConstructor() { + // GIVEN + List attachmentsPath = Arrays.asList("one", "two", "three"); + BacktraceReport report = new BacktraceReport(new IllegalAccessException("test-message"), attachmentsPath); - // TODO: Add test with BacktraceData constructor + 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(backtraceData.getClassifiers(), new String[]{"java.lang.IllegalAccessException"}); + assertEquals(backtraceData.getReport(), report); + assertEquals(backtraceData.getAttributes().get("classifier"), "java.lang.IllegalAccessException"); + assertEquals(backtraceData.getAgent(), "backtrace-android"); + assertEquals(backtraceData.getAgentVersion(), backtraceio.library.BuildConfig.VERSION_NAME); + assertEquals(backtraceData.getLang(), "java"); + assertEquals(backtraceData.getLangVersion(), "0"); + assertEquals(backtraceData.getSymbolication(), ""); + assertEquals(backtraceData.getTimestamp(), report.timestamp); + assertEquals(backtraceData.getUuid(), report.uuid.toString()); + assertEquals(backtraceData.getAttributes().size(), 43); + assertEquals(backtraceData.getAnnotations().size(), 3); + assertEquals(backtraceData.getMainThread(), "instr: androidx.test.runner.androidjunitrunner"); + assertEquals(backtraceData.getSourceCode().size(), 34); + assertEquals(backtraceData.getThreadInformationMap().size(), 13); + assertEquals(backtraceData.getAttachmentPaths().size(), 3); + assertEquals(backtraceData.getAttributes().get("attr-1"), "1"); + assertEquals(backtraceData.getAttributes().get("attr-2"), "true"); + assertEquals(backtraceData.getAttributes().get("attr-3"), "test"); + } } From 4b76c021e755e8e5fd04eb291346495997a4c301 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 23 Oct 2024 21:54:33 +0200 Subject: [PATCH 092/100] Improve formatting --- .../src/main/java/backtraceio/backtraceio/MainActivity.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/example-app/src/main/java/backtraceio/backtraceio/MainActivity.java b/example-app/src/main/java/backtraceio/backtraceio/MainActivity.java index 19534647..56157702 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(); @@ -74,8 +74,7 @@ private void symlinkAndWriteFile() { } private BacktraceClient initializeBacktrace(final String submissionUrl) { - BacktraceCredentials credentials = new BacktraceCredentials("https://yolo.sp.backtrace.io:6098/", - "2dd86e8e779d1fc7e22e7b19a9489abeedec3b1426abe7e2209888e92362fba4"); + BacktraceCredentials credentials = new BacktraceCredentials(submissionUrl); Context context = getApplicationContext(); String dbPath = context.getFilesDir().getAbsolutePath(); From 7a3eb9d36095341d67a817c4aa2d28f01d041c3e Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 23 Oct 2024 21:55:17 +0200 Subject: [PATCH 093/100] Revert test changes --- .../main/java/backtraceio/backtraceio/MainActivity.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/example-app/src/main/java/backtraceio/backtraceio/MainActivity.java b/example-app/src/main/java/backtraceio/backtraceio/MainActivity.java index 56157702..75fc7c02 100644 --- a/example-app/src/main/java/backtraceio/backtraceio/MainActivity.java +++ b/example-app/src/main/java/backtraceio/backtraceio/MainActivity.java @@ -149,12 +149,7 @@ public void handledException(View view) { throw new IndexOutOfBoundsException("Invalid index of selected element!"); } } catch (IndexOutOfBoundsException e) { - Map attr = new HashMap<>(); - attr.put("XYZ", "ATTR"); - String path = "/asdas.txt"; - List l = new ArrayList<>(); - l.add(path); - backtraceClient.send(new BacktraceReport(e, attr, l), this.listener); + backtraceClient.send(new BacktraceReport(e), this.listener); } } From ad7017ba1f68f2924e1778c7a18620465424b4f8 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 23 Oct 2024 22:24:07 +0200 Subject: [PATCH 094/100] Reverse test args --- .../library/models/BacktraceDataTest.java | 77 ++++++++++--------- 1 file changed, 39 insertions(+), 38 deletions(-) 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 2a5ac57e..4517b315 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/models/BacktraceDataTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/models/BacktraceDataTest.java @@ -2,6 +2,7 @@ import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import android.content.Context; @@ -42,25 +43,25 @@ public void createBacktraceDataTest() { BacktraceData backtraceData = new BacktraceData.Builder(context, report, clientAttributes).build(); // THEN - assertArrayEquals(backtraceData.getClassifiers(), new String[]{"java.lang.IllegalAccessException"}); - assertEquals(backtraceData.getReport(), report); - assertEquals(backtraceData.getAttributes().get("classifier"), "java.lang.IllegalAccessException"); - assertEquals(backtraceData.getAgent(), "backtrace-android"); - assertEquals(backtraceData.getAgentVersion(), backtraceio.library.BuildConfig.VERSION_NAME); - assertEquals(backtraceData.getLang(), "java"); - assertEquals(backtraceData.getLangVersion(), "0"); - assertEquals(backtraceData.getSymbolication(), ""); - assertEquals(backtraceData.getTimestamp(), report.timestamp); - assertEquals(backtraceData.getUuid(), report.uuid.toString()); - assertEquals(backtraceData.getAttributes().size(), 43); - assertEquals(backtraceData.getAnnotations().size(), 3); - assertEquals(backtraceData.getMainThread(), "instr: androidx.test.runner.androidjunitrunner"); - assertEquals(backtraceData.getSourceCode().size(), 34); - assertEquals(backtraceData.getThreadInformationMap().size(), 15); - assertEquals(backtraceData.getAttachmentPaths().size(), 3); - assertEquals(backtraceData.getAttributes().get("attr-1"), "1"); - assertEquals(backtraceData.getAttributes().get("attr-2"), "true"); - assertEquals(backtraceData.getAttributes().get("attr-3"), "test"); + 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() { @@ -77,24 +78,24 @@ public void testBacktraceDataConstructor() { BacktraceData backtraceData = new BacktraceData(context, report, clientAttributes); // THEN - assertArrayEquals(backtraceData.getClassifiers(), new String[]{"java.lang.IllegalAccessException"}); - assertEquals(backtraceData.getReport(), report); - assertEquals(backtraceData.getAttributes().get("classifier"), "java.lang.IllegalAccessException"); - assertEquals(backtraceData.getAgent(), "backtrace-android"); - assertEquals(backtraceData.getAgentVersion(), backtraceio.library.BuildConfig.VERSION_NAME); - assertEquals(backtraceData.getLang(), "java"); - assertEquals(backtraceData.getLangVersion(), "0"); - assertEquals(backtraceData.getSymbolication(), ""); - assertEquals(backtraceData.getTimestamp(), report.timestamp); - assertEquals(backtraceData.getUuid(), report.uuid.toString()); - assertEquals(backtraceData.getAttributes().size(), 43); - assertEquals(backtraceData.getAnnotations().size(), 3); - assertEquals(backtraceData.getMainThread(), "instr: androidx.test.runner.androidjunitrunner"); - assertEquals(backtraceData.getSourceCode().size(), 34); - assertEquals(backtraceData.getThreadInformationMap().size(), 13); - assertEquals(backtraceData.getAttachmentPaths().size(), 3); - assertEquals(backtraceData.getAttributes().get("attr-1"), "1"); - assertEquals(backtraceData.getAttributes().get("attr-2"), "true"); - assertEquals(backtraceData.getAttributes().get("attr-3"), "test"); + 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")); } } From 59df61274221d777a58b88d6efad312d8e8dcffb Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Thu, 24 Oct 2024 20:25:03 +0200 Subject: [PATCH 095/100] Revert removed method --- .../backtraceio/library/models/BacktraceData.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) 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 7d8d0c63..5b8ee603 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java @@ -161,6 +161,19 @@ public List getAttachmentPaths() { return report.attachmentPaths; } + /** + * Get paths to report attachments + * + * @deprecated + * Please use {@link #getAttachmentPaths()} instead. + * + * @return paths to attachments + */ + @Deprecated + public List getAttachments() { + return this.getAttachmentPaths(); + } + public Map getThreadInformationMap() { return threadInformationMap; } From 835dd1d98bd62bdc338db067d88b8f431cc1de73 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Thu, 24 Oct 2024 20:29:40 +0200 Subject: [PATCH 096/100] Throw exception instead of return null --- .../main/java/backtraceio/library/models/BacktraceData.java | 2 +- .../java/backtraceio/library/models/BacktraceStackFrame.java | 4 ++-- .../backtraceio/library/models/BacktraceStackFrameTest.java | 4 +--- 3 files changed, 4 insertions(+), 6 deletions(-) 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 5b8ee603..d38b797d 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java @@ -173,7 +173,7 @@ public List getAttachmentPaths() { public List getAttachments() { return this.getAttachmentPaths(); } - + public Map getThreadInformationMap() { return threadInformationMap; } 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 d68739a7..1fae489a 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceStackFrame.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceStackFrame.java @@ -63,8 +63,8 @@ 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 null; + BacktraceLogger.e(LOG_TAG, "Frame or method name is null"); + throw new IllegalArgumentException("Frame or method name is null"); } final String functionName = frame.getClassName() + "." + frame.getMethodName(); final String fileName = frame.getFileName(); diff --git a/backtrace-library/src/test/java/backtraceio/library/models/BacktraceStackFrameTest.java b/backtrace-library/src/test/java/backtraceio/library/models/BacktraceStackFrameTest.java index da34e10e..b68c5bd2 100644 --- a/backtrace-library/src/test/java/backtraceio/library/models/BacktraceStackFrameTest.java +++ b/backtrace-library/src/test/java/backtraceio/library/models/BacktraceStackFrameTest.java @@ -43,12 +43,10 @@ public void serializeFromStackTraceElement() { assertEquals(expectedJson, json); } - @Test + @Test(expected = IllegalArgumentException.class) public void createFromNullStackTraceElement() { // GIVEN BacktraceStackFrame obj = BacktraceStackFrame.fromStackTraceElement(null); - // THEN - assertNull(obj); } @Test From f254db4b55a7ab642253c4ada112180d3fb91690 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Thu, 24 Oct 2024 20:34:35 +0200 Subject: [PATCH 097/100] Add deprecated docs to BacktraceStackFrame constructors --- .../library/models/BacktraceStackFrame.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) 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 1fae489a..bed1f1d9 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceStackFrame.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceStackFrame.java @@ -39,11 +39,20 @@ public class BacktraceStackFrame { /** * Create new instance of BacktraceStackFrame + * + * @deprecated + * Use {@link #fromStackTraceElement(StackTraceElement frame)} instead. */ @SuppressWarnings({"UnusedDeclaration"}) + @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); From 52282bc9d8080c21aac3dd287d3a248f6c6fa211 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Thu, 24 Oct 2024 20:55:16 +0200 Subject: [PATCH 098/100] Fix minify json - use JSONObject to verify serialization --- backtrace-library/build.gradle | 1 + .../java/backtraceio/library/TestUtils.java | 10 ++++++---- .../models/BacktraceStackFrameTest.java | 19 ++++++++++--------- .../models/json/BacktraceReportTest.java | 5 +++-- .../models/json/SourceCodeDataTest.java | 7 ++++--- .../library/models/json/SourceCodeTest.java | 7 ++++--- .../models/json/ThreadInformationTest.java | 7 ++++--- 7 files changed, 32 insertions(+), 24 deletions(-) diff --git a/backtrace-library/build.gradle b/backtrace-library/build.gradle index e5e1ff1e..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' diff --git a/backtrace-library/src/test/java/backtraceio/library/TestUtils.java b/backtrace-library/src/test/java/backtraceio/library/TestUtils.java index 5c31907e..737d7e08 100644 --- a/backtrace-library/src/test/java/backtraceio/library/TestUtils.java +++ b/backtrace-library/src/test/java/backtraceio/library/TestUtils.java @@ -7,6 +7,9 @@ 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; @@ -36,10 +39,9 @@ public static String readFileAsString(Object obj, String fileName) { return null; } - public static String unifyJsonString(String json) { - return json.replace("\n", "") - .replace(" ", "") - .replace("\t", ""); + public static String minifyJsonString(String json) throws JSONException { + JSONObject jsonObject = new JSONObject(json); + return jsonObject.toString(); } public static boolean compareJson(String json1, String json2) { diff --git a/backtrace-library/src/test/java/backtraceio/library/models/BacktraceStackFrameTest.java b/backtrace-library/src/test/java/backtraceio/library/models/BacktraceStackFrameTest.java index b68c5bd2..6639cc14 100644 --- a/backtrace-library/src/test/java/backtraceio/library/models/BacktraceStackFrameTest.java +++ b/backtrace-library/src/test/java/backtraceio/library/models/BacktraceStackFrameTest.java @@ -3,6 +3,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; +import org.json.JSONException; import org.junit.Before; import org.junit.Test; @@ -18,26 +19,26 @@ public void setUp() { } private final String JSON_FILE = "backtraceStackFrame.json"; @Test - public void serialize() { + public void serialize() throws JSONException { // GIVEN BacktraceStackFrame obj = new BacktraceStackFrame("java.util.TimerThread.run", "TimerThread", 512, "85c0915f-3b99-4942-91c8-221e23846ded"); // WHEN - String json = BacktraceSerializeHelper.toJson(obj); + String json = TestUtils.minifyJsonString(BacktraceSerializeHelper.toJson(obj)); // THEN - String expectedJson = TestUtils.unifyJsonString(TestUtils.readFileAsString(this, JSON_FILE)); + String expectedJson = TestUtils.minifyJsonString(TestUtils.readFileAsString(this, JSON_FILE)); assertEquals(expectedJson, json); } @Test - public void serializeFromStackTraceElement() { + 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 = BacktraceSerializeHelper.toJson(obj); + String json = TestUtils.minifyJsonString(BacktraceSerializeHelper.toJson(obj)); // THEN - String expectedJson = TestUtils.unifyJsonString(TestUtils.readFileAsString(this, JSON_FILE)). + String expectedJson = TestUtils.minifyJsonString(TestUtils.readFileAsString(this, JSON_FILE)). replace(sourceCodeUuid, obj.sourceCode); assertEquals(expectedJson, json); @@ -46,13 +47,13 @@ public void serializeFromStackTraceElement() { @Test(expected = IllegalArgumentException.class) public void createFromNullStackTraceElement() { // GIVEN - BacktraceStackFrame obj = BacktraceStackFrame.fromStackTraceElement(null); + BacktraceStackFrame.fromStackTraceElement(null); } @Test - public void deserialize() { + public void deserialize() throws JSONException { // GIVEN - String json = TestUtils.unifyJsonString(TestUtils.readFileAsString(this, JSON_FILE)); + String json = TestUtils.minifyJsonString(TestUtils.readFileAsString(this, JSON_FILE)); // WHEN BacktraceStackFrame obj = BacktraceSerializeHelper.fromJson(json, BacktraceStackFrame.class); // THEN 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 index 9f2f1f3b..49d769f7 100644 --- a/backtrace-library/src/test/java/backtraceio/library/models/json/BacktraceReportTest.java +++ b/backtrace-library/src/test/java/backtraceio/library/models/json/BacktraceReportTest.java @@ -5,6 +5,7 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import org.json.JSONException; import org.junit.Test; import java.util.ArrayList; @@ -20,7 +21,7 @@ public class BacktraceReportTest { private final String JSON_FILE = "backtraceReport.json"; @Test - public void serialize() { + public void serialize() throws JSONException { // GIVEN final List diagnosticStack = new ArrayList<>(); @@ -40,7 +41,7 @@ public void serialize() { String json = BacktraceSerializeHelper.toJson(report); // THEN - String expectedJson = TestUtils.unifyJsonString( + String expectedJson = TestUtils.minifyJsonString( TestUtils.readFileAsString(this, JSON_FILE) ); 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 index c8567556..6c695a1d 100644 --- a/backtrace-library/src/test/java/backtraceio/library/models/json/SourceCodeDataTest.java +++ b/backtrace-library/src/test/java/backtraceio/library/models/json/SourceCodeDataTest.java @@ -3,6 +3,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; +import org.json.JSONException; import org.junit.Test; import java.util.ArrayList; @@ -15,7 +16,7 @@ public class SourceCodeDataTest { private final String JSON_FILE = "sourceCodeData.json"; @Test - public void serialize() { + public void serialize() throws JSONException { // GIVEN List frames = new ArrayList() {{ add(new BacktraceStackFrame(null, "VMStack.java", null, "8751bea6-d6f6-48f4-9f96-1355c3408a9a")); @@ -24,10 +25,10 @@ public void serialize() { SourceCodeData obj = new SourceCodeData(frames); // WHEN - String json = BacktraceSerializeHelper.toJson(obj); + String json = TestUtils.minifyJsonString(BacktraceSerializeHelper.toJson(obj)); // THEN - String expectedJson = TestUtils.unifyJsonString( + String expectedJson = TestUtils.minifyJsonString( TestUtils.readFileAsString(this, JSON_FILE) ); 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 index 91b9ad1c..30c3edab 100644 --- a/backtrace-library/src/test/java/backtraceio/library/models/json/SourceCodeTest.java +++ b/backtrace-library/src/test/java/backtraceio/library/models/json/SourceCodeTest.java @@ -2,6 +2,7 @@ import static org.junit.Assert.assertEquals; +import org.json.JSONException; import org.junit.Test; import backtraceio.library.TestUtils; @@ -11,15 +12,15 @@ public class SourceCodeTest { private final String JSON_FILE = "sourceCode.json"; @Test - public void serialize() { + public void serialize() throws JSONException { // GIVEN SourceCode obj = new SourceCode(17, "InvokeMethod.java"); // WHEN - String json = BacktraceSerializeHelper.toJson(obj); + String json = TestUtils.minifyJsonString(BacktraceSerializeHelper.toJson(obj)); // THEN - String expectedJson = TestUtils.unifyJsonString( + String expectedJson = TestUtils.minifyJsonString( TestUtils.readFileAsString(this, JSON_FILE) ); 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 index 1f1e12e0..a31a24cb 100644 --- a/backtrace-library/src/test/java/backtraceio/library/models/json/ThreadInformationTest.java +++ b/backtrace-library/src/test/java/backtraceio/library/models/json/ThreadInformationTest.java @@ -5,6 +5,7 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import org.json.JSONException; import org.junit.Test; import java.util.ArrayList; @@ -17,7 +18,7 @@ public class ThreadInformationTest { @Test - public void serialize() { + 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")); @@ -25,10 +26,10 @@ public void serialize() { ThreadInformation obj = new ThreadInformation("main", true, frames); // WHEN - String json = BacktraceSerializeHelper.toJson(obj); + String json = TestUtils.minifyJsonString(BacktraceSerializeHelper.toJson(obj)); // THEN - String expectedJson = TestUtils.unifyJsonString( + String expectedJson = TestUtils.minifyJsonString( TestUtils.readFileAsString(this, "threadInformation.json") ); From ca7cda6f12ab404291a4f9635cc27beb5f416767 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Fri, 25 Oct 2024 23:06:38 +0200 Subject: [PATCH 099/100] Refactor BacktraceData builder - move to separated methods --- .../BacktraceDatabaseContextTest.java | 10 ++--- .../BacktraceDatabaseFileContextTest.java | 34 ++++++++--------- .../database/BacktraceDatabaseRecordTest.java | 12 +++--- .../library/models/BacktraceDataTest.java | 2 +- .../library/base/BacktraceBase.java | 2 +- .../library/models/BacktraceData.java | 37 ++++++++++--------- .../library/models/json/BacktraceReport.java | 2 +- 7 files changed, 50 insertions(+), 49 deletions(-) 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 4a4352d0..67092948 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseContextTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseContextTest.java @@ -145,7 +145,7 @@ public void notContainsInDatabaseContext() { // GIVEN fillDatabase(); BacktraceReport report = new BacktraceReport(this.testMessage); - BacktraceData data = new BacktraceData.Builder(this.context, report, null).build(); + BacktraceData data = new BacktraceData.Builder(report).setAttributes(this.context, null).build(); BacktraceDatabaseRecord record = new BacktraceDatabaseRecord(data, this.dbPath); // WHEN @@ -234,7 +234,7 @@ public void tryDeleteNotExistingRecordFromDatabaseContext() { // GIVEN fillDatabase(); BacktraceReport report = new BacktraceReport(this.testMessage); - BacktraceData data = new BacktraceData.Builder(this.context, report, null).build(); + BacktraceData data = new BacktraceData.Builder(report).setAttributes(this.context, null).build(); BacktraceDatabaseRecord record = new BacktraceDatabaseRecord(data, this.dbPath); // WHEN @@ -259,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.Builder(this.context, report, null).build(); - BacktraceData data2 = new BacktraceData.Builder(this.context, report2, null).build(); - BacktraceData data3 = new BacktraceData.Builder(this.context, report3, null).build(); + 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 1ba68e65..3c3dc2ab 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseFileContextTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseFileContextTest.java @@ -57,7 +57,7 @@ public void after() { public void getFilesAfterAddOne() { // GIVEN BacktraceReport report = new BacktraceReport(testMessage); - this.databaseContext.add(new BacktraceData.Builder(this.context, report, null).build()); + 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.Builder(this.context, report, null).build()); - this.databaseContext.add(new BacktraceData.Builder(this.context, report2, null).build()); - this.databaseContext.add(new BacktraceData.Builder(this.context, report3, null).build()); + 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.Builder(this.context, report, null).build()); - this.databaseContext.add(new BacktraceData.Builder(this.context, report2, null).build()); - this.databaseContext.add(new BacktraceData.Builder(this.context, report3, null).build()); + 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.Builder(this.context, report, null).build()); - this.databaseContext.add(new BacktraceData.Builder(this.context, report2, null).build()); + 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.Builder(this.context, report, null).build()); - this.databaseContext.add(new BacktraceData.Builder(this.context, report2, null).build()); + 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(); @@ -149,8 +149,8 @@ public void forceInconsistencyMaxRecordCount() { BacktraceReport report = new BacktraceReport(testMessage); BacktraceReport report2 = new BacktraceReport(testMessage); - this.databaseContext.add(new BacktraceData.Builder(this.context, report, null).build()); - this.databaseContext.add(new BacktraceData.Builder(this.context, report2, null).build()); + 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.Builder(this.context, report, null).build()); - this.databaseContext.add(new BacktraceData.Builder(this.context, report2, null).build()); + 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.Builder(this.context, report, null).build()); - this.databaseContext.add(new BacktraceData.Builder(this.context, report2, null).build()); + 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/BacktraceDatabaseRecordTest.java b/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseRecordTest.java index 6a38cf9a..bb903dba 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseRecordTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/database/BacktraceDatabaseRecordTest.java @@ -51,7 +51,7 @@ public void after() { public void saveAndGetRecord() { // GIVEN final BacktraceReport report = new BacktraceReport(testMessage); - final BacktraceData data = new BacktraceData.Builder(this.context, report, null).build(); + final BacktraceData data = new BacktraceData.Builder(report).setAttributes(this.context, null).build(); final BacktraceDatabaseRecord record = new BacktraceDatabaseRecord(data, this.database.getSettings().getDatabasePath()); // WHEN @@ -85,7 +85,7 @@ public void saveAndGetRecordWithAttachments() { } final BacktraceReport report = new BacktraceReport(testMessage, attachments); - final BacktraceData data = new BacktraceData.Builder(this.context, report, null).build(); + final BacktraceData data = new BacktraceData.Builder(report).setAttributes(this.context, null).build(); final BacktraceDatabaseRecord record = new BacktraceDatabaseRecord(data, this.database.getSettings().getDatabasePath()); // WHEN @@ -107,7 +107,7 @@ public void saveAndGetRecordWithAttachments() { public void deleteFileDiagnosticPathToCorruptRecord() { // GIVEN BacktraceReport report = new BacktraceReport(testMessage); - BacktraceData data = new BacktraceData.Builder(this.context, report, null).build(); + BacktraceData data = new BacktraceData.Builder(report).setAttributes(this.context, null).build(); BacktraceDatabaseRecord record = new BacktraceDatabaseRecord(data, this.database.getSettings().getDatabasePath()); // WHEN @@ -125,7 +125,7 @@ public void deleteFileDiagnosticPathToCorruptRecord() { public void deleteFileReportPathToCorruptRecord() { // GIVEN BacktraceReport report = new BacktraceReport(testMessage); - BacktraceData data = new BacktraceData.Builder(this.context, report, null).build(); + BacktraceData data = new BacktraceData.Builder(report).setAttributes(this.context, null).build(); BacktraceDatabaseRecord record = new BacktraceDatabaseRecord(data, this.database.getSettings().getDatabasePath()); // WHEN @@ -143,7 +143,7 @@ public void deleteFileReportPathToCorruptRecord() { public void createAndDeleteRecordFiles() { // GIVEN BacktraceReport report = new BacktraceReport(testMessage); - BacktraceData data = new BacktraceData.Builder(this.context, report, null).build(); + BacktraceData data = new BacktraceData.Builder(report).setAttributes(this.context, null).build(); BacktraceDatabaseRecord record = new BacktraceDatabaseRecord(data, this.database.getSettings().getDatabasePath()); // WHEN @@ -163,7 +163,7 @@ public void createAndDeleteRecordFiles() { public void readFileAndDeserialize() { // GIVEN final BacktraceReport report = new BacktraceReport(testMessage); - final BacktraceData data = new BacktraceData.Builder(this.context, report, null).build(); + final BacktraceData data = new BacktraceData.Builder(report).setAttributes(this.context, null).build(); final BacktraceDatabaseRecord record = new BacktraceDatabaseRecord(data, this.database.getSettings().getDatabasePath()); record.save(); 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 4517b315..2c2ed334 100644 --- a/backtrace-library/src/androidTest/java/backtraceio/library/models/BacktraceDataTest.java +++ b/backtrace-library/src/androidTest/java/backtraceio/library/models/BacktraceDataTest.java @@ -40,7 +40,7 @@ public void createBacktraceDataTest() { clientAttributes.put("attr-2", true); clientAttributes.put("attr-3", "test"); // WHEN - BacktraceData backtraceData = new BacktraceData.Builder(context, report, clientAttributes).build(); + BacktraceData backtraceData = new BacktraceData.Builder(report).setAttributes(context, clientAttributes).build(); // THEN assertArrayEquals( new String[]{"java.lang.IllegalAccessException"} , backtraceData.getClassifiers()); 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 ff60e189..bc524ffc 100644 --- a/backtrace-library/src/main/java/backtraceio/library/base/BacktraceBase.java +++ b/backtrace-library/src/main/java/backtraceio/library/base/BacktraceBase.java @@ -584,7 +584,7 @@ public void send(BacktraceReport report, final OnServerResponseEventListener cal addReportAttachments(report); String symbolication = this.isProguardEnabled ? "proguard" : null; - BacktraceData backtraceData = new BacktraceData.Builder(context, report, symbolication, this.attributes).build(); + 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/models/BacktraceData.java b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java index d38b797d..bbdcc46d 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/BacktraceData.java @@ -113,11 +113,10 @@ public class BacktraceData { */ @Deprecated public BacktraceData(Context context, BacktraceReport report, Map clientAttributes) { - BacktraceData obj = new Builder( - context, - report, - clientAttributes - ).build(); + BacktraceData obj = new Builder(report) + .setAttributes(context, clientAttributes) + .setSymbolication("") + .build(); this.uuid = obj.uuid; this.symbolication = obj.symbolication; @@ -234,7 +233,7 @@ public BacktraceReport getReport() { public static class Builder { private final BacktraceReport report; - private final String symbolication; + private String symbolication = ""; private String uuid; @@ -252,18 +251,11 @@ public static class Builder { private Map attributes; private String mainThread; - public Builder(Context context, BacktraceReport report, Map - clientAttributes) { - this(context, report, "", clientAttributes); - } - public Builder(Context context, BacktraceReport report, String symbolication, Map - clientAttributes) { + public Builder(BacktraceReport report) { this.report = report; - this.symbolication = symbolication; this.setDefaultReportInformation(this.report); this.setDefaultThreadsInformation(); - this.setAttributes(context, clientAttributes); } public BacktraceData build() { @@ -283,21 +275,27 @@ public BacktraceData build() { ); } + public Builder setSymbolication(String symbolication) { + this.symbolication = symbolication; + return this; + } + /** * Set report information such as report identifier (UUID), timestamp, classifier */ - private void setDefaultReportInformation(BacktraceReport report) { + 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 void setDefaultThreadsInformation() { + private Builder setDefaultThreadsInformation() { BacktraceLogger.d(LOG_TAG, "Setting threads information"); ThreadData threadData = new ThreadData(report.diagnosticStack); @@ -306,9 +304,10 @@ private void setDefaultThreadsInformation() { this.mainThread = threadData.getMainThread(); this.threadInformationMap = threadData.threadInformation; this.sourceCode = sourceCodeData.data.isEmpty() ? null : sourceCodeData.data; + return this; } - private void setAttributes(Context context, Map clientAttributes) { + public Builder setAttributes(Context context, Map clientAttributes) { BacktraceLogger.d(LOG_TAG, "Setting attributes"); BacktraceAttributes backtraceAttributes = new BacktraceAttributes( context, @@ -317,9 +316,10 @@ private void setAttributes(Context context, Map clientAttributes this.attributes = backtraceAttributes.attributes; setAnnotations(backtraceAttributes.getComplexAttributes()); + return this; } - private void setAnnotations(Map complexAttributes) { + private Builder setAnnotations(Map complexAttributes) { BacktraceLogger.d(LOG_TAG, "Setting annotations"); Object exceptionMessage = null; @@ -328,6 +328,7 @@ private void setAnnotations(Map complexAttributes) { 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/json/BacktraceReport.java b/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceReport.java index 742c70d1..0a580bb7 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceReport.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceReport.java @@ -268,6 +268,6 @@ public BacktraceData toBacktraceData(Context context, Map client public BacktraceData toBacktraceData(Context context, Map clientAttributes, boolean isProguardEnabled) { final String symbolication = isProguardEnabled ? "proguard" : null; - return new BacktraceData.Builder(context, this, symbolication, clientAttributes).build(); + return new BacktraceData.Builder(this).setAttributes(context, clientAttributes).setSymbolication(symbolication).build(); } } \ No newline at end of file From ac491125b0b2e93f9d7c86dd4e55928f08a4a6e5 Mon Sep 17 00:00:00 2001 From: Bartosz Litwiniuk <> Date: Wed, 8 Jan 2025 17:21:16 +0100 Subject: [PATCH 100/100] Remove unused code --- .../library/models/json/BacktraceReport.java | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceReport.java b/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceReport.java index 056c23a4..fe996394 100644 --- a/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceReport.java +++ b/backtrace-library/src/main/java/backtraceio/library/models/json/BacktraceReport.java @@ -226,16 +226,6 @@ public Throwable getException() { return this.originalException != null ? this.originalException : this.exception; } -// public BacktraceData toBacktraceData(Context context, Map clientAttributes) { -// return toBacktraceData(context, clientAttributes, false); -// } -// -// public BacktraceData toBacktraceData(Context context, Map clientAttributes, boolean isProguardEnabled) { -// BacktraceData backtraceData = new BacktraceData(context, this, clientAttributes); -// backtraceData.symbolication = isProguardEnabled ? "proguard" : null; -// return backtraceData; -// } - private String getExceptionClassifier(Throwable exception) { return exception.getClass().getCanonicalName(); } @@ -256,13 +246,6 @@ private Exception prepareException(Throwable 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 */