def test_ephemeral_ipv4_network_noop_when_configured(self, m_subp): """EphemeralIPv4Network handles exception when address is setup. It performs no cleanup as the interface was already setup. """ params = { 'interface': 'eth0', 'ip': '192.168.2.2', 'prefix_or_mask': '255.255.255.0', 'broadcast': '192.168.2.255' } m_subp.side_effect = ProcessExecutionError( '', 'RTNETLINK answers: File exists', 2) expected_calls = [ mock.call([ 'ip', '-family', 'inet', 'addr', 'add', '192.168.2.2/24', 'broadcast', '192.168.2.255', 'dev', 'eth0' ], capture=True, update_env={'LANG': 'C'}) ] with net.EphemeralIPv4Network(**params): pass self.assertEqual(expected_calls, m_subp.call_args_list) self.assertIn('Skip ephemeral network setup, eth0 already has address', self.logs.getvalue())
def test_returns_none_on_error(self, m_subp): """On 'file' execution error, None should be returned.""" m_subp.side_effect = ProcessExecutionError("FILE_FAILED", exit_code=99) fname = self.tmp_path("myfile") write_file(fname, "plain text content here\n") self.assertEqual(None, identify_file(fname)) self.assertEqual( [mock.call(["file", "--brief", "--mime-type", fname])], m_subp.call_args_list)
class TestUbuntuDrivers(CiTestCase): cfg_accepted = {'drivers': {'nvidia': {'license-accepted': True}}} install_gpgpu = ['ubuntu-drivers', 'install', '--gpgpu', 'nvidia'] with_logs = True @skipUnlessJsonSchema() def test_schema_requires_boolean_for_license_accepted(self): with self.assertRaisesRegex(SchemaValidationError, ".*license-accepted.*TRUE.*boolean"): validate_cloudconfig_schema( {'drivers': { 'nvidia': { 'license-accepted': "TRUE" } }}, schema=drivers.schema, strict=True) @mock.patch(MPATH + "util.subp", return_value=('', '')) @mock.patch(MPATH + "util.which", return_value=False) def _assert_happy_path_taken(self, config, m_which, m_subp): """Positive path test through handle. Package should be installed.""" myCloud = mock.MagicMock() drivers.handle('ubuntu_drivers', config, myCloud, None, None) self.assertEqual([mock.call(['ubuntu-drivers-common'])], myCloud.distro.install_packages.call_args_list) self.assertEqual([mock.call(self.install_gpgpu)], m_subp.call_args_list) def test_handle_does_package_install(self): self._assert_happy_path_taken(self.cfg_accepted) def test_trueish_strings_are_considered_approval(self): for true_value in ['yes', 'true', 'on', '1']: new_config = copy.deepcopy(self.cfg_accepted) new_config['drivers']['nvidia']['license-accepted'] = true_value self._assert_happy_path_taken(new_config) @mock.patch(MPATH + "util.subp", side_effect=ProcessExecutionError( stdout='No drivers found for installation.\n', exit_code=1)) @mock.patch(MPATH + "util.which", return_value=False) def test_handle_raises_error_if_no_drivers_found(self, m_which, m_subp): """If ubuntu-drivers doesn't install any drivers, raise an error.""" myCloud = mock.MagicMock() with self.assertRaises(Exception): drivers.handle('ubuntu_drivers', self.cfg_accepted, myCloud, None, None) self.assertEqual([mock.call(['ubuntu-drivers-common'])], myCloud.distro.install_packages.call_args_list) self.assertEqual([mock.call(self.install_gpgpu)], m_subp.call_args_list) self.assertIn('ubuntu-drivers found no drivers for installation', self.logs.getvalue()) @mock.patch(MPATH + "util.subp", return_value=('', '')) @mock.patch(MPATH + "util.which", return_value=False) def _assert_inert_with_config(self, config, m_which, m_subp): """Helper to reduce repetition when testing negative cases""" myCloud = mock.MagicMock() drivers.handle('ubuntu_drivers', config, myCloud, None, None) self.assertEqual(0, myCloud.distro.install_packages.call_count) self.assertEqual(0, m_subp.call_count) def test_handle_inert_if_license_not_accepted(self): """Ensure we don't do anything if the license is rejected.""" self._assert_inert_with_config( {'drivers': { 'nvidia': { 'license-accepted': False } }}) def test_handle_inert_if_garbage_in_license_field(self): """Ensure we don't do anything if unknown text is in license field.""" self._assert_inert_with_config( {'drivers': { 'nvidia': { 'license-accepted': 'garbage' } }}) def test_handle_inert_if_no_license_key(self): """Ensure we don't do anything if no license key.""" self._assert_inert_with_config({'drivers': {'nvidia': {}}}) def test_handle_inert_if_no_nvidia_key(self): """Ensure we don't do anything if other license accepted.""" self._assert_inert_with_config( {'drivers': { 'acme': { 'license-accepted': True } }}) def test_handle_inert_if_string_given(self): """Ensure we don't do anything if string refusal given.""" for false_value in ['no', 'false', 'off', '0']: self._assert_inert_with_config( {'drivers': { 'nvidia': { 'license-accepted': false_value } }}) @mock.patch(MPATH + "install_drivers") def test_handle_no_drivers_does_nothing(self, m_install_drivers): """If no 'drivers' key in the config, nothing should be done.""" myCloud = mock.MagicMock() myLog = mock.MagicMock() drivers.handle('ubuntu_drivers', {'foo': 'bzr'}, myCloud, myLog, None) self.assertIn('Skipping module named', myLog.debug.call_args_list[0][0][0]) self.assertEqual(0, m_install_drivers.call_count) @mock.patch(MPATH + "util.subp", return_value=('', '')) @mock.patch(MPATH + "util.which", return_value=True) def test_install_drivers_no_install_if_present(self, m_which, m_subp): """If 'ubuntu-drivers' is present, no package install should occur.""" pkg_install = mock.MagicMock() drivers.install_drivers(self.cfg_accepted['drivers'], pkg_install_func=pkg_install) self.assertEqual(0, pkg_install.call_count) self.assertEqual([mock.call('ubuntu-drivers')], m_which.call_args_list) self.assertEqual([mock.call(self.install_gpgpu)], m_subp.call_args_list) def test_install_drivers_rejects_invalid_config(self): """install_drivers should raise TypeError if not given a config dict""" pkg_install = mock.MagicMock() with self.assertRaisesRegex(TypeError, ".*expected dict.*"): drivers.install_drivers("mystring", pkg_install_func=pkg_install) self.assertEqual(0, pkg_install.call_count) @mock.patch(MPATH + "util.subp", side_effect=ProcessExecutionError( stderr=OLD_UBUNTU_DRIVERS_ERROR_STDERR, exit_code=2)) @mock.patch(MPATH + "util.which", return_value=False) def test_install_drivers_handles_old_ubuntu_drivers_gracefully( self, m_which, m_subp): """Older ubuntu-drivers versions should emit message and raise error""" myCloud = mock.MagicMock() with self.assertRaises(Exception): drivers.handle('ubuntu_drivers', self.cfg_accepted, myCloud, None, None) self.assertEqual([mock.call(['ubuntu-drivers-common'])], myCloud.distro.install_packages.call_args_list) self.assertEqual([mock.call(self.install_gpgpu)], m_subp.call_args_list) self.assertIn( 'WARNING: the available version of ubuntu-drivers is' ' too old to perform requested driver installation', self.logs.getvalue())
def fake_subp(cmd): if cmd[0].startswith(tdir): return raise ProcessExecutionError( stdout='No drivers found for installation.\n', exit_code=1)
def fake_subp(cmd): if cmd[0].startswith(tdir): return raise ProcessExecutionError(stderr=OLD_UBUNTU_DRIVERS_ERROR_STDERR, exit_code=2)
class TestFetchIdevs: """Tests cc_grub_dpkg.fetch_idevs()""" # Note: udevadm info returns devices in a large single line string @pytest.mark.parametrize( "grub_output,path_exists,expected_log_call,udevadm_output" ",expected_idevs", [ # Inside a container, grub not installed ( ProcessExecutionError(reason=FileNotFoundError()), False, mock.call("'grub-probe' not found in $PATH"), '', '', ), # Inside a container, grub installed ( ProcessExecutionError(stderr="failed to get canonical path"), False, mock.call("grub-probe 'failed to get canonical path'"), '', '', ), # KVM Instance ( ['/dev/vda'], True, None, ('/dev/disk/by-path/pci-0000:00:00.0 ', '/dev/disk/by-path/virtio-pci-0000:00:00.0 '), '/dev/vda', ), # Xen Instance ( ['/dev/xvda'], True, None, '', '/dev/xvda', ), # NVMe Hardware Instance ( ['/dev/nvme1n1'], True, None, ('/dev/disk/by-id/nvme-Company_hash000 ', '/dev/disk/by-id/nvme-nvme.000-000-000-000-000 ', '/dev/disk/by-path/pci-0000:00:00.0-nvme-0 '), '/dev/disk/by-id/nvme-Company_hash000', ), # SCSI Hardware Instance ( ['/dev/sda'], True, None, ('/dev/disk/by-id/company-user-1 ', '/dev/disk/by-id/scsi-0Company_user-1 ', '/dev/disk/by-path/pci-0000:00:00.0-scsi-0:0:0:0 '), '/dev/disk/by-id/company-user-1', ), ], ) @mock.patch("cloudinit.config.cc_grub_dpkg.util.logexc") @mock.patch("cloudinit.config.cc_grub_dpkg.os.path.exists") @mock.patch("cloudinit.config.cc_grub_dpkg.util.subp") def test_fetch_idevs(self, m_subp, m_exists, m_logexc, grub_output, path_exists, expected_log_call, udevadm_output, expected_idevs): """Tests outputs from grub-probe and udevadm info against grub-dpkg""" m_subp.side_effect = [grub_output, ["".join(udevadm_output)]] m_exists.return_value = path_exists log = mock.Mock(spec=Logger) idevs = fetch_idevs(log) assert expected_idevs == idevs if expected_log_call is not None: assert expected_log_call in log.debug.call_args_list