summaryrefslogtreecommitdiffstats
path: root/features
diff options
context:
space:
mode:
authorintrigeri <intrigeri@boum.org>2016-11-11 09:41:57 +0000
committerintrigeri <intrigeri@boum.org>2016-11-11 09:41:57 +0000
commitf6077cb746048a16dce0d22fd65163604d65f97f (patch)
treeffd6196c97ce2ec660b8dba612521d14655d2bd6 /features
parent422da348a66d0cf447988c1c7d8234fa520f7001 (diff)
parent176215ec701a30373e837b48fac1c8abbabb17d5 (diff)
Merge remote-tracking branch 'origin/stable' into test/11616-emergency-shutdown-applet-is-fragile
Diffstat (limited to 'features')
-rw-r--r--features/apt.feature3
-rw-r--r--features/build.feature40
-rw-r--r--features/domains/cdrom.xml5
-rw-r--r--features/domains/default.xml17
-rw-r--r--features/electrum.feature2
-rw-r--r--features/emergency_shutdown.feature2
-rw-r--r--features/erase_memory.feature8
-rw-r--r--features/evince.feature4
-rw-r--r--features/icedove.feature38
-rw-r--r--features/images/GpgAppletIconEncrypted.pngbin873 -> 875 bytes
-rw-r--r--features/images/GpgAppletIconNormal.pngbin585 -> 521 bytes
-rw-r--r--features/images/GpgAppletIconSigned.pngbin948 -> 1015 bytes
-rw-r--r--features/images/IcedoveEnigmailAdvancedParameters.pngbin815 -> 0 bytes
-rw-r--r--features/images/IcedoveEnigmailAdvancedTab.pngbin1198 -> 0 bytes
-rw-r--r--features/images/IcedoveEnigmailExpertSettingsButton.pngbin3077 -> 0 bytes
-rw-r--r--features/images/IcedoveEnigmailKeyserver.pngbin2002 -> 0 bytes
-rw-r--r--features/images/IcedoveEnigmailKeyserverTab.pngbin1128 -> 0 bytes
-rw-r--r--features/images/IcedoveEnigmailPreferences.pngbin1151 -> 0 bytes
-rw-r--r--features/images/IcedoveEnigmailPreferencesWindow.pngbin2426 -> 0 bytes
-rw-r--r--features/images/IcedoveEnigmailProxy.pngbin2267 -> 0 bytes
-rw-r--r--features/images/IcedoveMailAccountSetup.pngbin2708 -> 0 bytes
-rw-r--r--features/images/IcedoveMainWindow.pngbin1905 -> 0 bytes
-rw-r--r--features/images/IcedoveMenuViewToolbars.pngbin998 -> 0 bytes
-rw-r--r--features/images/IcedoveMenuViewToolbarsStatusBar.pngbin1084 -> 0 bytes
-rw-r--r--features/images/IcedoveProtocolIMAP.pngbin1277 -> 0 bytes
-rw-r--r--features/images/IcedoveToolsMenuAddOns.pngbin939 -> 0 bytes
-rw-r--r--features/images/IcedoveTorbirdyEnabled.pngbin4037 -> 0 bytes
-rw-r--r--features/images/IcedoveTorbirdyPreferences.pngbin2177 -> 0 bytes
-rw-r--r--features/images/MozillaAddonsManagerExtensions.pngbin5192 -> 2045 bytes
-rw-r--r--features/images/MozillaExtensionsTorbirdy.pngbin4007 -> 2077 bytes
-rw-r--r--features/images/SampleLocalMp4VideoFrame.pngbin14887 -> 50014 bytes
-rw-r--r--features/images/SynapticFailure.pngbin0 -> 2449 bytes
-rw-r--r--features/images/SynapticLoaded.pngbin0 -> 1833 bytes
-rw-r--r--features/images/SynapticReloadButton.pngbin1957 -> 0 bytes
-rw-r--r--features/images/SynapticSearchWindow.pngbin715 -> 671 bytes
-rw-r--r--features/images/TailsBootMenuKernelCmdline.pngbin0 -> 1629 bytes
-rw-r--r--features/images/TailsBootMenuKernelCmdlineUEFI.pngbin0 -> 2575 bytes
-rw-r--r--features/images/TailsBootSplash.pngbin5964 -> 0 bytes
-rw-r--r--features/images/TailsBootSplashUEFI.pngbin9188 -> 0 bytes
-rw-r--r--features/images/TailsBooting.pngbin0 -> 164 bytes
-rw-r--r--features/images/TailsUpgraderDone.pngbin0 -> 3215 bytes
-rw-r--r--features/images/TailsUpgraderFailure.pngbin0 -> 2196 bytes
-rw-r--r--features/images/TailsUpgraderUpgradeNowButton.pngbin0 -> 2232 bytes
-rw-r--r--features/images/TailsUpgraderUpgradeTo1.1~test.pngbin0 -> 2512 bytes
-rw-r--r--features/images/UEFIFirmwareSetup.pngbin0 -> 172 bytes
-rw-r--r--features/localization.feature2
-rw-r--r--features/mat.feature3
-rw-r--r--features/persistence.feature3
-rw-r--r--features/pidgin.feature1
-rw-r--r--features/step_definitions/apt.rb52
-rw-r--r--features/step_definitions/checks.rb5
-rw-r--r--features/step_definitions/common_steps.rb120
-rw-r--r--features/step_definitions/erase_memory.rb12
-rw-r--r--features/step_definitions/icedove.rb246
-rw-r--r--features/step_definitions/tor.rb18
-rw-r--r--features/step_definitions/torified_gnupg.rb2
-rw-r--r--features/step_definitions/totem.rb2
-rw-r--r--features/step_definitions/usb.rb132
-rw-r--r--features/support/config.rb14
-rw-r--r--features/support/extra_hooks.rb43
-rw-r--r--features/support/helpers/dogtail.rb67
-rw-r--r--features/support/helpers/exec_helper.rb30
-rw-r--r--features/support/helpers/storage_helper.rb3
-rw-r--r--features/support/helpers/vm_helper.rb84
-rw-r--r--features/support/hooks.rb2
-rw-r--r--features/tor_enforcement.feature4
-rw-r--r--features/torified_browsing.feature15
-rw-r--r--features/totem.feature8
-rw-r--r--features/untrusted_partitions.feature14
-rw-r--r--features/usb_install.feature11
-rw-r--r--features/usb_upgrade.feature26
-rw-r--r--features/virtualization.feature6
72 files changed, 759 insertions, 285 deletions
diff --git a/features/apt.feature b/features/apt.feature
index 02a122c..7a1f0ec 100644
--- a/features/apt.feature
+++ b/features/apt.feature
@@ -16,8 +16,7 @@ Feature: Installing packages through APT
When I update APT using apt
Then I should be able to install a package using apt
- #10441: Synaptic test is fragile
- @check_tor_leaks @fragile
+ @check_tor_leaks
Scenario: Install packages using Synaptic
When I start Synaptic
And I update APT using Synaptic
diff --git a/features/build.feature b/features/build.feature
index 4241197..49b2d24 100644
--- a/features/build.feature
+++ b/features/build.feature
@@ -31,10 +31,10 @@ Feature: custom APT sources to build branches
And Tails 1.0 has not been released yet
And no frozen APT snapshot is encoded in config/APT_snapshots.d
When I successfully run "apt-snapshots-serials prepare-build"
- And I successfully run "apt-mirror debian"
- Then I should see the 0.10 tagged snapshot
- When I successfully run "apt-mirror torproject"
- Then I should see the 0.10 tagged snapshot
+ And I run "apt-mirror debian"
+ Then it should fail
+ When I run "apt-mirror torproject"
+ Then it should fail
When I successfully run "apt-mirror debian-security"
Then I should see a time-based snapshot
@@ -77,10 +77,10 @@ Feature: custom APT sources to build branches
And no frozen APT snapshot is encoded in config/APT_snapshots.d
And I checkout the 0.10 tag
When I successfully run "apt-snapshots-serials prepare-build"
- And I successfully run "apt-mirror debian"
- Then I should see the 0.10 tagged snapshot
- When I successfully run "apt-mirror torproject"
- Then I should see the 0.10 tagged snapshot
+ And I run "apt-mirror debian"
+ Then it should fail
+ When I run "apt-mirror torproject"
+ Then it should fail
When I successfully run "apt-mirror debian-security"
Then I should see the 0.10 tagged snapshot
@@ -127,10 +127,10 @@ Feature: custom APT sources to build branches
And I am working on the bugfix/disable_gdomap branch based on stable
And no frozen APT snapshot is encoded in config/APT_snapshots.d
When I successfully run "apt-snapshots-serials prepare-build"
- And I successfully run "apt-mirror debian"
- Then I should see the 0.10 tagged snapshot
- When I successfully run "apt-mirror torproject"
- Then I should see the 0.10 tagged snapshot
+ And I run "apt-mirror debian"
+ Then it should fail
+ When I run "apt-mirror torproject"
+ Then it should fail
When I successfully run "apt-mirror debian-security"
Then I should see a time-based snapshot
@@ -178,10 +178,10 @@ Feature: custom APT sources to build branches
And Tails 1.0 has not been released yet
And no frozen APT snapshot is encoded in config/APT_snapshots.d
When I successfully run "apt-snapshots-serials prepare-build"
- And I successfully run "apt-mirror debian"
- Then I should see a time-based snapshot
- When I successfully run "apt-mirror torproject"
- Then I should see a time-based snapshot
+ And I run "apt-mirror debian"
+ Then it should fail
+ When I run "apt-mirror torproject"
+ Then it should fail
When I successfully run "apt-mirror debian-security"
Then I should see a time-based snapshot
@@ -273,10 +273,10 @@ Feature: custom APT sources to build branches
And I am working on the bugfix/disable_gdomap branch based on testing
And no frozen APT snapshot is encoded in config/APT_snapshots.d
When I successfully run "apt-snapshots-serials prepare-build"
- And I successfully run "apt-mirror debian"
- Then I should see a time-based snapshot
- When I successfully run "apt-mirror torproject"
- Then I should see a time-based snapshot
+ And I run "apt-mirror debian"
+ Then it should fail
+ When I run "apt-mirror torproject"
+ Then it should fail
When I successfully run "apt-mirror debian-security"
Then I should see a time-based snapshot
diff --git a/features/domains/cdrom.xml b/features/domains/cdrom.xml
new file mode 100644
index 0000000..8bc3be7
--- /dev/null
+++ b/features/domains/cdrom.xml
@@ -0,0 +1,5 @@
+<disk type='file' device='cdrom'>
+ <driver name='qemu' type='raw'/>
+ <target dev='hdc' bus='sata'/>
+ <readonly/>
+</disk>
diff --git a/features/domains/default.xml b/features/domains/default.xml
index 924bb85..431dcde 100644
--- a/features/domains/default.xml
+++ b/features/domains/default.xml
@@ -1,9 +1,9 @@
<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
<memory unit='KiB'>2097152</memory>
<currentMemory unit='KiB'>2097152</currentMemory>
- <vcpu>1</vcpu>
+ <vcpu>2</vcpu>
<os>
- <type arch='x86_64' machine='pc-0.15'>hvm</type>
+ <type arch='x86_64' machine='pc-i440fx-2.5'>hvm</type>
<boot dev='cdrom'/>
</os>
<features>
@@ -18,17 +18,8 @@
<on_crash>restart</on_crash>
<devices>
<emulator>/usr/bin/qemu-system-x86_64</emulator>
- <disk type='file' device='cdrom'>
- <driver name='qemu' type='raw'/>
- <source file=''/>
- <target dev='hdc' bus='ide'/>
- <readonly/>
- </disk>
- <controller type='usb' index='0' model='ich9-ehci1'/>
- <controller type='usb' index='0' model='ich9-uhci1'>
- <master startport='0'/>
- </controller>
- <controller type='ide' index='0'/>
+ <controller type='usb' index='0' model='nec-xhci'/>
+ <controller type='sata' index='0'/>
<controller type='virtio-serial' index='0'/>
<interface type='network'>
<mac address='52:54:00:ac:dd:ee'/>
diff --git a/features/electrum.feature b/features/electrum.feature
index 9807fec..9beb2e8 100644
--- a/features/electrum.feature
+++ b/features/electrum.feature
@@ -10,7 +10,7 @@ Feature: Electrum Bitcoin client
But persistence for "electrum" is not enabled
Then I see a warning that Electrum is not persistent
- #10720: Tails Installer freezes on Jenkins
+ #11697
@fragile
Scenario: Using a persistent Electrum configuration
Given I have started Tails without network from a USB drive with a persistent partition enabled and logged in
diff --git a/features/emergency_shutdown.feature b/features/emergency_shutdown.feature
index 0f4c1cb..3fac61e 100644
--- a/features/emergency_shutdown.feature
+++ b/features/emergency_shutdown.feature
@@ -16,8 +16,6 @@ Feature: Emergency shutdown
When I eject the boot medium
Then Tails eventually shuts down
- #10720
- @fragile
Scenario: Tails shuts down on USB boot medium removal
Given I have started Tails without network from a USB drive without a persistent partition and logged in
When I eject the boot medium
diff --git a/features/erase_memory.feature b/features/erase_memory.feature
index d3425fd..28779f6 100644
--- a/features/erase_memory.feature
+++ b/features/erase_memory.feature
@@ -20,8 +20,6 @@ Feature: System memory erasure on shutdown
And I stop the boot at the bootloader menu
Then I find many patterns in the guest's memory
- #10776
- @fragile
Scenario: Memory erasure on a modern computer
Given a computer
And the computer is a modern 64-bit system
@@ -44,7 +42,7 @@ Feature: System memory erasure on shutdown
And I set Tails to boot with options "debug=wipemem"
And I start Tails from DVD with network unplugged and I login
Then the non-PAE kernel is running
- And at least 3500 MiB of RAM was detected
+ And at least 3 GiB of RAM was detected
And process "memlockd" is running
And process "udev-watchdog" is running
And udev-watchdog is monitoring the correct device
@@ -53,8 +51,6 @@ Feature: System memory erasure on shutdown
And I stop the boot at the bootloader menu
Then I find many patterns in the guest's memory
- #10776
- @fragile
Scenario: Memory erasure on an old computer
Given a computer
And the computer is an old pentium without the PAE extension
@@ -62,7 +58,7 @@ Feature: System memory erasure on shutdown
And I set Tails to boot with options "debug=wipemem"
And I start Tails from DVD with network unplugged and I login
And the non-PAE kernel is running
- And at least 3500 MiB of RAM was detected
+ And at least 3 GiB of RAM was detected
And process "memlockd" is running
And process "udev-watchdog" is running
And udev-watchdog is monitoring the correct device
diff --git a/features/evince.feature b/features/evince.feature
index 581e53e..c9501f9 100644
--- a/features/evince.feature
+++ b/features/evince.feature
@@ -44,7 +44,7 @@ Feature: Using Evince
# as /lib/live/mount/overlay.
And AppArmor has denied "/usr/bin/evince" from opening "/lib/live/mount/overlay/home/amnesia/.gnupg/default-testpage.pdf"
- #10720: Tails Installer freezes on Jenkins
+ #10994
@fragile
Scenario: I can view and print a PDF file stored in persistent /home/amnesia/Persistent
Given I have started Tails without network from a USB drive with a persistent partition enabled and logged in
@@ -54,8 +54,6 @@ Feature: Using Evince
Then I see "CupsTestPage.png" after at most 40 seconds
And I can print the current document to "/home/amnesia/Persistent/output.pdf"
- #10720: Tails Installer freezes on Jenkins
- @fragile
Scenario: I cannot view a PDF file stored in persistent /home/amnesia/.gnupg
Given I have started Tails without network from a USB drive with a persistent partition enabled and logged in
And I copy "/usr/share/cups/data/default-testpage.pdf" to "/home/amnesia/.gnupg" as user "amnesia"
diff --git a/features/icedove.feature b/features/icedove.feature
index 8693a44..ffc8c39 100644
--- a/features/icedove.feature
+++ b/features/icedove.feature
@@ -1,31 +1,53 @@
#11465
-@product @check_tor_leaks @fragile
+@product @check_tor_leaks
Feature: Icedove email client
As a Tails user
I may want to use an email client
Background:
Given I have started Tails from DVD and logged in and the network is connected
- When I start "Icedove" via the GNOME "Internet" applications menu
- And Icedove has started
And I have not configured an email account
+ When I start Icedove
Then I am prompted to setup an email account
- Scenario: Adblock is not enabled within Icedove
+ Scenario: Only the expected addons are installed
Given I cancel setting up an email account
When I open Icedove's Add-ons Manager
And I click the extensions tab
- Then I see that Adblock is not installed in Icedove
+ Then I see that only the amnesia branding, Enigmail and TorBirdy addons are enabled in Icedove
Scenario: Enigmail is configured to use the correct keyserver
Given I cancel setting up an email account
And I go into Enigmail's preferences
- When I click Enigmail's keyserver tab
+ And I enable Enigmail's expert settings
+ When I click Enigmail's Keyserver tab
Then I see that Enigmail is configured to use the correct keyserver
- When I click Enigmail's advanced tab
+ When I click Enigmail's Advanced tab
Then I see that Enigmail is configured to use the correct SOCKS proxy
Scenario: Torbirdy is configured to use Tor
Given I cancel setting up an email account
- And I open Torbirdy's preferences
Then I see that Torbirdy is configured to use Tor
+
+ Scenario: Icedove's autoconfiguration wizard defaults to IMAP and secure protocols
+ When I enter my email credentials into the autoconfiguration wizard
+ Then the autoconfiguration wizard's choice for the incoming server is secure IMAP
+ Then the autoconfiguration wizard's choice for the outgoing server is secure SMTP
+
+ Scenario: Icedove can send emails, and receive emails over IMAP
+ When I enter my email credentials into the autoconfiguration wizard
+ Then the autoconfiguration wizard's choice for the incoming server is secure IMAP
+ When I accept the autoconfiguration wizard's configuration
+ And I send an email to myself
+ And I fetch my email
+ Then I can find the email I sent to myself in my inbox
+
+ Scenario: Icedove can send emails, and receive emails over POP3
+ When I enter my email credentials into the autoconfiguration wizard
+ Then the autoconfiguration wizard's choice for the incoming server is secure IMAP
+ When I select the autoconfiguration wizard's POP3 choice
+ Then the autoconfiguration wizard's choice for the incoming server is secure POP3
+ When I accept the autoconfiguration wizard's configuration
+ And I send an email to myself
+ And I fetch my email
+ Then I can find the email I sent to myself in my inbox
diff --git a/features/images/GpgAppletIconEncrypted.png b/features/images/GpgAppletIconEncrypted.png
index 940772a..479438e 100644
--- a/features/images/GpgAppletIconEncrypted.png
+++ b/features/images/GpgAppletIconEncrypted.png
Binary files differ
diff --git a/features/images/GpgAppletIconNormal.png b/features/images/GpgAppletIconNormal.png
index 5775c4f..102b903 100644
--- a/features/images/GpgAppletIconNormal.png
+++ b/features/images/GpgAppletIconNormal.png
Binary files differ
diff --git a/features/images/GpgAppletIconSigned.png b/features/images/GpgAppletIconSigned.png
index 44ec2e3..44978e6 100644
--- a/features/images/GpgAppletIconSigned.png
+++ b/features/images/GpgAppletIconSigned.png
Binary files differ
diff --git a/features/images/IcedoveEnigmailAdvancedParameters.png b/features/images/IcedoveEnigmailAdvancedParameters.png
deleted file mode 100644
index 9f7a325..0000000
--- a/features/images/IcedoveEnigmailAdvancedParameters.png
+++ /dev/null
Binary files differ
diff --git a/features/images/IcedoveEnigmailAdvancedTab.png b/features/images/IcedoveEnigmailAdvancedTab.png
deleted file mode 100644
index 808192a..0000000
--- a/features/images/IcedoveEnigmailAdvancedTab.png
+++ /dev/null
Binary files differ
diff --git a/features/images/IcedoveEnigmailExpertSettingsButton.png b/features/images/IcedoveEnigmailExpertSettingsButton.png
deleted file mode 100644
index d66767b..0000000
--- a/features/images/IcedoveEnigmailExpertSettingsButton.png
+++ /dev/null
Binary files differ
diff --git a/features/images/IcedoveEnigmailKeyserver.png b/features/images/IcedoveEnigmailKeyserver.png
deleted file mode 100644
index afe56ad..0000000
--- a/features/images/IcedoveEnigmailKeyserver.png
+++ /dev/null
Binary files differ
diff --git a/features/images/IcedoveEnigmailKeyserverTab.png b/features/images/IcedoveEnigmailKeyserverTab.png
deleted file mode 100644
index b9bdcae..0000000
--- a/features/images/IcedoveEnigmailKeyserverTab.png
+++ /dev/null
Binary files differ
diff --git a/features/images/IcedoveEnigmailPreferences.png b/features/images/IcedoveEnigmailPreferences.png
deleted file mode 100644
index 51153dc..0000000
--- a/features/images/IcedoveEnigmailPreferences.png
+++ /dev/null
Binary files differ
diff --git a/features/images/IcedoveEnigmailPreferencesWindow.png b/features/images/IcedoveEnigmailPreferencesWindow.png
deleted file mode 100644
index c840b04..0000000
--- a/features/images/IcedoveEnigmailPreferencesWindow.png
+++ /dev/null
Binary files differ
diff --git a/features/images/IcedoveEnigmailProxy.png b/features/images/IcedoveEnigmailProxy.png
deleted file mode 100644
index 10c034f..0000000
--- a/features/images/IcedoveEnigmailProxy.png
+++ /dev/null
Binary files differ
diff --git a/features/images/IcedoveMailAccountSetup.png b/features/images/IcedoveMailAccountSetup.png
deleted file mode 100644
index 4f8d1c8..0000000
--- a/features/images/IcedoveMailAccountSetup.png
+++ /dev/null
Binary files differ
diff --git a/features/images/IcedoveMainWindow.png b/features/images/IcedoveMainWindow.png
deleted file mode 100644
index 9ec3dc9..0000000
--- a/features/images/IcedoveMainWindow.png
+++ /dev/null
Binary files differ
diff --git a/features/images/IcedoveMenuViewToolbars.png b/features/images/IcedoveMenuViewToolbars.png
deleted file mode 100644
index 857320a..0000000
--- a/features/images/IcedoveMenuViewToolbars.png
+++ /dev/null
Binary files differ
diff --git a/features/images/IcedoveMenuViewToolbarsStatusBar.png b/features/images/IcedoveMenuViewToolbarsStatusBar.png
deleted file mode 100644
index e6d8313..0000000
--- a/features/images/IcedoveMenuViewToolbarsStatusBar.png
+++ /dev/null
Binary files differ
diff --git a/features/images/IcedoveProtocolIMAP.png b/features/images/IcedoveProtocolIMAP.png
deleted file mode 100644
index 1872487..0000000
--- a/features/images/IcedoveProtocolIMAP.png
+++ /dev/null
Binary files differ
diff --git a/features/images/IcedoveToolsMenuAddOns.png b/features/images/IcedoveToolsMenuAddOns.png
deleted file mode 100644
index 8b38ac2..0000000
--- a/features/images/IcedoveToolsMenuAddOns.png
+++ /dev/null
Binary files differ
diff --git a/features/images/IcedoveTorbirdyEnabled.png b/features/images/IcedoveTorbirdyEnabled.png
deleted file mode 100644
index 938b36b..0000000
--- a/features/images/IcedoveTorbirdyEnabled.png
+++ /dev/null
Binary files differ
diff --git a/features/images/IcedoveTorbirdyPreferences.png b/features/images/IcedoveTorbirdyPreferences.png
deleted file mode 100644
index 06d6d0d..0000000
--- a/features/images/IcedoveTorbirdyPreferences.png
+++ /dev/null
Binary files differ
diff --git a/features/images/MozillaAddonsManagerExtensions.png b/features/images/MozillaAddonsManagerExtensions.png
index 2241c1e..96d6d58 100644
--- a/features/images/MozillaAddonsManagerExtensions.png
+++ b/features/images/MozillaAddonsManagerExtensions.png
Binary files differ
diff --git a/features/images/MozillaExtensionsTorbirdy.png b/features/images/MozillaExtensionsTorbirdy.png
index 7560932..0beca90 100644
--- a/features/images/MozillaExtensionsTorbirdy.png
+++ b/features/images/MozillaExtensionsTorbirdy.png
Binary files differ
diff --git a/features/images/SampleLocalMp4VideoFrame.png b/features/images/SampleLocalMp4VideoFrame.png
index 336c955..df65c3a 100644
--- a/features/images/SampleLocalMp4VideoFrame.png
+++ b/features/images/SampleLocalMp4VideoFrame.png
Binary files differ
diff --git a/features/images/SynapticFailure.png b/features/images/SynapticFailure.png
new file mode 100644
index 0000000..a0a702b
--- /dev/null
+++ b/features/images/SynapticFailure.png
Binary files differ
diff --git a/features/images/SynapticLoaded.png b/features/images/SynapticLoaded.png
new file mode 100644
index 0000000..91b9062
--- /dev/null
+++ b/features/images/SynapticLoaded.png
Binary files differ
diff --git a/features/images/SynapticReloadButton.png b/features/images/SynapticReloadButton.png
deleted file mode 100644
index 1af3f1d..0000000
--- a/features/images/SynapticReloadButton.png
+++ /dev/null
Binary files differ
diff --git a/features/images/SynapticSearchWindow.png b/features/images/SynapticSearchWindow.png
index 98574cf..2077789 100644
--- a/features/images/SynapticSearchWindow.png
+++ b/features/images/SynapticSearchWindow.png
Binary files differ
diff --git a/features/images/TailsBootMenuKernelCmdline.png b/features/images/TailsBootMenuKernelCmdline.png
new file mode 100644
index 0000000..efc5d89
--- /dev/null
+++ b/features/images/TailsBootMenuKernelCmdline.png
Binary files differ
diff --git a/features/images/TailsBootMenuKernelCmdlineUEFI.png b/features/images/TailsBootMenuKernelCmdlineUEFI.png
new file mode 100644
index 0000000..0a00fde
--- /dev/null
+++ b/features/images/TailsBootMenuKernelCmdlineUEFI.png
Binary files differ
diff --git a/features/images/TailsBootSplash.png b/features/images/TailsBootSplash.png
deleted file mode 100644
index 2bed76d..0000000
--- a/features/images/TailsBootSplash.png
+++ /dev/null
Binary files differ
diff --git a/features/images/TailsBootSplashUEFI.png b/features/images/TailsBootSplashUEFI.png
deleted file mode 100644
index 445f6dc..0000000
--- a/features/images/TailsBootSplashUEFI.png
+++ /dev/null
Binary files differ
diff --git a/features/images/TailsBooting.png b/features/images/TailsBooting.png
new file mode 100644
index 0000000..8a7a77b
--- /dev/null
+++ b/features/images/TailsBooting.png
Binary files differ
diff --git a/features/images/TailsUpgraderDone.png b/features/images/TailsUpgraderDone.png
new file mode 100644
index 0000000..4bbb10c
--- /dev/null
+++ b/features/images/TailsUpgraderDone.png
Binary files differ
diff --git a/features/images/TailsUpgraderFailure.png b/features/images/TailsUpgraderFailure.png
new file mode 100644
index 0000000..34cdf9f
--- /dev/null
+++ b/features/images/TailsUpgraderFailure.png
Binary files differ
diff --git a/features/images/TailsUpgraderUpgradeNowButton.png b/features/images/TailsUpgraderUpgradeNowButton.png
new file mode 100644
index 0000000..8cf0cc9
--- /dev/null
+++ b/features/images/TailsUpgraderUpgradeNowButton.png
Binary files differ
diff --git a/features/images/TailsUpgraderUpgradeTo1.1~test.png b/features/images/TailsUpgraderUpgradeTo1.1~test.png
new file mode 100644
index 0000000..2790588
--- /dev/null
+++ b/features/images/TailsUpgraderUpgradeTo1.1~test.png
Binary files differ
diff --git a/features/images/UEFIFirmwareSetup.png b/features/images/UEFIFirmwareSetup.png
new file mode 100644
index 0000000..368857d
--- /dev/null
+++ b/features/images/UEFIFirmwareSetup.png
Binary files differ
diff --git a/features/localization.feature b/features/localization.feature
index 4ec4a05..2f36aa2 100644
--- a/features/localization.feature
+++ b/features/localization.feature
@@ -13,6 +13,8 @@ Feature: Localization
When I double-click the Report an Error launcher on the desktop
Then the support documentation page opens in Tor Browser
+ #11711
+ @fragile
Scenario: The Unsafe Browser can be used in all languages supported in Tails
Given I have started Tails from DVD and logged in and the network is connected
Then the Unsafe Browser works in all supported languages
diff --git a/features/mat.feature b/features/mat.feature
index e492b0f..506c44f 100644
--- a/features/mat.feature
+++ b/features/mat.feature
@@ -1,4 +1,5 @@
-@product
+#11901: mat does not clean PDF files anymore
+@product @fragile
Feature: Metadata Anonymization Toolkit
As a Tails user
I want to be able to remove leaky metadata from documents and media files
diff --git a/features/persistence.feature b/features/persistence.feature
index 507f05e..c7416e4 100644
--- a/features/persistence.feature
+++ b/features/persistence.feature
@@ -1,5 +1,4 @@
-#10720: Tails Installer freezes on Jenkins
-@product @fragile
+@product
Feature: Tails persistence
As a Tails user
I want to use Tails persistence feature
diff --git a/features/pidgin.feature b/features/pidgin.feature
index 2858482..84ec5dd 100644
--- a/features/pidgin.feature
+++ b/features/pidgin.feature
@@ -91,7 +91,6 @@ Feature: Chatting anonymously using Pidgin
And I close Pidgin's certificate manager
Then I cannot add a certificate from the "/live/overlay/home/amnesia/.gnupg" directory to Pidgin
- #10720: Tails Installer freezes on Jenkins
#11584
@check_tor_leaks @fragile
Scenario: Using a persistent Pidgin configuration
diff --git a/features/step_definitions/apt.rb b/features/step_definitions/apt.rb
index f96795a..5163167 100644
--- a/features/step_definitions/apt.rb
+++ b/features/step_definitions/apt.rb
@@ -41,28 +41,52 @@ Then /^I should be able to install a package using apt$/ do
end
When /^I update APT using Synaptic$/ do
- @screen.click('SynapticReloadButton.png')
- @screen.wait('SynapticReloadPrompt.png', 20)
- @screen.waitVanish('SynapticReloadPrompt.png', 30*60)
+ recovery_proc = Proc.new do
+ step 'I kill the process "synaptic"'
+ step "I start Synaptic"
+ end
+ retry_tor(recovery_proc) do
+ try_for(60, :msg => "Failed to trigger the reload of the package list") {
+ # here using the Synaptic keyboard shortcut is more effective on retries.
+ @screen.type("r", Sikuli::KeyModifier.CTRL)
+ @screen.wait('SynapticReloadPrompt.png', 10)
+ }
+ try_for(15*60, :msg => "Took too much time to download the APT data") {
+ !$vm.has_process?("/usr/lib/apt/methods/tor+http")
+ }
+ if @screen.exists('SynapticFailure.png')
+ raise "Updating APT with Synaptic failed."
+ end
+ if !$vm.has_process?("synaptic")
+ raise "Synaptic process vanished, did it segfault again?"
+ end
+ end
end
Then /^I should be able to install a package using Synaptic$/ do
package = "cowsay"
- try_for(60) do
- @screen.wait_and_click('SynapticSearchButton.png', 10)
- @screen.wait_and_click('SynapticSearchWindow.png', 10)
+ recovery_proc = Proc.new do
+ step 'I kill the process "synaptic"'
+ $vm.execute("apt -y purge #{package}")
+ step "I start Synaptic"
+ end
+ retry_tor(recovery_proc) do
+ try_for(60) do
+ @screen.wait_and_click('SynapticSearchButton.png', 10)
+ @screen.wait_and_click('SynapticSearchWindow.png', 10)
+ end
+ @screen.type(package + Sikuli::Key.ENTER)
+ @screen.wait_and_double_click('SynapticCowsaySearchResult.png', 20)
+ @screen.wait_and_click('SynapticApplyButton.png', 10)
+ @screen.wait('SynapticApplyPrompt.png', 60)
+ @screen.type(Sikuli::Key.ENTER)
+ @screen.wait('SynapticChangesAppliedPrompt.png', 4*60)
+ step "package \"#{package}\" is installed"
end
- @screen.type(package + Sikuli::Key.ENTER)
- @screen.wait_and_double_click('SynapticCowsaySearchResult.png', 20)
- @screen.wait_and_click('SynapticApplyButton.png', 10)
- @screen.wait('SynapticApplyPrompt.png', 60)
- @screen.type(Sikuli::Key.ENTER)
- @screen.wait('SynapticChangesAppliedPrompt.png', 240)
- step "package \"#{package}\" is installed"
end
When /^I start Synaptic$/ do
step 'I start "Synaptic Package Manager" via the GNOME "System Tools" applications menu'
deal_with_polkit_prompt('PolicyKitAuthPrompt.png', @sudo_password)
- @screen.wait('SynapticReloadButton.png', 30)
+ @screen.wait('SynapticLoaded.png', 30)
end
diff --git a/features/step_definitions/checks.rb b/features/step_definitions/checks.rb
index 423b839..06824b3 100644
--- a/features/step_definitions/checks.rb
+++ b/features/step_definitions/checks.rb
@@ -96,6 +96,11 @@ Then /^no unexpected services are listening for network connections$/ do
end
end
+When /^Tails has booted a 32-bit kernel$/ do
+ assert(! $vm.execute("uname -r | grep -qs 'amd64$'").success?,
+ "Tails has not booted a 32-bit kernel.")
+end
+
When /^Tails has booted a 64-bit kernel$/ do
assert($vm.execute("uname -r | grep -qs 'amd64$'").success?,
"Tails has not booted a 64-bit kernel.")
diff --git a/features/step_definitions/common_steps.rb b/features/step_definitions/common_steps.rb
index 6d8d738..798aee6 100644
--- a/features/step_definitions/common_steps.rb
+++ b/features/step_definitions/common_steps.rb
@@ -164,6 +164,11 @@ Given /^the network is unplugged$/ do
$vm.unplug_network
end
+Given /^the network connection is ready(?: within (\d+) seconds)?$/ do |timeout|
+ timeout ||= 30
+ try_for(timeout.to_i) { $vm.has_network? }
+end
+
Given /^the hardware clock is set to "([^"]*)"$/ do |time|
$vm.set_hardware_clock(DateTime.parse(time).to_time)
end
@@ -252,16 +257,16 @@ When /^I destroy the computer$/ do
$vm.destroy_and_undefine
end
-def bootsplash
+def boot_menu_cmdline_image
case @os_loader
when "UEFI"
- 'TailsBootSplashUEFI.png'
+ 'TailsBootMenuKernelCmdlineUEFI.png'
else
- 'TailsBootSplash.png'
+ 'TailsBootMenuKernelCmdline.png'
end
end
-def bootsplash_tab_msg
+def boot_menu_tab_msg_image
case @os_loader
when "UEFI"
'TailsBootSplashTabMsgUEFI.png'
@@ -270,20 +275,73 @@ def bootsplash_tab_msg
end
end
-Given /^the computer (re)?boots Tails$/ do |reboot|
+def memory_wipe_timeout
+ nr_gigs_of_ram = convert_from_bytes($vm.get_ram_size_in_bytes, 'GiB').ceil
+ nr_gigs_of_ram*30
+end
- boot_timeout = 30
+Given /^Tails is at the boot menu's cmdline( after rebooting)?$/ do |reboot|
+ boot_timeout = 3*60
# We need some extra time for memory wiping if rebooting
- boot_timeout += 90 if reboot
-
- @screen.wait(bootsplash, boot_timeout)
- @screen.wait(bootsplash_tab_msg, 10)
- @screen.type(Sikuli::Key.TAB)
- @screen.waitVanish(bootsplash_tab_msg, 1)
+ boot_timeout += memory_wipe_timeout if reboot
+ # Simply looking for the boot splash image is not robust; sometimes
+ # sikuli is not fast enough to see it. Here we hope that spamming
+ # TAB, which will halt the boot process by showing the prompt for
+ # the kernel cmdline, will make this a bit more robust. We want this
+ # spamming to happen in parallel with Sikuli waiting for the image,
+ # but multi-threading etc is working extremely poor in our Ruby +
+ # jrb environment when Sikuli is involved. Hence we run the spamming
+ # from a separate process.
+ tab_spammer_code = <<-EOF
+ require 'libvirt'
+ tab_key_code = 0xf
+ virt = Libvirt::open("qemu:///system")
+ begin
+ domain = virt.lookup_domain_by_name('#{$vm.domain_name}')
+ loop do
+ domain.send_key(Libvirt::Domain::KEYCODE_SET_LINUX, 0, [tab_key_code])
+ sleep 0.1
+ end
+ ensure
+ virt.close
+ end
+ EOF
+ # Our UEFI firmware (OVMF) has the interesting "feature" that pressing
+ # any button will open its setup menu, so we have to exit the setup,
+ # and to not have the TAB spammer potentially interfering we pause
+ # it meanwhile.
+ dealt_with_uefi_setup = false
+ # The below code is not completely reliable, so we might have to
+ # retry by rebooting.
+ try_for(boot_timeout) do
+ begin
+ tab_spammer = IO.popen(['ruby', '-e', tab_spammer_code])
+ if not(dealt_with_uefi_setup) && @os_loader == 'UEFI'
+ @screen.wait('UEFIFirmwareSetup.png', 30)
+ Process.kill("TSTP", tab_spammer.pid)
+ @screen.type(Sikuli::Key.ENTER)
+ Process.kill("CONT", tab_spammer.pid)
+ dealt_with_uefi_setup = true
+ end
+ @screen.wait(boot_menu_cmdline_image, 15)
+ rescue FindFailed => e
+ debug_log('We missed the boot menu before we could deal with it, ' +
+ 'resetting...')
+ dealt_with_uefi_setup = false
+ $vm.reset
+ retry
+ ensure
+ Process.kill("TERM", tab_spammer.pid)
+ tab_spammer.close
+ end
+ end
+end
+Given /^the computer (re)?boots Tails$/ do |reboot|
+ step "Tails is at the boot menu's cmdline" + (reboot ? ' after rebooting' : '')
@screen.type(" autotest_never_use_this_option blacklist=psmouse #{@boot_options}" +
Sikuli::Key.ENTER)
- @screen.wait('TailsGreeter.png', 30*60)
+ @screen.wait('TailsGreeter.png', 5*60)
$vm.wait_until_remote_shell_is_up
activate_filesystem_shares
step 'I configure Tails to use a simulated Tor network'
@@ -301,7 +359,7 @@ Given /^I log in to a new session(?: in )?(|German)$/ do |lang|
else
raise "Unsupported language: #{lang}"
end
- step 'Tails Greeter has dealt with the sudo password'
+ step 'Tails Greeter has applied all settings'
step 'the Tails desktop is ready'
end
@@ -323,11 +381,12 @@ Given /^I set an administration password$/ do
@screen.type(@sudo_password)
end
-Given /^Tails Greeter has dealt with the sudo password$/ do
- f1 = "/etc/sudoers.d/tails-greeter"
- f2 = "#{f1}-no-password-lecture"
+Given /^Tails Greeter has applied all settings$/ do
+ # I.e. it is done with PostLogin, which is ensured to happen before
+ # a logind session is opened for LIVE_USER.
try_for(120) {
- $vm.execute("test -e '#{f1}' -o -e '#{f2}'").success?
+ $vm.execute_successfully("loginctl").stdout
+ .match(/^\s*\S+\s+\d+\s+#{LIVE_USER}\s+seat\d+\s*$/) != nil
}
end
@@ -517,16 +576,13 @@ Given /^I kill the process "([^"]+)"$/ do |process|
end
Then /^Tails eventually shuts down$/ do
- nr_gibs_of_ram = convert_from_bytes($vm.get_ram_size_in_bytes, 'GiB').ceil
- timeout = nr_gibs_of_ram*5*60
- try_for(timeout, :msg => "VM is still running after #{timeout} seconds") do
+ try_for(memory_wipe_timeout, :msg => "VM is still running") do
! $vm.is_running?
end
end
Then /^Tails eventually restarts$/ do
- nr_gibs_of_ram = convert_from_bytes($vm.get_ram_size_in_bytes, 'GiB').ceil
- @screen.wait('TailsBootSplash.png', nr_gibs_of_ram*5*60)
+ step 'the computer reboots Tails'
end
Given /^I shutdown Tails and wait for the computer to power off$/ do
@@ -905,7 +961,7 @@ When /^I eject the boot medium$/ do
dev_type = device_info(dev)['ID_TYPE']
case dev_type
when 'cd'
- $vm.remove_cdrom
+ $vm.eject_cdrom
when 'disk'
boot_disk_name = $vm.disk_name(dev)
$vm.unplug_drive(boot_disk_name)
@@ -913,3 +969,19 @@ When /^I eject the boot medium$/ do
raise "Unsupported medium type '#{dev_type}' for boot device '#{dev}'"
end
end
+
+Given /^Tails is fooled to think it is running version (.+)$/ do |version|
+ $vm.execute_successfully(
+ "sed -i " +
+ "'s/^TAILS_VERSION_ID=.*$/TAILS_VERSION_ID=\"#{version}\"/' " +
+ "/etc/os-release"
+ )
+end
+
+Then /^Tails is running version (.+)$/ do |version|
+ v1 = $vm.execute_successfully('tails-version').stdout.split.first
+ assert_equal(version, v1, "The version doesn't match tails-version's output")
+ v2 = $vm.file_content('/etc/os-release')
+ .scan(/TAILS_VERSION_ID="(#{version})"/).flatten.first
+ assert_equal(version, v2, "The version doesn't match /etc/os-release")
+end
diff --git a/features/step_definitions/erase_memory.rb b/features/step_definitions/erase_memory.rb
index 24b21e0..246a245 100644
--- a/features/step_definitions/erase_memory.rb
+++ b/features/step_definitions/erase_memory.rb
@@ -64,7 +64,7 @@ Given /^at least (\d+) ([[:alpha:]]+) of RAM was detected$/ do |min_ram, unit|
puts "Detected #{@detected_ram_m} MiB of RAM"
min_ram_m = convert_to_MiB(min_ram.to_i, unit)
# All RAM will not be reported by `free`, so we allow a 196 MB gap
- gap = convert_to_MiB(196, "MiB")
+ gap = convert_to_MiB(256, "MiB")
assert(@detected_ram_m + gap >= min_ram_m, "Didn't detect enough RAM")
end
@@ -181,7 +181,7 @@ end
Then /^I find very few patterns in the guest's memory$/ do
coverage = pattern_coverage_in_guest_ram()
- max_coverage = 0.005
+ max_coverage = 0.008
assert(coverage < max_coverage,
"#{"%.3f" % (coverage*100)}% of the free memory still has the " +
"pattern, but less than #{"%.3f" % (max_coverage*100)}% was expected")
@@ -200,16 +200,12 @@ When /^I reboot without wiping the memory$/ do
end
When /^I stop the boot at the bootloader menu$/ do
- @screen.wait(bootsplash, 90)
- @screen.wait(bootsplash_tab_msg, 10)
- @screen.type(Sikuli::Key.TAB)
- @screen.waitVanish(bootsplash_tab_msg, 1)
+ step "Tails is at the boot menu's cmdline"
end
When /^I shutdown and wait for Tails to finish wiping the memory$/ do
$vm.spawn("halt")
- nr_gibs_of_ram = convert_from_bytes($vm.get_ram_size_in_bytes, 'GiB').ceil
- try_for(nr_gibs_of_ram*5*60, { :msg => "memory wipe didn't finish, probably the VM crashed" }) do
+ try_for(memory_wipe_timeout, { :msg => "memory wipe didn't finish, probably the VM crashed" }) do
# We spam keypresses to prevent console blanking from hiding the
# image we're waiting for
@screen.type(" ")
diff --git a/features/step_definitions/icedove.rb b/features/step_definitions/icedove.rb
index dd3a0a0..4806622 100644
--- a/features/step_definitions/icedove.rb
+++ b/features/step_definitions/icedove.rb
@@ -1,84 +1,234 @@
-Then /^Icedove has started$/ do
- step 'process "icedove" is running within 30 seconds'
- @screen.wait('IcedoveMainWindow.png', 60)
+def icedove_app
+ Dogtail::Application.new('Icedove')
end
-When /^I have not configured an email account$/ do
- icedove_prefs = $vm.file_content("/home/#{LIVE_USER}/.icedove/profile.default/prefs.js").chomp
- assert(!icedove_prefs.include?('mail.accountmanager.accounts'))
+def icedove_main
+ # The main window title depends on context so without regexes it
+ # will be hard to find it, but it so happens that it is always the
+ # first frame of Icedove, so we do not have to be specific.
+ icedove_app.child(roleName: 'frame')
end
-Then /^I am prompted to setup an email account$/ do
- $vm.focus_window('Mail Account Setup')
- @screen.wait('IcedoveMailAccountSetup.png', 30)
+def icedove_wizard
+ icedove_app.child('Mail Account Setup', roleName: 'frame')
+end
+
+When /^I start Icedove$/ do
+ workaround_pref_lines = [
+ # When we generate a random subject line it may contain one of the
+ # keywords that will make Icedove show an extra prompt when trying
+ # to send an email. Let's disable this feature.
+ 'pref("mail.compose.attachment_reminder", false);'
+ ]
+ workaround_pref_lines.each do |line|
+ $vm.file_append('/etc/icedove/pref/icedove.js ', line)
+ end
+ step 'I start "Icedove" via the GNOME "Internet" applications menu'
+ icedove_main.wait(60)
+end
+
+When /^I have not configured an email account$/ do
+ conf_path = "/home/#{LIVE_USER}/.icedove/profile.default/prefs.js"
+ if $vm.file_exist?(conf_path)
+ icedove_prefs = $vm.file_content(conf_path).chomp
+ assert(!icedove_prefs.include?('mail.accountmanager.accounts'))
+ end
end
-Then /^IMAP is the default protocol$/ do
- $vm.focus_window('Mail Account Setup')
- @screen.wait('IcedoveProtocolIMAP.png', 10)
+Then /^I am prompted to setup an email account$/ do
+ icedove_wizard.wait(30)
end
Then /^I cancel setting up an email account$/ do
- $vm.focus_window('Mail Account Setup')
- @screen.type(Sikuli::Key.ESC)
- @screen.waitVanish('IcedoveMailAccountSetup.png', 10)
+ icedove_wizard.button('Cancel').click
end
Then /^I open Icedove's Add-ons Manager$/ do
- $vm.focus_window('Icedove')
- @screen.wait_and_click('MozillaMenuButton.png', 10)
- @screen.wait_and_click('IcedoveToolsMenuAddOns.png', 10)
- @screen.wait('MozillaAddonsManagerExtensions.png', 30)
+ icedove_main.button('AppMenu').click
+ icedove_main.child('Add-ons', roleName: 'menu item').click
+ @icedove_addons = icedove_app.child(
+ 'Add-ons Manager - Icedove Mail/News', roleName: 'frame'
+ )
+ @icedove_addons.wait
end
Then /^I click the extensions tab$/ do
- @screen.wait_and_click('MozillaAddonsManagerExtensions.png', 10)
+ @icedove_addons.child('Extensions', roleName: 'list item').click
end
-Then /^I see that Adblock is not installed in Icedove$/ do
- if @screen.exists('MozillaExtensionsAdblockPlus.png')
- raise 'Adblock should not be enabled within Icedove'
+Then /^I see that only the (.+) addons are enabled in Icedove$/ do |addons|
+ expected_addons = addons.split(/, | and /)
+ actual_addons =
+ @icedove_addons.child('amnesia branding', roleName: 'label')
+ .parent.parent.children(roleName: 'list item', recursive: false)
+ .map { |item| item.name }
+ expected_addons.each do |addon|
+ result = actual_addons.find { |e| e.start_with?(addon) }
+ assert_not_nil(result)
+ actual_addons.delete(result)
end
+ assert_equal(0, actual_addons.size)
end
When /^I go into Enigmail's preferences$/ do
$vm.focus_window('Icedove')
@screen.type("a", Sikuli::KeyModifier.ALT)
- @screen.wait_and_click('IcedoveEnigmailPreferences.png', 10)
- @screen.wait('IcedoveEnigmailPreferencesWindow.png', 10)
- @screen.click('IcedoveEnigmailExpertSettingsButton.png')
- @screen.wait('IcedoveEnigmailKeyserverTab.png', 10)
+ icedove_main.child('Preferences', roleName: 'menu item').click
+ @enigmail_prefs = icedove_app.dialog('Enigmail Preferences')
end
-When /^I click Enigmail's keyserver tab$/ do
- @screen.wait_and_click('IcedoveEnigmailKeyserverTab.png', 10)
+When /^I enable Enigmail's expert settings$/ do
+ @enigmail_prefs.button('Display Expert Settings and Menus').click
end
-Then /^I see that Enigmail is configured to use the correct keyserver$/ do
- @screen.wait('IcedoveEnigmailKeyserver.png', 10)
+Then /^I click Enigmail's (.+) tab$/ do |tab_name|
+ @enigmail_prefs.child(tab_name, roleName: 'page tab').click
end
-Then /^I click Enigmail's advanced tab$/ do
- @screen.wait_and_click('IcedoveEnigmailAdvancedTab.png', 10)
+Then /^I see that Enigmail is configured to use the correct keyserver$/ do
+ keyservers = @enigmail_prefs.child(
+ 'Specify your keyserver(s):', roleName: 'entry'
+ ).text
+ assert_equal('hkps://hkps.pool.sks-keyservers.net', keyservers)
end
Then /^I see that Enigmail is configured to use the correct SOCKS proxy$/ do
- @screen.click('IcedoveEnigmailAdvancedParameters.png')
- @screen.type(Sikuli::Key.END)
- @screen.wait('IcedoveEnigmailProxy.png', 10)
+ gnupg_parameters = @enigmail_prefs.child(
+ 'Additional parameters for GnuPG', roleName: 'entry'
+ ).text
+ assert_not_nil(
+ gnupg_parameters['--keyserver-options http-proxy=socks5h://127.0.0.1:9050']
+ )
end
Then /^I see that Torbirdy is configured to use Tor$/ do
- @screen.wait('IcedoveTorbirdyEnabled.png', 10)
-end
-
-When /^I open Torbirdy's preferences$/ do
- step "I open Icedove's Add-ons Manager"
- step 'I click the extensions tab'
- @screen.wait_and_click('MozillaExtensionsTorbirdy.png', 10)
- @screen.type(Sikuli::Key.TAB) # Select 'More' link
- @screen.type(Sikuli::Key.TAB) # Select 'Preferences' button
- @screen.type(Sikuli::Key.SPACE) # Press 'Preferences' button
- @screen.wait('GnomeQuestionDialogIcon.png', 10)
- @screen.type(Sikuli::Key.ENTER)
+ icedove_main.child(roleName: 'status bar')
+ .child('TorBirdy Enabled: Tor', roleName: 'label').wait
+end
+
+When /^I enter my email credentials into the autoconfiguration wizard$/ do
+ icedove_wizard.child('Email address:', roleName: 'entry')
+ .typeText($config['Icedove']['address'])
+ icedove_wizard.child('Password:', roleName: 'entry')
+ .typeText($config['Icedove']['password'])
+ icedove_wizard.button('Continue').click
+ # This button is shown if and only if a configuration has been found
+ icedove_wizard.button('Done').wait(120)
+end
+
+Then /^the autoconfiguration wizard's choice for the (incoming|outgoing) server is secure (.+)$/ do |type, protocol|
+ type = type.capitalize + ':'
+ assert_not_nil(
+ icedove_wizard.child(type, roleName: 'entry').text
+ .match(/^#{protocol},[^,]+, (SSL|STARTTLS)$/)
+ )
+end
+
+When /^I fetch my email$/ do
+ account = icedove_main.child($config['Icedove']['address'],
+ roleName: 'table row')
+ account.click
+ icedove_main = icedove_app.child("#{$config['Icedove']['address']} - Icedove Mail/News", roleName: 'frame')
+
+ icedove_main.child('Mail Toolbar', roleName: 'tool bar')
+ .button('Get Messages').click
+ fetch_progress = icedove_main.child(roleName: 'status bar')
+ .child(roleName: 'progress bar')
+ fetch_progress.wait_vanish(120)
+end
+
+When /^I accept the (?:autoconfiguration wizard's|manual) configuration$/ do
+ # The password check can fail due to bad Tor circuits.
+ retry_tor do
+ try_for(120) do
+ if icedove_wizard.exist?
+ # Spam the button, even if it is disabled (while it is still
+ # testing the password).
+ icedove_wizard.button('Done').click
+ false
+ else
+ true
+ end
+ end
+ end
+ # The account isn't fully created before we fetch our mail. For
+ # instance, if we'd try to send an email before this, yet another
+ # wizard will start, indicating (incorrectly) that we do not have an
+ # account set up yet.
+ step 'I fetch my email'
+end
+
+When /^I select the autoconfiguration wizard's (IMAP|POP3) choice$/ do |protocol|
+ if protocol == 'IMAP'
+ choice = 'IMAP (remote folders)'
+ else
+ choice = 'POP3 (keep mail on your computer)'
+ end
+ icedove_wizard.child(choice, roleName: 'radio button').click
+end
+
+When /^I select manual configuration$/ do
+ icedove_wizard.button('Manual config').click
+end
+
+When /^I alter the email configuration to use (.*) over a hidden services$/ do |protocol|
+ case protocol.upcase
+ when 'IMAP', 'POP3'
+ entry_name = 'Incoming:'
+ when 'SMTP'
+ entry_name = 'Outgoing:'
+ else
+ raise "Unknown mail protocol '#{protocol}'"
+ end
+ entry = icedove_wizard.child(entry_name, roleName: 'entry')
+ entry.text = ''
+ entry.typeText($config['Icedove']["#{protocol.downcase}_hidden_service"])
+end
+
+When /^I send an email to myself$/ do
+ icedove_main.child('Mail Toolbar', roleName: 'tool bar').button('Write').click
+ compose_window = icedove_app.child('Write: (no subject)')
+ compose_window.wait(10)
+ compose_window.child('To:', roleName: 'autocomplete').child(roleName: 'entry')
+ .typeText($config['Icedove']['address'])
+ # The randomness of the subject will make it easier for us to later
+ # find *exactly* this email. This makes it safe to run several tests
+ # in parallel.
+ @subject = "Automated test suite: #{random_alnum_string(32)}"
+ compose_window.child('Subject:', roleName: 'entry')
+ .typeText(@subject)
+ compose_window = icedove_app.child("Write: #{@subject}")
+ compose_window.child('about:blank', roleName: 'document frame')
+ .typeText('test')
+ compose_window.child('Composition Toolbar', roleName: 'tool bar')
+ .button('Send').click
+ compose_window.wait_vanish(120)
+end
+
+Then /^I can find the email I sent to myself in my inbox$/ do
+ recovery_proc = Proc.new { step 'I fetch my email' }
+ retry_tor(recovery_proc) do
+ folder_view = icedove_main.child($config['Icedove']['address'],
+ roleName: 'table row').parent
+ inbox = folder_view.children(roleName: 'table row', recursive: false).find do |e|
+ e.name.match(/^Inbox( .*)?$/)
+ end
+ inbox.click
+ filter = icedove_main.child('Filter these messages <Ctrl+Shift+K>',
+ roleName: 'entry')
+ filter.typeText(@subject)
+ hit_counter = icedove_main.child('1 message')
+ hit_counter.wait
+ inbox_view = hit_counter.parent
+ message_list = inbox_view.child(roleName: 'table')
+ the_message = message_list.children(roleName: 'table row').find do |message|
+ # The message will be cropped in the list, so we cannot search
+ # for the full message.
+ message.name.start_with?("Automated test suite:")
+ end
+ assert_not_nil(the_message)
+ # Let's clean up
+ the_message.click
+ inbox_view.button('Delete').click
+ end
end
diff --git a/features/step_definitions/tor.rb b/features/step_definitions/tor.rb
index babde27..ff78d81 100644
--- a/features/step_definitions/tor.rb
+++ b/features/step_definitions/tor.rb
@@ -394,21 +394,3 @@ When /^all Internet traffic has only flowed through the configured pluggable tra
@bridge_hosts.include?({ address: c.daddr, port: c.dport })
end
end
-
-Then /^the Tor binary is configured to use the expected Tor authorities$/ do
- tor_auths = Set.new
- tor_binary_orport_strings = $vm.execute_successfully(
- "strings /usr/bin/tor | grep -E 'orport=[0-9]+'").stdout.chomp.split("\n")
- tor_binary_orport_strings.each do |potential_auth_string|
- auth_regex = /^\S+ orport=\d+( bridge)?( no-v2)?( v3ident=[A-Z0-9]{40})? ([0-9\.]+):\d+( [A-Z0-9]{4}){10}$/
- m = auth_regex.match(potential_auth_string)
- if m
- auth_ipv4_addr = m[4]
- tor_auths << auth_ipv4_addr
- end
- end
- expected_tor_auths = Set.new(TOR_AUTHORITIES)
- assert_equal(expected_tor_auths, tor_auths,
- "The Tor binary does not have the expected Tor authorities " +
- "configured")
-end
diff --git a/features/step_definitions/torified_gnupg.rb b/features/step_definitions/torified_gnupg.rb
index 282db48..cb0a9db 100644
--- a/features/step_definitions/torified_gnupg.rb
+++ b/features/step_definitions/torified_gnupg.rb
@@ -108,7 +108,7 @@ end
Then /^I synchronize keys in Seahorse$/ do
recovery_proc = Proc.new do
- # The versions of Seahorse in Wheezy and Jessie will abort with a
+ # The version of Seahorse in Jessie will abort with a
# segmentation fault whenever there's any sort of network error while
# syncing keys. This will usually happens after clicking away the error
# message. This does not appear to be a problem in Stretch.
diff --git a/features/step_definitions/totem.rb b/features/step_definitions/totem.rb
index 7b45b2e..520e7d6 100644
--- a/features/step_definitions/totem.rb
+++ b/features/step_definitions/totem.rb
@@ -4,7 +4,7 @@ Given /^I create sample videos$/ do
FileUtils.mkdir_p(@shared_video_dir_on_host)
add_after_scenario_hook { FileUtils.rm_r(@shared_video_dir_on_host) }
fatal_system("avconv -loop 1 -t 30 -f image2 " +
- "-i 'features/images/TailsBootSplash.png' " +
+ "-i 'features/images/USBTailsLogo.png' " +
"-an -vcodec libx264 -y " +
'-filter:v "crop=in_w-mod(in_w\,2):in_h-mod(in_h\,2)" ' +
"'#{@shared_video_dir_on_host}/video.mp4' >/dev/null 2>&1")
diff --git a/features/step_definitions/usb.rb b/features/step_definitions/usb.rb
index 85ad27a..ce46916 100644
--- a/features/step_definitions/usb.rb
+++ b/features/step_definitions/usb.rb
@@ -48,6 +48,14 @@ def persistent_volumes_mountpoints
$vm.execute("ls -1 -d /live/persistence/*_unlocked/").stdout.chomp.split
end
+def recover_from_upgrader_failure
+ $vm.execute('killall tails-upgrade-frontend tails-upgrade-frontend-wrapper zenity')
+ # Remove unnecessary sleep for retry
+ $vm.execute_successfully('sed -i "/^sleep 30$/d" ' +
+ '/usr/local/bin/tails-upgrade-frontend-wrapper')
+ $vm.spawn('tails-upgrade-frontend-wrapper', user: LIVE_USER)
+end
+
Given /^I clone USB drive "([^"]+)" to a new USB drive "([^"]+)"$/ do |from, to|
$vm.storage.clone_to_new_disk(from, to)
end
@@ -73,14 +81,19 @@ def usb_install_helper(name)
if @screen.exists("USBCannotUpgrade.png")
raise UpgradeNotSupported
end
- @screen.wait_and_click('USBCreateLiveUSB.png', 10)
- @screen.wait('USBCreateLiveUSBConfirmWindow.png', 10)
- @screen.wait_and_click('USBCreateLiveUSBConfirmYes.png', 10)
- @screen.wait('USBInstallationComplete.png', 30*60)
+ begin
+ @screen.wait_and_click('USBCreateLiveUSB.png', 10)
+ @screen.wait('USBCreateLiveUSBConfirmWindow.png', 10)
+ @screen.wait_and_click('USBCreateLiveUSBConfirmYes.png', 10)
+ @screen.wait('USBInstallationComplete.png', 30*60)
+ rescue FindFailed => e
+ debug_log("Tails Installer debug log:\n" + $vm.file_content('/tmp/tails-installer-*'))
+ raise e
+ end
end
When /^I start Tails Installer$/ do
- step 'I start "Tails Installer" via the GNOME "Tails" applications menu'
+ step 'I run "export DEBUG=1 ; tails-installer-launcher" in GNOME Terminal'
@screen.wait('USBCloneAndInstall.png', 30)
end
@@ -395,7 +408,7 @@ end
Then /^Tails is running from (.*) drive "([^"]+)"$/ do |bus, name|
bus = bus.downcase
case bus
- when "ide"
+ when "sata"
expected_bus = "ata"
else
expected_bus = bus
@@ -627,3 +640,110 @@ end
Then /^no USB drive is selected$/ do
@screen.wait("TailsInstallerNoQEMUHardDisk.png", 30)
end
+
+Given /^the file system changes introduced in version (.+) are (not )?present(?: in the (\S+) Browser's chroot)?$/ do |version, not_present, chroot_browser|
+ assert_equal('1.1~test', version)
+ upgrade_applied = not_present.nil?
+ chroot_browser = "#{chroot_browser.downcase}-browser" if chroot_browser
+ changes = [
+ {
+ filesystem: :rootfs,
+ path: 'some_new_file',
+ status: :added,
+ new_content: <<-EOF
+Some content
+ EOF
+ },
+ {
+ filesystem: :rootfs,
+ path: 'etc/amnesia/version',
+ status: :modified,
+ new_content: <<-EOF
+#{version} - 20380119
+ffffffffffffffffffffffffffffffffffffffff
+live-build: 3.0.5+really+is+2.0.12-0.tails2
+live-boot: 4.0.2-1
+live-config: 4.0.4-1
+ EOF
+ },
+ {
+ filesystem: :rootfs,
+ path: 'etc/os-release',
+ status: :modified,
+ new_content: <<-EOF
+TAILS_PRODUCT_NAME="Tails"
+TAILS_VERSION_ID="#{version}"
+ EOF
+ },
+ {
+ filesystem: :rootfs,
+ path: 'usr/share/common-licenses/BSD',
+ status: :removed
+ },
+ {
+ filesystem: :medium,
+ path: 'utils/linux/syslinux',
+ status: :removed
+ },
+ ]
+ changes.each do |change|
+ case change[:filesystem]
+ when :rootfs
+ path = '/'
+ path += "var/lib/#{chroot_browser}/chroot/" if chroot_browser
+ path += change[:path]
+ when :medium
+ path = '/lib/live/mount/medium/' + change[:path]
+ else
+ raise "Unknown filesysten '#{change[:filesystem]}'"
+ end
+ case change[:status]
+ when :removed
+ assert_equal(!upgrade_applied, $vm.file_exist?(path))
+ when :added
+ assert_equal(upgrade_applied, $vm.file_exist?(path))
+ if upgrade_applied && change[:new_content]
+ assert_equal(change[:new_content], $vm.file_content(path))
+ end
+ when :modified
+ assert($vm.file_exist?(path))
+ if upgrade_applied
+ assert_not_nil(change[:new_content])
+ assert_equal(change[:new_content], $vm.file_content(path))
+ end
+ else
+ raise "Unknown status '#{change[:status]}'"
+ end
+ end
+end
+
+Then /^I am proposed to install an incremental upgrade to version (.+)$/ do |version|
+ recovery_proc = Proc.new do
+ recover_from_upgrader_failure
+ end
+ failure_pic = 'TailsUpgraderFailure.png'
+ success_pic = "TailsUpgraderUpgradeTo#{version}.png"
+ retry_tor(recovery_proc) do
+ match, _ = @screen.waitAny([success_pic, failure_pic], 2*60)
+ assert_equal(success_pic, match)
+ end
+end
+
+When /^I agree to install the incremental upgrade$/ do
+ @screen.click('TailsUpgraderUpgradeNowButton.png')
+end
+
+Then /^I can successfully install the incremental upgrade to version (.+)$/ do |version|
+ step 'I agree to install the incremental upgrade'
+ recovery_proc = Proc.new do
+ recover_from_upgrader_failure
+ step "I am proposed to install an incremental upgrade to version #{version}"
+ step 'I agree to install the incremental upgrade'
+ end
+ failure_pic = 'TailsUpgraderFailure.png'
+ success_pic = "TailsUpgraderDone.png"
+ retry_tor(recovery_proc) do
+ match, _ = @screen.waitAny([success_pic, failure_pic], 2*60)
+ assert_equal(success_pic, match)
+ end
+end
diff --git a/features/support/config.rb b/features/support/config.rb
index ce3c048..89fa1ba 100644
--- a/features/support/config.rb
+++ b/features/support/config.rb
@@ -74,20 +74,6 @@ SERVICES_EXPECTED_ON_ALL_IFACES =
]
# OpenDNS
SOME_DNS_SERVER = "208.67.222.222"
-TOR_AUTHORITIES =
- # List grabbed from Tor's sources, src/or/config.c:~750.
- [
- "86.59.21.38",
- "128.31.0.39",
- "194.109.206.212",
- "82.94.251.203",
- "199.254.238.52",
- "131.188.40.189",
- "193.23.244.244",
- "208.83.223.34",
- "171.25.193.9",
- "154.35.175.225",
- ]
VM_XML_PATH = "#{Dir.pwd}/features/domains"
TAILS_SIGNING_KEY = cmd_helper(". #{Dir.pwd}/config/amnesia; echo ${AMNESIA_DEV_KEYID}").tr(' ', '').chomp
diff --git a/features/support/extra_hooks.rb b/features/support/extra_hooks.rb
index 16196a5..b990b9b 100644
--- a/features/support/extra_hooks.rb
+++ b/features/support/extra_hooks.rb
@@ -1,18 +1,21 @@
# Make the code below work with cucumber >= 2.0. Once we stop
# supporting <2.0 we should probably do this differently, but this way
# we can easily support both at the same time.
+
begin
if not(Cucumber::Core::Ast::Feature.instance_methods.include?(:accept_hook?))
- require 'gherkin/tag_expression'
+ if Gem::Version.new(Cucumber::VERSION) >= Gem::Version.new('2.4.0')
+ require 'cucumber/core/gherkin/tag_expression'
+ else
+ require 'gherkin/tag_expression'
+ Cucumber::Core::Gherkin = Gherkin
+ end
class Cucumber::Core::Ast::Feature
# Code inspired by Cucumber::Core::Test::Case.match_tags?() in
# cucumber-ruby-core 1.1.3, lib/cucumber/core/test/case.rb:~59.
def accept_hook?(hook)
- tag_expr = Gherkin::TagExpression.new(hook.tag_expressions.flatten)
- tags = @tags.map do |t|
- Gherkin::Formatter::Model::Tag.new(t.name, t.line)
- end
- tag_expr.evaluate(tags)
+ tag_expr = Cucumber::Core::Gherkin::TagExpression.new(hook.tag_expressions.flatten)
+ tag_expr.evaluate(@tags)
end
end
end
@@ -53,10 +56,10 @@ if not($at_exit_print_artifacts_dir_patching_done)
alias old_print_stats print_stats
end
def print_stats(*args)
- if Dir.exists?(ARTIFACTS_DIR) and Dir.entries(ARTIFACTS_DIR).size > 2
- @io.puts "Artifacts directory: #{ARTIFACTS_DIR}"
- @io.puts
- end
+ @io.puts "Artifacts directory: #{ARTIFACTS_DIR}"
+ @io.puts
+ @io.puts "Debug log: #{ARTIFACTS_DIR}/debug.log"
+ @io.puts
if self.class.method_defined?(:old_print_stats)
old_print_stats(*args)
end
@@ -104,8 +107,11 @@ module ExtraFormatters
# anything. We only use it do hook into the correct events so we can
# add our extra hooks.
class ExtraHooks
- def initialize(*args)
+ def initialize(runtime, io, options)
# We do not care about any of the arguments.
+ # XXX: We should be able to just have `*args` for the arguments
+ # in the prototype, but since moving to cucumber 2.4 that breaks
+ # this formatter for some unknown reason.
end
def before_feature(feature)
@@ -127,8 +133,8 @@ module ExtraFormatters
# The pretty formatter with debug logging mixed into its output.
class PrettyDebug < Cucumber::Formatter::Pretty
- def initialize(*args)
- super(*args)
+ def initialize(runtime, io, options)
+ super(runtime, io, options)
$debug_log_fns ||= []
$debug_log_fns << self.method(:debug_log)
end
@@ -160,6 +166,13 @@ AfterConfiguration do |config|
# AfterConfiguration hook multiple times. We only want our
# ExtraHooks formatter to be loaded once, otherwise the hooks would
# be run miltiple times.
- extra_hooks = ['ExtraFormatters::ExtraHooks', '/dev/null']
- config.formats << extra_hooks if not(config.formats.include?(extra_hooks))
+ extra_hooks = [
+ ['ExtraFormatters::ExtraHooks', '/dev/null'],
+ ['Cucumber::Formatter::Pretty', "#{ARTIFACTS_DIR}/pretty.log"],
+ ['Cucumber::Formatter::Json', "#{ARTIFACTS_DIR}/cucumber.json"],
+ ['ExtraFormatters::PrettyDebug', "#{ARTIFACTS_DIR}/debug.log"],
+ ]
+ extra_hooks.each do |hook|
+ config.formats << hook if not(config.formats.include?(hook))
+ end
end
diff --git a/features/support/helpers/dogtail.rb b/features/support/helpers/dogtail.rb
index c9cf79d..59fac3c 100644
--- a/features/support/helpers/dogtail.rb
+++ b/features/support/helpers/dogtail.rb
@@ -16,6 +16,10 @@ module Dogtail
:textentry,
]
+ TREE_API_NODE_SEARCH_FIELDS = [
+ :parent,
+ ]
+
TREE_API_NODE_ACTIONS = [
:click,
:doubleClick,
@@ -54,6 +58,9 @@ module Dogtail
@init_lines = @opts[:init_lines] || [
"from dogtail import tree",
"from dogtail.config import config",
+ "config.logDebugToFile = False",
+ "config.logDebugToStdOut = False",
+ "config.blinkOnActions = True",
"config.searchShowingOnly = True",
"application = tree.root.application('#{@app_name}')",
]
@@ -81,12 +88,12 @@ module Dogtail
$vm.file_overwrite(script_path, script, @opts[:user])
args = ["/usr/bin/python '#{script_path}'", @opts]
if @opts[:allow_failure]
- $vm.execute(*args)
+ ret = $vm.execute(*args)
else
- $vm.execute_successfully(*args)
+ ret = $vm.execute_successfully(*args)
end
- ensure
$vm.execute("rm -f '#{script_path}'")
+ ret
end
def self.value_to_s(v)
@@ -109,6 +116,7 @@ module Dogtail
# into the parentheses of a Python function call.
# Example: [42, {:foo => 'bar'}] => "42, foo = 'bar'"
def self.args_to_s(args)
+ return "" if args.size == 0
args_list = args
args_hash = nil
if args_list.class == Array && args_list.last.class == Hash
@@ -128,9 +136,39 @@ module Dogtail
end
end
+ def exist?
+ @opts[:allow_failure] = true
+ # We do not want any retries since this method should return the
+ # result for the immediate situation, not for the situation up
+ # to 20 retries in the future.
+ optimization = "config.searchCutoffCount = 1"
+ @init_lines << optimization unless @init_lines.include?(optimization)
+ run.success?
+ end
+
+ def wait_vanish(timeout)
+ try_for(timeout) { not(exist?) }
+ end
+
# Equivalent to the Tree API's Node.findChildren(), with the
# arguments constructing a GenericPredicate to use as parameter.
def children(*args)
+ non_predicates = [:recursive, :showingOnly]
+ findChildren_opts = []
+ findChildren_opts_hash = Hash.new
+ if args.last.class == Hash
+ args_hash = args.last
+ non_predicates.each do |opt|
+ if args_hash.has_key?(opt)
+ findChildren_opts_hash[opt] = args_hash[opt]
+ args_hash.delete(opt)
+ end
+ end
+ end
+ findChildren_opts = ""
+ if findChildren_opts_hash.size > 0
+ findChildren_opts = ", " + self.class.args_to_s([findChildren_opts_hash])
+ end
# A fundamental assumption of ScriptProxy is that we will only
# act on *one* object at a time. If we were to allow more, we'd
# have to port looping, conditionals and much more into our
@@ -140,9 +178,10 @@ module Dogtail
# internal a11y AT-SPI "path" to uniquely identify a Dogtail
# node, so we can give handles to each of them that can be used
# later to re-find them.
+ predicate_opts = self.class.args_to_s(args)
find_paths_script_lines = [
"from dogtail import predicate",
- "for n in #{build_line}.findChildren(predicate.GenericPredicate(#{self.class.args_to_s(args)})):",
+ "for n in #{build_line}.findChildren(predicate.GenericPredicate(#{predicate_opts})#{findChildren_opts}):",
" print(n.path)",
]
a11y_at_spi_paths = run(find_paths_script_lines).stdout.chomp.split("\n")
@@ -180,6 +219,14 @@ module Dogtail
get_field('text')
end
+ def text=(value)
+ set_field('text', value)
+ end
+
+ def name
+ get_field('name')
+ end
+
def proxy_call(method, args)
args_str = self.class.args_to_s(args)
method_call = "#{method.to_s}(#{args_str})"
@@ -198,6 +245,18 @@ module Dogtail
end
end
+ TREE_API_NODE_SEARCH_FIELDS.each do |field|
+ define_method(field) do
+ Node.new(
+ @app_name,
+ @opts.merge(
+ init_lines: @init_lines,
+ components: @components + [field]
+ )
+ )
+ end
+ end
+
end
class Node < Application
diff --git a/features/support/helpers/exec_helper.rb b/features/support/helpers/exec_helper.rb
index 98fba8c..6f221de 100644
--- a/features/support/helpers/exec_helper.rb
+++ b/features/support/helpers/exec_helper.rb
@@ -3,6 +3,8 @@ require 'socket'
class VMCommand
+ @@request_id ||= 0
+
attr_reader :cmd, :returncode, :stdout, :stderr
def initialize(vm, cmd, options = {})
@@ -29,25 +31,23 @@ class VMCommand
options[:user] ||= "root"
options[:spawn] ||= false
type = options[:spawn] ? "spawn" : "call"
+ id = (@@request_id += 1)
socket = TCPSocket.new("127.0.0.1", vm.get_remote_shell_port)
debug_log("#{type}ing as #{options[:user]}: #{cmd}")
- begin
- socket.puts(JSON.dump([type, options[:user], cmd]))
+ socket.puts(JSON.dump([id, type, options[:user], cmd]))
+ loop do
s = socket.readline(sep = "\0").chomp("\0")
- ensure
- socket.close
- end
- debug_log("#{type} returned: #{s}") if not(options[:spawn])
- begin
- return JSON.load(s)
- rescue JSON::ParserError
- # The server often returns something unparsable for the very
- # first execute() command issued after a VM start/restore
- # (generally from wait_until_remote_shell_is_up()) presumably
- # because the TCP -> serial link isn't properly setup yet. All
- # will be well after that initial hickup, so we just retry.
- return VMCommand.execute(vm, cmd, options)
+ response_id, *rest = JSON.load(s)
+ if response_id == id
+ debug_log("#{type} returned: #{s}") if not(options[:spawn])
+ return rest
+ else
+ debug_log("Dropped out-of-order remote shell response: " +
+ "got id #{response_id} but expected id #{id}")
+ end
end
+ ensure
+ socket.close if defined?(socket) && socket
end
def success?
diff --git a/features/support/helpers/storage_helper.rb b/features/support/helpers/storage_helper.rb
index 21537a9..0e452ed 100644
--- a/features/support/helpers/storage_helper.rb
+++ b/features/support/helpers/storage_helper.rb
@@ -24,7 +24,8 @@ class VMStorage
rescue Libvirt::RetrieveError
@pool = nil
end
- if @pool and not(KEEP_SNAPSHOTS)
+ if @pool and (not(KEEP_SNAPSHOTS) or
+ (KEEP_SNAPSHOTS and not(Dir.exists?(@pool_path))))
VMStorage.clear_storage_pool(@pool)
@pool = nil
end
diff --git a/features/support/helpers/vm_helper.rb b/features/support/helpers/vm_helper.rb
index 72448f3..04cf7bc 100644
--- a/features/support/helpers/vm_helper.rb
+++ b/features/support/helpers/vm_helper.rb
@@ -63,7 +63,7 @@ end
class VM
- attr_reader :domain, :display, :vmnet, :storage
+ attr_reader :domain, :domain_name, :display, :vmnet, :storage
def initialize(virt, xml_path, vmnet, storage, x_display)
@virt = virt
@@ -147,30 +147,40 @@ class VM
update(domain_xml.to_s)
end
- def set_cdrom_image(image)
- image = nil if image == ''
- domain_xml = REXML::Document.new(@domain.xml_desc)
- domain_xml.elements.each('domain/devices/disk') do |e|
- if e.attribute('device').to_s == "cdrom"
- if image.nil?
- e.elements.delete('source')
- else
- if ! e.elements['source']
- e.add_element('source')
- end
- e.elements['source'].attributes['file'] = image
- end
- if is_running?
- @domain.update_device(e.to_s)
- else
- update(domain_xml.to_s)
- end
- end
+ def add_cdrom_device
+ if is_running?
+ raise "Can't attach a CDROM device to a running domain"
+ end
+ domain_rexml = REXML::Document.new(@domain.xml_desc)
+ if domain_rexml.elements["domain/devices/disk[@device='cdrom']"]
+ raise "A CDROM device already exists"
+ end
+ cdrom_rexml = REXML::Document.new(File.read("#{@xml_path}/cdrom.xml")).root
+ domain_rexml.elements['domain/devices'].add_element(cdrom_rexml)
+ update(domain_rexml.to_s)
+ end
+
+ def remove_cdrom_device
+ if is_running?
+ raise "Can't detach a CDROM device to a running domain"
+ end
+ domain_rexml = REXML::Document.new(@domain.xml_desc)
+ cdrom_el = domain_rexml.elements["domain/devices/disk[@device='cdrom']"]
+ if cdrom_el.nil?
+ raise "No CDROM device is present"
end
+ domain_rexml.elements["domain/devices"].delete_element(cdrom_el)
+ update(domain_rexml.to_s)
end
- def remove_cdrom
- set_cdrom_image(nil)
+ def eject_cdrom
+ domain_rexml = REXML::Document.new(@domain.xml_desc)
+ cdrom_el = domain_rexml.elements["domain/devices/disk[@device='cdrom']"]
+ if cdrom_el.nil?
+ raise "No CDROM device is present"
+ end
+ cdrom_el.delete_element('source')
+ update(domain_rexml.to_s)
rescue Libvirt::Error => e
# While the CD-ROM is removed successfully we still get this
# error, so let's ignore it.
@@ -181,12 +191,27 @@ class VM
raise e if not(Regexp.new(acceptable_error).match(e.to_s))
end
+ def set_cdrom_image(image)
+ if image.nil? or image == ''
+ raise "Can't set cdrom image to an empty string"
+ end
+ eject_cdrom
+ domain_rexml = REXML::Document.new(@domain.xml_desc)
+ cdrom_el = domain_rexml.elements["domain/devices/disk[@device='cdrom']"]
+ cdrom_el.add_element('source', { 'file' => image })
+ update(domain_rexml.to_s)
+ end
+
def set_cdrom_boot(image)
if is_running?
raise "boot settings can only be set for inactive vms"
end
- set_boot_device('cdrom')
+ domain_rexml = REXML::Document.new(@domain.xml_desc)
+ if not domain_rexml.elements["domain/devices/disk[@device='cdrom']"]
+ add_cdrom_device
+ end
set_cdrom_image(image)
+ set_boot_device('cdrom')
end
def list_disk_devs
@@ -309,9 +334,16 @@ class VM
end
plug_drive(name, type) if not(disk_plugged?(name))
set_boot_device('hd')
- # For some reason setting the boot device doesn't prevent cdrom
- # boot unless it's empty
- remove_cdrom
+ # XXX:Stretch: since our isotesters upgraded QEMU from
+ # 2.5+dfsg-4~bpo8+1 to 2.6+dfsg-3.1~bpo8+1 it seems we must remove
+ # the CDROM device to allow disk boot. This is not the case with the same
+ # version on Debian Sid. Let's hope we can remove this ugly
+ # workaround when we only support running the automated test suite
+ # on Stretch.
+ domain_rexml = REXML::Document.new(@domain.xml_desc)
+ if domain_rexml.elements["domain/devices/disk[@device='cdrom']"]
+ remove_cdrom_device
+ end
end
# XXX-9p: Shares don't work together with snapshot save+restore. See
diff --git a/features/support/hooks.rb b/features/support/hooks.rb
index 6589d9b..3e2d7e1 100644
--- a/features/support/hooks.rb
+++ b/features/support/hooks.rb
@@ -26,6 +26,8 @@ AfterConfiguration do |config|
# excluding persistence) and will create yet another disk and
# install Tails on it. This should be the peak of disk usage.
'features/usb_install.feature',
+ # This feature needs a copy of the ISO and creates a new disk.
+ 'features/usb_upgrade.feature',
]
feature_files = config.feature_files
# The &-intersection is specified to keep the element ordering of
diff --git a/features/tor_enforcement.feature b/features/tor_enforcement.feature
index a958b14..fd4acef 100644
--- a/features/tor_enforcement.feature
+++ b/features/tor_enforcement.feature
@@ -5,10 +5,6 @@ Feature: The Tor enforcement is effective
And as a Tails developer
I want to ensure that the automated test suite detects firewall leaks reliably
- Scenario: Tails' Tor binary is configured to use the expected Tor authorities
- Given I have started Tails from DVD and logged in and the network is connected
- Then the Tor binary is configured to use the expected Tor authorities
-
Scenario: The firewall configuration is very restrictive
Given I have started Tails from DVD and logged in and the network is connected
Then the firewall's policy is to drop all IPv4 traffic
diff --git a/features/torified_browsing.feature b/features/torified_browsing.feature
index 3811968..39e1dbf 100644
--- a/features/torified_browsing.feature
+++ b/features/torified_browsing.feature
@@ -50,6 +50,17 @@ Feature: Browsing the web using the Tor Browser
And I click the HTML5 play button
And 1 application is playing audio after 10 seconds
+ @check_tor_leaks @fragile
+ Scenario: Watching a WebM video
+ Given I have started Tails from DVD and logged in and the network is connected
+ When I start the Tor Browser
+ And the Tor Browser has started and loaded the startup page
+ And I open the address "https://tails.boum.org/lib/test_suite/test.webm" in the Tor Browser
+ And I click the blocked video icon
+ And I see "TorBrowserNoScriptTemporarilyAllowDialog.png" after at most 30 seconds
+ And I accept to temporarily allow playing this video
+ Then I see "TorBrowserSampleRemoteWebMVideoFrame.png" after at most 180 seconds
+
#11592
@fragile
Scenario: I can view a file stored in "~/Tor Browser" but not in ~/.gnupg
@@ -123,7 +134,7 @@ Feature: Browsing the web using the Tor Browser
And the Tor Browser has started and loaded the startup page
Then the Tor Browser has no plugins installed
- #10720, #11592
+ #11592
@fragile
Scenario: The persistent Tor Browser directory is usable
Given I have started Tails without network from a USB drive with a persistent partition enabled and logged in
@@ -140,7 +151,7 @@ Feature: Browsing the web using the Tor Browser
Then I see "TorBrowserSavedStartupPage.png" after at most 10 seconds
And I can print the current page as "output.pdf" to the persistent Tor Browser directory
- #10720, #11585
+ #11585
@fragile
Scenario: Persistent browser bookmarks
Given I have started Tails without network from a USB drive with a persistent partition enabled and logged in
diff --git a/features/totem.feature b/features/totem.feature
index c702694..d8d9054 100644
--- a/features/totem.feature
+++ b/features/totem.feature
@@ -39,14 +39,18 @@ Feature: Using Totem
# Due to our AppArmor aliases, /live/overlay will be treated
# as /lib/live/mount/overlay.
And AppArmor has denied "/usr/bin/totem" from opening "/lib/live/mount/overlay/home/amnesia/.gnupg/video.mp4"
+ Given I close Totem
+ And I copy "/home/amnesia/video.mp4" to "/home/amnesia/.purple/otr.private_key" as user "amnesia"
+ And I restart monitoring the AppArmor log of "/usr/bin/totem"
+ When I try to open "/home/amnesia/.purple/otr.private_key" with Totem
+ Then I see "TotemUnableToOpen.png" after at most 10 seconds
+ And AppArmor has denied "/usr/bin/totem" from opening "/home/amnesia/.purple/otr.private_key"
@check_tor_leaks @fragile
Scenario: Watching a WebM video over HTTPS
Given I have started Tails from DVD and logged in and the network is connected
Then I can watch a WebM video over HTTPs
- #10720: Tails Installer freezes on Jenkins
- @fragile
Scenario: Watching MP4 videos stored on the persistent volume should work as expected given our AppArmor confinement
Given I have started Tails without network from a USB drive with a persistent partition and stopped at Tails Greeter's login screen
# Due to bug #5571 we have to reboot to be able to use
diff --git a/features/untrusted_partitions.feature b/features/untrusted_partitions.feature
index b1045c4..ff94cd5 100644
--- a/features/untrusted_partitions.feature
+++ b/features/untrusted_partitions.feature
@@ -7,7 +7,7 @@ Feature: Untrusted partitions
Given a computer
And I temporarily create a 100 MiB disk named "swap"
And I create a gpt swap partition on disk "swap"
- And I plug ide drive "swap"
+ And I plug sata drive "swap"
When I start Tails with network unplugged and I login
Then a "swap" partition was detected by Tails on drive "swap"
But Tails has no disk swap enabled
@@ -36,7 +36,7 @@ Feature: Untrusted partitions
Given a computer
And I temporarily create a 100 MiB disk named "fake_TailsData"
And I create a gpt partition labeled "TailsData" with an ext4 filesystem encrypted with password "asdf" on disk "fake_TailsData"
- And I plug ide drive "fake_TailsData"
+ And I plug sata drive "fake_TailsData"
When I start the computer
And the computer boots Tails
Then drive "fake_TailsData" is detected by Tails
@@ -46,16 +46,16 @@ Feature: Untrusted partitions
Given a computer
And I temporarily create a 2 GiB disk named "live_hd"
And I cat an ISO of the Tails image to disk "live_hd"
- And the computer is set to boot from ide drive "live_hd"
+ And the computer is set to boot from sata drive "live_hd"
And I set Tails to boot with options "live-media="
When I start Tails with network unplugged and I login
- Then Tails is running from ide drive "live_hd"
+ Then Tails is running from sata drive "live_hd"
Scenario: Tails booting from a DVD does not use live systems stored on hard drives
Given a computer
And I temporarily create a 2 GiB disk named "live_hd"
And I cat an ISO of the Tails image to disk "live_hd"
- And I plug ide drive "live_hd"
+ And I plug sata drive "live_hd"
And I start Tails from DVD with network unplugged and I login
Then drive "live_hd" is detected by Tails
And drive "live_hd" is not mounted
@@ -64,7 +64,7 @@ Feature: Untrusted partitions
Given a computer
And I temporarily create a 100 MiB disk named "gpt_ext2"
And I create a gpt partition with an ext2 filesystem on disk "gpt_ext2"
- And I plug ide drive "gpt_ext2"
+ And I plug sata drive "gpt_ext2"
And I start Tails from DVD with network unplugged and I login
Then drive "gpt_ext2" is detected by Tails
And drive "gpt_ext2" is not mounted
@@ -73,7 +73,7 @@ Feature: Untrusted partitions
Given a computer
And I temporarily create a 100 MiB disk named "msdos_fat32"
And I create an msdos partition with a vfat filesystem on disk "msdos_fat32"
- And I plug ide drive "msdos_fat32"
+ And I plug sata drive "msdos_fat32"
And I start Tails from DVD with network unplugged and I login
Then drive "msdos_fat32" is detected by Tails
And drive "msdos_fat32" is not mounted
diff --git a/features/usb_install.feature b/features/usb_install.feature
index 166386d..64da8ee 100644
--- a/features/usb_install.feature
+++ b/features/usb_install.feature
@@ -27,8 +27,6 @@ Feature: Installing Tails to a USB drive
Then no USB drive is selected
And a suitable USB device is not found
- #10720: Tails Installer freezes on Jenkins
- @fragile
Scenario: Installing Tails to a pristine USB drive
Given I have started Tails from DVD without network and logged in
And I temporarily create a 4 GiB disk named "install"
@@ -37,16 +35,12 @@ Feature: Installing Tails to a USB drive
Then the running Tails is installed on USB drive "install"
But there is no persistence partition on USB drive "install"
- #10720: Tails Installer freezes on Jenkins
- @fragile
Scenario: Booting Tails from a USB drive without a persistent partition and creating one
Given I have started Tails without network from a USB drive without a persistent partition and stopped at Tails Greeter's login screen
And I log in to a new session
When I create a persistent partition
Then a Tails persistence partition exists on USB drive "__internal"
- #10720: Tails Installer freezes on Jenkins
- @fragile
Scenario: Booting Tails from a USB drive without a persistent partition
Given I have started Tails without network from a USB drive without a persistent partition and stopped at Tails Greeter's login screen
When I log in to a new session
@@ -54,7 +48,6 @@ Feature: Installing Tails to a USB drive
And the persistent Tor Browser directory does not exist
And there is no persistence partition on USB drive "__internal"
- #10720: Tails Installer freezes on Jenkins
#11583
@fragile
Scenario: Booting Tails from a USB drive in UEFI mode
@@ -67,8 +60,6 @@ Feature: Installing Tails to a USB drive
And the boot device has safe access rights
And Tails has started in UEFI mode
- #10720: Tails Installer freezes on Jenkins
- @fragile
Scenario: Installing Tails to a USB drive with an MBR partition table but no partitions, and making sure that it boots
Given I have started Tails from DVD without network and logged in
And I temporarily create a 4 GiB disk named "mbr"
@@ -83,8 +74,6 @@ Feature: Installing Tails to a USB drive
And the boot device has safe access rights
And there is no persistence partition on USB drive "mbr"
- #10720: Tails Installer freezes on Jenkins
- @fragile
Scenario: Cat:ing a Tails isohybrid to a USB drive and booting it, then trying to upgrading it but ending up having to do a fresh installation, which boots
Given a computer
And I temporarily create a 4 GiB disk named "isohybrid"
diff --git a/features/usb_upgrade.feature b/features/usb_upgrade.feature
index fc61308..0aa9a95 100644
--- a/features/usb_upgrade.feature
+++ b/features/usb_upgrade.feature
@@ -1,5 +1,4 @@
-#10720: Tails Installer freezes on Jenkins
-@product @fragile
+@product
Feature: Upgrading an old Tails USB installation
As a Tails user
If I have an old versoin of Tails installed on a USB device
@@ -45,7 +44,7 @@ Feature: Upgrading an old Tails USB installation
And I temporarily create a 4 GiB disk named "gptfat"
And I create a gpt partition with a vfat filesystem on disk "gptfat"
And I plug USB drive "gptfat"
- And I start Tails Installer in "Upgrade from ISO" mode
+ And I start Tails Installer in "Clone & Upgrade" mode
Then a suitable USB device is not found
And I am told that the destination device cannot be upgraded
@@ -160,3 +159,24 @@ Feature: Upgrading an old Tails USB installation
And the boot device has safe access rights
And the expected persistent files created with the old Tails version are present in the filesystem
And all persistent directories from the old Tails version have safe access rights
+
+ Scenario: Upgrading Tails with Tails Upgrader through an incremental upgrade
+ Given I have started Tails without network from a USB drive with a persistent partition enabled and logged in
+ And Tails is fooled to think it is running version 1.0~test
+ And the file system changes introduced in version 1.1~test are not present
+ When the network is plugged
+ And Tor is ready
+ And all notifications have disappeared
+ Then I am proposed to install an incremental upgrade to version 1.1~test
+ And I can successfully install the incremental upgrade to version 1.1~test
+ Given I shutdown Tails and wait for the computer to power off
+ When I start Tails from USB drive "__internal" with network unplugged and I login with persistence enabled
+ Then Tails is running version 1.1~test
+ And all persistence presets are enabled
+ And the file system changes introduced in version 1.1~test are present
+ When the network is plugged
+ And the network connection is ready within 30 seconds
+ And all notifications have disappeared
+ # Regression test on #8158 (i.e. the IUK's filesystem is not part of the Unsafe Browser's chroot)
+ And I successfully start the Unsafe Browser
+ Then the file system changes introduced in version 1.1~test are present in the Unsafe Browser's chroot
diff --git a/features/virtualization.feature b/features/virtualization.feature
index e04a5ff..38a4e80 100644
--- a/features/virtualization.feature
+++ b/features/virtualization.feature
@@ -2,6 +2,8 @@
Feature: Virtualization support
Scenario: VirtualBox guest modules are available
- Given I have started Tails from DVD without network and logged in
- When Tails has booted a 64-bit kernel
+ Given a computer
+ And the computer is an old pentium without the PAE extension
+ And I start Tails from DVD with network unplugged and I login
+ When Tails has booted a 32-bit kernel
Then the VirtualBox guest modules are available