Skip to content

Commit

Permalink
Merge pull request #1301 from bugsnag/next
Browse files Browse the repository at this point in the history
v5.9.5
  • Loading branch information
lemnik authored Jun 28, 2021
2 parents f9f5413 + 9b1f1d5 commit aef3558
Show file tree
Hide file tree
Showing 154 changed files with 2,233 additions and 968 deletions.
206 changes: 15 additions & 191 deletions .buildkite/pipeline.full.yml

Large diffs are not rendered by default.

39 changes: 8 additions & 31 deletions .buildkite/pipeline.quick.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ steps:
plugins:
artifacts#v1.2.0:
download: "build/release/fixture-r16.apk"
upload: "maze_output/failed/**/*"
docker-compose#v3.7.0:
pull: android-maze-runner
run: android-maze-runner
Expand All @@ -27,6 +28,7 @@ steps:
plugins:
artifacts#v1.2.0:
download: "build/release/fixture-r16.apk"
upload: "maze_output/failed/**/*"
docker-compose#v3.7.0:
pull: android-maze-runner
run: android-maze-runner
Expand All @@ -46,6 +48,7 @@ steps:
plugins:
artifacts#v1.2.0:
download: "build/release/fixture-r19.apk"
upload: "maze_output/failed/**/*"
docker-compose#v3.7.0:
pull: android-maze-runner
run: android-maze-runner
Expand All @@ -65,6 +68,7 @@ steps:
plugins:
artifacts#v1.2.0:
download: "build/release/fixture-r19.apk"
upload: "maze_output/failed/**/*"
docker-compose#v3.7.0:
pull: android-maze-runner
run: android-maze-runner
Expand All @@ -84,6 +88,7 @@ steps:
plugins:
artifacts#v1.2.0:
download: "build/release/fixture-r21.apk"
upload: "maze_output/failed/**/*"
docker-compose#v3.7.0:
pull: android-maze-runner
run: android-maze-runner
Expand All @@ -104,6 +109,7 @@ steps:
plugins:
artifacts#v1.2.0:
download: "build/release/fixture-r21.apk"
upload: "maze_output/failed/**/*"
docker-compose#v3.7.0:
pull: android-maze-runner
run: android-maze-runner
Expand All @@ -112,8 +118,6 @@ steps:
- "--app=/app/build/release/fixture-r21.apk"
- "--farm=bs"
- "--device=ANDROID_9_0"
- "--tags"
- "not @Flaky"
concurrency: 9
concurrency_group: 'browserstack-app'

Expand All @@ -125,6 +129,7 @@ steps:
plugins:
artifacts#v1.2.0:
download: "build/release/fixture-r21.apk"
upload: "maze_output/failed/**/*"
docker-compose#v3.7.0:
pull: android-maze-runner
run: android-maze-runner
Expand All @@ -133,35 +138,6 @@ steps:
- "--app=/app/build/release/fixture-r21.apk"
- "--farm=bs"
- "--device=ANDROID_9_0"
- "--tags"
- "not @Flaky"
concurrency: 9
concurrency_group: 'browserstack-app'

#
# Flaky scenarios. These should be skipped if there are no scenarios annotated with the @Flaky tag (as we should
# always be aiming for) to avoid unnecessary CI wait times and potential flakes from resource unavailability.
#
- label: ':hankey: Flaky Android 9 NDK r21 end-to-end tests'
skip: There are no @Flaky scenarios at present
depends_on:
- "fixture-r21"
timeout_in_minutes: 60
plugins:
artifacts#v1.2.0:
download: "build/release/fixture-r21.apk"
docker-compose#v3.7.0:
pull: android-maze-runner
run: android-maze-runner
command:
- "features/full_tests"
- "--retry=2"
- "--strict-undefined"
- "--strict-pending"
- "--app=/app/build/release/fixture-r21.apk"
- "--farm=bs"
- "--device=ANDROID_9_0"
- "--tags=@Flaky"
concurrency: 9
concurrency_group: 'browserstack-app'

Expand All @@ -172,6 +148,7 @@ steps:
plugins:
artifacts#v1.2.0:
download: "build/release/fixture-r21.apk"
upload: "maze_output/failed/**/*"
docker-compose#v3.7.0:
pull: android-maze-runner
run: android-maze-runner
Expand Down
18 changes: 18 additions & 0 deletions .buildkite/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,22 @@ steps:
run: android-ci
env:
INSTRUMENTATION_DEVICES: '["Google Pixel-7.1"]'
TEST_APK_LOCATION: 'bugsnag-android-core/build/outputs/apk/androidTest/debug/bugsnag-android-core-debug-androidTest.apk'
concurrency: 9
concurrency_group: 'browserstack-app'

