Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create a test for SRIOV Intel NIC's (New) #1293

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
Open
489 changes: 488 additions & 1 deletion providers/base/bin/virtualization.py

Large diffs are not rendered by default.

250 changes: 248 additions & 2 deletions providers/base/tests/test_virtualization.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.

import itertools
import unittest
from unittest import TestCase
from unittest.mock import patch, MagicMock
from unittest.mock import patch, MagicMock, mock_open

from virtualization import LXDTest_vm
from virtualization import LXDTest_vm, LXDTest_sriov, check_sriov_interfaces


class TestLXDTest_vm(TestCase):
Expand Down Expand Up @@ -217,3 +218,248 @@ def test_setup_failure(self):
setup_return = LXDTest_vm.setup(self_mock)

self.assertFalse(setup_return)


class TestLXDTest_sriov(TestCase):
@patch("virtualization.logging")
@patch("virtualization.RunCommand")
def test_run_command_no_stderr(self, run_command_mock, logging_mock):
task = run_command_mock()
task.returncode = 0
task.stdout = "abc"
task.stderr = None

command_result = LXDTest_sriov.run_command(
MagicMock(), "command", log_stderr=True
)

self.assertTrue(logging_mock.debug.called)
self.assertTrue(command_result)

@patch("virtualization.logging")
@patch("virtualization.RunCommand")
def test_run_command_no_log_stderr(self, run_command_mock, logging_mock):
task = run_command_mock()
task.returncode = 1
task.stdout = "abc"
task.stderr = None

command_result = LXDTest_sriov.run_command(
MagicMock(), "command", log_stderr=False
)

self.assertFalse(command_result)

@patch("virtualization.logging")
@patch("virtualization.RunCommand")
def test_run_command_error(self, run_command_mock, logging_mock):
task = run_command_mock()
task.returncode = 1
task.stdout = "abc"
task.stderr = "some error"

command_result = LXDTest_sriov.run_command(
MagicMock(), "command", log_stderr=True
)

self.assertTrue(logging_mock.error.called)
self.assertFalse(command_result)

@patch("virtualization.logging")
@patch("virtualization.RunCommand")
def test_run_command_ok(self, run_command_mock, logging_mock):
task = run_command_mock()
task.returncode = 0
task.stdout = "abc"
task.stderr = "some error"

command_result = LXDTest_sriov.run_command(
MagicMock(), "command", log_stderr=True
)

self.assertTrue(logging_mock.debug.called)
self.assertTrue(command_result)

@patch("virtualization.logging")
@patch("virtualization.RunCommand")
def test_run_command_ok_no_stdout(self, run_command_mock, logging_mock):
task = run_command_mock()
task.returncode = 0
task.stdout = ""
task.stderr = "some error"

command_result = LXDTest_sriov.run_command(
MagicMock(), "command", log_stderr=True
)

self.assertTrue(logging_mock.debug.called)
self.assertTrue(command_result)

@patch("virtualization.logging")
def test_cleanup(self, logging_mock):
self_mock = MagicMock()
LXDTest_sriov.cleanup(self_mock)

self.assertTrue(self_mock.run_command.called)

@patch("virtualization.logging")
def test_start_sriov_fail_setup(self, logging_mock):
self_mock = MagicMock()
self_mock.setup.return_value = False

start_result = LXDTest_sriov.start_sriov(self_mock)
self.assertFalse(start_result)

@patch("virtualization.logging")
def test_start_sriov_fail_init_no_img_alias(self, logging_mock):
self_mock = MagicMock()
self_mock.setup.return_value = True
self_mock.image_url = None
self_mock.template_url = None
self_mock.network_name = "sriov_network"
self_mock.test_type = "vm"
self_mock.name = "testbed"
self_mock.run_command.side_effect = [False]

start_result = LXDTest_sriov.start_sriov(self_mock)
self.assertFalse(start_result)

@patch("virtualization.logging")
def test_start_sriov_fail_start(self, logging_mock):
self_mock = MagicMock()
self_mock.setup.return_value = True
self_mock.image_url = "image url"
self_mock.template_url = "template url"
self_mock.network_name = "sriov_network"
self_mock.test_type = "vm"
self_mock.name = "testbed"
self_mock.run_command.side_effect = [True, False]

start_result = LXDTest_sriov.start_sriov(self_mock)
self.assertFalse(start_result)

@patch("virtualization.logging")
def test_start_sriov_fail_list(self, logging_mock):
self_mock = MagicMock()
self_mock.setup.return_value = True
self_mock.image_url = "image url"
self_mock.template_url = "template url"
self_mock.network_name = "sriov_network"
self_mock.test_type = "vm"
self_mock.name = "testbed"
self_mock.run_command.side_effect = [True, True, False]

start_result = LXDTest_sriov.start_sriov(self_mock)
self.assertFalse(start_result)

@patch("time.sleep")
@patch("virtualization.logging")
def test_start_sriov_fail_exec(self, logging_mock, time_sleep_mock):
self_mock = MagicMock()
self_mock.setup.return_value = False
self_mock.image_url = "image url"
self_mock.template_url = "template url"
self_mock.network_name = "sriov_network"
self_mock.test_type = "vm"
self_mock.name = "testbed"
self_mock.run_command.side_effect = itertools.chain(
[True, True, True], itertools.repeat(False)
)

start_result = LXDTest_sriov.start_sriov(self_mock)
self.assertFalse(start_result)

@patch("time.sleep")
@patch("virtualization.print")
@patch("virtualization.logging")
def test_start_sriov_success(
self, logging_mock, print_mock, time_sleep_mock
):
self_mock = MagicMock()
self_mock.setup.return_value = True
self_mock.image_url = "image url"
self_mock.template_url = "template url"
self_mock.network_name = "sriov_network"
self_mock.test_type = "vm"
self_mock.name = "testbed"
self_mock.run_command.side_effect = itertools.chain(
[True, True, True], itertools.repeat(False)
)

start_result = LXDTest_sriov.start_sriov(self_mock)

self.assertFalse(start_result)
self.assertTrue(print_mock.called)

def test_setup_failure(self):
self_mock = MagicMock()
self_mock.run_command.return_value = False
self_mock.image_url = None
self_mock.template_url = None
self_mock.network_name = None
self_mock.test_type = None

setup_return = LXDTest_sriov.setup(self_mock)

self.assertFalse(setup_return)


class TestCheckSriovInterfaces(unittest.TestCase):
@patch("builtins.open", new_callable=mock_open)
@patch("os.path.exists")
@patch("glob.glob")
def test_check_sriov_interfaces_with_intel_device(
self, mock_glob, mock_exists, mock_file
):
# Mocking the glob to return a fake list of network devices
mock_glob.return_value = ["/sys/class/net/eth0", "/sys/class/net/eth1"]

# Mock os.path.exists to return True for sriov_totalvfs, vendor,
# and carrier for eth0, False for eth1
def exists_side_effect(path):
if (
"eth0/device/sriov_totalvfs" in path
or "eth0/device/vendor" in path
or "eth0/carrier" in path
):
return True # eth0 has SR-IOV, Intel vendor, and carrier is up
return False # eth1 does not support SR-IOV

mock_exists.side_effect = exists_side_effect

# Mock open to return values based on the file being opened
# eth0 supports SR-IOV with 4 VFs
# Intel vendor ID for eth0
# eth0 carrier status is up
def open_side_effect(file, mode="r", *args, **kwargs):
if "eth0/device/sriov_totalvfs" in file:
return mock_open(read_data="4").return_value
if "eth0/device/vendor" in file:
return mock_open(read_data="0x8086").return_value
if "eth0/carrier" in file:
return mock_open(read_data="1").return_value

mock_file.side_effect = open_side_effect

# Call the function being tested
intel_device = check_sriov_interfaces()

# Assert that 'eth0' is correctly identified as the Intel device
self.assertEqual(intel_device, "eth1")

@patch("builtins.open", new_callable=mock_open, read_data="0")
@patch("os.path.exists")
@patch("glob.glob")
def test_check_sriov_interfaces_no_sriov_device(
self, mock_glob, mock_exists, mock_file
):
# Mocking the glob to return a fake list of devices
mock_glob.return_value = ["/sys/class/net/eth0", "/sys/class/net/eth1"]

# Mock os.path.exists to return True for sriov_totalvfs path
mock_exists.side_effect = lambda path: "sriov_totalvfs" in path

intel_device = check_sriov_interfaces()

# Asserting that no Intel device is found
self.assertNotEqual(intel_device, "eth0")
28 changes: 28 additions & 0 deletions providers/base/units/virtualization/jobs.pxu
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,31 @@ _purpose:
Verifies that an LXD container can be created and launched
_summary:
Verify LXD container launches

