Create only necessary resources for compute v2 and network tests

This patch leverages the set_network_resources method in order to allow
tempest api tests for compute v2 and network to create only those
network resources which are required by the test

Related-Bug: #1262334

Change-Id: I7fad33d883e66a7a0e7d079c319a4a6ba815bf45
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 311e158..49c767a 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -169,6 +169,8 @@
 
     @classmethod
     def setUpClass(cls):
+        # By default compute tests do not create network resources
+        cls.set_network_resources()
         super(BaseV2ComputeTest, cls).setUpClass()
         cls.servers_client = cls.os.servers_client
         cls.flavors_client = cls.os.flavors_client
diff --git a/tempest/api/compute/floating_ips/base.py b/tempest/api/compute/floating_ips/base.py
new file mode 100644
index 0000000..e2c9b04
--- /dev/null
+++ b/tempest/api/compute/floating_ips/base.py
@@ -0,0 +1,28 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2014 OpenStack Foundation
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.api.compute import base
+
+
+class BaseFloatingIPsTest(base.BaseV2ComputeTest):
+
+    @classmethod
+    def setUpClass(cls):
+        # Floating IP actions might need a full network configuration
+        cls.set_network_resources(network=True, subnet=True,
+                                  router=True, dhcp=True)
+        super(BaseFloatingIPsTest, cls).setUpClass()
diff --git a/tempest/api/compute/floating_ips/test_floating_ips_actions.py b/tempest/api/compute/floating_ips/test_floating_ips_actions.py
index 32e7b39..cd5f4a8 100644
--- a/tempest/api/compute/floating_ips/test_floating_ips_actions.py
+++ b/tempest/api/compute/floating_ips/test_floating_ips_actions.py
@@ -15,13 +15,13 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.api.compute import base
+from tempest.api.compute.floating_ips import base
 from tempest.common.utils.data_utils import rand_name
 from tempest import exceptions
 from tempest.test import attr
 
 
-class FloatingIPsTestJSON(base.BaseV2ComputeTest):
+class FloatingIPsTestJSON(base.BaseFloatingIPsTest):
     _interface = 'json'
     server_id = None
     floating_ip = None
diff --git a/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py b/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py
index 89315bb..674669c 100644
--- a/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py
+++ b/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py
@@ -17,13 +17,13 @@
 
 import uuid
 
-from tempest.api.compute import base
+from tempest.api.compute.floating_ips import base
 from tempest.common.utils import data_utils
 from tempest import exceptions
 from tempest.test import attr
 
 
-class FloatingIPsNegativeTestJSON(base.BaseV2ComputeTest):
+class FloatingIPsNegativeTestJSON(base.BaseFloatingIPsTest):
     _interface = 'json'
     server_id = None
 
diff --git a/tempest/api/compute/security_groups/base.py b/tempest/api/compute/security_groups/base.py
new file mode 100644
index 0000000..66f2600
--- /dev/null
+++ b/tempest/api/compute/security_groups/base.py
@@ -0,0 +1,27 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2012 OpenStack Foundation
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.api.compute import base
+
+
+class BaseSecurityGroupsTest(base.BaseV2ComputeTest):
+
+    @classmethod
+    def setUpClass(cls):
+        # A network and a subnet will be created for these tests
+        cls.set_network_resources(network=True, subnet=True)
+        super(BaseSecurityGroupsTest, cls).setUpClass()
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 2ccc3a8..eddccc1 100644
--- a/tempest/api/compute/security_groups/test_security_group_rules.py
+++ b/tempest/api/compute/security_groups/test_security_group_rules.py
@@ -15,12 +15,12 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.api.compute import base
+from tempest.api.compute.security_groups import base
 from tempest.common.utils import data_utils
 from tempest.test import attr
 
 
-class SecurityGroupRulesTestJSON(base.BaseV2ComputeTest):
+class SecurityGroupRulesTestJSON(base.BaseSecurityGroupsTest):
     _interface = 'json'
 
     @classmethod
diff --git a/tempest/api/compute/security_groups/test_security_group_rules_negative.py b/tempest/api/compute/security_groups/test_security_group_rules_negative.py
index c0b202d..bec95ad 100644
--- a/tempest/api/compute/security_groups/test_security_group_rules_negative.py
+++ b/tempest/api/compute/security_groups/test_security_group_rules_negative.py
@@ -17,7 +17,7 @@
 
 import testtools
 
-from tempest.api.compute import base
+from tempest.api.compute.security_groups import base
 from tempest.common.utils import data_utils
 from tempest import config
 from tempest import exceptions
@@ -27,7 +27,7 @@
 CONF = config.CONF
 
 
-class SecurityGroupRulesNegativeTestJSON(base.BaseV2ComputeTest):
+class SecurityGroupRulesNegativeTestJSON(base.BaseSecurityGroupsTest):
     _interface = 'json'
 
     @classmethod
diff --git a/tempest/api/compute/security_groups/test_security_groups.py b/tempest/api/compute/security_groups/test_security_groups.py
index 4ae65be..ffd9fd2 100644
--- a/tempest/api/compute/security_groups/test_security_groups.py
+++ b/tempest/api/compute/security_groups/test_security_groups.py
@@ -15,13 +15,13 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.api.compute import base
+from tempest.api.compute.security_groups import base
 from tempest.common.utils import data_utils
 from tempest import exceptions
 from tempest import test
 
 
-class SecurityGroupsTestJSON(base.BaseV2ComputeTest):
+class SecurityGroupsTestJSON(base.BaseSecurityGroupsTest):
     _interface = 'json'
 
     @classmethod
