22
33from tempfile import TemporaryDirectory
44
5- from zenlib .util import colorize as c_
6- from zenlib . util import contains
5+ from zenlib .util import colorize , contains
6+ from time import sleep
77
88
99@contains ("test_flag" , "A test flag must be set to create a test image" , raise_exception = True )
@@ -12,18 +12,45 @@ def init_banner(self):
1212 self ["banner" ] = f"echo { self ['test_flag' ]} "
1313
1414
15+ @contains ("test_resume" )
16+ def resume_tests (self ):
17+ return [
18+ 'if [ "$(</sys/power/resume)" != "0:0" ] ; then' ,
19+ ' [ -e "/resumed" ] && (rm /resumed ; echo c > /proc/sysrq-trigger)' ,
20+ # Set correct resume parameters
21+ " echo reboot > /sys/power/disk" ,
22+ # trigger resume
23+ " echo disk > /sys/power/state" ,
24+ ' [ -e "/resume" ] || echo c > /proc/sysrq-trigger' ,
25+ # if we reach this point, resume was successful
26+ # reset environment in case resume needs to be rerun
27+ " rm /resumed" ,
28+ ' echo "Resume completed without error.' ,
29+ "else" ,
30+ ' echo "No resume device found! Resume test not possible!' ,
31+ "fi" ,
32+ ]
33+
34+
35+ def complete_tests (self ):
36+ return [
37+ "echo s > /proc/sysrq-trigger" ,
38+ "echo o > /proc/sysrq-trigger" ,
39+ ]
40+
41+
1542def _allocate_image (self , image_path , padding = 0 ):
1643 """Allocate the test image size"""
1744 self ._mkdir (image_path .parent , resolve_build = False ) # Make sure the parent directory exists
1845 if image_path .exists ():
1946 if self .clean :
20- self .logger .warning ("Removing existing filesystem image file: %s" % c_ (image_path , "red" ))
47+ self .logger .warning ("Removing existing filesystem image file: %s" % colorize (image_path , "red" ))
2148 image_path .unlink ()
2249 else :
23- raise Exception ("File already exists and 'clean' is off: %s" % c_ (image_path , "red" , bold = True ))
50+ raise Exception ("File already exists and 'clean' is off: %s" % colorize (image_path , "red" , bold = True ))
2451
2552 with open (image_path , "wb" ) as f :
26- self .logger .info ("Allocating test image file: %s" % c_ (f .name , "green" ))
53+ self .logger .info ("Allocating test image file: %s" % colorize (f .name , "green" ))
2754 f .write (b"\0 " * (self .test_image_size + padding ) * 2 ** 20 )
2855
2956
@@ -61,8 +88,8 @@ def make_test_luks_image(self, image_path):
6188 pass
6289 _allocate_image (self , image_path , padding = 32 ) # First allocate the image file, adding padding for the LUKS header
6390 keyfile_path = _get_luks_keyfile (self )
64- self .logger .info ("Using LUKS keyfile: %s" % c_ (keyfile_path , "green" ))
65- self .logger .info ("Creating LUKS image: %s" % c_ (image_path , "green" ))
91+ self .logger .info ("Using LUKS keyfile: %s" % colorize (keyfile_path , "green" ))
92+ self .logger .info ("Creating LUKS image: %s" % colorize (image_path , "green" ))
6693 self ._run (
6794 [
6895 "cryptsetup" ,
@@ -75,14 +102,14 @@ def make_test_luks_image(self, image_path):
75102 keyfile_path ,
76103 ]
77104 )
78- self .logger .info ("Opening LUKS image: %s" % c_ (image_path , "magenta" ))
105+ self .logger .info ("Opening LUKS image: %s" % colorize (image_path , "magenta" ))
79106 self ._run (["cryptsetup" , "luksOpen" , image_path , "test_image" , "--key-file" , keyfile_path ])
80107
81108
82109def make_test_image (self ):
83110 """Creates a test image from the build dir"""
84111 build_dir = self ._get_build_path ("/" ).resolve ()
85- self .logger .info ("Creating test image from: %s" % c_ (build_dir , "blue" , bold = True ))
112+ self .logger .info ("Creating test image from: %s" % colorize (build_dir , "blue" , bold = True ))
86113
87114 rootfs_type = self ["mounts" ]["root" ]["type" ]
88115 try :
@@ -99,6 +126,33 @@ def make_test_image(self):
99126 else :
100127 _allocate_image (self , image_path )
101128
129+ loopback = None
130+ if self .get ("test_resume" ):
131+ try :
132+ self ._run (["sgdisk" , "-og" , image_path ])
133+ self ._run (["sgdisk" , "-n" , "1:0:+256" , image_path ])
134+ self ._run (["sgdisk" , "-n" , "2:0" , image_path ])
135+ except RuntimeError as e :
136+ raise RuntimeError ("Failed to partition test disk: %s" , e )
137+
138+ try :
139+ out = self ._run (["losetup" , "--show" , "-fP" , image_path ])
140+ loopback = out .stdout .decode ("utf-8" ).strip ()
141+
142+ image_path = f"{ loopback } p2"
143+ except RuntimeError as e :
144+ raise RuntimeError ("Failed to allocate loopback device for disk creation: %s" , e )
145+
146+ # sleep for 100ms, to give the loopback device time to scan for partitions
147+ # usually fast, but losetup doesn't wait for this to complete before returning.
148+ # TODO: replace with an proper check/wait loop
149+ sleep (0.100 )
150+
151+ try :
152+ self ._run (["mkswap" , "-U" , self ["test_swap_uuid" ], f"{ loopback } p1" ])
153+ except RuntimeError as e :
154+ raise RuntimeError ("Failed to create swap partition on test disk: %s" , e )
155+
102156 if rootfs_type == "ext4" :
103157 self ._run (["mkfs" , "-t" , rootfs_type , "-d" , build_dir , "-U" , rootfs_uuid , "-F" , image_path ])
104158 elif rootfs_type == "btrfs" :
@@ -117,7 +171,7 @@ def make_test_image(self):
117171 squashfs_image = self ._get_out_path (f"squash/{ self ['squashfs_image' ]} " )
118172 if squashfs_image .exists ():
119173 if self .clean :
120- self .logger .warning ("Removing existing squashfs image file: %s" % c_ (squashfs_image , "red" ))
174+ self .logger .warning ("Removing existing squashfs image file: %s" % colorize (squashfs_image , "red" ))
121175 squashfs_image .unlink ()
122176 else :
123177 raise Exception ("File already exists and 'clean' is off: %s" % squashfs_image )
@@ -129,6 +183,11 @@ def make_test_image(self):
129183 else :
130184 raise NotImplementedError ("Unsupported test rootfs type: %s" % rootfs_type )
131185
186+ # Clean up loopback device used to access test image partitions
187+ if loopback :
188+ self .logger .info ("Closing test image loopback device: %s" , colorize (loopback , "magenta" ))
189+ self ._run (["losetup" , "-d" , loopback ])
190+
132191 if self .get ("cryptsetup" ): # Leave it open in the event of failure, close it before executing tests
133- self .logger .info ("Closing LUKS image: %s" % c_ (image_path , "magenta" ))
192+ self .logger .info ("Closing LUKS image: %s" % colorize (image_path , "magenta" ))
134193 self ._run (["cryptsetup" , "luksClose" , "test_image" ])
0 commit comments