Merge "Wait for server activations for the updated servers"
diff --git a/tempest/api/compute/security_groups/test_security_group_rules.py b/tempest/api/compute/security_groups/test_security_group_rules.py
index b04ab8a..35f6fc2 100644
--- a/tempest/api/compute/security_groups/test_security_group_rules.py
+++ b/tempest/api/compute/security_groups/test_security_group_rules.py
@@ -75,7 +75,6 @@
                                                    to_port,
                                                    cidr=cidr,
                                                    group_id=group_id)
-        self.addCleanup(self.client.delete_security_group_rule, rule['id'])
         self.assertEqual(200, resp.status)
 
     @test.attr(type='smoke')
@@ -95,8 +94,6 @@
                                                    ip_protocol1,
                                                    from_port1, to_port1)
         rule1_id = rule['id']
-        # Delete the Security Group rule1 at the end of this method
-        self.addCleanup(self.client.delete_security_group_rule, rule1_id)
 
         # Add a second rule to the created Security Group
         ip_protocol2 = 'icmp'
diff --git a/tempest/api/compute/servers/test_list_servers_negative.py b/tempest/api/compute/servers/test_list_servers_negative.py
index fe9b7ca..28d64fb 100644
--- a/tempest/api/compute/servers/test_list_servers_negative.py
+++ b/tempest/api/compute/servers/test_list_servers_negative.py
@@ -13,8 +13,6 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import datetime
-
 from six import moves
 
 from tempest.api.compute import base
@@ -37,7 +35,6 @@
         # tearDownClass method of the super-class.
         cls.existing_fixtures = []
         cls.deleted_fixtures = []
-        cls.start_time = datetime.datetime.utcnow()
         for x in moves.xrange(2):
             resp, srv = cls.create_test_server(wait_until='ACTIVE')
             cls.existing_fixtures.append(srv)
@@ -127,19 +124,6 @@
         self.assertRaises(exceptions.BadRequest, self.client.list_servers,
                           {'limit': -1})
 
-    @test.attr(type='gate')
-    def test_list_servers_by_changes_since(self):
-        # Servers are listed by specifying changes-since date
-        changes_since = {'changes-since': self.start_time.isoformat()}
-        resp, body = self.client.list_servers(changes_since)
-        self.assertEqual('200', resp['status'])
-        # changes-since returns all instances, including deleted.
-        num_expected = (len(self.existing_fixtures) +
-                        len(self.deleted_fixtures))
-        self.assertEqual(num_expected, len(body['servers']),
-                         "Number of servers %d is wrong in %s" %
-                         (num_expected, body['servers']))
-
     @test.attr(type=['negative', 'gate'])
     def test_list_servers_by_changes_since_invalid_date(self):
         # Return an error when invalid date format is passed
diff --git a/tempest/api/network/test_security_groups.py b/tempest/api/network/test_security_groups.py
index 97b3c4b..b98cea1 100644
--- a/tempest/api/network/test_security_groups.py
+++ b/tempest/api/network/test_security_groups.py
@@ -86,9 +86,6 @@
                 direction='ingress'
             )
             self.assertEqual('201', resp['status'])
-            self.addCleanup(self._delete_security_group_rule,
-                            rule_create_body['security_group_rule']['id']
-                            )
 
             # Show details of the created security rule
             resp, show_rule_body = self.client.show_security_group_rule(
@@ -130,9 +127,6 @@
 
         self.assertEqual('201', resp['status'])
         sec_group_rule = rule_create_body['security_group_rule']
-        self.addCleanup(self._delete_security_group_rule,
-                        sec_group_rule['id']
-                        )
 
         self.assertEqual(sec_group_rule['direction'], direction)
         self.assertEqual(sec_group_rule['protocol'], protocol)
diff --git a/tempest/api/volume/admin/test_volume_types.py b/tempest/api/volume/admin/test_volume_types.py
index ee1d09a..3b8c214 100644
--- a/tempest/api/volume/admin/test_volume_types.py
+++ b/tempest/api/volume/admin/test_volume_types.py
@@ -118,14 +118,16 @@
                          'from the created Volume_type')
 
     @test.attr(type='smoke')
-    def test_volume_type_encryption_create_get(self):
-        # Create/get encryption type.
+    def test_volume_type_encryption_create_get_delete(self):
+        # Create/get/delete encryption type.
         provider = "LuksEncryptor"
         control_location = "front-end"
         name = data_utils.rand_name("volume-type-")
         resp, body = self.client.create_volume_type(name)
         self.assertEqual(200, resp.status)
         self.addCleanup(self._delete_volume_type, body['id'])
+
+        # Create encryption type
         resp, encryption_type = self.client.create_encryption_type(
             body['id'], provider=provider,
             control_location=control_location)
@@ -137,6 +139,8 @@
         self.assertEqual(control_location, encryption_type['control_location'],
                          "The created encryption_type control_location is not "
                          "equal to the requested control_location")
+
+        # Get encryption type
         resp, fetched_encryption_type = self.client.get_encryption_type(
             encryption_type['volume_type_id'])
         self.assertEqual(200, resp.status)
@@ -148,3 +152,15 @@
                          fetched_encryption_type['control_location'],
                          'The fetched encryption_type control_location is '
                          'different from the created encryption_type')
+
+        # Delete encryption type
+        resp, _ = self.client.delete_encryption_type(
+            encryption_type['volume_type_id'])
+        self.assertEqual(202, resp.status)
+        resource = {"id": encryption_type['volume_type_id'],
+                    "type": "encryption-type"}
+        self.client.wait_for_resource_deletion(resource)
+        resp, deleted_encryption_type = self.client.get_encryption_type(
+            encryption_type['volume_type_id'])
+        self.assertEqual(200, resp.status)
+        self.assertEmpty(deleted_encryption_type)
diff --git a/tempest/common/commands.py b/tempest/common/commands.py
index 6580c65..6720847 100644
--- a/tempest/common/commands.py
+++ b/tempest/common/commands.py
@@ -75,3 +75,22 @@
 
 def ovs_db_dump():
     return sudo_cmd_call("ovsdb-client dump")
+
+
+def copy_file_to_host(file_from, dest, host, username, pkey):
+    dest = "%s@%s:%s" % (username, host, dest)
+    cmd = "scp -v -o UserKnownHostsFile=/dev/null " \
+          "-o StrictHostKeyChecking=no " \
+          "-i %(pkey)s %(file1)s %(dest)s" % {'pkey': pkey,
+                                              'file1': file_from,
+                                              'dest': dest}
+    args = shlex.split(cmd)
+    subprocess_args = {'stdout': subprocess.PIPE,
+                       'stderr': subprocess.STDOUT}
+    proc = subprocess.Popen(args, **subprocess_args)
+    stdout, stderr = proc.communicate()
+    if proc.returncode != 0:
+        LOG.error(("Command {0} returned with exit status {1},"
+                  "output {2}, error {3}").format(cmd, proc.returncode,
+                                                  stdout, stderr))
+    return stdout
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 40fbf05..f4850bb 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -285,7 +285,6 @@
         for ruleset in rulesets:
             sg_rule = client.security_group_rules.create(secgroup_id,
                                                          **ruleset)
-            self.set_resource(sg_rule.id, sg_rule)
             rules.append(sg_rule)
         return rules
 
@@ -923,7 +922,6 @@
             client=client,
             **sg_rule['security_group_rule']
         )
-        self.set_resource(sg_rule.id, sg_rule)
         self.assertEqual(secgroup.tenant_id, sg_rule.tenant_id)
         self.assertEqual(secgroup.id, sg_rule.security_group_id)
 
diff --git a/tempest/scenario/test_load_balancer_basic.py b/tempest/scenario/test_load_balancer_basic.py
index 9152220..1c24b5c 100644
--- a/tempest/scenario/test_load_balancer_basic.py
+++ b/tempest/scenario/test_load_balancer_basic.py
@@ -13,10 +13,14 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+
+import httplib
+import tempfile
 import time
