Merge lp:~canonical-platform-qa/ubuntu-system-tests/refactor-command-line into lp:ubuntu-system-tests

Proposed by Richard Huddie
Status: Merged
Approved by: Allan LeSage
Approved revision: 465
Merged at revision: 410
Proposed branch: lp:~canonical-platform-qa/ubuntu-system-tests/refactor-command-line
Merge into: lp:ubuntu-system-tests
Diff against target: 2945 lines (+1552/-1027)
10 files modified
README.rst (+18/-18)
debian/tests/control (+2/-2)
debian/tests/setup (+29/-0)
ubuntu_system_tests/host/command_line.py (+240/-610)
ubuntu_system_tests/host/commands.py (+535/-0)
ubuntu_system_tests/host/debian.py (+130/-0)
ubuntu_system_tests/selftests/test_command_line.py (+211/-397)
ubuntu_system_tests/selftests/test_commands.py (+239/-0)
ubuntu_system_tests/selftests/test_debian.py (+125/-0)
ubuntu_system_tests/selftests/utils.py (+23/-0)
To merge this branch: bzr merge lp:~canonical-platform-qa/ubuntu-system-tests/refactor-command-line
Reviewer Review Type Date Requested Status
platform-qa-bot continuous-integration Approve
Allan LeSage (community) Approve
Review via email: mp+298321@code.launchpad.net

Commit message

Refactor command line interface to seperate setup and test execution.

Description of the change

Command line now uses 2 commands: setup or run.

setup is used to provision the device ready for testing and allows: apt-get update, dist-upgrade, cache dependencies or install tests options. The default setup if no arguments are provided with setup command are to apt-get update, dist-upgrade, install apt-cacher and then download dependencies. It will only mount the file system and reboot when it needs to.

run is used only to run suites of tests on the device and won't try and change the state of the device.

Use -h option to get full list of options for each command.

Example to setup a device where network is already done:
python3 -m ubuntu_system_tests.run setup --network-ready

Example to run a test on a device that has been setup already:

python3 -m ubuntu_system_tests.run run -n -t ubuntu_system_tests.tests.scopes.test_manage_scopes.ManageScopesTest.test_manage_scopes_displays_scopes

When this lands the following MP into qa-jenkins-jobs will also need to land to keep the jenkins jobs working: https://code.launchpad.net/~canonical-platform-qa/qa-jenkins-jobs/ust-cmdline-refactor/+merge/298529

Readme and setup tests updated too, but there is another task to give the readme a complete overhaul.

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

Add sync command before reboot and report failure state of reboot.

