'Failed to enable code coverage: TypeError: Cannot read properties of undefined (reading 'split')' error when enabling JaCoCo coverage on Ant task without supplying optional input
ataverascrespo opened this issue · 0 comments
The issue was previously opened in the azure-pipelines-tasks
repo, as issue #19724, but I will be re-opening the issue in this repo (the correct one).
To summarize, when creating an Azure DevOps build pipeline, and working with Ant@V1 task, enabling JaCoCo code coverage is failing, and is generating the following error:
##[warning]Failed to enable code coverage: TypeError: Cannot read properties of undefined (reading 'split')
Here is the log output:
masking file paths with (...)
##[debug]classFilter=undefined
##[debug]classFilesDirectories=build/src/
##[debug]srcDirectories=undefined
##[debug]rm -rf (...)/cobertura.ser
##[debug]rm -rf (...)/CCReport43F6D5EF
##[debug]removing directory
##[debug]rm -rf (...)/CCReportBuildA4D283EG.xml
##[debug]removing file
##[debug]rm -rf (...)/InstrumentedClasses
##[debug]Input parameters: {"buildfile":"(...)/build.xml","classfilesdirectories":"build/src/","summaryfile":"summary.xml","reportdirectory":"(...)/CCReport43F6D5EF","ccreporttask":"CodeCoverage_9064e1d0","reportbuildfile":"(...)/CCReportBuildA4D283EG.xml"}
##[debug]Extracting Azure Pipelines filter: undefined
##[debug]Applying the filter pattern: op:
##[debug]Applying the filter pattern: op:
##[debug]Reading XML file: (...)/build.xml
##[debug]Converting XML file to JSON
##[warning]Failed to enable code coverage: TypeError: Cannot read properties of undefined (reading 'split')
##[debug]Processed: ##vso[task.issue type=warning;]Failed to enable code coverage: TypeError: Cannot read properties of undefined (reading 'split')
This error was generated with the following YAML configuration for the Ant@V1 task:
codeCoverageToolOptions: 'JaCoCo'
codeCoverageClassFilesDirectories: 'build/src/'
After several days of debugging, our team found the issue was able to be resolved by adding the following optional field to the YAML configuration for the Ant@V1 task:
codeCoverageSourceDirectories: 'components/src/'
This is inconsistent with the Ant@V1 documentation, which states the codeCoverageSourceDirectories
input is optional when codeCoverageToolOptions != None
. I looked into the JaCoCo code coverage functions and believe I found the root cause of the issue in the enableCodeCoverage()
function in the jacoco.ant.cc.enabler class.
In enableCodeCoverage()
, the global sourceDirs
variable is set to the value of ccProps["sourcedirectories"]
, which contains the value of the INPUT_SRCDIRECTORIES
environment variable passed from the Ant task.
From there, addCodeCoverageData()
is called, which then calls getSourceFilter()
.
protected getSourceFilter(): string {
let srcData = "";
let srcDirs = this.sourceDirs === null ? "" : this.sourceDirs;
srcDirs.split(",").forEach(dir => {
if (!util.isNullOrWhitespace(dir)) {
srcData += `<fileset dir="${dir}"/>`;
srcData += os.EOL;
}
});
if (util.isNullOrWhitespace(srcData)) {
srcData = `<fileset dir="."/>`;
srcData += os.EOL;
}
return srcData;
}
If the codeCoverageSourceDirectories
YAML input is not given a value, then INPUT_SRCDIRECTORIES
is undefined, meaning the value of global var sourceDirs
is set to undefined. Thus, calling split()
on an undefined value generates the error and causes JaCoCo code coverage to fail on the pipeline.
I believe the issue is due to a lack of handling undefined values. At the same time, that doesn't seem to affect that classFilter
variable when that value is undefined. I have reproduced this on several build pipelines, all to the same effect. This probably just needs a bare minimum change like
if (srcDirs) {
srcDirs.split(",").forEach(dir => {
// continues if srcDirs != undefined
});
}
else {
// continues if srcDirs == undefined
}
but not sure if anyone has run into this issue ever...