Merge "Adding test_security_group_rules_create_with_invalid_port_range"
diff --git a/tempest/clients.py b/tempest/clients.py
index ef07d9c..f2e89a7 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -52,7 +52,7 @@
 from tempest.services.identity.json.identity_client import TokenClientJSON
 from tempest.services.identity.xml.identity_client import IdentityClientXML
 from tempest.services.identity.xml.identity_client import TokenClientXML
-from tempest.services.image.json.image_client import ImageClientJSON
+from tempest.services.image.v1.json.image_client import ImageClientJSON
 from tempest.services.network.json.network_client import NetworkClient
 from tempest.services.object_storage.account_client import AccountClient
 from tempest.services.object_storage.account_client import \
diff --git a/tempest/services/compute/xml/servers_client.py b/tempest/services/compute/xml/servers_client.py
index efb28e6..bd393e8 100644
--- a/tempest/services/compute/xml/servers_client.py
+++ b/tempest/services/compute/xml/servers_client.py
@@ -182,13 +182,13 @@
         server = Element("server")
         doc.append(server)
 
-        if name:
+        if name is not None:
             server.add_attr("name", name)
-        if accessIPv4:
+        if accessIPv4 is not None:
             server.add_attr("accessIPv4", accessIPv4)
-        if accessIPv6:
+        if accessIPv6 is not None:
             server.add_attr("accessIPv6", accessIPv6)
-        if meta:
+        if meta is not None:
             metadata = Element("metadata")
             server.append(metadata)
             for k, v in meta:
@@ -228,10 +228,26 @@
                          flavorRef=flavor_ref,
                          name=name)
 
-        for attr in ["adminPass", "accessIPv4", "accessIPv6", "key_name"]:
+        for attr in ["adminPass", "accessIPv4", "accessIPv6", "key_name",
+                     "user_data", "availability_zone"]:
             if attr in kwargs:
                 server.add_attr(attr, kwargs[attr])
 
+        if 'security_groups' in kwargs:
+            secgroups = Element("security_groups")
+            server.append(secgroups)
+            for secgroup in kwargs['security_groups']:
+                s = Element("security_group", name=secgroup['name'])
+                secgroups.append(s)
+
+        if 'networks' in kwargs:
+            networks = Element("networks")
+            server.append(networks)
+            for network in kwargs['networks']:
+                s = Element("network", uuid=network['uuid'],
+                            fixed_ip=network['fixed_ip'])
+                networks.append(s)
+
         if 'meta' in kwargs:
             metadata = Element("metadata")
             server.append(metadata)
@@ -383,6 +399,58 @@
     def remove_security_group(self, server_id, name):
         return self.action(server_id, 'removeSecurityGroup', None, name=name)
 
+    def list_server_metadata(self, server_id):
+        resp, body = self.get("servers/%s/metadata" % str(server_id),
+                              self.headers)
+        body = self._parse_key_value(etree.fromstring(body))
+        return resp, body
+
+    def set_server_metadata(self, server_id, meta):
+        doc = Document()
+        metadata = Element("metadata")
+        doc.append(metadata)
+        for k, v in meta.items():
+            meta_element = Element("meta", key=k)
+            meta_element.append(Text(v))
+            metadata.append(meta_element)
+        resp, body = self.put('servers/%s/metadata' % str(server_id),
+                              str(doc), self.headers)
+        return resp, xml_to_json(etree.fromstring(body))
+
+    def update_server_metadata(self, server_id, meta):
+        doc = Document()
+        metadata = Element("metadata")
+        doc.append(metadata)
+        for k, v in meta.items():
+            meta_element = Element("meta", key=k)
+            meta_element.append(Text(v))
+            metadata.append(meta_element)
+        resp, body = self.post("/servers/%s/metadata" % str(server_id),
+                               str(doc), headers=self.headers)
+        body = xml_to_json(etree.fromstring(body))
+        return resp, body
+
+    def get_server_metadata_item(self, server_id, key):
+        resp, body = self.get("servers/%s/metadata/%s" % (str(server_id), key),
+                              headers=self.headers)
+        return resp, dict([(etree.fromstring(body).attrib['key'],
+                            xml_to_json(etree.fromstring(body)))])
+
+    def set_server_metadata_item(self, server_id, key, meta):
+        doc = Document()
+        for k, v in meta.items():
+            meta_element = Element("meta", key=k)
+            meta_element.append(Text(v))
+            doc.append(meta_element)
+        resp, body = self.put('servers/%s/metadata/%s' % (str(server_id), key),
+                              str(doc), self.headers)
+        return resp, xml_to_json(etree.fromstring(body))
+
+    def delete_server_metadata_item(self, server_id, key):
+        resp, body = self.delete("servers/%s/metadata/%s" %
+                                 (str(server_id), key))
+        return resp, body
+
     def get_console_output(self, server_id, length):
         return self.action(server_id, 'os-getConsoleOutput', 'output',
                            length=length)
