#!/bin/sh # # Regression tester for SRC. # # Set the umask for a bit of defensiveness umask 0077 # Needs to not be a subdirectory of here, or git gets confused. Use # -u so that src's initialization will be tested. SANDBOX=$(mktemp -u /tmp/src_XXXXXXXX) # Set the PATH to include the current directory, so the repository # head version of src can always be tested. PATH="$(pwd)":$PATH trap "rm -fr $SANDBOX" 0 1 2 15 backend="rcs" python="python" while getopts b:p:e: opt do case $opt in b) backend=$OPTARG;; p) python=$OPTARG;; e) src=$OPTARG;; esac done shift $(($OPTIND - 1)) $backend >/dev/null 2>&1 if [ "$?" = 127 ] then echo "srctest: backend ${backend} is missing." exit 1 fi if [ -z "$src" ] then src="${python} ${PWD}/src" fi check() { case $? in 0) echo "srctest ($python $backend): $1 succeeded";; *) echo "srctest ($python $backend): $1 failed"; exit 1;; esac } historify () { case $backend in rcs) history=.src/$1,v ;; sccs) history=SCCS/s.$1 ;; esac } mkdir $SANDBOX check "scratch directory creation" cd $SANDBOX TESTOPTS="-T $* $backend" DIFFOPTS="--label Expected --label Actual -u" COLUMNS=73 export COLUMNS cat >testfile1 </dev/null check "commit with -m option" $src $TESTOPTS cat testfile1 | diff -u testfile1 - >/dev/null check "content check after first commit" cat >testfile1 <testfile4 <testfile5 diff -u testfile4 testfile5 check "nonempty diff" ! $src $TESTOPTS diff -@ testfile1 2>diff.err && grep unexpected diff.err >/dev/null check "bogus diff option" sleep 1 # Force commit to have different timestamp echo "Second comment" | $src $TESTOPTS commit - testfile1 >/dev/null check "commit with -" $src $TESTOPTS cat testfile1 | diff $DIFFOPTS testfile1 - check "content check after second commit" cat >testfile2 <testfile3 diff $DIFFOPTS testfile2 testfile3 check "list test" cat >testfile2 <testfile3 diff $DIFFOPTS testfile2 testfile3 check "2-commit log test" cat >testfile1 <testfile4 </dev/null check "commit with -f" cat >testfile4 <testfile5 diff $DIFFOPTS testfile4 testfile5 check "3-commit log test" cat >testfile14 <testfile15 diff $DIFFOPTS testfile14 testfile15 check "log --patch" cat >testfile6 <testfile7 2>&1 diff $DIFFOPTS testfile6 testfile7 check "oob revision spec check" for rev in 1 2 3 do $src $TESTOPTS checkout $rev testfile1 >/dev/null check "revision $rev checkout test" diff $DIFFOPTS testrev${rev} testfile1 check "revision $rev content test" done if [ "$backend" = "sccs" ] then echo "srctest ($python $backend): skipping tag creation/deletion/listing checks." else $src $TESTOPTS tag create sampletag check "tag set to default tip revision" cat >testfile8 <testfile9 diff $DIFFOPTS testfile8 testfile9 check "tag list check" $src $TESTOPTS tag create basetag 1 check "tag set to revision 1" cat >testfile10 <testfile11 diff $DIFFOPTS testfile10 testfile11 check "second tag list check" $src $TESTOPTS tag delete sampletag check "tag deletion: sampletag" cat >testfile12 <testfile13 diff $DIFFOPTS testfile12 testfile13 check "tag list check after deletion" # Alas, we have to do this or the fast-export regression will fail. # We don't know how to be perfectly canonical about tags yet. $src $TESTOPTS tag delete basetag check "tag deletion: basetag" fi test_export () { testname="$1" shift srcfi=$testname-src.fi gitfi=$testname-git.fi mkdir foo $src $TESTOPTS fast-export "$@" >$srcfi 2>export.err grep jrh $srcfi >/dev/null check "fast-export: $testname" cat $srcfi | (cd foo >/dev/null; git init --quiet; git fast-import --quiet) if ! grep refs/heads/master $srcfi >/dev/null then perl -0777 -pi -e 's|^reset refs/heads/.+?\nfrom :.+?\n\n||gm' $srcfi fi (cd foo >/dev/null; git fast-export --all) >$gitfi diff $DIFFOPTS $srcfi $gitfi check "fast-export roundtrip: $testname" rm -fr foo } test_export filename testfile1 echo flower power >testfile14 $src $TESTOPTS commit -m "Alfred E. Newman" testfile14 >/dev/null test_export filenames testfile1 testfile14 historify testfile14 rm -f $history test_export revspec-filename -- testfile1 grep refs/heads/master revspec-filename-src.fi >/dev/null && ! grep refs/heads/testfile1/master revspec-filename-src.fi >/dev/null check "fast-export revspec/filename distinction" rm -f testfile1 test_export not-checked-out testfile1 check "fast-export consults history only" $src $TESTOPTS checkout testfile1 >/dev/null if [ "$backend" = "sccs" ] then echo "srctest ($python $backend): skipping fast-import checks: RCS-only" elif ! command -v rcs-fast-import >/dev/null 2>&1 then echo "srctest ($python $backend): skipping fast-import checks: rcs-fast-import missing" else mkdir RCS ! $src $TESTOPTS fast-import -p /dev/null 2>err && grep 'existing RCS' err >/dev/null check "fast-import don't clobber RCS" rm -fr RCS historify testfile1 rm -f $history $src $TESTOPTS fast-import -p /dev/null 2>&1 && test -f $history check "fast-import" $src $TESTOPTS fast-export testfile1 >testfile1.fi && diff -u filename-git.fi testfile1.fi check "fast-import roundtrip" fi $src $TESTOPTS move testfile1 newname1 check "move command" historify newname1 if [ -e newname1 -a -e $history ] then echo "srctest ($python $backend): content move succeeded" else echo "srctest ($python $backend): content move failed" exit 1 fi $src $TESTOPTS copy newname1 newname2 check "copy command" historify newname2 if [ -e newname2 -a -e $history ] then echo "srctest ($python $backend): content copy succeeded" else echo "srctest ($python $backend): content copy failed" exit 1 fi cat >testfile16 <>testfile16 $src $TESTOPTS status testfile16 | grep "^M" >/dev/null check "M status check after modification" rm testfile16 $src $TESTOPTS status testfile16 | grep "^!" >/dev/null check "! status check after deletion" $src $TESTOPTS checkout testfile16 $src $TESTOPTS status testfile16 | grep "^=" >/dev/null check "= status check after restoration" historify testfile16 rm -f $history $src $TESTOPTS status testfile16 | grep "^?" >/dev/null check "? status check after master deletion" $src $TESTOPTS amend -m "Amended comment" newname1 check "amend" $src $TESTOPTS list 3 newname1 | grep "Amended comment" >/dev/null check "amended comment content" cat >testfile17 </dev/null check "unadorned status command" if [ "$backend" = "sccs" ] then echo "srctest ($python $backend): skipping tag and branch tests" else # Introduce a test history with some branchiness, so # we can test traversal across branch joins. Also has tags. cat >.src/sample,v <sampledot <1First comment.>]; 1 -> 2; 2 [shape=box,width=5,label=<
2Second comment.
>]; 2 -> 3; 3 [shape=box,width=5,label=<
3Third comment.
>]; 3 -> 4; 4 [shape=box,width=5,label=<
4On a branch?
>]; "trunk" [shape=oval,width=2]; "4" -> "trunk" [style=dotted]; 3 -> 5; 5 [shape=box,width=5,label=<
5Totally unfubared.
>]; 5 -> 6; 6 [shape=box,width=5,label=<
6Still utterly fubar
>]; 6 -> 7; 7 [shape=box,width=5,label=<
7Totally chenille.
>]; 7 -> 8; 8 [shape=box,width=5,label=<
8Utterly fubar
>]; "muggle" [shape=oval,width=2]; "8" -> "muggle" [style=dotted]; 8 -> 9; 9 [shape=box,width=5,label=<
9All fixed up.
>]; 9 -> 10; 10 [shape=box,width=5,label=<
10It' all good.
>]; 10 -> 11; 11 [shape=box,width=5,label=<
11No good.
>]; 11 -> 12; 12 [shape=box,width=5,label=<
12That's good.
>]; 12 -> 13; 13 [shape=box,width=5,label=<
13I see you
>]; "sample" [shape=oval,width=2]; "13" -> "sample" [style=dotted]; {rank=same; "GLARB"; "4"} "GLARB" -> "4" [style=dotted]; {rank=same; "GORP"; "8"} "GORP" -> "8" [style=dotted]; } EOF $src $TESTOPTS visualize sample >tryit diff $DIFFOPTS sampledot tryit check "dot visualization" cat >statuslog <sample.seqlog <tryit diff $DIFFOPTS sample.seqlog tryit check "traversal by -" cat >sample.branchlog <tryit diff $DIFFOPTS sample.branchlog tryit check "traversal by .." cat >sample.branchlog-p <tryit diff $DIFFOPTS sample.branchlog-p tryit check "branchy log --patch" cat >sample.taglog <tryit diff $DIFFOPTS sample.taglog tryit check "named-tag lookup with @" $src $TESTOPTS rename tag GLARB GROTTY sample check "tag renaming" cat >changes <tryit diff $DIFFOPTS tryit changes check "tag list after rename" cat >branchlist <tryit check "branch list" $src $TESTOPTS branch -l sample >tryit diff $DIFFOPTS branchlist tryit check "branch list content" cat >branchlog <branchlog check "branch name resolution" $src $TESTOPTS list @trunk sample >tryit diff $DIFFOPTS branchlog tryit check "branch name resolved content" cat >statuslog <tryit diff $DIFFOPTS statuslog tryit check "status before ignore" echo "newname1" >.srcignore cat >statuslog <tryit diff $DIFFOPTS statuslog tryit check "status after ignore" $src $TESTOPTS branch delete trunk sample check "branch delete" cat >newlist <tryit diff $DIFFOPTS newlist tryit check "branch list check after delete" cat >newlog <tryit diff $DIFFOPTS newlog tryit check "content after branch deletion" fi echo "Random content for numeric file" >23 $src $TESTOPTS commit -m "I don't know why you say goodbye" -- 23 >/dev/null check "commit of file with numeric name" cat >randomcontent <tryit diff $DIFFOPTS randomcontent tryit check "cat of file with numeric name" # Eric Sunshine writes: # # The test itself is working properly. The problem is that stock SCCS # does not preserve executable permission on files under its control, so # the test is correctly failing. # # The GNU version of SCCS does provide an 'x' flag[1] for compatibility # with SCO OpenServer which enables executable permission preservation. # However, I haven't convinced myself that it would make sense to put in # the work to add executable-preservation support to the SCCS backend # for these special cases (GNU CSSC and SCO OpenServer). # # [1]: https://www.gnu.org/software/cssc/manual/Flags.html#Flag # if [ "$backend" = sccs ] then echo "srctest ($python $backend): skipping exec-bit propagation test" else echo "Should not be executable" >exectest $src $TESTOPTS commit -m "First comment on exectest" exectest >/dev/null check "first commit of exectest" chmod a+x exectest echo "Should be executable" >exectest $src $TESTOPTS commit -m "Second comment on exectest" exectest >/dev/null check "second commit of exectest" ls -l exectest | grep '^...x' >/dev/null check "propagation of exec bit" fi cat >diffall.expect <>newname1 echo "and even more" >>newname2 $src $TESTOPTS diff >diffall.actual && diff $DIFFOPTS diffall.expect diffall.actual && $src $TESTOPTS checkout newname1 newname2 >/dev/null check "default file list" cat >limit.list <limit.log <limit.expect diff limit.$i limit.expect check "$i $j" done done # Test for Tom Willemse's multi-commit bug. echo "test 1" > file1 echo "test 2" > file2 $src $TESTOPTS commit -m "Initial commit" file1 file2 >/dev/null check "multi-file registration" echo "test 1 line 2" >> file1 echo "test 2 line 2" >> file2 $src $TESTOPTS commit -m "Second commit" file1 file2 >/dev/null check "multi-file commit" # Test the edit logic cat >modify <<'EOF' echo "Different first line" >modified$$ cat $1 >>modified$$ mv modified$$ $1 EOF chmod a+x modify echo "test 1 line 3" >> file1 EDITOR="./modify" $src $TESTOPTS commit file1 check "edit logic" cat >binary <binary.chk <>binary $src $TESTOPTS commit -m "Binary file after modification." binary cmp binary binary.chk check "binary content in checkouts and commits" if [ "$backend" = "sccs" ] then echo "srctest ($python $backend): skipping binary cat test" else $src $TESTOPTS cat binary >catted cmp binary catted check "binary content in cat" fi cat >newline <newline.chk <>newline $src $TESTOPTS commit -m "DOS newline file after modification." newline cmp newline newline.chk check "newline preservation in checkouts and commits" if [ "$backend" = "sccs" ] then echo "srctest ($python $backend): skipping newline cat test" else $src $TESTOPTS cat newline >ncatted cmp newline ncatted check "newline content in cat" fi cat >padcomment <<'EOF' printf "\n\n\n\n" >modified$$ cat $1 >>modified$$ mv modified$$ $1 EOF chmod a+x padcomment echo gommelgor >padfile $src $TESTOPTS commit -m pingle padfile for i in commit amend do echo "more stuff" >>padfile EDITOR="./padcomment" $src $TESTOPTS $i padfile >padout grep cancelled padout >/dev/null check "whitespace-only $i cancel" $src $TESTOPTS checkout padfile done cat >clonemsg <<'EOF' echo "I think I'm a clone now" >modified$$ cat $1 >>modified$$ mv modified$$ $1 cp $1 clonedmsg EOF chmod a+x clonemsg echo gommelgor >diffledore $src $TESTOPTS commit -m pingle diffledore for i in commit amend do test $i = commit && echo "more stuff" >>diffledore EDITOR="./clonemsg" $src $TESTOPTS $i diffledore >/dev/null grep -F -e 'Changes to be committed' clonedmsg >/dev/null && grep -F -e '@@ ' clonedmsg >/dev/null && grep -F -e '+++ ' clonedmsg >/dev/null && grep -F -e '--- ' clonedmsg >/dev/null check "$i diff in boilerplate" done cat >dontinvoke <<'EOF' echo "panic!" >>nochanges EOF chmod a+x dontinvoke echo "bingleby" >canttouchthis $src $TESTOPTS commit -m pingle canttouchthis EDITOR="./dontinvoke" $src $TESTOPTS commit canttouchthis >>nochanges grep 'no changes to commit' nochanges >/dev/null && ! grep panic nochanges >/dev/null check "nothing to commit" cat >ignore.ws <ignore.ws <ignore.expect-b <ignore.expect-w <ignore.actual$i diff ignore.expect$i ignore.actual$i check "diff $i" done if [ "$backend" = "sccs" ] then echo "srctest ($python $backend): skipping commit date tie-breaking tests" else # Introduce a test history with all commits having same date so we can # test native revision ID tie-breaking. cat >.src/tiebreak,v < Author-Date: Mon 20 Nov 2017 21:37:42 -0500 Committer: Roy G. Biv Committer-Date: Tue 21 Nov 2017 01:45:15 +0000 Mark: :22 Parents: :20 eleventh @ text @eleventh @ 1.10 log @Author: Eric Sunshine Author-Date: Mon 20 Nov 2017 21:30:40 -0500 Committer: Roy G. Biv Committer-Date: Tue 21 Nov 2017 01:45:15 +0000 Mark: :20 Parents: :18 tenth @ text @d1 1 a1 1 tenth @ 1.9 log @Author: Eric Sunshine Author-Date: Mon 20 Nov 2017 21:27:29 -0500 Committer: Roy G. Biv Committer-Date: Tue 21 Nov 2017 01:45:15 +0000 Mark: :18 Parents: :16 ninth @ text @d1 1 a1 1 ninth @ 1.8 log @Author: Eric Sunshine Author-Date: Mon 20 Nov 2017 21:25:22 -0500 Committer: Roy G. Biv Committer-Date: Tue 21 Nov 2017 01:45:15 +0000 Mark: :16 Parents: :14 eighth @ text @d1 1 a1 1 eighth @ 1.7 log @Author: Eric Sunshine Author-Date: Mon 20 Nov 2017 23:02:46 -0500 Committer: Roy G. Biv Committer-Date: Tue 21 Nov 2017 01:45:15 +0000 Mark: :14 Parents: :12 seventh @ text @d1 1 a1 1 seventh @ 1.6 log @Author: Eric Sunshine Author-Date: Mon 20 Nov 2017 22:56:46 -0500 Committer: Roy G. Biv Committer-Date: Tue 21 Nov 2017 01:45:15 +0000 Mark: :12 Parents: :10 sixth @ text @d1 1 a1 1 sixth @ 1.5 log @Author: Eric Sunshine Author-Date: Fri 03 Nov 2017 13:30:17 -0500 Committer: Roy G. Biv Committer-Date: Tue 21 Nov 2017 01:45:15 +0000 Mark: :10 Parents: :8 fifth @ text @d1 1 a1 1 fifth @ 1.4 log @Author: Eric Sunshine Author-Date: Fri 03 Nov 2017 13:28:35 -0500 Committer: Roy G. Biv Committer-Date: Tue 21 Nov 2017 01:45:15 +0000 Mark: :8 Parents: :6 fourth @ text @d1 1 a1 1 fourth @ 1.3 log @Author: Eric Sunshine Author-Date: Fri 03 Nov 2017 13:26:41 -0500 Committer: Roy G. Biv Committer-Date: Tue 21 Nov 2017 01:45:15 +0000 Mark: :6 Parents: :4 third @ text @d1 1 a1 1 third @ 1.2 log @Author: Eric Sunshine Author-Date: Fri 03 Nov 2017 13:25:01 -0500 Committer: Roy G. Biv Committer-Date: Tue 21 Nov 2017 01:45:15 +0000 Mark: :4 Parents: :2 second @ text @d1 1 a1 1 second @ 1.1 log @Author: Eric Sunshine Author-Date: Fri 03 Nov 2017 13:12:48 -0500 Committer: Roy G. Biv Committer-Date: Tue 21 Nov 2017 01:45:15 +0000 Mark: :2 first @ text @d1 1 a1 1 first @ EOF cat >tiebreak.expect <tiebreak.actual diff tiebreak.expect tiebreak.actual check "same date tie-breaking" cat >noheaders.expect <noheaders.actual diff noheaders.expect noheaders.actual check "log suppresses headers" cat >logheaders.expect < Author-Date: 2017-11-21T02:37:42Z Author-Date-Offset: -18000 Committer: Roy G. Biv Committer-Date: 2017-11-21T01:45:15Z Committer-Date-Offset: 0 Mark: :22 Parents: :20 eleventh ------------------------------------------------------------------------ 10 | 1970-01-02T00:09:00Z | trunk Author: Eric Sunshine Author-Date: 2017-11-21T02:30:40Z Author-Date-Offset: -18000 Committer: Roy G. Biv Committer-Date: 2017-11-21T01:45:15Z Committer-Date-Offset: 0 Mark: :20 Parents: :18 tenth ------------------------------------------------------------------------ EOF $src $TESTOPTS log -v -v -2 tiebreak >logheaders.actual diff logheaders.expect logheaders.actual check "log -v -v shows all headers" cat >summaryheaders.expect < 2017-11-21T02:37:42Z Committer: Roy G. Biv 2017-11-21T01:45:15Z eleventh ------------------------------------------------------------------------ 10 | 1970-01-02T00:09:00Z | trunk Author: Eric Sunshine 2017-11-21T02:30:40Z Committer: Roy G. Biv 2017-11-21T01:45:15Z tenth ------------------------------------------------------------------------ EOF $src $TESTOPTS log -v -2 tiebreak >summaryheaders.actual diff summaryheaders.expect summaryheaders.actual check "log -v shows summarized headers" cat >authordate.expect <authordate.actual $src ${TESTOPTS#-T} log -2 tiebreak >>authordate.actual diff authordate.expect authordate.actual check "author date from RFC 822 header" cat >rfc822export.expect < 1509732768 -0500 committer Roy G. Biv 1511228715 +0000 EOF $src ${TESTOPTS#-T} fast-export 1 tiebreak | grep -E 'author|committer' >rfc822export.actual diff rfc822export.expect rfc822export.actual check "fast-export: consult RFC 822 headers" fi echo "srctest ($python $backend): all tests succeeded" rm -fr $SANDBOX # end