159 lines
6.1 KiB
Bash
Executable File
159 lines
6.1 KiB
Bash
Executable File
# Copyright (c) (2018,2019) Apple Inc. All rights reserved.
|
||
#
|
||
# corecrypto is licensed under Apple Inc.’s Internal Use License Agreement (which
|
||
# is contained in the License.txt file distributed with corecrypto) and only to
|
||
# people who accept that license. IMPORTANT: Any license rights granted to you by
|
||
# Apple Inc. (if any) are limited to internal use within your organization only on
|
||
# devices and computers you own or control, for the sole purpose of verifying the
|
||
# security characteristics and correct functioning of the Apple Software. You may
|
||
# not, directly or indirectly, redistribute the Apple Software or any portions thereof.
|
||
|
||
#!/bin/bash
|
||
|
||
# Grab the root directory before anything else happens.
|
||
export ROOTDIR=${PWD}
|
||
export BRANCHDEFAULT=${BRANCH:=master}
|
||
|
||
# Echo to stderr.
|
||
echoerr() { echo "$@" 1>&2; }
|
||
|
||
# Polling xcodebuild for project settings is slow; do it only once
|
||
# for a given execution.
|
||
set_globals() {
|
||
export XCODEPROJ=`ls -d *.xcodeproj | head -1` # Auto-find the .xcodeproj file.
|
||
|
||
echoerr "Finding project directories..."
|
||
export OBJROOT=`xcodebuild -project ${XCODEPROJ} -showBuildSettings -configuration Debug 2>/dev/null | \
|
||
grep " OBJROOT =" | awk '{print $3}'`
|
||
export PRODROOT=`xcodebuild -project ${XCODEPROJ} -showBuildSettings -configuration Debug 2>/dev/null | \
|
||
grep " BUILT_PRODUCTS_DIR = " | awk '{print $3}'`
|
||
export COVROOT=${OBJROOT}/CodeCoverage
|
||
# Required clang flags for enabling coverage
|
||
export COVFLAGS="-fprofile-instr-generate -fcoverage-mapping"
|
||
|
||
# For whatever reason, xcodebuild never outputs the top level directory.
|
||
export PROJROOT="$(dirname $(dirname $(dirname ${PRODROOT})))"
|
||
export REPORTDIR="${PWD}/cov_report"
|
||
mkdir -p ${REPORTDIR}
|
||
}
|
||
|
||
compile_for_coverage() {
|
||
XCODESCHEME=$1
|
||
|
||
LOG=${REPORTDIR}/build-${XCODESCHEME}.log
|
||
echoerr "Building ${XCODESCHEME}..."
|
||
xcodebuild build -project ${XCODEPROJ} -scheme ${XCODESCHEME} \
|
||
-configuration Debug \
|
||
-destination 'platform=macOS,arch=x86_64' -- \
|
||
OTHER_CFLAGS="${COVFLAGS} \${inherited}" \
|
||
OTHER_LDFLAGS="${COVFLAGS} \${inherited}" \
|
||
>> ${LOG} 2>&1
|
||
ERR=$?
|
||
if [ ${ERR} != 0 ]; then
|
||
echoerr "Failed; examine ${LOG}"
|
||
exit -1
|
||
fi
|
||
}
|
||
|
||
# Execute an arbitrary binary built through the specified xcode project
|
||
# and acquire the coverage results.
|
||
#
|
||
# Expects the binary to already have been built.
|
||
#
|
||
# generate_bin_coverage <scheme>
|
||
#
|
||
# For example:
|
||
# generate_bin_coverage corecrypto_test
|
||
generate_bin_coverage() {
|
||
XCODESCHEME=$1
|
||
|
||
if [ "${XCODESCHEME}" == "" ]; then
|
||
echoerr "missing: xcodescheme"
|
||
exit -1
|
||
fi
|
||
|
||
# If the binary is deployed/installed somewhere else, it ends up in a
|
||
# BuildProducts subdirectory. Use find to simplify searching.
|
||
TESTBIN=`find ${PRODROOT} -name ${XCODESCHEME} | grep -v dSYM | head -1`
|
||
echoerr "Executing ${TESTBIN}..."
|
||
|
||
echo DYLD_PRINT_LIBRARIES=1 \
|
||
DYLD_PRINT_LIBRARIES_POST_LAUNCH=1 \
|
||
DYLD_FRAMEWORK_PATH=${PRODROOT} \
|
||
DYLD_LIBRARY_PATH=${PRODROOT} \
|
||
LLVM_PROFILE_FILE=${REPORTDIR}/${XCODESCHEME}.profraw \
|
||
${TESTBIN} \
|
||
>> ${REPORTDIR}/${XCODESCHEME}.log 2>&1
|
||
DYLD_PRINT_LIBRARIES=1 \
|
||
DYLD_PRINT_LIBRARIES_POST_LAUNCH=1 \
|
||
DYLD_FRAMEWORK_PATH=${PRODROOT} \
|
||
DYLD_LIBRARY_PATH=${PRODROOT} \
|
||
LLVM_PROFILE_FILE=${REPORTDIR}/${XCODESCHEME}.profraw \
|
||
${TESTBIN} \
|
||
>> ${REPORTDIR}/${XCODESCHEME}.log 2>&1
|
||
RET=$?
|
||
if [ ${RET} != 0 ]; then
|
||
echoerr "Note: test ${TESTBIN} failed: ${RET}"
|
||
exit -1
|
||
fi
|
||
|
||
# Add to the list of binaries that've been tested.
|
||
BINARIES="${BINARIES} ${TESTBIN}"
|
||
}
|
||
|
||
# Create a report from a 'run.profdata' file in the report directory
|
||
#
|
||
# generate_report [exclude paths...]
|
||
#
|
||
# For example:
|
||
# generate_report Applications OSX
|
||
generate_report() {
|
||
EXCLUDE_PATHS="$@"
|
||
|
||
if [ "${BINARIES}" == "" ]; then
|
||
echoerr "missing: tested binaries"
|
||
exit -1
|
||
fi
|
||
|
||
COVBINS=
|
||
BINARIES="`ls ${BINARIES} | sort -u`"
|
||
echo "Generating list of binaries:"
|
||
for bin in ${BINARIES}; do
|
||
echo " -- ${bin}"
|
||
if [ "${COVBINS}" == "" ]; then
|
||
COVBINS=${bin}
|
||
else
|
||
COVBINS="${COVBINS} -object ${bin}"
|
||
fi
|
||
done
|
||
|
||
echoerr "Merging coverage data..."
|
||
xcrun llvm-profdata merge ${REPORTDIR}/*.profraw -o ${REPORTDIR}/run.profdata
|
||
RET=$?
|
||
if [ ${RET} != 0 ]; then
|
||
echoerr "failed merging coverage data: ${RET}"
|
||
exit -1
|
||
fi
|
||
|
||
echoerr "Generating coverage report..."
|
||
echo xcrun --toolchain osx llvm-cov show \
|
||
-instr-profile=${REPORTDIR}/run.profdata -format=html -output-dir=${REPORTDIR} \
|
||
${COVBINS}
|
||
xcrun --toolchain osx llvm-cov show \
|
||
-instr-profile=${REPORTDIR}/run.profdata -format=html -output-dir=${REPORTDIR} \
|
||
${COVBINS}
|
||
RET=$?
|
||
if [ ${RET} != 0 ]; then
|
||
echoerr "failed coverage report generation: ${RET}"
|
||
echoerr ""
|
||
echoerr "This failure often occurs because binaries that weren't"
|
||
echoerr "exercised as part of the unit tests are included in the llvm-cov report"
|
||
echoerr "generation. If the test uses the 'add_all_binaries_to_report' command,"
|
||
echoerr "consider switching to one of the more specific variants. Because there"
|
||
echoerr "is quite a bit of variability on where frameworks live, the 'find_'"
|
||
echoerr "variant of the function may be necessary instead."
|
||
exit -1
|
||
fi
|
||
|
||
open ${REPORTDIR}/index.html
|
||
} |