Run Synaptic from the Applications menu (Closes: #5550).
[tails-test.git] / features / step_definitions / common_steps.rb
blobc6d66a402f71d384acab24fc2f0bcc5b073a1da3
1 require 'fileutils'
3 def post_vm_start_hook
4   # Sometimes the first click is lost (presumably it's used to give
5   # focus to virt-viewer or similar) so we do that now rather than
6   # having an important click lost. The point we click should be
7   # somewhere where no clickable elements generally reside.
8   @screen.click_point(@screen.w, @screen.h/2)
9 end
11 def activate_filesystem_shares
12   # XXX-9p: First of all, filesystem shares cannot be mounted while we
13   # do a snapshot save+restore, so unmounting+remounting them seems
14   # like a good idea. However, the 9p modules get into a broken state
15   # during the save+restore, so we also would like to unload+reload
16   # them, but loading of 9pnet_virtio fails after a restore with
17   # "probe of virtio2 failed with error -2" (in dmesg) which makes the
18   # shares unavailable. Hence we leave this code commented for now.
19   #for mod in ["9pnet_virtio", "9p"] do
20   #  @vm.execute("modprobe #{mod}")
21   #end
23   @vm.list_shares.each do |share|
24     @vm.execute("mkdir -p #{share}")
25     @vm.execute("mount -t 9p -o trans=virtio #{share} #{share}")
26   end
27 end
29 def deactivate_filesystem_shares
30   @vm.list_shares.each do |share|
31     @vm.execute("umount #{share}")
32   end
34   # XXX-9p: See XXX-9p above
35   #for mod in ["9p", "9pnet_virtio"] do
36   #  @vm.execute("modprobe -r #{mod}")
37   #end
38 end
40 def restore_background
41   @vm.restore_snapshot($background_snapshot)
42   @vm.wait_until_remote_shell_is_up
43   post_vm_start_hook
45   # XXX-9p: See XXX-9p above
46   #activate_filesystem_shares
48   # The guest's Tor's circuits' states are likely to get out of sync
49   # with the other relays, so we ensure that we have fresh circuits.
50   # Time jumps and incorrect clocks also confuses Tor in many ways.
51   if @vm.has_network?
52     if @vm.execute("service tor status").success?
53       @vm.execute("service tor stop")
54       @vm.execute("killall vidalia")
55       @vm.host_to_guest_time_sync
56       @vm.execute("service tor start")
57       wait_until_tor_is_working
58       @vm.spawn("/usr/local/sbin/restart-vidalia")
59     end
60   end
61 end
63 def run_dialog_picture
64   case @theme
65   when "windows"
66     return 'WindowsRunDialog.png'
67   else
68     return 'GnomeRunDialog.png'
69   end
70 end
72 Given /^a computer$/ do
73   @vm.destroy if @vm
74   @vm = VM.new($vm_xml_path, $x_display)
75 end
77 Given /^the computer has (\d+) ([[:alpha:]]+) of RAM$/ do |size, unit|
78   next if @skip_steps_while_restoring_background
79   @vm.set_ram_size(size, unit)
80 end
82 Given /^the computer is set to boot from the Tails DVD$/ do
83   next if @skip_steps_while_restoring_background
84   @vm.set_cdrom_boot($tails_iso)
85 end
87 Given /^the computer is set to boot from (.+?) drive "(.+?)"$/ do |type, name|
88   next if @skip_steps_while_restoring_background
89   @vm.set_disk_boot(name, type.downcase)
90 end
92 Given /^I plug ([[:alpha:]]+) drive "([^"]+)"$/ do |bus, name|
93   next if @skip_steps_while_restoring_background
94   @vm.plug_drive(name, bus.downcase)
95   if @vm.is_running?
96     step "drive \"#{name}\" is detected by Tails"
97   end
98 end
100 Then /^drive "([^"]+)" is detected by Tails$/ do |name|
101   next if @skip_steps_while_restoring_background
102   if @vm.is_running?
103     try_for(10, :msg => "Drive '#{name}' is not detected by Tails") {
104       @vm.disk_detected?(name)
105     }
106   else
107     STDERR.puts "Cannot tell if drive '#{name}' is detected by Tails: " +
108                 "Tails is not running"
109   end
112 Given /^the network is plugged$/ do
113   next if @skip_steps_while_restoring_background
114   @vm.plug_network
117 Given /^the network is unplugged$/ do
118   next if @skip_steps_while_restoring_background
119   @vm.unplug_network
122 Given /^I capture all network traffic$/ do
123   # Note: We don't want skip this particular stpe if
124   # @skip_steps_while_restoring_background is set since it starts
125   # something external to the VM state.
126   @sniffer = Sniffer.new("TestSniffer", @vm.net.bridge_name)
127   @sniffer.capture
130 Given /^I set Tails to boot with options "([^"]*)"$/ do |options|
131   next if @skip_steps_while_restoring_background
132   @boot_options = options
135 When /^I start the computer$/ do
136   next if @skip_steps_while_restoring_background
137   assert(!@vm.is_running?,
138          "Trying to start a VM that is already running")
139   @vm.start
140   post_vm_start_hook
143 When /^I power off the computer$/ do
144   next if @skip_steps_while_restoring_background
145   assert(@vm.is_running?,
146          "Trying to power off an already powered off VM")
147   @vm.power_off
150 When /^I cold reboot the computer$/ do
151   next if @skip_steps_while_restoring_background
152   step "I power off the computer"
153   step "I start the computer"
156 When /^I destroy the computer$/ do
157   next if @skip_steps_while_restoring_background
158   @vm.destroy
161 Given /^the computer boots Tails$/ do
162   next if @skip_steps_while_restoring_background
163   @screen.wait('TailsBootSplash.png', 30)
164   @screen.wait('TailsBootSplashTabMsg.png', 10)
165   @screen.type(Sikuli::Key.TAB)
166   @screen.waitVanish('TailsBootSplashTabMsg.png', 1)
167   @screen.type(" autotest_never_use_this_option #{@boot_options}" +
168                Sikuli::Key.ENTER)
169   @screen.wait('TailsGreeter.png', 30*60)
170   @vm.wait_until_remote_shell_is_up
171   activate_filesystem_shares
174 Given /^I log in to a new session$/ do
175   next if @skip_steps_while_restoring_background
176   @screen.wait_and_click('TailsGreeterLoginButton.png', 10)
179 Given /^I enable more Tails Greeter options$/ do
180   next if @skip_steps_while_restoring_background
181   match = @screen.find('TailsGreeterMoreOptions.png')
182   @screen.click(match.getCenter.offset(match.w/2, match.h*2))
183   @screen.wait_and_click('TailsGreeterForward.png', 10)
184   @screen.wait('TailsGreeterLoginButton.png', 20)
187 Given /^I set sudo password "([^"]*)"$/ do |password|
188   @sudo_password = password
189   next if @skip_steps_while_restoring_background
190   @screen.wait("TailsGreeterAdminPassword.png", 20)
191   @screen.type(@sudo_password)
192   @screen.type(Sikuli::Key.TAB)
193   @screen.type(@sudo_password)
196 Given /^Tails Greeter has dealt with the sudo password$/ do
197   next if @skip_steps_while_restoring_background
198   f1 = "/etc/sudoers.d/tails-greeter"
199   f2 = "#{f1}-no-password-lecture"
200   try_for(20) {
201     @vm.execute("test -e '#{f1}' -o -e '#{f2}'").success?
202   }
205 Given /^GNOME has started$/ do
206   next if @skip_steps_while_restoring_background
207   case @theme
208   when "windows"
209     desktop_started_picture = 'WindowsStartButton.png'
210   else
211     desktop_started_picture = 'GnomeApplicationsMenu.png'
212   end
213   @screen.wait(desktop_started_picture, 180)
216 Then /^Tails seems to have booted normally$/ do
217   next if @skip_steps_while_restoring_background
218   step "GNOME has started"
221 Given /^Tor is ready$/ do
222   next if @skip_steps_while_restoring_background
223   @screen.wait("GnomeTorIsReady.png", 300)
224   @screen.waitVanish("GnomeTorIsReady.png", 15)
226   # Having seen the "Tor is ready" notification implies that Tor has
227   # built a circuit, but let's check it directly to be on the safe side.
228   step "Tor has built a circuit"
230   step "the time has synced"
233 Given /^Tor has built a circuit$/ do
234   next if @skip_steps_while_restoring_background
235   wait_until_tor_is_working
238 Given /^the time has synced$/ do
239   next if @skip_steps_while_restoring_background
240   ["/var/run/tordate/done", "/var/run/htpdate/success"].each do |file|
241     try_for(300) { @vm.execute("test -e #{file}").success? }
242   end
245 Given /^available upgrades have been checked$/ do
246   next if @skip_steps_while_restoring_background
247   try_for(300) {
248     @vm.execute("test -e '/var/run/tails-upgrader/checked_upgrades'").success?
249   }
252 Given /^Iceweasel has started and is not loading a web page$/ do
253   next if @skip_steps_while_restoring_background
254   case @theme
255   when "windows"
256     iceweasel_picture = "WindowsIceweaselWindow.png"
257   else
258     iceweasel_picture = "IceweaselWindow.png"
259   end
261   # Stop iceweasel to load its home page. We do this to prevent Tor
262   # from getting confused in case we save and restore a snapshot in
263   # the middle of loading a page.
264   @screen.wait_and_click(iceweasel_picture, 120)
265   @screen.type("l", Sikuli::KeyModifier.CTRL)
266   @screen.type("about:blank" + Sikuli::Key.ENTER)
269 Given /^all notifications have disappeared$/ do
270   next if @skip_steps_while_restoring_background
271   case @theme
272   when "windows"
273     notification_picture = "WindowsNotificationX.png"
274   else
275     notification_picture = "GnomeNotificationX.png"
276   end
277   @screen.waitVanish(notification_picture, 60)
280 Given /^I save the state so the background can be restored next scenario$/ do
281   if @skip_steps_while_restoring_background
282     assert(File.size?($background_snapshot),
283            "We have been skipping steps but there is no snapshot to restore")
284   else
285     # To be sure we run the feature from scratch we remove any
286     # leftover snapshot that wasn't removed.
287     if File.exist?($background_snapshot)
288       File.delete($background_snapshot)
289     end
290     # Workaround: when libvirt takes ownership of the snapshot it may
291     # become unwritable for the user running this script so it cannot
292     # be removed during clean up.
293     FileUtils.touch($background_snapshot)
294     FileUtils.chmod(0666, $background_snapshot)
296     # Snapshots cannot be saved while filesystem shares are mounted
297     # XXX-9p: See XXX-9p above.
298     #deactivate_filesystem_shares
300     @vm.save_snapshot($background_snapshot)
301   end
302   restore_background
303   # Now we stop skipping steps from the snapshot restore.
304   @skip_steps_while_restoring_background = false
307 Then /^I see "([^"]*)" after at most (\d+) seconds$/ do |image, time|
308   next if @skip_steps_while_restoring_background
309   @screen.wait(image, time.to_i)
312 Then /^all Internet traffic has only flowed through Tor$/ do
313   next if @skip_steps_while_restoring_background
314   leaks = FirewallLeakCheck.new(@sniffer.pcap_file, get_tor_relays)
315   if !leaks.empty?
316     if !leaks.ipv4_tcp_leaks.empty?
317       puts "The following IPv4 TCP non-Tor Internet hosts were contacted:"
318       puts leaks.ipv4_tcp_leaks.join("\n")
319       puts
320     end
321     if !leaks.ipv4_nontcp_leaks.empty?
322       puts "The following IPv4 non-TCP Internet hosts were contacted:"
323       puts leaks.ipv4_nontcp_leaks.join("\n")
324       puts
325     end
326     if !leaks.ipv6_leaks.empty?
327       puts "The following IPv6 Internet hosts were contacted:"
328       puts leaks.ipv6_leaks.join("\n")
329       puts
330     end
331     if !leaks.nonip_leaks.empty?
332       puts "Some non-IP packets were sent\n"
333     end
334     save_pcap_file
335     raise "There were network leaks!"
336   end
339 When /^I open the GNOME run dialog$/ do
340   next if @skip_steps_while_restoring_background
341   @screen.type(Sikuli::Key.F2, Sikuli::KeyModifier.ALT)
342   @screen.wait(run_dialog_picture, 10)
345 When /^I run "([^"]*)"$/ do |program|
346   next if @skip_steps_while_restoring_background
347   step "I open the GNOME run dialog"
348   @screen.type(program)
349   sleep 0.5
350   @screen.type(Sikuli::Key.ENTER)
353 Given /^I enter the sudo password in the gksu prompt$/ do
354   next if @skip_steps_while_restoring_background
355   @screen.wait('GksuAuthPrompt.png', 60)
356   sleep 1 # wait for weird fade-in to unblock the "Ok" button
357   @screen.type(@sudo_password)
358   @screen.type(Sikuli::Key.ENTER)
359   @screen.waitVanish('GksuAuthPrompt.png', 10)
362 Given /^I enter the sudo password in the pkexec prompt$/ do
363   next if @skip_steps_while_restoring_background
364   step "I enter the \"#{@sudo_password}\" password in the pkexec prompt"
367 def deal_with_polkit_prompt (image, password)
368   @screen.wait(image, 60)
369   sleep 1 # wait for weird fade-in to unblock the "Ok" button
370   @screen.type(password)
371   @screen.type(Sikuli::Key.ENTER)
372   @screen.waitVanish(image, 10)
375 Given /^I enter the "([^"]*)" password in the pkexec prompt$/ do |password|
376   next if @skip_steps_while_restoring_background
377   deal_with_polkit_prompt('PolicyKitAuthPrompt.png', password)
380 Given /^process "([^"]+)" is running$/ do |process|
381   next if @skip_steps_while_restoring_background
382   assert(@vm.has_process?(process),
383          "Process '#{process}' is not running")
386 Given /^process "([^"]+)" is running within (\d+) seconds$/ do |process, time|
387   next if @skip_steps_while_restoring_background
388   try_for(time.to_i, :msg => "Process '#{process}' is not running after " +
389                              "waiting for #{time} seconds") do
390     @vm.has_process?(process)
391   end
394 Given /^process "([^"]+)" is not running$/ do |process|
395   next if @skip_steps_while_restoring_background
396   assert(!@vm.has_process?(process),
397          "Process '#{process}' is running")
400 Given /^I kill the process "([^"]+)"$/ do |process|
401   next if @skip_steps_while_restoring_background
402   @vm.execute("killall #{process}")
403   try_for(10, :msg => "Process '#{process}' could not be killed") {
404     !@vm.has_process?(process)
405   }
408 Then /^Tails eventually shuts down$/ do
409   next if @skip_steps_while_restoring_background
410   nr_gibs_of_ram = (detected_ram_in_MiB.to_f/(2**10)).ceil
411   timeout = nr_gibs_of_ram*5*60
412   try_for(timeout, :msg => "VM is still running after #{timeout} seconds") do
413     ! @vm.is_running?
414   end
417 Then /^Tails eventually restarts$/ do
418   next if @skip_steps_while_restoring_background
419   nr_gibs_of_ram = (detected_ram_in_MiB.to_f/(2**10)).ceil
420   @screen.wait('TailsBootSplashPostReset.png', nr_gibs_of_ram*5*60)
423 Given /^I shutdown Tails and wait for the computer to power off$/ do
424   next if @skip_steps_while_restoring_background
425   @vm.execute("poweroff")
426   step 'Tails eventually shuts down'
429 When /^I request a shutdown using the emergency shutdown applet$/ do
430   next if @skip_steps_while_restoring_background
431   @screen.hide_cursor
432   @screen.wait_and_click('TailsEmergencyShutdownButton.png', 10)
433   @screen.hide_cursor
434   @screen.wait_and_click('TailsEmergencyShutdownHalt.png', 10)
437 When /^I request a reboot using the emergency shutdown applet$/ do
438   next if @skip_steps_while_restoring_background
439   @screen.hide_cursor
440   @screen.wait_and_click('TailsEmergencyShutdownButton.png', 10)
441   @screen.hide_cursor
442   @screen.wait_and_click('TailsEmergencyShutdownReboot.png', 10)
445 Given /^package "([^"]+)" is installed$/ do |package|
446   next if @skip_steps_while_restoring_background
447   assert(@vm.execute("dpkg -s '#{package}' 2>/dev/null | grep -qs '^Status:.*installed$'").success?,
448          "Package '#{package}' is not installed")