Merge "Use standard assertVolumeStatusWait for volume detachment"
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index f509cb4..0f2b2cf 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -260,7 +260,8 @@
# The endpoint type to use for the compute service. (string value)
#endpoint_type = publicURL
-# Visible fixed network name (string value)
+# Name of the fixed network that is visible to all test tenants.
+# (string value)
#fixed_network_name = private
# Valid primary flavor to use in tests. (string value)
@@ -270,7 +271,8 @@
#flavor_ref_alt = 2
# Unallocated floating IP range, which will be used to test the
-# floating IP bulk feature for CRUD operation. (string value)
+# floating IP bulk feature for CRUD operation. This block must not
+# overlap an existing floating IP pool. (string value)
#floating_ip_range = 10.0.0.0/29
# Password used to authenticate to an instance using the alternate
@@ -299,7 +301,8 @@
# IP version used for SSH connections. (integer value)
#ip_version_for_ssh = 4
-# Network used for SSH connections. (string value)
+# Network used for SSH connections. Ignored if
+# use_floatingip_for_ssh=true or run_ssh=false. (string value)
#network_for_ssh = public
# Path to a private key file for SSH access to remote hosts (string
diff --git a/tempest/api/compute/floating_ips/test_floating_ips_actions.py b/tempest/api/compute/floating_ips/test_floating_ips_actions.py
index ba66ab9..3bb7d19 100644
--- a/tempest/api/compute/floating_ips/test_floating_ips_actions.py
+++ b/tempest/api/compute/floating_ips/test_floating_ips_actions.py
@@ -130,7 +130,8 @@
# Make sure no longer associated with old server
self.assertRaises((exceptions.NotFound,
- exceptions.UnprocessableEntity),
+ exceptions.UnprocessableEntity,
+ exceptions.Conflict),
self.client.disassociate_floating_ip_from_server,
self.floating_ip, self.server_id)
diff --git a/tempest/config.py b/tempest/config.py
index 63a7226..616a476 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -222,10 +222,12 @@
"channel."),
cfg.StrOpt('fixed_network_name',
default='private',
- help="Visible fixed network name "),
+ help="Name of the fixed network that is visible to all test "
+ "tenants."),
cfg.StrOpt('network_for_ssh',
default='public',
- help="Network used for SSH connections."),
+ help="Network used for SSH connections. Ignored if "
+ "use_floatingip_for_ssh=true or run_ssh=false."),
cfg.IntOpt('ip_version_for_ssh',
default=4,
help="IP version used for SSH connections."),
@@ -266,7 +268,9 @@
cfg.StrOpt('floating_ip_range',
default='10.0.0.0/29',
help='Unallocated floating IP range, which will be used to '
- 'test the floating IP bulk feature for CRUD operation.')
+ 'test the floating IP bulk feature for CRUD operation. '
+ 'This block must not overlap an existing floating IP '
+ 'pool.')
]
compute_features_group = cfg.OptGroup(name='compute-feature-enabled',
@@ -975,7 +979,14 @@
baremetal_group = cfg.OptGroup(name='baremetal',
- title='Baremetal provisioning service options')
+ title='Baremetal provisioning service options',
+ help='When enabling baremetal tests, Nova '
+ 'must be configured to use the Ironic '
+ 'driver. The following paremeters for the '
+ '[compute] section must be disabled: '
+ 'console_output, interface_attach, '
+ 'live_migration, pause, rescue, resize '
+ 'shelve, snapshot, and suspend')
BaremetalGroup = [
cfg.StrOpt('catalog_type',
diff --git a/tempest/scenario/test_swift_telemetry_middleware.py b/tempest/scenario/test_swift_telemetry_middleware.py
new file mode 100644
index 0000000..e8eb45c
--- /dev/null
+++ b/tempest/scenario/test_swift_telemetry_middleware.py
@@ -0,0 +1,103 @@
+#
+# Copyright 2014 Red Hat
+#
+# Author: Chris Dent <chdent@redhat.com>
+# 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 import config
+from tempest.openstack.common import log as logging
+from tempest.scenario import manager
+from tempest import test
+
+CONF = config.CONF
+
+LOG = logging.getLogger(__name__)
+
+# Loop for up to 120 seconds waiting on notifications
+# NOTE(chdent): The choice of 120 seconds is fairly
+# arbitrary: Long enough to give the notifications the
+# chance to travel across a highly latent bus but not
+# so long as to allow excessive latency to never be visible.
+# TODO(chdent): Ideally this value would come from configuration.
+NOTIFICATIONS_WAIT = 120
+NOTIFICATIONS_SLEEP = 1
+
+
+class TestSwiftTelemetry(manager.SwiftScenarioTest):
+ """
+ Test that swift uses the ceilometer middleware.
+ * create container.
+ * upload a file to the created container.
+ * retrieve the file from the created container.
+ * wait for notifications from ceilometer.
+ """
+
+ @classmethod
+ def resource_setup(cls):
+ if not CONF.service_available.ceilometer:
+ skip_msg = ("%s skipped as ceilometer is not available" %
+ cls.__name__)
+ raise cls.skipException(skip_msg)
+ elif CONF.telemetry.too_slow_to_test:
+ skip_msg = "Ceilometer feature for fast work mysql is disabled"
+ raise cls.skipException(skip_msg)
+ super(TestSwiftTelemetry, cls).resource_setup()
+ cls.telemetry_client = cls.manager.telemetry_client
+
+ def _confirm_notifications(self, container_name, obj_name):
+ """
+ Loop seeking for appropriate notifications about the containers
+ and objects sent to swift.
+ """
+
+ def _check_samples():
+ """
+ Return True only if we have notifications about some
+ containers and some objects and the notifications are about
+ the expected containers and objects.
+ Otherwise returning False will case _check_samples to be
+ called again.
+ """
+ _, results = self.telemetry_client.list_samples(
+ 'storage.api.request')
+ LOG.debug('got samples %s', results)
+
+ # Extract container info from samples.
+ containers = [sample['resource_metadata']['container']
+ for sample in results
+ if sample['resource_metadata']['container']
+ != 'None']
+ # Extract object info from samples.
+ objects = [sample['resource_metadata']['object']
+ for sample in results
+ if sample['resource_metadata']['object'] != 'None']
+
+ return (containers
+ and objects
+ and container_name in containers
+ and obj_name in objects)
+
+ self.assertTrue(test.call_until_true(_check_samples,
+ NOTIFICATIONS_WAIT,
+ NOTIFICATIONS_SLEEP),
+ 'Correct notifications were not received after '
+ '%s seconds.' % NOTIFICATIONS_WAIT)
+
+ @test.services('object_storage', 'telemetry')
+ def test_swift_middleware_notifies(self):
+ container_name = self.create_container()
+ obj_name, _ = self.upload_object_to_container(container_name)
+ self._confirm_notifications(container_name, obj_name)