Merge ~chad.smith/curtin:ubuntu/devel into curtin:ubuntu/devel

Proposed by Chad Smith
Status: Merged
Merged at revision: cfa2da2bd7a47b5bd585d04f824be7e3c22ccd5e
Proposed branch: ~chad.smith/curtin:ubuntu/devel
Merge into: curtin:ubuntu/devel
Diff against target: 2225 lines (+662/-342)
51 files modified
bin/curtin (+1/-1)
curtin/__main__.py (+4/-0)
curtin/block/__init__.py (+14/-10)
curtin/block/clear_holders.py (+24/-2)
curtin/block/mkfs.py (+2/-2)
curtin/commands/__main__.py (+4/-0)
curtin/commands/curthooks.py (+3/-1)
curtin/commands/features.py (+20/-0)
curtin/commands/main.py (+3/-3)
debian/changelog (+25/-0)
doc/topics/integration-testing.rst (+4/-0)
doc/topics/storage.rst (+79/-3)
examples/tests/install_disable_unmount.yaml (+2/-2)
examples/tests/mirrorboot-msdos-partition.yaml (+2/-2)
examples/tests/mirrorboot-uefi.yaml (+4/-4)
examples/tests/vmtest_pollinate.yaml (+10/-0)
tests/unittests/test_clear_holders.py (+94/-38)
tests/vmtests/__init__.py (+201/-73)
tests/vmtests/releases.py (+19/-20)
tests/vmtests/test_apt_config_cmd.py (+2/-2)
tests/vmtests/test_basic.py (+20/-10)
tests/vmtests/test_bcache_basic.py (+2/-2)
tests/vmtests/test_bcache_bug1718699.py (+2/-2)
tests/vmtests/test_fs_battery.py (+4/-0)
tests/vmtests/test_iscsi.py (+2/-2)
tests/vmtests/test_journald_reporter.py (+2/-2)
tests/vmtests/test_lvm.py (+3/-2)
tests/vmtests/test_lvm_iscsi.py (+2/-2)
tests/vmtests/test_lvm_root.py (+5/-35)
tests/vmtests/test_mdadm_bcache.py (+17/-21)
tests/vmtests/test_mdadm_iscsi.py (+2/-2)
tests/vmtests/test_multipath.py (+2/-2)
tests/vmtests/test_network.py (+2/-2)
tests/vmtests/test_network_alias.py (+2/-2)
tests/vmtests/test_network_bonding.py (+15/-26)
tests/vmtests/test_network_bridging.py (+18/-26)
tests/vmtests/test_network_ipv6.py (+2/-2)
tests/vmtests/test_network_ipv6_static.py (+2/-2)
tests/vmtests/test_network_ipv6_vlan.py (+2/-2)
tests/vmtests/test_network_mtu.py (+4/-12)
tests/vmtests/test_network_static.py (+2/-2)
tests/vmtests/test_network_static_routes.py (+2/-2)
tests/vmtests/test_network_vlan.py (+3/-3)
tests/vmtests/test_nvme.py (+5/-4)
tests/vmtests/test_pollinate_useragent.py (+3/-0)
tests/vmtests/test_raid5_bcache.py (+2/-2)
tests/vmtests/test_simple.py (+2/-2)
tests/vmtests/test_uefi_basic.py (+4/-4)
tests/vmtests/test_zfsroot.py (+6/-2)
tools/xkvm (+5/-1)
tox.ini (+1/-1)
Reviewer Review Type Date Requested Status
Server Team CI bot continuous-integration Approve
Scott Moser (community) Approve
Review via email: mp+352901@code.launchpad.net

Commit message

Sync new-upstream-snapshot of curtin for release into Cosmic

To post a comment you must log in.
Revision history for this message
Scott Moser (smoser) wrote :

lgtm

