[#560] Detect strict mode violations on CI
This commit is contained in:
parent
173f5048f0
commit
1bd5e7518e
|
@ -313,7 +313,49 @@ jobs:
|
||||||
name: Test Android modules with WTF results
|
name: Test Android modules with WTF results
|
||||||
path: ~/artifacts
|
path: ~/artifacts
|
||||||
|
|
||||||
release_build:
|
|
||||||
|
# Performs a button mash test on the debug build of the app with strict mode enabled
|
||||||
|
test_robo_debug:
|
||||||
|
if: needs.check_firebase_secrets.outputs.has-secrets == 'true'
|
||||||
|
needs: [check_firebase_secrets]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
packages: read
|
||||||
|
contents: read
|
||||||
|
id-token: write
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
timeout-minutes: 1
|
||||||
|
uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b
|
||||||
|
- name: Setup
|
||||||
|
id: setup
|
||||||
|
timeout-minutes: 5
|
||||||
|
uses: ./.github/actions/setup
|
||||||
|
- name: Build
|
||||||
|
timeout-minutes: 20
|
||||||
|
env:
|
||||||
|
ORG_GRADLE_PROJECT_IS_CRASH_ON_STRICT_MODE_VIOLATION: true
|
||||||
|
run: |
|
||||||
|
./gradlew :app:assembleDebug
|
||||||
|
- name: Authenticate to Google Cloud for Firebase Test Lab
|
||||||
|
id: auth_test_lab
|
||||||
|
uses: google-github-actions/auth@ceee102ec2387dd9e844e01b530ccd4ec87ce955
|
||||||
|
with:
|
||||||
|
create_credentials_file: true
|
||||||
|
project_id: ${{ secrets.FIREBASE_TEST_LAB_PROJECT }}
|
||||||
|
service_account: ${{ secrets.FIREBASE_TEST_LAB_SERVICE_ACCOUNT }}
|
||||||
|
workload_identity_provider: ${{ secrets.FIREBASE_TEST_LAB_WORKLOAD_IDENTITY_PROVIDER }}
|
||||||
|
access_token_lifetime: '900s'
|
||||||
|
- name: Robo test
|
||||||
|
timeout-minutes: 20
|
||||||
|
env:
|
||||||
|
# This first environment variable is used by Flank, since the temporary token is missing the project name
|
||||||
|
GOOGLE_CLOUD_PROJECT: ${{ secrets.FIREBASE_TEST_LAB_PROJECT }}
|
||||||
|
ORG_GRADLE_PROJECT_ZCASH_FIREBASE_TEST_LAB_API_KEY_PATH: ${{ steps.auth_test_lab.outputs.credentials_file_path }}
|
||||||
|
run: |
|
||||||
|
./gradlew :app:runFlankSanityConfigDebug
|
||||||
|
|
||||||
|
build:
|
||||||
needs: prime_cache
|
needs: prime_cache
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
permissions:
|
||||||
|
@ -360,10 +402,9 @@ jobs:
|
||||||
path: ~/artifacts
|
path: ~/artifacts
|
||||||
|
|
||||||
# Performs a button mash test on the release build of the app
|
# Performs a button mash test on the release build of the app
|
||||||
# Note that we might need to help it get past the onboarding test with a script
|
test_robo_release:
|
||||||
test_robo:
|
|
||||||
if: needs.check_firebase_secrets.outputs.has-secrets == 'true'
|
if: needs.check_firebase_secrets.outputs.has-secrets == 'true'
|
||||||
needs: [release_build, check_firebase_secrets]
|
needs: [build, check_firebase_secrets]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
permissions:
|
||||||
packages: read
|
packages: read
|
||||||
|
@ -400,4 +441,4 @@ jobs:
|
||||||
ORG_GRADLE_PROJECT_ZCASH_FIREBASE_TEST_LAB_API_KEY_PATH: ${{ steps.auth_test_lab.outputs.credentials_file_path }}
|
ORG_GRADLE_PROJECT_ZCASH_FIREBASE_TEST_LAB_API_KEY_PATH: ${{ steps.auth_test_lab.outputs.credentials_file_path }}
|
||||||
run: |
|
run: |
|
||||||
unzip ${BINARIES_ZIP_PATH}
|
unzip ${BINARIES_ZIP_PATH}
|
||||||
./gradlew :app:runFlankSanityConfig
|
./gradlew :app:runFlankSanityConfigRelease
|
||||||
|
|
|
@ -104,6 +104,13 @@ android {
|
||||||
signingConfig = signingConfigs.getByName("release")
|
signingConfig = signingConfigs.getByName("release")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
all {
|
||||||
|
buildConfigField(
|
||||||
|
"boolean",
|
||||||
|
"IS_STRICT_MODE_CRASH_ENABLED",
|
||||||
|
project.property("IS_CRASH_ON_STRICT_MODE_VIOLATION").toString()
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolve final app name
|
// Resolve final app name
|
||||||
|
@ -112,16 +119,16 @@ android {
|
||||||
val debugAppNameSuffix = project.property("ZCASH_DEBUG_APP_NAME_SUFFIX").toString()
|
val debugAppNameSuffix = project.property("ZCASH_DEBUG_APP_NAME_SUFFIX").toString()
|
||||||
when (this.name) {
|
when (this.name) {
|
||||||
"zcashtestnetDebug" -> {
|
"zcashtestnetDebug" -> {
|
||||||
resValue( "string", "app_name", "$defaultAppName ($testnetNetworkName)$debugAppNameSuffix")
|
resValue("string", "app_name", "$defaultAppName ($testnetNetworkName)$debugAppNameSuffix")
|
||||||
}
|
}
|
||||||
"zcashmainnetDebug" -> {
|
"zcashmainnetDebug" -> {
|
||||||
resValue( "string", "app_name", "$defaultAppName$debugAppNameSuffix")
|
resValue("string", "app_name", "$defaultAppName$debugAppNameSuffix")
|
||||||
}
|
}
|
||||||
"zcashtestnetRelease" -> {
|
"zcashtestnetRelease" -> {
|
||||||
resValue( "string", "app_name", "$defaultAppName ($testnetNetworkName)")
|
resValue("string", "app_name", "$defaultAppName ($testnetNetworkName)")
|
||||||
}
|
}
|
||||||
"zcashmainnetRelease" -> {
|
"zcashmainnetRelease" -> {
|
||||||
resValue( "string", "app_name", defaultAppName)
|
resValue("string", "app_name", defaultAppName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -265,7 +272,25 @@ fladle {
|
||||||
}
|
}
|
||||||
|
|
||||||
configs {
|
configs {
|
||||||
create("sanityConfig") {
|
create("sanityConfigDebug") {
|
||||||
|
clearPropertiesForSanityRobo()
|
||||||
|
|
||||||
|
debugApk.set(
|
||||||
|
project.provider {
|
||||||
|
"${buildDir}/outputs/apk/zcashmainnet/debug/app-zcashmainnet-debug.apk"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
testTimeout.set("3m")
|
||||||
|
|
||||||
|
devices.addAll(
|
||||||
|
mapOf("model" to "Pixel2", "version" to minSdkVersion),
|
||||||
|
mapOf("model" to "Pixel2", "version" to targetSdkVersion)
|
||||||
|
)
|
||||||
|
|
||||||
|
flankVersion.set(libs.versions.flank.get())
|
||||||
|
}
|
||||||
|
create("sanityConfigRelease") {
|
||||||
clearPropertiesForSanityRobo()
|
clearPropertiesForSanityRobo()
|
||||||
|
|
||||||
debugApk.set(
|
debugApk.set(
|
||||||
|
|
|
@ -15,7 +15,7 @@ class ZcashApplication : Application() {
|
||||||
Twig.info { "Starting application…" }
|
Twig.info { "Starting application…" }
|
||||||
|
|
||||||
if (BuildConfig.DEBUG) {
|
if (BuildConfig.DEBUG) {
|
||||||
StrictModeCompat.enableStrictMode()
|
StrictModeCompat.enableStrictMode(BuildConfig.IS_STRICT_MODE_CRASH_ENABLED)
|
||||||
|
|
||||||
// This is an internal API to the Zcash SDK to enable logging; it could change in the future
|
// This is an internal API to the Zcash SDK to enable logging; it could change in the future
|
||||||
cash.z.ecc.android.sdk.internal.Twig.enabled(true)
|
cash.z.ecc.android.sdk.internal.Twig.enabled(true)
|
||||||
|
|
|
@ -26,6 +26,10 @@ IS_ANDROID_INSTRUMENTATION_TEST_COVERAGE_ENABLED=false
|
||||||
# It is disabled by default, because it causes tests to take about 2x longer to run.
|
# It is disabled by default, because it causes tests to take about 2x longer to run.
|
||||||
IS_USE_TEST_ORCHESTRATOR=false
|
IS_USE_TEST_ORCHESTRATOR=false
|
||||||
|
|
||||||
|
# Optionally enable crashes for strict mode violations in debug builds.
|
||||||
|
# It is disabled by default, because it can be annoying when debugging. Gets turned on by CI jobs that need it.
|
||||||
|
IS_CRASH_ON_STRICT_MODE_VIOLATION=false
|
||||||
|
|
||||||
# Either provide a path to a Firebase Test Lab service key (best for CI)
|
# Either provide a path to a Firebase Test Lab service key (best for CI)
|
||||||
# OR
|
# OR
|
||||||
# login with `./gradlew flankAuth` and provide the project name (best for local development)
|
# login with `./gradlew flankAuth` and provide the project name (best for local development)
|
||||||
|
|
|
@ -8,26 +8,32 @@ import android.os.StrictMode
|
||||||
|
|
||||||
object StrictModeCompat {
|
object StrictModeCompat {
|
||||||
|
|
||||||
fun enableStrictMode() {
|
fun enableStrictMode(isCrashOnViolation: Boolean) {
|
||||||
configureStrictMode()
|
configureStrictMode(isCrashOnViolation)
|
||||||
|
|
||||||
// Workaround for Android bug
|
// Workaround for Android bug
|
||||||
// https://issuetracker.google.com/issues/36951662
|
// https://issuetracker.google.com/issues/36951662
|
||||||
// Not needed if target O_MR1 and running on O_MR1
|
// Not needed if target O_MR1 and running on O_MR1
|
||||||
// Don't really need to check target, because of Google Play enforcement on targetSdkVersion for app updates
|
// Don't really need to check target, because of Google Play enforcement on targetSdkVersion for app updates
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O_MR1) {
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O_MR1) {
|
||||||
Handler(Looper.getMainLooper()).postAtFrontOfQueue { configureStrictMode() }
|
Handler(Looper.getMainLooper()).postAtFrontOfQueue {
|
||||||
|
configureStrictMode(isCrashOnViolation)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
private fun configureStrictMode() {
|
private fun configureStrictMode(isCrashOnViolation: Boolean) {
|
||||||
StrictMode.enableDefaults()
|
StrictMode.enableDefaults()
|
||||||
|
|
||||||
StrictMode.setThreadPolicy(
|
StrictMode.setThreadPolicy(
|
||||||
StrictMode.ThreadPolicy.Builder().apply {
|
StrictMode.ThreadPolicy.Builder().apply {
|
||||||
detectAll()
|
detectAll()
|
||||||
penaltyLog()
|
if (isCrashOnViolation) {
|
||||||
|
penaltyDeath()
|
||||||
|
} else {
|
||||||
|
penaltyLog()
|
||||||
|
}
|
||||||
}.build()
|
}.build()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -46,13 +52,23 @@ object StrictModeCompat {
|
||||||
// Disable because this is mostly flagging Android X and Play Services
|
// Disable because this is mostly flagging Android X and Play Services
|
||||||
// builder.detectNonSdkApiUsage();
|
// builder.detectNonSdkApiUsage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isCrashOnViolation) {
|
||||||
|
penaltyDeath()
|
||||||
|
} else {
|
||||||
|
penaltyLog()
|
||||||
|
}
|
||||||
}.build()
|
}.build()
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
StrictMode.setVmPolicy(
|
StrictMode.setVmPolicy(
|
||||||
StrictMode.VmPolicy.Builder().apply {
|
StrictMode.VmPolicy.Builder().apply {
|
||||||
detectAll()
|
detectAll()
|
||||||
penaltyLog()
|
if (isCrashOnViolation) {
|
||||||
|
penaltyDeath()
|
||||||
|
} else {
|
||||||
|
penaltyLog()
|
||||||
|
}
|
||||||
}.build()
|
}.build()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue