From 3b651fb14c1018d017b7fecd0be9a853094726d2 Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Sat, 4 Mar 2017 20:14:33 +0200 Subject: Make basic ian can clone scenario work --- 000.yarn | 214 +++++++++++++--------------------------------------- check | 2 + yarnhelper.py | 71 +++++++++++++++-- yarnhelper_tests.py | 11 +-- 4 files changed, 121 insertions(+), 177 deletions(-) diff --git a/000.yarn b/000.yarn index a726711..f78a27a 100644 --- a/000.yarn +++ b/000.yarn @@ -197,180 +197,70 @@ This is going to be a long scenario, but that's just so that we don't need to re-do the setup. The setup consists of creating test users, groups, and respositories. - - - - - + SCENARIO ian can clone qvarn.git + WHEN admin creates user ian + AND admin creates group qvarndevs + AND admin adds ian to qvarndevs + AND admin creates repository qvarn + AND admin sets qvarn config writers to qvarndevs + THEN ian can clone qvarn -# Scenario step implementations - - IMPLEMENTS ASSUMING only the gitano-admin repository exists - output = helper.gitano('ls') - print 'ls output:' - print output - lines = [x for x in output.splitlines() if 'gitano-admin' not in x] - helper.assertEqual(lines, []) - - IMPLEMENTS WHEN we run gitano (.+) - args = helper.get_next_match() - whoami_output = helper.gitano(args) - helper.set_variable('admin_whoami', whoami_output) + FINALLY admin removes things that were created - IMPLEMENTS THEN we are in group gitano-admin - whoami = helper.get_variable('admin_whoami') - helper.assertIn('gitano-admin', whoami) +# Scenario step implementations - IMPLEMENTS WHEN we create user (\S+) + IMPLEMENTS WHEN admin creates user (\S+) username = helper.get_next_match() - helper.gitano('user add {} user@example.com Test User'.format(username)) - - IMPLEMENTS WHEN we create group (\S+) + # FIXME: Create first, this is temporary + helper.append_to_list('users', username) + helper.gitano(None, 'user add {} {}@example.com Test {}'.format(username, username, username)) + pubkey = helper.ssh_keygen(username) + helper.gitano(None, 'as {} sshkey add default'.format(username), stdin=pubkey) + print helper.gitano(username, 'whoami') + + IMPLEMENTS WHEN admin creates group (\S+) group = helper.get_next_match() - helper.gitano('group add {} Test group'.format(group)) + # FIXME: Create first, this is temporary + helper.append_to_list('groups', group) + helper.gitano(None, 'group add {} Test group'.format(group)) - IMPLEMENTS FINALLY remove user (\S+) - username = helper.get_next_match() - try: - output = helper.gitano('user del {}'.format(username)) - except cliapp.AppException: - pass - else: - last_line = output.splitlines()[-1] - token = last_line.split()[-1] - helper.gitano('user del {} {}'.format(username, token)) - - IMPLEMENTS FINALLY remove group (\S+) - group = helper.get_next_match() - try: - output = helper.gitano('group del {}'.format(group)) - except cliapp.AppException: - pass - else: - last_line = output.splitlines()[-1] - token = last_line.split()[-1] - helper.gitano('group del {} {}'.format(group, token)) - - IMPLEMENTS WHEN we add (\S+) to (\S+) + IMPLEMENTS WHEN admin adds (\S+) to (\S+) user = helper.get_next_match() group = helper.get_next_match() - output = helper.gitano('group adduser {} {}'.format(group, user)) + output = helper.gitano(None, 'group adduser {} {}'.format(group, user)) - IMPLEMENTS WHEN we create repository (\S+) + IMPLEMENTS WHEN admin creates repository (\S+) repo = helper.get_next_match() - output = helper.gitano('create {}'.format(repo)) + # FIXME: Create first, this is temporary + helper.append_to_list('repositories', repo) + output = helper.gitano(None, 'create {}'.format(repo)) - IMPLEMENTS FINALLY remove repository (\S+) + IMPLEMENTS THEN (\S+) can clone (\S+) + user = helper.get_next_match() repo = helper.get_next_match() - try: - output = helper.gitano('destroy {}'.format(repo)) - except cliapp.AppException: - pass - else: - last_line = output.splitlines()[-1] - token = last_line.split()[-1] - helper.gitano('destroy {} {}'.format(repo, token)) - - IMPLEMENTS WHEN we set (\S+) config (\S+) to (\S+) + url = helper.repo_ssh_url(repo) + dirname = '{}_{}'.format(user, repo) + + print 'user:', user + print 'repo:', repo + print 'url:', url + print helper.gitano(user, 'whoami') + + print helper.git_as(user, ['clone', url, dirname]) + + IMPLEMENTS WHEN admin sets (\S+) config (\S+) to (\S+) repo = helper.get_next_match() key = helper.get_next_match() value = helper.get_next_match() - helper.gitano('config {} set {} {}'.format(repo, key, value)) + helper.gitano(None, 'config {} set {} {}'.format(repo, key, value)) + + IMPLEMENTS FINALLY admin removes things that were created + def iter(var, prefix): + items = helper.get_variable(var, []) + with open('/tmp/yarn.out', 'a') as f: + f.write('%s: %r\n' % (var, items)) + for item in items: + helper.gitano_confirm_with_token(prefix, item) + iter('users', 'user del') + iter('groups', 'group del') + iter('repositories', 'destroy') diff --git a/check b/check index ae85315..cd7eed7 100755 --- a/check +++ b/check @@ -3,11 +3,13 @@ set -eu server="$1" +sshkey="$2" shift 1 python -m CoverageTestRunner --ignore-missing-from=without-tests . yarn \ --env "GITANO_SERVER=$server" \ + --env "ADMIN_SSH_KEY=$sshkey" \ --shell=python2 \ --shell-arg '' \ --shell-library lib.py \ diff --git a/yarnhelper.py b/yarnhelper.py index 67b0a88..a3c2ddd 100644 --- a/yarnhelper.py +++ b/yarnhelper.py @@ -47,12 +47,10 @@ class YarnHelper(object): self._next_match += 1 return self._env[name] - def get_variable(self, name): + def get_variable(self, name, default=None): if self._variables is None: self._variables = self._load_variables() - if name not in self._variables: - raise Error('no variable {}'.format(name)) - return self._variables[name] + return self._variables.get(name, default) def _load_variables(self): if os.path.exists(variables_filename): @@ -137,22 +135,79 @@ class YarnHelper(object): m.close() m.logout() - def gitano(self, args): # pragma: no cover + def ssh_keygen(self, user): # pragma: no cover + filename = self.ssh_key_file_for_user(user) + cliapp.runcmd(['ssh-keygen', '-f', filename, '-N', '', '-C', user]) + with open(filename + '.pub') as f: + return f.read() + + def ssh_key_file_for_user(self, user): # pragma: no cover + return '{}.key'.format(user) + + def repo_ssh_url(self, repo): # pragma: no cover + return 'ssh://git@{}/{}'.format(os.environ['GITANO_SERVER'], repo) + + def git_as(self, user, args): # pragma: no cover + server = os.environ['GITANO_SERVER'] + env = dict(os.environ) + env['GIT_SSH_COMMAND'] = self.env_ssh_command(user) + print 'g_s_c:', env['GIT_SSH_COMMAND'] + return cliapp.runcmd( + ['git'] + args, + stderr=subprocess.STDOUT, + env=env) + + def env_ssh_command(self, user): # pragma: no cover + argv = [ + 'ssh', + '-o', 'PasswordAuthentication=no', + '-o', 'IdentitiesOnly=yes', + ] + if user is not None: + key = self.ssh_key_file_for_user(user) + argv.extend(['-i', key]) + return ' '.join(argv) + + def get_admin_ssh_key(self): # pragma: no cover + return os.environ['ADMIN_SSH_KEY'] + + def get_user_ssh_key(self, user): # pragma: no cover + if user is None: + return self.get_admin_ssh_key() + else: + return self.ssh_key_file_for_user(user) + + def gitano(self, user, args, stdin=None): # pragma: no cover server = os.environ['GITANO_SERVER'] + print '=' * 77 + print 'tgt:', 'git@{}'.format(server) + print 'args:', repr(args.split()) + print 'listdir:', repr(os.listdir('.')) + kwargs = { + 'stderr': subprocess.STDOUT, + 'ssh_options': [ + '-oPasswordAuthentication=no', + '-oIdentitiesOnly=yes', + '-i', self.get_user_ssh_key(user), + ], + } + if stdin is not None: + kwargs['feed_stdin'] = stdin + print 'kwargs:', repr(kwargs) return cliapp.ssh_runcmd( 'git@{}'.format(server), args.split(), - stderr=subprocess.STDOUT) + **kwargs) def gitano_confirm_with_token(self, prefix, which): # pragma: no cover try: - output = self.gitano('{} {}'.format(prefix, which)) + output = self.gitano(None, '{} {}'.format(prefix, which)) except cliapp.AppException: pass else: last_line = output.splitlines()[-1] token = last_line.split()[-1] - self.gitano('{} {}'.format(prefix, token)) + self.gitano(None, '{} {} {}'.format(prefix, which, token)) class Error(Exception): diff --git a/yarnhelper_tests.py b/yarnhelper_tests.py index 46a0604..cd1c9a3 100644 --- a/yarnhelper_tests.py +++ b/yarnhelper_tests.py @@ -66,13 +66,6 @@ class PersistentVariableTests(unittest.TestCase): if os.path.exists(yarnhelper.variables_filename): os.remove(yarnhelper.variables_filename) - def test_raises_error_if_no_such_variable(self): - h = yarnhelper.YarnHelper() - with self.assertRaises(yarnhelper.Error): - h.get_variable('FOO') - print - print 'variables:', h._variables - def test_sets_variable_persistently(self): h = yarnhelper.YarnHelper() h.set_variable('FOO', 'bar') @@ -80,6 +73,10 @@ class PersistentVariableTests(unittest.TestCase): h2 = yarnhelper.YarnHelper() self.assertEqual(h2.get_variable('FOO'), 'bar') + def test_get_returns_default_if_variable_not_set(self): + h = yarnhelper.YarnHelper() + self.assertEqual(h.get_variable('FOO', 'bar'), 'bar') + def test_appends_to_empty_list(self): h = yarnhelper.YarnHelper() h.append_to_list('foo', 1) -- cgit v1.2.1