Nguyen Hung Phuong ca69ffed43 Add functional API tests for volume connector and volume target
Extend baremetal json client with volume connector and volume target.
Add basic positive tests for volume connector and volume target:

    test_create_volume_connector_error
    test_delete_volume_connector
    test_delete_volume_connector_error
    test_show_volume_connector
    test_list_volume_connectors
    test_list_with_limit
    test_update_volume_connector_replace
    test_update_volume_connector_replace_error
    test_update_volume_connector_remove_item
    test_update_volume_connector_remove_collection
    test_update_volume_connector_add

    test_create_volume_target_error
    test_delete_volume_target
    test_delete_volume_target_error
    test_show_volume_target
    test_list_volume_targets
    test_list_with_limit
    test_update_volume_target_replace
    test_update_volume_target_replace_error
    test_update_volume_target_remove_item
    test_update_volume_target_remove_collection
    test_update_volume_target_add

Change-Id: I642a02cff2afe7f89b6800d69e14d05e04e6a59c
Partial-bug: #1559691
2017-06-13 14:22:10 +07:00

211 lines
8.9 KiB
Python

# Copyright 2017 FUJITSU 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 tempest.lib.common.utils import data_utils
from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from ironic_tempest_plugin.tests.api.admin import api_microversion_fixture
from ironic_tempest_plugin.tests.api.admin import base
class TestVolumeTarget(base.BaseBaremetalTest):
"""Basic test cases for volume target."""
min_microversion = '1.32'
extra = {'key1': 'value1', 'key2': 'value2'}
def setUp(self):
super(TestVolumeTarget, self).setUp()
self.useFixture(
api_microversion_fixture.APIMicroversionFixture(
self.min_microversion))
_, self.chassis = self.create_chassis()
_, self.node = self.create_node(self.chassis['uuid'])
_, self.volume_target = self.create_volume_target(
self.node['uuid'], volume_type=data_utils.rand_name('volume_type'),
volume_id=data_utils.rand_name('volume_id'),
boot_index=10,
extra=self.extra)
@decorators.attr(type=['negative'])
@decorators.idempotent_id('da5c27d4-68cc-499f-b8ab-3048b87d3bca')
def test_create_volume_target_error(self):
"""Create a volume target.
Fail when creating a volume target with same boot index as the
existing volume target.
"""
regex_str = (r'.*A volume target .*already exists')
self.assertRaisesRegex(
lib_exc.Conflict, regex_str,
self.create_volume_target,
self.node['uuid'],
volume_type=data_utils.rand_name('volume_type'),
volume_id=data_utils.rand_name('volume_id'),
boot_index=self.volume_target['boot_index'])
@decorators.idempotent_id('ea3a9b2e-8971-4830-9274-abaf0239f1ce')
def test_delete_volume_target(self):
"""Delete a volume target."""
# Powering off the Node before deleting a volume target.
self.client.set_node_power_state(self.node['uuid'], 'power off')
self.delete_volume_target(self.volume_target['uuid'])
self.assertRaises(lib_exc.NotFound, self.client.show_volume_target,
self.volume_target['uuid'])
@decorators.attr(type=['negative'])
@decorators.idempotent_id('532a06bc-a9b2-44b0-828a-c53279c87cb2')
def test_delete_volume_target_error(self):
"""Fail when deleting a volume target on node with power on state."""
# Powering on the Node before deleting a volume target.
self.client.set_node_power_state(self.node['uuid'], 'power on')
regex_str = (r'.*The requested action \\\\"volume target '
r'deletion\\\\" can not be performed on node*')
self.assertRaisesRegex(lib_exc.BadRequest,
regex_str,
self.delete_volume_target,
self.volume_target['uuid'])
@decorators.idempotent_id('a2598388-8f61-4b7e-944f-f37e4f60e1e2')
def test_show_volume_target(self):
"""Show a specified volume target."""
_, volume_target = self.client.show_volume_target(
self.volume_target['uuid'])
self._assertExpected(self.volume_target, volume_target)
@decorators.idempotent_id('ae99a986-d93c-4324-9cdc-41d89e3a659f')
def test_list_volume_targets(self):
"""List volume targets."""
_, body = self.client.list_volume_targets()
self.assertIn(self.volume_target['uuid'],
[i['uuid'] for i in body['targets']])
self.assertIn(self.volume_target['volume_type'],
[i['volume_type'] for i in body['targets']])
self.assertIn(self.volume_target['volume_id'],
[i['volume_id'] for i in body['targets']])
@decorators.idempotent_id('9da25447-0370-4b33-9c1f-d4503f5950ae')
def test_list_with_limit(self):
"""List volume targets with limit."""
_, body = self.client.list_volume_targets(limit=3)
next_marker = body['targets'][-1]['uuid']
self.assertIn(next_marker, body['next'])
@decorators.idempotent_id('8559cd08-feae-4f1a-a0ad-5bad8ea12b76')
def test_update_volume_target_replace(self):
"""Update a volume target by replacing volume id."""
new_volume_id = data_utils.rand_name('volume_id')
patch = [{'path': '/volume_id',
'op': 'replace',
'value': new_volume_id}]
# Powering off the Node before updating a volume target.
self.client.set_node_power_state(self.node['uuid'], 'power off')
self.client.update_volume_target(self.volume_target['uuid'], patch)
_, body = self.client.show_volume_target(self.volume_target['uuid'])
self.assertEqual(new_volume_id, body['volume_id'])
@decorators.attr(type=['negative'])
@decorators.idempotent_id('fd5266d3-4f3c-4dce-9c87-bfdea2b756c7')
def test_update_volume_target_replace_error(self):
"""Fail when updating a volume target on node with power on state."""
new_volume_id = data_utils.rand_name('volume_id')
patch = [{'path': '/volume_id',
'op': 'replace',
'value': new_volume_id}]
# Powering on the Node before updating a volume target.
self.client.set_node_power_state(self.node['uuid'], 'power on')
regex_str = (r'.*The requested action \\\\"volume target '
r'update\\\\" can not be performed on node*')
self.assertRaisesRegex(lib_exc.BadRequest,
regex_str,
self.client.update_volume_target,
self.volume_target['uuid'],
patch)
@decorators.idempotent_id('1c13a4ee-1a49-4739-8c19-77960fbd1af8')
def test_update_volume_target_remove_item(self):
"""Update a volume target by removing one item from the collection."""
new_extra = {'key1': 'value1'}
_, body = self.client.show_volume_target(self.volume_target['uuid'])
volume_id = body['volume_id']
volume_type = body['volume_type']
# Powering off the Node before updating a volume target.
self.client.set_node_power_state(self.node['uuid'], 'power off')
# Removing one item from the collection
self.client.update_volume_target(self.volume_target['uuid'],
[{'path': '/extra/key2',
'op': 'remove'}])
_, body = self.client.show_volume_target(self.volume_target['uuid'])
self.assertEqual(new_extra, body['extra'])
# Assert nothing else was changed
self.assertEqual(volume_id, body['volume_id'])
self.assertEqual(volume_type, body['volume_type'])
@decorators.idempotent_id('6784ddb0-9144-41ea-b8a0-f888ad5c5b62')
def test_update_volume_target_remove_collection(self):
"""Update a volume target by removing the collection."""
_, body = self.client.show_volume_target(self.volume_target['uuid'])
volume_id = body['volume_id']
volume_type = body['volume_type']
# Powering off the Node before updating a volume target.
self.client.set_node_power_state(self.node['uuid'], 'power off')
# Removing the collection
self.client.update_volume_target(self.volume_target['uuid'],
[{'path': '/extra',
'op': 'remove'}])
_, body = self.client.show_volume_target(self.volume_target['uuid'])
self.assertEqual({}, body['extra'])
# Assert nothing else was changed
self.assertEqual(volume_id, body['volume_id'])
self.assertEqual(volume_type, body['volume_type'])
@decorators.idempotent_id('9629715d-57ba-423b-b985-232674cc3a25')
def test_update_volume_target_add(self):
"""Update a volume target by adding to the collection."""
new_extra = {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}
patch = [{'path': '/extra/key3',
'op': 'add',
'value': new_extra['key3']}]
# Powering off the Node before updating a volume target.
self.client.set_node_power_state(self.node['uuid'], 'power off')
self.client.update_volume_target(self.volume_target['uuid'], patch)
_, body = self.client.show_volume_target(self.volume_target['uuid'])
self.assertEqual(new_extra, body['extra'])