Merge "Stop running CONF getattr during import"
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index b9e3393..ee2da40 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -359,6 +359,10 @@
# iSCSI volumes (boolean value)
#block_migrate_cinder_iscsi=false
+# Enable VNC console. This configuration value should be same
+# as [nova.vnc]->vnc_enabled in nova.conf (boolean value)
+#vnc_console=false
+
[dashboard]
diff --git a/requirements.txt b/requirements.txt
index a08a437..0bddca3 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,4 +1,4 @@
-pbr>=0.5.21,<1.0
+pbr>=0.6,<1.0
anyjson>=0.3.3
httplib2>=0.7.5
jsonschema>=2.0.0,<3.0.0
@@ -8,18 +8,18 @@
paramiko>=1.9.0
netaddr>=0.7.6
python-glanceclient>=0.9.0
-python-keystoneclient>=0.4.2
+python-keystoneclient>=0.6.0
python-novaclient>=2.15.0
-python-neutronclient>=2.3.3,<3
+python-neutronclient>=2.3.4,<3
python-cinderclient>=1.0.6
python-heatclient>=0.2.3
-python-savannaclient>=0.4.1
-python-swiftclient>=1.5
+python-savannaclient>=0.5.0
+python-swiftclient>=1.6
testresources>=0.2.4
keyring>=1.6.1,<2.0,>=2.1
-testrepository>=0.0.17
+testrepository>=0.0.18
oslo.config>=1.2.0
-six>=1.4.1
+six>=1.5.2
iso8601>=0.1.8
fixtures>=0.3.14
testscenarios>=0.4
diff --git a/tempest/api/compute/admin/test_servers.py b/tempest/api/compute/admin/test_servers.py
index 8a5f1a5..3b7f221 100644
--- a/tempest/api/compute/admin/test_servers.py
+++ b/tempest/api/compute/admin/test_servers.py
@@ -175,6 +175,16 @@
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):
+ # Reset Network of a Server
+ resp, server = self.create_test_server(wait_until='ACTIVE')
+ resp, server_body = self.client.reset_network(server['id'])
+ self.assertEqual(202, resp.status)
+ # Inject the Network Info into Server
+ resp, server_body = self.client.inject_network_info(server['id'])
+ self.assertEqual(202, resp.status)
+
class ServersAdminTestXML(ServersAdminTestJSON):
_host_key = (
diff --git a/tempest/api/compute/servers/test_attach_interfaces.py b/tempest/api/compute/servers/test_attach_interfaces.py
index 9cdac55..c8ab5ae 100644
--- a/tempest/api/compute/servers/test_attach_interfaces.py
+++ b/tempest/api/compute/servers/test_attach_interfaces.py
@@ -48,6 +48,7 @@
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']
@@ -55,6 +56,7 @@
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)
@@ -64,6 +66,7 @@
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)
@@ -73,12 +76,14 @@
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]
- self.client.delete_interface(server['id'], iface['port_id'])
+ 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())
@@ -123,6 +128,33 @@
_ifs = self._test_delete_interface(server, ifs)
self.assertEqual(len(ifs) - 1, len(_ifs))
+ @attr(type='gate')
+ 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.assertTrue(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)
+ # Remove the fixed IP from server.
+ server_resp, server_detail = self.os.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['OS-EXT-IPS:type'] == 'fixed':
+ fixed_ip = ip['addr']
+ break
+ if fixed_ip is not None:
+ break
+ resp, body = self.client.remove_fixed_ip(server['id'],
+ fixed_ip)
+ self.assertEqual(202, resp.status)
+
class AttachInterfacesTestXML(AttachInterfacesTestJSON):
_interface = 'xml'
diff --git a/tempest/api/compute/v3/servers/test_attach_interfaces.py b/tempest/api/compute/v3/servers/test_attach_interfaces.py
index a3046c7..e1c69d9 100644
--- a/tempest/api/compute/v3/servers/test_attach_interfaces.py
+++ b/tempest/api/compute/v3/servers/test_attach_interfaces.py
@@ -47,6 +47,7 @@
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']
@@ -54,6 +55,7 @@
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)
@@ -63,6 +65,7 @@
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)
@@ -72,12 +75,14 @@
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]
- self.client.delete_interface(server['id'], iface['port_id'])
+ 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())
@@ -121,3 +126,30 @@
_ifs = self._test_delete_interface(server, ifs)
self.assertEqual(len(ifs) - 1, len(_ifs))
+
+ @attr(type='gate')
+ 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_server_actions.py b/tempest/api/compute/v3/servers/test_server_actions.py
index e642715..406c45a 100644
--- a/tempest/api/compute/v3/servers/test_server_actions.py
+++ b/tempest/api/compute/v3/servers/test_server_actions.py
@@ -410,3 +410,16 @@
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')
+
+ @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)
+ self.assertEqual(console_type, body['type'])
+ self.assertNotEqual('', body['url'])
diff --git a/tempest/api/identity/admin/v3/test_endpoints.py b/tempest/api/identity/admin/v3/test_endpoints.py
index 78ecf93..05b704f 100644
--- a/tempest/api/identity/admin/v3/test_endpoints.py
+++ b/tempest/api/identity/admin/v3/test_endpoints.py
@@ -125,7 +125,7 @@
self.assertEqual(interface2, endpoint['interface'])
self.assertEqual(url2, endpoint['url'])
self.assertEqual(region2, endpoint['region'])
- self.assertEqual('False', str(endpoint['enabled']))
+ self.assertEqual('false', str(endpoint['enabled']).lower())
self.addCleanup(self.client.delete_endpoint, endpoint_for_update['id'])
diff --git a/tempest/api/image/v2/test_images.py b/tempest/api/image/v2/test_images.py
index 759c4a9..d448c01 100644
--- a/tempest/api/image/v2/test_images.py
+++ b/tempest/api/image/v2/test_images.py
@@ -249,3 +249,19 @@
self.assertEqual(len(images_list), params['limit'],
"Failed to get images by limit")
+
+ @attr(type='gate')
+ def test_get_image_schema(self):
+ # Test to get image schema
+ schema = "image"
+ resp, body = self.client.get_schema(schema)
+ self.assertEqual(200, resp.status)
+ self.assertEqual("image", body['name'])
+
+ @attr(type='gate')
+ def test_get_images_schema(self):
+ # Test to get images schema
+ schema = "images"
+ resp, body = self.client.get_schema(schema)
+ self.assertEqual(200, resp.status)
+ self.assertEqual("images", body['name'])
diff --git a/tempest/config.py b/tempest/config.py
index 7706eaf..887bac3 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -263,7 +263,11 @@
cfg.BoolOpt('block_migrate_cinder_iscsi',
default=False,
help="Does the test environment block migration support "
- "cinder iSCSI volumes")
+ "cinder iSCSI volumes"),
+ cfg.BoolOpt('vnc_console',
+ default=False,
+ help='Enable VNC console. This configuration value should '
+ 'be same as [nova.vnc]->vnc_enabled in nova.conf')
]
diff --git a/tempest/services/compute/json/interfaces_client.py b/tempest/services/compute/json/interfaces_client.py
index f4c4c64..de3aa19 100644
--- a/tempest/services/compute/json/interfaces_client.py
+++ b/tempest/services/compute/json/interfaces_client.py
@@ -80,3 +80,25 @@
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({
+ 'addFixedIp': {
+ 'networkId': network_id
+ }
+ })
+ resp, body = self.post('servers/%s/action' % str(server_id),
+ post_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({
+ 'removeFixedIp': {
+ 'address': ip_address
+ }
+ })
+ resp, body = self.post('servers/%s/action' % str(server_id),
+ post_body)
+ return resp, body
diff --git a/tempest/services/compute/json/servers_client.py b/tempest/services/compute/json/servers_client.py
index 025c4e5..deb78ee 100644
--- a/tempest/services/compute/json/servers_client.py
+++ b/tempest/services/compute/json/servers_client.py
@@ -428,3 +428,11 @@
def restore_soft_deleted_server(self, server_id, **kwargs):
"""Restore a soft-deleted server."""
return self.action(server_id, 'restore', None, **kwargs)
+
+ def reset_network(self, server_id, **kwargs):
+ """Resets the Network of a server"""
+ return self.action(server_id, 'resetNetwork', None, **kwargs)
+
+ def inject_network_info(self, server_id, **kwargs):
+ """Inject the Network Info into server"""
+ return self.action(server_id, 'injectNetworkInfo', None, **kwargs)
diff --git a/tempest/services/compute/v3/json/interfaces_client.py b/tempest/services/compute/v3/json/interfaces_client.py
index c167520..f8b9d09 100644
--- a/tempest/services/compute/v3/json/interfaces_client.py
+++ b/tempest/services/compute/v3/json/interfaces_client.py
@@ -81,3 +81,25 @@
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)
+ 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)
+ return resp, body
diff --git a/tempest/services/compute/v3/json/servers_client.py b/tempest/services/compute/v3/json/servers_client.py
index 840e914..819e366 100644
--- a/tempest/services/compute/v3/json/servers_client.py
+++ b/tempest/services/compute/v3/json/servers_client.py
@@ -423,3 +423,15 @@
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)
+ return resp, body['console']
diff --git a/tempest/services/compute/xml/interfaces_client.py b/tempest/services/compute/xml/interfaces_client.py
index 5df6187..8d4bfcc 100644
--- a/tempest/services/compute/xml/interfaces_client.py
+++ b/tempest/services/compute/xml/interfaces_client.py
@@ -24,6 +24,7 @@
from tempest.services.compute.xml.common import Element
from tempest.services.compute.xml.common import Text
from tempest.services.compute.xml.common import xml_to_json
+from tempest.services.compute.xml.common import XMLNS_11
CONF = config.CONF
@@ -104,3 +105,21 @@
(port_id, 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 = Element("addFixedIp",
+ xmlns=XMLNS_11,
+ networkId=network_id)
+ resp, body = self.post('servers/%s/action' % str(server_id),
+ str(Document(post_body)))
+ return resp, body
+
+ def remove_fixed_ip(self, server_id, ip_address):
+ """Remove input fixed IP from input server instance."""
+ post_body = Element("removeFixedIp",
+ xmlns=XMLNS_11,
+ address=ip_address)
+ resp, body = self.post('servers/%s/action' % str(server_id),
+ str(Document(post_body)))
+ return resp, body
diff --git a/tempest/services/compute/xml/servers_client.py b/tempest/services/compute/xml/servers_client.py
index da01b83..cd2cb06 100644
--- a/tempest/services/compute/xml/servers_client.py
+++ b/tempest/services/compute/xml/servers_client.py
@@ -633,3 +633,11 @@
def restore_soft_deleted_server(self, server_id, **kwargs):
"""Restore a soft-deleted server."""
return self.action(server_id, 'restore', None, **kwargs)
+
+ def reset_network(self, server_id, **kwargs):
+ """Resets the Network of a server"""
+ return self.action(server_id, 'resetNetwork', None, **kwargs)
+
+ def inject_network_info(self, server_id, **kwargs):
+ """Inject the Network Info into server"""
+ return self.action(server_id, 'injectNetworkInfo', None, **kwargs)
diff --git a/tempest/services/identity/v3/xml/endpoints_client.py b/tempest/services/identity/v3/xml/endpoints_client.py
index a32eede..d79ea92 100644
--- a/tempest/services/identity/v3/xml/endpoints_client.py
+++ b/tempest/services/identity/v3/xml/endpoints_client.py
@@ -67,6 +67,8 @@
"""Create endpoint."""
region = kwargs.get('region', None)
enabled = kwargs.get('enabled', None)
+ if enabled is not None:
+ enabled = str(enabled).lower()
create_endpoint = Element("endpoint",
xmlns=XMLNS,
service_id=service_id,
@@ -93,7 +95,7 @@
if region:
endpoint.add_attr("region", region)
if enabled is not None:
- endpoint.add_attr("enabled", enabled)
+ endpoint.add_attr("enabled", str(enabled).lower())
resp, body = self.patch('endpoints/%s' % str(endpoint_id), str(doc))
body = self._parse_body(etree.fromstring(body))
return resp, body
diff --git a/tempest/services/image/v2/json/image_client.py b/tempest/services/image/v2/json/image_client.py
index 30c6ffc..b3014fc 100644
--- a/tempest/services/image/v2/json/image_client.py
+++ b/tempest/services/image/v2/json/image_client.py
@@ -39,23 +39,9 @@
filters=self.filters,
insecure=dscv)
- def get_images_schema(self):
- url = 'v2/schemas/images'
- resp, body = self.get(url)
- body = json.loads(body)
- return resp, body
-
- def get_image_schema(self):
- url = 'v2/schemas/image'
- resp, body = self.get(url)
- body = json.loads(body)
- return resp, body
-
def _validate_schema(self, body, type='image'):
- if type == 'image':
- resp, schema = self.get_image_schema()
- elif type == 'images':
- resp, schema = self.get_images_schema()
+ if type in ['image', 'images']:
+ resp, schema = self.get_schema(type)
else:
raise ValueError("%s is not a valid schema type" % type)
@@ -184,3 +170,9 @@
resp, _ = self.delete(url)
self.expected_success(204, resp)
return resp
+
+ def get_schema(self, schema):
+ url = 'v2/schemas/%s' % schema
+ resp, body = self.get(url)
+ body = json.loads(body)
+ return resp, body
diff --git a/tools/check_logs.py b/tools/check_logs.py
index 15988a6..98e079a 100755
--- a/tools/check_logs.py
+++ b/tools/check_logs.py
@@ -32,7 +32,7 @@
def process_files(file_specs, url_specs, whitelists):
- regexp = re.compile(r"^.* (ERROR|CRITICAL) .*\[.*\-.*\]")
+ regexp = re.compile(r"^.* (ERROR|CRITICAL|TRACE) .*\[.*\-.*\]")
had_errors = False
for (name, filename) in file_specs:
whitelist = whitelists.get(name, [])