Merge "moves addCleanup few lines upper to avoid potential leftovers"
diff --git a/tempest/common/ssh.py b/tempest/common/ssh.py
index be350c8..2ed1057 100644
--- a/tempest/common/ssh.py
+++ b/tempest/common/ssh.py
@@ -114,9 +114,13 @@
         err_data = []
         poll = select.poll()
         poll.register(channel, select.POLLIN)
+        start_time = time.time()
+
         while True:
             ready = poll.poll(self.channel_timeout)
             if not any(ready):
+                if not self._is_timed_out(self.timeout, start_time):
+                    continue
                 raise exceptions.TimeoutException(
                     "Command: '{0}' executed on host '{1}'.".format(
                         cmd, self.host))
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 1703248..7681f04 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -371,6 +371,24 @@
         LOG.debug("Created volume: %s", volume)
         return volume
 
+    def create_server_snapshot(self, server, compute_client=None,
+                               image_client=None, name=None):
+        if compute_client is None:
+            compute_client = self.compute_client
+        if image_client is None:
+            image_client = self.image_client
+        if name is None:
+            name = rand_name('scenario-snapshot-')
+        LOG.debug("Creating a snapshot image for server: %s", server.name)
+        image_id = compute_client.servers.create_image(server, name)
+        self.addCleanup(image_client.images.delete, image_id)
+        self.status_timeout(image_client.images, image_id, 'active')
+        snapshot_image = image_client.images.get(image_id)
+        self.assertEquals(name, snapshot_image.name)
+        LOG.debug("Created snapshot image %s for server %s",
+                  snapshot_image.name, server.name)
+        return snapshot_image
+
     def create_keypair(self, client=None, name=None):
         if client is None:
             client = self.compute_client
diff --git a/tempest/scenario/test_snapshot_pattern.py b/tempest/scenario/test_snapshot_pattern.py
index c55e2a3..95d2862 100644
--- a/tempest/scenario/test_snapshot_pattern.py
+++ b/tempest/scenario/test_snapshot_pattern.py
@@ -15,7 +15,6 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.common.utils.data_utils import rand_name
 from tempest.openstack.common import log as logging
 from tempest.scenario import manager
 
@@ -34,14 +33,6 @@
 
     """
 
-    def _wait_for_server_status(self, server, status):
-        self.status_timeout(self.compute_client.servers,
-                            server.id,
-                            status)
-
-    def _wait_for_image_status(self, image_id, status):
-        self.status_timeout(self.image_client.images, image_id, status)
-
     def _boot_image(self, image_id):
         create_kwargs = {
             'key_name': self.keypair.name
@@ -61,17 +52,6 @@
         ssh_client.exec_command('date > /tmp/timestamp; sync')
         self.timestamp = ssh_client.exec_command('cat /tmp/timestamp')
 
-    def _create_image(self, server):
-        snapshot_name = rand_name('scenario-snapshot-')
-        create_image_client = self.compute_client.servers.create_image
-        image_id = create_image_client(server, snapshot_name)
-        self.addCleanup(self.image_client.images.delete, image_id)
-        self._wait_for_server_status(server, 'ACTIVE')
-        self._wait_for_image_status(image_id, 'active')
-        snapshot_image = self.image_client.images.get(image_id)
-        self.assertEquals(snapshot_name, snapshot_image.name)
-        return image_id
-
     def _check_timestamp(self, server_or_ip):
         ssh_client = self._ssh_to_server(server_or_ip)
         got_timestamp = ssh_client.exec_command('cat /tmp/timestamp')
@@ -100,10 +80,10 @@
             self._write_timestamp(server)
 
         # snapshot the instance
-        snapshot_image_id = self._create_image(server)
+        snapshot_image = self.create_server_snapshot(server=server)
 
         # boot a second instance from the snapshot
-        server_from_snapshot = self._boot_image(snapshot_image_id)
+        server_from_snapshot = self._boot_image(snapshot_image.id)
 
         # check the existence of the timestamp file in the second instance
         if self.config.compute.use_floatingip_for_ssh:
diff --git a/tempest/scenario/test_stamp_pattern.py b/tempest/scenario/test_stamp_pattern.py
index c74b88d..3cbd1fa 100644
--- a/tempest/scenario/test_stamp_pattern.py
+++ b/tempest/scenario/test_stamp_pattern.py
@@ -50,14 +50,6 @@
     14. Check the existence of a file which created at 6. in volume2
     """
 
