Merge "Adding network api xml support"
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index f1aaa07..703d92a 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -1,5 +1,5 @@
[DEFAULT]
-# log_config = /opt/stack/tempest/etc/logging.conf.sample
+#log_config = /opt/stack/tempest/etc/logging.conf.sample
# disable logging to the stderr
use_stderr = False
@@ -272,6 +272,9 @@
# Set to True if the Account Quota middleware is enabled
accounts_quotas_available = True
+# Set operator role for tests that require creating a container
+operator_role = Member
+
[boto]
# This section contains configuration options used when executing tests
# with boto.
@@ -285,7 +288,7 @@
aws_access =
aws_secret =
-#Image materials for S3 upload
+# Image materials for S3 upload
# ALL content of the specified directory will be uploaded to S3
s3_materials_path = /opt/stack/devstack/files/images/s3-materials/cirros-0.3.1
@@ -293,22 +296,22 @@
# Subdirectories not allowed!
# The filenames will be used as a Keys in the S3 Buckets
-#ARI Ramdisk manifest. Must be in the above s3_materials_path
+# ARI Ramdisk manifest. Must be in the above s3_materials_path
ari_manifest = cirros-0.3.1-x86_64-initrd.manifest.xml
-#AMI Machine Image manifest. Must be in the above s3_materials_path
+# AMI Machine Image manifest. Must be in the above s3_materials_path
ami_manifest = cirros-0.3.1-x86_64-blank.img.manifest.xml
-#AKI Kernel Image manifest, Must be in the above s3_materials_path
+# AKI Kernel Image manifest, Must be in the above s3_materials_path
aki_manifest = cirros-0.3.1-x86_64-vmlinuz.manifest.xml
-#Instance type
+# Instance type
instance_type = m1.tiny
-#TCP/IP connection timeout
+# TCP/IP connection timeout
http_socket_timeout = 5
-#Number of retries actions on connection or 5xx error
+# Number of retries actions on connection or 5xx error
num_retries = 1
# Status change wait timout
diff --git a/tempest/api/compute/volumes/test_attach_volume.py b/tempest/api/compute/volumes/test_attach_volume.py
index a3b051e..b67a5e0 100644
--- a/tempest/api/compute/volumes/test_attach_volume.py
+++ b/tempest/api/compute/volumes/test_attach_volume.py
@@ -55,6 +55,7 @@
# Start a server and wait for it to become ready
resp, server = self.create_server(wait_until='ACTIVE',
adminPass='password')
+ self.server = server
# Record addresses so that we can ssh later
resp, server['addresses'] = \
diff --git a/tempest/api/identity/admin/v3/test_roles.py b/tempest/api/identity/admin/v3/test_roles.py
index cab84c0..980323a 100644
--- a/tempest/api/identity/admin/v3/test_roles.py
+++ b/tempest/api/identity/admin/v3/test_roles.py
@@ -54,7 +54,7 @@
resp[1], _ = cls.v3_client.delete_group(cls.group_body['id'])
resp[2], _ = cls.v3_client.delete_user(cls.user_body['id'])
resp[3], _ = cls.v3_client.delete_project(cls.project['id'])
- #NOTE(harika-vakadi): It is necessary to disable the domian
+ # NOTE(harika-vakadi): It is necessary to disable the domian
# before deleting,or else it would result in unauthorized error
cls.v3_client.update_domain(cls.domain['id'], enabled=False)
resp[4], _ = cls.v3_client.delete_domain(cls.domain['id'])
diff --git a/tempest/api/object_storage/base.py b/tempest/api/object_storage/base.py
index 820328c..e6e8d17 100644
--- a/tempest/api/object_storage/base.py
+++ b/tempest/api/object_storage/base.py
@@ -18,6 +18,7 @@
from tempest.api.identity.base import DataGenerator
from tempest import clients
+from tempest.common import isolated_creds
from tempest import exceptions
import tempest.test
@@ -30,16 +31,41 @@
if not cls.config.service_available.swift:
skip_msg = ("%s skipped as swift is not available" % cls.__name__)
raise cls.skipException(skip_msg)
- cls.os = clients.Manager()
+ cls.isolated_creds = isolated_creds.IsolatedCreds(cls.__name__)
+ if cls.config.compute.allow_tenant_isolation:
+ # Get isolated creds for normal user
+ creds = cls.isolated_creds.get_primary_creds()
+ username, tenant_name, password = creds
+ cls.os = clients.Manager(username=username,
+ password=password,
+ tenant_name=tenant_name)
+ # Get isolated creds for admin user
+ admin_creds = cls.isolated_creds.get_admin_creds()
+ admin_username, admin_tenant_name, admin_password = admin_creds
+ cls.os_admin = clients.Manager(username=admin_username,
+ password=admin_password,
+ tenant_name=admin_tenant_name)
+ # Get isolated creds for alt user
+ alt_creds = cls.isolated_creds.get_alt_creds()
+ alt_username, alt_tenant, alt_password = alt_creds
+ cls.os_alt = clients.Manager(username=alt_username,
+ password=alt_password,
+ tenant_name=alt_tenant)
+ # Add isolated users to operator role so that they can create a
+ # container in swift.
+ cls._assign_member_role()
+ else:
+ cls.os = clients.Manager()
+ cls.os_admin = clients.AdminManager()
+ cls.os_alt = clients.AltManager()
+
cls.object_client = cls.os.object_client
cls.container_client = cls.os.container_client
cls.account_client = cls.os.account_client
cls.custom_object_client = cls.os.custom_object_client
- cls.os_admin = clients.AdminManager()
cls.token_client = cls.os_admin.token_client
cls.identity_admin_client = cls.os_admin.identity_client
cls.custom_account_client = cls.os.custom_account_client
- cls.os_alt = clients.AltManager()
cls.object_client_alt = cls.os_alt.object_client
cls.container_client_alt = cls.os_alt.container_client
cls.identity_client_alt = cls.os_alt.identity_client
@@ -47,6 +73,22 @@
cls.data = DataGenerator(cls.identity_admin_client)
@classmethod
+ def _assign_member_role(cls):
+ primary_user = cls.isolated_creds.get_primary_user()
+ alt_user = cls.isolated_creds.get_alt_user()
+ swift_role = cls.config.object_storage.operator_role
+ try:
+ resp, roles = cls.os_admin.identity_client.list_roles()
+ role = next(r for r in roles if r['name'] == swift_role)
+ except StopIteration:
+ msg = "No role named %s found" % swift_role
+ raise exceptions.NotFound(msg)
+ for user in [primary_user, alt_user]:
+ cls.os_admin.identity_client.assign_user_role(user['tenantId'],
+ user['id'],
+ role['id'])
+
+ @classmethod
def delete_containers(cls, containers, container_client=None,
object_client=None):
"""Remove given containers and all objects in them.
diff --git a/tempest/cli/__init__.py b/tempest/cli/__init__.py
index f04d23f..b34d516 100644
--- a/tempest/cli/__init__.py
+++ b/tempest/cli/__init__.py
@@ -93,7 +93,7 @@
def cmd_with_auth(self, cmd, action, flags='', params='',
admin=True, fail_ok=False):
"""Executes given command with auth attributes appended."""
- #TODO(jogo) make admin=False work
+ # TODO(jogo) make admin=False work
creds = ('--os-username %s --os-tenant-name %s --os-password %s '
'--os-auth-url %s ' % (self.identity.admin_username,
self.identity.admin_tenant_name, self.identity.admin_password,
diff --git a/tempest/cli/simple_read_only/test_compute.py b/tempest/cli/simple_read_only/test_compute.py
index 4c7f604..9b358e6 100644
--- a/tempest/cli/simple_read_only/test_compute.py
+++ b/tempest/cli/simple_read_only/test_compute.py
@@ -48,7 +48,7 @@
self.nova,
'this-does-nova-exist')
- #NOTE(jogo): Commands in order listed in 'nova help'
+ # NOTE(jogo): Commands in order listed in 'nova help'
# Positional arguments:
diff --git a/tempest/cli/simple_read_only/test_compute_manage.py b/tempest/cli/simple_read_only/test_compute_manage.py
index 1848827..523c65f 100644
--- a/tempest/cli/simple_read_only/test_compute_manage.py
+++ b/tempest/cli/simple_read_only/test_compute_manage.py
@@ -41,7 +41,7 @@
self.nova_manage,
'this-does-nova-exist')
- #NOTE(jogo): Commands in order listed in 'nova-manage -h'
+ # NOTE(jogo): Commands in order listed in 'nova-manage -h'
# test flags
def test_help_flag(self):
diff --git a/tempest/common/rest_client.py b/tempest/common/rest_client.py
index 759ab81..ea5b4f4 100644
--- a/tempest/common/rest_client.py
+++ b/tempest/common/rest_client.py
@@ -323,7 +323,7 @@
if (resp.status in set((204, 205, 304)) or resp.status < 200 or
method.upper() == 'HEAD') and resp_body:
raise exceptions.ResponseWithNonEmptyBody(status=resp.status)
- #NOTE(afazekas):
+ # NOTE(afazekas):
# If the HTTP Status Code is 205
# 'The response MUST NOT include an entity.'
# A HTTP entity has an entity-body and an 'entity-header'.
@@ -336,7 +336,7 @@
0 != len(set(resp.keys()) - set(('status',)) -
self.response_header_lc - self.general_header_lc)):
raise exceptions.ResponseWithEntity()
- #NOTE(afazekas)
+ # NOTE(afazekas)
# Now the swift sometimes (delete not empty container)
# returns with non json error response, we can create new rest class
# for swift.
@@ -458,8 +458,8 @@
message = resp_body
if parse_resp:
resp_body = self._parse_resp(resp_body)
- #I'm seeing both computeFault and cloudServersFault come back.
- #Will file a bug to fix, but leave as is for now.
+ # I'm seeing both computeFault and cloudServersFault come back.
+ # Will file a bug to fix, but leave as is for now.
if 'cloudServersFault' in resp_body:
message = resp_body['cloudServersFault']['message']
elif 'computeFault' in resp_body:
diff --git a/tempest/common/utils/linux/remote_client.py b/tempest/common/utils/linux/remote_client.py
index de2bf43..2cbb74d 100644
--- a/tempest/common/utils/linux/remote_client.py
+++ b/tempest/common/utils/linux/remote_client.py
@@ -24,7 +24,7 @@
class RemoteClient():
- #Note(afazekas): It should always get an address instead of server
+ # NOTE(afazekas): It should always get an address instead of server
def __init__(self, server, username, password=None, pkey=None):
ssh_timeout = TempestConfig().compute.ssh_timeout
network = TempestConfig().compute.network_for_ssh
diff --git a/tempest/config.py b/tempest/config.py
index 9b1a91e..e0ac843 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -369,6 +369,10 @@
cfg.BoolOpt('accounts_quotas_available',
default=True,
help="Set to True if the Account Quota middleware is enabled"),
+ cfg.StrOpt('operator_role',
+ default='Member',
+ help="Role to add to users created for swift tests to "
+ "enable creating containers"),
]
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index d512ae8..dded93d 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -283,6 +283,16 @@
LOG.debug("Created server: %s", server)
return server
+ def create_keypair(self, client=None, name=None):
+ if client is None:
+ client = self.compute_client
+ if name is None:
+ name = rand_name('scenario-keypair-')
+ keypair = client.keypairs.create(name)
+ self.assertEqual(keypair.name, name)
+ self.set_resource(name, keypair)
+ return keypair
+
class NetworkScenarioTest(OfficialClientTest):
"""
@@ -293,7 +303,7 @@
def check_preconditions(cls):
if (cls.config.service_available.neutron):
cls.enabled = True
- #verify that neutron_available is telling the truth
+ # verify that neutron_available is telling the truth
try:
cls.network_client.list_networks()
except exc.EndpointNotFound:
@@ -312,16 +322,6 @@
cls.config.identity.password,
cls.config.identity.tenant_name).tenant_id
- def _create_keypair(self, client, namestart='keypair-smoke-'):
- kp_name = rand_name(namestart)
- keypair = client.keypairs.create(kp_name)
- try:
- self.assertEqual(keypair.id, kp_name)
- self.set_resource(kp_name, keypair)
- except AttributeError:
- self.fail("Keypair object not successfully created.")
- return keypair
-
def _create_security_group(self, client, namestart='secgroup-smoke-'):
# Create security group
sg_name = rand_name(namestart)
diff --git a/tempest/scenario/test_minimum_basic.py b/tempest/scenario/test_minimum_basic.py
index b789fa2..53d6435 100644
--- a/tempest/scenario/test_minimum_basic.py
+++ b/tempest/scenario/test_minimum_basic.py
@@ -83,11 +83,7 @@
properties=properties)
def nova_keypair_add(self):
- name = rand_name('scenario-keypair-')
-
- self.keypair = self.compute_client.keypairs.create(name=name)
- self.addCleanup(self.compute_client.keypairs.delete, self.keypair)
- self.assertEqual(name, self.keypair.name)
+ self.keypair = self.create_keypair()
def nova_boot(self):
create_kwargs = {'key_name': self.keypair.name}
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index 99b0071..70939f6 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -16,8 +16,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-import testtools
-
from tempest.api.network import common as net_common
from tempest.common.utils.data_utils import rand_name
from tempest import config
@@ -43,7 +41,7 @@
ssh server hosted at the IP address. This check guarantees
that the IP address is associated with the target VM.
- #TODO(mnewby) - Need to implement the following:
+ # TODO(mnewby) - Need to implement the following:
- the Tempest host can ssh into the VM via the IP address and
successfully execute the following:
@@ -162,8 +160,8 @@
@attr(type='smoke')
def test_001_create_keypairs(self):
- self.keypairs[self.tenant_id] = self._create_keypair(
- self.compute_client)
+ self.keypairs[self.tenant_id] = self.create_keypair(
+ name=rand_name('keypair-smoke-'))
@attr(type='smoke')
def test_002_create_security_groups(self):
@@ -182,8 +180,8 @@
@attr(type='smoke')
def test_004_check_networks(self):
- #Checks that we see the newly created network/subnet/router via
- #checking the result of list_[networks,routers,subnets]
+ # Checks that we see the newly created network/subnet/router via
+ # checking the result of list_[networks,routers,subnets]
seen_nets = self._list_networks()
seen_names = [n['name'] for n in seen_nets]
seen_ids = [n['id'] for n in seen_nets]
@@ -254,8 +252,6 @@
self.floating_ips[server].append(floating_ip)
@attr(type='smoke')
- @testtools.skipIf(CONF.service_available.neutron,
- "Skipped unti bug #1210664 is resolved")
def test_008_check_public_network_connectivity(self):
if not self.floating_ips:
raise self.skipTest('No floating ips have been allocated.')
diff --git a/tempest/scenario/test_server_basic_ops.py b/tempest/scenario/test_server_basic_ops.py
index 43ac2d9..e89ff9c 100644
--- a/tempest/scenario/test_server_basic_ops.py
+++ b/tempest/scenario/test_server_basic_ops.py
@@ -36,14 +36,8 @@
* Terminate the instance
"""
- def create_keypair(self):
- kp_name = rand_name('keypair-smoke')
- self.keypair = self.compute_client.keypairs.create(kp_name)
- try:
- self.assertEqual(self.keypair.id, kp_name)
- self.set_resource('keypair', self.keypair)
- except AttributeError:
- self.fail("Keypair object not successfully created.")
+ def add_keypair(self):
+ self.keypair = self.create_keypair()
def create_security_group(self):
sg_name = rand_name('secgroup-smoke')
@@ -83,7 +77,7 @@
def boot_instance(self):
create_kwargs = {
- 'key_name': self.get_resource('keypair').id
+ 'key_name': self.keypair.id
}
instance = self.create_server(self.compute_client,
create_kwargs=create_kwargs)
@@ -131,7 +125,7 @@
self.remove_resource('instance')
def test_server_basicops(self):
- self.create_keypair()
+ self.add_keypair()
self.create_security_group()
self.boot_instance()
self.pause_server()
diff --git a/tempest/scenario/test_snapshot_pattern.py b/tempest/scenario/test_snapshot_pattern.py
index e8ce1bd..41b0fda 100644
--- a/tempest/scenario/test_snapshot_pattern.py
+++ b/tempest/scenario/test_snapshot_pattern.py
@@ -51,10 +51,7 @@
create_kwargs=create_kwargs)
def _add_keypair(self):
- name = rand_name('scenario-keypair-')
- self.keypair = self.compute_client.keypairs.create(name=name)
- self.addCleanup(self.compute_client.keypairs.delete, self.keypair)
- self.assertEqual(name, self.keypair.name)
+ self.keypair = self.create_keypair()
def _create_security_group_rule(self):
sgs = self.compute_client.security_groups.list()
diff --git a/tempest/scenario/test_stamp_pattern.py b/tempest/scenario/test_stamp_pattern.py
index 038d251..2155129 100644
--- a/tempest/scenario/test_stamp_pattern.py
+++ b/tempest/scenario/test_stamp_pattern.py
@@ -71,10 +71,7 @@
create_kwargs=create_kwargs)
def _add_keypair(self):
- name = rand_name('scenario-keypair-')
- self.keypair = self.compute_client.keypairs.create(name=name)
- self.addCleanup(self.compute_client.keypairs.delete, self.keypair)
- self.assertEqual(name, self.keypair.name)
+ self.keypair = self.create_keypair()
def _create_floating_ip(self):
floating_ip = self.compute_client.floating_ips.create()
diff --git a/tempest/whitebox/manager.py b/tempest/whitebox/manager.py
index b2632f1..3b1b107 100644
--- a/tempest/whitebox/manager.py
+++ b/tempest/whitebox/manager.py
@@ -72,7 +72,7 @@
cls.flavor_ref = cls.config.compute.flavor_ref
cls.flavor_ref_alt = cls.config.compute.flavor_ref_alt
- #NOTE(afazekas): Mimics the helper method used in the api tests
+ # NOTE(afazekas): Mimics the helper method used in the api tests
@classmethod
def create_server(cls, **kwargs):
flavor_ref = cls.config.compute.flavor_ref
@@ -127,7 +127,7 @@
cmd = shlex.split(cmd)
result = subprocess.Popen(cmd, stdout=subprocess.PIPE)
- #Todo(rohitk): Need to define host connection parameters in config
+ # TODO(rohitk): Need to define host connection parameters in config
else:
client = self.get_ssh_connection(self.config.whitebox.api_host,
self.config.whitebox.api_user,
diff --git a/tempest/whitebox/test_servers_whitebox.py b/tempest/whitebox/test_servers_whitebox.py
index 1c1cdeb..abe903c 100644
--- a/tempest/whitebox/test_servers_whitebox.py
+++ b/tempest/whitebox/test_servers_whitebox.py
@@ -26,7 +26,7 @@
@classmethod
def setUpClass(cls):
super(ServersWhiteboxTest, cls).setUpClass()
- #NOTE(afazekas): Strange relationship
+ # NOTE(afazekas): Strange relationship
BaseIdentityAdminTest.setUpClass()
cls.client = cls.servers_client
cls.img_client = cls.images_client