From a76b6e522bafe93ccc81548a438d06f44d327cc1 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Tue, 14 Jun 2022 15:56:16 +0100 Subject: [PATCH] splitting unit and instrumentation test tasks so that we can configure the android plugin testCoverage parameter - there's a bug that causes the output to be invalid for unit tests --- .github/workflows/tests.yml | 10 ++++++++-- build.gradle | 4 ++-- coverage.gradle | 28 ++++++++++++++-------------- matrix-sdk-android/build.gradle | 9 ++++++++- vector/build.gradle | 13 +++++++++---- 5 files changed, 41 insertions(+), 23 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index a8a2d91f70..3446c7e641 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -49,7 +49,10 @@ jobs: emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none disable-animations: true emulator-build: 7425822 - script: ./gradlew theCodeCoverageReport -Pandroid.testInstrumentationRunnerArguments.notPackage=im.vector.app.ui --stacktrace $CI_GRADLE_ARG_PROPERTIES + script: | + ./gradlew unitTestsWithCoverage --stacktrace $CI_GRADLE_ARG_PROPERTIES + ./gradlew instrumentationTestsWithCoverage -Pandroid.testInstrumentationRunnerArguments.notPackage=im.vector.app.ui --stacktrace $CI_GRADLE_ARG_PROPERTIES + ./gradlew generateCoverageReport --stacktrace $CI_GRADLE_ARG_PROPERTIES # NB: continue-on-error marks steps.tests.conclusion = 'success' but leaves stes.tests.outcome = 'failure' - name: Run all the codecoverage tests at once (retry if emulator failed) uses: reactivecircus/android-emulator-runner@v2 @@ -62,7 +65,10 @@ jobs: emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none disable-animations: true emulator-build: 7425822 - script: ./gradlew theCodeCoverageReport -Pandroid.testInstrumentationRunnerArguments.notPackage=im.vector.app.ui --stacktrace $CI_GRADLE_ARG_PROPERTIES + script: | + ./gradlew unitTestsWithCoverage --stacktrace $CI_GRADLE_ARG_PROPERTIES + ./gradlew instrumentationTestsWithCoverage -Pandroid.testInstrumentationRunnerArguments.notPackage=im.vector.app.ui --stacktrace $CI_GRADLE_ARG_PROPERTIES + ./gradlew generateCoverageReport --stacktrace $CI_GRADLE_ARG_PROPERTIES - run: ./gradlew sonarqube $CI_GRADLE_ARG_PROPERTIES if: always() # we may have failed a previous step and retried, that's OK env: diff --git a/build.gradle b/build.gradle index eabe7bb5d2..b70a4ac6e3 100644 --- a/build.gradle +++ b/build.gradle @@ -168,7 +168,7 @@ def launchTask = getGradle() .toString() .toLowerCase() -if (launchTask.contains("codeCoverageReport".toLowerCase())) { +if (launchTask.contains("coverage".toLowerCase())) { apply from: 'coverage.gradle' } @@ -191,7 +191,7 @@ sonarqube { property "sonar.links.issue", "https://github.com/vector-im/element-android/issues" property "sonar.organization", "new_vector_ltd_organization" property "sonar.java.coveragePlugin", "jacoco" - property "sonar.coverage.jacoco.xmlReportPaths", "${project.buildDir}/reports/jacoco/theCodeCoverageReport/theCodeCoverageReport.xml" + property "sonar.coverage.jacoco.xmlReportPaths", "${project.buildDir}/reports/jacoco/generateCoverageReport/generateCoverageReport.xml" property "sonar.login", project.hasProperty("SONAR_LOGIN") ? SONAR_LOGIN : "invalid" } } diff --git a/coverage.gradle b/coverage.gradle index 1deda1b8d9..be30047afd 100644 --- a/coverage.gradle +++ b/coverage.gradle @@ -27,7 +27,7 @@ def initializeReport(report, projects, classExcludes) { report.executionData { fileTree(rootProject.rootDir.absolutePath).include( - "**/build/outputs/unit_test_code_coverage/**/*.exec", + "**/build/**/*.exec", "**/build/outputs/code_coverage/**/coverage.ec", ) } @@ -45,13 +45,11 @@ def initializeReport(report, projects, classExcludes) { switch (project) { case { project.plugins.hasPlugin("com.android.application") }: androidClassDirs.add("${project.buildDir}/tmp/kotlin-classes/gplayDebug") - androidSourceDirs.add("${project.buildDir}/generated/source/kapt/gplayDebug") androidSourceDirs.add("${project.projectDir}/src/main/kotlin") androidSourceDirs.add("${project.projectDir}/src/main/java") break case { project.plugins.hasPlugin("com.android.library") }: androidClassDirs.add("${project.buildDir}/tmp/kotlin-classes/debug") - androidSourceDirs.add("${project.buildDir}/generated/source/kapt/debug") androidSourceDirs.add("${project.projectDir}/src/main/kotlin") androidSourceDirs.add("${project.projectDir}/src/main/java") break @@ -72,18 +70,20 @@ def collectProjects(predicate) { return subprojects.findAll { it.buildFile.isFile() && predicate(it) } } -task theCodeCoverageReport(type: JacocoReport) { +task generateCoverageReport(type: JacocoReport) { outputs.upToDateWhen { false } rootProject.apply plugin: 'jacoco' - tasks.withType(Test) { - jacoco.includeNoLocationClasses = true - } - def projects = collectProjects { ['vector','matrix-sdk-android'].contains(it.name) } - dependsOn { - [':vector:testGplayDebugUnitTest'] + - [':vector:connectedGplayDebugAndroidTest'] + - [':matrix-sdk-android:testDebugUnitTest'] + - [':matrix-sdk-android:connectedDebugAndroidTest'] - } + def projects = collectProjects { ['vector', 'matrix-sdk-android'].contains(it.name) } initializeReport(it, projects, excludes) } + +task unitTestsWithCoverage(type: GradleBuild) { + // the 7.1.3 android gradle plugin has a bug where enableTestCoverage generates invalid coverage + startParameter.projectProperties.coverage = [enableTestCoverage: false] + tasks = [':vector:testGplayDebugUnitTest', ':matrix-sdk-android:testDebugUnitTest'] +} + +task instrumentationTestsWithCoverage(type: GradleBuild) { + startParameter.projectProperties.coverage = [enableTestCoverage: true] + tasks = [':vector:connectedGplayDebugAndroidTest', 'matrix-sdk-android:connectedDebugAndroidTest'] +} diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle index 034b549d85..c248fe72be 100644 --- a/matrix-sdk-android/build.gradle +++ b/matrix-sdk-android/build.gradle @@ -5,6 +5,10 @@ apply plugin: 'kotlin-parcelize' apply plugin: 'realm-android' apply plugin: "org.jetbrains.dokka" +if (project.hasProperty("coverage")) { + apply plugin: 'jacoco' +} + buildscript { repositories { // Do not use `mavenCentral()`, it prevents Dependabot from working properly @@ -74,7 +78,10 @@ android { buildTypes { debug { - testCoverageEnabled true + if (project.hasProperty("coverage")) { + println(coverage) + testCoverageEnabled = coverage.enableTestCoverage + } // Set to true to log privacy or sensible data, such as token buildConfigField "boolean", "LOG_PRIVATE_DATA", project.property("vector.debugPrivateData") // Set to BODY instead of NONE to enable logging diff --git a/vector/build.gradle b/vector/build.gradle index 95e4b29007..072c5b99e4 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -9,6 +9,10 @@ apply plugin: 'com.likethesalad.stem' apply plugin: 'dagger.hilt.android.plugin' apply plugin: 'kotlinx-knit' +if (project.hasProperty("coverage")) { + apply plugin: 'jacoco' +} + kapt { correctErrorTypes = true } @@ -119,8 +123,6 @@ ext.abiVersionCodes = ["armeabi-v7a": 1, "arm64-v8a": 2, "x86": 3, "x86_64": 4]. def buildNumber = System.env.BUILDKITE_BUILD_NUMBER as Integer ?: 0 android { - - // Due to a bug introduced in Android gradle plugin 3.6.0, we have to specify the ndk version to use // Ref: https://issuetracker.google.com/issues/144111441 ndkVersion "21.3.6528147" @@ -145,7 +147,7 @@ android { versionName "${versionMajor}.${versionMinor}.${versionPatch}-sonar" // Generate a random app task affinity - manifestPlaceholders = [appTaskAffinitySuffix:"H_${gitRevision()}"] + manifestPlaceholders = [appTaskAffinitySuffix: "H_${gitRevision()}"] buildConfigField "String", "GIT_REVISION", "\"${gitRevision()}\"" buildConfigField "String", "GIT_REVISION_DATE", "\"${gitRevisionDate()}\"" @@ -244,7 +246,10 @@ android { buildConfigField "boolean", "ENABLE_STRICT_MODE_LOGS", "false" signingConfig signingConfigs.debug - testCoverageEnabled true + + if (project.hasProperty("coverage")) { + testCoverageEnabled = coverage.enableTestCoverage + } } release {