Bulk Subnets and Ports creation

Test case for bulk subnet and bulk port create and delete were mising.
I have added these missing testcases.

Change-Id: I0197829712368492f2b08e133fdcdae25eef47c4
diff --git a/tempest/api/network/test_networks.py b/tempest/api/network/test_networks.py
index f3d1485..66ca05f 100644
--- a/tempest/api/network/test_networks.py
+++ b/tempest/api/network/test_networks.py
@@ -58,6 +58,8 @@
     def setUpClass(cls):
         super(NetworksTestJSON, cls).setUpClass()
         cls.network = cls.create_network()
+        cls.network1 = cls.create_network()
+        cls.network2 = cls.create_network()
         cls.name = cls.network['name']
         cls.subnet = cls.create_subnet(cls.network)
         cls.cidr = cls.subnet['cidr']
@@ -75,6 +77,30 @@
         for n in created_networks:
             self.assertNotIn(n['id'], networks_list)
 
+    def _delete_subnets(self, created_subnets):
+        for n in created_subnets:
+            resp, body = self.client.delete_subnet(n['id'])
+            self.assertEqual(204, resp.status)
+        # Asserting that the subnets are not found in the list after deletion
+        resp, body = self.client.list_subnets()
+        subnets_list = list()
+        for subnet in body['subnets']:
+            subnets_list.append(subnet['id'])
+        for n in created_subnets:
+            self.assertNotIn(n['id'], subnets_list)
+
+    def _delete_ports(self, created_ports):
+        for n in created_ports:
+            resp, body = self.client.delete_port(n['id'])
+            self.assertEqual(204, resp.status)
+        # Asserting that the ports are not found in the list after deletion
+        resp, body = self.client.list_ports()
+        ports_list = list()
+        for port in body['ports']:
+            ports_list.append(port['id'])
+        for n in created_ports:
+            self.assertNotIn(n['id'], ports_list)
+
     @attr(type='smoke')
     def test_create_update_delete_network_subnet(self):
         # Creates a network
@@ -225,6 +251,74 @@
             self.assertIsNotNone(n['id'])
             self.assertIn(n['id'], networks_list)
 
+    @attr(type='smoke')
+    def test_bulk_create_delete_subnet(self):
+        # Creates 2 subnets in one request
+        cidr = netaddr.IPNetwork(self.network_cfg.tenant_network_cidr)
+        mask_bits = self.network_cfg.tenant_network_mask_bits
+        cidrs = []
+        for subnet_cidr in cidr.subnet(mask_bits):
+            cidrs.append(subnet_cidr)
+        names = []
+        networks = [self.network1['id'], self.network2['id']]
+        for i in range(len(networks)):
+            names.append(rand_name('subnet-'))
+        subnet_list = []
+        # TODO(raies): "for IPv6, version list [4, 6] will be used.
+        # and cidr for IPv6 will be of IPv6"
+        ip_version = [4, 4]
+        for i in range(len(names)):
+            p1 = {
+                'network_id': networks[i],
+                'cidr': str(cidrs[(i)]),
+                'name': names[i],
+                'ip_version': ip_version[i]
+            }
+            subnet_list.append(p1)
+        del subnet_list[1]['name']
+        resp, body = self.client.create_bulk_subnet(subnet_list)
+        created_subnets = body['subnets']
+        self.addCleanup(self._delete_subnets, created_subnets)
+        self.assertEqual('201', resp['status'])
+        # Asserting that the subnets are found in the list after creation
+        resp, body = self.client.list_subnets()
+        subnets_list = list()
+        for subnet in body['subnets']:
+            subnets_list.append(subnet['id'])
+        for n in created_subnets:
+            self.assertIsNotNone(n['id'])
+            self.assertIn(n['id'], subnets_list)
+
+    @attr(type='smoke')
+    def test_bulk_create_delete_port(self):
+        # Creates 2 ports in one request
+        names = []
+        networks = [self.network1['id'], self.network2['id']]
+        for i in range(len(networks)):
+            names.append(rand_name('port-'))
+        port_list = []
+        state = [True, False]
+        for i in range(len(names)):
+            p1 = {
+                'network_id': networks[i],
+                'name': names[i],
+                'admin_state_up': state[i],
+            }
+            port_list.append(p1)
+        del port_list[1]['name']
+        resp, body = self.client.create_bulk_port(port_list)
+        created_ports = body['ports']
+        self.addCleanup(self._delete_ports, created_ports)
+        self.assertEqual('201', resp['status'])
+        # Asserting that the ports are found in the list after creation
+        resp, body = self.client.list_ports()
+        ports_list = list()
+        for port in body['ports']:
+            ports_list.append(port['id'])
+        for n in created_ports:
+            self.assertIsNotNone(n['id'])
+            self.assertIn(n['id'], ports_list)
+
 
 class NetworksTestXML(NetworksTestJSON):
     _interface = 'xml'
