Merge "Make L3AgentSchedulerTestJSON DVR-aware"
diff --git a/requirements.txt b/requirements.txt
index 35b5144..bf7471e 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -12,7 +12,6 @@
 python-glanceclient>=0.15.0
 python-cinderclient>=1.1.0
 python-heatclient>=0.3.0
-python-saharaclient>=0.8.0
 python-swiftclient>=2.2.0
 testrepository>=0.0.18
 oslo.concurrency>=1.8.0,<1.9.0         # Apache-2.0
diff --git a/tempest/cli/simple_read_only/data_processing/__init__.py b/tempest/cli/simple_read_only/data_processing/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/cli/simple_read_only/data_processing/__init__.py
+++ /dev/null
diff --git a/tempest/cli/simple_read_only/data_processing/test_sahara.py b/tempest/cli/simple_read_only/data_processing/test_sahara.py
deleted file mode 100644
index 153dbd2..0000000
--- a/tempest/cli/simple_read_only/data_processing/test_sahara.py
+++ /dev/null
@@ -1,191 +0,0 @@
-# Copyright (c) 2013 Mirantis Inc.
-#
-# 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 logging
-import re
-
-from tempest_lib import exceptions
-import testtools
-
-from tempest import cli
-from tempest import config
-from tempest import test
-
-CONF = config.CONF
-
-LOG = logging.getLogger(__name__)
-
-
-class SimpleReadOnlySaharaClientTest(cli.ClientTestBase):
-    """Basic, read-only tests for Sahara CLI client.
-
-    Checks return values and output of read-only commands.
-    These tests do not presume any content, nor do they create
-    their own. They only verify the structure of output if present.
-    """
-
-    @classmethod
-    def resource_setup(cls):
-        if not CONF.service_available.sahara:
-            msg = "Skipping all Sahara cli tests because it is not available"
-            raise cls.skipException(msg)
-        super(SimpleReadOnlySaharaClientTest, cls).resource_setup()
-
-    def sahara(self, *args, **kwargs):
-        return self.clients.sahara(
-            *args, endpoint_type=CONF.data_processing.endpoint_type, **kwargs)
-
-    @test.attr(type='negative')
-    @test.idempotent_id('c8809259-710f-43f9-b452-54b2be3115a9')
-    def test_sahara_fake_action(self):
-        self.assertRaises(exceptions.CommandFailed,
-                          self.sahara,
-                          'this-does-not-exist')
-
-    @test.idempotent_id('39afe90c-0fd8-456e-89e2-da6de9680fff')
-    def test_sahara_plugins_list(self):
-        plugins = self.parser.listing(self.sahara('plugin-list'))
-        self.assertTableStruct(plugins, [
-            'name',
-            'versions',
-            'title'
-        ])
-
-    @test.idempotent_id('3eb36fd8-bb06-4004-9e90-84ddf4dbcf5b')
-    @testtools.skipUnless(CONF.data_processing_feature_enabled.plugins,
-                          'No plugins defined')
-    def test_sahara_plugins_show(self):
-        name_param = '--name %s' % \
-            (CONF.data_processing_feature_enabled.plugins[0])
-        result = self.sahara('plugin-show', params=name_param)
-        plugin = self.parser.listing(result)
-        self.assertTableStruct(plugin, [
-            'Property',
-            'Value'
-        ])
-
-    @test.idempotent_id('502b684b-3d41-4619-aa6c-4db3465ae79d')
-    def test_sahara_node_group_template_list(self):
-        result = self.sahara('node-group-template-list')
-        node_group_templates = self.parser.listing(result)
-        self.assertTableStruct(node_group_templates, [
-            'name',
-            'id',
-            'plugin_name',
-            'node_processes',
-            'description'
-        ])
-
-    @test.idempotent_id('6c36fe4d-3b88-4b0d-b702-2a051db7dae7')
-    def test_sahara_cluster_template_list(self):
-        result = self.sahara('cluster-template-list')
-        cluster_templates = self.parser.listing(result)
-        self.assertTableStruct(cluster_templates, [
-            'name',
-            'id',
-            'plugin_name',
-            'node_groups',
-            'description'
-        ])
-
-    @test.idempotent_id('b951949d-b9a6-49db-add5-8a18ac533810')
-    def test_sahara_cluster_list(self):
-        result = self.sahara('cluster-list')
-        clusters = self.parser.listing(result)
-        self.assertTableStruct(clusters, [
-            'name',
-            'id',
-            'status',
-            'node_count'
-        ])
-
-    @test.idempotent_id('dbc83a8c-15b6-4aa8-b274-5896577397e1')
-    def test_sahara_data_source_list(self):
-        result = self.sahara('data-source-list')
-        data_sources = self.parser.listing(result)
-        self.assertTableStruct(data_sources, [
-            'name',
-            'id',
-            'type',
-            'description'
-        ])
-
-    @test.idempotent_id('a8f77e05-d4bf-45c3-8245-57835d0de37b')
-    def test_sahara_job_binary_data_list(self):
-        result = self.sahara('job-binary-data-list')
-        job_binary_data_list = self.parser.listing(result)
-        self.assertTableStruct(job_binary_data_list, [
-            'id',
-            'name'
-        ])
-
-    @test.idempotent_id('a8f4d0f3-fa1c-49ce-b73f-d624d89dc381')
-    def test_sahara_job_binary_list(self):
-        result = self.sahara('job-binary-list')
-        job_binaries = self.parser.listing(result)
-        self.assertTableStruct(job_binaries, [
-            'id',
-            'name',
-            'description'
-        ])
-
-    @test.idempotent_id('91164ca4-d049-49e0-a52a-686b408196ff')
-    def test_sahara_job_template_list(self):
-        result = self.sahara('job-template-list')
-        job_templates = self.parser.listing(result)
-        self.assertTableStruct(job_templates, [
-            'id',
-            'name',
-            'description'
-        ])
-
-    @test.idempotent_id('6829c251-a8b6-449d-af86-7dd98b69a7ce')
-    def test_sahara_job_list(self):
-        result = self.sahara('job-list')
-        jobs = self.parser.listing(result)
-        self.assertTableStruct(jobs, [
-            'id',
-            'cluster_id',
-            'status'
-        ])
-
-    @test.idempotent_id('e4bd5d3b-474b-4b7a-82ab-f6bb0bc89faf')
-    def test_sahara_bash_completion(self):
-        self.sahara('bash-completion')
-
-    # Optional arguments
-    @test.idempotent_id('699c14e5-632e-46b8-91e5-6bff8c8307e5')
-    def test_sahara_help(self):
-        help_text = self.sahara('help')
-        lines = help_text.split('\n')
-        self.assertFirstLineStartsWith(lines, 'usage: sahara')
-
-        commands = []
-        cmds_start = lines.index('Positional arguments:')
-        cmds_end = lines.index('Optional arguments:')
-        command_pattern = re.compile('^ {4}([a-z0-9\-\_]+)')
-        for line in lines[cmds_start:cmds_end]:
-            match = command_pattern.match(line)
-            if match:
-                commands.append(match.group(1))
-        commands = set(commands)
-        wanted_commands = set(('cluster-create', 'data-source-create',
-                               'image-unregister', 'job-binary-create',
-                               'plugin-list', 'job-binary-create', 'help'))
-        self.assertFalse(wanted_commands - commands)
-
-    @test.idempotent_id('84a18ea6-6379-4024-af6b-0e938f60dfc2')
-    def test_sahara_version(self):
-        version = self.sahara('', flags='--version')
-        self.assertTrue(re.search('[0-9.]+', version))
diff --git a/tempest/cmd/javelin.py b/tempest/cmd/javelin.py
index 05aaabe..c945a46 100755
--- a/tempest/cmd/javelin.py
+++ b/tempest/cmd/javelin.py
@@ -306,10 +306,10 @@
     return tenants
 
 
-def _assign_swift_role(user):
+def _assign_swift_role(user, swift_role):
     admin = keystone_admin()
     roles = admin.identity.list_roles()
-    role = next(r for r in roles if r['name'] == 'Member')
+    role = next(r for r in roles if r['name'] == swift_role)
     LOG.debug(USERS[user])
     try:
         admin.identity.assign_user_role(
@@ -583,7 +583,8 @@
     LOG.info("Creating objects")
     for obj in objects:
         LOG.debug("Object %s" % obj)
-        _assign_swift_role(obj['owner'])
+        swift_role = obj.get('swift_role', 'Member')
+        _assign_swift_role(obj['owner'], swift_role)
         client = client_for_user(obj['owner'])
         client.containers.create_container(obj['container'])
         client.objects.create_object(
diff --git a/tempest/cmd/verify_tempest_config.py b/tempest/cmd/verify_tempest_config.py
index 909de96..3c71e07 100755
--- a/tempest/cmd/verify_tempest_config.py
+++ b/tempest/cmd/verify_tempest_config.py
@@ -253,10 +253,9 @@
         'database': 'trove'
     }
     # Get catalog list for endpoints to use for validation
-    endpoints = os.endpoints_client.list_endpoints()
-    for endpoint in endpoints:
-        service = os.service_client.get_service(endpoint['service_id'])
-        services.append(service['type'])
+    _token, auth_data = os.auth_provider.get_auth()
+    for entry in auth_data['serviceCatalog']:
+        services.append(entry['type'])
     # Pull all catalog types from config file and compare against endpoint list
     for cfgname in dir(CONF._config):
         cfg = getattr(CONF, cfgname)
@@ -330,7 +329,7 @@
         CONF_PARSER = moves.configparser.SafeConfigParser()
         CONF_PARSER.optionxform = str
         CONF_PARSER.readfp(conf_file)
-    os = clients.AdminManager()
+    os = clients.Manager()
     services = check_service_availability(os, update)
     results = {}
     for service in ['nova', 'cinder', 'neutron', 'swift']:
diff --git a/tempest/common/cred_provider.py b/tempest/common/cred_provider.py
index 9630d1c..2c6763d 100644
--- a/tempest/common/cred_provider.py
+++ b/tempest/common/cred_provider.py
@@ -147,3 +147,25 @@
     @abc.abstractmethod
     def is_role_available(self, role):
         return
+
+
+class TestResources(object):
+    """Readonly Credentials, with network resources added."""
+
+    def __init__(self, credentials):
+        self._credentials = credentials
+        self.network = None
+        self.subnet = None
+        self.router = None
+
+    def __getattr__(self, item):
+        return getattr(self._credentials, item)
+
+    def set_resources(self, **kwargs):
+        for key in kwargs.keys():
+            if hasattr(self, key):
+                setattr(self, key, kwargs[key])
+
+    @property
+    def credentials(self):
+        return self._credentials
diff --git a/tempest/common/fixed_network.py b/tempest/common/fixed_network.py
index b533898..67fbab1 100644
--- a/tempest/common/fixed_network.py
+++ b/tempest/common/fixed_network.py
@@ -42,7 +42,8 @@
     if (isinstance(creds_provider, isolated_creds.IsolatedCreds) and
         (CONF.service_available.neutron and
          not CONF.service_available.ironic)):
-        network = creds_provider.get_primary_network()
+        # tenant_allow_isolation == True, so network is defined
+        network = creds_provider.get_primary_creds().network
     else:
         if fixed_network_name:
             try:
diff --git a/tempest/common/isolated_creds.py b/tempest/common/isolated_creds.py
index 22fc9c3..1f85872 100644
--- a/tempest/common/isolated_creds.py
+++ b/tempest/common/isolated_creds.py
@@ -142,7 +142,6 @@
                                             network_resources)
         self.network_resources = network_resources
         self.isolated_creds = {}
-        self.isolated_net_resources = {}
         self.ports = []
         self.password = password
         self.default_admin_creds = cred_provider.get_configured_credentials(
@@ -207,7 +206,8 @@
         if roles:
             for role in roles:
                 self.creds_client.assign_user_role(user, project, role)
-        return self.creds_client.get_credentials(user, project, self.password)
+        creds = self.creds_client.get_credentials(user, project, self.password)
+        return cred_provider.TestResources(creds)
 
     def _create_network_resources(self, tenant_id):
         network = None
@@ -297,33 +297,6 @@
         self.network_admin_client.add_router_interface_with_subnet_id(
             router_id, subnet_id)
 
-    def get_primary_network(self):
-        return self.isolated_net_resources.get('primary')[0]
-
-    def get_primary_subnet(self):
-        return self.isolated_net_resources.get('primary')[1]
-
-    def get_primary_router(self):
-        return self.isolated_net_resources.get('primary')[2]
-
-    def get_admin_network(self):
-        return self.isolated_net_resources.get('admin')[0]
-
-    def get_admin_subnet(self):
-        return self.isolated_net_resources.get('admin')[1]
-
-    def get_admin_router(self):
-        return self.isolated_net_resources.get('admin')[2]
-
-    def get_alt_network(self):
-        return self.isolated_net_resources.get('alt')[0]
-
-    def get_alt_subnet(self):
-        return self.isolated_net_resources.get('alt')[1]
-
-    def get_alt_router(self):
-        return self.isolated_net_resources.get('alt')[2]
-
     def get_credentials(self, credential_type):
         if self.isolated_creds.get(str(credential_type)):
             credentials = self.isolated_creds[str(credential_type)]
@@ -341,8 +314,8 @@
                 not CONF.baremetal.driver_enabled):
                 network, subnet, router = self._create_network_resources(
                     credentials.tenant_id)
-                self.isolated_net_resources[str(credential_type)] = (
-                    network, subnet, router,)
+                credentials.set_resources(network=network, subnet=subnet,
+                                          router=router)
                 LOG.info("Created isolated network resources for : \n"
                          + " credentials: %s" % credentials)
         return credentials
@@ -368,12 +341,6 @@
             new_index = str(roles) + '-' + str(len(self.isolated_creds))
             self.isolated_creds[new_index] = exist_creds
             del self.isolated_creds[str(roles)]
-            # Handle isolated neutron resouces if they exist too
-            if CONF.service_available.neutron:
-                exist_net = self.isolated_net_resources.get(str(roles))
-                if exist_net:
-                    self.isolated_net_resources[new_index] = exist_net
-                    del self.isolated_net_resources[str(roles)]
         return self.get_credentials(roles)
 
     def _clear_isolated_router(self, router_id, router_name):
@@ -414,27 +381,33 @@
 
     def _clear_isolated_net_resources(self):
         net_client = self.network_admin_client
-        for cred in self.isolated_net_resources:
-            network, subnet, router = self.isolated_net_resources.get(cred)
+        for cred in self.isolated_creds:
+            creds = self.isolated_creds.get(cred)
+            if (not creds or not any([creds.router, creds.network,
+                                      creds.subnet])):
+                continue
             LOG.debug("Clearing network: %(network)s, "
                       "subnet: %(subnet)s, router: %(router)s",
-                      {'network': network, 'subnet': subnet, 'router': router})
+                      {'network': creds.network, 'subnet': creds.subnet,
+                       'router': creds.router})
             if (not self.network_resources or
-                self.network_resources.get('router')):
+                    (self.network_resources.get('router') and creds.subnet)):
                 try:
                     net_client.remove_router_interface_with_subnet_id(
-                        router['id'], subnet['id'])
+                        creds.router['id'], creds.subnet['id'])
                 except lib_exc.NotFound:
                     LOG.warn('router with name: %s not found for delete' %
-                             router['name'])
-                self._clear_isolated_router(router['id'], router['name'])
+                             creds.router['name'])
+                self._clear_isolated_router(creds.router['id'],
+                                            creds.router['name'])
             if (not self.network_resources or
                 self.network_resources.get('subnet')):
-                self._clear_isolated_subnet(subnet['id'], subnet['name'])
+                self._clear_isolated_subnet(creds.subnet['id'],
+                                            creds.subnet['name'])
             if (not self.network_resources or
                 self.network_resources.get('network')):
-                self._clear_isolated_network(network['id'], network['name'])
-        self.isolated_net_resources = {}
+                self._clear_isolated_network(creds.network['id'],
+                                             creds.network['name'])
 
     def clear_isolated_creds(self):
         if not self.isolated_creds:
diff --git a/tempest/manager.py b/tempest/manager.py
index a256f25..025ce65 100644
--- a/tempest/manager.py
+++ b/tempest/manager.py
@@ -46,8 +46,14 @@
         # Check if passed or default credentials are valid
         if not self.credentials.is_valid():
             raise exceptions.InvalidCredentials()
+        # Tenant isolation creates TestResources, but Accounts and some tests
+        # creates Credentials
+        if isinstance(credentials, cred_provider.TestResources):
+            creds = self.credentials.credentials
+        else:
+            creds = self.credentials
         # Creates an auth provider for the credentials
-        self.auth_provider = get_auth_provider(self.credentials)
+        self.auth_provider = get_auth_provider(creds)
         # FIXME(andreaf) unused
         self.client_attr_names = []
 
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index ce640b1..eb2276a 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -186,7 +186,8 @@
         if create_kwargs is None:
             create_kwargs = {}
         network = self.get_tenant_network()
-        fixed_network.set_networks_kwarg(network, create_kwargs)
+        create_kwargs = fixed_network.set_networks_kwarg(network,
+                                                         create_kwargs)
 
         LOG.debug("Creating a server (name: %s, image: %s, flavor: %s)",
                   name, image, flavor)
diff --git a/tempest/scenario/test_security_groups_basic_ops.py b/tempest/scenario/test_security_groups_basic_ops.py
index 4fab38b..1ecc212 100644
--- a/tempest/scenario/test_security_groups_basic_ops.py
+++ b/tempest/scenario/test_security_groups_basic_ops.py
@@ -125,6 +125,10 @@
         if CONF.baremetal.driver_enabled:
             msg = ('Not currently supported by baremetal.')
             raise cls.skipException(msg)
+        if CONF.network.port_vnic_type in ['direct', 'macvtap']:
+            msg = ('Not currently supported when using vnic_type'
+                   ' direct or macvtap')
+            raise cls.skipException(msg)
         if not (CONF.network.tenant_networks_reachable or
                 CONF.network.public_network_id):
             msg = ('Either tenant_networks_reachable must be "true", or '
diff --git a/tempest/tests/test_tenant_isolation.py b/tempest/tests/test_tenant_isolation.py
index 82cbde9..fd8718f 100644
--- a/tempest/tests/test_tenant_isolation.py
+++ b/tempest/tests/test_tenant_isolation.py
@@ -278,11 +278,11 @@
         router_interface_mock = self.patch(
             'tempest.services.network.json.network_client.NetworkClientJSON.'
             'add_router_interface_with_subnet_id')
-        iso_creds.get_primary_creds()
+        primary_creds = iso_creds.get_primary_creds()
         router_interface_mock.called_once_with('1234', '1234')
-        network = iso_creds.get_primary_network()
-        subnet = iso_creds.get_primary_subnet()
-        router = iso_creds.get_primary_router()
+        network = primary_creds.network
+        subnet = primary_creds.subnet
+        router = primary_creds.router
         self.assertEqual(network['id'], '1234')
         self.assertEqual(network['name'], 'fake_net')
         self.assertEqual(subnet['id'], '1234')
@@ -427,11 +427,11 @@
         router_interface_mock = self.patch(
             'tempest.services.network.json.network_client.NetworkClientJSON.'
             'add_router_interface_with_subnet_id')
-        iso_creds.get_alt_creds()
+        alt_creds = iso_creds.get_alt_creds()
         router_interface_mock.called_once_with('1234', '1234')
-        network = iso_creds.get_alt_network()
-        subnet = iso_creds.get_alt_subnet()
-        router = iso_creds.get_alt_router()
+        network = alt_creds.network
+        subnet = alt_creds.subnet
+        router = alt_creds.router
         self.assertEqual(network['id'], '1234')
         self.assertEqual(network['name'], 'fake_alt_net')
         self.assertEqual(subnet['id'], '1234')
@@ -453,11 +453,11 @@
             'tempest.services.network.json.network_client.NetworkClientJSON.'
             'add_router_interface_with_subnet_id')
         self._mock_list_roles('123456', 'admin')
-        iso_creds.get_admin_creds()
+        admin_creds = iso_creds.get_admin_creds()
         router_interface_mock.called_once_with('1234', '1234')
-        network = iso_creds.get_admin_network()
-        subnet = iso_creds.get_admin_subnet()
-        router = iso_creds.get_admin_router()
+        network = admin_creds.network
+        subnet = admin_creds.subnet
+        router = admin_creds.router
         self.assertEqual(network['id'], '1234')
         self.assertEqual(network['name'], 'fake_admin_net')
         self.assertEqual(subnet['id'], '1234')
@@ -490,13 +490,13 @@
                                    'delete_router')
         router_mock = router.start()
 
-        iso_creds.get_primary_creds()
+        primary_creds = iso_creds.get_primary_creds()
         self.assertEqual(net_mock.mock_calls, [])
         self.assertEqual(subnet_mock.mock_calls, [])
         self.assertEqual(router_mock.mock_calls, [])
-        network = iso_creds.get_primary_network()
-        subnet = iso_creds.get_primary_subnet()
-        router = iso_creds.get_primary_router()
+        network = primary_creds.network
+        subnet = primary_creds.subnet
+        router = primary_creds.router
         self.assertIsNone(network)
         self.assertIsNone(subnet)
         self.assertIsNone(router)