-
-
Save szigetics/9ace909a7f35a2f0f3043f90894fff4c to your computer and use it in GitHub Desktop.
A pair of scripts to help with basic parsing of LLVM code-coverage output data (nowadays the generated file's name is Coverage.profdata), as produced by Xcode 8.1 . The `cov-exclusions.txt` file can be used to exclude files and globs from the output. The generated output can be used for Teamcity code coverage reporting.
This file contains hidden or 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
| A pair of scripts to help with basic parsing of LLVM code-coverage output data | |
| (nowadays the generated file's name is Coverage.profdata), as produced by Xcode 8.1 . | |
| The `cov-exclusions.txt` file can be used to exclude files and globs from the output. | |
| The generated output can be used for Teamcity code coverage reporting. | |
| The generated output is fully compatible with Teamcity : | |
| the generated values are automatically processed by Teamcity and the results appears : | |
| - on the build result's overview tab and | |
| - on the build configuration's statistics tab. | |
| ref1.: https://confluence.jetbrains.com/pages/viewpage.action?pageId=74845225#HowTo...-ImportcoverageresultsinTeamCity | |
| ref2.: https://confluence.jetbrains.com/display/TCD10/Custom+Chart#CustomChart-predefinedStatisticsKeys | |
| This gist is originating from briancroom's gist : https://gist.github.com/briancroom/936a54108de98a63d8cf. | |
| Thank you really much briancroom for sharing those! |
This file contains hidden or 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
| SCHEME=$1 | |
| SOURCE_ROOT=$2 | |
| XCTESTRUN_ROOT=$3 | |
| DERIVED_DATA_ROOT=$4 | |
| ### | |
| SCRIPTDIR=`dirname "$BASH_SOURCE"` | |
| ABSOLUTE_SOURCE_ROOT=$(pushd "$SOURCE_ROOT"; pwd; popd) | |
| PROFDATA=$(find ${DERIVED_DATA_ROOT} -name "Coverage.profdata") | |
| echo "PROFDATA : $PROFDATA" | |
| BINARY=$(find ${XCTESTRUN_ROOT} -path "*${SCHEME}.app/${SCHEME}") | |
| echo "BINARY : $BINARY" | |
| if [[ -z $PROFDATA ]]; then | |
| echo "ERROR: Unable to find Coverage.profdata. Be sure to execute tests before running this script." | |
| exit 1 | |
| fi | |
| if [[ -z $BINARY ]]; then | |
| echo "ERROR: Unable to find binary. Make sure that you have given the correct parameters!" | |
| exit 1 | |
| fi | |
| #get the full file list based on Coverage.profdata -> remove the unnecessary lines from the output (both from it's head and it's tail) -> call xcrun llvm-cov report on the produced full file list -> using the python script : parse the output, and output the necessary Teamcity variables | |
| xcrun llvm-cov report -instr-profile ${PROFDATA} ${BINARY} | tail -n +3 | awk '{print $1}' | tail -r | tail -n +3 | tail -r | tr '\n' '\0' | \ | |
| xargs -0 xcrun llvm-cov report -instr-profile ${PROFDATA} ${BINARY} | "$SCRIPTDIR/parse-llvm-cov-report.py" |
This file contains hidden or 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
| MyClass.m | |
| *Pods* |
This file contains hidden or 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
| SCHEME=$1 | |
| SOURCE_ROOT=$2 | |
| XCODEPATH=$3 #example : /Applications/Xcode.app/Contents/Developer | |
| BUILD_CONFIG_NAME_CAPITAL="Debug" | |
| ### | |
| DERIVED_DATA_DIR="$SOURCE_ROOT/derivedDataDir" | |
| XCTESTRUN_ROOT="$SOURCE_ROOT/testSymRoot" | |
| echo "##teamcity[progressMessage 'Building Automated Tests']" | |
| SIMULATOR_DESTINATION_UUID=$(xcrun simctl list -j | python -c "import json,sys; obj=json.load(sys.stdin); iOS_10_1_Devices = obj['devices']['iOS 10.1']; iPhone6SImulatorsWithiOS_10_1 = [item for item in iOS_10_1_Devices if item['name'] == 'iPhone 6']; print(iPhone6SImulatorsWithiOS_10_1[0]['udid']) ") | |
| $XCODEPATH/usr/bin/xcodebuild build-for-testing -destination "platform=iOS Simulator,id=$SIMULATOR_DESTINATION_UUID" -enableCodeCoverage YES -project "$SOURCE_ROOT/$SCHEME.xcodeproj" -scheme $SCHEME -configuration "$BUILD_CONFIG_NAME_CAPITAL" -derivedDataPath "$DERIVED_DATA_DIR" SYMROOT="$XCTESTRUN_ROOT" | |
| echo "##teamcity[progressMessage 'Running Automated Tests']" | |
| XCTESTRUN_FILENAME=$(find $XCTESTRUN_ROOT -name "*.xctestrun") | |
| LOG_FILE_AUTOMATED_TESTS_RUN="$SOURCE_ROOT/xcodebuildAutomatedTestsRun.log" | |
| $XCODEPATH/usr/bin/xcodebuild test-without-building -destination "platform=iOS Simulator,id=$SIMULATOR_DESTINATION_UUID" -enableCodeCoverage YES -xctestrun $XCTESTRUN_FILENAME -derivedDataPath "$DERIVED_DATA_DIR" | tee -a "$LOG_FILE_AUTOMATED_TESTS_RUN" | xcpretty --report junit --output $SOURCE_ROOT/automated-test-results/TEST-UnitTests-$BUILD_CONFIG_NAME_CAPITAL.xml | |
| echo "##teamcity[importData type='junit' path='$SOURCE_ROOT/automated-test-results/TEST-UnitTests-$BUILD_CONFIG_NAME_CAPITAL.xml']" | |
| $SOURCE_ROOT/Code\ Coverage/code-coverage.sh $SCHEME $SOURCE_ROOT $XCTESTRUN_ROOT "$DERIVED_DATA_DIR" |
This file contains hidden or 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
| #!/usr/bin/python | |
| import os | |
| import sys | |
| import fnmatch | |
| currentFile = None | |
| covResults = [] | |
| inFile = open(sys.argv[1]) if len(sys.argv) > 1 else sys.stdin | |
| currentScriptContainingFolder = os.path.abspath(os.path.dirname(sys.argv[0])) | |
| covExclusionsFile = currentScriptContainingFolder + "/cov-exclusions.txt" | |
| try: | |
| fileExclusions = open(covExclusionsFile).read().splitlines() | |
| except IOError: | |
| fileExclusions = [] | |
| def matchesexclusion(filePath): | |
| basename = os.path.basename(filePath) | |
| return any([(fnmatch.fnmatch(filePath, exclusion) or fnmatch.fnmatch(basename, exclusion)) for exclusion in fileExclusions]) | |
| for line in inFile: | |
| lineComponents = line.split("'") | |
| if len(lineComponents) == 3 and line.startswith("File '"): | |
| filePath = lineComponents[1] | |
| if not matchesexclusion(filePath): | |
| currentFile = filePath | |
| else: | |
| currentFile = None | |
| print "parse-llvm-cov-report.py :: Skipping file: "+filePath | |
| elif line.startswith("TOTAL") and currentFile != None: | |
| lineComponents = line.split() | |
| (fileTotalLines, fileMissedLines) = (float(lineComponents[4]), float(lineComponents[5])) | |
| covPercentage = (fileTotalLines-fileMissedLines) / fileTotalLines | |
| covResults.append((currentFile, covPercentage, fileTotalLines, fileMissedLines)) | |
| covResults.sort(key=lambda x: x[1], reverse=True) | |
| # for (file, coverage, totalLines, missedLines) in covResults: | |
| # print file + ": {0:.2%}".format(coverage) | |
| totalLines = sum([x[2] for x in covResults]) | |
| missedLines = sum([x[3] for x in covResults]) | |
| covAverage = (totalLines-missedLines) / totalLines if totalLines>0 else 0 | |
| print "parse-llvm-cov-report.py :: fileExclusions : " | |
| print fileExclusions | |
| print "##teamcity[buildStatisticValue key='CodeCoverageAbsLTotal' value='%i']" % totalLines | |
| print "##teamcity[buildStatisticValue key='CodeCoverageAbsLCovered' value='%d']" % (totalLines-missedLines) | |
| print "parse-llvm-cov-report.py :: Coverage average is: {0:.2%}".format(covAverage) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment