From 3ea726f7c681b0a9288151ed8bab7f210682c252 Mon Sep 17 00:00:00 2001 From: Nicholas Hutchinson Date: Tue, 19 Jan 2021 20:27:00 +0000 Subject: [PATCH] Test suite fixes and improvements for Windows (#780) * 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 --- test/run | 42 +++++++++++++++++++++++++----------- test/suites/base.bash | 19 ++++++++++++---- test/suites/cleanup.bash | 5 +++-- test/suites/inode_cache.bash | 5 +++++ 4 files changed, 53 insertions(+), 18 deletions(-) diff --git a/test/run b/test/run index 9005dc97b5..e51dac5545 100755 --- a/test/run +++ b/test/run @@ -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() { @@ -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 } @@ -116,7 +117,7 @@ backdate() { else m=0 fi - touch -t 1999010100$(printf "%02u" $m) "$@" + touch -t $((199901010000 + m)) "$@" } file_size() { @@ -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" @@ -309,11 +321,12 @@ expect_perm() { } reset_environment() { - while read name; do - unset $name - done <&2 @@ -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 diff --git a/test/suites/base.bash b/test/suites/base.bash index d0143009e6..1bbc3d0df0 100644 --- a/test/suites/base.bash +++ b/test/suites/base.bash @@ -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 @@ -212,6 +213,7 @@ base_tests() { rm -rf src # ------------------------------------------------------------------------- +if ! $HOST_OS_WINDOWS; then TEST "Source file ending with dot" mkdir src @@ -230,6 +232,7 @@ base_tests() { rm foo.o rm -rf src +fi # ------------------------------------------------------------------------- TEST "Multiple file extensions" @@ -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 @@ -988,6 +995,7 @@ EOF # ------------------------------------------------------------------------- +if ! $HOST_OS_WINDOWS; then TEST "CCACHE_UMASK" saved_umask=$(umask) @@ -1046,6 +1054,7 @@ EOF expect_perm "$stats_file" -rw-rw-r-- umask $saved_umask +fi # ------------------------------------------------------------------------- TEST "No object file due to bad prefix" @@ -1365,6 +1374,7 @@ EOF fi # ------------------------------------------------------------------------- +if ! $HOST_OS_WINDOWS; then TEST "UNCACHED_ERR_FD" cat >compiler.sh <<'EOF' @@ -1395,6 +1405,7 @@ EOF if [ "$stderr" != "2Pu1Cc" ]; then test_failed "Unexpected stderr: $stderr != 2Pu1Cc" fi +fi # ------------------------------------------------------------------------- TEST "Invalid boolean environment configuration options" diff --git a/test/suites/cleanup.bash b/test/suites/cleanup.bash index 33cf02cd3b..b2c53a598a 100644 --- a/test/suites/cleanup.bash +++ b/test/suites/cleanup.bash @@ -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 diff --git a/test/suites/inode_cache.bash b/test/suites/inode_cache.bash index dc8d5f0efb..ef9c92490d 100644 --- a/test/suites/inode_cache.bash +++ b/test/suites/inode_cache.bash @@ -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