diff --git a/tempest/api/compute/security_groups/test_security_groups_negative.py b/tempest/api/compute/security_groups/test_security_groups_negative.py
index 6a8e604..cf78089 100644
--- a/tempest/api/compute/security_groups/test_security_groups_negative.py
+++ b/tempest/api/compute/security_groups/test_security_groups_negative.py
@@ -17,7 +17,7 @@
 
 import testtools
 
-from tempest.api.compute import base
+from tempest.api.compute.security_groups import base
 from tempest.common.utils import data_utils
 from tempest import config
 from tempest import exceptions
@@ -26,7 +26,7 @@
 CONF = config.CONF
 
 
-class SecurityGroupsNegativeTestJSON(base.BaseV2ComputeTest):
+class SecurityGroupsNegativeTestJSON(base.BaseSecurityGroupsTest):
     _interface = 'json'
 
     @classmethod
diff --git a/tempest/api/compute/servers/test_attach_interfaces.py b/tempest/api/compute/servers/test_attach_interfaces.py
index dbb7d75..738e4a8 100644
--- a/tempest/api/compute/servers/test_attach_interfaces.py
+++ b/tempest/api/compute/servers/test_attach_interfaces.py
@@ -26,6 +26,8 @@
     def setUpClass(cls):
         if not cls.config.service_available.neutron:
             raise cls.skipException("Neutron is required")
+        # This test class requires network and subnet
+        cls.set_network_resources(network=True, subnet=True)
         super(AttachInterfacesTestJSON, cls).setUpClass()
         cls.client = cls.os.interfaces_client
 
diff --git a/tempest/api/compute/servers/test_server_addresses.py b/tempest/api/compute/servers/test_server_addresses.py
index 1e55afb..39d9580 100644
--- a/tempest/api/compute/servers/test_server_addresses.py
+++ b/tempest/api/compute/servers/test_server_addresses.py
@@ -24,6 +24,8 @@
 
     @classmethod
     def setUpClass(cls):
+        # This test module might use a network and a subnet
+        cls.set_network_resources(network=True, subnet=True)
         super(ServerAddressesTestJSON, cls).setUpClass()
         cls.client = cls.servers_client
 
diff --git a/tempest/api/compute/servers/test_server_addresses_negative.py b/tempest/api/compute/servers/test_server_addresses_negative.py
index 30aa7d1..0343538 100644
--- a/tempest/api/compute/servers/test_server_addresses_negative.py
+++ b/tempest/api/compute/servers/test_server_addresses_negative.py
@@ -25,6 +25,7 @@
 
     @classmethod
     def setUpClass(cls):
+        cls.set_network_resources(network=True, subnet=True)
         super(ServerAddressesNegativeTestJSON, cls).setUpClass()
         cls.client = cls.servers_client
 
diff --git a/tempest/api/compute/servers/test_virtual_interfaces.py b/tempest/api/compute/servers/test_virtual_interfaces.py
index 968ae47..7bbe30b 100644
--- a/tempest/api/compute/servers/test_virtual_interfaces.py
+++ b/tempest/api/compute/servers/test_virtual_interfaces.py
@@ -29,6 +29,8 @@
 
     @classmethod
     def setUpClass(cls):
+        # This test needs a network and a subnet
+        cls.set_network_resources(network=True, subnet=True)
         super(VirtualInterfacesTestJSON, cls).setUpClass()
         cls.client = cls.servers_client
         resp, server = cls.create_test_server(wait_until='ACTIVE')
diff --git a/tempest/api/compute/servers/test_virtual_interfaces_negative.py b/tempest/api/compute/servers/test_virtual_interfaces_negative.py
index a2a6c11..d67e13a 100644
--- a/tempest/api/compute/servers/test_virtual_interfaces_negative.py
+++ b/tempest/api/compute/servers/test_virtual_interfaces_negative.py
@@ -27,6 +27,8 @@
 
     @classmethod
     def setUpClass(cls):
+        # For this test no network resources are needed
+        cls.set_network_resources()
         super(VirtualInterfacesNegativeTestJSON, cls).setUpClass()
         cls.client = cls.servers_client
 
diff --git a/tempest/api/compute/test_authorization.py b/tempest/api/compute/test_authorization.py
index 327c7d1..03075df 100644
--- a/tempest/api/compute/test_authorization.py
+++ b/tempest/api/compute/test_authorization.py
@@ -30,6 +30,8 @@
 
     @classmethod
     def setUpClass(cls):
+        # No network resources required for this test
+        cls.set_network_resources()
         super(AuthorizationTestJSON, cls).setUpClass()
         if not cls.multi_user:
             msg = "Need >1 user"
diff --git a/tempest/api/network/base.py b/tempest/api/network/base.py
index dcad101..fd3dc9f 100644
--- a/tempest/api/network/base.py
+++ b/tempest/api/network/base.py
@@ -50,6 +50,8 @@
 
     @classmethod
     def setUpClass(cls):
+        # Create no network resources for these test.
+        cls.set_network_resources()
         super(BaseNetworkTest, cls).setUpClass()
         os = clients.Manager(interface=cls._interface)
         cls.network_cfg = os.config.network
diff --git a/tempest/test.py b/tempest/test.py
index 83a4319..931aa5d 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -332,12 +332,16 @@
         @param subnet
         @param dhcp
         """
-        self.network_resources = {
-            'network': network,
-            'router': router,
-            'subnet': subnet,
-            'dhcp': dhcp,
-        }
+        # network resources should be set only once from callers
+        # in order to ensure that even if it's called multiple times in
+        # a chain of overloaded methods, the attribute is set only
+        # in the leaf class
+        if not self.network_resources:
+            self.network_resources = {
+                'network': network,
+                'router': router,
+                'subnet': subnet,
+                'dhcp': dhcp}
 
 
 def call_until_true(func, duration, sleep_for):