Merge "always use sitepackages"
diff --git a/tempest/api/compute/limits/test_absolute_limits.py b/tempest/api/compute/limits/test_absolute_limits.py
index 2809244..908d537 100644
--- a/tempest/api/compute/limits/test_absolute_limits.py
+++ b/tempest/api/compute/limits/test_absolute_limits.py
@@ -16,8 +16,7 @@
 #    under the License.
 
 from tempest.api.compute import base
-from tempest import exceptions
-from tempest.test import attr
+from tempest import test
 
 
 class AbsoluteLimitsTestJSON(base.BaseV2ComputeTest):
@@ -27,9 +26,8 @@
     def setUpClass(cls):
         super(AbsoluteLimitsTestJSON, cls).setUpClass()
         cls.client = cls.limits_client
-        cls.server_client = cls.servers_client
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_absLimits_get(self):
         # To check if all limits are present in the response
         resp, absolute_limits = self.client.get_absolute_limits()
@@ -49,25 +47,6 @@
                          "Failed to find element %s in absolute limits list"
                          % ', '.join(ele for ele in missing_elements))
 
-    @attr(type=['negative', 'gate'])
-    def test_max_image_meta_exceed_limit(self):
-        # We should not create vm with image meta over maxImageMeta limit
-        # Get max limit value
-        max_meta = self.client.get_specific_absolute_limit('maxImageMeta')
-
-        # Create server should fail, since we are passing > metadata Limit!
-        max_meta_data = int(max_meta) + 1
-
-        meta_data = {}
-        for xx in range(max_meta_data):
-            meta_data[str(xx)] = str(xx)
-
-        self.assertRaises(exceptions.OverLimit,
-                          self.server_client.create_server,
-                          name='test', meta=meta_data,
-                          flavor_ref=self.flavor_ref,
-                          image_ref=self.image_ref)
-
 
 class AbsoluteLimitsTestXML(AbsoluteLimitsTestJSON):
     _interface = 'xml'
diff --git a/tempest/api/compute/limits/test_absolute_limits_negative.py b/tempest/api/compute/limits/test_absolute_limits_negative.py
new file mode 100644
index 0000000..8547403
--- /dev/null
+++ b/tempest/api/compute/limits/test_absolute_limits_negative.py
@@ -0,0 +1,53 @@
+# 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
+from tempest import exceptions
+from tempest import test
+
+
+class AbsoluteLimitsNegativeTestJSON(base.BaseV2ComputeTest):
+    _interface = 'json'
+
+    @classmethod
+    def setUpClass(cls):
+        super(AbsoluteLimitsNegativeTestJSON, cls).setUpClass()
+        cls.client = cls.limits_client
+        cls.server_client = cls.servers_client
+
+    @test.attr(type=['negative', 'gate'])
+    def test_max_image_meta_exceed_limit(self):
+        # We should not create vm with image meta over maxImageMeta limit
+        # Get max limit value
+        max_meta = self.client.get_specific_absolute_limit('maxImageMeta')
+
+        # Create server should fail, since we are passing > metadata Limit!
+        max_meta_data = int(max_meta) + 1
+
+        meta_data = {}
+        for xx in range(max_meta_data):
+            meta_data[str(xx)] = str(xx)
+
+        self.assertRaises(exceptions.OverLimit,
+                          self.server_client.create_server,
+                          name='test', meta=meta_data,
+                          flavor_ref=self.flavor_ref,
+                          image_ref=self.image_ref)
+
+
+class AbsoluteLimitsNegativeTestXML(AbsoluteLimitsNegativeTestJSON):
+    _interface = 'xml'
diff --git a/tempest/api/compute/servers/test_server_addresses.py b/tempest/api/compute/servers/test_server_addresses.py
index 7ca8a52..1e55afb 100644
--- a/tempest/api/compute/servers/test_server_addresses.py
+++ b/tempest/api/compute/servers/test_server_addresses.py
@@ -16,34 +16,20 @@
 #    under the License.
 
 from tempest.api.compute import base
-from tempest import exceptions
-from tempest.test import attr
+from tempest import test
 
 
-class ServerAddressesTest(base.BaseV2ComputeTest):
+class ServerAddressesTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
-        super(ServerAddressesTest, cls).setUpClass()
+        super(ServerAddressesTestJSON, cls).setUpClass()
         cls.client = cls.servers_client
 
         resp, cls.server = cls.create_test_server(wait_until='ACTIVE')
 
-    @attr(type=['negative', 'gate'])
-    def test_list_server_addresses_invalid_server_id(self):
-        # List addresses request should fail if server id not in system
-        self.assertRaises(exceptions.NotFound, self.client.list_addresses,
-                          '999')
-
-    @attr(type=['negative', 'gate'])
-    def test_list_server_addresses_by_network_neg(self):
-        # List addresses by network should fail if network name not valid
-        self.assertRaises(exceptions.NotFound,
-                          self.client.list_addresses_by_network,
-                          self.server['id'], 'invalid')
-
-    @attr(type='smoke')
+    @test.attr(type='smoke')
     def test_list_server_addresses(self):
         # All public and private addresses for
         # a server should be returned
@@ -60,7 +46,7 @@
                 self.assertTrue(address['addr'])
                 self.assertTrue(address['version'])
 
-    @attr(type='smoke')
+    @test.attr(type='smoke')
     def test_list_server_addresses_by_network(self):
         # Providing a network type should filter
         # the addresses return by that type
@@ -80,5 +66,5 @@
                 self.assertTrue(any([a for a in addr if a == address]))
 
 
-class ServerAddressesTestXML(ServerAddressesTest):
+class ServerAddressesTestXML(ServerAddressesTestJSON):
     _interface = 'xml'
diff --git a/tempest/api/compute/servers/test_server_addresses_negative.py b/tempest/api/compute/servers/test_server_addresses_negative.py
new file mode 100644
index 0000000..30aa7d1
--- /dev/null
+++ b/tempest/api/compute/servers/test_server_addresses_negative.py
@@ -0,0 +1,48 @@
+# 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
+from tempest import exceptions
+from tempest import test
+
+
+class ServerAddressesNegativeTestJSON(base.BaseV2ComputeTest):
+    _interface = 'json'
+
+    @classmethod
+    def setUpClass(cls):
+        super(ServerAddressesNegativeTestJSON, cls).setUpClass()
+        cls.client = cls.servers_client
+
+        resp, cls.server = cls.create_test_server(wait_until='ACTIVE')
+
+    @test.attr(type=['negative', 'gate'])
+    def test_list_server_addresses_invalid_server_id(self):
+        # List addresses request should fail if server id not in system
+        self.assertRaises(exceptions.NotFound, self.client.list_addresses,
+                          '999')
+
+    @test.attr(type=['negative', 'gate'])
+    def test_list_server_addresses_by_network_neg(self):
+        # List addresses by network should fail if network name not valid
+        self.assertRaises(exceptions.NotFound,
+                          self.client.list_addresses_by_network,
+                          self.server['id'], 'invalid')
+
+
+class ServerAddressesNegativeTestXML(ServerAddressesNegativeTestJSON):
+    _interface = 'xml'
diff --git a/tempest/api/compute/test_auth_token.py b/tempest/api/compute/test_auth_token.py
deleted file mode 100644
index e52c415..0000000
--- a/tempest/api/compute/test_auth_token.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# Copyright 2013 IBM Corp
-#
-#   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.
-
-
-import testtools
-
-from tempest.api.compute import base
-import tempest.config as config
-
-CONF = config.CONF
-
-
-class AuthTokenTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
-
-    @classmethod
-    def setUpClass(cls):
-        super(AuthTokenTestJSON, cls).setUpClass()
-
-        cls.servers_v2 = cls.os.servers_client
-        cls.servers_v3 = cls.os.servers_client_v3_auth
-
-    def test_v2_token(self):
-        # Can get a token using v2 of the identity API and use that to perform
-        # an operation on the compute service.
-
-        # Doesn't matter which compute API is used,
-        # picking list_servers because it's easy.
-        self.servers_v2.list_servers()
-
-    @testtools.skipIf(not CONF.identity.uri_v3,
-                      'v3 auth client not configured')
-    def test_v3_token(self):
-        # Can get a token using v3 of the identity API and use that to perform
-        # an operation on the compute service.
-
-        # Doesn't matter which compute API is used,
-        # picking list_servers because it's easy.
-        self.servers_v3.list_servers()
-
-
-class AuthTokenTestXML(AuthTokenTestJSON):
-    _interface = 'xml'
diff --git a/tempest/api/network/base_routers.py b/tempest/api/network/base_routers.py
new file mode 100644
index 0000000..9baef04
--- /dev/null
+++ b/tempest/api/network/base_routers.py
@@ -0,0 +1,50 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 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.network import base
+
+
+class BaseRouterTest(base.BaseAdminNetworkTest):
+    # NOTE(salv-orlando): This class inherits from BaseAdminNetworkTest
+    # as some router operations, such as enabling or disabling SNAT
+    # require admin credentials by default
+
+    @classmethod
+    def setUpClass(cls):
+        super(BaseRouterTest, cls).setUpClass()
+
+    def _delete_router(self, router_id):
+        resp, _ = self.client.delete_router(router_id)
+        self.assertEqual(204, resp.status)
+        # Asserting that the router is not found in the list
+        # after deletion
+        resp, list_body = self.client.list_routers()
+        self.assertEqual('200', resp['status'])
+        routers_list = list()
+        for router in list_body['routers']:
+            routers_list.append(router['id'])
+        self.assertNotIn(router_id, routers_list)
+
+    def _remove_router_interface_with_subnet_id(self, router_id, subnet_id):
+        resp, _ = self.client.remove_router_interface_with_subnet_id(
+            router_id, subnet_id)
+        self.assertEqual('200', resp['status'])
+
+    def _remove_router_interface_with_port_id(self, router_id, port_id):
+        resp, _ = self.client.remove_router_interface_with_port_id(
+            router_id, port_id)
+        self.assertEqual('200', resp['status'])
diff --git a/tempest/api/network/test_routers.py b/tempest/api/network/test_routers.py
index 21934f2..b6022e8 100644
--- a/tempest/api/network/test_routers.py
+++ b/tempest/api/network/test_routers.py
@@ -17,43 +17,18 @@
 
 import netaddr
 
