1#!/usr/bin/env bash 2 3set -e 4 5# If the configuration of tests is not provided, no tests will be carried out. 6if [[ ! -f $1 ]]; then 7 echo "ERROR: SPDK test configuration not specified" 8 exit 1 9fi 10 11rootdir=$(readlink -f $(dirname $0)) 12 13source "$1" 14source "$rootdir/test/common/autotest_common.sh" 15 16out=$output_dir 17scanbuild="scan-build -o $output_dir/scan-build-tmp --exclude $rootdir/dpdk/ --status-bugs" 18config_params=$(get_config_params) 19 20trap '[[ -d $SPDK_WORKSPACE ]] && rm -rf "$SPDK_WORKSPACE"' 0 21 22SPDK_WORKSPACE=$(mktemp -dt "spdk_$(date +%s).XXXXXX") 23export SPDK_WORKSPACE 24 25umask 022 26cd $rootdir 27 28# Print some test system info out for the log 29date -u 30git describe --tags 31 32function ocf_precompile() { 33 # We compile OCF sources ourselves 34 # They don't need to be checked with scanbuild and code coverage is not applicable 35 # So we precompile OCF now for further use as standalone static library 36 ./configure $(echo $config_params | sed 's/--enable-coverage//g') 37 $MAKE $MAKEFLAGS include/spdk/config.h 38 CC=gcc CCAR=ar $MAKE $MAKEFLAGS -C lib/env_ocf exportlib O=$rootdir/build/ocf.a 39 # Set config to use precompiled library 40 config_params="$config_params --with-ocf=/$rootdir/build/ocf.a" 41 # need to reconfigure to avoid clearing ocf related files on future make clean. 42 ./configure $config_params 43} 44 45function build_native_dpdk() { 46 local external_dpdk_dir 47 local external_dpdk_base_dir 48 49 external_dpdk_dir="$SPDK_RUN_EXTERNAL_DPDK" 50 external_dpdk_base_dir="$(dirname $external_dpdk_dir)" 51 52 if [[ ! -d "$external_dpdk_base_dir" ]]; then 53 sudo mkdir -p "$external_dpdk_base_dir" 54 sudo chown -R $(whoami) "$external_dpdk_base_dir"/.. 55 fi 56 orgdir=$PWD 57 58 rm -rf "$external_dpdk_base_dir" 59 git clone --branch $SPDK_TEST_NATIVE_DPDK --depth 1 http://dpdk.org/git/dpdk "$external_dpdk_base_dir" 60 dpdk_cflags="-fPIC -g -Werror -fcommon" 61 dpdk_ldflags="" 62 63 # the drivers we use 64 DPDK_DRIVERS=("bus" "bus/pci" "bus/vdev" "mempool/ring") 65 # all possible DPDK drivers 66 DPDK_ALL_DRIVERS=($(find "$external_dpdk_base_dir/drivers" -mindepth 1 -type d | sed -n "s#^$external_dpdk_base_dir/drivers/##p")) 67 68 if [[ "$SPDK_TEST_CRYPTO" -eq 1 ]]; then 69 git clone --branch v0.54 --depth 1 https://github.com/intel/intel-ipsec-mb.git "$external_dpdk_base_dir/intel-ipsec-mb" 70 cd "$external_dpdk_base_dir/intel-ipsec-mb" 71 $MAKE $MAKEFLAGS all SHARED=n EXTRA_CFLAGS=-fPIC 72 DPDK_DRIVERS+=("crypto") 73 DPDK_DRIVERS+=("crypto/aesni_mb") 74 DPDK_DRIVERS+=("crypto/qat") 75 DPDK_DRIVERS+=("compress/qat") 76 DPDK_DRIVERS+=("common/qat") 77 dpdk_cflags+=" -I$external_dpdk_base_dir/intel-ipsec-mb" 78 dpdk_ldflags+=" -L$external_dpdk_base_dir/intel-ipsec-mb" 79 fi 80 81 if [[ "$SPDK_TEST_REDUCE" -eq 1 ]]; then 82 git clone --branch v2.29.0 --depth 1 https://github.com/intel/isa-l.git "$external_dpdk_base_dir/isa-l" 83 cd "$external_dpdk_base_dir/isa-l" 84 ./autogen.sh 85 ./configure CFLAGS="-fPIC -g -O2" --enable-shared=no 86 ln -s $PWD/include $PWD/isa-l 87 $MAKE $MAKEFLAGS all 88 DPDK_DRIVERS+=("compress") 89 DPDK_DRIVERS+=("compress/isal") 90 DPDK_DRIVERS+=("compress/qat") 91 DPDK_DRIVERS+=("common/qat") 92 dpdk_cflags+=" -I$external_dpdk_base_dir/isa-l" 93 dpdk_ldflags+=" -L$external_dpdk_base_dir/isa-l/.libs" 94 fi 95 96 # Use difference between DPDK_ALL_DRIVERS and DPDK_DRIVERS as a set of DPDK drivers we don't want or 97 # don't need to build. 98 DPDK_DISABLED_DRIVERS=($(sort <(printf "%s\n" "${DPDK_DRIVERS[@]}") <(printf "%s\n" "${DPDK_ALL_DRIVERS[@]}") | uniq -u)) 99 100 cd $external_dpdk_base_dir 101 if [ "$(uname -s)" = "Linux" ]; then 102 dpdk_cflags+=" -Wno-stringop-overflow" 103 fi 104 105 meson build-tmp --prefix="$external_dpdk_dir" --libdir lib \ 106 -Denable_docs=false -Denable_kmods=false -Dtests=false \ 107 -Dc_args="$dpdk_cflags $dpdk_ldflags" \ 108 -Dmachine=native -Ddisable_drivers=$(printf "%s," "${DPDK_DISABLED_DRIVERS[@]}") 109 ninja -C "$external_dpdk_base_dir/build-tmp" $MAKEFLAGS 110 ninja -C "$external_dpdk_base_dir/build-tmp" $MAKEFLAGS install 111 112 cd "$orgdir" 113} 114 115function make_fail_cleanup() { 116 if [ -d $out/scan-build-tmp ]; then 117 scanoutput=$(ls -1 $out/scan-build-tmp/) 118 mv $out/scan-build-tmp/$scanoutput $out/scan-build 119 rm -rf $out/scan-build-tmp 120 chmod -R a+rX $out/scan-build 121 fi 122 false 123} 124 125function scanbuild_make() { 126 pass=true 127 $scanbuild $MAKE $MAKEFLAGS > $out/build_output.txt && rm -rf $out/scan-build-tmp || make_fail_cleanup 128 xtrace_disable 129 130 rm -f $out/*files.txt 131 for ent in $(find app examples lib module test -type f | grep -vF ".h"); do 132 if [[ $ent == lib/env_ocf* ]]; then continue; fi 133 if file -bi $ent | grep -q 'text/x-c'; then 134 echo $ent | sed 's/\.cp\{0,2\}$//g' >> $out/all_c_files.txt 135 fi 136 done 137 xtrace_restore 138 139 grep -E "CC|CXX" $out/build_output.txt | sed 's/\s\s\(CC\|CXX\)\s//g' | sed 's/\.o//g' > $out/built_c_files.txt 140 cat $rootdir/test/common/skipped_build_files.txt >> $out/built_c_files.txt 141 142 sort -o $out/all_c_files.txt $out/all_c_files.txt 143 sort -o $out/built_c_files.txt $out/built_c_files.txt 144 # from comm manual: 145 # -2 suppress column 2 (lines unique to FILE2) 146 # -3 suppress column 3 (lines that appear in both files) 147 # comm may exit 1 if no lines were printed (undocumented, unreliable) 148 comm -2 -3 $out/all_c_files.txt $out/built_c_files.txt > $out/unbuilt_c_files.txt || true 149 150 if [ $(wc -l < $out/unbuilt_c_files.txt) -ge 1 ]; then 151 echo "missing files" 152 cat $out/unbuilt_c_files.txt 153 pass=false 154 fi 155 156 $pass 157} 158 159function porcelain_check() { 160 if [ $(git status --porcelain --ignore-submodules | wc -l) -ne 0 ]; then 161 echo "Generated files missing from .gitignore:" 162 git status --porcelain --ignore-submodules 163 exit 1 164 fi 165} 166 167# Check that header file dependencies are working correctly by 168# capturing a binary's stat data before and after touching a 169# header file and re-making. 170function header_dependency_check() { 171 STAT1=$(stat $SPDK_BIN_DIR/spdk_tgt) 172 sleep 1 173 touch lib/nvme/nvme_internal.h 174 $MAKE $MAKEFLAGS 175 STAT2=$(stat $SPDK_BIN_DIR/spdk_tgt) 176 177 if [ "$STAT1" == "$STAT2" ]; then 178 echo "Header dependency check failed" 179 false 180 fi 181} 182 183function test_make_uninstall() { 184 # Create empty file to check if it is not deleted by target uninstall 185 touch "$SPDK_WORKSPACE/usr/lib/sample_xyz.a" 186 $MAKE $MAKEFLAGS uninstall DESTDIR="$SPDK_WORKSPACE" prefix=/usr 187 if [[ $(find "$SPDK_WORKSPACE/usr" -maxdepth 1 -mindepth 1 | wc -l) -ne 2 ]] || [[ $(find "$SPDK_WORKSPACE/usr/lib/" -maxdepth 1 -mindepth 1 | wc -l) -ne 1 ]]; then 188 ls -lR "$SPDK_WORKSPACE" 189 echo "Make uninstall failed" 190 exit 1 191 fi 192} 193 194function build_doc() { 195 $MAKE -C "$rootdir"/doc --no-print-directory $MAKEFLAGS &> "$out"/doxygen.log 196 if [ -s "$out"/doxygen.log ]; then 197 cat "$out"/doxygen.log 198 echo "Doxygen errors found!" 199 exit 1 200 fi 201 if hash pdflatex 2> /dev/null; then 202 $MAKE -C "$rootdir"/doc/output/latex --no-print-directory $MAKEFLAGS &>> "$out"/doxygen.log 203 fi 204 mkdir -p "$out"/doc 205 mv "$rootdir"/doc/output/html "$out"/doc 206 if [ -f "$rootdir"/doc/output/latex/refman.pdf ]; then 207 mv "$rootdir"/doc/output/latex/refman.pdf "$out"/doc/spdk.pdf 208 fi 209 $MAKE -C "$rootdir"/doc --no-print-directory $MAKEFLAGS clean &>> "$out"/doxygen.log 210 if [ -s "$out"/doxygen.log ]; then 211 rm "$out"/doxygen.log 212 fi 213 rm -rf "$rootdir"/doc/output 214} 215 216function autobuild_test_suite() { 217 run_test "autobuild_check_format" ./scripts/check_format.sh 218 run_test "autobuild_external_code" sudo -E --preserve-env=PATH $rootdir/test/external_code/test_make.sh $rootdir 219 if [ "$SPDK_TEST_OCF" -eq 1 ]; then 220 run_test "autobuild_ocf_precompile" ocf_precompile 221 fi 222 run_test "autobuild_check_so_deps" $rootdir/test/make/check_so_deps.sh $1 223 ./configure $config_params --without-shared 224 run_test "scanbuild_make" scanbuild_make 225 run_test "autobuild_generated_files_check" porcelain_check 226 run_test "autobuild_header_dependency_check" header_dependency_check 227 run_test "autobuild_make_install" $MAKE $MAKEFLAGS install DESTDIR="$SPDK_WORKSPACE" prefix=/usr 228 run_test "autobuild_make_uninstall" test_make_uninstall 229 run_test "autobuild_build_doc" build_doc 230} 231 232if [ $SPDK_RUN_VALGRIND -eq 1 ]; then 233 run_test "valgrind" echo "using valgrind" 234fi 235 236if [ $SPDK_RUN_ASAN -eq 1 ]; then 237 run_test "asan" echo "using asan" 238fi 239 240if [ $SPDK_RUN_UBSAN -eq 1 ]; then 241 run_test "ubsan" echo "using ubsan" 242fi 243 244if [ -n "$SPDK_TEST_NATIVE_DPDK" ]; then 245 run_test "build_native_dpdk" build_native_dpdk 246fi 247 248./configure $config_params 249echo "** START ** Info for Hostname: $HOSTNAME" 250uname -a 251$MAKE cc_version 252$MAKE cxx_version 253echo "** END ** Info for Hostname: $HOSTNAME" 254 255if [ "$SPDK_TEST_AUTOBUILD" -eq 1 ]; then 256 run_test "autobuild" autobuild_test_suite $1 257else 258 if [ "$SPDK_TEST_OCF" -eq 1 ]; then 259 run_test "autobuild_ocf_precompile" ocf_precompile 260 fi 261 # if we aren't testing the unittests, build with shared objects. 262 ./configure $config_params --with-shared 263 run_test "make" $MAKE $MAKEFLAGS 264fi 265