diff options
| author | Ryan Harper <[email protected]> | 2018-09-21 08:00:05 +0000 |
|---|---|---|
| committer | Server Team CI Bot <[email protected]> | 2018-09-21 08:00:05 +0000 |
| commit | 5f0082d1d1af56d87646d31a8b7649c768c2011c (patch) | |
| tree | b35f7972eb60f7c622ca43cb263b0a1cece6ce62 /tests | |
| parent | b812ae8023765bfbf4402a9d3dc1bdfca8097ef5 (diff) | |
Enable custom storage configuration for centos images
Add support for the majority of storage configurations including
partitioning, lvm, raid, iscsi and combinations of these. Some
storage configs are unsupported at this time:
Unsupported storage config options on Centos:
- bcache (no kernel support)
- zfs (no kernel support)
- jfs, ntfs, reiserfs (no kernel, userspace support)
Curtin's built-in curthooks now support Centos in addition
to Ubuntu. The built-in curthooks are now callable by
in-image curthooks. This feature is announced by the
presence of the feature flag, 'CENTOS_CURTHOOK_SUPPORT'
Other notable features added:
- tools/jenkins-runner now includes a test filtering
ability which enables generating the list of tests to
run by specifying attributes of the classes. For example
to run all centos70 tests append:
--filter=target_release=centos70
- curtin/distro.py includes distro specific methods, such as
package install and distro version detection
- util.target_path has now moved to curtin.paths module
Diffstat (limited to 'tests')
53 files changed, 1026 insertions, 845 deletions
diff --git a/tests/unittests/test_apt_custom_sources_list.py b/tests/unittests/test_apt_custom_sources_list.py index 5567dd50..a427ae9c 100644 --- a/tests/unittests/test_apt_custom_sources_list.py +++ b/tests/unittests/test_apt_custom_sources_list.py @@ -11,6 +11,8 @@ from mock import call import textwrap import yaml +from curtin import distro +from curtin import paths from curtin import util from curtin.commands import apt_config from .helpers import CiTestCase @@ -106,7 +108,7 @@ class TestAptSourceConfigSourceList(CiTestCase): # make test independent to executing system with mock.patch.object(util, 'load_file', return_value=MOCKED_APT_SRC_LIST): - with mock.patch.object(util, 'lsb_release', + with mock.patch.object(distro, 'lsb_release', return_value={'codename': 'fakerel'}): apt_config.handle_apt(cfg, TARGET) @@ -115,10 +117,10 @@ class TestAptSourceConfigSourceList(CiTestCase): cloudfile = '/etc/cloud/cloud.cfg.d/curtin-preserve-sources.cfg' cloudconf = yaml.dump({'apt_preserve_sources_list': True}, indent=1) - calls = [call(util.target_path(TARGET, '/etc/apt/sources.list'), + calls = [call(paths.target_path(TARGET, '/etc/apt/sources.list'), expected, mode=0o644), - call(util.target_path(TARGET, cloudfile), + call(paths.target_path(TARGET, cloudfile), cloudconf, mode=0o644)] mockwrite.assert_has_calls(calls) @@ -147,19 +149,19 @@ class TestAptSourceConfigSourceList(CiTestCase): arch = util.get_architecture() # would fail inside the unittest context with mock.patch.object(util, 'get_architecture', return_value=arch): - with mock.patch.object(util, 'lsb_release', + with mock.patch.object(distro, 'lsb_release', return_value={'codename': 'fakerel'}): apt_config.handle_apt(cfg, target) self.assertEqual( EXPECTED_CONVERTED_CONTENT, - util.load_file(util.target_path(target, "/etc/apt/sources.list"))) - cloudfile = util.target_path( + util.load_file(paths.target_path(target, "/etc/apt/sources.list"))) + cloudfile = paths.target_path( target, '/etc/cloud/cloud.cfg.d/curtin-preserve-sources.cfg') self.assertEqual({'apt_preserve_sources_list': True}, yaml.load(util.load_file(cloudfile))) - @mock.patch("curtin.util.lsb_release") + @mock.patch("curtin.distro.lsb_release") @mock.patch("curtin.util.get_architecture", return_value="amd64") def test_trusty_source_lists(self, m_get_arch, m_lsb_release): """Support mirror equivalency with and without trailing /. @@ -199,7 +201,7 @@ class TestAptSourceConfigSourceList(CiTestCase): release = 'trusty' comps = 'main universe multiverse restricted' - easl = util.target_path(target, 'etc/apt/sources.list') + easl = paths.target_path(target, 'etc/apt/sources.list') orig_content = tmpl.format( mirror=orig_primary, security=orig_security, diff --git a/tests/unittests/test_apt_source.py b/tests/unittests/test_apt_source.py index 2ede9866..353cdf8c 100644 --- a/tests/unittests/test_apt_source.py +++ b/tests/unittests/test_apt_source.py @@ -12,8 +12,9 @@ import socket import mock from mock import call -from curtin import util +from curtin import distro from curtin import gpg +from curtin import util from curtin.commands import apt_config from .helpers import CiTestCase @@ -77,7 +78,7 @@ class TestAptSourceConfig(CiTestCase): @staticmethod def _add_apt_sources(*args, **kwargs): - with mock.patch.object(util, 'apt_update'): + with mock.patch.object(distro, 'apt_update'): apt_config.add_apt_sources(*args, **kwargs) @staticmethod @@ -86,7 +87,7 @@ class TestAptSourceConfig(CiTestCase): Get the most basic default mrror and release info to be used in tests """ params = {} - params['RELEASE'] = util.lsb_release()['codename'] + params['RELEASE'] = distro.lsb_release()['codename'] arch = util.get_architecture() params['MIRROR'] = apt_config.get_default_mirrors(arch)["PRIMARY"] return params @@ -472,7 +473,7 @@ class TestAptSourceConfig(CiTestCase): 'uri': 'http://testsec.ubuntu.com/%s/' % component}]} post = ("%s_dists_%s-updates_InRelease" % - (component, util.lsb_release()['codename'])) + (component, distro.lsb_release()['codename'])) fromfn = ("%s/%s_%s" % (pre, archive, post)) tofn = ("%s/test.ubuntu.com_%s" % (pre, post)) @@ -937,7 +938,7 @@ class TestDebconfSelections(CiTestCase): m_set_sel.assert_not_called() @mock.patch("curtin.commands.apt_config.debconf_set_selections") - @mock.patch("curtin.commands.apt_config.util.get_installed_packages") + @mock.patch("curtin.commands.apt_config.distro.get_installed_packages") def test_set_sel_call_has_expected_input(self, m_get_inst, m_set_sel): data = { 'set1': 'pkga pkga/q1 mybool false', @@ -960,7 +961,7 @@ class TestDebconfSelections(CiTestCase): @mock.patch("curtin.commands.apt_config.dpkg_reconfigure") @mock.patch("curtin.commands.apt_config.debconf_set_selections") - @mock.patch("curtin.commands.apt_config.util.get_installed_packages") + @mock.patch("curtin.commands.apt_config.distro.get_installed_packages") def test_reconfigure_if_intersection(self, m_get_inst, m_set_sel, m_dpkg_r): data = { @@ -985,7 +986,7 @@ class TestDebconfSelections(CiTestCase): @mock.patch("curtin.commands.apt_config.dpkg_reconfigure") @mock.patch("curtin.commands.apt_config.debconf_set_selections") - @mock.patch("curtin.commands.apt_config.util.get_installed_packages") + @mock.patch("curtin.commands.apt_config.distro.get_installed_packages") def test_reconfigure_if_no_intersection(self, m_get_inst, m_set_sel, m_dpkg_r): data = {'set1': 'pkga pkga/q1 mybool false'} diff --git a/tests/unittests/test_block_iscsi.py b/tests/unittests/test_block_iscsi.py index afaf1f6d..f8ef5d87 100644 --- a/tests/unittests/test_block_iscsi.py +++ b/tests/unittests/test_block_iscsi.py @@ -588,6 +588,13 @@ class TestBlockIscsiDiskFromConfig(CiTestCase): # utilize IscsiDisk str method for equality check self.assertEqual(str(expected_iscsi_disk), str(iscsi_disk)) + # test with cfg.get('storage') since caller may already have + # grabbed the 'storage' value from the curtin config + iscsi_disk = iscsi.get_iscsi_disks_from_config( + cfg.get('storage')).pop() + # utilize IscsiDisk str method for equality check + self.assertEqual(str(expected_iscsi_disk), str(iscsi_disk)) + def test_parse_iscsi_disk_from_config_no_iscsi(self): """Test parsing storage config with no iscsi disks included""" cfg = { diff --git a/tests/unittests/test_block_lvm.py b/tests/unittests/test_block_lvm.py index 22fb0649..c92c1ec8 100644 --- a/tests/unittests/test_block_lvm.py +++ b/tests/unittests/test_block_lvm.py @@ -73,7 +73,8 @@ class TestBlockLvm(CiTestCase): @mock.patch('curtin.block.lvm.lvmetad_running') @mock.patch('curtin.block.lvm.util') - def test_lvm_scan(self, mock_util, mock_lvmetad): + @mock.patch('curtin.block.lvm.distro') + def test_lvm_scan(self, mock_distro, mock_util, mock_lvmetad): """check that lvm_scan formats commands correctly for each release""" cmds = [['pvscan'], ['vgscan', '--mknodes']] for (count, (codename, lvmetad_status, use_cache)) in enumerate( @@ -81,7 +82,7 @@ class TestBlockLvm(CiTestCase): ('trusty', False, False), ('xenial', False, False), ('xenial', True, True), (None, True, True), (None, False, False)]): - mock_util.lsb_release.return_value = {'codename': codename} + mock_distro.lsb_release.return_value = {'codename': codename} mock_lvmetad.return_value = lvmetad_status lvm.lvm_scan() expected = [cmd for cmd in cmds] diff --git a/tests/unittests/test_block_mdadm.py b/tests/unittests/test_block_mdadm.py index 341e49df..d017930e 100644 --- a/tests/unittests/test_block_mdadm.py +++ b/tests/unittests/test_block_mdadm.py @@ -15,12 +15,13 @@ class TestBlockMdadmAssemble(CiTestCase): def setUp(self): super(TestBlockMdadmAssemble, self).setUp() self.add_patch('curtin.block.mdadm.util', 'mock_util') + self.add_patch('curtin.block.mdadm.lsb_release', 'mock_lsb_release') self.add_patch('curtin.block.mdadm.is_valid_device', 'mock_valid') self.add_patch('curtin.block.mdadm.udev', 'mock_udev') # Common mock settings self.mock_valid.return_value = True - self.mock_util.lsb_release.return_value = {'codename': 'precise'} + self.mock_lsb_release.return_value = {'codename': 'precise'} self.mock_util.subp.return_value = ('', '') def test_mdadm_assemble_scan(self): @@ -88,6 +89,7 @@ class TestBlockMdadmCreate(CiTestCase): def setUp(self): super(TestBlockMdadmCreate, self).setUp() self.add_patch('curtin.block.mdadm.util', 'mock_util') + self.add_patch('curtin.block.mdadm.lsb_release', 'mock_lsb_release') self.add_patch('curtin.block.mdadm.is_valid_device', 'mock_valid') self.add_patch('curtin.block.mdadm.get_holders', 'mock_holders') self.add_patch('curtin.block.mdadm.udev.udevadm_settle', @@ -95,7 +97,7 @@ class TestBlockMdadmCreate(CiTestCase): # Common mock settings self.mock_valid.return_value = True - self.mock_util.lsb_release.return_value = {'codename': 'precise'} + self.mock_lsb_release.return_value = {'codename': 'precise'} self.mock_holders.return_value = [] def prepare_mock(self, md_devname, raidlevel, devices, spares): @@ -236,14 +238,15 @@ class TestBlockMdadmExamine(CiTestCase): def setUp(self): super(TestBlockMdadmExamine, self).setUp() self.add_patch('curtin.block.mdadm.util', 'mock_util') + self.add_patch('curtin.block.mdadm.lsb_release', 'mock_lsb_release') self.add_patch('curtin.block.mdadm.is_valid_device', 'mock_valid') # Common mock settings self.mock_valid.return_value = True - self.mock_util.lsb_release.return_value = {'codename': 'precise'} + self.mock_lsb_release.return_value = {'codename': 'precise'} def test_mdadm_examine_export(self): - self.mock_util.lsb_release.return_value = {'codename': 'xenial'} + self.mock_lsb_release.return_value = {'codename': 'xenial'} self.mock_util.subp.return_value = ( """ MD_LEVEL=raid0 @@ -320,7 +323,7 @@ class TestBlockMdadmExamine(CiTestCase): class TestBlockMdadmStop(CiTestCase): def setUp(self): super(TestBlockMdadmStop, self).setUp() - self.add_patch('curtin.block.mdadm.util.lsb_release', 'mock_util_lsb') + self.add_patch('curtin.block.mdadm.lsb_release', 'mock_lsb_release') self.add_patch('curtin.block.mdadm.util.subp', 'mock_util_subp') self.add_patch('curtin.block.mdadm.util.write_file', 'mock_util_write_file') @@ -333,7 +336,7 @@ class TestBlockMdadmStop(CiTestCase): # Common mock settings self.mock_valid.return_value = True - self.mock_util_lsb.return_value = {'codename': 'xenial'} + self.mock_lsb_release.return_value = {'codename': 'xenial'} self.mock_util_subp.side_effect = iter([ ("", ""), # mdadm stop device ]) @@ -488,11 +491,12 @@ class TestBlockMdadmRemove(CiTestCase): def setUp(self): super(TestBlockMdadmRemove, self).setUp() self.add_patch('curtin.block.mdadm.util', 'mock_util') + self.add_patch('curtin.block.mdadm.lsb_release', 'mock_lsb_release') self.add_patch('curtin.block.mdadm.is_valid_device', 'mock_valid') # Common mock settings self.mock_valid.return_value = True - self.mock_util.lsb_release.return_value = {'codename': 'xenial'} + self.mock_lsb_release.return_value = {'codename': 'xenial'} self.mock_util.subp.side_effect = [ ("", ""), # mdadm remove device ] @@ -514,14 +518,15 @@ class TestBlockMdadmQueryDetail(CiTestCase): def setUp(self): super(TestBlockMdadmQueryDetail, self).setUp() self.add_patch('curtin.block.mdadm.util', 'mock_util') + self.add_patch('curtin.block.mdadm.lsb_release', 'mock_lsb_release') self.add_patch('curtin.block.mdadm.is_valid_device', 'mock_valid') # Common mock settings self.mock_valid.return_value = True - self.mock_util.lsb_release.return_value = {'codename': 'precise'} + self.mock_lsb_release.return_value = {'codename': 'precise'} def test_mdadm_query_detail_export(self): - self.mock_util.lsb_release.return_value = {'codename': 'xenial'} + self.mock_lsb_release.return_value = {'codename': 'xenial'} self.mock_util.subp.return_value = ( """ MD_LEVEL=raid1 @@ -592,13 +597,14 @@ class TestBlockMdadmDetailScan(CiTestCase): def setUp(self): super(TestBlockMdadmDetailScan, self).setUp() self.add_patch('curtin.block.mdadm.util', 'mock_util') + self.add_patch('curtin.block.mdadm.lsb_release', 'mock_lsb_release') self.add_patch('curtin.block.mdadm.is_valid_device', 'mock_valid') # Common mock settings self.scan_output = ("ARRAY /dev/md0 metadata=1.2 spares=2 name=0 " + "UUID=b1eae2ff:69b6b02e:1d63bb53:ddfa6e4a") self.mock_valid.return_value = True - self.mock_util.lsb_release.return_value = {'codename': 'xenial'} + self.mock_lsb_release.return_value = {'codename': 'xenial'} self.mock_util.subp.side_effect = [ (self.scan_output, ""), # mdadm --detail --scan ] @@ -627,10 +633,11 @@ class TestBlockMdadmMdHelpers(CiTestCase): def setUp(self): super(TestBlockMdadmMdHelpers, self).setUp() self.add_patch('curtin.block.mdadm.util', 'mock_util') + self.add_patch('curtin.block.mdadm.lsb_release', 'mock_lsb_release') self.add_patch('curtin.block.mdadm.is_valid_device', 'mock_valid') self.mock_valid.return_value = True - self.mock_util.lsb_release.return_value = {'codename': 'xenial'} + self.mock_lsb_release.return_value = {'codename': 'xenial'} def test_valid_mdname(self): mdname = "/dev/md0" diff --git a/tests/unittests/test_block_mkfs.py b/tests/unittests/test_block_mkfs.py index c756281d..679f85b8 100644 --- a/tests/unittests/test_block_mkfs.py +++ b/tests/unittests/test_block_mkfs.py @@ -37,11 +37,12 @@ class TestBlockMkfs(CiTestCase): @mock.patch("curtin.block.mkfs.block") @mock.patch("curtin.block.mkfs.os") @mock.patch("curtin.block.mkfs.util") + @mock.patch("curtin.block.mkfs.distro.lsb_release") def _run_mkfs_with_config(self, config, expected_cmd, expected_flags, - mock_util, mock_os, mock_block, + mock_lsb_release, mock_util, mock_os, mock_block, release="wily", strict=False): # Pretend we are on wily as there are no known edge cases for it - mock_util.lsb_release.return_value = {"codename": release} + mock_lsb_release.return_value = {"codename": release} mock_os.path.exists.return_value = True mock_block.get_blockdev_sector_size.return_value = (512, 512) diff --git a/tests/unittests/test_block_zfs.py b/tests/unittests/test_block_zfs.py index c18f6a35..9781946e 100644 --- a/tests/unittests/test_block_zfs.py +++ b/tests/unittests/test_block_zfs.py @@ -384,7 +384,7 @@ class TestBlockZfsAssertZfsSupported(CiTestCase): super(TestBlockZfsAssertZfsSupported, self).setUp() self.add_patch('curtin.block.zfs.util.subp', 'mock_subp') self.add_patch('curtin.block.zfs.util.get_platform_arch', 'mock_arch') - self.add_patch('curtin.block.zfs.util.lsb_release', 'mock_release') + self.add_patch('curtin.block.zfs.distro.lsb_release', 'mock_release') self.add_patch('curtin.block.zfs.util.which', 'mock_which') self.add_patch('curtin.block.zfs.get_supported_filesystems', 'mock_supfs') @@ -426,46 +426,52 @@ class TestAssertZfsSupported(CiTestCase): super(TestAssertZfsSupported, self).setUp() @mock.patch('curtin.block.zfs.get_supported_filesystems') + @mock.patch('curtin.block.zfs.distro') @mock.patch('curtin.block.zfs.util') - def test_zfs_assert_supported_returns_true(self, mock_util, mock_supfs): + def test_zfs_assert_supported_returns_true(self, mock_util, mock_distro, + mock_supfs): """zfs_assert_supported returns True on supported platforms""" mock_util.get_platform_arch.return_value = 'amd64' - mock_util.lsb_release.return_value = {'codename': 'bionic'} + mock_distro.lsb_release.return_value = {'codename': 'bionic'} mock_util.subp.return_value = ("", "") mock_supfs.return_value = ['zfs'] mock_util.which.side_effect = iter(['/wark/zpool', '/wark/zfs']) self.assertNotIn(mock_util.get_platform_arch.return_value, zfs.ZFS_UNSUPPORTED_ARCHES) - self.assertNotIn(mock_util.lsb_release.return_value['codename'], + self.assertNotIn(mock_distro.lsb_release.return_value['codename'], zfs.ZFS_UNSUPPORTED_RELEASES) self.assertTrue(zfs.zfs_supported()) + @mock.patch('curtin.block.zfs.distro') @mock.patch('curtin.block.zfs.util') def test_zfs_assert_supported_raises_exception_on_bad_arch(self, - mock_util): + mock_util, + mock_distro): """zfs_assert_supported raises RuntimeError on unspported arches""" - mock_util.lsb_release.return_value = {'codename': 'bionic'} + mock_distro.lsb_release.return_value = {'codename': 'bionic'} mock_util.subp.return_value = ("", "") for arch in zfs.ZFS_UNSUPPORTED_ARCHES: mock_util.get_platform_arch.return_value = arch with self.assertRaises(RuntimeError): zfs.zfs_assert_supported() + @mock.patch('curtin.block.zfs.distro') @mock.patch('curtin.block.zfs.util') - def test_zfs_assert_supported_raises_exc_on_bad_releases(self, mock_util): + def test_zfs_assert_supported_raises_exc_on_bad_releases(self, mock_util, + mock_distro): """zfs_assert_supported raises RuntimeError on unspported releases""" mock_util.get_platform_arch.return_value = 'amd64' mock_util.subp.return_value = ("", "") for release in zfs.ZFS_UNSUPPORTED_RELEASES: - mock_util.lsb_release.return_value = {'codename': release} + mock_distro.lsb_release.return_value = {'codename': release} with self.assertRaises(RuntimeError): zfs.zfs_assert_supported() @mock.patch('curtin.block.zfs.util.subprocess.Popen') @mock.patch('curtin.block.zfs.util.is_kmod_loaded') @mock.patch('curtin.block.zfs.get_supported_filesystems') - @mock.patch('curtin.block.zfs.util.lsb_release') + @mock.patch('curtin.block.zfs.distro.lsb_release') @mock.patch('curtin.block.zfs.util.get_platform_arch') def test_zfs_assert_supported_raises_exc_on_missing_module(self, m_arch, diff --git a/tests/unittests/test_commands_apply_net.py b/tests/unittests/test_commands_apply_net.py index a55ab177..04b7f2ef 100644 --- a/tests/unittests/test_commands_apply_net.py +++ b/tests/unittests/test_commands_apply_net.py @@ -5,7 +5,7 @@ import copy import os from curtin.commands import apply_net -from curtin import util +from curtin import paths from .helpers import CiTestCase @@ -153,8 +153,8 @@ class TestApplyNetPatchIfupdown(CiTestCase): prehookfn=prehookfn, posthookfn=posthookfn) - precfg = util.target_path(target, path=prehookfn) - postcfg = util.target_path(target, path=posthookfn) + precfg = paths.target_path(target, path=prehookfn) + postcfg = paths.target_path(target, path=posthookfn) precontents = apply_net.IFUPDOWN_IPV6_MTU_PRE_HOOK postcontents = apply_net.IFUPDOWN_IPV6_MTU_POST_HOOK @@ -231,7 +231,7 @@ class TestApplyNetPatchIpv6Priv(CiTestCase): apply_net._disable_ipv6_privacy_extensions(target) - cfg = util.target_path(target, path=path) + cfg = paths.target_path(target, path=path) mock_write.assert_called_with(cfg, expected_ipv6_priv_contents) @patch('curtin.util.load_file') @@ -259,7 +259,7 @@ class TestApplyNetPatchIpv6Priv(CiTestCase): apply_net._disable_ipv6_privacy_extensions(target, path=path) # source file not found - cfg = util.target_path(target, path) + cfg = paths.target_path(target, path) mock_ospath.exists.assert_called_with(cfg) self.assertEqual(0, mock_load.call_count) @@ -272,7 +272,7 @@ class TestApplyNetRemoveLegacyEth0(CiTestCase): def test_remove_legacy_eth0(self, mock_ospath, mock_load, mock_del): target = 'mytarget' path = 'eth0.cfg' - cfg = util.target_path(target, path) + cfg = paths.target_path(target, path) legacy_eth0_contents = ( 'auto eth0\n' 'iface eth0 inet dhcp') @@ -330,7 +330,7 @@ class TestApplyNetRemoveLegacyEth0(CiTestCase): apply_net._maybe_remove_legacy_eth0(target, path) # source file not found - cfg = util.target_path(target, path) + cfg = paths.target_path(target, path) mock_ospath.exists.assert_called_with(cfg) self.assertEqual(0, mock_load.call_count) self.assertEqual(0, mock_del.call_count) diff --git a/tests/unittests/test_commands_block_meta.py b/tests/unittests/test_commands_block_meta.py index a6a0b138..e70d6edb 100644 --- a/tests/unittests/test_commands_block_meta.py +++ b/tests/unittests/test_commands_block_meta.py @@ -7,7 +7,7 @@ from mock import patch, call import os from curtin.commands import block_meta -from curtin import util +from curtin import paths, util from .helpers import CiTestCase @@ -688,8 +688,9 @@ class TestFstabData(CiTestCase): if target is None: target = self.tmp_dir() - expected = [a if a != "_T_MP" else util.target_path(target, fdata.path) - for a in expected] + expected = [ + a if a != "_T_MP" else paths.target_path(target, fdata.path) + for a in expected] with patch("curtin.util.subp") as m_subp: block_meta.mount_fstab_data(fdata, target=target) diff --git a/tests/unittests/test_curthooks.py b/tests/unittests/test_curthooks.py index a8275c77..8fd79330 100644 --- a/tests/unittests/test_curthooks.py +++ b/tests/unittests/test_curthooks.py @@ -4,6 +4,7 @@ import os from mock import call, patch, MagicMock from curtin.commands import curthooks +from curtin import distro from curtin import util from curtin import config from curtin.reporter import events @@ -47,8 +48,8 @@ class TestGetFlashKernelPkgs(CiTestCase): class TestCurthooksInstallKernel(CiTestCase): def setUp(self): super(TestCurthooksInstallKernel, self).setUp() - self.add_patch('curtin.util.has_pkg_available', 'mock_haspkg') - self.add_patch('curtin.util.install_packages', 'mock_instpkg') + self.add_patch('curtin.distro.has_pkg_available', 'mock_haspkg') + self.add_patch('curtin.distro.install_packages', 'mock_instpkg') self.add_patch( 'curtin.commands.curthooks.get_flash_kernel_pkgs', 'mock_get_flash_kernel_pkgs') @@ -122,12 +123,21 @@ class TestInstallMissingPkgs(CiTestCase): def setUp(self): super(TestInstallMissingPkgs, self).setUp() self.add_patch('platform.machine', 'mock_machine') - self.add_patch('curtin.util.get_installed_packages', + self.add_patch('curtin.util.get_architecture', 'mock_arch') + self.add_patch('curtin.distro.get_installed_packages', 'mock_get_installed_packages') self.add_patch('curtin.util.load_command_environment', 'mock_load_cmd_evn') self.add_patch('curtin.util.which', 'mock_which') - self.add_patch('curtin.util.install_packages', 'mock_install_packages') + self.add_patch('curtin.util.is_uefi_bootable', 'mock_uefi') + self.add_patch('curtin.distro.has_pkg_available', 'mock_haspkg') + self.add_patch('curtin.distro.install_packages', + 'mock_install_packages') + self.add_patch('curtin.distro.get_osfamily', 'mock_osfamily') + self.distro_family = distro.DISTROS.debian + self.mock_osfamily.return_value = self.distro_family + self.mock_uefi.return_value = False + self.mock_haspkg.return_value = False @patch.object(events, 'ReportEventStack') def test_install_packages_s390x(self, mock_events): @@ -137,8 +147,8 @@ class TestInstallMissingPkgs(CiTestCase): target = "not-a-real-target" cfg = {} curthooks.install_missing_packages(cfg, target=target) - self.mock_install_packages.assert_called_with(['s390-tools'], - target=target) + self.mock_install_packages.assert_called_with( + ['s390-tools'], target=target, osfamily=self.distro_family) @patch.object(events, 'ReportEventStack') def test_install_packages_s390x_has_zipl(self, mock_events): @@ -159,6 +169,50 @@ class TestInstallMissingPkgs(CiTestCase): curthooks.install_missing_packages(cfg, target=target) self.assertEqual([], self.mock_install_packages.call_args_list) + @patch.object(events, 'ReportEventStack') + def test_install_packages_on_uefi_amd64_shim_signed(self, mock_events): + arch = 'amd64' + self.mock_arch.return_value = arch + self.mock_machine.return_value = 'x86_64' + expected_pkgs = ['grub-efi-%s' % arch, + 'grub-efi-%s-signed' % arch, + 'shim-signed'] + self.mock_machine.return_value = 'x86_64' + self.mock_uefi.return_value = True + self.mock_haspkg.return_value = True + target = "not-a-real-target" + cfg = {} + curthooks.install_missing_packages(cfg, target=target) + self.mock_install_packages.assert_called_with( + expected_pkgs, target=target, osfamily=self.distro_family) + + @patch.object(events, 'ReportEventStack') + def test_install_packages_on_uefi_i386_noshim_nosigned(self, mock_events): + arch = 'i386' + self.mock_arch.return_value = arch + self.mock_machine.return_value = 'i386' + expected_pkgs = ['grub-efi-%s' % arch] + self.mock_machine.return_value = 'i686' + self.mock_uefi.return_value = True + target = "not-a-real-target" + cfg = {} + curthooks.install_missing_packages(cfg, target=target) + self.mock_install_packages.assert_called_with( + expected_pkgs, target=target, osfamily=self.distro_family) + + @patch.object(events, 'ReportEventStack') + def test_install_packages_on_uefi_arm64_nosign_noshim(self, mock_events): + arch = 'arm64' + self.mock_arch.return_value = arch + self.mock_machine.return_value = 'aarch64' + expected_pkgs = ['grub-efi-%s' % arch] + self.mock_uefi.return_value = True + target = "not-a-real-target" + cfg = {} + curthooks.install_missing_packages(cfg, target=target) + self.mock_install_packages.assert_called_with( + expected_pkgs, target=target, osfamily=self.distro_family) + class TestSetupZipl(CiTestCase): @@ -192,7 +246,8 @@ class TestSetupGrub(CiTestCase): def setUp(self): super(TestSetupGrub, self).setUp() self.target = self.tmp_dir() - self.add_patch('curtin.util.lsb_release', 'mock_lsb_release') + self.distro_family = distro.DISTROS.debian + self.add_patch('curtin.distro.lsb_release', 'mock_lsb_release') self.mock_lsb_release.return_value = { 'codename': 'xenial', } @@ -219,11 +274,12 @@ class TestSetupGrub(CiTestCase): 'grub_install_devices': ['/dev/vdb'] } self.subp_output.append(('', '')) - curthooks.setup_grub(cfg, self.target) + curthooks.setup_grub(cfg, self.target, osfamily=self.distro_family) self.assertEquals( ([ 'sh', '-c', 'exec "$0" "$@" 2>&1', - 'install-grub', self.target, '/dev/vdb'],), + 'install-grub', '--os-family=%s' % self.distro_family, + self.target, '/dev/vdb'],), self.mock_subp.call_args_list[0][0]) def test_uses_install_devices_in_grubcfg(self): @@ -233,11 +289,12 @@ class TestSetupGrub(CiTestCase): }, } self.subp_output.append(('', '')) - curthooks.setup_grub(cfg, self.target) + curthooks.setup_grub(cfg, self.target, osfamily=self.distro_family) self.assertEquals( ([ 'sh', '-c', 'exec "$0" "$@" 2>&1', - 'install-grub', self.target, '/dev/vdb'],), + 'install-grub', '--os-family=%s' % self.distro_family, + self.target, '/dev/vdb'],), self.mock_subp.call_args_list[0][0]) def test_uses_grub_install_on_storage_config(self): @@ -255,11 +312,12 @@ class TestSetupGrub(CiTestCase): }, } self.subp_output.append(('', '')) - curthooks.setup_grub(cfg, self.target) + curthooks.setup_grub(cfg, self.target, osfamily=self.distro_family) self.assertEquals( ([ 'sh', '-c', 'exec "$0" "$@" 2>&1', - 'install-grub', self.target, '/dev/vdb'],), + 'install-grub', '--os-family=%s' % self.distro_family, + self.target, '/dev/vdb'],), self.mock_subp.call_args_list[0][0]) def test_grub_install_installs_to_none_if_install_devices_None(self): @@ -269,62 +327,17 @@ class TestSetupGrub(CiTestCase): }, } self.subp_output.append(('', '')) - curthooks.setup_grub(cfg, self.target) - self.assertEquals( - ([ - 'sh', '-c', 'exec "$0" "$@" 2>&1', - 'install-grub', self.target, 'none'],), - self.mock_subp.call_args_list[0][0]) - - def test_grub_install_uefi_installs_signed_packages_for_amd64(self): - self.add_patch('curtin.util.install_packages', 'mock_install') - self.add_patch('curtin.util.has_pkg_available', 'mock_haspkg') - self.mock_is_uefi_bootable.return_value = True - cfg = { - 'grub': { - 'install_devices': ['/dev/vdb'], - 'update_nvram': False, - }, - } - self.subp_output.append(('', '')) - self.mock_arch.return_value = 'amd64' - self.mock_haspkg.return_value = True - curthooks.setup_grub(cfg, self.target) - self.assertEquals( - (['grub-efi-amd64', 'grub-efi-amd64-signed', 'shim-signed'],), - self.mock_install.call_args_list[0][0]) + curthooks.setup_grub(cfg, self.target, osfamily=self.distro_family) self.assertEquals( ([ 'sh', '-c', 'exec "$0" "$@" 2>&1', - 'install-grub', '--uefi', self.target, '/dev/vdb'],), - self.mock_subp.call_args_list[0][0]) - - def test_grub_install_uefi_installs_packages_for_arm64(self): - self.add_patch('curtin.util.install_packages', 'mock_install') - self.add_patch('curtin.util.has_pkg_available', 'mock_haspkg') - self.mock_is_uefi_bootable.return_value = True - cfg = { - 'grub': { - 'install_devices': ['/dev/vdb'], - 'update_nvram': False, - }, - } - self.subp_output.append(('', '')) - self.mock_arch.return_value = 'arm64' - self.mock_haspkg.return_value = False - curthooks.setup_grub(cfg, self.target) - self.assertEquals( - (['grub-efi-arm64'],), - self.mock_install.call_args_list[0][0]) - self.assertEquals( - ([ - 'sh', '-c', 'exec "$0" "$@" 2>&1', - 'install-grub', '--uefi', self.target, '/dev/vdb'],), + 'install-grub', '--os-family=%s' % self.distro_family, + self.target, 'none'],), self.mock_subp.call_args_list[0][0]) def test_grub_install_uefi_updates_nvram_skips_remove_and_reorder(self): - self.add_patch('curtin.util.install_packages', 'mock_install') - self.add_patch('curtin.util.has_pkg_available', 'mock_haspkg') + self.add_patch('curtin.distro.install_packages', 'mock_install') + self.add_patch('curtin.distro.has_pkg_available', 'mock_haspkg') self.add_patch('curtin.util.get_efibootmgr', 'mock_efibootmgr') self.mock_is_uefi_bootable.return_value = True cfg = { @@ -347,17 +360,18 @@ class TestSetupGrub(CiTestCase): } } } - curthooks.setup_grub(cfg, self.target) + curthooks.setup_grub(cfg, self.target, osfamily=self.distro_family) self.assertEquals( ([ 'sh', '-c', 'exec "$0" "$@" 2>&1', 'install-grub', '--uefi', '--update-nvram', + '--os-family=%s' % self.distro_family, self.target, '/dev/vdb'],), self.mock_subp.call_args_list[0][0]) def test_grub_install_uefi_updates_nvram_removes_old_loaders(self): - self.add_patch('curtin.util.install_packages', 'mock_install') - self.add_patch('curtin.util.has_pkg_available', 'mock_haspkg') + self.add_patch('curtin.distro.install_packages', 'mock_install') + self.add_patch('curtin.distro.has_pkg_available', 'mock_haspkg') self.add_patch('curtin.util.get_efibootmgr', 'mock_efibootmgr') self.mock_is_uefi_bootable.return_value = True cfg = { @@ -392,7 +406,7 @@ class TestSetupGrub(CiTestCase): self.in_chroot_subp_output.append(('', '')) self.in_chroot_subp_output.append(('', '')) self.mock_haspkg.return_value = False - curthooks.setup_grub(cfg, self.target) + curthooks.setup_grub(cfg, self.target, osfamily=self.distro_family) self.assertEquals( ['efibootmgr', '-B', '-b'], self.mock_in_chroot_subp.call_args_list[0][0][0][:3]) @@ -406,8 +420,8 @@ class TestSetupGrub(CiTestCase): self.mock_in_chroot_subp.call_args_list[1][0][0][3]])) def test_grub_install_uefi_updates_nvram_reorders_loaders(self): - self.add_patch('curtin.util.install_packages', 'mock_install') - self.add_patch('curtin.util.has_pkg_available', 'mock_haspkg') + self.add_patch('curtin.distro.install_packages', 'mock_install') + self.add_patch('curtin.distro.has_pkg_available', 'mock_haspkg') self.add_patch('curtin.util.get_efibootmgr', 'mock_efibootmgr') self.mock_is_uefi_bootable.return_value = True cfg = { @@ -436,7 +450,7 @@ class TestSetupGrub(CiTestCase): } self.in_chroot_subp_output.append(('', '')) self.mock_haspkg.return_value = False - curthooks.setup_grub(cfg, self.target) + curthooks.setup_grub(cfg, self.target, osfamily=self.distro_family) self.assertEquals( (['efibootmgr', '-o', '0001,0000'],), self.mock_in_chroot_subp.call_args_list[0][0]) @@ -453,11 +467,11 @@ class TestUbuntuCoreHooks(CiTestCase): 'var/lib/snapd') util.ensure_dir(ubuntu_core_path) self.assertTrue(os.path.isdir(ubuntu_core_path)) - is_core = curthooks.target_is_ubuntu_core(self.target) + is_core = distro.is_ubuntu_core(self.target) self.assertTrue(is_core) def test_target_is_ubuntu_core_no_target(self): - is_core = curthooks.target_is_ubuntu_core(self.target) + is_core = distro.is_ubuntu_core(self.target) self.assertFalse(is_core) def test_target_is_ubuntu_core_noncore_target(self): @@ -465,7 +479,7 @@ class TestUbuntuCoreHooks(CiTestCase): non_core_path = os.path.join(self.target, 'curtin') util.ensure_dir(non_core_path) self.assertTrue(os.path.isdir(non_core_path)) - is_core = curthooks.target_is_ubuntu_core(self.target) + is_core = distro.is_ubuntu_core(self.target) self.assertFalse(is_core) @patch('curtin.util.write_file') @@ -736,15 +750,15 @@ class TestDetectRequiredPackages(CiTestCase): ({'network': { 'version': 2, 'items': ('bridge',)}}, - ('bridge-utils',)), + ()), ({'network': { 'version': 2, 'items': ('vlan',)}}, - ('vlan',)), + ()), ({'network': { 'version': 2, 'items': ('vlan', 'bridge')}}, - ('vlan', 'bridge-utils')), + ()), )) def test_mixed_storage_v1_network_v2_detect(self): @@ -755,7 +769,7 @@ class TestDetectRequiredPackages(CiTestCase): 'storage': { 'version': 1, 'items': ('raid', 'bcache', 'ext4')}}, - ('vlan', 'bridge-utils', 'mdadm', 'bcache-tools', 'e2fsprogs')), + ('mdadm', 'bcache-tools', 'e2fsprogs')), )) def test_invalid_version_in_config(self): @@ -782,7 +796,7 @@ class TestCurthooksWriteFiles(CiTestCase): dict((cfg[i]['path'], cfg[i]['content']) for i in cfg.keys()), dir2dict(tmpd, prefix=tmpd)) - @patch('curtin.commands.curthooks.futil.target_path') + @patch('curtin.commands.curthooks.paths.target_path') @patch('curtin.commands.curthooks.futil.write_finfo') def test_handle_write_files_finfo(self, mock_write_finfo, mock_tp): """ Validate that futils.write_files handles target_path correctly """ @@ -816,6 +830,8 @@ class TestCurthooksPollinate(CiTestCase): self.add_patch('curtin.util.write_file', 'mock_write') self.add_patch('curtin.commands.curthooks.get_maas_version', 'mock_maas_version') + self.add_patch('curtin.util.which', 'mock_which') + self.mock_which.return_value = '/usr/bin/pollinate' self.target = self.tmp_dir() def test_handle_pollinate_user_agent_disable(self): @@ -826,6 +842,15 @@ class TestCurthooksPollinate(CiTestCase): self.assertEqual(0, self.mock_maas_version.call_count) self.assertEqual(0, self.mock_write.call_count) + def test_handle_pollinate_returns_if_no_pollinate_binary(self): + """ handle_pollinate_user_agent does nothing if no pollinate binary""" + self.mock_which.return_value = None + cfg = {'reporting': {'maas': {'endpoint': 'http://127.0.0.1/foo'}}} + curthooks.handle_pollinate_user_agent(cfg, self.target) + self.assertEqual(0, self.mock_curtin_version.call_count) + self.assertEqual(0, self.mock_maas_version.call_count) + self.assertEqual(0, self.mock_write.call_count) + def test_handle_pollinate_user_agent_default(self): """ handle_pollinate_user_agent checks curtin/maas version by default """ diff --git a/tests/unittests/test_distro.py b/tests/unittests/test_distro.py new file mode 100644 index 00000000..d4e5a1e2 --- /dev/null +++ b/tests/unittests/test_distro.py @@ -0,0 +1,302 @@ +# This file is part of curtin. See LICENSE file for copyright and license info. + +from unittest import skipIf +import mock +import sys + +from curtin import distro +from curtin import paths +from curtin import util +from .helpers import CiTestCase + + +class TestLsbRelease(CiTestCase): + + def setUp(self): + super(TestLsbRelease, self).setUp() + self._reset_cache() + + def _reset_cache(self): + keys = [k for k in distro._LSB_RELEASE.keys()] + for d in keys: + del distro._LSB_RELEASE[d] + + @mock.patch("curtin.distro.subp") + def test_lsb_release_functional(self, mock_subp): + output = '\n'.join([ + "Distributor ID: Ubuntu", + "Description: Ubuntu 14.04.2 LTS", + "Release: 14.04", + "Codename: trusty", + ]) + rdata = {'id': 'Ubuntu', 'description': 'Ubuntu 14.04.2 LTS', + 'codename': 'trusty', 'release': '14.04'} + + def fake_subp(cmd, capture=False, target=None): + return output, 'No LSB modules are available.' + + mock_subp.side_effect = fake_subp + found = distro.lsb_release() + mock_subp.assert_called_with( + ['lsb_release', '--all'], capture=True, target=None) + self.assertEqual(found, rdata) + + @mock.patch("curtin.distro.subp") + def test_lsb_release_unavailable(self, mock_subp): + def doraise(*args, **kwargs): + raise util.ProcessExecutionError("foo") + mock_subp.side_effect = doraise + + expected = {k: "UNAVAILABLE" for k in + ('id', 'description', 'codename', 'release')} + self.assertEqual(distro.lsb_release(), expected) + + +class TestParseDpkgVersion(CiTestCase): + """test parse_dpkg_version.""" + + def test_none_raises_type_error(self): + self.assertRaises(TypeError, distro.parse_dpkg_version, None) + + @skipIf(sys.version_info.major < 3, "python 2 bytes are strings.") + def test_bytes_raises_type_error(self): + self.assertRaises(TypeError, distro.parse_dpkg_version, b'1.2.3-0') + + def test_simple_native_package_version(self): + """dpkg versions must have a -. If not present expect value error.""" + self.assertEqual( + {'major': 2, 'minor': 28, 'micro': 0, 'extra': None, + 'raw': '2.28', 'upstream': '2.28', 'name': 'germinate', + 'semantic_version': 22800}, + distro.parse_dpkg_version('2.28', name='germinate')) + + def test_complex_native_package_version(self): + dver = '1.0.106ubuntu2+really1.0.97ubuntu1' + self.assertEqual( + {'major': 1, 'minor': 0, 'micro': 106, + 'extra': 'ubuntu2+really1.0.97ubuntu1', + 'raw': dver, 'upstream': dver, 'name': 'debootstrap', + 'semantic_version': 100106}, + distro.parse_dpkg_version(dver, name='debootstrap', + semx=(100000, 1000, 1))) + + def test_simple_valid(self): + self.assertEqual( + {'major': 1, 'minor': 2, 'micro': 3, 'extra': None, + 'raw': '1.2.3-0', 'upstream': '1.2.3', 'name': 'foo', + 'semantic_version': 10203}, + distro.parse_dpkg_version('1.2.3-0', name='foo')) + + def test_simple_valid_with_semx(self): + self.assertEqual( + {'major': 1, 'minor': 2, 'micro': 3, 'extra': None, + 'raw': '1.2.3-0', 'upstream': '1.2.3', + 'semantic_version': 123}, + distro.parse_dpkg_version('1.2.3-0', semx=(100, 10, 1))) + + def test_upstream_with_hyphen(self): + """upstream versions may have a hyphen.""" + cver = '18.2-14-g6d48d265-0ubuntu1' + self.assertEqual( + {'major': 18, 'minor': 2, 'micro': 0, 'extra': '-14-g6d48d265', + 'raw': cver, 'upstream': '18.2-14-g6d48d265', + 'name': 'cloud-init', 'semantic_version': 180200}, + distro.parse_dpkg_version(cver, name='cloud-init')) + + def test_upstream_with_plus(self): + """multipath tools has a + in it.""" + mver = '0.5.0+git1.656f8865-5ubuntu2.5' + self.assertEqual( + {'major': 0, 'minor': 5, 'micro': 0, 'extra': '+git1.656f8865', + 'raw': mver, 'upstream': '0.5.0+git1.656f8865', + 'semantic_version': 500}, + distro.parse_dpkg_version(mver)) + + +class TestDistros(CiTestCase): + + def test_distro_names(self): + all_distros = list(distro.DISTROS) + for distro_name in distro.DISTRO_NAMES: + distro_enum = getattr(distro.DISTROS, distro_name) + self.assertIn(distro_enum, all_distros) + + def test_distro_names_unknown(self): + distro_name = "ImNotADistro" + self.assertNotIn(distro_name, distro.DISTRO_NAMES) + with self.assertRaises(AttributeError): + getattr(distro.DISTROS, distro_name) + + def test_distro_osfamily(self): + for variant, family in distro.OS_FAMILIES.items(): + self.assertNotEqual(variant, family) + self.assertIn(variant, distro.DISTROS) + for dname in family: + self.assertIn(dname, distro.DISTROS) + + def test_distro_osfmaily_identity(self): + for family, variants in distro.OS_FAMILIES.items(): + self.assertIn(family, variants) + + def test_name_to_distro(self): + for distro_name in distro.DISTRO_NAMES: + dobj = distro.name_to_distro(distro_name) + self.assertEqual(dobj, getattr(distro.DISTROS, distro_name)) + + def test_name_to_distro_unknown_value(self): + with self.assertRaises(ValueError): + distro.name_to_distro(None) + + def test_name_to_distro_unknown_attr(self): + with self.assertRaises(ValueError): + distro.name_to_distro('NotADistro') + + def test_distros_unknown_attr(self): + with self.assertRaises(AttributeError): + distro.DISTROS.notadistro + + def test_distros_unknown_index(self): + with self.assertRaises(IndexError): + distro.DISTROS[len(distro.DISTROS)+1] + + +class TestDistroInfo(CiTestCase): + + def setUp(self): + super(TestDistroInfo, self).setUp() + self.add_patch('curtin.distro.os_release', 'mock_os_release') + + def test_get_distroinfo(self): + for distro_name in distro.DISTRO_NAMES: + self.mock_os_release.return_value = {'ID': distro_name} + variant = distro.name_to_distro(distro_name) + family = distro.DISTRO_TO_OSFAMILY[variant] + distro_info = distro.get_distroinfo() + self.assertEqual(variant, distro_info.variant) + self.assertEqual(family, distro_info.family) + + def test_get_distro(self): + for distro_name in distro.DISTRO_NAMES: + self.mock_os_release.return_value = {'ID': distro_name} + variant = distro.name_to_distro(distro_name) + distro_obj = distro.get_distro() + self.assertEqual(variant, distro_obj) + + def test_get_osfamily(self): + for distro_name in distro.DISTRO_NAMES: + self.mock_os_release.return_value = {'ID': distro_name} + variant = distro.name_to_distro(distro_name) + family = distro.DISTRO_TO_OSFAMILY[variant] + distro_obj = distro.get_osfamily() + self.assertEqual(family, distro_obj) + + +class TestDistroIdentity(CiTestCase): + + def setUp(self): + super(TestDistroIdentity, self).setUp() + self.add_patch('curtin.distro.os.path.exists', 'mock_os_path') + + def test_is_ubuntu_core(self): + for exists in [True, False]: + self.mock_os_path.return_value = exists + self.assertEqual(exists, distro.is_ubuntu_core()) + self.mock_os_path.assert_called_with('/system-data/var/lib/snapd') + + def test_is_centos(self): + for exists in [True, False]: + self.mock_os_path.return_value = exists + self.assertEqual(exists, distro.is_centos()) + self.mock_os_path.assert_called_with('/etc/centos-release') + + def test_is_rhel(self): + for exists in [True, False]: + self.mock_os_path.return_value = exists + self.assertEqual(exists, distro.is_rhel()) + self.mock_os_path.assert_called_with('/etc/redhat-release') + + +class TestYumInstall(CiTestCase): + + @mock.patch.object(util.ChrootableTarget, "__enter__", new=lambda a: a) + @mock.patch('curtin.util.subp') + def test_yum_install(self, m_subp): + pkglist = ['foobar', 'wark'] + target = 'mytarget' + mode = 'install' + expected_calls = [ + mock.call(['yum', '--assumeyes', '--quiet', 'install', + '--downloadonly', '--setopt=keepcache=1'] + pkglist, + env=None, retries=[1] * 10, + target=paths.target_path(target)), + mock.call(['yum', '--assumeyes', '--quiet', 'install', + '--cacheonly'] + pkglist, env=None, + target=paths.target_path(target)) + ] + + # call yum_install directly + distro.yum_install(mode, pkglist, target=target) + m_subp.assert_has_calls(expected_calls) + + # call yum_install through run_yum_command + m_subp.reset() + distro.run_yum_command('install', pkglist, target=target) + m_subp.assert_has_calls(expected_calls) + + # call yum_install through install_packages + m_subp.reset() + osfamily = distro.DISTROS.redhat + distro.install_packages(pkglist, osfamily=osfamily, target=target) + m_subp.assert_has_calls(expected_calls) + + +class TestHasPkgAvailable(CiTestCase): + + def setUp(self): + super(TestHasPkgAvailable, self).setUp() + self.package = 'foobar' + self.target = paths.target_path('mytarget') + + @mock.patch.object(util.ChrootableTarget, "__enter__", new=lambda a: a) + @mock.patch('curtin.distro.subp') + def test_has_pkg_available_debian(self, m_subp): + osfamily = distro.DISTROS.debian + m_subp.return_value = (self.package, '') + result = distro.has_pkg_available(self.package, self.target, osfamily) + self.assertTrue(result) + m_subp.assert_has_calls([mock.call(['apt-cache', 'pkgnames'], + capture=True, + target=self.target)]) + + @mock.patch.object(util.ChrootableTarget, "__enter__", new=lambda a: a) + @mock.patch('curtin.distro.subp') + def test_has_pkg_available_debian_returns_false_not_avail(self, m_subp): + pkg = 'wark' + osfamily = distro.DISTROS.debian + m_subp.return_value = (pkg, '') + result = distro.has_pkg_available(self.package, self.target, osfamily) + self.assertEqual(pkg == self.package, result) + m_subp.assert_has_calls([mock.call(['apt-cache', 'pkgnames'], + capture=True, + target=self.target)]) + + @mock.patch.object(util.ChrootableTarget, "__enter__", new=lambda a: a) + @mock.patch('curtin.distro.run_yum_command') + def test_has_pkg_available_redhat(self, m_subp): + osfamily = distro.DISTROS.redhat + m_subp.return_value = (self.package, '') + result = distro.has_pkg_available(self.package, self.target, osfamily) + self.assertTrue(result) + m_subp.assert_has_calls([mock.call('list', opts=['--cacheonly'])]) + + @mock.patch.object(util.ChrootableTarget, "__enter__", new=lambda a: a) + @mock.patch('curtin.distro.run_yum_command') + def test_has_pkg_available_redhat_returns_false_not_avail(self, m_subp): + pkg = 'wark' + osfamily = distro.DISTROS.redhat + m_subp.return_value = (pkg, '') + result = distro.has_pkg_available(self.package, self.target, osfamily) + self.assertEqual(pkg == self.package, result) + m_subp.assert_has_calls([mock.call('list', opts=['--cacheonly'])]) + +# vi: ts=4 expandtab syntax=python diff --git a/tests/unittests/test_feature.py b/tests/unittests/test_feature.py index c62e0cdd..7c558821 100644 --- a/tests/unittests/test_feature.py +++ b/tests/unittests/test_feature.py @@ -21,4 +21,7 @@ class TestExportsFeatures(CiTestCase): def test_has_centos_apply_network_config(self): self.assertIn('CENTOS_APPLY_NETWORK_CONFIG', curtin.FEATURES) + def test_has_centos_curthook_support(self): + self.assertIn('CENTOS_CURTHOOK_SUPPORT', curtin.FEATURES) + # vi: ts=4 expandtab syntax=python diff --git a/tests/unittests/test_pack.py b/tests/unittests/test_pack.py index 1aae4567..cb0b135e 100644 --- a/tests/unittests/test_pack.py +++ b/tests/unittests/test_pack.py @@ -97,6 +97,8 @@ class TestPack(TestCase): }} out, err, rc, log_contents = self.run_install(cfg) + print("out=%s" % out) + print("err=%s" % err) # the version string and users command output should be in output self.assertIn(version.version_string(), out) diff --git a/tests/unittests/test_util.py b/tests/unittests/test_util.py index 7fb332d2..a64be162 100644 --- a/tests/unittests/test_util.py +++ b/tests/unittests/test_util.py @@ -4,10 +4,10 @@ from unittest import skipIf import mock import os import stat -import sys from textwrap import dedent from curtin import util +from curtin import paths from .helpers import CiTestCase, simple_mocked_open @@ -104,48 +104,6 @@ class TestWhich(CiTestCase): self.assertEqual(found, "/usr/bin2/fuzz") -class TestLsbRelease(CiTestCase): - - def setUp(self): - super(TestLsbRelease, self).setUp() - self._reset_cache() - - def _reset_cache(self): - keys = [k for k in util._LSB_RELEASE.keys()] - for d in keys: - del util._LSB_RELEASE[d] - - @mock.patch("curtin.util.subp") - def test_lsb_release_functional(self, mock_subp): - output = '\n'.join([ - "Distributor ID: Ubuntu", - "Description: Ubuntu 14.04.2 LTS", - "Release: 14.04", - "Codename: trusty", - ]) - rdata = {'id': 'Ubuntu', 'description': 'Ubuntu 14.04.2 LTS', - 'codename': 'trusty', 'release': '14.04'} - - def fake_subp(cmd, capture=False, target=None): - return output, 'No LSB modules are available.' - - mock_subp.side_effect = fake_subp - found = util.lsb_release() - mock_subp.assert_called_with( - ['lsb_release', '--all'], capture=True, target=None) - self.assertEqual(found, rdata) - - @mock.patch("curtin.util.subp") - def test_lsb_release_unavailable(self, mock_subp): - def doraise(*args, **kwargs): - raise util.ProcessExecutionError("foo") - mock_subp.side_effect = doraise - - expected = {k: "UNAVAILABLE" for k in - ('id', 'description', 'codename', 'release')} - self.assertEqual(util.lsb_release(), expected) - - class TestSubp(CiTestCase): stdin2err = ['bash', '-c', 'cat >&2'] @@ -312,7 +270,7 @@ class TestSubp(CiTestCase): # if target is not provided or is /, chroot should not be used calls = m_popen.call_args_list popen_args, popen_kwargs = calls[-1] - target = util.target_path(kwargs.get('target', None)) + target = paths.target_path(kwargs.get('target', None)) unshcmd = self.mock_get_unshare_pid_args.return_value if target == "/": self.assertEqual(unshcmd + list(cmd), popen_args[0]) @@ -554,44 +512,44 @@ class TestSetUnExecutable(CiTestCase): class TestTargetPath(CiTestCase): def test_target_empty_string(self): - self.assertEqual("/etc/passwd", util.target_path("", "/etc/passwd")) + self.assertEqual("/etc/passwd", paths.target_path("", "/etc/passwd")) def test_target_non_string_raises(self): - self.assertRaises(ValueError, util.target_path, False) - self.assertRaises(ValueError, util.target_path, 9) - self.assertRaises(ValueError, util.target_path, True) + self.assertRaises(ValueError, paths.target_path, False) + self.assertRaises(ValueError, paths.target_path, 9) + self.assertRaises(ValueError, paths.target_path, True) def test_lots_of_slashes_is_slash(self): - self.assertEqual("/", util.target_path("/")) - self.assertEqual("/", util.target_path("//")) - self.assertEqual("/", util.target_path("///")) - self.assertEqual("/", util.target_path("////")) + self.assertEqual("/", paths.target_path("/")) + self.assertEqual("/", paths.target_path("//")) + self.assertEqual("/", paths.target_path("///")) + self.assertEqual("/", paths.target_path("////")) def test_empty_string_is_slash(self): - self.assertEqual("/", util.target_path("")) + self.assertEqual("/", paths.target_path("")) def test_recognizes_relative(self): - self.assertEqual("/", util.target_path("/foo/../")) - self.assertEqual("/", util.target_path("/foo//bar/../../")) + self.assertEqual("/", paths.target_path("/foo/../")) + self.assertEqual("/", paths.target_path("/foo//bar/../../")) def test_no_path(self): - self.assertEqual("/my/target", util.target_path("/my/target")) + self.assertEqual("/my/target", paths.target_path("/my/target")) def test_no_target_no_path(self): - self.assertEqual("/", util.target_path(None)) + self.assertEqual("/", paths.target_path(None)) def test_no_target_with_path(self): - self.assertEqual("/my/path", util.target_path(None, "/my/path")) + self.assertEqual("/my/path", paths.target_path(None, "/my/path")) def test_trailing_slash(self): self.assertEqual("/my/target/my/path", - util.target_path("/my/target/", "/my/path")) + paths.target_path("/my/target/", "/my/path")) def test_bunch_of_slashes_in_path(self): self.assertEqual("/target/my/path/", - util.target_path("/target/", "//my/path/")) + paths.target_path("/target/", "//my/path/")) self.assertEqual("/target/my/path/", - util.target_path("/target/", "///my/path/")) + paths.target_path("/target/", "///my/path/")) class TestRunInChroot(CiTestCase): @@ -1036,65 +994,4 @@ class TestLoadKernelModule(CiTestCase): self.assertEqual(0, self.m_subp.call_count) -class TestParseDpkgVersion(CiTestCase): - """test parse_dpkg_version.""" - - def test_none_raises_type_error(self): - self.assertRaises(TypeError, util.parse_dpkg_version, None) - - @skipIf(sys.version_info.major < 3, "python 2 bytes are strings.") - def test_bytes_raises_type_error(self): - self.assertRaises(TypeError, util.parse_dpkg_version, b'1.2.3-0') - - def test_simple_native_package_version(self): - """dpkg versions must have a -. If not present expect value error.""" - self.assertEqual( - {'major': 2, 'minor': 28, 'micro': 0, 'extra': None, - 'raw': '2.28', 'upstream': '2.28', 'name': 'germinate', - 'semantic_version': 22800}, - util.parse_dpkg_version('2.28', name='germinate')) - - def test_complex_native_package_version(self): - dver = '1.0.106ubuntu2+really1.0.97ubuntu1' - self.assertEqual( - {'major': 1, 'minor': 0, 'micro': 106, - 'extra': 'ubuntu2+really1.0.97ubuntu1', - 'raw': dver, 'upstream': dver, 'name': 'debootstrap', - 'semantic_version': 100106}, - util.parse_dpkg_version(dver, name='debootstrap', - semx=(100000, 1000, 1))) - - def test_simple_valid(self): - self.assertEqual( - {'major': 1, 'minor': 2, 'micro': 3, 'extra': None, - 'raw': '1.2.3-0', 'upstream': '1.2.3', 'name': 'foo', - 'semantic_version': 10203}, - util.parse_dpkg_version('1.2.3-0', name='foo')) - - def test_simple_valid_with_semx(self): - self.assertEqual( - {'major': 1, 'minor': 2, 'micro': 3, 'extra': None, - 'raw': '1.2.3-0', 'upstream': '1.2.3', - 'semantic_version': 123}, - util.parse_dpkg_version('1.2.3-0', semx=(100, 10, 1))) - - def test_upstream_with_hyphen(self): - """upstream versions may have a hyphen.""" - cver = '18.2-14-g6d48d265-0ubuntu1' - self.assertEqual( - {'major': 18, 'minor': 2, 'micro': 0, 'extra': '-14-g6d48d265', - 'raw': cver, 'upstream': '18.2-14-g6d48d265', - 'name': 'cloud-init', 'semantic_version': 180200}, - util.parse_dpkg_version(cver, name='cloud-init')) - - def test_upstream_with_plus(self): - """multipath tools has a + in it.""" - mver = '0.5.0+git1.656f8865-5ubuntu2.5' - self.assertEqual( - {'major': 0, 'minor': 5, 'micro': 0, 'extra': '+git1.656f8865', - 'raw': mver, 'upstream': '0.5.0+git1.656f8865', - 'semantic_version': 500}, - util.parse_dpkg_version(mver)) - - # vi: ts=4 expandtab syntax=python diff --git a/tests/vmtests/__init__.py b/tests/vmtests/__init__.py index bd159c4b..7e314914 100644 --- a/tests/vmtests/__init__.py +++ b/tests/vmtests/__init__.py @@ -493,18 +493,67 @@ def skip_by_date(bugnum, fixby, removeby=None, skips=None, install=True): return decorator +DEFAULT_COLLECT_SCRIPTS = { + 'common': [textwrap.dedent(""" + cd OUTPUT_COLLECT_D + cp /etc/fstab ./fstab + cp -a /etc/udev/rules.d ./udev_rules.d + ifconfig -a | cat >ifconfig_a + ip a | cat >ip_a + cp -a /var/log/messages . + cp -a /var/log/syslog . + cp -a /var/log/cloud-init* . + cp -a /var/lib/cloud ./var_lib_cloud + cp -a /run/cloud-init ./run_cloud-init + cp -a /proc/cmdline ./proc_cmdline + cp -a /proc/mounts ./proc_mounts + cp -a /proc/partitions ./proc_partitions + cp -a /proc/swaps ./proc-swaps + # ls -al /dev/disk/* + mkdir -p /dev/disk/by-dname + ls /dev/disk/by-dname/ | cat >ls_dname + ls -al /dev/disk/by-dname/ | cat >ls_al_bydname + ls -al /dev/disk/by-id/ | cat >ls_al_byid + ls -al /dev/disk/by-uuid/ | cat >ls_al_byuuid + blkid -o export | cat >blkid.out + find /boot | cat > find_boot.out + [ -e /sys/firmware/efi ] && { + efibootmgr -v | cat >efibootmgr.out; + } + """)], + 'centos': [textwrap.dedent(""" + # XXX: command | cat >output is required for Centos under SELinux + # http://danwalsh.livejournal.com/22860.html + cd OUTPUT_COLLECT_D + rpm -qa | cat >rpm_qa + cp -a /etc/sysconfig/network-scripts . + rpm -q --queryformat '%{VERSION}\n' cloud-init |tee rpm_ci_version + rpm -E '%rhel' > rpm_dist_version_major + cp -a /etc/centos-release . + """)], + 'ubuntu': [textwrap.dedent(""" + cd OUTPUT_COLLECT_D + dpkg-query --show \ + --showformat='${db:Status-Abbrev}\t${Package}\t${Version}\n' \ + > debian-packages.txt 2> debian-packages.txt.err + cp -av /etc/network/interfaces . + cp -av /etc/network/interfaces.d . + find /etc/network/interfaces.d > find_interfacesd + v="" + out=$(apt-config shell v Acquire::HTTP::Proxy) + eval "$out" + echo "$v" > apt-proxy + """)] +} + + class VMBaseClass(TestCase): __test__ = False expected_failure = False arch_skip = [] boot_timeout = BOOT_TIMEOUT - collect_scripts = [textwrap.dedent(""" - cd OUTPUT_COLLECT_D - dpkg-query --show \ - --showformat='${db:Status-Abbrev}\t${Package}\t${Version}\n' \ - > debian-packages.txt 2> debian-packages.txt.err - cat /proc/swaps > proc-swaps - """)] + collect_scripts = [] + extra_collect_scripts = [] conf_file = "examples/tests/basic.yaml" nr_cpus = None dirty_disks = False @@ -528,6 +577,10 @@ class VMBaseClass(TestCase): conf_replace = {} uefi = False proxy = None + url_map = { + '/MAAS/api/version/': '2.0', + '/MAAS/api/2.0/version/': + json.dumps({'version': '2.5.0+curtin-vmtest'})} # these get set from base_vm_classes release = None @@ -773,6 +826,16 @@ class VMBaseClass(TestCase): cls.arch) raise SkipTest(reason) + # assign default collect scripts + if not cls.collect_scripts: + cls.collect_scripts = ( + DEFAULT_COLLECT_SCRIPTS['common'] + + DEFAULT_COLLECT_SCRIPTS[cls.target_distro]) + + # append extra from subclass + if cls.extra_collect_scripts: + cls.collect_scripts.extend(cls.extra_collect_scripts) + setup_start = time.time() logger.info( ('Starting setup for testclass: {__name__} ' @@ -994,7 +1057,8 @@ class VMBaseClass(TestCase): # set reporting logger cls.reporting_log = os.path.join(cls.td.logs, 'webhooks-events.json') - reporting_logger = CaptureReporting(cls.reporting_log) + reporting_logger = CaptureReporting(cls.reporting_log, + url_mapping=cls.url_map) # write reporting config reporting_config = os.path.join(cls.td.install, 'reporting.cfg') @@ -1442,6 +1506,8 @@ class VMBaseClass(TestCase): if self.target_release == "trusty": raise SkipTest( "(LP: #1523037): dname does not work on trusty kernels") + if self.target_distro != "ubuntu": + raise SkipTest("dname not present in non-ubuntu releases") if not disk_to_check: disk_to_check = self.disk_to_check @@ -1449,11 +1515,9 @@ class VMBaseClass(TestCase): logger.debug('test_dname: no disks to check') return logger.debug('test_dname: checking disks: %s', disk_to_check) - path = self.collect_path("ls_dname") - if not os.path.exists(path): - logger.debug('test_dname: no "ls_dname" file: %s', path) - return - contents = util.load_file(path) + self.output_files_exist(["ls_dname"]) + + contents = self.load_collect_file("ls_dname") for diskname, part in self.disk_to_check: if part is not 0: link = diskname + "-part" + str(part) @@ -1485,6 +1549,9 @@ class VMBaseClass(TestCase): """ Check that curtin has removed /etc/network/interfaces.d/eth0.cfg by examining the output of a find /etc/network > find_interfaces.d """ + # target_distro is set for non-ubuntu targets + if self.target_distro != 'ubuntu': + raise SkipTest("eni/ifupdown not present in non-ubuntu releases") interfacesd = self.load_collect_file("find_interfacesd") self.assertNotIn("/etc/network/interfaces.d/eth0.cfg", interfacesd.split("\n")) diff --git a/tests/vmtests/helpers.py b/tests/vmtests/helpers.py index 10e20b3e..6dddcc6e 100644 --- a/tests/vmtests/helpers.py +++ b/tests/vmtests/helpers.py @@ -2,6 +2,7 @@ # This file is part of curtin. See LICENSE file for copyright and license info. import os +import re import subprocess import signal import threading @@ -86,7 +87,26 @@ def check_call(cmd, signal=signal.SIGTERM, **kwargs): return Command(cmd, signal).run(**kwargs) -def find_testcases(): +def find_testcases_by_attr(**kwargs): + class_match = set() + for test_case in find_testcases(**kwargs): + tc_name = str(test_case.__class__) + full_path = tc_name.split("'")[1].split(".") + class_name = full_path[-1] + if class_name in class_match: + continue + class_match.add(class_name) + filename = "/".join(full_path[0:-1]) + ".py" + yield "%s:%s" % (filename, class_name) + + +def _attr_match(pattern, value): + if not value: + return False + return re.match(pattern, str(value)) + + +def find_testcases(**kwargs): # Use the TestLoder to load all test cases defined within tests/vmtests/ # and figure out what distros and releases they are testing. Any tests # which are disabled will be excluded. @@ -97,12 +117,19 @@ def find_testcases(): root_dir = os.path.split(os.path.split(tests_dir)[0])[0] # Find all test modules defined in curtin/tests/vmtests/ module_test_suites = loader.discover(tests_dir, top_level_dir=root_dir) + filter_attrs = [attr for attr, value in kwargs.items() if value] for mts in module_test_suites: for class_test_suite in mts: for test_case in class_test_suite: # skip disabled tests if not getattr(test_case, '__test__', False): continue + # compare each filter attr with the specified value + tcmatch = [not _attr_match(kwargs[attr], + getattr(test_case, attr, False)) + for attr in filter_attrs] + if any(tcmatch): + continue yield test_case diff --git a/tests/vmtests/image_sync.py b/tests/vmtests/image_sync.py index e2cedc17..69c19ef3 100644 --- a/tests/vmtests/image_sync.py +++ b/tests/vmtests/image_sync.py @@ -30,7 +30,9 @@ IMAGE_SRC_URL = os.environ.get( "http://maas.ubuntu.com/images/ephemeral-v3/daily/streams/v1/index.sjson") IMAGE_DIR = os.environ.get("IMAGE_DIR", "/srv/images") -KEYRING = '/usr/share/keyrings/ubuntu-cloudimage-keyring.gpg' +KEYRING = os.environ.get( + 'IMAGE_SRC_KEYRING', + '/usr/share/keyrings/ubuntu-cloudimage-keyring.gpg') ITEM_NAME_FILTERS = \ ['ftype~(boot-initrd|boot-kernel|root-tgz|squashfs)'] FORMAT_JSON = 'JSON' diff --git a/tests/vmtests/releases.py b/tests/vmtests/releases.py index 02cbfe58..7be8feb4 100644 --- a/tests/vmtests/releases.py +++ b/tests/vmtests/releases.py @@ -131,8 +131,8 @@ class _Releases(object): class _CentosReleases(object): - centos70fromxenial = _Centos70FromXenialBase - centos66fromxenial = _Centos66FromXenialBase + centos70_xenial = _Centos70FromXenialBase + centos66_xenial = _Centos66FromXenialBase class _UbuntuCoreReleases(object): diff --git a/tests/vmtests/report_webhook_logger.py b/tests/vmtests/report_webhook_logger.py index e95397c7..5e7d63bf 100755 --- a/tests/vmtests/report_webhook_logger.py +++ b/tests/vmtests/report_webhook_logger.py @@ -76,7 +76,10 @@ class ServerHandler(http_server.SimpleHTTPRequestHandler): self._message = None self.send_response(200) self.end_headers() - self.wfile.write(("content of %s\n" % self.path).encode('utf-8')) + if self.url_mapping and self.path in self.url_mapping: + self.wfile.write(self.url_mapping[self.path].encode('utf-8')) + else: + self.wfile.write(("content of %s\n" % self.path).encode('utf-8')) def do_POST(self): length = int(self.headers['Content-Length']) @@ -96,13 +99,14 @@ class ServerHandler(http_server.SimpleHTTPRequestHandler): self.wfile.write(msg.encode('utf-8')) -def GenServerHandlerWithResultFile(file_path): +def GenServerHandlerWithResultFile(file_path, url_map): class ExtendedServerHandler(ServerHandler): result_log_file = file_path + url_mapping = url_map return ExtendedServerHandler -def get_httpd(port=None, result_file=None): +def get_httpd(port=None, result_file=None, url_mapping=None): # avoid 'Address already in use' after ctrl-c socketserver.TCPServer.allow_reuse_address = True @@ -111,7 +115,7 @@ def get_httpd(port=None, result_file=None): port = 0 if result_file: - Handler = GenServerHandlerWithResultFile(result_file) + Handler = GenServerHandlerWithResultFile(result_file, url_mapping) else: Handler = ServerHandler httpd = HTTPServerV6(("::", port), Handler) @@ -143,10 +147,11 @@ def run_server(port=DEFAULT_PORT, log_data=True): class CaptureReporting: - def __init__(self, result_file): + def __init__(self, result_file, url_mapping=None): + self.url_mapping = url_mapping self.result_file = result_file self.httpd = get_httpd(result_file=self.result_file, - port=None) + port=None, url_mapping=self.url_mapping) self.httpd.server_activate() # socket.AF_INET6 returns # (host, port, flowinfo, scopeid) diff --git a/tests/vmtests/test_apt_config_cmd.py b/tests/vmtests/test_apt_config_cmd.py index efd04f3e..f9b6a097 100644 --- a/tests/vmtests/test_apt_config_cmd.py +++ b/tests/vmtests/test_apt_config_cmd.py @@ -12,16 +12,14 @@ from .releases import base_vm_classes as relbase class TestAptConfigCMD(VMBaseClass): """TestAptConfigCMD - test standalone command""" + test_type = 'config' conf_file = "examples/tests/apt_config_command.yaml" interactive = False extra_disks = [] fstab_expected = {} disk_to_check = [] - collect_scripts = VMBaseClass.collect_scripts + [textwrap.dedent(""" + extra_collect_scripts = [textwrap.dedent(""" cd OUTPUT_COLLECT_D - cat /etc/fstab > fstab - ls /dev/disk/by-dname > ls_dname - find /etc/network/interfaces.d > find_interfacesd cp /etc/apt/sources.list.d/curtin-dev-ubuntu-test-archive-*.list . cp /etc/cloud/cloud.cfg.d/curtin-preserve-sources.cfg . apt-cache policy | grep proposed > proposed-enabled diff --git a/tests/vmtests/test_apt_source.py b/tests/vmtests/test_apt_source.py index f34913a3..bb502b2c 100644 --- a/tests/vmtests/test_apt_source.py +++ b/tests/vmtests/test_apt_source.py @@ -14,15 +14,13 @@ from curtin import util class TestAptSrcAbs(VMBaseClass): """TestAptSrcAbs - Basic tests for apt features of curtin""" + test_type = 'config' interactive = False extra_disks = [] fstab_expected = {} disk_to_check = [] - collect_scripts = VMBaseClass.collect_scripts + [textwrap.dedent(""" + extra_collect_scripts = [textwrap.dedent(""" cd OUTPUT_COLLECT_D - cat /etc/fstab > fstab - ls /dev/disk/by-dname > ls_dname - find /etc/network/interfaces.d > find_interfacesd apt-key list "F430BBA5" > keyid-F430BBA5 apt-key list "0165013E" > keyppa-0165013E apt-key list "F470A0AC" > keylongid-F470A0AC diff --git a/tests/vmtests/test_basic.py b/tests/vmtests/test_basic.py index 01ffc897..54e3df80 100644 --- a/tests/vmtests/test_basic.py +++ b/tests/vmtests/test_basic.py @@ -4,12 +4,14 @@ from . import ( VMBaseClass, get_apt_proxy) from .releases import base_vm_classes as relbase +from .releases import centos_base_vm_classes as centos_relbase import textwrap from unittest import SkipTest class TestBasicAbs(VMBaseClass): + test_type = 'storage' interactive = False nr_cpus = 2 dirty_disks = True @@ -18,29 +20,18 @@ class TestBasicAbs(VMBaseClass): nvme_disks = ['4G'] disk_to_check = [('main_disk_with_in---valid--dname', 1), ('main_disk_with_in---valid--dname', 2)] - collect_scripts = VMBaseClass.collect_scripts + [textwrap.dedent(""" + extra_collect_scripts = [textwrap.dedent(""" cd OUTPUT_COLLECT_D - blkid -o export /dev/vda > blkid_output_vda - blkid -o export /dev/vda1 > blkid_output_vda1 - blkid -o export /dev/vda2 > blkid_output_vda2 + blkid -o export /dev/vda | cat >blkid_output_vda + blkid -o export /dev/vda1 | cat >blkid_output_vda1 + blkid -o export /dev/vda2 | cat >blkid_output_vda2 dev="/dev/vdd"; f="btrfs_uuid_${dev#/dev/*}"; if command -v btrfs-debug-tree >/dev/null; then btrfs-debug-tree -r $dev | awk '/^uuid/ {print $2}' | grep "-" else btrfs inspect-internal dump-super $dev | awk '/^dev_item.fsid/ {print $2}' - fi > $f - cat /proc/partitions > proc_partitions - ls -al /dev/disk/by-uuid/ > ls_uuid - cat /etc/fstab > fstab - mkdir -p /dev/disk/by-dname - ls /dev/disk/by-dname/ > ls_dname - find /etc/network/interfaces.d > find_interfacesd - - v="" - out=$(apt-config shell v Acquire::HTTP::Proxy) - eval "$out" - echo "$v" > apt-proxy + fi | cat >$f """)] def _kname_to_uuid(self, kname): @@ -48,7 +39,7 @@ class TestBasicAbs(VMBaseClass): # parsing ls -al output on /dev/disk/by-uuid: # lrwxrwxrwx 1 root root 9 Dec 4 20:02 # d591e9e9-825a-4f0a-b280-3bfaf470b83c -> ../../vdg - ls_uuid = self.load_collect_file("ls_uuid") + ls_uuid = self.load_collect_file("ls_al_byuuid") uuid = [line.split()[8] for line in ls_uuid.split('\n') if ("../../" + kname) in line.split()] self.assertEqual(len(uuid), 1) @@ -57,81 +48,99 @@ class TestBasicAbs(VMBaseClass): self.assertEqual(len(uuid), 36) return uuid - def test_output_files_exist(self): - self.output_files_exist( - ["blkid_output_vda", "blkid_output_vda1", "blkid_output_vda2", - "btrfs_uuid_vdd", "fstab", "ls_dname", "ls_uuid", - "proc_partitions", - "root/curtin-install.log", "root/curtin-install-cfg.yaml"]) - - def test_ptable(self, disk_to_check=None): + def _test_ptable(self, blkid_output, expected): if self.target_release == "trusty": raise SkipTest("No PTTYPE blkid output on trusty") - blkid_info = self.get_blkid_data("blkid_output_vda") - self.assertEquals(blkid_info["PTTYPE"], "dos") + if not blkid_output: + raise RuntimeError('_test_ptable requires blkid output file') - def test_partition_numbers(self): - # vde should have partitions 1 and 10 - disk = "vde" + if not expected: + raise RuntimeError('_test_ptable requires expected value') + + self.output_files_exist([blkid_output]) + blkid_info = self.get_blkid_data(blkid_output) + self.assertEquals(expected, blkid_info["PTTYPE"]) + + def _test_partition_numbers(self, disk, expected): found = [] + self.output_files_exist(["proc_partitions"]) proc_partitions = self.load_collect_file('proc_partitions') for line in proc_partitions.splitlines(): if disk in line: found.append(line.split()[3]) - # /proc/partitions should have 3 lines with 'vde' in them. - expected = [disk + s for s in ["", "1", "10"]] - self.assertEqual(found, expected) - - def test_partitions(self): - fstab_lines = self.load_collect_file('fstab').splitlines() - print("\n".join(fstab_lines)) - # Test that vda1 is on / - blkid_info = self.get_blkid_data("blkid_output_vda1") - fstab_entry = None - for line in fstab_lines: - if blkid_info['UUID'] in line: - fstab_entry = line - break - self.assertIsNotNone(fstab_entry) - self.assertEqual(fstab_entry.split(' ')[1], "/") - - # Test that vda2 is on /home - blkid_info = self.get_blkid_data("blkid_output_vda2") - fstab_entry = None - for line in fstab_lines: - if blkid_info['UUID'] in line: - fstab_entry = line - break - self.assertIsNotNone(fstab_entry) - self.assertEqual(fstab_entry.split(' ')[1], "/home") - - # Test whole disk vdd is mounted at /btrfs - uuid = self._kname_to_uuid('vdd') - fstab_entry = None - for line in fstab_lines: - if uuid in line: - fstab_entry = line - break - self.assertIsNotNone(fstab_entry) - self.assertEqual(fstab_entry.split(' ')[1], "/btrfs") - self.assertEqual(fstab_entry.split(' ')[3], "defaults,noatime") - - def test_whole_disk_format(self): + self.assertEqual(expected, found) + + def _test_fstab_entries(self, fstab, byuuid, expected): + """ + expected = [ + (kname, mp, fsopts), + ... + ] + """ + self.output_files_exist([fstab, byuuid]) + fstab_lines = self.load_collect_file(fstab).splitlines() + for (kname, mp, fsopts) in expected: + uuid = self._kname_to_uuid(kname) + if not uuid: + raise RuntimeError('Did not find uuid for kname: %s', kname) + for line in fstab_lines: + if uuid in line: + fstab_entry = line + break + self.assertIsNotNone(fstab_entry) + self.assertEqual(mp, fstab_entry.split(' ')[1]) + self.assertEqual(fsopts, fstab_entry.split(' ')[3]) + + def _test_whole_disk_uuid(self, kname, uuid_file): + # confirm the whole disk format is the expected device - btrfs_uuid = self.load_collect_file('btrfs_uuid_vdd').strip() + self.output_files_exist([uuid_file]) + btrfs_uuid = self.load_collect_file(uuid_file).strip() # extract uuid from btrfs superblock self.assertTrue(btrfs_uuid is not None) self.assertEqual(len(btrfs_uuid), 36) # extract uuid from ls_uuid by kname - kname_uuid = self._kname_to_uuid('vdd') + kname_uuid = self._kname_to_uuid(kname) # compare them self.assertEqual(kname_uuid, btrfs_uuid) + # class specific input + def test_output_files_exist(self): + self.output_files_exist( + ["ls_al_byuuid", + "root/curtin-install.log", "root/curtin-install-cfg.yaml"]) + + def test_ptable(self): + self._test_ptable("blkid_output_vda", "dos") + + def test_partition_numbers(self): + # vde should have partitions 1 and 10 + disk = "vde" + expected = [disk + s for s in ["", "1", "10"]] + self._test_partition_numbers(disk, expected) + + def test_fstab_entries(self): + """" + dev=vda1 mp=/ fsopts=defaults + dev=vda2 mp=/home fsopts=defaults + dev=vdd mp=/btrfs fsopts=defaults,noatime + """ + expected = [('vda1', '/', 'defaults'), + ('vda2', '/home', 'defaults'), + ('vdd', '/btrfs', 'defaults,noatime')] + self._test_fstab_entries('fstab', 'ls_al_byuuid', expected) + + def test_whole_disk_uuid(self): + self._test_whole_disk_uuid("vdd", "btrfs_uuid_vdd") + def test_proxy_set(self): + if self.target_distro != 'ubuntu': + raise SkipTest("No apt-proxy for non-ubuntu distros") + self.output_files_exist(['apt-proxy']) expected = get_apt_proxy() apt_proxy_found = self.load_collect_file("apt-proxy").rstrip() if expected: @@ -149,6 +158,28 @@ class TestBasicAbs(VMBaseClass): self.assertEqual(source_version, installed_version) +class CentosTestBasicAbs(TestBasicAbs): + def test_centos_release(self): + """Test this image is the centos release expected""" + self.output_files_exist(["rpm_dist_version_major", "centos-release"]) + + centos_release = self.load_collect_file("centos-release").lower() + rpm_major_version = ( + self.load_collect_file("rpm_dist_version_major").strip()) + _, os_id, os_version = self.target_release.partition("centos") + + self.assertTrue(os_version.startswith(rpm_major_version), + "%s doesn't start with %s" % (os_version, + rpm_major_version)) + self.assertTrue(centos_release.startswith(os_id), + "%s doesn't start with %s" % (centos_release, os_id)) + + +class Centos70XenialTestBasic(centos_relbase.centos70_xenial, + CentosTestBasicAbs): + __test__ = True + + class TrustyTestBasic(relbase.trusty, TestBasicAbs): __test__ = True @@ -187,104 +218,47 @@ class TestBasicScsiAbs(TestBasicAbs): disk_driver = 'scsi-hd' extra_disks = ['128G', '128G', '4G'] nvme_disks = ['4G'] - collect_scripts = VMBaseClass.collect_scripts + [textwrap.dedent(""" + extra_collect_scripts = [textwrap.dedent(""" cd OUTPUT_COLLECT_D - blkid -o export /dev/sda > blkid_output_sda - blkid -o export /dev/sda1 > blkid_output_sda1 - blkid -o export /dev/sda2 > blkid_output_sda2 + blkid -o export /dev/sda | cat >blkid_output_sda + blkid -o export /dev/sda1 | cat >blkid_output_sda1 + blkid -o export /dev/sda2 | cat >blkid_output_sda2 dev="/dev/sdc"; f="btrfs_uuid_${dev#/dev/*}"; if command -v btrfs-debug-tree >/dev/null; then btrfs-debug-tree -r $dev | awk '/^uuid/ {print $2}' | grep "-" else btrfs inspect-internal dump-super $dev | awk '/^dev_item.fsid/ {print $2}' - fi > $f - cat /proc/partitions > proc_partitions - ls -al /dev/disk/by-uuid/ > ls_uuid - ls -al /dev/disk/by-id/ > ls_disk_id - cat /etc/fstab > fstab - mkdir -p /dev/disk/by-dname - ls /dev/disk/by-dname/ > ls_dname - find /etc/network/interfaces.d > find_interfacesd - - v="" - out=$(apt-config shell v Acquire::HTTP::Proxy) - eval "$out" - echo "$v" > apt-proxy + fi | cat >$f """)] - def test_output_files_exist(self): - self.output_files_exist( - ["blkid_output_sda", "blkid_output_sda1", "blkid_output_sda2", - "btrfs_uuid_sdc", "fstab", "ls_dname", "ls_uuid", - "ls_disk_id", "proc_partitions"]) - def test_ptable(self): - if self.target_release == "trusty": - raise SkipTest("No PTTYPE blkid output on trusty") - - blkid_info = self.get_blkid_data("blkid_output_sda") - self.assertEquals(blkid_info["PTTYPE"], "dos") + self._test_ptable("blkid_output_sda", "dos") def test_partition_numbers(self): - # vde should have partitions 1 and 10 + # sdd should have partitions 1 and 10 disk = "sdd" - found = [] - proc_partitions = self.load_collect_file('proc_partitions') - for line in proc_partitions.splitlines(): - if disk in line: - found.append(line.split()[3]) - # /proc/partitions should have 3 lines with 'vde' in them. expected = [disk + s for s in ["", "1", "10"]] - self.assertEqual(found, expected) - - def test_partitions(self): - fstab_lines = self.load_collect_file('fstab').splitlines() - print("\n".join(fstab_lines)) - # Test that vda1 is on / - blkid_info = self.get_blkid_data("blkid_output_sda1") - fstab_entry = None - for line in fstab_lines: - if blkid_info['UUID'] in line: - fstab_entry = line - break - self.assertIsNotNone(fstab_entry) - self.assertEqual(fstab_entry.split(' ')[1], "/") - - # Test that vda2 is on /home - blkid_info = self.get_blkid_data("blkid_output_sda2") - fstab_entry = None - for line in fstab_lines: - if blkid_info['UUID'] in line: - fstab_entry = line - break - self.assertIsNotNone(fstab_entry) - self.assertEqual(fstab_entry.split(' ')[1], "/home") - - # Test whole disk sdc is mounted at /btrfs, and uses defaults,noatime - uuid = self._kname_to_uuid('sdc') - fstab_entry = None - for line in fstab_lines: - if uuid in line: - fstab_entry = line - break - self.assertIsNotNone(fstab_entry) - self.assertEqual(fstab_entry.split(' ')[1], "/btrfs") - self.assertEqual(fstab_entry.split(' ')[3], "defaults,noatime") - - def test_whole_disk_format(self): - # confirm the whole disk format is the expected device - btrfs_uuid = self.load_collect_file("btrfs_uuid_sdc").strip() + self._test_partition_numbers(disk, expected) - # extract uuid from btrfs superblock - self.assertTrue(btrfs_uuid is not None) - self.assertEqual(len(btrfs_uuid), 36) + def test_fstab_entries(self): + """" + dev=sda1 mp=/ fsopts=defaults + dev=sda2 mp=/home fsopts=defaults + dev=sdc mp=/btrfs fsopts=defaults,noatime + """ + expected = [('sda1', '/', 'defaults'), + ('sda2', '/home', 'defaults'), + ('sdc', '/btrfs', 'defaults,noatime')] + self._test_fstab_entries('fstab', 'ls_al_byuuid', expected) - # extract uuid from ls_uuid by kname - kname_uuid = self._kname_to_uuid('sdc') + def test_whole_disk_uuid(self): + self._test_whole_disk_uuid("sdc", "btrfs_uuid_sdc") - # compare them - self.assertEqual(kname_uuid, btrfs_uuid) + +class Centos70XenialTestScsiBasic(centos_relbase.centos70_xenial, + TestBasicScsiAbs, CentosTestBasicAbs): + __test__ = True class XenialGATestScsiBasic(relbase.xenial_ga, TestBasicScsiAbs): diff --git a/tests/vmtests/test_bcache_basic.py b/tests/vmtests/test_bcache_basic.py index 4989c8e3..b4191b68 100644 --- a/tests/vmtests/test_bcache_basic.py +++ b/tests/vmtests/test_bcache_basic.py @@ -10,19 +10,16 @@ class TestBcacheBasic(VMBaseClass): arch_skip = [ "s390x", # lp:1565029 ] + test_type = 'storage' conf_file = "examples/tests/bcache_basic.yaml" nr_cpus = 2 dirty_disks = True extra_disks = ['2G'] - collect_scripts = VMBaseClass.collect_scripts + [textwrap.dedent(""" + extra_collect_scripts = [textwrap.dedent(""" cd OUTPUT_COLLECT_D bcache-super-show /dev/vda2 > bcache_super_vda2 ls /sys/fs/bcache > bcache_ls cat /sys/block/bcache0/bcache/cache_mode > bcache_cache_mode - cat /proc/mounts > proc_mounts - cat /proc/partitions > proc_partitions - find /etc/network/interfaces.d > find_interfacesd - cat /proc/cmdline > cmdline """)] def test_bcache_output_files_exist(self): @@ -42,7 +39,7 @@ class TestBcacheBasic(VMBaseClass): self.check_file_regex("bcache_cache_mode", r"\[writeback\]") def test_proc_cmdline_root_by_uuid(self): - self.check_file_regex("cmdline", r"root=UUID=") + self.check_file_regex("proc_cmdline", r"root=UUID=") class TrustyBcacheBasic(relbase.trusty, TestBcacheBasic): diff --git a/tests/vmtests/test_centos_basic.py b/tests/vmtests/test_centos_basic.py deleted file mode 100644 index 7857e741..00000000 --- a/tests/vmtests/test_centos_basic.py +++ /dev/null @@ -1,96 +0,0 @@ -# This file is part of curtin. See LICENSE file for copyright and license info. - -from . import VMBaseClass -from .releases import centos_base_vm_classes as relbase -from .test_network import TestNetworkBaseTestsAbs - -import textwrap - - -# FIXME: should eventually be integrated with the real TestBasic -class CentosTestBasicAbs(VMBaseClass): - __test__ = False - conf_file = "examples/tests/centos_basic.yaml" - # XXX: command | tee output is required for Centos under SELinux - # http://danwalsh.livejournal.com/22860.html - collect_scripts = VMBaseClass.collect_scripts + [textwrap.dedent( - """ - cd OUTPUT_COLLECT_D - cat /etc/fstab > fstab - rpm -qa | cat >rpm_qa - ifconfig -a | cat >ifconfig_a - ip a | cat >ip_a - cp -a /etc/sysconfig/network-scripts . - cp -a /var/log/messages . - cp -a /var/log/cloud-init* . - cp -a /var/lib/cloud ./var_lib_cloud - cp -a /run/cloud-init ./run_cloud-init - rpm -E '%rhel' > rpm_dist_version_major - cp -a /etc/centos-release . - """)] - fstab_expected = { - 'LABEL=cloudimg-rootfs': '/', - } - - def test_dname(self): - pass - - def test_interfacesd_eth0_removed(self): - pass - - def test_output_files_exist(self): - self.output_files_exist(["fstab"]) - - def test_centos_release(self): - """Test this image is the centos release expected""" - self.output_files_exist(["rpm_dist_version_major", "centos-release"]) - - centos_release = self.load_collect_file("centos-release").lower() - rpm_major_version = ( - self.load_collect_file("rpm_dist_version_major").strip()) - _, os_id, os_version = self.target_release.partition("centos") - - self.assertTrue(os_version.startswith(rpm_major_version), - "%s doesn't start with %s" % (os_version, - rpm_major_version)) - self.assertTrue(centos_release.startswith(os_id), - "%s doesn't start with %s" % (centos_release, os_id)) - - -# FIXME: this naming scheme needs to be replaced -class Centos70FromXenialTestBasic(relbase.centos70fromxenial, - CentosTestBasicAbs): - __test__ = True - - -class Centos66FromXenialTestBasic(relbase.centos66fromxenial, - CentosTestBasicAbs): - __test__ = False - # FIXME: test is disabled because the grub config script in target - # specifies drive using hd(1,0) syntax, which breaks when the - # installation medium is removed. other than this, the install works - - -class CentosTestBasicNetworkAbs(TestNetworkBaseTestsAbs): - conf_file = "examples/tests/centos_basic.yaml" - collect_scripts = TestNetworkBaseTestsAbs.collect_scripts + [ - textwrap.dedent(""" - cd OUTPUT_COLLECT_D - cp -a /etc/sysconfig/network-scripts . - cp -a /var/log/cloud-init* . - cp -a /var/lib/cloud ./var_lib_cloud - cp -a /run/cloud-init ./run_cloud-init - """)] - - def test_etc_network_interfaces(self): - pass - - def test_etc_resolvconf(self): - pass - - -class Centos70BasicNetworkFromXenialTestBasic(relbase.centos70fromxenial, - CentosTestBasicNetworkAbs): - __test__ = True - -# vi: ts=4 expandtab syntax=python diff --git a/tests/vmtests/test_fs_battery.py b/tests/vmtests/test_fs_battery.py index 3e417179..defdf1a9 100644 --- a/tests/vmtests/test_fs_battery.py +++ b/tests/vmtests/test_fs_battery.py @@ -2,6 +2,7 @@ from . import VMBaseClass from .releases import base_vm_classes as relbase +from .releases import centos_base_vm_classes as centos_relbase from curtin import config @@ -43,19 +44,14 @@ def _parse_blkid_output(content): class TestFsBattery(VMBaseClass): interactive = False + test_type = 'storage' conf_file = "examples/tests/filesystem_battery.yaml" extra_disks = ['20G'] - collect_scripts = VMBaseClass.collect_scripts + [textwrap.dedent(""" + extra_collect_scripts = [textwrap.dedent(""" cd OUTPUT_COLLECT_D - blkid -o export > blkid.out - cat /proc/mounts > proc_mounts - cat /proc/partitions > proc_partitions - find /etc/network/interfaces.d > find_interfacesd - cat /proc/cmdline > cmdline - cat /etc/fstab > fstab cat /proc/1/mountinfo > mountinfo - for p in /my/bind-over-var-lib/apt /my/bind-ro-etc/passwd; do + for p in /my/bind-over-var-cache/man /my/bind-ro-etc/passwd; do [ -e "$p" ] && echo "$p: present" || echo "$p: missing" done > my-path-checks @@ -162,7 +158,7 @@ class TestFsBattery(VMBaseClass): expected = [ "none /my/tmpfs tmpfs size=4194304 0 0".split(), "none /my/ramfs ramfs defaults 0 0".split(), - "/my/bind-over-var-lib /var/lib none bind 0 0".split(), + "/my/bind-over-var-cache /var/cache none bind 0 0".split(), "/etc /my/bind-ro-etc none bind,ro 0 0".split(), ] fstab_found = [ @@ -185,7 +181,7 @@ class TestFsBattery(VMBaseClass): dest_src[toks[4]] = toks[3] self.assertTrue("/my/ramfs" in dest_src) self.assertTrue("/my/tmpfs" in dest_src) - self.assertEqual(dest_src.get("/var/lib"), "/my/bind-over-var-lib") + self.assertEqual(dest_src.get("/var/cache"), "/my/bind-over-var-cache") self.assertEqual(dest_src.get("/my/bind-ro-etc"), "/etc") def test_expected_files_from_bind_mounts(self): @@ -197,10 +193,28 @@ class TestFsBattery(VMBaseClass): paths[path] = val.strip() self.assertEqual( - {'/my/bind-over-var-lib/apt': 'present', + {'/my/bind-over-var-cache/man': 'present', '/my/bind-ro-etc/passwd': 'present'}, paths) +class Centos70XenialTestFsBattery(centos_relbase.centos70_xenial, + TestFsBattery): + __test__ = True + + def test_mount_umount(self): + """Check output of mount and unmount operations for each fs.""" + # centos does not support: jfs, ntfs, reiserfs + unsupported = ['jfs', 'ntfs', 'reiserfs'] + results = [ent for ent in + self.load_collect_file("battery-mount-umount").splitlines() + if ent.split()[-1].replace("'", "") not in unsupported] + entries = {k: v for k, v in self.get_fs_entries().items() + if v['fstype'] not in unsupported} + expected = (["%s mount: PASS" % k for k in entries] + + ["%s umount: PASS" % k for k in entries]) + self.assertEqual(sorted(expected), sorted(results)) + + class TrustyTestFsBattery(relbase.trusty, TestFsBattery): __test__ = True diff --git a/tests/vmtests/test_install_umount.py b/tests/vmtests/test_install_umount.py index 6fcc9a79..931cf556 100644 --- a/tests/vmtests/test_install_umount.py +++ b/tests/vmtests/test_install_umount.py @@ -3,32 +3,15 @@ from . import VMBaseClass from .releases import base_vm_classes as relbase -import textwrap import yaml class TestInstallUnmount(VMBaseClass): """ Test a curtin install which disabled unmonting """ conf_file = "examples/tests/install_disable_unmount.yaml""" + test_type = 'config' extra_nics = [] extra_disks = [] - collect_scripts = VMBaseClass.collect_scripts + [textwrap.dedent(""" - cd OUTPUT_COLLECT_D - sfdisk --list > sfdisk_list - for d in /dev/[sv]d[a-z] /dev/xvd?; do - [ -b "$d" ] || continue - echo == $d == - sgdisk --print $d - done > sgdisk_list - blkid > blkid - cat /proc/partitions > proc_partitions - cp /etc/network/interfaces interfaces - if [ -f /var/log/cloud-init-output.log ]; then - cp /var/log/cloud-init-output.log . - fi - cp /var/log/cloud-init.log . - find /etc/network/interfaces.d > find_interfacesd - """)] def test_proc_mounts_before_unmount(self): """Test TARGET_MOUNT_POINT value is in ephemeral /proc/mounts""" diff --git a/tests/vmtests/test_iscsi.py b/tests/vmtests/test_iscsi.py index 1ac96604..a800df5f 100644 --- a/tests/vmtests/test_iscsi.py +++ b/tests/vmtests/test_iscsi.py @@ -2,12 +2,14 @@ from . import VMBaseClass from .releases import base_vm_classes as relbase +from .releases import centos_base_vm_classes as centos_relbase import textwrap class TestBasicIscsiAbs(VMBaseClass): interactive = False + test_type = 'storage' iscsi_disks = [ {'size': '3G'}, {'size': '4G', 'auth': 'user:passw0rd'}, @@ -16,14 +18,11 @@ class TestBasicIscsiAbs(VMBaseClass): conf_file = "examples/tests/basic_iscsi.yaml" nr_testfiles = 4 - collect_scripts = VMBaseClass.collect_scripts + [textwrap.dedent( - """ + extra_collect_scripts = [textwrap.dedent(""" cd OUTPUT_COLLECT_D - cat /etc/fstab > fstab - ls /dev/disk/by-dname/ > ls_dname - find /etc/network/interfaces.d > find_interfacesd + cp -a /etc/iscsi ./etc_iscsi bash -c \ - 'for f in /mnt/iscsi*; do cat $f/testfile > testfile${f: -1}; done' + 'for f in /mnt/iscsi*; do cp $f/testfile testfile${f: -1}; done' """)] def test_fstab_has_netdev_option(self): @@ -49,6 +48,11 @@ class TestBasicIscsiAbs(VMBaseClass): (testfile, expected_content, content)) +class Centos70XenialTestIscsiBasic(centos_relbase.centos70_xenial, + TestBasicIscsiAbs): + __test__ = True + + class TrustyTestIscsiBasic(relbase.trusty, TestBasicIscsiAbs): __test__ = True diff --git a/tests/vmtests/test_journald_reporter.py b/tests/vmtests/test_journald_reporter.py index ad34d52c..c60a862a 100644 --- a/tests/vmtests/test_journald_reporter.py +++ b/tests/vmtests/test_journald_reporter.py @@ -4,18 +4,15 @@ from . import VMBaseClass from .releases import base_vm_classes as relbase import json -import textwrap class TestJournaldReporter(VMBaseClass): # Test that curtin with no config does the right thing conf_file = "examples/tests/journald_reporter.yaml" + test_type = 'config' extra_disks = [] extra_nics = [] - collect_scripts = VMBaseClass.collect_scripts + [textwrap.dedent(""" - cd OUTPUT_COLLECT_D - find /etc/network/interfaces.d > find_interfacesd - """)] + extra_collect_scripts = [] def test_output_files_exist(self): self.output_files_exist(["root/journalctl.curtin_events.log", diff --git a/tests/vmtests/test_lvm.py b/tests/vmtests/test_lvm.py index 8972ae41..37053fed 100644 --- a/tests/vmtests/test_lvm.py +++ b/tests/vmtests/test_lvm.py @@ -2,24 +2,19 @@ from . import VMBaseClass from .releases import base_vm_classes as relbase +from .releases import centos_base_vm_classes as centos_relbase import textwrap class TestLvmAbs(VMBaseClass): conf_file = "examples/tests/lvm.yaml" + test_type = 'storage' interactive = False extra_disks = ['10G'] dirty_disks = True - collect_scripts = VMBaseClass.collect_scripts + [textwrap.dedent(""" + extra_collect_scripts = [textwrap.dedent(""" cd OUTPUT_COLLECT_D - cat /etc/fstab > fstab - ls /dev/disk/by-dname > ls_dname - ls -al /dev/disk/by-dname > lsal_dname - ls -al /dev/disk/by-id/ > ls_byid - ls -al /dev/disk/by-uuid/ > ls_byuuid - cat /proc/partitions > proc_partitions - find /etc/network/interfaces.d > find_interfacesd pvdisplay -C --separator = -o vg_name,pv_name --noheadings > pvs lvdisplay -C --separator = -o lv_name,vg_name --noheadings > lvs """)] @@ -46,6 +41,10 @@ class TestLvmAbs(VMBaseClass): ["fstab", "ls_dname"]) +class Centos70XenialTestLvm(centos_relbase.centos70_xenial, TestLvmAbs): + __test__ = True + + class TrustyTestLvm(relbase.trusty, TestLvmAbs): __test__ = True diff --git a/tests/vmtests/test_lvm_iscsi.py b/tests/vmtests/test_lvm_iscsi.py index cb5f33cf..091461e3 100644 --- a/tests/vmtests/test_lvm_iscsi.py +++ b/tests/vmtests/test_lvm_iscsi.py @@ -1,6 +1,7 @@ # This file is part of curtin. See LICENSE file for copyright and license info. from .releases import base_vm_classes as relbase +from .releases import centos_base_vm_classes as centos_relbase from .test_lvm import TestLvmAbs from .test_iscsi import TestBasicIscsiAbs @@ -16,13 +17,12 @@ class TestLvmIscsiAbs(TestLvmAbs, TestBasicIscsiAbs): conf_file = "examples/tests/lvm_iscsi.yaml" nr_testfiles = 4 - collect_scripts = TestLvmAbs.collect_scripts - collect_scripts += TestBasicIscsiAbs.collect_scripts + [textwrap.dedent( + extra_collect_scripts = TestLvmAbs.extra_collect_scripts + extra_collect_scripts += TestBasicIscsiAbs.extra_collect_scripts + extra_collect_scripts += [textwrap.dedent( """ cd OUTPUT_COLLECT_D ls -al /sys/class/block/dm*/slaves/ > dm_slaves - cp -a /etc/udev/rules.d udev_rules_d - cp -a /etc/iscsi etc_iscsi """)] fstab_expected = { @@ -55,6 +55,11 @@ class TestLvmIscsiAbs(TestLvmAbs, TestBasicIscsiAbs): self.check_file_strippedline("pvs", "vg2=/dev/sdb6") +class Centos70XenialTestLvmIscsi(centos_relbase.centos70_xenial, + TestLvmIscsiAbs): + __test__ = True + + class TrustyTestIscsiLvm(relbase.trusty, TestLvmIscsiAbs): __test__ = True diff --git a/tests/vmtests/test_lvm_root.py b/tests/vmtests/test_lvm_root.py index bc8b047f..7e7472da 100644 --- a/tests/vmtests/test_lvm_root.py +++ b/tests/vmtests/test_lvm_root.py @@ -2,27 +2,24 @@ from . import VMBaseClass from .releases import base_vm_classes as relbase +from .releases import centos_base_vm_classes as centos_relbase import json +import os import textwrap class TestLvmRootAbs(VMBaseClass): conf_file = "examples/tests/lvmroot.yaml" + test_type = 'storage' interactive = False rootfs_uuid = '04836770-e989-460f-8774-8e277ddcb40f' extra_disks = [] dirty_disks = True - collect_scripts = VMBaseClass.collect_scripts + [textwrap.dedent(""" + extra_collect_scripts = [textwrap.dedent(""" cd OUTPUT_COLLECT_D - cat /etc/fstab > fstab lsblk --json --fs -o KNAME,MOUNTPOINT,UUID,FSTYPE > lsblk.json lsblk --fs -P -o KNAME,MOUNTPOINT,UUID,FSTYPE > lsblk.out - ls -al /dev/disk/by-dname > ls_al_dname - ls -al /dev/disk/by-id > ls_al_byid - ls -al /dev/disk/by-uuid > ls_al_byuuid - ls -al /dev/mapper > ls_al_dev_mapper - find /etc/network/interfaces.d > find_interfacesd pvdisplay -C --separator = -o vg_name,pv_name --noheadings > pvs lvdisplay -C --separator = -o lv_name,vg_name --noheadings > lvs pvdisplay > pvdisplay @@ -39,8 +36,8 @@ class TestLvmRootAbs(VMBaseClass): self.output_files_exist(["fstab"]) def test_rootfs_format(self): - if self.release not in ['trusty']: - self.output_files_exist(["lsblk.json"]) + self.output_files_exist(["lsblk.json"]) + if os.path.getsize(self.collect_path('lsblk.json')) > 0: lsblk_data = json.load(open(self.collect_path('lsblk.json'))) print(json.dumps(lsblk_data, indent=4)) [entry] = [entry for entry in lsblk_data.get('blockdevices') @@ -62,6 +59,22 @@ class TestLvmRootAbs(VMBaseClass): self.assertEqual(self.conf_replace['__ROOTFS_FORMAT__'], fstype) +class Centos70XenialTestLvmRootExt4(centos_relbase.centos70_xenial, + TestLvmRootAbs): + __test__ = True + conf_replace = { + '__ROOTFS_FORMAT__': 'ext4', + } + + +class Centos70XenialTestLvmRootXfs(centos_relbase.centos70_xenial, + TestLvmRootAbs): + __test__ = False + conf_replace = { + '__ROOTFS_FORMAT__': 'xfs', + } + + class TrustyTestLvmRootExt4(relbase.trusty, TestLvmRootAbs): __test__ = True conf_replace = { @@ -97,6 +110,24 @@ class TestUefiLvmRootAbs(TestLvmRootAbs): uefi = True +class Centos70XenialTestUefiLvmRootExt4(centos_relbase.centos70_xenial, + TestUefiLvmRootAbs): + __test__ = True + conf_replace = { + '__BOOTFS_FORMAT__': 'ext4', + '__ROOTFS_FORMAT__': 'ext4', + } + + +class Centos70XenialTestUefiLvmRootXfs(centos_relbase.centos70_xenial, + TestUefiLvmRootAbs): + __test__ = True + conf_replace = { + '__BOOTFS_FORMAT__': 'ext4', + '__ROOTFS_FORMAT__': 'xfs', + } + + class XenialTestUefiLvmRootExt4(relbase.xenial, TestUefiLvmRootAbs): __test__ = True conf_replace = { diff --git a/tests/vmtests/test_mdadm_bcache.py b/tests/vmtests/test_mdadm_bcache.py index 21cf45f8..adfa55be 100644 --- a/tests/vmtests/test_mdadm_bcache.py +++ b/tests/vmtests/test_mdadm_bcache.py @@ -2,32 +2,27 @@ from . import VMBaseClass from .releases import base_vm_classes as relbase - +from .releases import centos_base_vm_classes as centos_relbase import textwrap class TestMdadmAbs(VMBaseClass): interactive = False + test_type = 'storage' active_mdadm = "1" dirty_disks = True - collect_scripts = VMBaseClass.collect_scripts + [textwrap.dedent(""" + extra_collect_scripts = [textwrap.dedent(""" cd OUTPUT_COLLECT_D - cat /etc/fstab > fstab mdadm --detail --scan > mdadm_status mdadm --detail --scan | grep -c ubuntu > mdadm_active1 grep -c active /proc/mdstat > mdadm_active2 ls /dev/disk/by-dname > ls_dname - ls -al /dev/disk/by-dname > lsal_dname - ls -al /dev/disk/by-uuid > lsal_uuid - find /etc/network/interfaces.d > find_interfacesd cat /proc/mdstat | tee mdstat - cat /proc/partitions | tee procpartitions ls -1 /sys/class/block | tee sys_class_block ls -1 /dev/md* | tee dev_md ls -al /sys/fs/bcache/* > lsal_sys_fs_bcache_star ls -al /dev/bcache* > lsal_dev_bcache_star ls -al /dev/bcache/by_uuid/* > lsal_dev_bcache_byuuid_star - cp -a /var/log/syslog . """)] def test_mdadm_output_files_exist(self): @@ -58,7 +53,8 @@ class TestMdadmBcacheAbs(TestMdadmAbs): ('cached_array_2', 0), ('cached_array_3', 0)] extra_disks = ['4G', '4G', '4G', '4G', '4G'] - collect_scripts = TestMdadmAbs.collect_scripts + [textwrap.dedent(""" + extra_collect_scripts = TestMdadmAbs.extra_collect_scripts + [ + textwrap.dedent(""" cd OUTPUT_COLLECT_D bcache-super-show /dev/vda6 > bcache_super_vda6 bcache-super-show /dev/vda7 > bcache_super_vda7 @@ -67,9 +63,6 @@ class TestMdadmBcacheAbs(TestMdadmAbs): cat /sys/block/bcache0/bcache/cache_mode > bcache_cache_mode cat /sys/block/bcache1/bcache/cache_mode >> bcache_cache_mode cat /sys/block/bcache2/bcache/cache_mode >> bcache_cache_mode - cat /proc/mounts > proc_mounts - find /etc/network/interfaces.d > find_interfacesd - cp -a /etc/udev/rules.d etc_udev_rules.d """)] fstab_expected = { '/dev/vda1': '/media/sda1', @@ -169,6 +162,11 @@ class TestMirrorbootAbs(TestMdadmAbs): ('md0', 0)] +class Centos70TestMirrorboot(centos_relbase.centos70_xenial, + TestMirrorbootAbs): + __test__ = True + + class TrustyTestMirrorboot(relbase.trusty, TestMirrorbootAbs): __test__ = True @@ -208,6 +206,11 @@ class TestMirrorbootPartitionsAbs(TestMdadmAbs): ('md0', 2)] +class Centos70TestMirrorbootPartitions(centos_relbase.centos70_xenial, + TestMirrorbootPartitionsAbs): + __test__ = True + + class TrustyTestMirrorbootPartitions(relbase.trusty, TestMirrorbootPartitionsAbs): __test__ = True @@ -259,6 +262,11 @@ class TestMirrorbootPartitionsUEFIAbs(TestMdadmAbs): dirty_disks = True +class Centos70TestMirrorbootPartitionsUEFI(centos_relbase.centos70_xenial, + TestMirrorbootPartitionsUEFIAbs): + __test__ = True + + class TrustyTestMirrorbootPartitionsUEFI(relbase.trusty, TestMirrorbootPartitionsUEFIAbs): __test__ = True @@ -301,11 +309,15 @@ class TestRaid5bootAbs(TestMdadmAbs): ('md0', 0)] -class TrustyTestRaid5Boot(relbase.trusty, TestRaid5bootAbs): +class Centos70TestRaid5boot(centos_relbase.centos70_xenial, TestRaid5bootAbs): __test__ = True -class TrustyHWEXTestRaid5Boot(relbase.trusty_hwe_x, TrustyTestRaid5Boot): +class TrustyTestRaid5boot(relbase.trusty, TestRaid5bootAbs): + __test__ = True + + +class TrustyHWEXTestRaid5boot(relbase.trusty_hwe_x, TrustyTestRaid5boot): # This tests kernel upgrade in target __test__ = True @@ -341,10 +353,11 @@ class TestRaid6bootAbs(TestMdadmAbs): ('third_disk', 1), ('fourth_disk', 1), ('md0', 0)] - collect_scripts = TestMdadmAbs.collect_scripts + [textwrap.dedent(""" + extra_collect_scripts = ( + TestMdadmAbs.extra_collect_scripts + [textwrap.dedent(""" cd OUTPUT_COLLECT_D mdadm --detail --scan > mdadm_detail - """)] + """)]) def test_raid6_output_files_exist(self): self.output_files_exist( @@ -355,6 +368,10 @@ class TestRaid6bootAbs(TestMdadmAbs): self.check_file_regex("mdadm_detail", r"ubuntu:foobar") +class Centos70TestRaid6boot(centos_relbase.centos70_xenial, TestRaid6bootAbs): + __test__ = True + + class TrustyTestRaid6boot(relbase.trusty, TestRaid6bootAbs): __test__ = True @@ -396,6 +413,11 @@ class TestRaid10bootAbs(TestMdadmAbs): ('md0', 0)] +class Centos70TestRaid10boot(centos_relbase.centos70_xenial, + TestRaid10bootAbs): + __test__ = True + + class TrustyTestRaid10boot(relbase.trusty, TestRaid10bootAbs): __test__ = True @@ -460,7 +482,8 @@ class TestAllindataAbs(TestMdadmAbs): ('vg1-lv1', 0), ('vg1-lv2', 0)] - collect_scripts = TestMdadmAbs.collect_scripts + [textwrap.dedent(""" + extra_collect_scripts = ( + TestMdadmAbs.extra_collect_scripts + [textwrap.dedent(""" cd OUTPUT_COLLECT_D pvdisplay -C --separator = -o vg_name,pv_name --noheadings > pvs lvdisplay -C --separator = -o lv_name,vg_name --noheadings > lvs @@ -470,7 +493,7 @@ class TestAllindataAbs(TestMdadmAbs): mkdir -p /tmp/xfstest mount /dev/mapper/dmcrypt0 /tmp/xfstest xfs_info /tmp/xfstest/ > xfs_info - """)] + """)]) fstab_expected = { '/dev/vg1/lv1': '/srv/data', '/dev/vg1/lv2': '/srv/backup', diff --git a/tests/vmtests/test_mdadm_iscsi.py b/tests/vmtests/test_mdadm_iscsi.py index eba200a8..537baec0 100644 --- a/tests/vmtests/test_mdadm_iscsi.py +++ b/tests/vmtests/test_mdadm_iscsi.py @@ -1,6 +1,7 @@ # This file is part of curtin. See LICENSE file for copyright and license info. from .releases import base_vm_classes as relbase +from .releases import centos_base_vm_classes as centos_relbase from .test_mdadm_bcache import TestMdadmAbs from .test_iscsi import TestBasicIscsiAbs @@ -17,14 +18,19 @@ class TestMdadmIscsiAbs(TestMdadmAbs, TestBasicIscsiAbs): conf_file = "examples/tests/mdadm_iscsi.yaml" nr_testfiles = 1 - collect_scripts = TestMdadmAbs.collect_scripts - collect_scripts += TestBasicIscsiAbs.collect_scripts + [textwrap.dedent( - """ + extra_collect_scripts = TestMdadmAbs.extra_collect_scripts + extra_collect_scripts += TestBasicIscsiAbs.extra_collect_scripts + extra_collect_scripts += [textwrap.dedent(""" cd OUTPUT_COLLECT_D ls -al /sys/class/block/md*/slaves/ > md_slaves """)] +class Centos70TestIscsiMdadm(centos_relbase.centos70_xenial, + TestMdadmIscsiAbs): + __test__ = True + + class TrustyTestIscsiMdadm(relbase.trusty, TestMdadmIscsiAbs): __test__ = True diff --git a/tests/vmtests/test_multipath.py b/tests/vmtests/test_multipath.py index 0bf63b79..a6bd8ce1 100644 --- a/tests/vmtests/test_multipath.py +++ b/tests/vmtests/test_multipath.py @@ -2,39 +2,26 @@ from . import VMBaseClass from .releases import base_vm_classes as relbase +from .releases import centos_base_vm_classes as centos_relbase import textwrap class TestMultipathBasicAbs(VMBaseClass): conf_file = "examples/tests/multipath.yaml" + test_type = 'storage' multipath = True disk_driver = 'scsi-hd' extra_disks = [] nvme_disks = [] - collect_scripts = VMBaseClass.collect_scripts + [textwrap.dedent(""" + extra_collect_scripts = [textwrap.dedent(""" cd OUTPUT_COLLECT_D - blkid -o export /dev/sda > blkid_output_sda - blkid -o export /dev/sda1 > blkid_output_sda1 - blkid -o export /dev/sda2 > blkid_output_sda2 - blkid -o export /dev/sdb > blkid_output_sdb - blkid -o export /dev/sdb1 > blkid_output_sdb1 - blkid -o export /dev/sdb2 > blkid_output_sdb2 - dmsetup ls > dmsetup_ls - dmsetup info > dmsetup_info - cat /proc/partitions > proc_partitions multipath -ll > multipath_ll multipath -v3 -ll > multipath_v3_ll multipath -r > multipath_r cp -a /etc/multipath* . - ls -al /dev/disk/by-uuid/ > ls_uuid - ls -al /dev/disk/by-id/ > ls_disk_id readlink -f /sys/class/block/sda/holders/dm-0 > holders_sda readlink -f /sys/class/block/sdb/holders/dm-0 > holders_sdb - cat /etc/fstab > fstab - mkdir -p /dev/disk/by-dname - ls /dev/disk/by-dname/ > ls_dname - find /etc/network/interfaces.d > find_interfacesd """)] def test_multipath_disks_match(self): @@ -45,6 +32,11 @@ class TestMultipathBasicAbs(VMBaseClass): self.assertEqual(sda_data, sdb_data) +class Centos70TestMultipathBasic(centos_relbase.centos70_xenial, + TestMultipathBasicAbs): + __test__ = True + + class TrustyTestMultipathBasic(relbase.trusty, TestMultipathBasicAbs): __test__ = True diff --git a/tests/vmtests/test_network.py b/tests/vmtests/test_network.py index 65328419..ce4cdb95 100644 --- a/tests/vmtests/test_network.py +++ b/tests/vmtests/test_network.py @@ -17,20 +17,16 @@ import yaml class TestNetworkBaseTestsAbs(VMBaseClass): interactive = False + test_type = 'network' extra_disks = [] extra_nics = [] # XXX: command | tee output is required for Centos under SELinux # http://danwalsh.livejournal.com/22860.html - collect_scripts = VMBaseClass.collect_scripts + [textwrap.dedent(""" + extra_collect_scripts = [textwrap.dedent(""" cd OUTPUT_COLLECT_D echo "waiting for ipv6 to settle" && sleep 5 route -n | tee first_route_n - ifconfig -a | tee ifconfig_a ip link show | tee ip_link_show - ip a | tee ip_a - find /etc/network/interfaces.d > find_interfacesd - cp -av /etc/network/interfaces . - cp -av /etc/network/interfaces.d . cp /etc/resolv.conf . cp -av /etc/udev/rules.d/70-persistent-net.rules . ||: ip -o route show | tee ip_route_show @@ -41,7 +37,6 @@ class TestNetworkBaseTestsAbs(VMBaseClass): cp -av /var/log/upstart ./upstart ||: cp -av /etc/cloud ./etc_cloud cp -av /var/log/cloud*.log ./ - rpm -q --queryformat '%{VERSION}\n' cloud-init |tee rpm_ci_version V=/usr/lib/python*/*-packages/cloudinit/version.py; grep -c NETWORK_CONFIG_V2 $V |tee cloudinit_passthrough_available mkdir -p etc_netplan @@ -58,8 +53,6 @@ class TestNetworkBaseTestsAbs(VMBaseClass): def test_output_files_exist(self): self.output_files_exist([ - "find_interfacesd", - "ifconfig_a", "ip_a", "ip_route_show", "route_6_n", @@ -437,14 +430,6 @@ class TestNetworkBasicAbs(TestNetworkBaseTestsAbs): class CentosTestNetworkBasicAbs(TestNetworkBaseTestsAbs): conf_file = "examples/tests/centos_basic.yaml" - collect_scripts = TestNetworkBaseTestsAbs.collect_scripts + [ - textwrap.dedent(""" - cd OUTPUT_COLLECT_D - cp -a /etc/sysconfig/network-scripts . - cp -a /var/log/cloud-init* . - cp -a /var/lib/cloud ./var_lib_cloud - cp -a /run/cloud-init ./run_cloud-init - """)] def test_etc_network_interfaces(self): pass @@ -488,12 +473,12 @@ class CosmicTestNetworkBasic(relbase.cosmic, TestNetworkBasicAbs): __test__ = True -class Centos66TestNetworkBasic(centos_relbase.centos66fromxenial, +class Centos66TestNetworkBasic(centos_relbase.centos66_xenial, CentosTestNetworkBasicAbs): __test__ = True -class Centos70TestNetworkBasic(centos_relbase.centos70fromxenial, +class Centos70TestNetworkBasic(centos_relbase.centos70_xenial, CentosTestNetworkBasicAbs): __test__ = True diff --git a/tests/vmtests/test_network_alias.py b/tests/vmtests/test_network_alias.py index d466299c..1d1837f0 100644 --- a/tests/vmtests/test_network_alias.py +++ b/tests/vmtests/test_network_alias.py @@ -19,7 +19,7 @@ class TestNetworkAliasAbs(TestNetworkBaseTestsAbs): class CentosTestNetworkAliasAbs(TestNetworkAliasAbs): - collect_scripts = TestNetworkAliasAbs.collect_scripts + [ + extra_collect_scripts = TestNetworkAliasAbs.extra_collect_scripts + [ textwrap.dedent(""" cd OUTPUT_COLLECT_D cp -a /etc/sysconfig/network-scripts . @@ -32,12 +32,12 @@ class CentosTestNetworkAliasAbs(TestNetworkAliasAbs): pass -class Centos66TestNetworkAlias(centos_relbase.centos66fromxenial, +class Centos66TestNetworkAlias(centos_relbase.centos66_xenial, CentosTestNetworkAliasAbs): __test__ = True -class Centos70TestNetworkAlias(centos_relbase.centos70fromxenial, +class Centos70TestNetworkAlias(centos_relbase.centos70_xenial, CentosTestNetworkAliasAbs): __test__ = True diff --git a/tests/vmtests/test_network_bonding.py b/tests/vmtests/test_network_bonding.py index 9dba07b6..572f2406 100644 --- a/tests/vmtests/test_network_bonding.py +++ b/tests/vmtests/test_network_bonding.py @@ -25,7 +25,7 @@ class TestNetworkBondingAbs(TestNetworkBaseTestsAbs): class CentosTestNetworkBondingAbs(TestNetworkBondingAbs): - collect_scripts = TestNetworkBondingAbs.collect_scripts + [ + extra_collect_scripts = TestNetworkBondingAbs.extra_collect_scripts + [ textwrap.dedent(""" cd OUTPUT_COLLECT_D cp -a /etc/sysconfig/network-scripts . @@ -79,12 +79,12 @@ class CosmicTestBonding(relbase.cosmic, TestNetworkBondingAbs): __test__ = True -class Centos66TestNetworkBonding(centos_relbase.centos66fromxenial, +class Centos66TestNetworkBonding(centos_relbase.centos66_xenial, CentosTestNetworkBondingAbs): __test__ = True -class Centos70TestNetworkBonding(centos_relbase.centos70fromxenial, +class Centos70TestNetworkBonding(centos_relbase.centos70_xenial, CentosTestNetworkBondingAbs): __test__ = True diff --git a/tests/vmtests/test_network_bridging.py b/tests/vmtests/test_network_bridging.py index 91df02e3..ed9b7288 100644 --- a/tests/vmtests/test_network_bridging.py +++ b/tests/vmtests/test_network_bridging.py @@ -96,7 +96,7 @@ def sysfs_to_dict(input): class TestBridgeNetworkAbs(TestNetworkBaseTestsAbs): conf_file = "examples/tests/bridging_network.yaml" - collect_scripts = TestNetworkBaseTestsAbs.collect_scripts + [ + extra_collect_scripts = TestNetworkBaseTestsAbs.extra_collect_scripts + [ textwrap.dedent(""" cd OUTPUT_COLLECT_D grep -r . /sys/class/net/br0 > sysfs_br0 @@ -192,7 +192,7 @@ class TestBridgeNetworkAbs(TestNetworkBaseTestsAbs): class CentosTestBridgeNetworkAbs(TestBridgeNetworkAbs): - collect_scripts = TestBridgeNetworkAbs.collect_scripts + [ + extra_collect_scripts = TestBridgeNetworkAbs.extra_collect_scripts + [ textwrap.dedent(""" cd OUTPUT_COLLECT_D cp -a /etc/sysconfig/network-scripts . @@ -216,12 +216,12 @@ class CentosTestBridgeNetworkAbs(TestBridgeNetworkAbs): self.assertTrue('bridge' in status) -class Centos66TestBridgeNetwork(centos_relbase.centos66fromxenial, +class Centos66TestBridgeNetwork(centos_relbase.centos66_xenial, CentosTestBridgeNetworkAbs): __test__ = True -class Centos70TestBridgeNetwork(centos_relbase.centos70fromxenial, +class Centos70TestBridgeNetwork(centos_relbase.centos70_xenial, CentosTestBridgeNetworkAbs): __test__ = True diff --git a/tests/vmtests/test_network_ipv6.py b/tests/vmtests/test_network_ipv6.py index d3c34a5b..b8a69e8d 100644 --- a/tests/vmtests/test_network_ipv6.py +++ b/tests/vmtests/test_network_ipv6.py @@ -16,7 +16,7 @@ class TestNetworkIPV6Abs(TestNetworkBaseTestsAbs): - all IP is static """ conf_file = "examples/network-ipv6-bond-vlan.yaml" - collect_scripts = TestNetworkBaseTestsAbs.collect_scripts + [ + extra_collect_scripts = TestNetworkBaseTestsAbs.extra_collect_scripts + [ textwrap.dedent(""" grep . -r /sys/class/net/bond0/ > sysfs_bond0 || : grep . -r /sys/class/net/bond0.108/ > sysfs_bond0.108 || : @@ -25,7 +25,7 @@ class TestNetworkIPV6Abs(TestNetworkBaseTestsAbs): class CentosTestNetworkIPV6Abs(TestNetworkIPV6Abs): - collect_scripts = TestNetworkIPV6Abs.collect_scripts + [ + extra_collect_scripts = TestNetworkIPV6Abs.extra_collect_scripts + [ textwrap.dedent(""" cd OUTPUT_COLLECT_D cp -a /etc/sysconfig/network-scripts . @@ -72,12 +72,12 @@ class CosmicTestNetworkIPV6(relbase.cosmic, TestNetworkIPV6Abs): __test__ = True -class Centos66TestNetworkIPV6(centos_relbase.centos66fromxenial, +class Centos66TestNetworkIPV6(centos_relbase.centos66_xenial, CentosTestNetworkIPV6Abs): __test__ = True -class Centos70TestNetworkIPV6(centos_relbase.centos70fromxenial, +class Centos70TestNetworkIPV6(centos_relbase.centos70_xenial, CentosTestNetworkIPV6Abs): __test__ = True diff --git a/tests/vmtests/test_network_ipv6_static.py b/tests/vmtests/test_network_ipv6_static.py index 0396e432..7ebc5eb2 100644 --- a/tests/vmtests/test_network_ipv6_static.py +++ b/tests/vmtests/test_network_ipv6_static.py @@ -54,12 +54,12 @@ class CosmicTestNetworkIPV6Static(relbase.cosmic, TestNetworkIPV6StaticAbs): __test__ = True -class Centos66TestNetworkIPV6Static(centos_relbase.centos66fromxenial, +class Centos66TestNetworkIPV6Static(centos_relbase.centos66_xenial, CentosTestNetworkIPV6StaticAbs): __test__ = True -class Centos70TestNetworkIPV6Static(centos_relbase.centos70fromxenial, +class Centos70TestNetworkIPV6Static(centos_relbase.centos70_xenial, CentosTestNetworkIPV6StaticAbs): __test__ = True diff --git a/tests/vmtests/test_network_ipv6_vlan.py b/tests/vmtests/test_network_ipv6_vlan.py index e001da98..2f7bd493 100644 --- a/tests/vmtests/test_network_ipv6_vlan.py +++ b/tests/vmtests/test_network_ipv6_vlan.py @@ -35,12 +35,12 @@ class CosmicTestNetworkIPV6Vlan(relbase.cosmic, TestNetworkIPV6VlanAbs): __test__ = True -class Centos66TestNetworkIPV6Vlan(centos_relbase.centos66fromxenial, +class Centos66TestNetworkIPV6Vlan(centos_relbase.centos66_xenial, CentosTestNetworkIPV6VlanAbs): __test__ = True -class Centos70TestNetworkIPV6Vlan(centos_relbase.centos70fromxenial, +class Centos70TestNetworkIPV6Vlan(centos_relbase.centos70_xenial, CentosTestNetworkIPV6VlanAbs): __test__ = True diff --git a/tests/vmtests/test_network_mtu.py b/tests/vmtests/test_network_mtu.py index 7a10bf10..971f15d6 100644 --- a/tests/vmtests/test_network_mtu.py +++ b/tests/vmtests/test_network_mtu.py @@ -25,7 +25,8 @@ class TestNetworkMtuAbs(TestNetworkIPV6Abs): ipv6 first, then ipv4 with mtu. """ conf_file = "examples/tests/network_mtu.yaml" - collect_scripts = TestNetworkIPV6Abs.collect_scripts + [textwrap.dedent(""" + extra_collect_scripts = TestNetworkIPV6Abs.extra_collect_scripts + [ + textwrap.dedent(""" cd OUTPUT_COLLECT_D proc_v6="/proc/sys/net/ipv6/conf" for f in `seq 0 7`; do @@ -120,7 +121,7 @@ class TestNetworkMtuAbs(TestNetworkIPV6Abs): class CentosTestNetworkMtuAbs(TestNetworkMtuAbs): conf_file = "examples/tests/network_mtu.yaml" - collect_scripts = TestNetworkMtuAbs.collect_scripts + [ + extra_collect_scripts = TestNetworkMtuAbs.extra_collect_scripts + [ textwrap.dedent(""" cd OUTPUT_COLLECT_D cp -a /etc/sysconfig/network-scripts . @@ -199,12 +200,12 @@ class CosmicTestNetworkMtu(relbase.cosmic, TestNetworkMtuAbs): __test__ = True -class Centos66TestNetworkMtu(centos_relbase.centos66fromxenial, +class Centos66TestNetworkMtu(centos_relbase.centos66_xenial, CentosTestNetworkMtuAbs): __test__ = True -class Centos70TestNetworkMtu(centos_relbase.centos70fromxenial, +class Centos70TestNetworkMtu(centos_relbase.centos70_xenial, CentosTestNetworkMtuAbs): __test__ = True diff --git a/tests/vmtests/test_network_static.py b/tests/vmtests/test_network_static.py index 40468f39..9e042a51 100644 --- a/tests/vmtests/test_network_static.py +++ b/tests/vmtests/test_network_static.py @@ -3,7 +3,6 @@ from .releases import base_vm_classes as relbase from .releases import centos_base_vm_classes as centos_relbase from .test_network import TestNetworkBaseTestsAbs -import textwrap class TestNetworkStaticAbs(TestNetworkBaseTestsAbs): @@ -13,14 +12,6 @@ class TestNetworkStaticAbs(TestNetworkBaseTestsAbs): class CentosTestNetworkStaticAbs(TestNetworkStaticAbs): - collect_scripts = TestNetworkBaseTestsAbs.collect_scripts + [ - textwrap.dedent(""" - cd OUTPUT_COLLECT_D - cp -a /etc/sysconfig/network-scripts . - cp -a /var/log/cloud-init* . - cp -a /var/lib/cloud ./var_lib_cloud - cp -a /run/cloud-init ./run_cloud-init - """)] def test_etc_network_interfaces(self): pass @@ -68,12 +59,12 @@ class CosmicTestNetworkStatic(relbase.cosmic, TestNetworkStaticAbs): __test__ = True -class Centos66TestNetworkStatic(centos_relbase.centos66fromxenial, +class Centos66TestNetworkStatic(centos_relbase.centos66_xenial, CentosTestNetworkStaticAbs): __test__ = True -class Centos70TestNetworkStatic(centos_relbase.centos70fromxenial, +class Centos70TestNetworkStatic(centos_relbase.centos70_xenial, CentosTestNetworkStaticAbs): __test__ = True diff --git a/tests/vmtests/test_network_static_routes.py b/tests/vmtests/test_network_static_routes.py index 9fa89ff3..ad18eefd 100644 --- a/tests/vmtests/test_network_static_routes.py +++ b/tests/vmtests/test_network_static_routes.py @@ -59,12 +59,12 @@ class CosmicTestNetworkStaticRoutes(relbase.cosmic, __test__ = True -class Centos66TestNetworkStaticRoutes(centos_relbase.centos66fromxenial, +class Centos66TestNetworkStaticRoutes(centos_relbase.centos66_xenial, CentosTestNetworkStaticRoutesAbs): __test__ = False -class Centos70TestNetworkStaticRoutes(centos_relbase.centos70fromxenial, +class Centos70TestNetworkStaticRoutes(centos_relbase.centos70_xenial, CentosTestNetworkStaticRoutesAbs): __test__ = False diff --git a/tests/vmtests/test_network_vlan.py b/tests/vmtests/test_network_vlan.py index 94e2966c..9e55bfa7 100644 --- a/tests/vmtests/test_network_vlan.py +++ b/tests/vmtests/test_network_vlan.py @@ -11,7 +11,7 @@ import yaml class TestNetworkVlanAbs(TestNetworkBaseTestsAbs): conf_file = "examples/tests/vlan_network.yaml" - collect_scripts = TestNetworkBaseTestsAbs.collect_scripts + [ + extra_collect_scripts = TestNetworkBaseTestsAbs.extra_collect_scripts + [ textwrap.dedent(""" cd OUTPUT_COLLECT_D ip -d link show interface1.2667 |tee ip_link_show_interface1.2667 @@ -54,14 +54,6 @@ class TestNetworkVlanAbs(TestNetworkBaseTestsAbs): class CentosTestNetworkVlanAbs(TestNetworkVlanAbs): - collect_scripts = TestNetworkVlanAbs.collect_scripts + [ - textwrap.dedent(""" - cd OUTPUT_COLLECT_D - cp -a /etc/sysconfig/network-scripts . - cp -a /var/log/cloud-init* . - cp -a /var/lib/cloud ./var_lib_cloud - cp -a /run/cloud-init ./run_cloud-init - """)] def test_etc_network_interfaces(self): pass @@ -94,12 +86,12 @@ class CosmicTestNetworkVlan(relbase.cosmic, TestNetworkVlanAbs): __test__ = True -class Centos66TestNetworkVlan(centos_relbase.centos66fromxenial, +class Centos66TestNetworkVlan(centos_relbase.centos66_xenial, CentosTestNetworkVlanAbs): __test__ = True -class Centos70TestNetworkVlan(centos_relbase.centos70fromxenial, +class Centos70TestNetworkVlan(centos_relbase.centos70_xenial, CentosTestNetworkVlanAbs): __test__ = True diff --git a/tests/vmtests/test_nvme.py b/tests/vmtests/test_nvme.py index 80d9cbf2..f3d1ae27 100644 --- a/tests/vmtests/test_nvme.py +++ b/tests/vmtests/test_nvme.py @@ -2,15 +2,19 @@ from . import VMBaseClass from .releases import base_vm_classes as relbase +from .releases import centos_base_vm_classes as centos_relbase import os import textwrap +centos70_xenial = centos_relbase.centos70_xenial + class TestNvmeAbs(VMBaseClass): arch_skip = [ "s390x", # nvme is a pci device, no pci on s390x ] + test_type = 'storage' interactive = False conf_file = "examples/tests/nvme.yaml" extra_disks = [] @@ -18,41 +22,36 @@ class TestNvmeAbs(VMBaseClass): disk_to_check = [('main_disk', 1), ('main_disk', 2), ('main_disk', 15), ('nvme_disk', 1), ('nvme_disk', 2), ('nvme_disk', 3), ('second_nvme', 1)] - collect_scripts = VMBaseClass.collect_scripts + [textwrap.dedent(""" + extra_collect_scripts = [textwrap.dedent(""" cd OUTPUT_COLLECT_D ls /sys/class/ > sys_class ls /sys/class/nvme/ > ls_nvme ls /dev/nvme* > ls_dev_nvme - ls /dev/disk/by-dname/ > ls_dname - blkid -o export /dev/vda > blkid_output_vda - blkid -o export /dev/vda1 > blkid_output_vda1 - blkid -o export /dev/vda2 > blkid_output_vda2 - cat /proc/partitions > proc_partitions - ls -al /dev/disk/by-uuid/ > ls_uuid - cat /etc/fstab > fstab - mkdir -p /dev/disk/by-dname - ls /dev/disk/by-dname/ > ls_dname - find /etc/network/interfaces.d > find_interfacesd - - v="" - out=$(apt-config shell v Acquire::HTTP::Proxy) - eval "$out" - echo "$v" > apt-proxy """)] - def test_output_files_exist(self): - self.output_files_exist(["ls_nvme", "ls_dname", "ls_dev_nvme"]) + def _test_nvme_device_names(self, expected): + self.output_files_exist(["ls_nvme", "ls_dev_nvme"]) + print('expected: %s' % expected) + if os.path.getsize(self.collect_path('ls_dev_nvme')) > 0: + print('using ls_dev_nvme') + for device in ['/dev/' + dev for dev in expected]: + print('checking device: %s' % device) + self.check_file_strippedline("ls_dev_nvme", device) - def test_nvme_device_names(self): - ls_nvme = self.collect_path('ls_nvme') # trusty and vivid do not have sys/class/nvme but # nvme devices do work - if os.path.getsize(ls_nvme) > 0: - self.check_file_strippedline("ls_nvme", "nvme0") - self.check_file_strippedline("ls_nvme", "nvme1") else: - self.check_file_strippedline("ls_dev_nvme", "/dev/nvme0") - self.check_file_strippedline("ls_dev_nvme", "/dev/nvme1") + print('using ls_nvme') + for device in expected: + print('checking device: %s' % device) + self.check_file_strippedline("ls_nvme", device) + + def test_nvme_device_names(self): + self._test_nvme_device_names(['nvme0', 'nvme1']) + + +class Centos70TestNvme(centos70_xenial, TestNvmeAbs): + __test__ = True class TrustyTestNvme(relbase.trusty, TestNvmeAbs): @@ -83,7 +82,7 @@ class CosmicTestNvme(relbase.cosmic, TestNvmeAbs): __test__ = True -class TestNvmeBcacheAbs(VMBaseClass): +class TestNvmeBcacheAbs(TestNvmeAbs): arch_skip = [ "s390x", # nvme is a pci device, no pci on s390x ] @@ -94,50 +93,24 @@ class TestNvmeBcacheAbs(VMBaseClass): uefi = True disk_to_check = [('sda', 1), ('sda', 2), ('sda', 3)] - collect_scripts = VMBaseClass.collect_scripts + [textwrap.dedent(""" + extra_collect_scripts = [textwrap.dedent(""" cd OUTPUT_COLLECT_D ls /sys/class/ > sys_class ls /sys/class/nvme/ > ls_nvme ls /dev/nvme* > ls_dev_nvme - ls /dev/disk/by-dname/ > ls_dname ls -al /dev/bcache/by-uuid/ > ls_bcache_by_uuid |: - blkid -o export /dev/vda > blkid_output_vda - blkid -o export /dev/vda1 > blkid_output_vda1 - blkid -o export /dev/vda2 > blkid_output_vda2 bcache-super-show /dev/nvme0n1p1 > bcache_super_nvme0n1p1 ls /sys/fs/bcache > bcache_ls cat /sys/block/bcache0/bcache/cache_mode > bcache_cache_mode - cat /proc/partitions > proc_partitions - ls -al /dev/disk/by-uuid/ > ls_uuid - cat /etc/fstab > fstab - mkdir -p /dev/disk/by-dname - ls /dev/disk/by-dname/ > ls_dname - find /etc/network/interfaces.d > find_interfacesd - - v="" - out=$(apt-config shell v Acquire::HTTP::Proxy) - eval "$out" - echo "$v" > apt-proxy """)] - def test_output_files_exist(self): - self.output_files_exist(["ls_nvme", "ls_dname", "ls_dev_nvme"]) - - def test_nvme_device_names(self): - ls_nvme = self.collect_path('ls_nvme') - # trusty and vivid do not have sys/class/nvme but - # nvme devices do work - if os.path.getsize(ls_nvme) > 0: - self.check_file_strippedline("ls_nvme", "nvme0") - else: - self.check_file_strippedline("ls_dev_nvme", "/dev/nvme0") - self.check_file_strippedline("ls_dev_nvme", "/dev/nvme0n1") - self.check_file_strippedline("ls_dev_nvme", "/dev/nvme0n1p1") - def test_bcache_output_files_exist(self): self.output_files_exist(["bcache_super_nvme0n1p1", "bcache_ls", "bcache_cache_mode"]) + def test_nvme_device_names(self): + self._test_nvme_device_names(['nvme0', 'nvme0n1', 'nvme0n1p1']) + def test_bcache_status(self): bcache_cset_uuid = None bcache_super = self.load_collect_file("bcache_super_nvme0n1p1") diff --git a/tests/vmtests/test_old_apt_features.py b/tests/vmtests/test_old_apt_features.py index 5aaac2ea..33561a37 100644 --- a/tests/vmtests/test_old_apt_features.py +++ b/tests/vmtests/test_old_apt_features.py @@ -38,14 +38,12 @@ def sources_to_dict(lines): class TestOldAptAbs(VMBaseClass): """TestOldAptAbs - Basic tests for old apt features of curtin""" interactive = False + test_type = 'config' extra_disks = [] fstab_expected = {} disk_to_check = [] - collect_scripts = VMBaseClass.collect_scripts + [textwrap.dedent(""" + extra_collect_scripts = [textwrap.dedent(""" cd OUTPUT_COLLECT_D - cat /etc/fstab > fstab - ls /dev/disk/by-dname > ls_dname - find /etc/network/interfaces.d > find_interfacesd grep -A 3 "Name: debconf/priority" /var/cache/debconf/config.dat > debc apt-config dump > aptconf cp /etc/apt/apt.conf.d/90curtin-aptproxy . diff --git a/tests/vmtests/test_pollinate_useragent.py b/tests/vmtests/test_pollinate_useragent.py index 201cca1b..13dd28ca 100644 --- a/tests/vmtests/test_pollinate_useragent.py +++ b/tests/vmtests/test_pollinate_useragent.py @@ -11,11 +11,11 @@ from unittest import SkipTest class TestPollinateUserAgent(VMBaseClass): # Test configuring pollinate useragent conf_file = "examples/tests/pollinate-useragent.yaml" + test_type = 'config' extra_disks = [] extra_nics = [] - collect_scripts = VMBaseClass.collect_scripts + [textwrap.dedent(""" + extra_collect_scripts = [textwrap.dedent(""" cd OUTPUT_COLLECT_D - find /etc/network/interfaces.d > find_interfacesd cp -a /etc/pollinate etc_pollinate pollinate --print-user-agent > pollinate_print_user_agent """)] diff --git a/tests/vmtests/test_raid5_bcache.py b/tests/vmtests/test_raid5_bcache.py index bb00b656..8d24f8e1 100644 --- a/tests/vmtests/test_raid5_bcache.py +++ b/tests/vmtests/test_raid5_bcache.py @@ -8,22 +8,19 @@ import textwrap class TestMdadmAbs(VMBaseClass): interactive = False + test_type = 'storage' extra_disks = ['10G', '10G', '10G', '10G'] active_mdadm = "1" - collect_scripts = VMBaseClass.collect_scripts + [textwrap.dedent(""" + extra_collect_scripts = [textwrap.dedent(""" cd OUTPUT_COLLECT_D - cat /etc/fstab > fstab mdadm --detail --scan > mdadm_status mdadm --detail --scan | grep -c ubuntu > mdadm_active1 grep -c active /proc/mdstat > mdadm_active2 - ls /dev/disk/by-dname > ls_dname - find /etc/network/interfaces.d > find_interfacesd """)] def test_mdadm_output_files_exist(self): - self.output_files_exist( - ["fstab", "mdadm_status", "mdadm_active1", "mdadm_active2", - "ls_dname"]) + self.output_files_exist(["mdadm_status", "mdadm_active1", + "mdadm_active2"]) def test_mdadm_status(self): # ubuntu:<ID> is the name assigned to the md array @@ -36,14 +33,12 @@ class TestMdadmBcacheAbs(TestMdadmAbs): conf_file = "examples/tests/raid5bcache.yaml" disk_to_check = [('md0', 0), ('sda', 2)] - collect_scripts = TestMdadmAbs.collect_scripts + [textwrap.dedent(""" + extra_collect_scripts = TestMdadmAbs.extra_collect_scripts + extra_collect_scripts += [textwrap.dedent(""" cd OUTPUT_COLLECT_D bcache-super-show /dev/vda2 > bcache_super_vda2 ls /sys/fs/bcache > bcache_ls cat /sys/block/bcache0/bcache/cache_mode > bcache_cache_mode - cat /proc/mounts > proc_mounts - cat /proc/partitions > proc_partitions - find /etc/network/interfaces.d > find_interfacesd """)] fstab_expected = { '/dev/bcache0': '/', diff --git a/tests/vmtests/test_simple.py b/tests/vmtests/test_simple.py index de1c6753..8948f72f 100644 --- a/tests/vmtests/test_simple.py +++ b/tests/vmtests/test_simple.py @@ -2,6 +2,7 @@ from . import VMBaseClass from .releases import base_vm_classes as relbase +from .releases import centos_base_vm_classes as centos_relbase import textwrap @@ -11,28 +12,14 @@ class TestSimple(VMBaseClass): conf_file = "examples/tests/simple.yaml" extra_disks = [] extra_nics = [] - collect_scripts = VMBaseClass.collect_scripts + [textwrap.dedent(""" + extra_collect_scripts = [textwrap.dedent(""" cd OUTPUT_COLLECT_D - sfdisk --list > sfdisk_list - for d in /dev/[sv]d[a-z] /dev/xvd?; do - [ -b "$d" ] || continue - echo == $d == - sgdisk --print $d - done > sgdisk_list - blkid > blkid - cat /proc/partitions > proc_partitions - cp /etc/network/interfaces interfaces cp /etc/netplan/50-cloud-init.yaml netplan.yaml - if [ -f /var/log/cloud-init-output.log ]; then - cp /var/log/cloud-init-output.log . - fi - cp /var/log/cloud-init.log . - find /etc/network/interfaces.d > find_interfacesd """)] - def test_output_files_exist(self): - self.output_files_exist(["sfdisk_list", "blkid", - "proc_partitions"]) + +class Centos70TestSimple(centos_relbase.centos70_xenial, TestSimple): + __test__ = True class TrustyTestSimple(relbase.trusty, TestSimple): diff --git a/tests/vmtests/test_ubuntu_core.py b/tests/vmtests/test_ubuntu_core.py index 14234ce4..732399b7 100644 --- a/tests/vmtests/test_ubuntu_core.py +++ b/tests/vmtests/test_ubuntu_core.py @@ -10,12 +10,9 @@ class TestUbuntuCoreAbs(VMBaseClass): target_ftype = "root-image.xz" interactive = False conf_file = "examples/tests/ubuntu_core.yaml" - collect_scripts = VMBaseClass.collect_scripts + [textwrap.dedent(""" + extra_collect_scripts = VMBaseClass.extra_collect_scripts + [ + textwrap.dedent(""" cd OUTPUT_COLLECT_D - cat /proc/partitions > proc_partitions - ls -al /dev/disk/by-uuid/ > ls_uuid - cat /etc/fstab > fstab - find /etc/network/interfaces.d > find_interfacesd snap list > snap_list cp -a /run/cloud-init ./run_cloud_init |: cp -a /etc/cloud ./etc_cloud |: @@ -23,10 +20,8 @@ class TestUbuntuCoreAbs(VMBaseClass): cp -a /var/lib/extrausers . |: """)] - def test_output_files_exist(self): - self.output_files_exist(["snap_list"]) - def test_ubuntu_core_snaps_installed(self): + self.output_files_exist(["snap_list"]) snap_list = self.load_collect_file('snap_list') print(snap_list) for snap in ['core', 'pc', 'pc-kernel', 'hello', diff --git a/tests/vmtests/test_uefi_basic.py b/tests/vmtests/test_uefi_basic.py index 641a0770..40ece659 100644 --- a/tests/vmtests/test_uefi_basic.py +++ b/tests/vmtests/test_uefi_basic.py @@ -1,46 +1,33 @@ # This file is part of curtin. See LICENSE file for copyright and license info. from . import (VMBaseClass) - from .releases import base_vm_classes as relbase +from .releases import centos_base_vm_classes as centos_relbase import textwrap class TestBasicAbs(VMBaseClass): interactive = False + test_type = 'storage' arch_skip = ["s390x"] conf_file = "examples/tests/uefi_basic.yaml" extra_disks = ['4G'] uefi = True disk_to_check = [('main_disk', 1), ('main_disk', 2)] - collect_scripts = VMBaseClass.collect_scripts + [textwrap.dedent(""" + extra_collect_scripts = [textwrap.dedent(""" cd OUTPUT_COLLECT_D - blkid -o export /dev/vda > blkid_output_vda - blkid -o export /dev/vda1 > blkid_output_vda1 - blkid -o export /dev/vda2 > blkid_output_vda2 - cat /proc/partitions > proc_partitions - ls -al /dev/disk/by-uuid/ > ls_uuid - cat /etc/fstab > fstab - mkdir -p /dev/disk/by-dname - ls /dev/disk/by-dname/ > ls_dname - find /etc/network/interfaces.d > find_interfacesd - ls /sys/firmware/efi/ > ls_sys_firmware_efi - cat /sys/class/block/vda/queue/logical_block_size > vda_lbs - cat /sys/class/block/vda/queue/physical_block_size > vda_pbs - blockdev --getsz /dev/vda > vda_blockdev_getsz - blockdev --getss /dev/vda > vda_blockdev_getss - blockdev --getpbsz /dev/vda > vda_blockdev_getpbsz - blockdev --getbsz /dev/vda > vda_blockdev_getbsz + ls /sys/firmware/efi/ | cat >ls_sys_firmware_efi + cp /sys/class/block/vda/queue/logical_block_size vda_lbs + cp /sys/class/block/vda/queue/physical_block_size vda_pbs + blockdev --getsz /dev/vda | cat >vda_blockdev_getsz + blockdev --getss /dev/vda | cat >vda_blockdev_getss + blockdev --getpbsz /dev/vda | cat >vda_blockdev_getpbsz + blockdev --getbsz /dev/vda | cat >vda_blockdev_getbsz """)] - def test_output_files_exist(self): - self.output_files_exist( - ["blkid_output_vda", "blkid_output_vda1", "blkid_output_vda2", - "fstab", "ls_dname", "ls_uuid", "ls_sys_firmware_efi", - "proc_partitions"]) - def test_sys_firmware_efi(self): + self.output_files_exist(["ls_sys_firmware_efi"]) sys_efi_possible = [ 'config_table', 'efivars', @@ -62,8 +49,10 @@ class TestBasicAbs(VMBaseClass): """ Test disk logical and physical block size are match the class block size. """ - for bs in ['lbs', 'pbs']: - size = int(self.load_collect_file('vda_' + bs)) + blocksize_files = ['vda_' + bs for bs in ['lbs', 'pbs']] + self.output_files_exist(blocksize_files) + for bs_file in blocksize_files: + size = int(self.load_collect_file(bs_file)) self.assertEqual(self.disk_block_size, size) def test_disk_block_size_with_blockdev(self): @@ -73,11 +62,17 @@ class TestBasicAbs(VMBaseClass): --getpbsz get physical block (sector) size --getbsz get blocksize """ - for syscall in ['getss', 'getpbsz']: - size = int(self.load_collect_file('vda_blockdev_' + syscall)) + bdev_files = ['vda_blockdev_' + sc for sc in ['getss', 'getpbsz']] + self.output_files_exist(bdev_files) + for sc_file in bdev_files: + size = int(self.load_collect_file(sc_file)) self.assertEqual(self.disk_block_size, size) +class Centos70UefiTestBasic(centos_relbase.centos70_xenial, TestBasicAbs): + __test__ = True + + class PreciseUefiTestBasic(relbase.precise, TestBasicAbs): __test__ = False @@ -120,6 +115,10 @@ class CosmicUefiTestBasic(relbase.cosmic, TestBasicAbs): __test__ = True +class Centos70UefiTestBasic4k(centos_relbase.centos70_xenial, TestBasicAbs): + disk_block_size = 4096 + + class TrustyUefiTestBasic4k(TrustyUefiTestBasic): disk_block_size = 4096 diff --git a/tests/vmtests/test_zfsroot.py b/tests/vmtests/test_zfsroot.py index e159d176..4e257aec 100644 --- a/tests/vmtests/test_zfsroot.py +++ b/tests/vmtests/test_zfsroot.py @@ -6,43 +6,27 @@ import textwrap class TestZfsRootAbs(VMBaseClass): interactive = False + test_type = 'storage' nr_cpus = 2 dirty_disks = True conf_file = "examples/tests/zfsroot.yaml" extra_disks = [] - collect_scripts = VMBaseClass.collect_scripts + [ - textwrap.dedent(""" + extra_collect_scripts = [textwrap.dedent(""" cd OUTPUT_COLLECT_D blkid -o export /dev/vda > blkid_output_vda - blkid -o export /dev/vda1 > blkid_output_vda1 - blkid -o export /dev/vda2 > blkid_output_vda2 zfs list > zfs_list zpool list > zpool_list zpool status > zpool_status - cat /proc/partitions > proc_partitions - cat /proc/mounts > proc_mounts - cat /proc/cmdline > proc_cmdline - ls -al /dev/disk/by-uuid/ > ls_uuid - cat /etc/fstab > fstab - mkdir -p /dev/disk/by-dname - ls /dev/disk/by-dname/ > ls_dname - find /etc/network/interfaces.d > find_interfacesd - v="" - out=$(apt-config shell v Acquire::HTTP::Proxy) - eval "$out" - echo "$v" > apt-proxy """)] @skip_if_flag('expected_failure') def test_output_files_exist(self): - self.output_files_exist( - ["blkid_output_vda", "blkid_output_vda1", "blkid_output_vda2", - "fstab", "ls_dname", "ls_uuid", - "proc_partitions", - "root/curtin-install.log", "root/curtin-install-cfg.yaml"]) + self.output_files_exist(["root/curtin-install.log", + "root/curtin-install-cfg.yaml"]) @skip_if_flag('expected_failure') def test_ptable(self): + self.output_files_exist(["blkid_output_vda"]) blkid_info = self.get_blkid_data("blkid_output_vda") self.assertEquals(blkid_info["PTTYPE"], "gpt") |