review: Approve
Revision history for this message
Server Team CI bot (server-team-bot) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/bin/curtin b/bin/curtin
index 6c4e457..793fbcb 100755
--- a/bin/curtin
+++ b/bin/curtin
@@ -1,7 +1,7 @@
1#!/bin/sh1#!/bin/sh
2# This file is part of curtin. See LICENSE file for copyright and license info.2# This file is part of curtin. See LICENSE file for copyright and license info.
33
4PY3OR2_MAIN="curtin.commands.main"4PY3OR2_MAIN="curtin"
5PY3OR2_MCHECK="curtin.deps.check"5PY3OR2_MCHECK="curtin.deps.check"
6PY3OR2_PYTHONS=${PY3OR2_PYTHONS:-"python3:python"}6PY3OR2_PYTHONS=${PY3OR2_PYTHONS:-"python3:python"}
7PYTHON=${PY3OR2_PYTHON}7PYTHON=${PY3OR2_PYTHON}
diff --git a/curtin/__main__.py b/curtin/__main__.py
8new file mode 1006448new file mode 100644
index 0000000..5b6aeca
--- /dev/null
+++ b/curtin/__main__.py
@@ -0,0 +1,4 @@
1if __name__ == '__main__':
2 from .commands.main import main
3 import sys
4 sys.exit(main())
diff --git a/curtin/block/__init__.py b/curtin/block/__init__.py
index a8ee8a6..b49b9d3 100644
--- a/curtin/block/__init__.py
+++ b/curtin/block/__init__.py
@@ -378,24 +378,28 @@ def stop_all_unused_multipath_devices():
378 LOG.warn("Failed to stop multipath devices: %s", e)378 LOG.warn("Failed to stop multipath devices: %s", e)
379379
380380
381def rescan_block_devices(warn_on_fail=True):381def rescan_block_devices(devices=None, warn_on_fail=True):
382 """382 """
383 run 'blockdev --rereadpt' for all block devices not currently mounted383 run 'blockdev --rereadpt' for all block devices not currently mounted
384 """384 """
385 unused = get_unused_blockdev_info()385 if not devices:
386 devices = []386 unused = get_unused_blockdev_info()
387 for devname, data in unused.items():387 devices = []
388 if data.get('RM') == "1":388 for devname, data in unused.items():
389 continue389 if data.get('RM') == "1":
390 if data.get('RO') != "0" or data.get('TYPE') != "disk":390 continue
391 continue391 if data.get('RO') != "0" or data.get('TYPE') != "disk":
392 devices.append(data['device_path'])392 continue
393 devices.append(data['device_path'])
393394
394 if not devices:395 if not devices:
395 LOG.debug("no devices found to rescan")396 LOG.debug("no devices found to rescan")
396 return397 return
397398
398 cmd = ['blockdev', '--rereadpt'] + devices399 # blockdev needs /dev/ parameters, convert if needed
400 cmd = ['blockdev', '--rereadpt'] + [dev if dev.startswith('/dev/')
401 else sysfs_to_devpath(dev)
402 for dev in devices]
399 try:403 try:
400 util.subp(cmd, capture=True)404 util.subp(cmd, capture=True)
401 except util.ProcessExecutionError as e:405 except util.ProcessExecutionError as e:
diff --git a/curtin/block/clear_holders.py b/curtin/block/clear_holders.py
index 20c572b..9d73b28 100644
--- a/curtin/block/clear_holders.py
+++ b/curtin/block/clear_holders.py
@@ -300,6 +300,9 @@ def wipe_superblock(device):
300 else:300 else:
301 raise e301 raise e
302302
303 # gather any partitions
304 partitions = block.get_sysfs_partitions(device)
305
303 # release zfs member by exporting the pool306 # release zfs member by exporting the pool
304 if block.is_zfs_member(blockdev):307 if block.is_zfs_member(blockdev):
305 poolname = zfs.device_to_poolname(blockdev)308 poolname = zfs.device_to_poolname(blockdev)
@@ -325,6 +328,27 @@ def wipe_superblock(device):
325328
326 _wipe_superblock(blockdev)329 _wipe_superblock(blockdev)
327330
331 # if we had partitions, make sure they've been removed
332 if partitions:
333 LOG.debug('%s had partitions, issuing partition reread', device)
334 retries = [.5, .5, 1, 2, 5, 7]
335 for attempt, wait in enumerate(retries):
336 try:
337 # only rereadpt on wiped device
338 block.rescan_block_devices(devices=[blockdev])
339 # may raise IOError, OSError due to wiped partition table
340 curparts = block.get_sysfs_partitions(device)
341 if len(curparts) == 0:
342 return
343 except (IOError, OSError):
344 if attempt + 1 >= len(retries):
345 raise
346
347 LOG.debug("%s partitions still present, rereading pt"
348 " (%s/%s). sleeping %ss before retry",
349 device, attempt + 1, len(retries), wait)
350 time.sleep(wait)
351
328352
329def _wipe_superblock(blockdev, exclusive=True):353def _wipe_superblock(blockdev, exclusive=True):
330 """ No checks, just call wipe_volume """354 """ No checks, just call wipe_volume """
@@ -579,8 +603,6 @@ def clear_holders(base_paths, try_preserve=False):
579 dev_info['dev_type'])603 dev_info['dev_type'])
580 continue604 continue
581605
582 # scan before we check
583 block.rescan_block_devices(warn_on_fail=False)
584 if os.path.exists(dev_info['device']):606 if os.path.exists(dev_info['device']):
585 LOG.info("shutdown running on holder type: '%s' syspath: '%s'",607 LOG.info("shutdown running on holder type: '%s' syspath: '%s'",
586 dev_info['dev_type'], dev_info['device'])608 dev_info['dev_type'], dev_info['device'])
diff --git a/curtin/block/mkfs.py b/curtin/block/mkfs.py
index a199d05..f39017c 100644
--- a/curtin/block/mkfs.py
+++ b/curtin/block/mkfs.py
@@ -8,7 +8,7 @@ from curtin import block
88
9import string9import string
10import os10import os
11from uuid import uuid111from uuid import uuid4
1212
13mkfs_commands = {13mkfs_commands = {
14 "btrfs": "mkfs.btrfs",14 "btrfs": "mkfs.btrfs",
@@ -191,7 +191,7 @@ def mkfs(path, fstype, strict=False, label=None, uuid=None, force=False):
191191
192 # If uuid is not specified, generate one and try to use it192 # If uuid is not specified, generate one and try to use it
193 if uuid is None:193 if uuid is None:
194 uuid = str(uuid1())194 uuid = str(uuid4())
195 cmd.extend(get_flag_mapping("uuid", fs_family, param=uuid, strict=strict))195 cmd.extend(get_flag_mapping("uuid", fs_family, param=uuid, strict=strict))
196196
197 if fs_family == "fat":197 if fs_family == "fat":
diff --git a/curtin/commands/__main__.py b/curtin/commands/__main__.py
198new file mode 100644198new file mode 100644
index 0000000..41c6d17
--- /dev/null
+++ b/curtin/commands/__main__.py
@@ -0,0 +1,4 @@
1if __name__ == '__main__':
2 from .main import main
3 import sys
4 sys.exit(main())
diff --git a/curtin/commands/curthooks.py b/curtin/commands/curthooks.py
index a514560..f9a5a66 100644
--- a/curtin/commands/curthooks.py
+++ b/curtin/commands/curthooks.py
@@ -679,7 +679,9 @@ def install_missing_packages(cfg, target):
679 needed_packages.add(pkg)679 needed_packages.add(pkg)
680680
681 # Filter out ifupdown network packages on netplan enabled systems.681 # Filter out ifupdown network packages on netplan enabled systems.
682 if 'ifupdown' not in installed_packages and 'nplan' in installed_packages:682 has_netplan = ('nplan' in installed_packages or
683 'netplan.io' in installed_packages)
684 if 'ifupdown' not in installed_packages and has_netplan:
683 drops = set(['bridge-utils', 'ifenslave', 'vlan'])685 drops = set(['bridge-utils', 'ifenslave', 'vlan'])
684 if needed_packages.union(drops):686 if needed_packages.union(drops):
685 LOG.debug("Skipping install of %s. Not needed on netplan system.",687 LOG.debug("Skipping install of %s. Not needed on netplan system.",
diff --git a/curtin/commands/features.py b/curtin/commands/features.py
686new file mode 100644688new file mode 100644
index 0000000..0f6085b
--- /dev/null
+++ b/curtin/commands/features.py
@@ -0,0 +1,20 @@
1# This file is part of curtin. See LICENSE file for copyright and license info.
2"""List the supported feature names to stdout."""
3
4import sys
5from .. import FEATURES
6from . import populate_one_subcmd
7
8CMD_ARGUMENTS = ((tuple()))
9
10
11def features_main(args):
12 sys.stdout.write("\n".join(sorted(FEATURES)) + "\n")
13 sys.exit(0)
14
15
16def POPULATE_SUBCMD(parser):
17 populate_one_subcmd(parser, CMD_ARGUMENTS, features_main)
18 parser.description = __doc__
19
20# vi: ts=4 expandtab syntax=python
diff --git a/curtin/commands/main.py b/curtin/commands/main.py
index 779bb03..bccfc51 100644
--- a/curtin/commands/main.py
+++ b/curtin/commands/main.py
@@ -16,9 +16,9 @@ VERSIONSTR = version.version_string()
16SUB_COMMAND_MODULES = [16SUB_COMMAND_MODULES = [
17 'apply_net', 'apt-config', 'block-attach-iscsi', 'block-detach-iscsi',17 'apply_net', 'apt-config', 'block-attach-iscsi', 'block-detach-iscsi',
18 'block-info', 'block-meta', 'block-wipe', 'clear-holders', 'curthooks',18 'block-info', 'block-meta', 'block-wipe', 'clear-holders', 'curthooks',
19 'collect-logs', 'extract', 'hook', 'install', 'mkfs', 'in-target',19 'collect-logs', 'extract', 'features',
20 'net-meta', 'pack', 'swap', 'system-install', 'system-upgrade', 'unmount',20 'hook', 'install', 'mkfs', 'in-target', 'net-meta', 'pack', 'swap',
21 'version',21 'system-install', 'system-upgrade', 'unmount', 'version',
22]22]
2323
2424
diff --git a/debian/changelog b/debian/changelog
index dfd5560..8f013e6 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,28 @@
1curtin (18.1-44-g2b12b8fc-0ubuntu1) cosmic; urgency=medium
2
3 * New upstream snapshot.
4 - Add main so that 'python3 -m curtin' does the right thing.
5 - Add subcommand 'features'.
6 - block: use uuid4 (random) when autogenerating UUIDS for filesystems
7 - vmtests: Increase size of root filesystems.
8 - clear-holders: reread ptable after wiping disks with partitions
9 - vmtest: Skip proposed pocket on dev release when 'proposed' in ADD_REPOS.
10 - tests: remove Ubuntu Artful [Joshua Powers]
11 - vmtests: Let a raised SkipTest go through skip_by_date.
12 - vmtests: Increase root fs to give upgrades to -proposed more space.
13 - vmtest: Order the vmtest_pollinate late_command earlier.
14 - vmtest: always add 'curtin/vmtest' to installed pollinate user_agent.
15 - vmtests: make skip_by_date a decorator that runs and reports.
16 - vmtests: always declare certain attributes and remove redundant tests.
17 - vmtests: Add Cosmic release to tests [Joshua Powers]
18 - vmtests: skip TrustyTestMdadmBcache until 2019-01-22.
19 - tox: use simplestreams from git repository rather than bzr.
20 - document that you can set ptable on raids [Michael Hudson-Doyle]
21 - vmtests: move skip-by date of xfs root and xfs boot out 1 year.
22 - vmtests: network_mtu move fixby date out 4 months from last value
23
24 -- Chad Smith <chad.smith@canonical.com> Fri, 10 Aug 2018 09:22:12 -0600
25
1curtin (18.1-25-g9d0e557e-0ubuntu1) cosmic; urgency=medium26curtin (18.1-25-g9d0e557e-0ubuntu1) cosmic; urgency=medium
227
3 * New upstream snapshot.28 * New upstream snapshot.
diff --git a/doc/topics/integration-testing.rst b/doc/topics/integration-testing.rst
index 7753068..6093b55 100644
--- a/doc/topics/integration-testing.rst
+++ b/doc/topics/integration-testing.rst
@@ -314,6 +314,10 @@ Some environment variables affect the running of vmtest
314 setting (auto), then a upgrade will be done to make sure to include314 setting (auto), then a upgrade will be done to make sure to include
315 any new packages.315 any new packages.
316316
317 The string 'proposed' is handled specially. It will enable the
318 Ubuntu -proposed pocket for non-devel releases. If you wish to test
319 the -proposed pocket for a devel release, use 'PROPOSED'.
320
317- ``CURTIN_VMTEST_SYSTEM_UPGRADE``: default 'auto'321- ``CURTIN_VMTEST_SYSTEM_UPGRADE``: default 'auto'
318 The default setting of 'auto' means to do a system upgrade if322 The default setting of 'auto' means to do a system upgrade if
319 there are additional repos added. To enable this explicitly, set323 there are additional repos added. To enable this explicitly, set
diff --git a/doc/topics/storage.rst b/doc/topics/storage.rst
index ca6253c..b28964b 100644
--- a/doc/topics/storage.rst
+++ b/doc/topics/storage.rst
@@ -60,9 +60,9 @@ table. A disk command may contain all or some of the following keys:
6060
61**ptable**: *msdos, gpt*61**ptable**: *msdos, gpt*
6262
63If the ``ptable`` key is present and a valid type of partition table, curtin63If the ``ptable`` key is present and a curtin will create an empty
64will create an empty partition table of that type on the disk. At the moment,64partition table of that type on the disk. Curtin supports msdos and
65msdos and gpt partition tables are supported.65gpt partition tables.
6666
67**serial**: *<serial number>*67**serial**: *<serial number>*
6868
@@ -613,6 +613,11 @@ The ``spare_devices`` key specifies a list of the devices that will be used for
613spares in the raid array. Each device must be referenced by ``id`` and the613spares in the raid array. Each device must be referenced by ``id`` and the
614device must be previously defined in the storage configuration. May be empty.614device must be previously defined in the storage configuration. May be empty.
615615
616**ptable**: *msdos, gpt*
617
618To partition the array rather than mounting it directly, the
619``ptable`` key must be present and a valid type of partition table,
620i.e. msdos or gpt.
616621
617**Config Example**::622**Config Example**::
618623
@@ -801,6 +806,7 @@ Learn by examples.
801- LVM806- LVM
802- Bcache807- Bcache
803- RAID Boot808- RAID Boot
809- Partitioned RAID
804- RAID5 + Bcache810- RAID5 + Bcache
805- ZFS Root Simple811- ZFS Root Simple
806- ZFS Root812- ZFS Root
@@ -1045,6 +1051,76 @@ RAID Boot
1045 path: /1051 path: /
1046 device: md_root1052 device: md_root
10471053
1054Partitioned RAID
1055~~~~~~~~~~~~~~~~
1056
1057::
1058
1059 storage:
1060 config:
1061 - type: disk
1062 id: disk-0
1063 ptable: gpt
1064 path: /dev/vda
1065 wipe: superblock
1066 grub_device: true
1067 - type: disk
1068 id: disk-1
1069 path: /dev/vdb
1070 wipe: superblock
1071 - type: disk
1072 id: disk-2
1073 path: /dev/vdc
1074 wipe: superblock
1075 - type: partition
1076 id: part-0
1077 device: disk-0
1078 size: 1048576
1079 flag: bios_grub
1080 - type: partition
1081 id: part-1
1082 device: disk-0
1083 size: 21471690752
1084 - id: raid-0
1085 type: raid
1086 name: md0
1087 raidlevel: 1
1088 devices: [disk-2, disk-1]
1089 ptable: gpt
1090 - type: partition
1091 id: part-2
1092 device: raid-0
1093 size: 10737418240
1094 - type: partition
1095 id: part-3
1096 device: raid-0
1097 size: 10735321088,
1098 - type: format
1099 id: fs-0
1100 fstype: ext4
1101 volume: part-1
1102 - type: format
1103 id: fs-1
1104 fstype: xfs
1105 volume: part-2
1106 - type: format
1107 id: fs-2
1108 fstype: ext4
1109 volume: part-3
1110 - type: mount
1111 id: mount-0
1112 device: fs-0
1113 path: /
1114 - type: mount
1115 id: mount-1
1116 device: fs-1
1117 path: /srv
1118 - type: mount
1119 id: mount-2
1120 device: fs-2
1121 path: /home
1122 version: 1
1123
10481124
1049RAID5 + Bcache1125RAID5 + Bcache
1050~~~~~~~~~~~~~~1126~~~~~~~~~~~~~~
diff --git a/examples/tests/install_disable_unmount.yaml b/examples/tests/install_disable_unmount.yaml
index d3e583f..c0cd759 100644
--- a/examples/tests/install_disable_unmount.yaml
+++ b/examples/tests/install_disable_unmount.yaml
@@ -14,5 +14,5 @@ post_cmds:
14late_commands:14late_commands:
15 01_get_proc_mounts: [sh, -c, *cat_proc_mounts]15 01_get_proc_mounts: [sh, -c, *cat_proc_mounts]
16 02_write_out_target: [sh, -c, *echo_target_mp]16 02_write_out_target: [sh, -c, *echo_target_mp]
17 03_unmount_target: [curtin, unmount]17 99a_unmount_target: [curtin, unmount]
18 04_get_proc_mounts: [cat, /proc/mounts]18 99b_get_proc_mounts: [cat, /proc/mounts]
diff --git a/examples/tests/mirrorboot-msdos-partition.yaml b/examples/tests/mirrorboot-msdos-partition.yaml
index 1a418fa..2b111a7 100644
--- a/examples/tests/mirrorboot-msdos-partition.yaml
+++ b/examples/tests/mirrorboot-msdos-partition.yaml
@@ -47,7 +47,7 @@ storage:
47 name: md0-part147 name: md0-part1
48 number: 148 number: 1
49 offset: 4194304B49 offset: 4194304B
50 size: 2GB50 size: 3GB
51 type: partition51 type: partition
52 uuid: 4f4fa336-2762-48e4-ae54-9451141665cd52 uuid: 4f4fa336-2762-48e4-ae54-9451141665cd
53 wipe: superblock53 wipe: superblock
@@ -55,7 +55,7 @@ storage:
55 id: md0-part255 id: md0-part2
56 name: md0-part256 name: md0-part2
57 number: 257 number: 2
58 size: 2GB58 size: 1.5GB
59 type: partition59 type: partition
60 uuid: c2d21fd3-3cde-4432-8eab-f08594bbe76e60 uuid: c2d21fd3-3cde-4432-8eab-f08594bbe76e
61 wipe: superblock61 wipe: superblock
diff --git a/examples/tests/mirrorboot-uefi.yaml b/examples/tests/mirrorboot-uefi.yaml
index e1f393f..ca55be9 100644
--- a/examples/tests/mirrorboot-uefi.yaml
+++ b/examples/tests/mirrorboot-uefi.yaml
@@ -30,7 +30,7 @@ storage:
30 id: sda-part230 id: sda-part2
31 name: sda-part231 name: sda-part2
32 number: 232 number: 2
33 size: 2G33 size: 3G
34 type: partition34 type: partition
35 uuid: 47c97eae-f35d-473f-8f3d-d64161d571f135 uuid: 47c97eae-f35d-473f-8f3d-d64161d571f1
36 wipe: superblock36 wipe: superblock
@@ -38,7 +38,7 @@ storage:
38 id: sda-part338 id: sda-part3
39 name: sda-part339 name: sda-part3
40 number: 340 number: 3
41 size: 2G41 size: 1G
42 type: partition42 type: partition
43 uuid: e3202633-841c-4936-a520-b18d1f7938ea43 uuid: e3202633-841c-4936-a520-b18d1f7938ea
44 wipe: superblock44 wipe: superblock
@@ -56,7 +56,7 @@ storage:
56 id: sdb-part256 id: sdb-part2
57 name: sdb-part257 name: sdb-part2
58 number: 258 number: 2
59 size: 2G59 size: 3G
60 type: partition60 type: partition
61 uuid: a33a83dd-d1bf-4940-bf3e-6d931de85dbc61 uuid: a33a83dd-d1bf-4940-bf3e-6d931de85dbc
62 wipe: superblock62 wipe: superblock
@@ -72,7 +72,7 @@ storage:
72 id: sdb-part372 id: sdb-part3
73 name: sdb-part373 name: sdb-part3
74 number: 374 number: 3
75 size: 2G75 size: 1G
76 type: partition76 type: partition
77 uuid: 27e29758-fdcf-4c6a-8578-c92f907a8a9d77 uuid: 27e29758-fdcf-4c6a-8578-c92f907a8a9d
78 wipe: superblock78 wipe: superblock
diff --git a/examples/tests/vmtest_pollinate.yaml b/examples/tests/vmtest_pollinate.yaml
79new file mode 10064479new file mode 100644
index 0000000..e4fac06
--- /dev/null
+++ b/examples/tests/vmtest_pollinate.yaml
@@ -0,0 +1,10 @@
1# this updates pollinate in the installed target to add a vmtest identifier.
2# specifically pollinate's user-agent should contain 'curtin/vmtest'.
3_vmtest_pollinate:
4 - &pvmtest |
5 cfg="/etc/pollinate/add-user-agent"
6 [ -d "${cfg%/*}" ] || exit 0
7 echo curtin/vmtest >> "$cfg"
8
9late_commands:
10 01_vmtest_pollinate: ['curtin', 'in-target', '--', 'sh', '-c', *pvmtest]
diff --git a/tests/unittests/test_clear_holders.py b/tests/unittests/test_clear_holders.py
index ceb5615..6c29171 100644
--- a/tests/unittests/test_clear_holders.py
+++ b/tests/unittests/test_clear_holders.py
@@ -10,7 +10,7 @@ from .helpers import CiTestCase
1010
1111
12class TestClearHolders(CiTestCase):12class TestClearHolders(CiTestCase):
13 test_blockdev = '/dev/null'13 test_blockdev = '/wark/dev/null'
14 test_syspath = '/sys/class/block/null'14 test_syspath = '/sys/class/block/null'
15 remove_retries = [0.2] * 150 # clear_holders defaults to 30 seconds15 remove_retries = [0.2] * 150 # clear_holders defaults to 30 seconds
16 example_holders_trees = [16 example_holders_trees = [
@@ -153,7 +153,7 @@ class TestClearHolders(CiTestCase):
153 #153 #
154154
155 device = self.test_syspath155 device = self.test_syspath
156 mock_block.sys_block_path.return_value = '/dev/null'156 mock_block.sys_block_path.return_value = self.test_blockdev
157 bcache_cset_uuid = 'c08ae789-a964-46fb-a66e-650f0ae78f94'157 bcache_cset_uuid = 'c08ae789-a964-46fb-a66e-650f0ae78f94'
158158
159 mock_os.path.exists.return_value = True159 mock_os.path.exists.return_value = True
@@ -189,9 +189,8 @@ class TestClearHolders(CiTestCase):
189 def test_shutdown_bcache_non_sysfs_device(self, mock_get_bcache, mock_log,189 def test_shutdown_bcache_non_sysfs_device(self, mock_get_bcache, mock_log,
190 mock_os, mock_util,190 mock_os, mock_util,
191 mock_get_bcache_block):191 mock_get_bcache_block):
192 device = "/dev/fakenull"
193 with self.assertRaises(ValueError):192 with self.assertRaises(ValueError):
194 clear_holders.shutdown_bcache(device)193 clear_holders.shutdown_bcache(self.test_blockdev)
195194
196 self.assertEqual(0, len(mock_get_bcache.call_args_list))195 self.assertEqual(0, len(mock_get_bcache.call_args_list))
197 self.assertEqual(0, len(mock_log.call_args_list))196 self.assertEqual(0, len(mock_log.call_args_list))
@@ -208,11 +207,10 @@ class TestClearHolders(CiTestCase):
208 def test_shutdown_bcache_no_device(self, mock_get_bcache, mock_log,207 def test_shutdown_bcache_no_device(self, mock_get_bcache, mock_log,
209 mock_os, mock_util,208 mock_os, mock_util,
210 mock_get_bcache_block, mock_block):209 mock_get_bcache_block, mock_block):
211 device = "/sys/class/block/null"210 mock_block.sysfs_to_devpath.return_value = self.test_blockdev
212 mock_block.sysfs_to_devpath.return_value = '/dev/null'
213 mock_os.path.exists.return_value = False211 mock_os.path.exists.return_value = False
214212
215 clear_holders.shutdown_bcache(device)213 clear_holders.shutdown_bcache(self.test_syspath)
216214
217 self.assertEqual(3, len(mock_log.info.call_args_list))215 self.assertEqual(3, len(mock_log.info.call_args_list))
218 self.assertEqual(1, len(mock_os.path.exists.call_args_list))216 self.assertEqual(1, len(mock_os.path.exists.call_args_list))
@@ -229,18 +227,17 @@ class TestClearHolders(CiTestCase):
229 def test_shutdown_bcache_no_cset(self, mock_get_bcache, mock_log,227 def test_shutdown_bcache_no_cset(self, mock_get_bcache, mock_log,
230 mock_os, mock_util,228 mock_os, mock_util,
231 mock_get_bcache_block, mock_block):229 mock_get_bcache_block, mock_block):
232 device = "/sys/class/block/null"230 mock_block.sysfs_to_devpath.return_value = self.test_blockdev
233 mock_block.sysfs_to_devpath.return_value = '/dev/null'
234 mock_os.path.exists.side_effect = iter([231 mock_os.path.exists.side_effect = iter([
235 True, # backing device exists232 True, # backing device exists
236 False, # cset device not present (already removed)233 False, # cset device not present (already removed)
237 True, # backing device (still) exists234 True, # backing device (still) exists
238 ])235 ])
239 mock_get_bcache.return_value = '/sys/fs/bcache/fake'236 mock_get_bcache.return_value = '/sys/fs/bcache/fake'
240 mock_get_bcache_block.return_value = device + '/bcache'237 mock_get_bcache_block.return_value = self.test_syspath + '/bcache'
241 mock_os.path.join.side_effect = os.path.join238 mock_os.path.join.side_effect = os.path.join
242239
243 clear_holders.shutdown_bcache(device)240 clear_holders.shutdown_bcache(self.test_syspath)
244241
245 self.assertEqual(4, len(mock_log.info.call_args_list))242 self.assertEqual(4, len(mock_log.info.call_args_list))
246 self.assertEqual(3, len(mock_os.path.exists.call_args_list))243 self.assertEqual(3, len(mock_os.path.exists.call_args_list))
@@ -249,14 +246,15 @@ class TestClearHolders(CiTestCase):
249 self.assertEqual(1, len(mock_util.write_file.call_args_list))246 self.assertEqual(1, len(mock_util.write_file.call_args_list))
250 self.assertEqual(2, len(mock_util.wait_for_removal.call_args_list))247 self.assertEqual(2, len(mock_util.wait_for_removal.call_args_list))
251248
252 mock_get_bcache.assert_called_with(device, strict=False)249 mock_get_bcache.assert_called_with(self.test_syspath, strict=False)
253 mock_get_bcache_block.assert_called_with(device, strict=False)250 mock_get_bcache_block.assert_called_with(self.test_syspath,
254 mock_util.write_file.assert_called_with(device + '/bcache/stop',251 strict=False)
255 '1', mode=None)252 mock_util.write_file.assert_called_with(
253 self.test_syspath + '/bcache/stop', '1', mode=None)
256 retries = self.remove_retries254 retries = self.remove_retries
257 mock_util.wait_for_removal.assert_has_calls([255 mock_util.wait_for_removal.assert_has_calls([
258 mock.call(device, retries=retries),256 mock.call(self.test_syspath, retries=retries),
259 mock.call(device + '/bcache', retries=retries)])257 mock.call(self.test_syspath + '/bcache', retries=retries)])
260258
261 @mock.patch('curtin.block.clear_holders.block')259 @mock.patch('curtin.block.clear_holders.block')
262 @mock.patch('curtin.block.clear_holders.udev.udevadm_settle')260 @mock.patch('curtin.block.clear_holders.udev.udevadm_settle')
@@ -271,8 +269,7 @@ class TestClearHolders(CiTestCase):
271 mock_get_bcache_block,269 mock_get_bcache_block,
272 mock_udevadm_settle,270 mock_udevadm_settle,
273 mock_block):271 mock_block):
274 device = "/sys/class/block/null"272 mock_block.sysfs_to_devpath.return_value = self.test_blockdev
275 mock_block.sysfs_to_devpath.return_value = '/dev/null'
276 mock_os.path.exists.side_effect = iter([273 mock_os.path.exists.side_effect = iter([
277 True, # backing device exists274 True, # backing device exists
278 True, # cset device not present (already removed)275 True, # cset device not present (already removed)
@@ -280,10 +277,10 @@ class TestClearHolders(CiTestCase):
280 ])277 ])
281 cset = '/sys/fs/bcache/fake'278 cset = '/sys/fs/bcache/fake'
282 mock_get_bcache.return_value = cset279 mock_get_bcache.return_value = cset
283 mock_get_bcache_block.return_value = device + '/bcache'280 mock_get_bcache_block.return_value = self.test_syspath + '/bcache'
284 mock_os.path.join.side_effect = os.path.join281 mock_os.path.join.side_effect = os.path.join
285282
286 clear_holders.shutdown_bcache(device)283 clear_holders.shutdown_bcache(self.test_syspath)
287284
288 self.assertEqual(4, len(mock_log.info.call_args_list))285 self.assertEqual(4, len(mock_log.info.call_args_list))
289 self.assertEqual(3, len(mock_os.path.exists.call_args_list))286 self.assertEqual(3, len(mock_os.path.exists.call_args_list))
@@ -292,14 +289,15 @@ class TestClearHolders(CiTestCase):
292 self.assertEqual(2, len(mock_util.write_file.call_args_list))289 self.assertEqual(2, len(mock_util.write_file.call_args_list))
293 self.assertEqual(3, len(mock_util.wait_for_removal.call_args_list))290 self.assertEqual(3, len(mock_util.wait_for_removal.call_args_list))
294291
295 mock_get_bcache.assert_called_with(device, strict=False)292 mock_get_bcache.assert_called_with(self.test_syspath, strict=False)
296 mock_get_bcache_block.assert_called_with(device, strict=False)293 mock_get_bcache_block.assert_called_with(self.test_syspath,
294 strict=False)
297 mock_util.write_file.assert_has_calls([295 mock_util.write_file.assert_has_calls([
298 mock.call(cset + '/stop', '1', mode=None),296 mock.call(cset + '/stop', '1', mode=None),
299 mock.call(device + '/bcache/stop', '1', mode=None)])297 mock.call(self.test_syspath + '/bcache/stop', '1', mode=None)])
300 mock_util.wait_for_removal.assert_has_calls([298 mock_util.wait_for_removal.assert_has_calls([
301 mock.call(cset, retries=self.remove_retries),299 mock.call(cset, retries=self.remove_retries),
302 mock.call(device, retries=self.remove_retries)300 mock.call(self.test_syspath, retries=self.remove_retries)
303 ])301 ])
304302
305 @mock.patch('curtin.block.clear_holders.block')303 @mock.patch('curtin.block.clear_holders.block')
@@ -315,8 +313,7 @@ class TestClearHolders(CiTestCase):
315 mock_get_bcache_block,313 mock_get_bcache_block,
316 mock_udevadm_settle,314 mock_udevadm_settle,
317 mock_block):315 mock_block):
318 device = "/sys/class/block/null"316 mock_block.sysfs_to_devpath.return_value = self.test_blockdev
319 mock_block.sysfs_to_devpath.return_value = '/dev/null'
320 mock_os.path.exists.side_effect = iter([317 mock_os.path.exists.side_effect = iter([
321 True, # backing device exists318 True, # backing device exists
322 True, # cset device not present (already removed)319 True, # cset device not present (already removed)
@@ -324,10 +321,10 @@ class TestClearHolders(CiTestCase):
324 ])321 ])
325 cset = '/sys/fs/bcache/fake'322 cset = '/sys/fs/bcache/fake'
326 mock_get_bcache.return_value = cset323 mock_get_bcache.return_value = cset
327 mock_get_bcache_block.return_value = device + '/bcache'324 mock_get_bcache_block.return_value = self.test_syspath + '/bcache'
328 mock_os.path.join.side_effect = os.path.join325 mock_os.path.join.side_effect = os.path.join
329326
330 clear_holders.shutdown_bcache(device)327 clear_holders.shutdown_bcache(self.test_syspath)
331328
332 self.assertEqual(4, len(mock_log.info.call_args_list))329 self.assertEqual(4, len(mock_log.info.call_args_list))
333 self.assertEqual(3, len(mock_os.path.exists.call_args_list))330 self.assertEqual(3, len(mock_os.path.exists.call_args_list))
@@ -336,7 +333,7 @@ class TestClearHolders(CiTestCase):
336 self.assertEqual(1, len(mock_util.write_file.call_args_list))333 self.assertEqual(1, len(mock_util.write_file.call_args_list))
337 self.assertEqual(1, len(mock_util.wait_for_removal.call_args_list))334 self.assertEqual(1, len(mock_util.wait_for_removal.call_args_list))
338335
339 mock_get_bcache.assert_called_with(device, strict=False)336 mock_get_bcache.assert_called_with(self.test_syspath, strict=False)
340 mock_util.write_file.assert_has_calls([337 mock_util.write_file.assert_has_calls([
341 mock.call(cset + '/stop', '1', mode=None),338 mock.call(cset + '/stop', '1', mode=None),
342 ])339 ])
@@ -361,8 +358,7 @@ class TestClearHolders(CiTestCase):
361 mock_wipe,358 mock_wipe,
362 mock_block):359 mock_block):
363 """Test writes sysfs write failures pass if file not present"""360 """Test writes sysfs write failures pass if file not present"""
364 device = "/sys/class/block/null"361 mock_block.sysfs_to_devpath.return_value = self.test_blockdev
365 mock_block.sysfs_to_devpath.return_value = '/dev/null'
366 mock_os.path.exists.side_effect = iter([362 mock_os.path.exists.side_effect = iter([
367 True, # backing device exists363 True, # backing device exists
368 True, # cset device not present (already removed)364 True, # cset device not present (already removed)
@@ -371,14 +367,14 @@ class TestClearHolders(CiTestCase):
371 ])367 ])
372 cset = '/sys/fs/bcache/fake'368 cset = '/sys/fs/bcache/fake'
373 mock_get_bcache.return_value = cset369 mock_get_bcache.return_value = cset
374 mock_get_bcache_block.return_value = device + '/bcache'370 mock_get_bcache_block.return_value = self.test_syspath + '/bcache'
375 mock_os.path.join.side_effect = os.path.join371 mock_os.path.join.side_effect = os.path.join
376372
377 # make writes to sysfs fail373 # make writes to sysfs fail
378 mock_util.write_file.side_effect = IOError(errno.ENOENT,374 mock_util.write_file.side_effect = IOError(errno.ENOENT,
379 "File not found")375 "File not found")
380376
381 clear_holders.shutdown_bcache(device)377 clear_holders.shutdown_bcache(self.test_syspath)
382378
383 self.assertEqual(4, len(mock_log.info.call_args_list))379 self.assertEqual(4, len(mock_log.info.call_args_list))
384 self.assertEqual(3, len(mock_os.path.exists.call_args_list))380 self.assertEqual(3, len(mock_os.path.exists.call_args_list))
@@ -387,7 +383,7 @@ class TestClearHolders(CiTestCase):
387 self.assertEqual(1, len(mock_util.write_file.call_args_list))383 self.assertEqual(1, len(mock_util.write_file.call_args_list))
388 self.assertEqual(1, len(mock_util.wait_for_removal.call_args_list))384 self.assertEqual(1, len(mock_util.wait_for_removal.call_args_list))
389385
390 mock_get_bcache.assert_called_with(device, strict=False)386 mock_get_bcache.assert_called_with(self.test_syspath, strict=False)
391 mock_util.write_file.assert_has_calls([387 mock_util.write_file.assert_has_calls([
392 mock.call(cset + '/stop', '1', mode=None),388 mock.call(cset + '/stop', '1', mode=None),
393 ])389 ])
@@ -528,10 +524,15 @@ class TestClearHolders(CiTestCase):
528 self.assertTrue(mock_log.debug.called)524 self.assertTrue(mock_log.debug.called)
529 self.assertTrue(mock_log.critical.called)525 self.assertTrue(mock_log.critical.called)
530526
527 @mock.patch('curtin.block.clear_holders.is_swap_device')
528 @mock.patch('curtin.block.clear_holders.os.path.exists')
531 @mock.patch('curtin.block.clear_holders.LOG')529 @mock.patch('curtin.block.clear_holders.LOG')
532 @mock.patch('curtin.block.clear_holders.block')530 @mock.patch('curtin.block.clear_holders.block')
533 def test_clear_holders_wipe_superblock(self, mock_block, mock_log):531 def test_clear_holders_wipe_superblock(self, mock_block, mock_log,
532 mock_os_path, mock_swap):
534 """test clear_holders.wipe_superblock handles errors right"""533 """test clear_holders.wipe_superblock handles errors right"""
534 mock_swap.return_value = False
535 mock_os_path.return_value = False
535 mock_block.sysfs_to_devpath.return_value = self.test_blockdev536 mock_block.sysfs_to_devpath.return_value = self.test_blockdev
536 mock_block.is_extended_partition.return_value = True537 mock_block.is_extended_partition.return_value = True
537 clear_holders.wipe_superblock(self.test_syspath)538 clear_holders.wipe_superblock(self.test_syspath)
@@ -543,12 +544,14 @@ class TestClearHolders(CiTestCase):
543 mock_block.wipe_volume.assert_called_with(544 mock_block.wipe_volume.assert_called_with(
544 self.test_blockdev, exclusive=True, mode='superblock')545 self.test_blockdev, exclusive=True, mode='superblock')
545546
547 @mock.patch('curtin.block.clear_holders.is_swap_device')
546 @mock.patch('curtin.block.clear_holders.zfs')548 @mock.patch('curtin.block.clear_holders.zfs')
547 @mock.patch('curtin.block.clear_holders.LOG')549 @mock.patch('curtin.block.clear_holders.LOG')
548 @mock.patch('curtin.block.clear_holders.block')550 @mock.patch('curtin.block.clear_holders.block')
549 def test_clear_holders_wipe_superblock_zfs(self, mock_block, mock_log,551 def test_clear_holders_wipe_superblock_zfs(self, mock_block, mock_log,
550 mock_zfs):552 mock_zfs, mock_swap):
551 """test clear_holders.wipe_superblock handles zfs member"""553 """test clear_holders.wipe_superblock handles zfs member"""
554 mock_swap.return_value = False
552 mock_block.sysfs_to_devpath.return_value = self.test_blockdev555 mock_block.sysfs_to_devpath.return_value = self.test_blockdev
553 mock_block.is_extended_partition.return_value = True556 mock_block.is_extended_partition.return_value = True
554 clear_holders.wipe_superblock(self.test_syspath)557 clear_holders.wipe_superblock(self.test_syspath)
@@ -563,6 +566,59 @@ class TestClearHolders(CiTestCase):
563 mock_block.wipe_volume.assert_called_with(566 mock_block.wipe_volume.assert_called_with(
564 self.test_blockdev, exclusive=True, mode='superblock')567 self.test_blockdev, exclusive=True, mode='superblock')
565568
569 @mock.patch('curtin.block.clear_holders.is_swap_device')
570 @mock.patch('curtin.block.clear_holders.time')
571 @mock.patch('curtin.block.clear_holders.LOG')
572 @mock.patch('curtin.block.clear_holders.block')
573 def test_clear_holders_wipe_superblock_rereads_pt(self, mock_block,
574 mock_log, m_time,
575 mock_swap):
576 """test clear_holders.wipe_superblock re-reads partition table"""
577 mock_swap.return_value = False
578 mock_block.sysfs_to_devpath.return_value = self.test_blockdev
579 mock_block.is_extended_partition.return_value = False
580 mock_block.is_zfs_member.return_value = False
581 mock_block.get_sysfs_partitions.side_effect = iter([
582 ['p1', 'p2'], # has partitions before wipe
583 ['p1', 'p2'], # still has partitions after wipe
584 [], # partitions are now gone
585 ])
586 clear_holders.wipe_superblock(self.test_syspath)
587 mock_block.sysfs_to_devpath.assert_called_with(self.test_syspath)
588 mock_block.wipe_volume.assert_called_with(
589 self.test_blockdev, exclusive=True, mode='superblock')
590 mock_block.get_sysfs_partitions.assert_has_calls(
591 [mock.call(self.test_syspath)] * 3)
592 mock_block.rescan_block_devices.assert_has_calls(
593 [mock.call(devices=[self.test_blockdev])] * 2)
594
595 @mock.patch('curtin.block.clear_holders.is_swap_device')
596 @mock.patch('curtin.block.clear_holders.time')
597 @mock.patch('curtin.block.clear_holders.LOG')
598 @mock.patch('curtin.block.clear_holders.block')
599 def test_clear_holders_wipe_superblock_rereads_pt_oserr(self, mock_block,
600 mock_log, m_time,
601 mock_swap):
602 """test clear_holders.wipe_superblock re-reads ptable handles oserr"""
603 mock_swap.return_value = False
604 mock_block.sysfs_to_devpath.return_value = self.test_blockdev
605 mock_block.is_extended_partition.return_value = False
606 mock_block.is_zfs_member.return_value = False
607 mock_block.get_sysfs_partitions.side_effect = iter([
608 ['p1', 'p2'], # has partitions before wipe
609 OSError('No sysfs path for partition'),
610 [], # partitions are now gone
611 ])
612 clear_holders.wipe_superblock(self.test_syspath)
613 mock_block.sysfs_to_devpath.assert_called_with(self.test_syspath)
614 mock_block.wipe_volume.assert_called_with(
615 self.test_blockdev, exclusive=True, mode='superblock')
616 mock_block.get_sysfs_partitions.assert_has_calls(
617 [mock.call(self.test_syspath)] * 3)
618 mock_block.rescan_block_devices.assert_has_calls(
619 [mock.call(devices=[self.test_blockdev])] * 2)
620 self.assertEqual(1, m_time.sleep.call_count)
621
566 @mock.patch('curtin.block.clear_holders.LOG')622 @mock.patch('curtin.block.clear_holders.LOG')
567 @mock.patch('curtin.block.clear_holders.block')623 @mock.patch('curtin.block.clear_holders.block')
568 @mock.patch('curtin.block.clear_holders.os')624 @mock.patch('curtin.block.clear_holders.os')
@@ -716,7 +772,7 @@ class TestClearHolders(CiTestCase):
716 def test_assert_clear(self, mock_gen_holders_tree, mock_syspath):772 def test_assert_clear(self, mock_gen_holders_tree, mock_syspath):
717 mock_gen_holders_tree.return_value = self.example_holders_trees[0][0]773 mock_gen_holders_tree.return_value = self.example_holders_trees[0][0]
718 mock_syspath.side_effect = lambda x: x774 mock_syspath.side_effect = lambda x: x
719 device = '/dev/null'775 device = self.test_blockdev
720 with self.assertRaises(OSError):776 with self.assertRaises(OSError):
721 clear_holders.assert_clear(device)777 clear_holders.assert_clear(device)
722 mock_gen_holders_tree.assert_called_with(device)778 mock_gen_holders_tree.assert_called_with(device)
diff --git a/tests/vmtests/__init__.py b/tests/vmtests/__init__.py
index 0c3d17e..68b7442 100644
--- a/tests/vmtests/__init__.py
+++ b/tests/vmtests/__init__.py
@@ -26,6 +26,7 @@ from .image_sync import query as imagesync_query
26from .image_sync import mirror as imagesync_mirror26from .image_sync import mirror as imagesync_mirror
27from .image_sync import (IMAGE_SRC_URL, IMAGE_DIR, ITEM_NAME_FILTERS)27from .image_sync import (IMAGE_SRC_URL, IMAGE_DIR, ITEM_NAME_FILTERS)
28from .helpers import check_call, TimeoutExpired, ip_a_to_dict28from .helpers import check_call, TimeoutExpired, ip_a_to_dict
29from functools import wraps
29from unittest import TestCase, SkipTest30from unittest import TestCase, SkipTest
3031
31try:32try:
@@ -55,6 +56,7 @@ SYSTEM_UPGRADE = os.environ.get("CURTIN_VMTEST_SYSTEM_UPGRADE", "auto")
5556
5657
57_UNSUPPORTED_UBUNTU = None58_UNSUPPORTED_UBUNTU = None
59_DEVEL_UBUNTU = None
5860
59_TOPDIR = None61_TOPDIR = None
6062
@@ -354,6 +356,7 @@ def skip_if_flag(flag):
354 def decorator(func):356 def decorator(func):
355 """the name test_wrapper below has to start with test, or nose's357 """the name test_wrapper below has to start with test, or nose's
356 filter will not run it."""358 filter will not run it."""
359 @wraps(func)
357 def test_wrapper(self, *args, **kwargs):360 def test_wrapper(self, *args, **kwargs):
358 val = getattr(self, flag, None)361 val = getattr(self, flag, None)
359 if val:362 if val:
@@ -364,6 +367,132 @@ def skip_if_flag(flag):
364 return decorator367 return decorator
365368
366369
370def skip_by_date(bugnum, fixby, removeby=None, skips=None, install=True):
371 """A decorator to skip a test or test class based on current date.
372
373 @param bugnum: A bug number with which to identify the action.
374 @param fixby: string: A date string in the format of YYYY-MM-DD
375 tuple (YYYY,MM,DD). Raises SkipTest with testcase results until
376 the current date is >= fixby value.
377 @param removeby: string: A date string in the format of YYYY-MM-DD
378 or (YYYY,MM,DD). Raises RuntimeError with testcase results
379 if current date is >= removeby value.
380 Default value is 3 weeks past fixby value.
381 @param skips: list of test cases (string method names) to be skipped.
382 If None, all class testcases will be skipped per evaluation of
383 fixby and removeby params. This is ignored when decorating a method.
384 Example skips=["test_test1", "test_test2"]
385 @param install: boolean: When True, setUpClass raises skipTest
386 exception while "today" < "fixby" date. Useful for handling
387 testcases where the install or boot would hang.
388 install parameter is ignored when decorating a method."""
389 def as_dtdate(date):
390 if not isinstance(date, str):
391 return date
392 return datetime.date(*map(int, date.split("-")))
393
394 def as_str(dtdate):
395 return "%s-%02d-%02d" % (dtdate.year, dtdate.month, dtdate.day)
396
397 d_today = datetime.date.today()
398 d_fixby = as_dtdate(fixby)
399 if removeby is None:
400 # give 3 weeks by default.
401 d_removeby = d_fixby + datetime.timedelta(21)
402 else:
403 d_removeby = as_dtdate(removeby)
404
405 envname = 'CURTIN_VMTEST_SKIP_BY_DATE_BUGS'
406 envval = os.environ.get(envname, "")
407 skip_bugs = envval.replace(",", " ").split()
408 _setUpClass = "setUpClass"
409
410 def decorator(test):
411 def decorate_callable(mycallable, classname=test.__name__):
412 funcname = mycallable.__name__
413 name = '.'.join((classname, funcname))
414 bmsg = ("skip_by_date({name}) LP: #{bug} "
415 "fixby={fixby} removeby={removeby}: ".format(
416 name=name, bug=bugnum,
417 fixby=as_str(d_fixby), removeby=as_str(d_removeby)))
418
419 @wraps(mycallable)
420 def wrapper(*args, **kwargs):
421 skip_reason = None
422 if "*" in skip_bugs or bugnum in skip_bugs:
423 skip_reason = "skip per %s=%s" % (envname, envval)
424 elif (funcname == _setUpClass and
425 (not install and d_today < d_fixby)):
426 skip_reason = "skip per install=%s" % install
427
428 if skip_reason:
429 logger.info(bmsg + skip_reason)
430 raise SkipTest(bmsg + skip_reason)
431
432 if d_today < d_fixby:
433 tmsg = "NOT_YET_FIXBY"
434 elif d_today > d_removeby:
435 tmsg = "REMOVE_WORKAROUND"
436 else:
437 tmsg = "PAST_FIXBY"
438
439 if funcname == _setUpClass:
440 logger.info(bmsg + "Running test (%s)", tmsg)
441
442 exc = None
443 try:
444 mycallable(*args, **kwargs)
445 except SkipTest:
446 raise
447 except Exception as e:
448 exc = e
449
450 if exc is None:
451 result = "Passed."
452 elif isinstance(exc, SkipTest):
453 result = "Skipped: %s" % exc
454 else:
455 result = "Failed: %s" % exc
456
457 msg = (bmsg + "(%s)" % tmsg + " " + result)
458
459 logger.info(msg)
460 if d_today < d_fixby:
461 if funcname != _setUpClass:
462 raise SkipTest(msg)
463 else:
464 # Expected fixed.
465 if d_today > d_removeby:
466 raise RuntimeError(msg)
467 elif exc:
468 raise RuntimeError(msg)
469
470 return wrapper
471
472 def decorate_test_methods(klass):
473 for attr in dir(klass):
474 attr_value = getattr(klass, attr)
475 if not hasattr(attr_value, "__call__"):
476 continue
477
478 if attr != _setUpClass:
479 if not attr.startswith('test_'):
480 continue
481 elif not (skips is None or attr in skips):
482 continue
483
484 setattr(klass, attr,
485 decorate_callable(attr_value,
486 classname=klass.__name__))
487 return klass
488
489 if isinstance(test, (type,)):
490 return decorate_test_methods(klass=test)
491 return decorate_callable(test)
492
493 return decorator
494
495
367class VMBaseClass(TestCase):496class VMBaseClass(TestCase):
368 __test__ = False497 __test__ = False
369 expected_failure = False498 expected_failure = False
@@ -450,8 +579,8 @@ class VMBaseClass(TestCase):
450 else:579 else:
451 target_img_verstr, target_ftypes = get_images(580 target_img_verstr, target_ftypes = get_images(
452 IMAGE_SRC_URL, IMAGE_DIR,581 IMAGE_SRC_URL, IMAGE_DIR,
453 cls.target_distro if cls.target_distro else cls.distro,582 cls.target_distro,
454 cls.target_release if cls.target_release else cls.release,583 cls.target_release,
455 cls.arch, subarch=cls.subarch if cls.subarch else None,584 cls.arch, subarch=cls.subarch if cls.subarch else None,
456 kflavor=cls.kflavor if cls.kflavor else None,585 kflavor=cls.kflavor if cls.kflavor else None,
457 krel=cls.target_krel, sync=CURTIN_VMTEST_IMAGE_SYNC,586 krel=cls.target_krel, sync=CURTIN_VMTEST_IMAGE_SYNC,
@@ -566,61 +695,6 @@ class VMBaseClass(TestCase):
566 return disks695 return disks
567696
568 @classmethod697 @classmethod
569 def skip_by_date(cls, bugnum, fixby, removeby=None,
570 release=None, name=None):
571 """Raise SkipTest with bug message until 'fixby'.
572 Raise RutimeError after removeby.
573 fixby and removeby support string (2018-01-01) or tuple(2018,01,01)
574 removeby defaults to 3 weeks after fixby.
575 """
576 def as_dtdate(date):
577 if not isinstance(date, str):
578 return date
579 return datetime.date(*map(int, date.split("-")))
580
581 def as_str(dtdate):
582 return "%s-%02d-%02d" % (dtdate.year, dtdate.month, dtdate.day)
583
584 if name is None:
585 name = cls.__name__
586
587 if release is None:
588 release = cls.release
589
590 d_today = datetime.date.today()
591 d_fixby = as_dtdate(fixby)
592 if removeby is None:
593 # give 3 weeks by default.
594 d_removeby = d_fixby + datetime.timedelta(21)
595 else:
596 d_removeby = as_dtdate(removeby)
597
598 bmsg = ("[{name}/{rel}] skip_by_date LP: #{bug} "
599 "fixby={fixby} removeby={removeby}: ".format(
600 name=name, rel=release, bug=bugnum,
601 fixby=as_str(d_fixby), removeby=as_str(d_removeby)))
602
603 envname = 'CURTIN_VMTEST_SKIP_BY_DATE_BUGS'
604 envval = os.environ.get(envname, "")
605 skip_bugs = envval.replace(",", " ").split()
606
607 result = None
608 msg = bmsg + "Not skipping."
609 if "*" in skip_bugs or bugnum in skip_bugs:
610 msg = bmsg + "skip per %s=%s" % (envname, envval)
611 result = SkipTest
612 elif d_today < d_fixby:
613 msg = bmsg + "skip (today < fixby)"
614 result = SkipTest
615 elif d_today > d_removeby:
616 msg = bmsg + "Remove workaround."
617 result = RuntimeError
618
619 logger.info(msg)
620 if result:
621 raise result(msg)
622
623 @classmethod
624 def get_config_smp(cls):698 def get_config_smp(cls):
625 """Get number of cpus to use for guest"""699 """Get number of cpus to use for guest"""
626700
@@ -670,6 +744,12 @@ class VMBaseClass(TestCase):
670 return {'kernel': {'fallback-package': package}}744 return {'kernel': {'fallback-package': package}}
671745
672 @classmethod746 @classmethod
747 def skip_by_date(cls, *args, **kwargs):
748 """skip_by_date wrapper. this way other modules do not have
749 to add an import of skip_by_date to start skipping."""
750 return skip_by_date(*args, **kwargs)
751
752 @classmethod
673 def setUpClass(cls):753 def setUpClass(cls):
674 # initialize global logger with class name to help make sense of754 # initialize global logger with class name to help make sense of
675 # parallel vmtest runs which intermingle output.755 # parallel vmtest runs which intermingle output.
@@ -677,6 +757,13 @@ class VMBaseClass(TestCase):
677 logger = _initialize_logging(name=cls.__name__)757 logger = _initialize_logging(name=cls.__name__)
678 cls.logger = logger758 cls.logger = logger
679759
760 req_attrs = ('target_distro', 'target_release', 'release', 'distro')
761 missing = [a for a in req_attrs if not getattr(cls, a)]
762 if missing:
763 raise ValueError(
764 "Class %s does not have required attrs set: %s" %
765 (cls.__name__, missing))
766
680 if is_unsupported_ubuntu(cls.release):767 if is_unsupported_ubuntu(cls.release):
681 raise SkipTest('"%s" is unsupported release.' % cls.release)768 raise SkipTest('"%s" is unsupported release.' % cls.release)
682769
@@ -687,7 +774,14 @@ class VMBaseClass(TestCase):
687 raise SkipTest(reason)774 raise SkipTest(reason)
688775
689 setup_start = time.time()776 setup_start = time.time()
690 logger.info('Starting setup for testclass: {}'.format(cls.__name__))777 logger.info(
778 ('Starting setup for testclass: {__name__} '
779 '({distro}/{release} -> '
780 '{target_distro}/{target_release})').format(
781 **{k: getattr(cls, k)
782 for k in ('__name__', 'distro', 'release',
783 'target_distro', 'target_release')}))
784
691 # set up tempdir785 # set up tempdir
692 cls.td = TempDir(786 cls.td = TempDir(
693 name=cls.__name__,787 name=cls.__name__,
@@ -823,7 +917,7 @@ class VMBaseClass(TestCase):
823 disks.extend(cls.build_iscsi_disks())917 disks.extend(cls.build_iscsi_disks())
824918
825 # proxy config919 # proxy config
826 configs = [cls.conf_file]920 configs = [cls.conf_file, 'examples/tests/vmtest_pollinate.yaml']
827 cls.proxy = get_apt_proxy()921 cls.proxy = get_apt_proxy()
828 if cls.proxy is not None and not cls.td.restored:922 if cls.proxy is not None and not cls.td.restored:
829 proxy_config = os.path.join(cls.td.install, 'proxy.cfg')923 proxy_config = os.path.join(cls.td.install, 'proxy.cfg')
@@ -864,14 +958,19 @@ class VMBaseClass(TestCase):
864 system_upgrade = SYSTEM_UPGRADE958 system_upgrade = SYSTEM_UPGRADE
865 upgrade_packages = UPGRADE_PACKAGES959 upgrade_packages = UPGRADE_PACKAGES
866 if add_repos:960 if add_repos:
867 # enable if user has set a value here961 cfg_repos = generate_repo_config(add_repos.split(","),
868 if system_upgrade == "auto":962 release=cls.target_release)
869 system_upgrade = True963 if cfg_repos:
870 logger.info('Adding apt repositories: %s', add_repos)964 logger.info('Adding apt repositories: %s', add_repos)
871 repo_cfg = os.path.join(cls.td.install, 'add_repos.cfg')965 # enable if user has set a value here
872 util.write_file(repo_cfg,966 if system_upgrade == "auto":
873 generate_repo_config(add_repos.split(",")))967 system_upgrade = True
874 configs.append(repo_cfg)968 repo_cfg = os.path.join(cls.td.install, 'add_repos.cfg')
969 util.write_file(repo_cfg, cfg_repos)
970 configs.append(repo_cfg)
971 else:
972 logger.info("add_repos=%s processed to empty config.",
973 add_repos)
875 elif system_upgrade == "auto":974 elif system_upgrade == "auto":
876 system_upgrade = False975 system_upgrade = False
877976
@@ -1146,7 +1245,7 @@ class VMBaseClass(TestCase):
1146 """Return install uri and a list of files needed to be published."""1245 """Return install uri and a list of files needed to be published."""
1147 # if release (install environment) is the same as target1246 # if release (install environment) is the same as target
1148 # target (thing to install) then install via cp://1247 # target (thing to install) then install via cp://
1149 if cls.target_release in (None, cls.release):1248 if cls.target_release == cls.release:
1150 install_src = "cp:///media/root-ro"1249 install_src = "cp:///media/root-ro"
1151 return install_src, []1250 return install_src, []
11521251
@@ -1339,7 +1438,7 @@ class VMBaseClass(TestCase):
13391438
1340 @skip_if_flag('expected_failure')1439 @skip_if_flag('expected_failure')
1341 def test_dname(self, disk_to_check=None):1440 def test_dname(self, disk_to_check=None):
1342 if "trusty" in [self.release, self.target_release]:1441 if self.target_release == "trusty":
1343 raise SkipTest(1442 raise SkipTest(
1344 "(LP: #1523037): dname does not work on trusty kernels")1443 "(LP: #1523037): dname does not work on trusty kernels")
13451444
@@ -1393,7 +1492,7 @@ class VMBaseClass(TestCase):
1393 def test_installed_correct_kernel_package(self):1492 def test_installed_correct_kernel_package(self):
1394 """ Test curtin installs the correct kernel package. """1493 """ Test curtin installs the correct kernel package. """
1395 # target_distro is set for non-ubuntu targets1494 # target_distro is set for non-ubuntu targets
1396 if self.target_distro is not None:1495 if self.target_distro != "ubuntu":
1397 raise SkipTest("Can't check non-ubuntu kernel packages")1496 raise SkipTest("Can't check non-ubuntu kernel packages")
13981497
1399 kpackage = self.get_kernel_package()1498 kpackage = self.get_kernel_package()
@@ -1849,7 +1948,25 @@ def is_unsupported_ubuntu(release):
1849 return release in _UNSUPPORTED_UBUNTU1948 return release in _UNSUPPORTED_UBUNTU
18501949
18511950
1852def generate_repo_config(repos):1951def is_devel_release(release):
1952 global _DEVEL_UBUNTU
1953 if _DEVEL_UBUNTU is None:
1954 udi = 'ubuntu-distro-info'
1955 env = os.environ.get('_DEVEL_UBUNTU')
1956 if env:
1957 # allow it to be , or " " separated.
1958 _DEVEL_UBUNTU = env.replace(",", " ").split()
1959 elif util.which(udi):
1960 _DEVEL_UBUNTU = util.subp(
1961 [udi, '--devel'], capture=True)[0].splitlines()
1962 else:
1963 # no way to tell.
1964 _DEVEL_UBUNTU = []
1965
1966 return release in _DEVEL_UBUNTU
1967
1968
1969def generate_repo_config(repos, release=None):
1853 """Generate apt yaml configuration to add specified repositories.1970 """Generate apt yaml configuration to add specified repositories.
18541971
1855 @param repos: A list of add-apt-repository strings.1972 @param repos: A list of add-apt-repository strings.
@@ -1857,8 +1974,19 @@ def generate_repo_config(repos):
1857 pocket of a particular release.1974 pocket of a particular release.
1858 @returns: string: A yaml string1975 @returns: string: A yaml string
1859 """1976 """
1860 sources = {"add_repos_%02d" % idx: {'source': v}1977 sources = {}
1861 for idx, v in enumerate(repos)}1978 for idx, v in enumerate(repos):
1979 if v == 'proposed' and is_devel_release(release):
1980 # lower case 'proposed' is magically handled by apt repo
1981 # processing. But dev release's -proposed is "known broken".
1982 # if you want to test development release, then use 'PROPOSED'.
1983 continue
1984 if v == 'PROPOSED':
1985 v = 'proposed'
1986 sources['add_repos_%02d' % idx] = {'source': v}
1987 if not sources:
1988 return None
1989
1862 return yaml.dump({'apt': {'sources': sources}})1990 return yaml.dump({'apt': {'sources': sources}})
18631991
18641992
diff --git a/tests/vmtests/releases.py b/tests/vmtests/releases.py
index 18a5e75..02cbfe5 100644
--- a/tests/vmtests/releases.py
+++ b/tests/vmtests/releases.py
@@ -11,6 +11,7 @@ class _ReleaseBase(object):
11class _UbuntuBase(_ReleaseBase):11class _UbuntuBase(_ReleaseBase):
12 distro = "ubuntu"12 distro = "ubuntu"
13 kflavor = "generic"13 kflavor = "generic"
14 target_distro = "ubuntu"
1415
1516
16class _CentosFromUbuntuBase(_UbuntuBase):17class _CentosFromUbuntuBase(_UbuntuBase):
@@ -39,6 +40,7 @@ class _UbuntuCore16FromXenialBase(_UbuntuCoreUbuntuBase):
39 release = "xenial"40 release = "xenial"
40 # release for target41 # release for target
41 target_release = "ubuntu-core-16"42 target_release = "ubuntu-core-16"
43 target_distro = "ubuntu-core"
4244
4345
44class _Centos66FromXenialBase(_CentosFromUbuntuBase):46class _Centos66FromXenialBase(_CentosFromUbuntuBase):
@@ -59,59 +61,56 @@ class _PreciseHWET(_PreciseBase):
5961
60class _TrustyBase(_UbuntuBase):62class _TrustyBase(_UbuntuBase):
61 release = "trusty"63 release = "trusty"
64 target_release = "trusty"
6265
6366
64class _TrustyHWEU(_UbuntuBase):67class _TrustyHWEU(_TrustyBase):
65 release = "trusty"
66 krel = "utopic"68 krel = "utopic"
6769
6870
69class _TrustyHWEV(_UbuntuBase):71class _TrustyHWEV(_TrustyBase):
70 release = "trusty"
71 krel = "vivid"72 krel = "vivid"
7273
7374
74class _TrustyHWEW(_UbuntuBase):75class _TrustyHWEW(_TrustyBase):
75 release = "trusty"
76 krel = "wily"76 krel = "wily"
7777
7878
79class _TrustyHWEX(_UbuntuBase):79class _TrustyHWEX(_TrustyBase):
80 release = "trusty"
81 krel = "xenial"80 krel = "xenial"
8281
8382
84class _TrustyFromXenial(_UbuntuBase):83class _TrustyFromXenial(_TrustyBase):
85 release = "xenial"84 release = "xenial"
86 target_release = "trusty"85 target_release = "trusty"
8786
8887
89class _XenialBase(_UbuntuBase):88class _XenialBase(_UbuntuBase):
90 release = "xenial"89 release = "xenial"
90 target_release = "xenial"
91 subarch = "ga-16.04"91 subarch = "ga-16.04"
9292
9393
94class _XenialGA(_UbuntuBase):94class _XenialGA(_XenialBase):
95 release = "xenial"
96 subarch = "ga-16.04"95 subarch = "ga-16.04"
9796
9897
99class _XenialHWE(_UbuntuBase):98class _XenialHWE(_XenialBase):
100 release = "xenial"
101 subarch = "hwe-16.04"99 subarch = "hwe-16.04"
102100
103101
104class _XenialEdge(_UbuntuBase):102class _XenialEdge(_XenialBase):
105 release = "xenial"
106 subarch = "hwe-16.04-edge"103 subarch = "hwe-16.04-edge"
107104
108105
109class _ArtfulBase(_UbuntuBase):
110 release = "artful"
111
112
113class _BionicBase(_UbuntuBase):106class _BionicBase(_UbuntuBase):
114 release = "bionic"107 release = "bionic"
108 target_release = "bionic"
109
110
111class _CosmicBase(_UbuntuBase):
112 release = "cosmic"
113 target_release = "cosmic"
115114
116115
117class _Releases(object):116class _Releases(object):
@@ -127,8 +126,8 @@ class _Releases(object):
127 xenial_ga = _XenialGA126 xenial_ga = _XenialGA
128 xenial_hwe = _XenialHWE127 xenial_hwe = _XenialHWE
129 xenial_edge = _XenialEdge128 xenial_edge = _XenialEdge
130 artful = _ArtfulBase
131 bionic = _BionicBase129 bionic = _BionicBase
130 cosmic = _CosmicBase
132131
133132
134class _CentosReleases(object):133class _CentosReleases(object):
diff --git a/tests/vmtests/test_apt_config_cmd.py b/tests/vmtests/test_apt_config_cmd.py
index 2c135c4..efd04f3 100644
--- a/tests/vmtests/test_apt_config_cmd.py
+++ b/tests/vmtests/test_apt_config_cmd.py
@@ -57,11 +57,11 @@ class XenialTestAptConfigCMDCMD(relbase.xenial, TestAptConfigCMD):
57 __test__ = True57 __test__ = True
5858
5959
60class ArtfulTestAptConfigCMDCMD(relbase.artful, TestAptConfigCMD):60class BionicTestAptConfigCMDCMD(relbase.bionic, TestAptConfigCMD):
61 __test__ = True61 __test__ = True
6262
6363
64class BionicTestAptConfigCMDCMD(relbase.bionic, TestAptConfigCMD):64class CosmicTestAptConfigCMDCMD(relbase.cosmic, TestAptConfigCMD):
65 __test__ = True65 __test__ = True
6666
67# vi: ts=4 expandtab syntax=python67# vi: ts=4 expandtab syntax=python
diff --git a/tests/vmtests/test_basic.py b/tests/vmtests/test_basic.py
index 2e47cb6..01ffc89 100644
--- a/tests/vmtests/test_basic.py
+++ b/tests/vmtests/test_basic.py
@@ -23,8 +23,13 @@ class TestBasicAbs(VMBaseClass):
23 blkid -o export /dev/vda > blkid_output_vda23 blkid -o export /dev/vda > blkid_output_vda
24 blkid -o export /dev/vda1 > blkid_output_vda124 blkid -o export /dev/vda1 > blkid_output_vda1
25 blkid -o export /dev/vda2 > blkid_output_vda225 blkid -o export /dev/vda2 > blkid_output_vda2
26 f="btrfs_uuid_vdd"26 dev="/dev/vdd"; f="btrfs_uuid_${dev#/dev/*}";
27 btrfs-debug-tree -r /dev/vdd | awk '/^uuid/ {print $2}' | grep "-" > $f27 if command -v btrfs-debug-tree >/dev/null; then
28 btrfs-debug-tree -r $dev | awk '/^uuid/ {print $2}' | grep "-"
29 else
30 btrfs inspect-internal dump-super $dev |
31 awk '/^dev_item.fsid/ {print $2}'
32 fi > $f
28 cat /proc/partitions > proc_partitions33 cat /proc/partitions > proc_partitions
29 ls -al /dev/disk/by-uuid/ > ls_uuid34 ls -al /dev/disk/by-uuid/ > ls_uuid
30 cat /etc/fstab > fstab35 cat /etc/fstab > fstab
@@ -60,7 +65,7 @@ class TestBasicAbs(VMBaseClass):
60 "root/curtin-install.log", "root/curtin-install-cfg.yaml"])65 "root/curtin-install.log", "root/curtin-install-cfg.yaml"])
6166
62 def test_ptable(self, disk_to_check=None):67 def test_ptable(self, disk_to_check=None):
63 if "trusty" in [self.release, self.target_release]:68 if self.target_release == "trusty":
64 raise SkipTest("No PTTYPE blkid output on trusty")69 raise SkipTest("No PTTYPE blkid output on trusty")
6570
66 blkid_info = self.get_blkid_data("blkid_output_vda")71 blkid_info = self.get_blkid_data("blkid_output_vda")
@@ -169,11 +174,11 @@ class XenialEdgeTestBasic(relbase.xenial_edge, TestBasicAbs):
169 __test__ = True174 __test__ = True
170175
171176
172class ArtfulTestBasic(relbase.artful, TestBasicAbs):177class BionicTestBasic(relbase.bionic, TestBasicAbs):
173 __test__ = True178 __test__ = True
174179
175180
176class BionicTestBasic(relbase.bionic, TestBasicAbs):181class CosmicTestBasic(relbase.cosmic, TestBasicAbs):
177 __test__ = True182 __test__ = True
178183
179184
@@ -187,8 +192,13 @@ class TestBasicScsiAbs(TestBasicAbs):
187 blkid -o export /dev/sda > blkid_output_sda192 blkid -o export /dev/sda > blkid_output_sda
188 blkid -o export /dev/sda1 > blkid_output_sda1193 blkid -o export /dev/sda1 > blkid_output_sda1
189 blkid -o export /dev/sda2 > blkid_output_sda2194 blkid -o export /dev/sda2 > blkid_output_sda2
190 f="btrfs_uuid_sdc"195 dev="/dev/sdc"; f="btrfs_uuid_${dev#/dev/*}";
191 btrfs-debug-tree -r /dev/sdc | awk '/^uuid/ {print $2}' | grep "-" > $f196 if command -v btrfs-debug-tree >/dev/null; then
197 btrfs-debug-tree -r $dev | awk '/^uuid/ {print $2}' | grep "-"
198 else
199 btrfs inspect-internal dump-super $dev |
200 awk '/^dev_item.fsid/ {print $2}'
201 fi > $f
192 cat /proc/partitions > proc_partitions202 cat /proc/partitions > proc_partitions
193 ls -al /dev/disk/by-uuid/ > ls_uuid203 ls -al /dev/disk/by-uuid/ > ls_uuid
194 ls -al /dev/disk/by-id/ > ls_disk_id204 ls -al /dev/disk/by-id/ > ls_disk_id
@@ -210,7 +220,7 @@ class TestBasicScsiAbs(TestBasicAbs):
210 "ls_disk_id", "proc_partitions"])220 "ls_disk_id", "proc_partitions"])
211221
212 def test_ptable(self):222 def test_ptable(self):
213 if "trusty" in [self.release, self.target_release]:223 if self.target_release == "trusty":
214 raise SkipTest("No PTTYPE blkid output on trusty")224 raise SkipTest("No PTTYPE blkid output on trusty")
215225
216 blkid_info = self.get_blkid_data("blkid_output_sda")226 blkid_info = self.get_blkid_data("blkid_output_sda")
@@ -289,11 +299,11 @@ class XenialEdgeTestScsiBasic(relbase.xenial_edge, TestBasicScsiAbs):
289 __test__ = True299 __test__ = True
290300
291301
292class ArtfulTestScsiBasic(relbase.artful, TestBasicScsiAbs):302class BionicTestScsiBasic(relbase.bionic, TestBasicScsiAbs):
293 __test__ = True303 __test__ = True
294304
295305
296class BionicTestScsiBasic(relbase.bionic, TestBasicScsiAbs):306class CosmicTestScsiBasic(relbase.cosmic, TestBasicScsiAbs):
297 __test__ = True307 __test__ = True
298308
299# vi: ts=4 expandtab syntax=python309# vi: ts=4 expandtab syntax=python
diff --git a/tests/vmtests/test_bcache_basic.py b/tests/vmtests/test_bcache_basic.py
index 1844bc6..4989c8e 100644
--- a/tests/vmtests/test_bcache_basic.py
+++ b/tests/vmtests/test_bcache_basic.py
@@ -65,11 +65,11 @@ class XenialEdgeBcacheBasic(relbase.xenial_edge, TestBcacheBasic):
65 __test__ = True65 __test__ = True
6666
6767
68class ArtfulBcacheBasic(relbase.artful, TestBcacheBasic):68class BionicBcacheBasic(relbase.bionic, TestBcacheBasic):
69 __test__ = True69 __test__ = True
7070
7171
72class BionicBcacheBasic(relbase.bionic, TestBcacheBasic):72class CosmicBcacheBasic(relbase.cosmic, TestBcacheBasic):
73 __test__ = True73 __test__ = True
7474
75# vi: ts=4 expandtab syntax=python75# vi: ts=4 expandtab syntax=python
diff --git a/tests/vmtests/test_bcache_bug1718699.py b/tests/vmtests/test_bcache_bug1718699.py
index bb1b32f..bc0f1e0 100644
--- a/tests/vmtests/test_bcache_bug1718699.py
+++ b/tests/vmtests/test_bcache_bug1718699.py
@@ -15,11 +15,11 @@ class XenialTestBcacheBug1718699(relbase.xenial, TestBcacheBug1718699):
15 __test__ = True15 __test__ = True
1616
1717
18class ArtfulTestBcacheBug1718699(relbase.artful, TestBcacheBug1718699):18class BionicTestBcacheBug1718699(relbase.bionic, TestBcacheBug1718699):
19 __test__ = True19 __test__ = True
2020
2121
22class BionicTestBcacheBug1718699(relbase.bionic, TestBcacheBug1718699):22class CosmicTestBcacheBug1718699(relbase.cosmic, TestBcacheBug1718699):
23 __test__ = True23 __test__ = True
2424
25# vi: ts=4 expandtab syntax=python25# vi: ts=4 expandtab syntax=python
diff --git a/tests/vmtests/test_fs_battery.py b/tests/vmtests/test_fs_battery.py
index 423cc1e..3e41717 100644
--- a/tests/vmtests/test_fs_battery.py
+++ b/tests/vmtests/test_fs_battery.py
@@ -225,4 +225,8 @@ class BionicTestFsBattery(relbase.bionic, TestFsBattery):
225 __test__ = True225 __test__ = True
226226
227227
228class CosmicTestFsBattery(relbase.cosmic, TestFsBattery):
229 __test__ = True
230
231
228# vi: ts=4 expandtab syntax=python232# vi: ts=4 expandtab syntax=python
diff --git a/tests/vmtests/test_iscsi.py b/tests/vmtests/test_iscsi.py
index bddd78c..1ac9660 100644
--- a/tests/vmtests/test_iscsi.py
+++ b/tests/vmtests/test_iscsi.py
@@ -65,11 +65,11 @@ class XenialEdgeTestIscsiBasic(relbase.xenial_edge, TestBasicIscsiAbs):
65 __test__ = True65 __test__ = True
6666
6767
68class ArtfulTestIscsiBasic(relbase.artful, TestBasicIscsiAbs):68class BionicTestIscsiBasic(relbase.bionic, TestBasicIscsiAbs):
69 __test__ = True69 __test__ = True
7070
7171
72class BionicTestIscsiBasic(relbase.bionic, TestBasicIscsiAbs):72class CosmicTestIscsiBasic(relbase.cosmic, TestBasicIscsiAbs):
73 __test__ = True73 __test__ = True
7474
75# vi: ts=4 expandtab syntax=python75# vi: ts=4 expandtab syntax=python
diff --git a/tests/vmtests/test_journald_reporter.py b/tests/vmtests/test_journald_reporter.py
index 35ece6d..ad34d52 100644
--- a/tests/vmtests/test_journald_reporter.py
+++ b/tests/vmtests/test_journald_reporter.py
@@ -35,11 +35,11 @@ class XenialTestJournaldReporter(relbase.xenial, TestJournaldReporter):
35 __test__ = True35 __test__ = True
3636
3737
38class ArtfulTestJournaldReporter(relbase.artful, TestJournaldReporter):38class BionicTestJournaldReporter(relbase.bionic, TestJournaldReporter):
39 __test__ = True39 __test__ = True
4040
4141
42class BionicTestJournaldReporter(relbase.bionic, TestJournaldReporter):42class CosmicTestJournaldReporter(relbase.cosmic, TestJournaldReporter):
43 __test__ = True43 __test__ = True
4444
45# vi: ts=4 expandtab syntax=python45# vi: ts=4 expandtab syntax=python
diff --git a/tests/vmtests/test_lvm.py b/tests/vmtests/test_lvm.py
index ed708fd..8972ae4 100644
--- a/tests/vmtests/test_lvm.py
+++ b/tests/vmtests/test_lvm.py
@@ -66,11 +66,12 @@ class XenialEdgeTestLvm(relbase.xenial_edge, TestLvmAbs):
66 __test__ = True66 __test__ = True
6767
6868
69class ArtfulTestLvm(relbase.artful, TestLvmAbs):69class BionicTestLvm(relbase.bionic, TestLvmAbs):
70 __test__ = True70 __test__ = True
7171
7272
73class BionicTestLvm(relbase.bionic, TestLvmAbs):73class CosmicTestLvm(relbase.cosmic, TestLvmAbs):
74 __test__ = True74 __test__ = True
7575
76
76# vi: ts=4 expandtab syntax=python77# vi: ts=4 expandtab syntax=python
diff --git a/tests/vmtests/test_lvm_iscsi.py b/tests/vmtests/test_lvm_iscsi.py
index 2a11d6e..cb5f33c 100644
--- a/tests/vmtests/test_lvm_iscsi.py
+++ b/tests/vmtests/test_lvm_iscsi.py
@@ -75,11 +75,11 @@ class XenialEdgeTestIscsiLvm(relbase.xenial_edge, TestLvmIscsiAbs):
75 __test__ = True75 __test__ = True
7676
7777
78class ArtfulTestIscsiLvm(relbase.artful, TestLvmIscsiAbs):78class BionicTestIscsiLvm(relbase.bionic, TestLvmIscsiAbs):
79 __test__ = True79 __test__ = True
8080
8181
82class BionicTestIscsiLvm(relbase.bionic, TestLvmIscsiAbs):82class CosmicTestIscsiLvm(relbase.cosmic, TestLvmIscsiAbs):
83 __test__ = True83 __test__ = True
8484
85# vi: ts=4 expandtab syntax=python85# vi: ts=4 expandtab syntax=python
diff --git a/tests/vmtests/test_lvm_root.py b/tests/vmtests/test_lvm_root.py
index 24ecb41..8ca69d4 100644
--- a/tests/vmtests/test_lvm_root.py
+++ b/tests/vmtests/test_lvm_root.py
@@ -92,20 +92,6 @@ class XenialTestLvmRootXfs(relbase.xenial, TestLvmRootAbs):
92 }92 }
9393
9494
95class ArtfulTestLvmRootExt4(relbase.artful, TestLvmRootAbs):
96 __test__ = True
97 conf_replace = {
98 '__ROOTFS_FORMAT__': 'ext4',
99 }
100
101
102class ArtfulTestLvmRootXfs(relbase.artful, TestLvmRootAbs):
103 __test__ = True
104 conf_replace = {
105 '__ROOTFS_FORMAT__': 'xfs',
106 }
107
108
109class TestUefiLvmRootAbs(TestLvmRootAbs):95class TestUefiLvmRootAbs(TestLvmRootAbs):
110 conf_file = "examples/tests/uefi_lvmroot.yaml"96 conf_file = "examples/tests/uefi_lvmroot.yaml"
111 uefi = True97 uefi = True
@@ -127,31 +113,15 @@ class XenialTestUefiLvmRootXfs(relbase.xenial, TestUefiLvmRootAbs):
127 }113 }
128114
129115
116@VMBaseClass.skip_by_date("1652822", fixby="2019-06-01")
130class XenialTestUefiLvmRootXfsBootXfs(relbase.xenial, TestUefiLvmRootAbs):117class XenialTestUefiLvmRootXfsBootXfs(relbase.xenial, TestUefiLvmRootAbs):
131 __test__ = True118 """This tests xfs root and xfs boot with uefi.
132 conf_replace = {
133 '__BOOTFS_FORMAT__': 'xfs', # Expected to fail until LP: #1652822
134 '__ROOTFS_FORMAT__': 'xfs',
135 }
136
137 @classmethod
138 def setUpClass(cls):
139 cls.skip_by_date("1652822", fixby="2018-05-26")
140 super().setUpClass()
141119
142120 It is known broken (LP: #1652822) and unlikely to be fixed without pushing,
143class ArtfulTestUefiLvmRootExt4(relbase.artful, TestUefiLvmRootAbs):121 so we skip-by for a long time."""
144 __test__ = True122 __test__ = True
145 conf_replace = {123 conf_replace = {
146 '__BOOTFS_FORMAT__': 'ext4',124 '__BOOTFS_FORMAT__': 'xfs',
147 '__ROOTFS_FORMAT__': 'ext4',
148 }
149
150
151class ArtfulTestUefiLvmRootXfs(relbase.artful, TestUefiLvmRootAbs):
152 __test__ = True
153 conf_replace = {
154 '__BOOTFS_FORMAT__': 'ext4',
155 '__ROOTFS_FORMAT__': 'xfs',125 '__ROOTFS_FORMAT__': 'xfs',
156 }126 }
157127
diff --git a/tests/vmtests/test_mdadm_bcache.py b/tests/vmtests/test_mdadm_bcache.py
index 49d4782..21cf45f 100644
--- a/tests/vmtests/test_mdadm_bcache.py
+++ b/tests/vmtests/test_mdadm_bcache.py
@@ -129,14 +129,10 @@ class TestMdadmBcacheAbs(TestMdadmAbs):
129 self.test_dname(disk_to_check=self.bcache_dnames)129 self.test_dname(disk_to_check=self.bcache_dnames)
130130
131131
132@VMBaseClass.skip_by_date("1754581", fixby="2019-01-22", install=False)
132class TrustyTestMdadmBcache(relbase.trusty, TestMdadmBcacheAbs):133class TrustyTestMdadmBcache(relbase.trusty, TestMdadmBcacheAbs):
133 __test__ = True134 __test__ = True
134135
135 @classmethod
136 def setUpClass(cls):
137 cls.skip_by_date("1754581", fixby="2018-06-22")
138 super().setUpClass()
139
140136
141class TrustyHWEXTestMdadmBcache(relbase.trusty_hwe_x, TestMdadmBcacheAbs):137class TrustyHWEXTestMdadmBcache(relbase.trusty_hwe_x, TestMdadmBcacheAbs):
142 __test__ = True138 __test__ = True
@@ -154,11 +150,11 @@ class XenialEdgeTestMdadmBcache(relbase.xenial_edge, TestMdadmBcacheAbs):
154 __test__ = True150 __test__ = True
155151
156152
157class ArtfulTestMdadmBcache(relbase.artful, TestMdadmBcacheAbs):153class BionicTestMdadmBcache(relbase.bionic, TestMdadmBcacheAbs):
158 __test__ = True154 __test__ = True
159155
160156
161class BionicTestMdadmBcache(relbase.bionic, TestMdadmBcacheAbs):157class CosmicTestMdadmBcache(relbase.cosmic, TestMdadmBcacheAbs):
162 __test__ = True158 __test__ = True
163159
164160
@@ -194,11 +190,11 @@ class XenialEdgeTestMirrorboot(relbase.xenial_edge, TestMirrorbootAbs):
194 __test__ = True190 __test__ = True
195191
196192
197class ArtfulTestMirrorboot(relbase.artful, TestMirrorbootAbs):193class BionicTestMirrorboot(relbase.bionic, TestMirrorbootAbs):
198 __test__ = True194 __test__ = True
199195
200196
201class BionicTestMirrorboot(relbase.bionic, TestMirrorbootAbs):197class CosmicTestMirrorboot(relbase.cosmic, TestMirrorbootAbs):
202 __test__ = True198 __test__ = True
203199
204200
@@ -238,12 +234,12 @@ class XenialEdgeTestMirrorbootPartitions(relbase.xenial_edge,
238 __test__ = True234 __test__ = True
239235
240236
241class ArtfulTestMirrorbootPartitions(relbase.artful,237class BionicTestMirrorbootPartitions(relbase.bionic,
242 TestMirrorbootPartitionsAbs):238 TestMirrorbootPartitionsAbs):
243 __test__ = True239 __test__ = True
244240
245241
246class BionicTestMirrorbootPartitions(relbase.bionic,242class CosmicTestMirrorbootPartitions(relbase.cosmic,
247 TestMirrorbootPartitionsAbs):243 TestMirrorbootPartitionsAbs):
248 __test__ = True244 __test__ = True
249245
@@ -283,12 +279,12 @@ class XenialEdgeTestMirrorbootPartitionsUEFI(relbase.xenial_edge,
283 __test__ = True279 __test__ = True
284280
285281
286class ArtfulTestMirrorbootPartitionsUEFI(relbase.artful,282class BionicTestMirrorbootPartitionsUEFI(relbase.bionic,
287 TestMirrorbootPartitionsUEFIAbs):283 TestMirrorbootPartitionsUEFIAbs):
288 __test__ = True284 __test__ = True
289285
290286
291class BionicTestMirrorbootPartitionsUEFI(relbase.bionic,287class CosmicTestMirrorbootPartitionsUEFI(relbase.cosmic,
292 TestMirrorbootPartitionsUEFIAbs):288 TestMirrorbootPartitionsUEFIAbs):
293 __test__ = True289 __test__ = True
294290
@@ -326,11 +322,11 @@ class XenialEdgeTestRaid5boot(relbase.xenial_edge, TestRaid5bootAbs):
326 __test__ = True322 __test__ = True
327323
328324
329class ArtfulTestRaid5boot(relbase.artful, TestRaid5bootAbs):325class BionicTestRaid5boot(relbase.bionic, TestRaid5bootAbs):
330 __test__ = True326 __test__ = True
331327
332328
333class BionicTestRaid5boot(relbase.bionic, TestRaid5bootAbs):329class CosmicTestRaid5boot(relbase.cosmic, TestRaid5bootAbs):
334 __test__ = True330 __test__ = True
335331
336332
@@ -379,11 +375,11 @@ class XenialEdgeTestRaid6boot(relbase.xenial_edge, TestRaid6bootAbs):
379 __test__ = True375 __test__ = True
380376
381377
382class ArtfulTestRaid6boot(relbase.artful, TestRaid6bootAbs):378class BionicTestRaid6boot(relbase.bionic, TestRaid6bootAbs):
383 __test__ = True379 __test__ = True
384380
385381
386class BionicTestRaid6boot(relbase.bionic, TestRaid6bootAbs):382class CosmicTestRaid6boot(relbase.cosmic, TestRaid6bootAbs):
387 __test__ = True383 __test__ = True
388384
389385
@@ -420,11 +416,11 @@ class XenialEdgeTestRaid10boot(relbase.xenial_edge, TestRaid10bootAbs):
420 __test__ = True416 __test__ = True
421417
422418
423class ArtfulTestRaid10boot(relbase.artful, TestRaid10bootAbs):419class BionicTestRaid10boot(relbase.bionic, TestRaid10bootAbs):
424 __test__ = True420 __test__ = True
425421
426422
427class BionicTestRaid10boot(relbase.bionic, TestRaid10bootAbs):423class CosmicTestRaid10boot(relbase.cosmic, TestRaid10bootAbs):
428 __test__ = True424 __test__ = True
429425
430426
@@ -521,11 +517,11 @@ class XenialEdgeTestAllindata(relbase.xenial_edge, TestAllindataAbs):
521 __test__ = True517 __test__ = True
522518
523519
524class ArtfulTestAllindata(relbase.artful, TestAllindataAbs):520class BionicTestAllindata(relbase.bionic, TestAllindataAbs):
525 __test__ = True521 __test__ = True
526522
527523
528class BionicTestAllindata(relbase.bionic, TestAllindataAbs):524class CosmicTestAllindata(relbase.cosmic, TestAllindataAbs):
529 __test__ = True525 __test__ = True
530526
531# vi: ts=4 expandtab syntax=python527# vi: ts=4 expandtab syntax=python
diff --git a/tests/vmtests/test_mdadm_iscsi.py b/tests/vmtests/test_mdadm_iscsi.py
index 3c8e6ef..eba200a 100644
--- a/tests/vmtests/test_mdadm_iscsi.py
+++ b/tests/vmtests/test_mdadm_iscsi.py
@@ -41,11 +41,11 @@ class XenialEdgeTestIscsiMdadm(relbase.xenial_edge, TestMdadmIscsiAbs):
41 __test__ = True41 __test__ = True
4242
4343
44class ArtfulTestIscsiMdadm(relbase.artful, TestMdadmIscsiAbs):44class BionicTestIscsiMdadm(relbase.bionic, TestMdadmIscsiAbs):
45 __test__ = True45 __test__ = True
4646
4747
48class BionicTestIscsiMdadm(relbase.bionic, TestMdadmIscsiAbs):48class CosmicTestIscsiMdadm(relbase.cosmic, TestMdadmIscsiAbs):
49 __test__ = True49 __test__ = True
5050
51# vi: ts=4 expandtab syntax=python51# vi: ts=4 expandtab syntax=python
diff --git a/tests/vmtests/test_multipath.py b/tests/vmtests/test_multipath.py
index ffb78b8..0bf63b7 100644
--- a/tests/vmtests/test_multipath.py
+++ b/tests/vmtests/test_multipath.py
@@ -66,11 +66,11 @@ class XenialEdgeTestMultipathBasic(relbase.xenial_edge, TestMultipathBasicAbs):
66 __test__ = True66 __test__ = True
6767
6868
69class ArtfulTestMultipathBasic(relbase.artful, TestMultipathBasicAbs):69class BionicTestMultipathBasic(relbase.bionic, TestMultipathBasicAbs):
70 __test__ = True70 __test__ = True
7171
7272
73class BionicTestMultipathBasic(relbase.bionic, TestMultipathBasicAbs):73class CosmicTestMultipathBasic(relbase.cosmic, TestMultipathBasicAbs):
74 __test__ = True74 __test__ = True
7575
76# vi: ts=4 expandtab syntax=python76# vi: ts=4 expandtab syntax=python
diff --git a/tests/vmtests/test_network.py b/tests/vmtests/test_network.py
index 59a25fe..6532841 100644
--- a/tests/vmtests/test_network.py
+++ b/tests/vmtests/test_network.py
@@ -480,11 +480,11 @@ class XenialTestNetworkBasic(relbase.xenial, TestNetworkBasicAbs):
480 __test__ = True480 __test__ = True
481481
482482
483class ArtfulTestNetworkBasic(relbase.artful, TestNetworkBasicAbs):483class BionicTestNetworkBasic(relbase.bionic, TestNetworkBasicAbs):
484 __test__ = True484 __test__ = True
485485
486486
487class BionicTestNetworkBasic(relbase.bionic, TestNetworkBasicAbs):487class CosmicTestNetworkBasic(relbase.cosmic, TestNetworkBasicAbs):
488 __test__ = True488 __test__ = True
489489
490490
diff --git a/tests/vmtests/test_network_alias.py b/tests/vmtests/test_network_alias.py
index 903b395..d466299 100644
--- a/tests/vmtests/test_network_alias.py
+++ b/tests/vmtests/test_network_alias.py
@@ -69,11 +69,11 @@ class XenialTestNetworkAlias(relbase.xenial, TestNetworkAliasAbs):
69 __test__ = True69 __test__ = True
7070
7171
72class ArtfulTestNetworkAlias(relbase.artful, TestNetworkAliasAbs):72class BionicTestNetworkAlias(relbase.bionic, TestNetworkAliasAbs):
73 __test__ = True73 __test__ = True
7474
7575
76class BionicTestNetworkAlias(relbase.bionic, TestNetworkAliasAbs):76class CosmicTestNetworkAlias(relbase.cosmic, TestNetworkAliasAbs):
77 __test__ = True77 __test__ = True
7878
79# vi: ts=4 expandtab syntax=python79# vi: ts=4 expandtab syntax=python
diff --git a/tests/vmtests/test_network_bonding.py b/tests/vmtests/test_network_bonding.py
index 7d07413..9dba07b 100644
--- a/tests/vmtests/test_network_bonding.py
+++ b/tests/vmtests/test_network_bonding.py
@@ -10,9 +10,18 @@ import textwrap
10class TestNetworkBondingAbs(TestNetworkBaseTestsAbs):10class TestNetworkBondingAbs(TestNetworkBaseTestsAbs):
11 conf_file = "examples/tests/bonding_network.yaml"11 conf_file = "examples/tests/bonding_network.yaml"
1212
13 def test_ifenslave_installed(self):13 def test_ifenslave_package_status(self):
14 self.assertIn("ifenslave", self.debian_packages,14 """ifenslave is expected installed in Ubuntu < artful."""
15 "ifenslave deb not installed")15 rel = self.target_release
16 pkg = "ifenslave"
17 if rel in ("precise", "trusty", "xenial"):
18 self.assertIn(
19 pkg, self.debian_packages,
20 "%s package expected in %s but not found" % (pkg, rel))
21 else:
22 self.assertNotIn(
23 pkg, self.debian_packages,
24 "%s package found but not expected in %s" % (pkg, rel))
1625
1726
18class CentosTestNetworkBondingAbs(TestNetworkBondingAbs):27class CentosTestNetworkBondingAbs(TestNetworkBondingAbs):
@@ -26,7 +35,7 @@ class CentosTestNetworkBondingAbs(TestNetworkBondingAbs):
26 rpm -qf `which ifenslave` |tee ifenslave_installed35 rpm -qf `which ifenslave` |tee ifenslave_installed
27 """)]36 """)]
2837
29 def test_ifenslave_installed(self):38 def test_ifenslave_package_status(self):
30 status = self.load_collect_file("ifenslave_installed")39 status = self.load_collect_file("ifenslave_installed")
31 self.logger.debug('ifenslave installed: {}'.format(status))40 self.logger.debug('ifenslave installed: {}'.format(status))
32 self.assertTrue('iputils' in status)41 self.assertTrue('iputils' in status)
@@ -62,32 +71,12 @@ class XenialTestBonding(relbase.xenial, TestNetworkBondingAbs):
62 __test__ = True71 __test__ = True
6372
6473
65class ArtfulTestBonding(relbase.artful, TestNetworkBondingAbs):
66 __test__ = True
67
68 def test_ifenslave_installed(self):
69 """Artful should not have ifenslave installed."""
70 pass
71
72 def test_ifenslave_not_installed(self):
73 """Confirm that ifenslave is not installed on artful"""
74 self.assertNotIn('ifenslave', self.debian_packages,
75 "ifenslave is not expected in artful: %s" %
76 self.debian_packages.get('ifenslave'))
77
78
79class BionicTestBonding(relbase.bionic, TestNetworkBondingAbs):74class BionicTestBonding(relbase.bionic, TestNetworkBondingAbs):
80 __test__ = True75 __test__ = True
8176
82 def test_ifenslave_installed(self):
83 """Bionic should not have ifenslave installed."""
84 pass
8577
86 def test_ifenslave_not_installed(self):78class CosmicTestBonding(relbase.cosmic, TestNetworkBondingAbs):
87 """Confirm that ifenslave is not installed on bionic"""79 __test__ = True
88 self.assertNotIn('ifenslave', self.debian_packages,
89 "ifenslave is not expected in bionic: %s" %
90 self.debian_packages.get('ifenslave'))
9180
9281
93class Centos66TestNetworkBonding(centos_relbase.centos66fromxenial,82class Centos66TestNetworkBonding(centos_relbase.centos66fromxenial,
diff --git a/tests/vmtests/test_network_bridging.py b/tests/vmtests/test_network_bridging.py
index ca8964e..91df02e 100644
--- a/tests/vmtests/test_network_bridging.py
+++ b/tests/vmtests/test_network_bridging.py
@@ -109,9 +109,18 @@ class TestBridgeNetworkAbs(TestNetworkBaseTestsAbs):
109 "sysfs_br0_eth1",109 "sysfs_br0_eth1",
110 "sysfs_br0_eth2"])110 "sysfs_br0_eth2"])
111111
112 def test_bridge_utils_installed(self):112 def test_bridge_package_status(self):
113 self.assertIn("bridge-utils", self.debian_packages,113 """bridge-utils is expected installed in Ubuntu < artful."""
114 "bridge-utilsi deb not installed")114 rel = self.target_release
115 pkg = "bridge-utils"
116 if rel in ("precise", "trusty", "xenial"):
117 self.assertIn(
118 pkg, self.debian_packages,
119 "%s package expected in %s but not found" % (pkg, rel))
120 else:
121 self.assertNotIn(
122 pkg, self.debian_packages,
123 "%s package found but not expected in %s" % (pkg, rel))
115124
116 def test_bridge_params(self):125 def test_bridge_params(self):
117126
@@ -132,11 +141,10 @@ class TestBridgeNetworkAbs(TestNetworkBaseTestsAbs):
132 return br0141 return br0
133142
134 def _get_bridge_params(br):143 def _get_bridge_params(br):
135 release = (
136 self.target_release if self.target_release else self.release)
137 bridge_params_uncheckable = default_bridge_params_uncheckable144 bridge_params_uncheckable = default_bridge_params_uncheckable
138 bridge_params_uncheckable.extend(145 bridge_params_uncheckable.extend(
139 release_to_bridge_params_uncheckable.get(release, []))146 release_to_bridge_params_uncheckable.get(
147 self.target_release, []))
140 return [p for p in br.keys()148 return [p for p in br.keys()
141 if (p.startswith('bridge_') and149 if (p.startswith('bridge_') and
142 p not in bridge_params_uncheckable)]150 p not in bridge_params_uncheckable)]
@@ -200,7 +208,8 @@ class CentosTestBridgeNetworkAbs(TestBridgeNetworkAbs):
200 def test_etc_resolvconf(self):208 def test_etc_resolvconf(self):
201 pass209 pass
202210
203 def test_bridge_utils_installed(self):211 def test_bridge_package_status(self):
212 """bridge-utils is expected installed in centos."""
204 self.output_files_exist(["bridge-utils_installed"])213 self.output_files_exist(["bridge-utils_installed"])
205 status = self.load_collect_file("bridge-utils_installed").strip()214 status = self.load_collect_file("bridge-utils_installed").strip()
206 self.logger.debug('bridge-utils installed: {}'.format(status))215 self.logger.debug('bridge-utils installed: {}'.format(status))
@@ -219,29 +228,12 @@ class Centos70TestBridgeNetwork(centos_relbase.centos70fromxenial,
219228
220# only testing Yakkety or newer as older releases do not yet229# only testing Yakkety or newer as older releases do not yet
221# have updated ifupdown/bridge-utils packages;230# have updated ifupdown/bridge-utils packages;
222class ArtfulTestBridging(relbase.artful, TestBridgeNetworkAbs):231class BionicTestBridging(relbase.bionic, TestBridgeNetworkAbs):
223 __test__ = True232 __test__ = True
224233
225 def test_bridge_utils_installed(self):
226 """bridge-utils not needed in artful."""
227 pass
228
229 def test_bridge_utils_not_installed(self):
230 self.assertNotIn("bridge-utils", self.debian_packages,
231 "bridge-utils is not expected in artful: %s" %
232 self.debian_packages.get('bridge-utils'))
233
234234
235class BionicTestBridging(relbase.bionic, TestBridgeNetworkAbs):235class CosmicTestBridging(relbase.cosmic, TestBridgeNetworkAbs):
236 __test__ = True236 __test__ = True
237237
238 def test_bridge_utils_installed(self):
239 """bridge-utils not needed in bionic."""
240 pass
241
242 def test_bridge_utils_not_installed(self):
243 self.assertNotIn("bridge-utils", self.debian_packages,
244 "bridge-utils is not expected in bionic: %s" %
245 self.debian_packages.get('bridge-utils'))
246238
247# vi: ts=4 expandtab syntax=python239# vi: ts=4 expandtab syntax=python
diff --git a/tests/vmtests/test_network_ipv6.py b/tests/vmtests/test_network_ipv6.py
index 6d87dcf..d3c34a5 100644
--- a/tests/vmtests/test_network_ipv6.py
+++ b/tests/vmtests/test_network_ipv6.py
@@ -64,11 +64,11 @@ class XenialTestNetworkIPV6(relbase.xenial, TestNetworkIPV6Abs):
64 __test__ = True64 __test__ = True
6565
6666
67class ArtfulTestNetworkIPV6(relbase.artful, TestNetworkIPV6Abs):67class BionicTestNetworkIPV6(relbase.bionic, TestNetworkIPV6Abs):
68 __test__ = True68 __test__ = True
6969
7070
71class BionicTestNetworkIPV6(relbase.bionic, TestNetworkIPV6Abs):71class CosmicTestNetworkIPV6(relbase.cosmic, TestNetworkIPV6Abs):
72 __test__ = True72 __test__ = True
7373
7474
diff --git a/tests/vmtests/test_network_ipv6_static.py b/tests/vmtests/test_network_ipv6_static.py
index 81fee8f..0396e43 100644
--- a/tests/vmtests/test_network_ipv6_static.py
+++ b/tests/vmtests/test_network_ipv6_static.py
@@ -46,11 +46,11 @@ class XenialTestNetworkIPV6Static(relbase.xenial, TestNetworkIPV6StaticAbs):
46 __test__ = True46 __test__ = True
4747
4848
49class ArtfulTestNetworkIPV6Static(relbase.artful, TestNetworkIPV6StaticAbs):49class BionicTestNetworkIPV6Static(relbase.bionic, TestNetworkIPV6StaticAbs):
50 __test__ = True50 __test__ = True
5151
5252
53class BionicTestNetworkIPV6Static(relbase.bionic, TestNetworkIPV6StaticAbs):53class CosmicTestNetworkIPV6Static(relbase.cosmic, TestNetworkIPV6StaticAbs):
54 __test__ = True54 __test__ = True
5555
5656
diff --git a/tests/vmtests/test_network_ipv6_vlan.py b/tests/vmtests/test_network_ipv6_vlan.py
index 68cf6e0..e001da9 100644
--- a/tests/vmtests/test_network_ipv6_vlan.py
+++ b/tests/vmtests/test_network_ipv6_vlan.py
@@ -27,11 +27,11 @@ class XenialTestNetworkIPV6Vlan(relbase.xenial, TestNetworkIPV6VlanAbs):
27 __test__ = True27 __test__ = True
2828
2929
30class ArtfulTestNetworkIPV6Vlan(relbase.artful, TestNetworkIPV6VlanAbs):30class BionicTestNetworkIPV6Vlan(relbase.bionic, TestNetworkIPV6VlanAbs):
31 __test__ = True31 __test__ = True
3232
3333
34class BionicTestNetworkIPV6Vlan(relbase.bionic, TestNetworkIPV6VlanAbs):34class CosmicTestNetworkIPV6Vlan(relbase.cosmic, TestNetworkIPV6VlanAbs):
35 __test__ = True35 __test__ = True
3636
3737
diff --git a/tests/vmtests/test_network_mtu.py b/tests/vmtests/test_network_mtu.py
index 41b1383..7a10bf1 100644
--- a/tests/vmtests/test_network_mtu.py
+++ b/tests/vmtests/test_network_mtu.py
@@ -189,23 +189,15 @@ class TestNetworkMtu(relbase.xenial, TestNetworkMtuAbs):
189 __test__ = True189 __test__ = True
190190
191191
192class ArtfulTestNetworkMtu(relbase.artful, TestNetworkMtuAbs):192@TestNetworkMtuAbs.skip_by_date("1671951", fixby="2018-09-26")
193class BionicTestNetworkMtu(relbase.bionic, TestNetworkMtuAbs):
193 __test__ = True194 __test__ = True
194195
195 @classmethod
196 def setUpClass(cls):
197 cls.skip_by_date("1671951", fixby="2018-05-26")
198 super().setUpClass()
199
200196
201class BionicTestNetworkMtu(relbase.bionic, TestNetworkMtuAbs):197@TestNetworkMtuAbs.skip_by_date("1671951", fixby="2018-09-26")
198class CosmicTestNetworkMtu(relbase.cosmic, TestNetworkMtuAbs):
202 __test__ = True199 __test__ = True
203200
204 @classmethod
205 def setUpClass(cls):
206 cls.skip_by_date("1671951", fixby="2018-05-26")
207 super().setUpClass()
208
209201
210class Centos66TestNetworkMtu(centos_relbase.centos66fromxenial,202class Centos66TestNetworkMtu(centos_relbase.centos66fromxenial,
211 CentosTestNetworkMtuAbs):203 CentosTestNetworkMtuAbs):
diff --git a/tests/vmtests/test_network_static.py b/tests/vmtests/test_network_static.py
index d96d3eb..40468f3 100644
--- a/tests/vmtests/test_network_static.py
+++ b/tests/vmtests/test_network_static.py
@@ -60,11 +60,11 @@ class XenialTestNetworkStatic(relbase.xenial, TestNetworkStaticAbs):
60 __test__ = True60 __test__ = True
6161
6262
63class ArtfulTestNetworkStatic(relbase.artful, TestNetworkStaticAbs):63class BionicTestNetworkStatic(relbase.bionic, TestNetworkStaticAbs):
64 __test__ = True64 __test__ = True
6565
6666
67class BionicTestNetworkStatic(relbase.bionic, TestNetworkStaticAbs):67class CosmicTestNetworkStatic(relbase.cosmic, TestNetworkStaticAbs):
68 __test__ = True68 __test__ = True
6969
7070
diff --git a/tests/vmtests/test_network_static_routes.py b/tests/vmtests/test_network_static_routes.py
index 92ff267..9fa89ff 100644
--- a/tests/vmtests/test_network_static_routes.py
+++ b/tests/vmtests/test_network_static_routes.py
@@ -49,12 +49,12 @@ class XenialTestNetworkStaticRoutes(relbase.xenial,
49 __test__ = True49 __test__ = True
5050
5151
52class ArtfulTestNetworkStaticRoutes(relbase.artful,52class BionicTestNetworkStaticRoutes(relbase.bionic,
53 TestNetworkStaticRoutesAbs):53 TestNetworkStaticRoutesAbs):
54 __test__ = True54 __test__ = True
5555
5656
57class BionicTestNetworkStaticRoutes(relbase.bionic,57class CosmicTestNetworkStaticRoutes(relbase.cosmic,
58 TestNetworkStaticRoutesAbs):58 TestNetworkStaticRoutesAbs):
59 __test__ = True59 __test__ = True
6060
diff --git a/tests/vmtests/test_network_vlan.py b/tests/vmtests/test_network_vlan.py
index 3cb6eae..94e2966 100644
--- a/tests/vmtests/test_network_vlan.py
+++ b/tests/vmtests/test_network_vlan.py
@@ -35,7 +35,7 @@ class TestNetworkVlanAbs(TestNetworkBaseTestsAbs):
35 self.output_files_exist(link_files)35 self.output_files_exist(link_files)
3636
37 def test_vlan_installed(self):37 def test_vlan_installed(self):
38 release = self.target_release if self.target_release else self.release38 release = self.target_release
39 if release not in ('precise', 'trusty', 'xenial', 'artful'):39 if release not in ('precise', 'trusty', 'xenial', 'artful'):
40 raise SkipTest("release '%s' does not need the vlan package" %40 raise SkipTest("release '%s' does not need the vlan package" %
41 release)41 release)
@@ -86,11 +86,11 @@ class XenialTestNetworkVlan(relbase.xenial, TestNetworkVlanAbs):
86 __test__ = True86 __test__ = True
8787
8888
89class ArtfulTestNetworkVlan(relbase.artful, TestNetworkVlanAbs):89class BionicTestNetworkVlan(relbase.bionic, TestNetworkVlanAbs):
90 __test__ = True90 __test__ = True
9191
9292
93class BionicTestNetworkVlan(relbase.bionic, TestNetworkVlanAbs):93class CosmicTestNetworkVlan(relbase.cosmic, TestNetworkVlanAbs):
94 __test__ = True94 __test__ = True
9595
9696
diff --git a/tests/vmtests/test_nvme.py b/tests/vmtests/test_nvme.py
index a9e3bc3..80d9cbf 100644
--- a/tests/vmtests/test_nvme.py
+++ b/tests/vmtests/test_nvme.py
@@ -75,11 +75,11 @@ class XenialEdgeTestNvme(relbase.xenial_edge, TestNvmeAbs):
75 __test__ = True75 __test__ = True
7676
7777
78class ArtfulTestNvme(relbase.artful, TestNvmeAbs):78class BionicTestNvme(relbase.bionic, TestNvmeAbs):
79 __test__ = True79 __test__ = True
8080
8181
82class BionicTestNvme(relbase.bionic, TestNvmeAbs):82class CosmicTestNvme(relbase.cosmic, TestNvmeAbs):
83 __test__ = True83 __test__ = True
8484
8585
@@ -164,11 +164,12 @@ class XenialEdgeTestNvmeBcache(relbase.xenial_edge, TestNvmeBcacheAbs):
164 __test__ = True164 __test__ = True
165165
166166
167class ArtfulTestNvmeBcache(relbase.artful, TestNvmeBcacheAbs):167class BionicTestNvmeBcache(relbase.bionic, TestNvmeBcacheAbs):
168 __test__ = True168 __test__ = True
169169
170170
171class BionicTestNvmeBcache(relbase.bionic, TestNvmeBcacheAbs):171class CosmicTestNvmeBcache(relbase.cosmic, TestNvmeBcacheAbs):
172 __test__ = True172 __test__ = True
173173
174
174# vi: ts=4 expandtab syntax=python175# vi: ts=4 expandtab syntax=python
diff --git a/tests/vmtests/test_pollinate_useragent.py b/tests/vmtests/test_pollinate_useragent.py
index abd6daf..201cca1 100644
--- a/tests/vmtests/test_pollinate_useragent.py
+++ b/tests/vmtests/test_pollinate_useragent.py
@@ -63,4 +63,7 @@ class BionicTestPollinateUserAgent(relbase.bionic, TestPollinateUserAgent):
63 __test__ = True63 __test__ = True
6464
6565
66class CosmicTestPollinateUserAgent(relbase.cosmic, TestPollinateUserAgent):
67 __test__ = True
68
66# vi: ts=4 expandtab syntax=python69# vi: ts=4 expandtab syntax=python
diff --git a/tests/vmtests/test_raid5_bcache.py b/tests/vmtests/test_raid5_bcache.py
index aa2bebf..bb00b65 100644
--- a/tests/vmtests/test_raid5_bcache.py
+++ b/tests/vmtests/test_raid5_bcache.py
@@ -99,11 +99,11 @@ class XenialEdgeTestRaid5Bcache(relbase.xenial_edge, TestMdadmBcacheAbs):
99 __test__ = True99 __test__ = True
100100
101101
102class ArtfulTestRaid5Bcache(relbase.artful, TestMdadmBcacheAbs):102class BionicTestRaid5Bcache(relbase.bionic, TestMdadmBcacheAbs):
103 __test__ = True103 __test__ = True
104104
105105
106class BionicTestRaid5Bcache(relbase.bionic, TestMdadmBcacheAbs):106class CosmicTestRaid5Bcache(relbase.cosmic, TestMdadmBcacheAbs):
107 __test__ = True107 __test__ = True
108108
109# vi: ts=4 expandtab syntax=python109# vi: ts=4 expandtab syntax=python
diff --git a/tests/vmtests/test_simple.py b/tests/vmtests/test_simple.py
index 54fa24d..de1c675 100644
--- a/tests/vmtests/test_simple.py
+++ b/tests/vmtests/test_simple.py
@@ -43,14 +43,14 @@ class XenialTestSimple(relbase.xenial, TestSimple):
43 __test__ = True43 __test__ = True
4444
4545
46class ArtfulTestSimple(relbase.artful, TestSimple):46class BionicTestSimple(relbase.bionic, TestSimple):
47 __test__ = True47 __test__ = True
4848
49 def test_output_files_exist(self):49 def test_output_files_exist(self):
50 self.output_files_exist(["netplan.yaml"])50 self.output_files_exist(["netplan.yaml"])
5151
5252
53class BionicTestSimple(relbase.bionic, TestSimple):53class CosmicTestSimple(relbase.cosmic, TestSimple):
54 __test__ = True54 __test__ = True
5555
56 def test_output_files_exist(self):56 def test_output_files_exist(self):
diff --git a/tests/vmtests/test_uefi_basic.py b/tests/vmtests/test_uefi_basic.py
index 517554f..641a077 100644
--- a/tests/vmtests/test_uefi_basic.py
+++ b/tests/vmtests/test_uefi_basic.py
@@ -112,11 +112,11 @@ class XenialEdgeUefiTestBasic(relbase.xenial_edge, TestBasicAbs):
112 __test__ = True112 __test__ = True
113113
114114
115class ArtfulUefiTestBasic(relbase.artful, TestBasicAbs):115class BionicUefiTestBasic(relbase.bionic, TestBasicAbs):
116 __test__ = True116 __test__ = True
117117
118118
119class BionicUefiTestBasic(relbase.bionic, TestBasicAbs):119class CosmicUefiTestBasic(relbase.cosmic, TestBasicAbs):
120 __test__ = True120 __test__ = True
121121
122122
@@ -132,11 +132,11 @@ class XenialGAUefiTestBasic4k(XenialGAUefiTestBasic):
132 disk_block_size = 4096132 disk_block_size = 4096
133133
134134
135class ArtfulUefiTestBasic4k(ArtfulUefiTestBasic):135class BionicUefiTestBasic4k(BionicUefiTestBasic):
136 disk_block_size = 4096136 disk_block_size = 4096
137137
138138
139class BionicUefiTestBasic4k(BionicUefiTestBasic):139class CosmicUefiTestBasic4k(CosmicUefiTestBasic):
140 disk_block_size = 4096140 disk_block_size = 4096
141141
142# vi: ts=4 expandtab syntax=python142# vi: ts=4 expandtab syntax=python
diff --git a/tests/vmtests/test_zfsroot.py b/tests/vmtests/test_zfsroot.py
index 1ebc616..e159d17 100644
--- a/tests/vmtests/test_zfsroot.py
+++ b/tests/vmtests/test_zfsroot.py
@@ -96,11 +96,11 @@ class XenialEdgeTestZfsRoot(relbase.xenial_edge, TestZfsRootAbs):
96 __test__ = True96 __test__ = True
9797
9898
99class ArtfulTestZfsRoot(relbase.artful, TestZfsRootAbs):99class BionicTestZfsRoot(relbase.bionic, TestZfsRootAbs):
100 __test__ = True100 __test__ = True
101101
102102
103class BionicTestZfsRoot(relbase.bionic, TestZfsRootAbs):103class CosmicTestZfsRoot(relbase.cosmic, TestZfsRootAbs):
104 __test__ = True104 __test__ = True
105105
106106
@@ -120,3 +120,7 @@ class XenialGAi386TestZfsRootFsType(relbase.xenial_ga, TestZfsRootFsTypeAbs,
120120
121class BionicTestZfsRootFsType(relbase.bionic, TestZfsRootFsTypeAbs):121class BionicTestZfsRootFsType(relbase.bionic, TestZfsRootFsTypeAbs):
122 __test__ = True122 __test__ = True
123
124
125class CosmicTestZfsRootFsType(relbase.cosmic, TestZfsRootFsTypeAbs):
126 __test__ = True
diff --git a/tools/xkvm b/tools/xkvm
index deb769e..dbcba6f 100755
--- a/tools/xkvm
+++ b/tools/xkvm
@@ -648,9 +648,13 @@ main() {
648648
649 local bus_devices649 local bus_devices
650 bus_devices=( -device "$virtio_scsi_bus,id=virtio-scsi-xkvm" )650 bus_devices=( -device "$virtio_scsi_bus,id=virtio-scsi-xkvm" )
651 cmd=( "${kvmcmd[@]}" "${archopts[@]}" 651 local rng_devices
652 rng_devices=( -object "rng-random,filename=/dev/urandom,id=rng0"
653 -device "virtio-rng-pci,rng=rng0" )
654 cmd=( "${kvmcmd[@]}" "${archopts[@]}"
652 "${bios_opts[@]}"655 "${bios_opts[@]}"
653 "${bus_devices[@]}"656 "${bus_devices[@]}"
657 "${rng_devices[@]}"
654 "${netargs[@]}"658 "${netargs[@]}"
655 "${diskargs[@]}" "${pt[@]}" )659 "${diskargs[@]}" "${pt[@]}" )
656 local pcmd=$(quote_cmd "${cmd[@]}")660 local pcmd=$(quote_cmd "${cmd[@]}")
diff --git a/tox.ini b/tox.ini
index 6f14381..8e5faf2 100644
--- a/tox.ini
+++ b/tox.ini
@@ -51,7 +51,7 @@ commands = {envpython} -m flake8 {posargs:curtin tests/}
51basepython = python351basepython = python3
52deps = {[testenv]deps}52deps = {[testenv]deps}
53 pylint==1.8.153 pylint==1.8.1
54 bzr+lp:simplestreams54 git+https://git.launchpad.net/simplestreams
55commands = {envpython} -m pylint --errors-only {posargs:curtin tests/vmtests}55commands = {envpython} -m pylint --errors-only {posargs:curtin tests/vmtests}
5656
57[testenv:py27-pylint]57[testenv:py27-pylint]

Subscribers

People subscribed via source and target branches