-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #70 from cqse/ts/41282_xcresult_missing_coverage_r…
…eworked_internals TS-41282 XCResult coverage conversion extracts coverage from only one test plan in case there are multiple
- Loading branch information
Showing
14 changed files
with
693 additions
and
474 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
30 changes: 30 additions & 0 deletions
30
src/main/java/com/teamscale/upload/xcode/ConversionException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package com.teamscale.upload.xcode; | ||
|
||
import com.teamscale.upload.autodetect_revision.ProcessUtils; | ||
|
||
/** | ||
* Custom exception used to indicate errors during conversion. | ||
*/ | ||
public class ConversionException extends Exception { | ||
|
||
public ConversionException(String message) { | ||
super(message); | ||
} | ||
|
||
public ConversionException(String message, Exception e) { | ||
super(message, e); | ||
} | ||
|
||
/** | ||
* Creates a {@link ConversionException} with the given message and the | ||
* {@linkplain ProcessUtils.ProcessResult#errorOutput error output of the | ||
* command}. | ||
*/ | ||
public static ConversionException withProcessResult(String message, ProcessUtils.ProcessResult processResult) { | ||
String messageIncludingErrorOutput = message; | ||
if (processResult.errorOutput != null) { | ||
messageIncludingErrorOutput += " (command output: " + processResult.errorOutput + ")"; | ||
} | ||
return new ConversionException(messageIncludingErrorOutput, processResult.exception); | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
src/main/java/com/teamscale/upload/xcode/ConversionFunction.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package com.teamscale.upload.xcode; | ||
|
||
import java.io.IOException; | ||
|
||
/** Functional interface that represents a conversion function. */ | ||
@FunctionalInterface | ||
public interface ConversionFunction<T> { | ||
|
||
/** Runs the conversion function. */ | ||
T run() throws ConversionException, IOException; | ||
} |
69 changes: 69 additions & 0 deletions
69
src/main/java/com/teamscale/upload/xcode/ConversionUtils.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package com.teamscale.upload.xcode; | ||
|
||
import java.io.File; | ||
import java.io.IOException; | ||
|
||
/** Utilities for converting Xcode coverage reports. */ | ||
public class ConversionUtils { | ||
/** | ||
* File extension used for converted XCResult bundles. | ||
*/ | ||
public static final String XCCOV_REPORT_FILE_EXTENSION = ".xccov"; | ||
|
||
/** | ||
* File extension used for xccov archives | ||
* | ||
* @see #isXccovArchive(File) | ||
*/ | ||
public static final String XCCOV_ARCHIVE_FILE_EXTENSION = ".xccovarchive"; | ||
|
||
/** | ||
* File extension used for xcresult files | ||
* | ||
* @see #isXccovArchive(File) | ||
*/ | ||
public static final String XCRESULT_FILE_EXTENSION = ".xcresult"; | ||
|
||
/** | ||
* Returns true if the file is a regular XCResult bundle directory indicated by | ||
* the ".xcresult" ending in the directory name. | ||
*/ | ||
public static boolean isXcresultBundle(File file) { | ||
return file.isDirectory() && file.getName().endsWith(XCRESULT_FILE_EXTENSION); | ||
} | ||
|
||
/** | ||
* Returns true if the file is a xccov archive which is more compact than a | ||
* regular XCResult bundle. A xccov archive can only be generated by XCode | ||
* internal tooling but provides much better performance when extracting | ||
* coverage. Note that xccov archives don't contain test results. | ||
*/ | ||
public static boolean isXccovArchive(File file) { | ||
return file.isDirectory() && file.getName().endsWith(XCCOV_ARCHIVE_FILE_EXTENSION); | ||
} | ||
|
||
/** | ||
* Runs the given conversions tasks and ensures that the given teardown is | ||
* executed, even after an interrupt. | ||
*/ | ||
public static <R> R runWithTeardown(ConversionFunction<R> execute, Runnable teardown) | ||
throws ConversionException, IOException { | ||
Thread cleanupShutdownHook = new Thread(teardown); | ||
try { | ||
Runtime.getRuntime().addShutdownHook(cleanupShutdownHook); | ||
|
||
return execute.run(); | ||
} finally { | ||
Runtime.getRuntime().removeShutdownHook(cleanupShutdownHook); | ||
teardown.run(); | ||
} | ||
} | ||
|
||
/** Removes the suffix from the given string, if present. */ | ||
public static String removeSuffix(String string, String suffix) { | ||
if (string.endsWith(suffix)) { | ||
string = string.substring(0, string.length() - suffix.length()); | ||
} | ||
return string; | ||
} | ||
} |
62 changes: 62 additions & 0 deletions
62
src/main/java/com/teamscale/upload/xcode/ConverterBase.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package com.teamscale.upload.xcode; | ||
|
||
import java.io.File; | ||
import java.io.IOException; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
|
||
/** | ||
* Base class for class that converts specific file formats into other formats. | ||
*/ | ||
/* package */ abstract class ConverterBase<T> { | ||
|
||
/** | ||
* The installed and used XCode version. Can be determined by | ||
* {@link XcodeVersion#determine()}. | ||
* | ||
* @implNote The version should be determined by the caller and passed to this | ||
* class (i.e., instead of determining it in this class). This is | ||
* because when multiple {@link XcresultConverter} are created, we | ||
* want to show warnings/errors related to the version determination | ||
* only once | ||
*/ | ||
private final XcodeVersion xcodeVersion; | ||
|
||
/** The directory where intermediate results can be stored. */ | ||
private final Path workingDirectory; | ||
|
||
/** The directory where the final conversion results are stored. */ | ||
private Path outputDirectory; | ||
|
||
public ConverterBase(XcodeVersion xcodeVersion, Path workingDirectory) { | ||
this.xcodeVersion = xcodeVersion; | ||
this.workingDirectory = workingDirectory; | ||
} | ||
|
||
/** Converts a single file into the expected output format. */ | ||
abstract T convert(File file) throws ConversionException, IOException; | ||
|
||
/** | ||
* Returns the path under which an output file with the given name should be | ||
* stored. Does not create the file though. | ||
*/ | ||
public Path getOutputFilePath(String name) throws IOException { | ||
if (outputDirectory == null) { | ||
outputDirectory = Files.createTempDirectory(getWorkingDirectory(), this.getClass().getSimpleName()); | ||
} | ||
return outputDirectory.resolve(name); | ||
} | ||
|
||
/** Creates a file where the outputs of the converter can be written to. */ | ||
public File createOutputFile(String name) throws IOException { | ||
return Files.createFile(getOutputFilePath(name)).toFile(); | ||
} | ||
|
||
public XcodeVersion getXcodeVersion() { | ||
return xcodeVersion; | ||
} | ||
|
||
public Path getWorkingDirectory() { | ||
return workingDirectory; | ||
} | ||
} |
44 changes: 44 additions & 0 deletions
44
src/main/java/com/teamscale/upload/xcode/TarArchiveConverter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package com.teamscale.upload.xcode; | ||
|
||
import java.io.File; | ||
import java.io.IOException; | ||
import java.nio.file.Path; | ||
import java.util.Collections; | ||
import java.util.List; | ||
|
||
import com.teamscale.upload.utils.FileSystemUtils; | ||
|
||
/** | ||
* Converts a {@link FileSystemUtils#isTarFile(File) tar file} into the | ||
* {@value ConversionUtils#XCCOV_REPORT_FILE_EXTENSION} format. | ||
*/ | ||
/* package */ class TarArchiveConverter extends ConverterBase<List<File>> { | ||
|
||
public TarArchiveConverter(XcodeVersion xcodeVersion, Path workingDirectory) { | ||
super(xcodeVersion, workingDirectory); | ||
} | ||
|
||
@Override | ||
public List<File> convert(File tarFile) throws ConversionException, IOException { | ||
File xcodeReport = extractTar(tarFile); | ||
|
||
if (ConversionUtils.isXccovArchive(xcodeReport)) { | ||
return Collections.singletonList( | ||
new XccovArchiveConverter(getXcodeVersion(), getWorkingDirectory()).convert(xcodeReport)); | ||
} else if (ConversionUtils.isXcresultBundle(xcodeReport)) { | ||
return new XcresultConverter(getXcodeVersion(), getWorkingDirectory()).convert(xcodeReport); | ||
} | ||
|
||
throw new ConversionException( | ||
"Report location must be an existing directory with a name that ends with '.xcresult' or " | ||
+ "'.xccovarchive'. The directory may be contained in a tar archive indicated by the file " | ||
+ "extensions '.tar', '.tar.gz' or '.tgz'." + tarFile); | ||
} | ||
|
||
private File extractTar(File tarFile) throws IOException { | ||
String tarNameWithoutExtension = FileSystemUtils.stripTarExtension(tarFile.getName()); | ||
File destination = getWorkingDirectory().resolve(tarNameWithoutExtension).toFile(); | ||
FileSystemUtils.extractTarArchive(tarFile, destination); | ||
return destination; | ||
} | ||
} |
Oops, something went wrong.