Merge lp:~canonical-platform-qa/ubuntu-system-tests/device_monitoring into lp:ubuntu-system-tests
- device_monitoring
- Merge into trunk
Status: | Work in progress |
---|---|
Proposed branch: | lp:~canonical-platform-qa/ubuntu-system-tests/device_monitoring |
Merge into: | lp:ubuntu-system-tests |
Diff against target: |
820 lines (+503/-29) 15 files modified
debian/control (+3/-0) debian/tests/control (+1/-0) ubuntu_system_tests/command_line.py (+5/-0) ubuntu_system_tests/config.py (+11/-0) ubuntu_system_tests/helpers/data.py (+14/-2) ubuntu_system_tests/helpers/file_system.py (+1/-0) ubuntu_system_tests/helpers/monitoring.py (+61/-0) ubuntu_system_tests/helpers/sdcard.py (+5/-0) ubuntu_system_tests/results.py (+51/-0) ubuntu_system_tests/tests/base.py (+42/-26) ubuntu_system_tests/tests/data/perf/metadata.json (+8/-0) ubuntu_system_tests/tests/data/perf/plot.json (+12/-0) ubuntu_system_tests/tests/perf/__init__.py (+91/-0) ubuntu_system_tests/tests/perf/test_apps.py (+197/-0) ubuntu_system_tests/tests/test_sdcard.py (+1/-1) |
To merge this branch: | bzr merge lp:~canonical-platform-qa/ubuntu-system-tests/device_monitoring |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
platform-qa-bot | continuous-integration | Needs Fixing | |
Brendan Donegan (community) | Needs Information | ||
PS Jenkins bot | continuous-integration | Approve | |
Richard Huddie (community) | Needs Fixing | ||
prod-platform-qa | continuous-integration | Pending | |
Sergio Cazzolato | Pending | ||
Review via email: mp+280167@code.launchpad.net |
Commit message
Enable the device monitoring used to visualize the resources usage in the device during tests execution
Description of the change
Brendan Donegan (brendan-donegan) wrote : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:287
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 288. By Sergio Cazzolato
-
Adding test case to open 100 time several apps
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:288
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 289. By Sergio Cazzolato
-
Adding new test to open all the apps
- 290. By Sergio Cazzolato
-
Adding new test case
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:290
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 291. By Sergio Cazzolato
-
Flake8 fix
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:291
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 292. By Sergio Cazzolato
-
Improving webapps start
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:292
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Sergio Cazzolato (sergio-j-cazzolato) wrote : | # |
> Do you think the plotting of the data should be coupled to ubuntu-system-
> tests? I suppose it's a nice to have but really the plotting should be done
> externally so we have a choice of which tool to use, how to configure it etc.
Agree with that, I just added the visualization as part of the branch to make easy to see if the results are what we need, after that I could remove it.
- 293. By Sergio Cazzolato
-
Adding config parameter for nmon
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:293
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 294. By Sergio Cazzolato
-
Removing clock app
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:294
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 295. By Sergio Cazzolato
-
Adding new test case to maname apps in a cicle
- 296. By Sergio Cazzolato
-
Minor improvements for new test
- 297. By Sergio Cazzolato
-
Adding fixtures for test
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:297
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 298. By Sergio Cazzolato
-
Minor fixes
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:298
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 299. By Sergio Cazzolato
-
Moving test configuration to json file
- 300. By Sergio Cazzolato
-
Merge with trunk
- 301. By Sergio Cazzolato
-
Adding comments
- 302. By Sergio Cazzolato
-
Adding missing file
- 303. By Sergio Cazzolato
-
Minor fix in name
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:303
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 304. By Sergio Cazzolato
-
Fixing camera actions
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:304
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 305. By Sergio Cazzolato
-
Adding config file with plotting directives
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:305
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Sergio Cazzolato (sergio-j-cazzolato) wrote : | # |
Getting this error from jenkins http://
- 306. By Sergio Cazzolato
-
Moving dependencies and increasing iterations
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:306
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Richard Huddie (rhuddie) wrote : | # |
Looks good, some minor comments below. I had this problem when running test_open_apps: http://
The other test was running, but I've not had a chance to run it until completion yet.
- 307. By Sergio Cazzolato
-
Fixes based on PM comments
- 308. By Sergio Cazzolato
-
Minor fix
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:308
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Richard Huddie (rhuddie) wrote : | # |
I got the following error when running test_open_apps: http://
I was able to create an HTML graph for statistics using nmonchart (http://
Other question, when I ran on Arale with no SD card, the exception is raised which gets reported as error: http://
This is not an error, but just unsupported feature. Could this just be logged, rather than raising exception?
Also, it would be useful if the the error message ("testtools.
Selene ToyKeeper (toykeeper) wrote : | # |
To get this working at all, I had to rename a couple functions:
--- ubuntu_
+++ ubuntu_
@@ -2,7 +2,7 @@
"test_
"apps": ["camera-app", "webbrowser-app", "messaging-app",
- "address-book-app", "ubuntu-
+ "address-book", "calculator-app", "dialer-app"]
},
"test_
... and to run on arale, I had to disable _validate_sd_card() in ubuntu_
I'm still getting 4 errors in test_do_actions() though, which I haven't finished tracing.
What is the recommended way to get pyNmonAnalyzer?
Sergio Cazzolato (sergio-j-cazzolato) wrote : | # |
> To get this working at all, I had to rename a couple functions:
> --- ubuntu_
> +0000
> +++ ubuntu_
> +0000
> @@ -2,7 +2,7 @@
> "test_open_apps": {
> "iterations": 100,
> "apps": ["camera-app", "webbrowser-app", "messaging-app",
> - "address-book-app", "ubuntu-
> + "address-book", "calculator-app", "dialer-app"]
> },
> "test_do_actions": {
> "iterations": 2,
I am working on that, I think I am going to remove this test and will add actions to close the apps so we will be able to manage everything in the test test_do_actions
>
>
>
> ... and to run on arale, I had to disable _validate_sd_card() in
> ubuntu_
This is fixed in the next commit. When you want to use the sdcard and it is not inserted in the device, this action will be skipped and logged as a warning
>
> I'm still getting 4 errors in test_do_actions() though, which I haven't
> finished tracing.
>
> What is the recommended way to get pyNmonAnalyzer?
You need to have installed pip as a prerequisite. Then:
sudo apt-get install python-numpy python-matplotlib
sudo pip install pyNmonAnalyzer
In the meantime I am analyzing other tools to plot the nmon information. Here you have an example graphic that I took https:/
Thanks for the review
Sergio Cazzolato (sergio-j-cazzolato) wrote : | # |
> I got the following error when running test_open_apps:
> http://
I am going to remove this test and adding some actions to close apps so this test will be included in the test_do_actions.
>
> I was able to create an HTML graph for statistics using nmonchart
> (http://
> usage? It would be useful to add a section to README to explain how to
> generate graphs from the .nmon result file.
Nice, taking a look now
>
> Other question, when I ran on Arale with no SD card, the exception is raised
> which gets reported as error: http://
> This is not an error, but just unsupported feature. Could this just be logged,
> rather than raising exception?
Done, When you want to use the sdcard and it is not inserted in the device, this action will be skipped and logged as a warning
>
> Also, it would be useful if the the error message
> ("testtools.
> a summary of the reported errors. Otherwise it could be long job to go through
> the logs to understand what has happened.
WIP
- 309. By Sergio Cazzolato
-
Changes based on comments in review
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:309
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 310. By Sergio Cazzolato
-
adding wait action
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:310
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 311. By Sergio Cazzolato
-
Merge from trunk
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:311
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Brendan Donegan (brendan-donegan) wrote : | # |
From a code point of view this is fine, but I would look for some early feedback from jibel to make sure this is what is wanted. In my opinion this solution could do with being a bit more flexible. Rather than writing tests specifically for performance, it might be a better idea to re-use existing tests and have a way to get the metrics at certain points (in between tests, after all the tests are completed, etc). It might also be possible to granularise the test approach, so rather than gathering all the metrics for all tests, have a specific set of tests for memory usage, a specific set for CPU usage and a specific set for network usage. It really depends on what the intent is - is it to emulate real usage or is it to provoke specific bugs?
Richard Huddie (rhuddie) wrote : | # |
Showing some conflicts on this branch:
Text conflict in ubuntu_
Text conflict in ubuntu_
2 conflicts encountered.
Could you update?
platform-qa-bot (platform-qa-bot) wrote : | # |
FAILED: Continuous integration, rev:311
https:/
Executed test runs:
FAILURE: https:/
FAILURE: https:/
None: https:/
Click here to trigger a rebuild:
https:/
platform-qa-bot (platform-qa-bot) wrote : | # |
FAILED: Continuous integration, rev:311
https:/
Executed test runs:
FAILURE: https:/
FAILURE: https:/
None: https:/
Click here to trigger a rebuild:
https:/
Unmerged revisions
- 311. By Sergio Cazzolato
-
Merge from trunk
- 310. By Sergio Cazzolato
-
adding wait action
- 309. By Sergio Cazzolato
-
Changes based on comments in review
- 308. By Sergio Cazzolato
-
Minor fix
- 307. By Sergio Cazzolato
-
Fixes based on PM comments
- 306. By Sergio Cazzolato
-
Moving dependencies and increasing iterations
- 305. By Sergio Cazzolato
-
Adding config file with plotting directives
- 304. By Sergio Cazzolato
-
Fixing camera actions
- 303. By Sergio Cazzolato
-
Minor fix in name
- 302. By Sergio Cazzolato
-
Adding missing file
Preview Diff
1 | === modified file 'debian/control' |
2 | --- debian/control 2015-06-26 22:41:14 +0000 |
3 | +++ debian/control 2016-01-20 15:40:48 +0000 |
4 | @@ -22,7 +22,10 @@ |
5 | Architecture: all |
6 | Depends: ${misc:Depends}, |
7 | ${python3:Depends}, |
8 | + pyNmonAnalyzer, |
9 | python3-dbus, |
10 | + python3-matplotlib, |
11 | + python3-numpy, |
12 | python3-testtools, |
13 | python3-uci-config, |
14 | subunit, |
15 | |
16 | === modified file 'debian/tests/control' |
17 | --- debian/tests/control 2015-11-25 15:04:04 +0000 |
18 | +++ debian/tests/control 2016-01-20 15:40:48 +0000 |
19 | @@ -14,6 +14,7 @@ |
20 | mediaplayer-app-autopilot, |
21 | messaging-app, |
22 | messaging-app-autopilot, # TMPINSTALL |
23 | + nmon, |
24 | oxideqt-chromedriver, |
25 | python3-autopilot, |
26 | python3-dbus, |
27 | |
28 | === modified file 'ubuntu_system_tests/command_line.py' |
29 | --- ubuntu_system_tests/command_line.py 2015-12-03 20:15:55 +0000 |
30 | +++ ubuntu_system_tests/command_line.py 2016-01-20 15:40:48 +0000 |
31 | @@ -456,6 +456,11 @@ |
32 | def generate_user_report(config_stack): |
33 | """Create a human readable report from the subunit results.""" |
34 | artifacts_directory = results.get_artifacts_directory(config_stack) |
35 | + if config_stack.get('profiling_statistics'): |
36 | + serial = config_stack.get('device_serial') |
37 | + data_file = results.copy_monitor_data(artifacts_directory, serial) |
38 | + if config_stack.get('plot_statistics'): |
39 | + results.generate_statistics_report(artifacts_directory, data_file) |
40 | results.convert_subunit_results_to_pyunit(artifacts_directory) |
41 | results.print_results(artifacts_directory) |
42 | |
43 | |
44 | === modified file 'ubuntu_system_tests/config.py' |
45 | --- ubuntu_system_tests/config.py 2015-11-05 17:35:49 +0000 |
46 | +++ ubuntu_system_tests/config.py 2016-01-20 15:40:48 +0000 |
47 | @@ -109,6 +109,17 @@ |
48 | 'max_unity8_retry_delay', default=30000, |
49 | help_string='The boundary for how long we should be retrying until ' |
50 | 'unity8 is started'), |
51 | + options.Option( |
52 | + 'profiling_statistics', |
53 | + help_string="Enable performance profiling. CPU, Disk usage, Memory, " |
54 | + "Network and other statistics will be measured and stored " |
55 | + "as part of the test results. If empty, statistics won't " |
56 | + "be taken from the device."), |
57 | + options.Option( |
58 | + 'plot_statistics', |
59 | + help_string="Enable performance plotting. A report will be generated " |
60 | + "as part of the test results. If empty, statistics won't " |
61 | + "be plotted."), |
62 | ] |
63 | """Options for tests in external debian and click packages.""" |
64 | |
65 | |
66 | === modified file 'ubuntu_system_tests/helpers/data.py' |
67 | --- ubuntu_system_tests/helpers/data.py 2015-09-23 21:12:39 +0000 |
68 | +++ ubuntu_system_tests/helpers/data.py 2016-01-20 15:40:48 +0000 |
69 | @@ -28,7 +28,7 @@ |
70 | """ Class used to decode a dict into a AttrDict object """ |
71 | |
72 | def __init__(self, *args, **kargs): |
73 | - JSONDecoder.__init__(self, object_hook=dict_to_attr_dict) |
74 | + JSONDecoder.__init__(self, object_hook=_dict_to_attr_dict) |
75 | |
76 | |
77 | class AttrDict(dict): |
78 | @@ -51,7 +51,7 @@ |
79 | return file |
80 | |
81 | |
82 | -def dict_to_attr_dict(d): |
83 | +def _dict_to_attr_dict(d): |
84 | try: |
85 | return AttrDict(**d) |
86 | except: |
87 | @@ -91,3 +91,15 @@ |
88 | |
89 | _full_dict = _load_metadata_list(fs.DIR_TEST_DATA) |
90 | return _full_dict |
91 | + |
92 | + |
93 | +def load_data_file(file): |
94 | + """ Load in a AttrDict the data stored in the specific json file |
95 | + :param file: the path to the json file |
96 | + :return: A AttrDict with the data stored in the specific json file |
97 | + """ |
98 | + if not path.isfile(file): |
99 | + raise RuntimeError('Json data file does not exist') |
100 | + |
101 | + with open(file) as data_file: |
102 | + return load(data_file, cls=AttrDictDecoder) |
103 | |
104 | === modified file 'ubuntu_system_tests/helpers/file_system.py' |
105 | --- ubuntu_system_tests/helpers/file_system.py 2015-12-22 23:21:51 +0000 |
106 | +++ ubuntu_system_tests/helpers/file_system.py 2016-01-20 15:40:48 +0000 |
107 | @@ -91,6 +91,7 @@ |
108 | DIR_TEST_DATA_VIDEO = os.path.join(DIR_TEST_DATA, 'video') |
109 | DIR_TEST_DATA_DEVICES = os.path.join(DIR_TEST_DATA, 'devices') |
110 | DIR_TEST_DATA_DATABASES = os.path.join(DIR_TEST_DATA, 'databases') |
111 | +DIR_TEST_DATA_PERF = os.path.join(DIR_TEST_DATA, 'perf') |
112 | |
113 | # Media dirs |
114 | DIR_MEDIA = '/media' |
115 | |
116 | === added file 'ubuntu_system_tests/helpers/monitoring.py' |
117 | --- ubuntu_system_tests/helpers/monitoring.py 1970-01-01 00:00:00 +0000 |
118 | +++ ubuntu_system_tests/helpers/monitoring.py 2016-01-20 15:40:48 +0000 |
119 | @@ -0,0 +1,61 @@ |
120 | + |
121 | +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
122 | + |
123 | +# Ubuntu System Tests |
124 | +# Copyright (C) 2015 Canonical |
125 | +# |
126 | +# This program is free software: you can redistribute it and/or modify |
127 | +# it under the terms of the GNU General Public License as published by |
128 | +# the Free Software Foundation, either version 3 of the License, or |
129 | +# (at your option) any later version. |
130 | +# |
131 | +# This program is distributed in the hope that it will be useful, |
132 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
133 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
134 | +# GNU General Public License for more details. |
135 | +# |
136 | +# You should have received a copy of the GNU General Public License |
137 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
138 | + |
139 | +import logging |
140 | +import os |
141 | +import subprocess |
142 | + |
143 | +from ubuntu_system_tests import config |
144 | +from ubuntu_system_tests.helpers import file_system as fs |
145 | + |
146 | +logger = logging.getLogger(__name__) |
147 | + |
148 | + |
149 | +MONITOR = 'nmon' |
150 | +NAME = 'monitoring_data.nmon' |
151 | +OUTPUT_DIR = '/tmp/monitor_data' |
152 | + |
153 | + |
154 | +def is_monitoring_enabled(): |
155 | + """ Determine if the monitoring was requested in the config file """ |
156 | + return bool(config.get_device_config_stack().get('profiling_statistics')) |
157 | + |
158 | + |
159 | +def get_output_file(): |
160 | + """ Retrieve the .nmon file for current/last execution """ |
161 | + return os.path.join(OUTPUT_DIR, NAME) |
162 | + |
163 | + |
164 | +def start(interval=2, counts=50000): |
165 | + """ Start the monitoring tool with defined parameters |
166 | + :param interval: time in seconds between snap shots |
167 | + :param counts: number of snapshots before nmon stops |
168 | + """ |
169 | + fs.create_directory_if_not_exists(OUTPUT_DIR) |
170 | + fs.clean_files(OUTPUT_DIR) |
171 | + cmd = '{mon} -F {name} -s {interval} -t -c {counts}' |
172 | + vars = dict(mon=MONITOR, interval=interval, name=get_output_file(), |
173 | + counts=counts) |
174 | + |
175 | + subprocess.call(cmd.format(**vars), shell=True) |
176 | + |
177 | + |
178 | +def stop(): |
179 | + """ Stop the nmon process """ |
180 | + subprocess.call('pkill {}'.format(MONITOR), shell=True) |
181 | |
182 | === modified file 'ubuntu_system_tests/helpers/sdcard.py' |
183 | --- ubuntu_system_tests/helpers/sdcard.py 2015-11-03 21:03:37 +0000 |
184 | +++ ubuntu_system_tests/helpers/sdcard.py 2016-01-20 15:40:48 +0000 |
185 | @@ -106,3 +106,8 @@ |
186 | :param dst_name: The filename in the sd card |
187 | """ |
188 | return copy_file(src_path, fs.DIR_PICTURES, dst_name) |
189 | + |
190 | + |
191 | +def is_sdcard_mounted(): |
192 | + """ Indicate if the sd card is mounted in the device """ |
193 | + return fs.is_media_folder_dir(fs.DIR_PICTURES) |
194 | |
195 | === modified file 'ubuntu_system_tests/results.py' |
196 | --- ubuntu_system_tests/results.py 2015-05-21 18:15:40 +0000 |
197 | +++ ubuntu_system_tests/results.py 2016-01-20 15:40:48 +0000 |
198 | @@ -18,9 +18,16 @@ |
199 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
200 | # |
201 | |
202 | +import logging |
203 | import os |
204 | import subprocess |
205 | |
206 | +from ubuntu_system_tests.helpers import data |
207 | +from ubuntu_system_tests.helpers import file_system as fs |
208 | +from ubuntu_system_tests.helpers import monitoring |
209 | + |
210 | +logger = logging.getLogger(__name__) |
211 | + |
212 | |
213 | def convert_subunit_results_to_pyunit(artifacts_directory): |
214 | subunit_source_file_path = os.path.join( |
215 | @@ -48,3 +55,47 @@ |
216 | """Return the path to the directory in which artifacts are stored.""" |
217 | output_dir = config_stack.get('output_dir') |
218 | return os.path.join(output_dir, 'artifacts') |
219 | + |
220 | + |
221 | +def copy_monitor_data(artifacts_directory, device=None): |
222 | + """ Copy the monitoring data from the device to the test results dir |
223 | + :param artifacts_directory: the path where the artifacts are stored |
224 | + :param device: the serial for the desired device |
225 | + """ |
226 | + from_file = monitoring.get_output_file() |
227 | + to_file = os.path.join(artifacts_directory, os.path.basename(from_file)) |
228 | + if device: |
229 | + cmd = 'adb -s {} pull {} {}'.format(device, from_file, to_file) |
230 | + else: |
231 | + cmd = 'adb pull {} {}'.format(from_file, to_file) |
232 | + subprocess.call(cmd, shell=True) |
233 | + return to_file |
234 | + |
235 | + |
236 | +def _write_statistics_config_file(config_file, directives): |
237 | + """ Create the config file used to plot the monitoring data """ |
238 | + fs.delete_file(config_file) |
239 | + with open(config_file, 'w') as f: |
240 | + for directive in directives: |
241 | + f.write(directive + '\n') |
242 | + |
243 | + |
244 | +def generate_statistics_report(artifacts_directory, data_file): |
245 | + """ Generate the html report with the statistics usage |
246 | + :param artifacts_directory: the path where the artifacts are stored |
247 | + :param data_file: file with monitoring raw data copied from the device |
248 | + """ |
249 | + plot_data = data.load_data_file(os.path.join(fs.DIR_TEST_DATA_PERF, |
250 | + 'plot.json')) |
251 | + |
252 | + output_report_dir = os.path.join(artifacts_directory, plot_data.output_dir) |
253 | + config_file = os.path.join(artifacts_directory, plot_data.config_file_name) |
254 | + _write_statistics_config_file(config_file, plot_data.directives) |
255 | + |
256 | + cmd = 'pyNmonAnalyzer -x -b -o {} -i {} -t static -r {}'.format( |
257 | + output_report_dir, data_file, config_file) |
258 | + try: |
259 | + subprocess.call(cmd, shell=True) |
260 | + except OSError: |
261 | + logger.error("Statistics not generated. Error to call " |
262 | + "pyNmonAnalyzer") |
263 | |
264 | === modified file 'ubuntu_system_tests/tests/base.py' |
265 | --- ubuntu_system_tests/tests/base.py 2016-01-11 11:06:16 +0000 |
266 | +++ ubuntu_system_tests/tests/base.py 2016-01-20 15:40:48 +0000 |
267 | @@ -48,6 +48,7 @@ |
268 | from ubuntu_system_tests.helpers import click |
269 | from ubuntu_system_tests.helpers import images |
270 | from ubuntu_system_tests.helpers import mir |
271 | +from ubuntu_system_tests.helpers import monitoring |
272 | from ubuntu_system_tests.helpers import processes |
273 | from ubuntu_system_tests.helpers import screen |
274 | from ubuntu_system_tests.helpers import unity8 |
275 | @@ -61,9 +62,21 @@ |
276 | # Any test name ending with this will leave device locked |
277 | TEST_ID_DEVICE_LOCKED = 'device_locked' |
278 | |
279 | +logger = logging.getLogger(__name__) |
280 | + |
281 | +# Apps and cleanup names |
282 | +ADDRESS_BOOK_APP = 'address-book-app' |
283 | CALCULATOR_APP = 'ubuntu-calculator-app' |
284 | - |
285 | -logger = logging.getLogger(__name__) |
286 | +CAMERA_APP = 'camera-app' |
287 | +CLOCK_APP = 'ubuntu-clock-app' |
288 | +DIALER_APP = 'dialer-app' |
289 | +GALLERY_APP = 'gallery-app' |
290 | +MEDIA_PLAYER_APP = 'mediaplayer-app' |
291 | +MESSAGING_APP = 'messaging-app' |
292 | +SYSTEM_SETTINGS = 'system-settings' |
293 | +SYSTEM_SETTINGS_CLEANUP = 'ubuntu-system-settings' |
294 | +UNITY_8 = 'unity8' |
295 | +WEB_BROWSER_APP = 'webbrowser-app' |
296 | |
297 | |
298 | class BaseUbuntuSystemTestCase(testcase.AutopilotTestCase): |
299 | @@ -72,11 +85,15 @@ |
300 | def setUpClass(cls): |
301 | unity8.ensure_unity_stopped() |
302 | super().setUpClass() |
303 | + if monitoring.is_monitoring_enabled(): |
304 | + monitoring.start() |
305 | |
306 | @classmethod |
307 | def tearDownClass(cls): |
308 | super().tearDownClass() |
309 | unity8.ensure_unity_running_and_greeter_hidden() |
310 | + if monitoring.is_monitoring_enabled(): |
311 | + monitoring.stop() |
312 | |
313 | def setUp(self): |
314 | super().setUp() |
315 | @@ -106,7 +123,7 @@ |
316 | else: |
317 | self._start_unity_with_testability() |
318 | |
319 | - unity = self.get_job_proxy_object('unity8') |
320 | + unity = self.get_job_proxy_object(UNITY_8) |
321 | unity.wait_for_greeter_content() |
322 | self._reset_keyboard() |
323 | # Workaround for bug lp:1474444 |
324 | @@ -115,7 +132,7 @@ |
325 | return unity |
326 | |
327 | def _start_unity_with_testability(self): |
328 | - process_helpers.start_job('unity8', 'QT_LOAD_TESTABILITY=1') |
329 | + process_helpers.start_job(UNITY_8, 'QT_LOAD_TESTABILITY=1') |
330 | |
331 | # Retry added until fix for bug 1427946 in QtMir is landed |
332 | @retry(stop_max_delay=30000, |
333 | @@ -153,7 +170,7 @@ |
334 | def _create_sensors(self): |
335 | """Create fake sensors for testing""" |
336 | Eventually(Equals(True)).match( |
337 | - lambda: process_helpers.is_job_running('unity8') |
338 | + lambda: process_helpers.is_job_running(UNITY_8) |
339 | ) |
340 | unity_pid = process_helpers._get_unity_pid() |
341 | fifo_path = '/tmp/sensor-fifo-{}'.format(unity_pid) |
342 | @@ -200,7 +217,7 @@ |
343 | |
344 | def _get_screenshot_size(self, x, y, width, height): |
345 | """ Calculate the screenshot size """ |
346 | - unity = self.get_job_proxy_object('unity8') |
347 | + unity = self.get_job_proxy_object(UNITY_8) |
348 | if width and height: |
349 | return width, height |
350 | else: |
351 | @@ -240,7 +257,7 @@ |
352 | :param app_name: Name of the displayed application. |
353 | |
354 | """ |
355 | - unity = self.get_job_proxy_object('unity8') |
356 | + unity = self.get_job_proxy_object(UNITY_8) |
357 | unity.main_window.launch_application(app_name) |
358 | |
359 | def _get_proxy_object_for_existing_app( |
360 | @@ -332,7 +349,7 @@ |
361 | |
362 | """ |
363 | from ubuntu_system_tests.helpers.addressbook import _cpo # NOQA |
364 | - proxy = self._get_proxy_object_for_existing_app('address-book-app') |
365 | + proxy = self._get_proxy_object_for_existing_app(ADDRESS_BOOK_APP) |
366 | return proxy.main_window |
367 | |
368 | def launch_camera_app(self): |
369 | @@ -360,7 +377,7 @@ |
370 | """ |
371 | from ubuntu_system_tests.helpers.camera._cpo import MainWindow |
372 | proxy = self._get_proxy_object_for_existing_app( |
373 | - 'camera-app', |
374 | + CAMERA_APP, |
375 | cleanup_process=click.get_click_app_identifier('com.ubuntu.camera') |
376 | ) |
377 | return MainWindow(proxy) |
378 | @@ -383,7 +400,7 @@ |
379 | |
380 | """ |
381 | from ubuntu_system_tests.helpers.dialer_app import _cpo # NOQA |
382 | - proxy = self._get_proxy_object_for_existing_app('dialer-app') |
383 | + proxy = self._get_proxy_object_for_existing_app(DIALER_APP) |
384 | return proxy.main_view |
385 | |
386 | def launch_gallery_app(self): |
387 | @@ -404,9 +421,9 @@ |
388 | :return: Proxy object for gallery application. |
389 | |
390 | """ |
391 | - proxy = self._get_proxy_object_for_existing_app('gallery-app') |
392 | + proxy = self._get_proxy_object_for_existing_app(GALLERY_APP) |
393 | # ubuntu-app-stop does not work with gallery app, use process helper |
394 | - self.addCleanup(processes.stop_process, 'gallery-app') |
395 | + self.addCleanup(processes.stop_process, GALLERY_APP) |
396 | return proxy |
397 | |
398 | def get_gallery_events_view(self): |
399 | @@ -427,7 +444,7 @@ |
400 | |
401 | """ |
402 | from ubuntu_system_tests.helpers.mediaplayer._cpo import MainWindow |
403 | - proxy = self._get_proxy_object_for_existing_app('mediaplayer-app') |
404 | + proxy = self._get_proxy_object_for_existing_app(MEDIA_PLAYER_APP) |
405 | return MainWindow(proxy) |
406 | |
407 | def launch_messaging_app(self): |
408 | @@ -453,7 +470,7 @@ |
409 | base=base) |
410 | |
411 | from ubuntu_system_tests.helpers.messaging._cpo import MainView |
412 | - proxy = self._get_proxy_object_for_existing_app('messaging-app') |
413 | + proxy = self._get_proxy_object_for_existing_app(MESSAGING_APP) |
414 | return proxy.wait_select_single(MainView) |
415 | |
416 | def launch_system_settings(self): |
417 | @@ -475,7 +492,7 @@ |
418 | """ |
419 | from ubuntu_system_tests.helpers.system_settings import _cpo # NOQA |
420 | proxy = self._get_proxy_object_for_existing_app( |
421 | - 'system-settings', cleanup_process='ubuntu-system-settings') |
422 | + SYSTEM_SETTINGS, cleanup_process=SYSTEM_SETTINGS_CLEANUP) |
423 | return proxy.main_view |
424 | |
425 | def launch_webbrowser_app(self): |
426 | @@ -496,7 +513,7 @@ |
427 | |
428 | """ |
429 | from ubuntu_system_tests.helpers.webbrowser import _cpo # NOQA |
430 | - proxy = self._get_proxy_object_for_existing_app('webbrowser-app') |
431 | + proxy = self._get_proxy_object_for_existing_app(WEB_BROWSER_APP) |
432 | return proxy.main_window |
433 | |
434 | def launch_calendar_app(self): |
435 | @@ -530,14 +547,9 @@ |
436 | """ |
437 | self._launch_application_from_apps_scope('Clock') |
438 | wait_until(processes.is_qmlscene_running_with_qmlfile, |
439 | - 'ubuntu-clock-app') |
440 | + CLOCK_APP) |
441 | return self.get_clock_app_proxy() |
442 | |
443 | - def launch_webbrowser_from_launcher(self): |
444 | - """Start webbrowser from the launcher.""" |
445 | - self._launch_application_from_launcher('webbrowser-app') |
446 | - return self.get_webbrowser_app_proxy() |
447 | - |
448 | def get_clock_app_proxy(self): |
449 | """ |
450 | Return clock app proxy object from existing process. |
451 | @@ -546,18 +558,22 @@ |
452 | |
453 | """ |
454 | from ubuntu_system_tests.helpers.clock import _cpo # NOQA |
455 | - proxy = self._get_proxy_object_for_existing_qmlscene_process( |
456 | - 'ubuntu-clock-app') |
457 | + proxy = self._get_proxy_object_for_existing_qmlscene_process(CLOCK_APP) |
458 | return proxy.main_view |
459 | |
460 | + def launch_webbrowser_from_launcher(self): |
461 | + """Start webbrowser from the launcher.""" |
462 | + self._launch_application_from_launcher(WEB_BROWSER_APP) |
463 | + return self.get_webbrowser_app_proxy() |
464 | + |
465 | def launch_messaging_app_from_launcher(self): |
466 | """Drag out the launcher and tap the messaging app icon to start it.""" |
467 | - self._launch_application_from_launcher('messaging-app') |
468 | + self._launch_application_from_launcher(MESSAGING_APP) |
469 | return self.get_messaging_app_proxy() |
470 | |
471 | def launch_dialer_app_from_launcher(self): |
472 | """Drag out the launcher and tap the dialer app icon to start it.""" |
473 | - self._launch_application_from_launcher('dialer-app') |
474 | + self._launch_application_from_launcher(DIALER_APP) |
475 | return self.get_dialer_app_proxy() |
476 | |
477 | def get_webapp_proxy(self, web_app_package): |
478 | |
479 | === added directory 'ubuntu_system_tests/tests/data/perf' |
480 | === added file 'ubuntu_system_tests/tests/data/perf/metadata.json' |
481 | --- ubuntu_system_tests/tests/data/perf/metadata.json 1970-01-01 00:00:00 +0000 |
482 | +++ ubuntu_system_tests/tests/data/perf/metadata.json 2016-01-20 15:40:48 +0000 |
483 | @@ -0,0 +1,8 @@ |
484 | +{ |
485 | + "test_perform_actions": { |
486 | + "setup_actions": ["start_all_webapps"], |
487 | + "iterations": 2, |
488 | + "test_actions": ["take_photo", "open_two_urls", "add_random_contact", |
489 | + "add_random_numbers", "remove_add_sdcard", "record_video"] |
490 | + } |
491 | +} |
492 | |
493 | === added file 'ubuntu_system_tests/tests/data/perf/plot.json' |
494 | --- ubuntu_system_tests/tests/data/perf/plot.json 1970-01-01 00:00:00 +0000 |
495 | +++ ubuntu_system_tests/tests/data/perf/plot.json 2016-01-20 15:40:48 +0000 |
496 | @@ -0,0 +1,12 @@ |
497 | +{ |
498 | + "output_dir": "monitoring_report", |
499 | + "config_file_name": "report.config", |
500 | + "directives": [ |
501 | + "CPU_ALL={stackedGraph: true, fillGraph: true}", |
502 | + "MEM={}", |
503 | + "NET=wlan0{}", |
504 | + "DISKBUSY=mmcblk0,mmcblk0p1,mmcblk0p2,mmcblk0p3,mmcblk0p4,mmcblk0p5,mmcblk0p6,mmcblk0p7,mmcblk0boot1,mmcblk0boot0,mmcblk1,mmcblk1p1{}", |
505 | + "DISKREAD=mmcblk0,mmcblk0p1,mmcblk0p2,mmcblk0p3,mmcblk0p4,mmcblk0p5,mmcblk0p6,mmcblk0p7,mmcblk0boot1,mmcblk0boot0,mmcblk1,mmcblk1p1{}", |
506 | + "DISKWRITE=mmcblk0,mmcblk0p1,mmcblk0p2,mmcblk0p3,mmcblk0p4,mmcblk0p5,mmcblk0p6,mmcblk0p7,mmcblk0boot1,mmcblk0boot0,mmcblk1,mmcblk1p1{}" |
507 | + ] |
508 | +} |
509 | |
510 | === added directory 'ubuntu_system_tests/tests/perf' |
511 | === added file 'ubuntu_system_tests/tests/perf/__init__.py' |
512 | --- ubuntu_system_tests/tests/perf/__init__.py 1970-01-01 00:00:00 +0000 |
513 | +++ ubuntu_system_tests/tests/perf/__init__.py 2016-01-20 15:40:48 +0000 |
514 | @@ -0,0 +1,91 @@ |
515 | +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
516 | + |
517 | +# |
518 | +# Ubuntu System Tests |
519 | +# Copyright (C) 2015 Canonical |
520 | +# |
521 | +# This program is free software: you can redistribute it and/or modify |
522 | +# it under the terms of the GNU General Public License as published by |
523 | +# the Free Software Foundation, either version 3 of the License, or |
524 | +# (at your option) any later version. |
525 | +# |
526 | +# This program is distributed in the hope that it will be useful, |
527 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
528 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
529 | +# GNU General Public License for more details. |
530 | +# |
531 | +# You should have received a copy of the GNU General Public License |
532 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
533 | +# |
534 | + |
535 | +import logging |
536 | +import traceback |
537 | + |
538 | +from ubuntu_system_tests.helpers.addressbook import ( |
539 | + fixture_setup as addressbook_fixtures) |
540 | +from ubuntu_system_tests.helpers import autopilot |
541 | +from ubuntu_system_tests.helpers.backup_restore_fixture import ( |
542 | + BackupRestoreFixture) |
543 | +from ubuntu_system_tests.helpers.camera.fixture_setup import ( |
544 | + SetCameraAccessRequests) |
545 | +from ubuntu_system_tests.helpers.clock.fixture_setup import ( |
546 | + SetClockAccessRequests) |
547 | +from ubuntu_system_tests.helpers import file_system as fs |
548 | +from ubuntu_system_tests.helpers.location.fixture_setup import ( |
549 | + SetLocationAccessRequests) |
550 | +from ubuntu_system_tests.helpers import media |
551 | +from ubuntu_system_tests.helpers.scopes import go_to_apps_scope |
552 | +from ubuntu_system_tests.helpers.webbrowser.fixture_setup import ( |
553 | + WebbrowserTestEnvironment) |
554 | + |
555 | +from ubuntu_system_tests.tests import base |
556 | + |
557 | +logger = logging.getLogger(__name__) |
558 | + |
559 | +WEB_APPS = ['Gmail', 'Facebook', 'Twitter', 'Amazon', 'eBay', 'HERE Maps'] |
560 | + |
561 | + |
562 | +class BasePerfTestCase(base.BaseUbuntuSystemTestCase): |
563 | + |
564 | + def setUp(self): |
565 | + super().setUp() |
566 | + |
567 | + self.useFixture(SetCameraAccessRequests()) |
568 | + self.useFixture(SetClockAccessRequests()) |
569 | + self.useFixture(SetLocationAccessRequests('com.nokia.heremaps_here')) |
570 | + |
571 | + self.useFixture(BackupRestoreFixture(fs.DIR_HOME_CAMERA_CONFIG)) |
572 | + self.useFixture(BackupRestoreFixture(fs.DIR_HOME_CAMERA_THUMBNAILS)) |
573 | + self.useFixture(media.BackupRestoreLocalMediaFixture()) |
574 | + |
575 | + self.useFixture(addressbook_fixtures.AddressBookTestEnvironment()) |
576 | + self.useFixture(WebbrowserTestEnvironment()) |
577 | + |
578 | + self.errors = 0 |
579 | + self.errors_msg = [] |
580 | + self.addCleanup(self._print_errors) |
581 | + |
582 | + def _manage_app(self, method, *args): |
583 | + try: |
584 | + method(*args) |
585 | + except Exception as e: |
586 | + self.errors += 1 |
587 | + self.errors_msg.append(traceback.format_exc()) |
588 | + logger.error(e) |
589 | + |
590 | + def _start_webapp(self, app_name): |
591 | + apps_scope = go_to_apps_scope() |
592 | + apps_scope.click_scope_item('local', app_name) |
593 | + |
594 | + def _validate_camera_app(self): |
595 | + if not autopilot.is_camera_supported(): |
596 | + raise RuntimeError("Camera-app required") |
597 | + |
598 | + def _print_errors(self): |
599 | + print('*' * 100) |
600 | + print('ERRORS FOUND') |
601 | + print('*' * 100) |
602 | + for error in self.errors_msg: |
603 | + print(error) |
604 | + print('-' * 50) |
605 | + print('*' * 100) |
606 | |
607 | === added file 'ubuntu_system_tests/tests/perf/test_apps.py' |
608 | --- ubuntu_system_tests/tests/perf/test_apps.py 1970-01-01 00:00:00 +0000 |
609 | +++ ubuntu_system_tests/tests/perf/test_apps.py 2016-01-20 15:40:48 +0000 |
610 | @@ -0,0 +1,197 @@ |
611 | +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
612 | + |
613 | +# |
614 | +# Ubuntu System Tests |
615 | +# Copyright (C) 2015 Canonical |
616 | +# |
617 | +# This program is free software: you can redistribute it and/or modify |
618 | +# it under the terms of the GNU General Public License as published by |
619 | +# the Free Software Foundation, either version 3 of the License, or |
620 | +# (at your option) any later version. |
621 | +# |
622 | +# This program is distributed in the hope that it will be useful, |
623 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
624 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
625 | +# GNU General Public License for more details. |
626 | +# |
627 | +# You should have received a copy of the GNU General Public License |
628 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
629 | +# |
630 | + |
631 | +import logging |
632 | +import subprocess |
633 | +import random |
634 | +import os |
635 | +from testtools import skipUnless |
636 | + |
637 | +from address_book_app.address_book.data import Phone, Contact |
638 | + |
639 | +from ubuntu_system_tests.helpers import camera |
640 | +from ubuntu_system_tests.helpers.data import load_test_metadata |
641 | +from ubuntu_system_tests.helpers import monitoring |
642 | +from ubuntu_system_tests.helpers import processes |
643 | +from ubuntu_system_tests.helpers import sdcard |
644 | +from ubuntu_system_tests.helpers import wait_until |
645 | + |
646 | +from ubuntu_system_tests.tests import base |
647 | +from ubuntu_system_tests.tests import perf |
648 | + |
649 | +logger = logging.getLogger(__name__) |
650 | + |
651 | + |
652 | +class AppsTestCase(perf.BasePerfTestCase): |
653 | + """ This Class tests performance aspects open and closing apps """ |
654 | + |
655 | + @skipUnless(monitoring.is_monitoring_enabled(), 'Perf test skipped') |
656 | + def setUp(self): |
657 | + super().setUp() |
658 | + self.unity_proxy = self.restart_unity() |
659 | + self.test_metadata = load_test_metadata().perf |
660 | + self.pic = 0 |
661 | + |
662 | + def _start_action(self, action): |
663 | + getattr(self, '_action_{}'.format(action))() |
664 | + |
665 | + def _action_open_webbrowser(self): |
666 | + self.launch_webbrowser_app() |
667 | + |
668 | + def _action_close_webbrowser(self): |
669 | + self.ensure_application_closed(base.WEB_BROWSER_APP) |
670 | + |
671 | + def _action_open_dialer(self): |
672 | + self.launch_dialer_app() |
673 | + |
674 | + def _action_close_dialer(self): |
675 | + self.ensure_application_closed(base.DIALER_APP) |
676 | + |
677 | + def _action_open_messaging(self): |
678 | + self.launch_messaging_app() |
679 | + |
680 | + def _action_close_messaging(self): |
681 | + self.ensure_application_closed(base.MESSAGING_APP) |
682 | + |
683 | + def _action_open_clock(self): |
684 | + self.launch_clock_app() |
685 | + |
686 | + def _action_close_clock(self): |
687 | + self.ensure_application_closed(base.CLOCK_APP) |
688 | + |
689 | + def _action_open_address_book(self): |
690 | + self.launch_address_book() |
691 | + |
692 | + def _action_close_address_book(self): |
693 | + self.ensure_application_closed(base.ADDRESS_BOOK_APP) |
694 | + |
695 | + def _action_open_camera(self): |
696 | + self.launch_calendar_app() |
697 | + |
698 | + def _action_close_camera(self): |
699 | + self.ensure_application_closed(base.CAMERA_APP) |
700 | + |
701 | + def _action_open_calculator(self): |
702 | + self.launch_calculator_app() |
703 | + |
704 | + def _action_close_calculator(self): |
705 | + processes.stop_qmlscene_process(base.CALCULATOR_APP) |
706 | + |
707 | + def _action_open_system_settings(self): |
708 | + self.launch_system_settings() |
709 | + |
710 | + def _action_close_system_settings(self): |
711 | + processes.ensure_application_closed(base.SYSTEM_SETTINGS_CLEANUP) |
712 | + |
713 | + def _action_start_all_webapps(self): |
714 | + # Open apps that will be open during the whole tests |
715 | + self._manage_app(self._start_webapp, 'Gmail') |
716 | + self._manage_app(self._start_webapp, 'Facebook') |
717 | + self._manage_app(self._start_webapp, 'Twitter') |
718 | + self._manage_app(self._start_webapp, 'Amazon') |
719 | + self._manage_app(self._start_webapp, 'eBay') |
720 | + self._manage_app(self._start_webapp, 'HERE Maps') |
721 | + self.addCleanup(self._action_close_all_webapps) |
722 | + |
723 | + def _action_close_all_webapps(self): |
724 | + cmd = 'pkill -ef --signal SIGKILL webapp-container' |
725 | + subprocess.call(cmd, shell=True) |
726 | + |
727 | + def _action_open_two_urls(self): |
728 | + """ Open two pages """ |
729 | + browser = self.launch_webbrowser_app() |
730 | + browser.go_to_url('launchpad.net') |
731 | + browser.wait_page_loaded() |
732 | + browser.go_to_url('canonical.com') |
733 | + browser.wait_page_loaded() |
734 | + |
735 | + def _action_add_random_contact(self): |
736 | + # Add a random contact |
737 | + address_book = self.launch_address_book() |
738 | + |
739 | + first_name = 'first_name_{}'.format(random.randint(0, 999999)) |
740 | + last_name = 'last_name_{}'.format(random.randint(0, 999999)) |
741 | + phone = Phone(type_='Mobile', number='818616313') |
742 | + test_contact = Contact(first_name=first_name, last_name=last_name, |
743 | + phones=[phone]) |
744 | + contact_editor = address_book.go_to_add_contact() |
745 | + contact_editor.fill_form(test_contact) |
746 | + address_book.save() |
747 | + |
748 | + def _action_add_random_numbers(self): |
749 | + """ Add two numbers """ |
750 | + calculator = self.launch_calculator_app() |
751 | + calculator.calculate('{}+{}').format(random.randint(0, 999), |
752 | + random.randint(0, 999)) |
753 | + |
754 | + def _action_remove_add_sdcard(self): |
755 | + # Remove and insert the sd card |
756 | + if sdcard.is_sdcard_mounted(): |
757 | + device = sdcard.remove() |
758 | + sdcard.insert(device) |
759 | + else: |
760 | + logging.warning('Action Remove Add sdcard skipped') |
761 | + |
762 | + def _action_take_photo(self): |
763 | + self._validate_camera_app() |
764 | + camera_app = self.launch_camera_app() |
765 | + config = camera.get_config(mode='camera') |
766 | + camera.config_camera(camera_app, config) |
767 | + photoroll_hint = camera_app.take_photo(self.pic == 0) |
768 | + self.pic += 1 |
769 | + if photoroll_hint: |
770 | + gallery = photoroll_hint.swipe_to_dismiss() |
771 | + gallery.go_back() |
772 | + |
773 | + def _action_record_video(self): |
774 | + self._validate_camera_app() |
775 | + camera_app = self.launch_camera_app() |
776 | + config = camera.get_config(mode='video') |
777 | + camera.config_camera(camera_app, config) |
778 | + camera_app.record_video(2, random_focus=False) |
779 | + if self.pic == 0: |
780 | + camera_app.swipe_to_gallery(self) |
781 | + camera_app.start_playback() |
782 | + |
783 | + def _action_wait_for_stop_test_file(self): |
784 | + file = os.path.join('/', 'home', 'stop_test') |
785 | + timeout = 60 * 60 * 12 |
786 | + if wait_until(os.path.isfile, file, timeout=timeout, period=5): |
787 | + os.remove(file) |
788 | + |
789 | + def test_perform_actions(self): |
790 | + """ Perform all the actions defined in the input test data repeatedly. |
791 | + The test first read the test_perform_actions test data and based on |
792 | + that execute all the setup actions first, then it performs |
793 | + iteratively based on the iterations parameter the test_actions. |
794 | + The cleanup has to be set through the standard cleanup method. |
795 | + The test passes when all the actions finished successfully. The |
796 | + exceptions raise during the execution are printed in stdout. |
797 | + """ |
798 | + test_data = self.test_metadata.test_perform_actions |
799 | + |
800 | + for action in test_data.setup_actions: |
801 | + self._manage_app(self._start_action, action) |
802 | + |
803 | + for i in range(test_data.iterations): |
804 | + for action in test_data.test_actions: |
805 | + self._manage_app(self._start_action, action) |
806 | + |
807 | + self.assertEqual(0, self.errors, 'Errors found {}'.format(self.errors)) |
808 | |
809 | === modified file 'ubuntu_system_tests/tests/test_sdcard.py' |
810 | --- ubuntu_system_tests/tests/test_sdcard.py 2015-12-23 13:30:00 +0000 |
811 | +++ ubuntu_system_tests/tests/test_sdcard.py 2016-01-20 15:40:48 +0000 |
812 | @@ -62,7 +62,7 @@ |
813 | class SDCardSystemTest(base.BaseUbuntuSystemTestCase): |
814 | """This Class tests the sd card""" |
815 | |
816 | - @skipUnless(fs.is_media_folder_dir(fs.DIR_PICTURES), SKIP_REASON) |
817 | + @skipUnless(sdcard.is_sdcard_mounted(), SKIP_REASON) |
818 | def setUp(self): |
819 | super().setUp() |
820 | self.useFixture(ScopesHints()) |
Do you think the plotting of the data should be coupled to ubuntu- system- tests? I suppose it's a nice to have but really the plotting should be done externally so we have a choice of which tool to use, how to configure it etc.