Skip to content

Commit

Permalink
Test suite fixes and improvements for Windows (ccache#780)
Browse files Browse the repository at this point in the history
* Tests: properly handle compiler arguments from CC environment variable

* Tests: don't pass test names directly to printf

In some cases test names would be interpreted as invalid arguments to
`printf` instead of a string to be printed, and this resulted in
confusing output on test failure.

* Tests: enable symlink support on Windows

git-bash's `ln -s` defaults to making a copy instead of making a symlink
for compatibility, but it is possible to ask for native Windows symlink
support instead.

Creating symlinks on Windows requires suitable permissions, or that
"Developer Mode" is enabled. (This is true for the Github Actions
Windows runners.)

* Tests: performance fixes for Windows

On Windows, git-bash's emulation of fork/exec is exteremely slow -- on
my machine it's typically around 30ms to spawn /usr/bin/true from a bash
script compared to 2ms on my macOS machine.

This is really noticeable when running ccache tests. This patch fixes
some of the hot code (i.e. code invoked for every test case) to avoid
spawning external commands or creating as many subshells.

* Tests: get more tests passing on Windows

- account for \r\n line endings in --version test
- skip tests that can never succeed on Windows
  • Loading branch information
nickhutchinson authored Jan 19, 2021
1 parent 3e29af0 commit 3ea726f
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 18 deletions.
42 changes: 30 additions & 12 deletions test/run
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,15 @@ if [[ -t 1 ]]; then
fi

green() {
printf "$ansi_boldgreen$*$ansi_reset\n"
printf "$ansi_boldgreen%s$ansi_reset\n" "$*"
}

red() {
printf "$ansi_boldred$*$ansi_reset\n"
printf "$ansi_boldred%s$ansi_reset\n" "$*"
}

bold() {
printf "$ansi_bold$*$ansi_reset\n"
printf "$ansi_bold%s$ansi_reset\n" "$*"
}

test_failed() {
Expand Down Expand Up @@ -81,9 +81,10 @@ find_compiler() {
generate_code() {
local nlines=$1
local outfile=$2
local i

rm -f $outfile
for i in $(seq $nlines); do
for ((i = 1; i <= nlines; i++)); do
echo "int foo_$i(int x) { return x; }" >>$outfile
done
}
Expand Down Expand Up @@ -116,7 +117,7 @@ backdate() {
else
m=0
fi
touch -t 1999010100$(printf "%02u" $m) "$@"
touch -t $((199901010000 + m)) "$@"
}

file_size() {
Expand Down Expand Up @@ -148,7 +149,18 @@ objdump_grep_cmd() {
expect_stat() {
local stat="$1"
local expected_value="$2"
local value="$(echo $($CCACHE -s | fgrep "$stat" | cut -c33-))"
local line
local value=""

while IFS= read -r line; do
if [[ $line = *"$stat"* ]]; then
value="${line:32}"
# remove leading & trailing whitespace
value="${value#${value%%[![:space:]]*}}"
value="${value%${value##*[![:space:]]}}"
break
fi
done < <($CCACHE -s)

if [ "$expected_value" != "$value" ]; then
test_failed "Expected \"$stat\" to be $expected_value, actual $value"
Expand Down Expand Up @@ -309,11 +321,12 @@ expect_perm() {
}

reset_environment() {
while read name; do
unset $name
done <<EOF
$(env | sed -n 's/^\(CCACHE_[A-Z0-9_]*\)=.*$/\1/p')
EOF
while IFS= read -r name; do
if [[ $name =~ ^CCACHE_[A-Z0-9_]*$ ]]; then
unset $name
fi
done < <(compgen -e)

unset GCC_COLORS
unset TERM
unset XDG_CACHE_HOME
Expand Down Expand Up @@ -438,7 +451,7 @@ case $compiler_version in
;;
*clang*)
COMPILER_TYPE_CLANG=true
CLANG_VERSION_SUFFIX=$(echo $COMPILER | sed 's/.*clang//')
CLANG_VERSION_SUFFIX=$(echo "${COMPILER%% *}" | sed 's/.*clang//')
;;
*)
echo "WARNING: Compiler $COMPILER not supported (version: $compiler_version) -- not running tests" >&2
Expand Down Expand Up @@ -479,6 +492,11 @@ else
PATH_DELIM=":"
fi

if [[ $OSTYPE = msys* ]]; then
# Native symlink support for Windows.
export MSYS="${MSYS:-} winsymlinks:nativestrict"
fi

if $HOST_OS_APPLE; then
SDKROOT=$(xcrun --sdk macosx --show-sdk-path 2>/dev/null)
if [ "$SDKROOT" = "" ]; then
Expand Down
19 changes: 15 additions & 4 deletions test/suites/base.bash
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ base_tests() {

# The exact output is not tested, but at least it's something human readable
# and not random memory.
if [ $($CCACHE --version | grep -c '^ccache version [a-zA-Z0-9_./+-]*$') -ne 1 ]; then
local version_pattern=$'^ccache version [a-zA-Z0-9_./+-]*\r?$'
if [ $($CCACHE --version | grep -E -c "$version_pattern") -ne 1 ]; then
test_failed "Unexpected output of --version"
fi

Expand Down Expand Up @@ -212,6 +213,7 @@ base_tests() {
rm -rf src

# -------------------------------------------------------------------------
if ! $HOST_OS_WINDOWS; then
TEST "Source file ending with dot"

mkdir src
Expand All @@ -230,6 +232,7 @@ base_tests() {
rm foo.o

rm -rf src
fi

# -------------------------------------------------------------------------
TEST "Multiple file extensions"
Expand Down Expand Up @@ -778,19 +781,23 @@ b"
expect_stat 'files in cache' 1
expect_equal_object_files reference_test1.o test1.o

CCACHE_COMPILER=$COMPILER $CCACHE non_existing_compiler_will_be_overridden_anyway -c test1.c
CCACHE_COMPILER=$COMPILER_BIN $CCACHE \
non_existing_compiler_will_be_overridden_anyway \
$COMPILER_ARGS -c test1.c
expect_stat 'cache hit (preprocessed)' 1
expect_stat 'cache miss' 1
expect_stat 'files in cache' 1
expect_equal_object_files reference_test1.o test1.o

CCACHE_COMPILER=$COMPILER $CCACHE same/for/relative -c test1.c
CCACHE_COMPILER=$COMPILER_BIN $CCACHE same/for/relative \
$COMPILER_ARGS -c test1.c
expect_stat 'cache hit (preprocessed)' 2
expect_stat 'cache miss' 1
expect_stat 'files in cache' 1
expect_equal_object_files reference_test1.o test1.o

CCACHE_COMPILER=$COMPILER $CCACHE /and/even/absolute/compilers -c test1.c
CCACHE_COMPILER=$COMPILER_BIN $CCACHE /and/even/absolute/compilers \
$COMPILER_ARGS -c test1.c
expect_stat 'cache hit (preprocessed)' 3
expect_stat 'cache miss' 1
expect_stat 'files in cache' 1
Expand Down Expand Up @@ -988,6 +995,7 @@ EOF


# -------------------------------------------------------------------------
if ! $HOST_OS_WINDOWS; then
TEST "CCACHE_UMASK"

saved_umask=$(umask)
Expand Down Expand Up @@ -1046,6 +1054,7 @@ EOF
expect_perm "$stats_file" -rw-rw-r--

umask $saved_umask
fi

# -------------------------------------------------------------------------
TEST "No object file due to bad prefix"
Expand Down Expand Up @@ -1365,6 +1374,7 @@ EOF
fi

# -------------------------------------------------------------------------
if ! $HOST_OS_WINDOWS; then
TEST "UNCACHED_ERR_FD"

cat >compiler.sh <<'EOF'
Expand Down Expand Up @@ -1395,6 +1405,7 @@ EOF
if [ "$stderr" != "2Pu1Cc" ]; then
test_failed "Unexpected stderr: $stderr != 2Pu1Cc"
fi
fi

# -------------------------------------------------------------------------
TEST "Invalid boolean environment configuration options"
Expand Down
5 changes: 3 additions & 2 deletions test/suites/cleanup.bash
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
prepare_cleanup_test_dir() {
local dir=$1
local i

rm -rf $dir
mkdir -p $dir
for i in $(seq 0 9); do
printf '%4017s' '' | tr ' ' 'A' >$dir/result${i}R
for ((i = 0; i < 10; ++i)); do
printf 'A%.0s' {1..4017} >$dir/result${i}R
backdate $((3 * i + 1)) $dir/result${i}R
done
# NUMFILES: 10, TOTALSIZE: 13 KiB, MAXFILES: 0, MAXSIZE: 0
Expand Down
5 changes: 5 additions & 0 deletions test/suites/inode_cache.bash
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
SUITE_inode_cache_PROBE() {
if $HOST_OS_WINDOWS; then
echo "inode cache not available on Windows"
return
fi

temp_dir=$(dirname $($CCACHE -k temporary_dir))
fs=$(stat -fLc %T $temp_dir)
if [ "$fs" = "nfs" ]; then
Expand Down

0 comments on commit 3ea726f

Please sign in to comment.