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

Add Strictmode scenarios #254

Merged
merged 4 commits into from
Feb 23, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 9 additions & 0 deletions features/strict_mode_disc.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Feature: Android support

Scenario: Test handled Android Exception
When I run "StrictModeDiscScenario" with the defaults
Then I should receive a request
And the request is a valid for the error reporting API
And the exception "errorClass" equals "android.os.StrictMode$StrictModeViolation"
And the exception "message" equals "policy=262145 violation=1"
And the event "metaData.StrictMode.Violation" equals "DiskWrite"
9 changes: 9 additions & 0 deletions features/strict_mode_network.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Feature: Android support

Scenario: Test handled Android Exception
When I run "StrictModeNetworkScenario" with the defaults
Then I should receive a request
And the request is a valid for the error reporting API
And the exception "errorClass" equals "android.os.StrictMode$StrictModeViolation"
And the exception "message" equals "policy=262148 violation=4"
And the event "metaData.StrictMode.Violation" equals "NetworkOperation"
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class MainActivity : Activity() {
private fun executeTestCase() {
val eventType = intent.getStringExtra("EVENT_TYPE")
Log.d("Bugsnag", "Received test case, executing " + eventType)
val testCase = factory.testCaseForName(eventType)
val testCase = factory.testCaseForName(eventType, this)
testCase.run()
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package com.bugsnag.android.mazerunner

import android.content.Context
import com.bugsnag.android.mazerunner.scenarios.Scenario

internal class TestCaseFactory {

fun testCaseForName(eventType: String?): Scenario {
fun testCaseForName(eventType: String?, context: Context?): Scenario {
try {
val clz = Class.forName("com.bugsnag.android.mazerunner.scenarios.$eventType")
return clz.newInstance() as Scenario
val scenario = clz.newInstance() as Scenario
scenario.context = context
return scenario
} catch (e: Exception) {
throw IllegalArgumentException("Failed to find class for $eventType")
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package com.bugsnag.android.mazerunner.scenarios

import android.content.Context
import com.bugsnag.android.Bugsnag
import com.bugsnag.android.NetworkException

abstract internal class Scenario {

var context: Context? = null

abstract fun run()

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.bugsnag.android.mazerunner.scenarios

import android.os.StrictMode
import java.io.File

/**
* Generates a strictmode exception caused by writing to disc on main thread
*/
internal class StrictModeDiscScenario : Scenario() {

override fun run() {
StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.Builder()
.detectDiskWrites()
.penaltyDeath()
.build())
val file = File(context?.cacheDir, "fake")
file.writeBytes("test".toByteArray())
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.bugsnag.android.mazerunner.scenarios

import android.os.StrictMode
import java.net.HttpURLConnection
import java.net.URL

/**
* Generates a strictmode exception caused by performing a network request on the main thread
*/
internal class StrictModeNetworkScenario : Scenario() {

override fun run() {
StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.Builder()
.detectNetwork()
.penaltyDeath()
.build())

val urlConnection = URL("http://example.com").openConnection() as HttpURLConnection
urlConnection.doOutput = true
urlConnection.responseMessage
}

}
13 changes: 11 additions & 2 deletions sdk/src/main/java/com/bugsnag/android/ExceptionHandler.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.bugsnag.android;

import android.os.StrictMode;
import android.support.annotation.NonNull;

import java.lang.Thread.UncaughtExceptionHandler;
Expand Down Expand Up @@ -70,8 +71,16 @@ public void uncaughtException(@NonNull Thread thread, @NonNull Throwable throwab

String severityReason = strictModeThrowable
? HandledState.REASON_STRICT_MODE : HandledState.REASON_UNHANDLED_EXCEPTION;
client.cacheAndNotify(throwable, Severity.ERROR,
metaData, severityReason, violationDesc);

if (strictModeThrowable) { // writes to disk on main thread
StrictMode.ThreadPolicy originalThreadPolicy = StrictMode.getThreadPolicy();
StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.LAX);

client.cacheAndNotify(throwable, Severity.ERROR,
metaData, severityReason, violationDesc);

StrictMode.setThreadPolicy(originalThreadPolicy);
}
}

// Pass exception on to original exception handler
Expand Down