1# Shell library to run an HTTP server for use in tests. 2# Ends the test early if httpd tests should not be run, 3# for example because the user has not enabled them. 4# 5# Usage: 6# 7# . ./test-lib.sh 8# . "$TEST_DIRECTORY"/lib-httpd.sh 9# start_httpd 10# 11# test_expect_success '...' ' 12# ... 13# ' 14# 15# test_expect_success ... 16# 17# test_done 18# 19# Can be configured using the following variables. 20# 21# GIT_TEST_HTTPD enable HTTPD tests 22# LIB_HTTPD_PATH web server path 23# LIB_HTTPD_MODULE_PATH web server modules path 24# LIB_HTTPD_PORT listening port 25# LIB_HTTPD_DAV enable DAV 26# LIB_HTTPD_SVN enable SVN at given location (e.g. "svn") 27# LIB_HTTPD_SSL enable SSL 28# 29# Copyright (c) 2008 Clemens Buchacher <drizzd@aon.at> 30# 31 32if test -n "$NO_CURL" 33then 34 skip_all='skipping test, git built without http support' 35 test_done 36fi 37 38if test -n "$NO_EXPAT" && test -n "$LIB_HTTPD_DAV" 39then 40 skip_all='skipping test, git built without expat support' 41 test_done 42fi 43 44if ! test_bool_env GIT_TEST_HTTPD true 45then 46 skip_all="Network testing disabled (unset GIT_TEST_HTTPD to enable)" 47 test_done 48fi 49 50if ! test_have_prereq NOT_ROOT; then 51 test_skip_or_die GIT_TEST_HTTPD \ 52 "Cannot run httpd tests as root" 53fi 54 55HTTPD_PARA="" 56 57for DEFAULT_HTTPD_PATH in '/usr/sbin/httpd' '/usr/sbin/apache2' 58do 59 if test -x "$DEFAULT_HTTPD_PATH" 60 then 61 break 62 fi 63done 64 65for DEFAULT_HTTPD_MODULE_PATH in '/usr/libexec/apache2' \ 66 '/usr/lib/apache2/modules' \ 67 '/usr/lib64/httpd/modules' \ 68 '/usr/lib/httpd/modules' 69do 70 if test -d "$DEFAULT_HTTPD_MODULE_PATH" 71 then 72 break 73 fi 74done 75 76case $(uname) in 77 Darwin) 78 HTTPD_PARA="$HTTPD_PARA -DDarwin" 79 ;; 80esac 81 82LIB_HTTPD_PATH=${LIB_HTTPD_PATH-"$DEFAULT_HTTPD_PATH"} 83test_set_port LIB_HTTPD_PORT 84 85TEST_PATH="$TEST_DIRECTORY"/lib-httpd 86HTTPD_ROOT_PATH="$PWD"/httpd 87HTTPD_DOCUMENT_ROOT_PATH=$HTTPD_ROOT_PATH/www 88 89# hack to suppress apache PassEnv warnings 90GIT_VALGRIND=$GIT_VALGRIND; export GIT_VALGRIND 91GIT_VALGRIND_OPTIONS=$GIT_VALGRIND_OPTIONS; export GIT_VALGRIND_OPTIONS 92GIT_TEST_SIDEBAND_ALL=$GIT_TEST_SIDEBAND_ALL; export GIT_TEST_SIDEBAND_ALL 93GIT_TRACE=$GIT_TRACE; export GIT_TRACE 94 95if ! test -x "$LIB_HTTPD_PATH" 96then 97 test_skip_or_die GIT_TEST_HTTPD "no web server found at '$LIB_HTTPD_PATH'" 98fi 99 100HTTPD_VERSION=$($LIB_HTTPD_PATH -v | \ 101 sed -n 's/^Server version: Apache\/\([0-9]*\)\..*$/\1/p; q') 102 103if test -n "$HTTPD_VERSION" 104then 105 if test -z "$LIB_HTTPD_MODULE_PATH" 106 then 107 if ! test $HTTPD_VERSION -ge 2 108 then 109 test_skip_or_die GIT_TEST_HTTPD \ 110 "at least Apache version 2 is required" 111 fi 112 if ! test -d "$DEFAULT_HTTPD_MODULE_PATH" 113 then 114 test_skip_or_die GIT_TEST_HTTPD \ 115 "Apache module directory not found" 116 fi 117 118 LIB_HTTPD_MODULE_PATH="$DEFAULT_HTTPD_MODULE_PATH" 119 fi 120else 121 test_skip_or_die GIT_TEST_HTTPD \ 122 "Could not identify web server at '$LIB_HTTPD_PATH'" 123fi 124 125install_script () { 126 write_script "$HTTPD_ROOT_PATH/$1" <"$TEST_PATH/$1" 127} 128 129prepare_httpd() { 130 mkdir -p "$HTTPD_DOCUMENT_ROOT_PATH" 131 cp "$TEST_PATH"/passwd "$HTTPD_ROOT_PATH" 132 install_script incomplete-length-upload-pack-v2-http.sh 133 install_script incomplete-body-upload-pack-v2-http.sh 134 install_script error-no-report.sh 135 install_script broken-smart-http.sh 136 install_script error-smart-http.sh 137 install_script error.sh 138 install_script apply-one-time-perl.sh 139 140 ln -s "$LIB_HTTPD_MODULE_PATH" "$HTTPD_ROOT_PATH/modules" 141 142 if test -n "$LIB_HTTPD_SSL" 143 then 144 HTTPD_PROTO=https 145 146 RANDFILE_PATH="$HTTPD_ROOT_PATH"/.rnd openssl req \ 147 -config "$TEST_PATH/ssl.cnf" \ 148 -new -x509 -nodes \ 149 -out "$HTTPD_ROOT_PATH/httpd.pem" \ 150 -keyout "$HTTPD_ROOT_PATH/httpd.pem" 151 GIT_SSL_NO_VERIFY=t 152 export GIT_SSL_NO_VERIFY 153 HTTPD_PARA="$HTTPD_PARA -DSSL" 154 else 155 HTTPD_PROTO=http 156 fi 157 HTTPD_DEST=127.0.0.1:$LIB_HTTPD_PORT 158 HTTPD_URL=$HTTPD_PROTO://$HTTPD_DEST 159 HTTPD_URL_USER=$HTTPD_PROTO://user%40host@$HTTPD_DEST 160 HTTPD_URL_USER_PASS=$HTTPD_PROTO://user%40host:pass%40host@$HTTPD_DEST 161 162 if test -n "$LIB_HTTPD_DAV" || test -n "$LIB_HTTPD_SVN" 163 then 164 HTTPD_PARA="$HTTPD_PARA -DDAV" 165 166 if test -n "$LIB_HTTPD_SVN" 167 then 168 HTTPD_PARA="$HTTPD_PARA -DSVN" 169 LIB_HTTPD_SVNPATH="$rawsvnrepo" 170 svnrepo="http://127.0.0.1:$LIB_HTTPD_PORT/" 171 svnrepo="$svnrepo$LIB_HTTPD_SVN" 172 export LIB_HTTPD_SVN LIB_HTTPD_SVNPATH 173 fi 174 fi 175} 176 177start_httpd() { 178 prepare_httpd >&3 2>&4 179 180 test_atexit stop_httpd 181 182 "$LIB_HTTPD_PATH" -d "$HTTPD_ROOT_PATH" \ 183 -f "$TEST_PATH/apache.conf" $HTTPD_PARA \ 184 -c "Listen 127.0.0.1:$LIB_HTTPD_PORT" -k start \ 185 >&3 2>&4 186 if test $? -ne 0 187 then 188 cat "$HTTPD_ROOT_PATH"/error.log >&4 2>/dev/null 189 test_skip_or_die GIT_TEST_HTTPD "web server setup failed" 190 fi 191} 192 193stop_httpd() { 194 "$LIB_HTTPD_PATH" -d "$HTTPD_ROOT_PATH" \ 195 -f "$TEST_PATH/apache.conf" $HTTPD_PARA -k stop 196} 197 198test_http_push_nonff () { 199 REMOTE_REPO=$1 200 LOCAL_REPO=$2 201 BRANCH=$3 202 EXPECT_CAS_RESULT=${4-failure} 203 204 test_expect_success 'non-fast-forward push fails' ' 205 cd "$REMOTE_REPO" && 206 HEAD=$(git rev-parse --verify HEAD) && 207 208 cd "$LOCAL_REPO" && 209 git checkout $BRANCH && 210 echo "changed" > path2 && 211 git commit -a -m path2 --amend && 212 213 test_must_fail git push -v origin >output 2>&1 && 214 (cd "$REMOTE_REPO" && 215 test $HEAD = $(git rev-parse --verify HEAD)) 216 ' 217 218 test_expect_success 'non-fast-forward push show ref status' ' 219 grep "^ ! \[rejected\][ ]*$BRANCH -> $BRANCH (non-fast-forward)$" output 220 ' 221 222 test_expect_success 'non-fast-forward push shows help message' ' 223 test_i18ngrep "Updates were rejected because" output 224 ' 225 226 test_expect_${EXPECT_CAS_RESULT} 'force with lease aka cas' ' 227 HEAD=$( cd "$REMOTE_REPO" && git rev-parse --verify HEAD ) && 228 test_when_finished '\'' 229 (cd "$REMOTE_REPO" && git update-ref HEAD "$HEAD") 230 '\'' && 231 ( 232 cd "$LOCAL_REPO" && 233 git push -v --force-with-lease=$BRANCH:$HEAD origin 234 ) && 235 git rev-parse --verify "$BRANCH" >expect && 236 ( 237 cd "$REMOTE_REPO" && git rev-parse --verify HEAD 238 ) >actual && 239 test_cmp expect actual 240 ' 241} 242 243setup_askpass_helper() { 244 test_expect_success 'setup askpass helper' ' 245 write_script "$TRASH_DIRECTORY/askpass" <<-\EOF && 246 echo >>"$TRASH_DIRECTORY/askpass-query" "askpass: $*" && 247 case "$*" in 248 *Username*) 249 what=user 250 ;; 251 *Password*) 252 what=pass 253 ;; 254 esac && 255 cat "$TRASH_DIRECTORY/askpass-$what" 256 EOF 257 GIT_ASKPASS="$TRASH_DIRECTORY/askpass" && 258 export GIT_ASKPASS && 259 export TRASH_DIRECTORY 260 ' 261} 262 263set_askpass() { 264 >"$TRASH_DIRECTORY/askpass-query" && 265 echo "$1" >"$TRASH_DIRECTORY/askpass-user" && 266 echo "$2" >"$TRASH_DIRECTORY/askpass-pass" 267} 268 269expect_askpass() { 270 dest=$HTTPD_DEST${3+/$3} 271 272 { 273 case "$1" in 274 none) 275 ;; 276 pass) 277 echo "askpass: Password for 'http://$2@$dest': " 278 ;; 279 both) 280 echo "askpass: Username for 'http://$dest': " 281 echo "askpass: Password for 'http://$2@$dest': " 282 ;; 283 *) 284 false 285 ;; 286 esac 287 } >"$TRASH_DIRECTORY/askpass-expect" && 288 test_cmp "$TRASH_DIRECTORY/askpass-expect" \ 289 "$TRASH_DIRECTORY/askpass-query" 290} 291 292strip_access_log() { 293 sed -e " 294 s/^.* \"// 295 s/\"// 296 s/ [1-9][0-9]*\$// 297 s/^GET /GET / 298 " "$HTTPD_ROOT_PATH"/access.log 299} 300 301# Requires one argument: the name of a file containing the expected stripped 302# access log entries. 303check_access_log() { 304 sort "$1" >"$1".sorted && 305 strip_access_log >access.log.stripped && 306 sort access.log.stripped >access.log.sorted && 307 if ! test_cmp "$1".sorted access.log.sorted 308 then 309 test_cmp "$1" access.log.stripped 310 fi 311} 312