Revision history for this message
platform-qa-bot (platform-qa-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Allan LeSage (allanlesage) wrote :

Able to get a passing test with this in Jenkins, suggest we land and debug further as necessary, one teensy comment.

review: Approve
465. By Richard Huddie

Fix typo.

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

> Able to get a passing test with this in Jenkins, suggest we land and debug
> further as necessary, one teensy comment.

Good spot, fixed the typo.

Revision history for this message
platform-qa-bot (platform-qa-bot) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'README.rst'
2--- README.rst 2016-06-10 13:25:06 +0000
3+++ README.rst 2016-06-29 08:06:07 +0000
4@@ -37,7 +37,7 @@
5
6 ::
7
8- $ sudo add-apt-repository ppa:canonical-platform-qa/ppa
9+ $ sudo add-apt-repository ppa:canonical-platform-qa/ubuntu-system-tests
10 $ sudo apt-get update
11 $ sudo apt-get install ubuntu-system-tests-host
12
13@@ -238,7 +238,7 @@
14
15 ::
16
17- $ run-system-tests
18+ $ system-tests run
19
20 Running specific sets of tests
21 ------------------------------
22@@ -249,12 +249,12 @@
23 just output the list of tests as an argument to the tool, like so:
24
25 ::
26- $ run-system-tests `cat test_lists/sanity.tests`
27+ $ system-tests run `cat test_lists/sanity.tests`
28
29 Command line arguments
30 ----------------------
31
32-You can pass arguments to the run-system-tests command to change the default
33+You can pass arguments to the system-tests command to change the default
34 behavior. In the following sections you will find some information about how
35 to use the arguments for some common scenarios.
36
37@@ -263,7 +263,7 @@
38
39 ::
40
41- $ run-system-tests --help
42+ $ system-tests --help
43
44 Run with a different configuration file
45 ---------------------------------------
46@@ -273,7 +273,7 @@
47
48 ::
49
50- $ run-system-tests --config myconfig.conf
51+ $ system-tests run --config myconfig.conf
52
53 By default, the config file should be in the *~/.config* directory, but you can
54 use a config file from a different directory by setting the *XDG_CONFIG_HOME*
55@@ -282,7 +282,7 @@
56
57 ::
58
59- $ XDG_CONFIG_HOME=/tmp run-system-tests --config myconfig.conf
60+ $ XDG_CONFIG_HOME=/tmp system-tests run --config myconfig.conf
61
62 You can use the different configuration files to store values for different
63 test profiles that you commonly use. For example, if you usually have two
64@@ -327,7 +327,7 @@
65
66 ::
67
68- $ run-system-tests --config-section arale
69+ $ system-tests run --config-section arale
70
71 Using this option also allows concurrent execution of tests on multiple devices
72 from the same host machine. In order to do this *device_serial* and
73@@ -371,7 +371,7 @@
74
75 ::
76
77- $ run-system-tests --touch-visualization ubuntu_system_tests.tests.test_tutorial.TutorialTestCase.test_complete_tutorial
78+ $ system-tests run --touch-visualization ubuntu_system_tests.tests.test_tutorial.TutorialTestCase.test_complete_tutorial
79
80 Install tests dependencies in the device
81 ----------------------------------------
82@@ -384,7 +384,7 @@
83
84 ::
85
86- $ run-system-tests --install-tests package1.module1
87+ $ system-tests setup --install-tests
88
89 Upgrade device using dist-upgrade
90 ---------------------------------
91@@ -396,7 +396,7 @@
92
93 ::
94
95- $ run-system-tests --dist-upgrade package1.module1
96+ $ system-tests setup --dist-upgrade
97
98 Cache downloaded dependencies on the device
99 -------------------------------------------
100@@ -419,7 +419,7 @@
101
102 ::
103
104- $ run-system-tests --cache-deps package1.module1
105+ $ system-tests setup --cache-deps
106
107 This will install the dependency cacher on the device and then reboot before
108 continuing to execute the tests as normal. Dependencies will be downloaded
109@@ -438,31 +438,31 @@
110 Easy device setup
111 -----------------
112
113-To allow devices be updated and prepared for testing easily *--setup* or *-a*
114-option can be used. This will use the --update-apt, --dist-upgrade and
115+To allow devices be updated and prepared for testing easily use setup command.
116+This will use the --update-apt, --dist-upgrade and
117 --cache-deps options to configure the device ready for testing.
118
119 ::
120
121- $ run-system-tests --setup package1.module1
122+ $ system-tests setup
123
124
125 Specify the list of tests to run
126 --------------------------------
127
128-The run-system-tests command receives an optional list of tests to run. For
129+The system-tests run command receives an optional list of tests to run. For
130 example, to run only the tests with id package1.module1.test1 and
131 package2.module2.test2:
132
133 ::
134
135- $ run-system-tests package1.module1.test1 package2.module2.test2
136+ $ system-tests run package1.module1.test1 package2.module2.test2
137
138 You can also pass a package or module id to run all the tests defined in it,
139 like:
140
141 ::
142
143- $ run-system-tests package1 package2.module2
144+ $ system-tests run package1 package2.module2
145
146 If you don't pass any test as argument it will run all the tests in the suite.
147
148=== modified file 'debian/tests/control'
149--- debian/tests/control 2016-05-26 14:25:26 +0000
150+++ debian/tests/control 2016-06-29 08:06:07 +0000
151@@ -1,4 +1,4 @@
152-Tests: systemtests
153+Tests: systemtests, setup
154 # Many tests output the emulators deprecation message to stderr.
155 Restrictions: allow-stderr
156 Depends: address-book-app,
157@@ -11,7 +11,7 @@
158 gallery-app,
159 gallery-app-autopilot,
160 mediaplayer-app,
161- mediaplayer-app-autopilot,
162+ mediaplayer-app-autopilot, # TMPINSTALL
163 messaging-app,
164 messaging-app-autopilot, # TMPINSTALL
165 oxideqt-chromedriver, # TMPINSTALL
166
167=== added file 'debian/tests/setup'
168--- debian/tests/setup 1970-01-01 00:00:00 +0000
169+++ debian/tests/setup 2016-06-29 08:06:07 +0000
170@@ -0,0 +1,29 @@
171+#!/usr/bin/python3
172+
173+#
174+# Ubuntu System Tests
175+# Copyright (C) 2016 Canonical
176+#
177+# This program is free software: you can redistribute it and/or modify
178+# it under the terms of the GNU General Public License as published by
179+# the Free Software Foundation, either version 3 of the License, or
180+# (at your option) any later version.
181+#
182+# This program is distributed in the hope that it will be useful,
183+# but WITHOUT ANY WARRANTY; without even the implied warranty of
184+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
185+# GNU General Public License for more details.
186+#
187+# You should have received a copy of the GNU General Public License
188+# along with this program. If not, see <http://www.gnu.org/licenses/>.
189+#
190+
191+import sys
192+
193+
194+def main():
195+ print('Setup successfully completed.')
196+
197+
198+if __name__ == '__main__':
199+ sys.exit(main())
200
201=== renamed file 'run-system-tests' => 'system-tests'
202=== modified file 'ubuntu_system_tests/host/command_line.py'
203--- ubuntu_system_tests/host/command_line.py 2016-06-10 13:25:06 +0000
204+++ ubuntu_system_tests/host/command_line.py 2016-06-29 08:06:07 +0000
205@@ -19,142 +19,186 @@
206 # along with this program. If not, see <http://www.gnu.org/licenses/>.
207 #
208
209-import deb822
210-import glob
211-import json
212 import logging
213 import os
214 import subprocess
215 import sys
216-import tempfile
217
218 from argparse import ArgumentParser
219+from collections import namedtuple
220+
221 from ubuntu_system_tests.host import (
222+ commands as cmds,
223+ debian,
224 results,
225- testdesc
226 )
227 from ubuntu_system_tests.common import (
228 clean_dir,
229 config,
230- ssh,
231 )
232
233 logger = logging.getLogger(__name__)
234-_ADT_RUN_SHORT_TIMEOUT = 600 # 10 minutes.
235-_ADT_RUN_TEST_TIMEOUT = 86400 # 24 hours
236-
237-# apt-cacher-ng definitions
238-APT_CACHER = 'apt-cacher-ng'
239-APT_CACHER_CACHE_DIR = '/var/cache/apt-cacher-ng'
240-APT_CACHER_LOG_DIR = '/var/log/apt-cacher-ng/'
241-APT_CACHER_INIT_FILE = '/etc/init/apt-cacher-ng.conf'
242-APT_PROXY = 'Acquire::http { Proxy "http://127.0.0.1:3142"; };'
243-APT_PROXY_FILE = '/etc/apt/apt.conf.d/01proxy'
244-EXT_CACHE_DIR = '/userdata/apt-cacher-ng/cache'
245-EXT_LOG_DIR = '/userdata/apt-cacher-ng/logs'
246-PERMISSION = '755'
247-
248-# Installation path for shared files
249-INSTALLED_SHARE_DIR = '/usr/share/ubuntu-system-tests'
250-# Installation path for installed python scripts
251-INSTALLED_PYTHON_DIR = '/usr/lib/python'
252+
253+Option = namedtuple('Option', ['args', 'kwargs'])
254+OPTION_CACHE_DEPS = Option(
255+ ['--cache-deps', '-d'],
256+ {'action': 'store_true',
257+ 'help': 'Cache dependencies on the device so they don\'t have to be '
258+ 'downloaded for every test run.',
259+ 'default': False})
260+OPTION_CONFIG = Option(
261+ ['--config', '-c'],
262+ {'help': 'The config file to use for this run.',
263+ 'default': 'ubuntu-system-tests.conf'})
264+OPTION_CONFIG_SECTION = Option(
265+ ['--config-section', '-e'],
266+ {'help': 'The section name to use in config file.',
267+ 'default': config.KEY_DEFAULT})
268+OPTION_DIST_UPGRADE = Option(
269+ ['--dist-upgrade', '-p'],
270+ {'action': 'store_true',
271+ 'help': 'Perform a dist-upgrade on the device to install latest '
272+ 'available updates from archive.',
273+ 'default': False})
274+OPTION_INSTALL_TESTS = Option(
275+ ['--install-tests', '-i'],
276+ {'action': 'store_true',
277+ 'help': 'Install all dependencies permanently in the device instead '
278+ 'of in the /tmp directory. This includes all production and test '
279+ 'dependencies.',
280+ 'default': False})
281+OPTION_NETWORK_READY = Option(
282+ ['--network-ready', '-n'],
283+ {'action': 'store_true',
284+ 'help': 'Assume that the network connection is already setup.',
285+ 'default': False})
286+OPTION_SILENT = Option(
287+ ['--silent', '-s'],
288+ {'action': 'store_true',
289+ 'help': 'Do not prompt for missing user config options, use default '
290+ 'values instead.',
291+ 'default': False})
292+OPTION_SUITES = Option(
293+ ['suites'],
294+ {'nargs': '*',
295+ 'help': 'The list of test suites to run. If left blank then all tests '
296+ 'from ubuntu_system_tests.tests will be run.'})
297+OPTION_TOUCH_VISUALIZATION = Option(
298+ ['--touch-visualization', '-t'],
299+ {'action': 'store_true',
300+ 'help': 'Enable visualization of touch points on screen.',
301+ 'default': False})
302+OPTION_UPDATE_APT = Option(
303+ ['--update-apt', '-u'],
304+ {'action': 'store_true',
305+ 'help': 'Update apt lists before installing the dependencies.',
306+ 'default': False})
307+OPTION_VERBOSE = Option(
308+ ['--verbose', '-v'],
309+ {'action': 'store_true',
310+ 'help': 'Provide verbose logging.',
311+ 'default': False})
312+
313+COMMON_ARGS = [
314+ OPTION_CONFIG,
315+ OPTION_CONFIG_SECTION,
316+ OPTION_NETWORK_READY,
317+ OPTION_VERBOSE]
318+RUN_ARGS = [
319+ OPTION_SILENT,
320+ OPTION_SUITES,
321+ OPTION_TOUCH_VISUALIZATION]
322+SETUP_ARGS = [
323+ OPTION_CACHE_DEPS,
324+ OPTION_DIST_UPGRADE,
325+ OPTION_INSTALL_TESTS,
326+ OPTION_UPDATE_APT
327+]
328+
329+COMMAND_RUN = 'run'
330+COMMAND_SETUP = 'setup'
331
332
333 def main(argv=None):
334- if argv is None:
335- argv = sys.argv[1:]
336- args = _parse_arguments(argv)
337- if args.setup:
338- args.update_apt = args.cache_deps = args.dist_upgrade = True
339- return run_system_tests(args.config, args.config_section, args.suites,
340- args.update_apt, args.network_ready,
341- args.touch_visualization, args.dist_upgrade,
342- args.install_tests, args.silent, args.cache_deps,
343- args.verbose)
344+ args = _parse_arguments(argv or sys.argv[1:])
345+ if args.command not in [COMMAND_RUN, COMMAND_SETUP]:
346+ logger.warning(
347+ 'Command option must be either "{r}" or "{s}". Use -h option for '
348+ 'further help.'.format(r=COMMAND_RUN, s=COMMAND_SETUP))
349+ return
350+
351+ if args.command == COMMAND_RUN:
352+ return run_system_tests(args)
353+ else:
354+ return setup_system_tests(args)
355+
356+
357+def _add_options(parser, options):
358+ """Add the specified list of options to the option parser object."""
359+ for option in options:
360+ parser.add_argument(*option.args, **option.kwargs)
361
362
363 def _parse_arguments(argv=None):
364- parser = ArgumentParser('Run system tests for Ubuntu Touch.')
365- parser.add_argument('--config', '-c',
366- help='The config file to use for this run.',
367- default='ubuntu-system-tests.conf')
368- parser.add_argument('--config-section', '-e',
369- help='The section name to use in config file.',
370- default=config.KEY_DEFAULT)
371- parser.add_argument(
372- '--update-apt', '-u', action='store_true',
373- help='Update apt lists before installing the dependencies',
374- default=False)
375- parser.add_argument(
376- '--touch-visualization', '-t', action='store_true',
377- help='Enable visualization of touch points on screen.')
378- parser.add_argument(
379- '--network-ready', '-n', action='store_true',
380- help='Assume that the network connection is already setup.')
381- parser.add_argument(
382- '--dist-upgrade', '-p', action='store_true',
383- help='Perform a dist-upgrade on the device to install latest '
384- 'available updates from archive.',
385- default=False)
386- parser.add_argument(
387- '--install-tests', '-i', action='store_true',
388- help='Install all dependencies permanently in the device instead of '
389- 'in the /tmp directory. This includes all production and test '
390- 'dependencies.',
391- default=False)
392- parser.add_argument(
393- '--silent', '-s', action='store_true',
394- help='Do not prompt for missing user config options, use default '
395- 'values instead.')
396- parser.add_argument(
397- '--cache-deps', '-d', action='store_true',
398- help='Cache dependencies on the device so they don\'t have to be '
399- 'downloaded for every test run.')
400- parser.add_argument(
401- '--setup', '-a', action='store_true',
402- help='Setup the device ready for testing. This will use --update-apt, '
403- '--dist-upgrade and --cache-deps options to update the device '
404- 'and cache dependencies so it is ready for testing.')
405- parser.add_argument(
406- 'suites', nargs='*', help='The list of test suites to run.')
407- parser.add_argument(
408- '--verbose', '-v', action='store_true',
409- help='Provide verbose logging.', default=False)
410+ """Parse the provided arguments and return in Namespace object."""
411+ parser = ArgumentParser(
412+ 'ubuntu-system-tests',
413+ description='Autopilot system test suite for Ubuntu Touch devices. '
414+ 'Allows devices to be setup for testing and then used to execute '
415+ 'suites of autopilot tests from ubuntu-system-tests or other '
416+ 'projects. For further help use -h option with required command.')
417+ subparsers = parser.add_subparsers(
418+ dest='command',
419+ help='Command options')
420+ run = subparsers.add_parser(
421+ COMMAND_RUN,
422+ help='Run tests on the device',
423+ description='Executes a list of tests on a connected device once it '
424+ 'has been setup using the setup command. If no tests are specified '
425+ 'to be run then all tests from ubuntu_system_tests.tests will be '
426+ 'executed.')
427+ _add_options(run, COMMON_ARGS + RUN_ARGS)
428+ setup = subparsers.add_parser(
429+ COMMAND_SETUP,
430+ help='Setup device ready for testing',
431+ description='Sets up the device ready for testing. This can include '
432+ 'performing apt-get update and dist-upgrade operations. Also it is '
433+ 'possible to install apt-cacher-ng to allow downloaded dependencies '
434+ 'to be cached on the device so they don\'t need to be downloaded for '
435+ 'every test run. If no arguments are specified then the default '
436+ 'operation will be to perform apt-get update, dist-upgrade and '
437+ 'install apt-cacher-ng. If any single option is specified then only '
438+ 'this action will be performed.')
439+ _add_options(setup, COMMON_ARGS + SETUP_ARGS)
440 return parser.parse_args(args=argv)
441
442
443-def run_system_tests(conf_name, config_section, tests_to_run, update_apt=False,
444- network_ready=False, touch_visualization=False,
445- dist_upgrade=False, install_tests=False, silent=False,
446- cache_deps=False, verbose=False):
447+def setup_system_tests(args):
448+ """Validate arguments and execute required setup commands on device."""
449+ if ((args.cache_deps or args.dist_upgrade or args.install_tests) and
450+ not args.update_apt):
451+ # An install operation is requested without update_apt, so set
452+ # update_apt to True.
453+ args.update_apt = True
454+ elif not (args.cache_deps or args.dist_upgrade or args.update_apt):
455+ # There were no optional args specified.
456+ # In this case apply the default actions, which are:
457+ # update_apt, cache_deps and dist_upgrade
458+ args.cache_deps = args.dist_upgrade = args.update_apt = True
459+ return run_autopkg_setup(args)
460+
461+
462+def run_system_tests(args):
463 """Run system tests in a device connected via USB and report the results.
464- :param conf_name: The name of the configuration file that will be used
465- for the system tests.
466- :param config_section: The section name to use in the config file.
467- :param tests_to_run: A list of tests to run.
468- :param update_apt: Boolean representing whether apt-get update should be
469- run on the device before installing dependencies.
470- :param network_ready: Boolean representing whether phablet-network should
471- be run to provision the network on the device.
472- :param dist_upgrade: Upgrade the device using dist-upgrade.
473- :param install_tests: Install the test dependencies permanently in the
474- device instead of in the /tmp directory.
475- :param touch_visualization: Enable visualization of touch points on screen
476- :param silent: If True then do not prompt for user config options, instead
477- use the default value.
478- :param cache_deps: If True then cache the downloaded dependencies so that
479- they don't have to be downloaded for every test run.
480+ :param args: command line options.
481 :returns: 0 when successful, other value when failed.
482
483 """
484- config_stack = _get_config_stack(conf_name, config_section, silent)
485 print_warnings()
486- clean_output_directory(config_stack)
487+ config_stack = _prepare_config(args)
488
489 enable_autopilot_introspection(config_stack)
490- return_code = run_autopkg_test(
491- config_stack, config_section, tests_to_run, update_apt, network_ready,
492- touch_visualization, dist_upgrade, install_tests, cache_deps, verbose)
493+ return_code = run_autopkg_test(config_stack, args)
494
495 if return_code <= 6:
496 # Return codes higher than 6 mean that there was a problem with adt or
497@@ -165,6 +209,14 @@
498 return return_code
499
500
501+def _prepare_config(args):
502+ """Get config object for specified arguments and clear previous results."""
503+ config_stack = _get_config_stack(
504+ args.config, args.config_section, vars(args).get('silent', False))
505+ clean_output_directory(config_stack)
506+ return config_stack
507+
508+
509 def get_camera_warning():
510 return '- Please ensure device is raised from surface to allow rear ' \
511 'camera to take a photograph during camera tests.'
512@@ -214,523 +266,101 @@
513 return config_stack
514
515
516-def _get_serial_argument(config_stack):
517- device_serial = config_stack.get('device_serial')
518- if device_serial:
519- return ['-s', device_serial]
520- else:
521- # No serial in the config, run the commands as if only one device is
522- # connected.
523- return []
524-
525-
526 def enable_autopilot_introspection(config_stack):
527- command = _build_enable_autopilot_introspection_command(config_stack)
528+ """Enable autopilot introspection on the required device."""
529+ command = cmds.build_enable_autopilot_introspection_command(config_stack)
530 subprocess.check_output(command)
531
532
533-def _build_enable_autopilot_introspection_command(config_stack):
534- command = (
535- ['phablet-config'] +
536- _get_serial_argument(config_stack) +
537- ['autopilot', '--dbus-probe', 'enable']
538- )
539- return command
540-
541-
542-def run_autopkg_test(config_stack, config_section, tests_to_run, update_apt,
543- network_ready, touch_visualization, dist_upgrade,
544- install_tests, cache_deps, verbose):
545- """ Run the autopkgtest in the revice for the tests selected
546+def run_autopkg_setup(args):
547+ """Run setup commands on the required device, rebooting if required.
548+ :param args: Command line arguments for setup command.
549+ :return: Setup status code, 0 indicating setup was successful. Any error
550+ status encountered during setup will be translated to error
551+ status 16 from autopkgtest which indicates a testbed failure.
552+ """
553+ config_stack = _prepare_config(args)
554+ adt_run_cmd = cmds.build_adt_run_setup_command(
555+ config_stack,
556+ args.config_section,
557+ cache_deps=args.cache_deps,
558+ dist_upgrade=args.dist_upgrade,
559+ install_tests=args.install_tests,
560+ network_ready=args.network_ready,
561+ update_apt=args.update_apt,
562+ verbose=args.verbose)
563+
564+ return run_setup_commands(adt_run_cmd, config_stack)
565+
566+
567+def run_setup_commands(setup_cmd, config_stack):
568+ """Run setup commands to prepare the device for test execution.
569+
570+ This will run the setup command on the device. If this causes a failure
571+ on the device, or a reboot is required, the device will reboot. The setup
572+ command will then be executed on the device again. If the second attempt
573+ at setup fails then the failure status will be reported and setup will
574+ stop.
575+
576+ :param setup_cmd: Command to execute to set the device up.
577+ :param config_stack: Device configuration data.
578+ :return: Setup status code, 0 indicating setup was successful. Any error
579+ status encountered during setup will be translated to error
580+ status 16 from autopkgtest which indicates a testbed failure.
581+ """
582+ count = 0
583+ status = 1
584+ while (status and count < 2):
585+ clean_output_directory(config_stack)
586+ status = subprocess.call(setup_cmd)
587+ if status and count < 1:
588+ # Error was reported after first setup attempt,
589+ # so reboot device and try again.
590+ logger.warning(
591+ 'Rebooting device after setup completed with '
592+ 'status {s}.'.format(s=status))
593+ reboot_status = _reboot_device(config_stack)
594+ if reboot_status:
595+ logger.warning(
596+ 'Device reboot completed with status '
597+ '{s}.'.format(s=reboot_status))
598+ return reboot_status
599+ count += 1
600+ return status
601+
602+
603+def _reboot_device(config_stack):
604+ """Reboot the device specified in config.
605+ :param config_stack: Device configuration.
606+ :return: Status of reboot command.
607+ """
608+ for reboot_command in cmds._get_adb_reboot_commands(config_stack):
609+ status = subprocess.call(reboot_command)
610+ if status:
611+ # Error status reported from reboot, so don't attempt any further
612+ # commands and return status value.
613+ break
614+ return status
615+
616+
617+def run_autopkg_test(config_stack, args):
618+ """ Run the autopkgtest in the device for the tests selected
619 :param config_stack: The config objects
620- :param config_section: The name of config section to use.
621- :param tests_to_run: List of tests to run.
622- :param update_apt: True if the packages hasve to be updated
623- :param network_ready: True if the network set in the config has to be
624- configured in the device
625- :param dist_upgrade: Upgrade the device using dist-upgrade.
626- :param install_tests: Install the test dependencies permanently in the
627- device instead of in the /tmp directory.
628- :param cache_deps: If True then cache the downloaded dependencies so that
629- they don't have to be downloaded for every test run.
630- :param verbose: True to provide verbose logging.
631+ :param args: command line arguments
632 :return: the autopkgtest execution exit code
633 """
634- extra_depends = _get_extra_dependencies(
635- config_stack.get('tests_to_run', '').split()
636- )
637- if cache_deps:
638- adt_run_cmd = _build_adt_run_test_command(
639- config_stack,
640- config_section,
641- update_apt=update_apt,
642- network_ready=network_ready,
643- cache_deps=True,
644- verbose=verbose)
645- subprocess.call(adt_run_cmd)
646- clean_output_directory(config_stack)
647- logger.info('apt-cacher-ng installed on device')
648- update_apt = False
649-
650- if dist_upgrade:
651- adt_run_cmd = _build_adt_run_test_command(
652- config_stack,
653- config_section,
654- update_apt=update_apt,
655- network_ready=network_ready,
656- dist_upgrade=True,
657- verbose=verbose)
658- subprocess.call(adt_run_cmd)
659- clean_output_directory(config_stack)
660- update_apt = False
661-
662- if install_tests:
663- adt_run_cmd = _build_adt_run_test_command(
664- config_stack,
665- config_section,
666- extra_depends=extra_depends,
667- update_apt=update_apt,
668- network_ready=network_ready,
669- install_tests=True,
670- verbose=verbose)
671- subprocess.call(adt_run_cmd)
672- clean_output_directory(config_stack)
673- update_apt = False
674-
675- adt_run_cmd = _build_adt_run_test_command(
676+ extra_depends = debian.get_extra_dependencies(args.suites)
677+ adt_run_cmd = cmds.build_adt_run_test_command(
678 config_stack,
679- config_section,
680- tests_to_run=tests_to_run,
681+ args.config_section,
682+ tests_to_run=args.suites,
683 extra_depends=extra_depends,
684- update_apt=update_apt,
685- network_ready=network_ready,
686- touch_visualization=touch_visualization,
687- add_ppa=True,
688- verbose=verbose)
689+ network_ready=args.network_ready,
690+ touch_visualization=args.touch_visualization,
691+ verbose=args.verbose)
692 return subprocess.call(adt_run_cmd)
693
694
695-def _get_extra_dependencies(tests_to_run):
696- """
697- Get any extra dependencies required to run the list of
698- tests provided
699-
700- :param tests_to_run: The list of tests to run
701- :returns: A list of the extra dependencies
702- """
703- depends_map = _read_dependency_files(
704- os.path.realpath('ubuntu_system_tests/external_tests')
705- )
706- extra_depends = []
707- for test in tests_to_run:
708- extra_depends.extend(_extra_dependencies_for_test(test, depends_map))
709- return list(set(extra_depends))
710-
711-
712-def _read_dependency_files(deps_path):
713- """
714- Read the information about how dependencies map
715- to test names from the .json files in the path
716- provided.
717-
718- :param deps_path: The path to the directory containing the files
719- :returns: A dictionary associating test prefixes with lists of dependencies
720- """
721- depends_map = {}
722- for file in glob.glob(deps_path + '/*.json'):
723- with open(file) as deps_file:
724- for depends in json.loads(deps_file.read())['test_dependencies']:
725- depends_map[depends['id']] = depends['depends']
726- return depends_map
727-
728-
729-def _extra_dependencies_for_test(test, depends_map):
730- """
731- Calculates the extra dependencies required for a particular test
732-
733- :param test: The test to get the dependencies for
734- :param depends_map: The dependency mapping
735- :returns: A list of the extra dependencies
736- """
737- extra_dependencies = []
738- for id in depends_map.keys():
739- if test.startswith(id):
740- extra_dependencies.append(depends_map[id])
741- return extra_dependencies
742-
743-
744-def _create_temp_control_file(dependencies,
745- control_file='debian/tests/control'):
746- """Create a copy of the test suite control file, appending the list of
747- dependencies
748-
749- :param dependencies: List of dependencies to append to file
750- :returns: File path to the new control file
751- """
752- # create a temporary file
753- _, tmp_path = tempfile.mkstemp(text=True)
754- # open existing control file
755- with open(os.path.realpath(control_file), 'r') as tests_control:
756- new_content = _append_dependencies(
757- tests_control, dependencies)
758- # write the new content to the temp file
759- with open(tmp_path, 'w') as tmp_file:
760- tmp_file.write(new_content)
761- # save the path in config
762- return tmp_path
763-
764-
765-def _append_dependencies(tests_control, dependencies):
766- """Append the list of dependencies to the file content and return"""
767- content = ''
768- for pkg in deb822.Packages.iter_paragraphs(tests_control):
769- if pkg['Tests'] == 'systemtests':
770- current_deps = pkg['Depends']
771- for dep in dependencies:
772- current_deps += '\n {},'.format(dep)
773- pkg['Depends'] = current_deps
774- content += pkg.dump() + '\n'
775- return content.rstrip()
776-
777-
778-def _is_installed():
779- """Return True if the suite is running from installed location."""
780- return os.path.realpath(__file__).startswith(INSTALLED_PYTHON_DIR)
781-
782-
783-def _get_debian_path():
784- """Return the path of the debian folder.
785- This will depend on whether tests are running from installed location
786- or local source directory.
787- """
788- return INSTALLED_SHARE_DIR if _is_installed() else os.getcwd()
789-
790-
791-def _build_basic_adt_run_test_command(config_stack, extra_depends, verbose):
792- """ Build and return the first part of the adt-run """
793- output_dir = config_stack.get('output_dir')
794-
795- run_cmd = ['adt-run']
796- if verbose:
797- run_cmd.append('-ddd')
798- if extra_depends:
799- run_cmd.append('--override-control={}'.format(
800- _create_temp_control_file(extra_depends))
801- )
802- run_cmd.extend([
803- # Updating and installing can take a while.
804- '--timeout-short={}'.format(_ADT_RUN_SHORT_TIMEOUT),
805- # Regression tests can take up to 8 hours, no reason to cut short.
806- '--timeout-test={}'.format(_ADT_RUN_TEST_TIMEOUT),
807- '-B',
808- '--unbuilt-tree={}'.format(_get_debian_path()),
809- '--output-dir',
810- output_dir,
811- # Even if the config file on the host has a different name, on the
812- # testbed it's copied with the default name.
813- '--copy',
814- '{src}:{dest}'.format(
815- src=config_stack.file_path,
816- dest=config.get_device_config_file_path()),
817- ])
818- return run_cmd
819-
820-
821-def _build_adt_run_test_command(config_stack, config_section,
822- tests_to_run=None, extra_depends=None,
823- update_apt=False, network_ready=False,
824- touch_visualization=False, add_ppa=False,
825- dist_upgrade=False, install_tests=False,
826- cache_deps=False, verbose=False):
827-
828- device_password = config_stack.get('device_password')
829- run_cmd = _build_basic_adt_run_test_command(
830- config_stack, extra_depends, verbose)
831-
832- ssh_cmd = (
833- ['ssh', '-s', 'adb', '--', '-p', device_password] +
834- _get_serial_argument(config_stack)
835- )
836- run_cmd.extend(_get_set_tests_to_run_command(tests_to_run))
837- run_cmd.extend(_get_set_config_section_command(config_section))
838- run_cmd.extend(_get_set_touch_visualization(touch_visualization))
839- run_cmd.extend(_get_network_setup_command(config_stack, network_ready))
840- run_cmd.extend(_get_update_apt_command(update_apt))
841- run_cmd.extend(_get_apparmor_rules_update_command())
842- run_cmd.extend(ssh.get_ssh_config_commands())
843-
844- if cache_deps:
845- run_cmd.extend(_get_apt_cacher_setup_command())
846- return run_cmd + ['---'] + ssh_cmd
847-
848- if dist_upgrade:
849- run_cmd.extend(_get_dist_upgrade_setup_command())
850- return run_cmd + ['---'] + ssh_cmd
851-
852- run_cmd = _add_ppa_commands(add_ppa, run_cmd)
853-
854- if install_tests:
855- run_cmd.extend(_get_install_tests_setup_command())
856- else:
857- run_cmd.extend(_get_fs_ro_command())
858-
859- return run_cmd + ['---'] + ssh_cmd
860-
861-
862-def _add_ppa_commands(add_ppa, run_cmd):
863- """Add the ppa setup commands if required and return command list."""
864- if add_ppa:
865- run_cmd.extend(_get_fs_rw_command())
866- run_cmd.extend(_get_ppa_and_testability_setup_command())
867- return run_cmd
868-
869-
870-def _get_set_tests_to_run_command(tests_to_run):
871- """Return command to set list of tests as environment variable."""
872- tests = ' '.join(tests_to_run or [])
873- return _get_set_env_var_command('TESTS_TO_RUN', tests)
874-
875-
876-def _get_set_config_section_command(config_section):
877- """Return command to set config section name as environment variable."""
878- return _get_set_env_var_command('CONFIG_SECTION', config_section)
879-
880-
881-def _get_set_touch_visualization(touch_visualization):
882- """Return command to set touch visualization as environment variable."""
883- return _get_set_env_var_command(
884- 'TOUCH_VISUALIZATION', str(touch_visualization).lower())
885-
886-
887-def _get_set_env_var_command(name, value):
888- """Return command to set environment variable on device."""
889- return ['--env={n}={v}'.format(n=name, v=value)]
890-
891-
892-def _get_update_apt_command(update_apt):
893- """Return command to update apt."""
894- if update_apt:
895- return [
896- '--setup-commands',
897- # emulate pitti's convenience 'ro-apt-update' script, see
898- # http://anonscm.debian.org/cgit/autopkgtest/autopkgtest.git/commit/?id=a51f26f61c376 # NOQA
899- 'echo "Mounting rw to update"; RETRY=0; '
900- 'until mount -o remount,rw / || [ $RETRY -gt 10 ]; do sleep 1; '
901- 'RETRY=$(($RETRY+1)); echo "mount attempt failed, trying '
902- 'again..."; done; if [ $RETRY -gt 10 ]; then exit 1; fi; '
903- 'echo "apt-get updating"; apt-get update || '
904- '(sleep 15; apt-get update); '
905- 'echo "Mounting ro after updating"; RETRY=0; '
906- 'until mount -o remount,ro / || [ $RETRY -gt 60 ]; do '
907- 'sleep 1; RETRY=$(($RETRY+1)); echo "mount attempt failed, '
908- 'trying again..."; done; if [ $RETRY -gt 60 ]; then exit 1; fi'
909- ]
910- return []
911-
912-
913-def _get_device_network_command(wifi_ssid, wifi_password):
914- """Return command to configure wifi network on device.
915-
916- :param wifi_ssid: SSID of required wifi network
917- :param wifi_password: Password of required wifi network
918-
919- """
920- cmd_fmt = ('nmcli device wifi connect '
921- '\'{ssid}\' password \'{password}\' 2>/dev/null || true')
922- return cmd_fmt.format(ssid=wifi_ssid, password=wifi_password)
923-
924-
925-def _get_fs_rw_command():
926- return [
927- '--setup-commands',
928- 'echo "Mounting rw to install packages"; '
929- 'sync; RETRY=0; until mount -o remount,rw / || [ $RETRY -gt 10 ]; '
930- 'do sleep 1; RETRY=$(($RETRY+1)); echo "mount attempt failed, trying '
931- 'again..."; done; if [ $RETRY -gt 10 ]; then exit 1; fi'
932- ]
933-
934-
935-def _get_fs_ro_command():
936- return [
937- '--setup-commands',
938- 'echo "Mounting ro after installing packages"; '
939- 'sync; RETRY=0; until mount -o remount,ro / || [ $RETRY -gt 10 ]; '
940- 'do sleep 1; RETRY=$(($RETRY+1)); echo "mount attempt failed, trying '
941- 'again..."; done; if [ $RETRY -gt 10 ]; then exit 1; fi'
942- ]
943-
944-
945-def _get_network_setup_command(config_stack, network_ready):
946- """ The network needs to be configured on the device
947- This setup-command should be the first to run so that wi-fi is ready
948- """
949- cmd = []
950- if not network_ready:
951- network_cmd = _get_device_network_command(
952- config_stack.get('wifi_ssid'),
953- config_stack.get('wifi_password'))
954- cmd = ['--setup-commands', network_cmd]
955-
956- return cmd + [
957- '--setup-commands', 'echo \'Checking device network connection...\'; '
958- 'RETRY=0; until wget -q --spider launchpad.net || [ $RETRY -gt 30 ]; '
959- 'do sleep 1; RETRY=$(($RETRY+1)); echo "wget attempt $RETRY failed, '
960- ' trying again..."; done; if [ $RETRY -gt 30 ]; then echo \'Device '
961- 'has no network connection!\'; exit 1; fi'
962- ]
963-
964-
965-def _get_ppa_and_testability_setup_command():
966- return [
967- '--setup-commands',
968- 'if ! ls /etc/apt/sources.list.d/canonical-platform-qa* > /dev/null '
969- '2>&1; then '
970- 'apt-add-repository -y ppa:canonical-platform-qa/selenium; '
971- 'apt-add-repository -y ppa:canonical-platform-qa/ubuntu-system-tests; '
972- 'apt-get --no-list-cleanup update -o Dir::Etc::SourceList=/dev/null; '
973- 'fi',
974- '--setup-commands',
975- 'if apt-cache policy qttestability-autopilot | '
976- 'grep -q "Installed: (none)"; then '
977- 'apt-get install -y --no-install-recommends qttestability-autopilot; '
978- 'fi'
979- ]
980-
981-
982-def _get_reboot_command():
983- """Return command to reboot device."""
984- return ['--setup-commands', 'reboot']
985-
986-
987-def _get_apt_cacher_autostart_command():
988- """Write the apt-cacher-ng conf file into /etc/init/apt-cacher-ng.conf
989- to re-launch apt-cacher-ng on each subsequent reboot.
990-
991- This method assumes that upstart is used as the init system. If this
992- changes in future then this method will need updating to accomodate that.
993- """
994- script = ('start on runlevel [2345]\n'
995- 'script\n' +
996- _get_mount_dir_command(EXT_LOG_DIR, APT_CACHER_LOG_DIR) +
997- _get_mount_dir_command(EXT_CACHE_DIR, APT_CACHER_CACHE_DIR) +
998- _get_apt_cacher_start_command() +
999- '\nend script')
1000- return ['--setup-commands',
1001- _get_create_file_command(
1002- content=script, path=APT_CACHER_INIT_FILE)]
1003-
1004-
1005-def _get_apt_cacher_install_command():
1006- """Return command to install apt-cacher-ng on device and configure it to
1007- use userdata partion for caching and logging."""
1008- return [
1009- '--setup-commands',
1010- _get_install_package_command(APT_CACHER) +
1011- _get_apt_cacher_stop_command() +
1012- _get_create_folder_command(
1013- path=EXT_LOG_DIR, owner=APT_CACHER, permissions=PERMISSION) +
1014- _get_create_folder_command(
1015- path=EXT_CACHE_DIR, owner=APT_CACHER, permissions=PERMISSION) +
1016- _get_create_folder_command(
1017- path=APT_CACHER_CACHE_DIR, owner=APT_CACHER,
1018- permissions=PERMISSION) +
1019- _get_mount_dir_command(EXT_LOG_DIR, APT_CACHER_LOG_DIR) +
1020- _get_mount_dir_command(EXT_CACHE_DIR, APT_CACHER_CACHE_DIR) +
1021- _get_create_file_command(content=APT_PROXY, path=APT_PROXY_FILE) +
1022- _get_apt_cacher_start_command()]
1023-
1024-
1025-def _get_create_folder_command(path, owner, permissions):
1026- """Return command to create a folder with specified path, owner and
1027- permissions."""
1028- return ('if ! [ -d {path} ]; then '
1029- 'mkdir -p {path}; fi; '
1030- 'chown {owner}:{owner} {path}; '
1031- 'chmod {permissions} {path}; ').format(
1032- path=path, owner=owner, permissions=permissions)
1033-
1034-
1035-def _get_install_package_command(package):
1036- """Return command to install package on device."""
1037- return ('apt-get -y install {package}; ').format(package=package)
1038-
1039-
1040-def _get_mount_dir_command(target, source):
1041- """Return command to create a symlink between source and target
1042- directories."""
1043- return 'mount -o bind {target} {source}; '.format(
1044- target=target, source=source)
1045-
1046-
1047-def _get_create_file_command(content, path):
1048- """Return command to create file with specified content and path."""
1049- return 'echo \'{content}\' | tee {path}; '.format(
1050- content=content, path=path)
1051-
1052-
1053-def _get_apt_cacher_start_command():
1054- """Return command to start apt-cacher-ng process."""
1055- return ('/usr/sbin/apt-cacher-ng -c /etc/apt-cacher-ng '
1056- 'pidfile=/var/run/apt-cacher-ng/pid '
1057- 'SocketPath=/var/run/apt-cacher-ng/socket '
1058- 'foreground=0; ')
1059-
1060-
1061-def _get_apt_cacher_stop_command():
1062- """Return command to stop apt-cacher-ng process."""
1063- return 'pkill apt-cacher-ng || true; '
1064-
1065-
1066-def _get_dist_upgrade_command():
1067- """Return command to dist-upgrade device."""
1068- return ['--setup-commands', 'apt-get -y dist-upgrade']
1069-
1070-
1071-def _get_apt_cacher_setup_command():
1072- """Return command to install and configure apt-cacher-ng on device."""
1073- return (_get_fs_rw_command() + _get_apt_cacher_install_command() +
1074- _get_apt_cacher_autostart_command() + _get_reboot_command())
1075-
1076-
1077-def _get_dist_upgrade_setup_command():
1078- """Return command to dist-upgrade the device."""
1079- return (_get_fs_rw_command() + _get_dist_upgrade_command() +
1080- _get_reboot_command())
1081-
1082-
1083-def _get_install_tests_setup_command():
1084- """ Get a list with all the dependencies from the tests/control file and
1085- when the apt-get install does not install any package, the device is set
1086- as ro and exit, otherwise it is rebooted and will start as ro
1087- """
1088- dir_name = _get_debian_path()
1089- dependencies = testdesc.get_all_dependencies(dir_name, 'TMPINSTALL')
1090- install_command = 'apt-get -o dir::cache::archives="/tmp/" -y install'
1091- clean_command = 'apt-get clean'
1092- for dep in dependencies:
1093- install_command += ' {}'.format(dep.split()[0])
1094-
1095- return ['--setup-commands', clean_command,
1096- '--setup-commands', install_command,
1097- '--setup-commands', 'sleep 5',
1098- '--setup-commands', clean_command,
1099- '--setup-commands', 'rm -f /userdata/.writable_image',
1100- '--setup-commands', 'reboot']
1101-
1102-
1103-def _get_apparmor_rules_update_command():
1104- rules_file = '/var/cache/apparmor/click-ap.rules'
1105- update_command = 'printf "dbus (receive, send) ' \
1106- 'bus=session path=/com/canonical/Autopilot/**,\n' \
1107- '/tmp/adt-run.** r,\n" > {rules};' \
1108- 'aa-clickhook --include={rules}'.format(rules=rules_file)
1109- return [
1110- '--setup-commands',
1111- 'if [ ! -e {rules} ];then {command};fi'.format(rules=rules_file,
1112- command=update_command)
1113- ]
1114-
1115-
1116 def generate_user_report(config_stack):
1117 """Create a human readable report from the subunit results."""
1118 artifacts_directory = results.get_artifacts_directory(config_stack)
1119
1120=== added file 'ubuntu_system_tests/host/commands.py'
1121--- ubuntu_system_tests/host/commands.py 1970-01-01 00:00:00 +0000
1122+++ ubuntu_system_tests/host/commands.py 2016-06-29 08:06:07 +0000
1123@@ -0,0 +1,535 @@
1124+#!/usr/bin/env python3
1125+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
1126+
1127+#
1128+# Ubuntu System Tests
1129+# Copyright (C) 2014-2016 Canonical
1130+#
1131+# This program is free software: you can redistribute it and/or modify
1132+# it under the terms of the GNU General Public License as published by
1133+# the Free Software Foundation, either version 3 of the License, or
1134+# (at your option) any later version.
1135+#
1136+# This program is distributed in the hope that it will be useful,
1137+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1138+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1139+# GNU General Public License for more details.
1140+#
1141+# You should have received a copy of the GNU General Public License
1142+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1143+#
1144+
1145+from ubuntu_system_tests.common import (
1146+ config,
1147+ ssh,
1148+)
1149+from ubuntu_system_tests.host import (
1150+ debian,
1151+ testdesc,
1152+)
1153+
1154+# apt-cacher-ng definitions
1155+APT_CACHER = 'apt-cacher-ng'
1156+APT_CACHER_CACHE_DIR = '/var/cache/apt-cacher-ng'
1157+APT_CACHER_LOG_DIR = '/var/log/apt-cacher-ng/'
1158+APT_CACHER_INIT_FILE = '/etc/init/apt-cacher-ng.conf'
1159+APT_PROXY = 'Acquire::http { Proxy "http://127.0.0.1:3142"; };'
1160+APT_PROXY_FILE = '/etc/apt/apt.conf.d/01proxy'
1161+EXT_CACHE_DIR = '/userdata/apt-cacher-ng/cache'
1162+EXT_LOG_DIR = '/userdata/apt-cacher-ng/logs'
1163+PERMISSION = '755'
1164+
1165+QTTESTABILITY_AUTOPILOT = 'qttestability-autopilot'
1166+
1167+PPA_LIST = ['ppa:canonical-platform-qa/selenium',
1168+ 'ppa:canonical-platform-qa/ubuntu-system-tests']
1169+INSTALL_LIST = [QTTESTABILITY_AUTOPILOT]
1170+
1171+
1172+_ADT_RUN_SHORT_TIMEOUT = 600 # 10 minutes.
1173+_ADT_RUN_TEST_TIMEOUT = 86400 # 24 hours
1174+
1175+REBOOT_FILE = '/tmp/ust-reboot-required'
1176+
1177+STATUS_NO_CONNECTION = 1
1178+STATUS_FS_RO_MOUNT_ERROR = 2
1179+STATUS_FS_RW_MOUNT_ERROR = 3
1180+STATUS_REBOOT_REQUIRED = 4
1181+
1182+
1183+def build_basic_adt_run_test_command(config_stack, extra_depends, verbose):
1184+ """Build and return first part of adt-run command for test execution."""
1185+ run_cmd = _get_adt_run_cmd_start(config_stack, verbose)
1186+ if extra_depends:
1187+ run_cmd.append('--override-control={}'.format(
1188+ debian.create_temp_control_file(extra_depends))
1189+ )
1190+ run_cmd.extend([
1191+ # Updating and installing can take a while.
1192+ '--timeout-short={}'.format(_ADT_RUN_SHORT_TIMEOUT),
1193+ # Regression tests can take up to 8 hours, no reason to cut short.
1194+ '--timeout-test={}'.format(_ADT_RUN_TEST_TIMEOUT),
1195+ '--testname=systemtests',
1196+ '-B',
1197+ '--unbuilt-tree={}'.format(debian.get_debian_path()),
1198+ # Even if the config file on the host has a different name, on the
1199+ # testbed it's copied with the default name.
1200+ '--copy',
1201+ '{src}:{dest}'.format(
1202+ src=config_stack.file_path,
1203+ dest=config.get_device_config_file_path()),
1204+ ])
1205+ return run_cmd
1206+
1207+
1208+def build_basic_adt_run_setup_command(config_stack, verbose, cache_deps):
1209+ """Build and return first part of adt-run command for device setup."""
1210+ run_cmd = _get_adt_run_cmd_start(config_stack, verbose)
1211+ if cache_deps:
1212+ # Run the setup script from the control file listing all required
1213+ # dependencies. This will ensure all required dependencies are
1214+ # downloaded and cached as part of the setup command.
1215+ run_cmd.append('--testname=setup')
1216+ else:
1217+ # Dependency caching is not required. In this case don't download
1218+ # any dependencies by using a control file with no dependencies.
1219+ tmp_control = debian.create_temp_file('Tests: setup\nDepends: \n')
1220+ run_cmd.append('--override-control={}'.format(tmp_control))
1221+ run_cmd.extend([
1222+ '-B',
1223+ '--unbuilt-tree={}'.format(debian.get_debian_path())])
1224+ return run_cmd
1225+
1226+
1227+def build_adt_run_setup_command(config_stack, config_section, update_apt=False,
1228+ network_ready=False, dist_upgrade=False,
1229+ install_tests=False, cache_deps=False,
1230+ verbose=False):
1231+ """Build and return adt-run command for device setup."""
1232+ run_cmd = build_basic_adt_run_setup_command(
1233+ config_stack, verbose, cache_deps)
1234+
1235+ run_cmd.extend(_get_delete_reboot_required_setup_command())
1236+ run_cmd.extend(_get_set_config_section_command(config_section))
1237+ run_cmd.extend(_get_network_setup_command(config_stack, network_ready))
1238+ run_cmd.extend(_get_disable_auto_reboot_setup_command())
1239+ run_cmd.extend(_get_add_ppa_if_required_setup_command())
1240+ run_cmd.extend(_get_update_apt_setup_command(update_apt))
1241+ run_cmd.extend(_get_install_test_pkgs_if_required_setup_command())
1242+ run_cmd.extend(_get_apt_cacher_install_setup_command(cache_deps))
1243+ run_cmd.extend(_get_dist_upgrade_if_required_setup_command(dist_upgrade))
1244+ run_cmd.extend(_get_install_tests_setup_command(install_tests))
1245+ run_cmd.extend(_get_fs_ro_setup_command())
1246+ run_cmd.extend(_get_apparmor_rules_update_setup_command())
1247+ run_cmd.extend(_get_check_reboot_required_setup_command())
1248+
1249+ return run_cmd + ['---'] + _get_ssh_command(config_stack)
1250+
1251+
1252+def build_adt_run_test_command(config_stack, config_section,
1253+ tests_to_run=None, extra_depends=None,
1254+ network_ready=False, touch_visualization=False,
1255+ verbose=False):
1256+ """Build and return adt-run command for executing tests on device."""
1257+ run_cmd = build_basic_adt_run_test_command(
1258+ config_stack, extra_depends, verbose)
1259+
1260+ run_cmd.extend(_get_set_tests_to_run_command(tests_to_run))
1261+ run_cmd.extend(_get_set_config_section_command(config_section))
1262+ run_cmd.extend(_get_set_touch_visualization(touch_visualization))
1263+ run_cmd.extend(_get_network_setup_command(config_stack, network_ready))
1264+ run_cmd.extend(_get_apparmor_rules_update_setup_command())
1265+ run_cmd.extend(ssh.get_ssh_config_commands())
1266+
1267+ return run_cmd + ['---'] + _get_ssh_command(config_stack)
1268+
1269+
1270+def _get_adt_run_cmd_start(config_stack, verbose):
1271+ """Return the start of adt_run command."""
1272+ output_dir = config_stack.get('output_dir')
1273+ run_cmd = ['adt-run', '--output-dir', output_dir]
1274+ if verbose:
1275+ run_cmd.append('-ddd')
1276+ return run_cmd
1277+
1278+
1279+def _get_ssh_command(config_stack):
1280+ """Return command parameters for ssh connection to requried device."""
1281+ device_password = config_stack.get('device_password')
1282+ return (['ssh', '-s', 'adb', '--', '-p', device_password] +
1283+ _get_serial_argument(config_stack))
1284+
1285+
1286+def build_enable_autopilot_introspection_command(config_stack):
1287+ """Return command to enable autopilot introspection on required device."""
1288+ command = (
1289+ ['phablet-config'] +
1290+ _get_serial_argument(config_stack) +
1291+ ['autopilot', '--dbus-probe', 'enable']
1292+ )
1293+ return command
1294+
1295+
1296+def _get_adb_reboot_commands(config_stack):
1297+ """Return list of adb commands to reboot device."""
1298+ return [
1299+ _get_adb_command(config_stack, 'shell', 'sync'),
1300+ _get_adb_command(config_stack, 'reboot')]
1301+
1302+
1303+def _get_adb_command(config_stack, *args):
1304+ """Return adb command to run specified command args on connected device."""
1305+ return ['adb'] + _get_serial_argument(config_stack) + list(args)
1306+
1307+
1308+def _get_serial_argument(config_stack):
1309+ """Return serial commands from config, or empty list if not specified."""
1310+ device_serial = config_stack.get('device_serial')
1311+ if device_serial:
1312+ return ['-s', device_serial]
1313+ else:
1314+ # No serial in the config, run the commands as if only one device is
1315+ # connected.
1316+ return []
1317+
1318+
1319+def _get_set_tests_to_run_command(tests_to_run):
1320+ """Return command to set list of tests as environment variable."""
1321+ tests = ' '.join(tests_to_run or [])
1322+ return _get_set_env_var_adt_command('TESTS_TO_RUN', tests)
1323+
1324+
1325+def _get_set_config_section_command(config_section):
1326+ """Return command to set config section name as environment variable."""
1327+ return _get_set_env_var_adt_command('CONFIG_SECTION', config_section)
1328+
1329+
1330+def _get_set_touch_visualization(touch_visualization):
1331+ """Return command to set touch visualization as environment variable."""
1332+ return _get_set_env_var_adt_command(
1333+ 'TOUCH_VISUALIZATION', str(touch_visualization).lower())
1334+
1335+
1336+def _get_set_env_var_adt_command(name, value):
1337+ """Return command to set environment variable on device."""
1338+ return ['--env={n}={v}'.format(n=name, v=value)]
1339+
1340+
1341+def _get_update_apt_command():
1342+ """Return command to apt-get update."""
1343+ return ('echo "apt-get updating"; apt-get update || '
1344+ '(sleep 15; apt-get update); ')
1345+
1346+
1347+def _get_update_apt_setup_command(update_apt):
1348+ """Return setup command to apt-get update."""
1349+ if update_apt:
1350+ return [
1351+ '--setup-commands',
1352+ _get_fs_rw_command() +
1353+ _get_update_apt_command()]
1354+ return []
1355+
1356+
1357+def _get_device_network_command(wifi_ssid, wifi_password):
1358+ """Return command to configure wifi network on device.
1359+
1360+ :param wifi_ssid: SSID of required wifi network
1361+ :param wifi_password: Password of required wifi network
1362+
1363+ """
1364+ cmd_fmt = ('nmcli device wifi connect '
1365+ '\'{ssid}\' password \'{password}\' 2>/dev/null || true')
1366+ return cmd_fmt.format(ssid=wifi_ssid, password=wifi_password)
1367+
1368+
1369+def _get_is_fs_ro_command():
1370+ """Return command to indicate if file system is currently read-only."""
1371+ return 'grep \' /\ ext\' /proc/mounts | grep -q \'ro\''
1372+
1373+
1374+def _get_is_fs_rw_command():
1375+ """Return command to indicate if file system is currently writable."""
1376+ return 'grep \' /\ ext\' /proc/mounts | grep -q \'rw\''
1377+
1378+
1379+def _get_fs_rw_command():
1380+ """Return command to set file system read-write if not already."""
1381+ return _get_if_command(_get_is_fs_ro_command(), _get_set_fs_rw_command())
1382+
1383+
1384+def _get_fs_ro_setup_command():
1385+ """Return setup command to set file system read-only if not already."""
1386+ return [
1387+ '--setup-commands',
1388+ _get_if_command(_get_is_fs_rw_command(), _get_set_fs_ro_command())
1389+ ]
1390+
1391+
1392+def _get_set_fs_rw_command():
1393+ """Return command to set file system writable, retyring on failure."""
1394+ return ('echo "Mounting file system rw"; '
1395+ 'sync; RETRY=0; until mount -o remount,rw / || [ $RETRY -gt 10 ]; '
1396+ 'do sleep 1; RETRY=$(($RETRY+1)); echo "mount attempt failed, '
1397+ 'trying again..."; done; if [ $RETRY -gt 10 ]; then exit '
1398+ '{status}; fi; '.format(status=STATUS_FS_RW_MOUNT_ERROR))
1399+
1400+
1401+def _get_set_fs_ro_command():
1402+ """Return command to set file system read-only, retyring on failure."""
1403+ return ('echo "Mounting file system ro"; '
1404+ 'sync; RETRY=0; until mount -o remount,ro / || [ $RETRY -gt 10 ]; '
1405+ 'do sleep 1; RETRY=$(($RETRY+1)); echo "mount attempt failed, '
1406+ 'trying again..."; done; if [ $RETRY -gt 10 ]; then exit '
1407+ '{status}; fi; '.format(status=STATUS_FS_RO_MOUNT_ERROR))
1408+
1409+
1410+def _get_network_setup_command(config_stack, network_ready):
1411+ """ The network needs to be configured on the device
1412+ This setup-command should be the first to run so that wi-fi is ready
1413+ """
1414+ cmd = []
1415+ if not network_ready:
1416+ network_cmd = _get_device_network_command(
1417+ config_stack.get('wifi_ssid'),
1418+ config_stack.get('wifi_password'))
1419+ cmd = ['--setup-commands', network_cmd]
1420+
1421+ return cmd + [
1422+ '--setup-commands', 'echo \'Checking device network connection...\'; '
1423+ 'RETRY=0; until wget -q --spider launchpad.net || [ $RETRY -gt 60 ]; '
1424+ 'do sleep 1; RETRY=$(($RETRY+1)); echo "wget attempt $RETRY failed, '
1425+ ' trying again..."; done; if [ $RETRY -gt 60 ]; then echo \'Device '
1426+ 'has no network connection!\'; exit {status}; fi'.format(
1427+ status=STATUS_NO_CONNECTION)
1428+ ]
1429+
1430+
1431+def _get_apt_cacher_autostart_command():
1432+ """Write the apt-cacher-ng conf file into /etc/init/apt-cacher-ng.conf
1433+ to re-launch apt-cacher-ng on each subsequent reboot.
1434+
1435+ This method assumes that upstart is used as the init system. If this
1436+ changes in future then this method will need updating to accomodate that.
1437+ """
1438+ script = ('start on runlevel [2345]\n'
1439+ 'script\n' +
1440+ _get_mount_dir_command(EXT_LOG_DIR, APT_CACHER_LOG_DIR) +
1441+ _get_mount_dir_command(EXT_CACHE_DIR, APT_CACHER_CACHE_DIR) +
1442+ _get_apt_cacher_start_command() +
1443+ '\nend script')
1444+ return _get_create_file_command(content=script, path=APT_CACHER_INIT_FILE)
1445+
1446+
1447+def _get_apt_cacher_install_setup_command(apt_cacher_required):
1448+ """Return command to install apt-cacher-ng on device and configure it to
1449+ use userdata partion for caching and logging. If apt-cacher-ng is already
1450+ installed on the device then no action will be taken."""
1451+ if not apt_cacher_required:
1452+ return []
1453+ is_apt_cacher_installed = _get_packages_installed_command(APT_CACHER)
1454+ install_apt_cacher_cmds = (
1455+ _get_fs_rw_command() +
1456+ _get_install_packages_command(APT_CACHER) +
1457+ _get_apt_cacher_stop_command() +
1458+ _get_create_folder_command(
1459+ path=EXT_LOG_DIR, owner=APT_CACHER, permissions=PERMISSION) +
1460+ _get_create_folder_command(
1461+ path=EXT_CACHE_DIR, owner=APT_CACHER, permissions=PERMISSION) +
1462+ _get_create_folder_command(
1463+ path=APT_CACHER_CACHE_DIR, owner=APT_CACHER,
1464+ permissions=PERMISSION) +
1465+ _get_mount_dir_command(EXT_LOG_DIR, APT_CACHER_LOG_DIR) +
1466+ _get_mount_dir_command(EXT_CACHE_DIR, APT_CACHER_CACHE_DIR) +
1467+ _get_create_file_command(content=APT_PROXY, path=APT_PROXY_FILE) +
1468+ _get_apt_cacher_start_command() +
1469+ _get_apt_cacher_autostart_command())
1470+ return ['--setup-commands', _get_if_not_command(
1471+ is_apt_cacher_installed, install_apt_cacher_cmds)]
1472+
1473+
1474+def _get_if_not_command(condition, commands):
1475+ """Return if command for specified condition and commands."""
1476+ return 'if ! ({condition}); then {commands} fi; '.format(
1477+ condition=condition, commands=commands)
1478+
1479+
1480+def _get_if_command(condition, commands):
1481+ """Return if not command for specified condition and commands."""
1482+ return 'if ({condition}); then {commands} fi; '.format(
1483+ condition=condition, commands=commands)
1484+
1485+
1486+def _get_create_folder_command(path, owner, permissions):
1487+ """Return command to create a folder with specified path, owner and
1488+ permissions."""
1489+ return ('if ! [ -d {path} ]; then '
1490+ 'mkdir -p {path}; fi; '
1491+ 'chown {owner}:{owner} {path}; '
1492+ 'chmod {permissions} {path}; ').format(
1493+ path=path, owner=owner, permissions=permissions)
1494+
1495+
1496+def _get_install_test_packages_command():
1497+ """Return command to install required test packages."""
1498+ return (_get_fs_rw_command() +
1499+ _get_install_packages_command(' '.join(INSTALL_LIST)))
1500+
1501+
1502+def _get_test_packages_installed_command():
1503+ """Return command to indicate whether all required packages are already
1504+ installed or not.
1505+ :param apt_cacher_required: Whether apt-cahcer-ng is required to be
1506+ installed or not.
1507+ """
1508+ return _get_packages_installed_command(' '.join(INSTALL_LIST))
1509+
1510+
1511+def _get_packages_installed_command(packages):
1512+ """Return command to tell if all listed packages are installed or not."""
1513+ return ('! apt-cache policy {packages} | '
1514+ 'grep -q \'Installed: (none)\'; '.format(packages=packages))
1515+
1516+
1517+def _get_add_ppa_required_command():
1518+ """Return command to indicate if any ppa is required to be added."""
1519+ return ('! ls /etc/apt/sources.list.d/canonical-platform-qa* > /dev/null '
1520+ '2>&1')
1521+
1522+
1523+def _get_add_ppas_command():
1524+ """Return command to add all required ppas."""
1525+ cmd = ''
1526+ for ppa in PPA_LIST:
1527+ cmd += 'apt-add-repository -y {ppa}; '.format(ppa=ppa)
1528+ return _get_fs_rw_command() + cmd
1529+
1530+
1531+def _get_add_ppa_if_required_setup_command():
1532+ """Return setup command to add required ppas to device if required."""
1533+ return ['--setup-commands', _get_if_command(
1534+ _get_add_ppa_required_command(), _get_add_ppas_command())]
1535+
1536+
1537+def _dist_upgrade_required_command():
1538+ """Return command to indicate if any packages need to be updated as part
1539+ of a dist-upgrade command."""
1540+ return ('su - $ADT_NORMAL_USER -c \'apt-get dist-upgrade -s\' | '
1541+ 'grep -q \'Inst\\|Conf\\|Remv\'; ')
1542+
1543+
1544+def _get_dist_upgrade_if_required_setup_command(required):
1545+ """Return setup command to perform dist-upgrade if required."""
1546+ if not required:
1547+ return []
1548+ return ['--setup-commands', _get_if_command(
1549+ _dist_upgrade_required_command(), _get_dist_upgrade_command())]
1550+
1551+
1552+def _get_install_test_pkgs_if_required_setup_command():
1553+ """Return setup command to install test packages if required."""
1554+ return ['--setup-commands',
1555+ _get_if_not_command(
1556+ _get_test_packages_installed_command(),
1557+ _get_install_test_packages_command())]
1558+
1559+
1560+def _get_install_packages_command(packages):
1561+ """Return command to install packages on device."""
1562+ return ('apt-get -y --no-install-recommends install {packages}; ').format(
1563+ packages=packages)
1564+
1565+
1566+def _get_mount_dir_command(target, source):
1567+ """Return command to create a symlink between source and target
1568+ directories."""
1569+ return 'mount -o bind {target} {source}; '.format(
1570+ target=target, source=source)
1571+
1572+
1573+def _get_create_file_command(content, path):
1574+ """Return command to create file with specified content and path."""
1575+ return 'echo \'{content}\' | tee {path}; '.format(
1576+ content=content, path=path)
1577+
1578+
1579+def _get_apt_cacher_start_command():
1580+ """Return command to start apt-cacher-ng process."""
1581+ return ('/usr/sbin/apt-cacher-ng -c /etc/apt-cacher-ng '
1582+ 'pidfile=/var/run/apt-cacher-ng/pid '
1583+ 'SocketPath=/var/run/apt-cacher-ng/socket '
1584+ 'foreground=0; ')
1585+
1586+
1587+def _get_apt_cacher_stop_command():
1588+ """Return command to stop apt-cacher-ng process."""
1589+ return 'pkill apt-cacher-ng || true; '
1590+
1591+
1592+def _get_dist_upgrade_command():
1593+ """Return command to dist-upgrade device."""
1594+ return (_get_set_reboot_required_command() + 'apt-get -y dist-upgrade; ')
1595+
1596+
1597+def _get_check_reboot_required_setup_command():
1598+ """If a reboot is required, then exit with status to indicate that."""
1599+ return [
1600+ '--setup-commands',
1601+ 'if [ -f {p} ]; then exit {s}; fi; '.format(
1602+ p=REBOOT_FILE, s=STATUS_REBOOT_REQUIRED)]
1603+
1604+
1605+def _get_set_reboot_required_command():
1606+ """Create file to indicate that reboot is required."""
1607+ return 'if [ ! -f {p} ]; then touch {p}; fi; '.format(p=REBOOT_FILE)
1608+
1609+
1610+def _get_delete_reboot_required_setup_command():
1611+ """Delete file to indicate that reboot is required."""
1612+ return [
1613+ '--setup-commands',
1614+ 'if [ -f {p} ]; then rm -f {p}; fi; '.format(p=REBOOT_FILE)]
1615+
1616+
1617+def _get_disable_auto_reboot_setup_command():
1618+ """Return setup command to disable automatic rebooting by autopkgtest."""
1619+ return [
1620+ '--setup-commands',
1621+ 'if [ ! -f /run/autopkgtest_no_reboot.stamp ]; then '
1622+ 'touch /run/autopkgtest_no_reboot.stamp; fi; ']
1623+
1624+
1625+def _get_install_tests_setup_command(required):
1626+ """ Get a list with all the dependencies from the tests/control file and
1627+ when the apt-get install does not install any package, the device is set
1628+ as ro and exit, otherwise it is rebooted and will start as ro
1629+ """
1630+ if not required:
1631+ return []
1632+ dir_name = debian.get_debian_path()
1633+ dependencies = testdesc.get_all_dependencies(dir_name, 'TMPINSTALL')
1634+ install_command = 'apt-get -o dir::cache::archives="/tmp/" -y install'
1635+ clean_command = 'apt-get clean; '
1636+ for dep in dependencies:
1637+ install_command += ' {}'.format(dep.split()[0])
1638+ install_command += '; sleep 5; '
1639+
1640+ return ['--setup-commands',
1641+ _get_fs_rw_command() +
1642+ clean_command +
1643+ install_command +
1644+ clean_command]
1645+
1646+
1647+def _get_apparmor_rules_update_setup_command():
1648+ """Return setup command to update apparmor for autopilot introspection."""
1649+ rules_file = '/var/cache/apparmor/click-ap.rules'
1650+ update_command = 'printf "dbus (receive, send) ' \
1651+ 'bus=session path=/com/canonical/Autopilot/**,\n' \
1652+ '/tmp/adt-run.** r,\n" > {rules};' \
1653+ 'aa-clickhook --include={rules}'.format(rules=rules_file)
1654+ return [
1655+ '--setup-commands',
1656+ 'if [ ! -e {rules} ];then {command};fi'.format(rules=rules_file,
1657+ command=update_command)
1658+ ]
1659
1660=== added file 'ubuntu_system_tests/host/debian.py'
1661--- ubuntu_system_tests/host/debian.py 1970-01-01 00:00:00 +0000
1662+++ ubuntu_system_tests/host/debian.py 2016-06-29 08:06:07 +0000
1663@@ -0,0 +1,130 @@
1664+#!/usr/bin/env python3
1665+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
1666+
1667+#
1668+# Ubuntu System Tests
1669+# Copyright (C) 2014-2016 Canonical
1670+#
1671+# This program is free software: you can redistribute it and/or modify
1672+# it under the terms of the GNU General Public License as published by
1673+# the Free Software Foundation, either version 3 of the License, or
1674+# (at your option) any later version.
1675+#
1676+# This program is distributed in the hope that it will be useful,
1677+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1678+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1679+# GNU General Public License for more details.
1680+#
1681+# You should have received a copy of the GNU General Public License
1682+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1683+#
1684+
1685+import deb822
1686+import glob
1687+import json
1688+import os
1689+import tempfile
1690+
1691+# Installation path for shared files
1692+INSTALLED_SHARE_DIR = '/usr/share/ubuntu-system-tests'
1693+# Installation path for installed python scripts
1694+INSTALLED_PYTHON_DIR = '/usr/lib/python'
1695+
1696+
1697+def get_extra_dependencies(tests_to_run):
1698+ """
1699+ Get any extra dependencies required to run the list of
1700+ tests provided
1701+
1702+ :param tests_to_run: The list of tests to run
1703+ :returns: A list of the extra dependencies
1704+ """
1705+ depends_map = _read_dependency_files(
1706+ os.path.realpath('ubuntu_system_tests/external_tests')
1707+ )
1708+ extra_depends = []
1709+ for test in tests_to_run:
1710+ extra_depends.extend(_extra_dependencies_for_test(test, depends_map))
1711+ return list(set(extra_depends))
1712+
1713+
1714+def _read_dependency_files(deps_path):
1715+ """
1716+ Read the information about how dependencies map
1717+ to test names from the .json files in the path
1718+ provided.
1719+
1720+ :param deps_path: The path to the directory containing the files
1721+ :returns: A dictionary associating test prefixes with lists of dependencies
1722+ """
1723+ depends_map = {}
1724+ for file in glob.glob(deps_path + '/*.json'):
1725+ with open(file) as deps_file:
1726+ for depends in json.loads(deps_file.read())['test_dependencies']:
1727+ depends_map[depends['id']] = depends['depends']
1728+ return depends_map
1729+
1730+
1731+def _extra_dependencies_for_test(test, depends_map):
1732+ """
1733+ Calculates the extra dependencies required for a particular test
1734+
1735+ :param test: The test to get the dependencies for
1736+ :param depends_map: The dependency mapping
1737+ :returns: A list of the extra dependencies
1738+ """
1739+ extra_dependencies = []
1740+ for id in depends_map.keys():
1741+ if test.startswith(id):
1742+ extra_dependencies.append(depends_map[id])
1743+ return extra_dependencies
1744+
1745+
1746+def create_temp_control_file(dependencies,
1747+ control_file='debian/tests/control'):
1748+ """Create a copy of the test suite control file, appending the list of
1749+ dependencies
1750+
1751+ :param dependencies: List of dependencies to append to file
1752+ :returns: File path to the new control file
1753+ """
1754+ # open existing control file
1755+ with open(os.path.realpath(control_file), 'r') as tests_control:
1756+ new_content = _append_dependencies(
1757+ tests_control, dependencies)
1758+ return create_temp_file(new_content)
1759+
1760+
1761+def create_temp_file(content):
1762+ """Create a temporary file with specified content and return path to it."""
1763+ # create a temporary file and write content to it
1764+ _, tmp_path = tempfile.mkstemp(text=True)
1765+ with open(tmp_path, 'w') as tmp_file:
1766+ tmp_file.write(content)
1767+ return tmp_path
1768+
1769+
1770+def _append_dependencies(tests_control, dependencies):
1771+ """Append the list of dependencies to the file content and return"""
1772+ content = ''
1773+ for pkg in deb822.Packages.iter_paragraphs(tests_control):
1774+ if pkg['Tests'].startswith('systemtests'):
1775+ current_deps = pkg['Depends']
1776+ for dep in dependencies:
1777+ current_deps += '\n {},'.format(dep)
1778+ pkg['Depends'] = current_deps
1779+ content += pkg.dump() + '\n'
1780+ return content.rstrip()
1781+
1782+
1783+def _is_installed():
1784+ """Return True if the suite is running from installed location."""
1785+ return os.path.realpath(__file__).startswith(INSTALLED_PYTHON_DIR)
1786+
1787+
1788+def get_debian_path():
1789+ """Return the path of the debian folder.
1790+ This will depend on whether tests are running from installed location
1791+ or local source directory.
1792+ """
1793+ return INSTALLED_SHARE_DIR if _is_installed() else os.getcwd()
1794
1795=== modified file 'ubuntu_system_tests/selftests/test_command_line.py'
1796--- ubuntu_system_tests/selftests/test_command_line.py 2016-05-26 16:40:52 +0000
1797+++ ubuntu_system_tests/selftests/test_command_line.py 2016-06-29 08:06:07 +0000
1798@@ -18,10 +18,7 @@
1799 # along with this program. If not, see <http://www.gnu.org/licenses/>.
1800 #
1801
1802-import fixtures
1803-import json
1804 import os
1805-from tempfile import NamedTemporaryFile
1806 from unittest import mock
1807
1808 import testscenarios
1809@@ -29,248 +26,14 @@
1810 from ubuntu_system_tests import selftests
1811 from ubuntu_system_tests.host import command_line
1812 from ubuntu_system_tests.common import config
1813-
1814-
1815-def check_any_item_in_list_contains_value(list, value):
1816- return any(item.find(value) for item in list)
1817-
1818-
1819-def check_any_item_in_list_startswith_value(list, value):
1820- return any(item.startswith(value) for item in list)
1821-
1822-
1823-class CommandLineTestCase(selftests.ConfigBaseTestCase):
1824-
1825- def setUp(self):
1826- super().setUp()
1827- self.config_stack = config.UbuntuSystemTestsConfig()
1828-
1829- def test_setup_network_command_contains_credentials(self):
1830- self.set_config_values()
1831-
1832- command = command_line._get_device_network_command(
1833- 'test_ssid', 'test_password')
1834-
1835- self.assertTrue(command.startswith(
1836- 'nmcli device wifi connect \'test_ssid\' '
1837- 'password \'test_password\''))
1838-
1839- def test_enable_introspection_with_serial(self):
1840- serial = 'test_serial'
1841- self.set_config_values(device_serial=serial)
1842-
1843- command = command_line._build_enable_autopilot_introspection_command(
1844- self.config_stack)
1845-
1846- self.assertEqual(['phablet-config', '-s', 'test_serial'], command[:3])
1847-
1848- def test_enable_introspection_without_serial(self):
1849- self.set_config_values(device_serial='')
1850-
1851- command = command_line._build_enable_autopilot_introspection_command(
1852- self.config_stack)
1853-
1854- self.assertNotIn('-s', command)
1855-
1856- def test_adt_run_must_be_called_with_short_timeout(self):
1857- self.set_config_values()
1858-
1859- command = command_line._build_adt_run_test_command(
1860- self.config_stack, config.KEY_DEFAULT)
1861- command = ' '.join(command)
1862-
1863- run_arguments, _ = command.split('---')
1864- self.assertIn('--timeout-short=600', run_arguments)
1865-
1866- def test_ppa_setup_commands_set_image_readwrite(self):
1867- self.set_config_values()
1868- self.assertIn(
1869- 'mount -o remount,rw /',
1870- ' '.join(command_line._build_adt_run_test_command(
1871- self.config_stack, config.KEY_DEFAULT, add_ppa=True))
1872- )
1873-
1874- def test_adt_run_command_set_image_back_to_readonly(self):
1875- self.set_config_values()
1876- self.assertIn(
1877- 'mount -o remount,ro /',
1878- ' '.join(command_line._build_adt_run_test_command(
1879- self.config_stack, config.KEY_DEFAULT))
1880- )
1881-
1882- def test_ppa_setup_commands_only_update_ppa_details(self):
1883- aptget_command = str('apt-get --no-list-cleanup update -o'
1884- ' Dir::Etc::SourceList=/dev/null')
1885- self.assertTrue(
1886- check_any_item_in_list_contains_value(
1887- command_line._get_ppa_and_testability_setup_command(),
1888- aptget_command)
1889- )
1890-
1891- def test_ppa_setup_commands_install_testability_libs(self):
1892- self.assertTrue(
1893- check_any_item_in_list_contains_value(
1894- command_line._get_ppa_and_testability_setup_command(),
1895- 'apt-get install -y --no-install-recommends '
1896- 'qttestability-autopilot')
1897- )
1898-
1899- def test_ppa_setup_commands_used_in_adt_run(self):
1900- self.set_config_values()
1901- command = command_line._build_adt_run_test_command(
1902- self.config_stack, config.KEY_DEFAULT, add_ppa=True)
1903- command = ' '.join(command)
1904-
1905- run_arguments, _ = command.split('---')
1906- self.assertIn(
1907- 'apt-add-repository -y ppa:canonical-platform-qa/selenium',
1908- run_arguments
1909- )
1910-
1911- def test_adt_run_with_serial(self):
1912- serial = 'test_serial'
1913- self.set_config_values(device_serial=serial)
1914-
1915- command = command_line._build_adt_run_test_command(
1916- self.config_stack, config.KEY_DEFAULT)
1917- command = ' '.join(command)
1918-
1919- _, adb_arguments = command.split('ssh -s adb --')
1920- self.assertIn('-s test_serial', adb_arguments)
1921-
1922- def test_adt_run_without_serial(self):
1923- self.set_config_values(device_serial='')
1924-
1925- command = command_line._build_adt_run_test_command(
1926- self.config_stack, config.KEY_DEFAULT)
1927- command = ' '.join(command)
1928-
1929- _, adb_arguments = command.split('ssh -s adb --')
1930- self.assertNotIn('-s test_serial', adb_arguments)
1931-
1932- def test_adt_run_without_apt_update_must_be_called_without_setup_command(
1933- self):
1934- self.set_config_values()
1935-
1936- command = command_line._build_adt_run_test_command(
1937- self.config_stack, config.KEY_DEFAULT, update_apt=False)
1938- command = ' '.join(command)
1939-
1940- run_arguments, _ = command.split('---')
1941- self.assertNotIn('apt-get update', run_arguments)
1942-
1943- def test_adt_run_with_apt_update_must_be_called_with_setup_command(self):
1944- self.set_config_values()
1945-
1946- command = command_line._build_adt_run_test_command(
1947- self.config_stack, config.KEY_DEFAULT, update_apt=True)
1948- command = ' '.join(command)
1949-
1950- run_arguments, _ = command.split('---')
1951- self.assertIn('apt-get update', run_arguments)
1952-
1953- def test_adt_run_command_with_network_ready_creates_no_network(self):
1954- self.set_config_values()
1955-
1956- command = command_line._build_adt_run_test_command(
1957- self.config_stack, config.KEY_DEFAULT, network_ready=True)
1958-
1959- self.assertFalse(check_any_item_in_list_startswith_value(
1960- command, 'nmcli device wifi connect'))
1961-
1962- def test_adt_run_command_with_default_parameters_creates_network(self):
1963- self.set_config_values()
1964-
1965- command = command_line._build_adt_run_test_command(
1966- self.config_stack, config.KEY_DEFAULT)
1967-
1968- self.assertTrue(check_any_item_in_list_startswith_value(
1969- command, 'nmcli device wifi connect'))
1970-
1971- def test_get_extra_dependencies(self):
1972- tests = ('app1.tests.test_module.TestClass.test_x '
1973- 'app2.tests.test_module.TestClass.test_y '
1974- 'app3.tests.test_module.TestClass.test_z')
1975- self.set_config_values(tests_to_run=tests)
1976- expected_depends = ['dep1',
1977- 'dep2']
1978- # Mock _read_dependency_files
1979- with mock.patch(
1980- 'ubuntu_system_tests.host.command_line._read_dependency_files'
1981- ) as mock_read_depends:
1982- mock_read_depends.return_value = {
1983- 'app2.tests': 'dep1',
1984- 'app3.tests': 'dep2'
1985- }
1986- extra_depends = command_line._get_extra_dependencies(
1987- self.config_stack.get('tests_to_run').split()
1988- )
1989- self.assertCountEqual(extra_depends, expected_depends)
1990-
1991- def test_read_dependency_file(self):
1992- with fixtures.TempDir() as deps_dir:
1993- deps_file1 = open(os.path.join(deps_dir.path, 'deps1.json'), 'w')
1994- deps_file2 = open(os.path.join(deps_dir.path, 'deps2.json'), 'w')
1995- deps_json1 = {
1996- "test_dependencies": [
1997- {"id": "app1.tests", "depends": "dep1"}
1998- ]
1999- }
2000- deps_json2 = {
2001- "test_dependencies": [
2002- {"id": "app2.tests", "depends": "dep2"}
2003- ]
2004- }
2005- deps_file1.write(json.dumps(deps_json1))
2006- deps_file2.write(json.dumps(deps_json2))
2007- deps_file1.close()
2008- deps_file2.close()
2009-
2010- expected = {'app1.tests': 'dep1', 'app2.tests': 'dep2'}
2011- actual = command_line._read_dependency_files(deps_dir.path)
2012- self.assertEqual(expected, actual)
2013-
2014- def test_extra_dependencies_for_test(self):
2015- test = 'app1.tests.test_module.TestClass.test_y'
2016- dependencies_map = {'app1.tests': 'dep1', 'app2.tests': 'dep2'}
2017- extra_depends = command_line._extra_dependencies_for_test(
2018- test, dependencies_map
2019- )
2020- self.assertEqual(extra_depends, ['dep1'])
2021-
2022- def test_create_temp_control(self):
2023- with NamedTemporaryFile() as control:
2024- control.write("""Tests: systemtests
2025-Depends: dep1,
2026- dep2,
2027- dep3,
2028-
2029-Tests: someothertests
2030-Depends: other1,
2031- other2,
2032- other3,""".encode('utf-8'))
2033- control.flush()
2034- temp_control = command_line._create_temp_control_file(
2035- ['dep4', 'dep5'], control.name
2036- )
2037- with open(temp_control) as temp:
2038- tmp_control_content = temp.read()
2039- expected_content = """Tests: systemtests
2040-Depends: dep1,
2041- dep2,
2042- dep3,
2043- dep4,
2044- dep5,
2045-
2046-Tests: someothertests
2047-Depends: other1,
2048- other2,
2049- other3,"""
2050- self.assertEqual(tmp_control_content, expected_content)
2051-
2052-
2053-class RunSystemTestsCommandsTestCase(selftests.ConfigBaseTestCase,
2054- testscenarios.TestWithScenarios):
2055+from ubuntu_system_tests.selftests.utils import (
2056+ get_cmdline_run_params,
2057+ get_cmdline_setup_params,
2058+)
2059+
2060+
2061+class SetupSystemTestsCommandsTestCase(selftests.ConfigBaseTestCase,
2062+ testscenarios.TestWithScenarios):
2063
2064 scenarios = [
2065 # The nmcli network setup command is passed as --setup-command option
2066@@ -278,16 +41,12 @@
2067 ('without network setup', {
2068 'keyword_arguments': {'update_apt': False,
2069 'network_ready': True},
2070- 'expected_commands': ['phablet-config',
2071- 'grep',
2072- 'adt-run'],
2073+ 'expected_commands': ['adt-run'],
2074 }),
2075 ('with network setup', {
2076 'keyword_arguments': {'update_apt': False,
2077 'network_ready': False},
2078- 'expected_commands': ['phablet-config',
2079- 'grep',
2080- 'adt-run'],
2081+ 'expected_commands': ['adt-run'],
2082 }),
2083 ]
2084
2085@@ -296,12 +55,18 @@
2086 self.config_stack = config.UbuntuSystemTestsConfig()
2087
2088 @mock.patch('ubuntu_system_tests.host.command_line.generate_user_report')
2089- def test_run_system_tests_commands(self, mock_generate_user_report):
2090+ def test_setup_system_tests_commands(self, mock_generate_user_report):
2091 def get_command_from_call(call):
2092 """Return the name of the command, without the arguments."""
2093- return call[0][0][0]
2094+ cmd_list = call[0][0]
2095+ if type(cmd_list) == str:
2096+ cmd_list = cmd_list.split(' ')
2097+ return cmd_list[0]
2098
2099 self.set_config_values()
2100+ conf_name = os.path.basename(self.config_stack.file_path)
2101+ params = get_cmdline_setup_params(
2102+ config=conf_name, **self.keyword_arguments)
2103
2104 # Do not execute the subprocesses, just record their calls.
2105 with mock.patch('subprocess.Popen') as mock_popen:
2106@@ -310,10 +75,7 @@
2107 enter.communicate = mock.Mock(return_value=(0, 'dummy'))
2108 enter.poll = mock.Mock(return_value=0)
2109 enter.wait = mock.Mock(return_value=0)
2110-
2111- conf_name = os.path.basename(self.config_stack.file_path)
2112- command_line.run_system_tests(conf_name, config.KEY_DEFAULT, [],
2113- **self.keyword_arguments)
2114+ command_line.setup_system_tests(params)
2115
2116 # The first call doesn't run any command.
2117 calls = mock_popen.call_args_list[1:]
2118@@ -321,11 +83,11 @@
2119 self.assertEqual(self.expected_commands, commands)
2120
2121
2122-class MainPassingCommandLineArgumentsTestCase(testscenarios.TestWithScenarios):
2123+class SetupCommandLineArgumentsTestCase(testscenarios.TestWithScenarios):
2124
2125+ SETUP_CMD = 'setup'
2126 DEFAULT_CONFIG_FILE = 'ubuntu-system-tests.conf'
2127 DEFAULT_CONFIG_SECT = config.KEY_DEFAULT
2128- RUN_ALL_TESTS = []
2129 DO_APT_UPDATE = True
2130 DONT_APT_UPDATE = False
2131 NETWORK_ALREADY_SETUP = True
2132@@ -334,201 +96,254 @@
2133 DONT_DIST_UPGRADE = False
2134 DO_INSTALL_TESTS = True
2135 DONT_INSTALL_TESTS = False
2136- VISUALIZATION_ON = True
2137- VISUALIZATION_OFF = False
2138- DO_USE_SILENT = True
2139- DONT_USE_SILENT = False
2140 DO_USE_CACHE_DEPS = True
2141 DONT_USE_CACHE_DEPS = False
2142 DO_USE_VERBOSE_LOGGING = True
2143 DONT_USE_VERBOSE_LOGGING = False
2144
2145 scenarios = [
2146- ('no arguments', {
2147+ ('default setup arguments', {
2148 'command_line_arguments': [],
2149 'parsed_arguments': (
2150+ SETUP_CMD,
2151 DEFAULT_CONFIG_FILE,
2152 DEFAULT_CONFIG_SECT,
2153- RUN_ALL_TESTS,
2154- DONT_APT_UPDATE,
2155 NETWORK_NOT_ALREADY_SETUP,
2156- VISUALIZATION_OFF,
2157- DONT_DIST_UPGRADE,
2158+ DONT_USE_VERBOSE_LOGGING,
2159+ DO_USE_CACHE_DEPS,
2160+ DO_DIST_UPGRADE,
2161 DONT_INSTALL_TESTS,
2162- DONT_USE_SILENT,
2163- DONT_USE_CACHE_DEPS,
2164- DONT_USE_VERBOSE_LOGGING,
2165+ DO_APT_UPDATE,
2166 )
2167 }),
2168 ('alternative config', {
2169 'command_line_arguments': ['--config=alternative.conf'],
2170 'parsed_arguments': (
2171+ SETUP_CMD,
2172 'alternative.conf',
2173 DEFAULT_CONFIG_SECT,
2174- RUN_ALL_TESTS,
2175- DONT_APT_UPDATE,
2176 NETWORK_NOT_ALREADY_SETUP,
2177- VISUALIZATION_OFF,
2178- DONT_DIST_UPGRADE,
2179+ DONT_USE_VERBOSE_LOGGING,
2180+ DO_USE_CACHE_DEPS,
2181+ DO_DIST_UPGRADE,
2182 DONT_INSTALL_TESTS,
2183- DONT_USE_SILENT,
2184- DONT_USE_CACHE_DEPS,
2185- DONT_USE_VERBOSE_LOGGING,
2186+ DO_APT_UPDATE,
2187 )
2188 }),
2189 ('alternative config section', {
2190 'command_line_arguments': ['--config-section=custom-section'],
2191 'parsed_arguments': (
2192+ SETUP_CMD,
2193 DEFAULT_CONFIG_FILE,
2194 'custom-section',
2195- RUN_ALL_TESTS,
2196- DONT_APT_UPDATE,
2197 NETWORK_NOT_ALREADY_SETUP,
2198- VISUALIZATION_OFF,
2199- DONT_DIST_UPGRADE,
2200+ DONT_USE_VERBOSE_LOGGING,
2201+ DO_USE_CACHE_DEPS,
2202+ DO_DIST_UPGRADE,
2203 DONT_INSTALL_TESTS,
2204- DONT_USE_SILENT,
2205- DONT_USE_CACHE_DEPS,
2206- DONT_USE_VERBOSE_LOGGING,
2207+ DO_APT_UPDATE,
2208 )
2209 }),
2210- ('with apt-get update', {
2211+ ('only apt-get update', {
2212 'command_line_arguments': ['--update-apt'],
2213 'parsed_arguments': (
2214+ SETUP_CMD,
2215 DEFAULT_CONFIG_FILE,
2216 DEFAULT_CONFIG_SECT,
2217- RUN_ALL_TESTS,
2218+ NETWORK_NOT_ALREADY_SETUP,
2219+ DONT_USE_VERBOSE_LOGGING,
2220+ DONT_USE_CACHE_DEPS,
2221+ DONT_DIST_UPGRADE,
2222+ DONT_INSTALL_TESTS,
2223 DO_APT_UPDATE,
2224- NETWORK_NOT_ALREADY_SETUP,
2225- VISUALIZATION_OFF,
2226- DONT_DIST_UPGRADE,
2227- DONT_INSTALL_TESTS,
2228- DONT_USE_SILENT,
2229- DONT_USE_CACHE_DEPS,
2230- DONT_USE_VERBOSE_LOGGING,
2231- )
2232- }),
2233- ('one test suite', {
2234- 'command_line_arguments': ['test_suite'],
2235- 'parsed_arguments': (
2236- DEFAULT_CONFIG_FILE,
2237- DEFAULT_CONFIG_SECT,
2238- ['test_suite'],
2239- DONT_APT_UPDATE,
2240- NETWORK_NOT_ALREADY_SETUP,
2241- VISUALIZATION_OFF,
2242- DONT_DIST_UPGRADE,
2243- DONT_INSTALL_TESTS,
2244- DONT_USE_SILENT,
2245- DONT_USE_CACHE_DEPS,
2246- DONT_USE_VERBOSE_LOGGING,
2247- )
2248- }),
2249- ('multiple test suites', {
2250- 'command_line_arguments': [
2251- 'test_suite1', 'test_suite2', 'test_suite3'
2252- ],
2253- 'parsed_arguments': (
2254- DEFAULT_CONFIG_FILE,
2255- DEFAULT_CONFIG_SECT,
2256- ['test_suite1', 'test_suite2', 'test_suite3'],
2257- DONT_APT_UPDATE, NETWORK_NOT_ALREADY_SETUP, VISUALIZATION_OFF,
2258- DONT_DIST_UPGRADE,
2259- DONT_INSTALL_TESTS,
2260- DONT_USE_SILENT,
2261- DONT_USE_CACHE_DEPS,
2262- DONT_USE_VERBOSE_LOGGING,
2263 )
2264 }),
2265 ('with network already setup', {
2266 'command_line_arguments': ['--network-ready'],
2267 'parsed_arguments': (
2268- DEFAULT_CONFIG_FILE, DEFAULT_CONFIG_SECT, [], DONT_APT_UPDATE,
2269+ SETUP_CMD,
2270+ DEFAULT_CONFIG_FILE,
2271+ DEFAULT_CONFIG_SECT,
2272 NETWORK_ALREADY_SETUP,
2273- VISUALIZATION_OFF,
2274- DONT_DIST_UPGRADE,
2275- DONT_INSTALL_TESTS,
2276- DONT_USE_SILENT,
2277- DONT_USE_CACHE_DEPS,
2278- DONT_USE_VERBOSE_LOGGING,
2279- )
2280- }),
2281- ('with touch visualisation enabled', {
2282- 'command_line_arguments': ['--touch-visualization'],
2283- 'parsed_arguments': (
2284- DEFAULT_CONFIG_FILE, DEFAULT_CONFIG_SECT, [], DONT_APT_UPDATE,
2285- NETWORK_NOT_ALREADY_SETUP,
2286- VISUALIZATION_ON,
2287- DONT_DIST_UPGRADE,
2288- DONT_INSTALL_TESTS,
2289- DONT_USE_SILENT,
2290- DONT_USE_CACHE_DEPS,
2291- DONT_USE_VERBOSE_LOGGING,
2292- )
2293- }),
2294- ('with install dependencies enabled', {
2295+ DONT_USE_VERBOSE_LOGGING,
2296+ DO_USE_CACHE_DEPS,
2297+ DO_DIST_UPGRADE,
2298+ DONT_INSTALL_TESTS,
2299+ DO_APT_UPDATE,
2300+ )
2301+ }),
2302+ ('with dist-upgrade enabled', {
2303 'command_line_arguments': ['--dist-upgrade'],
2304 'parsed_arguments': (
2305- DEFAULT_CONFIG_FILE, DEFAULT_CONFIG_SECT, [], DONT_APT_UPDATE,
2306+ SETUP_CMD,
2307+ DEFAULT_CONFIG_FILE,
2308+ DEFAULT_CONFIG_SECT,
2309 NETWORK_NOT_ALREADY_SETUP,
2310- VISUALIZATION_OFF,
2311+ DONT_USE_VERBOSE_LOGGING,
2312+ DONT_USE_CACHE_DEPS,
2313 DO_DIST_UPGRADE,
2314 DONT_INSTALL_TESTS,
2315- DONT_USE_SILENT,
2316- DONT_USE_CACHE_DEPS,
2317- DONT_USE_VERBOSE_LOGGING,
2318+ DO_APT_UPDATE,
2319 )
2320 }),
2321 ('with install dependencies enabled', {
2322 'command_line_arguments': ['--install-tests'],
2323 'parsed_arguments': (
2324- DEFAULT_CONFIG_FILE, DEFAULT_CONFIG_SECT, [], DONT_APT_UPDATE,
2325+ SETUP_CMD,
2326+ DEFAULT_CONFIG_FILE,
2327+ DEFAULT_CONFIG_SECT,
2328 NETWORK_NOT_ALREADY_SETUP,
2329- VISUALIZATION_OFF,
2330+ DONT_USE_VERBOSE_LOGGING,
2331+ DONT_USE_CACHE_DEPS,
2332 DONT_DIST_UPGRADE,
2333 DO_INSTALL_TESTS,
2334- DONT_USE_SILENT,
2335- DONT_USE_CACHE_DEPS,
2336- DONT_USE_VERBOSE_LOGGING,
2337- )
2338- }),
2339- ('with silent mode specified', {
2340- 'command_line_arguments': ['--silent'],
2341- 'parsed_arguments': (
2342- DEFAULT_CONFIG_FILE, DEFAULT_CONFIG_SECT, [], DONT_APT_UPDATE,
2343- NETWORK_NOT_ALREADY_SETUP,
2344- VISUALIZATION_OFF,
2345- DONT_DIST_UPGRADE,
2346- DONT_INSTALL_TESTS,
2347- DO_USE_SILENT,
2348- DONT_USE_CACHE_DEPS,
2349- DONT_USE_VERBOSE_LOGGING,
2350+ DO_APT_UPDATE,
2351 )
2352 }),
2353 ('with cache deps specified', {
2354 'command_line_arguments': ['--cache-deps'],
2355 'parsed_arguments': (
2356- DEFAULT_CONFIG_FILE, DEFAULT_CONFIG_SECT, [], DONT_APT_UPDATE,
2357- NETWORK_NOT_ALREADY_SETUP,
2358- VISUALIZATION_OFF,
2359- DONT_DIST_UPGRADE,
2360- DONT_INSTALL_TESTS,
2361- DONT_USE_SILENT,
2362- DO_USE_CACHE_DEPS,
2363- DONT_USE_VERBOSE_LOGGING,
2364- )
2365- }),
2366- ('with verbose logging specified', {
2367- 'command_line_arguments': ['--verbose'],
2368- 'parsed_arguments': (
2369- DEFAULT_CONFIG_FILE, DEFAULT_CONFIG_SECT, [], DONT_APT_UPDATE,
2370- NETWORK_NOT_ALREADY_SETUP,
2371- VISUALIZATION_OFF,
2372- DONT_DIST_UPGRADE,
2373- DONT_INSTALL_TESTS,
2374- DONT_USE_SILENT,
2375- DONT_USE_CACHE_DEPS,
2376- DO_USE_VERBOSE_LOGGING,
2377+ SETUP_CMD,
2378+ DEFAULT_CONFIG_FILE,
2379+ DEFAULT_CONFIG_SECT,
2380+ NETWORK_NOT_ALREADY_SETUP,
2381+ DONT_USE_VERBOSE_LOGGING,
2382+ DO_USE_CACHE_DEPS,
2383+ DONT_DIST_UPGRADE,
2384+ DONT_INSTALL_TESTS,
2385+ DO_APT_UPDATE,
2386+ )
2387+ }),
2388+ ('with verbose logging specified', {
2389+ 'command_line_arguments': ['--verbose'],
2390+ 'parsed_arguments': (
2391+ SETUP_CMD,
2392+ DEFAULT_CONFIG_FILE,
2393+ DEFAULT_CONFIG_SECT,
2394+ NETWORK_NOT_ALREADY_SETUP,
2395+ DO_USE_VERBOSE_LOGGING,
2396+ DO_USE_CACHE_DEPS,
2397+ DO_DIST_UPGRADE,
2398+ DONT_INSTALL_TESTS,
2399+ DO_APT_UPDATE,
2400+ )
2401+ }),
2402+ ]
2403+
2404+ @mock.patch('ubuntu_system_tests.host.command_line.run_autopkg_setup')
2405+ def test_main_must_pass_command_line_arguments_to_run_system_tests(
2406+ self, mock_run_autopkg_setup):
2407+ command_line.main([self.SETUP_CMD] + self.command_line_arguments)
2408+ params = get_cmdline_setup_params(*self.parsed_arguments)
2409+ mock_run_autopkg_setup.assert_called_once_with(params)
2410+
2411+
2412+class RunCommandLineArgumentsTestCase(testscenarios.TestWithScenarios):
2413+
2414+ RUN_CMD = 'run'
2415+ DEFAULT_CONFIG_FILE = 'ubuntu-system-tests.conf'
2416+ DEFAULT_CONFIG_SECT = config.KEY_DEFAULT
2417+ ALL_SUITES = []
2418+ NETWORK_ALREADY_SETUP = True
2419+ NETWORK_NOT_ALREADY_SETUP = False
2420+ DO_USE_VERBOSE_LOGGING = True
2421+ DONT_USE_VERBOSE_LOGGING = False
2422+ DO_USE_TOUCH_VISUALIZATION = True
2423+ DONT_USE_TOUCH_VISUALIZATION = False
2424+ DO_USE_SILENT_MODE = True
2425+ DONT_USE_SILENT_MODE = False
2426+
2427+ scenarios = [
2428+ ('default run arguments', {
2429+ 'command_line_arguments': [],
2430+ 'parsed_arguments': (
2431+ RUN_CMD,
2432+ DEFAULT_CONFIG_FILE,
2433+ DEFAULT_CONFIG_SECT,
2434+ NETWORK_NOT_ALREADY_SETUP,
2435+ DONT_USE_VERBOSE_LOGGING,
2436+ DONT_USE_SILENT_MODE,
2437+ ALL_SUITES,
2438+ DONT_USE_TOUCH_VISUALIZATION,
2439+ )
2440+ }),
2441+ ('alternative config', {
2442+ 'command_line_arguments': ['--config=alternative.conf'],
2443+ 'parsed_arguments': (
2444+ RUN_CMD,
2445+ 'alternative.conf',
2446+ DEFAULT_CONFIG_SECT,
2447+ NETWORK_NOT_ALREADY_SETUP,
2448+ DONT_USE_VERBOSE_LOGGING,
2449+ DONT_USE_SILENT_MODE,
2450+ ALL_SUITES,
2451+ DONT_USE_TOUCH_VISUALIZATION,
2452+ )
2453+ }),
2454+ ('alternative config section', {
2455+ 'command_line_arguments': ['--config-section=custom-section'],
2456+ 'parsed_arguments': (
2457+ RUN_CMD,
2458+ DEFAULT_CONFIG_FILE,
2459+ 'custom-section',
2460+ NETWORK_NOT_ALREADY_SETUP,
2461+ DONT_USE_VERBOSE_LOGGING,
2462+ DONT_USE_SILENT_MODE,
2463+ ALL_SUITES,
2464+ DONT_USE_TOUCH_VISUALIZATION,
2465+ )
2466+ }),
2467+ ('with network already setup', {
2468+ 'command_line_arguments': ['--network-ready'],
2469+ 'parsed_arguments': (
2470+ RUN_CMD,
2471+ DEFAULT_CONFIG_FILE,
2472+ DEFAULT_CONFIG_SECT,
2473+ NETWORK_ALREADY_SETUP,
2474+ DONT_USE_VERBOSE_LOGGING,
2475+ DONT_USE_SILENT_MODE,
2476+ ALL_SUITES,
2477+ DONT_USE_TOUCH_VISUALIZATION,
2478+ )
2479+ }),
2480+ ('with verbose logging specified', {
2481+ 'command_line_arguments': ['--verbose'],
2482+ 'parsed_arguments': (
2483+ RUN_CMD,
2484+ DEFAULT_CONFIG_FILE,
2485+ DEFAULT_CONFIG_SECT,
2486+ NETWORK_NOT_ALREADY_SETUP,
2487+ DO_USE_VERBOSE_LOGGING,
2488+ DONT_USE_SILENT_MODE,
2489+ ALL_SUITES,
2490+ DONT_USE_TOUCH_VISUALIZATION,
2491+ )
2492+ }),
2493+ ('single test', {
2494+ 'command_line_arguments': ['suite.tests.test_1'],
2495+ 'parsed_arguments': (
2496+ RUN_CMD,
2497+ DEFAULT_CONFIG_FILE,
2498+ DEFAULT_CONFIG_SECT,
2499+ NETWORK_NOT_ALREADY_SETUP,
2500+ DONT_USE_VERBOSE_LOGGING,
2501+ DONT_USE_SILENT_MODE,
2502+ ['suite.tests.test_1'],
2503+ DONT_USE_TOUCH_VISUALIZATION,
2504+ )
2505+ }),
2506+ ('mutliple tests', {
2507+ 'command_line_arguments': [
2508+ 'suite.tests.test_1', 'suite.tests.test_2'],
2509+ 'parsed_arguments': (
2510+ RUN_CMD,
2511+ DEFAULT_CONFIG_FILE,
2512+ DEFAULT_CONFIG_SECT,
2513+ NETWORK_NOT_ALREADY_SETUP,
2514+ DONT_USE_VERBOSE_LOGGING,
2515+ DONT_USE_SILENT_MODE,
2516+ ['suite.tests.test_1', 'suite.tests.test_2'],
2517+ DONT_USE_TOUCH_VISUALIZATION,
2518 )
2519 }),
2520 ]
2521@@ -536,7 +351,6 @@
2522 @mock.patch('ubuntu_system_tests.host.command_line.run_system_tests')
2523 def test_main_must_pass_command_line_arguments_to_run_system_tests(
2524 self, mock_run_system_tests):
2525- command_line.main(self.command_line_arguments)
2526-
2527- mock_run_system_tests.assert_called_once_with(
2528- *self.parsed_arguments)
2529+ command_line.main([self.RUN_CMD] + self.command_line_arguments)
2530+ params = get_cmdline_run_params(*self.parsed_arguments)
2531+ mock_run_system_tests.assert_called_once_with(params)
2532
2533=== added file 'ubuntu_system_tests/selftests/test_commands.py'
2534--- ubuntu_system_tests/selftests/test_commands.py 1970-01-01 00:00:00 +0000
2535+++ ubuntu_system_tests/selftests/test_commands.py 2016-06-29 08:06:07 +0000
2536@@ -0,0 +1,239 @@
2537+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2538+
2539+#
2540+# Ubuntu System Tests
2541+# Copyright (C) 2016 Canonical
2542+#
2543+# This program is free software: you can redistribute it and/or modify
2544+# it under the terms of the GNU General Public License as published by
2545+# the Free Software Foundation, either version 3 of the License, or
2546+# (at your option) any later version.
2547+#
2548+# This program is distributed in the hope that it will be useful,
2549+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2550+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2551+# GNU General Public License for more details.
2552+#
2553+# You should have received a copy of the GNU General Public License
2554+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2555+#
2556+
2557+from unittest import mock
2558+
2559+from ubuntu_system_tests import selftests
2560+from ubuntu_system_tests.host import commands
2561+from ubuntu_system_tests.common import config
2562+
2563+
2564+def check_any_item_in_list_contains_value(list, value):
2565+ return any(item.find(value) >= 0 for item in list)
2566+
2567+
2568+def check_any_item_in_list_startswith_value(list, value):
2569+ return any(item.startswith(value) for item in list)
2570+
2571+
2572+class RunCommandTestCase(selftests.ConfigBaseTestCase):
2573+
2574+ def setUp(self):
2575+ super().setUp()
2576+ self.config_stack = config.UbuntuSystemTestsConfig()
2577+
2578+ def test_setup_network_command_contains_credentials(self):
2579+ self.set_config_values()
2580+
2581+ command = commands._get_device_network_command(
2582+ 'test_ssid', 'test_password')
2583+
2584+ self.assertTrue(command.startswith(
2585+ 'nmcli device wifi connect \'test_ssid\' '
2586+ 'password \'test_password\''))
2587+
2588+ def test_enable_introspection_with_serial(self):
2589+ serial = 'test_serial'
2590+ self.set_config_values(device_serial=serial)
2591+
2592+ command = commands.build_enable_autopilot_introspection_command(
2593+ self.config_stack)
2594+
2595+ self.assertEqual(['phablet-config', '-s', 'test_serial'], command[:3])
2596+
2597+ def test_enable_introspection_without_serial(self):
2598+ self.set_config_values(device_serial='')
2599+
2600+ command = commands.build_enable_autopilot_introspection_command(
2601+ self.config_stack)
2602+
2603+ self.assertNotIn('-s', command)
2604+
2605+ def test_adt_run_must_be_called_with_short_timeout(self):
2606+ self.set_config_values()
2607+
2608+ command = commands.build_adt_run_test_command(
2609+ self.config_stack, config.KEY_DEFAULT)
2610+ command = ' '.join(command)
2611+
2612+ run_arguments, _ = command.split('---')
2613+ self.assertIn('--timeout-short=600', run_arguments)
2614+
2615+ def test_adt_run_command_no_file_mount(self):
2616+ self.set_config_values()
2617+ run_cmd = ' '.join(commands.build_adt_run_test_command(
2618+ self.config_stack, config.KEY_DEFAULT))
2619+ self.assertNotIn('mount -o remount,ro /', run_cmd)
2620+ self.assertNotIn('mount -o remount,rw /', run_cmd)
2621+
2622+ def test_adt_run_with_serial(self):
2623+ serial = 'test_serial'
2624+ self.set_config_values(device_serial=serial)
2625+
2626+ command = commands.build_adt_run_test_command(
2627+ self.config_stack, config.KEY_DEFAULT)
2628+ command = ' '.join(command)
2629+
2630+ _, adb_arguments = command.split('ssh -s adb --')
2631+ self.assertIn('-s test_serial', adb_arguments)
2632+
2633+ def test_adt_run_without_serial(self):
2634+ self.set_config_values(device_serial='')
2635+
2636+ command = commands.build_adt_run_test_command(
2637+ self.config_stack, config.KEY_DEFAULT)
2638+ command = ' '.join(command)
2639+
2640+ _, adb_arguments = command.split('ssh -s adb --')
2641+ self.assertNotIn('-s test_serial', adb_arguments)
2642+
2643+ def test_adt_run_command_with_network_ready_creates_no_network(self):
2644+ self.set_config_values()
2645+
2646+ command = commands.build_adt_run_test_command(
2647+ self.config_stack, config.KEY_DEFAULT, network_ready=True)
2648+
2649+ self.assertFalse(check_any_item_in_list_startswith_value(
2650+ command, 'nmcli device wifi connect'))
2651+
2652+ def test_adt_run_command_with_default_parameters_creates_network(self):
2653+ self.set_config_values()
2654+
2655+ command = commands.build_adt_run_test_command(
2656+ self.config_stack, config.KEY_DEFAULT)
2657+
2658+ self.assertTrue(check_any_item_in_list_startswith_value(
2659+ command, 'nmcli device wifi connect'))
2660+
2661+ def test_enabling_verbose_option(self):
2662+ self.set_config_values()
2663+ command = commands.build_adt_run_test_command(
2664+ self.config_stack, config.KEY_DEFAULT, verbose=True)
2665+ self.assertTrue(check_any_item_in_list_contains_value(command, '-ddd'))
2666+
2667+ def test_verbose_disabled_by_default(self):
2668+ self.set_config_values()
2669+ command = commands.build_adt_run_test_command(
2670+ self.config_stack, config.KEY_DEFAULT)
2671+ self.assertFalse(
2672+ check_any_item_in_list_contains_value(command, '-ddd'))
2673+
2674+
2675+class SetupCommandTestCase(selftests.ConfigBaseTestCase):
2676+
2677+ def setUp(self):
2678+ super().setUp()
2679+ self.config_stack = config.UbuntuSystemTestsConfig()
2680+
2681+ def test_ppa_setup_commands_set_image_readwrite(self):
2682+ self.set_config_values()
2683+ self.assertIn(
2684+ 'mount -o remount,rw /',
2685+ ' '.join(commands.build_adt_run_setup_command(
2686+ self.config_stack, config.KEY_DEFAULT))
2687+ )
2688+
2689+ def test_ppa_setup_commands_used_in_adt_setup(self):
2690+ self.set_config_values()
2691+ command = commands.build_adt_run_setup_command(
2692+ self.config_stack, config.KEY_DEFAULT)
2693+ command = ' '.join(command)
2694+
2695+ run_arguments, _ = command.split('---')
2696+ self.assertIn(
2697+ 'apt-add-repository -y ppa:canonical-platform-qa',
2698+ run_arguments
2699+ )
2700+
2701+ def test_setup_commands_install_testability_libs(self):
2702+ self.set_config_values()
2703+ command = commands.build_adt_run_setup_command(
2704+ self.config_stack, config.KEY_DEFAULT)
2705+ self.assertTrue(
2706+ check_any_item_in_list_contains_value(
2707+ command,
2708+ 'apt-get -y --no-install-recommends install '
2709+ 'qttestability-autopilot')
2710+ )
2711+
2712+ def test_setting_fs_rw_is_conditional_on_current_state(self):
2713+ self.assertIn(
2714+ commands._get_is_fs_ro_command(), commands._get_fs_rw_command())
2715+
2716+ def test_setting_fs_ro_is_conditional_on_current_state(self):
2717+ command = commands._get_fs_ro_setup_command()
2718+ check_any_item_in_list_contains_value(
2719+ command, commands._get_is_fs_rw_command())
2720+
2721+ def test_enabling_verbose_option(self):
2722+ self.set_config_values()
2723+ command = commands.build_adt_run_setup_command(
2724+ self.config_stack, config.KEY_DEFAULT, verbose=True)
2725+ self.assertTrue(check_any_item_in_list_contains_value(command, '-ddd'))
2726+
2727+ def test_verbose_disabled_by_default(self):
2728+ self.set_config_values()
2729+ command = commands.build_adt_run_setup_command(
2730+ self.config_stack, config.KEY_DEFAULT)
2731+ self.assertFalse(
2732+ check_any_item_in_list_contains_value(command, '-ddd'))
2733+
2734+ def test_cache_deps_uses_default_control_file(self):
2735+ self.set_config_values()
2736+ command = commands.build_adt_run_setup_command(
2737+ self.config_stack, config.KEY_DEFAULT, cache_deps=True)
2738+ self.assertFalse(
2739+ check_any_item_in_list_contains_value(
2740+ command, '--override-control'))
2741+
2742+ def test_no_cache_deps_overrides_control_file(self):
2743+ self.set_config_values()
2744+ command = commands.build_adt_run_setup_command(
2745+ self.config_stack, config.KEY_DEFAULT)
2746+ self.assertTrue(
2747+ check_any_item_in_list_contains_value(
2748+ command, '--override-control'))
2749+
2750+ def test_cache_deps_installs_apt_cacher(self):
2751+ self.set_config_values()
2752+ command = commands.build_adt_run_setup_command(
2753+ self.config_stack, config.KEY_DEFAULT, cache_deps=True)
2754+ self.assertTrue(
2755+ check_any_item_in_list_contains_value(
2756+ command,
2757+ 'apt-get -y --no-install-recommends install apt-cacher-ng'))
2758+
2759+ def test_default_no_apt_cacher_install(self):
2760+ self.set_config_values()
2761+ command = commands.build_adt_run_setup_command(
2762+ self.config_stack, config.KEY_DEFAULT)
2763+ self.assertFalse(
2764+ check_any_item_in_list_contains_value(command, 'apt-cacher-ng'))
2765+
2766+ @mock.patch('ubuntu_system_tests.host.testdesc.get_all_dependencies')
2767+ def test_install_tests_adds_extra_dependencies(
2768+ self, mock_get_all_dependencies):
2769+ self.set_config_values()
2770+ mock_get_all_dependencies.return_value = ['test-dep-1', 'test-dep-2']
2771+ command = commands.build_adt_run_setup_command(
2772+ self.config_stack, config.KEY_DEFAULT, install_tests=True)
2773+ self.assertTrue(
2774+ check_any_item_in_list_contains_value(
2775+ command, 'install test-dep-1 test-dep-2'))
2776
2777=== added file 'ubuntu_system_tests/selftests/test_debian.py'
2778--- ubuntu_system_tests/selftests/test_debian.py 1970-01-01 00:00:00 +0000
2779+++ ubuntu_system_tests/selftests/test_debian.py 2016-06-29 08:06:07 +0000
2780@@ -0,0 +1,125 @@
2781+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2782+
2783+#
2784+# Ubuntu System Tests
2785+# Copyright (C) 2016 Canonical
2786+#
2787+# This program is free software: you can redistribute it and/or modify
2788+# it under the terms of the GNU General Public License as published by
2789+# the Free Software Foundation, either version 3 of the License, or
2790+# (at your option) any later version.
2791+#
2792+# This program is distributed in the hope that it will be useful,
2793+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2794+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2795+# GNU General Public License for more details.
2796+#
2797+# You should have received a copy of the GNU General Public License
2798+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2799+#
2800+
2801+import fixtures
2802+import json
2803+import os
2804+from tempfile import NamedTemporaryFile
2805+from unittest import mock
2806+
2807+from ubuntu_system_tests import selftests
2808+from ubuntu_system_tests.host import debian
2809+from ubuntu_system_tests.common import config
2810+
2811+
2812+def check_any_item_in_list_contains_value(list, value):
2813+ return any(item.find(value) for item in list)
2814+
2815+
2816+def check_any_item_in_list_startswith_value(list, value):
2817+ return any(item.startswith(value) for item in list)
2818+
2819+
2820+class CommandTestCase(selftests.ConfigBaseTestCase):
2821+
2822+ def setUp(self):
2823+ super().setUp()
2824+ self.config_stack = config.UbuntuSystemTestsConfig()
2825+
2826+ def test_get_extra_dependencies(self):
2827+ tests = ('app1.tests.test_module.TestClass.test_x '
2828+ 'app2.tests.test_module.TestClass.test_y '
2829+ 'app3.tests.test_module.TestClass.test_z')
2830+ self.set_config_values(tests_to_run=tests)
2831+ expected_depends = ['dep1',
2832+ 'dep2']
2833+ # Mock _read_dependency_files
2834+ with mock.patch(
2835+ 'ubuntu_system_tests.host.debian._read_dependency_files'
2836+ ) as mock_read_depends:
2837+ mock_read_depends.return_value = {
2838+ 'app2.tests': 'dep1',
2839+ 'app3.tests': 'dep2'
2840+ }
2841+ extra_depends = debian.get_extra_dependencies(
2842+ self.config_stack.get('tests_to_run').split()
2843+ )
2844+ self.assertCountEqual(extra_depends, expected_depends)
2845+
2846+ def test_read_dependency_file(self):
2847+ with fixtures.TempDir() as deps_dir:
2848+ deps_file1 = open(os.path.join(deps_dir.path, 'deps1.json'), 'w')
2849+ deps_file2 = open(os.path.join(deps_dir.path, 'deps2.json'), 'w')
2850+ deps_json1 = {
2851+ "test_dependencies": [
2852+ {"id": "app1.tests", "depends": "dep1"}
2853+ ]
2854+ }
2855+ deps_json2 = {
2856+ "test_dependencies": [
2857+ {"id": "app2.tests", "depends": "dep2"}
2858+ ]
2859+ }
2860+ deps_file1.write(json.dumps(deps_json1))
2861+ deps_file2.write(json.dumps(deps_json2))
2862+ deps_file1.close()
2863+ deps_file2.close()
2864+
2865+ expected = {'app1.tests': 'dep1', 'app2.tests': 'dep2'}
2866+ actual = debian._read_dependency_files(deps_dir.path)
2867+ self.assertEqual(expected, actual)
2868+
2869+ def test_extra_dependencies_for_test(self):
2870+ test = 'app1.tests.test_module.TestClass.test_y'
2871+ dependencies_map = {'app1.tests': 'dep1', 'app2.tests': 'dep2'}
2872+ extra_depends = debian._extra_dependencies_for_test(
2873+ test, dependencies_map
2874+ )
2875+ self.assertEqual(extra_depends, ['dep1'])
2876+
2877+ def test_create_temp_control(self):
2878+ with NamedTemporaryFile() as control:
2879+ control.write("""Tests: systemtests
2880+Depends: dep1,
2881+ dep2,
2882+ dep3,
2883+
2884+Tests: someothertests
2885+Depends: other1,
2886+ other2,
2887+ other3,""".encode('utf-8'))
2888+ control.flush()
2889+ temp_control = debian.create_temp_control_file(
2890+ ['dep4', 'dep5'], control.name
2891+ )
2892+ with open(temp_control) as temp:
2893+ tmp_control_content = temp.read()
2894+ expected_content = """Tests: systemtests
2895+Depends: dep1,
2896+ dep2,
2897+ dep3,
2898+ dep4,
2899+ dep5,
2900+
2901+Tests: someothertests
2902+Depends: other1,
2903+ other2,
2904+ other3,"""
2905+ self.assertEqual(tmp_control_content, expected_content)
2906
2907=== modified file 'ubuntu_system_tests/selftests/utils.py'
2908--- ubuntu_system_tests/selftests/utils.py 2016-06-02 13:08:41 +0000
2909+++ ubuntu_system_tests/selftests/utils.py 2016-06-29 08:06:07 +0000
2910@@ -22,6 +22,7 @@
2911 import shutil
2912 import tempfile
2913 import unittest
2914+from argparse import Namespace
2915 from unittest import mock
2916
2917 from ubuntu_system_tests.common import config
2918@@ -60,6 +61,28 @@
2919 self.config_stack.save()
2920
2921
2922+def get_cmdline_run_params(
2923+ command='run', config=config.DEFAULT_CONF,
2924+ config_section=config.KEY_DEFAULT, network_ready=False, verbose=False,
2925+ silent=False, suites=[], touch_visualization=False):
2926+ return Namespace(
2927+ command=command, config=config, config_section=config_section,
2928+ network_ready=network_ready, verbose=verbose, silent=silent,
2929+ suites=suites, touch_visualization=touch_visualization)
2930+
2931+
2932+def get_cmdline_setup_params(
2933+ command='setup', config=config.DEFAULT_CONF,
2934+ config_section=config.KEY_DEFAULT, network_ready=False, verbose=False,
2935+ cache_deps=False, dist_upgrade=False, install_tests=False,
2936+ update_apt=False):
2937+ return Namespace(
2938+ command=command, config=config, config_section=config_section,
2939+ network_ready=network_ready, verbose=verbose, cache_deps=cache_deps,
2940+ dist_upgrade=dist_upgrade, install_tests=install_tests,
2941+ update_apt=update_apt)
2942+
2943+
2944 def set_uniq_cwd(test, prefix=None):
2945 """Create a temporary directory an cd into it for the test duration.
2946

Subscribers

People subscribed via source and target branches

to all changes: