Merge "Simplify xml-json inheritance in compute"
diff --git a/cli/simple_read_only/test_compute.py b/cli/simple_read_only/test_compute.py
index 742b5a4..073fde1 100644
--- a/cli/simple_read_only/test_compute.py
+++ b/cli/simple_read_only/test_compute.py
@@ -55,6 +55,7 @@
cls.identity = config.TempestConfig().identity
super(SimpleReadOnlyNovaCLientTest, cls).setUpClass()
+ #NOTE(jogo): This should eventually be moved into a base class
def nova(self, action, flags='', params='', admin=True, fail_ok=False):
"""Executes nova command for the given action."""
#TODO(jogo) make admin=False work
@@ -66,39 +67,144 @@
cmd = ' '.join([CONF.cli.cli_dir + 'nova', flags, action, params])
LOG.info("running: '%s'" % cmd)
cmd = shlex.split(cmd)
- result = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
+ try:
+ result = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
+ except subprocess.CalledProcessError, e:
+ LOG.error("command output:\n%s" % e.output)
+ raise
return result
- def test_admin_version(self):
- self.nova('', flags='--version')
-
- def test_admin_timing(self):
- self.nova('list', flags='--timing')
-
- def test_admin_timeout(self):
- self.nova('list', flags='--timeout 2')
-
- def test_admin_debug_list(self):
- self.nova('list', flags='--debug')
-
def test_admin_fake_action(self):
self.assertRaises(subprocess.CalledProcessError,
self.nova,
'this-does-nova-exist')
+ #NOTE(jogo): Commands in order listed in 'nova help'
+
+ # Positional arguments:
+
+ def test_admin_absolute_limites(self):
+ self.nova('absolute-limits')
+
def test_admin_aggregate_list(self):
self.nova('aggregate-list')
+ def test_admin_availability_zone_list(self):
+ self.nova('availability-zone-list')
+
def test_admin_cloudpipe_list(self):
self.nova('cloudpipe-list')
- def test_admin_image_list(self):
- self.nova('image-list')
+ def test_admin_credentials(self):
+ self.nova('credentials')
def test_admin_dns_domains(self):
self.nova('dns-domains')
+ @testtools.skip("needs parameters")
+ def test_admin_dns_list(self):
+ self.nova('dns-list')
+
+ def test_admin_endpoints(self):
+ self.nova('endpoints')
+
+ def test_admin_flavor_acces_list(self):
+ self.assertRaises(subprocess.CalledProcessError,
+ self.nova,
+ 'flavor-access-list')
+ # Failed to get access list for public flavor type
+ self.assertRaises(subprocess.CalledProcessError,
+ self.nova,
+ 'flavor-access-list',
+ params='--flavor m1.tiny')
+
def test_admin_flavor_list(self):
self.nova('flavor-list')
- #TODO(jogo) add more tests
+ def test_admin_floating_ip_bulk_list(self):
+ self.nova('floating-ip-bulk-list')
+
+ def test_admin_floating_ip_list(self):
+ self.nova('floating-ip-list')
+
+ def test_admin_floating_ip_pool_list(self):
+ self.nova('floating-ip-pool-list')
+
+ def test_admin_host_list(self):
+ self.nova('host-list')
+
+ def test_admin_hypervisor_list(self):
+ self.nova('hypervisor-list')
+
+ def test_admin_image_list(self):
+ self.nova('image-list')
+
+ @testtools.skip("needs parameters")
+ def test_admin_interface_list(self):
+ self.nova('interface-list')
+
+ def test_admin_keypair_list(self):
+ self.nova('keypair-list')
+
+ def test_admin_list(self):
+ self.nova('list')
+ self.nova('list', params='--all-tenants 1')
+ self.nova('list', params='--all-tenants 0')
+ self.assertRaises(subprocess.CalledProcessError,
+ self.nova,
+ 'list',
+ params='--all-tenants bad')
+
+ def test_admin_network_list(self):
+ self.nova('network-list')
+
+ def test_admin_rate_limits(self):
+ self.nova('rate-limits')
+
+ def test_admin_secgroup_list(self):
+ self.nova('secgroup-list')
+
+ @testtools.skip("needs parameters")
+ def test_admin_secgroup_list_rules(self):
+ self.nova('secgroup-list-rules')
+
+ def test_admin_servce_list(self):
+ self.nova('service-list')
+
+ def test_admin_usage(self):
+ self.nova('usage')
+
+ def test_admin_usage_list(self):
+ self.nova('usage-list')
+
+ def test_admin_volume_list(self):
+ self.nova('volume-list')
+
+ def test_admin_volume_snapshot_list(self):
+ self.nova('volume-snapshot-list')
+
+ def test_admin_volume_type_list(self):
+ self.nova('volume-type-list')
+
+ def test_admin_help(self):
+ self.nova('help')
+
+ def test_admin_list_extensions(self):
+ self.nova('list-extensions')
+
+ def test_admin_net_list(self):
+ self.nova('net-list')
+
+ # Optional arguments:
+
+ def test_admin_version(self):
+ self.nova('', flags='--version')
+
+ def test_admin_debug_list(self):
+ self.nova('list', flags='--debug')
+
+ def test_admin_timeout(self):
+ self.nova('list', flags='--timeout 2')
+
+ def test_admin_timing(self):
+ self.nova('list', flags='--timing')
diff --git a/tempest/common/glance_http.py b/tempest/common/glance_http.py
index 45737be..36a9abd 100644
--- a/tempest/common/glance_http.py
+++ b/tempest/common/glance_http.py
@@ -16,9 +16,11 @@
# Originally copied from python-glanceclient
import copy
+import hashlib
import httplib
import logging
import posixpath
+import re
import socket
import StringIO
import struct
@@ -42,6 +44,7 @@
LOG = logging.getLogger(__name__)
USER_AGENT = 'tempest'
CHUNKSIZE = 1024 * 64 # 64kB
+TOKEN_CHARS_RE = re.compile('^[-A-Za-z0-9+/=]*$')
class HTTPClient(object):
@@ -92,42 +95,6 @@
except httplib.InvalidURL:
raise exc.EndpointNotFound
- def log_curl_request(self, method, url, kwargs):
- curl = ['curl -i -X %s' % method]
-
- for (key, value) in kwargs['headers'].items():
- header = '-H \'%s: %s\'' % (key, value)
- curl.append(header)
-
- conn_params_fmt = [
- ('key_file', '--key %s'),
- ('cert_file', '--cert %s'),
- ('cacert', '--cacert %s'),
- ]
- for (key, fmt) in conn_params_fmt:
- value = self.connection_kwargs.get(key)
- if value:
- curl.append(fmt % value)
-
- if self.connection_kwargs.get('insecure'):
- curl.append('-k')
-
- if 'body' in kwargs:
- curl.append('-d \'%s\'' % kwargs['body'])
-
- curl.append('%s%s' % (self.endpoint, url))
- LOG.debug(' '.join(curl))
-
- @staticmethod
- def log_http_response(resp, body=None):
- status = (resp.version / 10.0, resp.status, resp.reason)
- dump = ['\nHTTP/%.1f %s %s' % status]
- dump.extend(['%s: %s' % (k, v) for k, v in resp.getheaders()])
- dump.append('')
- if body:
- dump.extend([body, ''])
- LOG.debug('\n'.join(dump))
-
def _http_request(self, url, method, **kwargs):
"""Send an http request with the specified characteristics.
@@ -140,7 +107,8 @@
if self.auth_token:
kwargs['headers'].setdefault('X-Auth-Token', self.auth_token)
- self.log_curl_request(method, url, kwargs)
+ self._log_request(method, url, kwargs['headers'])
+
conn = self.get_connection()
try:
@@ -172,13 +140,37 @@
# Read body into string if it isn't obviously image data
if resp.getheader('content-type', None) != 'application/octet-stream':
body_str = ''.join([chunk for chunk in body_iter])
- self.log_http_response(resp, body_str)
body_iter = StringIO.StringIO(body_str)
+ self._log_response(resp, None)
else:
- self.log_http_response(resp)
+ self._log_response(resp, body_iter)
return resp, body_iter
+ def _log_request(self, method, url, headers):
+ LOG.info('Request: ' + method + ' ' + url)
+ if headers:
+ headers_out = headers
+ if 'X-Auth-Token' in headers and headers['X-Auth-Token']:
+ token = headers['X-Auth-Token']
+ if len(token) > 64 and TOKEN_CHARS_RE.match(token):
+ headers_out = headers.copy()
+ headers_out['X-Auth-Token'] = "<Token omitted>"
+ LOG.info('Request Headers: ' + str(headers_out))
+
+ def _log_response(self, resp, body):
+ status = str(resp.status)
+ LOG.info("Response Status: " + status)
+ if resp.getheaders():
+ LOG.info('Response Headers: ' + str(resp.getheaders()))
+ if body:
+ str_body = str(body)
+ length = len(body)
+ LOG.info('Response Body: ' + str_body[:2048])
+ if length >= 2048:
+ self.LOG.debug("Large body (%d) md5 summary: %s", length,
+ hashlib.md5(str_body).hexdigest())
+
def json_request(self, method, url, **kwargs):
kwargs.setdefault('headers', {})
kwargs['headers'].setdefault('Content-Type', 'application/json')
diff --git a/tempest/tests/compute/servers/test_server_metadata.py b/tempest/tests/compute/servers/test_server_metadata.py
index 2905a6b..6958a7d 100644
--- a/tempest/tests/compute/servers/test_server_metadata.py
+++ b/tempest/tests/compute/servers/test_server_metadata.py
@@ -163,6 +163,21 @@
'not succeed')
@attr(type='negative')
+ def test_set_server_metadata_item_incorrect_uri_key(self):
+ #Raise BadRequest if key in uri does not match
+ #the key passed in body.
+
+ meta = {'testkey': 'testvalue'}
+ try:
+ resp, metadata = self.client.set_server_metadata_item(
+ self.server_id, 'key', meta)
+ except exceptions.BadRequest:
+ pass
+ else:
+ self.fail('Should raise BadRequest if URI key does not match key'
+ 'passed in the body')
+
+ @attr(type='negative')
def test_set_nonexistant_server_metadata(self):
# Negative test: Set metadata on a non existant server should not
# succeed
diff --git a/tempest/tests/compute/servers/test_servers_negative.py b/tempest/tests/compute/servers/test_servers_negative.py
index 9b528f6..553af78 100644
--- a/tempest/tests/compute/servers/test_servers_negative.py
+++ b/tempest/tests/compute/servers/test_servers_negative.py
@@ -287,3 +287,9 @@
pass
else:
self.fail('Server was created with nonexistent security group')
+
+ @attr(type='negative')
+ def test_get_non_existent_server(self):
+ # Get a non existent server details
+ self.assertRaises(exceptions.NotFound, self.client.get_server,
+ '999erra43')
diff --git a/tempest/tests/identity/admin/test_services.py b/tempest/tests/identity/admin/test_services.py
index 9ac102a..77c8e83 100644
--- a/tempest/tests/identity/admin/test_services.py
+++ b/tempest/tests/identity/admin/test_services.py
@@ -56,12 +56,13 @@
self.assertEqual(fetched_service['description'],
service_data['description'])
finally:
- #Deleting the service created in this method
- resp, _ = self.client.delete_service(service_data['id'])
- self.assertTrue(resp['status'].startswith('2'))
- #Checking whether service is deleted successfully
- self.assertRaises(exceptions.NotFound, self.client.get_service,
- service_data['id'])
+ if 'service_data' in locals():
+ # Deleting the service created in this method
+ resp, _ = self.client.delete_service(service_data['id'])
+ self.assertEqual(resp['status'], '204')
+ # Checking whether service is deleted successfully
+ self.assertRaises(exceptions.NotFound, self.client.get_service,
+ service_data['id'])
def test_list_services(self):
# Create, List, Verify and Delete Services