aboutsummaryrefslogtreecommitdiff
path: root/gitosis/test
diff options
context:
space:
mode:
Diffstat (limited to 'gitosis/test')
-rw-r--r--gitosis/test/__init__.py0
-rw-r--r--gitosis/test/test_access.py79
-rw-r--r--gitosis/test/test_group.py125
-rw-r--r--gitosis/test/test_ssh.py202
4 files changed, 406 insertions, 0 deletions
diff --git a/gitosis/test/__init__.py b/gitosis/test/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/gitosis/test/__init__.py
diff --git a/gitosis/test/test_access.py b/gitosis/test/test_access.py
new file mode 100644
index 0000000..00b1fe8
--- /dev/null
+++ b/gitosis/test/test_access.py
@@ -0,0 +1,79 @@
+from nose.tools import eq_ as eq
+
+from ConfigParser import RawConfigParser
+
+from gitosis import access
+
+def test_write_no_simple():
+ cfg = RawConfigParser()
+ eq(access.haveAccess(config=cfg, user='jdoe', mode='writable', path='foo/bar'),
+ None)
+
+def test_write_yes_simple():
+ cfg = RawConfigParser()
+ cfg.add_section('group fooers')
+ cfg.set('group fooers', 'members', 'jdoe')
+ cfg.set('group fooers', 'writable', 'foo/bar')
+ eq(access.haveAccess(config=cfg, user='jdoe', mode='writable', path='foo/bar'),
+ 'foo/bar')
+
+def test_write_no_simple_wouldHaveReadonly():
+ cfg = RawConfigParser()
+ cfg.add_section('group fooers')
+ cfg.set('group fooers', 'members', 'jdoe')
+ cfg.set('group fooers', 'readonly', 'foo/bar')
+ eq(access.haveAccess(config=cfg, user='jdoe', mode='writable', path='foo/bar'),
+ None)
+
+def test_write_yes_map():
+ cfg = RawConfigParser()
+ cfg.add_section('group fooers')
+ cfg.set('group fooers', 'members', 'jdoe')
+ cfg.set('group fooers', 'map writable foo/bar', 'quux/thud')
+ eq(access.haveAccess(config=cfg, user='jdoe', mode='writable', path='foo/bar'),
+ 'quux/thud')
+
+def test_write_no_map_wouldHaveReadonly():
+ cfg = RawConfigParser()
+ cfg.add_section('group fooers')
+ cfg.set('group fooers', 'members', 'jdoe')
+ cfg.set('group fooers', 'map readonly foo/bar', 'quux/thud')
+ eq(access.haveAccess(config=cfg, user='jdoe', mode='writable', path='foo/bar'),
+ None)
+
+def test_read_no_simple():
+ cfg = RawConfigParser()
+ eq(access.haveAccess(config=cfg, user='jdoe', mode='readonly', path='foo/bar'),
+ None)
+
+def test_read_yes_simple():
+ cfg = RawConfigParser()
+ cfg.add_section('group fooers')
+ cfg.set('group fooers', 'members', 'jdoe')
+ cfg.set('group fooers', 'readonly', 'foo/bar')
+ eq(access.haveAccess(config=cfg, user='jdoe', mode='readonly', path='foo/bar'),
+ 'foo/bar')
+
+def test_read_yes_simple_wouldHaveWritable():
+ cfg = RawConfigParser()
+ cfg.add_section('group fooers')
+ cfg.set('group fooers', 'members', 'jdoe')
+ cfg.set('group fooers', 'writable', 'foo/bar')
+ eq(access.haveAccess(config=cfg, user='jdoe', mode='readonly', path='foo/bar'),
+ None)
+
+def test_read_yes_map():
+ cfg = RawConfigParser()
+ cfg.add_section('group fooers')
+ cfg.set('group fooers', 'members', 'jdoe')
+ cfg.set('group fooers', 'map readonly foo/bar', 'quux/thud')
+ eq(access.haveAccess(config=cfg, user='jdoe', mode='readonly', path='foo/bar'),
+ 'quux/thud')
+
+def test_read_yes_map_wouldHaveWritable():
+ cfg = RawConfigParser()
+ cfg.add_section('group fooers')
+ cfg.set('group fooers', 'members', 'jdoe')
+ cfg.set('group fooers', 'map writable foo/bar', 'quux/thud')
+ eq(access.haveAccess(config=cfg, user='jdoe', mode='readonly', path='foo/bar'),
+ None)
diff --git a/gitosis/test/test_group.py b/gitosis/test/test_group.py
new file mode 100644
index 0000000..c282661
--- /dev/null
+++ b/gitosis/test/test_group.py
@@ -0,0 +1,125 @@
+from nose.tools import eq_ as eq, assert_raises
+
+from ConfigParser import RawConfigParser
+
+from gitosis import group
+
+def test_no_emptyConfig():
+ cfg = RawConfigParser()
+ gen = group.getMembership(config=cfg, user='jdoe')
+ assert_raises(StopIteration, gen.next)
+
+def test_no_emptyGroup():
+ cfg = RawConfigParser()
+ cfg.add_section('group hackers')
+ gen = group.getMembership(config=cfg, user='jdoe')
+ assert_raises(StopIteration, gen.next)
+
+def test_no_notListed():
+ cfg = RawConfigParser()
+ cfg.add_section('group hackers')
+ cfg.set('group hackers', 'members', 'wsmith')
+ gen = group.getMembership(config=cfg, user='jdoe')
+ assert_raises(StopIteration, gen.next)
+
+def test_yes_simple():
+ cfg = RawConfigParser()
+ cfg.add_section('group hackers')
+ cfg.set('group hackers', 'members', 'jdoe')
+ gen = group.getMembership(config=cfg, user='jdoe')
+ eq(gen.next(), 'hackers')
+ assert_raises(StopIteration, gen.next)
+
+def test_yes_leading():
+ cfg = RawConfigParser()
+ cfg.add_section('group hackers')
+ cfg.set('group hackers', 'members', 'jdoe wsmith')
+ gen = group.getMembership(config=cfg, user='jdoe')
+ eq(gen.next(), 'hackers')
+ assert_raises(StopIteration, gen.next)
+
+def test_yes_trailing():
+ cfg = RawConfigParser()
+ cfg.add_section('group hackers')
+ cfg.set('group hackers', 'members', 'wsmith jdoe')
+ gen = group.getMembership(config=cfg, user='jdoe')
+ eq(gen.next(), 'hackers')
+ assert_raises(StopIteration, gen.next)
+
+def test_yes_middle():
+ cfg = RawConfigParser()
+ cfg.add_section('group hackers')
+ cfg.set('group hackers', 'members', 'wsmith jdoe danny')
+ gen = group.getMembership(config=cfg, user='jdoe')
+ eq(gen.next(), 'hackers')
+ assert_raises(StopIteration, gen.next)
+
+def test_yes_recurse_one():
+ cfg = RawConfigParser()
+ cfg.add_section('group hackers')
+ cfg.set('group hackers', 'members', 'wsmith @smackers')
+ cfg.add_section('group smackers')
+ cfg.set('group smackers', 'members', 'danny jdoe')
+ gen = group.getMembership(config=cfg, user='jdoe')
+ eq(gen.next(), 'smackers')
+ eq(gen.next(), 'hackers')
+ assert_raises(StopIteration, gen.next)
+
+def test_yes_recurse_one_ordering():
+ cfg = RawConfigParser()
+ cfg.add_section('group smackers')
+ cfg.set('group smackers', 'members', 'danny jdoe')
+ cfg.add_section('group hackers')
+ cfg.set('group hackers', 'members', 'wsmith @smackers')
+ gen = group.getMembership(config=cfg, user='jdoe')
+ eq(gen.next(), 'smackers')
+ eq(gen.next(), 'hackers')
+ assert_raises(StopIteration, gen.next)
+
+def test_yes_recurse_three():
+ cfg = RawConfigParser()
+ cfg.add_section('group hackers')
+ cfg.set('group hackers', 'members', 'wsmith @smackers')
+ cfg.add_section('group smackers')
+ cfg.set('group smackers', 'members', 'danny @snackers')
+ cfg.add_section('group snackers')
+ cfg.set('group snackers', 'members', '@whackers foo')
+ cfg.add_section('group whackers')
+ cfg.set('group whackers', 'members', 'jdoe')
+ gen = group.getMembership(config=cfg, user='jdoe')
+ eq(gen.next(), 'whackers')
+ eq(gen.next(), 'snackers')
+ eq(gen.next(), 'smackers')
+ eq(gen.next(), 'hackers')
+ assert_raises(StopIteration, gen.next)
+
+def test_yes_recurse_junk():
+ cfg = RawConfigParser()
+ cfg.add_section('group hackers')
+ cfg.set('group hackers', 'members', '@notexist @smackers')
+ cfg.add_section('group smackers')
+ cfg.set('group smackers', 'members', 'jdoe')
+ gen = group.getMembership(config=cfg, user='jdoe')
+ eq(gen.next(), 'smackers')
+ eq(gen.next(), 'hackers')
+ assert_raises(StopIteration, gen.next)
+
+def test_yes_recurse_loop():
+ cfg = RawConfigParser()
+ cfg.add_section('group hackers')
+ cfg.set('group hackers', 'members', '@smackers')
+ cfg.add_section('group smackers')
+ cfg.set('group smackers', 'members', '@hackers jdoe')
+ gen = group.getMembership(config=cfg, user='jdoe')
+ eq(gen.next(), 'smackers')
+ eq(gen.next(), 'hackers')
+ assert_raises(StopIteration, gen.next)
+
+def test_no_recurse_loop():
+ cfg = RawConfigParser()
+ cfg.add_section('group hackers')
+ cfg.set('group hackers', 'members', '@smackers')
+ cfg.add_section('group smackers')
+ cfg.set('group smackers', 'members', '@hackers')
+ gen = group.getMembership(config=cfg, user='jdoe')
+ assert_raises(StopIteration, gen.next)
diff --git a/gitosis/test/test_ssh.py b/gitosis/test/test_ssh.py
new file mode 100644
index 0000000..e699506
--- /dev/null
+++ b/gitosis/test/test_ssh.py
@@ -0,0 +1,202 @@
+from nose.tools import eq_ as eq, assert_raises
+
+import os, errno
+from cStringIO import StringIO
+
+from gitosis import ssh
+
+def mkdir(path):
+ try:
+ os.mkdir(path)
+ except OSError, e:
+ if e.errno == errno.EEXIST:
+ pass
+ else:
+ raise
+
+def maketemp():
+ tmp = os.path.join(os.path.dirname(__file__), 'tmp')
+ mkdir(tmp)
+ me = os.path.splitext(os.path.basename(__file__))[0]
+ tmp = os.path.join(tmp, me)
+ mkdir(tmp)
+ return tmp
+
+def writeFile(path, content):
+ tmp = '%s.tmp' % path
+ f = file(tmp, 'w')
+ try:
+ f.write(content)
+ finally:
+ f.close()
+ os.rename(tmp, path)
+
+def _key(s):
+ return ''.join(s.split('\n')).strip()
+
+KEY_1 = _key("""
+ssh-rsa +v5XLsUrLsHOKy7Stob1lHZM17YCCNXplcKfbpIztS2PujyixOaBev1ku6H6ny
+gUXfuYVzY+PmfTLviSwD3UETxEkR/jlBURACDQARJdUxpgt9XG2Lbs8bhOjonAPapxrH0o
+9O8R0Y6Pm1Vh+H2U0B4UBhPgEframpeJYedijBxBV5aq3yUvHkXpcjM/P0gsKqr036k= j
+unk@gunk
+""")
+
+KEY_2 = _key("""
+ssh-rsa 4BX2TxZoD3Og2zNjHwaMhVEa5/NLnPcw+Z02TDR0IGJrrqXk7YlfR3oz+Wb/Eb
+Ctli20SoWY0Ur8kBEF/xR4hRslZ2U8t0PAJhr8cq5mifhok/gAdckmSzjD67QJ68uZbga8
+ZwIAo7y/BU7cD3Y9UdVZykG34NiijHZLlCBo/TnobXjFIPXvFbfgQ3y8g+akwocFVcQ= f
+roop@snoop
+""")
+
+class ReadKeys_Test(object):
+ def test_empty(self):
+ tmp = maketemp()
+ empty = os.path.join(tmp, 'empty')
+ mkdir(empty)
+ gen = ssh.readKeys(keydir=empty)
+ assert_raises(StopIteration, gen.next)
+
+ def test_ignore_dot(self):
+ tmp = maketemp()
+ keydir = os.path.join(tmp, 'ignore_dot')
+ mkdir(keydir)
+ writeFile(os.path.join(keydir, '.jdoe.pub'), KEY_1+'\n')
+ gen = ssh.readKeys(keydir=keydir)
+ assert_raises(StopIteration, gen.next)
+
+ def test_ignore_nonpub(self):
+ tmp = maketemp()
+ keydir = os.path.join(tmp, 'ignore_dot')
+ mkdir(keydir)
+ writeFile(os.path.join(keydir, 'jdoe.xub'), KEY_1+'\n')
+ gen = ssh.readKeys(keydir=keydir)
+ assert_raises(StopIteration, gen.next)
+
+ def test_one(self):
+ tmp = maketemp()
+ keydir = os.path.join(tmp, 'one')
+ mkdir(keydir)
+ writeFile(os.path.join(keydir, 'jdoe.pub'), KEY_1+'\n')
+
+ gen = ssh.readKeys(keydir=keydir)
+ eq(gen.next(), ('jdoe', KEY_1))
+ assert_raises(StopIteration, gen.next)
+
+ def test_two(self):
+ tmp = maketemp()
+ keydir = os.path.join(tmp, 'two')
+ mkdir(keydir)
+ writeFile(os.path.join(keydir, 'jdoe.pub'), KEY_1+'\n')
+ writeFile(os.path.join(keydir, 'wsmith.pub'), KEY_2+'\n')
+
+ gen = ssh.readKeys(keydir=keydir)
+ got = frozenset(gen)
+
+ eq(got,
+ frozenset([
+ ('jdoe', KEY_1),
+ ('wsmith', KEY_2),
+ ]))
+
+class GenerateAuthorizedKeys_Test(object):
+ def test_simple(self):
+ def k():
+ yield ('jdoe', KEY_1)
+ yield ('wsmith', KEY_2)
+ gen = ssh.generateAuthorizedKeys(k())
+ eq(gen.next(), ssh.COMMENT)
+ eq(gen.next(), (
+ 'command="gitosis-serve jdoe",no-port-forwarding,no-X11-f'
+ +'orwarding,no-agent-forwarding,no-pty %s' % KEY_1))
+ eq(gen.next(), (
+ 'command="gitosis-serve wsmith",no-port-forwarding,no-X11'
+ +'-forwarding,no-agent-forwarding,no-pty %s' % KEY_2))
+ assert_raises(StopIteration, gen.next)
+
+
+class FilterAuthorizedKeys_Test(object):
+ def run(self, s):
+ f = StringIO(s)
+ lines = ssh.filterAuthorizedKeys(f)
+ got = ''.join(['%s\n' % line for line in lines])
+ return got
+
+ def check_no_change(self, s):
+ got = self.run(s)
+ eq(got, s)
+
+ def test_notFiltered_comment(self):
+ self.check_no_change('#comment\n')
+
+ def test_notFiltered_junk(self):
+ self.check_no_change('junk\n')
+
+ def test_notFiltered_key(self):
+ self.check_no_change('%s\n' % KEY_1)
+
+ def test_notFiltered_keyWithCommand(self):
+ s = '''\
+command="faketosis-serve wsmith",no-port-forwarding,no-X11-forwardin\
+g,no-agent-forwarding,no-pty %(key_1)s
+''' % dict(key_1=KEY_1)
+ self.check_no_change(s)
+
+
+ def test_filter_autogeneratedComment_backwardsCompat(self):
+ got = self.run('### autogenerated by gitosis, DO NOT EDIT\n')
+ eq(got, '')
+
+ def test_filter_autogeneratedComment_current(self):
+ got = self.run(ssh.COMMENT+'\n')
+ eq(got, '')
+
+ def test_filter_simple(self):
+ s = '''\
+command="gitosis-serve wsmith",no-port-forwarding,no-X11-forwardin\
+g,no-agent-forwarding,no-pty %(key_1)s
+''' % dict(key_1=KEY_1)
+ got = self.run(s)
+ eq(got, '')
+
+ def test_filter_withPath(self):
+ s = '''\
+command="/foo/bar/baz/gitosis-serve wsmith",no-port-forwarding,no-X11-forwardin\
+g,no-agent-forwarding,no-pty %(key_1)s
+''' % dict(key_1=KEY_1)
+ got = self.run(s)
+ eq(got, '')
+
+
+class WriteAuthorizedKeys_Test(object):
+ def test_simple(self):
+ tmp = maketemp()
+ path = os.path.join(tmp, 'authorized_keys')
+ oldfp = StringIO('''\
+# foo
+bar
+### autogenerated by gitosis, DO NOT EDIT
+command="/foo/bar/baz/gitosis-serve wsmith",no-port-forwarding,\
+no-X11-forwarding,no-agent-forwarding,no-pty %(key_2)s
+baz
+''' % dict(key_2=KEY_2))
+ keydir = os.path.join(tmp, 'one')
+ mkdir(keydir)
+ writeFile(os.path.join(keydir, 'jdoe.pub'), KEY_1+'\n')
+
+ ssh.writeAuthorizedKeys(
+ oldfp=oldfp, newpath=path, keydir=keydir)
+
+ f = file(path)
+ try:
+ got = f.read()
+ finally:
+ f.close()
+
+ eq(got, '''\
+# foo
+bar
+baz
+### autogenerated by gitosis, DO NOT EDIT
+command="gitosis-serve jdoe",no-port-forwarding,\
+no-X11-forwarding,no-agent-forwarding,no-pty %(key_1)s
+''' % dict(key_1=KEY_1))