Addresses lp#1004971

* Adds method to get last boot time of a server instance
* Adds instance level checks to most server actions tests

Change-Id: I4b0f85f58898a276c09893c3af0594d389419bd6
diff --git a/tempest/common/utils/__init__.py b/tempest/common/utils/__init__.py
index b9829a3..38f3d38 100644
--- a/tempest/common/utils/__init__.py
+++ b/tempest/common/utils/__init__.py
@@ -1,4 +1,4 @@
-LAST_REBOOT_TIME_FORMAT = '%Y-%m-%d %H:%M'
+LAST_REBOOT_TIME_FORMAT = '%Y-%m-%d %H:%M:%S'
 PING_IPV4_COMMAND = 'ping -c 3 '
 PING_IPV6_COMMAND = 'ping6 -c 3 '
 PING_PACKET_LOSS_REGEX = '(\d{1,3})\.?\d*\% packet loss'
diff --git a/tempest/common/utils/linux/remote_client.py b/tempest/common/utils/linux/remote_client.py
index e06aef5..f7b467b 100644
--- a/tempest/common/utils/linux/remote_client.py
+++ b/tempest/common/utils/linux/remote_client.py
@@ -1,7 +1,10 @@
 from tempest.common.ssh import Client
 from tempest.config import TempestConfig
+from tempest.common import utils
 from tempest.exceptions import SSHTimeout, ServerUnreachable
 
+import time
+
 
 class RemoteClient():
 
@@ -52,3 +55,10 @@
         command = 'cat /proc/partitions'
         output = self.ssh_client.exec_command(command)
         return output
+
+    def get_boot_time(self):
+        cmd = 'date -d "`cut -f1 -d. /proc/uptime` seconds ago" \
+            "+%Y-%m-%d %H:%M:%S"'
+        boot_time_string = self.ssh_client.exec_command(cmd)
+        boot_time_string = boot_time_string.replace('\n', '')
+        return time.strptime(boot_time_string, utils.LAST_REBOOT_TIME_FORMAT)
diff --git a/tempest/tests/compute/test_server_actions.py b/tempest/tests/compute/test_server_actions.py
index c51e0fa..81a12db 100644
--- a/tempest/tests/compute/test_server_actions.py
+++ b/tempest/tests/compute/test_server_actions.py
@@ -24,6 +24,7 @@
 import tempest.config
 from tempest import exceptions
 from tempest.common.utils.data_utils import rand_name
+from tempest.common.utils.linux.remote_client import RemoteClient
 from tempest.tests.compute.base import BaseComputeTest
 from tempest.tests import compute
 
@@ -31,6 +32,7 @@
 class ServerActionsTest(BaseComputeTest):
 
     resize_available = tempest.config.TempestConfig().compute.resize_available
+    run_ssh = tempest.config.TempestConfig().compute.run_ssh
 
     @classmethod
     def setUpClass(cls):
@@ -43,7 +45,7 @@
                                                  self.image_ref,
                                                  self.flavor_ref)
         self.server_id = server['id']
-
+        self.password = server['adminPass']
         self.client.wait_for_server_status(self.server_id, 'ACTIVE')
 
     def tearDown(self):
@@ -54,25 +56,60 @@
                          'Change password not available.')
     def test_change_server_password(self):
         """The server's password should be set to the provided password"""
-        resp, body = self.client.change_password(self.server_id, 'newpass')
+        new_password = 'Newpass1234'
+        resp, body = self.client.change_password(self.server_id, new_password)
         self.assertEqual(202, resp.status)
         self.client.wait_for_server_status(self.server_id, 'ACTIVE')
 
+        if self.run_ssh:
+            # Verify that the user can authenticate with the new password
+            resp, server = self.client.get_server(self.server_id)
+            linux_client = RemoteClient(server, self.ssh_user, new_password)
+            self.assertTrue(linux_client.can_authenticate())
+
     @attr(type='smoke')
     def test_reboot_server_hard(self):
         """ The server should be power cycled """
+        if self.run_ssh:
+            # Get the time the server was last rebooted,
+            # waiting for one minute as who doesn't have seconds precision
+            resp, server = self.client.get_server(self.server_id)
+            linux_client = RemoteClient(server, self.ssh_user, self.password)
+            boot_time = linux_client.get_boot_time()
+            time.sleep(60)
+
         resp, body = self.client.reboot(self.server_id, 'HARD')
         self.assertEqual(202, resp.status)
         self.client.wait_for_server_status(self.server_id, 'ACTIVE')
 
+        if self.run_ssh:
+            # Log in and verify the boot time has changed
+            linux_client = RemoteClient(server, self.ssh_user, self.password)
+            new_boot_time = linux_client.get_boot_time()
+            self.assertGreater(new_boot_time, boot_time)
+
     @attr(type='smoke')
     @unittest.skip('Until bug 1014647 is dealt with.')
     def test_reboot_server_soft(self):
         """The server should be signaled to reboot gracefully"""
+        if self.run_ssh:
+            # Get the time the server was last rebooted,
+            # waiting for one minute as who doesn't have seconds precision
+            resp, server = self.client.get_server(self.server_id)
+            linux_client = RemoteClient(server, self.ssh_user, self.password)
+            boot_time = linux_client.get_boot_time()
+            time.sleep(60)
+
         resp, body = self.client.reboot(self.server_id, 'SOFT')
         self.assertEqual(202, resp.status)
         self.client.wait_for_server_status(self.server_id, 'ACTIVE')
 
+        if self.run_ssh:
+            # Log in and verify the boot time has changed
+            linux_client = RemoteClient(server, self.ssh_user, self.password)
+            new_boot_time = linux_client.get_boot_time()
+            self.assertGreater(new_boot_time, boot_time)
+
     @attr(type='smoke')
     def test_rebuild_server(self):
         """ The server should be rebuilt using the provided image and data """
@@ -81,12 +118,12 @@
         file_contents = 'Test server rebuild.'
         personality = [{'path': '/etc/rebuild.txt',
                        'contents': base64.b64encode(file_contents)}]
-
+        password = 'rebuildPassw0rd'
         resp, rebuilt_server = self.client.rebuild(self.server_id,
                                                    self.image_ref_alt,
                                                    name=new_name, meta=meta,
                                                    personality=personality,
-                                                   adminPass='rebuild')
+                                                   adminPass=password)
 
         #Verify the properties in the initial response are correct
         self.assertEqual(self.server_id, rebuilt_server['id'])
@@ -101,6 +138,11 @@
         self.assertTrue(self.image_ref_alt.endswith(rebuilt_image_id))
         self.assertEqual(new_name, rebuilt_server['name'])
 
+        if self.run_ssh:
+            # Verify that the user can authenticate with the provided password
+            linux_client = RemoteClient(server, self.ssh_user, password)
+            self.assertTrue(linux_client.can_authenticate())
+
     @attr(type='smoke')
     @unittest.skipIf(not resize_available, 'Resize not available.')
     def test_resize_server_confirm(self):