-    def _wait_for_server_status(self, server, status):
-        self.status_timeout(self.compute_client.servers,
-                            server.id,
-                            status)
-
-    def _wait_for_image_status(self, image_id, status):
-        self.status_timeout(self.image_client.images, image_id, status)
-
     def _wait_for_volume_snapshot_status(self, volume_snapshot, status):
         self.status_timeout(self.volume_client.volume_snapshots,
                             volume_snapshot.id, status)
@@ -84,17 +76,6 @@
         linux_client = self.get_remote_client(server_or_ip)
         return linux_client.ssh_client
 
-    def _create_image(self, server):
-        snapshot_name = rand_name('scenario-snapshot-')
-        create_image_client = self.compute_client.servers.create_image
-        image_id = create_image_client(server, snapshot_name)
-        self.addCleanup(self.image_client.images.delete, image_id)
-        self._wait_for_server_status(server, 'ACTIVE')
-        self._wait_for_image_status(image_id, 'active')
-        snapshot_image = self.image_client.images.get(image_id)
-        self.assertEquals(snapshot_name, snapshot_image.name)
-        return image_id
-
     def _create_volume_snapshot(self, volume):
         snapshot_name = rand_name('scenario-snapshot-')
         volume_snapshots = self.volume_client.volume_snapshots
@@ -189,14 +170,14 @@
         volume_snapshot = self._create_volume_snapshot(volume)
 
         # snapshot the instance
-        snapshot_image_id = self._create_image(server)
+        snapshot_image = self.create_server_snapshot(server=server)
 
         # create second volume from the snapshot(volume2)
         volume_from_snapshot = self._create_volume(
             snapshot_id=volume_snapshot.id)
 
         # boot second instance from the snapshot(instance2)
-        server_from_snapshot = self._boot_image(snapshot_image_id)
+        server_from_snapshot = self._boot_image(snapshot_image.id)
 
         # create and add floating IP to server_from_snapshot
         if self.config.compute.use_floatingip_for_ssh:
diff --git a/tempest/stress/actions/unit_test.py b/tempest/stress/actions/unit_test.py
index 95cc1bc..5ab5573 100644
--- a/tempest/stress/actions/unit_test.py
+++ b/tempest/stress/actions/unit_test.py
@@ -13,6 +13,7 @@
 #    under the License.
 
 from tempest.openstack.common import importutils
+from tempest.openstack.common import log as logging
 import tempest.stress.stressaction as stressaction
 
 
@@ -46,6 +47,7 @@
         method = kwargs['test_method'].split('.')
         self.test_method = method.pop()
         self.klass = importutils.import_class('.'.join(method))
+        self.logger = logging.getLogger('.'.join(method))
         # valid options are 'process', 'application' , 'action'
         self.class_setup_per = kwargs.get('class_setup_per',
                                           SetUpClassRunTime.process)
@@ -55,6 +57,12 @@
             self.klass.setUpClass()
         self.setupclass_called = False
 
+    @property
+    def action(self):
+        if self.test_method:
+            return self.test_method
+        return super(UnitTest, self).action
+
     def run_core(self):
         res = self.klass(self.test_method).run()
         if res.errors:
diff --git a/tempest/stress/driver.py b/tempest/stress/driver.py
index 5171da2..e518d28 100644
--- a/tempest/stress/driver.py
+++ b/tempest/stress/driver.py
@@ -148,7 +148,7 @@
 
             process = {'process': p,
                        'p_number': p_number,
-                       'action': test['action'],
+                       'action': test_run.action,
                        'statistic': shared_statistic}
 
             processes.append(process)
diff --git a/tempest/stress/stressaction.py b/tempest/stress/stressaction.py
index 6284cef..28251af 100644
--- a/tempest/stress/stressaction.py
+++ b/tempest/stress/stressaction.py
@@ -33,6 +33,13 @@
         self.tearDown()
         sys.exit(0)
 
+    @property
+    def action(self):
+        """This methods returns the action. Overload this if you
+        create a stress test wrapper.
+        """
+        return self.__class__.__name__
+
     def setUp(self, **kwargs):
         """This method is called before the run method
         to help the test initiatlize any structures.
diff --git a/tox.ini b/tox.ini
index c60e19e..0b57eb2 100644
--- a/tox.ini
+++ b/tox.ini
@@ -34,6 +34,13 @@
 commands =
   sh tools/pretty_tox_serial.sh '(?=.*\[.*\bslow\b.*\])(^tempest\.(api|scenario)\.orchestration) {posargs}'
 
+[testenv:large-ops]
+sitepackages = True
+setenv = VIRTUAL_ENV={envdir}
+commands =
+  python setup.py testr --slowest --testr-args='tempest.scenario.test_large_ops {posargs}'
+
+
 [testenv:py26-full]
 sitepackages = True
 setenv = VIRTUAL_ENV={envdir}