Merge "Remove skipping test_list_servers_by_admin_with_all_tenants test"
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index 08f3fd4..96ef11a 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -452,6 +452,10 @@
# value)
#enable_instance_password=true
+# Does the test environment support dynamic network interface
+# attachment? (boolean value)
+#interface_attach=true
+
[dashboard]
diff --git a/tempest/api/baremetal/README.rst b/tempest/api/baremetal/README.rst
new file mode 100644
index 0000000..759c937
--- /dev/null
+++ b/tempest/api/baremetal/README.rst
@@ -0,0 +1,25 @@
+Tempest Field Guide to Baremetal API tests
+==========================================
+
+
+What are these tests?
+---------------------
+
+These tests stress the OpenStack baremetal provisioning API provided by
+Ironic.
+
+
+Why are these tests in tempest?
+------------------------------
+
+The purpose of these tests is to exercise the various APIs provided by Ironic
+for managing baremetal nodes.
+
+
+Scope of these tests
+--------------------
+
+The baremetal API test perform basic CRUD operations on the Ironic node
+inventory. They do not actually perform hardware provisioning. It is important
+to note that all Ironic API actions are admin operations meant to be used
+either by cloud operators or other OpenStack services (i.e., Nova).
diff --git a/tempest/api/baremetal/admin/__init__.py b/tempest/api/baremetal/admin/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/api/baremetal/admin/__init__.py
diff --git a/tempest/api/baremetal/base.py b/tempest/api/baremetal/admin/base.py
similarity index 100%
rename from tempest/api/baremetal/base.py
rename to tempest/api/baremetal/admin/base.py
diff --git a/tempest/api/baremetal/test_api_discovery.py b/tempest/api/baremetal/admin/test_api_discovery.py
similarity index 97%
rename from tempest/api/baremetal/test_api_discovery.py
rename to tempest/api/baremetal/admin/test_api_discovery.py
index bee10b9..7368b3e 100644
--- a/tempest/api/baremetal/test_api_discovery.py
+++ b/tempest/api/baremetal/admin/test_api_discovery.py
@@ -10,7 +10,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-from tempest.api.baremetal import base
+from tempest.api.baremetal.admin import base
from tempest import test
diff --git a/tempest/api/baremetal/test_chassis.py b/tempest/api/baremetal/admin/test_chassis.py
similarity index 98%
rename from tempest/api/baremetal/test_chassis.py
rename to tempest/api/baremetal/admin/test_chassis.py
index 4ab86c2..c306c34 100644
--- a/tempest/api/baremetal/test_chassis.py
+++ b/tempest/api/baremetal/admin/test_chassis.py
@@ -11,7 +11,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-from tempest.api.baremetal import base
+from tempest.api.baremetal.admin import base
from tempest.common.utils import data_utils
from tempest import exceptions as exc
from tempest import test
diff --git a/tempest/api/baremetal/test_drivers.py b/tempest/api/baremetal/admin/test_drivers.py
similarity index 96%
rename from tempest/api/baremetal/test_drivers.py
rename to tempest/api/baremetal/admin/test_drivers.py
index 852b6ab..649886b 100644
--- a/tempest/api/baremetal/test_drivers.py
+++ b/tempest/api/baremetal/admin/test_drivers.py
@@ -12,7 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-from tempest.api.baremetal import base
+from tempest.api.baremetal.admin import base
from tempest import config
from tempest import test
diff --git a/tempest/api/baremetal/test_nodes.py b/tempest/api/baremetal/admin/test_nodes.py
similarity index 98%
rename from tempest/api/baremetal/test_nodes.py
rename to tempest/api/baremetal/admin/test_nodes.py
index 1572840..fc67854 100644
--- a/tempest/api/baremetal/test_nodes.py
+++ b/tempest/api/baremetal/admin/test_nodes.py
@@ -12,7 +12,7 @@
import six
-from tempest.api.baremetal import base
+from tempest.api.baremetal.admin import base
from tempest import exceptions as exc
from tempest import test
diff --git a/tempest/api/baremetal/test_nodestates.py b/tempest/api/baremetal/admin/test_nodestates.py
similarity index 97%
rename from tempest/api/baremetal/test_nodestates.py
rename to tempest/api/baremetal/admin/test_nodestates.py
index 3044bc6..f24f490 100644
--- a/tempest/api/baremetal/test_nodestates.py
+++ b/tempest/api/baremetal/admin/test_nodestates.py
@@ -12,7 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-from tempest.api.baremetal import base
+from tempest.api.baremetal.admin import base
from tempest import exceptions
from tempest.openstack.common import timeutils
from tempest import test
diff --git a/tempest/api/baremetal/test_ports.py b/tempest/api/baremetal/admin/test_ports.py
similarity index 99%
rename from tempest/api/baremetal/test_ports.py
rename to tempest/api/baremetal/admin/test_ports.py
index 4ac7e29..d4adba9 100644
--- a/tempest/api/baremetal/test_ports.py
+++ b/tempest/api/baremetal/admin/test_ports.py
@@ -10,7 +10,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-from tempest.api.baremetal import base
+from tempest.api.baremetal.admin import base
from tempest.common.utils import data_utils
from tempest import exceptions as exc
from tempest import test
diff --git a/tempest/api/baremetal/test_ports_negative.py b/tempest/api/baremetal/admin/test_ports_negative.py
similarity index 99%
rename from tempest/api/baremetal/test_ports_negative.py
rename to tempest/api/baremetal/admin/test_ports_negative.py
index 3e77a5f..7646677 100644
--- a/tempest/api/baremetal/test_ports_negative.py
+++ b/tempest/api/baremetal/admin/test_ports_negative.py
@@ -10,7 +10,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-from tempest.api.baremetal import base
+from tempest.api.baremetal.admin import base
from tempest.common.utils import data_utils
from tempest import exceptions as exc
from tempest import test
diff --git a/tempest/api/compute/servers/test_attach_interfaces.py b/tempest/api/compute/servers/test_attach_interfaces.py
index 067d721..d1192c0 100644
--- a/tempest/api/compute/servers/test_attach_interfaces.py
+++ b/tempest/api/compute/servers/test_attach_interfaces.py
@@ -29,6 +29,8 @@
def setUpClass(cls):
if not CONF.service_available.neutron:
raise cls.skipException("Neutron is required")
+ if not CONF.compute_feature_enabled.interface_attach:
+ raise cls.skipException("Interface attachment is not available.")
# This test class requires network and subnet
cls.set_network_resources(network=True, subnet=True)
super(AttachInterfacesTestJSON, cls).setUpClass()
diff --git a/tempest/api/compute/servers/test_server_rescue_negative.py b/tempest/api/compute/servers/test_server_rescue_negative.py
index b35e55c..4582a46 100644
--- a/tempest/api/compute/servers/test_server_rescue_negative.py
+++ b/tempest/api/compute/servers/test_server_rescue_negative.py
@@ -34,7 +34,7 @@
cls.set_network_resources(network=True, subnet=True, router=True)
super(ServerRescueNegativeTestJSON, cls).setUpClass()
- cls.device = 'vdf'
+ cls.device = CONF.compute.volume_device_name
# Create a volume and wait for it to become ready for attach
resp, cls.volume = cls.volumes_extensions_client.create_volume(
diff --git a/tempest/api/compute/v3/servers/test_attach_interfaces.py b/tempest/api/compute/v3/servers/test_attach_interfaces.py
index 43440c1..c2cf7e0 100644
--- a/tempest/api/compute/v3/servers/test_attach_interfaces.py
+++ b/tempest/api/compute/v3/servers/test_attach_interfaces.py
@@ -29,6 +29,8 @@
def setUpClass(cls):
if not CONF.service_available.neutron:
raise cls.skipException("Neutron is required")
+ if not CONF.compute_feature_enabled.interface_attach:
+ raise cls.skipException("Interface attachment is not available.")
# This test class requires network and subnet
cls.set_network_resources(network=True, subnet=True)
super(AttachInterfacesV3Test, cls).setUpClass()
diff --git a/tempest/api/compute/v3/servers/test_server_rescue_negative.py b/tempest/api/compute/v3/servers/test_server_rescue_negative.py
index 5eb6c9a..83fe128 100644
--- a/tempest/api/compute/v3/servers/test_server_rescue_negative.py
+++ b/tempest/api/compute/v3/servers/test_server_rescue_negative.py
@@ -33,7 +33,7 @@
raise cls.skipException(msg)
super(ServerRescueNegativeV3Test, cls).setUpClass()
- cls.device = 'vdf'
+ cls.device = CONF.compute.volume_device_name
# Create a volume and wait for it to become ready for attach
resp, cls.volume = cls.volumes_client.create_volume(
diff --git a/tempest/api/network/test_routers.py b/tempest/api/network/test_routers.py
index d38633f..dca4c17 100644
--- a/tempest/api/network/test_routers.py
+++ b/tempest/api/network/test_routers.py
@@ -110,6 +110,36 @@
create_body['router']['id'])
self.assertEqual(tenant_id, create_body['router']['tenant_id'])
+ @test.requires_ext(extension='ext-gw-mode', service='network')
+ @test.attr(type='smoke')
+ def test_create_router_with_default_snat_value(self):
+ # Create a router with default snat rule
+ name = data_utils.rand_name('router')
+ router = self._create_router(name,
+ external_network_id=CONF.network.public_network_id)
+ self._verify_router_gateway(router['id'],
+ {'network_id': CONF.network.public_network_id,
+ 'enable_snat': True})
+
+ @test.requires_ext(extension='ext-gw-mode', service='network')
+ @test.attr(type='smoke')
+ def test_create_router_with_snat_explicit(self):
+ name = data_utils.rand_name('snat-router')
+ # Create a router enabling snat attributes
+ enable_snat_states = [False, True]
+ for enable_snat in enable_snat_states:
+ external_gateway_info = {
+ 'network_id': CONF.network.public_network_id,
+ 'enable_snat': enable_snat}
+ resp, create_body = self.admin_client.create_router(
+ name, external_gateway_info=external_gateway_info)
+ self.assertEqual('201', resp['status'])
+ self.addCleanup(self.admin_client.delete_router,
+ create_body['router']['id'])
+ # Verify snat attributes after router creation
+ self._verify_router_gateway(create_body['router']['id'],
+ exp_ext_gw_info=external_gateway_info)
+
@test.attr(type='smoke')
def test_add_remove_router_interface_with_subnet_id(self):
network = self.create_network()
@@ -151,7 +181,7 @@
router['id'])
def _verify_router_gateway(self, router_id, exp_ext_gw_info=None):
- resp, show_body = self.client.show_router(router_id)
+ resp, show_body = self.admin_client.show_router(router_id)
self.assertEqual('200', resp['status'])
actual_ext_gw_info = show_body['router']['external_gateway_info']
if exp_ext_gw_info is None:
diff --git a/tempest/api_schema/response/compute/v2/flavors.py b/tempest/api_schema/response/compute/v2/flavors.py
index 66710b2..811ea84 100644
--- a/tempest/api_schema/response/compute/v2/flavors.py
+++ b/tempest/api_schema/response/compute/v2/flavors.py
@@ -18,7 +18,7 @@
list_flavors_details = copy.deepcopy(flavors.common_flavor_list_details)
-# 'swap' attributes comes as integre value but if it is empty it comes as "".
+# 'swap' attributes comes as integer value but if it is empty it comes as "".
# So defining type of as string and integer.
list_flavors_details['response_body']['properties']['flavors']['items'][
'properties']['swap'] = {'type': ['string', 'integer']}
@@ -38,7 +38,7 @@
create_get_flavor_details = copy.deepcopy(flavors.common_flavor_details)
-# 'swap' attributes comes as integre value but if it is empty it comes as "".
+# 'swap' attributes comes as integer value but if it is empty it comes as "".
# So defining type of as string and integer.
create_get_flavor_details['response_body']['properties']['flavor'][
'properties']['swap'] = {'type': ['string', 'integer']}
diff --git a/tempest/config.py b/tempest/config.py
index db54269..7d195bf 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -324,7 +324,11 @@
default=True,
help='Enables returning of the instance password by the '
'relevant server API calls such as create, rebuild '
- 'or rescue.')
+ 'or rescue.'),
+ cfg.BoolOpt('interface_attach',
+ default=True,
+ help='Does the test environment support dynamic network '
+ 'interface attachment?')
]
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 3cfc698..606208e 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -1085,7 +1085,8 @@
try:
source.ping_host(dest)
except exceptions.SSHExecCommandFailed:
- LOG.exception('Failed to ping host via ssh connection')
+ LOG.warn('Failed to ping IP: %s via a ssh connection from: %s.'
+ % (dest, source.ssh_client.host))
return not should_succeed
return should_succeed
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index 7dc817d..8c7af3d 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -14,8 +14,8 @@
# License for the specific language governing permissions and limitations
# under the License.
import collections
-
import re
+import testtools
from tempest.api.network import common as net_common
from tempest.common import debug
@@ -347,6 +347,8 @@
msg="after re-associate "
"floating ip")
+ @testtools.skipUnless(CONF.compute_feature_enabled.interface_attach,
+ 'NIC hotplug not available')
@test.attr(type='smoke')
@test.services('compute', 'network')
def test_hotplug_nic(self):