Merge branch 'maint'
[git] / t / t9400-git-cvsserver-server.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2007 Frank Lichtenheld
4 #
5
6 test_description='git-cvsserver access
7
8 tests read access to a git repository with the
9 cvs CLI client via git-cvsserver server'
10
11 . ./test-lib.sh
12
13 if ! test_have_prereq PERL; then
14         say 'skipping git cvsserver tests, perl not available'
15         test_done
16 fi
17 cvs >/dev/null 2>&1
18 if test $? -ne 1
19 then
20     say 'skipping git-cvsserver tests, cvs not found'
21     test_done
22 fi
23 "$PERL_PATH" -e 'use DBI; use DBD::SQLite' >/dev/null 2>&1 || {
24     say 'skipping git-cvsserver tests, Perl SQLite interface unavailable'
25     test_done
26 }
27
28 unset GIT_DIR GIT_CONFIG
29 WORKDIR=$(pwd)
30 SERVERDIR=$(pwd)/gitcvs.git
31 git_config="$SERVERDIR/config"
32 CVSROOT=":fork:$SERVERDIR"
33 CVSWORK="$(pwd)/cvswork"
34 CVS_SERVER=git-cvsserver
35 export CVSROOT CVS_SERVER
36
37 rm -rf "$CVSWORK" "$SERVERDIR"
38 test_expect_success 'setup' '
39   echo >empty &&
40   git add empty &&
41   git commit -q -m "First Commit" &&
42   mkdir secondroot &&
43   ( cd secondroot &&
44   git init &&
45   touch secondrootfile &&
46   git add secondrootfile &&
47   git commit -m "second root") &&
48   git pull secondroot master &&
49   git clone -q --bare "$WORKDIR/.git" "$SERVERDIR" >/dev/null 2>&1 &&
50   GIT_DIR="$SERVERDIR" git config --bool gitcvs.enabled true &&
51   GIT_DIR="$SERVERDIR" git config gitcvs.logfile "$SERVERDIR/gitcvs.log"
52 '
53
54 # note that cvs doesn't accept absolute pathnames
55 # as argument to co -d
56 test_expect_success 'basic checkout' \
57   'GIT_CONFIG="$git_config" cvs -Q co -d cvswork master &&
58    test "$(echo $(grep -v ^D cvswork/CVS/Entries|cut -d/ -f2,3,5 | head -n 1))" = "empty/1.1/"
59    test "$(echo $(grep -v ^D cvswork/CVS/Entries|cut -d/ -f2,3,5 | sed -ne \$p))" = "secondrootfile/1.1/"'
60
61 #------------------------
62 # PSERVER AUTHENTICATION
63 #------------------------
64
65 cat >request-anonymous  <<EOF
66 BEGIN AUTH REQUEST
67 $SERVERDIR
68 anonymous
69
70 END AUTH REQUEST
71 EOF
72
73 cat >request-git  <<EOF
74 BEGIN AUTH REQUEST
75 $SERVERDIR
76 git
77
78 END AUTH REQUEST
79 EOF
80
81 cat >login-anonymous <<EOF
82 BEGIN VERIFICATION REQUEST
83 $SERVERDIR
84 anonymous
85
86 END VERIFICATION REQUEST
87 EOF
88
89 cat >login-git <<EOF
90 BEGIN VERIFICATION REQUEST
91 $SERVERDIR
92 git
93
94 END VERIFICATION REQUEST
95 EOF
96
97 test_expect_success 'pserver authentication' \
98   'cat request-anonymous | git-cvsserver pserver >log 2>&1 &&
99    sed -ne \$p log | grep "^I LOVE YOU\$"'
100
101 test_expect_success 'pserver authentication failure (non-anonymous user)' \
102   'if cat request-git | git-cvsserver pserver >log 2>&1
103    then
104        false
105    else
106        true
107    fi &&
108    sed -ne \$p log | grep "^I HATE YOU\$"'
109
110 test_expect_success 'pserver authentication (login)' \
111   'cat login-anonymous | git-cvsserver pserver >log 2>&1 &&
112    sed -ne \$p log | grep "^I LOVE YOU\$"'
113
114 test_expect_success 'pserver authentication failure (login/non-anonymous user)' \
115   'if cat login-git | git-cvsserver pserver >log 2>&1
116    then
117        false
118    else
119        true
120    fi &&
121    sed -ne \$p log | grep "^I HATE YOU\$"'
122
123
124 # misuse pserver authentication for testing of req_Root
125
126 cat >request-relative  <<EOF
127 BEGIN AUTH REQUEST
128 gitcvs.git
129 anonymous
130
131 END AUTH REQUEST
132 EOF
133
134 cat >request-conflict  <<EOF
135 BEGIN AUTH REQUEST
136 $SERVERDIR
137 anonymous
138
139 END AUTH REQUEST
140 Root $WORKDIR
141 EOF
142
143 test_expect_success 'req_Root failure (relative pathname)' \
144   'if cat request-relative | git-cvsserver pserver >log 2>&1
145    then
146        echo unexpected success
147        false
148    else
149        true
150    fi &&
151    tail log | grep "^error 1 Root must be an absolute pathname$"'
152
153 test_expect_success 'req_Root failure (conflicting roots)' \
154   'cat request-conflict | git-cvsserver pserver >log 2>&1 &&
155    tail log | grep "^error 1 Conflicting roots specified$"'
156
157 test_expect_success 'req_Root (strict paths)' \
158   'cat request-anonymous | git-cvsserver --strict-paths pserver "$SERVERDIR" >log 2>&1 &&
159    sed -ne \$p log | grep "^I LOVE YOU\$"'
160
161 test_expect_success 'req_Root failure (strict-paths)' '
162     ! cat request-anonymous |
163     git-cvsserver --strict-paths pserver "$WORKDIR" >log 2>&1
164 '
165
166 test_expect_success 'req_Root (w/o strict-paths)' \
167   'cat request-anonymous | git-cvsserver pserver "$WORKDIR/" >log 2>&1 &&
168    sed -ne \$p log | grep "^I LOVE YOU\$"'
169
170 test_expect_success 'req_Root failure (w/o strict-paths)' '
171     ! cat request-anonymous |
172     git-cvsserver pserver "$WORKDIR/gitcvs" >log 2>&1
173 '
174
175 cat >request-base  <<EOF
176 BEGIN AUTH REQUEST
177 /gitcvs.git
178 anonymous
179
180 END AUTH REQUEST
181 Root /gitcvs.git
182 EOF
183
184 test_expect_success 'req_Root (base-path)' \
185   'cat request-base | git-cvsserver --strict-paths --base-path "$WORKDIR/" pserver "$SERVERDIR" >log 2>&1 &&
186    sed -ne \$p log | grep "^I LOVE YOU\$"'
187
188 test_expect_success 'req_Root failure (base-path)' '
189     ! cat request-anonymous |
190     git-cvsserver --strict-paths --base-path "$WORKDIR" pserver "$SERVERDIR" >log 2>&1
191 '
192
193 GIT_DIR="$SERVERDIR" git config --bool gitcvs.enabled false || exit 1
194
195 test_expect_success 'req_Root (export-all)' \
196   'cat request-anonymous | git-cvsserver --export-all pserver "$WORKDIR" >log 2>&1 &&
197    sed -ne \$p log | grep "^I LOVE YOU\$"'
198
199 test_expect_success 'req_Root failure (export-all w/o whitelist)' \
200   '! (cat request-anonymous | git-cvsserver --export-all pserver >log 2>&1 || false)'
201
202 test_expect_success 'req_Root (everything together)' \
203   'cat request-base | git-cvsserver --export-all --strict-paths --base-path "$WORKDIR/" pserver "$SERVERDIR" >log 2>&1 &&
204    sed -ne \$p log | grep "^I LOVE YOU\$"'
205
206 GIT_DIR="$SERVERDIR" git config --bool gitcvs.enabled true || exit 1
207
208 #--------------
209 # CONFIG TESTS
210 #--------------
211
212 test_expect_success 'gitcvs.enabled = false' \
213   'GIT_DIR="$SERVERDIR" git config --bool gitcvs.enabled false &&
214    if GIT_CONFIG="$git_config" cvs -Q co -d cvswork2 master >cvs.log 2>&1
215    then
216      echo unexpected cvs success
217      false
218    else
219      true
220    fi &&
221    grep "GITCVS emulation disabled" cvs.log &&
222    test ! -d cvswork2'
223
224 rm -fr cvswork2
225 test_expect_success 'gitcvs.ext.enabled = true' \
226   'GIT_DIR="$SERVERDIR" git config --bool gitcvs.ext.enabled true &&
227    GIT_DIR="$SERVERDIR" git config --bool gitcvs.enabled false &&
228    GIT_CONFIG="$git_config" cvs -Q co -d cvswork2 master >cvs.log 2>&1 &&
229    test_cmp cvswork cvswork2'
230
231 rm -fr cvswork2
232 test_expect_success 'gitcvs.ext.enabled = false' \
233   'GIT_DIR="$SERVERDIR" git config --bool gitcvs.ext.enabled false &&
234    GIT_DIR="$SERVERDIR" git config --bool gitcvs.enabled true &&
235    if GIT_CONFIG="$git_config" cvs -Q co -d cvswork2 master >cvs.log 2>&1
236    then
237      echo unexpected cvs success
238      false
239    else
240      true
241    fi &&
242    grep "GITCVS emulation disabled" cvs.log &&
243    test ! -d cvswork2'
244
245 rm -fr cvswork2
246 test_expect_success 'gitcvs.dbname' \
247   'GIT_DIR="$SERVERDIR" git config --bool gitcvs.ext.enabled true &&
248    GIT_DIR="$SERVERDIR" git config gitcvs.dbname %Ggitcvs.%a.%m.sqlite &&
249    GIT_CONFIG="$git_config" cvs -Q co -d cvswork2 master >cvs.log 2>&1 &&
250    test_cmp cvswork cvswork2 &&
251    test -f "$SERVERDIR/gitcvs.ext.master.sqlite" &&
252    cmp "$SERVERDIR/gitcvs.master.sqlite" "$SERVERDIR/gitcvs.ext.master.sqlite"'
253
254 rm -fr cvswork2
255 test_expect_success 'gitcvs.ext.dbname' \
256   'GIT_DIR="$SERVERDIR" git config --bool gitcvs.ext.enabled true &&
257    GIT_DIR="$SERVERDIR" git config gitcvs.ext.dbname %Ggitcvs1.%a.%m.sqlite &&
258    GIT_DIR="$SERVERDIR" git config gitcvs.dbname %Ggitcvs2.%a.%m.sqlite &&
259    GIT_CONFIG="$git_config" cvs -Q co -d cvswork2 master >cvs.log 2>&1 &&
260    test_cmp cvswork cvswork2 &&
261    test -f "$SERVERDIR/gitcvs1.ext.master.sqlite" &&
262    test ! -f "$SERVERDIR/gitcvs2.ext.master.sqlite" &&
263    cmp "$SERVERDIR/gitcvs.master.sqlite" "$SERVERDIR/gitcvs1.ext.master.sqlite"'
264
265
266 #------------
267 # CVS UPDATE
268 #------------
269
270 rm -fr "$SERVERDIR"
271 cd "$WORKDIR" &&
272 git clone -q --bare "$WORKDIR/.git" "$SERVERDIR" >/dev/null 2>&1 &&
273 GIT_DIR="$SERVERDIR" git config --bool gitcvs.enabled true &&
274 GIT_DIR="$SERVERDIR" git config gitcvs.logfile "$SERVERDIR/gitcvs.log" ||
275 exit 1
276
277 test_expect_success 'cvs update (create new file)' \
278   'echo testfile1 >testfile1 &&
279    git add testfile1 &&
280    git commit -q -m "Add testfile1" &&
281    git push gitcvs.git >/dev/null &&
282    cd cvswork &&
283    GIT_CONFIG="$git_config" cvs -Q update &&
284    test "$(echo $(grep testfile1 CVS/Entries|cut -d/ -f2,3,5))" = "testfile1/1.1/" &&
285    test_cmp testfile1 ../testfile1'
286
287 cd "$WORKDIR"
288 test_expect_success 'cvs update (update existing file)' \
289   'echo line 2 >>testfile1 &&
290    git add testfile1 &&
291    git commit -q -m "Append to testfile1" &&
292    git push gitcvs.git >/dev/null &&
293    cd cvswork &&
294    GIT_CONFIG="$git_config" cvs -Q update &&
295    test "$(echo $(grep testfile1 CVS/Entries|cut -d/ -f2,3,5))" = "testfile1/1.2/" &&
296    test_cmp testfile1 ../testfile1'
297
298 cd "$WORKDIR"
299 #TODO: cvsserver doesn't support update w/o -d
300 test_expect_failure "cvs update w/o -d doesn't create subdir (TODO)" '
301    mkdir test &&
302    echo >test/empty &&
303    git add test &&
304    git commit -q -m "Single Subdirectory" &&
305    git push gitcvs.git >/dev/null &&
306    cd cvswork &&
307    GIT_CONFIG="$git_config" cvs -Q update &&
308    test ! -d test
309 '
310
311 cd "$WORKDIR"
312 test_expect_success 'cvs update (subdirectories)' \
313   '(for dir in A A/B A/B/C A/D E; do
314       mkdir $dir &&
315       echo "test file in $dir" >"$dir/file_in_$(echo $dir|sed -e "s#/# #g")"  &&
316       git add $dir;
317    done) &&
318    git commit -q -m "deep sub directory structure" &&
319    git push gitcvs.git >/dev/null &&
320    cd cvswork &&
321    GIT_CONFIG="$git_config" cvs -Q update -d &&
322    (for dir in A A/B A/B/C A/D E; do
323       filename="file_in_$(echo $dir|sed -e "s#/# #g")" &&
324       if test "$(echo $(grep -v ^D $dir/CVS/Entries|cut -d/ -f2,3,5))" = "$filename/1.1/" &&
325         test_cmp "$dir/$filename" "../$dir/$filename"; then
326         :
327       else
328         echo >failure
329       fi
330     done) &&
331    test ! -f failure'
332
333 cd "$WORKDIR"
334 test_expect_success 'cvs update (delete file)' \
335   'git rm testfile1 &&
336    git commit -q -m "Remove testfile1" &&
337    git push gitcvs.git >/dev/null &&
338    cd cvswork &&
339    GIT_CONFIG="$git_config" cvs -Q update &&
340    test -z "$(grep testfile1 CVS/Entries)" &&
341    test ! -f testfile1'
342
343 cd "$WORKDIR"
344 test_expect_success 'cvs update (re-add deleted file)' \
345   'echo readded testfile >testfile1 &&
346    git add testfile1 &&
347    git commit -q -m "Re-Add testfile1" &&
348    git push gitcvs.git >/dev/null &&
349    cd cvswork &&
350    GIT_CONFIG="$git_config" cvs -Q update &&
351    test "$(echo $(grep testfile1 CVS/Entries|cut -d/ -f2,3,5))" = "testfile1/1.4/" &&
352    test_cmp testfile1 ../testfile1'
353
354 cd "$WORKDIR"
355 test_expect_success 'cvs update (merge)' \
356   'echo Line 0 >expected &&
357    for i in 1 2 3 4 5 6 7
358    do
359      echo Line $i >>merge
360      echo Line $i >>expected
361    done &&
362    echo Line 8 >>expected &&
363    git add merge &&
364    git commit -q -m "Merge test (pre-merge)" &&
365    git push gitcvs.git >/dev/null &&
366    cd cvswork &&
367    GIT_CONFIG="$git_config" cvs -Q update &&
368    test "$(echo $(grep merge CVS/Entries|cut -d/ -f2,3,5))" = "merge/1.1/" &&
369    test_cmp merge ../merge &&
370    ( echo Line 0; cat merge ) >merge.tmp &&
371    mv merge.tmp merge &&
372    cd "$WORKDIR" &&
373    echo Line 8 >>merge &&
374    git add merge &&
375    git commit -q -m "Merge test (merge)" &&
376    git push gitcvs.git >/dev/null &&
377    cd cvswork &&
378    sleep 1 && touch merge &&
379    GIT_CONFIG="$git_config" cvs -Q update &&
380    test_cmp merge ../expected'
381
382 cd "$WORKDIR"
383
384 cat >expected.C <<EOF
385 <<<<<<< merge.mine
386 Line 0
387 =======
388 LINE 0
389 >>>>>>> merge.3
390 EOF
391
392 for i in 1 2 3 4 5 6 7 8
393 do
394   echo Line $i >>expected.C
395 done
396
397 test_expect_success 'cvs update (conflict merge)' \
398   '( echo LINE 0; cat merge ) >merge.tmp &&
399    mv merge.tmp merge &&
400    git add merge &&
401    git commit -q -m "Merge test (conflict)" &&
402    git push gitcvs.git >/dev/null &&
403    cd cvswork &&
404    GIT_CONFIG="$git_config" cvs -Q update &&
405    test_cmp merge ../expected.C'
406
407 cd "$WORKDIR"
408 test_expect_success 'cvs update (-C)' \
409   'cd cvswork &&
410    GIT_CONFIG="$git_config" cvs -Q update -C &&
411    test_cmp merge ../merge'
412
413 cd "$WORKDIR"
414 test_expect_success 'cvs update (merge no-op)' \
415    'echo Line 9 >>merge &&
416     cp merge cvswork/merge &&
417     git add merge &&
418     git commit -q -m "Merge test (no-op)" &&
419     git push gitcvs.git >/dev/null &&
420     cd cvswork &&
421     sleep 1 && touch merge &&
422     GIT_CONFIG="$git_config" cvs -Q update &&
423     test_cmp merge ../merge'
424
425 cd "$WORKDIR"
426 test_expect_success 'cvs update (-p)' '
427     touch really-empty &&
428     echo Line 1 > no-lf &&
429     printf "Line 2" >> no-lf &&
430     git add really-empty no-lf &&
431     git commit -q -m "Update -p test" &&
432     git push gitcvs.git >/dev/null &&
433     cd cvswork &&
434     GIT_CONFIG="$git_config" cvs update &&
435     rm -f failures &&
436     for i in merge no-lf empty really-empty; do
437         GIT_CONFIG="$git_config" cvs update -p "$i" >$i.out
438         diff $i.out ../$i >>failures 2>&1
439     done &&
440     test -z "$(cat failures)"
441 '
442
443 cd "$WORKDIR"
444 test_expect_success 'cvs update (module list supports packed refs)' '
445     GIT_DIR="$SERVERDIR" git pack-refs --all &&
446     GIT_CONFIG="$git_config" cvs -n up -d 2> out &&
447     grep "cvs update: New directory \`master'\''" < out
448 '
449
450 #------------
451 # CVS STATUS
452 #------------
453
454 cd "$WORKDIR"
455 test_expect_success 'cvs status' '
456     mkdir status.dir &&
457     echo Line > status.dir/status.file &&
458     echo Line > status.file &&
459     git add status.dir status.file &&
460     git commit -q -m "Status test" &&
461     git push gitcvs.git >/dev/null &&
462     cd cvswork &&
463     GIT_CONFIG="$git_config" cvs update &&
464     GIT_CONFIG="$git_config" cvs status | grep "^File: status.file" >../out &&
465     test $(wc -l <../out) = 2
466 '
467
468 cd "$WORKDIR"
469 test_expect_success 'cvs status (nonrecursive)' '
470     cd cvswork &&
471     GIT_CONFIG="$git_config" cvs status -l | grep "^File: status.file" >../out &&
472     test $(wc -l <../out) = 1
473 '
474
475 cd "$WORKDIR"
476 test_expect_success 'cvs status (no subdirs in header)' '
477     cd cvswork &&
478     GIT_CONFIG="$git_config" cvs status | grep ^File: >../out &&
479     ! grep / <../out
480 '
481
482 #------------
483 # CVS CHECKOUT
484 #------------
485
486 cd "$WORKDIR"
487 test_expect_success 'cvs co -c (shows module database)' '
488     GIT_CONFIG="$git_config" cvs co -c > out &&
489     grep "^master[       ]\+master$" < out &&
490     ! grep -v "^master[  ]\+master$" < out
491 '
492
493 #------------
494 # CVS ANNOTATE
495 #------------
496
497 cd "$WORKDIR"
498 test_expect_success 'cvs annotate' '
499     cd cvswork &&
500     GIT_CONFIG="$git_config" cvs annotate merge >../out &&
501     sed -e "s/ .*//" ../out >../actual &&
502     for i in 3 1 1 1 1 1 1 1 2 4; do echo 1.$i; done >../expect &&
503     test_cmp ../expect ../actual
504 '
505
506 test_done