Merge "increase failure information for ip_regex test"
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 e32d401..b3fb8a8 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/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/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)