diff --git a/tempest/services/image/json/__init__.py b/tempest/services/image/v1/__init__.py
similarity index 100%
copy from tempest/services/image/json/__init__.py
copy to tempest/services/image/v1/__init__.py
diff --git a/tempest/services/image/json/__init__.py b/tempest/services/image/v1/json/__init__.py
similarity index 100%
rename from tempest/services/image/json/__init__.py
rename to tempest/services/image/v1/json/__init__.py
diff --git a/tempest/services/image/json/image_client.py b/tempest/services/image/v1/json/image_client.py
similarity index 100%
rename from tempest/services/image/json/image_client.py
rename to tempest/services/image/v1/json/image_client.py
diff --git a/tempest/tests/boto/test_ec2_instance_run.py b/tempest/tests/boto/test_ec2_instance_run.py
index 09bfc10..4ad37b6 100644
--- a/tempest/tests/boto/test_ec2_instance_run.py
+++ b/tempest/tests/boto/test_ec2_instance_run.py
@@ -152,16 +152,18 @@
                                                                group_desc)
         self.addResourceCleanUp(self.destroy_security_group_wait,
                                 security_group)
-        self.ec2_client.authorize_security_group(sec_group_name,
-                                                 ip_protocol="icmp",
-                                                 cidr_ip="0.0.0.0/0",
-                                                 from_port=-1,
-                                                 to_port=-1)
-        self.ec2_client.authorize_security_group(sec_group_name,
-                                                 ip_protocol="tcp",
-                                                 cidr_ip="0.0.0.0/0",
-                                                 from_port=22,
-                                                 to_port=22)
+        self.assertTrue(self.ec2_client.authorize_security_group(
+                sec_group_name,
+                ip_protocol="icmp",
+                cidr_ip="0.0.0.0/0",
+                from_port=-1,
+                to_port=-1))
+        self.assertTrue(self.ec2_client.authorize_security_group(
+                sec_group_name,
+                ip_protocol="tcp",
+                cidr_ip="0.0.0.0/0",
+                from_port=22,
+                to_port=22))
         reservation = image_ami.run(kernel_id=self.images["aki"]["image_id"],
                                     ramdisk_id=self.images["ari"]["image_id"],
                                     instance_type=self.instance_type,
@@ -178,7 +180,7 @@
 
         address = self.ec2_client.allocate_address()
         rcuk_a = self.addResourceCleanUp(address.delete)
-        address.associate(instance.id)
+        self.assertTrue(address.associate(instance.id))
 
         rcuk_da = self.addResourceCleanUp(address.disassociate)
         #TODO(afazekas): ping test. dependecy/permission ?
diff --git a/tempest/tests/compute/servers/test_server_metadata.py b/tempest/tests/compute/servers/test_server_metadata.py
index 4b17fa2..bc523de 100644
--- a/tempest/tests/compute/servers/test_server_metadata.py
+++ b/tempest/tests/compute/servers/test_server_metadata.py
@@ -15,28 +15,25 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.common.utils.data_utils import rand_name
 from tempest import exceptions
 from tempest.test import attr
 from tempest.tests.compute import base
 
 
-class ServerMetadataTest(base.BaseComputeTest):
+class ServerMetadataTestJSON(base.BaseComputeTest):
     _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
-        super(ServerMetadataTest, cls).setUpClass()
+        super(ServerMetadataTestJSON, cls).setUpClass()
         cls.client = cls.servers_client
         cls.quotas = cls.quotas_client
         cls.admin_client = cls._get_identity_admin_client()
         resp, tenants = cls.admin_client.list_tenants()
         cls.tenant_id = [tnt['id'] for tnt in tenants if tnt['name'] ==
                          cls.client.tenant_name][0]
-        #Create a server to be used for all read only tests
-        name = rand_name('server')
-        resp, server = cls.client.create_server(name, cls.image_ref,
-                                                cls.flavor_ref, meta={})
+        resp, server = cls.create_server(meta={})
+
         cls.server_id = server['id']
 
         #Wait for the server to become active
@@ -45,10 +42,10 @@
     @classmethod
     def tearDownClass(cls):
         cls.client.delete_server(cls.server_id)
-        super(ServerMetadataTest, cls).tearDownClass()
+        super(ServerMetadataTestJSON, cls).tearDownClass()
 
     def setUp(self):
-        super(ServerMetadataTest, self).setUp()
+        super(ServerMetadataTestJSON, self).setUp()
         meta = {'key1': 'value1', 'key2': 'value2'}
         resp, _ = self.client.set_server_metadata(self.server_id, meta)
         self.assertEqual(resp.status, 200)
@@ -238,3 +235,7 @@
         self.assertRaises(exceptions.BadRequest,
                           self.client.set_server_metadata,
                           self.server_id, meta=meta)
+
+
+class ServerMetadataTestXML(ServerMetadataTestJSON):
+    _interface = 'xml'
diff --git a/tempest/tests/compute/servers/test_servers_negative.py b/tempest/tests/compute/servers/test_servers_negative.py
index 366b630..9013b36 100644
--- a/tempest/tests/compute/servers/test_servers_negative.py
+++ b/tempest/tests/compute/servers/test_servers_negative.py
@@ -29,7 +29,6 @@
 
     @classmethod
     def setUpClass(cls):
-        raise cls.skipException("Until Bug 1046870 is fixed")
         super(ServersNegativeTest, cls).setUpClass()
         cls.client = cls.servers_client
         cls.img_client = cls.images_client
@@ -115,6 +114,8 @@
     @attr(type='negative')
     def test_create_numeric_server_name(self):
         # Create a server with a numeric name
+        if self.__class__._interface == "xml":
+            raise self.skipException("Not testable in XML")
 
         server_name = 12345
         self.assertRaises(exceptions.BadRequest,
@@ -182,7 +183,7 @@
     def test_update_server_of_another_tenant(self):
         # Update name of a server that belongs to another tenant
 
-        server = self.create_server()
+        resp, server = self.create_server(wait_until='ACTIVE')
         new_name = server['id'] + '_new'
         self.assertRaises(exceptions.NotFound,
                           self.alt_client.update_server, server['id'],
@@ -192,7 +193,7 @@
     def test_update_server_name_length_exceeds_256(self):
         # Update name of server exceed the name length limit
 
-        server = self.create_server()
+        resp, server = self.create_server(wait_until='ACTIVE')
         new_name = 'a' * 256
         self.assertRaises(exceptions.BadRequest,
                           self.client.update_server,
@@ -210,7 +211,7 @@
     def test_delete_a_server_of_another_tenant(self):
         # Delete a server that belongs to another tenant
         try:
-            server = self.create_server()
+            resp, server = self.create_server(wait_until='ACTIVE')
             self.assertRaises(exceptions.NotFound,
                               self.alt_client.delete_server,
                               server['id'])
@@ -245,3 +246,7 @@
 
         self.assertRaises(exceptions.NotFound, self.client.get_server,
                           '999erra43')
+
+
+class ServersNegativeTestXML(ServersNegativeTest):
+    _interface = 'xml'
diff --git a/tempest/services/image/json/__init__.py b/tempest/tests/image/v1/__init__.py
similarity index 100%
copy from tempest/services/image/json/__init__.py
copy to tempest/tests/image/v1/__init__.py
diff --git a/tempest/tests/image/test_images.py b/tempest/tests/image/v1/test_images.py
similarity index 100%
rename from tempest/tests/image/test_images.py
rename to tempest/tests/image/v1/test_images.py