summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2017-03-04 20:14:33 +0200
committerLars Wirzenius <liw@liw.fi>2017-03-04 20:14:33 +0200
commit3b651fb14c1018d017b7fecd0be9a853094726d2 (patch)
tree6018b109bcf4f7662bf4061faaeae49e3c5339ee
parentf22175e01ed092acf408aff01af54005ea426268 (diff)
downloadgit.liw.fi-ruleset-tests-3b651fb14c1018d017b7fecd0be9a853094726d2.tar.gz
Make basic ian can clone scenario work
-rw-r--r--000.yarn214
-rwxr-xr-xcheck2
-rw-r--r--yarnhelper.py71
-rw-r--r--yarnhelper_tests.py11
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 create users, groups, repositories
- ASSUMING only the gitano-admin repository exists
- WHEN we run gitano whoami
- THEN we are in group gitano-admin
-
- WHEN we create user ian
- AND we create user olive
- AND we create user steven
- AND we create user gabriella
- AND we create user tina
- AND we create user ci
-
- WHEN we create group qvarndevs
- AND we create group qvarnguests
- AND we create group ops
- AND we create group otherdevs
- AND we create group staff
-
- WHEN we add ian to qvarndevs
- AND we add tina to qvarndevs
- AND we add gabriella to qvarnguests
- AND we add olive to ops
- AND we add tina to otherdevs
- AND we add steven to staff
-
- WHEN we create repository qvarn
- AND we create repository ops/secrets
- AND we create repository ops/ansible
- AND we create repository intrawiki
- AND we create repository otherproject
-
- WHEN we set qvarn config writers to qvarndevs
- AND we set qvarn config guests to qvarnguests
- AND we set qvarn config public to yes
- AND we set ops/secrets config writers to ops
- AND we set ops/ansible config writers to ops
- AND we set intrawiki config writers to staff
-
--->
-
-<!--
-
-Now we can start defining use cases.
-
-Use case: Ian makes a bugfix to Qvarn.
-
- WHEN ci clonse qvarn
- AND ian clones qvarn
- AND ian creates local qvarn branch ian/bugfix
- AND ian pushes qvarn
- AND ian merges ian/bugfix into master
- AND ian pushes qvarn
- THEN ci sees new commit in qvarn
-
-Use case: Ian makes a release.
-
- WHEN ian creates tag qvarn-1.0 in qvarn master
- AND ian pushes qvarn
- THEN ci sees tag qvarn-1.0 in qvarn
-
-Use case: Olive provisions a new Qvarn instance.
-
- WHEN olive clones ops/ansible
- AND olive clones ops/secrets
- AND olive creates local ops/ansible branch newthing
- AND olive pushes ops/ansible
- AND merges ops/ansible branch newthing to master
- AND olive pushes ops/ansible
-
-Use case: Steven updates internal wiki.
-
- WHEN ci clones intrawiki
- AND steven clones intrawiki
- AND steven makes a change in intrawiki master
- AND steven pushes intrawiki
- THEN ci sees a new commit in intrawiki
-
--->
-
-<!--
-
- FINALLY remove user ian
- AND remove user olive
- AND remove user steven
- AND remove user gabriella
- AND remove user tina
- AND remove user ci
-
- AND remove group qvarndevs
- AND remove group qvarnguests
- AND remove group ops
- AND remove group otherdevs
- AND remove group staff
-
- AND remove repository qvarn
- AND remove repository ops/secrets
- AND remove repository ops/ansible
- AND remove repository intrawiki
- AND remove repository otherproject
-
--->
+ 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)