-import urllib
+import urllib2
 
 from tempest.api.network import common as net_common
+from tempest.common import commands
 from tempest import config
 from tempest import exceptions
 from tempest.scenario import manager
@@ -135,71 +139,53 @@
 
         1. SSH to the instance
         2. Start two http backends listening on ports 80 and 88 respectively
-        In case there are two instances, each backend is created on a separate
-        instance.
-
-        The backends are the inetd services. To start them we need to edit
-        /etc/inetd.conf in the following way:
-        www stream tcp nowait root /bin/sh sh /home/cirros/script_name
-
-        Where /home/cirros/script_name is a path to a script which
-        echoes the responses:
-        echo -e 'HTTP/1.0 200 OK\r\n\r\nserver_name
-
-        If we want the server to listen on port 88, then we use
-        "kerberos" instead of "www".
         """
 
         for server_id, ip in self.server_ips.iteritems():
             private_key = self.servers_keypairs[server_id].private_key
             server_name = self.compute_client.servers.get(server_id).name
+            username = config.scenario.ssh_user
             ssh_client = self.get_remote_client(
                 server_or_ip=ip,
                 private_key=private_key)
             ssh_client.validate_authentication()
-            # Create service for inetd
-            create_script = """sudo sh -c "echo -e \\"echo -e 'HTTP/1.0 """ \
-                            """200 OK\\\\\\r\\\\\\n\\\\\\r\\\\\\n""" \
-                            """%(server)s'\\" >>/home/cirros/%(script)s\""""
 
-            cmd = create_script % {
-                'server': server_name,
-                'script': 'script1'}
+            # Write a backend's responce into a file
+            resp = """HTTP/1.0 200 OK\r\nContent-Length: 8\r\n\r\n%s"""
+            with tempfile.NamedTemporaryFile() as script:
+                script.write(resp % server_name)
+                script.flush()
+                with tempfile.NamedTemporaryFile() as key:
+                    key.write(private_key)
+                    key.flush()
+                    commands.copy_file_to_host(script.name,
+                                               "~/script1",
+                                               ip,
+                                               username, key.name)
+            # Start netcat
+            start_server = """sudo nc -ll -p %(port)s -e cat """ \
+                           """~/%(script)s &"""
+            cmd = start_server % {'port': self.port1,
+                                  'script': 'script1'}
             ssh_client.exec_command(cmd)
-            # Configure inetd
-            configure_inetd = """sudo sh -c "echo -e \\"%(service)s """ \
-                              """stream tcp nowait root /bin/sh sh """ \
-                              """/home/cirros/%(script)s\\" >> """ \
-                              """/etc/inetd.conf\""""
-            # "www" stands for port 80
-            cmd = configure_inetd % {'service': 'www',
-                                     'script': 'script1'}
-            ssh_client.exec_command(cmd)
-
             if len(self.server_ips) == 1:
-                cmd = create_script % {'server': 'server2',
-                                       'script': 'script2'}
+                with tempfile.NamedTemporaryFile() as script:
+                    script.write(resp % 'server2')
+                    script.flush()
+                    with tempfile.NamedTemporaryFile() as key:
+                        key.write(private_key)
+                        key.flush()
+                        commands.copy_file_to_host(script.name,
+                                                   "~/script2", ip,
+                                                   username, key.name)
+                cmd = start_server % {'port': self.port2,
+                                      'script': 'script2'}
                 ssh_client.exec_command(cmd)
-                # "kerberos" stands for port 88
-                cmd = configure_inetd % {'service': 'kerberos',
-                                         'script': 'script2'}
-                ssh_client.exec_command(cmd)
-
-            # Get PIDs of inetd
-            pids = ssh_client.get_pids('inetd')
-            if pids != ['']:
-                # If there are any inetd processes, reload them
-                kill_cmd = "sudo kill -HUP %s" % ' '.join(pids)
-                ssh_client.exec_command(kill_cmd)
-            else:
-                # In other case start inetd
-                start_inetd = "sudo /usr/sbin/inetd /etc/inetd.conf"
-                ssh_client.exec_command(start_inetd)
 
     def _check_connection(self, check_ip, port=80):
         def try_connect(ip, port):
             try:
