summaryrefslogtreecommitdiff
path: root/yarns
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2017-12-03 18:51:13 +0200
committerLars Wirzenius <liw@liw.fi>2017-12-03 20:11:03 +0200
commit107ffc0a60de703d84957cf6d8948ed7d61d7362 (patch)
tree624cddece68a78d3f66c3ec02c002e34e7057e3a /yarns
parentdd250d5a64d81ed247ce8e19fc300feaaa1e44c9 (diff)
downloadick2-107ffc0a60de703d84957cf6d8948ed7d61d7362.tar.gz
Add: scenario for testing blob service
Diffstat (limited to 'yarns')
-rw-r--r--yarns/700-blob-service.yarn52
-rw-r--r--yarns/900-implements.yarn35
-rw-r--r--yarns/900-local.yarn42
-rw-r--r--yarns/lib.py9
4 files changed, 138 insertions, 0 deletions
diff --git a/yarns/700-blob-service.yarn b/yarns/700-blob-service.yarn
new file mode 100644
index 0000000..1fd0c06
--- /dev/null
+++ b/yarns/700-blob-service.yarn
@@ -0,0 +1,52 @@
+<!--
+
+Copyright 2017 Lars Wirzenius
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+-->
+
+# Blob service
+
+This scenario tests the blob service API to store and retrieve blobs.
+At this stage the blob service is the simplest possible; so simple, in
+fact, it will certainly change in the future.
+
+ SCENARIO blob service
+
+Set up the blob service.
+
+ GIVEN an RSA key pair for token signing
+ AND blob service config uses blobs at the blob directory
+ AND an access token for user with scopes
+ ... uapi_blobs_id_put
+ ... uapi_blobs_id_get
+ AND a running blob service
+
+Try to get a non-existent blob. It should result in an error.
+
+ WHEN user retrieves /blobs/cake from blob service
+ THEN result has status code 404
+
+Create and store a blob, retrieve it and verify we get it back intack.
+
+ WHEN user creates a blob named cake with random data
+ AND user sends blob cake to blob service as /blobs/cake
+ THEN result has status code 200
+
+ WHEN user retrieves /blobs/cake from blob service
+ THEN result has status code 200
+ AND body is the same as the blob cake
+
+ FINALLY stop blob service
diff --git a/yarns/900-implements.yarn b/yarns/900-implements.yarn
index d08cbc9..6f9d423 100644
--- a/yarns/900-implements.yarn
+++ b/yarns/900-implements.yarn
@@ -19,6 +19,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
# Scenario step implementations (local and remote instances)
+## Data file creation
+
+ IMPLEMENTS WHEN user creates a blob named (\S+) with random data
+ filename = get_next_match()
+ n = 16
+ blob = os.urandom(n)
+ write(filename, blob)
+
## HTTP requests of various kinds
IMPLEMENTS WHEN (\S+) makes request GET (\S+)
@@ -32,6 +40,17 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
vars['headers'] = headers
vars['body'] = body
+ IMPLEMENTS WHEN (\S+) retrieves (\S+) from blob service
+ user = get_next_match()
+ path = get_next_match()
+ token = get_token(user)
+ url = vars['bsurl']
+ status, content_type, headers, body = get(url + path, token)
+ vars['status_code'] = status
+ vars['content_type'] = content_type
+ vars['headers'] = headers
+ vars['body'] = body
+
IMPLEMENTS WHEN (\S+) makes request GET (\S+) with an invalid token
user = get_next_match()
path = get_next_match()
@@ -86,6 +105,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
vars['headers'] = headers
vars['body'] = body
+ IMPLEMENTS WHEN (\S+) sends blob (\S+) to blob service as (\S+)
+ user = get_next_match()
+ filename = get_next_match()
+ path = get_next_match()
+ body = cat(filename)
+ token = get_token(user)
+ url = vars['bsurl']
+ status, content_type, headers, body = put_blob(url + path, body, token)
+ vars['status_code'] = status
+
IMPLEMENTS WHEN (\S+) makes request PUT (\S+) with an invalid token
user = get_next_match()
path = get_next_match()
@@ -130,6 +159,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
actual = vars['body']
assertEqual(expected, actual)
+ IMPLEMENTS THEN body is the same as the blob (\S+)
+ filename = get_next_match()
+ blob = cat(filename)
+ body = vars['body']
+ assertEqual(body, blob)
+
IMPLEMENTS THEN version in body matches version from setup.py
body = vars['body']
obj = json.loads(body)
diff --git a/yarns/900-local.yarn b/yarns/900-local.yarn
index 409a8e6..89652de 100644
--- a/yarns/900-local.yarn
+++ b/yarns/900-local.yarn
@@ -100,3 +100,45 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
name = get_next_match()
filename = os.path.join(vars['statedir'], 'workers', name + '.yaml')
assertTrue(os.path.exists(filename))
+
+## Start and stop blob service
+
+ IMPLEMENTS GIVEN blob service config uses (\S+) at the blob directory
+ vars['blobdir'] = get_next_match()
+
+ IMPLEMENTS GIVEN a running blob service
+ import os, time, cliapp, yaml
+ vars['blob_service.log'] = 'blob_service.log'
+ vars['gunicorn3_bs.log'] = 'gunicorn3_bs.log'
+ vars['bsport'] = random_free_port()
+ vars['bsurl'] = 'http://127.0.0.1:{}'.format(vars['bsport'])
+ config = {
+ 'token-issuer': vars['issuer'],
+ 'token-audience': vars['audience'],
+ 'token-public-key': cat('token.key.pub'),
+ 'log': [
+ {
+ 'filename': vars['blob_service.log'],
+ },
+ ],
+ 'blobdir': vars['blobdir'],
+ }
+ env = dict(os.environ)
+ env['BLOB_SERVICE_CONFIG'] = 'blob_service.yaml'
+ yaml.safe_dump(config, open('blob_service.yaml', 'w'))
+ argv = [
+ 'gunicorn3',
+ '--daemon',
+ '--bind', '127.0.0.1:{}'.format(vars['bsport']),
+ '--log-file', vars['gunicorn3_bs.log'],
+ '--log-level', 'debug',
+ '-p', 'bspid',
+ 'blob_service:app',
+ ]
+ cliapp.runcmd(argv, env=env)
+ vars['bspid'] = int(cat('bspid'))
+ wait_for_port(vars['bsport'])
+
+ IMPLEMENTS FINALLY stop blob service
+ import os, signal
+ os.kill(vars['bspid'], signal.SIGTERM)
diff --git a/yarns/lib.py b/yarns/lib.py
index 486757c..00db015 100644
--- a/yarns/lib.py
+++ b/yarns/lib.py
@@ -122,6 +122,15 @@ def put(url, body_text, token):
return r.status_code, r.headers['Content-Type'], dict(r.headers), r.text
+def put_blob(url, body, token):
+ headers = {
+ 'Authorization': 'Bearer {}'.format(token),
+ 'Content-Type': 'application/octet-stream',
+ }
+ r = requests.put(url, headers=headers, data=body, verify=False)
+ return r.status_code, r.headers['Content-Type'], dict(r.headers), r.text
+
+
def delete(url, token):
headers = {
'Authorization': 'Bearer {}'.format(token),