Exemplo n.º 1
0
    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())
Exemplo n.º 2
0
 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)
Exemplo n.º 3
0
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())
Exemplo n.º 4
0
 def fake_subp(cmd):
     if cmd[0].startswith(tdir):
         return
     raise ProcessExecutionError(
         stdout='No drivers found for installation.\n', exit_code=1)
Exemplo n.º 5
0
 def fake_subp(cmd):
     if cmd[0].startswith(tdir):
         return
     raise ProcessExecutionError(stderr=OLD_UBUNTU_DRIVERS_ERROR_STDERR,
                                 exit_code=2)
Exemplo n.º 6
0
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