Merge "Fix ipv6 network scenario in multi-network environment"
diff --git a/requirements.txt b/requirements.txt
index ce5886e..f9d8036 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -17,7 +17,7 @@
python-cinderclient>=1.1.0
python-heatclient>=0.2.9
python-ironicclient>=0.2.1
-python-saharaclient>=0.7.5
+python-saharaclient>=0.7.6
python-swiftclient>=2.2.0
testrepository>=0.0.18
oslo.config>=1.4.0 # Apache-2.0
diff --git a/tempest/api/compute/admin/test_availability_zone.py b/tempest/api/compute/admin/test_availability_zone.py
index 068a710..e88fecb 100644
--- a/tempest/api/compute/admin/test_availability_zone.py
+++ b/tempest/api/compute/admin/test_availability_zone.py
@@ -17,15 +17,15 @@
from tempest import test
-class AZAdminV3Test(base.BaseComputeAdminTest):
+class AZAdminV2TestJSON(base.BaseComputeAdminTest):
"""
Tests Availability Zone API List
"""
- _api_version = 3
+ _api_version = 2
@classmethod
def resource_setup(cls):
- super(AZAdminV3Test, cls).resource_setup()
+ super(AZAdminV2TestJSON, cls).resource_setup()
cls.client = cls.availability_zone_admin_client
@test.attr(type='gate')
@@ -42,7 +42,3 @@
self.client.get_availability_zone_list_detail()
self.assertEqual(200, resp.status)
self.assertTrue(len(availability_zone) > 0)
-
-
-class AZAdminV2TestJSON(AZAdminV3Test):
- _api_version = 2
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 6a3ee44..4feba59 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -31,7 +31,7 @@
class BaseComputeTest(tempest.test.BaseTestCase):
"""Base test case class for all Compute API tests."""
- _api_version = 3
+ _api_version = 2
force_tenant_isolation = False
@classmethod
@@ -87,29 +87,6 @@
cls.migrations_client = cls.os.migrations_client
cls.security_group_default_rules_client = (
cls.os.security_group_default_rules_client)
-
- elif cls._api_version == 3:
- if not CONF.compute_feature_enabled.api_v3:
- skip_msg = ("%s skipped as nova v3 api is not available" %
- cls.__name__)
- raise cls.skipException(skip_msg)
- cls.servers_client = cls.os.servers_v3_client
- cls.images_client = cls.os.image_client
- cls.flavors_client = cls.os.flavors_v3_client
- cls.services_client = cls.os.services_v3_client
- cls.extensions_client = cls.os.extensions_v3_client
- cls.availability_zone_client = cls.os.availability_zone_v3_client
- cls.interfaces_client = cls.os.interfaces_v3_client
- cls.hypervisor_client = cls.os.hypervisor_v3_client
- cls.keypairs_client = cls.os.keypairs_v3_client
- cls.volumes_client = cls.os.volumes_client
- cls.certificates_client = cls.os.certificates_v3_client
- cls.keypairs_client = cls.os.keypairs_v3_client
- cls.aggregates_client = cls.os.aggregates_v3_client
- cls.hosts_client = cls.os.hosts_v3_client
- cls.quotas_client = cls.os.quotas_v3_client
- cls.version_client = cls.os.version_v3_client
- cls.migrations_client = cls.os.migrations_v3_client
else:
msg = ("Unexpected API version is specified (%s)" %
cls._api_version)
@@ -316,20 +293,14 @@
if 'name' in kwargs:
name = kwargs.pop('name')
- if cls._api_version == 2:
- resp, image = cls.images_client.create_image(server_id, name)
- elif cls._api_version == 3:
- resp, image = cls.servers_client.create_image(server_id, name)
+ resp, image = cls.images_client.create_image(server_id, name)
image_id = data_utils.parse_image_id(resp['location'])
cls.images.append(image_id)
if 'wait_until' in kwargs:
cls.images_client.wait_for_image_status(image_id,
kwargs['wait_until'])
- if cls._api_version == 2:
- resp, image = cls.images_client.get_image(image_id)
- elif cls._api_version == 3:
- resp, image = cls.images_client.get_image_meta(image_id)
+ resp, image = cls.images_client.get_image(image_id)
if kwargs['wait_until'] == 'ACTIVE':
if kwargs.get('wait_for_server', True):
@@ -347,19 +318,13 @@
except Exception:
LOG.exception('Failed to delete server %s' % server_id)
resp, server = cls.create_test_server(wait_until='ACTIVE', **kwargs)
- if cls._api_version == 2:
- cls.password = server['adminPass']
- elif cls._api_version == 3:
- cls.password = server['admin_password']
+ cls.password = server['adminPass']
return server['id']
@classmethod
def delete_volume(cls, volume_id):
"""Deletes the given volume and waits for it to be gone."""
- if cls._api_version == 2:
- cls._delete_volume(cls.volumes_extensions_client, volume_id)
- elif cls._api_version == 3:
- cls._delete_volume(cls.volumes_client, volume_id)
+ cls._delete_volume(cls.volumes_extensions_client, volume_id)
class BaseV2ComputeTest(BaseComputeTest):
@@ -367,11 +332,6 @@
_interface = "json"
-class BaseV3ComputeTest(BaseComputeTest):
- _api_version = 3
- _interface = "json"
-
-
class BaseComputeAdminTest(BaseComputeTest):
"""Base test case class for Compute Admin API tests."""
_interface = "json"
@@ -387,29 +347,10 @@
msg = ("Missing Compute Admin API credentials in configuration.")
raise cls.skipException(msg)
- if cls._api_version == 2:
- cls.availability_zone_admin_client = (
- cls.os_adm.availability_zone_client)
-
- else:
- cls.servers_admin_client = cls.os_adm.servers_v3_client
- cls.services_admin_client = cls.os_adm.services_v3_client
- cls.availability_zone_admin_client = \
- cls.os_adm.availability_zone_v3_client
- cls.hypervisor_admin_client = cls.os_adm.hypervisor_v3_client
- cls.flavors_admin_client = cls.os_adm.flavors_v3_client
- cls.aggregates_admin_client = cls.os_adm.aggregates_v3_client
- cls.hosts_admin_client = cls.os_adm.hosts_v3_client
- cls.quotas_admin_client = cls.os_adm.quotas_v3_client
- cls.agents_admin_client = cls.os_adm.agents_v3_client
- cls.migrations_admin_client = cls.os_adm.migrations_v3_client
+ cls.availability_zone_admin_client = (
+ cls.os_adm.availability_zone_client)
class BaseV2ComputeAdminTest(BaseComputeAdminTest):
"""Base test case class for Compute Admin V2 API tests."""
_api_version = 2
-
-
-class BaseV3ComputeAdminTest(BaseComputeAdminTest):
- """Base test case class for Compute Admin V3 API tests."""
- _api_version = 3
diff --git a/tempest/api/compute/certificates/test_certificates.py b/tempest/api/compute/certificates/test_certificates.py
index 5c55eec..15ccf53 100644
--- a/tempest/api/compute/certificates/test_certificates.py
+++ b/tempest/api/compute/certificates/test_certificates.py
@@ -17,9 +17,9 @@
from tempest import test
-class CertificatesV3Test(base.BaseComputeTest):
+class CertificatesV2TestJSON(base.BaseComputeTest):
- _api_version = 3
+ _api_version = 2
@test.attr(type='gate')
def test_create_root_certificate(self):
@@ -35,7 +35,3 @@
self.assertEqual(200, resp.status)
self.assertIn('data', body)
self.assertIn('private_key', body)
-
-
-class CertificatesV2TestJSON(CertificatesV3Test):
- _api_version = 2
diff --git a/tempest/api/compute/flavors/test_flavors.py b/tempest/api/compute/flavors/test_flavors.py
index 86eeba3..992f86a 100644
--- a/tempest/api/compute/flavors/test_flavors.py
+++ b/tempest/api/compute/flavors/test_flavors.py
@@ -17,15 +17,15 @@
from tempest import test
-class FlavorsV3Test(base.BaseComputeTest):
+class FlavorsV2TestJSON(base.BaseComputeTest):
- _api_version = 3
- _min_disk = 'min_disk'
- _min_ram = 'min_ram'
+ _api_version = 2
+ _min_disk = 'minDisk'
+ _min_ram = 'minRam'
@classmethod
def resource_setup(cls):
- super(FlavorsV3Test, cls).resource_setup()
+ super(FlavorsV2TestJSON, cls).resource_setup()
cls.client = cls.flavors_client
@test.attr(type='smoke')
@@ -125,10 +125,3 @@
params = {self._min_ram: flavor['ram'] + 1}
resp, flavors = self.client.list_flavors(params)
self.assertFalse(any([i for i in flavors if i['id'] == flavor_id]))
-
-
-class FlavorsV2TestJSON(FlavorsV3Test):
-
- _api_version = 2
- _min_disk = 'minDisk'
- _min_ram = 'minRam'
diff --git a/tempest/api/compute/keypairs/test_keypairs.py b/tempest/api/compute/keypairs/test_keypairs.py
index de8cab9..ce10fbe 100644
--- a/tempest/api/compute/keypairs/test_keypairs.py
+++ b/tempest/api/compute/keypairs/test_keypairs.py
@@ -18,13 +18,13 @@
from tempest import test
-class KeyPairsV3Test(base.BaseComputeTest):
+class KeyPairsV2TestJSON(base.BaseComputeTest):
- _api_version = 3
+ _api_version = 2
@classmethod
def resource_setup(cls):
- super(KeyPairsV3Test, cls).resource_setup()
+ super(KeyPairsV2TestJSON, cls).resource_setup()
cls.client = cls.keypairs_client
def _delete_keypair(self, keypair_name):
@@ -113,7 +113,3 @@
self.assertEqual(key_name, k_name,
"The created keypair name is not equal "
"to the requested name!")
-
-
-class KeyPairsV2TestJSON(KeyPairsV3Test):
- _api_version = 2
diff --git a/tempest/api/compute/limits/test_absolute_limits_negative.py b/tempest/api/compute/limits/test_absolute_limits_negative.py
index f729436..a9c72fb 100644
--- a/tempest/api/compute/limits/test_absolute_limits_negative.py
+++ b/tempest/api/compute/limits/test_absolute_limits_negative.py
@@ -32,6 +32,10 @@
# Get max limit value
max_meta = self.client.get_specific_absolute_limit('maxImageMeta')
+ # No point in running this test if there is no limit.
+ if int(max_meta) == -1:
+ raise self.skipException('no limit for maxImageMeta')
+
# Create server should fail, since we are passing > metadata Limit!
max_meta_data = int(max_meta) + 1
diff --git a/tempest/api/compute/servers/test_availability_zone.py b/tempest/api/compute/servers/test_availability_zone.py
index 28eb274..5ddf053 100644
--- a/tempest/api/compute/servers/test_availability_zone.py
+++ b/tempest/api/compute/servers/test_availability_zone.py
@@ -17,15 +17,15 @@
from tempest import test
-class AZV3Test(base.BaseComputeTest):
+class AZV2TestJSON(base.BaseComputeTest):
"""
Tests Availability Zone API List
"""
- _api_version = 3
+ _api_version = 2
@classmethod
def resource_setup(cls):
- super(AZV3Test, cls).resource_setup()
+ super(AZV2TestJSON, cls).resource_setup()
cls.client = cls.availability_zone_client
@test.attr(type='gate')
@@ -34,7 +34,3 @@
resp, availability_zone = self.client.get_availability_zone_list()
self.assertEqual(200, resp.status)
self.assertTrue(len(availability_zone) > 0)
-
-
-class AZV2TestJSON(AZV3Test):
- _api_version = 2
diff --git a/tempest/api/compute/servers/test_server_metadata_negative.py b/tempest/api/compute/servers/test_server_metadata_negative.py
index 8b074fd..ee1e652 100644
--- a/tempest/api/compute/servers/test_server_metadata_negative.py
+++ b/tempest/api/compute/servers/test_server_metadata_negative.py
@@ -124,6 +124,9 @@
# tenant.
_, quota_set = self.quotas.get_quota_set(self.tenant_id)
quota_metadata = quota_set['metadata_items']
+ if quota_metadata == -1:
+ raise self.skipException("No limit for metadata_items")
+
req_metadata = {}
for num in range(1, quota_metadata + 2):
req_metadata['key' + str(num)] = 'val' + str(num)
diff --git a/tempest/api/compute/servers/test_servers_negative.py b/tempest/api/compute/servers/test_servers_negative.py
index 4e6dcda..f44d158 100644
--- a/tempest/api/compute/servers/test_servers_negative.py
+++ b/tempest/api/compute/servers/test_servers_negative.py
@@ -13,7 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-import base64
import sys
import testtools
@@ -166,18 +165,10 @@
def test_rebuild_non_existent_server(self):
# Rebuild a non existent server
nonexistent_server = data_utils.rand_uuid()
- meta = {'rebuild': 'server'}
- new_name = data_utils.rand_name('server')
- file_contents = 'Test server rebuild.'
- personality = [{'path': '/etc/rebuild.txt',
- 'contents': base64.b64encode(file_contents)}]
self.assertRaises(exceptions.NotFound,
self.client.rebuild,
nonexistent_server,
- self.image_ref_alt,
- name=new_name, meta=meta,
- personality=personality,
- adminPass='rebuild')
+ self.image_ref_alt)
@test.attr(type=['negative', 'gate'])
def test_create_numeric_server_name(self):
diff --git a/tempest/api/compute/v3/__init__.py b/tempest/api/compute/v3/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/api/compute/v3/__init__.py
+++ /dev/null
diff --git a/tempest/api/compute/v3/admin/__init__.py b/tempest/api/compute/v3/admin/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/api/compute/v3/admin/__init__.py
+++ /dev/null
diff --git a/tempest/api/compute/v3/admin/test_agents.py b/tempest/api/compute/v3/admin/test_agents.py
deleted file mode 100644
index b7c0011..0000000
--- a/tempest/api/compute/v3/admin/test_agents.py
+++ /dev/null
@@ -1,91 +0,0 @@
-# Copyright 2014 NEC Corporation. All rights reserved.
-#
-# 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.api.compute import base
-from tempest import test
-
-
-class AgentsAdminV3Test(base.BaseV3ComputeAdminTest):
-
- """
- Tests Agents API that require admin privileges
- """
-
- @classmethod
- def resource_setup(cls):
- super(AgentsAdminV3Test, cls).resource_setup()
- cls.client = cls.agents_admin_client
-
- @test.attr(type='gate')
- def test_create_update_list_delete_agents(self):
-
- """
- 1. Create 2 agents.
- 2. Update one of the agents.
- 3. List all agent builds.
- 4. List the agent builds by the filter.
- 5. Delete agents.
- """
- params_kvm = expected_kvm = {'hypervisor': 'kvm',
- 'os': 'win',
- 'architecture': 'x86',
- 'version': '7.0',
- 'url': 'xxx://xxxx/xxx/xxx',
- 'md5hash': ("""add6bb58e139be103324d04d"""
- """82d8f545""")}
-
- resp, agent_kvm = self.client.create_agent(**params_kvm)
- self.assertEqual(201, resp.status)
- for expected_item, value in expected_kvm.items():
- self.assertEqual(value, agent_kvm[expected_item])
-
- params_xen = expected_xen = {'hypervisor': 'xen',
- 'os': 'linux',
- 'architecture': 'x86',
- 'version': '7.0',
- 'url': 'xxx://xxxx/xxx/xxx1',
- 'md5hash': """add6bb58e139be103324d04d8"""
- """2d8f546"""}
-
- resp, agent_xen = self.client.create_agent(**params_xen)
- self.assertEqual(201, resp.status)
-
- for expected_item, value in expected_xen.items():
- self.assertEqual(value, agent_xen[expected_item])
-
- params_kvm_new = expected_kvm_new = {'version': '8.0',
- 'url': 'xxx://xxxx/xxx/xxx2',
- 'md5hash': """add6bb58e139be103"""
- """324d04d82d8f547"""}
-
- resp, resp_agent_kvm = self.client.update_agent(agent_kvm['agent_id'],
- **params_kvm_new)
- self.assertEqual(200, resp.status)
- for expected_item, value in expected_kvm_new.items():
- self.assertEqual(value, resp_agent_kvm[expected_item])
-
- resp, agents = self.client.list_agents()
- self.assertEqual(200, resp.status)
- self.assertTrue(len(agents) > 1)
-
- params_filter = {'hypervisor': 'kvm'}
- resp, agent = self.client.list_agents(params_filter)
- self.assertEqual(200, resp.status)
- self.assertTrue(len(agent) > 0)
- self.assertEqual('kvm', agent[0]['hypervisor'])
-
- resp, _ = self.client.delete_agent(agent_kvm['agent_id'])
- self.assertEqual(204, resp.status)
- resp, _ = self.client.delete_agent(agent_xen['agent_id'])
- self.assertEqual(204, resp.status)
diff --git a/tempest/api/compute/v3/admin/test_aggregates.py b/tempest/api/compute/v3/admin/test_aggregates.py
deleted file mode 100644
index 1beeb13..0000000
--- a/tempest/api/compute/v3/admin/test_aggregates.py
+++ /dev/null
@@ -1,213 +0,0 @@
-# Copyright 2013 NEC Corporation.
-# All Rights Reserved.
-#
-# 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.api.compute import base
-from tempest.common import tempest_fixtures as fixtures
-from tempest.common.utils import data_utils
-from tempest import test
-
-
-class AggregatesAdminV3Test(base.BaseV3ComputeAdminTest):
-
- """
- Tests Aggregates API that require admin privileges
- """
-
- _host_key = 'os-extended-server-attributes:host'
-
- @classmethod
- def resource_setup(cls):
- super(AggregatesAdminV3Test, cls).resource_setup()
- cls.client = cls.aggregates_admin_client
- cls.aggregate_name_prefix = 'test_aggregate_'
- cls.az_name_prefix = 'test_az_'
-
- resp, hosts_all = cls.hosts_admin_client.list_hosts()
- hosts = map(lambda x: x['host_name'],
- filter(lambda y: y['service'] == 'compute', hosts_all))
- cls.host = hosts[0]
-
- @test.attr(type='gate')
- def test_aggregate_create_delete(self):
- # Create and delete an aggregate.
- aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- resp, aggregate = self.client.create_aggregate(name=aggregate_name)
- self.assertEqual(201, resp.status)
- self.assertEqual(aggregate_name, aggregate['name'])
- self.assertIsNone(aggregate['availability_zone'])
-
- resp, _ = self.client.delete_aggregate(aggregate['id'])
- self.assertEqual(204, resp.status)
- self.client.wait_for_resource_deletion(aggregate['id'])
-
- @test.attr(type='gate')
- def test_aggregate_create_delete_with_az(self):
- # Create and delete an aggregate.
- aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- az_name = data_utils.rand_name(self.az_name_prefix)
- resp, aggregate = self.client.create_aggregate(
- name=aggregate_name, availability_zone=az_name)
- self.assertEqual(201, resp.status)
- self.assertEqual(aggregate_name, aggregate['name'])
- self.assertEqual(az_name, aggregate['availability_zone'])
-
- resp, _ = self.client.delete_aggregate(aggregate['id'])
- self.assertEqual(204, resp.status)
- self.client.wait_for_resource_deletion(aggregate['id'])
-
- @test.attr(type='gate')
- def test_aggregate_create_verify_entry_in_list(self):
- # Create an aggregate and ensure it is listed.
- aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- resp, aggregate = self.client.create_aggregate(name=aggregate_name)
- self.addCleanup(self.client.delete_aggregate, aggregate['id'])
-
- resp, aggregates = self.client.list_aggregates()
- self.assertEqual(200, resp.status)
- self.assertIn((aggregate['id'], aggregate['availability_zone']),
- map(lambda x: (x['id'], x['availability_zone']),
- aggregates))
-
- @test.attr(type='gate')
- def test_aggregate_create_update_metadata_get_details(self):
- # Create an aggregate and ensure its details are returned.
- aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- resp, aggregate = self.client.create_aggregate(name=aggregate_name)
- self.addCleanup(self.client.delete_aggregate, aggregate['id'])
-
- resp, body = self.client.get_aggregate(aggregate['id'])
- self.assertEqual(200, resp.status)
- self.assertEqual(aggregate['name'], body['name'])
- self.assertEqual(aggregate['availability_zone'],
- body['availability_zone'])
- self.assertEqual({}, body["metadata"])
-
- # set the metadata of the aggregate
- meta = {"key": "value"}
- resp, body = self.client.set_metadata(aggregate['id'], meta)
- self.assertEqual(200, resp.status)
- self.assertEqual(meta, body["metadata"])
-
- # verify the metadata has been set
- resp, body = self.client.get_aggregate(aggregate['id'])
- self.assertEqual(200, resp.status)
- self.assertEqual(meta, body["metadata"])
-
- @test.attr(type='gate')
- def test_aggregate_create_update_with_az(self):
- # Update an aggregate and ensure properties are updated correctly
- self.useFixture(fixtures.LockFixture('availability_zone'))
- aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- az_name = data_utils.rand_name(self.az_name_prefix)
- resp, aggregate = self.client.create_aggregate(
- name=aggregate_name, availability_zone=az_name)
- self.addCleanup(self.client.delete_aggregate, aggregate['id'])
-
- self.assertEqual(201, resp.status)
- self.assertEqual(aggregate_name, aggregate['name'])
- self.assertEqual(az_name, aggregate['availability_zone'])
- self.assertIsNotNone(aggregate['id'])
-
- aggregate_id = aggregate['id']
- new_aggregate_name = aggregate_name + '_new'
- new_az_name = az_name + '_new'
-
- resp, resp_aggregate = self.client.update_aggregate(aggregate_id,
- new_aggregate_name,
- new_az_name)
- self.assertEqual(200, resp.status)
- self.assertEqual(new_aggregate_name, resp_aggregate['name'])
- self.assertEqual(new_az_name, resp_aggregate['availability_zone'])
-
- resp, aggregates = self.client.list_aggregates()
- self.assertEqual(200, resp.status)
- self.assertIn((aggregate_id, new_aggregate_name, new_az_name),
- map(lambda x:
- (x['id'], x['name'], x['availability_zone']),
- aggregates))
-
- @test.attr(type='gate')
- def test_aggregate_add_remove_host(self):
- # Add an host to the given aggregate and remove.
- self.useFixture(fixtures.LockFixture('availability_zone'))
- aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- resp, aggregate = self.client.create_aggregate(name=aggregate_name)
- self.addCleanup(self.client.delete_aggregate, aggregate['id'])
-
- resp, body = self.client.add_host(aggregate['id'], self.host)
- self.assertEqual(202, resp.status)
- self.assertEqual(aggregate_name, body['name'])
- self.assertEqual(aggregate['availability_zone'],
- body['availability_zone'])
- self.assertIn(self.host, body['hosts'])
-
- resp, body = self.client.remove_host(aggregate['id'], self.host)
- self.assertEqual(202, resp.status)
- self.assertEqual(aggregate_name, body['name'])
- self.assertEqual(aggregate['availability_zone'],
- body['availability_zone'])
- self.assertNotIn(self.host, body['hosts'])
-
- @test.attr(type='gate')
- def test_aggregate_add_host_list(self):
- # Add an host to the given aggregate and list.
- self.useFixture(fixtures.LockFixture('availability_zone'))
- aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- resp, aggregate = self.client.create_aggregate(name=aggregate_name)
- self.addCleanup(self.client.delete_aggregate, aggregate['id'])
- self.client.add_host(aggregate['id'], self.host)
- self.addCleanup(self.client.remove_host, aggregate['id'], self.host)
-
- resp, aggregates = self.client.list_aggregates()
- aggs = filter(lambda x: x['id'] == aggregate['id'], aggregates)
- self.assertEqual(1, len(aggs))
- agg = aggs[0]
- self.assertEqual(aggregate_name, agg['name'])
- self.assertIsNone(agg['availability_zone'])
- self.assertIn(self.host, agg['hosts'])
-
- @test.attr(type='gate')
- def test_aggregate_add_host_get_details(self):
- # Add an host to the given aggregate and get details.
- self.useFixture(fixtures.LockFixture('availability_zone'))
- aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- resp, aggregate = self.client.create_aggregate(name=aggregate_name)
- self.addCleanup(self.client.delete_aggregate, aggregate['id'])
- self.client.add_host(aggregate['id'], self.host)
- self.addCleanup(self.client.remove_host, aggregate['id'], self.host)
-
- resp, body = self.client.get_aggregate(aggregate['id'])
- self.assertEqual(aggregate_name, body['name'])
- self.assertIsNone(body['availability_zone'])
- self.assertIn(self.host, body['hosts'])
-
- @test.attr(type='gate')
- def test_aggregate_add_host_create_server_with_az(self):
- # Add an host to the given aggregate and create a server.
- self.useFixture(fixtures.LockFixture('availability_zone'))
- aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- az_name = data_utils.rand_name(self.az_name_prefix)
- resp, aggregate = self.client.create_aggregate(
- name=aggregate_name, availability_zone=az_name)
- self.addCleanup(self.client.delete_aggregate, aggregate['id'])
- self.client.add_host(aggregate['id'], self.host)
- self.addCleanup(self.client.remove_host, aggregate['id'], self.host)
- server_name = data_utils.rand_name('test_server_')
- admin_servers_client = self.servers_admin_client
- resp, server = self.create_test_server(name=server_name,
- availability_zone=az_name,
- wait_until='ACTIVE')
- resp, body = admin_servers_client.get_server(server['id'])
- self.assertEqual(self.host, body[self._host_key])
diff --git a/tempest/api/compute/v3/admin/test_aggregates_negative.py b/tempest/api/compute/v3/admin/test_aggregates_negative.py
deleted file mode 100644
index 093963f..0000000
--- a/tempest/api/compute/v3/admin/test_aggregates_negative.py
+++ /dev/null
@@ -1,188 +0,0 @@
-# Copyright 2013 Huawei Technologies Co.,LTD.
-# All Rights Reserved.
-#
-# 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.api.compute import base
-from tempest.common import tempest_fixtures as fixtures
-from tempest.common.utils import data_utils
-from tempest import exceptions
-from tempest import test
-
-
-class AggregatesAdminNegativeV3Test(base.BaseV3ComputeAdminTest):
-
- """
- Tests Aggregates API that require admin privileges
- """
-
- @classmethod
- def resource_setup(cls):
- super(AggregatesAdminNegativeV3Test, cls).resource_setup()
- cls.client = cls.aggregates_admin_client
- cls.user_client = cls.aggregates_client
- cls.aggregate_name_prefix = 'test_aggregate_'
- cls.az_name_prefix = 'test_az_'
-
- resp, hosts_all = cls.hosts_admin_client.list_hosts()
- hosts = map(lambda x: x['host_name'],
- filter(lambda y: y['service'] == 'compute', hosts_all))
- cls.host = hosts[0]
-
- @test.attr(type=['negative', 'gate'])
- def test_aggregate_create_as_user(self):
- # Regular user is not allowed to create an aggregate.
- aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- self.assertRaises(exceptions.Unauthorized,
- self.user_client.create_aggregate,
- name=aggregate_name)
-
- @test.attr(type=['negative', 'gate'])
- def test_aggregate_create_aggregate_name_length_less_than_1(self):
- # the length of aggregate name should >= 1 and <=255
- self.assertRaises(exceptions.BadRequest,
- self.client.create_aggregate,
- name='')
-
- @test.attr(type=['negative', 'gate'])
- def test_aggregate_create_aggregate_name_length_exceeds_255(self):
- # the length of aggregate name should >= 1 and <=255
- aggregate_name = 'a' * 256
- self.assertRaises(exceptions.BadRequest,
- self.client.create_aggregate,
- name=aggregate_name)
-
- @test.attr(type=['negative', 'gate'])
- def test_aggregate_create_with_existent_aggregate_name(self):
- # creating an aggregate with existent aggregate name is forbidden
- aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- resp, aggregate = self.client.create_aggregate(name=aggregate_name)
- self.assertEqual(201, resp.status)
- self.addCleanup(self.client.delete_aggregate, aggregate['id'])
-
- self.assertRaises(exceptions.Conflict,
- self.client.create_aggregate,
- name=aggregate_name)
-
- @test.attr(type=['negative', 'gate'])
- def test_aggregate_delete_as_user(self):
- # Regular user is not allowed to delete an aggregate.
- aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- resp, aggregate = self.client.create_aggregate(name=aggregate_name)
- self.assertEqual(201, resp.status)
- self.addCleanup(self.client.delete_aggregate, aggregate['id'])
-
- self.assertRaises(exceptions.Unauthorized,
- self.user_client.delete_aggregate,
- aggregate['id'])
-
- @test.attr(type=['negative', 'gate'])
- def test_aggregate_list_as_user(self):
- # Regular user is not allowed to list aggregates.
- self.assertRaises(exceptions.Unauthorized,
- self.user_client.list_aggregates)
-
- @test.attr(type=['negative', 'gate'])
- def test_aggregate_get_details_as_user(self):
- # Regular user is not allowed to get aggregate details.
- aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- resp, aggregate = self.client.create_aggregate(name=aggregate_name)
- self.assertEqual(201, resp.status)
- self.addCleanup(self.client.delete_aggregate, aggregate['id'])
-
- self.assertRaises(exceptions.Unauthorized,
- self.user_client.get_aggregate,
- aggregate['id'])
-
- @test.attr(type=['negative', 'gate'])
- def test_aggregate_delete_with_invalid_id(self):
- # Delete an aggregate with invalid id should raise exceptions.
- self.assertRaises(exceptions.NotFound,
- self.client.delete_aggregate, -1)
-
- @test.attr(type=['negative', 'gate'])
- def test_aggregate_get_details_with_invalid_id(self):
- # Get aggregate details with invalid id should raise exceptions.
- self.assertRaises(exceptions.NotFound,
- self.client.get_aggregate, -1)
-
- @test.attr(type=['negative', 'gate'])
- def test_aggregate_add_non_exist_host(self):
- # Adding a non-exist host to an aggregate should raise exceptions.
- resp, hosts_all = self.hosts_admin_client.list_hosts()
- hosts = map(lambda x: x['host_name'], hosts_all)
- while True:
- non_exist_host = data_utils.rand_name('nonexist_host_')
- if non_exist_host not in hosts:
- break
-
- aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- resp, aggregate = self.client.create_aggregate(name=aggregate_name)
- self.addCleanup(self.client.delete_aggregate, aggregate['id'])
-
- self.assertRaises(exceptions.NotFound, self.client.add_host,
- aggregate['id'], non_exist_host)
-
- @test.attr(type=['negative', 'gate'])
- def test_aggregate_add_host_as_user(self):
- # Regular user is not allowed to add a host to an aggregate.
- aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- resp, aggregate = self.client.create_aggregate(name=aggregate_name)
- self.assertEqual(201, resp.status)
- self.addCleanup(self.client.delete_aggregate, aggregate['id'])
-
- self.assertRaises(exceptions.Unauthorized,
- self.user_client.add_host,
- aggregate['id'], self.host)
-
- @test.attr(type=['negative', 'gate'])
- def test_aggregate_add_existent_host(self):
- self.useFixture(fixtures.LockFixture('availability_zone'))
- aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- resp, aggregate = self.client.create_aggregate(name=aggregate_name)
- self.assertEqual(201, resp.status)
- self.addCleanup(self.client.delete_aggregate, aggregate['id'])
-
- resp, body = self.client.add_host(aggregate['id'], self.host)
- self.assertEqual(202, resp.status)
- self.addCleanup(self.client.remove_host, aggregate['id'], self.host)
-
- self.assertRaises(exceptions.Conflict, self.client.add_host,
- aggregate['id'], self.host)
-
- @test.attr(type=['negative', 'gate'])
- def test_aggregate_remove_host_as_user(self):
- # Regular user is not allowed to remove a host from an aggregate.
- self.useFixture(fixtures.LockFixture('availability_zone'))
- aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- resp, aggregate = self.client.create_aggregate(name=aggregate_name)
- self.assertEqual(201, resp.status)
- self.addCleanup(self.client.delete_aggregate, aggregate['id'])
- resp, body = self.client.add_host(aggregate['id'], self.host)
- self.assertEqual(202, resp.status)
- self.addCleanup(self.client.remove_host, aggregate['id'], self.host)
-
- self.assertRaises(exceptions.Unauthorized,
- self.user_client.remove_host,
- aggregate['id'], self.host)
-
- @test.attr(type=['negative', 'gate'])
- def test_aggregate_remove_nonexistent_host(self):
- non_exist_host = data_utils.rand_name('nonexist_host_')
- aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- resp, aggregate = self.client.create_aggregate(name=aggregate_name)
- self.assertEqual(201, resp.status)
- self.addCleanup(self.client.delete_aggregate, aggregate['id'])
-
- self.assertRaises(exceptions.NotFound, self.client.remove_host,
- aggregate['id'], non_exist_host)
diff --git a/tempest/api/compute/v3/admin/test_availability_zone_negative.py b/tempest/api/compute/v3/admin/test_availability_zone_negative.py
deleted file mode 100644
index 56cdd6c..0000000
--- a/tempest/api/compute/v3/admin/test_availability_zone_negative.py
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright 2013 NEC Corporation
-# All Rights Reserved.
-#
-# 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.api.compute import base
-from tempest import exceptions
-from tempest import test
-
-
-class AZAdminNegativeV3Test(base.BaseV3ComputeAdminTest):
-
- """
- Tests Availability Zone API List
- """
-
- @classmethod
- def resource_setup(cls):
- super(AZAdminNegativeV3Test, cls).resource_setup()
- cls.client = cls.availability_zone_admin_client
- cls.non_adm_client = cls.availability_zone_client
-
- @test.attr(type=['negative', 'gate'])
- def test_get_availability_zone_list_detail_with_non_admin_user(self):
- # List of availability zones and available services with
- # non-administrator user
- self.assertRaises(
- exceptions.Unauthorized,
- self.non_adm_client.get_availability_zone_list_detail)
diff --git a/tempest/api/compute/v3/admin/test_flavors.py b/tempest/api/compute/v3/admin/test_flavors.py
deleted file mode 100644
index f307907..0000000
--- a/tempest/api/compute/v3/admin/test_flavors.py
+++ /dev/null
@@ -1,308 +0,0 @@
-# Copyright 2012 OpenStack Foundation
-# All Rights Reserved.
-#
-# 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 uuid
-
-from tempest.api.compute import base
-from tempest.common.utils import data_utils
-from tempest import exceptions
-from tempest import test
-
-
-class FlavorsAdminV3Test(base.BaseV3ComputeAdminTest):
-
- """
- Tests Flavors API Create and Delete that require admin privileges
- """
-
- @classmethod
- def resource_setup(cls):
- super(FlavorsAdminV3Test, cls).resource_setup()
-
- cls.client = cls.flavors_admin_client
- cls.user_client = cls.flavors_client
- cls.flavor_name_prefix = 'test_flavor_'
- cls.ram = 512
- cls.vcpus = 1
- cls.disk = 10
- cls.ephemeral = 10
- cls.swap = 1024
- cls.rxtx = 2
-
- def flavor_clean_up(self, flavor_id):
- resp, body = self.client.delete_flavor(flavor_id)
- self.assertEqual(resp.status, 204)
- self.client.wait_for_resource_deletion(flavor_id)
-
- def _create_flavor(self, flavor_id):
- # Create a flavor and ensure it is listed
- # This operation requires the user to have 'admin' role
- flavor_name = data_utils.rand_name(self.flavor_name_prefix)
-
- # Create the flavor
- resp, flavor = self.client.create_flavor(flavor_name,
- self.ram, self.vcpus,
- self.disk,
- flavor_id,
- ephemeral=self.ephemeral,
- swap=self.swap,
- rxtx=self.rxtx)
- self.addCleanup(self.flavor_clean_up, flavor['id'])
- self.assertEqual(201, resp.status)
- self.assertEqual(flavor['name'], flavor_name)
- self.assertEqual(flavor['vcpus'], self.vcpus)
- self.assertEqual(flavor['disk'], self.disk)
- self.assertEqual(flavor['ram'], self.ram)
- self.assertEqual(flavor['swap'], self.swap)
- if test.is_extension_enabled("os-flavor-rxtx", "compute_v3"):
- self.assertEqual(flavor['os-flavor-rxtx:rxtx_factor'], self.rxtx)
- self.assertEqual(flavor['ephemeral'],
- self.ephemeral)
- self.assertEqual(flavor['flavor-access:is_public'], True)
-
- # Verify flavor is retrieved
- resp, flavor = self.client.get_flavor_details(flavor['id'])
- self.assertEqual(resp.status, 200)
- self.assertEqual(flavor['name'], flavor_name)
-
- return flavor['id']
-
- @test.attr(type='gate')
- def test_create_flavor_with_int_id(self):
- flavor_id = data_utils.rand_int_id(start=1000)
- new_flavor_id = self._create_flavor(flavor_id)
- self.assertEqual(new_flavor_id, str(flavor_id))
-
- @test.attr(type='gate')
- def test_create_flavor_with_uuid_id(self):
- flavor_id = str(uuid.uuid4())
- new_flavor_id = self._create_flavor(flavor_id)
- self.assertEqual(new_flavor_id, flavor_id)
-
- @test.attr(type='gate')
- def test_create_flavor_with_none_id(self):
- # If nova receives a request with None as flavor_id,
- # nova generates flavor_id of uuid.
- flavor_id = None
- new_flavor_id = self._create_flavor(flavor_id)
- self.assertEqual(new_flavor_id, str(uuid.UUID(new_flavor_id)))
-
- @test.attr(type='gate')
- def test_create_flavor_verify_entry_in_list_details(self):
- # Create a flavor and ensure it's details are listed
- # This operation requires the user to have 'admin' role
- flavor_name = data_utils.rand_name(self.flavor_name_prefix)
- new_flavor_id = data_utils.rand_int_id(start=1000)
-
- # Create the flavor
- resp, flavor = self.client.create_flavor(flavor_name,
- self.ram, self.vcpus,
- self.disk,
- new_flavor_id,
- ephemeral=self.ephemeral,
- swap=self.swap,
- rxtx=self.rxtx)
- self.addCleanup(self.flavor_clean_up, flavor['id'])
- flag = False
- # Verify flavor is retrieved
- resp, flavors = self.client.list_flavors_with_detail()
- self.assertEqual(resp.status, 200)
- for flavor in flavors:
- if flavor['name'] == flavor_name:
- flag = True
- self.assertTrue(flag)
-
- @test.attr(type='gate')
- def test_create_list_flavor_without_extra_data(self):
- # Create a flavor and ensure it is listed
- # This operation requires the user to have 'admin' role
-
- def verify_flavor_response_extension(flavor):
- # check some extensions for the flavor create/show/detail response
- self.assertEqual(flavor['swap'], 0)
- if test.is_extension_enabled("os-flavor-rxtx", "compute_v3"):
- self.assertEqual(int(flavor['os-flavor-rxtx:rxtx_factor']), 1)
- self.assertEqual(int(flavor['ephemeral']), 0)
- self.assertEqual(flavor['flavor-access:is_public'], True)
-
- flavor_name = data_utils.rand_name(self.flavor_name_prefix)
- new_flavor_id = data_utils.rand_int_id(start=1000)
-
- # Create the flavor
- resp, flavor = self.client.create_flavor(flavor_name,
- self.ram, self.vcpus,
- self.disk,
- new_flavor_id)
- self.addCleanup(self.flavor_clean_up, flavor['id'])
- self.assertEqual(201, resp.status)
- self.assertEqual(flavor['name'], flavor_name)
- self.assertEqual(flavor['ram'], self.ram)
- self.assertEqual(flavor['vcpus'], self.vcpus)
- self.assertEqual(flavor['disk'], self.disk)
- self.assertEqual(int(flavor['id']), new_flavor_id)
- verify_flavor_response_extension(flavor)
-
- # Verify flavor is retrieved
- resp, flavor = self.client.get_flavor_details(new_flavor_id)
- self.assertEqual(resp.status, 200)
- self.assertEqual(flavor['name'], flavor_name)
- verify_flavor_response_extension(flavor)
-
- # Check if flavor is present in list
- resp, flavors = self.user_client.list_flavors_with_detail()
- self.assertEqual(resp.status, 200)
- for flavor in flavors:
- if flavor['name'] == flavor_name:
- verify_flavor_response_extension(flavor)
- flag = True
- self.assertTrue(flag)
-
- @test.attr(type='gate')
- def test_list_non_public_flavor(self):
- # Create a flavor with os-flavor-access:is_public false should
- # be present in list_details.
- # This operation requires the user to have 'admin' role
- flavor_name = data_utils.rand_name(self.flavor_name_prefix)
- new_flavor_id = data_utils.rand_int_id(start=1000)
-
- # Create the flavor
- resp, flavor = self.client.create_flavor(flavor_name,
- self.ram, self.vcpus,
- self.disk,
- new_flavor_id,
- is_public="False")
- self.addCleanup(self.flavor_clean_up, flavor['id'])
- # Verify flavor is retrieved
- flag = False
- resp, flavors = self.client.list_flavors_with_detail()
- self.assertEqual(resp.status, 200)
- for flavor in flavors:
- if flavor['name'] == flavor_name:
- flag = True
- self.assertTrue(flag)
-
- # Verify flavor is not retrieved with other user
- flag = False
- resp, flavors = self.user_client.list_flavors_with_detail()
- self.assertEqual(resp.status, 200)
- for flavor in flavors:
- if flavor['name'] == flavor_name:
- flag = True
- self.assertFalse(flag)
-
- @test.attr(type='gate')
- def test_create_server_with_non_public_flavor(self):
- # Create a flavor with os-flavor-access:is_public false
- flavor_name = data_utils.rand_name(self.flavor_name_prefix)
- new_flavor_id = data_utils.rand_int_id(start=1000)
-
- # Create the flavor
- resp, flavor = self.client.create_flavor(flavor_name,
- self.ram, self.vcpus,
- self.disk,
- new_flavor_id,
- is_public="False")
- self.addCleanup(self.flavor_clean_up, flavor['id'])
- self.assertEqual(201, resp.status)
-
- # Verify flavor is not used by other user
- self.assertRaises(exceptions.BadRequest,
- self.servers_client.create_server,
- 'test', self.image_ref, flavor['id'])
-
- @test.attr(type='gate')
- def test_list_public_flavor_with_other_user(self):
- # Create a Flavor with public access.
- # Try to List/Get flavor with another user
- flavor_name = data_utils.rand_name(self.flavor_name_prefix)
- new_flavor_id = data_utils.rand_int_id(start=1000)
-
- # Create the flavor
- resp, flavor = self.client.create_flavor(flavor_name,
- self.ram, self.vcpus,
- self.disk,
- new_flavor_id,
- is_public="True")
- self.addCleanup(self.flavor_clean_up, flavor['id'])
- flag = False
- self.new_client = self.flavors_client
- # Verify flavor is retrieved with new user
- resp, flavors = self.new_client.list_flavors_with_detail()
- self.assertEqual(resp.status, 200)
- for flavor in flavors:
- if flavor['name'] == flavor_name:
- flag = True
- self.assertTrue(flag)
-
- @test.attr(type='gate')
- def test_is_public_string_variations(self):
- flavor_id_not_public = data_utils.rand_int_id(start=1000)
- flavor_name_not_public = data_utils.rand_name(self.flavor_name_prefix)
- flavor_id_public = data_utils.rand_int_id(start=1000)
- flavor_name_public = data_utils.rand_name(self.flavor_name_prefix)
-
- # Create a non public flavor
- resp, flavor = self.client.create_flavor(flavor_name_not_public,
- self.ram, self.vcpus,
- self.disk,
- flavor_id_not_public,
- is_public="False")
- self.addCleanup(self.flavor_clean_up, flavor['id'])
-
- # Create a public flavor
- resp, flavor = self.client.create_flavor(flavor_name_public,
- self.ram, self.vcpus,
- self.disk,
- flavor_id_public,
- is_public="True")
- self.addCleanup(self.flavor_clean_up, flavor['id'])
-
- def _flavor_lookup(flavors, flavor_name):
- for flavor in flavors:
- if flavor['name'] == flavor_name:
- return flavor
- return None
-
- def _test_string_variations(variations, flavor_name):
- for string in variations:
- params = {'is_public': string}
- r, flavors = self.client.list_flavors_with_detail(params)
- self.assertEqual(r.status, 200)
- flavor = _flavor_lookup(flavors, flavor_name)
- self.assertIsNotNone(flavor)
-
- _test_string_variations(['f', 'false', 'no', '0'],
- flavor_name_not_public)
-
- _test_string_variations(['t', 'true', 'yes', '1'],
- flavor_name_public)
-
- @test.attr(type='gate')
- def test_create_flavor_using_string_ram(self):
- flavor_name = data_utils.rand_name(self.flavor_name_prefix)
- new_flavor_id = data_utils.rand_int_id(start=1000)
-
- ram = "1024"
- resp, flavor = self.client.create_flavor(flavor_name,
- ram, self.vcpus,
- self.disk,
- new_flavor_id)
- self.addCleanup(self.flavor_clean_up, flavor['id'])
- self.assertEqual(201, resp.status)
- self.assertEqual(flavor['name'], flavor_name)
- self.assertEqual(flavor['vcpus'], self.vcpus)
- self.assertEqual(flavor['disk'], self.disk)
- self.assertEqual(flavor['ram'], int(ram))
- self.assertEqual(int(flavor['id']), new_flavor_id)
diff --git a/tempest/api/compute/v3/admin/test_flavors_access.py b/tempest/api/compute/v3/admin/test_flavors_access.py
deleted file mode 100644
index c79e591..0000000
--- a/tempest/api/compute/v3/admin/test_flavors_access.py
+++ /dev/null
@@ -1,95 +0,0 @@
-# Copyright 2013 NEC Corporation.
-# All Rights Reserved.
-#
-# 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.api.compute import base
-from tempest.common.utils import data_utils
-from tempest import test
-
-
-class FlavorsAccessV3Test(base.BaseV3ComputeAdminTest):
-
- """
- Tests Flavor Access API extension.
- Add and remove Flavor Access require admin privileges.
- """
-
- @classmethod
- def resource_setup(cls):
- super(FlavorsAccessV3Test, cls).resource_setup()
-
- cls.client = cls.flavors_admin_client
- admin_client = cls._get_identity_admin_client()
- cls.tenant_id = cls.client.tenant_id
- cls.adm_tenant_id = admin_client.tenant_id
- cls.flavor_name_prefix = 'test_flavor_access_'
- cls.ram = 512
- cls.vcpus = 1
- cls.disk = 10
-
- @test.attr(type='gate')
- def test_flavor_access_list_with_private_flavor(self):
- # Test to list flavor access successfully by querying private flavor
- flavor_name = data_utils.rand_name(self.flavor_name_prefix)
- new_flavor_id = data_utils.rand_int_id(start=1000)
- resp, new_flavor = self.client.create_flavor(flavor_name,
- self.ram, self.vcpus,
- self.disk,
- new_flavor_id,
- is_public='False')
- self.addCleanup(self.client.delete_flavor, new_flavor['id'])
- self.assertEqual(resp.status, 201)
- resp, flavor_access = self.client.list_flavor_access(new_flavor_id)
- self.assertEqual(resp.status, 200)
- self.assertEqual(len(flavor_access), 1, str(flavor_access))
- first_flavor = flavor_access[0]
- self.assertEqual(str(new_flavor_id), str(first_flavor['flavor_id']))
- self.assertEqual(self.adm_tenant_id, first_flavor['tenant_id'])
-
- @test.attr(type='gate')
- def test_flavor_access_add_remove(self):
- # Test to add and remove flavor access to a given tenant.
- flavor_name = data_utils.rand_name(self.flavor_name_prefix)
- new_flavor_id = data_utils.rand_int_id(start=1000)
- resp, new_flavor = self.client.create_flavor(flavor_name,
- self.ram, self.vcpus,
- self.disk,
- new_flavor_id,
- is_public='False')
- self.addCleanup(self.client.delete_flavor, new_flavor['id'])
- # Add flavor access to a tenant.
- resp_body = {
- "tenant_id": str(self.tenant_id),
- "flavor_id": str(new_flavor['id']),
- }
- add_resp, add_body = \
- self.client.add_flavor_access(new_flavor['id'], self.tenant_id)
- self.assertEqual(add_resp.status, 200)
- self.assertIn(resp_body, add_body)
-
- # The flavor is present in list.
- resp, flavors = self.flavors_client.list_flavors_with_detail()
- self.assertEqual(resp.status, 200)
- self.assertIn(new_flavor['id'], map(lambda x: x['id'], flavors))
-
- # Remove flavor access from a tenant.
- remove_resp, remove_body = \
- self.client.remove_flavor_access(new_flavor['id'], self.tenant_id)
- self.assertEqual(remove_resp.status, 200)
- self.assertNotIn(resp_body, remove_body)
-
- # The flavor is not present in list.
- resp, flavors = self.flavors_client.list_flavors_with_detail()
- self.assertEqual(resp.status, 200)
- self.assertNotIn(new_flavor['id'], map(lambda x: x['id'], flavors))
diff --git a/tempest/api/compute/v3/admin/test_flavors_access_negative.py b/tempest/api/compute/v3/admin/test_flavors_access_negative.py
deleted file mode 100644
index 87e8cbf..0000000
--- a/tempest/api/compute/v3/admin/test_flavors_access_negative.py
+++ /dev/null
@@ -1,134 +0,0 @@
-# Copyright 2013 IBM Corporation
-# All Rights Reserved.
-#
-# 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 uuid
-
-from tempest.api.compute import base
-from tempest.common.utils import data_utils
-from tempest import exceptions
-from tempest import test
-
-
-class FlavorsAccessNegativeV3Test(base.BaseV3ComputeAdminTest):
-
- """
- Tests Flavor Access API extension.
- Add and remove Flavor Access require admin privileges.
- """
-
- @classmethod
- def resource_setup(cls):
- super(FlavorsAccessNegativeV3Test, cls).resource_setup()
-
- cls.client = cls.flavors_admin_client
- cls.tenant_id = cls.client.tenant_id
- cls.flavor_name_prefix = 'test_flavor_access_'
- cls.ram = 512
- cls.vcpus = 1
- cls.disk = 10
-
- @test.attr(type=['negative', 'gate'])
- def test_flavor_access_list_with_public_flavor(self):
- # Test to list flavor access with exceptions by querying public flavor
- flavor_name = data_utils.rand_name(self.flavor_name_prefix)
- new_flavor_id = data_utils.rand_int_id(start=1000)
- resp, new_flavor = self.client.create_flavor(flavor_name,
- self.ram, self.vcpus,
- self.disk,
- new_flavor_id,
- is_public='True')
- self.addCleanup(self.client.delete_flavor, new_flavor['id'])
- self.assertEqual(resp.status, 201)
- self.assertRaises(exceptions.NotFound,
- self.client.list_flavor_access,
- new_flavor_id)
-
- @test.attr(type=['negative', 'gate'])
- def test_flavor_non_admin_add(self):
- # Test to add flavor access as a user without admin privileges.
- flavor_name = data_utils.rand_name(self.flavor_name_prefix)
- new_flavor_id = data_utils.rand_int_id(start=1000)
- resp, new_flavor = self.client.create_flavor(flavor_name,
- self.ram, self.vcpus,
- self.disk,
- new_flavor_id,
- is_public='False')
- self.addCleanup(self.client.delete_flavor, new_flavor['id'])
- self.assertRaises(exceptions.Unauthorized,
- self.flavors_client.add_flavor_access,
- new_flavor['id'],
- self.tenant_id)
-
- @test.attr(type=['negative', 'gate'])
- def test_flavor_non_admin_remove(self):
- # Test to remove flavor access as a user without admin privileges.
- flavor_name = data_utils.rand_name(self.flavor_name_prefix)
- new_flavor_id = data_utils.rand_int_id(start=1000)
- resp, new_flavor = self.client.create_flavor(flavor_name,
- self.ram, self.vcpus,
- self.disk,
- new_flavor_id,
- is_public='False')
- self.addCleanup(self.client.delete_flavor, new_flavor['id'])
- # Add flavor access to a tenant.
- self.client.add_flavor_access(new_flavor['id'], self.tenant_id)
- self.addCleanup(self.client.remove_flavor_access,
- new_flavor['id'], self.tenant_id)
- self.assertRaises(exceptions.Unauthorized,
- self.flavors_client.remove_flavor_access,
- new_flavor['id'],
- self.tenant_id)
-
- @test.attr(type=['negative', 'gate'])
- def test_add_flavor_access_duplicate(self):
- # Create a new flavor.
- flavor_name = data_utils.rand_name(self.flavor_name_prefix)
- new_flavor_id = data_utils.rand_int_id(start=1000)
- resp, new_flavor = self.client.create_flavor(flavor_name,
- self.ram, self.vcpus,
- self.disk,
- new_flavor_id,
- is_public='False')
- self.addCleanup(self.client.delete_flavor, new_flavor['id'])
-
- # Add flavor access to a tenant.
- self.client.add_flavor_access(new_flavor['id'], self.tenant_id)
- self.addCleanup(self.client.remove_flavor_access,
- new_flavor['id'], self.tenant_id)
-
- # An exception should be raised when adding flavor access to the same
- # tenant
- self.assertRaises(exceptions.Conflict,
- self.client.add_flavor_access,
- new_flavor['id'],
- self.tenant_id)
-
- @test.attr(type=['negative', 'gate'])
- def test_remove_flavor_access_not_found(self):
- # Create a new flavor.
- flavor_name = data_utils.rand_name(self.flavor_name_prefix)
- new_flavor_id = data_utils.rand_int_id(start=1000)
- resp, new_flavor = self.client.create_flavor(flavor_name,
- self.ram, self.vcpus,
- self.disk,
- new_flavor_id,
- is_public='False')
- self.addCleanup(self.client.delete_flavor, new_flavor['id'])
-
- # An exception should be raised when flavor access is not found
- self.assertRaises(exceptions.NotFound,
- self.client.remove_flavor_access,
- new_flavor['id'],
- str(uuid.uuid4()))
diff --git a/tempest/api/compute/v3/admin/test_flavors_extra_specs.py b/tempest/api/compute/v3/admin/test_flavors_extra_specs.py
deleted file mode 100644
index 24844b1..0000000
--- a/tempest/api/compute/v3/admin/test_flavors_extra_specs.py
+++ /dev/null
@@ -1,120 +0,0 @@
-# Copyright 2012 OpenStack Foundation
-# All Rights Reserved.
-#
-# 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.api.compute import base
-from tempest.common.utils import data_utils
-from tempest import test
-
-
-class FlavorsExtraSpecsV3Test(base.BaseV3ComputeAdminTest):
-
- """
- Tests Flavor Extra Spec API extension.
- SET, UNSET, UPDATE Flavor Extra specs require admin privileges.
- GET Flavor Extra specs can be performed even by without admin privileges.
- """
-
- @classmethod
- def resource_setup(cls):
- super(FlavorsExtraSpecsV3Test, cls).resource_setup()
-
- cls.client = cls.flavors_admin_client
- flavor_name = data_utils.rand_name('test_flavor')
- ram = 512
- vcpus = 1
- disk = 10
- ephemeral = 10
- cls.new_flavor_id = data_utils.rand_int_id(start=1000)
- swap = 1024
- rxtx = 1
- # Create a flavor so as to set/get/unset extra specs
- resp, cls.flavor = cls.client.create_flavor(flavor_name,
- ram, vcpus,
- disk,
- cls.new_flavor_id,
- ephemeral=ephemeral,
- swap=swap, rxtx=rxtx)
-
- @classmethod
- def resource_cleanup(cls):
- resp, body = cls.client.delete_flavor(cls.flavor['id'])
- cls.client.wait_for_resource_deletion(cls.flavor['id'])
- super(FlavorsExtraSpecsV3Test, cls).resource_cleanup()
-
- @test.attr(type='gate')
- def test_flavor_set_get_update_show_unset_keys(self):
- # Test to SET, GET, UPDATE, SHOW, UNSET flavor extra
- # spec as a user with admin privileges.
- # Assigning extra specs values that are to be set
- specs = {"key1": "value1", "key2": "value2"}
- # SET extra specs to the flavor created in setUp
- set_resp, set_body = \
- self.client.set_flavor_extra_spec(self.flavor['id'], specs)
- self.assertEqual(set_resp.status, 201)
- self.assertEqual(set_body, specs)
- # GET extra specs and verify
- get_resp, get_body = \
- self.client.get_flavor_extra_spec(self.flavor['id'])
- self.assertEqual(get_resp.status, 200)
- self.assertEqual(get_body, specs)
-
- # UPDATE the value of the extra specs key1
- update_resp, update_body = \
- self.client.update_flavor_extra_spec(self.flavor['id'],
- "key1",
- key1="value")
- self.assertEqual(update_resp.status, 200)
- self.assertEqual({"key1": "value"}, update_body)
-
- # GET extra specs and verify the value of the key2
- # is the same as before
- get_resp, get_body = \
- self.client.get_flavor_extra_spec(self.flavor['id'])
- self.assertEqual(get_resp.status, 200)
- self.assertEqual(get_body, {"key1": "value", "key2": "value2"})
-
- # UNSET extra specs that were set in this test
- unset_resp, _ = \
- self.client.unset_flavor_extra_spec(self.flavor['id'], "key1")
- self.assertEqual(unset_resp.status, 204)
- unset_resp, _ = \
- self.client.unset_flavor_extra_spec(self.flavor['id'], "key2")
- self.assertEqual(unset_resp.status, 204)
-
- @test.attr(type='gate')
- def test_flavor_non_admin_get_all_keys(self):
- specs = {"key1": "value1", "key2": "value2"}
- set_resp, set_body = self.client.set_flavor_extra_spec(
- self.flavor['id'], specs)
- resp, body = self.flavors_client.get_flavor_extra_spec(
- self.flavor['id'])
- self.assertEqual(resp.status, 200)
-
- for key in specs:
- self.assertEqual(body[key], specs[key])
-
- @test.attr(type='gate')
- def test_flavor_non_admin_get_specific_key(self):
- specs = {"key1": "value1", "key2": "value2"}
- resp, body = self.client.set_flavor_extra_spec(
- self.flavor['id'], specs)
- self.assertEqual(resp.status, 201)
- self.assertEqual(body['key1'], 'value1')
- self.assertIn('key2', body)
- resp, body = self.flavors_client.get_flavor_extra_spec_with_key(
- self.flavor['id'], 'key1')
- self.assertEqual(resp.status, 200)
- self.assertEqual(body['key1'], 'value1')
- self.assertNotIn('key2', body)
diff --git a/tempest/api/compute/v3/admin/test_flavors_extra_specs_negative.py b/tempest/api/compute/v3/admin/test_flavors_extra_specs_negative.py
deleted file mode 100644
index 5fcd7a4..0000000
--- a/tempest/api/compute/v3/admin/test_flavors_extra_specs_negative.py
+++ /dev/null
@@ -1,124 +0,0 @@
-# Copyright 2012 OpenStack Foundation
-# All Rights Reserved.
-# Copyright 2013 IBM Corp.
-#
-# 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.api.compute import base
-from tempest.common.utils import data_utils
-from tempest import exceptions
-from tempest import test
-
-
-class FlavorsExtraSpecsNegativeV3Test(base.BaseV3ComputeAdminTest):
-
- """
- Negative Tests Flavor Extra Spec API extension.
- SET, UNSET, UPDATE Flavor Extra specs require admin privileges.
- """
-
- @classmethod
- def resource_setup(cls):
- super(FlavorsExtraSpecsNegativeV3Test, cls).resource_setup()
-
- cls.client = cls.flavors_admin_client
- flavor_name = data_utils.rand_name('test_flavor')
- ram = 512
- vcpus = 1
- disk = 10
- ephemeral = 10
- cls.new_flavor_id = data_utils.rand_int_id(start=1000)
- swap = 1024
- rxtx = 1
- # Create a flavor
- resp, cls.flavor = cls.client.create_flavor(flavor_name,
- ram, vcpus,
- disk,
- cls.new_flavor_id,
- ephemeral=ephemeral,
- swap=swap, rxtx=rxtx)
-
- @classmethod
- def resource_cleanup(cls):
- resp, body = cls.client.delete_flavor(cls.flavor['id'])
- cls.client.wait_for_resource_deletion(cls.flavor['id'])
- super(FlavorsExtraSpecsNegativeV3Test, cls).resource_cleanup()
-
- @test.attr(type=['negative', 'gate'])
- def test_flavor_non_admin_set_keys(self):
- # Test to SET flavor extra spec as a user without admin privileges.
- specs = {"key1": "value1", "key2": "value2"}
- self.assertRaises(exceptions.Unauthorized,
- self.flavors_client.set_flavor_extra_spec,
- self.flavor['id'],
- specs)
-
- @test.attr(type=['negative', 'gate'])
- def test_flavor_non_admin_update_specific_key(self):
- # non admin user is not allowed to update flavor extra spec
- specs = {"key1": "value1", "key2": "value2"}
- resp, body = self.client.set_flavor_extra_spec(
- self.flavor['id'], specs)
- self.assertEqual(resp.status, 201)
- self.assertEqual(body['key1'], 'value1')
- self.assertRaises(exceptions.Unauthorized,
- self.flavors_client.
- update_flavor_extra_spec,
- self.flavor['id'],
- 'key1',
- key1='value1_new')
-
- @test.attr(type=['negative', 'gate'])
- def test_flavor_non_admin_unset_keys(self):
- specs = {"key1": "value1", "key2": "value2"}
- set_resp, set_body = self.client.set_flavor_extra_spec(
- self.flavor['id'], specs)
-
- self.assertRaises(exceptions.Unauthorized,
- self.flavors_client.unset_flavor_extra_spec,
- self.flavor['id'],
- 'key1')
-
- @test.attr(type=['negative', 'gate'])
- def test_flavor_unset_nonexistent_key(self):
- nonexistent_key = data_utils.rand_name('flavor_key')
- self.assertRaises(exceptions.NotFound,
- self.client.unset_flavor_extra_spec,
- self.flavor['id'],
- nonexistent_key)
-
- @test.attr(type=['negative', 'gate'])
- def test_flavor_get_nonexistent_key(self):
- self.assertRaises(exceptions.NotFound,
- self.flavors_client.get_flavor_extra_spec_with_key,
- self.flavor['id'],
- "nonexistent_key")
-
- @test.attr(type=['negative', 'gate'])
- def test_flavor_update_mismatch_key(self):
- # the key will be updated should be match the key in the body
- self.assertRaises(exceptions.BadRequest,
- self.client.update_flavor_extra_spec,
- self.flavor['id'],
- "key2",
- key1="value")
-
- @test.attr(type=['negative', 'gate'])
- def test_flavor_update_more_key(self):
- # there should be just one item in the request body
- self.assertRaises(exceptions.BadRequest,
- self.client.update_flavor_extra_spec,
- self.flavor['id'],
- "key1",
- key1="value",
- key2="value")
diff --git a/tempest/api/compute/v3/admin/test_flavors_negative.py b/tempest/api/compute/v3/admin/test_flavors_negative.py
deleted file mode 100644
index 426d13e..0000000
--- a/tempest/api/compute/v3/admin/test_flavors_negative.py
+++ /dev/null
@@ -1,333 +0,0 @@
-# Copyright 2012 OpenStack Foundation
-# All Rights Reserved.
-#
-# 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 uuid
-
-from tempest.api.compute import base
-from tempest.common.utils import data_utils
-from tempest import exceptions
-from tempest import test
-
-
-class FlavorsAdminNegativeV3Test(base.BaseV3ComputeAdminTest):
-
- """
- Tests Flavors API Create and Delete that require admin privileges
- """
-
- @classmethod
- def resource_setup(cls):
- super(FlavorsAdminNegativeV3Test, cls).resource_setup()
-
- cls.client = cls.flavors_admin_client
- cls.user_client = cls.flavors_client
- cls.flavor_name_prefix = 'test_flavor_'
- cls.ram = 512
- cls.vcpus = 1
- cls.disk = 10
- cls.ephemeral = 10
- cls.swap = 1024
- cls.rxtx = 2
-
- def flavor_clean_up(self, flavor_id):
- resp, body = self.client.delete_flavor(flavor_id)
- self.assertEqual(resp.status, 204)
- self.client.wait_for_resource_deletion(flavor_id)
-
- @test.attr(type=['negative', 'gate'])
- def test_get_flavor_details_for_deleted_flavor(self):
- # Delete a flavor and ensure it is not listed
- # Create a test flavor
- flavor_name = data_utils.rand_name(self.flavor_name_prefix)
-
- # no need to specify flavor_id, we can get the flavor_id from a
- # response of create_flavor() call.
- resp, flavor = self.client.create_flavor(flavor_name,
- self.ram,
- self.vcpus, self.disk,
- None,
- ephemeral=self.ephemeral,
- swap=self.swap,
- rxtx=self.rxtx)
- # Delete the flavor
- new_flavor_id = flavor['id']
- resp_delete, body = self.client.delete_flavor(new_flavor_id)
- self.assertEqual(201, resp.status)
- self.assertEqual(204, resp_delete.status)
-
- # Deleted flavors can be seen via detailed GET
- resp, flavor = self.client.get_flavor_details(new_flavor_id)
- self.assertEqual(resp.status, 200)
- self.assertEqual(flavor['name'], flavor_name)
-
- # Deleted flavors should not show up in a list however
- resp, flavors = self.client.list_flavors_with_detail()
- self.assertEqual(resp.status, 200)
- flag = True
- for flavor in flavors:
- if flavor['name'] == flavor_name:
- flag = False
- self.assertTrue(flag)
-
- @test.attr(type=['negative', 'gate'])
- def test_invalid_is_public_string(self):
- # the 'is_public' parameter can be 'none/true/false' if it exists
- self.assertRaises(exceptions.BadRequest,
- self.client.list_flavors_with_detail,
- {'is_public': 'invalid'})
-
- @test.attr(type=['negative', 'gate'])
- def test_create_flavor_as_user(self):
- # only admin user can create a flavor
- flavor_name = data_utils.rand_name(self.flavor_name_prefix)
- new_flavor_id = str(uuid.uuid4())
-
- self.assertRaises(exceptions.Unauthorized,
- self.user_client.create_flavor,
- flavor_name, self.ram, self.vcpus, self.disk,
- new_flavor_id, ephemeral=self.ephemeral,
- swap=self.swap, rxtx=self.rxtx)
-
- @test.attr(type=['negative', 'gate'])
- def test_delete_flavor_as_user(self):
- # only admin user can delete a flavor
- self.assertRaises(exceptions.Unauthorized,
- self.user_client.delete_flavor,
- self.flavor_ref_alt)
-
- @test.attr(type=['negative', 'gate'])
- def test_create_flavor_using_invalid_ram(self):
- # the 'ram' attribute must be positive integer
- flavor_name = data_utils.rand_name(self.flavor_name_prefix)
- new_flavor_id = str(uuid.uuid4())
-
- self.assertRaises(exceptions.BadRequest,
- self.client.create_flavor,
- flavor_name, -1, self.vcpus,
- self.disk, new_flavor_id)
-
- @test.attr(type=['negative', 'gate'])
- def test_create_flavor_using_invalid_vcpus(self):
- # the 'vcpu' attribute must be positive integer
- flavor_name = data_utils.rand_name(self.flavor_name_prefix)
- new_flavor_id = str(uuid.uuid4())
-
- self.assertRaises(exceptions.BadRequest,
- self.client.create_flavor,
- flavor_name, self.ram, -1,
- self.disk, new_flavor_id)
-
- @test.attr(type=['negative', 'gate'])
- def test_create_flavor_with_name_length_less_than_1(self):
- # ensure name length >= 1
- new_flavor_id = str(uuid.uuid4())
-
- self.assertRaises(exceptions.BadRequest,
- self.client.create_flavor,
- '',
- self.ram, self.vcpus,
- self.disk,
- new_flavor_id,
- ephemeral=self.ephemeral,
- swap=self.swap,
- rxtx=self.rxtx,
- is_public='False')
-
- @test.attr(type=['negative', 'gate'])
- def test_create_flavor_with_name_length_exceeds_255(self):
- # ensure name do not exceed 255 characters
- new_flavor_name = 'a' * 256
- new_flavor_id = str(uuid.uuid4())
-
- self.assertRaises(exceptions.BadRequest,
- self.client.create_flavor,
- new_flavor_name,
- self.ram, self.vcpus,
- self.disk,
- new_flavor_id,
- ephemeral=self.ephemeral,
- swap=self.swap,
- rxtx=self.rxtx,
- is_public='False')
-
- @test.attr(type=['negative', 'gate'])
- def test_create_flavor_with_invalid_name(self):
- # the regex of flavor_name is '^[\w\.\- ]*$'
- invalid_flavor_name = data_utils.rand_name('invalid-!@#$%-')
- new_flavor_id = str(uuid.uuid4())
-
- self.assertRaises(exceptions.BadRequest,
- self.client.create_flavor,
- invalid_flavor_name,
- self.ram, self.vcpus,
- self.disk,
- new_flavor_id,
- ephemeral=self.ephemeral,
- swap=self.swap,
- rxtx=self.rxtx,
- is_public='False')
-
- @test.attr(type=['negative', 'gate'])
- def test_create_flavor_with_invalid_flavor_id(self):
- # the regex of flavor_id is '^[\w\.\- ]*$', and it cannot contain
- # leading and/or trailing whitespace
- new_flavor_name = data_utils.rand_name(self.flavor_name_prefix)
- invalid_flavor_id = '!@#$%'
-
- self.assertRaises(exceptions.BadRequest,
- self.client.create_flavor,
- new_flavor_name,
- self.ram, self.vcpus,
- self.disk,
- invalid_flavor_id,
- ephemeral=self.ephemeral,
- swap=self.swap,
- rxtx=self.rxtx,
- is_public='False')
-
- @test.attr(type=['negative', 'gate'])
- def test_create_flavor_with_id_length_exceeds_255(self):
- # the length of flavor_id should not exceed 255 characters
- new_flavor_name = data_utils.rand_name(self.flavor_name_prefix)
- invalid_flavor_id = 'a' * 256
-
- self.assertRaises(exceptions.BadRequest,
- self.client.create_flavor,
- new_flavor_name,
- self.ram, self.vcpus,
- self.disk,
- invalid_flavor_id,
- ephemeral=self.ephemeral,
- swap=self.swap,
- rxtx=self.rxtx,
- is_public='False')
-
- @test.attr(type=['negative', 'gate'])
- def test_create_flavor_with_invalid_root_gb(self):
- # root_gb attribute should be non-negative ( >= 0) integer
- new_flavor_name = data_utils.rand_name(self.flavor_name_prefix)
- new_flavor_id = str(uuid.uuid4())
-
- self.assertRaises(exceptions.BadRequest,
- self.client.create_flavor,
- new_flavor_name,
- self.ram, self.vcpus,
- -1,
- new_flavor_id,
- ephemeral=self.ephemeral,
- swap=self.swap,
- rxtx=self.rxtx,
- is_public='False')
-
- @test.attr(type=['negative', 'gate'])
- def test_create_flavor_with_invalid_ephemeral_gb(self):
- # ephemeral_gb attribute should be non-negative ( >= 0) integer
- new_flavor_name = data_utils.rand_name(self.flavor_name_prefix)
- new_flavor_id = str(uuid.uuid4())
-
- self.assertRaises(exceptions.BadRequest,
- self.client.create_flavor,
- new_flavor_name,
- self.ram, self.vcpus,
- self.disk,
- new_flavor_id,
- ephemeral=-1,
- swap=self.swap,
- rxtx=self.rxtx,
- is_public='False')
-
- @test.attr(type=['negative', 'gate'])
- def test_create_flavor_with_invalid_swap(self):
- # swap attribute should be non-negative ( >= 0) integer
- new_flavor_name = data_utils.rand_name(self.flavor_name_prefix)
- new_flavor_id = str(uuid.uuid4())
-
- self.assertRaises(exceptions.BadRequest,
- self.client.create_flavor,
- new_flavor_name,
- self.ram, self.vcpus,
- self.disk,
- new_flavor_id,
- ephemeral=self.ephemeral,
- swap=-1,
- rxtx=self.rxtx,
- is_public='False')
-
- @test.attr(type=['negative', 'gate'])
- def test_create_flavor_with_invalid_rxtx_factor(self):
- # rxtx_factor attribute should be a positive float
- new_flavor_name = data_utils.rand_name(self.flavor_name_prefix)
- new_flavor_id = str(uuid.uuid4())
-
- self.assertRaises(exceptions.BadRequest,
- self.client.create_flavor,
- new_flavor_name,
- self.ram, self.vcpus,
- self.disk,
- new_flavor_id,
- ephemeral=self.ephemeral,
- swap=self.swap,
- rxtx=-1.5,
- is_public='False')
-
- @test.attr(type=['negative', 'gate'])
- def test_create_flavor_with_invalid_is_public(self):
- # is_public attribute should be boolean
- new_flavor_name = data_utils.rand_name(self.flavor_name_prefix)
- new_flavor_id = str(uuid.uuid4())
-
- self.assertRaises(exceptions.BadRequest,
- self.client.create_flavor,
- new_flavor_name,
- self.ram, self.vcpus,
- self.disk,
- new_flavor_id,
- ephemeral=self.ephemeral,
- swap=self.swap,
- rxtx=self.rxtx,
- is_public='Invalid')
-
- @test.attr(type=['negative', 'gate'])
- def test_create_flavor_already_exists(self):
- flavor_name = data_utils.rand_name(self.flavor_name_prefix)
- new_flavor_id = str(uuid.uuid4())
-
- resp, flavor = self.client.create_flavor(flavor_name,
- self.ram, self.vcpus,
- self.disk,
- new_flavor_id,
- ephemeral=self.ephemeral,
- swap=self.swap,
- rxtx=self.rxtx)
- self.assertEqual(201, resp.status)
- self.addCleanup(self.flavor_clean_up, flavor['id'])
-
- self.assertRaises(exceptions.Conflict,
- self.client.create_flavor,
- flavor_name,
- self.ram, self.vcpus,
- self.disk,
- new_flavor_id,
- ephemeral=self.ephemeral,
- swap=self.swap,
- rxtx=self.rxtx)
-
- @test.attr(type=['negative', 'gate'])
- def test_delete_nonexistent_flavor(self):
- nonexistent_flavor_id = str(uuid.uuid4())
-
- self.assertRaises(exceptions.NotFound,
- self.client.delete_flavor,
- nonexistent_flavor_id)
diff --git a/tempest/api/compute/v3/admin/test_hosts.py b/tempest/api/compute/v3/admin/test_hosts.py
deleted file mode 100644
index 898a704..0000000
--- a/tempest/api/compute/v3/admin/test_hosts.py
+++ /dev/null
@@ -1,86 +0,0 @@
-# Copyright 2013 IBM Corp.
-#
-# 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.api.compute import base
-from tempest.common import tempest_fixtures as fixtures
-from tempest import test
-
-
-class HostsAdminV3Test(base.BaseV3ComputeAdminTest):
-
- """
- Tests hosts API using admin privileges.
- """
-
- @classmethod
- def resource_setup(cls):
- super(HostsAdminV3Test, cls).resource_setup()
- cls.client = cls.hosts_admin_client
-
- @test.attr(type='gate')
- def test_list_hosts(self):
- resp, hosts = self.client.list_hosts()
- self.assertEqual(200, resp.status)
- self.assertTrue(len(hosts) >= 2, str(hosts))
-
- @test.attr(type='gate')
- def test_list_hosts_with_zone(self):
- self.useFixture(fixtures.LockFixture('availability_zone'))
- resp, hosts = self.client.list_hosts()
- host = hosts[0]
- zone_name = host['zone']
- params = {'zone': zone_name}
- resp, hosts = self.client.list_hosts(params)
- self.assertEqual(200, resp.status)
- self.assertTrue(len(hosts) >= 1)
- self.assertIn(host, hosts)
-
- @test.attr(type='gate')
- def test_list_hosts_with_a_blank_zone(self):
- # If send the request with a blank zone, the request will be successful
- # and it will return all the hosts list
- params = {'zone': ''}
- resp, hosts = self.client.list_hosts(params)
- self.assertNotEqual(0, len(hosts))
- self.assertEqual(200, resp.status)
-
- @test.attr(type='gate')
- def test_list_hosts_with_nonexistent_zone(self):
- # If send the request with a nonexistent zone, the request will be
- # successful and no hosts will be retured
- params = {'zone': 'xxx'}
- resp, hosts = self.client.list_hosts(params)
- self.assertEqual(0, len(hosts))
- self.assertEqual(200, resp.status)
-
- @test.attr(type='gate')
- def test_show_host_detail(self):
- resp, hosts = self.client.list_hosts()
- self.assertEqual(200, resp.status)
-
- hosts = [host for host in hosts if host['service'] == 'compute']
- self.assertTrue(len(hosts) >= 1)
-
- for host in hosts:
- hostname = host['host_name']
- resp, resources = self.client.show_host_detail(hostname)
- self.assertEqual(200, resp.status)
- self.assertTrue(len(resources) >= 1)
- host_resource = resources[0]['resource']
- self.assertIsNotNone(host_resource)
- self.assertIsNotNone(host_resource['cpu'])
- self.assertIsNotNone(host_resource['disk_gb'])
- self.assertIsNotNone(host_resource['memory_mb'])
- self.assertIsNotNone(host_resource['project'])
- self.assertEqual(hostname, host_resource['host'])
diff --git a/tempest/api/compute/v3/admin/test_hosts_negative.py b/tempest/api/compute/v3/admin/test_hosts_negative.py
deleted file mode 100644
index 2b82baa..0000000
--- a/tempest/api/compute/v3/admin/test_hosts_negative.py
+++ /dev/null
@@ -1,168 +0,0 @@
-# Copyright 2013 Huawei Technologies Co.,LTD.
-#
-# 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.api.compute import base
-from tempest.common.utils import data_utils
-from tempest import exceptions
-from tempest import test
-
-
-class HostsAdminNegativeV3Test(base.BaseV3ComputeAdminTest):
-
- """
- Tests hosts API using admin privileges.
- """
-
- @classmethod
- def resource_setup(cls):
- super(HostsAdminNegativeV3Test, cls).resource_setup()
- cls.client = cls.hosts_admin_client
- cls.non_admin_client = cls.hosts_client
-
- def _get_host_name(self):
- resp, hosts = self.client.list_hosts()
- self.assertEqual(200, resp.status)
- self.assertTrue(len(hosts) >= 1)
- hostname = hosts[0]['host_name']
- return hostname
-
- @test.attr(type=['negative', 'gate'])
- def test_list_hosts_with_non_admin_user(self):
- self.assertRaises(exceptions.Unauthorized,
- self.non_admin_client.list_hosts)
-
- @test.attr(type=['negative', 'gate'])
- def test_show_host_detail_with_nonexistent_hostname(self):
- nonexitent_hostname = data_utils.rand_name('rand_hostname')
- self.assertRaises(exceptions.NotFound,
- self.client.show_host_detail, nonexitent_hostname)
-
- @test.attr(type=['negative', 'gate'])
- def test_show_host_detail_with_non_admin_user(self):
- hostname = self._get_host_name()
-
- self.assertRaises(exceptions.Unauthorized,
- self.non_admin_client.show_host_detail,
- hostname)
-
- @test.attr(type=['negative', 'gate'])
- def test_update_host_with_non_admin_user(self):
- hostname = self._get_host_name()
-
- self.assertRaises(exceptions.Unauthorized,
- self.non_admin_client.update_host,
- hostname,
- status='enable',
- maintenance_mode='enable')
-
- @test.attr(type=['negative', 'gate'])
- def test_update_host_with_extra_param(self):
- # only 'status' and 'maintenance_mode' are the valid params.
- hostname = self._get_host_name()
-
- self.assertRaises(exceptions.BadRequest,
- self.client.update_host,
- hostname,
- status='enable',
- maintenance_mode='enable',
- param='XXX')
-
- @test.attr(type=['negative', 'gate'])
- def test_update_host_with_invalid_status(self):
- # 'status' can only be 'enable' or 'disable'
- hostname = self._get_host_name()
-
- self.assertRaises(exceptions.BadRequest,
- self.client.update_host,
- hostname,
- status='invalid',
- maintenance_mode='enable')
-
- @test.attr(type=['negative', 'gate'])
- def test_update_host_with_invalid_maintenance_mode(self):
- # 'maintenance_mode' can only be 'enable' or 'disable'
- hostname = self._get_host_name()
-
- self.assertRaises(exceptions.BadRequest,
- self.client.update_host,
- hostname,
- status='enable',
- maintenance_mode='invalid')
-
- @test.attr(type=['negative', 'gate'])
- def test_update_host_without_param(self):
- # 'status' or 'maintenance_mode' needed for host update
- hostname = self._get_host_name()
-
- self.assertRaises(exceptions.BadRequest,
- self.client.update_host,
- hostname)
-
- @test.attr(type=['negative', 'gate'])
- def test_update_nonexistent_host(self):
- nonexitent_hostname = data_utils.rand_name('rand_hostname')
-
- self.assertRaises(exceptions.NotFound,
- self.client.update_host,
- nonexitent_hostname,
- status='enable',
- maintenance_mode='enable')
-
- @test.attr(type=['negative', 'gate'])
- def test_startup_nonexistent_host(self):
- nonexitent_hostname = data_utils.rand_name('rand_hostname')
-
- self.assertRaises(exceptions.NotFound,
- self.client.startup_host,
- nonexitent_hostname)
-
- @test.attr(type=['negative', 'gate'])
- def test_startup_host_with_non_admin_user(self):
- hostname = self._get_host_name()
-
- self.assertRaises(exceptions.Unauthorized,
- self.non_admin_client.startup_host,
- hostname)
-
- @test.attr(type=['negative', 'gate'])
- def test_shutdown_nonexistent_host(self):
- nonexitent_hostname = data_utils.rand_name('rand_hostname')
-
- self.assertRaises(exceptions.NotFound,
- self.client.shutdown_host,
- nonexitent_hostname)
-
- @test.attr(type=['negative', 'gate'])
- def test_shutdown_host_with_non_admin_user(self):
- hostname = self._get_host_name()
-
- self.assertRaises(exceptions.Unauthorized,
- self.non_admin_client.shutdown_host,
- hostname)
-
- @test.attr(type=['negative', 'gate'])
- def test_reboot_nonexistent_host(self):
- nonexitent_hostname = data_utils.rand_name('rand_hostname')
-
- self.assertRaises(exceptions.NotFound,
- self.client.reboot_host,
- nonexitent_hostname)
-
- @test.attr(type=['negative', 'gate'])
- def test_reboot_host_with_non_admin_user(self):
- hostname = self._get_host_name()
-
- self.assertRaises(exceptions.Unauthorized,
- self.non_admin_client.reboot_host,
- hostname)
diff --git a/tempest/api/compute/v3/admin/test_hypervisor.py b/tempest/api/compute/v3/admin/test_hypervisor.py
deleted file mode 100644
index 831e20f..0000000
--- a/tempest/api/compute/v3/admin/test_hypervisor.py
+++ /dev/null
@@ -1,117 +0,0 @@
-# Copyright 2013 IBM Corporation
-# All Rights Reserved.
-#
-# 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.api.compute import base
-from tempest import test
-
-
-class HypervisorAdminV3Test(base.BaseV3ComputeAdminTest):
-
- """
- Tests Hypervisors API that require admin privileges
- """
-
- @classmethod
- def resource_setup(cls):
- super(HypervisorAdminV3Test, cls).resource_setup()
- cls.client = cls.hypervisor_admin_client
-
- def _list_hypervisors(self):
- # List of hypervisors
- resp, hypers = self.client.get_hypervisor_list()
- self.assertEqual(200, resp.status)
- return hypers
-
- @test.attr(type='gate')
- def test_get_hypervisor_list(self):
- # List of hypervisor and available hypervisors hostname
- hypers = self._list_hypervisors()
- self.assertTrue(len(hypers) > 0)
-
- @test.attr(type='gate')
- def test_get_hypervisor_list_details(self):
- # Display the details of the all hypervisor
- resp, hypers = self.client.get_hypervisor_list_details()
- self.assertEqual(200, resp.status)
- self.assertTrue(len(hypers) > 0)
-
- @test.attr(type='gate')
- def test_get_hypervisor_show_details(self):
- # Display the details of the specified hypervisor
- hypers = self._list_hypervisors()
- self.assertTrue(len(hypers) > 0)
-
- resp, details = (self.client.
- get_hypervisor_show_details(hypers[0]['id']))
- self.assertEqual(200, resp.status)
- self.assertTrue(len(details) > 0)
- self.assertEqual(details['hypervisor_hostname'],
- hypers[0]['hypervisor_hostname'])
-
- @test.attr(type='gate')
- def test_get_hypervisor_show_servers(self):
- # Show instances about the specific hypervisors
- hypers = self._list_hypervisors()
- self.assertTrue(len(hypers) > 0)
-
- hypervisor_id = hypers[0]['id']
- resp, hypervisors = self.client.get_hypervisor_servers(hypervisor_id)
- self.assertEqual(200, resp.status)
- self.assertTrue(len(hypervisors) > 0)
-
- @test.attr(type='gate')
- def test_get_hypervisor_stats(self):
- # Verify the stats of the all hypervisor
- resp, stats = self.client.get_hypervisor_stats()
- self.assertEqual(200, resp.status)
- self.assertTrue(len(stats) > 0)
-
- @test.attr(type='gate')
- def test_get_hypervisor_uptime(self):
- # Verify that GET shows the specified hypervisor uptime
- hypers = self._list_hypervisors()
-
- # Ironic will register each baremetal node as a 'hypervisor',
- # so the hypervisor list can contain many hypervisors of type
- # 'ironic'. If they are ALL ironic, skip this test since ironic
- # doesn't support hypervisor uptime. Otherwise, remove them
- # from the list of hypervisors to test.
- ironic_only = True
- hypers_without_ironic = []
- for hyper in hypers:
- resp, details = (self.client.
- get_hypervisor_show_details(hypers[0]['id']))
- self.assertEqual(200, resp.status)
- if details['hypervisor_type'] != 'ironic':
- hypers_without_ironic.append(hyper)
- ironic_only = False
-
- if ironic_only:
- raise self.skipException(
- "Ironic does not support hypervisor uptime")
-
- resp, uptime = self.client.get_hypervisor_uptime(
- hypers_without_ironic[0]['id'])
- self.assertEqual(200, resp.status)
- self.assertTrue(len(uptime) > 0)
-
- @test.attr(type='gate')
- def test_search_hypervisor(self):
- hypers = self._list_hypervisors()
- self.assertTrue(len(hypers) > 0)
- resp, hypers = self.client.search_hypervisor(
- hypers[0]['hypervisor_hostname'])
- self.assertEqual(200, resp.status)
- self.assertTrue(len(hypers) > 0)
diff --git a/tempest/api/compute/v3/admin/test_hypervisor_negative.py b/tempest/api/compute/v3/admin/test_hypervisor_negative.py
deleted file mode 100644
index df23b46..0000000
--- a/tempest/api/compute/v3/admin/test_hypervisor_negative.py
+++ /dev/null
@@ -1,136 +0,0 @@
-# Copyright 2013 Huawei Technologies Co.,LTD.
-# All Rights Reserved.
-#
-# 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 uuid
-
-from tempest.api.compute import base
-from tempest.common.utils import data_utils
-from tempest import exceptions
-from tempest import test
-
-
-class HypervisorAdminNegativeV3Test(base.BaseV3ComputeAdminTest):
-
- """
- Tests Hypervisors API that require admin privileges
- """
-
- @classmethod
- def resource_setup(cls):
- super(HypervisorAdminNegativeV3Test, cls).resource_setup()
- cls.client = cls.hypervisor_admin_client
- cls.non_adm_client = cls.hypervisor_client
-
- def _list_hypervisors(self):
- # List of hypervisors
- resp, hypers = self.client.get_hypervisor_list()
- self.assertEqual(200, resp.status)
- return hypers
-
- @test.attr(type=['negative', 'gate'])
- def test_show_nonexistent_hypervisor(self):
- nonexistent_hypervisor_id = str(uuid.uuid4())
-
- self.assertRaises(
- exceptions.NotFound,
- self.client.get_hypervisor_show_details,
- nonexistent_hypervisor_id)
-
- @test.attr(type=['negative', 'gate'])
- def test_show_hypervisor_with_non_admin_user(self):
- hypers = self._list_hypervisors()
- self.assertTrue(len(hypers) > 0)
-
- self.assertRaises(
- exceptions.Unauthorized,
- self.non_adm_client.get_hypervisor_show_details,
- hypers[0]['id'])
-
- @test.attr(type=['negative', 'gate'])
- def test_show_servers_with_non_admin_user(self):
- hypers = self._list_hypervisors()
- self.assertTrue(len(hypers) > 0)
-
- self.assertRaises(
- exceptions.Unauthorized,
- self.non_adm_client.get_hypervisor_servers,
- hypers[0]['id'])
-
- @test.attr(type=['negative', 'gate'])
- def test_show_servers_with_nonexistent_hypervisor(self):
- nonexistent_hypervisor_id = str(uuid.uuid4())
-
- self.assertRaises(
- exceptions.NotFound,
- self.client.get_hypervisor_servers,
- nonexistent_hypervisor_id)
-
- @test.attr(type=['negative', 'gate'])
- def test_get_hypervisor_stats_with_non_admin_user(self):
- self.assertRaises(
- exceptions.Unauthorized,
- self.non_adm_client.get_hypervisor_stats)
-
- @test.attr(type=['negative', 'gate'])
- def test_get_nonexistent_hypervisor_uptime(self):
- nonexistent_hypervisor_id = str(uuid.uuid4())
-
- self.assertRaises(
- exceptions.NotFound,
- self.client.get_hypervisor_uptime,
- nonexistent_hypervisor_id)
-
- @test.attr(type=['negative', 'gate'])
- def test_get_hypervisor_uptime_with_non_admin_user(self):
- hypers = self._list_hypervisors()
- self.assertTrue(len(hypers) > 0)
-
- self.assertRaises(
- exceptions.Unauthorized,
- self.non_adm_client.get_hypervisor_uptime,
- hypers[0]['id'])
-
- @test.attr(type=['negative', 'gate'])
- def test_get_hypervisor_list_with_non_admin_user(self):
- # List of hypervisor and available services with non admin user
- self.assertRaises(
- exceptions.Unauthorized,
- self.non_adm_client.get_hypervisor_list)
-
- @test.attr(type=['negative', 'gate'])
- def test_get_hypervisor_list_details_with_non_admin_user(self):
- # List of hypervisor details and available services with non admin user
- self.assertRaises(
- exceptions.Unauthorized,
- self.non_adm_client.get_hypervisor_list_details)
-
- @test.attr(type=['negative', 'gate'])
- def test_search_nonexistent_hypervisor(self):
- nonexistent_hypervisor_name = data_utils.rand_name('test_hypervisor')
-
- resp, hypers = self.client.search_hypervisor(
- nonexistent_hypervisor_name)
- self.assertEqual(200, resp.status)
- self.assertEqual(0, len(hypers))
-
- @test.attr(type=['negative', 'gate'])
- def test_search_hypervisor_with_non_admin_user(self):
- hypers = self._list_hypervisors()
- self.assertTrue(len(hypers) > 0)
-
- self.assertRaises(
- exceptions.Unauthorized,
- self.non_adm_client.search_hypervisor,
- hypers[0]['hypervisor_hostname'])
diff --git a/tempest/api/compute/v3/admin/test_migrations.py b/tempest/api/compute/v3/admin/test_migrations.py
deleted file mode 100644
index e8bd473..0000000
--- a/tempest/api/compute/v3/admin/test_migrations.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright 2014 NEC Corporation. All rights reserved.
-#
-# 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 testtools
-
-from tempest.api.compute import base
-from tempest import config
-from tempest import test
-
-CONF = config.CONF
-
-
-class MigrationsAdminV3Test(base.BaseV3ComputeAdminTest):
-
- @test.attr(type='gate')
- def test_list_migrations(self):
- # Admin can get the migrations list
- resp, _ = self.migrations_admin_client.list_migrations()
- self.assertEqual(200, resp.status)
-
- @testtools.skipUnless(CONF.compute_feature_enabled.resize,
- 'Resize not available.')
- @test.attr(type='gate')
- def test_list_migrations_in_flavor_resize_situation(self):
- # Admin can get the migrations list which contains the resized server
- resp, server = self.create_test_server(wait_until="ACTIVE")
- server_id = server['id']
-
- resp, _ = self.servers_client.resize(server_id, self.flavor_ref_alt)
- self.assertEqual(202, resp.status)
- self.servers_client.wait_for_server_status(server_id, 'VERIFY_RESIZE')
- self.servers_client.confirm_resize(server_id)
- self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
-
- resp, body = self.migrations_admin_client.list_migrations()
- self.assertEqual(200, resp.status)
-
- instance_uuids = [x['instance_uuid'] for x in body]
- self.assertIn(server_id, instance_uuids)
diff --git a/tempest/api/compute/v3/admin/test_quotas.py b/tempest/api/compute/v3/admin/test_quotas.py
deleted file mode 100644
index 3dad45c..0000000
--- a/tempest/api/compute/v3/admin/test_quotas.py
+++ /dev/null
@@ -1,150 +0,0 @@
-# Copyright 2013 OpenStack Foundation
-# All Rights Reserved.
-#
-# 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.api.compute import base
-from tempest.common.utils import data_utils
-from tempest import config
-from tempest import test
-
-CONF = config.CONF
-
-
-class QuotasAdminV3Test(base.BaseV3ComputeAdminTest):
- force_tenant_isolation = True
-
- @classmethod
- def resource_setup(cls):
- super(QuotasAdminV3Test, cls).resource_setup()
- cls.client = cls.quotas_client
- cls.adm_client = cls.quotas_admin_client
-
- # NOTE(afazekas): these test cases should always create and use a new
- # tenant most of them should be skipped if we can't do that
- cls.demo_tenant_id = cls.client.tenant_id
-
- cls.default_quota_set = set(('metadata_items',
- 'ram', 'floating_ips',
- 'fixed_ips', 'key_pairs',
- 'instances', 'security_group_rules',
- 'cores', 'security_groups'))
-
- @test.attr(type='smoke')
- def test_get_default_quotas(self):
- # Admin can get the default resource quota set for a tenant
- expected_quota_set = self.default_quota_set | set(['id'])
- resp, quota_set = self.adm_client.get_default_quota_set(
- self.demo_tenant_id)
- self.assertEqual(200, resp.status)
- self.assertEqual(sorted(expected_quota_set),
- sorted(quota_set.keys()))
- self.assertEqual(quota_set['id'], self.demo_tenant_id)
-
- @test.attr(type='smoke')
- def test_get_quota_set_detail(self):
- # Admin can get the detail of resource quota set for a tenant
- expected_quota_set = self.default_quota_set | set(['id'])
- expected_detail = ['reserved', 'limit', 'in_use']
- resp, quota_set = self.adm_client.get_quota_set_detail(
- self.demo_tenant_id)
- self.assertEqual(200, resp.status)
- self.assertEqual(sorted(expected_quota_set), sorted(quota_set.keys()))
- self.assertEqual(quota_set['id'], self.demo_tenant_id)
- for quota in quota_set:
- if quota == 'id':
- continue
- self.assertEqual(sorted(expected_detail),
- sorted(quota_set[quota].keys()))
-
- @test.attr(type='gate')
- def test_update_all_quota_resources_for_tenant(self):
- # Admin can update all the resource quota limits for a tenant
- resp, default_quota_set = self.adm_client.get_default_quota_set(
- self.demo_tenant_id)
- new_quota_set = {'metadata_items': 256,
- 'ram': 10240, 'floating_ips': 20, 'fixed_ips': 10,
- 'key_pairs': 200,
- 'instances': 20, 'security_group_rules': 20,
- 'cores': 2, 'security_groups': 20}
- # Update limits for all quota resources
- resp, quota_set = self.adm_client.update_quota_set(
- self.demo_tenant_id,
- force=True,
- **new_quota_set)
-
- default_quota_set.pop('id')
- self.addCleanup(self.adm_client.update_quota_set,
- self.demo_tenant_id, **default_quota_set)
- self.assertEqual(200, resp.status)
- quota_set.pop('id')
- self.assertEqual(new_quota_set, quota_set)
-
- # TODO(afazekas): merge these test cases
- @test.attr(type='gate')
- def test_get_updated_quotas(self):
- # Verify that GET shows the updated quota set of tenant
- tenant_name = data_utils.rand_name('cpu_quota_tenant_')
- tenant_desc = tenant_name + '-desc'
- identity_client = self.os_adm.identity_client
- _, tenant = identity_client.create_tenant(name=tenant_name,
- description=tenant_desc)
- tenant_id = tenant['id']
- self.addCleanup(identity_client.delete_tenant, tenant_id)
-
- self.adm_client.update_quota_set(tenant_id, ram='5120')
- resp, quota_set = self.adm_client.get_quota_set(tenant_id)
- self.assertEqual(200, resp.status)
- self.assertEqual(5120, quota_set['ram'])
-
- # Verify that GET shows the updated quota set of user
- user_name = data_utils.rand_name('cpu_quota_user_')
- password = data_utils.rand_name('password-')
- email = user_name + '@testmail.tm'
- _, user = identity_client.create_user(name=user_name,
- password=password,
- tenant_id=tenant_id,
- email=email)
- user_id = user['id']
- self.addCleanup(identity_client.delete_user, user_id)
-
- self.adm_client.update_quota_set(tenant_id,
- user_id=user_id,
- ram='2048')
- resp, quota_set = self.adm_client.get_quota_set(tenant_id,
- user_id=user_id)
- self.assertEqual(200, resp.status)
- self.assertEqual(2048, quota_set['ram'])
-
- @test.attr(type='gate')
- def test_delete_quota(self):
- # Admin can delete the resource quota set for a tenant
- tenant_name = data_utils.rand_name('cpu_quota_tenant_')
- tenant_desc = tenant_name + '-desc'
- identity_client = self.os_adm.identity_client
- _, tenant = identity_client.create_tenant(name=tenant_name,
- description=tenant_desc)
- tenant_id = tenant['id']
- self.addCleanup(identity_client.delete_tenant, tenant_id)
- resp, quota_set_default = self.adm_client.get_quota_set(tenant_id)
- self.assertEqual(200, resp.status)
- ram_default = quota_set_default['ram']
-
- self.adm_client.update_quota_set(tenant_id, ram='5120')
- self.assertEqual(200, resp.status)
- resp, _ = self.adm_client.delete_quota_set(tenant_id)
- self.assertEqual(204, resp.status)
-
- resp, quota_set_new = self.adm_client.get_quota_set(tenant_id)
- self.assertEqual(200, resp.status)
- self.assertEqual(ram_default, quota_set_new['ram'])
diff --git a/tempest/api/compute/v3/admin/test_quotas_negative.py b/tempest/api/compute/v3/admin/test_quotas_negative.py
deleted file mode 100644
index 86abcab..0000000
--- a/tempest/api/compute/v3/admin/test_quotas_negative.py
+++ /dev/null
@@ -1,89 +0,0 @@
-# Copyright 2013 OpenStack Foundation
-# Copyright 2014 NEC Corporation
-# All Rights Reserved.
-#
-# 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.api.compute import base
-from tempest import exceptions
-from tempest import test
-
-
-class QuotasAdminNegativeV3Test(base.BaseV3ComputeAdminTest):
- force_tenant_isolation = True
-
- @classmethod
- def resource_setup(cls):
- super(QuotasAdminNegativeV3Test, cls).resource_setup()
- cls.client = cls.quotas_client
- cls.adm_client = cls.quotas_admin_client
-
- # NOTE(afazekas): these test cases should always create and use a new
- # tenant most of them should be skipped if we can't do that
- cls.demo_tenant_id = cls.isolated_creds.get_primary_creds().tenant_id
-
- # TODO(afazekas): Add dedicated tenant to the skiped quota tests
- # it can be moved into the setUpClass as well
- @test.attr(type=['negative', 'gate'])
- def test_create_server_when_cpu_quota_is_full(self):
- # Disallow server creation when tenant's vcpu quota is full
- resp, quota_set = self.adm_client.get_quota_set(self.demo_tenant_id)
- default_vcpu_quota = quota_set['cores']
- vcpu_quota = 0 # Set the quota to zero to conserve resources
-
- resp, quota_set = self.adm_client.update_quota_set(self.demo_tenant_id,
- force=True,
- cores=vcpu_quota)
-
- self.addCleanup(self.adm_client.update_quota_set, self.demo_tenant_id,
- cores=default_vcpu_quota)
- self.assertRaises((exceptions.Unauthorized, exceptions.OverLimit),
- self.create_test_server)
-
- @test.attr(type=['negative', 'gate'])
- def test_create_server_when_memory_quota_is_full(self):
- # Disallow server creation when tenant's memory quota is full
- resp, quota_set = self.adm_client.get_quota_set(self.demo_tenant_id)
- default_mem_quota = quota_set['ram']
- mem_quota = 0 # Set the quota to zero to conserve resources
-
- self.adm_client.update_quota_set(self.demo_tenant_id,
- force=True,
- ram=mem_quota)
-
- self.addCleanup(self.adm_client.update_quota_set, self.demo_tenant_id,
- ram=default_mem_quota)
- self.assertRaises((exceptions.Unauthorized, exceptions.OverLimit),
- self.create_test_server)
-
- @test.attr(type=['negative', 'gate'])
- def test_update_quota_normal_user(self):
- self.assertRaises(exceptions.Unauthorized,
- self.client.update_quota_set,
- self.demo_tenant_id,
- ram=0)
-
- @test.attr(type=['negative', 'gate'])
- def test_create_server_when_instances_quota_is_full(self):
- # Once instances quota limit is reached, disallow server creation
- resp, quota_set = self.adm_client.get_quota_set(self.demo_tenant_id)
- default_instances_quota = quota_set['instances']
- instances_quota = 0 # Set quota to zero to disallow server creation
-
- self.adm_client.update_quota_set(self.demo_tenant_id,
- force=True,
- instances=instances_quota)
- self.addCleanup(self.adm_client.update_quota_set, self.demo_tenant_id,
- instances=default_instances_quota)
- self.assertRaises((exceptions.Unauthorized, exceptions.OverLimit),
- self.create_test_server)
diff --git a/tempest/api/compute/v3/admin/test_servers.py b/tempest/api/compute/v3/admin/test_servers.py
deleted file mode 100644
index 36ea7ba..0000000
--- a/tempest/api/compute/v3/admin/test_servers.py
+++ /dev/null
@@ -1,174 +0,0 @@
-# Copyright 2013 IBM Corp.
-#
-# 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.api.compute import base
-from tempest.common.utils import data_utils
-from tempest import test
-
-
-class ServersAdminV3Test(base.BaseV3ComputeAdminTest):
-
- """
- Tests Servers API using admin privileges
- """
-
- _host_key = 'os-extended-server-attributes:host'
-
- @classmethod
- def resource_setup(cls):
- super(ServersAdminV3Test, cls).resource_setup()
- cls.client = cls.servers_admin_client
- cls.non_admin_client = cls.servers_client
- cls.flavors_client = cls.flavors_admin_client
-
- cls.s1_name = data_utils.rand_name('server')
- resp, server = cls.create_test_server(name=cls.s1_name,
- wait_until='ACTIVE')
- cls.s1_id = server['id']
-
- cls.s2_name = data_utils.rand_name('server')
- resp, server = cls.create_test_server(name=cls.s2_name,
- wait_until='ACTIVE')
- cls.s2_id = server['id']
-
- @test.attr(type='gate')
- def test_list_servers_by_admin(self):
- # Listing servers by admin user returns empty list by default
- resp, body = self.client.list_servers_with_detail()
- servers = body['servers']
- self.assertEqual('200', resp['status'])
- self.assertEqual([], servers)
-
- @test.attr(type='gate')
- def test_list_servers_by_admin_with_all_tenants(self):
- # Listing servers by admin user with all tenants parameter
- # Here should be listed all servers
- params = {'all_tenants': ''}
- resp, body = self.client.list_servers_with_detail(params)
- servers = body['servers']
- servers_name = map(lambda x: x['name'], servers)
-
- self.assertIn(self.s1_name, servers_name)
- self.assertIn(self.s2_name, servers_name)
-
- @test.attr(type='gate')
- def test_list_servers_filter_by_existent_host(self):
- # Filter the list of servers by existent host
- name = data_utils.rand_name('server')
- flavor = self.flavor_ref
- image_id = self.image_ref
- resp, test_server = self.client.create_server(
- name, image_id, flavor)
- self.assertEqual('202', resp['status'])
- self.addCleanup(self.client.delete_server, test_server['id'])
- self.client.wait_for_server_status(test_server['id'], 'ACTIVE')
- resp, server = self.client.get_server(test_server['id'])
- self.assertEqual(server['status'], 'ACTIVE')
- hostname = server[self._host_key]
- params = {'host': hostname}
- resp, body = self.client.list_servers(params)
- self.assertEqual('200', resp['status'])
- servers = body['servers']
- nonexistent_params = {'host': 'nonexistent_host'}
- resp, nonexistent_body = self.client.list_servers(
- nonexistent_params)
- self.assertEqual('200', resp['status'])
- nonexistent_servers = nonexistent_body['servers']
- self.assertIn(test_server['id'], map(lambda x: x['id'], servers))
- self.assertNotIn(test_server['id'],
- map(lambda x: x['id'], nonexistent_servers))
-
- @test.attr(type='gate')
- def test_reset_state_server(self):
- # Reset server's state to 'error'
- resp, server = self.client.reset_state(self.s1_id)
- self.assertEqual(202, resp.status)
-
- # Verify server's state
- resp, server = self.client.get_server(self.s1_id)
- self.assertEqual(server['status'], 'ERROR')
-
- # Reset server's state to 'active'
- resp, server = self.client.reset_state(self.s1_id, state='active')
- self.assertEqual(202, resp.status)
-
- # Verify server's state
- resp, server = self.client.get_server(self.s1_id)
- self.assertEqual(server['status'], 'ACTIVE')
-
- @test.attr(type='gate')
- @test.skip_because(bug="1240043")
- def test_get_server_diagnostics_by_admin(self):
- # Retrieve server diagnostics by admin user
- resp, diagnostic = self.client.get_server_diagnostics(self.s1_id)
- self.assertEqual(200, resp.status)
- basic_attrs = ['rx_packets', 'rx_errors', 'rx_drop',
- 'tx_packets', 'tx_errors', 'tx_drop',
- 'read_req', 'write_req', 'cpu', 'memory']
- for key in basic_attrs:
- self.assertIn(key, str(diagnostic.keys()))
-
- @test.attr(type='gate')
- def test_list_servers_filter_by_error_status(self):
- # Filter the list of servers by server error status
- params = {'status': 'error'}
- resp, server = self.client.reset_state(self.s1_id, state='error')
- resp, body = self.non_admin_client.list_servers(params)
- # Reset server's state to 'active'
- resp, server = self.client.reset_state(self.s1_id, state='active')
- # Verify server's state
- resp, server = self.client.get_server(self.s1_id)
- self.assertEqual(server['status'], 'ACTIVE')
- servers = body['servers']
- # Verify error server in list result
- self.assertIn(self.s1_id, map(lambda x: x['id'], servers))
- self.assertNotIn(self.s2_id, map(lambda x: x['id'], servers))
-
- @test.attr(type='gate')
- def test_rebuild_server_in_error_state(self):
- # The server in error state should be rebuilt using the provided
- # image and changed to ACTIVE state
-
- # resetting vm state require admin privilege
- resp, server = self.client.reset_state(self.s1_id, state='error')
- self.assertEqual(202, resp.status)
- resp, rebuilt_server = self.non_admin_client.rebuild(
- self.s1_id, self.image_ref_alt)
- self.addCleanup(self.non_admin_client.wait_for_server_status,
- self.s1_id, 'ACTIVE')
- self.addCleanup(self.non_admin_client.rebuild, self.s1_id,
- self.image_ref)
-
- # Verify the properties in the initial response are correct
- self.assertEqual(self.s1_id, rebuilt_server['id'])
- rebuilt_image_id = rebuilt_server['image']['id']
- self.assertEqual(self.image_ref_alt, rebuilt_image_id)
- self.assertEqual(self.flavor_ref, rebuilt_server['flavor']['id'])
- self.non_admin_client.wait_for_server_status(rebuilt_server['id'],
- 'ACTIVE',
- raise_on_error=False)
- # Verify the server properties after rebuilding
- resp, server = self.non_admin_client.get_server(rebuilt_server['id'])
- rebuilt_image_id = server['image']['id']
- self.assertEqual(self.image_ref_alt, rebuilt_image_id)
-
- @test.attr(type='gate')
- def test_reset_network_inject_network_info(self):
- resp, server = self.create_test_server(wait_until='ACTIVE')
- # Reset Network of a Server
- resp, server_body = self.client.reset_network(server['id'])
- self.assertEqual(202, resp.status)
- # Inject the Network Info into Server
- resp, server = self.client.inject_network_info(server['id'])
- self.assertEqual(202, resp.status)
diff --git a/tempest/api/compute/v3/admin/test_servers_negative.py b/tempest/api/compute/v3/admin/test_servers_negative.py
deleted file mode 100644
index f561ed3..0000000
--- a/tempest/api/compute/v3/admin/test_servers_negative.py
+++ /dev/null
@@ -1,144 +0,0 @@
-# Copyright 2013 Huawei Technologies Co.,LTD.
-#
-# 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 uuid
-
-import testtools
-
-from tempest.api.compute import base
-from tempest.common import tempest_fixtures as fixtures
-from tempest.common.utils import data_utils
-from tempest import config
-from tempest import exceptions
-from tempest import test
-
-CONF = config.CONF
-
-
-class ServersAdminNegativeV3Test(base.BaseV3ComputeAdminTest):
-
- """
- Tests Servers API using admin privileges
- """
-
- @classmethod
- def resource_setup(cls):
- super(ServersAdminNegativeV3Test, cls).resource_setup()
- cls.client = cls.servers_admin_client
- cls.non_adm_client = cls.servers_client
- cls.flavors_client = cls.flavors_admin_client
- cls.tenant_id = cls.client.tenant_id
-
- cls.s1_name = data_utils.rand_name('server')
- resp, server = cls.create_test_server(name=cls.s1_name,
- wait_until='ACTIVE')
- cls.s1_id = server['id']
-
- def _get_unused_flavor_id(self):
- flavor_id = data_utils.rand_int_id(start=1000)
- while True:
- try:
- resp, body = self.flavors_client.get_flavor_details(flavor_id)
- except exceptions.NotFound:
- break
- flavor_id = data_utils.rand_int_id(start=1000)
- return flavor_id
-
- @test.attr(type=['negative', 'gate'])
- def test_resize_server_using_overlimit_ram(self):
- # NOTE(mriedem): Avoid conflicts with os-quota-class-sets tests.
- self.useFixture(fixtures.LockFixture('compute_quotas'))
- flavor_name = data_utils.rand_name("flavor-")
- flavor_id = self._get_unused_flavor_id()
- resp, quota_set = self.quotas_client.get_default_quota_set(
- self.tenant_id)
- ram = int(quota_set['ram']) + 1
- vcpus = 8
- disk = 10
- resp, flavor_ref = self.flavors_client.create_flavor(flavor_name,
- ram, vcpus, disk,
- flavor_id)
- self.addCleanup(self.flavors_client.delete_flavor, flavor_id)
- self.assertRaises((exceptions.Unauthorized, exceptions.OverLimit),
- self.client.resize,
- self.servers[0]['id'],
- flavor_ref['id'])
-
- @test.attr(type=['negative', 'gate'])
- def test_resize_server_using_overlimit_vcpus(self):
- # NOTE(mriedem): Avoid conflicts with os-quota-class-sets tests.
- self.useFixture(fixtures.LockFixture('compute_quotas'))
- flavor_name = data_utils.rand_name("flavor-")
- flavor_id = self._get_unused_flavor_id()
- ram = 512
- resp, quota_set = self.quotas_client.get_default_quota_set(
- self.tenant_id)
- vcpus = int(quota_set['cores']) + 1
- disk = 10
- resp, flavor_ref = self.flavors_client.create_flavor(flavor_name,
- ram, vcpus, disk,
- flavor_id)
- self.addCleanup(self.flavors_client.delete_flavor, flavor_id)
- self.assertRaises((exceptions.Unauthorized, exceptions.OverLimit),
- self.client.resize,
- self.servers[0]['id'],
- flavor_ref['id'])
-
- @test.attr(type=['negative', 'gate'])
- def test_reset_state_server_invalid_state(self):
- self.assertRaises(exceptions.BadRequest,
- self.client.reset_state, self.s1_id,
- state='invalid')
-
- @test.attr(type=['negative', 'gate'])
- def test_reset_state_server_invalid_type(self):
- self.assertRaises(exceptions.BadRequest,
- self.client.reset_state, self.s1_id,
- state=1)
-
- @test.attr(type=['negative', 'gate'])
- def test_reset_state_server_nonexistent_server(self):
- self.assertRaises(exceptions.NotFound,
- self.client.reset_state, '999')
-
- @test.attr(type=['negative', 'gate'])
- def test_get_server_diagnostics_by_non_admin(self):
- # Non-admin user can not view server diagnostics according to policy
- self.assertRaises(exceptions.Unauthorized,
- self.non_adm_client.get_server_diagnostics,
- self.s1_id)
-
- @test.attr(type=['negative', 'gate'])
- def test_migrate_non_existent_server(self):
- # migrate a non existent server
- self.assertRaises(exceptions.NotFound,
- self.client.migrate_server,
- str(uuid.uuid4()))
-
- @testtools.skipUnless(CONF.compute_feature_enabled.suspend,
- 'Suspend is not available.')
- @test.attr(type=['negative', 'gate'])
- def test_migrate_server_invalid_state(self):
- # create server.
- resp, server = self.create_test_server(wait_until='ACTIVE')
- self.assertEqual(202, resp.status)
- server_id = server['id']
- # suspend the server.
- resp, _ = self.client.suspend_server(server_id)
- self.assertEqual(202, resp.status)
- self.client.wait_for_server_status(server_id, 'SUSPENDED')
- # migrate an suspended server should fail
- self.assertRaises(exceptions.Conflict,
- self.client.migrate_server,
- server_id)
diff --git a/tempest/api/compute/v3/admin/test_services.py b/tempest/api/compute/v3/admin/test_services.py
deleted file mode 100644
index f1c3b9a..0000000
--- a/tempest/api/compute/v3/admin/test_services.py
+++ /dev/null
@@ -1,79 +0,0 @@
-# Copyright 2013 NEC Corporation
-# Copyright 2013 IBM Corp.
-# All Rights Reserved.
-#
-# 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.api.compute import base
-from tempest import test
-
-
-class ServicesAdminV3Test(base.BaseV3ComputeAdminTest):
-
- """
- Tests Services API. List and Enable/Disable require admin privileges.
- """
-
- @classmethod
- def resource_setup(cls):
- super(ServicesAdminV3Test, cls).resource_setup()
- cls.client = cls.services_admin_client
-
- @test.attr(type='gate')
- def test_list_services(self):
- resp, services = self.client.list_services()
- self.assertEqual(200, resp.status)
- self.assertNotEqual(0, len(services))
-
- @test.attr(type='gate')
- def test_get_service_by_service_binary_name(self):
- binary_name = 'nova-compute'
- params = {'binary': binary_name}
- resp, services = self.client.list_services(params)
- self.assertEqual(200, resp.status)
- self.assertNotEqual(0, len(services))
- for service in services:
- self.assertEqual(binary_name, service['binary'])
-
- @test.attr(type='gate')
- def test_get_service_by_host_name(self):
- resp, services = self.client.list_services()
- self.assertEqual(200, resp.status)
- host_name = services[0]['host']
- services_on_host = [service for service in services if
- service['host'] == host_name]
- params = {'host': host_name}
-
- resp, services = self.client.list_services(params)
-
- # we could have a periodic job checkin between the 2 service
- # lookups, so only compare binary lists.
- s1 = map(lambda x: x['binary'], services)
- s2 = map(lambda x: x['binary'], services_on_host)
-
- # sort the lists before comparing, to take out dependency
- # on order.
- self.assertEqual(sorted(s1), sorted(s2))
-
- @test.attr(type='gate')
- def test_get_service_by_service_and_host_name(self):
- resp, services = self.client.list_services()
- host_name = services[0]['host']
- binary_name = services[0]['binary']
- params = {'host': host_name, 'binary': binary_name}
-
- resp, services = self.client.list_services(params)
- self.assertEqual(200, resp.status)
- self.assertEqual(1, len(services))
- self.assertEqual(host_name, services[0]['host'])
- self.assertEqual(binary_name, services[0]['binary'])
diff --git a/tempest/api/compute/v3/admin/test_services_negative.py b/tempest/api/compute/v3/admin/test_services_negative.py
deleted file mode 100644
index 1f9f2b1..0000000
--- a/tempest/api/compute/v3/admin/test_services_negative.py
+++ /dev/null
@@ -1,64 +0,0 @@
-# Copyright 2013 NEC Corporation
-# Copyright 2013 IBM Corp.
-# All Rights Reserved.
-#
-# 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.api.compute import base
-from tempest import exceptions
-from tempest import test
-
-
-class ServicesAdminNegativeV3Test(base.BaseV3ComputeAdminTest):
-
- """
- Tests Services API. List and Enable/Disable require admin privileges.
- """
-
- @classmethod
- def resource_setup(cls):
- super(ServicesAdminNegativeV3Test, cls).resource_setup()
- cls.client = cls.services_admin_client
- cls.non_admin_client = cls.services_client
-
- @test.attr(type=['negative', 'gate'])
- def test_list_services_with_non_admin_user(self):
- self.assertRaises(exceptions.Unauthorized,
- self.non_admin_client.list_services)
-
- @test.attr(type=['negative', 'gate'])
- def test_get_service_by_invalid_params(self):
- # return all services if send the request with invalid parameter
- resp, services = self.client.list_services()
- params = {'xxx': 'nova-compute'}
- resp, services_xxx = self.client.list_services(params)
- self.assertEqual(200, resp.status)
- self.assertEqual(len(services), len(services_xxx))
-
- @test.attr(type=['negative', 'gate'])
- def test_get_service_by_invalid_service_and_valid_host(self):
- resp, services = self.client.list_services()
- host_name = services[0]['host']
- params = {'host': host_name, 'binary': 'xxx'}
- resp, services = self.client.list_services(params)
- self.assertEqual(200, resp.status)
- self.assertEqual(0, len(services))
-
- @test.attr(type=['negative', 'gate'])
- def test_get_service_with_valid_service_and_invalid_host(self):
- resp, services = self.client.list_services()
- binary_name = services[0]['binary']
- params = {'host': 'xxx', 'binary': binary_name}
- resp, services = self.client.list_services(params)
- self.assertEqual(200, resp.status)
- self.assertEqual(0, len(services))
diff --git a/tempest/api/compute/v3/flavors/__init__.py b/tempest/api/compute/v3/flavors/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/api/compute/v3/flavors/__init__.py
+++ /dev/null
diff --git a/tempest/api/compute/v3/flavors/test_flavors_negative.py b/tempest/api/compute/v3/flavors/test_flavors_negative.py
deleted file mode 100644
index 2dd7b71..0000000
--- a/tempest/api/compute/v3/flavors/test_flavors_negative.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# Copyright 2013 OpenStack Foundation
-# All Rights Reserved.
-#
-# 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.api.compute import base
-from tempest.api_schema.request.compute.v3 import flavors
-from tempest import test
-
-
-load_tests = test.NegativeAutoTest.load_tests
-
-
-@test.SimpleNegativeAutoTest
-class FlavorsListNegativeV3Test(base.BaseV3ComputeTest,
- test.NegativeAutoTest):
- _service = 'computev3'
- _schema = flavors.flavor_list
-
-
-@test.SimpleNegativeAutoTest
-class FlavorDetailsNegativeV3Test(base.BaseV3ComputeTest,
- test.NegativeAutoTest):
- _service = 'computev3'
- _schema = flavors.flavors_details
-
- @classmethod
- def resource_setup(cls):
- super(FlavorDetailsNegativeV3Test, cls).resource_setup()
- cls.set_resource("flavor", cls.flavor_ref)
diff --git a/tempest/api/compute/v3/images/__init__.py b/tempest/api/compute/v3/images/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/api/compute/v3/images/__init__.py
+++ /dev/null
diff --git a/tempest/api/compute/v3/images/test_images.py b/tempest/api/compute/v3/images/test_images.py
deleted file mode 100644
index a234a22..0000000
--- a/tempest/api/compute/v3/images/test_images.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# Copyright 2012 OpenStack Foundation
-#
-# 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.api.compute import base
-from tempest.common.utils import data_utils
-from tempest import config
-from tempest import test
-
-CONF = config.CONF
-
-
-class ImagesV3Test(base.BaseV3ComputeTest):
-
- @classmethod
- def resource_setup(cls):
- super(ImagesV3Test, cls).resource_setup()
- if not CONF.service_available.glance:
- skip_msg = ("%s skipped as glance is not available" % cls.__name__)
- raise cls.skipException(skip_msg)
- cls.client = cls.images_client
-
- @test.attr(type='gate')
- def test_create_image_from_stopped_server(self):
- resp, server = self.create_test_server(wait_until='ACTIVE')
- self.servers_client.stop(server['id'])
- self.servers_client.wait_for_server_status(server['id'],
- 'SHUTOFF')
- self.addCleanup(self.servers_client.delete_server, server['id'])
- snapshot_name = data_utils.rand_name('test-snap-')
- resp, image = self.create_image_from_server(server['id'],
- name=snapshot_name,
- wait_until='active')
- self.addCleanup(self.client.delete_image, image['id'])
- self.assertEqual(snapshot_name, image['name'])
-
- @test.attr(type='gate')
- def test_delete_queued_image(self):
- snapshot_name = data_utils.rand_name('test-snap-')
- resp, server = self.create_test_server(wait_until='ACTIVE')
- self.addCleanup(self.servers_client.delete_server, server['id'])
- resp, image = self.create_image_from_server(server['id'],
- name=snapshot_name,
- wait_until='queued')
- resp, body = self.client.delete_image(image['id'])
- self.assertEqual('200', resp['status'])
diff --git a/tempest/api/compute/v3/images/test_images_negative.py b/tempest/api/compute/v3/images/test_images_negative.py
deleted file mode 100644
index 83e9436..0000000
--- a/tempest/api/compute/v3/images/test_images_negative.py
+++ /dev/null
@@ -1,82 +0,0 @@
-# Copyright 2014 NEC Corporation. All rights reserved.
-#
-# 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.api.compute import base
-from tempest.common.utils import data_utils
-from tempest import config
-from tempest import exceptions
-from tempest import test
-
-CONF = config.CONF
-
-
-class ImagesNegativeV3Test(base.BaseV3ComputeTest):
-
- @classmethod
- def resource_setup(cls):
- super(ImagesNegativeV3Test, cls).resource_setup()
- if not CONF.service_available.glance:
- skip_msg = ("%s skipped as glance is not available" % cls.__name__)
- raise cls.skipException(skip_msg)
- cls.client = cls.images_client
-
- def __create_image__(self, server_id, name, meta=None):
- resp, body = self.servers_client.create_image(server_id, name, meta)
- image_id = data_utils.parse_image_id(resp['location'])
- self.addCleanup(self.client.delete_image, image_id)
- self.client.wait_for_image_status(image_id, 'active')
- return resp, body
-
- @test.attr(type=['negative', 'gate'])
- def test_create_image_from_deleted_server(self):
- # An image should not be created if the server instance is removed
- resp, server = self.create_test_server(wait_until='ACTIVE')
-
- # Delete server before trying to create server
- self.servers_client.delete_server(server['id'])
- self.servers_client.wait_for_server_termination(server['id'])
- # Create a new image after server is deleted
- name = data_utils.rand_name('image')
- meta = {'image_type': 'test'}
- self.assertRaises(exceptions.NotFound,
- self.__create_image__,
- server['id'], name, meta)
-
- @test.attr(type=['negative', 'gate'])
- def test_create_image_from_nonexistent_server(self):
- # An image should not be created with invalid server id
- # Create a new image with invalid server id
- nonexistent_server_id = data_utils.rand_uuid()
- name = data_utils.rand_name('image')
- meta = {'image_type': 'test'}
- self.assertRaises(exceptions.NotFound, self.__create_image__,
- nonexistent_server_id, name, meta)
-
- @test.attr(type=['negative', 'gate'])
- def test_create_image_specify_uuid_35_characters_or_less(self):
- # Return an error if Image ID passed is 35 characters or less
- snapshot_name = data_utils.rand_name('test-snap-')
- test_uuid = ('a' * 35)
- self.assertRaises(exceptions.NotFound,
- self.servers_client.create_image,
- test_uuid, snapshot_name)
-
- @test.attr(type=['negative', 'gate'])
- def test_create_image_specify_uuid_37_characters_or_more(self):
- # Return an error if Image ID passed is 37 characters or more
- snapshot_name = data_utils.rand_name('test-snap-')
- test_uuid = ('a' * 37)
- self.assertRaises(exceptions.NotFound,
- self.servers_client.create_image,
- test_uuid, snapshot_name)
diff --git a/tempest/api/compute/v3/images/test_images_oneserver.py b/tempest/api/compute/v3/images/test_images_oneserver.py
deleted file mode 100644
index 87e730c..0000000
--- a/tempest/api/compute/v3/images/test_images_oneserver.py
+++ /dev/null
@@ -1,105 +0,0 @@
-# Copyright 2012 OpenStack Foundation
-# All Rights Reserved.
-#
-# 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.api.compute import base
-from tempest.common.utils import data_utils
-from tempest import config
-from tempest.openstack.common import log as logging
-from tempest import test
-
-CONF = config.CONF
-LOG = logging.getLogger(__name__)
-
-
-class ImagesOneServerV3Test(base.BaseV3ComputeTest):
-
- def setUp(self):
- # NOTE(afazekas): Normally we use the same server with all test cases,
- # but if it has an issue, we build a new one
- super(ImagesOneServerV3Test, self).setUp()
- # Check if the server is in a clean state after test
- try:
- self.servers_client.wait_for_server_status(self.server_id,
- 'ACTIVE')
- except Exception:
- LOG.exception('server %s timed out to become ACTIVE. rebuilding'
- % self.server_id)
- # Rebuild server if cannot reach the ACTIVE state
- # Usually it means the server had a serious accident
- self.__class__.server_id = self.rebuild_server(self.server_id)
-
- def tearDown(self):
- """Terminate test instances created after a test is executed."""
- self.server_check_teardown()
- super(ImagesOneServerV3Test, self).tearDown()
-
- @classmethod
- def resource_setup(cls):
- super(ImagesOneServerV3Test, cls).resource_setup()
- cls.client = cls.images_client
- if not CONF.service_available.glance:
- skip_msg = ("%s skipped as glance is not available" % cls.__name__)
- raise cls.skipException(skip_msg)
-
- resp, server = cls.create_test_server(wait_until='ACTIVE')
- cls.server_id = server['id']
-
- def _get_default_flavor_disk_size(self, flavor_id):
- resp, flavor = self.flavors_client.get_flavor_details(flavor_id)
- return flavor['disk']
-
- @test.attr(type='smoke')
- def test_create_delete_image(self):
-
- # Create a new image
- name = data_utils.rand_name('image')
- meta = {'image_type': 'test'}
- resp, body = self.servers_client.create_image(self.server_id,
- name, meta)
- self.assertEqual(202, resp.status)
- image_id = data_utils.parse_image_id(resp['location'])
- self.client.wait_for_image_status(image_id, 'active')
-
- # Verify the image was created correctly
- resp, image = self.client.get_image_meta(image_id)
- self.assertEqual(name, image['name'])
- self.assertEqual('test', image['properties']['image_type'])
-
- resp, original_image = self.client.get_image_meta(self.image_ref)
-
- # Verify minRAM is the same as the original image
- self.assertEqual(image['min_ram'], original_image['min_ram'])
-
- # Verify minDisk is the same as the original image or the flavor size
- flavor_disk_size = self._get_default_flavor_disk_size(self.flavor_ref)
- self.assertIn(str(image['min_disk']),
- (str(original_image['min_disk']), str(flavor_disk_size)))
-
- # Verify the image was deleted correctly
- resp, body = self.client.delete_image(image_id)
- self.assertEqual('200', resp['status'])
- self.client.wait_for_resource_deletion(image_id)
-
- @test.attr(type=['gate'])
- def test_create_image_specify_multibyte_character_image_name(self):
- # prefix character is:
- # http://www.fileformat.info/info/unicode/char/1F4A9/index.htm
- utf8_name = data_utils.rand_name(u'\xF0\x9F\x92\xA9')
- resp, body = self.servers_client.create_image(self.server_id,
- utf8_name)
- image_id = data_utils.parse_image_id(resp['location'])
- self.addCleanup(self.client.delete_image, image_id)
- self.assertEqual('202', resp['status'])
diff --git a/tempest/api/compute/v3/images/test_images_oneserver_negative.py b/tempest/api/compute/v3/images/test_images_oneserver_negative.py
deleted file mode 100644
index 5892cd7..0000000
--- a/tempest/api/compute/v3/images/test_images_oneserver_negative.py
+++ /dev/null
@@ -1,145 +0,0 @@
-# Copyright 2012 OpenStack Foundation
-# Copyright 2013 IBM Corp.
-# All Rights Reserved.
-#
-# 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.api.compute import base
-from tempest.common.utils import data_utils
-from tempest import config
-from tempest import exceptions
-from tempest.openstack.common import log as logging
-from tempest import test
-
-CONF = config.CONF
-
-LOG = logging.getLogger(__name__)
-
-
-class ImagesOneServerNegativeV3Test(base.BaseV3ComputeTest):
-
- def tearDown(self):
- """Terminate test instances created after a test is executed."""
- for image_id in self.image_ids:
- self.client.delete_image(image_id)
- self.image_ids.remove(image_id)
- self.server_check_teardown()
- super(ImagesOneServerNegativeV3Test, self).tearDown()
-
- def setUp(self):
- # NOTE(afazekas): Normally we use the same server with all test cases,
- # but if it has an issue, we build a new one
- super(ImagesOneServerNegativeV3Test, self).setUp()
- # Check if the server is in a clean state after test
- try:
- self.servers_client.wait_for_server_status(self.server_id,
- 'ACTIVE')
- except Exception:
- LOG.exception('server %s timed out to become ACTIVE. rebuilding'
- % self.server_id)
- # Rebuild server if cannot reach the ACTIVE state
- # Usually it means the server had a serious accident
- self._reset_server()
-
- def _reset_server(self):
- self.__class__.server_id = self.rebuild_server(self.server_id)
-
- @classmethod
- def resource_setup(cls):
- super(ImagesOneServerNegativeV3Test, cls).resource_setup()
- cls.client = cls.images_client
- if not CONF.service_available.glance:
- skip_msg = ("%s skipped as glance is not available" % cls.__name__)
- raise cls.skipException(skip_msg)
-
- resp, server = cls.create_test_server(wait_until='ACTIVE')
- cls.server_id = server['id']
-
- cls.image_ids = []
-
- @test.skip_because(bug="1006725")
- @test.attr(type=['negative', 'gate'])
- def test_create_image_specify_multibyte_character_image_name(self):
- # invalid multibyte sequence from:
- # http://stackoverflow.com/questions/1301402/
- # example-invalid-utf8-string
- invalid_name = data_utils.rand_name(u'\xc3\x28')
- self.assertRaises(exceptions.BadRequest,
- self.servers_client.create_image,
- self.server_id,
- invalid_name)
-
- @test.attr(type=['negative', 'gate'])
- def test_create_image_specify_invalid_metadata(self):
- # Return an error when creating image with invalid metadata
- snapshot_name = data_utils.rand_name('test-snap-')
- meta = {'': ''}
- self.assertRaises(exceptions.BadRequest,
- self.servers_client.create_image,
- self.server_id, snapshot_name, meta)
-
- @test.attr(type=['negative', 'gate'])
- def test_create_image_specify_metadata_over_limits(self):
- # Return an error when creating image with meta data over 256 chars
- snapshot_name = data_utils.rand_name('test-snap-')
- meta = {'a' * 260: 'b' * 260}
- self.assertRaises(exceptions.BadRequest,
- self.servers_client.create_image,
- self.server_id, snapshot_name, meta)
-
- @test.attr(type=['negative', 'gate'])
- def test_create_second_image_when_first_image_is_being_saved(self):
- # Disallow creating another image when first image is being saved
-
- # Create first snapshot
- snapshot_name = data_utils.rand_name('test-snap-')
- resp, body = self.servers_client.create_image(self.server_id,
- snapshot_name)
- self.assertEqual(202, resp.status)
- image_id = data_utils.parse_image_id(resp['location'])
- self.image_ids.append(image_id)
- self.addCleanup(self._reset_server)
-
- # Create second snapshot
- alt_snapshot_name = data_utils.rand_name('test-snap-')
- self.assertRaises(exceptions.Conflict,
- self.servers_client.create_image,
- self.server_id, alt_snapshot_name)
-
- @test.attr(type=['negative', 'gate'])
- def test_create_image_specify_name_over_256_chars(self):
- # Return an error if snapshot name over 256 characters is passed
-
- snapshot_name = data_utils.rand_name('a' * 260)
- self.assertRaises(exceptions.BadRequest,
- self.servers_client.create_image,
- self.server_id, snapshot_name)
-
- @test.attr(type=['negative', 'gate'])
- def test_delete_image_that_is_not_yet_active(self):
- # Return an error while trying to delete an image what is creating
-
- snapshot_name = data_utils.rand_name('test-snap-')
- resp, body = self.servers_client.create_image(self.server_id,
- snapshot_name)
- self.assertEqual(202, resp.status)
- image_id = data_utils.parse_image_id(resp['location'])
- self.image_ids.append(image_id)
- self.addCleanup(self._reset_server)
-
- # Do not wait, attempt to delete the image, ensure it's successful
- resp, body = self.client.delete_image(image_id)
- self.assertEqual('200', resp['status'])
- self.image_ids.remove(image_id)
-
- self.assertRaises(exceptions.NotFound, self.client.get_image, image_id)
diff --git a/tempest/api/compute/v3/keypairs/__init__.py b/tempest/api/compute/v3/keypairs/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/api/compute/v3/keypairs/__init__.py
+++ /dev/null
diff --git a/tempest/api/compute/v3/keypairs/test_keypairs_negative.py b/tempest/api/compute/v3/keypairs/test_keypairs_negative.py
deleted file mode 100644
index 1f7206a..0000000
--- a/tempest/api/compute/v3/keypairs/test_keypairs_negative.py
+++ /dev/null
@@ -1,94 +0,0 @@
-# Copyright 2012 OpenStack Foundation
-# Copyright 2013 IBM Corp
-# All Rights Reserved.
-#
-# 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.api.compute import base
-from tempest.common.utils import data_utils
-from tempest import exceptions
-from tempest import test
-
-
-class KeyPairsNegativeV3Test(base.BaseV3ComputeTest):
-
- @classmethod
- def resource_setup(cls):
- super(KeyPairsNegativeV3Test, cls).resource_setup()
- cls.client = cls.keypairs_client
-
- def _create_keypair(self, keypair_name, pub_key=None):
- self.client.create_keypair(keypair_name, pub_key)
- self.addCleanup(self.client.delete_keypair, keypair_name)
-
- @test.attr(type=['negative', 'gate'])
- def test_keypair_create_with_invalid_pub_key(self):
- # Keypair should not be created with a non RSA public key
- k_name = data_utils.rand_name('keypair-')
- pub_key = "ssh-rsa JUNK nova@ubuntu"
- self.assertRaises(exceptions.BadRequest,
- self._create_keypair, k_name, pub_key)
-
- @test.attr(type=['negative', 'gate'])
- def test_keypair_delete_nonexistent_key(self):
- # Non-existent key deletion should throw a proper error
- k_name = data_utils.rand_name("keypair-non-existent-")
- self.assertRaises(exceptions.NotFound, self.client.delete_keypair,
- k_name)
-
- @test.attr(type=['negative', 'gate'])
- def test_create_keypair_with_empty_public_key(self):
- # Keypair should not be created with an empty public key
- k_name = data_utils.rand_name("keypair-")
- pub_key = ' '
- self.assertRaises(exceptions.BadRequest, self._create_keypair,
- k_name, pub_key)
-
- @test.attr(type=['negative', 'gate'])
- def test_create_keypair_when_public_key_bits_exceeds_maximum(self):
- # Keypair should not be created when public key bits are too long
- k_name = data_utils.rand_name("keypair-")
- pub_key = 'ssh-rsa ' + 'A' * 2048 + ' openstack@ubuntu'
- self.assertRaises(exceptions.BadRequest, self._create_keypair,
- k_name, pub_key)
-
- @test.attr(type=['negative', 'gate'])
- def test_create_keypair_with_duplicate_name(self):
- # Keypairs with duplicate names should not be created
- k_name = data_utils.rand_name('keypair-')
- resp, _ = self.client.create_keypair(k_name)
- self.addCleanup(self.client.delete_keypair, k_name)
- self.assertEqual(201, resp.status)
- # Now try the same keyname to create another key
- self.assertRaises(exceptions.Conflict, self._create_keypair,
- k_name)
-
- @test.attr(type=['negative', 'gate'])
- def test_create_keypair_with_empty_name_string(self):
- # Keypairs with name being an empty string should not be created
- self.assertRaises(exceptions.BadRequest, self._create_keypair,
- '')
-
- @test.attr(type=['negative', 'gate'])
- def test_create_keypair_with_long_keynames(self):
- # Keypairs with name longer than 255 chars should not be created
- k_name = 'keypair-'.ljust(260, '0')
- self.assertRaises(exceptions.BadRequest, self._create_keypair,
- k_name)
-
- @test.attr(type=['negative', 'gate'])
- def test_create_keypair_invalid_name(self):
- # Keypairs with name being an invalid name should not be created
- k_name = 'key_/.\@:'
- self.assertRaises(exceptions.BadRequest, self._create_keypair,
- k_name)
diff --git a/tempest/api/compute/v3/servers/__init__.py b/tempest/api/compute/v3/servers/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/api/compute/v3/servers/__init__.py
+++ /dev/null
diff --git a/tempest/api/compute/v3/servers/test_attach_interfaces.py b/tempest/api/compute/v3/servers/test_attach_interfaces.py
deleted file mode 100644
index d4d4fca..0000000
--- a/tempest/api/compute/v3/servers/test_attach_interfaces.py
+++ /dev/null
@@ -1,157 +0,0 @@
-# Copyright 2013 IBM Corp.
-# All Rights Reserved.
-#
-# 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.api.compute import base
-from tempest import config
-from tempest import exceptions
-from tempest import test
-
-import time
-
-CONF = config.CONF
-
-
-class AttachInterfacesV3Test(base.BaseV3ComputeTest):
-
- @classmethod
- def resource_setup(cls):
- if not CONF.service_available.neutron:
- raise cls.skipException("Neutron is required")
- if not CONF.compute_feature_enabled.interface_attach:
- raise cls.skipException("Interface attachment is not available.")
- # This test class requires network and subnet
- cls.set_network_resources(network=True, subnet=True)
- super(AttachInterfacesV3Test, cls).resource_setup()
- cls.client = cls.interfaces_client
-
- def _check_interface(self, iface, port_id=None, network_id=None,
- fixed_ip=None):
- self.assertIn('port_state', iface)
- if port_id:
- self.assertEqual(iface['port_id'], port_id)
- if network_id:
- self.assertEqual(iface['net_id'], network_id)
- if fixed_ip:
- self.assertEqual(iface['fixed_ips'][0]['ip_address'], fixed_ip)
-
- def _create_server_get_interfaces(self):
- resp, server = self.create_test_server(wait_until='ACTIVE')
- resp, ifs = self.client.list_interfaces(server['id'])
- self.assertEqual(200, resp.status)
- resp, body = self.client.wait_for_interface_status(
- server['id'], ifs[0]['port_id'], 'ACTIVE')
- ifs[0]['port_state'] = body['port_state']
- return server, ifs
-
- def _test_create_interface(self, server):
- resp, iface = self.client.create_interface(server['id'])
- self.assertEqual(200, resp.status)
- resp, iface = self.client.wait_for_interface_status(
- server['id'], iface['port_id'], 'ACTIVE')
- self._check_interface(iface)
- return iface
-
- def _test_create_interface_by_network_id(self, server, ifs):
- network_id = ifs[0]['net_id']
- resp, iface = self.client.create_interface(server['id'],
- network_id=network_id)
- self.assertEqual(200, resp.status)
- resp, iface = self.client.wait_for_interface_status(
- server['id'], iface['port_id'], 'ACTIVE')
- self._check_interface(iface, network_id=network_id)
- return iface
-
- def _test_show_interface(self, server, ifs):
- iface = ifs[0]
- resp, _iface = self.client.show_interface(server['id'],
- iface['port_id'])
- self.assertEqual(200, resp.status)
- self.assertEqual(iface, _iface)
-
- def _test_delete_interface(self, server, ifs):
- # NOTE(danms): delete not the first or last, but one in the middle
- iface = ifs[1]
- resp, _ = self.client.delete_interface(server['id'], iface['port_id'])
- self.assertEqual(202, resp.status)
- _ifs = self.client.list_interfaces(server['id'])[1]
- start = int(time.time())
-
- while len(ifs) == len(_ifs):
- time.sleep(self.build_interval)
- _ifs = self.client.list_interfaces(server['id'])[1]
- timed_out = int(time.time()) - start >= self.build_timeout
- if len(ifs) == len(_ifs) and timed_out:
- message = ('Failed to delete interface within '
- 'the required time: %s sec.' % self.build_timeout)
- raise exceptions.TimeoutException(message)
-
- self.assertNotIn(iface['port_id'], [i['port_id'] for i in _ifs])
- return _ifs
-
- def _compare_iface_list(self, list1, list2):
- # NOTE(danms): port_state will likely have changed, so just
- # confirm the port_ids are the same at least
- list1 = [x['port_id'] for x in list1]
- list2 = [x['port_id'] for x in list2]
-
- self.assertEqual(sorted(list1), sorted(list2))
-
- @test.attr(type='smoke')
- def test_create_list_show_delete_interfaces(self):
- server, ifs = self._create_server_get_interfaces()
- interface_count = len(ifs)
- self.assertTrue(interface_count > 0)
- self._check_interface(ifs[0])
-
- iface = self._test_create_interface(server)
- ifs.append(iface)
-
- iface = self._test_create_interface_by_network_id(server, ifs)
- ifs.append(iface)
-
- resp, _ifs = self.client.list_interfaces(server['id'])
- self._compare_iface_list(ifs, _ifs)
-
- self._test_show_interface(server, ifs)
-
- _ifs = self._test_delete_interface(server, ifs)
- self.assertEqual(len(ifs) - 1, len(_ifs))
-
- @test.attr(type='smoke')
- def test_add_remove_fixed_ip(self):
- # Add and Remove the fixed IP to server.
- server, ifs = self._create_server_get_interfaces()
- interface_count = len(ifs)
- self.assertGreater(interface_count, 0)
- self._check_interface(ifs[0])
- network_id = ifs[0]['net_id']
- resp, body = self.client.add_fixed_ip(server['id'],
- network_id)
- self.assertEqual(202, resp.status)
- server_resp, server_detail = self.servers_client.get_server(
- server['id'])
- # Get the Fixed IP from server.
- fixed_ip = None
- for ip_set in server_detail['addresses']:
- for ip in server_detail['addresses'][ip_set]:
- if ip['type'] == 'fixed':
- fixed_ip = ip['addr']
- break
- if fixed_ip is not None:
- break
- # Remove the fixed IP from server.
- resp, body = self.client.remove_fixed_ip(server['id'],
- fixed_ip)
- self.assertEqual(202, resp.status)
diff --git a/tempest/api/compute/v3/servers/test_attach_volume.py b/tempest/api/compute/v3/servers/test_attach_volume.py
deleted file mode 100644
index 76b5549..0000000
--- a/tempest/api/compute/v3/servers/test_attach_volume.py
+++ /dev/null
@@ -1,111 +0,0 @@
-# Copyright 2013 IBM Corp.
-# All Rights Reserved.
-#
-# 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 testtools
-
-from tempest.api.compute import base
-from tempest.common.utils.linux import remote_client
-from tempest import config
-from tempest import test
-
-CONF = config.CONF
-
-
-class AttachVolumeV3Test(base.BaseV3ComputeTest):
-
- def __init__(self, *args, **kwargs):
- super(AttachVolumeV3Test, self).__init__(*args, **kwargs)
- self.server = None
- self.volume = None
- self.attached = False
-
- @classmethod
- def resource_setup(cls):
- cls.prepare_instance_network()
- super(AttachVolumeV3Test, cls).resource_setup()
- cls.device = CONF.compute.volume_device_name
- if not CONF.service_available.cinder:
- skip_msg = ("%s skipped as Cinder is not available" % cls.__name__)
- raise cls.skipException(skip_msg)
-
- def _detach(self, server_id, volume_id):
- if self.attached:
- self.servers_client.detach_volume(server_id, volume_id)
- self.volumes_client.wait_for_volume_status(volume_id, 'available')
-
- def _delete_volume(self):
- if self.volume:
- self.volumes_client.delete_volume(self.volume['id'])
- self.volume = None
-
- def _create_and_attach(self):
- # Start a server and wait for it to become ready
- admin_pass = self.image_ssh_password
- resp, server = self.create_test_server(wait_until='ACTIVE',
- admin_password=admin_pass)
- self.server = server
-
- # Record addresses so that we can ssh later
- resp, server['addresses'] = \
- self.servers_client.list_addresses(server['id'])
-
- # Create a volume and wait for it to become ready
- resp, volume = self.volumes_client.create_volume(1,
- display_name='test')
- self.volume = volume
- self.addCleanup(self._delete_volume)
- self.volumes_client.wait_for_volume_status(volume['id'], 'available')
-
- # Attach the volume to the server
- self.servers_client.attach_volume(server['id'], volume['id'],
- device='/dev/%s' % self.device)
- self.volumes_client.wait_for_volume_status(volume['id'], 'in-use')
-
- self.attached = True
- self.addCleanup(self._detach, server['id'], volume['id'])
-
- @testtools.skipUnless(CONF.compute.run_ssh, 'SSH required for this test')
- @test.attr(type='gate')
- def test_attach_detach_volume(self):
- # Stop and Start a server with an attached volume, ensuring that
- # the volume remains attached.
- self._create_and_attach()
- server = self.server
- volume = self.volume
-
- self.servers_client.stop(server['id'])
- self.servers_client.wait_for_server_status(server['id'], 'SHUTOFF')
-
- self.servers_client.start(server['id'])
- self.servers_client.wait_for_server_status(server['id'], 'ACTIVE')
-
- linux_client = remote_client.RemoteClient(server, self.image_ssh_user,
- server['admin_password'])
- partitions = linux_client.get_partitions()
- self.assertIn(self.device, partitions)
-
- self._detach(server['id'], volume['id'])
- self.attached = False
-
- self.servers_client.stop(server['id'])
- self.servers_client.wait_for_server_status(server['id'], 'SHUTOFF')
-
- self.servers_client.start(server['id'])
- self.servers_client.wait_for_server_status(server['id'], 'ACTIVE')
-
- linux_client = remote_client.RemoteClient(server, self.image_ssh_user,
- server['admin_password'])
- partitions = linux_client.get_partitions()
- self.assertNotIn(self.device, partitions)
diff --git a/tempest/api/compute/v3/servers/test_create_server.py b/tempest/api/compute/v3/servers/test_create_server.py
deleted file mode 100644
index bcd6176..0000000
--- a/tempest/api/compute/v3/servers/test_create_server.py
+++ /dev/null
@@ -1,199 +0,0 @@
-# Copyright 2012 OpenStack Foundation
-# All Rights Reserved.
-#
-# 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 base64
-
-import netaddr
-import testtools
-
-from tempest.api.compute import base
-from tempest.common.utils import data_utils
-from tempest.common.utils.linux import remote_client
-from tempest import config
-from tempest import test
-
-CONF = config.CONF
-
-
-class ServersV3Test(base.BaseV3ComputeTest):
- disk_config = 'AUTO'
-
- @classmethod
- def resource_setup(cls):
- cls.prepare_instance_network()
- super(ServersV3Test, cls).resource_setup()
- cls.meta = {'hello': 'world'}
- cls.accessIPv4 = '1.1.1.1'
- cls.accessIPv6 = '0000:0000:0000:0000:0000:babe:220.12.22.2'
- cls.name = data_utils.rand_name('server')
- file_contents = 'This is a test file.'
- personality = [{'path': '/test.txt',
- 'contents': base64.b64encode(file_contents)}]
- cls.client = cls.servers_client
- cli_resp = cls.create_test_server(name=cls.name,
- meta=cls.meta,
- access_ip_v4=cls.accessIPv4,
- access_ip_v6=cls.accessIPv6,
- personality=personality,
- disk_config=cls.disk_config)
- cls.resp, cls.server_initial = cli_resp
- cls.password = cls.server_initial['admin_password']
- cls.client.wait_for_server_status(cls.server_initial['id'], 'ACTIVE')
- resp, cls.server = cls.client.get_server(cls.server_initial['id'])
-
- @test.attr(type='smoke')
- def test_verify_server_details(self):
- # Verify the specified server attributes are set correctly
- self.assertEqual(self.accessIPv4,
- self.server['os-access-ips:access_ip_v4'])
- # NOTE(maurosr): See http://tools.ietf.org/html/rfc5952 (section 4)
- # Here we compare directly with the canonicalized format.
- self.assertEqual(self.server['os-access-ips:access_ip_v6'],
- str(netaddr.IPAddress(self.accessIPv6)))
- self.assertEqual(self.name, self.server['name'])
- self.assertEqual(self.image_ref, self.server['image']['id'])
- self.assertEqual(self.flavor_ref, self.server['flavor']['id'])
- self.assertEqual(self.meta, self.server['metadata'])
-
- @test.attr(type='smoke')
- def test_list_servers(self):
- # The created server should be in the list of all servers
- resp, body = self.client.list_servers()
- servers = body['servers']
- found = any([i for i in servers if i['id'] == self.server['id']])
- self.assertTrue(found)
-
- @test.attr(type='smoke')
- def test_list_servers_with_detail(self):
- # The created server should be in the detailed list of all servers
- resp, body = self.client.list_servers_with_detail()
- servers = body['servers']
- found = any([i for i in servers if i['id'] == self.server['id']])
- self.assertTrue(found)
-
- @testtools.skipUnless(CONF.compute.run_ssh,
- 'Instance validation tests are disabled.')
- @test.attr(type='gate')
- def test_verify_created_server_vcpus(self):
- # Verify that the number of vcpus reported by the instance matches
- # the amount stated by the flavor
- resp, flavor = self.flavors_client.get_flavor_details(self.flavor_ref)
- linux_client = remote_client.RemoteClient(self.server,
- self.ssh_user, self.password)
- self.assertEqual(flavor['vcpus'], linux_client.get_number_of_vcpus())
-
- @testtools.skipUnless(CONF.compute.run_ssh,
- 'Instance validation tests are disabled.')
- @test.attr(type='gate')
- def test_host_name_is_same_as_server_name(self):
- # Verify the instance host name is the same as the server name
- linux_client = remote_client.RemoteClient(self.server,
- self.ssh_user, self.password)
- self.assertTrue(linux_client.hostname_equals_servername(self.name))
-
-
-class ServersWithSpecificFlavorV3Test(base.BaseV3ComputeAdminTest):
- disk_config = 'AUTO'
-
- @classmethod
- def resource_setup(cls):
- cls.prepare_instance_network()
- super(ServersWithSpecificFlavorV3Test, cls).resource_setup()
- cls.client = cls.servers_client
- cls.flavor_client = cls.flavors_admin_client
-
- @testtools.skipUnless(CONF.compute.run_ssh,
- 'Instance validation tests are disabled.')
- @test.attr(type='gate')
- def test_verify_created_server_ephemeral_disk(self):
- # Verify that the ephemeral disk is created when creating server
-
- def create_flavor_with_extra_specs():
- flavor_with_eph_disk_name = data_utils.rand_name('eph_flavor')
- flavor_with_eph_disk_id = data_utils.rand_int_id(start=1000)
- ram = 512
- vcpus = 1
- disk = 10
-
- # Create a flavor with extra specs
- resp, flavor = (self.flavor_client.
- create_flavor(flavor_with_eph_disk_name,
- ram, vcpus, disk,
- flavor_with_eph_disk_id,
- ephemeral=1, rxtx=1))
- self.addCleanup(flavor_clean_up, flavor['id'])
- self.assertEqual(201, resp.status)
-
- return flavor['id']
-
- def create_flavor_without_extra_specs():
- flavor_no_eph_disk_name = data_utils.rand_name('no_eph_flavor')
- flavor_no_eph_disk_id = data_utils.rand_int_id(start=1000)
-
- ram = 512
- vcpus = 1
- disk = 10
-
- # Create a flavor without extra specs
- resp, flavor = (self.flavor_client.
- create_flavor(flavor_no_eph_disk_name,
- ram, vcpus, disk,
- flavor_no_eph_disk_id))
- self.addCleanup(flavor_clean_up, flavor['id'])
- self.assertEqual(201, resp.status)
-
- return flavor['id']
-
- def flavor_clean_up(flavor_id):
- resp, body = self.flavor_client.delete_flavor(flavor_id)
- self.assertEqual(resp.status, 204)
- self.flavor_client.wait_for_resource_deletion(flavor_id)
-
- flavor_with_eph_disk_id = create_flavor_with_extra_specs()
- flavor_no_eph_disk_id = create_flavor_without_extra_specs()
-
- admin_pass = self.image_ssh_password
-
- resp, server_no_eph_disk = (self.create_test_server(
- wait_until='ACTIVE',
- adminPass=admin_pass,
- flavor=flavor_no_eph_disk_id))
- resp, server_with_eph_disk = (self.create_test_server(
- wait_until='ACTIVE',
- adminPass=admin_pass,
- flavor=flavor_with_eph_disk_id))
- # Get partition number of server without extra specs.
- _, server_no_eph_disk = self.client.get_server(
- server_no_eph_disk['id'])
- linux_client = remote_client.RemoteClient(server_no_eph_disk,
- self.ssh_user, admin_pass)
- partition_num = len(linux_client.get_partitions().split('\n'))
- _, server_with_eph_disk = self.client.get_server(
- server_with_eph_disk['id'])
- linux_client = remote_client.RemoteClient(server_with_eph_disk,
- self.ssh_user, admin_pass)
- partition_num_emph = len(linux_client.get_partitions().split('\n'))
- self.assertEqual(partition_num + 1, partition_num_emph)
-
-
-class ServersV3TestManualDisk(ServersV3Test):
- disk_config = 'MANUAL'
-
- @classmethod
- def resource_setup(cls):
- if not CONF.compute_feature_enabled.disk_config:
- msg = "DiskConfig extension not enabled."
- raise cls.skipException(msg)
- super(ServersV3TestManualDisk, cls).resource_setup()
diff --git a/tempest/api/compute/v3/servers/test_delete_server.py b/tempest/api/compute/v3/servers/test_delete_server.py
deleted file mode 100644
index ab10b4c..0000000
--- a/tempest/api/compute/v3/servers/test_delete_server.py
+++ /dev/null
@@ -1,156 +0,0 @@
-# Copyright 2012 OpenStack Foundation
-#
-# 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 testtools
-
-from tempest.api.compute import base
-from tempest import config
-from tempest import test
-
-CONF = config.CONF
-
-
-class DeleteServersV3Test(base.BaseV3ComputeTest):
- # NOTE: Server creations of each test class should be under 10
- # for preventing "Quota exceeded for instances".
-
- @classmethod
- def resource_setup(cls):
- super(DeleteServersV3Test, cls).resource_setup()
- cls.client = cls.servers_client
-
- @test.attr(type='gate')
- def test_delete_server_while_in_building_state(self):
- # Delete a server while it's VM state is Building
- resp, server = self.create_test_server(wait_until='BUILD')
- resp, _ = self.client.delete_server(server['id'])
- self.assertEqual('204', resp['status'])
- self.client.wait_for_server_termination(server['id'])
-
- @test.attr(type='gate')
- def test_delete_active_server(self):
- # Delete a server while it's VM state is Active
- resp, server = self.create_test_server(wait_until='ACTIVE')
- resp, _ = self.client.delete_server(server['id'])
- self.assertEqual('204', resp['status'])
- self.client.wait_for_server_termination(server['id'])
-
- @test.attr(type='gate')
- def test_delete_server_while_in_shutoff_state(self):
- # Delete a server while it's VM state is Shutoff
- resp, server = self.create_test_server(wait_until='ACTIVE')
- resp, body = self.client.stop(server['id'])
- self.client.wait_for_server_status(server['id'], 'SHUTOFF')
- resp, _ = self.client.delete_server(server['id'])
- self.assertEqual('204', resp['status'])
- self.client.wait_for_server_termination(server['id'])
-
- @testtools.skipUnless(CONF.compute_feature_enabled.pause,
- 'Pause is not available.')
- @test.attr(type='gate')
- def test_delete_server_while_in_pause_state(self):
- # Delete a server while it's VM state is Pause
- resp, server = self.create_test_server(wait_until='ACTIVE')
- resp, body = self.client.pause_server(server['id'])
- self.client.wait_for_server_status(server['id'], 'PAUSED')
- resp, _ = self.client.delete_server(server['id'])
- self.assertEqual('204', resp['status'])
- self.client.wait_for_server_termination(server['id'])
-
- @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
- 'Shelve is not available.')
- @test.attr(type='gate')
- def test_delete_server_while_in_shelved_state(self):
- # Delete a server while it's VM state is Shelved
- resp, server = self.create_test_server(wait_until='ACTIVE')
- resp, body = self.client.shelve_server(server['id'])
- self.assertEqual(202, resp.status)
-
- offload_time = CONF.compute.shelved_offload_time
- if offload_time >= 0:
- self.client.wait_for_server_status(server['id'],
- 'SHELVED_OFFLOADED',
- extra_timeout=offload_time)
- else:
- self.client.wait_for_server_status(server['id'],
- 'SHELVED')
-
- resp, _ = self.client.delete_server(server['id'])
- self.assertEqual('204', resp['status'])
- self.client.wait_for_server_termination(server['id'])
-
- @testtools.skipIf(not CONF.compute_feature_enabled.resize,
- 'Resize not available.')
- @test.attr(type='gate')
- def test_delete_server_while_in_verify_resize_state(self):
- # Delete a server while it's VM state is VERIFY_RESIZE
- resp, server = self.create_test_server(wait_until='ACTIVE')
- resp, body = self.client.resize(server['id'], self.flavor_ref_alt)
- self.assertEqual(202, resp.status)
- self.client.wait_for_server_status(server['id'], 'VERIFY_RESIZE')
- resp, _ = self.client.delete_server(server['id'])
- self.assertEqual('204', resp['status'])
- self.client.wait_for_server_termination(server['id'])
-
- @test.attr(type='gate')
- def test_delete_server_while_in_attached_volume(self):
- # Delete a server while a volume is attached to it
- device = '/dev/%s' % CONF.compute.volume_device_name
- resp, server = self.create_test_server(wait_until='ACTIVE')
-
- resp, volume = self.volumes_client.create_volume(1)
- self.addCleanup(self.volumes_client.delete_volume, volume['id'])
- self.volumes_client.wait_for_volume_status(volume['id'], 'available')
- resp, body = self.client.attach_volume(server['id'],
- volume['id'],
- device=device)
- self.volumes_client.wait_for_volume_status(volume['id'], 'in-use')
-
- resp, _ = self.client.delete_server(server['id'])
- self.assertEqual('204', resp['status'])
- self.client.wait_for_server_termination(server['id'])
- self.volumes_client.wait_for_volume_status(volume['id'], 'available')
-
-
-class DeleteServersAdminV3Test(base.BaseV3ComputeAdminTest):
- # NOTE: Server creations of each test class should be under 10
- # for preventing "Quota exceeded for instances".
-
- @classmethod
- def resource_setup(cls):
- super(DeleteServersAdminV3Test, cls).resource_setup()
- cls.non_admin_client = cls.servers_client
- cls.admin_client = cls.servers_admin_client
-
- @test.attr(type='gate')
- def test_delete_server_while_in_error_state(self):
- # Delete a server while it's VM state is error
- resp, server = self.create_test_server(wait_until='ACTIVE')
- resp, body = self.admin_client.reset_state(server['id'], state='error')
- self.assertEqual(202, resp.status)
- # Verify server's state
- resp, server = self.non_admin_client.get_server(server['id'])
- self.assertEqual(server['status'], 'ERROR')
- resp, _ = self.non_admin_client.delete_server(server['id'])
- self.assertEqual('204', resp['status'])
- self.servers_client.wait_for_server_termination(server['id'],
- ignore_error=True)
-
- @test.attr(type='gate')
- def test_admin_delete_servers_of_others(self):
- # Administrator can delete servers of others
- resp, server = self.create_test_server(wait_until='ACTIVE')
- resp, _ = self.admin_client.delete_server(server['id'])
- self.assertEqual('204', resp['status'])
- self.servers_client.wait_for_server_termination(server['id'])
diff --git a/tempest/api/compute/v3/servers/test_instance_actions.py b/tempest/api/compute/v3/servers/test_instance_actions.py
deleted file mode 100644
index 227f6cd..0000000
--- a/tempest/api/compute/v3/servers/test_instance_actions.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright 2013 NEC Corporation
-# All Rights Reserved.
-#
-# 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.api.compute import base
-from tempest import test
-
-
-class InstanceActionsV3Test(base.BaseV3ComputeTest):
-
- @classmethod
- def resource_setup(cls):
- super(InstanceActionsV3Test, cls).resource_setup()
- cls.client = cls.servers_client
- resp, server = cls.create_test_server(wait_until='ACTIVE')
- cls.resp = resp
- cls.server_id = server['id']
-
- @test.attr(type='gate')
- def test_list_server_actions(self):
- # List actions of the provided server
- resp, body = self.client.reboot(self.server_id, 'HARD')
- self.client.wait_for_server_status(self.server_id, 'ACTIVE')
-
- resp, body = self.client.list_server_actions(self.server_id)
- self.assertEqual(200, resp.status)
- self.assertTrue(len(body) == 2, str(body))
- self.assertTrue(any([i for i in body if i['action'] == 'create']))
- self.assertTrue(any([i for i in body if i['action'] == 'reboot']))
-
- @test.attr(type='gate')
- def test_get_server_action(self):
- # Get the action details of the provided server
- request_id = self.resp['x-openstack-request-id']
- resp, body = self.client.get_server_action(self.server_id,
- request_id)
- self.assertEqual(200, resp.status)
- self.assertEqual(self.server_id, body['server_uuid'])
- self.assertEqual('create', body['action'])
diff --git a/tempest/api/compute/v3/servers/test_instance_actions_negative.py b/tempest/api/compute/v3/servers/test_instance_actions_negative.py
deleted file mode 100644
index b9d4be2..0000000
--- a/tempest/api/compute/v3/servers/test_instance_actions_negative.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright 2014 NEC Corporation
-# All Rights Reserved.
-#
-# 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.api.compute import base
-from tempest.common.utils import data_utils
-from tempest import exceptions
-from tempest import test
-
-
-class InstanceActionsNegativeV3Test(base.BaseV3ComputeTest):
-
- @classmethod
- def resource_setup(cls):
- super(InstanceActionsNegativeV3Test, cls).resource_setup()
- cls.client = cls.servers_client
- resp, server = cls.create_test_server(wait_until='ACTIVE')
- cls.server_id = server['id']
-
- @test.attr(type=['negative', 'gate'])
- def test_list_server_actions_invalid_server(self):
- # List actions of the invalid server id
- invalid_server_id = data_utils.rand_uuid()
- self.assertRaises(exceptions.NotFound,
- self.client.list_server_actions, invalid_server_id)
-
- @test.attr(type=['negative', 'gate'])
- def test_get_server_action_invalid_request(self):
- # Get the action details of the provided server with invalid request
- invalid_request_id = 'req-' + data_utils.rand_uuid()
- self.assertRaises(exceptions.NotFound, self.client.get_server_action,
- self.server_id, invalid_request_id)
diff --git a/tempest/api/compute/v3/servers/test_list_server_filters.py b/tempest/api/compute/v3/servers/test_list_server_filters.py
deleted file mode 100644
index 73844cf..0000000
--- a/tempest/api/compute/v3/servers/test_list_server_filters.py
+++ /dev/null
@@ -1,269 +0,0 @@
-# Copyright 2012 OpenStack Foundation
-# All Rights Reserved.
-#
-# 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.api.compute import base
-from tempest.api import utils
-from tempest.common.utils import data_utils
-from tempest import config
-from tempest import exceptions
-from tempest import test
-
-CONF = config.CONF
-
-
-class ListServerFiltersV3Test(base.BaseV3ComputeTest):
-
- @classmethod
- def resource_setup(cls):
- cls.set_network_resources(network=True, subnet=True, dhcp=True)
- super(ListServerFiltersV3Test, cls).resource_setup()
- cls.client = cls.servers_client
-
- # Check to see if the alternate image ref actually exists...
- images_client = cls.images_client
- resp, images = images_client.image_list()
-
- if cls.image_ref != cls.image_ref_alt and \
- any([image for image in images
- if image['id'] == cls.image_ref_alt]):
- cls.multiple_images = True
- else:
- cls.image_ref_alt = cls.image_ref
-
- # Do some sanity checks here. If one of the images does
- # not exist, fail early since the tests won't work...
- try:
- cls.images_client.get_image_meta(cls.image_ref)
- except exceptions.NotFound:
- raise RuntimeError("Image %s (image_ref) was not found!" %
- cls.image_ref)
-
- try:
- cls.images_client.get_image_meta(cls.image_ref_alt)
- except exceptions.NotFound:
- raise RuntimeError("Image %s (image_ref_alt) was not found!" %
- cls.image_ref_alt)
-
- cls.s1_name = data_utils.rand_name(cls.__name__ + '-instance')
- resp, cls.s1 = cls.create_test_server(name=cls.s1_name,
- wait_until='ACTIVE')
-
- cls.s2_name = data_utils.rand_name(cls.__name__ + '-instance')
- resp, cls.s2 = cls.create_test_server(name=cls.s2_name,
- image_id=cls.image_ref_alt,
- wait_until='ACTIVE')
-
- cls.s3_name = data_utils.rand_name(cls.__name__ + '-instance')
- resp, cls.s3 = cls.create_test_server(name=cls.s3_name,
- flavor=cls.flavor_ref_alt,
- wait_until='ACTIVE')
-
- cls.fixed_network_name = CONF.compute.fixed_network_name
- if CONF.service_available.neutron:
- if hasattr(cls.isolated_creds, 'get_primary_network'):
- network = cls.isolated_creds.get_primary_network()
- cls.fixed_network_name = network['name']
-
- @utils.skip_unless_attr('multiple_images', 'Only one image found')
- @test.attr(type='gate')
- def test_list_servers_filter_by_image(self):
- # Filter the list of servers by image
- params = {'image': self.image_ref}
- resp, body = self.client.list_servers(params)
- servers = body['servers']
-
- self.assertIn(self.s1['id'], map(lambda x: x['id'], servers))
- self.assertNotIn(self.s2['id'], map(lambda x: x['id'], servers))
- self.assertIn(self.s3['id'], map(lambda x: x['id'], servers))
-
- @test.attr(type='gate')
- def test_list_servers_filter_by_flavor(self):
- # Filter the list of servers by flavor
- params = {'flavor': self.flavor_ref_alt}
- resp, body = self.client.list_servers(params)
- servers = body['servers']
-
- self.assertNotIn(self.s1['id'], map(lambda x: x['id'], servers))
- self.assertNotIn(self.s2['id'], map(lambda x: x['id'], servers))
- self.assertIn(self.s3['id'], map(lambda x: x['id'], servers))
-
- @test.attr(type='gate')
- def test_list_servers_filter_by_server_name(self):
- # Filter the list of servers by server name
- params = {'name': self.s1_name}
- resp, body = self.client.list_servers(params)
- servers = body['servers']
-
- self.assertIn(self.s1_name, map(lambda x: x['name'], servers))
- self.assertNotIn(self.s2_name, map(lambda x: x['name'], servers))
- self.assertNotIn(self.s3_name, map(lambda x: x['name'], servers))
-
- @test.attr(type='gate')
- def test_list_servers_filter_by_server_status(self):
- # Filter the list of servers by server status
- params = {'status': 'active'}
- resp, body = self.client.list_servers(params)
- servers = body['servers']
-
- self.assertIn(self.s1['id'], map(lambda x: x['id'], servers))
- self.assertIn(self.s2['id'], map(lambda x: x['id'], servers))
- self.assertIn(self.s3['id'], map(lambda x: x['id'], servers))
-
- @test.attr(type='gate')
- def test_list_servers_filter_by_limit(self):
- # Verify only the expected number of servers are returned
- params = {'limit': 1}
- resp, servers = self.client.list_servers(params)
- self.assertEqual(1, len([x for x in servers['servers'] if 'id' in x]))
-
- @test.attr(type='gate')
- def test_list_servers_filter_by_zero_limit(self):
- # Verify only the expected number of servers are returned
- params = {'limit': 0}
- resp, servers = self.client.list_servers(params)
- self.assertEqual(0, len(servers['servers']))
-
- @test.attr(type='gate')
- def test_list_servers_filter_by_exceed_limit(self):
- # Verify only the expected number of servers are returned
- params = {'limit': 100000}
- resp, servers = self.client.list_servers(params)
- resp, all_servers = self.client.list_servers()
- self.assertEqual(len([x for x in all_servers['servers'] if 'id' in x]),
- len([x for x in servers['servers'] if 'id' in x]))
-
- @utils.skip_unless_attr('multiple_images', 'Only one image found')
- @test.attr(type='gate')
- def test_list_servers_detailed_filter_by_image(self):
- # Filter the detailed list of servers by image
- params = {'image': self.image_ref}
- resp, body = self.client.list_servers_with_detail(params)
- servers = body['servers']
-
- self.assertIn(self.s1['id'], map(lambda x: x['id'], servers))
- self.assertNotIn(self.s2['id'], map(lambda x: x['id'], servers))
- self.assertIn(self.s3['id'], map(lambda x: x['id'], servers))
-
- @test.attr(type='gate')
- def test_list_servers_detailed_filter_by_flavor(self):
- # Filter the detailed list of servers by flavor
- params = {'flavor': self.flavor_ref_alt}
- resp, body = self.client.list_servers_with_detail(params)
- servers = body['servers']
-
- self.assertNotIn(self.s1['id'], map(lambda x: x['id'], servers))
- self.assertNotIn(self.s2['id'], map(lambda x: x['id'], servers))
- self.assertIn(self.s3['id'], map(lambda x: x['id'], servers))
-
- @test.attr(type='gate')
- def test_list_servers_detailed_filter_by_server_name(self):
- # Filter the detailed list of servers by server name
- params = {'name': self.s1_name}
- resp, body = self.client.list_servers_with_detail(params)
- servers = body['servers']
-
- self.assertIn(self.s1_name, map(lambda x: x['name'], servers))
- self.assertNotIn(self.s2_name, map(lambda x: x['name'], servers))
- self.assertNotIn(self.s3_name, map(lambda x: x['name'], servers))
-
- @test.attr(type='gate')
- def test_list_servers_detailed_filter_by_server_status(self):
- # Filter the detailed list of servers by server status
- params = {'status': 'active'}
- resp, body = self.client.list_servers_with_detail(params)
- expected_servers = (self.s1['id'], self.s2['id'], self.s3['id'])
- servers = [x for x in body['servers'] if x['id'] in expected_servers]
-
- self.assertIn(self.s1['id'], map(lambda x: x['id'], servers))
- self.assertIn(self.s2['id'], map(lambda x: x['id'], servers))
- self.assertIn(self.s3['id'], map(lambda x: x['id'], servers))
- self.assertEqual(['ACTIVE'] * 3, [x['status'] for x in servers])
-
- @test.attr(type='gate')
- def test_list_servers_filter_by_shutoff_status(self):
- # Filter the list of servers by server shutoff status
- params = {'status': 'shutoff'}
- self.client.stop(self.s1['id'])
- self.client.wait_for_server_status(self.s1['id'],
- 'SHUTOFF')
- resp, body = self.client.list_servers(params)
- self.client.start(self.s1['id'])
- self.client.wait_for_server_status(self.s1['id'],
- 'ACTIVE')
- servers = body['servers']
-
- self.assertIn(self.s1['id'], map(lambda x: x['id'], servers))
- self.assertNotIn(self.s2['id'], map(lambda x: x['id'], servers))
- self.assertNotIn(self.s3['id'], map(lambda x: x['id'], servers))
-
- @test.attr(type='gate')
- def test_list_servers_filtered_by_name_wildcard(self):
- # List all servers that contains '-instance' in name
- params = {'name': '-instance'}
- resp, body = self.client.list_servers(params)
- servers = body['servers']
-
- self.assertIn(self.s1_name, map(lambda x: x['name'], servers))
- self.assertIn(self.s2_name, map(lambda x: x['name'], servers))
- self.assertIn(self.s3_name, map(lambda x: x['name'], servers))
-
- # Let's take random part of name and try to search it
- part_name = self.s1_name[6:-1]
-
- params = {'name': part_name}
- resp, body = self.client.list_servers(params)
- servers = body['servers']
-
- self.assertIn(self.s1_name, map(lambda x: x['name'], servers))
- self.assertNotIn(self.s2_name, map(lambda x: x['name'], servers))
- self.assertNotIn(self.s3_name, map(lambda x: x['name'], servers))
-
- @test.attr(type='gate')
- def test_list_servers_filtered_by_ip(self):
- # Filter servers by ip
- # Here should be listed 1 server
- resp, self.s1 = self.client.get_server(self.s1['id'])
- ip = self.s1['addresses'][self.fixed_network_name][0]['addr']
- params = {'ip': ip}
- resp, body = self.client.list_servers(params)
- servers = body['servers']
-
- self.assertIn(self.s1_name, map(lambda x: x['name'], servers))
- self.assertNotIn(self.s2_name, map(lambda x: x['name'], servers))
- self.assertNotIn(self.s3_name, map(lambda x: x['name'], servers))
-
- @test.skip_because(bug="1182883",
- condition=CONF.service_available.neutron)
- @test.attr(type='gate')
- def test_list_servers_filtered_by_ip_regex(self):
- # Filter servers by regex ip
- # List all servers filtered by part of ip address.
- # Here should be listed all servers
- resp, self.s1 = self.client.get_server(self.s1['id'])
- ip = self.s1['addresses'][self.fixed_network_name][0]['addr'][0:-3]
- params = {'ip': ip}
- resp, body = self.client.list_servers(params)
- servers = body['servers']
-
- self.assertIn(self.s1_name, map(lambda x: x['name'], servers))
- self.assertIn(self.s2_name, map(lambda x: x['name'], servers))
- self.assertIn(self.s3_name, map(lambda x: x['name'], servers))
-
- @test.attr(type='gate')
- def test_list_servers_detailed_limit_results(self):
- # Verify only the expected number of detailed results are returned
- params = {'limit': 1}
- resp, servers = self.client.list_servers_with_detail(params)
- self.assertEqual(1, len(servers['servers']))
diff --git a/tempest/api/compute/v3/servers/test_list_servers_negative.py b/tempest/api/compute/v3/servers/test_list_servers_negative.py
deleted file mode 100644
index 67e1155..0000000
--- a/tempest/api/compute/v3/servers/test_list_servers_negative.py
+++ /dev/null
@@ -1,164 +0,0 @@
-# Copyright 2012 OpenStack Foundation
-# All Rights Reserved.
-#
-# 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 datetime
-
-from six import moves
-
-from tempest.api.compute import base
-from tempest import exceptions
-from tempest import test
-
-
-class ListServersNegativeV3Test(base.BaseV3ComputeTest):
- force_tenant_isolation = True
-
- @classmethod
- def resource_setup(cls):
- super(ListServersNegativeV3Test, cls).resource_setup()
- cls.client = cls.servers_client
-
- # The following servers are created for use
- # by the test methods in this class. These
- # servers are cleaned up automatically in the
- # tearDownClass method of the super-class.
- cls.existing_fixtures = []
- cls.deleted_fixtures = []
- cls.start_time = datetime.datetime.utcnow()
- for x in moves.xrange(2):
- resp, srv = cls.create_test_server(wait_until='ACTIVE')
- cls.existing_fixtures.append(srv)
-
- resp, srv = cls.create_test_server()
- cls.client.delete_server(srv['id'])
- # We ignore errors on termination because the server may
- # be put into ERROR status on a quick spawn, then delete,
- # as the compute node expects the instance local status
- # to be spawning, not deleted. See LP Bug#1061167
- cls.client.wait_for_server_termination(srv['id'],
- ignore_error=True)
- cls.deleted_fixtures.append(srv)
-
- @test.attr(type=['negative', 'gate'])
- def test_list_servers_with_a_deleted_server(self):
- # Verify deleted servers do not show by default in list servers
- # List servers and verify server not returned
- resp, body = self.client.list_servers()
- servers = body['servers']
- deleted_ids = [s['id'] for s in self.deleted_fixtures]
- actual = [srv for srv in servers
- if srv['id'] in deleted_ids]
- self.assertEqual('200', resp['status'])
- self.assertEqual([], actual)
-
- @test.attr(type=['negative', 'gate'])
- def test_list_servers_by_non_existing_image(self):
- # Listing servers for a non existing image returns empty list
- non_existing_image = '1234abcd-zzz0-aaa9-ppp3-0987654abcde'
- resp, body = self.client.list_servers(dict(image=non_existing_image))
- servers = body['servers']
- self.assertEqual('200', resp['status'])
- self.assertEqual([], servers)
-
- @test.attr(type=['negative', 'gate'])
- def test_list_servers_by_non_existing_flavor(self):
- # Listing servers by non existing flavor returns empty list
- non_existing_flavor = 1234
- resp, body = self.client.list_servers(dict(flavor=non_existing_flavor))
- servers = body['servers']
- self.assertEqual('200', resp['status'])
- self.assertEqual([], servers)
-
- @test.attr(type=['negative', 'gate'])
- def test_list_servers_by_non_existing_server_name(self):
- # Listing servers for a non existent server name returns empty list
- non_existing_name = 'junk_server_1234'
- resp, body = self.client.list_servers(dict(name=non_existing_name))
- servers = body['servers']
- self.assertEqual('200', resp['status'])
- self.assertEqual([], servers)
-
- @test.attr(type=['negative', 'gate'])
- def test_list_servers_status_non_existing(self):
- # Return an empty list when invalid status is specified
- non_existing_status = 'BALONEY'
- resp, body = self.client.list_servers(dict(status=non_existing_status))
- servers = body['servers']
- self.assertEqual('200', resp['status'])
- self.assertEqual([], servers)
-
- @test.attr(type='gate')
- def test_list_servers_by_limits(self):
- # List servers by specifying limits
- resp, body = self.client.list_servers({'limit': 1})
- self.assertEqual('200', resp['status'])
- self.assertEqual(1, len([x for x in body['servers'] if 'id' in x]))
-
- @test.attr(type=['negative', 'gate'])
- def test_list_servers_by_limits_greater_than_actual_count(self):
- # List servers by specifying a greater value for limit
- resp, body = self.client.list_servers({'limit': 100})
- self.assertEqual('200', resp['status'])
- self.assertEqual(len(self.existing_fixtures), len(body['servers']))
-
- @test.attr(type=['negative', 'gate'])
- def test_list_servers_by_limits_pass_string(self):
- # Return an error if a string value is passed for limit
- self.assertRaises(exceptions.BadRequest, self.client.list_servers,
- {'limit': 'testing'})
-
- @test.attr(type=['negative', 'gate'])
- def test_list_servers_by_limits_pass_negative_value(self):
- # Return an error if a negative value for limit is passed
- self.assertRaises(exceptions.BadRequest, self.client.list_servers,
- {'limit': -1})
-
- @test.attr(type='gate')
- def test_list_servers_by_changes_since(self):
- # Servers are listed by specifying changes-since date
- changes_since = {'changes_since': self.start_time.isoformat()}
- resp, body = self.client.list_servers(changes_since)
- self.assertEqual('200', resp['status'])
- # changes-since returns all instances, including deleted.
- num_expected = (len(self.existing_fixtures) +
- len(self.deleted_fixtures))
- self.assertEqual(num_expected, len(body['servers']),
- "Number of servers %d is wrong in %s" %
- (num_expected, body['servers']))
-
- @test.attr(type=['negative', 'gate'])
- def test_list_servers_by_changes_since_invalid_date(self):
- # Return an error when invalid date format is passed
- self.assertRaises(exceptions.BadRequest, self.client.list_servers,
- {'changes_since': '2011/01/01'})
-
- @test.attr(type=['negative', 'gate'])
- def test_list_servers_by_changes_since_future_date(self):
- # Return an empty list when a date in the future is passed
- changes_since = {'changes_since': '2051-01-01T12:34:00Z'}
- resp, body = self.client.list_servers(changes_since)
- self.assertEqual('200', resp['status'])
- self.assertEqual(0, len(body['servers']))
-
- @test.attr(type=['negative', 'gate'])
- def test_list_servers_detail_server_is_deleted(self):
- # Server details are not listed for a deleted server
- deleted_ids = [s['id'] for s in self.deleted_fixtures]
- resp, body = self.client.list_servers_with_detail()
- servers = body['servers']
- actual = [srv for srv in servers
- if srv['id'] in deleted_ids]
- self.assertEqual('200', resp['status'])
- self.assertEqual([], actual)
diff --git a/tempest/api/compute/v3/servers/test_multiple_create.py b/tempest/api/compute/v3/servers/test_multiple_create.py
deleted file mode 100644
index 23e0854..0000000
--- a/tempest/api/compute/v3/servers/test_multiple_create.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# Copyright 2013 IBM Corp
-# All Rights Reserved.
-#
-# 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.api.compute import base
-from tempest.common.utils import data_utils
-from tempest import test
-
-
-class MultipleCreateV3Test(base.BaseV3ComputeTest):
- _name = 'multiple-create-test'
-
- def _generate_name(self):
- return data_utils.rand_name(self._name)
-
- def _create_multiple_servers(self, name=None, wait_until=None, **kwargs):
- """
- This is the right way to create_multiple servers and manage to get the
- created servers into the servers list to be cleaned up after all.
- """
- kwargs['name'] = kwargs.get('name', self._generate_name())
- resp, body = self.create_test_server(**kwargs)
-
- return resp, body
-
- @test.attr(type='gate')
- def test_multiple_create(self):
- resp, body = self._create_multiple_servers(wait_until='ACTIVE',
- min_count=1,
- max_count=2)
- # NOTE(maurosr): do status response check and also make sure that
- # reservation_id is not in the response body when the request send
- # contains return_reservation_id=False
- self.assertEqual('202', resp['status'])
- self.assertNotIn('reservation_id', body)
-
- @test.attr(type='gate')
- def test_multiple_create_with_reservation_return(self):
- resp, body = self._create_multiple_servers(wait_until='ACTIVE',
- min_count=1,
- max_count=2,
- return_reservation_id=True)
- self.assertEqual(resp['status'], '202')
- self.assertIn('reservation_id', body)
diff --git a/tempest/api/compute/v3/servers/test_multiple_create_negative.py b/tempest/api/compute/v3/servers/test_multiple_create_negative.py
deleted file mode 100644
index f208bc0..0000000
--- a/tempest/api/compute/v3/servers/test_multiple_create_negative.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# Copyright 2013 IBM Corp
-# All Rights Reserved.
-#
-# 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.api.compute import base
-from tempest.common.utils import data_utils
-from tempest import exceptions
-from tempest import test
-
-
-class MultipleCreateV3NegativeTest(base.BaseV3ComputeTest):
- _name = 'multiple-create-negative-test'
-
- def _generate_name(self):
- return data_utils.rand_name(self._name)
-
- def _create_multiple_servers(self, name=None, wait_until=None, **kwargs):
- """
- This is the right way to create_multiple servers and manage to get the
- created servers into the servers list to be cleaned up after all.
- """
- kwargs['name'] = kwargs.get('name', self._generate_name())
- resp, body = self.create_test_server(**kwargs)
-
- return resp, body
-
- @test.attr(type=['negative', 'gate'])
- def test_min_count_less_than_one(self):
- invalid_min_count = 0
- self.assertRaises(exceptions.BadRequest, self._create_multiple_servers,
- min_count=invalid_min_count)
-
- @test.attr(type=['negative', 'gate'])
- def test_min_count_non_integer(self):
- invalid_min_count = 2.5
- self.assertRaises(exceptions.BadRequest, self._create_multiple_servers,
- min_count=invalid_min_count)
-
- @test.attr(type=['negative', 'gate'])
- def test_max_count_less_than_one(self):
- invalid_max_count = 0
- self.assertRaises(exceptions.BadRequest, self._create_multiple_servers,
- max_count=invalid_max_count)
-
- @test.attr(type=['negative', 'gate'])
- def test_max_count_non_integer(self):
- invalid_max_count = 2.5
- self.assertRaises(exceptions.BadRequest, self._create_multiple_servers,
- max_count=invalid_max_count)
-
- @test.attr(type=['negative', 'gate'])
- def test_max_count_less_than_min_count(self):
- min_count = 3
- max_count = 2
- self.assertRaises(exceptions.BadRequest, self._create_multiple_servers,
- min_count=min_count,
- max_count=max_count)
diff --git a/tempest/api/compute/v3/servers/test_server_actions.py b/tempest/api/compute/v3/servers/test_server_actions.py
deleted file mode 100644
index a4e8dba..0000000
--- a/tempest/api/compute/v3/servers/test_server_actions.py
+++ /dev/null
@@ -1,509 +0,0 @@
-# Copyright 2012 OpenStack Foundation
-# All Rights Reserved.
-#
-# 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 logging
-import urlparse
-
-import testtools
-
-from tempest.api.compute import base
-from tempest.common.utils import data_utils
-from tempest.common.utils.linux import remote_client
-from tempest import config
-from tempest import exceptions
-from tempest import test
-
-CONF = config.CONF
-
-LOG = logging.getLogger(__name__)
-
-
-class ServerActionsV3Test(base.BaseV3ComputeTest):
- run_ssh = CONF.compute.run_ssh
-
- def setUp(self):
- # NOTE(afazekas): Normally we use the same server with all test cases,
- # but if it has an issue, we build a new one
- super(ServerActionsV3Test, self).setUp()
- # Check if the server is in a clean state after test
- try:
- self.client.wait_for_server_status(self.server_id, 'ACTIVE')
- except Exception:
- # Rebuild server if something happened to it during a test
- self.__class__.server_id = self.rebuild_server(self.server_id)
-
- def tearDown(self):
- _, server = self.client.get_server(self.server_id)
- self.assertEqual(self.image_ref, server['image']['id'])
- self.server_check_teardown()
- super(ServerActionsV3Test, self).tearDown()
-
- @classmethod
- def resource_setup(cls):
- cls.prepare_instance_network()
- super(ServerActionsV3Test, cls).resource_setup()
- cls.client = cls.servers_client
- cls.server_id = cls.rebuild_server(None)
-
- @testtools.skipUnless(CONF.compute_feature_enabled.change_password,
- 'Change password not available.')
- @test.attr(type='gate')
- def test_change_server_password(self):
- # The server's password should be set to the provided password
- new_password = 'Newpass1234'
- resp, body = self.client.change_password(self.server_id, new_password)
- self.assertEqual(202, resp.status)
- self.client.wait_for_server_status(self.server_id, 'ACTIVE')
-
- if self.run_ssh:
- # Verify that the user can authenticate with the new password
- resp, server = self.client.get_server(self.server_id)
- linux_client = remote_client.RemoteClient(server, self.ssh_user,
- new_password)
- linux_client.validate_authentication()
-
- @test.attr(type='smoke')
- def test_reboot_server_hard(self):
- # The server should be power cycled
- if self.run_ssh:
- # Get the time the server was last rebooted,
- resp, server = self.client.get_server(self.server_id)
- linux_client = remote_client.RemoteClient(server, self.ssh_user,
- self.password)
- boot_time = linux_client.get_boot_time()
-
- resp, body = self.client.reboot(self.server_id, 'HARD')
- self.assertEqual(202, resp.status)
- self.client.wait_for_server_status(self.server_id, 'ACTIVE')
-
- if self.run_ssh:
- # Log in and verify the boot time has changed
- linux_client = remote_client.RemoteClient(server, self.ssh_user,
- self.password)
- new_boot_time = linux_client.get_boot_time()
- self.assertGreater(new_boot_time, boot_time)
-
- @test.skip_because(bug="1014647")
- @test.attr(type='smoke')
- def test_reboot_server_soft(self):
- # The server should be signaled to reboot gracefully
- if self.run_ssh:
- # Get the time the server was last rebooted,
- resp, server = self.client.get_server(self.server_id)
- linux_client = remote_client.RemoteClient(server, self.ssh_user,
- self.password)
- boot_time = linux_client.get_boot_time()
-
- resp, body = self.client.reboot(self.server_id, 'SOFT')
- self.assertEqual(202, resp.status)
- self.client.wait_for_server_status(self.server_id, 'ACTIVE')
-
- if self.run_ssh:
- # Log in and verify the boot time has changed
- linux_client = remote_client.RemoteClient(server, self.ssh_user,
- self.password)
- new_boot_time = linux_client.get_boot_time()
- self.assertGreater(new_boot_time, boot_time)
-
- @test.attr(type='smoke')
- def test_rebuild_server(self):
- # The server should be rebuilt using the provided image and data
- meta = {'rebuild': 'server'}
- new_name = data_utils.rand_name('server')
- password = 'rebuildPassw0rd'
- resp, rebuilt_server = self.client.rebuild(self.server_id,
- self.image_ref_alt,
- name=new_name,
- metadata=meta,
- admin_password=password)
-
- # Verify the properties in the initial response are correct
- self.assertEqual(self.server_id, rebuilt_server['id'])
- rebuilt_image_id = rebuilt_server['image']['id']
- self.assertTrue(self.image_ref_alt.endswith(rebuilt_image_id))
- self.assertEqual(self.flavor_ref, rebuilt_server['flavor']['id'])
-
- # Verify the server properties after the rebuild completes
- self.client.wait_for_server_status(rebuilt_server['id'], 'ACTIVE')
- resp, server = self.client.get_server(rebuilt_server['id'])
- rebuilt_image_id = server['image']['id']
- self.assertTrue(self.image_ref_alt.endswith(rebuilt_image_id))
- self.assertEqual(new_name, server['name'])
-
- if self.run_ssh:
- # Verify that the user can authenticate with the provided password
- linux_client = remote_client.RemoteClient(server, self.ssh_user,
- password)
- linux_client.validate_authentication()
-
- if self.image_ref_alt != self.image_ref:
- self.client.rebuild(self.server_id, self.image_ref)
-
- @test.attr(type='gate')
- def test_rebuild_server_in_stop_state(self):
- # The server in stop state should be rebuilt using the provided
- # image and remain in SHUTOFF state
- resp, server = self.client.get_server(self.server_id)
- old_image = server['image']['id']
- new_image = self.image_ref_alt \
- if old_image == self.image_ref else self.image_ref
- resp, server = self.client.stop(self.server_id)
- self.assertEqual(202, resp.status)
- self.client.wait_for_server_status(self.server_id, 'SHUTOFF')
- resp, rebuilt_server = self.client.rebuild(self.server_id, new_image)
-
- # Verify the properties in the initial response are correct
- self.assertEqual(self.server_id, rebuilt_server['id'])
- rebuilt_image_id = rebuilt_server['image']['id']
- self.assertEqual(new_image, rebuilt_image_id)
- self.assertEqual(self.flavor_ref, rebuilt_server['flavor']['id'])
-
- # Verify the server properties after the rebuild completes
- self.client.wait_for_server_status(rebuilt_server['id'], 'SHUTOFF')
- resp, server = self.client.get_server(rebuilt_server['id'])
- rebuilt_image_id = server['image']['id']
- self.assertEqual(new_image, rebuilt_image_id)
-
- # Restore to the original image (The tearDown will test it again)
- if self.image_ref_alt != self.image_ref:
- self.client.rebuild(self.server_id, old_image)
- self.client.wait_for_server_status(self.server_id, 'SHUTOFF')
- self.client.start(self.server_id)
-
- def _detect_server_image_flavor(self, server_id):
- # Detects the current server image flavor ref.
- resp, server = self.client.get_server(server_id)
- current_flavor = server['flavor']['id']
- new_flavor_ref = self.flavor_ref_alt \
- if current_flavor == self.flavor_ref else self.flavor_ref
- return current_flavor, new_flavor_ref
-
- def _test_resize_server_confirm(self, stop=False):
- # The server's RAM and disk space should be modified to that of
- # the provided flavor
-
- previous_flavor_ref, new_flavor_ref = \
- self._detect_server_image_flavor(self.server_id)
-
- if stop:
- resp = self.servers_client.stop(self.server_id)[0]
- self.assertEqual(202, resp.status)
- self.servers_client.wait_for_server_status(self.server_id,
- 'SHUTOFF')
-
- resp, server = self.client.resize(self.server_id, new_flavor_ref)
- self.assertEqual(202, resp.status)
- self.client.wait_for_server_status(self.server_id, 'VERIFY_RESIZE')
-
- self.client.confirm_resize(self.server_id)
- expected_status = 'SHUTOFF' if stop else 'ACTIVE'
- self.client.wait_for_server_status(self.server_id, expected_status)
-
- resp, server = self.client.get_server(self.server_id)
- self.assertEqual(new_flavor_ref, server['flavor']['id'])
-
- if stop:
- # NOTE(mriedem): tearDown requires the server to be started.
- self.client.start(self.server_id)
-
- @testtools.skipUnless(CONF.compute_feature_enabled.resize,
- 'Resize not available.')
- @test.attr(type='smoke')
- def test_resize_server_confirm(self):
- self._test_resize_server_confirm(stop=False)
-
- @testtools.skipUnless(CONF.compute_feature_enabled.resize,
- 'Resize not available.')
- @test.attr(type='smoke')
- def test_resize_server_confirm_from_stopped(self):
- self._test_resize_server_confirm(stop=True)
-
- @testtools.skipUnless(CONF.compute_feature_enabled.resize,
- 'Resize not available.')
- @test.attr(type='gate')
- def test_resize_server_revert(self):
- # The server's RAM and disk space should return to its original
- # values after a resize is reverted
-
- previous_flavor_ref, new_flavor_ref = \
- self._detect_server_image_flavor(self.server_id)
-
- resp, server = self.client.resize(self.server_id, new_flavor_ref)
- self.assertEqual(202, resp.status)
- self.client.wait_for_server_status(self.server_id, 'VERIFY_RESIZE')
-
- self.client.revert_resize(self.server_id)
- self.client.wait_for_server_status(self.server_id, 'ACTIVE')
-
- resp, server = self.client.get_server(self.server_id)
- self.assertEqual(previous_flavor_ref, server['flavor']['id'])
-
- @testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
- 'Snapshotting not available, backup not possible.')
- @test.attr(type='gate')
- def test_create_backup(self):
- # Positive test:create backup successfully and rotate backups correctly
- # create the first and the second backup
- backup1 = data_utils.rand_name('backup-1')
- resp, _ = self.servers_client.create_backup(self.server_id,
- 'daily',
- 2,
- backup1)
- oldest_backup_exist = True
-
- # the oldest one should be deleted automatically in this test
- def _clean_oldest_backup(oldest_backup):
- if oldest_backup_exist:
- try:
- self.images_client.delete_image(oldest_backup)
- except exceptions.NotFound:
- pass
- else:
- LOG.warning("Deletion of oldest backup %s should not have "
- "been successful as it should have been "
- "deleted during rotation." % oldest_backup)
-
- image1_id = data_utils.parse_image_id(resp['location'])
- self.addCleanup(_clean_oldest_backup, image1_id)
- self.assertEqual(202, resp.status)
- self.images_client.wait_for_image_status(image1_id, 'active')
-
- backup2 = data_utils.rand_name('backup-2')
- self.servers_client.wait_for_server_status(self.server_id, 'ACTIVE')
- resp, _ = self.servers_client.create_backup(self.server_id,
- 'daily',
- 2,
- backup2)
- image2_id = data_utils.parse_image_id(resp['location'])
- self.addCleanup(self.images_client.delete_image, image2_id)
- self.assertEqual(202, resp.status)
- self.images_client.wait_for_image_status(image2_id, 'active')
-
- # verify they have been created
- properties = {
- 'image_type': 'backup',
- 'backup_type': "daily",
- 'instance_uuid': self.server_id,
- }
- resp, image_list = self.images_client.image_list_detail(
- properties,
- sort_key='created_at',
- sort_dir='asc')
- self.assertEqual(200, resp.status)
- self.assertEqual(2, len(image_list))
- self.assertEqual((backup1, backup2),
- (image_list[0]['name'], image_list[1]['name']))
-
- # create the third one, due to the rotation is 2,
- # the first one will be deleted
- backup3 = data_utils.rand_name('backup-3')
- self.servers_client.wait_for_server_status(self.server_id, 'ACTIVE')
- resp, _ = self.servers_client.create_backup(self.server_id,
- 'daily',
- 2,
- backup3)
- image3_id = data_utils.parse_image_id(resp['location'])
- self.addCleanup(self.images_client.delete_image, image3_id)
- self.assertEqual(202, resp.status)
- # the first back up should be deleted
- self.images_client.wait_for_resource_deletion(image1_id)
- oldest_backup_exist = False
- resp, image_list = self.images_client.image_list_detail(
- properties,
- sort_key='created_at',
- sort_dir='asc')
- self.assertEqual(200, resp.status)
- self.assertEqual(2, len(image_list),
- 'Unexpected number of images for '
- 'v3:test_create_backup; was the oldest backup not '
- 'yet deleted? Image list: %s' %
- [image['name'] for image in image_list])
- self.assertEqual((backup2, backup3),
- (image_list[0]['name'], image_list[1]['name']))
-
- def _get_output(self):
- resp, output = self.servers_client.get_console_output(
- self.server_id, 10)
- self.assertEqual(200, resp.status)
- self.assertTrue(output, "Console output was empty.")
- lines = len(output.split('\n'))
- self.assertEqual(lines, 10)
-
- @testtools.skipUnless(CONF.compute_feature_enabled.console_output,
- 'Console output not supported.')
- @test.attr(type='gate')
- def test_get_console_output(self):
- # Positive test:Should be able to GET the console output
- # for a given server_id and number of lines
-
- # This reboot is necessary for outputting some console log after
- # creating a instance backup. If a instance backup, the console
- # log file is truncated and we cannot get any console log through
- # "console-log" API.
- # The detail is https://bugs.launchpad.net/nova/+bug/1251920
- resp, body = self.servers_client.reboot(self.server_id, 'HARD')
- self.assertEqual(202, resp.status)
- self.servers_client.wait_for_server_status(self.server_id, 'ACTIVE')
-
- self.wait_for(self._get_output)
-
- @testtools.skipUnless(CONF.compute_feature_enabled.console_output,
- 'Console output not supported.')
- @test.attr(type='gate')
- def test_get_console_output_server_id_in_shutoff_status(self):
- # Positive test:Should be able to GET the console output
- # for a given server_id in SHUTOFF status
-
- # NOTE: SHUTOFF is irregular status. To avoid test instability,
- # one server is created only for this test without using
- # the server that was created in setupClass.
- resp, server = self.create_test_server(wait_until='ACTIVE')
- temp_server_id = server['id']
-
- resp, server = self.servers_client.stop(temp_server_id)
- self.assertEqual(202, resp.status)
- self.servers_client.wait_for_server_status(temp_server_id, 'SHUTOFF')
-
- self.wait_for(self._get_output)
-
- @testtools.skipUnless(CONF.compute_feature_enabled.pause,
- 'Pause is not available.')
- @test.attr(type='gate')
- def test_pause_unpause_server(self):
- resp, server = self.client.pause_server(self.server_id)
- self.assertEqual(202, resp.status)
- self.client.wait_for_server_status(self.server_id, 'PAUSED')
- resp, server = self.client.unpause_server(self.server_id)
- self.assertEqual(202, resp.status)
- self.client.wait_for_server_status(self.server_id, 'ACTIVE')
-
- @testtools.skipUnless(CONF.compute_feature_enabled.suspend,
- 'Suspend is not available.')
- @test.attr(type='gate')
- def test_suspend_resume_server(self):
- resp, server = self.client.suspend_server(self.server_id)
- self.assertEqual(202, resp.status)
- self.client.wait_for_server_status(self.server_id, 'SUSPENDED')
- resp, server = self.client.resume_server(self.server_id)
- self.assertEqual(202, resp.status)
- self.client.wait_for_server_status(self.server_id, 'ACTIVE')
-
- @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
- 'Shelve is not available.')
- @test.attr(type='gate')
- def test_shelve_unshelve_server(self):
- resp, server = self.client.shelve_server(self.server_id)
- self.assertEqual(202, resp.status)
-
- offload_time = CONF.compute.shelved_offload_time
- if offload_time >= 0:
- self.client.wait_for_server_status(self.server_id,
- 'SHELVED_OFFLOADED',
- extra_timeout=offload_time)
- else:
- self.client.wait_for_server_status(self.server_id,
- 'SHELVED')
-
- resp, server = self.client.shelve_offload_server(self.server_id)
- self.assertEqual(202, resp.status)
- self.client.wait_for_server_status(self.server_id,
- 'SHELVED_OFFLOADED')
-
- resp, server = self.client.get_server(self.server_id)
- image_name = server['name'] + '-shelved'
- resp, images = self.images_client.image_list(name=image_name)
- self.assertEqual(1, len(images))
- self.assertEqual(image_name, images[0]['name'])
-
- resp, server = self.client.unshelve_server(self.server_id)
- self.assertEqual(202, resp.status)
- self.client.wait_for_server_status(self.server_id, 'ACTIVE')
-
- @test.attr(type='gate')
- def test_stop_start_server(self):
- resp, server = self.servers_client.stop(self.server_id)
- self.assertEqual(202, resp.status)
- self.servers_client.wait_for_server_status(self.server_id, 'SHUTOFF')
- resp, server = self.servers_client.start(self.server_id)
- self.assertEqual(202, resp.status)
- self.servers_client.wait_for_server_status(self.server_id, 'ACTIVE')
-
- @test.attr(type='gate')
- def test_lock_unlock_server(self):
- # Lock the server,try server stop(exceptions throw),unlock it and retry
- resp, server = self.servers_client.lock_server(self.server_id)
- self.assertEqual(202, resp.status)
- resp, server = self.servers_client.get_server(self.server_id)
- self.assertEqual(200, resp.status)
- self.assertEqual(server['status'], 'ACTIVE')
- # Locked server is not allowed to be stopped by non-admin user
- self.assertRaises(exceptions.Conflict,
- self.servers_client.stop, self.server_id)
- resp, server = self.servers_client.unlock_server(self.server_id)
- self.assertEqual(202, resp.status)
- resp, server = self.servers_client.stop(self.server_id)
- self.assertEqual(202, resp.status)
- self.servers_client.wait_for_server_status(self.server_id, 'SHUTOFF')
- resp, server = self.servers_client.start(self.server_id)
- self.assertEqual(202, resp.status)
- self.servers_client.wait_for_server_status(self.server_id, 'ACTIVE')
-
- def _validate_url(self, url):
- valid_scheme = ['http', 'https']
- parsed_url = urlparse.urlparse(url)
- self.assertNotEqual('None', parsed_url.hostname)
- self.assertIn(parsed_url.scheme, valid_scheme)
-
- @testtools.skipUnless(CONF.compute_feature_enabled.vnc_console,
- 'VNC Console feature is disabled')
- @test.attr(type='gate')
- def test_get_vnc_console(self):
- # Get the VNC console
- console_types = ['novnc', 'xvpvnc']
- for console_type in console_types:
- resp, body = self.servers_client.get_vnc_console(self.server_id,
- console_type)
- self.assertEqual(
- 200, resp.status,
- "Failed to get Console Type: %s" % (console_type))
- self.assertEqual(console_type, body['type'])
- self.assertNotEqual('', body['url'])
- self._validate_url(body['url'])
-
- @testtools.skipUnless(CONF.compute_feature_enabled.spice_console,
- 'Spice Console feature is disabled.')
- @test.attr(type='gate')
- def test_get_spice_console(self):
- # Get the Spice console of type "spice-html5"
- console_type = 'spice-html5'
- resp, body = self.servers_client.get_spice_console(self.server_id,
- console_type)
- self.assertEqual(200, resp.status)
- self.assertEqual(console_type, body['type'])
- self.assertNotEqual('', body['url'])
- self._validate_url(body['url'])
-
- @testtools.skipUnless(CONF.compute_feature_enabled.rdp_console,
- 'RDP Console feature is disabled.')
- @test.attr(type='gate')
- def test_get_rdp_console(self):
- # Get the RDP console of type "rdp-html5"
- console_type = 'rdp-html5'
- resp, body = self.servers_client.get_rdp_console(self.server_id,
- console_type)
- self.assertEqual(200, resp.status)
- self.assertEqual(console_type, body['type'])
- self.assertNotEqual('', body['url'])
- self._validate_url(body['url'])
diff --git a/tempest/api/compute/v3/servers/test_server_addresses.py b/tempest/api/compute/v3/servers/test_server_addresses.py
deleted file mode 100644
index 7b41d71..0000000
--- a/tempest/api/compute/v3/servers/test_server_addresses.py
+++ /dev/null
@@ -1,65 +0,0 @@
-# Copyright 2012 OpenStack Foundation
-# All Rights Reserved.
-#
-# 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.api.compute import base
-from tempest import test
-
-
-class ServerAddressesV3Test(base.BaseV3ComputeTest):
-
- @classmethod
- def resource_setup(cls):
- # This test module might use a network and a subnet
- cls.set_network_resources(network=True, subnet=True)
- super(ServerAddressesV3Test, cls).resource_setup()
- cls.client = cls.servers_client
-
- resp, cls.server = cls.create_test_server(wait_until='ACTIVE')
-
- @test.attr(type='smoke')
- def test_list_server_addresses(self):
- # All public and private addresses for
- # a server should be returned
-
- resp, addresses = self.client.list_addresses(self.server['id'])
- self.assertEqual('200', resp['status'])
-
- # We do not know the exact network configuration, but an instance
- # should at least have a single public or private address
- self.assertTrue(len(addresses) >= 1)
- for network_name, network_addresses in addresses.iteritems():
- self.assertTrue(len(network_addresses) >= 1)
- for address in network_addresses:
- self.assertTrue(address['addr'])
- self.assertTrue(address['version'])
-
- @test.attr(type='smoke')
- def test_list_server_addresses_by_network(self):
- # Providing a network type should filter
- # the addresses return by that type
-
- resp, addresses = self.client.list_addresses(self.server['id'])
-
- # Once again we don't know the environment's exact network config,
- # but the response for each individual network should be the same
- # as the partial result of the full address list
- id = self.server['id']
- for addr_type in addresses:
- resp, addr = self.client.list_addresses_by_network(id, addr_type)
- self.assertEqual('200', resp['status'])
-
- addr = addr[addr_type]
- for address in addresses[addr_type]:
- self.assertTrue(any([a for a in addr if a == address]))
diff --git a/tempest/api/compute/v3/servers/test_server_addresses_negative.py b/tempest/api/compute/v3/servers/test_server_addresses_negative.py
deleted file mode 100644
index 7a1b6fc..0000000
--- a/tempest/api/compute/v3/servers/test_server_addresses_negative.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright 2012 OpenStack Foundation
-# All Rights Reserved.
-#
-# 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.api.compute import base
-from tempest.common.utils import data_utils
-from tempest import exceptions
-from tempest import test
-
-
-class ServerAddressesV3NegativeTest(base.BaseV3ComputeTest):
- _interface = 'json'
-
- @classmethod
- def resource_setup(cls):
- # This test module might use a network and a subnet
- cls.set_network_resources(network=True, subnet=True)
- super(ServerAddressesV3NegativeTest, cls).resource_setup()
- cls.client = cls.servers_client
-
- resp, cls.server = cls.create_test_server(wait_until='ACTIVE')
-
- @test.attr(type=['negative', 'gate'])
- def test_list_server_addresses_nonexistent_server_id(self):
- # List addresses request should fail if server id not in system
- non_existent_server_id = data_utils.rand_uuid()
- self.assertRaises(exceptions.NotFound, self.client.list_addresses,
- non_existent_server_id)
-
- @test.attr(type=['negative', 'gate'])
- def test_list_server_addresses_by_network_neg(self):
- # List addresses by network should fail if network name not valid
- self.assertRaises(exceptions.NotFound,
- self.client.list_addresses_by_network,
- self.server['id'], 'invalid')
diff --git a/tempest/api/compute/v3/servers/test_server_metadata.py b/tempest/api/compute/v3/servers/test_server_metadata.py
deleted file mode 100644
index ccdfbad..0000000
--- a/tempest/api/compute/v3/servers/test_server_metadata.py
+++ /dev/null
@@ -1,115 +0,0 @@
-# Copyright 2012 OpenStack Foundation
-# All Rights Reserved.
-#
-# 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.api.compute import base
-from tempest import test
-
-
-class ServerMetadataV3Test(base.BaseV3ComputeTest):
-
- @classmethod
- def resource_setup(cls):
- super(ServerMetadataV3Test, cls).resource_setup()
- cls.client = cls.servers_client
- cls.quotas = cls.quotas_client
- resp, server = cls.create_test_server(meta={}, wait_until='ACTIVE')
- cls.server_id = server['id']
-
- def setUp(self):
- super(ServerMetadataV3Test, self).setUp()
- meta = {'key1': 'value1', 'key2': 'value2'}
- resp, _ = self.client.set_server_metadata(self.server_id, meta)
- self.assertEqual(resp.status, 200)
-
- @test.attr(type='gate')
- def test_list_server_metadata(self):
- # All metadata key/value pairs for a server should be returned
- resp, resp_metadata = self.client.list_server_metadata(self.server_id)
-
- # Verify the expected metadata items are in the list
- self.assertEqual(200, resp.status)
- expected = {'key1': 'value1', 'key2': 'value2'}
- self.assertEqual(expected, resp_metadata)
-
- @test.attr(type='gate')
- def test_set_server_metadata(self):
- # The server's metadata should be replaced with the provided values
- # Create a new set of metadata for the server
- req_metadata = {'meta2': 'data2', 'meta3': 'data3'}
- resp, metadata = self.client.set_server_metadata(self.server_id,
- req_metadata)
- self.assertEqual(200, resp.status)
-
- # Verify the expected values are correct, and that the
- # previous values have been removed
- resp, resp_metadata = self.client.list_server_metadata(self.server_id)
- self.assertEqual(resp_metadata, req_metadata)
-
- @test.attr(type='gate')
- def test_update_server_metadata(self):
- # The server's metadata values should be updated to the
- # provided values
- meta = {'key1': 'alt1', 'key3': 'value3'}
- resp, metadata = self.client.update_server_metadata(self.server_id,
- meta)
- self.assertEqual(201, resp.status)
-
- # Verify the values have been updated to the proper values
- resp, resp_metadata = self.client.list_server_metadata(self.server_id)
- expected = {'key1': 'alt1', 'key2': 'value2', 'key3': 'value3'}
- self.assertEqual(expected, resp_metadata)
-
- @test.attr(type='gate')
- def test_update_metadata_empty_body(self):
- # The original metadata should not be lost if empty metadata body is
- # passed
- meta = {}
- _, metadata = self.client.update_server_metadata(self.server_id, meta)
- resp, resp_metadata = self.client.list_server_metadata(self.server_id)
- expected = {'key1': 'value1', 'key2': 'value2'}
- self.assertEqual(expected, resp_metadata)
-
- @test.attr(type='gate')
- def test_get_server_metadata_item(self):
- # The value for a specific metadata key should be returned
- resp, meta = self.client.get_server_metadata_item(self.server_id,
- 'key2')
- self.assertEqual('value2', meta['key2'])
-
- @test.attr(type='gate')
- def test_set_server_metadata_item(self):
- # The item's value should be updated to the provided value
- # Update the metadata value
- meta = {'nova': 'alt'}
- resp, body = self.client.set_server_metadata_item(self.server_id,
- 'nova', meta)
- self.assertEqual(200, resp.status)
-
- # Verify the meta item's value has been updated
- resp, resp_metadata = self.client.list_server_metadata(self.server_id)
- expected = {'key1': 'value1', 'key2': 'value2', 'nova': 'alt'}
- self.assertEqual(expected, resp_metadata)
-
- @test.attr(type='gate')
- def test_delete_server_metadata_item(self):
- # The metadata value/key pair should be deleted from the server
- resp, meta = self.client.delete_server_metadata_item(self.server_id,
- 'key1')
- self.assertEqual(204, resp.status)
-
- # Verify the metadata item has been removed
- resp, resp_metadata = self.client.list_server_metadata(self.server_id)
- expected = {'key2': 'value2'}
- self.assertEqual(expected, resp_metadata)
diff --git a/tempest/api/compute/v3/servers/test_server_metadata_negative.py b/tempest/api/compute/v3/servers/test_server_metadata_negative.py
deleted file mode 100644
index 036b126..0000000
--- a/tempest/api/compute/v3/servers/test_server_metadata_negative.py
+++ /dev/null
@@ -1,155 +0,0 @@
-# Copyright 2014 NEC Corporation. All rights reserved.
-#
-# 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.api.compute import base
-from tempest.common.utils import data_utils
-from tempest import exceptions
-from tempest import test
-
-
-class ServerMetadataV3NegativeTest(base.BaseV3ComputeTest):
-
- @classmethod
- def resource_setup(cls):
- super(ServerMetadataV3NegativeTest, cls).resource_setup()
- cls.client = cls.servers_client
- cls.quotas = cls.quotas_client
- cls.tenant_id = cls.client.tenant_id
- resp, server = cls.create_test_server(meta={}, wait_until='ACTIVE')
-
- cls.server_id = server['id']
-
- @test.skip_because(bug="1273948")
- @test.attr(type=['gate', 'negative'])
- def test_server_create_metadata_key_too_long(self):
- # Attempt to start a server with a meta-data key that is > 255
- # characters
-
- # Tryset_server_metadata_item a few values
- for sz in [256, 257, 511, 1023]:
- key = "k" * sz
- meta = {key: 'data1'}
- self.assertRaises(exceptions.BadRequest,
- self.create_test_server,
- meta=meta)
-
- # no teardown - all creates should fail
-
- @test.attr(type=['negative', 'gate'])
- def test_create_server_metadata_blank_key(self):
- # Blank key should trigger an error.
- meta = {'': 'data1'}
- self.assertRaises(exceptions.BadRequest,
- self.create_test_server,
- meta=meta)
-
- @test.attr(type=['negative', 'gate'])
- def test_server_metadata_non_existent_server(self):
- # GET on a non-existent server should not succeed
- non_existent_server_id = data_utils.rand_uuid()
- self.assertRaises(exceptions.NotFound,
- self.client.get_server_metadata_item,
- non_existent_server_id,
- 'test2')
-
- @test.attr(type=['negative', 'gate'])
- def test_list_server_metadata_non_existent_server(self):
- # List metadata on a non-existent server should not succeed
- non_existent_server_id = data_utils.rand_uuid()
- self.assertRaises(exceptions.NotFound,
- self.client.list_server_metadata,
- non_existent_server_id)
-
- @test.attr(type=['negative', 'gate'])
- def test_wrong_key_passed_in_body(self):
- # Raise BadRequest if key in uri does not match
- # the key passed in body.
- meta = {'testkey': 'testvalue'}
- self.assertRaises(exceptions.BadRequest,
- self.client.set_server_metadata_item,
- self.server_id, 'key', meta)
-
- @test.attr(type=['negative', 'gate'])
- def test_set_metadata_non_existent_server(self):
- # Set metadata on a non-existent server should not succeed
- non_existent_server_id = data_utils.rand_uuid()
- meta = {'meta1': 'data1'}
- self.assertRaises(exceptions.NotFound,
- self.client.set_server_metadata,
- non_existent_server_id,
- meta)
-
- @test.attr(type=['negative', 'gate'])
- def test_update_metadata_non_existent_server(self):
- # An update should not happen for a non-existent server
- non_existent_server_id = data_utils.rand_uuid()
- meta = {'key1': 'value1', 'key2': 'value2'}
- self.assertRaises(exceptions.NotFound,
- self.client.update_server_metadata,
- non_existent_server_id,
- meta)
-
- @test.attr(type=['negative', 'gate'])
- def test_update_metadata_with_blank_key(self):
- # Blank key should trigger an error
- meta = {'': 'data1'}
- self.assertRaises(exceptions.BadRequest,
- self.client.update_server_metadata,
- self.server_id, meta=meta)
-
- @test.attr(type=['negative', 'gate'])
- def test_delete_metadata_non_existent_server(self):
- # Should not be able to delete metadata item from a non-existent server
- non_existent_server_id = data_utils.rand_uuid()
- self.assertRaises(exceptions.NotFound,
- self.client.delete_server_metadata_item,
- non_existent_server_id,
- 'd')
-
- @test.attr(type=['negative', 'gate'])
- def test_metadata_items_limit(self):
- # Raise a 413 OverLimit exception while exceeding metadata items limit
- # for tenant.
- _, quota_set = self.quotas.get_quota_set(self.tenant_id)
- quota_metadata = quota_set['metadata_items']
- req_metadata = {}
- for num in range(1, quota_metadata + 2):
- req_metadata['key' + str(num)] = 'val' + str(num)
- self.assertRaises(exceptions.OverLimit,
- self.client.set_server_metadata,
- self.server_id, req_metadata)
-
- # Raise a 413 OverLimit exception while exceeding metadata items limit
- # for tenant (update).
- self.assertRaises(exceptions.OverLimit,
- self.client.update_server_metadata,
- self.server_id, req_metadata)
-
- @test.attr(type=['negative', 'gate'])
- def test_set_server_metadata_blank_key(self):
- # Raise a bad request error for blank key.
- # set_server_metadata will replace all metadata with new value
- meta = {'': 'data1'}
- self.assertRaises(exceptions.BadRequest,
- self.client.set_server_metadata,
- self.server_id, meta=meta)
-
- @test.attr(type=['negative', 'gate'])
- def test_set_server_metadata_missing_metadata(self):
- # Raise a bad request error for a missing metadata field
- # set_server_metadata will replace all metadata with new value
- meta = {'meta1': 'data1'}
- self.assertRaises(exceptions.BadRequest,
- self.client.set_server_metadata,
- self.server_id, meta=meta, no_metadata_field=True)
diff --git a/tempest/api/compute/v3/servers/test_server_password.py b/tempest/api/compute/v3/servers/test_server_password.py
deleted file mode 100644
index bb0e310..0000000
--- a/tempest/api/compute/v3/servers/test_server_password.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# Copyright 2013 IBM Corporation
-# All Rights Reserved.
-#
-# 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.api.compute import base
-from tempest import test
-
-
-class ServerPasswordV3Test(base.BaseV3ComputeTest):
-
- @classmethod
- def resource_setup(cls):
- super(ServerPasswordV3Test, cls).resource_setup()
- cls.client = cls.servers_client
- resp, cls.server = cls.create_test_server(wait_until="ACTIVE")
-
- @test.attr(type='gate')
- def test_get_server_password(self):
- resp, body = self.client.get_password(self.server['id'])
- self.assertEqual(200, resp.status)
-
- @test.attr(type='gate')
- def test_delete_server_password(self):
- resp, body = self.client.delete_password(self.server['id'])
- self.assertEqual(204, resp.status)
diff --git a/tempest/api/compute/v3/servers/test_server_rescue.py b/tempest/api/compute/v3/servers/test_server_rescue.py
deleted file mode 100644
index ae21a7e..0000000
--- a/tempest/api/compute/v3/servers/test_server_rescue.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright 2013 Hewlett-Packard Development Company, L.P.
-# All Rights Reserved.
-#
-# 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.api.compute import base
-from tempest import config
-from tempest import test
-
-CONF = config.CONF
-
-
-class ServerRescueV3Test(base.BaseV3ComputeTest):
-
- @classmethod
- def resource_setup(cls):
- if not CONF.compute_feature_enabled.rescue:
- msg = "Server rescue not available."
- raise cls.skipException(msg)
- super(ServerRescueV3Test, cls).resource_setup()
-
- # Server for positive tests
- resp, server = cls.create_test_server(wait_until='BUILD')
- cls.server_id = server['id']
- cls.password = server['admin_password']
- cls.servers_client.wait_for_server_status(cls.server_id, 'ACTIVE')
-
- @test.attr(type='smoke')
- def test_rescue_unrescue_instance(self):
- resp, body = self.servers_client.rescue_server(
- self.server_id, admin_password=self.password)
- self.assertEqual(202, resp.status)
- self.servers_client.wait_for_server_status(self.server_id, 'RESCUE')
- resp, body = self.servers_client.unrescue_server(self.server_id)
- self.assertEqual(202, resp.status)
- self.servers_client.wait_for_server_status(self.server_id, 'ACTIVE')
diff --git a/tempest/api/compute/v3/servers/test_server_rescue_negative.py b/tempest/api/compute/v3/servers/test_server_rescue_negative.py
deleted file mode 100644
index db26298..0000000
--- a/tempest/api/compute/v3/servers/test_server_rescue_negative.py
+++ /dev/null
@@ -1,145 +0,0 @@
-# Copyright 2013 Hewlett-Packard Development Company, L.P.
-# Copyright 2014 NEC Corporation. All rights reserved.
-#
-# 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 testtools
-
-from tempest.api.compute import base
-from tempest.common.utils import data_utils
-from tempest import config
-from tempest import exceptions
-from tempest import test
-
-CONF = config.CONF
-
-
-class ServerRescueNegativeV3Test(base.BaseV3ComputeTest):
-
- @classmethod
- def resource_setup(cls):
- if not CONF.compute_feature_enabled.rescue:
- msg = "Server rescue not available."
- raise cls.skipException(msg)
-
- super(ServerRescueNegativeV3Test, cls).resource_setup()
- cls.device = CONF.compute.volume_device_name
-
- # Create a volume and wait for it to become ready for attach
- resp, cls.volume = cls.volumes_client.create_volume(
- 1, display_name=data_utils.rand_name(cls.__name__ + '_volume'))
- cls.volumes_client.wait_for_volume_status(
- cls.volume['id'], 'available')
-
- # Server for negative tests
- resp, server = cls.create_test_server(wait_until='BUILD')
- resp, resc_server = cls.create_test_server(wait_until='ACTIVE')
- cls.server_id = server['id']
- cls.password = server['admin_password']
- cls.rescue_id = resc_server['id']
- cls.rescue_password = resc_server['admin_password']
-
- cls.servers_client.rescue_server(
- cls.rescue_id, admin_password=cls.rescue_password)
- cls.servers_client.wait_for_server_status(cls.rescue_id, 'RESCUE')
- cls.servers_client.wait_for_server_status(cls.server_id, 'ACTIVE')
-
- @classmethod
- def resource_cleanup(cls):
- if hasattr(cls, 'volume'):
- cls.delete_volume(cls.volume['id'])
- super(ServerRescueNegativeV3Test, cls).resource_cleanup()
-
- def _detach(self, server_id, volume_id):
- self.servers_client.detach_volume(server_id, volume_id)
- self.volumes_client.wait_for_volume_status(volume_id,
- 'available')
-
- def _unrescue(self, server_id):
- resp, body = self.servers_client.unrescue_server(server_id)
- self.assertEqual(202, resp.status)
- self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
-
- def _unpause(self, server_id):
- resp, body = self.servers_client.unpause_server(server_id)
- self.assertEqual(202, resp.status)
- self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
-
- @testtools.skipUnless(CONF.compute_feature_enabled.pause,
- 'Pause is not available.')
- @test.attr(type=['negative', 'gate'])
- def test_rescue_paused_instance(self):
- # Rescue a paused server
- resp, body = self.servers_client.pause_server(
- self.server_id)
- self.addCleanup(self._unpause, self.server_id)
- self.assertEqual(202, resp.status)
- self.servers_client.wait_for_server_status(self.server_id, 'PAUSED')
- self.assertRaises(exceptions.Conflict,
- self.servers_client.rescue_server,
- self.server_id)
-
- @test.attr(type=['negative', 'gate'])
- def test_rescued_vm_reboot(self):
- self.assertRaises(exceptions.Conflict, self.servers_client.reboot,
- self.rescue_id, 'HARD')
-
- @test.attr(type=['negative', 'gate'])
- def test_rescue_non_existent_server(self):
- # Rescue a non-existing server
- self.assertRaises(exceptions.NotFound,
- self.servers_client.rescue_server,
- data_utils.rand_uuid())
-
- @test.attr(type=['negative', 'gate'])
- def test_rescued_vm_rebuild(self):
- self.assertRaises(exceptions.Conflict,
- self.servers_client.rebuild,
- self.rescue_id,
- self.image_ref_alt)
-
- @test.attr(type=['negative', 'gate'])
- def test_rescued_vm_attach_volume(self):
- # Rescue the server
- self.servers_client.rescue_server(self.server_id,
- admin_password=self.password)
- self.servers_client.wait_for_server_status(self.server_id, 'RESCUE')
- self.addCleanup(self._unrescue, self.server_id)
-
- # Attach the volume to the server
- self.assertRaises(exceptions.Conflict,
- self.servers_client.attach_volume,
- self.server_id,
- self.volume['id'],
- device='/dev/%s' % self.device)
-
- @test.attr(type=['negative', 'gate'])
- def test_rescued_vm_detach_volume(self):
- # Attach the volume to the server
- self.servers_client.attach_volume(self.server_id,
- self.volume['id'],
- device='/dev/%s' % self.device)
- self.volumes_client.wait_for_volume_status(self.volume['id'], 'in-use')
-
- # Rescue the server
- self.servers_client.rescue_server(self.server_id,
- admin_password=self.password)
- self.servers_client.wait_for_server_status(self.server_id, 'RESCUE')
- # addCleanup is a LIFO queue
- self.addCleanup(self._detach, self.server_id, self.volume['id'])
- self.addCleanup(self._unrescue, self.server_id)
-
- # Detach the volume from the server expecting failure
- self.assertRaises(exceptions.Conflict,
- self.servers_client.detach_volume,
- self.server_id,
- self.volume['id'])
diff --git a/tempest/api/compute/v3/servers/test_servers.py b/tempest/api/compute/v3/servers/test_servers.py
deleted file mode 100644
index e09f4a8..0000000
--- a/tempest/api/compute/v3/servers/test_servers.py
+++ /dev/null
@@ -1,113 +0,0 @@
-# Copyright 2012 OpenStack Foundation
-# All Rights Reserved.
-#
-# 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.api.compute import base
-from tempest.common.utils import data_utils
-from tempest import test
-
-
-class ServersV3Test(base.BaseV3ComputeTest):
-
- @classmethod
- def resource_setup(cls):
- super(ServersV3Test, cls).resource_setup()
- cls.client = cls.servers_client
-
- def tearDown(self):
- self.clear_servers()
- super(ServersV3Test, self).tearDown()
-
- @test.attr(type='gate')
- def test_create_server_with_admin_password(self):
- # If an admin password is provided on server creation, the server's
- # root password should be set to that password.
- resp, server = self.create_test_server(admin_password='testpassword')
-
- # Verify the password is set correctly in the response
- self.assertEqual('testpassword', server['admin_password'])
-
- @test.attr(type='gate')
- def test_create_with_existing_server_name(self):
- # Creating a server with a name that already exists is allowed
-
- # TODO(sdague): clear out try, we do cleanup one layer up
- server_name = data_utils.rand_name('server')
- resp, server = self.create_test_server(name=server_name,
- wait_until='ACTIVE')
- id1 = server['id']
- resp, server = self.create_test_server(name=server_name,
- wait_until='ACTIVE')
- id2 = server['id']
- self.assertNotEqual(id1, id2, "Did not create a new server")
- resp, server = self.client.get_server(id1)
- name1 = server['name']
- resp, server = self.client.get_server(id2)
- name2 = server['name']
- self.assertEqual(name1, name2)
-
- @test.attr(type='gate')
- def test_create_specify_keypair(self):
- # Specify a keypair while creating a server
-
- key_name = data_utils.rand_name('key')
- resp, keypair = self.keypairs_client.create_keypair(key_name)
- resp, body = self.keypairs_client.list_keypairs()
- resp, server = self.create_test_server(key_name=key_name)
- self.assertEqual('202', resp['status'])
- self.client.wait_for_server_status(server['id'], 'ACTIVE')
- resp, server = self.client.get_server(server['id'])
- self.assertEqual(key_name, server['key_name'])
-
- @test.attr(type='gate')
- def test_update_server_name(self):
- # The server name should be changed to the the provided value
- resp, server = self.create_test_server(wait_until='ACTIVE')
-
- # Update the server with a new name
- resp, server = self.client.update_server(server['id'],
- name='newname')
- self.assertEqual(200, resp.status)
- self.client.wait_for_server_status(server['id'], 'ACTIVE')
-
- # Verify the name of the server has changed
- resp, server = self.client.get_server(server['id'])
- self.assertEqual('newname', server['name'])
-
- @test.attr(type='gate')
- def test_update_access_server_address(self):
- # The server's access addresses should reflect the provided values
- resp, server = self.create_test_server(wait_until='ACTIVE')
-
- # Update the IPv4 and IPv6 access addresses
- resp, body = self.client.update_server(server['id'],
- access_ip_v4='1.1.1.1',
- access_ip_v6='::babe:202:202')
- self.assertEqual(200, resp.status)
- self.client.wait_for_server_status(server['id'], 'ACTIVE')
-
- # Verify the access addresses have been updated
- resp, server = self.client.get_server(server['id'])
- self.assertEqual('1.1.1.1', server['os-access-ips:access_ip_v4'])
- self.assertEqual('::babe:202:202',
- server['os-access-ips:access_ip_v6'])
-
- @test.attr(type='gate')
- def test_create_server_with_ipv6_addr_only(self):
- # Create a server without an IPv4 address(only IPv6 address).
- resp, server = self.create_test_server(access_ip_v6='2001:2001::3')
- self.assertEqual('202', resp['status'])
- self.client.wait_for_server_status(server['id'], 'ACTIVE')
- resp, server = self.client.get_server(server['id'])
- self.assertEqual('2001:2001::3', server['os-access-ips:access_ip_v6'])
diff --git a/tempest/api/compute/v3/servers/test_servers_negative.py b/tempest/api/compute/v3/servers/test_servers_negative.py
deleted file mode 100644
index 4b1fe04..0000000
--- a/tempest/api/compute/v3/servers/test_servers_negative.py
+++ /dev/null
@@ -1,451 +0,0 @@
-# Copyright 2012 OpenStack Foundation
-# All Rights Reserved.
-#
-# 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 base64
-import sys
-
-import testtools
-
-from tempest.api.compute import base
-from tempest import clients
-from tempest.common.utils import data_utils
-from tempest import config
-from tempest import exceptions
-from tempest import test
-
-CONF = config.CONF
-
-
-class ServersNegativeV3Test(base.BaseV3ComputeTest):
-
- def setUp(self):
- super(ServersNegativeV3Test, self).setUp()
- try:
- self.client.wait_for_server_status(self.server_id, 'ACTIVE')
- except Exception:
- self.__class__.server_id = self.rebuild_server(self.server_id)
-
- def tearDown(self):
- self.server_check_teardown()
- super(ServersNegativeV3Test, self).tearDown()
-
- @classmethod
- def resource_setup(cls):
- super(ServersNegativeV3Test, cls).resource_setup()
- cls.client = cls.servers_client
- cls.alt_os = clients.Manager(cls.isolated_creds.get_alt_creds())
- cls.alt_client = cls.alt_os.servers_v3_client
- resp, server = cls.create_test_server(wait_until='ACTIVE')
- cls.server_id = server['id']
-
- @test.attr(type=['negative', 'gate'])
- def test_server_name_blank(self):
- # Create a server with name parameter empty
-
- self.assertRaises(exceptions.BadRequest,
- self.create_test_server,
- name='')
-
- @test.attr(type=['negative', 'gate'])
- def test_create_with_invalid_image(self):
- # Create a server with an unknown image
-
- self.assertRaises(exceptions.BadRequest,
- self.create_test_server,
- image_id=-1)
-
- @test.attr(type=['negative', 'gate'])
- def test_create_with_invalid_flavor(self):
- # Create a server with an unknown flavor
-
- self.assertRaises(exceptions.BadRequest,
- self.create_test_server,
- flavor=-1,)
-
- @test.attr(type=['negative', 'gate'])
- def test_invalid_access_ip_v4_address(self):
- # An access IPv4 address must match a valid address pattern
-
- IPv4 = '1.1.1.1.1.1'
- self.assertRaises(exceptions.BadRequest,
- self.create_test_server, access_ip_v4=IPv4)
-
- @test.attr(type=['negative', 'gate'])
- def test_invalid_ip_v6_address(self):
- # An access IPv6 address must match a valid address pattern
-
- IPv6 = 'notvalid'
-
- self.assertRaises(exceptions.BadRequest,
- self.create_test_server, access_ip_v6=IPv6)
-
- @test.attr(type=['negative', 'gate'])
- def test_resize_nonexistent_server(self):
- # Resize a non-existent server
- nonexistent_server = data_utils.rand_uuid()
- self.assertRaises(exceptions.NotFound,
- self.client.resize,
- nonexistent_server, self.flavor_ref)
-
- @test.attr(type=['negative', 'gate'])
- def test_resize_server_with_non_existent_flavor(self):
- # Resize a server with non-existent flavor
- nonexistent_flavor = data_utils.rand_uuid()
- self.assertRaises(exceptions.BadRequest, self.client.resize,
- self.server_id, flavor_ref=nonexistent_flavor)
-
- @test.attr(type=['negative', 'gate'])
- def test_resize_server_with_null_flavor(self):
- # Resize a server with null flavor
- self.assertRaises(exceptions.BadRequest, self.client.resize,
- self.server_id, flavor_ref="")
-
- @test.attr(type=['negative', 'gate'])
- def test_reboot_non_existent_server(self):
- # Reboot a non existent server
- nonexistent_server = data_utils.rand_uuid()
- self.assertRaises(exceptions.NotFound, self.client.reboot,
- nonexistent_server, 'SOFT')
-
- @testtools.skipUnless(CONF.compute_feature_enabled.pause,
- 'Pause is not available.')
- @test.attr(type=['negative', 'gate'])
- def test_pause_paused_server(self):
- # Pause a paused server.
- self.client.pause_server(self.server_id)
- self.client.wait_for_server_status(self.server_id, 'PAUSED')
- self.assertRaises(exceptions.Conflict,
- self.client.pause_server,
- self.server_id)
- self.client.unpause_server(self.server_id)
-
- @test.attr(type=['negative', 'gate'])
- def test_rebuild_reboot_deleted_server(self):
- # Rebuild and Reboot a deleted server
- _, server = self.create_test_server()
- self.client.delete_server(server['id'])
- self.client.wait_for_server_termination(server['id'])
-
- self.assertRaises(exceptions.NotFound,
- self.client.rebuild,
- server['id'], self.image_ref_alt)
- self.assertRaises(exceptions.NotFound, self.client.reboot,
- server['id'], 'SOFT')
-
- @test.attr(type=['negative', 'gate'])
- def test_rebuild_non_existent_server(self):
- # Rebuild a non existent server
- nonexistent_server = data_utils.rand_uuid()
- meta = {'rebuild': 'server'}
- new_name = data_utils.rand_name('server')
- file_contents = 'Test server rebuild.'
- personality = [{'path': '/etc/rebuild.txt',
- 'contents': base64.b64encode(file_contents)}]
- self.assertRaises(exceptions.NotFound,
- self.client.rebuild,
- nonexistent_server,
- self.image_ref_alt,
- name=new_name, meta=meta,
- personality=personality,
- adminPass='rebuild')
-
- @test.attr(type=['negative', 'gate'])
- def test_create_numeric_server_name(self):
- # Create a server with a numeric name
- server_name = 12345
- self.assertRaises(exceptions.BadRequest,
- self.create_test_server,
- name=server_name)
-
- @test.attr(type=['negative', 'gate'])
- def test_create_server_name_length_exceeds_256(self):
- # Create a server with name length exceeding 256 characters
-
- server_name = 'a' * 256
- self.assertRaises(exceptions.BadRequest,
- self.create_test_server,
- name=server_name)
-
- @test.skip_because(bug="1208743")
- @test.attr(type=['negative', 'gate'])
- def test_create_with_invalid_network_uuid(self):
- # Pass invalid network uuid while creating a server
-
- networks = [{'fixed_ip': '10.0.1.1', 'uuid': 'a-b-c-d-e-f-g-h-i-j'}]
- self.assertRaises(exceptions.BadRequest,
- self.create_test_server,
- networks=networks)
-
- @test.attr(type=['negative', 'gate'])
- def test_create_with_non_existent_keypair(self):
- # Pass a non-existent keypair while creating a server
-
- key_name = data_utils.rand_name('key')
- self.assertRaises(exceptions.BadRequest,
- self.create_test_server,
- key_name=key_name)
-
- @test.skip_because(bug="1273948")
- @test.attr(type=['negative', 'gate'])
- def test_create_server_metadata_exceeds_length_limit(self):
- # Pass really long metadata while creating a server
-
- metadata = {'a': 'b' * 260}
- self.assertRaises(exceptions.BadRequest,
- self.create_test_server,
- meta=metadata)
-
- @test.attr(type=['negative', 'gate'])
- def test_update_name_of_non_existent_server(self):
- # Update name of a non-existent server
-
- server_name = data_utils.rand_name('server')
- new_name = data_utils.rand_name('server') + '_updated'
-
- self.assertRaises(exceptions.NotFound, self.client.update_server,
- server_name, name=new_name)
-
- @test.attr(type=['negative', 'gate'])
- def test_update_server_set_empty_name(self):
- # Update name of the server to an empty string
-
- server_name = data_utils.rand_name('server')
- new_name = ''
-
- self.assertRaises(exceptions.BadRequest, self.client.update_server,
- server_name, name=new_name)
-
- @test.attr(type=['negative', 'gate'])
- def test_update_server_of_another_tenant(self):
- # Update name of a server that belongs to another tenant
-
- new_name = self.server_id + '_new'
- self.assertRaises(exceptions.NotFound,
- self.alt_client.update_server, self.server_id,
- name=new_name)
-
- @test.attr(type=['negative', 'gate'])
- def test_update_server_name_length_exceeds_256(self):
- # Update name of server exceed the name length limit
-
- new_name = 'a' * 256
- self.assertRaises(exceptions.BadRequest,
- self.client.update_server,
- self.server_id,
- name=new_name)
-
- @test.attr(type=['negative', 'gate'])
- def test_delete_non_existent_server(self):
- # Delete a non existent server
-
- nonexistent_server = data_utils.rand_uuid()
- self.assertRaises(exceptions.NotFound, self.client.delete_server,
- nonexistent_server)
-
- @test.attr(type=['negative', 'gate'])
- def test_delete_a_server_of_another_tenant(self):
- # Delete a server that belongs to another tenant
- self.assertRaises(exceptions.NotFound,
- self.alt_client.delete_server,
- self.server_id)
-
- @test.attr(type=['negative', 'gate'])
- def test_delete_server_pass_negative_id(self):
- # Pass an invalid string parameter to delete server
-
- self.assertRaises(exceptions.NotFound, self.client.delete_server, -1)
-
- @test.attr(type=['negative', 'gate'])
- def test_delete_server_pass_id_exceeding_length_limit(self):
- # Pass a server ID that exceeds length limit to delete server
-
- self.assertRaises(exceptions.NotFound, self.client.delete_server,
- sys.maxint + 1)
-
- @test.attr(type=['negative', 'gate'])
- def test_create_with_nonexistent_security_group(self):
- # Create a server with a nonexistent security group
-
- security_groups = [{'name': 'does_not_exist'}]
- self.assertRaises(exceptions.BadRequest,
- self.create_test_server,
- security_groups=security_groups)
-
- @test.attr(type=['negative', 'gate'])
- def test_get_non_existent_server(self):
- # Get a non existent server details
- nonexistent_server = data_utils.rand_uuid()
- self.assertRaises(exceptions.NotFound, self.client.get_server,
- nonexistent_server)
-
- @test.attr(type=['negative', 'gate'])
- def test_stop_non_existent_server(self):
- # Stop a non existent server
- nonexistent_server = data_utils.rand_uuid()
- self.assertRaises(exceptions.NotFound, self.servers_client.stop,
- nonexistent_server)
-
- @test.attr(type=['negative', 'gate'])
- def test_pause_non_existent_server(self):
- # pause a non existent server
- nonexistent_server = data_utils.rand_uuid()
- self.assertRaises(exceptions.NotFound, self.client.pause_server,
- nonexistent_server)
-
- @test.attr(type=['negative', 'gate'])
- def test_unpause_non_existent_server(self):
- # unpause a non existent server
- nonexistent_server = data_utils.rand_uuid()
- self.assertRaises(exceptions.NotFound, self.client.unpause_server,
- nonexistent_server)
-
- @test.attr(type=['negative', 'gate'])
- def test_unpause_server_invalid_state(self):
- # unpause an active server.
- self.assertRaises(exceptions.Conflict,
- self.client.unpause_server,
- self.server_id)
-
- @testtools.skipUnless(CONF.compute_feature_enabled.suspend,
- 'Suspend is not available.')
- @test.attr(type=['negative', 'gate'])
- def test_suspend_non_existent_server(self):
- # suspend a non existent server
- nonexistent_server = data_utils.rand_uuid()
- self.assertRaises(exceptions.NotFound, self.client.suspend_server,
- nonexistent_server)
-
- @testtools.skipUnless(CONF.compute_feature_enabled.suspend,
- 'Suspend is not available.')
- @test.attr(type=['negative', 'gate'])
- def test_suspend_server_invalid_state(self):
- # suspend a suspended server.
- resp, _ = self.client.suspend_server(self.server_id)
- self.assertEqual(202, resp.status)
- self.client.wait_for_server_status(self.server_id, 'SUSPENDED')
- self.assertRaises(exceptions.Conflict,
- self.client.suspend_server,
- self.server_id)
- self.client.resume_server(self.server_id)
-
- @test.attr(type=['negative', 'gate'])
- def test_resume_non_existent_server(self):
- # resume a non existent server
- nonexistent_server = data_utils.rand_uuid()
- self.assertRaises(exceptions.NotFound, self.client.resume_server,
- nonexistent_server)
-
- @testtools.skipUnless(CONF.compute_feature_enabled.suspend,
- 'Suspend is not available.')
- @test.attr(type=['negative', 'gate'])
- def test_resume_server_invalid_state(self):
- # resume an active server.
- self.assertRaises(exceptions.Conflict,
- self.client.resume_server,
- self.server_id)
-
- @test.attr(type=['negative', 'gate'])
- def test_get_console_output_of_non_existent_server(self):
- # get the console output for a non existent server
- nonexistent_server = data_utils.rand_uuid()
- self.assertRaises(exceptions.NotFound,
- self.client.get_console_output,
- nonexistent_server, 10)
-
- @test.attr(type=['negative', 'gate'])
- def test_force_delete_nonexistent_server_id(self):
- # force-delete a non existent server
- nonexistent_server = data_utils.rand_uuid()
- self.assertRaises(exceptions.NotFound,
- self.client.force_delete_server,
- nonexistent_server)
-
- @test.attr(type=['negative', 'gate'])
- def test_force_delete_server_invalid_state(self):
- # we can only force-delete a server in 'soft-delete' state
- self.assertRaises(exceptions.Conflict,
- self.client.force_delete_server,
- self.server_id)
-
- @test.attr(type=['negative', 'gate'])
- def test_restore_nonexistent_server_id(self):
- # restore-delete a non existent server
- nonexistent_server = data_utils.rand_uuid()
- self.assertRaises(exceptions.NotFound,
- self.client.restore_soft_deleted_server,
- nonexistent_server)
-
- @test.attr(type=['negative', 'gate'])
- def test_restore_server_invalid_state(self):
- # we can only restore-delete a server in 'soft-delete' state
- self.assertRaises(exceptions.Conflict,
- self.client.restore_soft_deleted_server,
- self.server_id)
-
- @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
- 'Shelve is not available.')
- @test.attr(type=['negative', 'gate'])
- def test_shelve_non_existent_server(self):
- # shelve a non existent server
- nonexistent_server = data_utils.rand_uuid()
- self.assertRaises(exceptions.NotFound, self.client.shelve_server,
- nonexistent_server)
-
- @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
- 'Shelve is not available.')
- @test.attr(type=['negative', 'gate'])
- def test_shelve_shelved_server(self):
- # shelve a shelved server.
- resp, server = self.client.shelve_server(self.server_id)
- self.assertEqual(202, resp.status)
-
- offload_time = CONF.compute.shelved_offload_time
- if offload_time >= 0:
- self.client.wait_for_server_status(self.server_id,
- 'SHELVED_OFFLOADED',
- extra_timeout=offload_time)
- else:
- self.client.wait_for_server_status(self.server_id,
- 'SHELVED')
-
- resp, server = self.client.get_server(self.server_id)
- image_name = server['name'] + '-shelved'
- resp, images = self.images_client.image_list(name=image_name)
- self.assertEqual(1, len(images))
- self.assertEqual(image_name, images[0]['name'])
-
- self.assertRaises(exceptions.Conflict,
- self.client.shelve_server,
- self.server_id)
-
- self.client.unshelve_server(self.server_id)
-
- @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
- 'Shelve is not available.')
- @test.attr(type=['negative', 'gate'])
- def test_unshelve_non_existent_server(self):
- # unshelve a non existent server
- nonexistent_server = data_utils.rand_uuid()
- self.assertRaises(exceptions.NotFound, self.client.unshelve_server,
- nonexistent_server)
-
- @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
- 'Shelve is not available.')
- @test.attr(type=['negative', 'gate'])
- def test_unshelve_server_invalid_state(self):
- # unshelve an active server.
- self.assertRaises(exceptions.Conflict,
- self.client.unshelve_server,
- self.server_id)
diff --git a/tempest/api/compute/v3/test_extensions.py b/tempest/api/compute/v3/test_extensions.py
deleted file mode 100644
index 3c612df..0000000
--- a/tempest/api/compute/v3/test_extensions.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# Copyright 2012 OpenStack Foundation
-# All Rights Reserved.
-#
-# 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.api.compute import base
-from tempest import config
-from tempest.openstack.common import log as logging
-from tempest import test
-
-CONF = config.CONF
-
-LOG = logging.getLogger(__name__)
-
-
-class ExtensionsV3Test(base.BaseV3ComputeTest):
-
- @test.attr(type='gate')
- def test_list_extensions(self):
- # List of all extensions
- if len(CONF.compute_feature_enabled.api_v3_extensions) == 0:
- raise self.skipException('There are not any extensions configured')
- resp, extensions = self.extensions_client.list_extensions()
- self.assertEqual(200, resp.status)
- ext = CONF.compute_feature_enabled.api_v3_extensions[0]
- if ext == 'all':
- self.assertIn('Hosts', map(lambda x: x['name'], extensions))
- elif ext:
- self.assertIn(ext, map(lambda x: x['name'], extensions))
- else:
- raise self.skipException('There are not any extensions configured')
- # Log extensions list
- extension_list = map(lambda x: x['name'], extensions)
- LOG.debug("Nova extensions: %s" % ','.join(extension_list))
-
- @test.attr(type='gate')
- def test_get_extension(self):
- # get the specified extensions
- resp, extension = self.extensions_client.get_extension('servers')
- self.assertEqual(200, resp.status)
- self.assertEqual('servers', extension['alias'])
diff --git a/tempest/api/compute/v3/test_live_block_migration.py b/tempest/api/compute/v3/test_live_block_migration.py
deleted file mode 100644
index d6231b7..0000000
--- a/tempest/api/compute/v3/test_live_block_migration.py
+++ /dev/null
@@ -1,132 +0,0 @@
-# Copyright 2012 OpenStack Foundation
-# All Rights Reserved.
-#
-# 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 testtools
-
-from tempest.api.compute import base
-from tempest import config
-from tempest import test
-
-CONF = config.CONF
-
-
-class LiveBlockMigrationV3Test(base.BaseV3ComputeAdminTest):
- _host_key = 'os-extended-server-attributes:host'
-
- @classmethod
- def resource_setup(cls):
- super(LiveBlockMigrationV3Test, cls).resource_setup()
-
- cls.admin_hosts_client = cls.hosts_admin_client
- cls.admin_servers_client = cls.servers_admin_client
-
- cls.created_server_ids = []
-
- def _get_compute_hostnames(self):
- _resp, body = self.admin_hosts_client.list_hosts()
- return [
- host_record['host_name']
- for host_record in body
- if host_record['service'] == 'compute'
- ]
-
- def _get_server_details(self, server_id):
- _resp, body = self.admin_servers_client.get_server(server_id)
- return body
-
- def _get_host_for_server(self, server_id):
- return self._get_server_details(server_id)[self._host_key]
-
- def _migrate_server_to(self, server_id, dest_host):
- _resp, body = self.admin_servers_client.live_migrate_server(
- server_id, dest_host,
- CONF.compute_feature_enabled.
- block_migration_for_live_migration)
- return body
-
- def _get_host_other_than(self, host):
- for target_host in self._get_compute_hostnames():
- if host != target_host:
- return target_host
-
- def _get_server_status(self, server_id):
- return self._get_server_details(server_id)['status']
-
- def _get_an_active_server(self):
- for server_id in self.created_server_ids:
- if 'ACTIVE' == self._get_server_status(server_id):
- return server_id
- else:
- _, server = self.create_test_server(wait_until="ACTIVE")
- server_id = server['id']
- self.password = server['admin_password']
- self.password = 'password'
- self.created_server_ids.append(server_id)
- return server_id
-
- def _volume_clean_up(self, server_id, volume_id):
- resp, body = self.volumes_client.get_volume(volume_id)
- if body['status'] == 'in-use':
- self.servers_client.detach_volume(server_id, volume_id)
- self.volumes_client.wait_for_volume_status(volume_id, 'available')
- self.volumes_client.delete_volume(volume_id)
-
- @testtools.skipIf(not CONF.compute_feature_enabled.live_migration,
- 'Live migration not available')
- @test.attr(type='gate')
- def test_live_block_migration(self):
- # Live block migrate an instance to another host
- if len(self._get_compute_hostnames()) < 2:
- raise self.skipTest(
- "Less than 2 compute nodes, skipping migration test.")
- server_id = self._get_an_active_server()
- actual_host = self._get_host_for_server(server_id)
- target_host = self._get_host_other_than(actual_host)
- self._migrate_server_to(server_id, target_host)
- self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
- self.assertEqual(target_host, self._get_host_for_server(server_id))
-
- @testtools.skipIf(not CONF.compute_feature_enabled.live_migration or not
- CONF.compute_feature_enabled.
- block_migration_for_live_migration,
- 'Block Live migration not available')
- @testtools.skipIf(not CONF.compute_feature_enabled.
- block_migrate_cinder_iscsi,
- 'Block Live migration not configured for iSCSI')
- @test.attr(type='gate')
- def test_iscsi_volume(self):
- # Live block migrate an instance to another host
- if len(self._get_compute_hostnames()) < 2:
- raise self.skipTest(
- "Less than 2 compute nodes, skipping migration test.")
- server_id = self._get_an_active_server()
- actual_host = self._get_host_for_server(server_id)
- target_host = self._get_host_other_than(actual_host)
-
- resp, volume = self.volumes_client.create_volume(1,
- display_name='test')
-
- self.volumes_client.wait_for_volume_status(volume['id'],
- 'available')
- self.addCleanup(self._volume_clean_up, server_id, volume['id'])
-
- # Attach the volume to the server
- self.servers_client.attach_volume(server_id, volume['id'],
- device='/dev/xvdb')
- self.volumes_client.wait_for_volume_status(volume['id'], 'in-use')
-
- self._migrate_server_to(server_id, target_host)
- self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
- self.assertEqual(target_host, self._get_host_for_server(server_id))
diff --git a/tempest/api/compute/v3/test_live_block_migration_negative.py b/tempest/api/compute/v3/test_live_block_migration_negative.py
deleted file mode 100644
index 93127f3..0000000
--- a/tempest/api/compute/v3/test_live_block_migration_negative.py
+++ /dev/null
@@ -1,53 +0,0 @@
-# Copyright 2012 OpenStack Foundation
-# All Rights Reserved.
-#
-# 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.api.compute import base
-from tempest.common.utils import data_utils
-from tempest import config
-from tempest import exceptions
-from tempest import test
-
-CONF = config.CONF
-
-
-class LiveBlockMigrationV3NegativeTest(base.BaseV3ComputeAdminTest):
- _host_key = 'os-extended-server-attributes:host'
-
- @classmethod
- def resource_setup(cls):
- super(LiveBlockMigrationV3NegativeTest, cls).resource_setup()
- if not CONF.compute_feature_enabled.live_migration:
- raise cls.skipException("Live migration is not enabled")
-
- cls.admin_hosts_client = cls.hosts_admin_client
- cls.admin_servers_client = cls.servers_admin_client
-
- def _migrate_server_to(self, server_id, dest_host):
- _resp, body = self.admin_servers_client.live_migrate_server(
- server_id, dest_host,
- CONF.compute_feature_enabled.
- block_migration_for_live_migration)
- return body
-
- @test.attr(type=['negative', 'gate'])
- def test_invalid_host_for_migration(self):
- # Migrating to an invalid host should not change the status
- target_host = data_utils.rand_name('host-')
- _, server = self.create_test_server(wait_until="ACTIVE")
- server_id = server['id']
- self.assertRaises(exceptions.BadRequest, self._migrate_server_to,
- server_id, target_host)
- self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
diff --git a/tempest/api/compute/v3/test_quotas.py b/tempest/api/compute/v3/test_quotas.py
deleted file mode 100644
index f6d8b3f..0000000
--- a/tempest/api/compute/v3/test_quotas.py
+++ /dev/null
@@ -1,76 +0,0 @@
-# Copyright 2012 OpenStack Foundation
-# All Rights Reserved.
-#
-# 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.api.compute import base
-from tempest.common import tempest_fixtures as fixtures
-from tempest import test
-
-
-class QuotasV3Test(base.BaseV3ComputeTest):
-
- def setUp(self):
- # NOTE(mriedem): Avoid conflicts with os-quota-class-sets tests.
- self.useFixture(fixtures.LockFixture('compute_quotas'))
- super(QuotasV3Test, self).setUp()
-
- @classmethod
- def resource_setup(cls):
- super(QuotasV3Test, cls).resource_setup()
- cls.client = cls.quotas_client
- cls.tenant_id = cls.client.tenant_id
- cls.user_id = cls.client.user_id
- cls.default_quota_set = set(('metadata_items',
- 'ram', 'floating_ips',
- 'fixed_ips', 'key_pairs',
- 'instances', 'security_group_rules',
- 'cores', 'security_groups'))
-
- @test.attr(type='smoke')
- def test_get_quotas(self):
- # User can get the quota set for it's tenant
- expected_quota_set = self.default_quota_set | set(['id'])
- resp, quota_set = self.client.get_quota_set(self.tenant_id)
- self.assertEqual(200, resp.status)
- self.assertEqual(sorted(expected_quota_set),
- sorted(quota_set.keys()))
- self.assertEqual(quota_set['id'], self.tenant_id)
-
- # get the quota set using user id
- resp, quota_set = self.client.get_quota_set(self.tenant_id,
- self.user_id)
- self.assertEqual(200, resp.status)
- self.assertEqual(sorted(expected_quota_set),
- sorted(quota_set.keys()))
- self.assertEqual(quota_set['id'], self.tenant_id)
-
- @test.attr(type='smoke')
- def test_get_default_quotas(self):
- # User can get the default quota set for it's tenant
- expected_quota_set = self.default_quota_set | set(['id'])
- resp, quota_set = self.client.get_default_quota_set(self.tenant_id)
- self.assertEqual(200, resp.status)
- self.assertEqual(sorted(expected_quota_set),
- sorted(quota_set.keys()))
- self.assertEqual(quota_set['id'], self.tenant_id)
-
- @test.attr(type='smoke')
- def test_compare_tenant_quotas_with_default_quotas(self):
- # Tenants are created with the default quota values
- resp, defualt_quota_set = \
- self.client.get_default_quota_set(self.tenant_id)
- self.assertEqual(200, resp.status)
- resp, tenant_quota_set = self.client.get_quota_set(self.tenant_id)
- self.assertEqual(200, resp.status)
- self.assertEqual(defualt_quota_set, tenant_quota_set)
diff --git a/tempest/api/compute/v3/test_version.py b/tempest/api/compute/v3/test_version.py
deleted file mode 100644
index 1a74e35..0000000
--- a/tempest/api/compute/v3/test_version.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright 2014 NEC Corporation.
-# All Rights Reserved.
-#
-# 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.api.compute import base
-from tempest import test
-
-
-class VersionV3Test(base.BaseV3ComputeTest):
-
- @test.attr(type='gate')
- def test_version(self):
- # Get version information
- resp, version = self.version_client.get_version()
- self.assertEqual(200, resp.status)
- self.assertIn("id", version)
- self.assertEqual("v3.0", version["id"])
diff --git a/tempest/api/network/test_dhcp_ipv6.py b/tempest/api/network/test_dhcp_ipv6.py
new file mode 100644
index 0000000..5bc63d0
--- /dev/null
+++ b/tempest/api/network/test_dhcp_ipv6.py
@@ -0,0 +1,389 @@
+# Copyright 2014 OpenStack Foundation
+# All Rights Reserved.
+#
+# 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 netaddr
+import random
+
+from tempest.api.network import base
+from tempest.common.utils import data_utils
+from tempest import config
+from tempest import exceptions
+
+CONF = config.CONF
+
+
+class NetworksTestDHCPv6(base.BaseNetworkTest):
+ _interface = 'json'
+ _ip_version = 6
+
+ """ Test DHCPv6 specific features using SLAAC, stateless and
+ stateful settings for subnets. Also it shall check dual-stack
+ functionality (IPv4 + IPv6 together).
+ The tests include:
+ generating of SLAAC EUI-64 address in subnets with various settings
+ receiving SLAAC addresses in combinations of various subnets
+ receiving stateful IPv6 addresses
+ addressing in subnets with router
+ """
+
+ @classmethod
+ def resource_setup(cls):
+ msg = None
+ if not CONF.network_feature_enabled.ipv6:
+ msg = "IPv6 is not enabled"
+ elif not CONF.network_feature_enabled.ipv6_subnet_attributes:
+ msg = "DHCPv6 attributes are not enabled."
+ if msg:
+ raise cls.skipException(msg)
+ super(NetworksTestDHCPv6, cls).resource_setup()
+ cls.network = cls.create_network()
+
+ def _remove_from_list_by_index(self, things_list, elem):
+ for index, i in enumerate(things_list):
+ if i['id'] == elem['id']:
+ break
+ del things_list[index]
+
+ def _clean_network(self):
+ resp, body = self.client.list_ports()
+ ports = body['ports']
+ for port in ports:
+ if (port['device_owner'] == 'network:router_interface'
+ and port['device_id'] in [r['id'] for r in self.routers]):
+ self.client.remove_router_interface_with_port_id(
+ port['device_id'], port['id']
+ )
+ else:
+ if port['id'] in [p['id'] for p in self.ports]:
+ self.client.delete_port(port['id'])
+ self._remove_from_list_by_index(self.ports, port)
+ resp, body = self.client.list_subnets()
+ subnets = body['subnets']
+ for subnet in subnets:
+ if subnet['id'] in [s['id'] for s in self.subnets]:
+ self.client.delete_subnet(subnet['id'])
+ self._remove_from_list_by_index(self.subnets, subnet)
+ resp, body = self.client.list_routers()
+ routers = body['routers']
+ for router in routers:
+ if router['id'] in [r['id'] for r in self.routers]:
+ self.client.delete_router(router['id'])
+ self._remove_from_list_by_index(self.routers, router)
+
+ def _get_ips_from_subnet(self, **kwargs):
+ subnet = self.create_subnet(self.network, **kwargs)
+ port_mac = data_utils.rand_mac_address()
+ port = self.create_port(self.network, mac_address=port_mac)
+ real_ip = next(iter(port['fixed_ips']), None)['ip_address']
+ eui_ip = data_utils.get_ipv6_addr_by_EUI64(subnet['cidr'],
+ port_mac).format()
+ return real_ip, eui_ip
+
+ def test_dhcpv6_stateless_eui64(self):
+ """When subnets configured with RAs SLAAC (AOM=100) and DHCP stateless
+ (AOM=110) both for radvd and dnsmasq, port shall receive IP address
+ calculated from its MAC.
+ """
+ for ra_mode, add_mode in (
+ ('slaac', 'slaac'),
+ ('dhcpv6-stateless', 'dhcpv6-stateless'),
+ ):
+ kwargs = {'ipv6_ra_mode': ra_mode,
+ 'ipv6_address_mode': add_mode}
+ real_ip, eui_ip = self._get_ips_from_subnet(**kwargs)
+ self._clean_network()
+ self.assertEqual(eui_ip, real_ip,
+ ('Real port IP is %s, but shall be %s when '
+ 'ipv6_ra_mode=%s and ipv6_address_mode=%s') % (
+ real_ip, eui_ip, ra_mode, add_mode))
+
+ def test_dhcpv6_stateless_no_ra(self):
+ """When subnets configured with dnsmasq SLAAC and DHCP stateless
+ and there is no radvd, port shall receive IP address calculated
+ from its MAC and mask of subnet.
+ """
+ for ra_mode, add_mode in (
+ (None, 'slaac'),
+ (None, 'dhcpv6-stateless'),
+ ):
+ kwargs = {'ipv6_ra_mode': ra_mode,
+ 'ipv6_address_mode': add_mode}
+ kwargs = {k: v for k, v in kwargs.iteritems() if v}
+ real_ip, eui_ip = self._get_ips_from_subnet(**kwargs)
+ self._clean_network()
+ self.assertEqual(eui_ip, real_ip,
+ ('Real port IP %s shall be equal to EUI-64 %s'
+ 'when ipv6_ra_mode=%s,ipv6_address_mode=%s') % (
+ real_ip, eui_ip,
+ ra_mode if ra_mode else "Off",
+ add_mode if add_mode else "Off"))
+
+ def test_dhcpv6_invalid_options(self):
+ """Different configurations for radvd and dnsmasq are not allowed"""
+ for ra_mode, add_mode in (
+ ('dhcpv6-stateless', 'dhcpv6-stateful'),
+ ('dhcpv6-stateless', 'slaac'),
+ ('slaac', 'dhcpv6-stateful'),
+ ('dhcpv6-stateful', 'dhcpv6-stateless'),
+ ('dhcpv6-stateful', 'slaac'),
+ ('slaac', 'dhcpv6-stateless'),
+ ):
+ kwargs = {'ipv6_ra_mode': ra_mode,
+ 'ipv6_address_mode': add_mode}
+ self.assertRaises(exceptions.BadRequest,
+ self.create_subnet,
+ self.network,
+ **kwargs)
+
+ def test_dhcpv6_stateless_no_ra_no_dhcp(self):
+ """If no radvd option and no dnsmasq option is configured
+ port shall receive IP from fixed IPs list of subnet.
+ """
+ real_ip, eui_ip = self._get_ips_from_subnet()
+ self._clean_network()
+ self.assertNotEqual(eui_ip, real_ip,
+ ('Real port IP %s equal to EUI-64 %s when '
+ 'ipv6_ra_mode=Off and ipv6_address_mode=Off,'
+ 'but shall be taken from fixed IPs') % (
+ real_ip, eui_ip))
+
+ def test_dhcpv6_two_subnets(self):
+ """When one IPv6 subnet configured with dnsmasq SLAAC or DHCP stateless
+ and other IPv6 is with DHCP stateful, port shall receive EUI-64 IP
+ addresses from first subnet and DHCP address from second one.
+ Order of subnet creating should be unimportant.
+ """
+ for order in ("slaac_first", "dhcp_first"):
+ for ra_mode, add_mode in (
+ ('slaac', 'slaac'),
+ ('dhcpv6-stateless', 'dhcpv6-stateless'),
+ ):
+ kwargs = {'ipv6_ra_mode': ra_mode,
+ 'ipv6_address_mode': add_mode}
+ kwargs_dhcp = {'ipv6_address_mode': 'dhcpv6-stateful'}
+ if order == "slaac_first":
+ subnet_slaac = self.create_subnet(self.network, **kwargs)
+ subnet_dhcp = self.create_subnet(
+ self.network, **kwargs_dhcp)
+ else:
+ subnet_dhcp = self.create_subnet(
+ self.network, **kwargs_dhcp)
+ subnet_slaac = self.create_subnet(self.network, **kwargs)
+ port_mac = data_utils.rand_mac_address()
+ dhcp_ip = subnet_dhcp["allocation_pools"][0]["start"]
+ eui_ip = data_utils.get_ipv6_addr_by_EUI64(
+ subnet_slaac['cidr'],
+ port_mac
+ ).format()
+ # TODO(sergsh): remove this when 1219795 is fixed
+ dhcp_ip = [dhcp_ip, (netaddr.IPAddress(dhcp_ip) + 1).format()]
+ port = self.create_port(self.network, mac_address=port_mac)
+ real_ips = dict([(k['subnet_id'], k['ip_address'])
+ for k in port['fixed_ips']])
+ real_dhcp_ip, real_eui_ip = [real_ips[sub['id']]
+ for sub in subnet_dhcp,
+ subnet_slaac]
+ self.client.delete_port(port['id'])
+ self.ports.pop()
+ _, body = self.client.list_ports()
+ ports_id_list = [i['id'] for i in body['ports']]
+ self.assertNotIn(port['id'], ports_id_list)
+ self._clean_network()
+ self.assertEqual(real_eui_ip,
+ eui_ip,
+ 'Real IP is {0}, but shall be {1}'.format(
+ real_eui_ip,
+ eui_ip))
+ self.assertIn(
+ real_dhcp_ip, dhcp_ip,
+ 'Real IP is {0}, but shall be one from {1}'.format(
+ real_dhcp_ip,
+ str(dhcp_ip)))
+
+ def test_dhcpv6_64_subnets(self):
+ """When one IPv6 subnet configured with dnsmasq SLAAC or DHCP stateless
+ and other IPv4 is with DHCP of IPv4, port shall receive EUI-64 IP
+ addresses from first subnet and IPv4 DHCP address from second one.
+ Order of subnet creating should be unimportant.
+ """
+ for order in ("slaac_first", "dhcp_first"):
+ for ra_mode, add_mode in (
+ ('slaac', 'slaac'),
+ ('dhcpv6-stateless', 'dhcpv6-stateless'),
+ ):
+ kwargs = {'ipv6_ra_mode': ra_mode,
+ 'ipv6_address_mode': add_mode}
+ if order == "slaac_first":
+ subnet_slaac = self.create_subnet(self.network, **kwargs)
+ subnet_dhcp = self.create_subnet(
+ self.network, ip_version=4)
+ else:
+ subnet_dhcp = self.create_subnet(
+ self.network, ip_version=4)
+ subnet_slaac = self.create_subnet(self.network, **kwargs)
+ port_mac = data_utils.rand_mac_address()
+ dhcp_ip = subnet_dhcp["allocation_pools"][0]["start"]
+ eui_ip = data_utils.get_ipv6_addr_by_EUI64(
+ subnet_slaac['cidr'],
+ port_mac
+ ).format()
+ # TODO(sergsh): remove this when 1219795 is fixed
+ dhcp_ip = [dhcp_ip, (netaddr.IPAddress(dhcp_ip) + 1).format()]
+ port = self.create_port(self.network, mac_address=port_mac)
+ real_ips = dict([(k['subnet_id'], k['ip_address'])
+ for k in port['fixed_ips']])
+ real_dhcp_ip, real_eui_ip = [real_ips[sub['id']]
+ for sub in subnet_dhcp,
+ subnet_slaac]
+ self._clean_network()
+ self.assertTrue({real_eui_ip,
+ real_dhcp_ip}.issubset([eui_ip] + dhcp_ip))
+ self.assertEqual(real_eui_ip,
+ eui_ip,
+ 'Real IP is {0}, but shall be {1}'.format(
+ real_eui_ip,
+ eui_ip))
+ self.assertIn(
+ real_dhcp_ip, dhcp_ip,
+ 'Real IP is {0}, but shall be one from {1}'.format(
+ real_dhcp_ip,
+ str(dhcp_ip)))
+
+ def test_dhcp_stateful(self):
+ """With all options below, DHCPv6 shall allocate first
+ address from subnet pool to port.
+ """
+ for ra_mode, add_mode in (
+ ('dhcpv6-stateful', 'dhcpv6-stateful'),
+ ('dhcpv6-stateful', None),
+ (None, 'dhcpv6-stateful'),
+ ):
+ kwargs = {'ipv6_ra_mode': ra_mode,
+ 'ipv6_address_mode': add_mode}
+ kwargs = {k: v for k, v in kwargs.iteritems() if v}
+ subnet = self.create_subnet(self.network, **kwargs)
+ port = self.create_port(self.network)
+ port_ip = next(iter(port['fixed_ips']), None)['ip_address']
+ dhcp_ip = subnet["allocation_pools"][0]["start"]
+ # TODO(sergsh): remove this when 1219795 is fixed
+ dhcp_ip = [dhcp_ip, (netaddr.IPAddress(dhcp_ip) + 1).format()]
+ self._clean_network()
+ self.assertIn(
+ port_ip, dhcp_ip,
+ 'Real IP is {0}, but shall be one from {1}'.format(
+ port_ip,
+ str(dhcp_ip)))
+
+ def test_dhcp_stateful_fixedips(self):
+ """With all options below, port shall be able to get
+ requested IP from fixed IP range not depending on
+ DHCP stateful (not SLAAC!) settings configured.
+ """
+ for ra_mode, add_mode in (
+ ('dhcpv6-stateful', 'dhcpv6-stateful'),
+ ('dhcpv6-stateful', None),
+ (None, 'dhcpv6-stateful'),
+ ):
+ kwargs = {'ipv6_ra_mode': ra_mode,
+ 'ipv6_address_mode': add_mode}
+ kwargs = {k: v for k, v in kwargs.iteritems() if v}
+ subnet = self.create_subnet(self.network, **kwargs)
+ ip_range = netaddr.IPRange(subnet["allocation_pools"][0]["start"],
+ subnet["allocation_pools"][0]["end"])
+ ip = netaddr.IPAddress(random.randrange(ip_range.first,
+ ip_range.last)).format()
+ port = self.create_port(self.network,
+ fixed_ips=[{'subnet_id': subnet['id'],
+ 'ip_address': ip}])
+ port_ip = next(iter(port['fixed_ips']), None)['ip_address']
+ self._clean_network()
+ self.assertEqual(port_ip, ip,
+ ("Port IP %s is not as fixed IP from "
+ "port create request: %s") % (
+ port_ip, ip))
+
+ def test_dhcp_stateful_fixedips_outrange(self):
+ """When port gets IP address from fixed IP range it
+ shall be checked if it's from subnets range.
+ """
+ kwargs = {'ipv6_ra_mode': 'dhcpv6-stateful',
+ 'ipv6_address_mode': 'dhcpv6-stateful'}
+ subnet = self.create_subnet(self.network, **kwargs)
+ ip_range = netaddr.IPRange(subnet["allocation_pools"][0]["start"],
+ subnet["allocation_pools"][0]["end"])
+ ip = netaddr.IPAddress(random.randrange(
+ ip_range.last + 1, ip_range.last + 10)).format()
+ self.assertRaisesRegexp(exceptions.BadRequest,
+ "not a valid IP for the defined subnet",
+ self.create_port,
+ self.network,
+ fixed_ips=[{'subnet_id': subnet['id'],
+ 'ip_address': ip}])
+
+ def test_dhcp_stateful_fixedips_duplicate(self):
+ """When port gets IP address from fixed IP range it
+ shall be checked if it's not duplicate.
+ """
+ kwargs = {'ipv6_ra_mode': 'dhcpv6-stateful',
+ 'ipv6_address_mode': 'dhcpv6-stateful'}
+ subnet = self.create_subnet(self.network, **kwargs)
+ ip_range = netaddr.IPRange(subnet["allocation_pools"][0]["start"],
+ subnet["allocation_pools"][0]["end"])
+ ip = netaddr.IPAddress(random.randrange(
+ ip_range.first, ip_range.last)).format()
+ self.create_port(self.network,
+ fixed_ips=[
+ {'subnet_id': subnet['id'],
+ 'ip_address': ip}])
+ self.assertRaisesRegexp(exceptions.Conflict,
+ "object with that identifier already exists",
+ self.create_port,
+ self.network,
+ fixed_ips=[{'subnet_id': subnet['id'],
+ 'ip_address': ip}])
+
+ def _create_subnet_router(self, kwargs):
+ subnet = self.create_subnet(self.network, **kwargs)
+ router = self.create_router(
+ router_name=data_utils.rand_name("routerv6-"),
+ admin_state_up=True)
+ port = self.create_router_interface(router['id'],
+ subnet['id'])
+ _, body = self.client.show_port(port['port_id'])
+ return subnet, body['port']
+
+ def test_dhcp_stateful_router(self):
+ """With all options below the router interface shall
+ receive DHCPv6 IP address from allocation pool.
+ """
+ for ra_mode, add_mode in (
+ ('dhcpv6-stateful', 'dhcpv6-stateful'),
+ ('dhcpv6-stateful', None),
+ (None, 'dhcpv6-stateful'),
+ ):
+ kwargs = {'ipv6_ra_mode': ra_mode,
+ 'ipv6_address_mode': add_mode}
+ kwargs = {k: v for k, v in kwargs.iteritems() if v}
+ subnet, port = self._create_subnet_router(kwargs)
+ port_ip = next(iter(port['fixed_ips']), None)['ip_address']
+ self._clean_network()
+ self.assertEqual(port_ip, subnet['gateway_ip'],
+ ("Port IP %s is not as first IP from "
+ "subnets allocation pool: %s") % (
+ port_ip, subnet['gateway_ip']))
+
+ def tearDown(self):
+ self._clean_network()
+ super(NetworksTestDHCPv6, self).tearDown()
diff --git a/tempest/api/network/test_ports.py b/tempest/api/network/test_ports.py
index 9cd5e2e..d919f2e 100644
--- a/tempest/api/network/test_ports.py
+++ b/tempest/api/network/test_ports.py
@@ -220,6 +220,22 @@
self.assertEqual(free_mac_address,
show_port['mac_address'])
+ @test.attr(type='smoke')
+ def test_create_port_with_no_securitygroups(self):
+ port = self.create_port(self.create_network(), security_groups=[])
+ self.assertIsNotNone(port['security_groups'])
+ self.assertEmpty(port['security_groups'])
+
+ @test.attr(type='smoke')
+ def test_update_port_with_no_securitygroups(self):
+ port = self.create_port(self.create_network())
+ # Verify that port is created with default security group
+ self.assertIsNotNone(port['security_groups'])
+ self.assertNotEmpty(port['security_groups'])
+ updated_port = self.update_port(port, security_groups=[])
+ self.assertIsNotNone(updated_port['security_groups'])
+ self.assertEmpty(updated_port['security_groups'])
+
class PortsAdminExtendedAttrsTestJSON(base.BaseAdminNetworkTest):
_interface = 'json'
diff --git a/tempest/api_schema/request/compute/v3/__init__.py b/tempest/api_schema/request/compute/v3/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/api_schema/request/compute/v3/__init__.py
+++ /dev/null
diff --git a/tempest/api_schema/request/compute/v3/flavors.py b/tempest/api_schema/request/compute/v3/flavors.py
deleted file mode 100644
index b913aca..0000000
--- a/tempest/api_schema/request/compute/v3/flavors.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# (c) 2014 Deutsche Telekom AG
-# 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 copy
-
-from tempest.api_schema.request.compute import flavors
-
-flavors_details = copy.deepcopy(flavors.common_flavor_details)
-
-flavor_list = copy.deepcopy(flavors.common_flavor_list)
-
-flavor_list["json-schema"]["properties"] = {
- "min_ram": {
- "type": "integer",
- "results": {
- "gen_none": 400,
- "gen_string": 400
- }
- },
- "min_disk": {
- "type": "integer",
- "results": {
- "gen_none": 400,
- "gen_string": 400
- }
- }
-}
diff --git a/tempest/api_schema/response/compute/v3/__init__.py b/tempest/api_schema/response/compute/v3/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/api_schema/response/compute/v3/__init__.py
+++ /dev/null
diff --git a/tempest/api_schema/response/compute/v3/agents.py b/tempest/api_schema/response/compute/v3/agents.py
deleted file mode 100644
index 9ef05df..0000000
--- a/tempest/api_schema/response/compute/v3/agents.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright 2014 NEC Corporation. All rights reserved.
-#
-# 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.api_schema.response.compute import agents
-
-create_agent = {
- 'status_code': [201],
- 'response_body': agents.common_create_agent
-}
-
-delete_agent = {
- 'status_code': [204]
-}
diff --git a/tempest/api_schema/response/compute/v3/aggregates.py b/tempest/api_schema/response/compute/v3/aggregates.py
deleted file mode 100644
index e3bae13..0000000
--- a/tempest/api_schema/response/compute/v3/aggregates.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright 2014 NEC Corporation. All rights reserved.
-#
-# 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 copy
-
-from tempest.api_schema.response.compute import aggregates
-
-delete_aggregate = {
- 'status_code': [204]
-}
-
-create_aggregate = copy.deepcopy(aggregates.common_create_aggregate)
-# V3 API's response status_code is 201
-create_aggregate['status_code'] = [201]
-
-aggregate_add_remove_host = copy.deepcopy(aggregates.aggregate_add_remove_host)
-# V3 API's response status_code is 202
-aggregate_add_remove_host['status_code'] = [202]
diff --git a/tempest/api_schema/response/compute/v3/availability_zone.py b/tempest/api_schema/response/compute/v3/availability_zone.py
deleted file mode 100644
index dbb1d41..0000000
--- a/tempest/api_schema/response/compute/v3/availability_zone.py
+++ /dev/null
@@ -1,53 +0,0 @@
-# Copyright 2014 NEC Corporation. All rights reserved.
-#
-# 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 copy
-
-from tempest.api_schema.response.compute import availability_zone as common
-
-
-base = {
- 'status_code': [200],
- 'response_body': {
- 'type': 'object',
- 'properties': {
- 'availability_zone_info': {
- 'type': 'array',
- 'items': {
- 'type': 'object',
- 'properties': {
- 'zone_name': {'type': 'string'},
- 'zone_state': {
- 'type': 'object',
- 'properties': {
- 'available': {'type': 'boolean'}
- },
- 'required': ['available']
- },
- # NOTE: Here is the difference between detail and
- # non-detail
- 'hosts': {'type': 'null'}
- },
- 'required': ['zone_name', 'zone_state', 'hosts']
- }
- }
- },
- 'required': ['availability_zone_info']
- }
-}
-
-get_availability_zone_list = copy.deepcopy(base)
-get_availability_zone_list_detail = copy.deepcopy(base)
-get_availability_zone_list_detail['response_body']['properties'][
- 'availability_zone_info']['items']['properties']['hosts'] = common.detail
diff --git a/tempest/api_schema/response/compute/v3/certificates.py b/tempest/api_schema/response/compute/v3/certificates.py
deleted file mode 100644
index c768391..0000000
--- a/tempest/api_schema/response/compute/v3/certificates.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright 2014 NEC Corporation. All rights reserved.
-#
-# 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 copy
-
-from tempest.api_schema.response.compute import certificates
-
-create_certificate = copy.deepcopy(certificates._common_schema)
-create_certificate['status_code'] = [201]
diff --git a/tempest/api_schema/response/compute/v3/extensions.py b/tempest/api_schema/response/compute/v3/extensions.py
deleted file mode 100644
index ceb0ce2..0000000
--- a/tempest/api_schema/response/compute/v3/extensions.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright 2014 NEC Corporation. All rights reserved.
-#
-# 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.
-
-list_extensions = {
- 'status_code': [200],
- 'response_body': {
- 'type': 'object',
- 'properties': {
- 'extensions': {
- 'type': 'array',
- 'items': {
- 'type': 'object',
- 'properties': {
- 'name': {'type': 'string'},
- 'alias': {'type': 'string'},
- 'description': {'type': 'string'},
- 'version': {'type': 'integer'}
- },
- 'required': ['name', 'alias', 'description', 'version']
- }
- }
- },
- 'required': ['extensions']
- }
-}
diff --git a/tempest/api_schema/response/compute/v3/flavors.py b/tempest/api_schema/response/compute/v3/flavors.py
deleted file mode 100644
index d6c2c85..0000000
--- a/tempest/api_schema/response/compute/v3/flavors.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# Copyright 2014 NEC Corporation. All rights reserved.
-#
-# 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 copy
-
-from tempest.api_schema.response.compute import flavors
-from tempest.api_schema.response.compute import flavors_extra_specs
-
-list_flavors_details = copy.deepcopy(flavors.common_flavor_list_details)
-
-# NOTE- In v3 API, 'swap' comes as '0' not empty string '""'
-# (In V2 API, it comes as empty string) So leaving 'swap'as integer type only.
-
-# Defining extra attributes for V3 flavor schema
-list_flavors_details['response_body']['properties']['flavors']['items'][
- 'properties'].update({'disabled': {'type': 'boolean'},
- 'ephemeral': {'type': 'integer'},
- 'flavor-access:is_public': {'type': 'boolean'},
- 'os-flavor-rxtx:rxtx_factor': {'type': 'number'}})
-# 'flavor-access' and 'os-flavor-rxtx' are API extensions.
-# So they are not 'required'.
-list_flavors_details['response_body']['properties']['flavors']['items'][
- 'required'].extend(['disabled', 'ephemeral'])
-
-set_flavor_extra_specs = copy.deepcopy(flavors_extra_specs.flavor_extra_specs)
-set_flavor_extra_specs['status_code'] = [201]
-
-unset_flavor_extra_specs = {
- 'status_code': [204]
-}
-
-get_flavor_details = copy.deepcopy(flavors.common_flavor_details)
-
-# NOTE- In v3 API, 'swap' comes as '0' not empty string '""'
-# (In V2 API, it comes as empty string) So leaving 'swap'as integer type only.
-
-# Defining extra attributes for V3 flavor schema
-get_flavor_details['response_body']['properties']['flavor'][
- 'properties'].update({'disabled': {'type': 'boolean'},
- 'ephemeral': {'type': 'integer'},
- 'flavor-access:is_public': {'type': 'boolean'},
- 'os-flavor-rxtx:rxtx_factor': {'type': 'number'}})
-
-# 'flavor-access' and 'os-flavor-rxtx' are API extensions.
-# So they are not 'required'.
-get_flavor_details['response_body']['properties']['flavor'][
- 'required'].extend(['disabled', 'ephemeral'])
-
-
-create_flavor_details = copy.deepcopy(get_flavor_details)
-
-# Overriding the status code for create flavor V3 API.
-create_flavor_details['status_code'] = [201]
-
-delete_flavor = {
- 'status_code': [204]
-}
diff --git a/tempest/api_schema/response/compute/v3/hosts.py b/tempest/api_schema/response/compute/v3/hosts.py
deleted file mode 100644
index f356371..0000000
--- a/tempest/api_schema/response/compute/v3/hosts.py
+++ /dev/null
@@ -1,53 +0,0 @@
-# Copyright 2014 NEC Corporation. All rights reserved.
-#
-# 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 copy
-
-from tempest.api_schema.response.compute import hosts
-
-startup_host = {
- 'status_code': [200],
- 'response_body': {
- 'type': 'object',
- 'properties': {
- 'host': hosts.common_start_up_body
- },
- 'required': ['host']
- }
-}
-
-# The 'power_action' attribute of 'shutdown_host' API is 'shutdown'
-shutdown_host = copy.deepcopy(startup_host)
-
-shutdown_host['response_body']['properties']['power_action'] = {
- 'enum': ['shutdown']
-}
-
-# The 'power_action' attribute of 'reboot_host' API is 'reboot'
-reboot_host = copy.deepcopy(startup_host)
-
-reboot_host['response_body']['properties']['power_action'] = {
- 'enum': ['reboot']
-}
-
-update_host = {
- 'status_code': [200],
- 'response_body': {
- 'type': 'object',
- 'properties': {
- 'host': hosts.update_host_common
- },
- 'required': ['host']
- }
-}
diff --git a/tempest/api_schema/response/compute/v3/hypervisors.py b/tempest/api_schema/response/compute/v3/hypervisors.py
deleted file mode 100644
index b36ae7e..0000000
--- a/tempest/api_schema/response/compute/v3/hypervisors.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# Copyright 2014 NEC Corporation. All rights reserved.
-#
-# 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 copy
-
-from tempest.api_schema.response.compute import hypervisors
-
-
-list_hypervisors_detail = copy.deepcopy(
- hypervisors.common_list_hypervisors_detail)
-# Defining extra attributes for V3 show hypervisor schema
-list_hypervisors_detail['response_body']['properties']['hypervisors'][
- 'items']['properties']['os-pci:pci_stats'] = {'type': 'array'}
-
-show_hypervisor = copy.deepcopy(hypervisors.common_show_hypervisor)
-# Defining extra attributes for V3 show hypervisor schema
-show_hypervisor['response_body']['properties']['hypervisor']['properties'][
- 'os-pci:pci_stats'] = {'type': 'array'}
-
-hypervisors_servers = copy.deepcopy(hypervisors.common_hypervisors_info)
-
-# Defining extra attributes for V3 show hypervisor schema
-hypervisors_servers['response_body']['properties']['hypervisor']['properties'][
- 'servers'] = {
- 'type': 'array',
- 'items': {
- 'type': 'object',
- 'properties': {
- # NOTE: Now the type of 'id' is integer,
- # but here allows 'string' also because we
- # will be able to change it to 'uuid' in
- # the future.
- 'id': {'type': ['integer', 'string']},
- 'name': {'type': 'string'}
- }
- }
- }
-# V3 API response body always contains the 'servers' attribute even there
-# is no server (VM) are present on Hypervisor host.
-hypervisors_servers['response_body']['properties']['hypervisor'][
- 'required'] = ['id', 'hypervisor_hostname', 'servers']
diff --git a/tempest/api_schema/response/compute/v3/interfaces.py b/tempest/api_schema/response/compute/v3/interfaces.py
deleted file mode 100644
index 7f716ee..0000000
--- a/tempest/api_schema/response/compute/v3/interfaces.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright 2014 NEC Corporation. All rights reserved.
-#
-# 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.api_schema.response.compute import interfaces as common_schema
-
-list_interfaces = {
- 'status_code': [200],
- 'response_body': {
- 'type': 'object',
- 'properties': {
- 'interface_attachments': {
- 'type': 'array',
- 'items': common_schema.interface_common_info
- }
- },
- 'required': ['interface_attachments']
- }
-}
diff --git a/tempest/api_schema/response/compute/v3/keypairs.py b/tempest/api_schema/response/compute/v3/keypairs.py
deleted file mode 100644
index ea15405..0000000
--- a/tempest/api_schema/response/compute/v3/keypairs.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright 2014 NEC Corporation. All rights reserved.
-#
-# 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.api_schema.response.compute import keypairs
-
-get_keypair = {
- 'status_code': [200],
- 'response_body': {
- 'type': 'object',
- 'properties': {
- 'keypair': {
- 'type': 'object',
- 'properties': {
- 'public_key': {'type': 'string'},
- 'name': {'type': 'string'},
- 'fingerprint': {'type': 'string'}
- },
- 'required': ['public_key', 'name', 'fingerprint']
- }
- },
- 'required': ['keypair']
- }
-}
-
-create_keypair = {
- 'status_code': [201],
- 'response_body': keypairs.create_keypair
-}
-
-delete_keypair = {
- 'status_code': [204],
-}
diff --git a/tempest/api_schema/response/compute/v3/quotas.py b/tempest/api_schema/response/compute/v3/quotas.py
deleted file mode 100644
index 85ed3b3..0000000
--- a/tempest/api_schema/response/compute/v3/quotas.py
+++ /dev/null
@@ -1,59 +0,0 @@
-# Copyright 2014 NEC Corporation. All rights reserved.
-#
-# 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 copy
-
-from tempest.api_schema.response.compute import quotas
-
-quota_set = copy.deepcopy(quotas.common_quota_set)
-quota_set['response_body']['properties']['quota_set']['properties'][
- 'id'] = {'type': 'string'}
-quota_set['response_body']['properties']['quota_set'][
- 'required'].extend(['id'])
-
-quota_common_info = {
- 'type': 'object',
- 'properties': {
- 'reserved': {'type': 'integer'},
- 'limit': {'type': 'integer'},
- 'in_use': {'type': 'integer'}
- },
- 'required': ['reserved', 'limit', 'in_use']
-}
-
-quota_set_detail = copy.deepcopy(quotas.common_quota_set)
-quota_set_detail['response_body']['properties']['quota_set']['properties'][
- 'id'] = {'type': 'string'}
-quota_set_detail['response_body']['properties']['quota_set']['properties'][
- 'instances'] = quota_common_info
-quota_set_detail['response_body']['properties']['quota_set']['properties'][
- 'cores'] = quota_common_info
-quota_set_detail['response_body']['properties']['quota_set']['properties'][
- 'ram'] = quota_common_info
-quota_set_detail['response_body']['properties']['quota_set']['properties'][
- 'floating_ips'] = quota_common_info
-quota_set_detail['response_body']['properties']['quota_set']['properties'][
- 'fixed_ips'] = quota_common_info
-quota_set_detail['response_body']['properties']['quota_set']['properties'][
- 'metadata_items'] = quota_common_info
-quota_set_detail['response_body']['properties']['quota_set']['properties'][
- 'key_pairs'] = quota_common_info
-quota_set_detail['response_body']['properties']['quota_set']['properties'][
- 'security_groups'] = quota_common_info
-quota_set_detail['response_body']['properties']['quota_set']['properties'][
- 'security_group_rules'] = quota_common_info
-
-delete_quota = {
- 'status_code': [204]
-}
diff --git a/tempest/api_schema/response/compute/v3/servers.py b/tempest/api_schema/response/compute/v3/servers.py
deleted file mode 100644
index d0edd44..0000000
--- a/tempest/api_schema/response/compute/v3/servers.py
+++ /dev/null
@@ -1,210 +0,0 @@
-# Copyright 2014 NEC Corporation. All rights reserved.
-#
-# 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 copy
-
-from tempest.api_schema.response.compute import parameter_types
-from tempest.api_schema.response.compute import servers
-
-create_server = {
- 'status_code': [202],
- 'response_body': {
- 'type': 'object',
- 'properties': {
- 'server': {
- 'type': 'object',
- 'properties': {
- 'id': {'type': 'string'},
- 'os-security-groups:security_groups': {'type': 'array'},
- 'links': parameter_types.links,
- 'os-access-ips:access_ip_v4': parameter_types.access_ip_v4,
- 'os-access-ips:access_ip_v6': parameter_types.access_ip_v6
- },
- # NOTE: os-access-ips:access_ip_v4/v6 are API extension,
- # and some environments return a response without these
- # attributes. So they are not 'required'.
- 'required': ['id', 'os-security-groups:security_groups',
- 'links']
- }
- },
- 'required': ['server']
- }
-}
-
-create_server_with_admin_pass = copy.deepcopy(create_server)
-create_server_with_admin_pass['response_body']['properties']['server'][
- 'properties'].update({'admin_password': {'type': 'string'}})
-create_server_with_admin_pass['response_body']['properties']['server'][
- 'required'].append('admin_password')
-
-addresses_v3 = copy.deepcopy(parameter_types.addresses)
-addresses_v3['patternProperties']['^[a-zA-Z0-9-_.]+$']['items'][
- 'properties'].update({
- 'type': {'type': 'string'},
- 'mac_addr': {'type': 'string'}
- })
-addresses_v3['patternProperties']['^[a-zA-Z0-9-_.]+$']['items'][
- 'required'].extend(['type', 'mac_addr'])
-
-update_server = copy.deepcopy(servers.base_update_get_server)
-update_server['response_body']['properties']['server']['properties'].update({
- 'addresses': addresses_v3,
- 'host_id': {'type': 'string'},
- 'os-access-ips:access_ip_v4': parameter_types.access_ip_v4,
- 'os-access-ips:access_ip_v6': parameter_types.access_ip_v6
-})
-update_server['response_body']['properties']['server']['required'].append(
- # NOTE: os-access-ips:access_ip_v4/v6 are API extension,
- # and some environments return a response without these
- # attributes. So they are not 'required'.
- 'host_id'
-)
-
-get_server = copy.deepcopy(servers.base_update_get_server)
-get_server['response_body']['properties']['server']['properties'].update({
- 'key_name': {'type': ['string', 'null']},
- 'host_id': {'type': 'string'},
-
- # NOTE: Non-admin users also can see "os-server-usage" and
- # "os-extended-availability-zone" attributes.
- 'os-server-usage:launched_at': {'type': ['string', 'null']},
- 'os-server-usage:terminated_at': {'type': ['string', 'null']},
- 'os-extended-availability-zone:availability_zone': {'type': 'string'},
-
- # NOTE: Admin users only can see "os-extended-status" and
- # "os-extended-server-attributes" attributes.
- 'os-extended-status:task_state': {'type': ['string', 'null']},
- 'os-extended-status:vm_state': {'type': 'string'},
- 'os-extended-status:power_state': {'type': 'integer'},
- 'os-extended-status:locked_by': {'type': ['string', 'null']},
- 'os-extended-server-attributes:host': {'type': ['string', 'null']},
- 'os-extended-server-attributes:instance_name': {'type': 'string'},
- 'os-extended-server-attributes:hypervisor_hostname': {
- 'type': ['string', 'null']
- },
- 'os-extended-volumes:volumes_attached': {'type': 'array'},
- 'os-pci:pci_devices': {'type': 'array'},
- 'os-access-ips:access_ip_v4': parameter_types.access_ip_v4,
- 'os-access-ips:access_ip_v6': parameter_types.access_ip_v6,
- 'os-config-drive:config_drive': {'type': 'string'}
-})
-get_server['response_body']['properties']['server']['required'].append(
- # NOTE: os-server-usage, os-extended-availability-zone,
- # os-extended-status, os-extended-server-attributes,
- # os-extended-volumes, os-pci, os-access-ips and
- # os-config-driveare API extension, and some environments
- # return a response without these attributes. So they are not 'required'.
- 'host_id'
-)
-
-attach_detach_volume = {
- 'status_code': [202]
-}
-
-set_get_server_metadata_item = copy.deepcopy(servers.set_server_metadata)
-
-list_addresses_by_network = {
- 'status_code': [200],
- 'response_body': addresses_v3
-}
-
-server_actions_change_password = copy.deepcopy(
- servers.server_actions_delete_password)
-
-list_addresses = {
- 'status_code': [200],
- 'response_body': {
- 'type': 'object',
- 'properties': {
- 'addresses': addresses_v3
- },
- 'required': ['addresses']
- }
-}
-
-update_server_metadata = copy.deepcopy(servers.update_server_metadata)
-# V3 API's response status_code is 201
-update_server_metadata['status_code'] = [201]
-
-server_actions_object = copy.deepcopy(servers.common_instance_actions)
-server_actions_object['properties'].update({'server_uuid': {'type': 'string'}})
-server_actions_object['required'].extend(['server_uuid'])
-
-list_server_actions = {
- 'status_code': [200],
- 'response_body': {
- 'type': 'object',
- 'properties': {
- 'server_actions': {
- 'type': 'array',
- 'items': server_actions_object
- }
- },
- 'required': ['server_actions']
- }
-}
-
-get_server_actions_object = copy.deepcopy(servers.common_get_instance_action)
-get_server_actions_object[
- 'properties'].update({'server_uuid': {'type': 'string'}})
-get_server_actions_object['required'].extend(['server_uuid'])
-
-get_server_action = {
- 'status_code': [200],
- 'response_body': {
- 'type': 'object',
- 'properties': {
- 'server_action': get_server_actions_object
- },
- 'required': ['server_action']
- }
-}
-
-list_servers_detail = copy.deepcopy(servers.base_list_servers_detail)
-list_servers_detail['response_body']['properties']['servers']['items'][
- 'properties'].update({
- 'addresses': addresses_v3,
- 'host_id': {'type': 'string'},
- 'os-access-ips:access_ip_v4': parameter_types.access_ip_v4,
- 'os-access-ips:access_ip_v6': parameter_types.access_ip_v6
- })
-# NOTE(GMann): os-access-ips:access_ip_v4/v6 are API extension,
-# and some environments return a response without these
-# attributes. So they are not 'required'.
-list_servers_detail['response_body']['properties']['servers']['items'][
- 'required'].append('host_id')
-
-rebuild_server = copy.deepcopy(update_server)
-rebuild_server['status_code'] = [202]
-
-rebuild_server_with_admin_pass = copy.deepcopy(rebuild_server)
-rebuild_server_with_admin_pass['response_body']['properties']['server'][
- 'properties'].update({'admin_password': {'type': 'string'}})
-rebuild_server_with_admin_pass['response_body']['properties']['server'][
- 'required'].append('admin_password')
-
-rescue_server_with_admin_pass = {
- 'status_code': [202],
- 'response_body': {
- 'type': 'object',
- 'properties': {
- 'admin_password': {'type': 'string'}
- },
- 'required': ['admin_password']
- }
-}
-
-rescue_server = copy.deepcopy(rescue_server_with_admin_pass)
-del rescue_server['response_body']['properties']
-del rescue_server['response_body']['required']
diff --git a/tempest/clients.py b/tempest/clients.py
index 91dc5f7..261b27c 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -59,33 +59,6 @@
TenantUsagesClientJSON
from tempest.services.compute.json.volumes_extensions_client import \
VolumesExtensionsClientJSON
-from tempest.services.compute.v3.json.agents_client import AgentsV3ClientJSON
-from tempest.services.compute.v3.json.aggregates_client import \
- AggregatesV3ClientJSON
-from tempest.services.compute.v3.json.availability_zone_client import \
- AvailabilityZoneV3ClientJSON
-from tempest.services.compute.v3.json.certificates_client import \
- CertificatesV3ClientJSON
-from tempest.services.compute.v3.json.extensions_client import \
- ExtensionsV3ClientJSON
-from tempest.services.compute.v3.json.flavors_client import FlavorsV3ClientJSON
-from tempest.services.compute.v3.json.hosts_client import HostsV3ClientJSON
-from tempest.services.compute.v3.json.hypervisor_client import \
- HypervisorV3ClientJSON
-from tempest.services.compute.v3.json.interfaces_client import \
- InterfacesV3ClientJSON
-from tempest.services.compute.v3.json.keypairs_client import \
- KeyPairsV3ClientJSON
-from tempest.services.compute.v3.json.migration_client import \
- MigrationsV3ClientJSON
-from tempest.services.compute.v3.json.quotas_client import \
- QuotasV3ClientJSON
-from tempest.services.compute.v3.json.servers_client import \
- ServersV3ClientJSON
-from tempest.services.compute.v3.json.services_client import \
- ServicesV3ClientJSON
-from tempest.services.compute.v3.json.version_client import \
- VersionV3ClientJSON
from tempest.services.data_processing.v1_1.client import DataProcessingClient
from tempest.services.database.json.flavors_client import \
DatabaseFlavorsClientJSON
@@ -224,45 +197,28 @@
def _set_compute_json_clients(self):
self.certificates_client = CertificatesClientJSON(self.auth_provider)
- self.certificates_v3_client = CertificatesV3ClientJSON(
- self.auth_provider)
self.servers_client = ServersClientJSON(self.auth_provider)
- self.servers_v3_client = ServersV3ClientJSON(self.auth_provider)
self.limits_client = LimitsClientJSON(self.auth_provider)
self.images_client = ImagesClientJSON(self.auth_provider)
self.keypairs_client = KeyPairsClientJSON(self.auth_provider)
- self.keypairs_v3_client = KeyPairsV3ClientJSON(self.auth_provider)
self.quotas_client = QuotasClientJSON(self.auth_provider)
self.quota_classes_client = QuotaClassesClientJSON(self.auth_provider)
- self.quotas_v3_client = QuotasV3ClientJSON(self.auth_provider)
self.flavors_client = FlavorsClientJSON(self.auth_provider)
- self.flavors_v3_client = FlavorsV3ClientJSON(self.auth_provider)
self.extensions_client = ExtensionsClientJSON(self.auth_provider)
- self.extensions_v3_client = ExtensionsV3ClientJSON(self.auth_provider)
self.volumes_extensions_client = VolumesExtensionsClientJSON(
self.auth_provider)
self.floating_ips_client = FloatingIPsClientJSON(self.auth_provider)
self.security_groups_client = SecurityGroupsClientJSON(
self.auth_provider)
self.interfaces_client = InterfacesClientJSON(self.auth_provider)
- self.interfaces_v3_client = InterfacesV3ClientJSON(self.auth_provider)
self.fixed_ips_client = FixedIPsClientJSON(self.auth_provider)
self.availability_zone_client = AvailabilityZoneClientJSON(
self.auth_provider)
- self.availability_zone_v3_client = AvailabilityZoneV3ClientJSON(
- self.auth_provider)
- self.services_v3_client = ServicesV3ClientJSON(self.auth_provider)
- self.agents_v3_client = AgentsV3ClientJSON(self.auth_provider)
self.aggregates_client = AggregatesClientJSON(self.auth_provider)
- self.aggregates_v3_client = AggregatesV3ClientJSON(self.auth_provider)
self.services_client = ServicesClientJSON(self.auth_provider)
self.tenant_usages_client = TenantUsagesClientJSON(self.auth_provider)
- self.version_v3_client = VersionV3ClientJSON(self.auth_provider)
- self.migrations_v3_client = MigrationsV3ClientJSON(self.auth_provider)
self.hosts_client = HostsClientJSON(self.auth_provider)
- self.hosts_v3_client = HostsV3ClientJSON(self.auth_provider)
self.hypervisor_client = HypervisorClientJSON(self.auth_provider)
- self.hypervisor_v3_client = HypervisorV3ClientJSON(self.auth_provider)
self.instance_usages_audit_log_client = \
InstanceUsagesAuditLogClientJSON(self.auth_provider)
diff --git a/tempest/cmd/verify_tempest_config.py b/tempest/cmd/verify_tempest_config.py
index 6f74c3e..8707427 100755
--- a/tempest/cmd/verify_tempest_config.py
+++ b/tempest/cmd/verify_tempest_config.py
@@ -137,7 +137,6 @@
def get_extension_client(os, service):
extensions_client = {
'nova': os.extensions_client,
- 'nova_v3': os.extensions_v3_client,
'cinder': os.volumes_extension_client,
'neutron': os.network_client,
'swift': os.account_client,
@@ -151,7 +150,6 @@
def get_enabled_extensions(service):
extensions_options = {
'nova': CONF.compute_feature_enabled.api_extensions,
- 'nova_v3': CONF.compute_feature_enabled.api_v3_extensions,
'cinder': CONF.volume_feature_enabled.api_extensions,
'neutron': CONF.network_feature_enabled.api_extensions,
'swift': CONF.object_storage_feature_enabled.discoverable_apis,
@@ -199,7 +197,6 @@
update_dict = {
'swift': 'object-storage-feature-enabled',
'nova': 'compute-feature-enabled',
- 'nova_v3': 'compute-feature-enabled',
'cinder': 'volume-feature-enabled',
'neutron': 'network-feature-enabled',
}
@@ -234,9 +231,6 @@
if service == 'swift':
change_option('discoverable_apis', update_dict[service],
output_string)
- elif service == 'nova_v3':
- change_option('api_v3_extensions', update_dict[service],
- output_string)
else:
change_option('api_extensions', update_dict[service],
output_string)
@@ -341,10 +335,8 @@
os = clients.ComputeAdminManager(interface='json')
services = check_service_availability(os, update)
results = {}
- for service in ['nova', 'nova_v3', 'cinder', 'neutron', 'swift']:
- if service == 'nova_v3' and 'nova' not in services:
- continue
- elif service not in services:
+ for service in ['nova', 'cinder', 'neutron', 'swift']:
+ if service not in services:
continue
results = verify_extensions(os, service, results)
diff --git a/tempest/common/rest_client.py b/tempest/common/rest_client.py
index 1df8896..c54f698 100644
--- a/tempest/common/rest_client.py
+++ b/tempest/common/rest_client.py
@@ -76,18 +76,6 @@
TYPE = "json"
- # This is used by _parse_resp method
- # Redefine it for purposes of your xml service client
- # List should contain top-xml_tag-names of data, which is like list/array
- # For example, in keystone it is users, roles, tenants and services
- # All of it has children with same tag-names
- list_tags = []
-
- # This is used by _parse_resp method too
- # Used for selection of dict-like xmls,
- # like metadata for Vms in nova, and volumes in cinder
- dict_tags = ["metadata", ]
-
LOG = logging.getLogger(__name__)
def __init__(self, auth_provider):
@@ -165,11 +153,6 @@
if catalog_type == service:
endpoint_type = getattr(cfg, 'endpoint_type', 'publicURL')
break
- # Special case for compute v3 service which hasn't its own
- # configuration group
- else:
- if service == CONF.compute.catalog_v3_type:
- endpoint_type = CONF.compute.endpoint_type
return endpoint_type
@property
@@ -495,9 +478,8 @@
# (and occasionally swift) are using.
TXT_ENC = ['text/plain', 'text/html', 'text/html; charset=utf-8',
'text/plain; charset=utf-8']
- XML_ENC = ['application/xml', 'application/xml; charset=utf-8']
- if ctype.lower() in JSON_ENC or ctype.lower() in XML_ENC:
+ if ctype.lower() in JSON_ENC:
parse_resp = True
elif ctype.lower() in TXT_ENC:
parse_resp = False
@@ -552,15 +534,17 @@
message = resp_body['cloudServersFault']['message']
elif 'computeFault' in resp_body:
message = resp_body['computeFault']['message']
- elif 'error' in resp_body: # Keystone errors
+ elif 'error' in resp_body:
message = resp_body['error']['message']
- raise exceptions.IdentityError(message)
elif 'message' in resp_body:
message = resp_body['message']
else:
message = resp_body
- raise exceptions.ServerFault(message)
+ if resp.status == 501:
+ raise exceptions.NotImplemented(message)
+ else:
+ raise exceptions.ServerFault(message)
if resp.status >= 400:
raise exceptions.UnexpectedResponseCode(str(resp.status))
@@ -569,13 +553,10 @@
if (not isinstance(resp_body, collections.Mapping) or
'retry-after' not in resp):
return True
- if self._get_type() is "json":
- over_limit = resp_body.get('overLimit', None)
- if not over_limit:
- return True
- return 'exceed' in over_limit.get('message', 'blabla')
- elif self._get_type() is "xml":
- return 'exceed' in resp_body.get('message', 'blabla')
+ over_limit = resp_body.get('overLimit', None)
+ if not over_limit:
+ return True
+ return 'exceed' in over_limit.get('message', 'blabla')
def wait_for_resource_deletion(self, id):
"""Waits for a resource to be deleted."""
diff --git a/tempest/common/utils/data_utils.py b/tempest/common/utils/data_utils.py
index 5a29ea0..d441778 100644
--- a/tempest/common/utils/data_utils.py
+++ b/tempest/common/utils/data_utils.py
@@ -14,6 +14,7 @@
# under the License.
import itertools
+import netaddr
import random
import uuid
@@ -79,3 +80,22 @@
"""
return ''.join([chr(random.randint(0, 255))
for i in range(size)])
+
+
+def get_ipv6_addr_by_EUI64(cidr, mac):
+ # Check if the prefix is IPv4 address
+ is_ipv4 = netaddr.valid_ipv4(cidr)
+ if is_ipv4:
+ msg = "Unable to generate IP address by EUI64 for IPv4 prefix"
+ raise TypeError(msg)
+ try:
+ eui64 = int(netaddr.EUI(mac).eui64())
+ prefix = netaddr.IPNetwork(cidr)
+ return netaddr.IPAddress(prefix.first + eui64 ^ (1 << 57))
+ except (ValueError, netaddr.AddrFormatError):
+ raise TypeError('Bad prefix or mac format for generating IPv6 '
+ 'address by EUI-64: %(prefix)s, %(mac)s:'
+ % {'prefix': cidr, 'mac': mac})
+ except TypeError:
+ raise TypeError('Bad prefix type for generate IPv6 address by '
+ 'EUI-64: %s' % cidr)
diff --git a/tempest/exceptions.py b/tempest/exceptions.py
index 213d5de..9b2b4d4 100644
--- a/tempest/exceptions.py
+++ b/tempest/exceptions.py
@@ -152,6 +152,10 @@
message = "Got server fault"
+class NotImplemented(RestClientException):
+ message = "Got NotImplemented error"
+
+
class ImageFault(TempestException):
message = "Got image fault"
diff --git a/tempest/scenario/test_dashboard_basic_ops.py b/tempest/scenario/test_dashboard_basic_ops.py
index 2014293..35f6689 100644
--- a/tempest/scenario/test_dashboard_basic_ops.py
+++ b/tempest/scenario/test_dashboard_basic_ops.py
@@ -67,7 +67,7 @@
response = urllib2.urlopen(CONF.dashboard.dashboard_url)
self.assertIn("Log In", response.read())
- def user_login(self):
+ def user_login(self, username, password):
self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor())
response = self.opener.open(CONF.dashboard.dashboard_url).read()
@@ -79,8 +79,8 @@
req = urllib2.Request(CONF.dashboard.login_url)
req.add_header('Content-type', 'application/x-www-form-urlencoded')
req.add_header('Referer', CONF.dashboard.dashboard_url)
- params = {'username': CONF.identity.username,
- 'password': CONF.identity.password,
+ params = {'username': username,
+ 'password': password,
'region': parser.region,
'csrfmiddlewaretoken': parser.csrf_token}
self.opener.open(req, urllib.urlencode(params))
@@ -91,6 +91,7 @@
@test.services('dashboard')
def test_basic_scenario(self):
+ creds = self.credentials()
self.check_login_page()
- self.user_login()
+ self.user_login(creds.username, creds.password)
self.check_home_page()
diff --git a/tempest/scenario/test_load_balancer_basic.py b/tempest/scenario/test_load_balancer_basic.py
index 4b2dacd..57a5406 100644
--- a/tempest/scenario/test_load_balancer_basic.py
+++ b/tempest/scenario/test_load_balancer_basic.py
@@ -48,12 +48,10 @@
cfg = config.network
if not test.is_extension_enabled('lbaas', 'network'):
msg = 'LBaaS Extension is not enabled'
- cls.enabled = False
raise cls.skipException(msg)
if not (cfg.tenant_networks_reachable or cfg.public_network_id):
msg = ('Either tenant_networks_reachable must be "true", or '
'public_network_id must be defined.')
- cls.enabled = False
raise cls.skipException(msg)
@classmethod
diff --git a/tempest/scenario/test_network_advanced_server_ops.py b/tempest/scenario/test_network_advanced_server_ops.py
index 61c710e..194a0bd 100644
--- a/tempest/scenario/test_network_advanced_server_ops.py
+++ b/tempest/scenario/test_network_advanced_server_ops.py
@@ -46,7 +46,6 @@
or CONF.network.public_network_id):
msg = ('Either tenant_networks_reachable must be "true", or '
'public_network_id must be defined.')
- cls.enabled = False
raise cls.skipException(msg)
@classmethod
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index 98e3fda..30c3b9d 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -83,7 +83,6 @@
or CONF.network.public_network_id):
msg = ('Either tenant_networks_reachable must be "true", or '
'public_network_id must be defined.')
- cls.enabled = False
raise cls.skipException(msg)
@classmethod
diff --git a/tempest/scenario/test_network_v6.py b/tempest/scenario/test_network_v6.py
index b3a2358..1a82e78 100644
--- a/tempest/scenario/test_network_v6.py
+++ b/tempest/scenario/test_network_v6.py
@@ -42,14 +42,16 @@
def check_preconditions(cls):
if not (CONF.network_feature_enabled.ipv6
and CONF.network_feature_enabled.ipv6_subnet_attributes):
- cls.enabled = False
raise cls.skipException('IPv6 or its attributes not supported')
if not (CONF.network.tenant_networks_reachable
or CONF.network.public_network_id):
msg = ('Either tenant_networks_reachable must be "true", or '
'public_network_id must be defined.')
- cls.enabled = False
raise cls.skipException(msg)
+ if CONF.baremetal.driver_enabled:
+ msg = ('Baremetal does not currently support network isolation')
+ raise cls.skipException(msg)
+
super(TestGettingAddress, cls).check_preconditions()
def setUp(self):
diff --git a/tempest/scenario/test_security_groups_basic_ops.py b/tempest/scenario/test_security_groups_basic_ops.py
index d8f7a26..5e2a9d0 100644
--- a/tempest/scenario/test_security_groups_basic_ops.py
+++ b/tempest/scenario/test_security_groups_basic_ops.py
@@ -116,14 +116,12 @@
def check_preconditions(cls):
if CONF.baremetal.driver_enabled:
msg = ('Not currently supported by baremetal.')
- cls.enabled = False
raise cls.skipException(msg)
super(TestSecurityGroupsBasicOps, cls).check_preconditions()
if not (CONF.network.tenant_networks_reachable or
CONF.network.public_network_id):
msg = ('Either tenant_networks_reachable must be "true", or '
'public_network_id must be defined.')
- cls.enabled = False
raise cls.skipException(msg)
@classmethod
diff --git a/tempest/services/compute/v3/__init__.py b/tempest/services/compute/v3/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/services/compute/v3/__init__.py
+++ /dev/null
diff --git a/tempest/services/compute/v3/json/__init__.py b/tempest/services/compute/v3/json/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/services/compute/v3/json/__init__.py
+++ /dev/null
diff --git a/tempest/services/compute/v3/json/agents_client.py b/tempest/services/compute/v3/json/agents_client.py
deleted file mode 100644
index ffca142..0000000
--- a/tempest/services/compute/v3/json/agents_client.py
+++ /dev/null
@@ -1,60 +0,0 @@
-# Copyright 2014 NEC Corporation. All rights reserved.
-#
-# 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 urllib
-
-from tempest.api_schema.response.compute import agents as common_schema
-from tempest.api_schema.response.compute.v3 import agents as schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
-
-
-class AgentsV3ClientJSON(rest_client.RestClient):
-
- def __init__(self, auth_provider):
- super(AgentsV3ClientJSON, self).__init__(auth_provider)
- self.service = CONF.compute.catalog_v3_type
-
- def list_agents(self, params=None):
- """List all agent builds."""
- url = 'os-agents'
- if params:
- url += '?%s' % urllib.urlencode(params)
- resp, body = self.get(url)
- body = json.loads(body)
- self.validate_response(common_schema.list_agents, resp, body)
- return resp, body['agents']
-
- def create_agent(self, **kwargs):
- """Create an agent build."""
- post_body = json.dumps({'agent': kwargs})
- resp, body = self.post('os-agents', post_body)
- body = json.loads(body)
- self.validate_response(schema.create_agent, resp, body)
- return resp, body['agent']
-
- def delete_agent(self, agent_id):
- """Delete an existing agent build."""
- resp, body = self.delete("os-agents/%s" % str(agent_id))
- self.validate_response(schema.delete_agent, resp, body)
- return resp, body
-
- def update_agent(self, agent_id, **kwargs):
- """Update an agent build."""
- put_body = json.dumps({'agent': kwargs})
- resp, body = self.put('os-agents/%s' % str(agent_id), put_body)
- return resp, self._parse_resp(body)
diff --git a/tempest/services/compute/v3/json/aggregates_client.py b/tempest/services/compute/v3/json/aggregates_client.py
deleted file mode 100644
index e11ed45..0000000
--- a/tempest/services/compute/v3/json/aggregates_client.py
+++ /dev/null
@@ -1,121 +0,0 @@
-# Copyright 2013 NEC Corporation.
-# All Rights Reserved.
-#
-# 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 tempest.api_schema.response.compute import aggregates as schema
-from tempest.api_schema.response.compute.v3 import aggregates as v3_schema
-from tempest.common import rest_client
-from tempest import config
-from tempest import exceptions
-
-CONF = config.CONF
-
-
-class AggregatesV3ClientJSON(rest_client.RestClient):
-
- def __init__(self, auth_provider):
- super(AggregatesV3ClientJSON, self).__init__(auth_provider)
- self.service = CONF.compute.catalog_v3_type
-
- def list_aggregates(self):
- """Get aggregate list."""
- resp, body = self.get("os-aggregates")
- body = json.loads(body)
- self.validate_response(schema.list_aggregates, resp, body)
- return resp, body['aggregates']
-
- def get_aggregate(self, aggregate_id):
- """Get details of the given aggregate."""
- resp, body = self.get("os-aggregates/%s" % str(aggregate_id))
- body = json.loads(body)
- self.validate_response(schema.get_aggregate, resp, body)
- return resp, body['aggregate']
-
- def create_aggregate(self, **kwargs):
- """Creates a new aggregate."""
- post_body = json.dumps({'aggregate': kwargs})
- resp, body = self.post('os-aggregates', post_body)
-
- body = json.loads(body)
- self.validate_response(v3_schema.create_aggregate, resp, body)
- return resp, body['aggregate']
-
- def update_aggregate(self, aggregate_id, name, availability_zone=None):
- """Update a aggregate."""
- put_body = {
- 'name': name,
- 'availability_zone': availability_zone
- }
- put_body = json.dumps({'aggregate': put_body})
- resp, body = self.put('os-aggregates/%s' % str(aggregate_id), put_body)
-
- body = json.loads(body)
- self.validate_response(schema.update_aggregate, resp, body)
- return resp, body['aggregate']
-
- def delete_aggregate(self, aggregate_id):
- """Deletes the given aggregate."""
- resp, body = self.delete("os-aggregates/%s" % str(aggregate_id))
- self.validate_response(v3_schema.delete_aggregate, resp, body)
- return resp, body
-
- def is_resource_deleted(self, id):
- try:
- self.get_aggregate(id)
- except exceptions.NotFound:
- return True
- return False
-
- @property
- def resource_type(self):
- """Returns the primary type of resource this client works with."""
- return 'aggregate'
-
- def add_host(self, aggregate_id, host):
- """Adds a host to the given aggregate."""
- post_body = {
- 'host': host,
- }
- post_body = json.dumps({'add_host': post_body})
- resp, body = self.post('os-aggregates/%s/action' % aggregate_id,
- post_body)
- body = json.loads(body)
- self.validate_response(v3_schema.aggregate_add_remove_host, resp, body)
- return resp, body['aggregate']
-
- def remove_host(self, aggregate_id, host):
- """Removes a host from the given aggregate."""
- post_body = {
- 'host': host,
- }
- post_body = json.dumps({'remove_host': post_body})
- resp, body = self.post('os-aggregates/%s/action' % aggregate_id,
- post_body)
- body = json.loads(body)
- self.validate_response(v3_schema.aggregate_add_remove_host, resp, body)
- return resp, body['aggregate']
-
- def set_metadata(self, aggregate_id, meta):
- """Replaces the aggregate's existing metadata with new metadata."""
- post_body = {
- 'metadata': meta,
- }
- post_body = json.dumps({'set_metadata': post_body})
- resp, body = self.post('os-aggregates/%s/action' % aggregate_id,
- post_body)
- body = json.loads(body)
- self.validate_response(schema.aggregate_set_metadata, resp, body)
- return resp, body['aggregate']
diff --git a/tempest/services/compute/v3/json/availability_zone_client.py b/tempest/services/compute/v3/json/availability_zone_client.py
deleted file mode 100644
index 0da78da..0000000
--- a/tempest/services/compute/v3/json/availability_zone_client.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright 2013 NEC Corporation.
-# All Rights Reserved.
-#
-# 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 tempest.api_schema.response.compute.v3 import availability_zone as schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
-
-
-class AvailabilityZoneV3ClientJSON(rest_client.RestClient):
-
- def __init__(self, auth_provider):
- super(AvailabilityZoneV3ClientJSON, self).__init__(
- auth_provider)
- self.service = CONF.compute.catalog_v3_type
-
- def get_availability_zone_list(self):
- resp, body = self.get('os-availability-zone')
- body = json.loads(body)
- self.validate_response(schema.get_availability_zone_list, resp, body)
- return resp, body['availability_zone_info']
-
- def get_availability_zone_list_detail(self):
- resp, body = self.get('os-availability-zone/detail')
- body = json.loads(body)
- self.validate_response(schema.get_availability_zone_list_detail, resp,
- body)
- return resp, body['availability_zone_info']
diff --git a/tempest/services/compute/v3/json/certificates_client.py b/tempest/services/compute/v3/json/certificates_client.py
deleted file mode 100644
index 42e9d5a..0000000
--- a/tempest/services/compute/v3/json/certificates_client.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright 2013 IBM Corp
-# All Rights Reserved.
-#
-# 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 tempest.api_schema.response.compute import certificates as schema
-from tempest.api_schema.response.compute.v3 import certificates as v3schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
-
-
-class CertificatesV3ClientJSON(rest_client.RestClient):
-
- def __init__(self, auth_provider):
- super(CertificatesV3ClientJSON, self).__init__(auth_provider)
- self.service = CONF.compute.catalog_v3_type
-
- def get_certificate(self, id):
- url = "os-certificates/%s" % (id)
- resp, body = self.get(url)
- body = json.loads(body)
- self.validate_response(schema.get_certificate, resp, body)
- return resp, body['certificate']
-
- def create_certificate(self):
- """create certificates."""
- url = "os-certificates"
- resp, body = self.post(url, None)
- body = json.loads(body)
- self.validate_response(v3schema.create_certificate, resp, body)
- return resp, body['certificate']
diff --git a/tempest/services/compute/v3/json/extensions_client.py b/tempest/services/compute/v3/json/extensions_client.py
deleted file mode 100644
index f172efd..0000000
--- a/tempest/services/compute/v3/json/extensions_client.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright 2012 OpenStack Foundation
-# All Rights Reserved.
-#
-# 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 tempest.api_schema.response.compute.v3 import extensions as schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
-
-
-class ExtensionsV3ClientJSON(rest_client.RestClient):
-
- def __init__(self, auth_provider):
- super(ExtensionsV3ClientJSON, self).__init__(auth_provider)
- self.service = CONF.compute.catalog_v3_type
-
- def list_extensions(self):
- url = 'extensions'
- resp, body = self.get(url)
- body = json.loads(body)
- self.validate_response(schema.list_extensions, resp, body)
- return resp, body['extensions']
-
- def is_enabled(self, extension):
- _, extensions = self.list_extensions()
- exts = extensions['extensions']
- return any([e for e in exts if e['name'] == extension])
-
- def get_extension(self, extension_alias):
- resp, body = self.get('extensions/%s' % extension_alias)
- body = json.loads(body)
- return resp, body['extension']
diff --git a/tempest/services/compute/v3/json/flavors_client.py b/tempest/services/compute/v3/json/flavors_client.py
deleted file mode 100644
index fdca6b3..0000000
--- a/tempest/services/compute/v3/json/flavors_client.py
+++ /dev/null
@@ -1,183 +0,0 @@
-# Copyright 2012 OpenStack Foundation
-# All Rights Reserved.
-#
-# 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 urllib
-
-from tempest.api_schema.response.compute import flavors as common_schema
-from tempest.api_schema.response.compute import flavors_access as schema_access
-from tempest.api_schema.response.compute import flavors_extra_specs \
- as schema_extra_specs
-from tempest.api_schema.response.compute.v3 import flavors as v3schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
-
-
-class FlavorsV3ClientJSON(rest_client.RestClient):
-
- def __init__(self, auth_provider):
- super(FlavorsV3ClientJSON, self).__init__(auth_provider)
- self.service = CONF.compute.catalog_v3_type
-
- def list_flavors(self, params=None):
- url = 'flavors'
- if params:
- url += '?%s' % urllib.urlencode(params)
-
- resp, body = self.get(url)
- body = json.loads(body)
- self.validate_response(common_schema.list_flavors, resp, body)
- return resp, body['flavors']
-
- def list_flavors_with_detail(self, params=None):
- url = 'flavors/detail'
- if params:
- url += '?%s' % urllib.urlencode(params)
-
- resp, body = self.get(url)
- body = json.loads(body)
- self.validate_response(v3schema.list_flavors_details, resp, body)
- return resp, body['flavors']
-
- def get_flavor_details(self, flavor_id):
- resp, body = self.get("flavors/%s" % str(flavor_id))
- body = json.loads(body)
- self.validate_response(v3schema.get_flavor_details, resp, body)
- return resp, body['flavor']
-
- def create_flavor(self, name, ram, vcpus, disk, flavor_id, **kwargs):
- """Creates a new flavor or instance type."""
- post_body = {
- 'name': name,
- 'ram': ram,
- 'vcpus': vcpus,
- 'disk': disk,
- 'id': flavor_id,
- }
- if kwargs.get('ephemeral'):
- post_body['ephemeral'] = kwargs.get('ephemeral')
- if kwargs.get('swap'):
- post_body['swap'] = kwargs.get('swap')
- if kwargs.get('rxtx'):
- post_body['os-flavor-rxtx:rxtx_factor'] = kwargs.get('rxtx')
- if kwargs.get('is_public'):
- post_body['flavor-access:is_public'] = kwargs.get('is_public')
- post_body = json.dumps({'flavor': post_body})
- resp, body = self.post('flavors', post_body)
-
- body = json.loads(body)
- self.validate_response(v3schema.create_flavor_details, resp, body)
- return resp, body['flavor']
-
- def delete_flavor(self, flavor_id):
- """Deletes the given flavor."""
- resp, body = self.delete("flavors/{0}".format(flavor_id))
- self.validate_response(v3schema.delete_flavor, resp, body)
- return resp, body
-
- def is_resource_deleted(self, id):
- # Did not use get_flavor_details(id) for verification as it gives
- # 200 ok even for deleted id. LP #981263
- # we can remove the loop here and use get by ID when bug gets sortedout
- resp, flavors = self.list_flavors_with_detail()
- for flavor in flavors:
- if flavor['id'] == id:
- return False
- return True
-
- @property
- def resource_type(self):
- """Returns the primary type of resource this client works with."""
- return 'flavor'
-
- def set_flavor_extra_spec(self, flavor_id, specs):
- """Sets extra Specs to the mentioned flavor."""
- post_body = json.dumps({'extra_specs': specs})
- resp, body = self.post('flavors/%s/flavor-extra-specs' % flavor_id,
- post_body)
- body = json.loads(body)
- self.validate_response(v3schema.set_flavor_extra_specs, resp, body)
- return resp, body['extra_specs']
-
- def get_flavor_extra_spec(self, flavor_id):
- """Gets extra Specs details of the mentioned flavor."""
- resp, body = self.get('flavors/%s/flavor-extra-specs' % flavor_id)
- body = json.loads(body)
- self.validate_response(schema_extra_specs.flavor_extra_specs,
- resp, body)
- return resp, body['extra_specs']
-
- def get_flavor_extra_spec_with_key(self, flavor_id, key):
- """Gets extra Specs key-value of the mentioned flavor and key."""
- resp, body = self.get('flavors/%s/flavor-extra-specs/%s' %
- (str(flavor_id), key))
- body = json.loads(body)
- self.validate_response(schema_extra_specs.flavor_extra_specs_key,
- resp, body)
- return resp, body
-
- def update_flavor_extra_spec(self, flavor_id, key, **kwargs):
- """Update specified extra Specs of the mentioned flavor and key."""
- resp, body = self.put('flavors/%s/flavor-extra-specs/%s' %
- (flavor_id, key), json.dumps(kwargs))
- body = json.loads(body)
- self.validate_response(schema_extra_specs.flavor_extra_specs_key,
- resp, body)
- return resp, body
-
- def unset_flavor_extra_spec(self, flavor_id, key):
- """Unsets extra Specs from the mentioned flavor."""
- resp, body = self.delete('flavors/%s/flavor-extra-specs/%s' %
- (str(flavor_id), key))
- self.validate_response(v3schema.unset_flavor_extra_specs, resp, body)
- return resp, body
-
- def list_flavor_access(self, flavor_id):
- """Gets flavor access information given the flavor id."""
- resp, body = self.get('flavors/%s/flavor-access' % flavor_id)
- body = json.loads(body)
- self.validate_response(schema_access.add_remove_list_flavor_access,
- resp, body)
- return resp, body['flavor_access']
-
- def add_flavor_access(self, flavor_id, tenant_id):
- """Add flavor access for the specified tenant."""
- post_body = {
- 'add_tenant_access': {
- 'tenant_id': tenant_id
- }
- }
- post_body = json.dumps(post_body)
- resp, body = self.post('flavors/%s/action' % flavor_id, post_body)
- body = json.loads(body)
- self.validate_response(schema_access.add_remove_list_flavor_access,
- resp, body)
- return resp, body['flavor_access']
-
- def remove_flavor_access(self, flavor_id, tenant_id):
- """Remove flavor access from the specified tenant."""
- post_body = {
- 'remove_tenant_access': {
- 'tenant_id': tenant_id
- }
- }
- post_body = json.dumps(post_body)
- resp, body = self.post('flavors/%s/action' % flavor_id, post_body)
- body = json.loads(body)
- self.validate_response(schema_access.add_remove_list_flavor_access,
- resp, body)
- return resp, body['flavor_access']
diff --git a/tempest/services/compute/v3/json/hosts_client.py b/tempest/services/compute/v3/json/hosts_client.py
deleted file mode 100644
index 476afad..0000000
--- a/tempest/services/compute/v3/json/hosts_client.py
+++ /dev/null
@@ -1,89 +0,0 @@
-# Copyright 2013 IBM Corp.
-#
-# 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 urllib
-
-from tempest.api_schema.response.compute import hosts as schema
-from tempest.api_schema.response.compute.v3 import hosts as v3_schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
-
-
-class HostsV3ClientJSON(rest_client.RestClient):
-
- def __init__(self, auth_provider):
- super(HostsV3ClientJSON, self).__init__(auth_provider)
- self.service = CONF.compute.catalog_v3_type
-
- def list_hosts(self, params=None):
- """Lists all hosts."""
-
- url = 'os-hosts'
- if params:
- url += '?%s' % urllib.urlencode(params)
-
- resp, body = self.get(url)
- body = json.loads(body)
- self.validate_response(schema.list_hosts, resp, body)
- return resp, body['hosts']
-
- def show_host_detail(self, hostname):
- """Show detail information for the host."""
-
- resp, body = self.get("os-hosts/%s" % str(hostname))
- body = json.loads(body)
- self.validate_response(schema.show_host_detail, resp, body)
- return resp, body['host']
-
- def update_host(self, hostname, **kwargs):
- """Update a host."""
-
- request_body = {
- 'status': None,
- 'maintenance_mode': None,
- }
- request_body.update(**kwargs)
- request_body = json.dumps({'host': request_body})
-
- resp, body = self.put("os-hosts/%s" % str(hostname), request_body)
- body = json.loads(body)
- self.validate_response(v3_schema.update_host, resp, body)
- return resp, body
-
- def startup_host(self, hostname):
- """Startup a host."""
-
- resp, body = self.get("os-hosts/%s/startup" % str(hostname))
- body = json.loads(body)
- self.validate_response(v3_schema.startup_host, resp, body)
- return resp, body['host']
-
- def shutdown_host(self, hostname):
- """Shutdown a host."""
-
- resp, body = self.get("os-hosts/%s/shutdown" % str(hostname))
- body = json.loads(body)
- self.validate_response(v3_schema.shutdown_host, resp, body)
- return resp, body['host']
-
- def reboot_host(self, hostname):
- """reboot a host."""
-
- resp, body = self.get("os-hosts/%s/reboot" % str(hostname))
- body = json.loads(body)
- self.validate_response(v3_schema.reboot_host, resp, body)
- return resp, body['host']
diff --git a/tempest/services/compute/v3/json/hypervisor_client.py b/tempest/services/compute/v3/json/hypervisor_client.py
deleted file mode 100644
index 507157a..0000000
--- a/tempest/services/compute/v3/json/hypervisor_client.py
+++ /dev/null
@@ -1,81 +0,0 @@
-# Copyright 2013 IBM Corporation.
-# All Rights Reserved.
-#
-# 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 tempest.api_schema.response.compute import hypervisors as common_schema
-from tempest.api_schema.response.compute.v3 import hypervisors as v3schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
-
-
-class HypervisorV3ClientJSON(rest_client.RestClient):
-
- def __init__(self, auth_provider):
- super(HypervisorV3ClientJSON, self).__init__(auth_provider)
- self.service = CONF.compute.catalog_v3_type
-
- def get_hypervisor_list(self):
- """List hypervisors information."""
- resp, body = self.get('os-hypervisors')
- body = json.loads(body)
- self.validate_response(common_schema.common_hypervisors_detail,
- resp, body)
- return resp, body['hypervisors']
-
- def get_hypervisor_list_details(self):
- """Show detailed hypervisors information."""
- resp, body = self.get('os-hypervisors/detail')
- body = json.loads(body)
- self.validate_response(v3schema.list_hypervisors_detail, resp, body)
- return resp, body['hypervisors']
-
- def get_hypervisor_show_details(self, hyper_id):
- """Display the details of the specified hypervisor."""
- resp, body = self.get('os-hypervisors/%s' % hyper_id)
- body = json.loads(body)
- self.validate_response(v3schema.show_hypervisor, resp, body)
- return resp, body['hypervisor']
-
- def get_hypervisor_servers(self, hyper_name):
- """List instances belonging to the specified hypervisor."""
- resp, body = self.get('os-hypervisors/%s/servers' % hyper_name)
- body = json.loads(body)
- self.validate_response(v3schema.hypervisors_servers, resp, body)
- return resp, body['hypervisor']
-
- def get_hypervisor_stats(self):
- """Get hypervisor statistics over all compute nodes."""
- resp, body = self.get('os-hypervisors/statistics')
- body = json.loads(body)
- self.validate_response(common_schema.hypervisor_statistics, resp, body)
- return resp, body['hypervisor_statistics']
-
- def get_hypervisor_uptime(self, hyper_id):
- """Display the uptime of the specified hypervisor."""
- resp, body = self.get('os-hypervisors/%s/uptime' % hyper_id)
- body = json.loads(body)
- self.validate_response(common_schema.hypervisor_uptime, resp, body)
- return resp, body['hypervisor']
-
- def search_hypervisor(self, hyper_name):
- """Search specified hypervisor."""
- resp, body = self.get('os-hypervisors/search?query=%s' % hyper_name)
- body = json.loads(body)
- self.validate_response(common_schema.common_hypervisors_detail,
- resp, body)
- return resp, body['hypervisors']
diff --git a/tempest/services/compute/v3/json/interfaces_client.py b/tempest/services/compute/v3/json/interfaces_client.py
deleted file mode 100644
index ccc20c8..0000000
--- a/tempest/services/compute/v3/json/interfaces_client.py
+++ /dev/null
@@ -1,115 +0,0 @@
-# Copyright 2013 IBM Corp.
-# All Rights Reserved.
-#
-# 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 time
-
-from tempest.api_schema.response.compute import interfaces as common_schema
-from tempest.api_schema.response.compute import servers as servers_schema
-from tempest.api_schema.response.compute.v3 import interfaces as schema
-from tempest.common import rest_client
-from tempest import config
-from tempest import exceptions
-
-CONF = config.CONF
-
-
-class InterfacesV3ClientJSON(rest_client.RestClient):
-
- def __init__(self, auth_provider):
- super(InterfacesV3ClientJSON, self).__init__(auth_provider)
- self.service = CONF.compute.catalog_v3_type
-
- def list_interfaces(self, server):
- resp, body = self.get('servers/%s/os-attach-interfaces' % server)
- body = json.loads(body)
- self.validate_response(schema.list_interfaces, resp, body)
- return resp, body['interface_attachments']
-
- def create_interface(self, server, port_id=None, network_id=None,
- fixed_ip=None):
- post_body = dict()
- if port_id:
- post_body['port_id'] = port_id
- if network_id:
- post_body['net_id'] = network_id
- if fixed_ip:
- post_body['fixed_ips'] = [dict(ip_address=fixed_ip)]
- post_body = json.dumps({'interface_attachment': post_body})
- resp, body = self.post('servers/%s/os-attach-interfaces' % server,
- body=post_body)
- body = json.loads(body)
- return resp, body['interface_attachment']
-
- def show_interface(self, server, port_id):
- resp, body =\
- self.get('servers/%s/os-attach-interfaces/%s' % (server, port_id))
- body = json.loads(body)
- return resp, body['interface_attachment']
-
- def delete_interface(self, server, port_id):
- resp, body =\
- self.delete('servers/%s/os-attach-interfaces/%s' % (server,
- port_id))
- self.validate_response(common_schema.delete_interface, resp, body)
- return resp, body
-
- def wait_for_interface_status(self, server, port_id, status):
- """Waits for a interface to reach a given status."""
- resp, body = self.show_interface(server, port_id)
- interface_status = body['port_state']
- start = int(time.time())
-
- while(interface_status != status):
- time.sleep(self.build_interval)
- resp, body = self.show_interface(server, port_id)
- interface_status = body['port_state']
-
- timed_out = int(time.time()) - start >= self.build_timeout
-
- if interface_status != status and timed_out:
- message = ('Interface %s failed to reach %s status '
- '(current %s) within the required time (%s s).' %
- (port_id, status, interface_status,
- self.build_timeout))
- raise exceptions.TimeoutException(message)
-
- return resp, body
-
- def add_fixed_ip(self, server_id, network_id):
- """Add a fixed IP to input server instance."""
- post_body = json.dumps({
- 'add_fixed_ip': {
- 'network_id': network_id
- }
- })
- resp, body = self.post('servers/%s/action' % str(server_id),
- post_body)
- self.validate_response(servers_schema.server_actions_common_schema,
- resp, body)
- return resp, body
-
- def remove_fixed_ip(self, server_id, ip_address):
- """Remove input fixed IP from input server instance."""
- post_body = json.dumps({
- 'remove_fixed_ip': {
- 'address': ip_address
- }
- })
- resp, body = self.post('servers/%s/action' % str(server_id),
- post_body)
- self.validate_response(servers_schema.server_actions_common_schema,
- resp, body)
- return resp, body
diff --git a/tempest/services/compute/v3/json/keypairs_client.py b/tempest/services/compute/v3/json/keypairs_client.py
deleted file mode 100644
index a290acb..0000000
--- a/tempest/services/compute/v3/json/keypairs_client.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# Copyright 2012 OpenStack Foundation
-# All Rights Reserved.
-#
-# 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 tempest.api_schema.response.compute import keypairs as common_schema
-from tempest.api_schema.response.compute.v3 import keypairs as schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
-
-
-class KeyPairsV3ClientJSON(rest_client.RestClient):
-
- def __init__(self, auth_provider):
- super(KeyPairsV3ClientJSON, self).__init__(auth_provider)
- self.service = CONF.compute.catalog_v3_type
-
- def list_keypairs(self):
- resp, body = self.get("keypairs")
- body = json.loads(body)
- # Each returned keypair is embedded within an unnecessary 'keypair'
- # element which is a deviation from other resources like floating-ips,
- # servers, etc. A bug?
- # For now we shall adhere to the spec, but the spec for keypairs
- # is yet to be found
- self.validate_response(common_schema.list_keypairs, resp, body)
- return resp, body['keypairs']
-
- def get_keypair(self, key_name):
- resp, body = self.get("keypairs/%s" % str(key_name))
- body = json.loads(body)
- self.validate_response(schema.get_keypair, resp, body)
- return resp, body['keypair']
-
- def create_keypair(self, name, pub_key=None):
- post_body = {'keypair': {'name': name}}
- if pub_key:
- post_body['keypair']['public_key'] = pub_key
- post_body = json.dumps(post_body)
- resp, body = self.post("keypairs", body=post_body)
- body = json.loads(body)
- self.validate_response(schema.create_keypair, resp, body)
- return resp, body['keypair']
-
- def delete_keypair(self, key_name):
- resp, body = self.delete("keypairs/%s" % str(key_name))
- self.validate_response(schema.delete_keypair, resp, body)
- return resp, body
diff --git a/tempest/services/compute/v3/json/migration_client.py b/tempest/services/compute/v3/json/migration_client.py
deleted file mode 100644
index bf1ae85..0000000
--- a/tempest/services/compute/v3/json/migration_client.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright 2014 NEC Corporation.
-#
-# 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 urllib
-
-from tempest.api_schema.response.compute import migrations as schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
-
-
-class MigrationsV3ClientJSON(rest_client.RestClient):
-
- def __init__(self, auth_provider):
- super(MigrationsV3ClientJSON, self).__init__(auth_provider)
- self.service = CONF.compute.catalog_v3_type
-
- def list_migrations(self, params=None):
- """Lists all migrations."""
-
- url = 'os-migrations'
- if params:
- url += '?%s' % urllib.urlencode(params)
-
- resp, body = self.get(url)
- body = json.loads(body)
- self.validate_response(schema.list_migrations, resp, body)
- return resp, body['migrations']
diff --git a/tempest/services/compute/v3/json/quotas_client.py b/tempest/services/compute/v3/json/quotas_client.py
deleted file mode 100644
index f9aa9e9..0000000
--- a/tempest/services/compute/v3/json/quotas_client.py
+++ /dev/null
@@ -1,117 +0,0 @@
-# Copyright 2012 NTT Data
-# All Rights Reserved.
-#
-# 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 tempest.api_schema.response.compute.v3 import quotas as schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
-
-
-class QuotasV3ClientJSON(rest_client.RestClient):
-
- def __init__(self, auth_provider):
- super(QuotasV3ClientJSON, self).__init__(auth_provider)
- self.service = CONF.compute.catalog_v3_type
-
- def get_quota_set(self, tenant_id, user_id=None):
- """List the quota set for a tenant."""
-
- url = 'os-quota-sets/%s' % str(tenant_id)
- if user_id:
- url += '?user_id=%s' % str(user_id)
- resp, body = self.get(url)
- body = json.loads(body)
- self.validate_response(schema.quota_set, resp, body)
- return resp, body['quota_set']
-
- def get_quota_set_detail(self, tenant_id):
- """Get the quota set detail for a tenant."""
-
- url = 'os-quota-sets/%s/detail' % str(tenant_id)
- resp, body = self.get(url)
- body = json.loads(body)
- self.validate_response(schema.quota_set_detail, resp, body)
- return resp, body['quota_set']
-
- def get_default_quota_set(self, tenant_id):
- """List the default quota set for a tenant."""
-
- url = 'os-quota-sets/%s/defaults' % str(tenant_id)
- resp, body = self.get(url)
- body = json.loads(body)
- self.validate_response(schema.quota_set, resp, body)
- return resp, body['quota_set']
-
- def update_quota_set(self, tenant_id, user_id=None, force=None,
- metadata_items=None, ram=None, floating_ips=None,
- fixed_ips=None, key_pairs=None, instances=None,
- security_group_rules=None, cores=None,
- security_groups=None):
- """
- Updates the tenant's quota limits for one or more resources
- """
- post_body = {}
-
- if force is not None:
- post_body['force'] = force
-
- if metadata_items is not None:
- post_body['metadata_items'] = metadata_items
-
- if ram is not None:
- post_body['ram'] = ram
-
- if floating_ips is not None:
- post_body['floating_ips'] = floating_ips
-
- if fixed_ips is not None:
- post_body['fixed_ips'] = fixed_ips
-
- if key_pairs is not None:
- post_body['key_pairs'] = key_pairs
-
- if instances is not None:
- post_body['instances'] = instances
-
- if security_group_rules is not None:
- post_body['security_group_rules'] = security_group_rules
-
- if cores is not None:
- post_body['cores'] = cores
-
- if security_groups is not None:
- post_body['security_groups'] = security_groups
-
- post_body = json.dumps({'quota_set': post_body})
-
- if user_id:
- resp, body = self.put('os-quota-sets/%s?user_id=%s' %
- (str(tenant_id), str(user_id)), post_body)
- else:
- resp, body = self.put('os-quota-sets/%s' % str(tenant_id),
- post_body)
-
- body = json.loads(body)
- self.validate_response(schema.quota_set, resp, body)
- return resp, body['quota_set']
-
- def delete_quota_set(self, tenant_id):
- """Delete the tenant's quota set."""
- resp, body = self.delete('os-quota-sets/%s' % str(tenant_id))
- self.validate_response(schema.delete_quota, resp, body)
- return resp, body
diff --git a/tempest/services/compute/v3/json/servers_client.py b/tempest/services/compute/v3/json/servers_client.py
deleted file mode 100644
index 89e282d..0000000
--- a/tempest/services/compute/v3/json/servers_client.py
+++ /dev/null
@@ -1,531 +0,0 @@
-# Copyright 2012 OpenStack Foundation
-# Copyright 2013 Hewlett-Packard Development Company, L.P.
-# Copyright 2013 IBM Corp
-# All Rights Reserved.
-#
-# 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 time
-import urllib
-
-from tempest.api_schema.response.compute import servers as common_schema
-from tempest.api_schema.response.compute.v3 import servers as schema
-from tempest.common import rest_client
-from tempest.common import waiters
-from tempest import config
-from tempest import exceptions
-
-CONF = config.CONF
-
-
-class ServersV3ClientJSON(rest_client.RestClient):
-
- def __init__(self, auth_provider):
- super(ServersV3ClientJSON, self).__init__(auth_provider)
- self.service = CONF.compute.catalog_v3_type
-
- def create_server(self, name, image_ref, flavor_ref, **kwargs):
- """
- Creates an instance of a server.
- name (Required): The name of the server.
- image_ref (Required): Reference to the image used to build the server.
- flavor_ref (Required): The flavor used to build the server.
- Following optional keyword arguments are accepted:
- admin_password: Sets the initial root password.
- key_name: Key name of keypair that was created earlier.
- meta: A dictionary of values to be used as metadata.
- security_groups: A list of security group dicts.
- networks: A list of network dicts with UUID and fixed_ip.
- user_data: User data for instance.
- availability_zone: Availability zone in which to launch instance.
- access_ip_v4: The IPv4 access address for the server.
- access_ip_v6: The IPv6 access address for the server.
- min_count: Count of minimum number of instances to launch.
- max_count: Count of maximum number of instances to launch.
- disk_config: Determines if user or admin controls disk configuration.
- return_reservation_id: Enable/Disable the return of reservation id
- block_device_mapping: Block device mapping for the server.
- """
- post_body = {
- 'name': name,
- 'image_ref': image_ref,
- 'flavor_ref': flavor_ref
- }
-
- for option in ['admin_password', 'key_name', 'networks',
- ('os-security-groups:security_groups',
- 'security_groups'),
- ('os-user-data:user_data', 'user_data'),
- ('os-availability-zone:availability_zone',
- 'availability_zone'),
- ('os-access-ips:access_ip_v4', 'access_ip_v4'),
- ('os-access-ips:access_ip_v6', 'access_ip_v6'),
- ('os-multiple-create:min_count', 'min_count'),
- ('os-multiple-create:max_count', 'max_count'),
- ('metadata', 'meta'),
- ('os-disk-config:disk_config', 'disk_config'),
- ('os-multiple-create:return_reservation_id',
- 'return_reservation_id'),
- ('os-block-device-mapping:block_device_mapping',
- 'block_device_mapping')]:
- if isinstance(option, tuple):
- post_param = option[0]
- key = option[1]
- else:
- post_param = option
- key = option
- value = kwargs.get(key)
- if value is not None:
- post_body[post_param] = value
- post_body = json.dumps({'server': post_body})
- resp, body = self.post('servers', post_body)
-
- body = json.loads(body)
- # NOTE(maurosr): this deals with the case of multiple server create
- # with return reservation id set True
- if 'servers_reservation' in body:
- return resp, body['servers_reservation']
- if CONF.compute_feature_enabled.enable_instance_password:
- create_schema = schema.create_server_with_admin_pass
- else:
- create_schema = schema.create_server
- self.validate_response(create_schema, resp, body)
- return resp, body['server']
-
- def update_server(self, server_id, name=None, meta=None, access_ip_v4=None,
- access_ip_v6=None, disk_config=None):
- """
- Updates the properties of an existing server.
- server_id: The id of an existing server.
- name: The name of the server.
- access_ip_v4: The IPv4 access address for the server.
- access_ip_v6: The IPv6 access address for the server.
- """
-
- post_body = {}
-
- if meta is not None:
- post_body['metadata'] = meta
-
- if name is not None:
- post_body['name'] = name
-
- if access_ip_v4 is not None:
- post_body['os-access-ips:access_ip_v4'] = access_ip_v4
-
- if access_ip_v6 is not None:
- post_body['os-access-ips:access_ip_v6'] = access_ip_v6
-
- if disk_config is not None:
- post_body['os-disk-config:disk_config'] = disk_config
-
- post_body = json.dumps({'server': post_body})
- resp, body = self.put("servers/%s" % str(server_id), post_body)
- body = json.loads(body)
- self.validate_response(schema.update_server, resp, body)
- return resp, body['server']
-
- def get_server(self, server_id):
- """Returns the details of an existing server."""
- resp, body = self.get("servers/%s" % str(server_id))
- body = json.loads(body)
- self.validate_response(schema.get_server, resp, body)
- return resp, body['server']
-
- def delete_server(self, server_id):
- """Deletes the given server."""
- resp, body = self.delete("servers/%s" % str(server_id))
- self.validate_response(common_schema.delete_server, resp, body)
- return resp, body
-
- def list_servers(self, params=None):
- """Lists all servers for a user."""
-
- url = 'servers'
- if params:
- url += '?%s' % urllib.urlencode(params)
-
- resp, body = self.get(url)
- body = json.loads(body)
- self.validate_response(common_schema.list_servers, resp, body)
- return resp, body
-
- def list_servers_with_detail(self, params=None):
- """Lists all servers in detail for a user."""
-
- url = 'servers/detail'
- if params:
- url += '?%s' % urllib.urlencode(params)
-
- resp, body = self.get(url)
- body = json.loads(body)
- self.validate_response(schema.list_servers_detail, resp, body)
- return resp, body
-
- def wait_for_server_status(self, server_id, status, extra_timeout=0,
- raise_on_error=True):
- """Waits for a server to reach a given status."""
- return waiters.wait_for_server_status(self, server_id, status,
- extra_timeout=extra_timeout,
- raise_on_error=raise_on_error)
-
- def wait_for_server_termination(self, server_id, ignore_error=False):
- """Waits for server to reach termination."""
- start_time = int(time.time())
- while True:
- try:
- resp, body = self.get_server(server_id)
- except exceptions.NotFound:
- return
-
- server_status = body['status']
- if server_status == 'ERROR' and not ignore_error:
- raise exceptions.BuildErrorException(server_id=server_id)
-
- if int(time.time()) - start_time >= self.build_timeout:
- raise exceptions.TimeoutException
-
- time.sleep(self.build_interval)
-
- def list_addresses(self, server_id):
- """Lists all addresses for a server."""
- resp, body = self.get("servers/%s/ips" % str(server_id))
- body = json.loads(body)
- self.validate_response(schema.list_addresses, resp, body)
- return resp, body['addresses']
-
- def list_addresses_by_network(self, server_id, network_id):
- """Lists all addresses of a specific network type for a server."""
- resp, body = self.get("servers/%s/ips/%s" %
- (str(server_id), network_id))
- body = json.loads(body)
- self.validate_response(schema.list_addresses_by_network, resp, body)
- return resp, body
-
- def action(self, server_id, action_name, response_key,
- schema=common_schema.server_actions_common_schema, **kwargs):
- post_body = json.dumps({action_name: kwargs})
- resp, body = self.post('servers/%s/action' % str(server_id),
- post_body)
- if response_key is not None:
- body = json.loads(body)
- # Check for Schema as 'None' because if we do not have any server
- # action schema implemented yet then they can pass 'None' to skip
- # the validation.Once all server action has their schema
- # implemented then, this check can be removed if every actions are
- # supposed to validate their response.
- # TODO(GMann): Remove the below 'if' check once all server actions
- # schema are implemented.
- if schema is not None:
- self.validate_response(schema, resp, body)
- body = body[response_key]
- else:
- self.validate_response(schema, resp, body)
- return resp, body
-
- def create_backup(self, server_id, backup_type, rotation, name):
- """Backup a server instance."""
- return self.action(server_id, "create_backup", None,
- backup_type=backup_type,
- rotation=rotation,
- name=name)
-
- def change_password(self, server_id, admin_password):
- """Changes the root password for the server."""
- return self.action(server_id, 'change_password',
- None, schema.server_actions_change_password,
- admin_password=admin_password)
-
- def get_password(self, server_id):
- resp, body = self.get("servers/%s/os-server-password" %
- str(server_id))
- body = json.loads(body)
- self.validate_response(common_schema.get_password, resp, body)
- return resp, body
-
- def delete_password(self, server_id):
- """
- Removes the encrypted server password from the metadata server
- Note that this does not actually change the instance server
- password.
- """
- resp, body = self.delete("servers/%s/os-server-password" %
- str(server_id))
- self.validate_response(common_schema.server_actions_delete_password,
- resp, body)
- return resp, body
-
- def reboot(self, server_id, reboot_type):
- """Reboots a server."""
- return self.action(server_id, 'reboot', None, type=reboot_type)
-
- def rebuild(self, server_id, image_ref, **kwargs):
- """Rebuilds a server with a new image."""
- kwargs['image_ref'] = image_ref
- if 'disk_config' in kwargs:
- kwargs['os-disk-config:disk_config'] = kwargs['disk_config']
- del kwargs['disk_config']
- if CONF.compute_feature_enabled.enable_instance_password:
- rebuild_schema = schema.rebuild_server_with_admin_pass
- else:
- rebuild_schema = schema.rebuild_server
- return self.action(server_id, 'rebuild', 'server',
- rebuild_schema, **kwargs)
-
- def resize(self, server_id, flavor_ref, **kwargs):
- """Changes the flavor of a server."""
- kwargs['flavor_ref'] = flavor_ref
- if 'disk_config' in kwargs:
- kwargs['os-disk-config:disk_config'] = kwargs['disk_config']
- del kwargs['disk_config']
- return self.action(server_id, 'resize', None, **kwargs)
-
- def confirm_resize(self, server_id, **kwargs):
- """Confirms the flavor change for a server."""
- return self.action(server_id, 'confirm_resize', None, **kwargs)
-
- def revert_resize(self, server_id, **kwargs):
- """Reverts a server back to its original flavor."""
- return self.action(server_id, 'revert_resize', None, **kwargs)
-
- def create_image(self, server_id, name, meta=None):
- """Creates an image of the original server."""
-
- post_body = {
- 'create_image': {
- 'name': name,
- }
- }
-
- if meta is not None:
- post_body['create_image']['metadata'] = meta
-
- post_body = json.dumps(post_body)
- resp, body = self.post('servers/%s/action' % str(server_id),
- post_body)
- return resp, body
-
- def list_server_metadata(self, server_id):
- resp, body = self.get("servers/%s/metadata" % str(server_id))
- body = json.loads(body)
- self.validate_response(common_schema.list_server_metadata, resp, body)
- return resp, body['metadata']
-
- def set_server_metadata(self, server_id, meta, no_metadata_field=False):
- if no_metadata_field:
- post_body = ""
- else:
- post_body = json.dumps({'metadata': meta})
- resp, body = self.put('servers/%s/metadata' % str(server_id),
- post_body)
- body = json.loads(body)
- self.validate_response(common_schema.set_server_metadata, resp, body)
- return resp, body['metadata']
-
- def update_server_metadata(self, server_id, meta):
- post_body = json.dumps({'metadata': meta})
- resp, body = self.post('servers/%s/metadata' % str(server_id),
- post_body)
- body = json.loads(body)
- self.validate_response(schema.update_server_metadata, resp, body)
- return resp, body['metadata']
-
- def get_server_metadata_item(self, server_id, key):
- resp, body = self.get("servers/%s/metadata/%s" % (str(server_id), key))
- body = json.loads(body)
- self.validate_response(schema.set_get_server_metadata_item,
- resp, body)
- return resp, body['metadata']
-
- def set_server_metadata_item(self, server_id, key, meta):
- post_body = json.dumps({'metadata': meta})
- resp, body = self.put('servers/%s/metadata/%s' % (str(server_id), key),
- post_body)
- body = json.loads(body)
- self.validate_response(schema.set_get_server_metadata_item,
- resp, body)
- return resp, body['metadata']
-
- def delete_server_metadata_item(self, server_id, key):
- resp, body = self.delete("servers/%s/metadata/%s" %
- (str(server_id), key))
- self.validate_response(common_schema.delete_server_metadata_item,
- resp, body)
- return resp, body
-
- def stop(self, server_id, **kwargs):
- return self.action(server_id, 'stop', None, **kwargs)
-
- def start(self, server_id, **kwargs):
- return self.action(server_id, 'start', None, **kwargs)
-
- def attach_volume(self, server_id, volume_id, device='/dev/vdz'):
- """Attaches a volume to a server instance."""
- resp, body = self.action(server_id, 'attach', None,
- volume_id=volume_id, device=device)
- self.validate_response(schema.attach_detach_volume, resp, body)
- return resp, body
-
- def detach_volume(self, server_id, volume_id):
- """Detaches a volume from a server instance."""
- resp, body = self.action(server_id, 'detach', None,
- volume_id=volume_id)
- self.validate_response(schema.attach_detach_volume, resp, body)
- return resp, body
-
- def live_migrate_server(self, server_id, dest_host, use_block_migration):
- """This should be called with administrator privileges ."""
-
- migrate_params = {
- "disk_over_commit": False,
- "block_migration": use_block_migration,
- "host": dest_host
- }
-
- req_body = json.dumps({'migrate_live': migrate_params})
-
- resp, body = self.post("servers/%s/action" % str(server_id),
- req_body)
- self.validate_response(common_schema.server_actions_common_schema,
- resp, body)
- return resp, body
-
- def migrate_server(self, server_id, **kwargs):
- """Migrates a server to a new host."""
- return self.action(server_id, 'migrate', None, **kwargs)
-
- def lock_server(self, server_id, **kwargs):
- """Locks the given server."""
- return self.action(server_id, 'lock', None, **kwargs)
-
- def unlock_server(self, server_id, **kwargs):
- """UNlocks the given server."""
- return self.action(server_id, 'unlock', None, **kwargs)
-
- def suspend_server(self, server_id, **kwargs):
- """Suspends the provided server."""
- return self.action(server_id, 'suspend', None, **kwargs)
-
- def resume_server(self, server_id, **kwargs):
- """Un-suspends the provided server."""
- return self.action(server_id, 'resume', None, **kwargs)
-
- def pause_server(self, server_id, **kwargs):
- """Pauses the provided server."""
- return self.action(server_id, 'pause', None, **kwargs)
-
- def unpause_server(self, server_id, **kwargs):
- """Un-pauses the provided server."""
- return self.action(server_id, 'unpause', None, **kwargs)
-
- def reset_state(self, server_id, state='error'):
- """Resets the state of a server to active/error."""
- return self.action(server_id, 'reset_state', None, state=state)
-
- def shelve_server(self, server_id, **kwargs):
- """Shelves the provided server."""
- return self.action(server_id, 'shelve', None, **kwargs)
-
- def unshelve_server(self, server_id, **kwargs):
- """Un-shelves the provided server."""
- return self.action(server_id, 'unshelve', None, **kwargs)
-
- def shelve_offload_server(self, server_id, **kwargs):
- """Shelve-offload the provided server."""
- return self.action(server_id, 'shelve_offload', None, **kwargs)
-
- def get_console_output(self, server_id, length):
- if length is None:
- # NOTE(mriedem): -1 means optional/unlimited in the nova v3 API.
- length = -1
- return self.action(server_id, 'get_console_output', 'output',
- common_schema.get_console_output, length=length)
-
- def rescue_server(self, server_id, **kwargs):
- """Rescue the provided server."""
- post_body = json.dumps({'rescue': kwargs})
- resp, body = self.post('servers/%s/action' % str(server_id),
- post_body)
- if CONF.compute_feature_enabled.enable_instance_password:
- rescue_schema = schema.rescue_server_with_admin_pass
- else:
- rescue_schema = schema.rescue_server
- body = json.loads(body)
- self.validate_response(rescue_schema, resp, body)
- return resp, body
-
- def unrescue_server(self, server_id):
- """Unrescue the provided server."""
- return self.action(server_id, 'unrescue', None)
-
- def get_server_diagnostics(self, server_id):
- """Get the usage data for a server."""
- resp, body = self.get("servers/%s/os-server-diagnostics" %
- str(server_id))
- return resp, json.loads(body)
-
- def list_server_actions(self, server_id):
- """List the provided server action."""
- resp, body = self.get("servers/%s/os-server-actions" %
- str(server_id))
- body = json.loads(body)
- self.validate_response(schema.list_server_actions, resp, body)
- return resp, body['server_actions']
-
- def get_server_action(self, server_id, request_id):
- """Returns the action details of the provided server."""
- resp, body = self.get("servers/%s/os-server-actions/%s" %
- (str(server_id), str(request_id)))
- body = json.loads(body)
- self.validate_response(schema.get_server_action, resp, body)
- return resp, body['server_action']
-
- def force_delete_server(self, server_id, **kwargs):
- """Force delete a server."""
- return self.action(server_id, 'force_delete', None, **kwargs)
-
- def restore_soft_deleted_server(self, server_id, **kwargs):
- """Restore a soft-deleted server."""
- return self.action(server_id, 'restore', None, **kwargs)
-
- def get_vnc_console(self, server_id, type):
- """Get URL of VNC console."""
- post_body = json.dumps({
- "get_vnc_console": {
- "type": type
- }
- })
- resp, body = self.post('servers/%s/action' % str(server_id),
- post_body)
- body = json.loads(body)
- self.validate_response(common_schema.get_vnc_console, resp, body)
- return resp, body['console']
-
- def reset_network(self, server_id, **kwargs):
- """Resets the Network of a server"""
- return self.action(server_id, 'reset_network', None, **kwargs)
-
- def inject_network_info(self, server_id, **kwargs):
- """Inject the Network Info into server"""
- return self.action(server_id, 'inject_network_info', None, **kwargs)
-
- def get_spice_console(self, server_id, console_type):
- """Get URL of Spice console."""
- return self.action(server_id, "get_spice_console"
- "console", None, type=console_type)
-
- def get_rdp_console(self, server_id, console_type):
- """Get URL of RDP console."""
- return self.action(server_id, "get_rdp_console"
- "console", None, type=console_type)
diff --git a/tempest/services/compute/v3/json/services_client.py b/tempest/services/compute/v3/json/services_client.py
deleted file mode 100644
index 0645287..0000000
--- a/tempest/services/compute/v3/json/services_client.py
+++ /dev/null
@@ -1,74 +0,0 @@
-# Copyright 2013 NEC Corporation
-# Copyright 2013 IBM Corp.
-# All Rights Reserved.
-#
-# 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 urllib
-
-from tempest.api_schema.response.compute import services as schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
-
-
-class ServicesV3ClientJSON(rest_client.RestClient):
-
- def __init__(self, auth_provider):
- super(ServicesV3ClientJSON, self).__init__(auth_provider)
- self.service = CONF.compute.catalog_v3_type
-
- def list_services(self, params=None):
- url = 'os-services'
- if params:
- url += '?%s' % urllib.urlencode(params)
-
- resp, body = self.get(url)
- body = json.loads(body)
- self.validate_response(schema.list_services, resp, body)
- return resp, body['services']
-
- def enable_service(self, host_name, binary):
- """
- Enable service on a host
- host_name: Name of host
- binary: Service binary
- """
- post_body = json.dumps({
- 'service': {
- 'binary': binary,
- 'host': host_name
- }
- })
- resp, body = self.put('os-services/enable', post_body)
- body = json.loads(body)
- self.validate_response(schema.enable_service, resp, body)
- return resp, body['service']
-
- def disable_service(self, host_name, binary):
- """
- Disable service on a host
- host_name: Name of host
- binary: Service binary
- """
- post_body = json.dumps({
- 'service': {
- 'binary': binary,
- 'host': host_name
- }
- })
- resp, body = self.put('os-services/disable', post_body)
- body = json.loads(body)
- return resp, body['service']
diff --git a/tempest/services/compute/v3/json/version_client.py b/tempest/services/compute/v3/json/version_client.py
deleted file mode 100644
index bc4f58c..0000000
--- a/tempest/services/compute/v3/json/version_client.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright 2014 NEC Corporation.
-# All Rights Reserved.
-#
-# 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 tempest.api_schema.response.compute import version as schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
-
-
-class VersionV3ClientJSON(rest_client.RestClient):
-
- def __init__(self, auth_provider):
- super(VersionV3ClientJSON, self).__init__(auth_provider)
- self.service = CONF.compute.catalog_v3_type
-
- def get_version(self):
- resp, body = self.get('')
- body = json.loads(body)
- self.validate_response(schema.version, resp, body)
- return resp, body['version']
diff --git a/tempest/services/identity/json/identity_client.py b/tempest/services/identity/json/identity_client.py
index e76c1bd..281464c 100644
--- a/tempest/services/identity/json/identity_client.py
+++ b/tempest/services/identity/json/identity_client.py
@@ -26,10 +26,6 @@
self.service = CONF.identity.catalog_type
self.endpoint_url = 'adminURL'
- # Needed for xml service client
- self.list_tags = ["roles", "tenants", "users", "services",
- "extensions"]
-
def has_admin_extensions(self):
"""
Returns True if the KSADM Admin Extensions are supported
@@ -335,9 +331,6 @@
body=None):
"""A simple HTTP request interface."""
if headers is None:
- # Always accept 'json', for TokenClientXML too.
- # Because XML response is not easily
- # converted to the corresponding JSON one
headers = self.get_headers(accept_type="json")
elif extra_headers:
try:
diff --git a/tempest/tests/cmd/test_verify_tempest_config.py b/tempest/tests/cmd/test_verify_tempest_config.py
index b672b86..ba69a5d 100644
--- a/tempest/tests/cmd/test_verify_tempest_config.py
+++ b/tempest/tests/cmd/test_verify_tempest_config.py
@@ -336,45 +336,6 @@
self.assertEqual(sorted(['fake1', 'fake2', 'not_fake']),
sorted(results['nova']['extensions']))
- def test_verify_extensions_nova_v3(self):
- def fake_list_extensions():
- return (None, [{'alias': 'fake1'},
- {'alias': 'fake2'},
- {'alias': 'not_fake'}])
- fake_os = mock.MagicMock()
- fake_os.extensions_v3_client.list_extensions = fake_list_extensions
- self.useFixture(mockpatch.PatchObject(
- verify_tempest_config, 'get_enabled_extensions',
- return_value=(['fake1', 'fake2', 'fake3'])))
- results = verify_tempest_config.verify_extensions(fake_os,
- 'nova_v3', {})
- self.assertIn('nova_v3', results)
- self.assertIn('fake1', results['nova_v3'])
- self.assertTrue(results['nova_v3']['fake1'])
- self.assertIn('fake2', results['nova_v3'])
- self.assertTrue(results['nova_v3']['fake2'])
- self.assertIn('fake3', results['nova_v3'])
- self.assertFalse(results['nova_v3']['fake3'])
- self.assertIn('not_fake', results['nova_v3'])
- self.assertFalse(results['nova_v3']['not_fake'])
-
- def test_verify_extensions_nova_v3_all(self):
- def fake_list_extensions():
- return (None, {'extensions': [{'alias': 'fake1'},
- {'alias': 'fake2'},
- {'alias': 'not_fake'}]})
- fake_os = mock.MagicMock()
- fake_os.extensions_v3_client.list_extensions = fake_list_extensions
- self.useFixture(mockpatch.PatchObject(
- verify_tempest_config, 'get_enabled_extensions',
- return_value=(['all'])))
- results = verify_tempest_config.verify_extensions(fake_os,
- 'nova_v3', {})
- self.assertIn('nova_v3', results)
- self.assertIn('extensions', results['nova_v3'])
- self.assertEqual(sorted(['fake1', 'fake2', 'not_fake']),
- sorted(results['nova_v3']['extensions']))
-
def test_verify_extensions_swift(self):
def fake_list_extensions():
return (None, {'fake1': 'metadata',
diff --git a/tempest/tests/test_credentials.py b/tempest/tests/test_credentials.py
index ea576c4..fc80fe2 100644
--- a/tempest/tests/test_credentials.py
+++ b/tempest/tests/test_credentials.py
@@ -24,7 +24,6 @@
from tempest import exceptions
from tempest.tests import base
from tempest.tests import fake_config
-from tempest.tests import fake_http
from tempest.tests import fake_identity
@@ -39,8 +38,6 @@
def setUp(self):
super(CredentialsTests, self).setUp()
- self.fake_http = fake_http.fake_httplib2(return_type=200)
- self.stubs.Set(http.ClosingHttp, 'request', self.fake_http.request)
self.useFixture(fake_config.ConfigFixture())
self.stubs.Set(config, 'TempestConfigPrivate', fake_config.FakePrivate)
@@ -83,7 +80,6 @@
def setUp(self):
super(KeystoneV2CredentialsTests, self).setUp()
self.stubs.Set(http.ClosingHttp, 'request', self.identity_response)
- self.stubs.Set(config, 'TempestConfigPrivate', fake_config.FakePrivate)
def _verify_credentials(self, credentials_class, filled=True,
creds_dict=None):
diff --git a/tempest/tests/test_rest_client.py b/tempest/tests/test_rest_client.py
index bb463e5..5b2ce7a 100644
--- a/tempest/tests/test_rest_client.py
+++ b/tempest/tests/test_rest_client.py
@@ -351,7 +351,7 @@
**self.set_data("500"))
def test_response_501_with_text(self):
- self.assertRaises(exceptions.ServerFault,
+ self.assertRaises(exceptions.NotImplemented,
self.rest_client._error_checker,
**self.set_data("501"))
@@ -363,7 +363,7 @@
def test_response_501_with_dict(self):
r_body = '{"resp_body": {"err": "fake_resp_body"}}'
- self.assertRaises(exceptions.ServerFault,
+ self.assertRaises(exceptions.NotImplemented,
self.rest_client._error_checker,
**self.set_data("501", r_body=r_body))