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