Add tempest tests to run in devstack gate

Added tests for secret create (single and two-phase), order
create, and versioning to run in the devstack gate.
These should both provide a base for additional tempest-based
tests and also ensure that future CRs won't regress basic
Barbican functionality.

Added skip to version tests until blueprint fix-version-api
has been implemented.

Change-Id: Ib1d6bb3a2251c21b9d7d647687d0ac30ad52e4c9
This commit is contained in:
Steve Heyman 2014-07-21 14:36:49 -05:00
parent 9d70030e58
commit efa6a39f6e
7 changed files with 232 additions and 1 deletions

View File

@ -1,5 +1,5 @@
[DEFAULT]
test_command=${PYTHON:-python} -m subunit.run discover -t . $LISTOPT $IDOPTION
test_command=${PYTHON:-python} -m subunit.run discover -s ./barbican -t . $LISTOPT $IDOPTION
test_id_option=--load-list $IDFILE
test_list_option=--list

View File

View File

@ -0,0 +1,60 @@
"""
Copyright 2014 Rackspace
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from tempest import auth
from tempest import clients
from tempest.common import rest_client
from tempest import config
import testtools
CONF = config.CONF
class BarbicanClient(rest_client.RestClient):
def __init__(self, auth_provider):
super(BarbicanClient, self).__init__(auth_provider)
# get the project id (aka tenant id) which we need in the API tests
# to build the correct URI.
credentials = auth_provider.fill_credentials()
self.project_id = credentials.tenant_id
self.service = 'keystore'
self.endpoint_url = 'publicURL'
class TestCase(testtools.TestCase):
def setUp(self):
super(TestCase, self).setUp()
credentials = BarbicanCredentials()
mgr = clients.Manager(credentials=credentials)
auth_provider = mgr.get_auth_provider(credentials)
self.client = BarbicanClient(auth_provider)
class BarbicanCredentials(auth.KeystoneV2Credentials):
def __init__(self):
credentials = dict(
username=CONF.identity.admin_username,
password=CONF.identity.admin_password,
tenant_name=CONF.identity.admin_tenant_name
)
super(BarbicanCredentials, self).__init__(**credentials)

View File

@ -0,0 +1,32 @@
# Copyright (c) 2014 Rackspace, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import json
import testtools
from functionaltests.api import base
class VersionDiscoveryTestCase(base.TestCase):
@testtools.skipIf(True, 'Skip until blueprint fix-version-api is complete')
def test_get_root_discovers_v1(self):
"""Covers retrieving version data for Barbican.
"""
resp, body = self.client.get(' ')
body = json.loads(body)
self.assertEqual(resp.status, 200)
self.assertEqual(body.get('v1'), 'current')
self.assertGreater(len(body.get('build')), 1)

View File

View File

@ -0,0 +1,46 @@
# Copyright (c) 2014 Rackspace, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import json
from functionaltests.api import base
create_order_data = {
"secret": {
"name": "secretname",
"algorithm": "AES",
"bit_length": 256,
"mode": "cbc",
"payload_content_type": "application/octet-stream",
}
}
class OrdersTestCase(base.TestCase):
def test_create_order(self):
"""Covers order creation. All of the data needed to
create the order is provided in a single POST.
"""
json_data = json.dumps(create_order_data)
project_id = self.client.project_id
resp, body = self.client.post(
'{0}/orders'.format(project_id), json_data, headers={
'content-type': 'application/json'})
self.assertEqual(resp.status, 202)
returned_data = json.loads(body)
order_ref = returned_data['order_ref']
self.assertIsNotNone(order_ref)

View File

@ -0,0 +1,93 @@
# Copyright (c) 2014 Rackspace, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import json
import os
from functionaltests.api import base
one_phase_create_data = {
"name": "AES key",
"expiration": "2018-02-28T19:14:44.180394",
"algorithm": "aes",
"bit_length": 256,
"mode": "cbc",
"payload": "gF6+lLoF3ohA9aPRpt+6bQ==",
"payload_content_type": "application/octet-stream",
"payload_content_encoding": "base64",
}
two_phase_create_data = {
"name": "AES key",
"expiration": "2018-02-28T19:14:44.180394",
"algorithm": "aes",
"bit_length": 256,
"mode": "cbc",
}
two_phase_payload_data = {
"payload": "gF6+lLoF3ohA9aPRpt+6bQ==",
"payload_content_type": "application/octet-stream",
"payload_content_encoding": "base64",
}
class SecretsTestCase(base.TestCase):
def test_create_secret_single_phase(self):
"""Covers single phase secret creation. All of the data needed to
create the secret, including payload, is provided in a single POST.
"""
json_data = json.dumps(one_phase_create_data)
project_id = self.client.project_id
resp, body = self.client.post(
'{0}/secrets'.format(project_id), json_data, headers={
'content-type': 'application/json'})
self.assertEqual(resp.status, 201)
returned_data = json.loads(body)
secret_ref = returned_data['secret_ref']
self.assertIsNotNone(secret_ref)
def test_create_secret_two_phase(self):
"""Covers two phase secret creation. The first call, a POST, provides
the metadata about the secret - everything except the payload. A
subsequent call (PUT) provides the payload.
"""
# phase 1 - POST secret without payload
json_data = json.dumps(two_phase_create_data)
project_id = self.client.project_id
resp, body = self.client.post(
'{0}/secrets'.format(project_id), json_data, headers={
'content-type': 'application/json'})
self.assertEqual(resp.status, 201)
returned_data = json.loads(body)
secret_ref = returned_data['secret_ref']
self.assertIsNotNone(secret_ref)
secret_id = os.path.split(secret_ref)[1]
self.assertIsNotNone(secret_id)
# phase 2 - provide (PUT) the secret payload
json_data = json.dumps(two_phase_payload_data)
resp, body = self.client.post(
'{0}/secrets/{1}'.format(project_id, secret_id), json_data,
headers={'content-type': 'application/json'})
self.assertEqual(resp.status, 200)
returned_data = json.loads(body)
secret_ref = returned_data['secret_ref']
self.assertIsNotNone(secret_ref)