Skip to content

Commit

Permalink
Merge pull request #28852 from anjaleeps/codecoveragexml
Browse files Browse the repository at this point in the history
Include coverage data from native libraries in the XML coverage report
  • Loading branch information
azinneera authored Feb 24, 2021
2 parents 97d7138 + 0c7d6ed commit 3171885
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ public void execute(Project project) {

try {
if (hasTests) {
generateCoverage(project, jarResolver, target);
generateCoverage(project, jarResolver, jBallerinaBackend, target);
generateHtmlReport(project, this.out, testReport, target);
}
} catch (IOException e) {
Expand All @@ -257,15 +257,17 @@ public void execute(Project project) {
cleanTempCache(project, cachesRoot);
}

private void generateCoverage(Project project, JarResolver jarResolver, Target target) throws IOException {
private void generateCoverage(Project project, JarResolver jarResolver, JBallerinaBackend jBallerinaBackend,
Target target) throws IOException {
// Generate code coverage
if (!coverage) {
return;
}
for (ModuleId moduleId : project.currentPackage().moduleIds()) {
Module module = project.currentPackage().module(moduleId);
CoverageReport coverageReport = new CoverageReport(module);
testReport.addCoverage(module.moduleName().toString(), coverageReport.generateReport(jarResolver));
testReport.addCoverage(module.moduleName().toString(), coverageReport.generateReport(jarResolver,
jBallerinaBackend));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,15 @@

import io.ballerina.projects.Document;
import io.ballerina.projects.DocumentId;
import io.ballerina.projects.JBallerinaBackend;
import io.ballerina.projects.JarResolver;
import io.ballerina.projects.Module;
import io.ballerina.projects.ModuleId;
import io.ballerina.projects.PlatformLibrary;
import io.ballerina.projects.PlatformLibraryScope;
import io.ballerina.projects.ResolvedPackageDependency;
import io.ballerina.projects.internal.model.Target;
import io.ballerina.projects.util.ProjectUtils;
import org.ballerinalang.test.runtime.util.CodeCoverageUtils;
import org.ballerinalang.test.runtime.util.TesterinaConstants;
import org.jacoco.core.analysis.Analyzer;
Expand Down Expand Up @@ -84,7 +90,8 @@ public CoverageReport(Module module) throws IOException {
*
* @throws IOException when file operations are failed
*/
public ModuleCoverage generateReport(JarResolver jarResolver) throws IOException {
public ModuleCoverage generateReport(JarResolver jarResolver, JBallerinaBackend jBallerinaBackend)
throws IOException {
String orgName = this.module.packageInstance().packageOrg().toString();
String packageName = this.module.packageInstance().packageName().toString();
String version = this.module.packageInstance().packageVersion().toString();
Expand All @@ -93,10 +100,10 @@ public ModuleCoverage generateReport(JarResolver jarResolver) throws IOException

if (!module.testDocumentIds().isEmpty()) {
filteredPathList =
filterPaths(jarResolver.getJarFilePathsRequiredForTestExecution(this.module.moduleName()));
filterPaths(jarResolver.getJarFilePathsRequiredForTestExecution(this.module.moduleName()),
jBallerinaBackend);
} else {
filteredPathList =
filterPaths(jarResolver.getJarFilePathsRequiredForExecution());
filteredPathList = filterPaths(jarResolver.getJarFilePathsRequiredForExecution(), jBallerinaBackend);
}

if (!filteredPathList.isEmpty()) {
Expand Down Expand Up @@ -199,19 +206,40 @@ private void createReport(final IBundleCoverage bundleCoverage, ModuleCoverage m
}
}

private List<Path> filterPaths(Collection<Path> pathCollection) {
private List<Path> filterPaths(Collection<Path> pathCollection, JBallerinaBackend jBallerinaBackend) {
List<Path> filteredPathList = new ArrayList<>();

List<Path> exclusionPathList = getExclusionJarList(jBallerinaBackend);
for (Path path : pathCollection) {
if (path.toString().contains(this.module.project().sourceRoot().toString()) &&
path.toString().contains(target.cachesPath().toString())) {
if (!exclusionPathList.contains(path)) {
filteredPathList.add(path);
}
}

return filteredPathList;
}

private List<Path> getExclusionJarList(JBallerinaBackend jBallerinaBackend) {
List<Path> exclusionPathList = new ArrayList<>();
module.packageInstance().getResolution().allDependencies()
.stream()
.map(ResolvedPackageDependency::packageInstance)
.forEach(pkg -> {
for (ModuleId dependencyModuleId : pkg.moduleIds()) {
Module dependencyModule = pkg.module(dependencyModuleId);
PlatformLibrary generatedJarLibrary = jBallerinaBackend.codeGeneratedLibrary(
pkg.packageId(), dependencyModule.moduleName());
exclusionPathList.add(generatedJarLibrary.path());
}
Collection<PlatformLibrary> otherJarDependencies = jBallerinaBackend.platformLibraryDependencies(
pkg.packageId(), PlatformLibraryScope.DEFAULT);
for (PlatformLibrary otherJarDependency : otherJarDependencies) {
exclusionPathList.add(otherJarDependency.path());
}
});
exclusionPathList.add(jBallerinaBackend.runtimeLibrary().path());
exclusionPathList.addAll(ProjectUtils.testDependencies());
return exclusionPathList;
}

private Collection<ISourceFileCoverage> modifySourceFiles(Collection<ISourceFileCoverage> sourcefiles) {
Collection<ISourceFileCoverage> modifiedSourceFiles = new ArrayList<>();
for (ISourceFileCoverage sourcefile : sourcefiles) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ public static void copyClassFilesToBinPath(Path destination, String destjarDir,

//Next we walk through extractedJarPath and copy only the class files
List<Path> pathList;
try (Stream<Path> walk = Files.walk(extractedJarPath, 5)) {
try (Stream<Path> walk = Files.walk(extractedJarPath)) {
pathList = walk.map(path -> path).filter(f -> f.toString().endsWith(".class")).collect(Collectors.toList());
} catch (IOException e) {
return;
Expand Down Expand Up @@ -140,16 +140,21 @@ public static void copyClassFilesToBinPath(Path destination, String destjarDir,
}

private static String resolveClassDir(Path classPath, String version) {
// Typical class path is .jar/<moduleName>/<version>/class
// This function extracts the <moduleName> to create a unique directory
// Typical class path is .jar/<moduleName>/<version>/class for .bal files
// This function extracts the <moduleName> to create a unique directory for .bal files
// For .java files, the parent directory of the class file is returned
version = version.replace(".", "_");
Path resolvedPath = classPath;
String pathVersion;
do {
resolvedPath = resolvedPath.getParent();
pathVersion = resolvedPath.getFileName().toString();
} while (!pathVersion.equals(version));
return resolvedPath.getParent().getFileName().toString();
if (!resolvedPath.toString().contains(version)) {
return resolvedPath.getParent().getFileName().toString();
} else {
String pathVersion;
do {
resolvedPath = resolvedPath.getParent();
pathVersion = resolvedPath.getFileName().toString();
} while (!pathVersion.equals(version));
return resolvedPath.getParent().getFileName().toString();
}
}

private static boolean isRequiredFile(String path, String orgName, String moduleName, String version) {
Expand All @@ -162,6 +167,8 @@ private static boolean isRequiredFile(String path, String orgName, String module
} else if (path.contains(
orgName + "/" + moduleName + "/" + version.replace(".", "_") + "/" + moduleName + ".class")) {
return false;
} else if (path.contains("module-info.class")) {
return false;
}
return true;
}
Expand Down

0 comments on commit 3171885

Please sign in to comment.