Merge lp:~canonical-platform-qa/ubuntu-system-tests/refine-depends-map into lp:ubuntu-system-tests

Proposed by Richard Huddie
Status: Merged
Approved by: Sergio Cazzolato
Approved revision: 441
Merged at revision: 430
Proposed branch: lp:~canonical-platform-qa/ubuntu-system-tests/refine-depends-map
Merge into: lp:ubuntu-system-tests
Diff against target: 318 lines (+173/-45)
3 files modified
debian/tests/dependencies.json (+134/-19)
ubuntu_system_tests/helpers/utils.py (+29/-26)
ubuntu_system_tests/selftests/test_debian.py (+10/-0)
To merge this branch: bzr merge lp:~canonical-platform-qa/ubuntu-system-tests/refine-depends-map
Reviewer Review Type Date Requested Status
Sergio Cazzolato Approve
platform-qa-bot continuous-integration Approve
Review via email: mp+301481@code.launchpad.net

Commit message

Refine the dependencies mapping file so that only required dependencies are used for tests being run.

Description of the change

Changes:
- Update the dependencies mappings for specific tests so they match the imports required.
- Replace DummyObject with DummyImportObject, which only works during test import. If a DummyImportObject is used during a test then it will raise exception. This is done to remove un-neccessary error logging during test setup, because only the minimum dependencies are now used.
- Add a self test to make sure the dependencies.json file is correctly formatted.

To test try any sequence of individual tests or groups of tests. The tests should run normally without import errors using only the dependencies required for the tests. - You may see some import warnings in the test log before the test runs, but this is expected. Once the test is running there should be no import errors shown.

To post a comment you must log in.
Revision history for this message
platform-qa-bot (platform-qa-bot) wrote :
review: Approve (continuous-integration)
438. By Richard Huddie

Merge from trunk.

Revision history for this message
platform-qa-bot (platform-qa-bot) wrote :
review: Approve (continuous-integration)
439. By Richard Huddie

Use DummyImportObject which only works during import and remove un-needed logging.

Revision history for this message
platform-qa-bot (platform-qa-bot) wrote :
review: Needs Fixing (continuous-integration)
440. By Richard Huddie

Fix flake8.

