Merge "Fixed Typos"
diff --git a/README.rst b/README.rst
index d7063ba..431be7c 100644
--- a/README.rst
+++ b/README.rst
@@ -41,11 +41,13 @@
will tell Tempest where to find the various OpenStack services and
other testing behavior switches.
-The easiest way to create a configuration file is to copy the sample
-one in the ``etc/`` directory ::
+The easiest way to create a configuration file is to generate a sample
+in the ``etc/`` directory ::
$> cd $TEMPEST_ROOT_DIR
- $> cp etc/tempest.conf.sample etc/tempest.conf
+ $> oslo-config-generator --config-file \
+ tools/config/config-generator.tempest.conf \
+ --output-file etc/tempest.conf
After that, open up the ``etc/tempest.conf`` file and edit the
configuration variables to match valid data in your environment.
diff --git a/doc/source/conf.py b/doc/source/conf.py
index daa293c..3ec25ea 100644
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -13,6 +13,19 @@
import sys
import os
+import subprocess
+
+# Build a tempest sample config file:
+def build_sample_config(app):
+ root_dir = os.path.dirname(
+ os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+ subprocess.call(["oslo-config-generator", "--config-file",
+ "tools/config/config-generator.tempest.conf",
+ "--output-file", "doc/source/_static/tempest.conf"],
+ cwd=root_dir)
+
+def setup(app):
+ app.connect('builder-inited', build_sample_config)
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
diff --git a/requirements.txt b/requirements.txt
index 415eaa5..f00de0d 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -15,7 +15,7 @@
oslo.concurrency>=2.3.0 # Apache-2.0
oslo.config>=1.11.0 # Apache-2.0
oslo.i18n>=1.5.0 # Apache-2.0
-oslo.log>=1.6.0 # Apache-2.0
+oslo.log>=1.8.0 # Apache-2.0
oslo.serialization>=1.4.0 # Apache-2.0
oslo.utils>=1.9.0 # Apache-2.0
six>=1.9.0
diff --git a/tempest/api/compute/servers/test_list_server_filters.py b/tempest/api/compute/servers/test_list_server_filters.py
index a75cb3e..6160844 100644
--- a/tempest/api/compute/servers/test_list_server_filters.py
+++ b/tempest/api/compute/servers/test_list_server_filters.py
@@ -305,12 +305,20 @@
params = {'ip': ip}
else:
params = {'ip6': ip}
+ # capture all servers in case something goes wrong
+ all_servers = self.client.list_servers(detail=True)
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))
+ self.assertIn(self.s1_name, map(lambda x: x['name'], servers),
+ "%s not found in %s, all servers %s" %
+ (self.s1_name, servers, all_servers))
+ self.assertIn(self.s2_name, map(lambda x: x['name'], servers),
+ "%s not found in %s, all servers %s" %
+ (self.s2_name, servers, all_servers))
+ self.assertIn(self.s3_name, map(lambda x: x['name'], servers),
+ "%s not found in %s, all servers %s" %
+ (self.s3_name, servers, all_servers))
@test.idempotent_id('67aec2d0-35fe-4503-9f92-f13272b867ed')
def test_list_servers_detailed_limit_results(self):
diff --git a/tempest/api/identity/admin/v2/test_endpoints.py b/tempest/api/identity/admin/v2/test_endpoints.py
new file mode 100644
index 0000000..3af2e90
--- /dev/null
+++ b/tempest/api/identity/admin/v2/test_endpoints.py
@@ -0,0 +1,90 @@
+# 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.identity import base
+from tempest.common.utils import data_utils
+from tempest import test
+
+
+class EndPointsTestJSON(base.BaseIdentityV2AdminTest):
+
+ @classmethod
+ def resource_setup(cls):
+ super(EndPointsTestJSON, cls).resource_setup()
+ cls.service_ids = list()
+ s_name = data_utils.rand_name('service')
+ s_type = data_utils.rand_name('type')
+ s_description = data_utils.rand_name('description')
+ cls.service_data =\
+ cls.client.create_service(s_name, s_type,
+ description=s_description)
+ cls.service_id = cls.service_data['id']
+ cls.service_ids.append(cls.service_id)
+ # Create endpoints so as to use for LIST and GET test cases
+ cls.setup_endpoints = list()
+ for i in range(2):
+ region = data_utils.rand_name('region')
+ url = data_utils.rand_url()
+ endpoint = cls.client.create_endpoint(cls.service_id,
+ region,
+ publicurl=url,
+ adminurl=url,
+ internalurl=url)
+ # list_endpoints() will return 'enabled' field
+ endpoint['enabled'] = True
+ cls.setup_endpoints.append(endpoint)
+
+ @classmethod
+ def resource_cleanup(cls):
+ for e in cls.setup_endpoints:
+ cls.client.delete_endpoint(e['id'])
+ for s in cls.service_ids:
+ cls.client.delete_service(s)
+ super(EndPointsTestJSON, cls).resource_cleanup()
+
+ @test.idempotent_id('11f590eb-59d8-4067-8b2b-980c7f387f51')
+ def test_list_endpoints(self):
+ # Get a list of endpoints
+ fetched_endpoints = self.client.list_endpoints()
+ # Asserting LIST endpoints
+ missing_endpoints =\
+ [e for e in self.setup_endpoints if e not in fetched_endpoints]
+ self.assertEqual(0, len(missing_endpoints),
+ "Failed to find endpoint %s in fetched list" %
+ ', '.join(str(e) for e in missing_endpoints))
+
+ @test.idempotent_id('9974530a-aa28-4362-8403-f06db02b26c1')
+ def test_create_list_delete_endpoint(self):
+ region = data_utils.rand_name('region')
+ url = data_utils.rand_url()
+ endpoint = self.client.create_endpoint(self.service_id,
+ region,
+ publicurl=url,
+ adminurl=url,
+ internalurl=url)
+ # Asserting Create Endpoint response body
+ self.assertIn('id', endpoint)
+ self.assertEqual(region, endpoint['region'])
+ self.assertEqual(url, endpoint['publicurl'])
+ # Checking if created endpoint is present in the list of endpoints
+ fetched_endpoints = self.client.list_endpoints()
+ fetched_endpoints_id = [e['id'] for e in fetched_endpoints]
+ self.assertIn(endpoint['id'], fetched_endpoints_id)
+ # Deleting the endpoint created in this method
+ self.client.delete_endpoint(endpoint['id'])
+ # Checking whether endpoint is deleted successfully
+ fetched_endpoints = self.client.list_endpoints()
+ fetched_endpoints_id = [e['id'] for e in fetched_endpoints]
+ self.assertNotIn(endpoint['id'], fetched_endpoints_id)
diff --git a/tempest/clients.py b/tempest/clients.py
index 2a06120..7cb4347 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -344,15 +344,25 @@
def _set_identity_clients(self):
params = {
'service': CONF.identity.catalog_type,
- 'region': CONF.identity.region,
- 'endpoint_type': 'adminURL'
+ 'region': CONF.identity.region
}
params.update(self.default_params_with_timeout_values)
-
+ params_v2_admin = params.copy()
+ params_v2_admin['endpoint_type'] = CONF.identity.v2_admin_endpoint_type
+ # Client uses admin endpoint type of Keystone API v2
self.identity_client = IdentityClient(self.auth_provider,
- **params)
+ **params_v2_admin)
+ params_v2_public = params.copy()
+ params_v2_public['endpoint_type'] = (
+ CONF.identity.v2_public_endpoint_type)
+ # Client uses public endpoint type of Keystone API v2
+ self.identity_public_client = IdentityClient(self.auth_provider,
+ **params_v2_public)
+ params_v3 = params.copy()
+ params_v3['endpoint_type'] = CONF.identity.v3_endpoint_type
+ # Client uses the endpoint type of Keystone API v3
self.identity_v3_client = IdentityV3Client(self.auth_provider,
- **params)
+ **params_v3)
self.endpoints_client = EndPointClient(self.auth_provider,
**params)
self.service_client = ServiceClient(self.auth_provider, **params)
diff --git a/tempest/common/glance_http.py b/tempest/common/glance_http.py
index 4be3da1..868a3e9 100644
--- a/tempest/common/glance_http.py
+++ b/tempest/common/glance_http.py
@@ -330,7 +330,7 @@
try:
self.context.load_verify_locations(self.ca_certs)
except Exception as e:
- msg = 'Unable to load CA from "%s"' % (self.ca_certs, e)
+ msg = 'Unable to load CA from "%s" %s' % (self.ca_certs, e)
raise exc.SSLConfigurationError(msg)
else:
self.context.set_default_verify_paths()
diff --git a/tempest/common/validation_resources.py b/tempest/common/validation_resources.py
index 402638d..14730cf 100644
--- a/tempest/common/validation_resources.py
+++ b/tempest/common/validation_resources.py
@@ -23,17 +23,17 @@
def create_ssh_security_group(os, add_rule=False):
- security_group_client = os.security_groups_client
+ security_groups_client = os.security_groups_client
+ security_group_rules_client = os.security_group_rules_client
sg_name = data_utils.rand_name('securitygroup-')
sg_description = data_utils.rand_name('description-')
- security_group = \
- security_group_client.create_security_group(name=sg_name,
- description=sg_description)
+ security_group = security_groups_client.create_security_group(
+ name=sg_name, description=sg_description)
if add_rule:
- security_group_client.create_security_group_rule(
+ security_group_rules_client.create_security_group_rule(
parent_group_id=security_group['id'], ip_protocol='tcp',
from_port=22, to_port=22)
- security_group_client.create_security_group_rule(
+ security_group_rules_client.create_security_group_rule(
parent_group_id=security_group['id'], ip_protocol='icmp',
from_port=-1, to_port=-1)
LOG.debug("SSH Validation resource security group with tcp and icmp "
diff --git a/tempest/config.py b/tempest/config.py
index 48417c3..0262d1b 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -112,11 +112,30 @@
"services' region name unless they are set explicitly. "
"If no such region is found in the service catalog, the "
"first found one is used."),
- cfg.StrOpt('endpoint_type',
+ cfg.StrOpt('v2_admin_endpoint_type',
+ default='adminURL',
+ choices=['public', 'admin', 'internal',
+ 'publicURL', 'adminURL', 'internalURL'],
+ help="The admin endpoint type to use for OpenStack Identity "
+ "(Keystone) API v2",
+ deprecated_opts=[cfg.DeprecatedOpt('endpoint_type',
+ group='identity')]),
+ cfg.StrOpt('v2_public_endpoint_type',
default='publicURL',
choices=['public', 'admin', 'internal',
'publicURL', 'adminURL', 'internalURL'],
- help="The endpoint type to use for the identity service."),
+ help="The public endpoint type to use for OpenStack Identity "
+ "(Keystone) API v2",
+ deprecated_opts=[cfg.DeprecatedOpt('endpoint_type',
+ group='identity')]),
+ cfg.StrOpt('v3_endpoint_type',
+ default='adminURL',
+ choices=['public', 'admin', 'internal',
+ 'publicURL', 'adminURL', 'internalURL'],
+ help="The endpoint type to use for OpenStack Identity "
+ "(Keystone) API v3",
+ deprecated_opts=[cfg.DeprecatedOpt('endpoint_type',
+ group='identity')]),
cfg.StrOpt('username',
help="Username to use for Nova API requests."),
cfg.StrOpt('tenant_name',
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 60bf7cb..da4ebbe 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -96,7 +96,7 @@
def addCleanup_with_wait(self, waiter_callable, thing_id, thing_id_param,
cleanup_callable, cleanup_args=None,
- cleanup_kwargs=None, ignore_error=True):
+ cleanup_kwargs=None):
"""Adds wait for async resource deletion at the end of cleanups
@param waiter_callable: callable to wait for the resource to delete
@@ -1080,11 +1080,6 @@
port = self._create_port(network_id=net_id,
client=net_client,
**create_port_body)
- # if port_vnic_type is set, ports in the passing
- # create_kwargs will be override, which cause the
- # inconsistence. Set the port_id according to network id
- if net_id == self.network['id']:
- self.port_id = port.id
ports.append({'port': port.id})
if ports:
create_kwargs['networks'] = ports
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index b31ba69..e676063 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -101,7 +101,6 @@
self.servers = []
def _setup_network_and_servers(self, **kwargs):
- vnic_type = CONF.network.port_vnic_type
boot_with_port = kwargs.pop('boot_with_port', False)
self.security_group = \
self._create_security_group(tenant_id=self.tenant_id)
@@ -109,9 +108,7 @@
self.check_networks()
self.port_id = None
- # when vnic_type is set, ports will be created in create_server.
- # So no need to create a port here in this case.
- if boot_with_port and not vnic_type:
+ if boot_with_port:
# create a port on the network and boot with that
self.port_id = self._create_port(self.network['id']).id
diff --git a/tempest/scenario/test_network_v6.py b/tempest/scenario/test_network_v6.py
index fba839a..9481e58 100644
--- a/tempest/scenario/test_network_v6.py
+++ b/tempest/scenario/test_network_v6.py
@@ -27,13 +27,17 @@
class TestGettingAddress(manager.NetworkScenarioTest):
- """Create network with subnets: one IPv4 and
- one or few IPv6 in a given address mode
- Boot 2 VMs on this network
- Allocate and assign 2 FIP4
- Check that vNICs of all VMs gets all addresses actually assigned
- Ping4 to one VM from another one
- If ping6 available in VM, do ping6 to all v6 addresses
+ """Test Summary:
+
+ 1. Create network with subnets:
+ 1.1. one IPv4 and
+ 1.2. one or more IPv6 in a given address mode
+ 2. Boot 2 VMs on this network
+ 3. Allocate and assign 2 FIP4
+ 4. Check that vNICs of all VMs gets all addresses actually assigned
+ 5. Each VM will ping the other's v4 private address
+ 6. If ping6 available in VM, each VM will ping all of the other's v6
+ addresses as well as the router's
"""
@classmethod
@@ -74,12 +78,13 @@
self.network = self._create_network(tenant_id=self.tenant_id)
sub4 = self._create_subnet(network=self.network,
namestart='sub4',
- ip_version=4,)
+ ip_version=4)
router = self._get_router(tenant_id=self.tenant_id)
sub4.add_to_router(router_id=router['id'])
self.addCleanup(sub4.delete)
+ self.subnets_v6 = []
for _ in range(n_subnets6):
sub6 = self._create_subnet(network=self.network,
namestart='sub6',
@@ -89,6 +94,7 @@
sub6.add_to_router(router_id=router['id'])
self.addCleanup(sub6.delete)
+ self.subnets_v6.append(sub6)
@staticmethod
def define_server_ips(srv):
@@ -145,23 +151,32 @@
self.assertTrue(test.call_until_true(srv2_v6_addr_assigned,
CONF.compute.ping_timeout, 1))
- result = sshv4_1.ping_host(ips_from_api_2['4'])
- self.assertIn('0% packet loss', result)
- result = sshv4_2.ping_host(ips_from_api_1['4'])
- self.assertIn('0% packet loss', result)
+ self._check_connectivity(sshv4_1, ips_from_api_2['4'])
+ self._check_connectivity(sshv4_2, ips_from_api_1['4'])
# Some VM (like cirros) may not have ping6 utility
result = sshv4_1.exec_command('whereis ping6')
is_ping6 = False if result == 'ping6:\n' else True
if is_ping6:
for i in range(n_subnets6):
- result = sshv4_1.ping_host(ips_from_api_2['6'][i])
- self.assertIn('0% packet loss', result)
- result = sshv4_2.ping_host(ips_from_api_1['6'][i])
- self.assertIn('0% packet loss', result)
+ self._check_connectivity(sshv4_1,
+ ips_from_api_2['6'][i])
+ self._check_connectivity(sshv4_1,
+ self.subnets_v6[i].gateway_ip)
+ self._check_connectivity(sshv4_2,
+ ips_from_api_1['6'][i])
+ self._check_connectivity(sshv4_2,
+ self.subnets_v6[i].gateway_ip)
else:
LOG.warning('Ping6 is not available, skipping')
+ def _check_connectivity(self, source, dest):
+ self.assertTrue(
+ self._check_remote_connectivity(source, dest),
+ "Timed out waiting for %s to become reachable from %s" %
+ (dest, source.ssh_client.host)
+ )
+
@test.idempotent_id('2c92df61-29f0-4eaa-bee3-7c65bef62a43')
@test.services('compute', 'network')
def test_slaac_from_os(self):
diff --git a/tempest/services/identity/v2/json/identity_client.py b/tempest/services/identity/v2/json/identity_client.py
index 1076fca..c9345e0 100644
--- a/tempest/services/identity/v2/json/identity_client.py
+++ b/tempest/services/identity/v2/json/identity_client.py
@@ -259,6 +259,33 @@
self.expected_success(204, resp.status)
return service_client.ResponseBody(resp, body)
+ def create_endpoint(self, service_id, region_id, **kwargs):
+ """Create an endpoint for service."""
+ post_body = {
+ 'service_id': service_id,
+ 'region': region_id,
+ 'publicurl': kwargs.get('publicurl'),
+ 'adminurl': kwargs.get('adminurl'),
+ 'internalurl': kwargs.get('internalurl')
+ }
+ post_body = json.dumps({'endpoint': post_body})
+ resp, body = self.post('/endpoints', post_body)
+ self.expected_success(200, resp.status)
+ return service_client.ResponseBody(resp, self._parse_resp(body))
+
+ def list_endpoints(self):
+ """List Endpoints - Returns Endpoints."""
+ resp, body = self.get('/endpoints')
+ self.expected_success(200, resp.status)
+ return service_client.ResponseBodyList(resp, self._parse_resp(body))
+
+ def delete_endpoint(self, endpoint_id):
+ """Delete an endpoint."""
+ url = '/endpoints/%s' % endpoint_id
+ resp, body = self.delete(url)
+ self.expected_success(204, resp.status)
+ return service_client.ResponseBody(resp, body)
+
def update_user_password(self, user_id, new_pass):
"""Update User Password."""
put_body = {
diff --git a/tempest/tests/services/compute/test_aggregates_client.py b/tempest/tests/services/compute/test_aggregates_client.py
index 9fe4544..eacc251 100644
--- a/tempest/tests/services/compute/test_aggregates_client.py
+++ b/tempest/tests/services/compute/test_aggregates_client.py
@@ -14,6 +14,7 @@
import httplib2
+from oslo_serialization import jsonutils as json
from oslotest import mockpatch
from tempest.services.compute.json import aggregates_client
@@ -45,3 +46,92 @@
def test_list_aggregates_with_bytes_body(self):
self._test_list_aggregates(bytes_body=True)
+
+ def _test_show_aggregate(self, bytes_body=False):
+ expected = {"name": "hoge",
+ "availability_zone": None,
+ "deleted": False,
+ "created_at":
+ "2015-07-16T03:07:32.000000",
+ "updated_at": None,
+ "hosts": [],
+ "deleted_at": None,
+ "id": 1,
+ "metadata": {}}
+ serialized_body = json.dumps({"aggregate": expected})
+ if bytes_body:
+ serialized_body = serialized_body.encode('utf-8')
+
+ mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
+ self.useFixture(mockpatch.Patch(
+ 'tempest.common.service_client.ServiceClient.get',
+ return_value=mocked_resp))
+ resp = self.client.show_aggregate(1)
+ self.assertEqual(expected, resp)
+
+ def test_show_aggregate_with_str_body(self):
+ self._test_show_aggregate()
+
+ def test_show_aggregate_with_bytes_body(self):
+ self._test_show_aggregate(bytes_body=True)
+
+ def _test_create_aggregate(self, bytes_body=False):
+ expected = {"name": u'\xf4',
+ "availability_zone": None,
+ "deleted": False,
+ "created_at": "2015-07-21T04:11:18.000000",
+ "updated_at": None,
+ "deleted_at": None,
+ "id": 1}
+ serialized_body = json.dumps({"aggregate": expected})
+ if bytes_body:
+ serialized_body = serialized_body.encode('utf-8')
+
+ mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
+ self.useFixture(mockpatch.Patch(
+ 'tempest.common.service_client.ServiceClient.post',
+ return_value=mocked_resp))
+ resp = self.client.create_aggregate(name='hoge')
+ self.assertEqual(expected, resp)
+
+ def test_create_aggregate_with_str_body(self):
+ self._test_create_aggregate()
+
+ def test_create_aggregate_with_bytes_body(self):
+ self._test_create_aggregate(bytes_body=True)
+
+ def test_delete_aggregate(self):
+ expected = {}
+ mocked_resp = (httplib2.Response({'status': 200}), None)
+ self.useFixture(mockpatch.Patch(
+ 'tempest.common.service_client.ServiceClient.delete',
+ return_value=mocked_resp))
+ resp = self.client.delete_aggregate("1")
+ self.assertEqual(expected, resp)
+
+ def _test_update_aggregate(self, bytes_body=False):
+ expected = {"name": u'\xe9',
+ "availability_zone": None,
+ "deleted": False,
+ "created_at": "2015-07-16T03:07:32.000000",
+ "updated_at": "2015-07-23T05:16:29.000000",
+ "hosts": [],
+ "deleted_at": None,
+ "id": 1,
+ "metadata": {}}
+ serialized_body = json.dumps({"aggregate": expected})
+ if bytes_body:
+ serialized_body = serialized_body.encode('utf-8')
+
+ mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
+ self.useFixture(mockpatch.Patch(
+ 'tempest.common.service_client.ServiceClient.put',
+ return_value=mocked_resp))
+ resp = self.client.update_aggregate(1)
+ self.assertEqual(expected, resp)
+
+ def test_update_aggregate_with_str_body(self):
+ self._test_update_aggregate()
+
+ def test_update_aggregate_with_bytes_body(self):
+ self._test_update_aggregate(bytes_body=True)
diff --git a/tempest/tests/services/compute/test_extensions_client.py b/tempest/tests/services/compute/test_extensions_client.py
new file mode 100644
index 0000000..aa46efa
--- /dev/null
+++ b/tempest/tests/services/compute/test_extensions_client.py
@@ -0,0 +1,75 @@
+# Copyright 2015 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 httplib2
+
+from oslo_serialization import jsonutils as json
+from oslotest import mockpatch
+
+from tempest.services.compute.json import extensions_client
+from tempest.tests import base
+from tempest.tests import fake_auth_provider
+
+
+class TestExtensionsClient(base.TestCase):
+
+ def setUp(self):
+ super(TestExtensionsClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.client = extensions_client.ExtensionsClient(
+ fake_auth, 'compute', 'regionOne')
+
+ def _test_list_extensions(self, bytes_body=False):
+ body = '{"extensions": []}'
+ if bytes_body:
+ body = body.encode('utf-8')
+ expected = []
+ response = (httplib2.Response({'status': 200}), body)
+ self.useFixture(mockpatch.Patch(
+ 'tempest.common.service_client.ServiceClient.get',
+ return_value=response))
+ self.assertEqual(expected, self.client.list_extensions())
+
+ def test_list_extensions_with_str_body(self):
+ self._test_list_extensions()
+
+ def test_list_extensions_with_bytes_body(self):
+ self._test_list_extensions(bytes_body=True)
+
+ def _test_show_extension(self, bytes_body=False):
+ expected = {
+ "updated": "2011-06-09T00:00:00Z",
+ "name": "Multinic",
+ "links": [],
+ "namespace":
+ "http://docs.openstack.org/compute/ext/multinic/api/v1.1",
+ "alias": "NMN",
+ "description": u'\u2740(*\xb4\u25e1`*)\u2740'
+ }
+ serialized_body = json.dumps({"extension": expected})
+ if bytes_body:
+ serialized_body = serialized_body.encode('utf-8')
+
+ mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
+ self.useFixture(mockpatch.Patch(
+ 'tempest.common.service_client.ServiceClient.get',
+ return_value=mocked_resp))
+ resp = self.client.show_extension("NMN")
+ self.assertEqual(expected, resp)
+
+ def test_show_extension_with_str_body(self):
+ self._test_show_extension()
+
+ def test_show_extension_with_bytes_body(self):
+ self._test_show_extension(bytes_body=True)
diff --git a/tempest/tests/services/compute/test_keypairs_client.py b/tempest/tests/services/compute/test_keypairs_client.py
index e79e411..a0022b4 100644
--- a/tempest/tests/services/compute/test_keypairs_client.py
+++ b/tempest/tests/services/compute/test_keypairs_client.py
@@ -12,8 +12,10 @@
# License for the specific language governing permissions and limitations
# under the License.
+import copy
import httplib2
+from oslo_serialization import jsonutils as json
from oslotest import mockpatch
from tempest.services.compute.json import keypairs_client
@@ -23,6 +25,13 @@
class TestKeyPairsClient(base.TestCase):
+ FAKE_KEYPAIR = {
+ "public_key": "ssh-rsa foo Generated-by-Nova",
+ "name": u'\u2740(*\xb4\u25e1`*)\u2740',
+ "user_id": "525d55f98980415ba98e634972fa4a10",
+ "fingerprint": "76:24:66:49:d7:ca:6e:5c:77:ea:8e:bb:9c:15:5f:98"
+ }
+
def setUp(self):
super(TestKeyPairsClient, self).setUp()
fake_auth = fake_auth_provider.FakeAuthProvider()
@@ -45,3 +54,58 @@
def test_list_keypairs_with_bytes_body(self):
self._test_list_keypairs(bytes_body=True)
+
+ def _test_show_keypair(self, bytes_body=False):
+ fake_keypair = copy.deepcopy(self.FAKE_KEYPAIR)
+ fake_keypair.update({
+ "deleted": False,
+ "created_at": "2015-07-22T04:53:52.000000",
+ "updated_at": None,
+ "deleted_at": None,
+ "id": 1
+ })
+ serialized_body = json.dumps({"keypair": fake_keypair})
+ if bytes_body:
+ serialized_body = serialized_body.encode('utf-8')
+
+ mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
+ self.useFixture(mockpatch.Patch(
+ 'tempest.common.service_client.ServiceClient.get',
+ return_value=mocked_resp))
+ resp = self.client.show_keypair("test")
+ self.assertEqual(fake_keypair, resp)
+
+ def test_show_keypair_with_str_body(self):
+ self._test_show_keypair()
+
+ def test_show_keypair_with_bytes_body(self):
+ self._test_show_keypair(bytes_body=True)
+
+ def _test_create_keypair(self, bytes_body=False):
+ fake_keypair = copy.deepcopy(self.FAKE_KEYPAIR)
+ fake_keypair.update({"private_key": "foo"})
+ serialized_body = json.dumps({"keypair": fake_keypair})
+ if bytes_body:
+ serialized_body = serialized_body.encode('utf-8')
+
+ mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
+ self.useFixture(mockpatch.Patch(
+ 'tempest.common.service_client.ServiceClient.post',
+ return_value=mocked_resp))
+ resp = self.client.create_keypair(name='test')
+ self.assertEqual(fake_keypair, resp)
+
+ def test_create_keypair_with_str_body(self):
+ self._test_create_keypair()
+
+ def test_create_keypair_with_bytes_body(self):
+ self._test_create_keypair(bytes_body=True)
+
+ def test_delete_keypair(self):
+ expected = {}
+ mocked_resp = (httplib2.Response({'status': 202}), None)
+ self.useFixture(mockpatch.Patch(
+ 'tempest.common.service_client.ServiceClient.delete',
+ return_value=mocked_resp))
+ resp = self.client.delete_keypair('test')
+ self.assertEqual(expected, resp)
diff --git a/tempest/tests/services/compute/test_limits_client.py b/tempest/tests/services/compute/test_limits_client.py
new file mode 100644
index 0000000..4086210
--- /dev/null
+++ b/tempest/tests/services/compute/test_limits_client.py
@@ -0,0 +1,69 @@
+# Copyright 2015 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 httplib2
+
+from oslo_serialization import jsonutils as json
+from oslotest import mockpatch
+
+from tempest.services.compute.json import limits_client
+from tempest.tests import base
+from tempest.tests import fake_auth_provider
+
+
+class TestLimitsClient(base.TestCase):
+
+ def setUp(self):
+ super(TestLimitsClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.client = limits_client.LimitsClient(
+ fake_auth, 'compute', 'regionOne')
+
+ def _test_show_limits(self, bytes_body=False):
+ expected = {"rate": [],
+ "absolute": {"maxServerMeta": 128,
+ "maxPersonality": 5,
+ "totalServerGroupsUsed": 0,
+ "maxImageMeta": 128,
+ "maxPersonalitySize": 10240,
+ "maxServerGroups": 10,
+ "maxSecurityGroupRules": 20,
+ "maxTotalKeypairs": 100,
+ "totalCoresUsed": 0,
+ "totalRAMUsed": 0,
+ "totalInstancesUsed": 0,
+ "maxSecurityGroups": 10,
+ "totalFloatingIpsUsed": 0,
+ "maxTotalCores": 20,
+ "totalSecurityGroupsUsed": 0,
+ "maxTotalFloatingIps": 10,
+ "maxTotalInstances": 10,
+ "maxTotalRAMSize": 51200,
+ "maxServerGroupMembers": 10}}
+ serialized_body = json.dumps({"limits": expected})
+ if bytes_body:
+ serialized_body = serialized_body.encode('utf-8')
+
+ mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
+ self.useFixture(mockpatch.Patch(
+ 'tempest.common.service_client.ServiceClient.get',
+ return_value=mocked_resp))
+ resp = self.client.show_limits()
+ self.assertEqual(expected, resp)
+
+ def test_show_limits_with_str_body(self):
+ self._test_show_limits()
+
+ def test_show_limits_with_bytes_body(self):
+ self._test_show_limits(bytes_body=True)
diff --git a/tempest/thirdparty/boto/test.py b/tempest/thirdparty/boto/test.py
index 1ff4dee..9f119b4 100644
--- a/tempest/thirdparty/boto/test.py
+++ b/tempest/thirdparty/boto/test.py
@@ -505,7 +505,7 @@
LOG.critical("%s Volume has %s snapshot(s)", volume.id,
map(snaps.id, snaps))
- # NOTE(afazekas): detaching/attching not valid EC2 status
+ # NOTE(afazekas): detaching/attaching not valid EC2 status
def _volume_state():
volume.update(validate=True)
try:
diff --git a/test-requirements.txt b/test-requirements.txt
index 2ea30ec..db2b2ce 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -9,4 +9,4 @@
mox>=0.5.3
mock>=1.2
coverage>=3.6
-oslotest>=1.9.0 # Apache-2.0
+oslotest>=1.10.0 # Apache-2.0
diff --git a/tox.ini b/tox.ini
index eae6fc7..15652e8 100644
--- a/tox.ini
+++ b/tox.ini
@@ -110,7 +110,6 @@
[testenv:docs]
# The sample config file we generate is included in the sphinxdoc, so build that first.
commands =
- oslo-config-generator --config-file tools/config/config-generator.tempest.conf --output-file doc/source/_static/tempest.conf
python setup.py build_sphinx {posargs}
[testenv:pep8]