-                resp = urllib.urlopen("http://{0}:{1}/".format(ip, port))
+                resp = urllib2.urlopen("http://{0}:{1}/".format(ip, port))
                 if resp.getcode() == 200:
                     return True
                 return False
@@ -284,27 +270,32 @@
 
     def _check_load_balancing(self):
         """
-        1. Send 100 requests on the floating ip associated with the VIP
+        1. Send 10 requests on the floating ip associated with the VIP
         2. Check that the requests are shared between
            the two servers and that both of them get equal portions
            of the requests
         """
 
         self._check_connection(self.vip_ip)
-        resp = self._send_requests(self.vip_ip)
-        self.assertEqual(set(["server1\n", "server2\n"]), set(resp))
-        self.assertEqual(50, resp.count("server1\n"))
-        self.assertEqual(50, resp.count("server2\n"))
+        self._send_requests(self.vip_ip, set(["server1", "server2"]))
 
-    def _send_requests(self, vip_ip):
-        resp = []
-        for count in range(100):
-            resp.append(
-                urllib.urlopen(
-                    "http://{0}/".format(vip_ip)).read())
-        return resp
+    def _send_requests(self, vip_ip, expected, num_req=10):
+        count = 0
+        while count < num_req:
+            try:
+                resp = []
+                for i in range(len(self.members)):
+                    resp.append(
+                        urllib2.urlopen(
+                            "http://{0}/".format(vip_ip)).read())
+                count += 1
+                self.assertEqual(expected,
+                                 set(resp))
+            # NOTE: There always is a slim chance of getting this exception
+            #       due to special aspects of haproxy internal behavior.
+            except httplib.BadStatusLine:
+                pass
 
-    @test.skip_because(bug='1295165')
     @test.attr(type='smoke')
     @test.services('compute', 'network')
     def test_load_balancer_basic(self):
diff --git a/tempest/services/volume/json/admin/volume_types_client.py b/tempest/services/volume/json/admin/volume_types_client.py
index c9c0582..65ecc67 100644
--- a/tempest/services/volume/json/admin/volume_types_client.py
+++ b/tempest/services/volume/json/admin/volume_types_client.py
@@ -18,6 +18,7 @@
 
 from tempest.common import rest_client
 from tempest import config
+from tempest import exceptions
 
 CONF = config.CONF
 
@@ -34,6 +35,26 @@
         self.build_interval = CONF.volume.build_interval
         self.build_timeout = CONF.volume.build_timeout
 
+    def is_resource_deleted(self, resource):
+        # to use this method self.resource must be defined to respective value
+        # Resource is a dictionary containing resource id and type
+        # Resource : {"id" : resource_id
+        #             "type": resource_type}
+        try:
+            if resource['type'] == "volume-type":
+                self.get_volume_type(resource['id'])
+            elif resource['type'] == "encryption-type":
+                resp, body = self.get_encryption_type(resource['id'])
+                assert 200 == resp.status
+                if not body:
+                    return True
+            else:
+                msg = (" resource value is either not defined or incorrect.")
+                raise exceptions.UnprocessableEntity(msg)
+        except exceptions.NotFound:
+            return True
+        return False
+
     def list_volume_types(self, params=None):
         """List all the volume_types created."""
         url = 'types'
@@ -150,3 +171,7 @@
         resp, body = self.post(url, post_body)
         body = json.loads(body)
         return resp, body['encryption']
+
+    def delete_encryption_type(self, vol_type_id):
+        """Delete the encryption type for the specified volume-type."""
+        return self.delete("/types/%s/encryption/provider" % str(vol_type_id))