summaryrefslogtreecommitdiff
diff options
authorUbuntu <ubuntu@cert-jenkins-slave-1-201406-15260.maas>2022-04-13 08:47:35 +0000
committerUbuntu <ubuntu@cert-jenkins-slave-1-201406-15260.maas>2022-04-13 08:47:35 +0000
commit3fecc91517cba898b3218616755bdb142b34c2a0 (patch)
treed6318b33d15319c0adfb59aeaf67b1a79ccb8afe
parent3a75e96f15036697cad5247029dfa4a6111f708e (diff)
parente082b09989614d2add395d9a22669016e4e49eb7 (diff)
Merge #418605 from ~sylvain-pineau/plainbox-provider-checkbox:wayland-support
-rwxr-xr-xbin/gnome_randr_cycle.py139
-rwxr-xr-xbin/rotation_test.py14
-rwxr-xr-xbin/xrandr_cycle.py109
-rw-r--r--units/graphics/jobs.pxu7
-rw-r--r--units/graphics/packaging.pxu8
-rw-r--r--units/suspend/suspend-graphics.pxu7
-rw-r--r--units/suspend/suspend.pxu24
7 files changed, 201 insertions, 107 deletions
diff --git a/bin/gnome_randr_cycle.py b/bin/gnome_randr_cycle.py
new file mode 100755
index 0000000..cf0a7cf
--- /dev/null
+++ b/bin/gnome_randr_cycle.py
@@ -0,0 +1,139 @@
+#!/usr/bin/env python3
+#
+# This file is part of Checkbox.
+#
+# Copyright 2022 Canonical Ltd.
+# Written by:
+# Sylvain Pineau <sylvain.pineau@canonical.com>
+#
+# Checkbox is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 3,
+# as published by the Free Software Foundation.
+#
+# Checkbox is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Checkbox. If not, see <http://www.gnu.org/licenses/>.
+
+import argparse
+import os
+import subprocess
+import sys
+import tarfile
+import time
+
+from collections import OrderedDict
+from fractions import Fraction
+
+parser = argparse.ArgumentParser()
+parser.add_argument('--keyword', default='',
+ help=('A keyword to distinguish the screenshots '
+ 'taken in this run of the script'))
+parser.add_argument('--screenshot-dir',
+ default=os.environ['HOME'],
+ help=('Specify a directory to store screenshots in. '
+ 'Default is %(default)s'))
+args = parser.parse_args()
+
+randrinfo = subprocess.Popen(
+ 'gnome-randr', shell=True, stdout=subprocess.PIPE)
+output = randrinfo.communicate()[0].decode().split('\n')
+
+monitor = ''
+monitors = dict()
+highest_modes = [] # list of highest-res modes for each aspect ratio
+current_modes = [] # remember the user's current settings for cleanup later
+failures = 0 # count the number of failed modesets
+
+for line in output:
+ # Ignore Interlaced modes that are indicated by presence of a
+ # trailing 'i' character.
+ if ':' in line or line == '' or 'i@' in line:
+ continue
+ if not (line.startswith(' ') or line.startswith('\t')):
+ try:
+ monitor = line.split()[0]
+ monitors[monitor] = OrderedDict()
+ continue
+ except IndexError:
+ continue
+ if monitor:
+ modeline = line.split()
+ try:
+ mode, resolution, rate = modeline[:3]
+ width, height = [int(x) for x in resolution.split('x')]
+ aspect = Fraction(width, height)
+ if width < 675 or width / aspect < 530:
+ continue
+ if resolution in monitors[monitor]:
+ existing_rate = monitors[monitor][resolution][4]
+ if rate < existing_rate:
+ continue
+ monitors[monitor][resolution] = (width, aspect, mode, rate)
+ except IndexError:
+ continue
+
+for monitor in monitors.keys():
+ # let's create a dict of aspect_ratio:largest_width for each display
+ # (width, because it's easier to compare simple ints when looking for the
+ # highest value).
+ top_res_per_aspect = OrderedDict()
+ connected = False
+ for resolution in monitors[monitor]:
+ width, aspect, mode, rate = monitors[monitor][resolution]
+ cur_max = top_res_per_aspect.get(aspect, 0)
+ top_res_per_aspect[aspect] = max(cur_max, width)
+ if '*' in rate:
+ connected = True
+ current_modes.append((monitor, resolution, mode, rate))
+ if not connected:
+ continue
+ for aspect_ratio, max_width in reversed(top_res_per_aspect.items()):
+ for resolution in monitors[monitor]:
+ width, aspect, mode, rate = monitors[monitor][resolution]
+ if aspect == aspect_ratio and width == max_width:
+ highest_modes.append((monitor, resolution, mode, rate))
+
+screenshot_path = os.path.join(args.screenshot_dir, 'xrandr_screens')
+
+if args.keyword:
+ screenshot_path = screenshot_path + '_' + args.keyword
+os.makedirs(screenshot_path, exist_ok=True)
+
+for monitor, resolution, mode, rate in highest_modes + current_modes:
+ rate = rate.replace('+', '').replace('*', '')
+ print("Set mode {}@{} for output {}".format(resolution, rate, monitor),
+ flush=True)
+ cmd = 'gnome-randr modify ' + monitor + ' -m ' + mode
+ try:
+ subprocess.run(cmd, check=True, shell=True, stdout=subprocess.PIPE)
+ mode_string = monitor + '_' + resolution
+ filename = os.path.join(screenshot_path, mode_string + '.jpg')
+ cmd = 'gnome-screenshot -f ' + filename
+ result = subprocess.run(cmd, shell=True, check=False)
+ if result.returncode != 0:
+ print("Could not capture screenshot -\n"
+ "you may need to install the package 'gnome-screenshot'.",
+ file=sys.stderr, flush=True)
+ except subprocess.CalledProcessError:
+ failures = failures + 1
+ print('Failed to set mode {} for output {}:'.format(mode, monitor),
+ file=sys.stderr, flush=True)
+ print(' {}'.format(cmd), file=sys.stderr, flush=True)
+ time.sleep(8) # let the hardware recover a bit
+
+# Tar up the screenshots for uploading
+try:
+ with tarfile.open(screenshot_path + '.tgz', 'w:gz') as screen_tar:
+ for screen in os.listdir(screenshot_path):
+ screen_tar.add(screenshot_path + '/' + screen, screen)
+except (IOError, OSError):
+ pass
+
+if failures != 0:
+ exit(1)
+else:
+ exit(0)
diff --git a/bin/rotation_test.py b/bin/rotation_test.py
index f3467b8..d6a5b47 100755
--- a/bin/rotation_test.py
+++ b/bin/rotation_test.py
@@ -23,8 +23,11 @@
# along with Checkbox. If not, see <http://www.gnu.org/licenses/>.
import gi
+import os
import time
import subprocess
+import warnings
+warnings.filterwarnings("ignore", category=DeprecationWarning)
gi.require_version('Gdk', '3.0')
from gi.repository import Gdk # noqa: E402
@@ -35,11 +38,14 @@ def main():
screen = Gdk.Screen.get_default()
output = screen.get_monitor_plug_name(screen.get_primary_monitor())
print("Using output: {}".format(output))
-
for rotation in ['right', 'inverted', 'left', 'normal']:
- print("Changing rotation to: {}".format(rotation))
- subprocess.check_call(
- ['xrandr', '--output', output, '--rotation', rotation])
+ if os.getenv('XDG_SESSION_TYPE') == 'wayland':
+ subprocess.check_call(
+ ['gnome-randr', 'modify', output, '--rotate', rotation])
+ else:
+ print("setting rotation to {}".format(rotation))
+ subprocess.check_call(
+ ['xrandr', '--output', output, '--rotation', rotation])
time.sleep(8)
diff --git a/bin/xrandr_cycle.py b/bin/xrandr_cycle.py
index 6c9afc5..819f12a 100755
--- a/bin/xrandr_cycle.py
+++ b/bin/xrandr_cycle.py
@@ -1,10 +1,7 @@
#!/usr/bin/env python3
import argparse
-import errno
import os
-import re
-import shutil
import subprocess
import sys
import tarfile
@@ -110,106 +107,30 @@ for adapter, params in top_res_per_aspect.items():
highest_modes.append((adapter, mode))
# Now we have a list of the modes we need to test. So let's do just that.
-profile_path = os.environ['HOME'] + '/.shutter/profiles/'
screenshot_path = os.path.join(args.screenshot_dir, 'xrandr_screens')
-# Where to find the shutter.xml template? Two possible locations.
-shutter_xml_template = None
-
-if 'PLAINBOX_PROVIDER_DATA' in os.environ:
- shutter_xml_template = os.path.join(os.environ['PLAINBOX_PROVIDER_DATA'],
- "settings", "shutter.xml")
-else:
- shutter_xml_template = os.path.join(
- os.path.split(os.path.dirname(os.path.realpath(__file__)))[0],
- "data",
- "settings",
- "shutter.xml")
-
if args.keyword:
screenshot_path = screenshot_path + '_' + args.keyword
-
-regex = re.compile(r'filename="[^"\r\n]*"')
-
-# Keep the shutter profile in place before starting
-
-# Any errors creating the directories or copying the template is fatal,
-# since things won't work if we fail.
-try:
- os.makedirs(profile_path, exist_ok=True)
- os.makedirs(screenshot_path, exist_ok=True)
-except OSError as excp:
- raise SystemExit("ERROR: Unable to create "
- "required directories: {}".format(excp))
-
-try:
- if os.path.exists(profile_path) and os.path.isfile(profile_path):
- try:
- os.remove(profile_path)
- except PermissionError as exc:
- print("Warning: could not remove {}. {}".format(
- profile_path, exc))
- else:
- shutil.copy(shutter_xml_template, profile_path)
-except (IOError, OSError) as excp:
- print("ERROR: Unable to copy {} to {}: {}".format(shutter_xml_template,
- profile_path,
- excp))
- if excp.errno == errno.ENOENT:
- print("Try setting PLAINBOX_PROVIDER_DATA to the the data path of a")
- print("provider shipping the 'shutter.xml' template file, usually ")
- print("found under /usr/share.")
- raise SystemExit()
-
-try:
- old_profile = open(profile_path + 'shutter.xml', 'r')
- content = old_profile.read()
- new_profile = open(profile_path + 'shutter.xml', 'w')
- # Replace the folder name with the desired one
- new_profile.write(re.sub(r'folder="[^"\r\n]*"',
- 'folder="%s"' % screenshot_path, content))
- new_profile.close()
- old_profile.close()
-except (IOError, OSError):
- raise SystemExit("ERROR: While updating folder name "
- "in shutter profile: {}".format(sys.exc_info()))
+os.makedirs(screenshot_path, exist_ok=True)
for mode in highest_modes:
+ message = 'Set mode ' + mode[1] + ' for output ' + mode[0]
+ print(message, flush=True)
cmd = 'xrandr --output ' + mode[0] + ' --mode ' + mode[1]
retval = subprocess.call(cmd, shell=True)
if retval != 0:
failures = failures + 1
message = 'Failed to set mode ' + mode[1] + ' for output ' + mode[0]
- failure_messages.append(message)
+ print(message, file=sys.stderr, flush=True)
else:
- # Update shutter profile to save the image as the right name
mode_string = mode[0] + '_' + mode[1]
-
- try:
- old_profile = open(profile_path + 'shutter.xml', 'r')
- content = old_profile.read()
- new_profile = open(profile_path + 'shutter.xml', 'w')
- new_profile.write(regex.sub('filename="%s"' % mode_string,
- content))
- new_profile.close()
- old_profile.close()
-
- shuttercmd = ['shutter', '--profile=shutter', '--full', '-e']
- retval = subprocess.call(shuttercmd, shell=False)
-
- if retval != 0:
- print("""Could not capture screenshot -
- you may need to install the package 'shutter'.""")
-
- except (IOError, OSError):
- print("""Could not configure screenshot tool -
- you may need to install the package 'shutter',
- or check that {}/{} exists and is writable.""".format(
- profile_path,
- 'shutter.xml'))
-
- message = 'Set mode ' + mode[1] + ' for output ' + mode[0]
- success_messages.append(message)
+ filename = os.path.join(screenshot_path, mode_string + '.jpg')
+ cmd = 'gnome-screenshot -f ' + filename
+ result = subprocess.run(cmd, shell=True, check=False)
+ if result.returncode != 0:
+ print("Could not capture screenshot -\n"
+ "you may need to install the package 'gnome-screenshot'.",
+ file=sys.stderr, flush=True)
time.sleep(8) # let the hardware recover a bit
# Put things back the way we found them
@@ -226,14 +147,6 @@ try:
except (IOError, OSError):
pass
-# Output some fun facts and knock off for the day
-
-for message in failure_messages:
- print(message, file=sys.stderr)
-
-for message in success_messages:
- print(message)
-
if failures != 0:
exit(1)
else:
diff --git a/units/graphics/jobs.pxu b/units/graphics/jobs.pxu
index 185193b..4dde304 100644
--- a/units/graphics/jobs.pxu
+++ b/units/graphics/jobs.pxu
@@ -230,7 +230,12 @@ depends: graphics/VESA_drivers_not_in_use
command:
# shellcheck disable=SC1091
source graphics_env.sh {driver} {index}
- xrandr_cycle.py --screenshot-dir "$PLAINBOX_SESSION_SHARE"
+ if [[ $XDG_SESSION_TYPE == "wayland" ]]
+ then
+ gnome_randr_cycle.py --screenshot-dir="$PLAINBOX_SESSION_SHARE"
+ else
+ xrandr_cycle.py --screenshot-dir="$PLAINBOX_SESSION_SHARE"
+ fi
estimated_duration: 250.000
_summary: Test resolution cycling for {vendor} {product}
_description:
diff --git a/units/graphics/packaging.pxu b/units/graphics/packaging.pxu
new file mode 100644
index 0000000..a81bc13
--- /dev/null
+++ b/units/graphics/packaging.pxu
@@ -0,0 +1,8 @@
+unit: packaging meta-data
+os-id: ubuntu
+os-version-id: 22.04
+Depends: gnome-randr
+
+unit: packaging meta-data
+os-id: debian
+Depends: gnome-screenshot
diff --git a/units/suspend/suspend-graphics.pxu b/units/suspend/suspend-graphics.pxu
index 4095273..aa93645 100644
--- a/units/suspend/suspend-graphics.pxu
+++ b/units/suspend/suspend-graphics.pxu
@@ -93,7 +93,12 @@ estimated_duration: 120.0
command:
# shellcheck disable=SC1091
source graphics_env.sh {{ driver }} {{ index }}
- xrandr_cycle.py --keyword={{ index }}_after_suspend --screenshot-dir "$PLAINBOX_SESSION_SHARE"
+ if [[ $XDG_SESSION_TYPE == "wayland" ]]
+ then
+ gnome_randr_cycle.py --keyword={{ index }}_after_suspend --screenshot-dir="$PLAINBOX_SESSION_SHARE"
+ else
+ xrandr_cycle.py --keyword={{ index }}_after_suspend --screenshot-dir="$PLAINBOX_SESSION_SHARE"
+ fi
_description:
PURPOSE:
This test will cycle through the detected display modes
diff --git a/units/suspend/suspend.pxu b/units/suspend/suspend.pxu
index 8f504fc..1225d90 100644
--- a/units/suspend/suspend.pxu
+++ b/units/suspend/suspend.pxu
@@ -1175,7 +1175,13 @@ id: suspend/cycle_resolutions_after_suspend
estimated_duration: 120.0
requires: package.name == 'xorg'
depends: suspend/suspend_advanced_auto
-command: xrandr_cycle.py --keyword=after_suspend --screenshot-dir "$PLAINBOX_SESSION_SHARE"
+command:
+ if [[ $XDG_SESSION_TYPE == "wayland" ]]
+ then
+ gnome_randr_cycle.py --keyword=after_suspend --screenshot-dir="$PLAINBOX_SESSION_SHARE"
+ else
+ xrandr_cycle.py --keyword=after_suspend --screenshot-dir="$PLAINBOX_SESSION_SHARE"
+ fi
_description:
PURPOSE:
This test will cycle through the detected display modes
@@ -1193,7 +1199,13 @@ id: suspend/{index}_cycle_resolutions_after_suspend_{product_slug}
requires: package.name == 'xorg'
depends: suspend/{index}_suspend_after_switch_to_card_{product_slug}
estimated_duration: 120.0
-command: xrandr_cycle.py --keyword={index}_after_suspend --screenshot-dir "$PLAINBOX_SESSION_SHARE"
+command:
+ if [[ $XDG_SESSION_TYPE == "wayland" ]]
+ then
+ gnome_randr_cycle.py --keyword={index}_after_suspend --screenshot-dir="$PLAINBOX_SESSION_SHARE"
+ else
+ xrandr_cycle.py --keyword={index}_after_suspend --screenshot-dir="$PLAINBOX_SESSION_SHARE"
+ fi
_description:
PURPOSE:
This test will cycle through the detected display modes
@@ -1211,7 +1223,13 @@ depends: suspend/suspend_advanced_auto
_description:
This test will check to make sure supported video modes work after a suspend and resume.
This is done automatically by taking screenshots and uploading them as an attachment.
-command: xrandr_cycle.py --keyword=after_suspend --screenshot-dir "$PLAINBOX_SESSION_SHARE"
+command:
+ if [[ $XDG_SESSION_TYPE == "wayland" ]]
+ then
+ gnome_randr_cycle.py --keyword=after_suspend --screenshot-dir="$PLAINBOX_SESSION_SHARE"
+ else
+ xrandr_cycle.py --keyword=after_suspend --screenshot-dir="$PLAINBOX_SESSION_SHARE"
+ fi
plugin: attachment
category_id: com.canonical.plainbox::suspend