Revision history for this message
platform-qa-bot (platform-qa-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Sergio Cazzolato (sergio-j-cazzolato) wrote :

Code looks good to me, still testing to validate all the dependency groups.

441. By Richard Huddie

Merge from trunk.

Revision history for this message
platform-qa-bot (platform-qa-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Sergio Cazzolato (sergio-j-cazzolato) wrote :

I see this error with the last build:

Unpacking lxc-android-config (0.230+15.04.20160729-0ubuntu1) over (0.230+15.04.20160602-0ubuntu1) ...
dpkg: error processing archive /var/cache/apt/archives/lxc-android-config_0.230+15.04.20160729-0ubuntu1_all.deb (--unpack):
 unable to make backup link of `./lib/udev/rules.d/70-android.rules' before installing new version: Invalid cross-device link
Processing triggers for dbus (1.8.12-1ubuntu5) ...
Processing triggers for ureadahead (0.100.0-19) ...
ureadahead will be reprofiled on next reboot
Errors were encountered while processing:
 /var/cache/apt/archives/lxc-android-config_0.230+15.04.20160729-0ubuntu1_all.deb
E: Sub-process /usr/bin/dpkg returned an error code (1)
Exit request sent.

Revision history for this message
Richard Huddie (rhuddie) wrote :

Just to confirm the above seems to be a problem with the current image/archive state. Same issue is reproduced with trunk version. So it should be resolved when the next image is produced.

Revision history for this message
Sergio Cazzolato (sergio-j-cazzolato) wrote :

> I see this error with the last build:
>
> Unpacking lxc-android-config (0.230+15.04.20160729-0ubuntu1) over
> (0.230+15.04.20160602-0ubuntu1) ...
> dpkg: error processing archive /var/cache/apt/archives/lxc-android-
> config_0.230+15.04.20160729-0ubuntu1_all.deb (--unpack):
> unable to make backup link of `./lib/udev/rules.d/70-android.rules' before
> installing new version: Invalid cross-device link
> Processing triggers for dbus (1.8.12-1ubuntu5) ...
> Processing triggers for ureadahead (0.100.0-19) ...
> ureadahead will be reprofiled on next reboot
> Errors were encountered while processing:
> /var/cache/apt/archives/lxc-android-
> config_0.230+15.04.20160729-0ubuntu1_all.deb
> E: Sub-process /usr/bin/dpkg returned an error code (1)
> Exit request sent.

As this error seems to be an archive problem, I'll approve this branch.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/tests/dependencies.json'
2--- debian/tests/dependencies.json 2016-07-18 16:39:49 +0000
3+++ debian/tests/dependencies.json 2016-08-03 11:19:31 +0000
4@@ -82,13 +82,6 @@
5 "ubuntu_system_tests"
6 ],
7 "depends": [
8- "address-book-app-autopilot",
9- "camera-app-autopilot",
10- "dialer-app-autopilot",
11- "exiftool",
12- "gallery-app-autopilot",
13- "mediaplayer-app-autopilot",
14- "messaging-app-autopilot",
15 "python3-autopilot",
16 "python3-dbus",
17 "python3-debian",
18@@ -97,31 +90,153 @@
19 "python3-pexpect",
20 "python3-requests",
21 "python3-retrying",
22- "python3-selenium",
23 "python3-testtools",
24 "python3-warlock",
25 "subunit",
26 "ubuntu-keyboard-autopilot",
27- "ubuntuone-credentials-autopilot",
28- "ubuntu-system-settings-autopilot",
29 "ubuntu-system-tests-helpers",
30 "ubuntu-system-tests-suite",
31 "unity8-autopilot",
32 "unity-scope-click-autopilot",
33- "usbutils",
34+ "usbutils"
35+ ]
36+ },
37+ {
38+ "ids": [
39+ "ubuntu_system_tests.perftests.app_startup",
40+ "ubuntu_system_tests.tests.test_messaging_sms",
41+ "ubuntu_system_tests.tests.test_messaging_mms",
42+ "ubuntu_system_tests.tests.test_calls",
43+ "ubuntu_system_tests.tests.test_app_switcher",
44+ "ubuntu_system_tests.tests.test_add_contact"
45+ ],
46+ "depends": [
47+ "address-book-app-autopilot"
48+ ]
49+ },
50+ {
51+ "ids": [
52+ "ubuntu_system_tests.perftests.app_startup",
53+ "ubuntu_system_tests.tests.test_messaging_sms",
54+ "ubuntu_system_tests.tests.test_messaging_mms",
55+ "ubuntu_system_tests.tests.test_app_switcher",
56+ "ubuntu_system_tests.tests.test_camera"
57+ ],
58+ "depends": [
59+ "camera-app-autopilot"
60+ ]
61+ },
62+ {
63+ "ids": [
64+ "ubuntu_system_tests.perftests.app_startup",
65+ "ubuntu_system_tests.tests.test_app_switcher",
66+ "ubuntu_system_tests.tests.test_calls",
67+ "ubuntu_system_tests.tests.test_add_contact",
68+ "ubuntu_system_tests.tests.test_with_dialer"
69+ ],
70+ "depends": [
71+ "dialer-app-autopilot"
72+ ]
73+ },
74+ {
75+ "ids": [
76+ "ubuntu_system_tests.perftests.scalability",
77+ "ubuntu_system_tests.tests.test_camera"
78+ ],
79+ "depends": [
80+ "exiftool"
81+ ]
82+ },
83+ {
84+ "ids": [
85+ "ubuntu_system_tests.tests.webapps"
86+ ],
87+ "depends": [
88+ "chromium-chromedriver",
89+ "python3-selenium"
90+ ]
91+ },
92+ {
93+ "ids": [
94+ "ubuntu_system_tests.perftests.scalability.test_photos",
95+ "ubuntu_system_tests.perftests.app_startup",
96+ "ubuntu_system_tests.tests.test_messaging_sms",
97+ "ubuntu_system_tests.tests.test_messaging_mms",
98+ "ubuntu_system_tests.tests.scopes.test_photos_scope",
99+ "ubuntu_system_tests.tests.test_sdcard",
100+ "ubuntu_system_tests.tests.test_with_webbrowser"
101+ ],
102+ "depends": [
103+ "gallery-app-autopilot"
104+ ]
105+ },
106+ {
107+ "ids": [
108+ "ubuntu_system_tests.tests.scopes.test_video_scope",
109+ "ubuntu_system_tests.tests.test_calls",
110+ "ubuntu_system_tests.tests.test_sdcard",
111+ "ubuntu_system_tests.tests.test_camera",
112+ "ubuntu_system_tests.tests.test_with_webbrowser"
113+ ],
114+ "depends": [
115+ "mediaplayer-app-autopilot"
116+ ]
117+ },
118+ {
119+ "ids": [
120+ "ubuntu_system_tests.perftests.app_startup",
121+ "ubuntu_system_tests.tests.test_ubuntu_keyboard",
122+ "ubuntu_system_tests.tests.test_messaging_sms",
123+ "ubuntu_system_tests.tests.test_messaging_mms",
124+ "ubuntu_system_tests.tests.test_app_switcher",
125+ "ubuntu_system_tests.tests.test_calls",
126+ "ubuntu_system_tests.tests.test_with_webbrowser"
127+ ],
128+ "depends": [
129+ "messaging-app-autopilot"
130+ ]
131+ },
132+ {
133+ "ids": [
134+ "ubuntu_system_tests.perftests.app_startup",
135+ "ubuntu_system_tests.tests.test_about_this_phone",
136+ "ubuntu_system_tests.tests.test_messaging_sms",
137+ "ubuntu_system_tests.tests.test_messaging_mms",
138+ "ubuntu_system_tests.tests.test_rotation",
139+ "ubuntu_system_tests.tests.test_bluetooth",
140+ "ubuntu_system_tests.tests.test_calls",
141+ "ubuntu_system_tests.tests.test_brightness",
142+ "ubuntu_system_tests.tests.indicators",
143+ "ubuntu_system_tests.tests.test_sim_pin",
144+ "ubuntu_system_tests.tests.test_system_settings"
145+ ],
146+ "depends": [
147+ "ubuntu-system-settings-autopilot"
148+ ]
149+ },
150+ {
151+ "ids": [
152+ "ubuntu_system_tests.tests.test_app_store"
153+ ],
154+ "depends": [
155+ "ubuntuone-credentials-autopilot"
156+ ]
157+ },
158+ {
159+ "ids": [
160+ "ubuntu_system_tests.perftests.app_startup",
161+ "ubuntu_system_tests.tests.test_messaging_sms",
162+ "ubuntu_system_tests.tests.test_messaging_mms",
163+ "ubuntu_system_tests.tests.scopes.test_video_scope",
164+ "ubuntu_system_tests.tests.test_calls",
165+ "ubuntu_system_tests.tests.test_with_webbrowser"
166+ ],
167+ "depends": [
168 "webbrowser-app-autopilot"
169 ]
170 },
171 {
172 "ids": [
173- "ubuntu_system_tests.tests.webapps"
174- ],
175- "depends": [
176- "chromium-chromedriver"
177- ]
178- },
179- {
180- "ids": [
181 "unity8"
182 ],
183 "depends": [
184
185=== modified file 'ubuntu_system_tests/helpers/utils.py'
186--- ubuntu_system_tests/helpers/utils.py 2016-07-15 10:02:49 +0000
187+++ ubuntu_system_tests/helpers/utils.py 2016-08-03 11:19:31 +0000
188@@ -27,10 +27,14 @@
189
190 logger = logging.getLogger(__name__)
191
192+DUMMY_IMPORT_ERR = ('DummyImportObject being used because try_import failed. '
193+ 'Check all required dependencies are installed.')
194+
195
196 def try_import(name, package=None):
197 """
198- Import named module from package and return it or DummyObject if not found.
199+ Import named module from package and return it or DummyImportObject if
200+ not found.
201
202 This method is used in cases where an import is made but should not raise
203 an ImportError if the module is not found. The main usage for this is
204@@ -39,22 +43,19 @@
205 module must import successfully, but won't actually be executed so it is
206 not neccessary to have the dependency installed.
207
208- If a DummyObject is returned this allows any attributes or methods to be
209- imported from the DummyObject without error.
210+ If a DummyImportObject is returned this allows any attributes or methods
211+ to be imported from the DummyImportObject without error.
212
213 :param name: Absolute or relative name of module to import.
214 :param package: If name is relative, package must specify the name of the
215 package to import from.
216- :return: Imported module or DummyObject if it doesn't exist.
217+ :return: Imported module or DummyImportObject if it doesn't exist.
218
219 """
220 try:
221 return import_module(name, package)
222- except ImportError as e:
223- logger.warn(e.msg)
224- logger.warn('DummyObject created for module: {m} at: {i}'.format(
225- m=name, i=_get_caller_info()))
226- return DummyObject()
227+ except ImportError:
228+ return DummyImportObject()
229
230
231 def wait_until(predicate, *args, timeout=10, period=1, stop_event=None,
232@@ -139,14 +140,14 @@
233 return bool(result)
234
235
236-def _get_caller_info(stack_level=2):
237- """Return info string about the caller of the calling function.
238-
239- :param stack_level: Number of level up the call stack to check.
240- :return: String info showing file path and line number.
241- """
242- caller = stack()[stack_level]
243- return '{path}:{line}'.format(path=caller[1], line=caller[2])
244+def _is_import():
245+ """Return True if being imported during test discovery."""
246+ stack_trace = stack()
247+ stack_trace.reverse()
248+ for frame in stack_trace:
249+ if frame[3] == 'load_test_suite_from_name':
250+ return True
251+ return False
252
253
254 class AttrDict(dict):
255@@ -157,13 +158,14 @@
256 self.__dict__ = self
257
258
259-class DummyObject:
260+class DummyImportObject:
261 """
262- Class used to create objects with dummy attributes and methods.
263+ Class used to create objects with dummy attributes and methods that can
264+ be accessed during import operations only.
265
266 This is used when an object is required to return a dummy attribute value
267- or method result rather than raise a AttributeError or TypeError
268- exception.
269+ or method result during import rather than raise a AttributeError or
270+ TypeError exception.
271
272 This class can be used to create objects that support nested attributes
273 and methods.
274@@ -176,12 +178,13 @@
275 def __getattribute__(self, name):
276 """Return a refernce to self for every attribute value to support
277 nested attributes."""
278- logger.warn('Accessing DummyObject attribute: {n} from: {f}'.format(
279- n=name, f=_get_caller_info()))
280- return self
281+ if _is_import():
282+ return self
283+ raise AttributeError(DUMMY_IMPORT_ERR)
284
285 def __call__(self, *args, **kwargs):
286 """Return a reference to self for every function call to support
287 nested function calls."""
288- logger.warn('DummyObject call from: {}'.format(_get_caller_info()))
289- return self
290+ if _is_import():
291+ return self
292+ raise AttributeError(DUMMY_IMPORT_ERR)
293
294=== modified file 'ubuntu_system_tests/selftests/test_debian.py'
295--- ubuntu_system_tests/selftests/test_debian.py 2016-07-21 08:34:46 +0000
296+++ ubuntu_system_tests/selftests/test_debian.py 2016-08-03 11:19:31 +0000
297@@ -18,7 +18,9 @@
298 # along with this program. If not, see <http://www.gnu.org/licenses/>.
299 #
300
301+import unittest
302 import json
303+import os
304 import testscenarios
305
306 from fixtures import TempDir
307@@ -340,3 +342,11 @@
308 dep = {'id': 'dep1', 'condition': 'installed', 'tmpinstall': 'true'}
309 self.assertFalse(debian.is_dependency_required(dep, tmp_install=False))
310 mock_is_installed.assert_not_called()
311+
312+
313+class ReadDependenciesJSONTestCase(unittest.TestCase):
314+
315+ def test_dependencies_json_file_valid(self):
316+ deps_path = os.path.realpath('debian/tests/dependencies.json')
317+ with open(deps_path) as deps_file:
318+ json.loads(deps_file.read())

Subscribers

People subscribed via source and target branches

to all changes: