Merge lp:~rhuddie/ubuntu-autopilot-tests/video_playback_tests into lp:ubuntu-autopilot-tests/ubuntu-experience-tests
- video_playback_tests
- Merge into ubuntu-experience-tests
Status: | Needs review |
---|---|
Proposed branch: | lp:~rhuddie/ubuntu-autopilot-tests/video_playback_tests |
Merge into: | lp:ubuntu-autopilot-tests/ubuntu-experience-tests |
Diff against target: |
655 lines (+609/-0) 6 files modified
debian/control (+3/-0) setup.py (+1/-0) ubuntu_experience_tests/tests/multimedia/__init__.py (+38/-0) ubuntu_experience_tests/tests/multimedia/config.ini (+8/-0) ubuntu_experience_tests/tests/multimedia/test_video_playback.py (+542/-0) ubuntu_experience_tests/tests/multimedia/video_samples/__init__.py (+17/-0) |
To merge this branch: | bzr merge lp:~rhuddie/ubuntu-autopilot-tests/video_playback_tests |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot | continuous-integration | Needs Fixing | |
Ubuntu Testcase Admins | Pending | ||
Review via email: mp+240014@code.launchpad.net |
Commit message
Description of the change
A new test for playing videos in the mediaplayer-app and validating playback is working.
PS Jenkins bot (ps-jenkins) wrote : | # |
- 35. By Richard Huddie
-
change relative paths to run from tests directory
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:35
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:34
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 36. By Richard Huddie
-
update import paths
- 37. By Richard Huddie
-
Update default helpers methods and file path
- 38. By Richard Huddie
-
use parameters for defaults
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:36
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:38
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:38
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 39. By Richard Huddie
-
remove config file path and use default instead
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:39
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 40. By Richard Huddie
-
add __init__.py to samples dir
- 41. By Richard Huddie
-
add data_files to setup.py
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:40
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:40
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:41
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 42. By Richard Huddie
-
add file names
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:42
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 43. By Richard Huddie
-
use include_
package_ data
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:43
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 44. By Richard Huddie
-
read boolean value from ini
- 45. By Richard Huddie
-
add MP4 and ini using package_data, exclude src types from video list
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:45
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 46. By Richard Huddie
-
remove unknown --fullscreen option
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:45
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
http://
Executed test runs:
None: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:45
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:46
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:46
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 47. By Richard Huddie
-
change base class and tidy
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:47
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Unmerged revisions
- 47. By Richard Huddie
-
change base class and tidy
- 46. By Richard Huddie
-
remove unknown --fullscreen option
- 45. By Richard Huddie
-
add MP4 and ini using package_data, exclude src types from video list
- 44. By Richard Huddie
-
read boolean value from ini
- 43. By Richard Huddie
-
use include_
package_ data - 42. By Richard Huddie
-
add file names
- 41. By Richard Huddie
-
add data_files to setup.py
- 40. By Richard Huddie
-
add __init__.py to samples dir
- 39. By Richard Huddie
-
remove config file path and use default instead
- 38. By Richard Huddie
-
use parameters for defaults
Preview Diff
1 | === modified file 'debian/control' | |||
2 | --- debian/control 2014-08-08 06:53:37 +0000 | |||
3 | +++ debian/control 2014-11-03 16:07:13 +0000 | |||
4 | @@ -22,6 +22,9 @@ | |||
5 | 22 | ubuntu-ui-toolkit-autopilot, | 22 | ubuntu-ui-toolkit-autopilot, |
6 | 23 | unity8-autopilot, | 23 | unity8-autopilot, |
7 | 24 | url-dispatcher-tools, | 24 | url-dispatcher-tools, |
8 | 25 | mediaplayer-app-autopilot, | ||
9 | 26 | python3-evdev, | ||
10 | 27 | imagemagick, | ||
11 | 25 | Description: Ubuntu user experience Autopilot tests | 28 | Description: Ubuntu user experience Autopilot tests |
12 | 26 | This package provides a set of autopilot tests for testing | 29 | This package provides a set of autopilot tests for testing |
13 | 27 | the inter-app integration under Unity8 | 30 | the inter-app integration under Unity8 |
14 | 28 | 31 | ||
15 | === modified file 'setup.py' | |||
16 | --- setup.py 2014-06-19 03:06:13 +0000 | |||
17 | +++ setup.py 2014-11-03 16:07:13 +0000 | |||
18 | @@ -32,4 +32,5 @@ | |||
19 | 32 | license='GPLv3', | 32 | license='GPLv3', |
20 | 33 | packages=setuptools.find_packages(), | 33 | packages=setuptools.find_packages(), |
21 | 34 | test_suite='ubuntu_experience_tests.tests', | 34 | test_suite='ubuntu_experience_tests.tests', |
22 | 35 | package_data={'': ['*.ini', '*.MP4'], }, | ||
23 | 35 | ) | 36 | ) |
24 | 36 | 37 | ||
25 | === added directory 'ubuntu_experience_tests/tests/multimedia' | |||
26 | === added file 'ubuntu_experience_tests/tests/multimedia/__init__.py' | |||
27 | --- ubuntu_experience_tests/tests/multimedia/__init__.py 1970-01-01 00:00:00 +0000 | |||
28 | +++ ubuntu_experience_tests/tests/multimedia/__init__.py 2014-11-03 16:07:13 +0000 | |||
29 | @@ -0,0 +1,38 @@ | |||
30 | 1 | # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- | ||
31 | 2 | # | ||
32 | 3 | # Copyright 2014 Canonical Ltd. | ||
33 | 4 | # | ||
34 | 5 | # This file is part of ubuntu-experience-tests. | ||
35 | 6 | # | ||
36 | 7 | # This program is free software; you can redistribute it and/or modify | ||
37 | 8 | # it under the terms of the GNU General Public License version 3, as published | ||
38 | 9 | # by the Free Software Foundation. | ||
39 | 10 | # | ||
40 | 11 | # This program is distributed in the hope that it will be useful, | ||
41 | 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
42 | 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
43 | 14 | # GNU General Public License for more details. | ||
44 | 15 | # | ||
45 | 16 | # You should have received a copy of the GNU General Public License | ||
46 | 17 | # along with this program. If not, see <http://www.gnu.org/licenses/> | ||
47 | 18 | |||
48 | 19 | |||
49 | 20 | import os | ||
50 | 21 | |||
51 | 22 | DEFAULT_CONFIG_FILE = 'config.ini' | ||
52 | 23 | DEFAULT_SAMPLES_DIR = 'video_samples' | ||
53 | 24 | |||
54 | 25 | |||
55 | 26 | def _get_current_dir(): | ||
56 | 27 | """Return the current dir path""" | ||
57 | 28 | return os.path.dirname(__file__) | ||
58 | 29 | |||
59 | 30 | |||
60 | 31 | def get_default_config_file(): | ||
61 | 32 | """Return the path for the default config file""" | ||
62 | 33 | return os.path.join(_get_current_dir(), DEFAULT_CONFIG_FILE) | ||
63 | 34 | |||
64 | 35 | |||
65 | 36 | def get_default_samples_dir(): | ||
66 | 37 | """Return the path for the default samples directory""" | ||
67 | 38 | return os.path.join(_get_current_dir(), DEFAULT_SAMPLES_DIR) | ||
68 | 0 | 39 | ||
69 | === added file 'ubuntu_experience_tests/tests/multimedia/config.ini' | |||
70 | --- ubuntu_experience_tests/tests/multimedia/config.ini 1970-01-01 00:00:00 +0000 | |||
71 | +++ ubuntu_experience_tests/tests/multimedia/config.ini 2014-11-03 16:07:13 +0000 | |||
72 | @@ -0,0 +1,8 @@ | |||
73 | 1 | [default] | ||
74 | 2 | sample-dir = | ||
75 | 3 | sample-file = | ||
76 | 4 | sample-interval-sec = 0.5 | ||
77 | 5 | sample-check-count = 3 | ||
78 | 6 | timeout = 10 | ||
79 | 7 | run-all = no | ||
80 | 8 | |||
81 | 0 | 9 | ||
82 | === added file 'ubuntu_experience_tests/tests/multimedia/test_video_playback.py' | |||
83 | --- ubuntu_experience_tests/tests/multimedia/test_video_playback.py 1970-01-01 00:00:00 +0000 | |||
84 | +++ ubuntu_experience_tests/tests/multimedia/test_video_playback.py 2014-11-03 16:07:13 +0000 | |||
85 | @@ -0,0 +1,542 @@ | |||
86 | 1 | # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- | ||
87 | 2 | # | ||
88 | 3 | # Copyright 2014 Canonical Ltd. | ||
89 | 4 | # | ||
90 | 5 | # This file is part of ubuntu-experience-tests. | ||
91 | 6 | # | ||
92 | 7 | # This program is free software; you can redistribute it and/or modify | ||
93 | 8 | # it under the terms of the GNU General Public License version 3, as published | ||
94 | 9 | # by the Free Software Foundation. | ||
95 | 10 | # | ||
96 | 11 | # This program is distributed in the hope that it will be useful, | ||
97 | 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
98 | 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
99 | 14 | # GNU General Public License for more details. | ||
100 | 15 | # | ||
101 | 16 | # You should have received a copy of the GNU General Public License | ||
102 | 17 | # along with this program. If not, see <http://www.gnu.org/licenses/> | ||
103 | 18 | |||
104 | 19 | import configparser | ||
105 | 20 | import os | ||
106 | 21 | import re | ||
107 | 22 | import subprocess | ||
108 | 23 | import tempfile | ||
109 | 24 | import time | ||
110 | 25 | from collections import deque | ||
111 | 26 | from threading import Timer | ||
112 | 27 | |||
113 | 28 | from autopilot import get_test_configuration | ||
114 | 29 | from autopilot.display import Display | ||
115 | 30 | from autopilot.matchers import Eventually | ||
116 | 31 | from mediaplayer_app.emulators.main_window import MainWindow | ||
117 | 32 | from testtools.matchers import Equals | ||
118 | 33 | from ubuntuuitoolkit import emulators as toolkit_emulators | ||
119 | 34 | from ubuntu_experience_tests import tests | ||
120 | 35 | |||
121 | 36 | |||
122 | 37 | class ConfigData: | ||
123 | 38 | """Class to read config data from file and cmd line options""" | ||
124 | 39 | |||
125 | 40 | # config keys | ||
126 | 41 | KEY_SAMPLE_DIR = 'sample-dir' | ||
127 | 42 | KEY_SAMPLE_FILE = 'sample-file' | ||
128 | 43 | KEY_SAMPLE_INTERVAL = 'sample-interval-sec' | ||
129 | 44 | KEY_SAMPLE_CHECK_COUNT = 'sample-check-count' | ||
130 | 45 | KEY_TIMEOUT = 'timeout' | ||
131 | 46 | KEY_CONFIG_FILE = 'config-file' | ||
132 | 47 | KEY_CONFIG_SECTION = 'config-section' | ||
133 | 48 | KEY_RUN_ALL = 'run-all' | ||
134 | 49 | KEY_DEFAULT = 'default' | ||
135 | 50 | |||
136 | 51 | # Default configuration values | ||
137 | 52 | DEFAULT_RUN_ALL = False | ||
138 | 53 | DEFAULT_SAMPLE_INTERVAL = 1 | ||
139 | 54 | DEFAULT_SAMPLE_CHECK_COUNT = 5 | ||
140 | 55 | DEFAULT_TIMEOUT = 0 | ||
141 | 56 | DEFAULT_SAMPLE_FILE = '' | ||
142 | 57 | |||
143 | 58 | def __init__(self, cmdline_config): | ||
144 | 59 | """Init using command line options for config file and section""" | ||
145 | 60 | # get cmdline options | ||
146 | 61 | self.cmdline_config = cmdline_config | ||
147 | 62 | # set default setup parameters | ||
148 | 63 | self.run_all = False | ||
149 | 64 | self.config_file = tests.multimedia.get_default_config_file() | ||
150 | 65 | self.config_section = self.KEY_DEFAULT | ||
151 | 66 | self.parser = configparser.ConfigParser() | ||
152 | 67 | # now load config from files and cmdline | ||
153 | 68 | self.load_config() | ||
154 | 69 | |||
155 | 70 | def load_config(self): | ||
156 | 71 | """Load the test config using command line and file""" | ||
157 | 72 | # reset the test config parameters | ||
158 | 73 | self.sample_dir = tests.multimedia.get_default_samples_dir() | ||
159 | 74 | self.sample_file = self.DEFAULT_SAMPLE_FILE | ||
160 | 75 | self.sample_interval = self.DEFAULT_SAMPLE_INTERVAL | ||
161 | 76 | self.sample_check_count = self.DEFAULT_SAMPLE_CHECK_COUNT | ||
162 | 77 | self.timeout = self.DEFAULT_TIMEOUT | ||
163 | 78 | # get config file from cmdline options if specified | ||
164 | 79 | self.get_custom_config_from_cmdline() | ||
165 | 80 | # now read config from file | ||
166 | 81 | self.get_test_config_from_file() | ||
167 | 82 | # finally overwrite config with any cmdline options | ||
168 | 83 | self.get_test_config_from_cmdline() | ||
169 | 84 | |||
170 | 85 | def get_custom_config_from_cmdline(self): | ||
171 | 86 | """Read the custom config options from cmd line parameters""" | ||
172 | 87 | # Get config-file and config-section from cmd line options | ||
173 | 88 | if self.KEY_CONFIG_FILE in self.cmdline_config: | ||
174 | 89 | self.config_file = self.cmdline_config[self.KEY_CONFIG_FILE] | ||
175 | 90 | if self.KEY_CONFIG_SECTION in self.cmdline_config: | ||
176 | 91 | self.config_section = self.cmdline_config[self.KEY_CONFIG_SECTION] | ||
177 | 92 | # Read the specified config file | ||
178 | 93 | self.parser.read(self.config_file) | ||
179 | 94 | # now get run-all parameter. check cmdline first, then file | ||
180 | 95 | if self.KEY_RUN_ALL in self.cmdline_config: | ||
181 | 96 | self.run_all = True | ||
182 | 97 | elif self.KEY_RUN_ALL in self.parser[self.config_section]: | ||
183 | 98 | if self.parser[self.config_section].getboolean(self.KEY_RUN_ALL): | ||
184 | 99 | self.run_all = True | ||
185 | 100 | |||
186 | 101 | def get_test_config_from_cmdline(self): | ||
187 | 102 | """Read test parameters from cmd line options""" | ||
188 | 103 | if self.KEY_SAMPLE_DIR in self.cmdline_config: | ||
189 | 104 | self.sample_dir = self.cmdline_config[self.KEY_SAMPLE_DIR] | ||
190 | 105 | self.sample_file = '' | ||
191 | 106 | if self.KEY_SAMPLE_FILE in self.cmdline_config: | ||
192 | 107 | self.sample_file = self.cmdline_config[self.KEY_SAMPLE_FILE] | ||
193 | 108 | # if a file is specified, then remove the directory config, | ||
194 | 109 | # otherwise this will take priority | ||
195 | 110 | self.sample_dir = '' | ||
196 | 111 | if self.KEY_SAMPLE_INTERVAL in self.cmdline_config: | ||
197 | 112 | self.sample_interval = int( | ||
198 | 113 | self.cmdline_config[self.KEY_SAMPLE_INTERVAL]) | ||
199 | 114 | if self.KEY_SAMPLE_CHECK_COUNT in self.cmdline_config: | ||
200 | 115 | self.sample_check_count = int( | ||
201 | 116 | self.cmdline_config[self.KEY_SAMPLE_CHECK_COUNT]) | ||
202 | 117 | if self.KEY_TIMEOUT in self.cmdline_config: | ||
203 | 118 | self.timeout = int(self.cmdline_config[self.KEY_TIMEOUT]) | ||
204 | 119 | |||
205 | 120 | def get_test_config_from_file(self): | ||
206 | 121 | """Read test parameters from config file""" | ||
207 | 122 | if self.KEY_SAMPLE_DIR in self.parser[self.config_section]: | ||
208 | 123 | val = self.parser[self.config_section][self.KEY_SAMPLE_DIR] | ||
209 | 124 | if len(val) > 0: | ||
210 | 125 | self.sample_dir = val | ||
211 | 126 | self.sample_file = '' | ||
212 | 127 | if self.KEY_SAMPLE_FILE in self.parser[self.config_section]: | ||
213 | 128 | val = self.parser[self.config_section][self.KEY_SAMPLE_FILE] | ||
214 | 129 | if len(val) > 0: | ||
215 | 130 | self.sample_file = val | ||
216 | 131 | # if a file is specified, then remove the directory config, | ||
217 | 132 | # otherwise this will take priority | ||
218 | 133 | self.sample_dir = '' | ||
219 | 134 | if self.KEY_SAMPLE_INTERVAL in self.parser[self.config_section]: | ||
220 | 135 | val = self.parser[self.config_section][self.KEY_SAMPLE_INTERVAL] | ||
221 | 136 | if len(val) > 0: | ||
222 | 137 | self.sample_interval = float(val) | ||
223 | 138 | if self.KEY_SAMPLE_CHECK_COUNT in self.parser[self.config_section]: | ||
224 | 139 | val = self.parser[self.config_section][self.KEY_SAMPLE_CHECK_COUNT] | ||
225 | 140 | if len(val) > 0: | ||
226 | 141 | self.sample_check_count = int(val) | ||
227 | 142 | if self.KEY_TIMEOUT in self.parser[self.config_section]: | ||
228 | 143 | val = self.parser[self.config_section][self.KEY_TIMEOUT] | ||
229 | 144 | if len(val) > 0: | ||
230 | 145 | self.timeout = int(val) | ||
231 | 146 | |||
232 | 147 | |||
233 | 148 | class VideoPlaybackTestCase(tests.UbuntuExperienceTestCase): | ||
234 | 149 | """Autopilot test suite for playing videos in Mediaplayer-app""" | ||
235 | 150 | |||
236 | 151 | def setUp(self): | ||
237 | 152 | """Setup test suite""" | ||
238 | 153 | super(VideoPlaybackTestCase, self).setUp() | ||
239 | 154 | self.pointing_device = toolkit_emulators.get_pointing_device() | ||
240 | 155 | # calculate screen crop area based on device geometry | ||
241 | 156 | self.crop_area = self.get_crop_area() | ||
242 | 157 | # create config data using any command line options | ||
243 | 158 | self.config = ConfigData(get_test_configuration()) | ||
244 | 159 | |||
245 | 160 | def start_timer(self): | ||
246 | 161 | """Start a timer if a time limit has been set""" | ||
247 | 162 | if self.is_timeout_set(): | ||
248 | 163 | self.test_timer = Timer(self.config.timeout, self.on_timeout) | ||
249 | 164 | self.test_timer.start() | ||
250 | 165 | |||
251 | 166 | def cancel_timer_if_active(self): | ||
252 | 167 | """Cancel timer if it is set and still running""" | ||
253 | 168 | if self.is_timeout_set() and not self.timeout: | ||
254 | 169 | self.test_timer.cancel() | ||
255 | 170 | |||
256 | 171 | def on_timeout(self): | ||
257 | 172 | """Timer timeout event handler""" | ||
258 | 173 | # Flag that a timeout has occured | ||
259 | 174 | self.timeout = True | ||
260 | 175 | |||
261 | 176 | def is_timeout_set(self): | ||
262 | 177 | """ | ||
263 | 178 | Decide whether a timeout is required | ||
264 | 179 | :return: True if timeout is set | ||
265 | 180 | False otherwise | ||
266 | 181 | """ | ||
267 | 182 | ret = False | ||
268 | 183 | if self.config.timeout > 0: | ||
269 | 184 | ret = True | ||
270 | 185 | return ret | ||
271 | 186 | |||
272 | 187 | def open_media_player_app(self, sample_file): | ||
273 | 188 | """ | ||
274 | 189 | Open media player app with the specified sample file | ||
275 | 190 | :param sample_file: Path to file to open | ||
276 | 191 | """ | ||
277 | 192 | app = self.launch_test_application( | ||
278 | 193 | "mediaplayer-app", | ||
279 | 194 | sample_file, | ||
280 | 195 | "--desktop_file_hint=" | ||
281 | 196 | "/usr/share/applications/mediaplayer-app.desktop", | ||
282 | 197 | app_type='qt') | ||
283 | 198 | self.player = MainWindow(app).get_player() | ||
284 | 199 | self.assertThat(self.player.playing, Eventually(Equals(True))) | ||
285 | 200 | |||
286 | 201 | def close_media_player_app(self): | ||
287 | 202 | """Close the running mediaplayer-app instance""" | ||
288 | 203 | out = subprocess.check_output(['pidof', '-s', 'mediaplayer-app']) | ||
289 | 204 | pid = out.decode().strip() | ||
290 | 205 | subprocess.check_call(['kill', '-9', pid]) | ||
291 | 206 | |||
292 | 207 | def is_playing(self): | ||
293 | 208 | """ | ||
294 | 209 | Check if the media player is currently playing video | ||
295 | 210 | :return: True if it is playing, False otherwise | ||
296 | 211 | """ | ||
297 | 212 | return self.player.playing | ||
298 | 213 | |||
299 | 214 | def get_rgba_screenshot(self, target_file): | ||
300 | 215 | """ | ||
301 | 216 | Take a screenshot in rgba format | ||
302 | 217 | :return: Path of screenshot rgba file | ||
303 | 218 | """ | ||
304 | 219 | try: | ||
305 | 220 | subprocess.check_call([ | ||
306 | 221 | 'mirscreencast', | ||
307 | 222 | '-m', '/run/mir_socket', | ||
308 | 223 | '-n', '1', | ||
309 | 224 | '-f', target_file | ||
310 | 225 | ]) | ||
311 | 226 | except FileNotFoundError as e: | ||
312 | 227 | e.args += ("The utility 'mirscreencast' is not available.", ) | ||
313 | 228 | raise | ||
314 | 229 | except subprocess.CalledProcessError as e: | ||
315 | 230 | e.args += ("Failed to take screenshot.", ) | ||
316 | 231 | raise | ||
317 | 232 | |||
318 | 233 | def convert_rgba_image(self, rgba_source_file, target_file): | ||
319 | 234 | """ | ||
320 | 235 | Convert rgba file to PNG target file | ||
321 | 236 | :param rgba_source_file: Path to rgba source image | ||
322 | 237 | :param target_file: Path to PNG target file | ||
323 | 238 | """ | ||
324 | 239 | try: | ||
325 | 240 | subprocess.check_call([ | ||
326 | 241 | 'convert', | ||
327 | 242 | '-alpha', 'off', | ||
328 | 243 | '-depth', '8', | ||
329 | 244 | '-size', '540x960', | ||
330 | 245 | 'rgba:{}[0]'.format(rgba_source_file), | ||
331 | 246 | target_file | ||
332 | 247 | ]) | ||
333 | 248 | except FileNotFoundError as e: | ||
334 | 249 | e.args += ("'convert' is not available, install imagemagick.", ) | ||
335 | 250 | raise | ||
336 | 251 | except subprocess.CalledProcessError as e: | ||
337 | 252 | e.args += ("Failed to convert screenshot to png format.", ) | ||
338 | 253 | raise | ||
339 | 254 | |||
340 | 255 | def get_screenshot(self): | ||
341 | 256 | """ | ||
342 | 257 | Take screen shot and return file path of png file | ||
343 | 258 | :return: Path of PNG screen image file | ||
344 | 259 | """ | ||
345 | 260 | timestamp = int(time.time()) | ||
346 | 261 | filename_rgba = 'screenshot-{}.rgba'.format(timestamp) | ||
347 | 262 | filename_png = 'screenshot-{}.png'.format(timestamp) | ||
348 | 263 | temp_dir = tempfile.gettempdir() | ||
349 | 264 | filepath_rgba = os.path.join(temp_dir, filename_rgba) | ||
350 | 265 | filepath_png = os.path.join(temp_dir, filename_png) | ||
351 | 266 | self.get_rgba_screenshot(filepath_rgba) | ||
352 | 267 | self.convert_rgba_image(filepath_rgba, filepath_png) | ||
353 | 268 | # finished with rgba file so delete it | ||
354 | 269 | os.remove(filepath_rgba) | ||
355 | 270 | return filepath_png | ||
356 | 271 | |||
357 | 272 | def get_crop_area(self): | ||
358 | 273 | """ | ||
359 | 274 | Calculate the crop area at centre of screen in pixel format | ||
360 | 275 | [width]x[height]+[x_start]+[y_start] | ||
361 | 276 | :return: Crop area measured in pixels | ||
362 | 277 | """ | ||
363 | 278 | crop_fmt = '{0}x{1}+{2}+{3}' | ||
364 | 279 | width = 100 | ||
365 | 280 | height = 100 | ||
366 | 281 | display = Display.create() | ||
367 | 282 | centre_x = display.get_screen_width() // 2 | ||
368 | 283 | centre_y = display.get_screen_height() // 2 | ||
369 | 284 | x_start = centre_x - (width // 2) | ||
370 | 285 | y_start = centre_y - (height // 2) | ||
371 | 286 | crop_str = crop_fmt.format(width, height, x_start, y_start) | ||
372 | 287 | return crop_str | ||
373 | 288 | |||
374 | 289 | def crop_screenshot(self, source_file): | ||
375 | 290 | """ | ||
376 | 291 | Crop the screen shot and return path for cropped image | ||
377 | 292 | :param source_file: Path of image file to crop | ||
378 | 293 | :return: Path of cropped image file | ||
379 | 294 | """ | ||
380 | 295 | split_path = os.path.splitext(source_file) | ||
381 | 296 | path = split_path[0] | ||
382 | 297 | ext = split_path[1] | ||
383 | 298 | crop_file_path = '{0}_crop{1}'.format(path, ext) | ||
384 | 299 | |||
385 | 300 | try: | ||
386 | 301 | subprocess.check_call([ | ||
387 | 302 | 'convert', | ||
388 | 303 | source_file, | ||
389 | 304 | '-crop', self.crop_area, | ||
390 | 305 | crop_file_path | ||
391 | 306 | ]) | ||
392 | 307 | except FileNotFoundError as e: | ||
393 | 308 | e.args += ("The utility 'convert' is not available.", ) | ||
394 | 309 | raise | ||
395 | 310 | except subprocess.CalledProcessError as e: | ||
396 | 311 | e.args += ("Failed to crop screenshot.", ) | ||
397 | 312 | raise | ||
398 | 313 | return crop_file_path | ||
399 | 314 | |||
400 | 315 | def get_average_colour(self, source_file): | ||
401 | 316 | """ | ||
402 | 317 | Calculate the average colour of the specified image | ||
403 | 318 | """ | ||
404 | 319 | try: | ||
405 | 320 | ret = subprocess.check_output([ | ||
406 | 321 | 'convert', | ||
407 | 322 | source_file, | ||
408 | 323 | '-resize', '1x1', | ||
409 | 324 | 'txt:' | ||
410 | 325 | ]) | ||
411 | 326 | except FileNotFoundError as e: | ||
412 | 327 | e.args += ("The utility 'convert' is not available.", ) | ||
413 | 328 | raise | ||
414 | 329 | except subprocess.CalledProcessError as e: | ||
415 | 330 | e.args += ("Failed to get average colour.", ) | ||
416 | 331 | raise | ||
417 | 332 | return self.get_hex_colour_code(ret.decode()) | ||
418 | 333 | |||
419 | 334 | def get_hex_colour_code(self, colour_string): | ||
420 | 335 | """ | ||
421 | 336 | Get the hex colour code from the specified colour string | ||
422 | 337 | :param colour_string: String representing colour output | ||
423 | 338 | :return: Hex representation of colour code | ||
424 | 339 | """ | ||
425 | 340 | colour_pattern = re.compile(r'^#.*#(.*?)\s+.*$', | ||
426 | 341 | re.IGNORECASE | re.DOTALL) | ||
427 | 342 | hex_code = None | ||
428 | 343 | match = colour_pattern.search(colour_string) | ||
429 | 344 | if match: | ||
430 | 345 | hex_code = match.group(1) | ||
431 | 346 | return hex_code | ||
432 | 347 | |||
433 | 348 | def capture_and_check_frames_whilst_playing(self): | ||
434 | 349 | """ | ||
435 | 350 | Capture and check screen frames during playback | ||
436 | 351 | :return: True if playback completes, or timeout is reached. | ||
437 | 352 | False if the screen is frozen and video doesn't play' | ||
438 | 353 | """ | ||
439 | 354 | # frame_colours is a FIFO queue which holds the required number of | ||
440 | 355 | # colour samples | ||
441 | 356 | frame_colours = deque(maxlen=self.config.sample_check_count) | ||
442 | 357 | timer_started = False | ||
443 | 358 | self.timeout = False | ||
444 | 359 | while self.player.playing: | ||
445 | 360 | if self.is_timeout_set() and not timer_started: | ||
446 | 361 | # start the timer if required once playback has started | ||
447 | 362 | self.start_timer() | ||
448 | 363 | timer_started = True | ||
449 | 364 | # take screenshot | ||
450 | 365 | screenshot = self.get_screenshot() | ||
451 | 366 | # store the frame colour | ||
452 | 367 | frame_colours.append(self.calculate_frame_colour(screenshot)) | ||
453 | 368 | # no longer need the screenshot file so delete it | ||
454 | 369 | os.remove(screenshot) | ||
455 | 370 | # check frames to make sure playback is working | ||
456 | 371 | if not self.check_frame_colours(frame_colours): | ||
457 | 372 | # playback error, so exit now | ||
458 | 373 | self.cancel_timer_if_active() | ||
459 | 374 | return False | ||
460 | 375 | # wait for required interval period, checking for timeouts | ||
461 | 376 | # at 0.1 second intervals | ||
462 | 377 | # The sample interval is defined in seconds (e.g. 0.5 sec), | ||
463 | 378 | # so multiply by 10 to get required number of 0.1 second waits | ||
464 | 379 | # Note: Sample period could be large (e.g. several minutes) | ||
465 | 380 | # for long running tests, so there is a need to check for timeouts | ||
466 | 381 | # between the sample interval. | ||
467 | 382 | for count in range(int(self.config.sample_interval * 10)): | ||
468 | 383 | time.sleep(0.1) | ||
469 | 384 | # check if a timeout has occured | ||
470 | 385 | if self.timeout: | ||
471 | 386 | # timeout has triggered, so exit now | ||
472 | 387 | # this is not considered a failure | ||
473 | 388 | # no need to cancel the timer as it has triggered | ||
474 | 389 | return True | ||
475 | 390 | # playback has completed with no timeout | ||
476 | 391 | self.cancel_timer_if_active() | ||
477 | 392 | return True | ||
478 | 393 | |||
479 | 394 | def calculate_frame_colour(self, frame): | ||
480 | 395 | """ | ||
481 | 396 | Calculate the colour of the centre of the specified image | ||
482 | 397 | :param frame: Path to image file | ||
483 | 398 | :return: Average colour of centre of image | ||
484 | 399 | """ | ||
485 | 400 | # crop to the centre of the image | ||
486 | 401 | crop = self.crop_screenshot(frame) | ||
487 | 402 | # get colour of cropped area | ||
488 | 403 | colour = self.get_average_colour(crop) | ||
489 | 404 | # now delete cropped file | ||
490 | 405 | os.remove(crop) | ||
491 | 406 | return colour | ||
492 | 407 | |||
493 | 408 | def check_frame_colours(self, frame_colours): | ||
494 | 409 | """ | ||
495 | 410 | Analyse the frame colours to check that playback is working | ||
496 | 411 | :param frame_colours: dequeue object containing frame colours | ||
497 | 412 | :return: True if frame colours are changing | ||
498 | 413 | False if all the framecolours are the same | ||
499 | 414 | """ | ||
500 | 415 | frames_ok = True | ||
501 | 416 | for colour in frame_colours: | ||
502 | 417 | # count the number of occurances of current colour in the | ||
503 | 418 | # previous colours | ||
504 | 419 | if frame_colours.count(colour) is frame_colours.maxlen: | ||
505 | 420 | # all the frames are same colour, so this is a fail | ||
506 | 421 | frames_ok = False | ||
507 | 422 | break | ||
508 | 423 | return frames_ok | ||
509 | 424 | |||
510 | 425 | def is_excluded_file(self, file_path): | ||
511 | 426 | """ | ||
512 | 427 | Determine whether the specified file is an excluded type | ||
513 | 428 | :param file_path: Path of the specified file | ||
514 | 429 | :return: True if the file is an excluded type, false otherwise | ||
515 | 430 | """ | ||
516 | 431 | # list of file extensions to ignore | ||
517 | 432 | excluded_list = ['.py', '.pyc', '.py~'] | ||
518 | 433 | file_ext = os.path.splitext(file_path)[1] | ||
519 | 434 | excluded = False | ||
520 | 435 | if file_ext in excluded_list: | ||
521 | 436 | excluded = True | ||
522 | 437 | return excluded | ||
523 | 438 | |||
524 | 439 | def get_sample_files_from_dir(self, sample_dir): | ||
525 | 440 | """ | ||
526 | 441 | Recursively search the specified directory for files to test | ||
527 | 442 | :param sample_dir: Top level directory to search | ||
528 | 443 | :return: List containing path of all sub-files | ||
529 | 444 | """ | ||
530 | 445 | file_list = [] | ||
531 | 446 | for root, dirs, files in os.walk(sample_dir): | ||
532 | 447 | for file in files: | ||
533 | 448 | # remove any excluded types of file | ||
534 | 449 | if not self.is_excluded_file(file): | ||
535 | 450 | file_list.append(os.path.abspath(os.path.join(root, file))) | ||
536 | 451 | return file_list | ||
537 | 452 | |||
538 | 453 | def get_sample_file_list(self): | ||
539 | 454 | """ | ||
540 | 455 | Based on supplied config get the list of files to test | ||
541 | 456 | :return: List of files required for the current test | ||
542 | 457 | """ | ||
543 | 458 | # get the list of video sample files to play, based on the test config | ||
544 | 459 | sample_files = [] | ||
545 | 460 | if self.config.sample_dir: | ||
546 | 461 | # get the files from the specified directory | ||
547 | 462 | sample_files = self.get_sample_files_from_dir( | ||
548 | 463 | self.config.sample_dir) | ||
549 | 464 | elif self.config.sample_file: | ||
550 | 465 | # use the specified file | ||
551 | 466 | sample_files.append(self.config.sample_file) | ||
552 | 467 | return sample_files | ||
553 | 468 | |||
554 | 469 | def play_and_sample_video(self, file_path): | ||
555 | 470 | """ | ||
556 | 471 | Play the specified sample file in the mediaplayer-app | ||
557 | 472 | :param file_path: Path to video file to launch in mediaplayer-app | ||
558 | 473 | :return: True if playback comleted successfully | ||
559 | 474 | False if playback didn't complete successfully | ||
560 | 475 | """ | ||
561 | 476 | # launch media player app | ||
562 | 477 | self.open_media_player_app(file_path) | ||
563 | 478 | # capture video frames | ||
564 | 479 | # This call will run until playback is completed | ||
565 | 480 | # timeout is reached, or a freeze is detected | ||
566 | 481 | result = self.capture_and_check_frames_whilst_playing() | ||
567 | 482 | # close the media app | ||
568 | 483 | self.close_media_player_app() | ||
569 | 484 | return result | ||
570 | 485 | |||
571 | 486 | def print_failures(self, failures): | ||
572 | 487 | """ | ||
573 | 488 | Print out a list of failed video files | ||
574 | 489 | :param failures: List containing path of all failed video files | ||
575 | 490 | """ | ||
576 | 491 | divider = '-----------------------------------------------------------' | ||
577 | 492 | fail_count = len(failures) | ||
578 | 493 | if fail_count > 0: | ||
579 | 494 | print((divider)) | ||
580 | 495 | print(('{} failures:'.format(fail_count))) | ||
581 | 496 | print((divider)) | ||
582 | 497 | for failure in failures: | ||
583 | 498 | print((' {}'.format(failure))) | ||
584 | 499 | print((divider)) | ||
585 | 500 | |||
586 | 501 | def test_video_playback_from_samples(self): | ||
587 | 502 | """ | ||
588 | 503 | Test to play video files based on test config | ||
589 | 504 | """ | ||
590 | 505 | failures = [] | ||
591 | 506 | sections = [] | ||
592 | 507 | if self.config.run_all: | ||
593 | 508 | # run through every config section in the config file | ||
594 | 509 | sections = self.config.parser.sections() | ||
595 | 510 | else: | ||
596 | 511 | # only use the specified config section | ||
597 | 512 | sections.append(self.config.config_section) | ||
598 | 513 | |||
599 | 514 | for section in sections: | ||
600 | 515 | # copy the current section into the config | ||
601 | 516 | self.config.config_section = section | ||
602 | 517 | # now update config for current section | ||
603 | 518 | self.config.load_config() | ||
604 | 519 | # run the test for this section | ||
605 | 520 | video_files = self.get_sample_file_list() | ||
606 | 521 | for video in video_files: | ||
607 | 522 | # play all of the samples before checking results | ||
608 | 523 | start_time = time.time() | ||
609 | 524 | result = self.play_and_sample_video(video) | ||
610 | 525 | if not result: | ||
611 | 526 | # record failure time | ||
612 | 527 | end_time = time.time() | ||
613 | 528 | elapsed = time.gmtime(end_time - start_time) | ||
614 | 529 | elapsed_str = time.strftime("%H:%M:%S", elapsed) | ||
615 | 530 | # print time of failure with file name | ||
616 | 531 | failures.append(' {0} {1}'.format(elapsed_str, video)) | ||
617 | 532 | # take a screenshot of the failure with name of video file | ||
618 | 533 | # this will be added to the test details by autopilot | ||
619 | 534 | video_file, video_ext = os.path.splitext( | ||
620 | 535 | os.path.split(video)[1]) | ||
621 | 536 | screenshot_name = '{0}-{1}{2}'.format( | ||
622 | 537 | video_file, elapsed_str, video_ext) | ||
623 | 538 | self.take_screenshot(screenshot_name) | ||
624 | 539 | |||
625 | 540 | self.print_failures(failures) | ||
626 | 541 | # fail the test if there were any failures | ||
627 | 542 | self.assertThat(len(failures), Equals(0)) | ||
628 | 0 | 543 | ||
629 | === added directory 'ubuntu_experience_tests/tests/multimedia/video_samples' | |||
630 | === added file 'ubuntu_experience_tests/tests/multimedia/video_samples/__init__.py' | |||
631 | --- ubuntu_experience_tests/tests/multimedia/video_samples/__init__.py 1970-01-01 00:00:00 +0000 | |||
632 | +++ ubuntu_experience_tests/tests/multimedia/video_samples/__init__.py 2014-11-03 16:07:13 +0000 | |||
633 | @@ -0,0 +1,17 @@ | |||
634 | 1 | # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- | ||
635 | 2 | # | ||
636 | 3 | # Copyright 2014 Canonical Ltd. | ||
637 | 4 | # | ||
638 | 5 | # This file is part of ubuntu-experience-tests. | ||
639 | 6 | # | ||
640 | 7 | # This program is free software; you can redistribute it and/or modify | ||
641 | 8 | # it under the terms of the GNU General Public License version 3, as published | ||
642 | 9 | # by the Free Software Foundation. | ||
643 | 10 | # | ||
644 | 11 | # This program is distributed in the hope that it will be useful, | ||
645 | 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
646 | 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
647 | 14 | # GNU General Public License for more details. | ||
648 | 15 | # | ||
649 | 16 | # You should have received a copy of the GNU General Public License | ||
650 | 17 | # along with this program. If not, see <http://www.gnu.org/licenses/> | ||
651 | 0 | 18 | ||
652 | === added file 'ubuntu_experience_tests/tests/multimedia/video_samples/big_buck_bunny_480p_H264_AAC_25fps_1800K_short.MP4' | |||
653 | 1 | Binary files ubuntu_experience_tests/tests/multimedia/video_samples/big_buck_bunny_480p_H264_AAC_25fps_1800K_short.MP4 1970-01-01 00:00:00 +0000 and ubuntu_experience_tests/tests/multimedia/video_samples/big_buck_bunny_480p_H264_AAC_25fps_1800K_short.MP4 2014-11-03 16:07:13 +0000 differ | 19 | Binary files ubuntu_experience_tests/tests/multimedia/video_samples/big_buck_bunny_480p_H264_AAC_25fps_1800K_short.MP4 1970-01-01 00:00:00 +0000 and ubuntu_experience_tests/tests/multimedia/video_samples/big_buck_bunny_480p_H264_AAC_25fps_1800K_short.MP4 2014-11-03 16:07:13 +0000 differ |
654 | === added file 'ubuntu_experience_tests/tests/multimedia/video_samples/big_buck_bunny_720p_H264_AAC_25fps_3400K_short.MP4' | |||
655 | 2 | Binary files ubuntu_experience_tests/tests/multimedia/video_samples/big_buck_bunny_720p_H264_AAC_25fps_3400K_short.MP4 1970-01-01 00:00:00 +0000 and ubuntu_experience_tests/tests/multimedia/video_samples/big_buck_bunny_720p_H264_AAC_25fps_3400K_short.MP4 2014-11-03 16:07:13 +0000 differ | 20 | Binary files ubuntu_experience_tests/tests/multimedia/video_samples/big_buck_bunny_720p_H264_AAC_25fps_3400K_short.MP4 1970-01-01 00:00:00 +0000 and ubuntu_experience_tests/tests/multimedia/video_samples/big_buck_bunny_720p_H264_AAC_25fps_3400K_short.MP4 2014-11-03 16:07:13 +0000 differ |
FAILED: Continuous integration, rev:34 /code.launchpad .net/~rhuddie/ ubuntu- autopilot- tests/video_ playback_ tests/+ merge/240014/ +edit-commit- message
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
http:// jenkins. qa.ubuntu. com/job/ ubuntu- autopilot- tests-ubuntu- experience- tests-ci/ 46/ jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- utopic- touch/6284 jenkins. qa.ubuntu. com/job/ ubuntu- autopilot- tests-ubuntu- experience- tests-utopic- amd64-ci/ 46 jenkins. qa.ubuntu. com/job/ ubuntu- autopilot- tests-ubuntu- experience- tests-utopic- armhf-ci/ 46 jenkins. qa.ubuntu. com/job/ ubuntu- autopilot- tests-ubuntu- experience- tests-utopic- i386-ci/ 46 jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- runner- mako/5893 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- armhf/7536 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- armhf/7536/ artifact/ work/output/ *zip*/output. zip s-jenkins. ubuntu- ci:8080/ job/touch- flash-device/ 15177
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/ubuntu- autopilot- tests-ubuntu- experience- tests-ci/ 46/rebuild
http://