Merge "[trivial] fix legacy driver reference"
diff --git a/doc/source/usage.rst b/doc/source/usage.rst
index 27b5ebe..ecb7218 100644
--- a/doc/source/usage.rst
+++ b/doc/source/usage.rst
@@ -9,14 +9,14 @@
 
 .. code-block:: ini
 
-    [service_enabled]
+    [service_available]
     ironic = True
 
 If introspection tests are needed, also enable support for ironic-inspector:
 
 .. code-block:: ini
 
-    [service_enabled]
+    [service_available]
     ironic_inspector = True
 
 See the following example configurations for more details:
diff --git a/ironic_tempest_plugin/config.py b/ironic_tempest_plugin/config.py
index 5fc9333..95b29b3 100644
--- a/ironic_tempest_plugin/config.py
+++ b/ironic_tempest_plugin/config.py
@@ -52,9 +52,8 @@
     cfg.StrOpt('catalog_type',
                default='baremetal',
                help="Catalog type of the baremetal provisioning service"),
-    # TODO(dtantsur): change to fake-hardware when Ocata is no longer supported
     cfg.StrOpt('driver',
-               default='fake',
+               default='fake-hardware',
                help="Driver name to use for API tests"),
     cfg.StrOpt('endpoint_type',
                default='publicURL',
diff --git a/ironic_tempest_plugin/tests/scenario/baremetal_standalone_manager.py b/ironic_tempest_plugin/tests/scenario/baremetal_standalone_manager.py
index 9948ca8..4f8bfe8 100644
--- a/ironic_tempest_plugin/tests/scenario/baremetal_standalone_manager.py
+++ b/ironic_tempest_plugin/tests/scenario/baremetal_standalone_manager.py
@@ -602,6 +602,14 @@
         # So we only move the node to active (verifying deployment).
         self.set_node_to_active()
 
+    def remove_root_device_hint(self):
+        patch = [{'path': '/properties/root_device',
+                  'op': 'remove'}]
+        self.update_node(self.node['uuid'], patch=patch)
+
+    def remove_raid_configuration(self):
+        self.baremetal_client.set_node_raid_config(self.node['uuid'], {})
+
     def rescue_unrescue(self):
         rescue_password = uuidutils.generate_uuid()
         self.rescue_node(self.node['uuid'], rescue_password)
diff --git a/ironic_tempest_plugin/tests/scenario/ironic_standalone/test_basic_ops.py b/ironic_tempest_plugin/tests/scenario/ironic_standalone/test_basic_ops.py
index 0f91b01..ea6f62d 100644
--- a/ironic_tempest_plugin/tests/scenario/ironic_standalone/test_basic_ops.py
+++ b/ironic_tempest_plugin/tests/scenario/ironic_standalone/test_basic_ops.py
@@ -324,3 +324,54 @@
     @utils.services('image', 'network')
     def test_ip_access_to_server(self):
         self.boot_and_verify_node()
+
+
+class BaremetalIloIPxeWholediskHttpLink(
+        bsm.BaremetalStandaloneScenarioTest):
+
+    api_microversion = '1.31'  # to set the deploy_interface
+    driver = 'ilo'
+    deploy_interface = 'direct'
+    boot_interface = 'ilo-ipxe'
+    image_ref = CONF.baremetal.whole_disk_image_url
+    image_checksum = CONF.baremetal.whole_disk_image_checksum
+    wholedisk_image = True
+
+    @decorators.idempotent_id('d926c683-1a32-edbc-07dc-95cd74eefecb')
+    @utils.services('network')
+    def test_ip_access_to_server(self):
+        self.boot_and_verify_node()
+
+
+class BaremetalRedfishDirectWholediskHttpLink(
+        bsm.BaremetalStandaloneScenarioTest):
+
+    api_microversion = '1.31'  # to set the deploy_interface
+    driver = 'redfish'
+    deploy_interface = 'direct'
+    boot_interface = 'redfish-virtual-media'
+    image_ref = CONF.baremetal.whole_disk_image_url
+    image_checksum = CONF.baremetal.whole_disk_image_checksum
+    wholedisk_image = True
+
+    @decorators.idempotent_id('113acd0a-9872-4631-b3ee-54da7e3bb262')
+    @utils.services('network')
+    def test_ip_access_to_server(self):
+        self.boot_and_verify_node()
+
+
+class BaremetalRedfishIPxeWholediskHttpLink(
+        bsm.BaremetalStandaloneScenarioTest):
+
+    api_microversion = '1.31'  # to set the deploy_interface
+    driver = 'redfish'
+    deploy_interface = 'direct'
+    boot_interface = 'ipxe'
+    image_ref = CONF.baremetal.whole_disk_image_url
+    image_checksum = CONF.baremetal.whole_disk_image_checksum
+    wholedisk_image = True
+
+    @decorators.idempotent_id('113acd0a-9872-4631-b3ee-54da7e3bb262')
+    @utils.services('network')
+    def test_ip_access_to_server(self):
+        self.boot_and_verify_node()
diff --git a/ironic_tempest_plugin/tests/scenario/ironic_standalone/test_cleaning.py b/ironic_tempest_plugin/tests/scenario/ironic_standalone/test_cleaning.py
index eb0d4d2..10b6663 100644
--- a/ironic_tempest_plugin/tests/scenario/ironic_standalone/test_cleaning.py
+++ b/ironic_tempest_plugin/tests/scenario/ironic_standalone/test_cleaning.py
@@ -85,6 +85,8 @@
     deploy_interface = 'iscsi'
     raid_interface = 'agent'
     api_microversion = '1.31'
+    # Software RAID is always local boot
+    boot_option = 'local'
 
     raid_config = {
         "logical_disks": [
@@ -106,6 +108,15 @@
     @utils.services('image', 'network')
     def test_software_raid(self):
         self.build_raid_and_verify_node()
+        # NOTE(TheJulia): tearing down/terminating the instance does not
+        # remove the root device hint, so it is best for us to go ahead
+        # and remove it before exiting the test.
+        self.remove_root_device_hint()
+        # Removes RAID configuration
+        # TODO(TheJulia): We _should_ tear the raid configuration down
+        # however bouncing neutron ports with known DHCP reload bugs
+        # is not a super great idea for tempest tests.
+        self.remove_raid_configuration()
 
 
 class SoftwareRaidDirect(bsm.BaremetalStandaloneScenarioTest):
@@ -116,6 +127,8 @@
     deploy_interface = 'direct'
     raid_interface = 'agent'
     api_microversion = '1.31'
+    # Software RAID is always local boot
+    boot_option = 'local'
 
     # TODO(dtantsur): more complex layout in this job
     raid_config = {
@@ -138,3 +151,12 @@
     @utils.services('image', 'network')
     def test_software_raid(self):
         self.build_raid_and_verify_node()
+        # NOTE(TheJulia): tearing down/terminating the instance does not
+        # remove the root device hint, so it is best for us to go ahead
+        # and remove it before exiting the test.
+        self.remove_root_device_hint()
+        # Removes RAID configuration
+        # TODO(TheJulia): We _should_ tear the raid configuration down
+        # however bouncing neutron ports with known DHCP reload bugs
+        # is not a super great idea for tempest tests.
+        self.remove_raid_configuration()
diff --git a/ironic_tempest_plugin/tests/scenario/test_baremetal_basic_ops.py b/ironic_tempest_plugin/tests/scenario/test_baremetal_basic_ops.py
index c515293..cc6b0dd 100644
--- a/ironic_tempest_plugin/tests/scenario/test_baremetal_basic_ops.py
+++ b/ironic_tempest_plugin/tests/scenario/test_baremetal_basic_ops.py
@@ -133,16 +133,7 @@
 
     def validate_ports(self):
         node_uuid = self.node['uuid']
-        vifs = []
-        # TODO(vsaienko) switch to get_node_vifs() when all stable releases
-        # supports Ironic API 1.28
-        if self._is_version_supported('1.28'):
-            vifs = self.get_node_vifs(node_uuid)
-        else:
-            for port in self.get_ports(self.node['uuid']):
-                vif = port['extra'].get('vif_port_id')
-                if vif:
-                    vifs.append({'id': vif})
+        vifs = self.get_node_vifs(node_uuid)
 
         ir_ports = self.get_ports(node_uuid)
         ir_ports_addresses = [x['address'] for x in ir_ports]
@@ -160,21 +151,8 @@
         those set on the node. Does not assume that resource classes and traits
         are in use.
         """
-        # Try to get a node with resource class (1.21) and traits (1.37).
-        # TODO(mgoddard): Remove this when all stable releases support these
-        # API versions.
-        for version in ('1.37', '1.21'):
-            if self._is_version_supported(version):
-                node = self.get_node(instance_id=self.instance['id'],
-                                     api_version=version)
-                break
-        else:
-            # Neither API is supported - cannot test.
-            LOG.warning("Cannot validate resource class and trait based "
-                        "scheduling as these require API version 1.21 and "
-                        "1.37 respectively")
-            return
-
+        node = self.get_node(instance_id=self.instance['id'],
+                             api_version='1.37')
         f_id = self.instance['flavor']['id']
         extra_specs = self.flavors_client.list_flavor_extra_specs(f_id)
         extra_specs = extra_specs['extra_specs']
diff --git a/releasenotes/notes/drop-py-2-7-c81e7ff14950791b.yaml b/releasenotes/notes/drop-py-2-7-c81e7ff14950791b.yaml
new file mode 100644
index 0000000..c9401c4
--- /dev/null
+++ b/releasenotes/notes/drop-py-2-7-c81e7ff14950791b.yaml
@@ -0,0 +1,6 @@
+---
+upgrade:
+  - |
+    Python 2.7 support has been dropped. Last release of ironic-tempest-plugin
+    to support py2.7 is OpenStack Train. The minimum version of Python now
+    supported by ironic-tempest-plugin is Python 3.6.
diff --git a/setup.cfg b/setup.cfg
index 53ca735..241739d 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -13,10 +13,9 @@
     License :: OSI Approved :: Apache Software License
     Operating System :: POSIX :: Linux
     Programming Language :: Python
-    Programming Language :: Python :: 2
-    Programming Language :: Python :: 2.7
     Programming Language :: Python :: 3
-    Programming Language :: Python :: 3.5
+    Programming Language :: Python :: 3.6
+    Programming Language :: Python :: 3.7
 
 [files]
 packages =
diff --git a/test-requirements.txt b/test-requirements.txt
index fb97fc6..9292937 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -4,8 +4,7 @@
 
 hacking!=0.13.0,<0.14,>=0.12.0 # Apache-2.0
 
-sphinx!=1.6.6,!=1.6.7,>=1.6.2,<2.0.0;python_version=='2.7' # BSD
-sphinx!=1.6.6,!=1.6.7,>=1.6.2;python_version>='3.4' # BSD
+sphinx!=1.6.6,!=1.6.7,>=1.6.2 # BSD
 openstackdocstheme>=1.20.0 # Apache-2.0
 
 reno>=2.5.0 # Apache-2.0
diff --git a/tox.ini b/tox.ini
index 410337a..60be8ec 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,10 +1,11 @@
 [tox]
 minversion = 3.1.0
-envlist = py3,py27,pep8
+envlist = py3,pep8
 skipsdist = True
 ignore_basepython_conflict=true
 
 [testenv]
+basepython = python3
 usedevelop = True
 install_command = pip install {opts} {packages}
 setenv =
@@ -15,29 +16,23 @@
 commands = python setup.py test --slowest --testr-args='{posargs}'
 
 [testenv:pep8]
-basepython = python3
 commands = flake8 {posargs}
 
 [testenv:venv]
-basepython = python3
 commands = {posargs}
 
 [testenv:cover]
-basepython = python3
 commands = python setup.py test --coverage --testr-args='{posargs}'
 
 [testenv:docs]
-basepython = python3
 commands = python setup.py build_sphinx
 
 [testenv:pdf-docs]
-basepython = python3
 whitelist_externals = make
 commands = sphinx-build -b latex doc/source doc/build/pdf
            make -C doc/build/pdf
 
 [testenv:debug]
-basepython = python3
 commands = oslo_debug_helper {posargs}
 
 [flake8]
diff --git a/zuul.d/project.yaml b/zuul.d/project.yaml
index ffb57a5..a579a12 100644
--- a/zuul.d/project.yaml
+++ b/zuul.d/project.yaml
@@ -9,22 +9,12 @@
         - ironic-standalone
         - ironic-standalone-train
         - ironic-standalone-stein
-        - ironic-dsvm-standalone-rocky:
-            voting: false
-        - ironic-dsvm-standalone-queens:
-            voting: false
         - ironic-tempest-functional-python3
         - ironic-tempest-functional-python3-train
         - ironic-tempest-functional-python3-stein
-        - ironic-tempest-dsvm-functional-python3-rocky:
-            voting: false
         - ironic-inspector-tempest
         - ironic-inspector-tempest-train
         - ironic-inspector-tempest-stein
-        - ironic-tempest-dsvm-ironic-inspector-rocky:
-            voting: false
-        - ironic-tempest-dsvm-ironic-inspector-queens:
-            voting: false
         # NOTE(dtantsur): these jobs cover rarely changed tests and are quite
         # unstable, so keep them non-voting.
         - ironic-tempest-ipa-wholedisk-direct-tinyipa-multinode:
@@ -33,19 +23,11 @@
             voting: false
         - ironic-tempest-ipa-wholedisk-direct-tinyipa-multinode-stein:
             voting: false
-        - ironic-tempest-dsvm-ipa-wholedisk-agent_ipmitool-tinyipa-multinode-rocky:
-            voting: false
-        - ironic-tempest-dsvm-ipa-wholedisk-agent_ipmitool-tinyipa-multinode-queens:
-            voting: false
         - ironic-inspector-tempest-discovery
         - ironic-inspector-tempest-discovery-train:
             voting: false
         - ironic-inspector-tempest-discovery-stein:
             voting: false
-        - ironic-inspector-tempest-dsvm-discovery-rocky:
-            voting: false
-        - ironic-inspector-tempest-dsvm-discovery-queens:
-            voting: false
     gate:
       queue: ironic
       jobs:
diff --git a/zuul.d/stable-jobs.yaml b/zuul.d/stable-jobs.yaml
index bfb6706..ec95d55 100644
--- a/zuul.d/stable-jobs.yaml
+++ b/zuul.d/stable-jobs.yaml
@@ -1,187 +1,78 @@
 - job:
     name: ironic-standalone-train
     parent: ironic-standalone
-    override-branch: stable/train
+    override-checkout: stable/train
     vars:
       devstack_localrc:
-        USE_PYTHON3: False
+        USE_PYTHON3: True
 
 - job:
     name: ironic-standalone-stein
     parent: ironic-standalone
-    override-branch: stable/stein
+    override-checkout: stable/stein
     vars:
       devstack_localrc:
-        USE_PYTHON3: False
-
-- job:
-    name: ironic-dsvm-standalone-rocky
-    parent: ironic-standalone
-    override-branch: stable/rocky
-    nodeset: openstack-single-node-xenial
-    vars:
-      devstack_localrc:
-        USE_PYTHON3: False
-
-- job:
-    name: ironic-dsvm-standalone-queens
-    parent: ironic-standalone
-    override-branch: stable/queens
-    nodeset: openstack-single-node-xenial
-    vars:
-      devstack_localrc:
-        FIXED_NETWORK_SIZE: 4096
-        EBTABLES_RACE_FIX: True
-        IRONIC_USE_MOD_WSGI: True
-        USE_PYTHON3: False
+        USE_PYTHON3: True
 
 - job:
     name: ironic-tempest-functional-python3-train
     parent: ironic-tempest-functional-python3
-    override-branch: stable/train
+    override-checkout: stable/train
 
 - job:
     name: ironic-tempest-functional-python3-stein
     parent: ironic-tempest-functional-python3
-    override-branch: stable/stein
+    override-checkout: stable/stein
 
-- job:
-    name: ironic-tempest-dsvm-functional-python3-rocky
-    parent: ironic-tempest-functional-python3
-    override-branch: stable/rocky
-    nodeset: openstack-single-node-xenial
-    vars:
-      devstack_localrc:
-        IRONIC_RPC_TRANSPORT: ""
-      devstack_services:
-        rabbit: True
 
 - job:
     name: ironic-tempest-ipa-wholedisk-direct-tinyipa-multinode-train
     parent: ironic-tempest-ipa-wholedisk-direct-tinyipa-multinode
-    override-branch: stable/train
+    override-checkout: stable/train
     vars:
       devstack_localrc:
-        USE_PYTHON3: False
+        USE_PYTHON3: True
 
 - job:
     name: ironic-tempest-ipa-wholedisk-direct-tinyipa-multinode-stein
     parent: ironic-tempest-ipa-wholedisk-direct-tinyipa-multinode
-    override-branch: stable/stein
+    override-checkout: stable/stein
     vars:
       devstack_localrc:
-        USE_PYTHON3: False
-
-- job:
-    name: ironic-tempest-dsvm-ipa-wholedisk-agent_ipmitool-tinyipa-multinode-rocky
-    parent: ironic-tempest-ipa-wholedisk-direct-tinyipa-multinode
-    override-branch: stable/rocky
-    nodeset: openstack-two-node-xenial
-    vars:
-      devstack_localrc:
-        IRONIC_DEFAULT_BOOT_OPTION: netboot
-        FIXED_NETWORK_SIZE: 4096
-        IRONIC_DEFAULT_RESCUE_INTERFACE: agent
-        EBTABLES_RACE_FIX: True
-        PUBLIC_BRIDGE: br_ironic_vxlan
-        OVS_BRIDGE_MAPPINGS: 'mynetwork:brbm,public:br_ironic_vxlan'
-        USE_PYTHON3: False
-    group-vars:
-      subnode:
-        devstack_localrc:
-          OVS_BRIDGE_MAPPINGS: 'mynetwork:sub1brbm,public:br_ironic_vxlan'
-
-- job:
-    name: ironic-tempest-dsvm-ipa-wholedisk-agent_ipmitool-tinyipa-multinode-queens
-    parent: ironic-tempest-ipa-wholedisk-direct-tinyipa-multinode
-    override-branch: stable/queens
-    nodeset: openstack-two-node-xenial
-    vars:
-      devstack_localrc:
-        IRONIC_DEFAULT_BOOT_OPTION: netboot
-        FIXED_NETWORK_SIZE: 4096
-        IRONIC_DEFAULT_RESCUE_INTERFACE: agent
-        EBTABLES_RACE_FIX: True
-        PUBLIC_BRIDGE: br_ironic_vxlan
-        OVS_BRIDGE_MAPPINGS: 'mynetwork:brbm,public:br_ironic_vxlan'
-        USE_PYTHON3: False
-    group-vars:
-      subnode:
-        devstack_localrc:
-          OVS_BRIDGE_MAPPINGS: 'mynetwork:sub1brbm,public:br_ironic_vxlan'
+        USE_PYTHON3: True
 
 - job:
     name: ironic-inspector-tempest-train
     parent: ironic-inspector-tempest
-    override-branch: stable/train
+    override-checkout: stable/train
     vars:
       devstack_localrc:
         FIXED_NETWORK_SIZE: 4096
         EBTABLES_RACE_FIX: True
-        USE_PYTHON3: False
+        USE_PYTHON3: True
 
 - job:
     name: ironic-inspector-tempest-stein
     parent: ironic-inspector-tempest
-    override-branch: stable/stein
+    override-checkout: stable/stein
     vars:
       devstack_localrc:
         FIXED_NETWORK_SIZE: 4096
         EBTABLES_RACE_FIX: True
-        USE_PYTHON3: False
-
-- job:
-    name: ironic-tempest-dsvm-ironic-inspector-rocky
-    parent: ironic-inspector-tempest
-    override-branch: stable/rocky
-    nodeset: openstack-single-node-xenial
-    vars:
-      devstack_localrc:
-        FIXED_NETWORK_SIZE: 4096
-        EBTABLES_RACE_FIX: True
-        USE_PYTHON3: False
-
-- job:
-    name: ironic-tempest-dsvm-ironic-inspector-queens
-    parent: ironic-inspector-tempest
-    override-branch: stable/queens
-    nodeset: openstack-single-node-xenial
-    vars:
-      devstack_localrc:
-        FIXED_NETWORK_SIZE: 4096
-        EBTABLES_RACE_FIX: True
-        USE_PYTHON3: False
+        USE_PYTHON3: True
 
 - job:
     name: ironic-inspector-tempest-discovery-train
     parent: ironic-inspector-tempest-discovery
-    override-branch: stable/train
+    override-checkout: stable/train
     vars:
       devstack_localrc:
-        USE_PYTHON3: False
+        USE_PYTHON3: True
 
 - job:
     name: ironic-inspector-tempest-discovery-stein
     parent: ironic-inspector-tempest-discovery
-    override-branch: stable/stein
+    override-checkout: stable/stein
     vars:
       devstack_localrc:
-        USE_PYTHON3: False
-
-- job:
-    name: ironic-inspector-tempest-dsvm-discovery-rocky
-    parent: ironic-inspector-tempest-discovery
-    override-branch: stable/rocky
-    nodeset: openstack-single-node-xenial
-    vars:
-      devstack_localrc:
-        USE_PYTHON3: False
-
-- job:
-    name: ironic-inspector-tempest-dsvm-discovery-queens
-    parent: ironic-inspector-tempest-discovery
-    override-branch: stable/queens
-    nodeset: openstack-single-node-xenial
-    vars:
-      devstack_localrc:
-        USE_PYTHON3: False
+        USE_PYTHON3: True