-from tempest.api.network import base
+from tempest.api.network import base_routers as base
 from tempest.common.utils import data_utils
 from tempest import test
 
 
-class RoutersTest(base.BaseAdminNetworkTest):
-    # NOTE(salv-orlando): This class inherits from BaseAdminNetworkTest
-    # as some router operations, such as enabling or disabling SNAT
-    # require admin credentials by default
+class RoutersTest(base.BaseRouterTest):
     _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
         super(RoutersTest, cls).setUpClass()
 
-    def _delete_router(self, router_id):
-        resp, _ = self.client.delete_router(router_id)
-        self.assertEqual(204, resp.status)
-        # Asserting that the router is not found in the list
-        # after deletion
-        resp, list_body = self.client.list_routers()
-        self.assertEqual('200', resp['status'])
-        routers_list = list()
-        for router in list_body['routers']:
-            routers_list.append(router['id'])
-        self.assertNotIn(router_id, routers_list)
-
-    def _remove_router_interface_with_subnet_id(self, router_id, subnet_id):
-        resp, _ = self.client.remove_router_interface_with_subnet_id(
-            router_id, subnet_id)
-        self.assertEqual('200', resp['status'])
-
-    def _remove_router_interface_with_port_id(self, router_id, port_id):
-        resp, _ = self.client.remove_router_interface_with_port_id(
-            router_id, port_id)
-        self.assertEqual('200', resp['status'])
-
     @test.attr(type='smoke')
     def test_create_show_list_update_delete_router(self):
         # Create a router
diff --git a/tempest/api/network/test_routers_negative.py b/tempest/api/network/test_routers_negative.py
new file mode 100644
index 0000000..520a612
--- /dev/null
+++ b/tempest/api/network/test_routers_negative.py
@@ -0,0 +1,57 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 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.network import base_routers as base
+from tempest.common.utils import data_utils
+from tempest import exceptions
+from tempest.test import attr
+
+
+class RoutersNegativeTest(base.BaseRouterTest):
+    _interface = 'json'
+
+    @classmethod
+    def setUpClass(cls):
+        super(RoutersNegativeTest, cls).setUpClass()
+        cls.router = cls.create_router(data_utils.rand_name('router-'))
+        cls.network = cls.create_network()
+        cls.subnet = cls.create_subnet(cls.network)
+
+    @attr(type=['negative', 'smoke'])
+    def test_router_add_gateway_invalid_network_returns_404(self):
+        self.assertRaises(exceptions.NotFound,
+                          self.client.update_router,
+                          self.router['id'],
+                          external_gateway_info={
+                              'network_id': self.router['id']})
+
+    @attr(type=['negative', 'smoke'])
+    def test_router_add_gateway_net_not_external_returns_400(self):
+        self.create_subnet(self.network)
+        self.assertRaises(exceptions.BadRequest,
+                          self.client.update_router,
+                          self.router['id'],
+                          external_gateway_info={
+                              'network_id': self.network['id']})
+
+    @attr(type=['negative', 'smoke'])
+    def test_router_remove_interface_in_use_returns_409(self):
+        self.client.add_router_interface_with_subnet_id(
+            self.router['id'], self.subnet['id'])
+        self.assertRaises(exceptions.Conflict,
+                          self.client.delete_router,
+                          self.router['id'])