From 107ffc0a60de703d84957cf6d8948ed7d61d7362 Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Sun, 3 Dec 2017 18:51:13 +0200 Subject: Add: scenario for testing blob service --- yarns/700-blob-service.yarn | 52 +++++++++++++++++++++++++++++++++++++++++++++ yarns/900-implements.yarn | 35 ++++++++++++++++++++++++++++++ yarns/900-local.yarn | 42 ++++++++++++++++++++++++++++++++++++ yarns/lib.py | 9 ++++++++ 4 files changed, 138 insertions(+) create mode 100644 yarns/700-blob-service.yarn (limited to 'yarns') 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 @@ + + +# 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 . # 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 . 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 . 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 . 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 . 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), -- cgit v1.2.1