diff options
Diffstat (limited to '')
-rwxr-xr-x | t/mirror-test | 445 | ||||
-rw-r--r-- | t/mirror-test-rc | 162 | ||||
-rwxr-xr-x | t/mirror-test-setup.sh | 196 | ||||
-rw-r--r-- | t/mirror-test-ssh-config | 11 |
4 files changed, 814 insertions, 0 deletions
diff --git a/t/mirror-test b/t/mirror-test new file mode 100755 index 0000000..3ace59b --- /dev/null +++ b/t/mirror-test @@ -0,0 +1,445 @@ +#!/usr/bin/perl +use strict; +use warnings; + +# you need 3 disposable userids: sam, frodo, gollum. Then the test user (say +# "g3") needs to be able to sudo into them. Put this in /etc/sudoers: + +# g3 ALL = (sam,frodo,gollum) NOPASSWD: ALL + +$ENV{TSH_ERREXIT} = 1; + +# this is hardcoded; change it if needed +use lib "src/lib"; +use Gitolite::Test; +use Cwd; +my $workdir = getcwd(); +my $h = $ENV{HOME}; +my ($t, $t2); # temp vars + +# basic tests +# ---------------------------------------------------------------------- + +try "plan 152"; +## try "DEF POK = !/DENIED/; !/failed to push/"; + +## confreset;confadd ' + +## '; + +## try "ADMIN_PUSH set1; !/FATAL/" or die text(); + +# ---------------------------------------------------------------------- + +# switch keys +sub swk { + my $h = $ENV{HOME}; + my $k = shift; + system("cp $h/.ssh/$k $h/.ssh/id_rsa"); + system("cp $h/.ssh/$k.pub $h/.ssh/id_rsa.pub"); +} + +sub all { + try "F " . join(" ", @_); + try "S " . join(" ", @_); + try "G " . join(" ", @_); +} + +try " + DEF F = sudo -u frodo -i + DEF S = sudo -u sam -i + DEF G = sudo -u gollum -i +"; + +my $bd = `gitolite query-rc -n GL_BINDIR`; + +try " + $bd/../t/mirror-test-setup.sh; ok or die mirror setup shell script failed + /hello server-frodo, this is frodo/ + /hello server-sam, this is frodo/ + /hello server-gollum, this is frodo/ + /hello server-frodo, this is sam/ + /hello server-sam, this is sam/ + /hello server-gollum, this is sam/ + /hello server-frodo, this is gollum/ + /hello server-sam, this is gollum/ + /hello server-gollum, this is gollum/ + /hello admin, this is frodo/ + /Initialized empty .*/gitolite-admin.git/ + /Initialized empty .*/r1.git/ + /Initialized empty .*/r2.git/ + /Initialized empty .*/testing.git/ + /Initialized empty .*/gitolite-admin.git/ + /Initialized empty .*/r1.git/ + /Initialized empty .*/r2.git/ + /Initialized empty .*/testing.git/ + /Initialized empty .*/gitolite-admin.git/ + /Initialized empty .*/r1.git/ + /Initialized empty .*/r2.git/ + /Initialized empty .*/testing.git/ +"; + +# ---------------------------------------------------------------------- +# SECTION 1: gitolite-admin shenanigans + +# push to frodo and see sam and gollum change +try " + git clone frodo\@localhost:gitolite-admin fga + ok; /Cloning into 'fga'.../ + cd fga; ok + cp $h/.ssh/u?.pub keydir; ok + git add keydir; ok + git commit -m 6keys; ok + git push; ok + /To localhost:gitolite-admin/ + /master -> master/ + sleep 5 + git rev-parse HEAD +"; + +chomp($t = text()); + +try " + git ls-remote sam\@localhost:gitolite-admin + ok; /$t/ + git ls-remote gollum\@localhost:gitolite-admin + ok; /$t/ +"; + +try " + cd .. + +"; + +# push to sam and see frodo and gollum change +try " + git clone sam\@localhost:gitolite-admin sga + ok; /Cloning into 'sga'.../ + cd sga; ok + empty; ok + git push; ok + /To localhost:gitolite-admin/ + /master -> master/ + sleep 5 + git rev-parse HEAD +"; + +chomp($t = text()); + +try " + git ls-remote frodo\@localhost:gitolite-admin + ok; /$t/ + git ls-remote gollum\@localhost:gitolite-admin + ok; /$t/ +"; + +try " + cd .. + +"; + +# push to gollum and fail at gollum +try " + git clone gollum\@localhost:gitolite-admin gga + ok; /Cloning into 'gga'.../ + cd gga; ok + empty; ok + git push; !ok + !/To localhost:gitolite-admin/ + !/master -> master/ + /gollum: pushing 'gitolite-admin' to copy 'gollum' not allowed/ + git rev-parse HEAD +"; + +chomp($t2 = text()); + +try " + git ls-remote frodo\@localhost:gitolite-admin + ok; /$t/; !/$t2/ + git ls-remote sam\@localhost:gitolite-admin + ok; /$t/; !/$t2/ + git ls-remote gollum\@localhost:gitolite-admin + ok; /$t/; !/$t2/ +"; + +# fake out the gollum failure to continue the redirected push and fail at frodo +try " + sudo -u gollum -i gitolite git-config -r gitolite-admin . + ok + /redirectOK.*sam/ + !/redirectOK.*gollum/ + + sudo -u gollum -i bash -c 'echo repo gitolite-admin > junk' + sudo -u gollum -i bash -c 'echo option mirror.redirectOK-1 = gollum >> junk' + sudo -u gollum -i bash -c 'cat junk >> .gitolite/conf/gitolite.conf' + sudo -u gollum -i gitolite compile + sudo -u gollum -i gitolite git-config -r gitolite-admin . + ok + /redirectOK.*sam/ + /redirectOK.*gollum/ + + git push; !ok + /frodo: redirection not allowed from 'gollum'/ + !/To gollum\@localhost:gitolite-admin/ + !/master -> master/ +"; + +# reset gollum via frodo +try " + cd .. + rm -rf fga + git clone frodo\@localhost:gitolite-admin fga + ok; /Cloning into 'fga'.../ + cd fga; ok + empty; ok + git push; ok + /To localhost:gitolite-admin/ + /master -> master/ + sleep 5 + + sudo -u gollum -i gitolite git-config -r gitolite-admin . + ok + /redirectOK.*sam/ + !/redirectOK.*gollum/ + + git rev-parse HEAD +"; + +chomp($t = text()); + +try " + git ls-remote sam\@localhost:gitolite-admin + ok; /$t/ + git ls-remote gollum\@localhost:gitolite-admin + ok; /$t/ +"; + +# ---------------------------------------------------------------------- +# user repo shenanigans + +# for a recap of the perms see t/mirror-test-setup.sh + +try " + cd .. + pwd + /tmp/tsh_tempdir/ or die not in the right place +" or die; + +swk('u1'); + +# u1 sam r1, R ok, W ok +try " + rm -rf fga sga gga + + git clone sam\@localhost:r1 sr1 + /Cloning into 'sr1'.../ + /warning: You appear to have cloned an empty repository/ + cd sr1 + empty + git push origin master + /new branch/; /master -> master/ + sleep 5 + git rev-parse HEAD +"; +chomp($t = text()); + +# u1 sam r1, W mirrors to frodo but not gollum +try " + git ls-remote sam\@localhost:r1 + /$t/ + git ls-remote frodo\@localhost:r1 + /$t/ + git ls-remote gollum\@localhost:r1 + /gollum: 'r1' is mirrored but not here/ +"; + +swk("u2"); +try " + empty + git rev-parse HEAD +"; +chomp($t2 = text()); + +# u2 sam r2 W ok, mirrors to all +try " + git push sam\@localhost:r2 master + /new branch/; /master -> master/ + /master -> master/ + sleep 5 + git ls-remote frodo\@localhost:r2 + !/$t/ + /$t2/ + git ls-remote gollum\@localhost:r2 + !/$t/ + /$t2/ +"; + +swk("u1"); + +# u1 gollum r1 -- "known unknown" :-) +# u1 frodo r1 R ok, W not ok +# u1 sam r1 R ok, W ok +try " + cd .. + rm -rf sr1 + + git clone gollum\@localhost:r1 fr1 + /gollum: 'r1' is mirrored but not here/ + + git clone frodo\@localhost:r1 fr1; ok + cd fr1 + empty + git push + /frodo: pushing 'r1' to copy 'frodo' not allowed/ + cd .. + git clone sam\@localhost:r1 sr1; ok + cd sr1 + empty + git push; ok + /master -> master/ + sleep 5 + git rev-parse HEAD +"; +chomp($t = text()); + +# u1 sam r1 W mirrored to frodo but not gollum +try " + git ls-remote sam\@localhost:r1 + /$t/ + git ls-remote frodo\@localhost:r1 + /$t/ + + git ls-remote gollum\@localhost:r1 + /gollum: 'r1' is mirrored but not here/ + + git reset --hard HEAD^; ok + tc a + git push; !ok + /rejected/ + /failed to push/ + + git push -f + /\\+ .......\\.\\.\\........ master -> master .forced update/ + sleep 5 +"; + +swk("u2"); + +# u2 frodo r1 R ok, W not allowed (no redirectOK) +# u2 frodo r2 W ok +try " + cd .. + rm -rf fr1 sr1 + + git clone frodo\@localhost:r1 fr1; ok + cd fr1 + tc b + git push + /frodo: pushing 'r1' to copy 'frodo' not allowed/ + cd .. + git clone frodo\@localhost:r2 fr2; ok + cd fr2 + tc c + git push + /master -> master/ + sleep 5 + git rev-parse HEAD +"; +chomp($t = text()); + +# u2 frodo r2 W mirrors to sam and gollum +try " + git ls-remote sam\@localhost:r2 + /$t/ + git ls-remote gollum\@localhost:r2 + /$t/ + + git reset --hard HEAD^; ok + tc d + git push + /rejected/ + /failed to push/ + + git push -f + /\\+ .......\\.\\.\\........ master -> master .forced update/ + sleep 5 + + cd .. + rm -rf fr1 fr2 +"; + +swk("u3"); + +# u3 frodo r2 R ok W ok +try " + git clone frodo\@localhost:r2 fr2; ok + cd fr2 + tc e + git push; ok + sleep 5 + + git rev-parse HEAD +"; +chomp($t = text()); + +# u3 frodo r2 W mirrors to sam and gollum +try " + git ls-remote sam\@localhost:r2 + /$t/ + git ls-remote gollum\@localhost:r2 + /$t/ + + git reset --hard HEAD^; ok + tc f + git push + /rejected/ + /failed to push/ + + sleep 10 + git push -f + /\\+ refs/heads/master r2 u3 DENIED by fallthru/ + /hook declined/ + /rejected/ +"; + +# ---------------------------------------------------------------------- +# all those vague edge cases where the two servers have totally wrong ideas +# about each other + +swk('u1'); + +try "sudo -u frodo -i ls .gitolite/logs"; +chomp($t = text()); +my $lfn = ".gitolite/logs/$t"; + +try " + ssh sam\@localhost mirror push frodo lfrodo; !ok + /FATAL: frodo: 'lfrodo' is local/ + + ssh sam\@localhost mirror push frodo mboth; !ok + /FATAL: frodo: 'mboth' is native/ + + ssh sam\@localhost mirror push frodo mnotsam; !ok + /FATAL: frodo: 'sam' is not the master for 'mnotsam'/ + + cd .. + git clone sam\@localhost:lfrodo2 lfrodo2; ok + cd lfrodo2 + empty + git push origin master; !ok + /FATAL: frodo: 'lfrodo2' is local/ + + cd .. + git clone sam\@localhost:nnfrodo nnfrodo; ok + cd nnfrodo + empty + git push origin master; !ok + /FATAL: frodo: 'nnfrodo' is not native/ + + cd .. + git clone sam\@localhost:nvsfrodo nvsfrodo; ok + cd nvsfrodo + empty + git push origin master; !ok + /FATAL: frodo: 'sam' is not a valid copy for 'nvsfrodo'/ +"; diff --git a/t/mirror-test-rc b/t/mirror-test-rc new file mode 100644 index 0000000..1d76783 --- /dev/null +++ b/t/mirror-test-rc @@ -0,0 +1,162 @@ +# This file is in perl syntax. But you do NOT need to know perl to edit it -- +# just mind the commas, use single quotes unless you know what you're doing, +# and make sure the brackets and braces stay matched up! + +# (Tip: perl allows a comma after the last item in a list also!) + +# HELP for commands (see COMMANDS list below) can be had by running the +# command with "-h" as the sole argument. + +# HELP for all the other FEATURES can be found in the documentation (look for +# "list of non-core programs shipped with gitolite" in the master index) or +# directly in the corresponding source file. + +%RC = ( + + # ------------------------------------------------------------------ + + HOSTNAME => '%HOSTNAME', + + # default umask gives you perms of '0700'; see the rc file docs for + # how/why you might change this + UMASK => 0077, + + # look in the "GIT-CONFIG" section in the README for what to do + GIT_CONFIG_KEYS => '', + + # comment out if you don't need all the extra detail in the logfile + LOG_EXTRA => 1, + + # roles. add more roles (like MANAGER, TESTER, ...) here. + # WARNING: if you make changes to this hash, you MUST run 'gitolite + # compile' afterward, and possibly also 'gitolite trigger POST_COMPILE' + ROLES => { + READERS => 1, + WRITERS => 1, + }, + # uncomment (and change) this if you wish + # DEFAULT_ROLE_PERMS => 'READERS @all', + + # CACHE => 'Redis', + + # ------------------------------------------------------------------ + + # rc variables used by various features + + # the 'info' command prints this as additional info, if it is set + # SITE_INFO => 'Please see http://blahblah/gitolite for more help', + + # the 'desc' command uses this + # WRITER_CAN_UPDATE_DESC => 1, + + # the CpuTime feature uses these + # display user, system, and elapsed times to user after each git operation + # DISPLAY_CPU_TIME => 1, + # display a warning if total CPU times (u, s, cu, cs) crosses this limit + # CPU_TIME_WARN_LIMIT => 0.1, + + # the Mirroring feature needs this + # HOSTNAME => "foo", + + # if you enabled 'Shell', you need this + # SHELL_USERS_LIST => "$ENV{HOME}/.gitolite.shell-users", + + # ------------------------------------------------------------------ + + # List of commands and features to enable + + ENABLE => [ + + # COMMANDS + + # These are the commands enabled by default + 'help', + 'desc', + 'info', + 'perms', + 'writable', + + 'mirror', + + # Uncomment or add new commands here. + # 'create', + # 'fork', + # 'mirror', + # 'sskm', + # 'D', + + # These FEATURES are enabled by default. + + # essential (unless you're using smart-http mode) + 'ssh-authkeys', + + # creates git-config enties from gitolite.conf file entries like 'config foo.bar = baz' + 'git-config', + + # creates git-daemon-export-ok files; if you don't use git-daemon, comment this out + 'daemon', + + # creates projects.list file; if you don't use gitweb, comment this out + 'gitweb', + + # These FEATURES are disabled by default; uncomment to enable. If you + # need to add new ones, ask on the mailing list :-) + + # user-visible behaviour + + # prevent wild repos auto-create on fetch/clone + # 'no-create-on-read', + # no auto-create at all (don't forget to enable the 'create' command!) + # 'no-auto-create', + + # access a repo by another (possibly legacy) name + # 'Alias', + + # give some users direct shell access + # 'Shell', + + # system admin stuff + + # enable mirroring (don't forget to set the HOSTNAME too!) + 'Mirroring', + + # allow people to submit pub files with more than one key in them + # 'ssh-authkeys-split', + + # selective read control hack + # 'partial-copy', + + # manage local, gitolite-controlled, copies of read-only upstream repos + # 'upstream', + + # updates 'description' file instead of 'gitweb.description' config item + # 'cgit', + + # performance, logging, monitoring... + + # be nice + # 'renice 10', + + # log CPU times (user, system, cumulative user, cumulative system) + # 'CpuTime', + + # syntactic_sugar for gitolite.conf and included files + + # allow backslash-escaped continuation lines in gitolite.conf + # 'continuation-lines', + + # create implicit user groups from directory names in keydir/ + # 'keysubdirs-as-groups', + + ], + +); + +# ------------------------------------------------------------------------------ +# per perl rules, this should be the last line in such a file: +1; + +# Local variables: +# mode: perl +# End: +# vim: set syn=perl: diff --git a/t/mirror-test-setup.sh b/t/mirror-test-setup.sh new file mode 100755 index 0000000..32bc462 --- /dev/null +++ b/t/mirror-test-setup.sh @@ -0,0 +1,196 @@ +#!/bin/bash + +set -e +hosts="frodo sam gollum" +mainhost=frodo + +# setup software +bd=`gitolite query-rc -n GL_BINDIR` +mkdir -p /tmp/g3 +rm -rf /tmp/g3/src +cp -a $bd /tmp/g3/src +chmod -R go+rX /tmp/g3 + +# setup symlinks in frodo, sam, and gollum's accounts +for h in $hosts +do + sudo -u $h -i bash -c "rm -rf *.pub bin .ssh projects.list repositories .gitolite .gitolite.rc" +done + +[ "$1" = "clear" ] && exit + +cd /tmp/g3 +[ -d keys ] || { + mkdir keys + cd keys + for h in $hosts + do + ssh-keygen -N '' -q -f server-$h -C $h + chmod go+r /tmp/g3/keys/server-$h + done + cp $bd/../t/mirror-test-ssh-config ssh-config +} +chmod -R go+rX /tmp/g3 + +for h in $hosts +do + sudo -u $h -i bash -c "mkdir -p bin; ln -sf /tmp/g3/src/gitolite bin; mkdir -p .ssh; chmod 0700 .ssh" + + sudo -u $h -i cp /tmp/g3/keys/ssh-config .ssh/config + sudo -u $h -i cp /tmp/g3/keys/server-$h .ssh/id_rsa + sudo -u $h -i cp /tmp/g3/keys/server-$h.pub .ssh/id_rsa.pub + sudo -u $h -i chmod go-rwx .ssh/id_rsa .ssh/config + +done + +# add all pubkeys to all servers +for h in $hosts +do + sudo -u $h -i gitolite setup -a admin + for j in $hosts + do + sudo -u $h -i gitolite setup -pk /tmp/g3/keys/server-$j.pub + echo sudo _u $j _i ssh $h@localhost info + sudo -u $j -i ssh -o StrictHostKeyChecking=no $h@localhost info + done + echo ---- +done + +# now copy our admin key to the main host +cd;cd .ssh +cp admin id_rsa; cp admin.pub id_rsa.pub +cp admin.pub /tmp/g3/keys; chmod go+r /tmp/g3/keys/admin.pub +sudo -u $mainhost -i gitolite setup -pk /tmp/g3/keys/admin.pub +ssh $mainhost@localhost info + +lines=" +repo gitolite-admin + option mirror.master = frodo + option mirror.copies-1 = sam gollum + option mirror.redirectOK = sam + +repo r1 + RW+ = u1 + RW = u2 + R = u3 + option mirror.master = sam + option mirror.copies-1 = frodo + +repo r2 + RW+ = u2 + RW = u3 + R = u4 + option mirror.master = sam + option mirror.copies-1 = frodo gollum + option mirror.redirectOK = all + +include \"%HOSTNAME.conf\" +" + +lines2=" +repo l-%HOSTNAME +RW = u1 +" + +# for each server, set the HOSTNAME to the rc, add the mirror options to the +# conf file, and compile +for h in $hosts +do + cat $bd/../t/mirror-test-rc | perl -pe "s/%HOSTNAME/$h/" > /tmp/g3/temp + chmod go+rX /tmp/g3/temp + sudo -u $h -i cp /tmp/g3/temp .gitolite.rc + echo "$lines" | sudo -u $h -i sh -c 'cat >> .gitolite/conf/gitolite.conf' + echo "$lines2" | sudo -u $h -i sh -c "cat >> .gitolite/conf/$h.conf" + sudo -u $h -i gitolite setup +done + +# goes on frodo +lines=" +# local to frodo but sam thinks frodo is a copy +repo lfrodo +RW = u1 + +# both think they're master +repo mboth +RW = u1 +option mirror.master = frodo +option mirror.copies = sam + +# frodo thinks someone else is the master but sam thinks he is +repo mnotsam +RW = u1 +option mirror.master = merry +option mirror.copies = frodo + +# local to frodo but sam thinks frodo is a master and redirect is OK +repo lfrodo2 +RW = u1 + +# non-native to frodo but sam thinks frodo is master +repo nnfrodo +RW = u1 +option mirror.master = gollum +option mirror.copies = frodo +option mirror.redirectOK = all + +# sam is not a valid copy to send stuff to frodo +repo nvsfrodo +RW = u1 +option mirror.master = frodo +option mirror.copies = gollum +option mirror.redirectOK = all +" + +echo "$lines" | sudo -u frodo -i sh -c "cat >> .gitolite/conf/frodo.conf" + +# goes on sam +lines=" +# local to frodo but sam thinks frodo is a copy +repo lfrodo +RW = u1 +option mirror.master = sam +option mirror.copies = frodo + +# both think they're master +repo mboth +RW = u1 +option mirror.master = sam +option mirror.copies = frodo + +# frodo thinks someone else is the master but sam thinks he is +repo mnotsam +RW = u1 +option mirror.master = sam +option mirror.copies = frodo + +# local to frodo but sam thinks frodo is a master and redirect is OK +repo lfrodo2 +RW = u1 +option mirror.master = frodo +option mirror.copies = sam +option mirror.redirectOK = all + +# non-native to frodo but sam thinks frodo is master +repo nnfrodo +RW = u1 +option mirror.master = frodo +option mirror.copies = sam +option mirror.redirectOK = all + +# sam is not a valid copy to send stuff to frodo +repo nvsfrodo +RW = u1 +option mirror.master = frodo +option mirror.copies = sam +option mirror.redirectOK = all +" + +echo "$lines" | sudo -u sam -i sh -c "cat >> .gitolite/conf/sam.conf" + +for h in $hosts +do + sudo -u $h -i gitolite setup +done + +# that ends the setup phase +echo ====================================================================== diff --git a/t/mirror-test-ssh-config b/t/mirror-test-ssh-config new file mode 100644 index 0000000..40de6d7 --- /dev/null +++ b/t/mirror-test-ssh-config @@ -0,0 +1,11 @@ +host frodo + user frodo + hostname localhost + +host sam + user sam + hostname localhost + +host gollum + user gollum + hostname localhost |