Merge "Add test cases for Capsule API"
This commit is contained in:
commit
01d9a045e1
@ -81,7 +81,8 @@ class Experimental(controllers_base.APIBase):
|
|||||||
'zun.experimental+json')]
|
'zun.experimental+json')]
|
||||||
experimental.capsules = [link.make_link('self',
|
experimental.capsules = [link.make_link('self',
|
||||||
pecan.request.host_url,
|
pecan.request.host_url,
|
||||||
'capsules', ''),
|
'experimental/capsules', '',
|
||||||
|
bookmark=True),
|
||||||
link.make_link('bookmark',
|
link.make_link('bookmark',
|
||||||
pecan.request.host_url,
|
pecan.request.host_url,
|
||||||
'capsules', '',
|
'capsules', '',
|
||||||
|
@ -86,9 +86,6 @@ class CapsuleController(base.Controller):
|
|||||||
compute_api = pecan.request.compute_api
|
compute_api = pecan.request.compute_api
|
||||||
policy.enforce(context, "capsule:create",
|
policy.enforce(context, "capsule:create",
|
||||||
action="capsule:create")
|
action="capsule:create")
|
||||||
capsule_dict['capsule_version'] = 'alpha'
|
|
||||||
capsule_dict['kind'] = 'capsule'
|
|
||||||
|
|
||||||
capsules_spec = capsule_dict['spec']
|
capsules_spec = capsule_dict['spec']
|
||||||
containers_spec = utils.check_capsule_template(capsules_spec)
|
containers_spec = utils.check_capsule_template(capsules_spec)
|
||||||
capsule_dict['uuid'] = uuidutils.generate_uuid()
|
capsule_dict['uuid'] = uuidutils.generate_uuid()
|
||||||
|
19
zun/tests/unit/api/controllers/auth-experimental-access.ini
Normal file
19
zun/tests/unit/api/controllers/auth-experimental-access.ini
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
[pipeline:main]
|
||||||
|
pipeline = cors request_id authtoken api_experimental
|
||||||
|
|
||||||
|
[app:api_experimental]
|
||||||
|
paste.app_factory = zun.api.app:app_factory
|
||||||
|
|
||||||
|
[filter:authtoken]
|
||||||
|
acl_public_routes = /experimental
|
||||||
|
paste.filter_factory = zun.api.middleware.auth_token:AuthTokenMiddleware.factory
|
||||||
|
|
||||||
|
[filter:request_id]
|
||||||
|
paste.filter_factory = oslo_middleware:RequestId.factory
|
||||||
|
|
||||||
|
[filter:cors]
|
||||||
|
paste.filter_factory = oslo_middleware.cors:filter_factory
|
||||||
|
oslo_config_project = zun
|
||||||
|
latent_allow_methods = GET, PUT, POST, DELETE
|
||||||
|
latent_allow_headers = X-Auth-Token, X-Identity-Status, X-Roles, X-Service-Catalog, X-User-Id, X-Tenant-Id, X-OpenStack-Request-ID
|
||||||
|
latent_expose_headers = X-Auth-Token, X-Subject-Token, X-Service-Token, X-OpenStack-Request-ID
|
141
zun/tests/unit/api/controllers/experimental/test_capsules.py
Normal file
141
zun/tests/unit/api/controllers/experimental/test_capsules.py
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
# Copyright 2017 Arm Limited
|
||||||
|
#
|
||||||
|
# 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 mock import patch
|
||||||
|
from webtest.app import AppError
|
||||||
|
from zun.common import exception
|
||||||
|
from zun.tests.unit.api import base as api_base
|
||||||
|
|
||||||
|
|
||||||
|
class TestCapsuleController(api_base.FunctionalTest):
|
||||||
|
@patch('zun.compute.api.API.capsule_create')
|
||||||
|
def test_create_capsule(self, mock_capsule_create):
|
||||||
|
params = ('{"spec": {"kind": "capsule",'
|
||||||
|
'"spec": {"containers":'
|
||||||
|
'[{"environment": {"ROOT_PASSWORD": "foo0"}, '
|
||||||
|
'"image": "test", "labels": {"app": "web"}, '
|
||||||
|
'"image_driver": "docker", "resources": '
|
||||||
|
'{"allocation": {"cpu": 1, "memory": 1024}}}], '
|
||||||
|
'"volumes": [{"name": "volume1", '
|
||||||
|
'"image": "test", "drivers": "cinder", "volumeType": '
|
||||||
|
'"type1", "driverOptions": "options", '
|
||||||
|
'"size": "5GB"}]}, '
|
||||||
|
'"metadata": {"labels": [{"foo0": "bar0"}, '
|
||||||
|
'{"foo1": "bar1"}], '
|
||||||
|
'"name": "capsule-example"}}}')
|
||||||
|
response = self.app.post('/capsules/',
|
||||||
|
params=params,
|
||||||
|
content_type='application/json')
|
||||||
|
return_value = response.json
|
||||||
|
expected_meta_name = "capsule-example"
|
||||||
|
expected_meta_label = [{"foo0": "bar0"}, {"foo1": "bar1"}]
|
||||||
|
expected_container_num = 2
|
||||||
|
self.assertEqual(len(return_value["containers_uuids"]),
|
||||||
|
expected_container_num)
|
||||||
|
self.assertEqual(return_value["meta_name"], expected_meta_name)
|
||||||
|
self.assertEqual(return_value["meta_labels"], expected_meta_label)
|
||||||
|
self.assertEqual(202, response.status_int)
|
||||||
|
self.assertTrue(mock_capsule_create.called)
|
||||||
|
|
||||||
|
@patch('zun.compute.api.API.capsule_create')
|
||||||
|
def test_create_capsule_two_containers(self, mock_capsule_create):
|
||||||
|
params = ('{"spec": {"kind": "capsule",'
|
||||||
|
'"spec": {"containers":'
|
||||||
|
'[{"environment": {"ROOT_PASSWORD": "foo0"}, '
|
||||||
|
'"image": "test1", "labels": {"app0": "web0"}, '
|
||||||
|
'"image_driver": "docker", "resources": '
|
||||||
|
'{"allocation": {"cpu": 1, "memory": 1024}}}, '
|
||||||
|
'{"environment": {"ROOT_PASSWORD": "foo1"}, '
|
||||||
|
'"image": "test1", "labels": {"app1": "web1"}, '
|
||||||
|
'"image_driver": "docker", "resources": '
|
||||||
|
'{"allocation": {"cpu": 1, "memory": 1024}}}]}, '
|
||||||
|
'"metadata": {"labels": [{"foo0": "bar0"}, '
|
||||||
|
'{"foo1": "bar1"}], '
|
||||||
|
'"name": "capsule-example"}}}')
|
||||||
|
response = self.app.post('/capsules/',
|
||||||
|
params=params,
|
||||||
|
content_type='application/json')
|
||||||
|
return_value = response.json
|
||||||
|
expected_meta_name = "capsule-example"
|
||||||
|
expected_meta_label = [{"foo0": "bar0"}, {"foo1": "bar1"}]
|
||||||
|
expected_container_num = 3
|
||||||
|
self.assertEqual(len(return_value["containers_uuids"]),
|
||||||
|
expected_container_num)
|
||||||
|
self.assertEqual(return_value["meta_name"],
|
||||||
|
expected_meta_name)
|
||||||
|
self.assertEqual(return_value["meta_labels"],
|
||||||
|
expected_meta_label)
|
||||||
|
self.assertEqual(202, response.status_int)
|
||||||
|
self.assertTrue(mock_capsule_create.called)
|
||||||
|
|
||||||
|
@patch('zun.compute.api.API.capsule_create')
|
||||||
|
@patch('zun.common.utils.check_capsule_template')
|
||||||
|
def test_create_capsule_wrong_kind_set(self, mock_check_template,
|
||||||
|
mock_capsule_create):
|
||||||
|
params = ('{"spec": {"kind": "test",'
|
||||||
|
'"spec": {"containers":'
|
||||||
|
'[{"environment": {"ROOT_PASSWORD": "foo0"}, '
|
||||||
|
'"image": "test1", "labels": {"app0": "web0"}, '
|
||||||
|
'"image_driver": "docker", "resources": '
|
||||||
|
'{"allocation": {"cpu": 1, "memory": 1024}}}]}, '
|
||||||
|
'"metadata": {"labels": [{"foo0": "bar0"}], '
|
||||||
|
'"name": "capsule-example"}}}')
|
||||||
|
mock_check_template.side_effect = exception.InvalidCapsuleTemplate(
|
||||||
|
"kind fields need to be set as capsule or Capsule")
|
||||||
|
response = self.post_json('/capsules/', params, expect_errors=True)
|
||||||
|
self.assertEqual(400, response.status_int)
|
||||||
|
self.assertFalse(mock_capsule_create.called)
|
||||||
|
|
||||||
|
@patch('zun.compute.api.API.capsule_create')
|
||||||
|
@patch('zun.common.utils.check_capsule_template')
|
||||||
|
def test_create_capsule_less_than_one_container(self, mock_check_template,
|
||||||
|
mock_capsule_create):
|
||||||
|
params = ('{"spec": {"kind": "capsule",'
|
||||||
|
'"spec": {container:[]}, '
|
||||||
|
'"metadata": {"labels": [{"foo0": "bar0"}], '
|
||||||
|
'"name": "capsule-example"}}}')
|
||||||
|
mock_check_template.side_effect = exception.InvalidCapsuleTemplate(
|
||||||
|
"Capsule need to have one container at least")
|
||||||
|
response = self.post_json('/capsules/', params, expect_errors=True)
|
||||||
|
self.assertEqual(400, response.status_int)
|
||||||
|
self.assertFalse(mock_capsule_create.called)
|
||||||
|
|
||||||
|
@patch('zun.compute.api.API.capsule_create')
|
||||||
|
@patch('zun.common.utils.check_capsule_template')
|
||||||
|
def test_create_capsule_no_container_field(self, mock_check_template,
|
||||||
|
mock_capsule_create):
|
||||||
|
params = ('{"spec": {"kind": "capsule",'
|
||||||
|
'"spec": {}, '
|
||||||
|
'"metadata": {"labels": [{"foo0": "bar0"}], '
|
||||||
|
'"name": "capsule-example"}}}')
|
||||||
|
mock_check_template.side_effect = exception.InvalidCapsuleTemplate(
|
||||||
|
"Capsule need to have one container at least")
|
||||||
|
self.assertRaises(AppError, self.app.post, '/capsules/',
|
||||||
|
params=params, content_type='application/json')
|
||||||
|
self.assertFalse(mock_capsule_create.called)
|
||||||
|
|
||||||
|
@patch('zun.compute.api.API.capsule_create')
|
||||||
|
@patch('zun.common.utils.check_capsule_template')
|
||||||
|
def test_create_capsule_no_container_image(self, mock_check_template,
|
||||||
|
mock_capsule_create):
|
||||||
|
params = ('{"spec": {"kind": "capsule",'
|
||||||
|
'"spec": {container:[{"environment": '
|
||||||
|
'{"ROOT_PASSWORD": "foo1"}]}, '
|
||||||
|
'"metadata": {"labels": [{"foo0": "bar0"}], '
|
||||||
|
'"name": "capsule-example"}}}')
|
||||||
|
mock_check_template.side_effect = exception.InvalidCapsuleTemplate(
|
||||||
|
"Container image is needed")
|
||||||
|
self.assertRaises(AppError, self.app.post, '/capsules/',
|
||||||
|
params=params, content_type='application/json')
|
||||||
|
self.assertFalse(mock_capsule_create.called)
|
@ -65,6 +65,22 @@ class TestRootController(api_base.FunctionalTest):
|
|||||||
{'href': 'http://localhost/images/',
|
{'href': 'http://localhost/images/',
|
||||||
'rel': 'bookmark'}]}
|
'rel': 'bookmark'}]}
|
||||||
|
|
||||||
|
self.experimental_expected = {
|
||||||
|
'media_types':
|
||||||
|
[{'base': 'application/json',
|
||||||
|
'type': 'application/vnd.openstack.zun.experimental+json'}],
|
||||||
|
'links': [{'href': 'http://localhost/experimental/',
|
||||||
|
'rel': 'self'},
|
||||||
|
{'href':
|
||||||
|
'https://docs.openstack.org/developer'
|
||||||
|
'/zun/dev/api-spec-v1.html',
|
||||||
|
'type': 'text/html', 'rel': 'describedby'}],
|
||||||
|
'id': 'experimental',
|
||||||
|
'capsules': [{'href': 'http://localhost/experimental/capsules/',
|
||||||
|
'rel': 'self'},
|
||||||
|
{'href': 'http://localhost/capsules/',
|
||||||
|
'rel': 'bookmark'}]}
|
||||||
|
|
||||||
def make_app(self, paste_file):
|
def make_app(self, paste_file):
|
||||||
file_name = self.get_path(paste_file)
|
file_name = self.get_path(paste_file)
|
||||||
cfg.CONF.set_override("api_paste_config", file_name, group="api")
|
cfg.CONF.set_override("api_paste_config", file_name, group="api")
|
||||||
@ -78,6 +94,10 @@ class TestRootController(api_base.FunctionalTest):
|
|||||||
response = self.app.get('/v1/')
|
response = self.app.get('/v1/')
|
||||||
self.assertEqual(self.v1_expected, response.json)
|
self.assertEqual(self.v1_expected, response.json)
|
||||||
|
|
||||||
|
def test_experimental_controller(self):
|
||||||
|
response = self.app.get('/experimental/')
|
||||||
|
self.assertEqual(self.experimental_expected, response.json)
|
||||||
|
|
||||||
def test_get_not_found(self):
|
def test_get_not_found(self):
|
||||||
response = self.app.get('/a/bogus/url', expect_errors=True)
|
response = self.app.get('/a/bogus/url', expect_errors=True)
|
||||||
assert response.status_int == 404
|
assert response.status_int == 404
|
||||||
@ -134,3 +154,14 @@ class TestRootController(api_base.FunctionalTest):
|
|||||||
|
|
||||||
response = app.get('/v1/containers', expect_errors=True)
|
response = app.get('/v1/containers', expect_errors=True)
|
||||||
self.assertEqual(401, response.status_int)
|
self.assertEqual(401, response.status_int)
|
||||||
|
|
||||||
|
def test_auth_with_experimental_access(self):
|
||||||
|
paste_file = \
|
||||||
|
"zun/tests/unit/api/controllers/auth-experimental-access.ini"
|
||||||
|
app = self.make_app(paste_file)
|
||||||
|
|
||||||
|
response = app.get('/', expect_errors=True)
|
||||||
|
self.assertEqual(401, response.status_int)
|
||||||
|
|
||||||
|
response = app.get('/experimental/')
|
||||||
|
self.assertEqual(self.experimental_expected, response.json)
|
||||||
|
@ -137,3 +137,41 @@ class TestUtils(base.TestCase):
|
|||||||
security_groups = ["not_attached_security_group_name"]
|
security_groups = ["not_attached_security_group_name"]
|
||||||
self.assertRaises(exception.ZunException, utils.get_security_group_ids,
|
self.assertRaises(exception.ZunException, utils.get_security_group_ids,
|
||||||
self.context, security_groups)
|
self.context, security_groups)
|
||||||
|
|
||||||
|
def test_check_capsule_template(self):
|
||||||
|
with self.assertRaisesRegex(
|
||||||
|
exception.InvalidCapsuleTemplate, "kind fields need to "
|
||||||
|
"be set as capsule or Capsule"):
|
||||||
|
params = ({"kind": "test", "spec": {"containers": []}})
|
||||||
|
utils.check_capsule_template(params)
|
||||||
|
|
||||||
|
with self.assertRaisesRegex(
|
||||||
|
exception.InvalidCapsuleTemplate, "No Spec found"):
|
||||||
|
params = ({"kind": "capsule"})
|
||||||
|
utils.check_capsule_template(params)
|
||||||
|
|
||||||
|
with self.assertRaisesRegex(
|
||||||
|
exception.InvalidCapsuleTemplate,
|
||||||
|
"No valid containers field"):
|
||||||
|
params = ({"kind": "capsule", "spec": {}})
|
||||||
|
utils.check_capsule_template(params)
|
||||||
|
|
||||||
|
with self.assertRaisesRegex(
|
||||||
|
exception.InvalidCapsuleTemplate,
|
||||||
|
"Capsule need to have one container at least"):
|
||||||
|
params = ({"kind": "capsule", "spec": {"containers": []}})
|
||||||
|
utils.check_capsule_template(params)
|
||||||
|
|
||||||
|
with self.assertRaisesRegex(
|
||||||
|
exception.InvalidCapsuleTemplate, "Container "
|
||||||
|
"image is needed"):
|
||||||
|
params = ({"kind": "capsule",
|
||||||
|
"spec": {"containers": [{"labels": {"app": "web"}}]}})
|
||||||
|
utils.check_capsule_template(params)
|
||||||
|
|
||||||
|
with self.assertRaisesRegex(
|
||||||
|
exception.InvalidCapsuleTemplate, "Container image is needed"):
|
||||||
|
params = ({"kind": "capsule",
|
||||||
|
"spec": {"containers": [{"image": "test1"},
|
||||||
|
{"environment": {"ROOT_PASSWORD": "foo0"}}]}})
|
||||||
|
utils.check_capsule_template(params)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user