@@ -52,12 +52,31 @@ def test_no_hypervisor(self):
5252 with self .assertRaises (RuntimeError ):
5353 Bootloader .readGrub2 ("tests/data/grub-no-hypervisor.cfg" )
5454
55+ def test_set_grub_variable (self ):
56+ tmpdir = mkdtemp (prefix = "testbl" )
57+ env = os .path .join (tmpdir , 'grubenv' )
58+ bl = Bootloader ("" , "" , env_block = env )
59+
60+ self .assertFalse (os .path .isfile (env ))
61+
62+ self .assertTrue (bl .setGrubVariable ("waffles=true" ))
63+
64+ self .assertTrue (os .path .isfile (env ))
65+ self .assertGreater (os .path .getsize (env ), 0 )
66+
67+ def test_set_grub_variable_throws_without_envfile (self ):
68+ bl = Bootloader ("" , "" , env_block = None )
69+
70+ with self .assertRaises (AssertionError ):
71+ bl .setGrubVariable ("waffles=true" )
72+
5573
5674class TestMenuEntry (unittest .TestCase ):
5775 def setUp (self ):
5876 self .tmpdir = mkdtemp (prefix = "testbl" )
5977 self .fn = os .path .join (self .tmpdir , 'grub.cfg' )
6078 self .bl = Bootloader ('grub2' , self .fn )
79+ self .env = os .path .join (self .tmpdir , 'grubenv' )
6180
6281 def tearDown (self ):
6382 shutil .rmtree (self .tmpdir )
@@ -137,6 +156,101 @@ def test_new_linux(self):
137156}
138157''' )
139158
159+ def test_arbitrary_contents (self ):
160+ """ Test that arbitrary data can be injected into the MenuEntry.contents field. """
161+ e = MenuEntry (hypervisor = 'xen.efi' , hypervisor_args = 'a' ,
162+ kernel = 'vmlinuz' , kernel_args = 'b' ,
163+ initrd = 'initrd.img' ,
164+ title = 'menu_name' )
165+
166+ e .contents .append ("\t extra data line 1" )
167+ e .contents .append ("\t extra data line 2" )
168+
169+ e .entry_format = Grub2Format .XEN_BOOT
170+
171+ self .bl .append ('menu_name' , e )
172+ self .bl .commit ()
173+
174+ with open_with_codec_handling (self .fn , 'r' ) as f :
175+ content = f .read ()
176+
177+ self .assertEqual (content ,
178+ '''menuentry 'menu_name' {
179+ extra data line 1
180+ extra data line 2
181+ xen_hypervisor xen.efi a
182+ xen_module vmlinuz b
183+ xen_module initrd.img
184+ }
185+ ''' )
186+
187+ def test_contents_not_clobbered_by_setnextboot (self ):
188+
189+ self .assertIsNone (self .bl .env_block )
190+ self .bl .env_block = self .env
191+
192+ e = MenuEntry (hypervisor = 'xen.efi' , hypervisor_args = 'a' ,
193+ kernel = 'vmlinuz' , kernel_args = 'b' ,
194+ initrd = 'initrd.img' ,
195+ title = 'menu_title' )
196+
197+ e .contents .append ("\t extra data line 1" )
198+ e .contents .append ("\t extra data line 2" )
199+
200+ e .entry_format = Grub2Format .XEN_BOOT
201+
202+ self .bl .append ('menu_title' , e )
203+ self .assertTrue (self .bl .setNextBoot ('menu_title' ))
204+ self .bl .commit ()
205+
206+
207+ with open_with_codec_handling (self .fn , 'r' ) as f :
208+ content = f .read ()
209+
210+ self .assertEqual (content ,
211+ '''menuentry 'menu_title' {
212+ unset override_entry
213+ save_env override_entry
214+ extra data line 1
215+ extra data line 2
216+ xen_hypervisor xen.efi a
217+ xen_module vmlinuz b
218+ xen_module initrd.img
219+ }
220+ ''' )
221+
222+ def test_setnextboot_is_indempotent (self ):
223+ self .bl .env_block = self .env
224+
225+ e = MenuEntry (hypervisor = 'xen.efi' , hypervisor_args = 'a' ,
226+ kernel = 'vmlinuz' , kernel_args = 'b' ,
227+ initrd = 'initrd.img' ,
228+ title = 'menu_title' )
229+
230+ e .entry_format = Grub2Format .XEN_BOOT
231+
232+ self .bl .append ('menu_title' , e )
233+
234+ # Calling twice should have thte same effect as calling once
235+ self .assertTrue (self .bl .setNextBoot ('menu_title' ))
236+ self .assertTrue (self .bl .setNextBoot ('menu_title' ))
237+
238+ self .bl .commit ()
239+
240+
241+ with open_with_codec_handling (self .fn , 'r' ) as f :
242+ content = f .read ()
243+
244+ self .assertEqual (content ,
245+ '''menuentry 'menu_title' {
246+ unset override_entry
247+ save_env override_entry
248+ xen_hypervisor xen.efi a
249+ xen_module vmlinuz b
250+ xen_module initrd.img
251+ }
252+ ''' )
253+
140254
141255class TestLinuxBootloader (unittest .TestCase ):
142256 def setUp (self ):
0 commit comments