Merge "Ramdisk iso boot tempest scenario test"
diff --git a/ironic_tempest_plugin/config.py b/ironic_tempest_plugin/config.py
index 44dcbe4..7354ef7 100644
--- a/ironic_tempest_plugin/config.py
+++ b/ironic_tempest_plugin/config.py
@@ -153,6 +153,10 @@
                      "being used, this option should be set to True as "
                      "it lacks the needed components to make it locally "
                      "from a partition image."),
+    cfg.StrOpt('boot_mode',
+               default='bios',
+               choices=['bios', 'uefi'],
+               help="The desired boot_mode to be used on testing nodes."),
 ]
 
 BaremetalFeaturesGroup = [
@@ -169,6 +173,10 @@
                 help="Defines if software RAID is enabled (available "
                      "starting with Train). Requires at least two disks "
                      "on testing nodes."),
+    cfg.BoolOpt('deploy_time_raid',
+                default=False,
+                help="Defines if in-band RAID can be built in deploy time "
+                     "(possible starting with Victoria)."),
 ]
 
 BaremetalIntrospectionGroup = [
diff --git a/ironic_tempest_plugin/tests/scenario/baremetal_standalone_manager.py b/ironic_tempest_plugin/tests/scenario/baremetal_standalone_manager.py
index da16252..6b9d9e3 100644
--- a/ironic_tempest_plugin/tests/scenario/baremetal_standalone_manager.py
+++ b/ironic_tempest_plugin/tests/scenario/baremetal_standalone_manager.py
@@ -216,8 +216,9 @@
                 return False
             return True
 
-        if (not test_utils.call_until_true(_try_to_associate_instance,
-            duration=CONF.baremetal.association_timeout, sleep_for=1)):
+        if (not test_utils.call_until_true(
+                _try_to_associate_instance,
+                duration=CONF.baremetal.association_timeout, sleep_for=1)):
             msg = ('Timed out waiting to associate instance to ironic node '
                    'uuid %s' % instance_uuid)
             raise lib_exc.TimeoutException(msg)
@@ -571,32 +572,53 @@
         self.assertTrue(self.ping_ip_address(self.node_ip,
                                              should_succeed=should_succeed))
 
-    def build_raid_and_verify_node(self, config=None, clean_steps=None):
+    def build_raid_and_verify_node(self, config=None, deploy_time=False):
         config = config or self.raid_config
-        clean_steps = clean_steps or [
-            {
-                "interface": "raid",
-                "step": "delete_configuration"
-            },
-            # NOTE(dtantsur): software RAID building fails if any
-            # partitions exist on holder devices.
-            {
-                "interface": "deploy",
-                "step": "erase_devices_metadata"
-            },
-            {
-                "interface": "raid",
-                "step": "create_configuration"
-            }
-        ]
-
-        self.baremetal_client.set_node_raid_config(self.node['uuid'], config)
-        self.manual_cleaning(self.node, clean_steps=clean_steps)
+        if deploy_time:
+            steps = [
+                {
+                    "interface": "deploy",
+                    "step": "erase_devices_metadata",
+                    "priority": 98,
+                    "args": {},
+                },
+                {
+                    "interface": "raid",
+                    "step": "apply_configuration",
+                    "priority": 97,
+                    "args": {"raid_config": config},
+                }
+            ]
+            self.baremetal_client.create_deploy_template(
+                'CUSTOM_RAID', steps=steps)
+            self.baremetal_client.add_node_trait(self.node['uuid'],
+                                                 'CUSTOM_RAID')
+        else:
+            steps = [
+                {
+                    "interface": "raid",
+                    "step": "delete_configuration"
+                },
+                {
+                    "interface": "deploy",
+                    "step": "erase_devices_metadata",
+                },
+                {
+                    "interface": "raid",
+                    "step": "create_configuration",
+                }
+            ]
+            self.baremetal_client.set_node_raid_config(self.node['uuid'],
+                                                       config)
+            self.manual_cleaning(self.node, clean_steps=steps)
 
         # NOTE(dtantsur): this is not required, but it allows us to check that
         # the RAID device was in fact created and is used for deployment.
         patch = [{'path': '/properties/root_device',
                   'op': 'add', 'value': {'name': '/dev/md0'}}]
+        if deploy_time:
+            patch.append({'path': '/instance_info/traits',
+                          'op': 'add', 'value': ['CUSTOM_RAID']})
         self.update_node(self.node['uuid'], patch=patch)
         # NOTE(dtantsur): apparently cirros cannot boot from md devices :(
         # So we only move the node to active (verifying deployment).
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 c068fbe..47e5f63 100644
--- a/ironic_tempest_plugin/tests/scenario/ironic_standalone/test_cleaning.py
+++ b/ironic_tempest_plugin/tests/scenario/ironic_standalone/test_cleaning.py
@@ -87,7 +87,7 @@
     wholedisk_image = True
     deploy_interface = 'iscsi'
     raid_interface = 'agent'
-    api_microversion = '1.31'
+    api_microversion = '1.55'
     # Software RAID is always local boot
     boot_option = 'local'
 
@@ -112,7 +112,8 @@
     @decorators.idempotent_id('7ecba4f7-98b8-4ea1-b95e-3ec399f46798')
     @utils.services('image', 'network')
     def test_software_raid(self):
-        self.build_raid_and_verify_node()
+        self.build_raid_and_verify_node(
+            deploy_time=CONF.baremetal_feature_enabled.deploy_time_raid)
         # 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.
@@ -134,7 +135,7 @@
     wholedisk_image = True
     deploy_interface = 'direct'
     raid_interface = 'agent'
-    api_microversion = '1.31'
+    api_microversion = '1.55'
     # Software RAID is always local boot
     boot_option = 'local'
 
@@ -160,7 +161,8 @@
     @decorators.idempotent_id('125361ac-0eb3-4d79-8be2-a91936aa3f46')
     @utils.services('image', 'network')
     def test_software_raid(self):
-        self.build_raid_and_verify_node()
+        self.build_raid_and_verify_node(
+            deploy_time=CONF.baremetal_feature_enabled.deploy_time_raid)
         # 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.
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 cc6b0dd..e3c1929 100644
--- a/ironic_tempest_plugin/tests/scenario/test_baremetal_basic_ops.py
+++ b/ironic_tempest_plugin/tests/scenario/test_baremetal_basic_ops.py
@@ -45,7 +45,11 @@
           expected state transitions
     """
 
+    credentials = ['primary', 'admin']
+
     TEST_RESCUE_MODE = False
+    image_ref = None
+    wholedisk_image = None
 
     @classmethod
     def skip_checks(cls):
@@ -183,9 +187,15 @@
             # Flavor traits should be a subset of node traits.
             self.assertTrue(traits.issubset(set(node['traits'])))
 
-    @decorators.idempotent_id('549173a5-38ec-42bb-b0e2-c8b9f4a08943')
-    @utils.services('compute', 'image', 'network')
-    def test_baremetal_server_ops(self):
+    def validate_uefi(self, client):
+        efi_dir = '/sys/firmware/efi'
+        success_string = "Found " + efi_dir
+        cmd = 'test -d {dir} && echo "Found {dir}" ||'\
+              ' echo "{dir} not found"'.format(dir=efi_dir)
+        output = client.exec_command(cmd).rstrip()
+        self.assertEqual(success_string, output)
+
+    def baremetal_server_ops(self):
         self.add_keypair()
         self.instance, self.node = self.boot_instance()
         self.validate_ports()
@@ -202,6 +212,9 @@
             self.create_timestamp(
                 ip_address, private_key=self.keypair['private_key'])
 
+        if CONF.baremetal.boot_mode == "uefi":
+            self.validate_uefi(vm_client)
+
         # Test rescue mode
         if self.TEST_RESCUE_MODE:
             self.rescue_instance(self.instance, self.node, ip_address)
@@ -209,6 +222,20 @@
 
         self.terminate_instance(self.instance)
 
+    @decorators.idempotent_id('549173a5-38ec-42bb-b0e2-c8b9f4a08943')
+    @utils.services('compute', 'image', 'network')
+    def test_baremetal_server_ops_partition_image(self):
+        self.image_ref = CONF.baremetal.partition_image_ref
+        self.wholedisk_image = False
+        self.baremetal_server_ops()
+
+    @decorators.idempotent_id('d7d48aa1-0395-4f31-a908-60969adc4322')
+    @utils.services('compute', 'image', 'network')
+    def test_baremetal_server_ops_wholedisk_image(self):
+        self.image_ref = CONF.baremetal.whole_disk_image_ref
+        self.wholedisk_image = True
+        self.baremetal_server_ops()
+
 
 class BaremetalBasicOpsAndRescue(BaremetalBasicOps):
     """This test includes rescue/unrescue ops."""
diff --git a/test-requirements.txt b/test-requirements.txt
index 7e4adb2..138ad35 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -2,7 +2,7 @@
 # of appearance. Changing the order has an impact on the overall integration
 # process, which may cause wedges in the gate later.
 
-hacking>=3.0.0,<3.1.0 # Apache-2.0
+hacking>=3.0.1,<3.1.0 # Apache-2.0
 
 stestr>=1.0.0 # Apache-2.0
 coverage!=4.4,>=4.0 # Apache-2.0
diff --git a/tox.ini b/tox.ini
index 28ac9e7..ac55994 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
 [tox]
-minversion = 3.1.0
+minversion = 3.2.1
 envlist = pep8
 skipsdist = True
 ignore_basepython_conflict=true
@@ -45,9 +45,8 @@
 commands = oslo_debug_helper {posargs}
 
 [flake8]
-# [E129] Visually indented line with same indent as next logical line.
 # [W503] Line break occurred before a binary operator. Conflicts with W504.
-ignore = E129,W503
+ignore = W503
 show-source = True
 builtins = _
 exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,build
diff --git a/zuul.d/project.yaml b/zuul.d/project.yaml
index b402cc1..b3cd832 100644
--- a/zuul.d/project.yaml
+++ b/zuul.d/project.yaml
@@ -21,16 +21,15 @@
         - ironic-inspector-tempest-train
         - ironic-inspector-tempest-stein:
             voting: false
-        # NOTE(dtantsur): these jobs cover rarely changed tests and are quite
-        # unstable, so keep them non-voting.
-        - ironic-standalone-redfish:
-            voting: false
+        - ironic-standalone-redfish
         - ironic-standalone-redfish-ussuri:
             voting: false
         - ironic-standalone-redfish-train:
             voting: false
         - ironic-standalone-redfish-stein:
             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:
             voting: false
         - ironic-tempest-ipa-wholedisk-direct-tinyipa-multinode-ussuri:
@@ -58,4 +57,5 @@
         - ironic-inspector-tempest
         - ironic-inspector-tempest-ussuri
         - ironic-inspector-tempest-train
+        - ironic-standalone-redfish
         - ironic-inspector-tempest-discovery