- label: ':android: Performance benchmarks'
key: 'perf-benchmarks'
depends_on:
- "android-ci"
timeout_in_minutes: 30
command: ./scripts/build-instrumentation-tests.sh && ./scripts/run-instrumentation-test.sh
plugins:
- docker-compose#v3.7.0:
run: android-ci
env:
INSTRUMENTATION_DEVICES: '["Google Pixel-7.1"]'
TEST_APK_LOCATION: 'bugsnag-benchmarks/build/outputs/apk/androidTest/release/bugsnag-benchmarks-release-androidTest.apk'
concurrency: 9
concurrency_group: 'browserstack-app'

Expand All @@ -174,6 +190,7 @@ steps:
plugins:
artifacts#v1.2.0:
download: "build/release/fixture-r16.apk"
upload: "maze_output/failed/**/*"
docker-compose#v3.7.0:
pull: android-maze-runner
run: android-maze-runner
Expand All @@ -197,6 +214,7 @@ steps:
plugins:
artifacts#v1.2.0:
download: "build/release/fixture-r21.apk"
upload: "maze_output/failed/**/*"
docker-compose#v3.7.0:
pull: android-maze-runner
run: android-maze-runner
Expand Down
50 changes: 50 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,55 @@
# Changelog

## 5.9.5 (2021-06-25)

