summaryrefslogtreecommitdiff
diff options
-rwxr-xr-xbin/camera_test143
-rw-r--r--units/camera/jobs.pxu58
-rw-r--r--units/camera/packaging.pxu3
-rw-r--r--units/camera/test-plan.pxu35
-rw-r--r--units/led/jobs.pxu15
-rw-r--r--units/led/test-plan.pxu8
-rw-r--r--units/miscellanea/jobs.pxu2
-rw-r--r--units/suspend/suspend.pxu65
8 files changed, 145 insertions, 184 deletions
diff --git a/bin/camera_test b/bin/camera_test
index 6128c0f..4ef90d7 100755
--- a/bin/camera_test
+++ b/bin/camera_test
@@ -2,7 +2,10 @@
#
# This file is part of Checkbox.
#
-# Copyright 2008-2012 Canonical Ltd.
+# Copyright 2008-2018 Canonical Ltd.
+# Written by:
+# Matt Fischer <matt@mattfischer.com>
+# Sylvain Pineau <sylvain.pineau@canonical.com>
#
# The v4l2 ioctl code comes from the Python bindings for the v4l2
# userspace api (http://pypi.python.org/pypi/v4l2):
@@ -15,7 +18,6 @@
# 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
@@ -36,9 +38,7 @@ import os
import re
import struct
import sys
-import time
-from gi.repository import GObject
from glob import glob
from subprocess import check_call, CalledProcessError, STDOUT
from tempfile import NamedTemporaryFile
@@ -151,9 +151,11 @@ class v4l2_fmtdesc(ctypes.Structure):
('reserved', ctypes.c_uint32 * 4),
]
+
V4L2_FMT_FLAG_COMPRESSED = 0x0001
V4L2_FMT_FLAG_EMULATED = 0x0002
+
# ioctl code for video devices
VIDIOC_QUERYCAP = _IOR('V', 0, v4l2_capability)
VIDIOC_ENUM_FRAMESIZES = _IOWR('V', 74, v4l2_frmsizeenum)
@@ -168,6 +170,7 @@ class CameraTest:
self.args = args
self._width = 640
self._height = 480
+ self._devices = []
def detect(self):
"""
@@ -186,10 +189,10 @@ class CameraTest:
print("%s: OK" % device)
print(" name : %s" % cp.card.decode('UTF-8'))
print(" driver : %s" % cp.driver.decode('UTF-8'))
- print(" version: %s.%s.%s"
- % (cp.version >> 16,
- (cp.version >> 8) & 0xff,
- cp.version & 0xff))
+ print(
+ " version: %s.%s.%s"
+ % (cp.version >> 16, (cp.version >> 8) & 0xff,
+ cp.version & 0xff))
print(" flags : 0x%x [" % cp.capabilities,
' CAPTURE' if cp.capabilities & V4L2_CAP_VIDEO_CAPTURE
else '',
@@ -212,51 +215,67 @@ class CameraTest:
cap_status = 0
return dev_status | cap_status
+ def _stop(self):
+ self.camerabin.set_state(Gst.State.NULL)
+ Gtk.main_quit()
+
+ def _on_error(self, bus, msg):
+ Gtk.main_quit()
+
def _on_destroy(self, *args):
Clutter.main_quit()
- def _take_photo(self, *args):
- Cheese.Camera.take_photo(self.camera, self.filename)
+ def _take_photo(self, filename):
+ self.camerabin.set_property("location", filename)
+ self.camerabin.emit("start-capture")
+
+ def _setup(self, sink=None):
+ webcam = Gst.ElementFactory.make('v4l2src')
+ webcam.set_property('device', self.args.device)
+ wrappercamerabinsrc = Gst.ElementFactory.make('wrappercamerabinsrc')
+ wrappercamerabinsrc.set_property('video-source', webcam)
+ self.camerabin = Gst.ElementFactory.make("camerabin")
+ self.camerabin.set_property('camera-source', wrappercamerabinsrc)
+ if sink:
+ vf_sink = Gst.ElementFactory.make(sink)
+ self.camerabin.set_property('viewfinder-sink', vf_sink)
+ self.camerabin.set_state(Gst.State.PAUSED)
+ caps = self.camerabin.get_property('viewfinder-supported-caps')
+ supported_resolutions = {}
+ for i in range(caps.get_size()):
+ key = caps.get_structure(i).get_int('width').value
+ try:
+ supported_resolutions[key].add(
+ caps.get_structure(i).get_int('height').value)
+ except KeyError:
+ supported_resolutions[key] = set()
+ width = min(supported_resolutions.keys(),
+ key=lambda x: abs(x - self._width))
+ height = min(supported_resolutions[width],
+ key=lambda y: abs(y - self._height))
+ vf_caps = Gst.Caps.from_string(
+ 'video/x-raw, width={}, height={}'.format(width, height))
+ self.camerabin.set_property('viewfinder-caps', vf_caps)
+ bus = self.camerabin.get_bus()
+ bus.add_signal_watch()
+ bus.connect('message::error', self._on_error)
+ self.camerabin.set_state(Gst.State.PLAYING)
def led(self):
"""
Activate camera (switch on led), but don't display any output
"""
- Clutter.threads_add_timeout(0, 3000, self._on_destroy, None, None)
- video_texture = Clutter.Actor()
- try:
- camera = Cheese.Camera.new(
- video_texture, self.args.device, self._width, self._height)
- except TypeError: # libcheese < 3.18 still use Clutter.Texture
- video_texture = Clutter.Texture()
- camera = Cheese.Camera.new(
- video_texture, self.args.device, self._width, self._height)
- Cheese.Camera.setup(camera, None)
- Cheese.Camera.play(camera)
- Clutter.main()
+ self._setup(sink='fakesink')
+ GLib.timeout_add_seconds(3, self._stop)
+ Gtk.main()
def display(self):
"""
Displays the preview window
"""
- stage = Clutter.Stage()
- stage.set_title('Camera test')
- stage.set_size(self._width, self._height)
- stage.connect('destroy', self._on_destroy)
- Clutter.threads_add_timeout(0, 10000, self._on_destroy, None, None)
- video_texture = Clutter.Actor()
- try:
- camera = Cheese.Camera.new(
- video_texture, self.args.device, self._width, self._height)
- except TypeError: # libcheese < 3.18 still use Clutter.Texture
- video_texture = Clutter.Texture()
- camera = Cheese.Camera.new(
- video_texture, self.args.device, self._width, self._height)
- stage.add_actor(video_texture)
- Cheese.Camera.setup(camera, None)
- Cheese.Camera.play(camera)
- stage.show()
- Clutter.main()
+ self._setup()
+ GLib.timeout_add_seconds(10, self._stop)
+ Gtk.main()
def still(self):
"""
@@ -280,7 +299,7 @@ class CameraTest:
"-d", self.args.device,
"-r", "%dx%d"
% (width, height), filename]
- use_cheese = False
+ use_camerabin = False
if pixelformat:
if 'MJPG' == pixelformat: # special tweak for fswebcam
pixelformat = 'MJPEG'
@@ -289,27 +308,12 @@ class CameraTest:
try:
check_call(command, stdout=open(os.devnull, 'w'), stderr=STDOUT)
except (CalledProcessError, OSError):
- use_cheese = True
-
- if use_cheese:
- stage = Clutter.Stage()
- stage.connect('destroy', self._on_destroy)
- video_texture = Clutter.Actor()
- try:
- self.camera = Cheese.Camera.new(
- video_texture, self.args.device, self._width, self._height)
- except TypeError: # libcheese < 3.18 still use Clutter.Texture
- video_texture = Clutter.Texture()
- self.camera = Cheese.Camera.new(
- video_texture, self.args.device, self._width, self._height)
- Cheese.Camera.setup(self.camera, None)
- Cheese.Camera.play(self.camera)
- self.filename = filename
- Clutter.threads_add_timeout(0, 3000, self._take_photo , None, None)
- Clutter.threads_add_timeout(0, 4000, self._on_destroy, None, None)
- Clutter.main()
- Cheese.Camera.stop(self.camera)
-
+ use_camerabin = True
+ if use_camerabin:
+ self._setup(sink='fakesink')
+ GLib.timeout_add_seconds(3, self._take_photo, filename)
+ GLib.timeout_add_seconds(4, self._stop)
+ Gtk.main()
if not quiet:
stage = Clutter.Stage()
stage.set_title('Camera still picture test')
@@ -328,7 +332,7 @@ class CameraTest:
ret = ""
for resolution in supported_resolutions:
ret += "Format: %s (%s)\n" % (resolution['pixelformat'],
- resolution['description'])
+ resolution['description'])
ret += "Resolutions: "
for res in resolution['resolutions']:
ret += "%sx%s," % (res[0], res[1])
@@ -568,20 +572,17 @@ if __name__ == "__main__":
# Import Gst only for the test cases that will need it
if args.test in ['display', 'still', 'led', 'resolutions']:
- import contextlib
- # Workaround to avoid "cluttervideosink missing"
- # See https://bugzilla.gnome.org/show_bug.cgi?id=721277
- with contextlib.suppress(FileNotFoundError):
- gst_registry = '~/.cache/gstreamer-1.0/registry.x86_64.bin'
- os.remove(os.path.expanduser(gst_registry))
import gi
gi.require_version('Gst', '1.0')
from gi.repository import Gst
- gi.require_version('Cheese', '3.0')
- from gi.repository import Cheese
+ gi.require_version('GLib', '2.0')
+ from gi.repository import GLib
gi.require_version('Clutter', '1.0')
from gi.repository import Clutter
+ gi.require_version('Gtk', '3.0')
+ from gi.repository import Gtk
Gst.init(None)
Clutter.init()
+ Gtk.init([])
camera = CameraTest(args)
sys.exit(getattr(camera, args.test)())
diff --git a/units/camera/jobs.pxu b/units/camera/jobs.pxu
index 4219462..b1e4b9c 100644
--- a/units/camera/jobs.pxu
+++ b/units/camera/jobs.pxu
@@ -8,65 +8,95 @@ command:
camera_test detect
_description: This Automated test attempts to detect a camera.
+unit: template
+template-resource: device
+template-filter: device.category == 'CAPTURE' and device.name != ''
+template-unit: job
plugin: user-interact-verify
category_id: com.canonical.plainbox::camera
-id: camera/display
+id: camera/display_{name}
+_summary: Webcam video display test for {product_slug}
estimated_duration: 120.0
depends: camera/detect
-requires:
- device.category == 'CAPTURE'
command:
- camera_test display
+ camera_test display -d /dev/{name}
_description:
PURPOSE:
- This test will check that the built-in camera works
+ This test will check that the {product_slug} camera works
STEPS:
1. Click on Test to display a video capture from the camera for ten seconds.
VERIFICATION:
Did you see the video capture?
+unit: template
+template-resource: device
+template-filter: device.category == 'CAPTURE' and device.name != ''
+template-unit: job
+plugin: user-interact-verify
+category_id: com.canonical.plainbox::camera
+id: camera/led_{name}
+_summary: Webcam LED test for {product_slug}
+estimated_duration: 120.0
+depends: camera/detect
+command:
+ camera_test led -d /dev/{name}
+_description:
+ PURPOSE:
+ This test will check that the {product_slug} camera LED works
+ STEPS:
+ 1. Select Test to activate camera
+ 2. Camera LED should light for a few seconds
+ VERIFICATION:
+ Did the camera LED light?
+
+unit: template
+template-resource: device
+template-filter: device.category == 'CAPTURE' and device.name != ''
+template-unit: job
plugin: user-interact-verify
template-engine: jinja2
category_id: com.canonical.plainbox::camera
-id: camera/still
+id: camera/still_{{ name }}
+_summary: Webcam still image capture test for {{ product_slug }}
estimated_duration: 120.0
depends: camera/detect
requires:
{%- if __on_ubuntucore__ %}
executable.name == 'fswebcam'
- device.category == 'CAPTURE'
{%- else %}
package.name == 'gir1.2-gst-plugins-base-1.0'
package.name == 'eog'
package.name == 'fswebcam' or package.name == 'gir1.2-gst-plugins-base-1.0'
- device.category == 'CAPTURE'
{% endif -%}
command:
- camera_test still
+ camera_test still -d /dev/{{ name }}
_description:
PURPOSE:
- This test will check that the built-in camera works
+ This test will check that the {{ product_slug }} works
STEPS:
1. Click on Test to display a still image from the camera for ten seconds.
VERIFICATION:
Did you see the image?
+unit: template
+template-resource: device
+template-filter: device.category == 'CAPTURE' and device.name != ''
+template-unit: job
plugin: shell
template-engine: jinja2
category_id: com.canonical.plainbox::camera
-id: camera/multiple-resolution-images
+id: camera/multiple-resolution-images_{{ name }}
+_summary: Webcam multiple resolution capture test for {{ product_slug }}
estimated_duration: 1.2
depends: camera/detect
requires:
{%- if __on_ubuntucore__ %}
executable.name == 'fswebcam'
- device.category == 'CAPTURE'
{%- else %}
package.name == 'fswebcam' or package.name == 'gir1.2-gst-plugins-base-1.0'
- device.category == 'CAPTURE'
{% endif -%}
command:
- camera_test resolutions
+ camera_test resolutions -d /dev/{{ name }}
_description:
Takes multiple pictures based on the resolutions supported by the camera and
validates their size and that they are of a valid format.
diff --git a/units/camera/packaging.pxu b/units/camera/packaging.pxu
deleted file mode 100644
index bb12d64..0000000
--- a/units/camera/packaging.pxu
+++ /dev/null
@@ -1,3 +0,0 @@
-unit: packaging meta-data
-os-id: debian
-Depends: gir1.2-cheese-3.0
diff --git a/units/camera/test-plan.pxu b/units/camera/test-plan.pxu
index e4302be..578a7ce 100644
--- a/units/camera/test-plan.pxu
+++ b/units/camera/test-plan.pxu
@@ -14,40 +14,49 @@ _name: Camera tests (Manual)
_description:
Camera tests (Manual)
include:
- camera/still certification-status=blocker
- camera/display certification-status=blocker
-
+ camera/still_.* certification-status=blocker
+ camera/display_.* certification-status=blocker
+bootstrap_include:
+ device
id: after-suspend-camera-cert-full
unit: test plan
_name: Camera tests (after suspend)
_description: Camera tests (after suspend)
include:
- camera/display_after_suspend certification-status=blocker
- camera/still_after_suspend certification-status=blocker
+ after-suspend-manual-camera/still_.* certification-status=blocker
+ after-suspend-manual-camera/display_.* certification-status=blocker
+bootstrap_include:
+ device
id: camera-cert-automated
unit: test plan
_name: Camera tests (automated)
_description: Camera tests (automated)
include:
- camera/detect certification-status=blocker
- camera/multiple-resolution-images certification-status=blocker
+ camera/detect certification-status=blocker
+ camera/multiple-resolution-images_.* certification-status=blocker
+bootstrap_include:
+ device
id: camera-cert-blockers
unit: test plan
_name: Camera tests (certification blockers only)
_description: Camera tests (certification blockers only)
include:
- camera/detect certification-status=blocker
- camera/still certification-status=blocker
- camera/display certification-status=blocker
- camera/multiple-resolution-images certification-status=blocker
+ camera/detect certification-status=blocker
+ camera/still_.* certification-status=blocker
+ camera/display_.* certification-status=blocker
+ camera/multiple-resolution-images_.* certification-status=blocker
+bootstrap_include:
+ device
id: after-suspend-camera-cert-blockers
unit: test plan
_name: Camera tests (after suspend, certification blockers only)
_description: Camera tests (after suspend, certification blockers only)
include:
- camera/display_after_suspend certification-status=blocker
- camera/still_after_suspend certification-status=blocker
+ after-suspend-manual-camera/still_.* certification-status=blocker
+ after-suspend-manual-camera/display_.* certification-status=blocker
+bootstrap_include:
+ device
diff --git a/units/led/jobs.pxu b/units/led/jobs.pxu
index 15d3065..2c2ea16 100644
--- a/units/led/jobs.pxu
+++ b/units/led/jobs.pxu
@@ -171,21 +171,6 @@ plugin: manual
category_id: led
estimated_duration: 180
-plugin: user-interact-verify
-category_id: led
-id: led/camera
-estimated_duration: 20.0
-depends: camera/detect
-command: camera_test led
-_description:
- PURPOSE:
- Camera LED verification
- STEPS:
- 1. Select Test to activate camera
- 2. Camera LED should light for a few seconds
- VERIFICATION:
- Did the camera LED light?
-
plugin: manual
category_id: led
id: led/touchpad
diff --git a/units/led/test-plan.pxu b/units/led/test-plan.pxu
index 88d38a6..0329717 100644
--- a/units/led/test-plan.pxu
+++ b/units/led/test-plan.pxu
@@ -25,10 +25,12 @@ include:
led/battery-charged
led/battery-charging
led/battery-low
- led/camera
+ camera/led_.*
led/caps-lock
led/power
led/touchpad
+bootstrap_include:
+ device
id: led-cert-automated
unit: test plan
@@ -50,10 +52,12 @@ include:
suspend/led_after_suspend/battery-charged
suspend/led_after_suspend/battery-charging
suspend/led_after_suspend/battery-low
- suspend/led_after_suspend/camera
+ after-suspend-manual-camera/led_.*
suspend/led_after_suspend/caps-lock
suspend/led_after_suspend/power
suspend/led_after_suspend/touchpad
+bootstrap_include:
+ device
id: led-full
unit: test plan
diff --git a/units/miscellanea/jobs.pxu b/units/miscellanea/jobs.pxu
index 7ddcc1b..6733a16 100644
--- a/units/miscellanea/jobs.pxu
+++ b/units/miscellanea/jobs.pxu
@@ -354,7 +354,7 @@ plugin: user-interact-verify
category_id: com.canonical.plainbox::miscellanea
estimated_duration: 5.0
id: miscellanea/device_check
-command: udev_resource -l VIDEO NETWORK WIRELESS DISK ACCELEROMETER | tee >([[ $DISPLAY ]] && zenity --text-info --title="Device report")
+command: udev_resource -l VIDEO NETWORK WIRELESS DISK CAPTURE ACCELEROMETER | tee >([[ $DISPLAY ]] && zenity --text-info --title="Device report")
_summary: Device Check
_purpose:
Device check
diff --git a/units/suspend/suspend.pxu b/units/suspend/suspend.pxu
index 1ab5829..0c3a942 100644
--- a/units/suspend/suspend.pxu
+++ b/units/suspend/suspend.pxu
@@ -1449,23 +1449,6 @@ _description:
VERIFICATION:
Did the bluetooth LED turn off and on twice after resuming from suspend?
-plugin: user-interact-verify
-category_id: com.canonical.plainbox::suspend
-id: suspend/led_after_suspend/camera
-estimated_duration: 120.0
-depends:
- camera/detect
- suspend/suspend_advanced
-command: camera_test led
-_description:
- PURPOSE:
- Validate that the camera LED still works as expected after resuming from suspend
- STEPS:
- 1. Select Test to activate camera
- 2. Camera LED should light for a few seconds
- VERIFICATION:
- Did the camera LED still turn on and off after resuming from suspend?
-
plugin: manual
category_id: com.canonical.plainbox::suspend
id: suspend/led_after_suspend/touchpad
@@ -2090,54 +2073,6 @@ _description:
VERIFICATION:
Does tap recognition work?
-plugin: user-interact-verify
-category_id: com.canonical.plainbox::suspend
-id: camera/display_after_suspend
-estimated_duration: 120.0
-depends: suspend/suspend_advanced
-requires:
- device.category == 'CAPTURE'
-command: camera_test display
-_description:
- PURPOSE:
- This test will check that the built-in camera works after suspend
- STEPS:
- 1. Click on Test to display a video capture from the camera for ten seconds.
- VERIFICATION:
- Did you see the video capture?
-
-plugin: user-interact-verify
-category_id: com.canonical.plainbox::suspend
-id: camera/still_after_suspend
-estimated_duration: 120.0
-depends: camera/display_after_suspend
-requires:
- package.name == 'gir1.2-gst-plugins-base-0.10' or package.name == 'gir1.2-gst-plugins-base-1.0'
- package.name == 'eog'
- package.name == 'fswebcam' or package.name == 'gir1.2-gst-plugins-base-0.10' or package.name == 'gir1.2-gst-plugins-base-1.0'
- device.category == 'CAPTURE'
-command: camera_test still
-_description:
- PURPOSE:
- This test will check that the built-in camera works after suspend
- STEPS:
- 1. Click on Test to display a still image from the camera for ten seconds.
- VERIFICATION:
- Did you see the image?
-
-plugin: shell
-category_id: com.canonical.plainbox::suspend
-id: camera/multiple_resolution_after_suspend
-estimated_duration: 1.2
-depends: camera/still_after_suspend
-requires:
- package.name == 'fswebcam' or package.name == 'gir1.2-gst-plugins-base-0.10' or package.name == 'gir1.2-gst-plugins-base-1.0'
- device.category == 'CAPTURE'
-command: camera_test resolutions
-_description:
- Takes multiple pictures based on the resolutions supported by the camera and
- validates their size and that they are of a valid format after suspend
-
unit: template
template-resource: device
template-filter: device.category == 'MOUSE' or device.category == 'TOUCHPAD' or device.category == 'TOUCHSCREEN'