summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorintrigeri <intrigeri@boum.org>2017-10-09 12:39:58 +0000
committerintrigeri <intrigeri@boum.org>2017-10-09 12:39:58 +0000
commit22d6549dca95adda1bca3e6581bdbb92657bc50e (patch)
tree470200e7ef94d35a99d56bfc243b35f6af02130a
parentceb6249a2ac87079ff28b25d32fcac4dff2751f6 (diff)
parent7c92cec5853d88c2b96d6e93614a21cd35e8c700 (diff)
Merge branch 'devel' into feature/buster
-rw-r--r--features/config/defaults.yml1
-rw-r--r--features/domains/default.xml1
-rw-r--r--features/support/config.rb2
-rw-r--r--features/support/helpers/remote_shell.rb2
-rw-r--r--features/support/helpers/sikuli_helper.rb127
-rw-r--r--features/support/hooks.rb8
-rwxr-xr-xrun_test_suite9
7 files changed, 85 insertions, 65 deletions
diff --git a/features/config/defaults.yml b/features/config/defaults.yml
index 1e7f8ea..0c450ae 100644
--- a/features/config/defaults.yml
+++ b/features/config/defaults.yml
@@ -3,6 +3,7 @@ CAPTURE_ALL: false
INTERACTIVE_DEBUGGING: false
MAX_NEW_TOR_CIRCUIT_RETRIES: 10
SIKULI_RETRY_FINDFAILED: false
+SIKULI_FUZZY_IMAGE_MATCHING: false
TMPDIR: "/tmp/TailsToaster"
Unsafe_SSH_private_key: |
diff --git a/features/domains/default.xml b/features/domains/default.xml
index 58a9bf8..5398735 100644
--- a/features/domains/default.xml
+++ b/features/domains/default.xml
@@ -37,6 +37,7 @@
<target type='virtio' name='com.redhat.spice.0'/>
</channel>
<graphics type='spice' port='-1' tlsPort='-1' autoport='yes'>
+ <clipboard copypaste='no'/>
<mouse mode='client'/>
</graphics>
<sound model='ich6'/>
diff --git a/features/support/config.rb b/features/support/config.rb
index 79c1b30..c654932 100644
--- a/features/support/config.rb
+++ b/features/support/config.rb
@@ -59,6 +59,8 @@ loop do
break
end
end
+SIKULI_CANDIDATES_DIR = "#{ARTIFACTS_DIR}/sikuli_candidates"
+SIKULI_IMAGE_PATH = "#{Dir.pwd}/features/images/"
# Constants that are statically initialized.
CONFIGURED_KEYSERVER_HOSTNAME = 'jirk5u4osbsr34t5.onion'
diff --git a/features/support/helpers/remote_shell.rb b/features/support/helpers/remote_shell.rb
index b890578..aea20dc 100644
--- a/features/support/helpers/remote_shell.rb
+++ b/features/support/helpers/remote_shell.rb
@@ -157,7 +157,7 @@ module RemoteShell
end
def read()
- Base64.decode64(self.class.open(@vm, 'read', @path))
+ Base64.decode64(self.class.open(@vm, 'read', @path)).force_encoding('utf-8')
end
def write(data)
diff --git a/features/support/helpers/sikuli_helper.rb b/features/support/helpers/sikuli_helper.rb
index a98120d..f8a2b45 100644
--- a/features/support/helpers/sikuli_helper.rb
+++ b/features/support/helpers/sikuli_helper.rb
@@ -1,19 +1,9 @@
require 'rjb'
require 'rjbextension'
$LOAD_PATH << ENV['SIKULI_HOME']
-begin
- require 'sikulixapi.jar'
- USING_SIKULIX = true
-rescue LoadError
- require 'sikuli-script.jar'
- USING_SIKULIX = false
-end
+require 'sikulixapi.jar'
Rjb::load
-def using_sikulix?
- USING_SIKULIX
-end
-
package_members = [
"java.io.FileOutputStream",
"java.io.PrintStream",
@@ -26,15 +16,10 @@ package_members = [
"org.sikuli.script.Pattern",
"org.sikuli.script.Region",
"org.sikuli.script.Screen",
+ "org.sikuli.basics.Settings",
+ "org.sikuli.script.ImagePath",
]
-if using_sikulix?
- package_members << "org.sikuli.basics.Settings"
- package_members << "org.sikuli.script.ImagePath"
-else
- package_members << "org.sikuli.script.Settings"
-end
-
# Note: we can't use anything that starts with "Java" on the right
# side, otherwise the :Java constant is defined and then
# test/unit/assertions will use JRuby-specific code that breaks our
@@ -70,8 +55,45 @@ def bind_java_to_pseudo_fifo_logger
RJava::Lang::System.setOut(print_stream)
end
-def findfailed_hook(pic)
- pause("FindFailed for: '#{pic}'")
+def findfailed_hook(proxy, exception, override_method, signature, args)
+ picture = args.first
+ candidate_path = "#{SIKULI_CANDIDATES_DIR}/#{picture}"
+ if ! File.exist?(candidate_path)
+ [0.80, 0.70, 0.60, 0.50, 0.40].each do |similarity|
+ pattern = Sikuli::Pattern.new(picture)
+ pattern.similar(similarity)
+ match = proxy._invoke('exists', 'Ljava.lang.Object;', pattern)
+ if match
+ debug_log("Found fuzzy candidate picture for #{picture} with " +
+ "similarity #{similarity}")
+ capture = proxy._invoke('capture', 'Lorg.sikuli.script.Region;', match)
+ capture_path = capture.getFilename
+ # Let's verify that our screen capture actually matches
+ # with the default similarity
+ if proxy._invoke('exists', 'Ljava.lang.Object;', capture_path)
+ FileUtils.mkdir_p(SIKULI_CANDIDATES_DIR)
+ FileUtils.mv(capture_path, candidate_path)
+ break
+ end
+ end
+ end
+ if ! File.exist?(candidate_path)
+ debug_log("Failed to find fuzzy candidate picture for #{picture}")
+ end
+ end
+
+ if $config['SIKULI_FUZZY_IMAGE_MATCHING'] && File.exist?(candidate_path)
+ debug_log("Using fuzzy candidate picture for #{picture}")
+ args_with_candidate = [candidate_path] + args.drop(1)
+ return proxy._invoke(override_method, signature, *args_with_candidate)
+ end
+
+ if $config["SIKULI_RETRY_FINDFAILED"]
+ pause("FindFailed for: '#{picture}'")
+ return proxy._invoke(override_method, signature, *args)
+ else
+ raise exception
+ end
end
# Since rjb imports Java classes without creating a corresponding
@@ -100,39 +122,29 @@ end
def sikuli_script_proxy.new(*args)
s = $_original_sikuli_screen_new.call(*args)
- if $config["SIKULI_RETRY_FINDFAILED"]
- # The usage of `_invoke()` below exemplifies how one can wrap
- # around Java objects' methods when they're imported using RJB. It
- # isn't pretty. The seconds argument is the parameter signature,
- # which can be obtained by creating the intended Java object using
- # RJB, and then calling its `java_methods` method.
-
- def s.wait(pic, time)
- self._invoke('wait', 'Ljava.lang.Object;D', pic, time)
- rescue FindFailed => e
- findfailed_hook(pic)
- self._invoke('wait', 'Ljava.lang.Object;D', pic, time)
- end
-
- def s.find(pic)
- self._invoke('find', 'Ljava.lang.Object;', pic)
- rescue FindFailed => e
- findfailed_hook(pic)
- self._invoke('find', 'Ljava.lang.Object;', pic)
- end
-
- def s.waitVanish(pic, time)
- self._invoke('waitVanish', 'Ljava.lang.Object;D', pic, time)
- rescue FindFailed => e
- findfailed_hook(pic)
- self._invoke('waitVanish', 'Ljava.lang.Object;D', pic, time)
- end
-
- def s.click(pic)
- self._invoke('click', 'Ljava.lang.Object;', pic)
- rescue FindFailed => e
- findfailed_hook(pic)
- self._invoke('click', 'Ljava.lang.Object;', pic)
+ findfail_overrides = [
+ ['wait', 'Ljava.lang.Object;D'],
+ ['find', 'Ljava.lang.Object;'],
+ ['waitVanish', 'Ljava.lang.Object;D'],
+ ['click', 'Ljava.lang.Object;'],
+ ]
+
+ # The usage of `_invoke()` below exemplifies how one can wrap
+ # around Java objects' methods when they're imported using RJB. It
+ # isn't pretty. The seconds argument is the parameter signature,
+ # which can be obtained by creating the intended Java object using
+ # RJB, and then calling its `java_methods` method.
+ findfail_overrides.each do |method_name, signature|
+ s.define_singleton_method(method_name) do |*args|
+ begin
+ self._invoke(method_name, signature, *args)
+ rescue Exception => exception
+ # We really would like to only capture the FindFailed
+ # exceptions imported by rjb here, but that hasn't happened
+ # at the time this code is run. Yeah, meta-programming! :)
+ raise e unless exception.class.name == "FindFailed"
+ findfailed_hook(self, exception, method_name, signature, args)
+ end
end
end
@@ -214,14 +226,7 @@ def sikuli_script_proxy.new(*args)
end
# Configure sikuli
-if using_sikulix?
- Sikuli::ImagePath.add("#{Dir.pwd}/features/images/")
-else
- java.lang.System.setProperty("SIKULI_IMAGE_PATH",
- "#{Dir.pwd}/features/images/")
- ENV["SIKULI_IMAGE_PATH"] = "#{Dir.pwd}/features/images/"
-end
-
+Sikuli::ImagePath.add(SIKULI_IMAGE_PATH)
# ruby and rjb doesn't play well together when it comes to static
# fields (and possibly methods) so we instantiate and access the field
# via objects instead. It actually works inside this file, but when
diff --git a/features/support/hooks.rb b/features/support/hooks.rb
index 4b4521f..4862dac 100644
--- a/features/support/hooks.rb
+++ b/features/support/hooks.rb
@@ -134,9 +134,13 @@ end
def save_journal(path)
File.open("#{path}/systemd.journal", 'w') { |file|
- file.write($vm.execute('journalctl -a --no-pager').stdout)
+ $vm.execute('journalctl -a --no-pager > /tmp/systemd.journal')
+ file.write($vm.file_content('/tmp/systemd.journal'))
}
save_failure_artifact("Systemd journal", "#{path}/systemd.journal")
+rescue Exception => e
+ info_log("Exception thrown while trying to save the journal: " +
+ "#{e.class.name}: #{e}")
end
# Due to Tails' Tor enforcement, we only allow contacting hosts that
@@ -279,7 +283,7 @@ After('@product') do |scenario|
# well cause the remote shell to not respond any more, e.g. when
# we cause a system crash), so let's collect everything depending
# on the remote shell here:
- if $vm.remote_shell_is_up?
+ if $vm && $vm.remote_shell_is_up?
save_journal($config['TMPDIR'])
end
$failure_artifacts.sort!
diff --git a/run_test_suite b/run_test_suite
index 5e4655f..4f2f783 100755
--- a/run_test_suite
+++ b/run_test_suite
@@ -72,6 +72,9 @@ Options for '@product' features:
--retry-find Print a warning whenever Sikuli fails to find an image
and allow *one* retry after pressing ENTER. This is useful
for updating outdated images.
+ --fuzzy-image-matching
+ When Sikuli fails to find an image, let it retry with more
+ fuzziness (or \"lower similarity factor\" in Sikuli terms).
--tmpdir Directory where various temporary files are written
during a test, e.g. VM snapshots and memory dumps,
failure screenshots, pcap files and disk images
@@ -188,10 +191,11 @@ VNC_SERVER=
INTERACTIVE_DEBUGGING=
KEEP_SNAPSHOTS=
SIKULI_RETRY_FINDFAILED=
+SIKULI_FUZZY_IMAGE_MATCHING=
TAILS_ISO=
OLD_TAILS_ISO=
-LONGOPTS="artifacts-base-uri:,view,vnc-server-only,capture,capture-all,help,tmpdir:,keep-snapshots,retry-find,iso:,old-iso:,interactive-debugging"
+LONGOPTS="artifacts-base-uri:,view,vnc-server-only,capture,capture-all,help,tmpdir:,keep-snapshots,retry-find,fuzzy-image-matching,iso:,old-iso:,interactive-debugging"
OPTS=$(getopt -o "" --longoptions $LONGOPTS -n "${NAME}" -- "$@")
eval set -- "$OPTS"
while [ $# -gt 0 ]; do
@@ -226,6 +230,9 @@ while [ $# -gt 0 ]; do
--retry-find)
export SIKULI_RETRY_FINDFAILED="yes"
;;
+ --fuzzy-image-matching)
+ export SIKULI_FUZZY_IMAGE_MATCHING="yes"
+ ;;
--tmpdir)
shift
export TMPDIR="$(readlink -f $1)"