Skip to content

Commit

Permalink
Merge 6181d68 into 061cf2f
Browse files Browse the repository at this point in the history
  • Loading branch information
fractalwrench committed Feb 19, 2019
2 parents 061cf2f + 6181d68 commit c978bba
Show file tree
Hide file tree
Showing 22 changed files with 627 additions and 44 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## 4.X.X (TBD)

### Enhancements

* Add stopSession() and resumeSession() to Client
[#429](https://github.com/bugsnag/bugsnag-android/pull/429)

## 4.11.0 (2019-01-22)

### Enhancements
Expand Down
16 changes: 9 additions & 7 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
GIT
remote: https://github.com/bugsnag/maze-runner
revision: 24f53756011b1247a166b70fe65ddf1c40b4fc89
revision: 6f5af2c98c6fa1cfb07d6466a5cf3eaca5dcbc90
specs:
bugsnag-maze-runner (1.0.0)
cucumber (~> 3.1.0)
cucumber-expressions (= 5.0.15)
minitest (~> 5.0)
os (~> 1.0.0)
rack (~> 2.0.0)
rake (~> 12.3.0)
test-unit (~> 3.2.0)
Expand Down Expand Up @@ -34,17 +35,18 @@ GEM
cucumber-wire (0.0.1)
diff-lcs (1.3)
gherkin (5.1.0)
method_source (0.9.0)
method_source (0.9.2)
minitest (5.11.3)
multi_json (1.13.1)
multi_test (0.1.2)
os (1.0.0)
power_assert (1.1.3)
pry (0.11.3)
pry (0.12.2)
coderay (~> 1.1.0)
method_source (~> 0.9.0)
rack (2.0.5)
rake (12.3.1)
test-unit (3.2.8)
rack (2.0.6)
rake (12.3.2)
test-unit (3.2.9)
power_assert

PLATFORMS
Expand All @@ -55,4 +57,4 @@ DEPENDENCIES
pry

BUNDLED WITH
1.16.2
1.16.1
20 changes: 20 additions & 0 deletions features/fixtures/mazerunner/src/main/cpp/bugsnags.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,26 @@ Java_com_bugsnag_android_mazerunner_scenarios_CXXAutoContextScenario_activate(JN
(char *)"This is a new world", BSG_SEVERITY_INFO);
}

JNIEXPORT int JNICALL
Java_com_bugsnag_android_mazerunner_scenarios_CXXStartSessionScenario_crash(JNIEnv *env,
jobject instance,
jint value) {
int x = 22;
if (x > 0)
__builtin_trap();
return 338;
}

JNIEXPORT int JNICALL
Java_com_bugsnag_android_mazerunner_scenarios_CXXStopSessionScenario_crash(JNIEnv *env,
jobject instance,
jint value) {
int x = 22552;
if (x > 0)
__builtin_trap();
return 555;
}

JNIEXPORT int JNICALL
Java_com_bugsnag_android_mazerunner_scenarios_CXXUpdateContextCrashScenario_crash(JNIEnv *env,
jobject instance,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.bugsnag.android.mazerunner.scenarios;

import android.content.Context;

import com.bugsnag.android.Bugsnag;
import com.bugsnag.android.Configuration;

import android.support.annotation.NonNull;

public class CXXStartSessionScenario extends Scenario {
static {
System.loadLibrary("bugsnag-ndk");
System.loadLibrary("monochrome");
System.loadLibrary("entrypoint");
}

public native int crash(int counter);

public CXXStartSessionScenario(@NonNull Configuration config, @NonNull Context context) {
super(config, context);
config.setAutoCaptureSessions(false);
}

@Override
public void run() {
super.run();
String metadata = getEventMetaData();

if (metadata == null || !metadata.equals("non-crashy")) {
Bugsnag.getClient().startSession();
crash(0);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.bugsnag.android.mazerunner.scenarios;

import android.content.Context;

import com.bugsnag.android.Bugsnag;
import com.bugsnag.android.Configuration;

import android.support.annotation.NonNull;

public class CXXStopSessionScenario extends Scenario {
static {
System.loadLibrary("bugsnag-ndk");
System.loadLibrary("monochrome");
System.loadLibrary("entrypoint");
}

public native int crash(int counter);

public CXXStopSessionScenario(@NonNull Configuration config, @NonNull Context context) {
super(config, context);
config.setAutoCaptureSessions(false);
}

@Override
public void run() {
super.run();
String metadata = getEventMetaData();

if (metadata == null || !metadata.equals("non-crashy")) {
Bugsnag.getClient().startSession();
Bugsnag.getClient().stopSession();
crash(0);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.bugsnag.android.mazerunner.scenarios

import android.content.Context
import com.bugsnag.android.Bugsnag
import com.bugsnag.android.Configuration
import android.os.Handler
import android.os.HandlerThread

/**
* Sends an exception after stopping the session
*/
internal class NewSessionScenario(config: Configuration,
context: Context) : Scenario(config, context) {
init {
config.setAutoCaptureSessions(false)
}

override fun run() {
super.run()
val client = Bugsnag.getClient()
val thread = HandlerThread("HandlerThread")
thread.start()

Handler(thread.looper).post {
// send 1st exception which should include session info
client.startSession()
client.notifyBlocking(generateException())

// stop tracking the existing session
client.stopSession()

// send 2nd exception which should contain new session info
client.startSession()
client.notifyBlocking(generateException())
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.bugsnag.android.mazerunner.scenarios

import android.content.Context
import com.bugsnag.android.Bugsnag
import com.bugsnag.android.Configuration
import android.os.Handler
import android.os.HandlerThread

/**
* Sends 2 exceptions, 1 before resuming a session, and 1 after resuming a session.
*/
internal class ResumedSessionScenario(config: Configuration,
context: Context) : Scenario(config, context) {
init {
config.setAutoCaptureSessions(false)
}

override fun run() {
super.run()
val client = Bugsnag.getClient()
val thread = HandlerThread("HandlerThread")
thread.start()

Handler(thread.looper).post {
// send 1st exception
client.startSession()
client.notifyBlocking(generateException())

// send 2nd exception after resuming a session
client.stopSession()
client.resumeSession()
client.notifyBlocking(generateException())
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.bugsnag.android.mazerunner.scenarios

import android.content.Context
import com.bugsnag.android.Bugsnag
import com.bugsnag.android.Configuration
import android.os.Handler
import android.os.HandlerThread

/**
* Sends an exception after stopping the session
*/
internal class StoppedSessionScenario(config: Configuration,
context: Context) : Scenario(config, context) {
init {
config.setAutoCaptureSessions(false)
}

override fun run() {
super.run()
val client = Bugsnag.getClient()
val thread = HandlerThread("HandlerThread")
thread.start()

Handler(thread.looper).post {
// send 1st exception which should include session info
client.startSession()
client.notifyBlocking(generateException())

// send 2nd exception which should not include session info
client.stopSession()
client.notifyBlocking(generateException())
}
}
}
19 changes: 19 additions & 0 deletions features/native_session_tracking.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
Feature: NDK Session Tracking

Scenario: Stopped session is not in payload of unhandled NDK error
When I run "CXXStopSessionScenario"
And I configure the app to run in the "non-crashy" state
And I relaunch the app
Then I should receive 2 requests
And the request 0 is a valid for the session tracking API
And the request 1 is a valid for the error reporting API
And the payload field "events.0.session" is null for request 1

Scenario: Started session is in payload of unhandled NDK error
When I run "CXXStartSessionScenario"
And I configure the app to run in the "non-crashy" state
And I relaunch the app
Then I should receive 2 requests
And the request 0 is a valid for the session tracking API
And the request 1 is a valid for the error reporting API
And the payload field "events.0.session.events.unhandled" equals 1 for request 1
32 changes: 32 additions & 0 deletions features/session_stopping.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
Feature: Stopping and resuming sessions

Scenario: When a session is stopped the error has no session information
When I run "StoppedSessionScenario"
Then I should receive 3 requests
And the request 0 is valid for the session tracking API
And the request 1 is valid for the error reporting API
And the request 2 is valid for the error reporting API
And the payload field "events.0.session" is not null for request 1
And the payload field "events.0.session" is null for request 2

Scenario: When a session is resumed the error uses the previous session information
When I run "ResumedSessionScenario"
Then I should receive 3 requests
And the request 0 is valid for the session tracking API
And the request 1 is valid for the error reporting API
And the request 2 is valid for the error reporting API
And the payload field "events.0.session.events.handled" equals 1 for request 1
And the payload field "events.0.session.events.handled" equals 2 for request 2
And the payload field "events.0.session.id" of request 1 equals the payload field "events.0.session.id" of request 2
And the payload field "events.0.session.startedAt" of request 1 equals the payload field "events.0.session.startedAt" of request 2

Scenario: When a new session is started the error uses different session information
When I run "NewSessionScenario"
Then I should receive 4 requests
And the request 0 is valid for the session tracking API
And the request 1 is valid for the error reporting API
And the request 2 is valid for the session tracking API
And the request 3 is valid for the error reporting API
And the payload field "events.0.session.events.handled" equals 1 for request 1
And the payload field "events.0.session.events.handled" equals 1 for request 3
And the payload field "events.0.session.id" of request 1 does not equal the payload field "events.0.session.id" of request 3
20 changes: 16 additions & 4 deletions ndk/src/main/java/com/bugsnag/android/ndk/NativeBridge.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ public static native void addBreadcrumb(String name, String type, String timesta

public static native void removeMetadata(String tab, String key);

public static native void startedSession(String sessionID, String key);
public static native void startedSession(String sessionID, String key, int handledCount);

public static native void stoppedSession();

public static native void updateAppVersion(String appVersion);

Expand Down Expand Up @@ -131,6 +133,9 @@ public void update(Observable observable, Object rawMessage) {
case START_SESSION:
handleStartSession(arg);
break;
case STOP_SESSION:
stoppedSession();
break;
case UPDATE_APP_VERSION:
handleAppVersionChange(arg);
break;
Expand Down Expand Up @@ -313,11 +318,14 @@ private void handleStartSession(Object arg) {
if (arg instanceof List) {
@SuppressWarnings("unchecked")
List<Object> metadata = (List<Object>)arg;
if (metadata.size() == 2) {
if (metadata.size() == 3) {
Object id = metadata.get(0);
Object startTime = metadata.get(1);
if (id instanceof String && startTime instanceof String) {
startedSession((String)id, (String)startTime);
Object handledCount = metadata.get(2);

if (id instanceof String && startTime instanceof String
&& handledCount instanceof Integer) {
startedSession((String)id, (String)startTime, (Integer) handledCount);
return;
}
}
Expand All @@ -326,6 +334,10 @@ private void handleStartSession(Object arg) {
warn("START_SESSION object is invalid: " + arg);
}

private void handleStopSession() {
stoppedSession();
}

private void handleReleaseStageChange(Object arg) {
if (arg instanceof String) {
updateReleaseStage((String)arg);
Expand Down

0 comments on commit c978bba

Please sign in to comment.