* Unity: Properly handle ANRs after multiple calls to autoNotify and autoDetectAnrs
[#1265](https://github.com/bugsnag/bugsnag-android/pull/1265)

* Cache value of app.backgroundWorkRestricted
[#1275](https://github.com/bugsnag/bugsnag-android/pull/1275)

* Optimize execution of callbacks
[#1276](https://github.com/bugsnag/bugsnag-android/pull/1276)

* Optimize implementation of internal state change observers
[#1274](https://github.com/bugsnag/bugsnag-android/pull/1274)

* Optimize metadata implementation by reducing type casts
[#1277](https://github.com/bugsnag/bugsnag-android/pull/1277)

* Trim stacktraces to <200 frames before attempting to construct POJOs
[#1281](https://github.com/bugsnag/bugsnag-android/pull/1281)

* Use direct field access when adding breadcrumbs and state updates
[#1279](https://github.com/bugsnag/bugsnag-android/pull/1279)

* Avoid using regex to validate api key
[#1282](https://github.com/bugsnag/bugsnag-android/pull/1282)

* Discard unwanted automatic data earlier where possible
[#1280](https://github.com/bugsnag/bugsnag-android/pull/1280)

* Enable ANR handling on immediately if started from the main thread
[#1283](https://github.com/bugsnag/bugsnag-android/pull/1283)

* Include `app.binaryArch` in all events
[#1287](https://github.com/bugsnag/bugsnag-android/pull/1287)

* Cache results from PackageManager
[#1288](https://github.com/bugsnag/bugsnag-android/pull/1288)

* Use ring buffer to store breadcrumbs
[#1286](https://github.com/bugsnag/bugsnag-android/pull/1286)

* Avoid expensive set construction in Config constructor
[#1289](https://github.com/bugsnag/bugsnag-android/pull/1289)

* Replace calls to String.format() with concatenation
[#1293](https://github.com/bugsnag/bugsnag-android/pull/1293)

* Optimize capture of thread traces
[#1300](https://github.com/bugsnag/bugsnag-android/pull/1300)

## 5.9.4 (2021-05-26)

* Unity: add methods for setting autoNotify and autoDetectAnrs
Expand Down
2 changes: 2 additions & 0 deletions bugsnag-android-core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,5 @@ dokka {
outputFormat = "html"
outputDirectory = "$buildDir/dokka"
}

apply from: "../gradle/kotlin.gradle"
16 changes: 12 additions & 4 deletions bugsnag-android-core/detekt-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<SmellBaseline>
<ManuallySuppressedIssues></ManuallySuppressedIssues>
<CurrentIssues>
<ID>ImplicitDefaultLocale:DeliveryHeaders.kt$String.format("%02x", byte)</ID>
<ID>LongParameterList:App.kt$App$( /** * The architecture of the running application binary */ var binaryArch: String?, /** * The package name of the application */ var id: String?, /** * The release stage set in [Configuration.releaseStage] */ var releaseStage: String?, /** * The version of the application set in [Configuration.version] */ var version: String?, /** The revision ID from the manifest (React Native apps only) */ var codeBundleId: String?, /** * The unique identifier for the build of the application set in [Configuration.buildUuid] */ var buildUuid: String?, /** * The application type set in [Configuration#version] */ var type: String?, /** * The version code of the application set in [Configuration.versionCode] */ var versionCode: Number? )</ID>
<ID>LongParameterList:AppDataCollector.kt$AppDataCollector$( appContext: Context, private val packageManager: PackageManager?, private val config: ImmutableConfig, private val sessionTracker: SessionTracker, private val activityManager: ActivityManager?, private val launchCrashTracker: LaunchCrashTracker, private val logger: Logger )</ID>
<ID>LongParameterList:AppWithState.kt$AppWithState$( binaryArch: String?, id: String?, releaseStage: String?, version: String?, codeBundleId: String?, buildUuid: String?, type: String?, versionCode: Number?, /** * The number of milliseconds the application was running before the event occurred */ var duration: Number?, /** * The number of milliseconds the application was running in the foreground before the * event occurred */ var durationInForeground: Number?, /** * Whether the application was in the foreground when the event occurred */ var inForeground: Boolean?, /** * Whether the application was launching when the event occurred */ var isLaunching: Boolean? )</ID>
Expand All @@ -11,20 +12,27 @@
<ID>LongParameterList:DeviceDataCollector.kt$DeviceDataCollector$( private val connectivity: Connectivity, private val appContext: Context, private val resources: Resources?, private val deviceId: String?, private val buildInfo: DeviceBuildInfo, private val dataDirectory: File, rootDetector: RootDetector, bgTaskService: BackgroundTaskService, private val logger: Logger )</ID>
<ID>LongParameterList:DeviceWithState.kt$DeviceWithState$( buildInfo: DeviceBuildInfo, jailbroken: Boolean?, id: String?, locale: String?, totalMemory: Long?, runtimeVersions: MutableMap&lt;String, Any&gt;, /** * The number of free bytes of storage available on the device */ var freeDisk: Long?, /** * The number of free bytes of memory available on the device */ var freeMemory: Long?, /** * The orientation of the device when the event occurred: either portrait or landscape */ var orientation: String?, /** * The timestamp on the device when the event occurred */ var time: Date? )</ID>
<ID>LongParameterList:EventFilenameInfo.kt$EventFilenameInfo.Companion$( obj: Any, uuid: String = UUID.randomUUID().toString(), apiKey: String?, timestamp: Long = System.currentTimeMillis(), config: ImmutableConfig, isLaunching: Boolean? = null )</ID>
<ID>LongParameterList:StateEvent.kt$StateEvent.Install$( val apiKey: String, val autoDetectNdkCrashes: Boolean, val appVersion: String?, val buildUuid: String?, val releaseStage: String?, val lastRunInfoPath: String, val consecutiveLaunchCrashes: Int )</ID>
<ID>LongParameterList:ThreadState.kt$ThreadState$( exc: Throwable?, isUnhandled: Boolean, sendThreads: ThreadSendPolicy, projectPackages: Collection&lt;String&gt;, logger: Logger, currentThread: java.lang.Thread = java.lang.Thread.currentThread(), stackTraces: MutableMap&lt;java.lang.Thread, Array&lt;StackTraceElement&gt;&gt; = java.lang.Thread.getAllStackTraces() )</ID>
<ID>LongParameterList:StateEvent.kt$StateEvent.Install$( @JvmField val apiKey: String, @JvmField val autoDetectNdkCrashes: Boolean, @JvmField val appVersion: String?, @JvmField val buildUuid: String?, @JvmField val releaseStage: String?, @JvmField val lastRunInfoPath: String, @JvmField val consecutiveLaunchCrashes: Int )</ID>
<ID>LongParameterList:ThreadState.kt$ThreadState$( stackTraces: MutableMap&lt;java.lang.Thread, Array&lt;StackTraceElement&gt;&gt;, currentThread: java.lang.Thread, exc: Throwable?, isUnhandled: Boolean, projectPackages: Collection&lt;String&gt;, logger: Logger )</ID>
<ID>MagicNumber:DefaultDelivery.kt$DefaultDelivery$299</ID>
<ID>MagicNumber:DefaultDelivery.kt$DefaultDelivery$429</ID>
<ID>MagicNumber:DefaultDelivery.kt$DefaultDelivery$499</ID>
<ID>MagicNumber:LastRunInfoStore.kt$LastRunInfoStore$3</ID>
<ID>MaxLineLength:LastRunInfo.kt$LastRunInfo$return "LastRunInfo(consecutiveLaunchCrashes=$consecutiveLaunchCrashes, crashed=$crashed, crashedDuringLaunch=$crashedDuringLaunch)"</ID>
<ID>ProtectedMemberInFinalClass:ConfigInternal.kt$ConfigInternal$protected val plugins = mutableSetOf&lt;Plugin&gt;()</ID>
<ID>ProtectedMemberInFinalClass:ConfigInternal.kt$ConfigInternal$protected val plugins = HashSet&lt;Plugin&gt;()</ID>
<ID>ProtectedMemberInFinalClass:EventInternal.kt$EventInternal$protected fun isAnr(event: Event): Boolean</ID>
<ID>ProtectedMemberInFinalClass:EventInternal.kt$EventInternal$protected fun shouldDiscardClass(): Boolean</ID>
<ID>ProtectedMemberInFinalClass:EventInternal.kt$EventInternal$protected fun updateSeverityInternal(severity: Severity)</ID>
<ID>ProtectedMemberInFinalClass:PluginClient.kt$PluginClient$protected val plugins: Set&lt;Plugin&gt;</ID>
<ID>ReturnCount:DefaultDelivery.kt$DefaultDelivery$fun deliver( urlString: String, streamable: JsonStream.Streamable, headers: Map&lt;String, String?&gt; ): DeliveryStatus</ID>
<ID>SwallowedException:AppDataCollector.kt$AppDataCollector$catch (exception: Exception) { logger.w("Could not check lowMemory status") }</ID>
<ID>SwallowedException:ContextExtensions.kt$catch (exc: RuntimeException) { null }</ID>
<ID>SwallowedException:DeviceDataCollector.kt$DeviceDataCollector$catch (exc: Exception) { false }</ID>
<ID>SwallowedException:DeviceDataCollector.kt$DeviceDataCollector$catch (exception: Exception) { logger.w("Could not get battery status") }</ID>
<ID>SwallowedException:DeviceDataCollector.kt$DeviceDataCollector$catch (exception: Exception) { logger.w("Could not get locationStatus") }</ID>
<ID>SwallowedException:DeviceIdStore.kt$DeviceIdStore$catch (exc: OverlappingFileLockException) { Thread.sleep(FILE_LOCK_WAIT_MS) }</ID>
<ID>SwallowedException:PluginClient.kt$PluginClient$catch (exc: ClassNotFoundException) { logger.d("Plugin '$clz' is not on the classpath - functionality will not be enabled.") null }</ID>
<ID>UnusedPrivateMember:ThreadStateTest.kt$ThreadStateTest$private val configuration = generateImmutableConfig()</ID>
<ID>VarCouldBeVal:SystemBroadcastReceiverTest.kt$SystemBroadcastReceiverTest$var config = BugsnagTestUtils.generateConfiguration()</ID>
<ID>VariableNaming:EventInternal.kt$EventInternal$/** * @return user information associated with this Event */ internal var _user = User(null, null, null)</ID>
</CurrentIssues>
</SmellBaseline>
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ class BreadcrumbFilterTest {
client = generateClient(configuration)

client.leaveBreadcrumb("Hello World")

assertEquals(1, client.breadcrumbState.store.size)
assertEquals(1, client.breadcrumbState.copy().size)
}

@Test
Expand All @@ -36,6 +35,6 @@ class BreadcrumbFilterTest {

client.leaveBreadcrumb("Hello World")

assertEquals(1, client.breadcrumbState.store.size)
assertEquals(1, client.breadcrumbState.copy().size)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class BreadcrumbStateTest {
fun testClientMethods() {
client = generateClient()
client!!.leaveBreadcrumb("Hello World")
val store = client!!.breadcrumbState.store
val store = client!!.breadcrumbState.copy()
var count = 0

for (breadcrumb in store) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package com.bugsnag.android;

import com.bugsnag.android.internal.ImmutableConfig;
import com.bugsnag.android.internal.ImmutableConfigKt;

import androidx.annotation.NonNull;
import androidx.test.core.app.ApplicationProvider;

Expand Down Expand Up @@ -87,7 +90,7 @@ static ImmutableConfig convert(Configuration config) {
} catch (IOException ignored) {
// swallow
}
return ImmutableConfigKt.convertToImmutableConfig(config, null);
return ImmutableConfigKt.convertToImmutableConfig(config, null, null, null);
}

static Device generateDevice() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,14 @@ public void testMaxBreadcrumbs() {
config.setEnabledBreadcrumbTypes(new HashSet<>(breadcrumbTypes));
config.setMaxBreadcrumbs(2);
client = generateClient(config);
assertEquals(0, client.breadcrumbState.getStore().size());
assertEquals(0, client.breadcrumbState.copy().size());

client.leaveBreadcrumb("test");
client.leaveBreadcrumb("another");
client.leaveBreadcrumb("yet another");
assertEquals(2, client.breadcrumbState.getStore().size());
assertEquals(2, client.breadcrumbState.copy().size());

Breadcrumb poll = client.breadcrumbState.getStore().poll();
Breadcrumb poll = client.breadcrumbState.copy().get(0);
assertEquals(BreadcrumbType.MANUAL, poll.getType());
assertEquals("another", poll.getMessage());
}
Expand Down Expand Up @@ -126,10 +126,12 @@ public void testClientUser() {

@Test
public void testClientBreadcrumbRetrieval() {
client = generateClient();
Configuration config = new Configuration("api-key");
config.setEnabledBreadcrumbTypes(Collections.<BreadcrumbType>emptySet());
client = generateClient(config);
client.leaveBreadcrumb("Hello World");
List<Breadcrumb> breadcrumbs = client.getBreadcrumbs();
List<Breadcrumb> store = new ArrayList<>(client.breadcrumbState.getStore());
List<Breadcrumb> store = new ArrayList<>(client.breadcrumbState.copy());
assertEquals(store, breadcrumbs);
assertNotSame(store, breadcrumbs);
}
Expand All @@ -153,8 +155,8 @@ public void testBreadcrumbStoreNotModified() {

breadcrumbs.clear(); // only the copy should be cleared
assertTrue(breadcrumbs.isEmpty());
assertEquals(1, client.breadcrumbState.getStore().size());
assertEquals("Manual breadcrumb", client.breadcrumbState.getStore().remove().getMessage());
assertEquals(1, client.breadcrumbState.copy().size());
assertEquals("Manual breadcrumb", client.breadcrumbState.copy().get(0).getMessage());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import static com.bugsnag.android.BugsnagTestUtils.streamableToJson;
import static org.junit.Assert.assertEquals;

import com.bugsnag.android.internal.ImmutableConfig;

import androidx.test.filters.SmallTest;

import org.json.JSONArray;
Expand All @@ -22,7 +24,6 @@ public class EventPayloadTest {

/**
* Generates a eventPayload
*
*/
@Before
public void setUp() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.bugsnag.android
import android.content.Context
import androidx.test.core.app.ApplicationProvider
import com.bugsnag.android.BugsnagTestUtils.generateConfiguration
import com.bugsnag.android.internal.convertToImmutableConfig
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNull
Expand All @@ -21,7 +22,9 @@ internal class LastRunInfoStoreTest {
val config = convertToImmutableConfig(
generateConfiguration().apply {
persistenceDirectory = ApplicationProvider.getApplicationContext<Context>().cacheDir
}
},
packageInfo = null,
appInfo = null
)
file = File(config.persistenceDirectory, "last-run-info")
file.delete()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public void onLowMemoryEvent() {
verify(context, times(1)).registerComponentCallbacks(componentCallbacksCaptor.capture());

BugsnagTestObserver observer = new BugsnagTestObserver();
client.registerObserver(observer);
client.addObserver(observer);

ComponentCallbacks callbacks = componentCallbacksCaptor.getValue();
callbacks.onLowMemory();
Expand All @@ -55,7 +55,7 @@ public void onLowMemoryEvent() {

assertTrue(
"observed event should be marked isLowMemory",
((StateEvent.UpdateMemoryTrimEvent) observedEvent).isLowMemory()
((StateEvent.UpdateMemoryTrimEvent) observedEvent).isLowMemory
);
}

Expand Down
Loading

0 comments on commit aef3558

Please sign in to comment.