diff --git a/modules/integration/tests-common/jacoco-report-generator/src/main/java/org/wso2/carbon/identity/jacoco/CodeCoverageUtils.java b/modules/integration/tests-common/jacoco-report-generator/src/main/java/org/wso2/carbon/identity/jacoco/CodeCoverageUtils.java deleted file mode 100644 index 3eec7c2b4d..0000000000 --- a/modules/integration/tests-common/jacoco-report-generator/src/main/java/org/wso2/carbon/identity/jacoco/CodeCoverageUtils.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). - * - * WSO2 LLC. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.wso2.carbon.identity.jacoco; - -import org.codehaus.plexus.util.DirectoryScanner; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; - -/** - * Utility class for code coverage related operations. - */ -public class CodeCoverageUtils { - - private static final int BUFFER_SIZE = 1024; - private static final String INVALID_EXTENSION_ERROR = "Invalid extension: %s is invalid"; - private static final String EXTRACTION_ERROR = "Error on archive extraction"; - - /** - * Extract jar files given at jar file path - * - * @param jarFilePath - Jar file path - * @param tempDir - Temporary directory to extract jar file - * @return - Jar file extracted directory. - * @throws IOException - Throws if jar extraction fails - */ - public synchronized static String extractJarFile(String jarFilePath, File tempDir) throws IOException { - - if (!jarFilePath.endsWith(".war") && !jarFilePath.endsWith(".jar")) { - throw new IllegalArgumentException(String.format(INVALID_EXTENSION_ERROR, jarFilePath)); - } - - String jarFileName = new File(jarFilePath).getName(); - String tempExtractedDir = new File(tempDir, jarFileName.substring(0, jarFileName.lastIndexOf('.'))).getPath(); - - try { - extractFile(jarFilePath, tempExtractedDir); - } catch (IOException e) { - throw new IOException("Could not extract the file " + jarFileName, e); - } - return tempExtractedDir; - } - - /** - * Scan given directory for include and exclude patterns. - * - * @param jarExtractedDir - Path to check for given include/exclude pattern - * @param includes - Include pattern array - * @param excludes - Exclude class pattern array - * @return - Included files - * @throws IOException - Throws if given directory path cannot be found. - */ - public static String[] scanDirectory(String jarExtractedDir, String[] includes, - String[] excludes) throws IOException { - - DirectoryScanner ds = new DirectoryScanner(); - - ds.setIncludes(includes); - ds.setExcludes(excludes); - ds.setBasedir(new File(jarExtractedDir)); - ds.setCaseSensitive(true); - - ds.scan(); - return ds.getIncludedFiles(); - } - - private static void extractFile(String sourceFilePath, String extractedDir) throws IOException { - - byte[] buf = new byte[BUFFER_SIZE]; - try (ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(sourceFilePath))) { - ZipEntry zipEntry; - while ((zipEntry = zipInputStream.getNextEntry()) != null) { - File newFile = new File(extractedDir, zipEntry.getName()); - if (zipEntry.isDirectory()) { - if (!newFile.isDirectory() && !newFile.mkdirs()) { - throw new IOException("Failed to create directory " + newFile); - } - } else { - File parent = newFile.getParentFile(); - if (!parent.isDirectory() && !parent.mkdirs()) { - throw new IOException("Failed to create directory " + parent); - } - try (FileOutputStream fos = new FileOutputStream(newFile)) { - int len; - while ((len = zipInputStream.read(buf)) > 0) { - fos.write(buf, 0, len); - } - } - } - zipInputStream.closeEntry(); - } - } catch (IOException e) { - throw new IOException(EXTRACTION_ERROR, e); - } - } -} diff --git a/modules/integration/tests-common/jacoco-report-generator/src/main/java/org/wso2/carbon/identity/jacoco/ReportGenerator.java b/modules/integration/tests-common/jacoco-report-generator/src/main/java/org/wso2/carbon/identity/jacoco/ReportGenerator.java index 6f4b0dc02f..044092d778 100644 --- a/modules/integration/tests-common/jacoco-report-generator/src/main/java/org/wso2/carbon/identity/jacoco/ReportGenerator.java +++ b/modules/integration/tests-common/jacoco-report-generator/src/main/java/org/wso2/carbon/identity/jacoco/ReportGenerator.java @@ -18,6 +18,7 @@ package org.wso2.carbon.identity.jacoco; +import org.codehaus.plexus.util.DirectoryScanner; import org.codehaus.plexus.util.FileUtils; import org.jacoco.core.analysis.Analyzer; import org.jacoco.core.analysis.CoverageBuilder; @@ -28,6 +29,7 @@ import org.jacoco.report.xml.XMLFormatter; import java.io.File; +import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; @@ -35,14 +37,18 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; /** - * This will create an XML report projects based on a - * single execution data store called jacoco.exec. + * This will create an XML report projects based on a single execution data store called jacoco.exec. */ public class ReportGenerator { - public static final String CLASS_FILE_PATTERN = "**/*.class"; + private static final String CLASS_FILE_PATTERN = "**/*.class"; + private static final int BUFFER_SIZE = 1024; + private static final String INVALID_EXTENSION_ERROR = "Invalid extension: %s is invalid"; + private static final String EXTRACTION_ERROR = "Error on archive extraction"; private final String title; private final File executionDataFile; @@ -52,6 +58,35 @@ public class ReportGenerator { private ExecFileLoader execFileLoader; + /** + * Starts the report generation process + * + * @param args Arguments to the report generation. + * [ ...] + * @throws IOException + */ + public static void main(final String[] args) throws IOException { + + if (args.length < 2) { + System.err.println("Usage: java -jar ReportGenerator.jar " + + "[ ...]"); + System.exit(1); + } + + File executionDataFile = new File(args[0]); + Set classDirectories = new HashSet<>(); + for (int i = 1; i < args.length; i++) { + classDirectories.add(new File(args[i])); + } + + try { + final ReportGenerator generator = new ReportGenerator(executionDataFile, classDirectories); + generator.create(); + } catch (Exception e) { + System.err.println("Error while creating report: " + e.getMessage()); + } + } + /** * Create a new generator based for the given project. * @@ -76,50 +111,22 @@ public ReportGenerator(File executionDataFile, Set classDirectories) { /** * Create the report. * - * @throws IOException + * @throws IOException - Throws if report creation fails */ public void create() throws IOException { - // Read the jacoco.exec file. Multiple data files could be merged - // at this point + // Read the jacoco.exec file. Multiple data files could be merged at this point loadExecutionData(); - // Run the structure analyzer on a single class folder to build up - // the coverage model. The process would be similar if your classes - // were in a jar file. Typically you would create a bundle for each - // class folder and each jar you want in your report. If you have - // more than one bundle you will need to add a grouping node to your - // report + // Run the structure analyzer on a single class folder to build up the coverage model. The process would be + // similar if your classes were in a jar file. Typically, you would create a bundle for each class folder and + // each jar you want in your report. If you have more than one bundle you will need to add a grouping node to + // your report. final IBundleCoverage bundleCoverage = analyzeStructure(); createReport(bundleCoverage); } - private void createReport(final IBundleCoverage bundleCoverage) throws IOException { - - // Create a concrete report visitor based on some supplied - // configuration. In this case we use the defaults - try (FileOutputStream fos = new FileOutputStream(xmlReport)) { - final XMLFormatter xmlFormatter = new XMLFormatter(); - final IReportVisitor visitor = xmlFormatter.createVisitor(fos); - - // Initialize the report with all the execution and session - // information. At this point the report doesn't know about the - // structure of the report being created - visitor.visitInfo(execFileLoader.getSessionInfoStore().getInfos(), - execFileLoader.getExecutionDataStore().getContents()); - - // Populate the report structure with the bundle coverage information. - // Call visitGroup if you need groups in your report. - visitor.visitBundle(bundleCoverage, - new DirectorySourceFileLocator(null, "utf-8", 4)); - - // Signal end of structure information to allow report to write all - // information out - visitor.visitEnd(); - } - } - private void loadExecutionData() throws IOException { execFileLoader = new ExecFileLoader(); @@ -136,7 +143,9 @@ private IBundleCoverage analyzeStructure() throws IOException { for (File classDirectory : classDirectories) { // Jar files to analyze - File[] files = classDirectory.listFiles((dir, name) -> name.startsWith("org.wso2.carbon") && !name.contains(".stub_")); + File[] files = + classDirectory.listFiles((dir, name) + -> name.startsWith("org.wso2.carbon") && !name.contains(".stub_")); if (files != null) { jarFilesToAnalyze.addAll(Arrays.asList(files)); } @@ -152,8 +161,8 @@ private IBundleCoverage analyzeStructure() throws IOException { String[] excludes = {"-*.stub*", "-*.stub_", "-*.stub_4.0.0", "-*.stub-"}; for (final File jarFile : jarFilesToAnalyze) { - String extractedDir = CodeCoverageUtils.extractJarFile(jarFile.getAbsolutePath(), tempDirectory); - String[] classFiles = CodeCoverageUtils.scanDirectory(extractedDir, includes, excludes); + String extractedDir = extractJarFile(jarFile.getAbsolutePath(), tempDirectory); + String[] classFiles = scanDirectory(extractedDir, includes, excludes); for (String classFile : classFiles) { analyzer.analyzeAll(new File(extractedDir + File.separator + classFile)); @@ -168,31 +177,108 @@ private IBundleCoverage analyzeStructure() throws IOException { return coverageBuilder.getBundle(title); } + private void createReport(final IBundleCoverage bundleCoverage) throws IOException { + + // Create a concrete report visitor based on some supplied configuration. In this case we use the defaults + try (FileOutputStream fos = new FileOutputStream(xmlReport)) { + final XMLFormatter xmlFormatter = new XMLFormatter(); + final IReportVisitor visitor = xmlFormatter.createVisitor(fos); + + // Initialize the report with all the execution and session information. At this point the report doesn't + // know about the structure of the report being created + visitor.visitInfo(execFileLoader.getSessionInfoStore().getInfos(), + execFileLoader.getExecutionDataStore().getContents()); + + // Populate the report structure with the bundle coverage information. + // Call visitGroup if you need groups in your report. + visitor.visitBundle(bundleCoverage, + new DirectorySourceFileLocator(null, "utf-8", 4)); + + // Signal end of structure information to allow report to write all information out. + visitor.visitEnd(); + } + } + /** - * Starts the report generation process + * Extract jar files given at jar file path * - * @param args Arguments to the report generation. - * [ ...] - * @throws IOException + * @param jarFilePath - Jar file path + * @param tempDir - Temporary directory to extract jar file + * @return - Jar file extracted directory. + * @throws IOException - Throws if jar extraction fails */ - public static void main(final String[] args) throws IOException { + private synchronized String extractJarFile(String jarFilePath, File tempDir) throws IOException { - if (args.length < 2) { - System.err.println("Usage: java -jar ReportGenerator.jar [ ...]"); - System.exit(1); + if (!jarFilePath.endsWith(".war") && !jarFilePath.endsWith(".jar")) { + throw new IllegalArgumentException(String.format(INVALID_EXTENSION_ERROR, jarFilePath)); } - File executionDataFile = new File(args[0]); - Set classDirectories = new HashSet<>(); - for (int i = 1; i < args.length; i++) { - classDirectories.add(new File(args[i])); - } + String jarFileName = new File(jarFilePath).getName(); + String tempExtractedDir = new File(tempDir, jarFileName.substring(0, jarFileName.lastIndexOf('.'))).getPath(); try { - final ReportGenerator generator = new ReportGenerator(executionDataFile, classDirectories); - generator.create(); - } catch (Exception e) { - System.err.println("Error while creating report: " + e.getMessage()); + extractFile(jarFilePath, tempExtractedDir); + } catch (IOException e) { + throw new IOException("Could not extract the file " + jarFileName, e); + } + return tempExtractedDir; + } + + /** + * Scan given directory for include and exclude patterns. + * + * @param jarExtractedDir - Path to check for given include/exclude pattern + * @param includes - Include pattern array + * @param excludes - Exclude class pattern array + * @return - Included files + */ + private String[] scanDirectory(String jarExtractedDir, String[] includes, String[] excludes) { + + DirectoryScanner ds = new DirectoryScanner(); + + ds.setIncludes(includes); + ds.setExcludes(excludes); + ds.setBasedir(new File(jarExtractedDir)); + ds.setCaseSensitive(true); + + ds.scan(); + return ds.getIncludedFiles(); + } + + /** + * Extract the given archive file to the given directory + * + * @param sourceFilePath - Path to the archive file + * @param extractedDir - Path to the directory to extract the archive file + * @throws IOException - Throws if extraction fails + */ + private void extractFile(String sourceFilePath, String extractedDir) throws IOException { + + byte[] buf = new byte[BUFFER_SIZE]; + try (ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(sourceFilePath))) { + ZipEntry zipEntry; + while ((zipEntry = zipInputStream.getNextEntry()) != null) { + File newFile = new File(extractedDir, zipEntry.getName()); + if (zipEntry.isDirectory()) { + if (!newFile.isDirectory() && !newFile.mkdirs()) { + throw new IOException("Failed to create directory " + newFile); + } + } else { + File parent = newFile.getParentFile(); + if (!parent.isDirectory() && !parent.mkdirs()) { + throw new IOException("Failed to create directory " + parent); + } + try (FileOutputStream fos = new FileOutputStream(newFile)) { + int len; + while ((len = zipInputStream.read(buf)) > 0) { + fos.write(buf, 0, len); + } + } + } + zipInputStream.closeEntry(); + } + } catch (IOException e) { + throw new IOException(EXTRACTION_ERROR, e); } } }