From 4637517baae586edb8bc87d381f172fbec4e79b1 Mon Sep 17 00:00:00 2001 From: jason Date: Tue, 23 Apr 2024 11:37:15 +0100 Subject: [PATCH] test(ndk): end-to-end test with 500 breadcrumbs in a native crash --- .buildkite/pipeline.full.yml | 2 ++ .../test/cpp/migrations/EventOnDiskTests.cpp | 5 +++- .../src/test/cpp/test_breadcrumbs.c | 8 ++++++ .../src/test/cpp/test_utils_serialize.c | 9 ++++++ .../src/main/cpp/cxx-scenarios.cpp | 5 ++++ .../CXXMaxBreadcrumbCrashScenario.kt | 28 +++++++++++++++++++ .../full_tests/native_breadcrumbs.feature | 8 ++++++ 7 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 features/fixtures/mazerunner/cxx-scenarios/src/main/java/com/bugsnag/android/mazerunner/scenarios/CXXMaxBreadcrumbCrashScenario.kt diff --git a/.buildkite/pipeline.full.yml b/.buildkite/pipeline.full.yml index 668b6a9bdd..02fe640f07 100644 --- a/.buildkite/pipeline.full.yml +++ b/.buildkite/pipeline.full.yml @@ -11,6 +11,8 @@ steps: timeout_in_minutes: 5 agents: queue: macos-14 + env: + JAVA_VERSION: 17 command: 'make example-app' - label: ':android: Build debug fixture APK' diff --git a/bugsnag-plugin-android-ndk/src/test/cpp/migrations/EventOnDiskTests.cpp b/bugsnag-plugin-android-ndk/src/test/cpp/migrations/EventOnDiskTests.cpp index 8ba09f69c2..a6bba0d8a4 100644 --- a/bugsnag-plugin-android-ndk/src/test/cpp/migrations/EventOnDiskTests.cpp +++ b/bugsnag-plugin-android-ndk/src/test/cpp/migrations/EventOnDiskTests.cpp @@ -41,7 +41,9 @@ static void *create_full_event() { event->app.version_code = 8139512718; // breadcrumbs - auto max = 50; + event->max_crumb_count = 50; + event->breadcrumbs = new bugsnag_breadcrumb[event->max_crumb_count]; + auto max = event->max_crumb_count; event->crumb_first_index = 2; // test the circular buffer logic char name[30]; for (int i = event->crumb_first_index; i < max; i++) { @@ -185,6 +187,7 @@ Java_com_bugsnag_android_ndk_migrations_EventOnDiskTests_generateAndStoreEvent( free(parsed_event->feature_flags[i].name); free(parsed_event->feature_flags[i].variant); } + free(parsed_event->breadcrumbs); free(parsed_event->feature_flags); free(parsed_event); diff --git a/bugsnag-plugin-android-ndk/src/test/cpp/test_breadcrumbs.c b/bugsnag-plugin-android-ndk/src/test/cpp/test_breadcrumbs.c index 9c10aee9de..5f5a9588c8 100644 --- a/bugsnag-plugin-android-ndk/src/test/cpp/test_breadcrumbs.c +++ b/bugsnag-plugin-android-ndk/src/test/cpp/test_breadcrumbs.c @@ -20,6 +20,9 @@ bugsnag_breadcrumb *init_breadcrumb(const char *name, const char *message, bugsn TEST test_add_breadcrumb(void) { bugsnag_event *event = calloc(1, sizeof(bugsnag_event)); + event->max_crumb_count = 50; + event->breadcrumbs = + calloc(event->max_crumb_count, sizeof(bugsnag_breadcrumb)); bugsnag_breadcrumb *crumb = init_breadcrumb("stroll", "this is a drill.", BSG_CRUMB_USER); bsg_event_add_breadcrumb(event, crumb); ASSERT_EQ(1, event->crumb_count); @@ -39,6 +42,7 @@ TEST test_add_breadcrumb(void) { ASSERT(strcmp("message", event->breadcrumbs[1].metadata.values[0].name) == 0); ASSERT(strcmp("this is not a drill.", event->breadcrumbs[1].metadata.values[0].char_value) == 0); + free(event->breadcrumbs); free(event); free(crumb2); PASS(); @@ -46,6 +50,9 @@ TEST test_add_breadcrumb(void) { TEST test_add_breadcrumbs_over_max(void) { bugsnag_event *event = calloc(1, sizeof(bugsnag_event)); + event->max_crumb_count = 50; + event->breadcrumbs = + calloc(event->max_crumb_count, sizeof(bugsnag_breadcrumb)); int breadcrumb_count = 64; for (int i=0; i < breadcrumb_count; i++) { @@ -71,6 +78,7 @@ TEST test_add_breadcrumbs_over_max(void) { ASSERT_STR_EQ("crumb: 14", event->breadcrumbs[14].name); ASSERT_STR_EQ("crumb: 15", event->breadcrumbs[15].name); ASSERT_STR_EQ("crumb: 16", event->breadcrumbs[16].name); + free(event->breadcrumbs); free(event); PASS(); } 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 15953ecd34..cd1835580d 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 @@ -87,6 +87,9 @@ void generate_basic_report(bugsnag_event *event) { bugsnag_event *bsg_generate_event(void) { bugsnag_event *report = calloc(1, sizeof(bugsnag_event)); + report->max_crumb_count = 50; + report->breadcrumbs = + calloc(report->max_crumb_count, sizeof(bugsnag_breadcrumb)); strcpy(report->grouping_hash, "foo-hash"); strcpy(report->api_key, "5d1e5fbd39a74caa1200142706a90b20"); strcpy(report->context, "SomeActivity"); @@ -177,6 +180,7 @@ TEST test_report_to_file(void) { strcpy(env->report_header.os_build, "macOS Sierra"); strcpy(env->next_event_path, SERIALIZE_TEST_FILE); ASSERT(bsg_serialize_event_to_file(env)); + free(report->breadcrumbs); free(report); free(env); PASS(); @@ -193,6 +197,7 @@ TEST test_report_with_feature_flags_to_file(void) { strcpy(env->report_header.os_build, "macOS Sierra"); strcpy(env->next_event_path, SERIALIZE_TEST_FILE); ASSERT(bsg_serialize_event_to_file(env)); + free(report->breadcrumbs); free(report); free(env); PASS(); @@ -212,6 +217,7 @@ TEST test_file_to_report(void) { ASSERT(report != NULL); ASSERT(strcmp("SIGBUS", report->error.errorClass) == 0); ASSERT(strcmp("POSIX is serious about oncoming traffic", report->error.errorMessage) == 0); + free(generated_report->breadcrumbs); free(generated_report); free(env); free(report); @@ -234,6 +240,7 @@ TEST test_report_with_feature_flags_from_file(void) { ASSERT_EQ(2, event->feature_flag_count); + free(report->breadcrumbs); free(report); free(env); free(event); @@ -259,6 +266,7 @@ TEST test_report_with_opaque_metadata_from_file(void) { ASSERT_EQ(BSG_METADATA_OPAQUE_VALUE, bugsnag_event_has_metadata(event, "opaque", "map")); ASSERT_EQ(BSG_METADATA_OPAQUE_VALUE, bugsnag_event_has_metadata(event, "opaque", "list")); + free(report->breadcrumbs); free(report); free(env); free(event); @@ -271,6 +279,7 @@ JSON_Value *bsg_generate_json(void) { char *json = bsg_serialize_event_to_json_string(event); JSON_Value *root_value = json_parse_string(json); free(json); + free(event->breadcrumbs); free(event); return root_value; } diff --git a/features/fixtures/mazerunner/cxx-scenarios/src/main/cpp/cxx-scenarios.cpp b/features/fixtures/mazerunner/cxx-scenarios/src/main/cpp/cxx-scenarios.cpp index c6fe958d2e..e188aa0864 100644 --- a/features/fixtures/mazerunner/cxx-scenarios/src/main/cpp/cxx-scenarios.cpp +++ b/features/fixtures/mazerunner/cxx-scenarios/src/main/cpp/cxx-scenarios.cpp @@ -274,5 +274,10 @@ Java_com_bugsnag_android_mazerunner_scenarios_UnhandledNdkAutoNotifyFalseScenari abort(); } +JNIEXPORT void JNICALL +Java_com_bugsnag_android_mazerunner_scenarios_CXXMaxBreadcrumbCrashScenario_activate(JNIEnv *env, + jobject thiz) { + abort(); } +} \ No newline at end of file diff --git a/features/fixtures/mazerunner/cxx-scenarios/src/main/java/com/bugsnag/android/mazerunner/scenarios/CXXMaxBreadcrumbCrashScenario.kt b/features/fixtures/mazerunner/cxx-scenarios/src/main/java/com/bugsnag/android/mazerunner/scenarios/CXXMaxBreadcrumbCrashScenario.kt new file mode 100644 index 0000000000..9dffb9ea54 --- /dev/null +++ b/features/fixtures/mazerunner/cxx-scenarios/src/main/java/com/bugsnag/android/mazerunner/scenarios/CXXMaxBreadcrumbCrashScenario.kt @@ -0,0 +1,28 @@ +package com.bugsnag.android.mazerunner.scenarios + +import android.content.Context +import com.bugsnag.android.Bugsnag +import com.bugsnag.android.Configuration + +private const val MAX_BREADCRUMB_COUNT = 500 + +class CXXMaxBreadcrumbCrashScenario( + config: Configuration, + context: Context, + eventMetadata: String? +) : Scenario(config, context, eventMetadata) { + init { + config.maxBreadcrumbs = MAX_BREADCRUMB_COUNT + } + + external fun activate() + + override fun startScenario() { + super.startScenario() + repeat(config.maxBreadcrumbs) { index -> + Bugsnag.leaveBreadcrumb("this is breadcrumb $index") + } + + activate() + } +} diff --git a/features/full_tests/native_breadcrumbs.feature b/features/full_tests/native_breadcrumbs.feature index 14388f3a3d..3775e0cfe1 100644 --- a/features/full_tests/native_breadcrumbs.feature +++ b/features/full_tests/native_breadcrumbs.feature @@ -23,3 +23,11 @@ Feature: Native Breadcrumbs API And the event "severity" equals "warning" And the event has a "process" breadcrumb named "Rerun field analysis" And the event "unhandled" is false + + Scenario: Leaving the maximum number of native breadcrumbs + When I run "CXXMaxBreadcrumbCrashScenario" and relaunch the crashed app + And I configure Bugsnag for "CXXMaxBreadcrumbCrashScenario" + And I wait to receive an error + And the error payload contains a completed handled native report + And the event "unhandled" is true + And the event has 500 breadcrumbs \ No newline at end of file