plugin: shell
category_id: com.canonical.plainbox::virtualization
id: virtualization/verify_lxd_vm_sriov
environ: LXD_TEMPLATE KVM_IMAGE
estimated_duration: 60.0
requires:
executable.name == 'lxc'
package.name == 'lxd-installer' or snap.name == 'lxd'
command: virtualization.py --debug sriov --type vm
_purpose:
Verifies that an SRIOV network device was created on an LXD Virtual Machine
_summary:
Verify SRIOV on LXD Virtual Machine

plugin: shell
category_id: com.canonical.plainbox::virtualization
id: virtualization/verify_lxd_container_sriov
environ: LXD_TEMPLATE LXD_ROOTFS
estimated_duration: 60.0
requires:
executable.name == 'lxc'
package.name == 'lxd-installer' or snap.name == 'lxd'
command: virtualization.py --debug sriov --type container
_purpose:
Verifies that an SRIOV network device was created on an LXD Container
_summary:
Verify SRIOV on LXD Container
2 changes: 2 additions & 0 deletions providers/base/units/virtualization/test-plan.pxu
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,5 @@ _name: Automated virtualization tests
include:
virtualization/verify_lxd
virtualization/verify_lxd_vm
virtualization/verify_lxd_vm_sriov
virtualization/verify_lxd_container_sriov
2 changes: 2 additions & 0 deletions providers/certification-server/units/server-full.pxu
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ include:
stress/cpu_stress_ng_test certification-status=blocker
virtualization/verify_lxd certification-status=blocker
virtualization/verify_lxd_vm certification-status=blocker
virtualization/verify_lxd_vm_sriov certification-status=non-blocker
virtualization/verify_lxd_container_sriov certification-status=non-blocker
info/kvm_output certification-status=non-blocker
miscellanea/oops certification-status=blocker
miscellanea/oops_results.log
Expand Down
2 changes: 2 additions & 0 deletions providers/certification-server/units/server-functional.pxu
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ include:
power-management/rtc certification-status=blocker
virtualization/verify_lxd certification-status=blocker
virtualization/verify_lxd_vm certification-status=blocker
virtualization/verify_lxd_vm_sriov certification-status=non-blocker
virtualization/verify_lxd_container_sriov certification-status=non-blocker
info/kvm_output certification-status=non-blocker
miscellanea/oops certification-status=non-blocker
miscellanea/oops_results.log certification-status=non-blocker
Expand Down
2 changes: 2 additions & 0 deletions providers/certification-server/units/server-regression.pxu
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ include:
usb/detect certification-status=non-blocker
virtualization/verify_lxd certification-status=blocker
virtualization/verify_lxd_vm certification-status=blocker
virtualization/verify_lxd_vm_sriov certification-status=non-blocker
virtualization/verify_lxd_container_sriov certification-status=non-blocker
info/kvm_output certification-status=non-blocker
miscellanea/oops certification-status=blocker
miscellanea/oops_results.log
Expand Down
2 changes: 2 additions & 0 deletions providers/certification-server/units/server-soc-cert.pxu
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ include:
stress/cpu_stress_ng_test certification-status=blocker
virtualization/verify_lxd certification-status=blocker
virtualization/verify_lxd_vm certification-status=blocker
virtualization/verify_lxd_vm_sriov certification-status=non-blocker
virtualization/verify_lxd_container_sriov certification-status=non-blocker
info/kvm_output certification-status=non-blocker
miscellanea/oops certification-status=non-blocker
miscellanea/oops_results.log
Expand Down
2 changes: 2 additions & 0 deletions providers/certification-server/units/server-ubuntucore-20.pxu
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ include:
usb3/storage-preinserted certification-status=blocker
virtualization/verify_lxd certification-status=blocker
virtualization/verify_lxd_vm certification-status=blocker
virtualization/verify_lxd_vm_sriov certification-status=non-blocker
virtualization/verify_lxd_container_sriov certification-status=non-blocker
info/kvm_output certification-status=non-blocker
miscellanea/oops certification-status=blocker
miscellanea/oops_results.log
Expand Down
2 changes: 2 additions & 0 deletions providers/certification-server/units/virtualization-only.pxu
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ include:
info/hdparm_.*.txt certification-status=non-blocker
virtualization/verify_lxd certification-status=blocker
virtualization/verify_lxd_vm certification-status=blocker
virtualization/verify_lxd_vm_sriov certification-status=non-blocker
virtualization/verify_lxd_container_sriov certification-status=non-blocker
info/kvm_output certification-status=non-blocker
miscellanea/oops certification-status=non-blocker
miscellanea/oops_results.log certification-status=non-blocker
Expand Down
Loading