diff --git a/tempest/services/network/json/network_client.py b/tempest/services/network/json/network_client.py
index 3550878..10e64f8 100644
--- a/tempest/services/network/json/network_client.py
+++ b/tempest/services/network/json/network_client.py
@@ -375,6 +375,14 @@
         body = json.loads(body)
         return resp, body
 
+    def create_bulk_subnet(self, subnet_list):
+        post_body = {'subnets': subnet_list}
+        body = json.dumps(post_body)
+        uri = '%s/subnets' % (self.uri_prefix)
+        resp, body = self.post(uri, headers=self.headers, body=body)
+        body = json.loads(body)
+        return resp, body
+
     def delete_security_group_rule(self, rule_id):
         uri = '%s/security-group-rules/%s' % (self.uri_prefix, rule_id)
         resp, body = self.delete(uri, self.headers)
@@ -385,3 +393,11 @@
         resp, body = self.get(uri, self.headers)
         body = json.loads(body)
         return resp, body
+
+    def create_bulk_port(self, port_list):
+        post_body = {'ports': port_list}
+        body = json.dumps(post_body)
+        uri = '%s/ports' % (self.uri_prefix)
+        resp, body = self.post(uri, headers=self.headers, body=body)
+        body = json.loads(body)
+        return resp, body
diff --git a/tempest/services/network/xml/network_client.py b/tempest/services/network/xml/network_client.py
index 0aef92f..8303bc0 100755
--- a/tempest/services/network/xml/network_client.py
+++ b/tempest/services/network/xml/network_client.py
@@ -219,6 +219,36 @@
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
+    def create_bulk_subnet(self, subnet_list):
+        uri = '%s/subnets' % (self.uri_prefix)
+        post_body = Element("subnets")
+        for i in range(len(subnet_list)):
+            v = subnet_list[i]
+            p1 = Element("subnet")
+            for k, kv in v.iteritems():
+                p2 = Element(k, kv)
+                p1.append(p2)
+            post_body.append(p1)
+        resp, body = self.post(uri, str(Document(post_body)), self.headers)
+        subnets = self._parse_array(etree.fromstring(body))
+        subnets = {"subnets": subnets}
+        return resp, subnets
+
+    def create_bulk_port(self, port_list):
+        uri = '%s/ports' % (self.uri_prefix)
+        post_body = Element("ports")
+        for i in range(len(port_list)):
+            v = port_list[i]
+            p1 = Element("port")
+            for k, kv in v.iteritems():
+                p2 = Element(k, kv)
+                p1.append(p2)
+            post_body.append(p1)
+        resp, body = self.post(uri, str(Document(post_body)), self.headers)
+        ports = self._parse_array(etree.fromstring(body))
+        ports = {"ports": ports}
+        return resp, ports
+
 
 def _root_tag_fetcher_and_xml_to_json_parse(xml_returned_body):
     body = ET.fromstring(xml_returned_body)