From 766ff042bd8528043947f16c84d13c9645d258d1 Mon Sep 17 00:00:00 2001
From: jamepark4 <jparker@redhat.com>
Date: Fri, 16 Feb 2024 10:42:29 -0500
Subject: [PATCH] Add vIOMMU device tests

Adds tests to verify [1] which allows operators to add vIOMMU devices to
their guests via flavor configuration. Tests do a basic smoke test that
creates a guest with the vIOMMU flavor requirements and confirms to
relevant XML element is present on the domain. Test also resizes a
standard guest to a flavor with vIOMMU, and confirms to XML is present.
Then revert and confirm the element is no longer present.

[1] https://blueprints.launchpad.net/nova/+spec/libvirt-viommu-device
Change-Id: I92c3538f985f0db0ef24ce2c49a797d3fcb69252
---
 .../api/compute/test_viommu_devices.py        | 79 +++++++++++++++++++
 whitebox_tempest_plugin/config.py             |  5 ++
 2 files changed, 84 insertions(+)
 create mode 100644 whitebox_tempest_plugin/api/compute/test_viommu_devices.py

diff --git a/whitebox_tempest_plugin/api/compute/test_viommu_devices.py b/whitebox_tempest_plugin/api/compute/test_viommu_devices.py
new file mode 100644
index 00000000..3839a5c2
--- /dev/null
+++ b/whitebox_tempest_plugin/api/compute/test_viommu_devices.py
@@ -0,0 +1,79 @@
+# Copyright 2024 Red Hat
+# 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 import config
+import testtools
+from whitebox_tempest_plugin.api.compute import base
+
+CONF = config.CONF
+
+
+class ViommuTestQ35ViaImage(base.BaseWhiteboxComputeTest):
+    """Test the creation of guests with attached Virtual IOMMU intel devices.
+    Q35 is is configured via adding the parameter to the guest image.
+    """
+    min_microversion = '2.93'
+
+    def setUp(self):
+        super(ViommuTestQ35ViaImage, self).setUp()
+        self.viommu_intel_flavor = self.create_flavor(
+            extra_specs={"hw:viommu_model": 'intel'})
+        self.q35_image_id = self.copy_default_image(hw_machine_type='q35')
+
+    def _get_iommu_xml_element(self, server):
+        root = self.get_server_xml(server['id'])
+        iommu = root.find(".devices/iommu[@model='intel']")
+        return iommu
+
+    def _assert_viommu_model(self, server):
+        iommu = self._get_iommu_xml_element(server)
+        self.assertTrue(
+            iommu, 'vIOMMU element is not present on %s' % server['id'])
+        intremap_status = iommu.find('driver').get('intremap')
+        self.assertEqual(
+            'on', intremap_status, "Expected intremap status to be 'on' but "
+            "instead found: %s" % intremap_status)
+
+    def _assert_viommu_not_present(self, server):
+        iommu = self._get_iommu_xml_element(server)
+        self.assertFalse(
+            iommu, 'vIOMMU element should no longer be present on %s'
+            % server['id'])
+
+    def test_deploy_intel_viommu_model_q35_via_image(self):
+        """Create a guest with viommu intel model and confirm it is present
+        """
+        server = self.create_test_server(
+            image_id=self.q35_image_id,
+            flavor=self.viommu_intel_flavor['id'],
+            wait_until='ACTIVE'
+        )
+        self._assert_viommu_model(server)
+
+    @testtools.skipUnless(CONF.compute_feature_enabled.resize,
+                          'Resize not available.')
+    def test_resize_intel_viommu_via_image(self):
+        """Resize guest to use viommu, confirm element is present, revert
+        and verify the element has been removed
+        """
+        server = self.create_test_server(
+            wait_until='ACTIVE',
+            image_id=self.q35_image_id)
+        self.resize_server(server['id'], self.viommu_intel_flavor['id'])
+
+        self._assert_viommu_model(server)
+        default_flavor = self.create_flavor()
+        self.resize_server(server['id'], default_flavor['id'])
+        self._assert_viommu_not_present(server)
diff --git a/whitebox_tempest_plugin/config.py b/whitebox_tempest_plugin/config.py
index 45f543b2..8394f415 100644
--- a/whitebox_tempest_plugin/config.py
+++ b/whitebox_tempest_plugin/config.py
@@ -129,6 +129,11 @@ general_opts = [
         'max_disk_devices_to_attach',
         default=None,
         help='Maximum number of disks allowed to attach to a singler server'),
+    cfg.StrOpt(
+        'libvirt_hw_machine_type',
+        default='pc',
+        choices=["pc", "q35"],
+        help='The machine type configured for the nova computes')
 ]
 
 nova_compute_group = cfg.OptGroup(