Bug 1473313 - Part 1: Set up geckoview build config for androidTest coverage runs. r=nalexander

This patch adds JaCoCo as a dependency for the geckoview androidTest configurations, as well as
the `mach android archive-geckoview-coverage-artifacts` command, and the `--enable-java-coverage`
mozconfig flag.

MozReview-Commit-ID: 36jNAzK44g3

--HG--
extra : rebase_source : 9edc37913a3929ad045270c601c77791d122e363
This commit is contained in:
Tudor-Gabriel Vîjială 2018-07-24 11:44:24 +01:00
parent 357b6b1348
commit ae279dbf60
9 changed files with 134 additions and 6 deletions

View File

@ -52,6 +52,7 @@ buildscript {
ext.kotlin_version = '1.2.41'
ext.support_library_version = '26.1.0'
ext.jacoco_version = '0.8.1'
if (gradle.mozconfig.substs.MOZ_ANDROID_GOOGLE_PLAY_SERVICES) {
ext.google_play_services_version = '15.0.1'

View File

@ -66,3 +66,10 @@ def javac_version(javac):
return version
except subprocess.CalledProcessError as e:
die('Failed to get javac version: %s', e.output)
# Java Code Coverage
# ========================================================
option('--enable-java-coverage', env='MOZ_JAVA_CODE_COVERAGE', help='Enable Java code coverage')
set_config('MOZ_JAVA_CODE_COVERAGE', depends('--enable-java-coverage')(lambda v: bool(v)))

View File

@ -34,6 +34,9 @@ ac_add_options --target=arm-linux-androideabi
ac_add_options --with-branding=mobile/android/branding/nightly
# Pull code coverage dependencies too.
ac_add_options --enable-java-coverage
export MOZILLA_OFFICIAL=1
export MOZ_TELEMETRY_REPORTING=1
export MOZ_ANDROID_MMA=1

View File

@ -165,6 +165,11 @@
# See: http://stackoverflow.com/questions/22441366/note-android-support-v4-text-icucompatics-cant-find-dynamically-referenced-cl
-dontnote android.support.**
# Don't warn when classes referenced by JaCoCo are missing when running the build from android-dependencies.
-dontwarn java.lang.instrument.**
-dontwarn java.lang.management.**
-dontwarn javax.management.**
-include "adjust-keeps.cfg"
-include "leakcanary-keeps.cfg"

View File

@ -372,3 +372,71 @@ apply from: "${topsrcdir}/mobile/android/gradle/jacoco_dependencies.gradle"
if (project.hasProperty('enable_code_coverage')) {
apply from: "${topsrcdir}/mobile/android/gradle/jacoco_for_junit.gradle"
}
// Set up code coverage for tests on emulators.
if (mozconfig.substs.MOZ_JAVA_CODE_COVERAGE) {
apply plugin: "jacoco"
jacoco {
toolVersion = "${project.jacoco_version}"
}
android {
jacoco {
version = "$jacoco_version"
}
buildTypes {
debug {
testCoverageEnabled true
}
}
}
configurations {
// This configuration is used for dependencies that are not needed at compilation or
// runtime, but need to be exported as artifacts of the build for usage on the testing
// machines.
coverageDependency
}
dependencies {
// This is required both in the instrumented application classes and the test classes,
// so `api` has to be used instead of `androidTestImplementation`.
api "org.jacoco:org.jacoco.agent:$jacoco_version:runtime"
coverageDependency ("org.jacoco:org.jacoco.cli:$jacoco_version:nodeps") {
exclude group: 'org.ow2.asm', module: '*'
}
}
// This task is used by `mach android archive-geckoview-coverage-artifacts`.
task copyCoverageDependencies(type: Copy) {
from(configurations.coverageDependency) {
include 'org.jacoco.cli-*-nodeps.jar'
rename { _ -> 'target.jacoco-cli.jar' }
}
into "$buildDir/coverage"
}
// Generate tasks to archive compiled classfiles for later use with JaCoCo report generation.
// One of these tasks is used by `mach android archive-geckoview-coverage-artifacts`.
android.libraryVariants.all { variant ->
def name = variant.name
def compileTask = tasks.getByName("compile${name.capitalize()}JavaWithJavac")
task "archiveClassfiles${name.capitalize()}"(type: Zip, dependsOn: compileTask) {
description = "Archive compiled classfiles for $name in order to export them as code coverage artifacts."
def fileFilter = ['**/androidTest/**',
'**/test/**',
'**/R.class',
'**/R$*.class',
'**/BuildConfig.*',
'**/Manifest*.*',
'**/*Test*.*',
'android/**/*.*']
from fileTree(dir: compileTask.destinationDir, excludes: fileFilter)
destinationDir = file("${buildDir}/coverage")
// Note: This task assumes only one variant of archiveClassfiles* will be used.
// Running multiple variants of this task will overwrite the output archive.
archiveName = 'target.geckoview_classfiles.zip'
}
}
}

View File

@ -237,6 +237,18 @@ def gradle_android_archive_geckoview_tasks(build_config):
set_config('GRADLE_ANDROID_ARCHIVE_GECKOVIEW_TASKS', gradle_android_archive_geckoview_tasks)
@depends(gradle_android_build_config)
def gradle_android_archive_geckoview_coverage_artifacts_tasks(build_config):
'''Gradle tasks run by |mach android archive-geckoview-coverage-artifacts|.'''
return [
'geckoview:archiveClassfiles{geckoview.variant.name}'.format(geckoview=build_config.geckoview),
'geckoview:copyCoverageDependencies',
]
set_config('GRADLE_ANDROID_ARCHIVE_GECKOVIEW_COVERAGE_ARTIFACTS_TASKS',
gradle_android_archive_geckoview_coverage_artifacts_tasks)
@depends(
gradle_android_app_tasks,
gradle_android_test_tasks,
@ -247,6 +259,7 @@ set_config('GRADLE_ANDROID_ARCHIVE_GECKOVIEW_TASKS', gradle_android_archive_geck
gradle_android_generate_sdk_bindings_tasks,
gradle_android_generate_generated_jni_wrappers_tasks,
gradle_android_generate_fennec_jni_wrappers_tasks,
gradle_android_archive_geckoview_coverage_artifacts_tasks,
)
@imports(_from='itertools', _import='imap')
@imports(_from='itertools', _import='chain')

View File

@ -3,11 +3,9 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
project.ext.jacoco_version = "0.7.8"
dependencies {
testImplementation "org.jacoco:org.jacoco.agent:${project.jacoco_version}"
testImplementation "org.jacoco:org.jacoco.ant:${project.jacoco_version}"
testImplementation "org.jacoco:org.jacoco.core:${project.jacoco_version}"
testImplementation "org.jacoco:org.jacoco.report:${project.jacoco_version}"
testImplementation "org.jacoco:org.jacoco.agent:$jacoco_version"
testImplementation "org.jacoco:org.jacoco.ant:$jacoco_version"
testImplementation "org.jacoco:org.jacoco.core:$jacoco_version"
testImplementation "org.jacoco:org.jacoco.report:$jacoco_version"
}

View File

@ -413,6 +413,15 @@ class MachCommands(MachCommandBase):
return 0
@SubCommand('android', 'archive-geckoview-coverage-artifacts',
"""Archive compiled geckoview classfiles to be used later in generating code coverage reports.""") # NOQA: E501
@CommandArgument('args', nargs=argparse.REMAINDER)
def android_archive_geckoview_classfiles(self, args):
self.gradle(self.substs['GRADLE_ANDROID_ARCHIVE_GECKOVIEW_COVERAGE_ARTIFACTS_TASKS'] +
["--continue"] + args, verbose=True)
return 0
@SubCommand('android', 'archive-geckoview',
"""Create GeckoView archives.
See http://firefox-source-docs.mozilla.org/build/buildsystem/toolchains.html#firefox-for-android-with-gradle""") # NOQA: E501

View File

@ -512,6 +512,7 @@ class TestChecksConfigure(unittest.TestCase):
'JAR': jar,
'JARSIGNER': jarsigner,
'KEYTOOL': keytool,
'MOZ_JAVA_CODE_COVERAGE': False,
})
self.assertEqual(out, textwrap.dedent('''\
checking for java... %s
@ -555,6 +556,7 @@ class TestChecksConfigure(unittest.TestCase):
'JAR': alt_jar,
'JARSIGNER': alt_jarsigner,
'KEYTOOL': alt_keytool,
'MOZ_JAVA_CODE_COVERAGE': False,
})
self.assertEqual(out, textwrap.dedent('''\
checking for java... %s
@ -584,6 +586,7 @@ class TestChecksConfigure(unittest.TestCase):
'JAR': alt_jar,
'JARSIGNER': alt_jarsigner,
'KEYTOOL': alt_keytool,
'MOZ_JAVA_CODE_COVERAGE': False,
})
self.assertEqual(out, textwrap.dedent('''\
checking for java... %s
@ -614,6 +617,7 @@ class TestChecksConfigure(unittest.TestCase):
'JAR': alt_jar,
'JARSIGNER': alt_jarsigner,
'KEYTOOL': alt_keytool,
'MOZ_JAVA_CODE_COVERAGE': False,
})
self.assertEqual(out, textwrap.dedent('''\
checking for java... %s
@ -626,6 +630,26 @@ class TestChecksConfigure(unittest.TestCase):
''' % (alt_java, alt_javah, alt_jar, alt_jarsigner,
alt_keytool, alt_javac)))
# --enable-java-coverage should set MOZ_JAVA_CODE_COVERAGE.
config, out, status = self.get_result(
args=['--enable-java-coverage'],
includes=includes,
extra_paths=paths,
environ={
'PATH': mozpath.dirname(java),
'JAVA_HOME': mozpath.dirname(mozpath.dirname(java)),
})
self.assertEqual(status, 0)
self.assertEqual(config, {
'JAVA': java,
'JAVAH': javah,
'JAVAC': javac,
'JAR': jar,
'JARSIGNER': jarsigner,
'KEYTOOL': keytool,
'MOZ_JAVA_CODE_COVERAGE': True,
})
def mock_old_javac(_, args):
if len(args) == 1 and args[0] == '-version':
return 0, '1.6.9', ''