Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modularise bugsnag-android into JVM, NDK, and ANR artefacts #522

Merged
merged 23 commits into from
Jul 18, 2019
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
4439a57
rename sdk module to bugsnag-android-core
fractalwrench Jul 8, 2019
b6d8fa7
create initial gradle skeleton for modules
fractalwrench Jul 8, 2019
02e250e
move ndk to bugsnag-android-ndk module
fractalwrench Jul 8, 2019
4d4fe65
begin extracting anr into separate module
fractalwrench Jul 8, 2019
8829d81
setup plugin interface for ndk
fractalwrench Jul 10, 2019
219a1b8
create separate artefacts that compile in example project
fractalwrench Jul 11, 2019
d7420c1
create working ANR + NDK plugins
fractalwrench Jul 11, 2019
979d68d
add readmes to modules
fractalwrench Jul 11, 2019
6d7f330
begin passing lint
fractalwrench Jul 11, 2019
ea0973d
pass unit tests
fractalwrench Jul 11, 2019
f46f062
update contributing docs
fractalwrench Jul 11, 2019
95642a1
remove unused git submodule
fractalwrench Jul 11, 2019
4e05aa0
alter mazerunner tests to build against modularised artefacts
fractalwrench Jul 11, 2019
b268d21
rename plugins as requested
fractalwrench Jul 12, 2019
49ccfc5
rename bugsnag-plugin-android-jvm to bugsnag-android-core
fractalwrench Jul 15, 2019
0720ad3
use latest version of gradle plugin
fractalwrench Jul 15, 2019
3ed0615
review feedback
fractalwrench Jul 15, 2019
a247e2a
refactor: set DETECT_NDK_CRASHES in bugsnag-android-ndk artefact
fractalwrench Jul 15, 2019
3cdf062
attempt to fix buildkite ci
fractalwrench Jul 16, 2019
ee43c17
enable ndk/anr detection explicitly by default, as now using the bugs…
fractalwrench Jul 17, 2019
15e2801
update gradle plugin
fractalwrench Jul 17, 2019
d207fc1
Merge branch 'next' into artefact-modularisation
fractalwrench Jul 18, 2019
72ec766
browserstack mazerunner scenario tweaks
fractalwrench Jul 18, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .buildkite/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ steps:
- docker-compose#v2.6.0:
run: android-instrumentation-tests
env:
APP_LOCATION: "/app/sdk/build/outputs/apk/androidTest/debug/bugsnag-android-debug-androidTest.apk"
APP_LOCATION: "/app/bugsnag-android-core/build/outputs/apk/androidTest/debug/bugsnag-android-core-debug-androidTest.apk"
INSTRUMENTATION_DEVICES: '["Google Nexus 5-4.4", "Google Pixel-7.1", "Google Pixel 3-9.0"]'
NDK_VERSION: "r12b"
concurrency: 5
Expand All @@ -152,7 +152,7 @@ steps:
- docker-compose#v2.6.0:
run: android-instrumentation-tests
env:
APP_LOCATION: "/app/sdk/build/outputs/apk/androidTest/debug/bugsnag-android-debug-androidTest.apk"
APP_LOCATION: "/app/bugsnag-android-core/build/outputs/apk/androidTest/debug/bugsnag-android-core-debug-androidTest.apk"
INSTRUMENTATION_DEVICES: '["Google Nexus 5-4.4", "Google Pixel-7.1", "Google Pixel 3-9.0"]'
NDK_VERSION: "r16b"
concurrency: 5
Expand All @@ -163,8 +163,8 @@ steps:
- docker-compose#v2.6.0:
run: android-instrumentation-tests
env:
APP_LOCATION: "/app/sdk/build/outputs/apk/androidTest/debug/bugsnag-android-debug-androidTest.apk"
APP_LOCATION: "/app/bugsnag-android-core/build/outputs/apk/androidTest/debug/bugsnag-android-core-debug-androidTest.apk"
INSTRUMENTATION_DEVICES: '["Google Nexus 5-4.4", "Google Pixel-7.1", "Google Pixel 3-9.0"]'
NDK_VERSION: "r19"
concurrency: 5
concurrency_group: 'browserstack-app'
concurrency_group: 'browserstack-app'
4 changes: 2 additions & 2 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[submodule "sdk/src/main/jni/external/libunwindstack"]
path = sdk/src/main/jni/external/libunwindstack
[submodule "bugsnag-plugin-android-ndk/src/main/jni/external/libunwindstack-ndk"]
path = bugsnag-plugin-android-ndk/src/main/jni/external/libunwindstack-ndk
url = https://github.com/bugsnag/libunwindstack-ndk
57 changes: 15 additions & 42 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,18 +84,18 @@ git submodule update --init --recursive
You can build new `.aar` files as follows:

```shell
./gradlew sdk:assemble
./gradlew assembleRelease
```

Files are generated into`sdk/build/outputs/aar`.
Files are generated into`<module>/build/outputs/aar`.

### Building with custom ABIs

To build the NDK module with specific ABIs, use the `ABI_FILTERS` project
option:

```shell
./gradlew assemble -PABI_FILTERS=x86,arm64-v8a
./gradlew assembleRelease -PABI_FILTERS=x86,arm64-v8a
```

## Testing
Expand All @@ -104,7 +104,7 @@ Full details of how to build and run tests can be found in [the testing guide](`

## Building the Example App

You can build and install the example app to as follows:
You can build and install the example app as follows:

```shell
./gradlew installDebug
Expand All @@ -115,41 +115,15 @@ device/emulator.

## Installing/testing against a local maven repository

Sometimes its helpful to build and install the bugsnag-android libraries into a
local repository and test the entire dependency flow inside of a sample
application.

To get started:

1. In the `bugsnag-android` directory, run
`./gradlew assembleRelease publishSDKPublicationToMavenLocal && ./gradlew assembleRelease publishSDKPublicationToMavenLocal -PreleaseNdkArtefact=true`.
This installs `bugsnag-android` and `bugsnag-android-ndk` into your local
maven repository.
2. In your sample application `build.gradle`, add `mavenLocal()` to the *top* of
your `allprojects` repositories section:

```groovy
allprojects {
repositories {
mavenLocal()
// other repos as needed
}
}
```
3. In your sample application `app/build.gradle`, add the following to the
dependencies section, inserting the exact version number required:

```groovy
dependencies {
implementation 'com.bugsnag:bugsnag-android-ndk:[VERSION NUMBER]'
}
```
4. Clean your sample application and reload dependencies *every time* you
rebuild/republish the local dependencies:

```
./gradlew clean --refresh-dependencies
```
Change `VERSION_NAME` in `gradle.properties` to a version higher than the currently
released bugsnag-android, then run:

```shell
./gradlew assembleRelease publishToMavenLocal
```

This installs bugsnag-android to a local maven repository. The example app should automatically use
this version when you next run the app.

# Releasing a New Version

Expand Down Expand Up @@ -224,12 +198,11 @@ If you are a project maintainer, you can build and release a new version of
- [ ] Update the version number and dex count badge by running `make VERSION=[number] bump`
- [ ] Inspect the updated CHANGELOG, README, and version files to ensure they are correct
- Once merged:
- Pull the latest changes (checking out master if necessary) and build by running `./gradlew sdk:assembleRelease`
- Pull the latest changes (checking out master if necessary) and build by running `./gradlew assembleRelease`
- Release to GitHub:
- [ ] Run `git tag vX.X.X && git push origin --tags`
- [ ] Create a release from your new tag on [GitHub Releases](https://github.com/bugsnag/bugsnag-android/releases)
- [ ] Upload the generated `.aar` file from `{sdk,ndk}/build/outputs/aar/bugsnag-android-*.aar`
fractalwrench marked this conversation as resolved.
Show resolved Hide resolved
- [ ] Release to Maven Central and Bintray by running `./gradlew sdk:assembleRelease publish bintrayUpload && ./gradlew sdk:assembleRelease publish bintrayUpload -PreleaseNdkArtefact=true`
- [ ] Release to Maven Central and Bintray by running `./gradlew assembleRelease publish bintrayUpload`
- [ ] "Promote" the release build on Maven Central:
- Go to the [sonatype open source dashboard](https://oss.sonatype.org/index.html#stagingRepositories)
- Click the search box at the top right, and type “com.bugsnag”
Expand Down
26 changes: 3 additions & 23 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
all: build

.PHONY: build test clean bump badge release
.PHONY: build test clean bump release

build:
./gradlew sdk:build
Expand All @@ -18,7 +18,7 @@ endif
ifeq ($(BROWSER_STACK_ACCESS_KEY),)
@$(error BROWSER_STACK_ACCESS_KEY is not defined)
endif
@APP_LOCATION=/app/sdk/build/outputs/apk/androidTest/debug/bugsnag-android-debug-androidTest.apk \
@APP_LOCATION=/app/bugsnag-android-core/build/outputs/apk/androidTest/debug/bugsnag-android-core-debug-androidTest.apk \
INSTRUMENTATION_DEVICES='["Google Nexus 5-4.4", "Google Pixel-7.1", "Google Pixel 3-9.0"]' \
docker-compose up --build android-instrumentation-tests

Expand All @@ -37,7 +37,7 @@ else
@APP_LOCATION=/app/build/fixture.apk docker-compose run android-maze-runner
endif

bump: badge
bump:
ifneq ($(shell git diff --staged),)
@git diff --staged
@$(error You have uncommitted changes. Push or discard them to continue)
Expand All @@ -51,26 +51,6 @@ endif
sdk/src/main/java/com/bugsnag/android/Notifier.java
@sed -i '' "s/## TBD/## $(VERSION) ($(shell date '+%Y-%m-%d'))/" CHANGELOG.md

badge: build
ifneq ($(shell git diff),)
@git diff
@$(error You have unstaged changes. Commit or discard them to continue)
endif
@echo "Counting ..."
@./gradlew countReleaseDexMethods > counter.txt
@awk 'BEGIN{ \
"cat counter.txt | grep \"com.bugsnag.android\$\"" | getline output;\
split(output, counts);\
"du -k sdk/build/outputs/aar/bugsnag-android-*.aar | cut -f1" | getline size;\
printf "![Method count and size](https://img.shields.io/badge/Methods%%20and%%20size-";\
printf counts[1] "%%20classes%%20|%%20" counts[2] "%%20methods%%20|%%20" counts[3] "%%20fields%%20|%%20";\
printf size "%%20KB-e91e63.svg)";\
};' > tmp_url.txt
@awk '/!.*Method count and size.*/ { getline < "tmp_url.txt" }1' README.md > README.md.tmp
@mv README.md.tmp README.md
@rm counter.txt tmp_url.txt


# Makes a release
release:
ifneq ($(shell git diff origin/master..master),)
Expand Down
3 changes: 0 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
# Bugsnag error monitoring & exception reporter for Android
[![Documentation](https://img.shields.io/badge/documentation-latest-blue.svg)](https://docs.bugsnag.com/platforms/android/)
[![Build status](https://api.travis-ci.com/bugsnag/bugsnag-android.svg?branch=master)](https://travis-ci.com/bugsnag/bugsnag-android)
[![Coverage Status](https://coveralls.io/repos/github/bugsnag/bugsnag-android/badge.svg?branch=master)](https://coveralls.io/github/bugsnag/bugsnag-android?branch=master)
<!-- Auto-generated line below: -->
![Method count and size](https://img.shields.io/badge/Methods%20and%20size-103%20classes%20|%20822%20methods%20|%20408%20fields%20|%202052%20KB-e91e63.svg)

Get comprehensive [Android crash reports](https://www.bugsnag.com/platforms/android/) to quickly debug errors.

Expand Down
29 changes: 15 additions & 14 deletions TESTING.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
# Testing the Bugsnag Android notifier

## Running Tests Locally
Commands can be run on the entire project, or on an individual module:

Running the test suite requires a connected android device or emulator.
```shell
./gradlew build // builds whole project
./gradlew bugsnag-plugin-android-anr:build // builds bugsnag-plugin-android-anr module only
```

## Static analysis

```shell
./gradlew lint checkstyle detekt
```

### Unit tests
## Running Tests Locally

You can run the test suite on a device/emulator as follows from within the sdk directory:
Running the test suite requires a connected android device or emulator.

```shell
./gradlew connectedCheck
```

### End-to-end tests
## End-to-end tests

To run the end-to-end tests, first set up the environment by running
[Bundler](https://bundler.io):
Expand All @@ -32,14 +41,6 @@ Then run the tests using:
bundle exec maze-runner
```

### Running Lint

You can run lint on the project using the following command:

```shell
./gradlew lint checkstyle detekt
```

## Running remote tests

These tests are implemented with our notifier testing tool [Maze runner](https://github.com/bugsnag/maze-runner).
Expand Down Expand Up @@ -95,4 +96,4 @@ Run `make remote-integration-tests`
If you wish to test a single feature, set the `TEST_FEATURE` environment variable to the name of the feature file.
For example, to test the `breadcrumb` feature, use the following command:

`TEST_FEATURE=breadcrumb.feature make remote-integration-tests`
`TEST_FEATURE=breadcrumb.feature make remote-integration-tests`
9 changes: 9 additions & 0 deletions bugsnag-android-core/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# bugsnag-android-core

This module detects JVM exceptions and reports them to bugsnag.

## High-level Overview

An `UncaughtExceptionHandler` is installed which generates an error report whenever an uncaught
`Throwable` propagates. This module is also responsible for the delivery of JSON payloads to the
Error Reporting API, and also provides the main public API for bugsnag-android.
13 changes: 13 additions & 0 deletions bugsnag-android-core/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
apply plugin: "com.android.library"
apply plugin: "kotlin-android"
apply plugin: "io.gitlab.arturbosch.detekt"

android {
compileSdkVersion rootProject.ext.compileSdkVersion
defaultConfig.minSdkVersion rootProject.ext.minSdkVersion
}

apply from: "../gradle/dependencies.gradle"
apply from: "../gradle/release.gradle"
apply from: "../gradle/detekt.gradle"
apply from: "../gradle/checkstyle.gradle"
2 changes: 2 additions & 0 deletions bugsnag-android-core/gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pomName=Bugsnag Android Core
artefactId=bugsnag-android-core
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,3 @@
-keep class com.bugsnag.android.Breadcrumbs { *; }
-keep class com.bugsnag.android.BreadcrumbType { *; }
-keep class com.bugsnag.android.Severity { *; }
-keep class com.bugsnag.android.ndk.NativeBridge { *; }
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public void setUp() throws Exception {

@Test
public void testAccessors() {
assertEquals("com.bugsnag.android.test", appData.get("packageName"));
assertEquals("com.bugsnag.android.core.test", appData.get("packageName"));
assertNull(appData.get("buildUUID"));
assertTrue(((Long) appData.get("duration")) > 0);
assertEquals(500L, appData.get("durationInForeground"));
Expand All @@ -68,7 +68,7 @@ public void testJsonSerialisation() throws JSONException {
assertEquals("1.0", appDataJson.get("version"));
assertEquals("development", appDataJson.get("releaseStage"));
assertEquals("android", appDataJson.get("type"));
assertEquals("com.bugsnag.android.test", appDataJson.get("id"));
assertEquals("com.bugsnag.android.core.test", appDataJson.get("id"));
assertNotNull(appDataJson.get("buildUUID"));
assertTrue(((Long) appData.get("duration")) > 0);
assertEquals(500L, appData.get("durationInForeground"));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.bugsnag.android

import org.junit.Test

import org.junit.Assert.*
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.junit.MockitoJUnitRunner

@RunWith(MockitoJUnitRunner::class)
class BugsnagPluginInterfaceTest {

@Mock
lateinit var client: Client

@Test
fun registerPlugin() {
BugsnagPluginInterface.registerPlugin(FakePlugin::class.java)
BugsnagPluginInterface.loadPlugins(client)
assertTrue(FakePlugin.initialised)
}
}

internal class FakePlugin: BugsnagPlugin {
companion object {
var initialised = false
}

override fun initialisePlugin(client: Client) {
initialised = true
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ public void testAppDataMetaData() {
Map<String, Object> app = client.getAppData().getAppDataMetaData();
assertEquals(6, app.size());
assertEquals("Bugsnag Android Tests", app.get("name"));
assertEquals("com.bugsnag.android.test", app.get("packageName"));
assertEquals("com.bugsnag.android.core.test", app.get("packageName"));
assertEquals("1.0", app.get("versionName"));
assertNotNull(app.get("memoryUsage"));
assertTrue(app.containsKey("activeScreen"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;

Expand Down Expand Up @@ -41,8 +40,8 @@ public class ErrorReaderTest {
/** Constructs an Error from a JSON file */
@BeforeClass
public static void setUp() throws IOException {
InputStream input = InstrumentationRegistry.getContext().getResources()
.openRawResource(com.bugsnag.android.test.R.raw.error);
ClassLoader classLoader = ErrorReaderTest.class.getClassLoader();
InputStream input = classLoader.getResourceAsStream("error.json");
File fixtureFile = File.createTempFile("error", ".json");
OutputStream output = new FileOutputStream(fixtureFile);
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class ProjectPackagesTest {
assertNull(configuration.projectPackages)

val client = Client(InstrumentationRegistry.getContext(), configuration)
assertArrayEquals(arrayOf("com.bugsnag.android.test"), client.config.projectPackages)
assertArrayEquals(arrayOf("com.bugsnag.android.core.test"), client.config.projectPackages)
client.close()
}

Expand Down
Loading