diff --git a/.buildkite/pipeline.full.yml b/.buildkite/pipeline.full.yml index c485f00310..c55bf48db5 100644 --- a/.buildkite/pipeline.full.yml +++ b/.buildkite/pipeline.full.yml @@ -869,6 +869,108 @@ steps: concurrency_group: 'browserstack-app' concurrency_method: eager + + - label: ':bitbar: Android 15 NDK r21 end-to-end tests - batch 1' + depends_on: "fixture-r21" + timeout_in_minutes: 60 + plugins: + artifacts#v1.9.0: + download: + - "build/fixture-r21-url.txt" + - "build/fixture-r21/*" + upload: + - "maze_output/failed/**/*" + - "maze_output/metrics.csv" + docker-compose#v4.7.0: + pull: maze-runner + run: maze-runner + service-ports: true + command: + - "features/full_tests" + - "--exclude=features/full_tests/[^a-k].*.feature" + - "--exclude=features/full_tests/anr.feature" + - "--app=@build/fixture-r21-url.txt" + - "--appium-version=1.22" + - "--no-tunnel" + - "--aws-public-ip" + - "--farm=bb" + - "--device=ANDROID_15" + test-collector#v1.10.2: + files: "reports/TEST-*.xml" + format: "junit" + branch: "^main|next$$" + env: + TEST_FIXTURE_SYMBOL_DIR: "build/fixture-r21" + concurrency: 25 + concurrency_group: 'bitbar' + concurrency_method: eager + + - label: ':bitbar: Android 15 NDK r21 end-to-end tests - batch 2' + depends_on: "fixture-r21" + timeout_in_minutes: 60 + plugins: + artifacts#v1.9.0: + download: + - "build/fixture-r21-url.txt" + - "build/fixture-r21/*" + upload: + - "maze_output/failed/**/*" + - "maze_output/metrics.csv" + docker-compose#v4.7.0: + pull: maze-runner + run: maze-runner + service-ports: true + command: + - "features/full_tests" + - "--exclude=features/full_tests/[^l-z].*.feature" + - "--exclude=features/full_tests/anr.feature" + - "--app=@build/fixture-r21-url.txt" + - "--appium-version=1.22" + - "--no-tunnel" + - "--aws-public-ip" + - "--farm=bb" + - "--device=ANDROID_15" + test-collector#v1.10.2: + files: "reports/TEST-*.xml" + format: "junit" + branch: "^main|next$$" + env: + TEST_FIXTURE_SYMBOL_DIR: "build/fixture-r21" + concurrency: 25 + concurrency_group: 'bitbar' + concurrency_method: eager + + - label: ':browserstack: Android 15 NDK r21 end-to-end tests - ANRs' + depends_on: "fixture-r21" + timeout_in_minutes: 30 + plugins: + artifacts#v1.9.0: + download: + - "build/bs-fixture-r21-url.txt" + - "build/fixture-r21/*" + upload: + - "maze_output/failed/**/*" + - "maze_output/metrics.csv" + docker-compose#v4.7.0: + pull: maze-runner + run: maze-runner + service-ports: true + command: + - "features/full_tests/anr.feature" + - "--app=@build/bs-fixture-r21-url.txt" + - "--appium-version=1.22.0" + - "--farm=bs" + - "--device=ANDROID_15" + test-collector#v1.10.2: + files: "reports/TEST-*.xml" + format: "junit" + branch: "^main|next$$" + env: + TEST_FIXTURE_SYMBOL_DIR: "build/fixture-r21" + concurrency: 5 + concurrency_group: 'browserstack-app' + concurrency_method: eager + # If there is a tag present activate a manual publishing step - block: 'Trigger package publish' diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 0096c3a7fe..4fdaa39036 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -64,7 +64,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d #v3.28.10 + uses: github/codeql-action/init@45775bd8235c68ba998cffa5171334d58593da47 #v3.28.15 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -83,6 +83,6 @@ jobs: ./gradlew --no-daemon assemble - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d #v3.28.10 + uses: github/codeql-action/analyze@45775bd8235c68ba998cffa5171334d58593da47 #v3.28.15 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index e91e2559d9..087efe3dba 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -59,7 +59,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: "Upload artifact" - uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: SARIF file path: results.sarif @@ -68,7 +68,7 @@ jobs: # Upload the results to GitHub's code scanning dashboard (optional). # Commenting out will disable upload of results to your repo's Code Scanning dashboard - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d # v3.28.10 + uses: github/codeql-action/upload-sarif@45775bd8235c68ba998cffa5171334d58593da47 # v3.28.15 with: sarif_file: results.sarif @@ -77,4 +77,4 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: gradle/actions/wrapper-validation@94baf225fe0a508e581a564467443d0e2379123b # v4.3.0 + - uses: gradle/actions/wrapper-validation@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 61f24d4e69..6d2d34482e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 6.13.0 (2025-04-15) + +### Enhancements + +* Attempt a second `System.loadLibrary` for native modules in case of library loading race-conditions + [#2170](https://github.com/bugsnag/bugsnag-android/pull/2170) + ## 6.12.1 (2025-03-03) ### Bug fixes diff --git a/bugsnag-android-core/src/main/java/com/bugsnag/android/LibraryLoader.java b/bugsnag-android-core/src/main/java/com/bugsnag/android/LibraryLoader.java index 1a5e8caf77..7827875aa4 100644 --- a/bugsnag-android-core/src/main/java/com/bugsnag/android/LibraryLoader.java +++ b/bugsnag-android-core/src/main/java/com/bugsnag/android/LibraryLoader.java @@ -39,8 +39,14 @@ void loadLibInternal(String name, Client client, OnErrorCallback callback) { try { System.loadLibrary(name); loaded = true; - } catch (UnsatisfiedLinkError error) { - client.notify(error, callback); + } catch (UnsatisfiedLinkError ignored) { + // retry once in case the failure wasn't permanent + try { + System.loadLibrary(name); + loaded = true; + } catch (UnsatisfiedLinkError error) { + client.notify(error, callback); + } } } } diff --git a/bugsnag-android-core/src/main/java/com/bugsnag/android/Notifier.kt b/bugsnag-android-core/src/main/java/com/bugsnag/android/Notifier.kt index 0c04a77374..63998aecf3 100644 --- a/bugsnag-android-core/src/main/java/com/bugsnag/android/Notifier.kt +++ b/bugsnag-android-core/src/main/java/com/bugsnag/android/Notifier.kt @@ -7,7 +7,7 @@ import java.io.IOException */ class Notifier @JvmOverloads constructor( var name: String = "Android Bugsnag Notifier", - var version: String = "6.12.1", + var version: String = "6.13.0", var url: String = "https://bugsnag.com" ) : JsonStream.Streamable { diff --git a/bugsnag-plugin-android-ndk/package.json b/bugsnag-plugin-android-ndk/package.json index 7e7f5c5514..fcfa47e898 100644 --- a/bugsnag-plugin-android-ndk/package.json +++ b/bugsnag-plugin-android-ndk/package.json @@ -1,7 +1,4 @@ { - "dependencies": { - "kgabis/parson": "0.0.0" - }, "development": { "silentbicycle/greatest": "v1.2.1" } diff --git a/bugsnag-plugin-android-ndk/src/main/CMakeLists.txt b/bugsnag-plugin-android-ndk/src/main/CMakeLists.txt index 73d98025d4..7bcebcccf6 100644 --- a/bugsnag-plugin-android-ndk/src/main/CMakeLists.txt +++ b/bugsnag-plugin-android-ndk/src/main/CMakeLists.txt @@ -27,7 +27,6 @@ add_library( # Specifies the name of the library. jni/utils/string.c jni/utils/threads.c jni/utils/memory.c - jni/deps/parson/parson.c ) include_directories( diff --git a/bugsnag-plugin-android-ndk/src/main/jni/jni_cache.c b/bugsnag-plugin-android-ndk/src/main/jni/jni_cache.c index b5909e885d..15f86c7fcb 100644 --- a/bugsnag-plugin-android-ndk/src/main/jni/jni_cache.c +++ b/bugsnag-plugin-android-ndk/src/main/jni/jni_cache.c @@ -141,17 +141,9 @@ bool bsg_jni_cache_init(JNIEnv *env) { CACHE_CLASS(Long, "java/lang/Long"); CACHE_STATIC_METHOD(Long, Long_valueOf, "valueOf", "(J)Ljava/lang/Long;"); - CACHE_METHOD(Long, Long_constructor, "", "(J)V"); CACHE_CLASS(String, "java/lang/String"); - CACHE_CLASS(ArrayList, "java/util/ArrayList"); - CACHE_METHOD(ArrayList, ArrayList_constructor_default, "", "()V"); - CACHE_METHOD(ArrayList, ArrayList_constructor_collection, "", - "(Ljava/util/Collection;)V"); - CACHE_METHOD(ArrayList, ArrayList_get, "get", "(I)Ljava/lang/Object;"); - CACHE_METHOD(ArrayList, ArrayList_add, "add", "(Ljava/lang/Object;)Z"); - CACHE_CLASS(Set, "java/util/Set"); CACHE_METHOD(Set, Set_iterator, "iterator", "()Ljava/util/Iterator;"); @@ -160,7 +152,6 @@ bool bsg_jni_cache_init(JNIEnv *env) { CACHE_METHOD(Iterator, Iterator_next, "next", "()Ljava/lang/Object;"); CACHE_CLASS(Map, "java/util/Map"); - CACHE_METHOD(Map, Map_keySet, "keySet", "()Ljava/util/Set;"); CACHE_METHOD(Map, Map_size, "size", "()I"); CACHE_METHOD(Map, Map_get, "get", "(Ljava/lang/Object;)Ljava/lang/Object;"); CACHE_METHOD(Map, Map_put, "put", @@ -173,8 +164,6 @@ bool bsg_jni_cache_init(JNIEnv *env) { CACHE_CLASS(HashMap, "java/util/HashMap"); CACHE_METHOD(HashMap, HashMap_constructor, "", "()V"); - CACHE_METHOD(HashMap, HashMap_keySet, "keySet", "()Ljava/util/Set;"); - CACHE_METHOD(HashMap, HashMap_size, "size", "()I"); CACHE_METHOD(HashMap, HashMap_get, "get", "(Ljava/lang/Object;)Ljava/lang/Object;"); CACHE_METHOD(HashMap, HashMap_put, "put", @@ -196,10 +185,6 @@ bool bsg_jni_cache_init(JNIEnv *env) { CACHE_STATIC_METHOD(NativeInterface, NativeInterface_notify, "notify", "([B[BLcom/bugsnag/android/Severity;[Lcom/bugsnag/" "android/NativeStackframe;)V"); - CACHE_STATIC_METHOD(NativeInterface, NativeInterface_isDiscardErrorClass, - "isDiscardErrorClass", "(Ljava/lang/String;)Z"); - CACHE_STATIC_METHOD(NativeInterface, NativeInterface_deliverReport, - "deliverReport", "([B[B[BLjava/lang/String;Z)V"); CACHE_STATIC_METHOD(NativeInterface, NativeInterface_leaveBreadcrumb, "leaveBreadcrumb", "([BLcom/bugsnag/android/BreadcrumbType;)V"); diff --git a/bugsnag-plugin-android-ndk/src/main/jni/jni_cache.h b/bugsnag-plugin-android-ndk/src/main/jni/jni_cache.h index 44253a390c..574b424d08 100644 --- a/bugsnag-plugin-android-ndk/src/main/jni/jni_cache.h +++ b/bugsnag-plugin-android-ndk/src/main/jni/jni_cache.h @@ -26,7 +26,6 @@ typedef struct { jmethodID Int_intValue; jclass Long; - jmethodID Long_constructor; jmethodID Long_valueOf; jclass Float; @@ -48,7 +47,6 @@ typedef struct { jmethodID Map_get; jmethodID Map_put; jmethodID Map_size; - jmethodID Map_keySet; jmethodID Map_entrySet; jclass MapEntry; @@ -59,14 +57,6 @@ typedef struct { jmethodID HashMap_constructor; jmethodID HashMap_get; jmethodID HashMap_put; - jmethodID HashMap_size; - jmethodID HashMap_keySet; - - jclass ArrayList; - jmethodID ArrayList_constructor_default; - jmethodID ArrayList_constructor_collection; - jmethodID ArrayList_get; - jmethodID ArrayList_add; jclass NativeInterface; jmethodID NativeInterface_getApp; @@ -77,8 +67,6 @@ typedef struct { jmethodID NativeInterface_getContext; jmethodID NativeInterface_notify; jmethodID NativeInterface_leaveBreadcrumb; - jmethodID NativeInterface_isDiscardErrorClass; - jmethodID NativeInterface_deliverReport; jclass NativeStackframe; jmethodID NativeStackframe_constructor; diff --git a/bugsnag-plugin-android-ndk/src/test/CMakeLists.txt b/bugsnag-plugin-android-ndk/src/test/CMakeLists.txt index d16594b30e..1434d7c829 100644 --- a/bugsnag-plugin-android-ndk/src/test/CMakeLists.txt +++ b/bugsnag-plugin-android-ndk/src/test/CMakeLists.txt @@ -14,5 +14,6 @@ add_library(bugsnag-ndk-test SHARED cpp/test_featureflags.c cpp/test_bsg_event.c cpp/UnwindTest.cpp + cpp/parson/parson.h ) target_link_libraries(bugsnag-ndk-test bugsnag-ndk) diff --git a/bugsnag-plugin-android-ndk/src/test/cpp/main.c b/bugsnag-plugin-android-ndk/src/test/cpp/main.c index 95b6dc3004..9b08e7994c 100644 --- a/bugsnag-plugin-android-ndk/src/test/cpp/main.c +++ b/bugsnag-plugin-android-ndk/src/test/cpp/main.c @@ -6,8 +6,8 @@ #define GREATEST_FPRINTF(ignore, fmt, ...) \ __android_log_print(ANDROID_LOG_INFO, "BugsnagNDKTest", fmt, ##__VA_ARGS__) +#include "parson/parson.h" #include -#include #include "test_bsg_event.h" #include "test_serializer.h" diff --git a/bugsnag-plugin-android-ndk/src/main/jni/deps/parson/package.json b/bugsnag-plugin-android-ndk/src/test/cpp/parson/package.json similarity index 100% rename from bugsnag-plugin-android-ndk/src/main/jni/deps/parson/package.json rename to bugsnag-plugin-android-ndk/src/test/cpp/parson/package.json diff --git a/bugsnag-plugin-android-ndk/src/main/jni/deps/parson/parson.c b/bugsnag-plugin-android-ndk/src/test/cpp/parson/parson.c similarity index 100% rename from bugsnag-plugin-android-ndk/src/main/jni/deps/parson/parson.c rename to bugsnag-plugin-android-ndk/src/test/cpp/parson/parson.c diff --git a/bugsnag-plugin-android-ndk/src/main/jni/deps/parson/parson.h b/bugsnag-plugin-android-ndk/src/test/cpp/parson/parson.h similarity index 100% rename from bugsnag-plugin-android-ndk/src/main/jni/deps/parson/parson.h rename to bugsnag-plugin-android-ndk/src/test/cpp/parson/parson.h diff --git a/bugsnag-plugin-android-ndk/src/test/cpp/test_serializer.c b/bugsnag-plugin-android-ndk/src/test/cpp/test_serializer.c index 682b8b2e71..446f594b64 100644 --- a/bugsnag-plugin-android-ndk/src/test/cpp/test_serializer.c +++ b/bugsnag-plugin-android-ndk/src/test/cpp/test_serializer.c @@ -1,18 +1,6 @@ #include #include "test_serializer.h" -enum greatest_test_res validate_serialized_json(const test_case *test_case, - JSON_Value *event_val) { - // convert to string - char *serialized_string = json_serialize_to_string(event_val); - json_value_free(event_val); - - // validate structure - char *expected = test_case->expected_json; - ASSERT_STR_EQ(expected, serialized_string); - PASS(); -} - void loadUserTestCase(bugsnag_event *event) { bugsnag_user *user = &event->user; strcpy(user->name, "Fenton"); diff --git a/bugsnag-plugin-android-ndk/src/test/cpp/test_serializer.h b/bugsnag-plugin-android-ndk/src/test/cpp/test_serializer.h index 19a1da016f..b8e2816e13 100644 --- a/bugsnag-plugin-android-ndk/src/test/cpp/test_serializer.h +++ b/bugsnag-plugin-android-ndk/src/test/cpp/test_serializer.h @@ -3,7 +3,7 @@ #include -#include +#include "parson/parson.h" #include @@ -12,8 +12,6 @@ typedef struct { char *expected_json; } test_case; -enum greatest_test_res validate_serialized_json(const test_case *test_case, - JSON_Value *event_val); void loadUserTestCase(bugsnag_event *event); void loadAppTestCase(bugsnag_event *event); void loadAppMetadataTestCase(bugsnag_event *event); diff --git a/bugsnag-plugin-android-ndk/src/test/cpp/test_utils_serialize.c b/bugsnag-plugin-android-ndk/src/test/cpp/test_utils_serialize.c index 2565b47185..be39ebdcd6 100644 --- a/bugsnag-plugin-android-ndk/src/test/cpp/test_utils_serialize.c +++ b/bugsnag-plugin-android-ndk/src/test/cpp/test_utils_serialize.c @@ -2,8 +2,8 @@ #include #include +#include "parson/parson.h" #include -#include #include #include diff --git a/docker-compose.yml b/docker-compose.yml index 0c1c17f863..08903779c8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -17,6 +17,7 @@ x-common-environment: &common-environment BUILDKITE_STEP_KEY: MAZE_BUGSNAG_API_KEY: MAZE_NO_FAIL_FAST: + MAZE_APPIUM_BUGSNAG_API_KEY: MAZE_SCENARIO_BUGSNAG_API_KEY: TEST_FIXTURE_SYMBOL_DIR: diff --git a/examples/sdk-app-example/app/build.gradle b/examples/sdk-app-example/app/build.gradle index ae4b0fa60a..fae64cbfb1 100644 --- a/examples/sdk-app-example/app/build.gradle +++ b/examples/sdk-app-example/app/build.gradle @@ -42,8 +42,8 @@ android { } dependencies { - implementation "com.bugsnag:bugsnag-android:6.12.1" - implementation "com.bugsnag:bugsnag-plugin-android-okhttp:6.12.1" + implementation "com.bugsnag:bugsnag-android:6.13.0" + implementation "com.bugsnag:bugsnag-plugin-android-okhttp:6.13.0" implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation "androidx.appcompat:appcompat:1.6.1" implementation "com.google.android.material:material:1.11.0" diff --git a/features/fixtures/mazerunner/jvm-scenarios/src/main/java/com/bugsnag/android/mazerunner/scenarios/DiscardOldSessionScenario.kt b/features/fixtures/mazerunner/jvm-scenarios/src/main/java/com/bugsnag/android/mazerunner/scenarios/DiscardOldSessionScenario.kt index 9b56ac98c3..cc2f357517 100644 --- a/features/fixtures/mazerunner/jvm-scenarios/src/main/java/com/bugsnag/android/mazerunner/scenarios/DiscardOldSessionScenario.kt +++ b/features/fixtures/mazerunner/jvm-scenarios/src/main/java/com/bugsnag/android/mazerunner/scenarios/DiscardOldSessionScenario.kt @@ -33,7 +33,7 @@ internal class DiscardOldSessionScenario( fun waitForSessionFile() { val dir = sessionDir() - while (dir.listFiles()!!.isEmpty()) { + while (dir.listFiles().isNullOrEmpty()) { Thread.sleep(100) } } diff --git a/features/fixtures/minimalapp/Dangerfile b/features/fixtures/minimalapp/Dangerfile index 093e967ee9..607aaad578 100644 --- a/features/fixtures/minimalapp/Dangerfile +++ b/features/fixtures/minimalapp/Dangerfile @@ -35,29 +35,29 @@ end buildOutputs(bugsnag: false, minified: false) -apk_size = `stat -f "%z" #{RELEASE_APK}`.to_i -aab_size = `stat -f "%z" #{STANDALONE_DIR + STANDALONE_HDPI_BASE}`.to_i +apk_size = File.size(RELEASE_APK) +aab_size = File.size(STANDALONE_DIR + STANDALONE_HDPI_BASE) buildOutputs(bugsnag: false, minified: true) -min_apk_size = `stat -f "%z" #{RELEASE_APK}`.to_i -min_aab_size = `stat -f "%z" #{STANDALONE_DIR + STANDALONE_HDPI_BASE}`.to_i +min_apk_size = File.size(RELEASE_APK) +min_aab_size = File.size(STANDALONE_DIR + STANDALONE_HDPI_BASE) buildOutputs(bugsnag: true, minified: false) -apk_bugsnag_size = `stat -f "%z" #{RELEASE_APK}`.to_i -arm64_bugsnag_size = `stat -f "%z" #{STANDALONE_DIR + STANDALONE_ARM64_V8A}`.to_i -armeabi_v7a_bugsnag_size = `stat -f "%z" #{STANDALONE_DIR + STANDALONE_ARMEABI_V7A}`.to_i -x86_64_bugsnag_size = `stat -f "%z" #{STANDALONE_DIR + STANDALONE_X86_64}`.to_i -x86_bugsnag_size = `stat -f "%z" #{STANDALONE_DIR + STANDALONE_X86}`.to_i +apk_bugsnag_size = File.size(RELEASE_APK) +arm64_bugsnag_size = File.size(STANDALONE_DIR + STANDALONE_ARM64_V8A) +armeabi_v7a_bugsnag_size = File.size(STANDALONE_DIR + STANDALONE_ARMEABI_V7A) +x86_64_bugsnag_size = File.size(STANDALONE_DIR + STANDALONE_X86_64) +x86_bugsnag_size = File.size(STANDALONE_DIR + STANDALONE_X86) buildOutputs(bugsnag: true, minified: true) -min_apk_bugsnag_size = `stat -f "%z" #{RELEASE_APK}`.to_i -min_arm64_bugsnag_size = `stat -f "%z" #{STANDALONE_DIR + STANDALONE_ARM64_V8A}`.to_i -min_armeabi_v7a_bugsnag_size = `stat -f "%z" #{STANDALONE_DIR + STANDALONE_ARMEABI_V7A}`.to_i -min_x86_64_bugsnag_size = `stat -f "%z" #{STANDALONE_DIR + STANDALONE_X86_64}`.to_i -min_x86_bugsnag_size = `stat -f "%z" #{STANDALONE_DIR + STANDALONE_X86}`.to_i +min_apk_bugsnag_size = File.size(RELEASE_APK) +min_arm64_bugsnag_size = File.size(STANDALONE_DIR + STANDALONE_ARM64_V8A) +min_armeabi_v7a_bugsnag_size = File.size(STANDALONE_DIR + STANDALONE_ARMEABI_V7A) +min_x86_64_bugsnag_size = File.size(STANDALONE_DIR + STANDALONE_X86_64) +min_x86_bugsnag_size = File.size(STANDALONE_DIR + STANDALONE_X86) calculated_sizes = { :arm64 => arm64_bugsnag_size - aab_size, diff --git a/features/full_tests/native_session_tracking.feature b/features/full_tests/native_session_tracking.feature index fc93d3ec16..590e798328 100644 --- a/features/full_tests/native_session_tracking.feature +++ b/features/full_tests/native_session_tracking.feature @@ -24,13 +24,17 @@ Feature: NDK Session Tracking And the error payload field "events.0.session.events.unhandled" equals 1 Scenario: Starting a session, notifying, followed by a C crash - When I run "CXXSessionInfoCrashScenario" and relaunch the crashed app - And I configure Bugsnag for "CXXSessionInfoCrashScenario" + When I run "CXXSessionInfoCrashScenario" And I wait to receive a session - And I wait to receive 3 errors + And I wait to receive 2 errors + And I discard the oldest session And I discard the oldest error And I discard the oldest error - Then the error payload contains a completed handled native report - And the event contains session info + + And I relaunch the app after a crash + And I configure Bugsnag for "CXXSessionInfoCrashScenario" + # The fixture will now send the unhandled error plus the 2 handled errors + # again, because they are invoked after the delivery of the session. + And I wait to receive 3 errors And the error payload field "events.0.session.events.unhandled" equals 1 - And the error payload field "events.0.session.events.handled" equals 2 + And the error payload field "events.0.session.events.handled" equals 2 \ No newline at end of file diff --git a/features/full_tests/naughty_strings.feature b/features/full_tests/naughty_strings.feature index 843e1124aa..53383de041 100644 --- a/features/full_tests/naughty_strings.feature +++ b/features/full_tests/naughty_strings.feature @@ -26,8 +26,6 @@ Feature: The notifier handles user data containing unusual strings And the error payload field "events.0.metaData.custom.val_13" equals "๐“ฃ๐“ฑ๐“ฎ ๐“บ๐“พ๐“ฒ๐“ฌ๐“ด ๐“ซ๐“ป๐“ธ๐”€๐“ท ๐“ฏ๐“ธ๐” ๐“ณ๐“พ๐“ถ๐“น๐“ผ ๐“ธ๐“ฟ๐“ฎ๐“ป ๐“ฝ๐“ฑ๐“ฎ ๐“ต๐“ช๐”ƒ๐”‚ ๐“ญ๐“ธ๐“ฐ" And the error payload field "events.0.metaData.custom.val_14" equals "ฺฏฺ†ูพฺ˜" -# commented out some failing unicode assertions and skipped Android <6 until PLAT-5606 is addressed - @skip_below_android_6 Scenario: Test unhandled NDK error When I run "CXXNaughtyStringsScenario" and relaunch the crashed app And I configure Bugsnag for "CXXNaughtyStringsScenario" diff --git a/features/full_tests/startup_anr.feature b/features/full_tests/startup_anr.feature index b1ad2f5edc..48737b8a32 100644 --- a/features/full_tests/startup_anr.feature +++ b/features/full_tests/startup_anr.feature @@ -9,8 +9,7 @@ Feature: onCreate ANR @skip_android_10 # Android 13+ Note: we no longer have permission to inject BACK button events, which are used to # trigger the ANR - so the test is not valid on Android 13 either - @skip_android_13 - @skip_android_14 + @skip_above_android_13 Scenario: onCreate ANR is reported When I clear any error dialogue And I run "ConfigureStartupAnrScenario" diff --git a/features/steps/android_steps.rb b/features/steps/android_steps.rb index d07d355dd1..111fa4d0e6 100644 --- a/features/steps/android_steps.rb +++ b/features/steps/android_steps.rb @@ -71,37 +71,38 @@ def press_at(x, y) end When("I terminate the app") do - Maze.driver.terminate_app Maze.driver.app_id + Maze::Api::Appium::AppManager.new.terminate end When("I close and relaunch the app") do - Maze.driver.terminate_app Maze.driver.app_id - Maze.driver.activate_app Maze.driver.app_id + Maze::Api::Appium::AppManager.new.terminate + Maze::Api::Appium::AppManager.new.activate end When("I close and relaunch the app after an ANR") do begin - Maze.driver.terminate_app Maze.driver.app_id + Maze::Api::Appium::AppManager.new.terminate rescue Selenium::WebDriver::Error::ServerError # Swallow any error, as Android may already have terminated the app end - Maze.driver.activate_app Maze.driver.app_id + Maze::Api::Appium::AppManager.new.activate end When('I set the screen orientation to portrait') do - Maze.driver.set_rotation(:portrait) + Maze::Api::Appium::DeviceManager.new.set_rotation(:portrait) end # Waits for up to 10 seconds for the app to stop running. It seems that Appium doesn't always # get the state correct (e.g. when backgrounding the app, or on old Android versions), so we # don't fail if it still says running after the time allowed. def wait_for_app_state(expected_state) + manager = Maze::Api::Appium::AppManager.new max_attempts = 20 attempts = 0 - state = Maze.driver.app_state('com.bugsnag.android.mazerunner') + state = manager.state until (attempts >= max_attempts) || state == expected_state attempts += 1 - state = Maze.driver.app_state('com.bugsnag.android.mazerunner') + state = manager.state sleep 0.5 end $logger.warn "App state #{state} instead of #{expected_state} after 10s" unless state == expected_state @@ -113,17 +114,18 @@ def wait_for_app_state(expected_state) end When("I relaunch the app after a crash") do + manager = Maze::Api::Appium::AppManager.new state = wait_for_app_state :not_running if Maze.config.legacy_driver? if state != :not_running - Maze.driver.close_app + manager.close end - Maze.driver.launch_app + manager.launch else if state != :not_running - Maze.driver.terminate_app Maze.driver.app_id + manager.terminate end - Maze.driver.activate_app Maze.driver.app_id + manager.activate end end @@ -132,15 +134,16 @@ def wait_for_app_state(expected_state) begin press_at 500, 300 rescue Selenium::WebDriver::Error::ElementNotInteractableError, Selenium::WebDriver::Error::InvalidElementStateError - # Ignore itยง + # Ignore it end sleep(1) } end When("I tap the back-button {int} times") do |count| + manager = Maze::Api::Appium::DeviceManager.new (1..count).each { |i| - Maze.driver.back + manager.back sleep(0.5) } end diff --git a/features/support/env.rb b/features/support/env.rb index b1af3f19f4..f1324267fb 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -24,6 +24,10 @@ skip_this_scenario("Skipping scenario") end +Before('@skip_above_android_13') do |scenario| + skip_this_scenario("Skipping scenario") if Maze.config.os_version >= 13 +end + Before('@skip_above_android_11') do |scenario| skip_this_scenario("Skipping scenario") if Maze.config.os_version >= 11 end @@ -32,10 +36,6 @@ skip_this_scenario("Skipping scenario") if Maze.config.os_version >= 9 end -Before('@skip_above_android_7') do |scenario| - skip_this_scenario("Skipping scenario") if Maze.config.os_version >= 8 -end - Before('@skip_below_android_11') do |scenario| skip_this_scenario("Skipping scenario") if Maze.config.os_version < 11 end @@ -48,49 +48,6 @@ skip_this_scenario("Skipping scenario") if Maze.config.os_version < 9 end -Before('@skip_below_android_8') do |scenario| - skip_this_scenario("Skipping scenario") if Maze.config.os_version < 8 -end - -Before('@skip_below_android_6') do |scenario| - skip_this_scenario("Skipping scenario") if Maze.config.os_version < 6 -end - -Before('@skip_below_android_5') do |scenario| - skip_this_scenario("Skipping scenario") if Maze.config.os_version < 5 -end - -Before('@skip_android_14') do |scenario| - skip_this_scenario("Skipping scenario") if Maze.config.os_version.floor == 14 -end - -Before('@skip_android_13') do |scenario| - skip_this_scenario("Skipping scenario") if Maze.config.os_version.floor == 13 -end - Before('@skip_android_10') do |scenario| skip_this_scenario("Skipping scenario") if Maze.config.os_version.floor == 10 end - -Before('@skip_android_7') do |scenario| - skip_this_scenario("Skipping scenario") if Maze.config.os_version.floor == 7 -end - -Before('@skip_android_6') do |scenario| - skip_this_scenario("Skipping scenario") if Maze.config.os_version.floor == 6 -end - -Before('@skip_samsung') do |scenario| - caps = Maze.driver.capabilities - options_cap = 'bitbar:options' - device_cap = 'device' - - device = if caps.has_key?(options_cap) - caps[options_cap][device_cap] - else - caps[device_cap] - end - - skip_this_scenario("Skipping scenario") if device&.downcase&.include? 'samsung' -end - diff --git a/gradle.properties b/gradle.properties index 4c3adcb2d8..7ee59b9028 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,7 +11,7 @@ org.gradle.jvmargs=-Xmx4096m # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects org.gradle.parallel=true -VERSION_NAME=6.12.1 +VERSION_NAME=6.13.0 GROUP=com.bugsnag POM_SCM_URL=https://github.com/bugsnag/bugsnag-android POM_SCM_CONNECTION=scm:git@github.com:bugsnag/bugsnag-android.git diff --git a/scripts/audit-dependency-licenses.sh b/scripts/audit-dependency-licenses.sh index 1e34538ff7..ad101e6ed6 100755 --- a/scripts/audit-dependency-licenses.sh +++ b/scripts/audit-dependency-licenses.sh @@ -3,4 +3,4 @@ curl https://raw.githubusercontent.com/bugsnag/license-audit/master/config/decision_files/global.yml -o decisions.yml license_finder --enabled-package-managers=gradle --decisions-file=decisions.yml -license_finder --project-path=bugsnag-plugin-android-ndk/src/main/jni/deps/parson --enabled-package-managers=npm --decisions-file=decisions.yml +license_finder --project-path=bugsnag-plugin-android-ndk/src/test/cpp/parson --enabled-package-managers=npm --decisions-file=decisions.yml