Merge lp:~zyga/checkbox/fix-exporter-crash into lp:checkbox
- fix-exporter-crash
- Merge into trunk
Status: | Work in progress |
---|---|
Proposed branch: | lp:~zyga/checkbox/fix-exporter-crash |
Merge into: | lp:checkbox |
Diff against target: |
1395 lines (+494/-103) 28 files modified
Vagrantfile (+1/-0) jobs/info.txt.in (+2/-2) jobs/networking.txt.in (+11/-2) jobs/peripheral.txt.in (+3/-0) jobs/power-management.txt.in (+1/-0) jobs/suspend.txt.in (+30/-0) jobs/usb.txt.in (+55/-0) jobs/user_apps.txt.in (+4/-0) jobs/wireless.txt.in (+27/-3) plainbox/MANIFEST.in (+1/-1) plainbox/daily-package-testing/Vagrantfile (+2/-0) plainbox/daily-package-testing/test-in-vagrant.sh (+19/-0) plainbox/plainbox/impl/commands/run.py (+3/-34) plainbox/plainbox/impl/commands/sru.py (+6/-4) plainbox/plainbox/impl/commands/test_run.py (+1/-17) plainbox/plainbox/impl/depmgr.py (+1/-1) plainbox/plainbox/impl/exporter/__init__.py (+37/-0) plainbox/plainbox/impl/exporter/json.py (+11/-7) plainbox/plainbox/impl/exporter/rfc822.py (+2/-2) plainbox/plainbox/impl/exporter/test_init.py (+18/-2) plainbox/plainbox/impl/exporter/test_json.py (+8/-3) plainbox/plainbox/impl/exporter/test_rfc822.py (+5/-1) plainbox/plainbox/impl/exporter/test_text.py (+1/-1) plainbox/plainbox/impl/exporter/text.py (+3/-3) plainbox/plainbox/impl/integration_tests.py (+59/-9) plainbox/plainbox/impl/session.py (+1/-1) plainbox/plainbox/test-data/sru-virtualbox-precise.txt (+171/-0) scripts/network_device_info (+11/-10) |
To merge this branch: | bzr merge lp:~zyga/checkbox/fix-exporter-crash |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Checkbox Developers | Pending | ||
Review via email: mp+157074@code.launchpad.net |
Commit message
Description of the change
work in progress to address the crash that happens at the end of 'plainbox sru' run.
The tests work on precise and raring but quantal, for some reason, produces different results. I'm checking that to see what's going on.
This branch also needs to be rebased on the very old and unused 'device profiles' branch so that plainbox sru tests are only started inside virtualbox.
UPDATE 1:
Running on quantal is now fixed, this was a missing dependency on python3-dbus on jobs that run network_device_info script. I've added that dependency and marked it for installation with vagrant. I've fixed a few other things in that script as I had a look at it. I _strongly_ believe that we need to do an audit of each script and job and start looking after them more than we currently do (this is a part of the jobbox proposal).
The comment about device profiles still stands so please don't land this yet
UPDATE 2:
Fixed a few things that were breaking tests (indeterministic iteration over a few sets).
I've also fixed the text exporter to add newlines (yay) and fixed all exporters to have
deterministic output.
Still needs device profiles work to only run in VMs
UPDATE 3:
Added explicit requirements on all environment variables so that stuff is not supported (with an explicit reason) rather than failing.
Still needs device profiles work to only run in VMs
UPDATE 4:
Finished checking jobs that fail. Out of the list only memory/info and memory/check still fail but for not reasons caused by plainbox. A number of jobs are not supported
those will require adding a few packages (most notably udisks and some gir packages)
so that we can run all tests reliably for SRU (SRU vagrant mode should install those packages).
Again before landing this branch needs to support device profiles to only run on VMs
(the branch name is somewhat inappropriate now, as a small version of this, with just the fix, is proposed separately).
- 2030. By Zygmunt Krynicki
-
vagrant: install python3-dbus
This package is needed by scripts that talk over dbus and have been
ported to python3Signed-off-by: Zygmunt Krynicki <email address hidden>
- 2031. By Zygmunt Krynicki
-
jobs: networking/detect: add dependency on python3-dbus
This package required python3-dbus to work. Let's make it explicit
Signed-off-by: Zygmunt Krynicki <email address hidden>
- 2032. By Zygmunt Krynicki
-
scripts: network_
device_ info: remove unused imports Signed-off-by: Zygmunt Krynicki <email address hidden>
- 2033. By Zygmunt Krynicki
-
scripts: network_
device_ info: fix PEP8 issues Signed-off-by: Zygmunt Krynicki <email address hidden>
- 2034. By Zygmunt Krynicki
-
scrips: network_
device_ info: rework style Using filter() with lambda is deprecated in favor of list comprehensions
Signed-off-by: Zygmunt Krynicki <email address hidden>
- 2035. By Zygmunt Krynicki
-
integration_tests: refactor XDGSandBoxMixIn from IntegrationTests
Signed-off-by: Zygmunt Krynicki <email address hidden>
- 2036. By Zygmunt Krynicki
-
integration_tests: fix PEP8 issues
Signed-off-by: Zygmunt Krynicki <email address hidden>
- 2037. By Zygmunt Krynicki
-
integration_tests: rename IntegrationTests to CheckBoxJobResponse
Signed-off-by: Zygmunt Krynicki <email address hidden>
- 2038. By Zygmunt Krynicki
-
depmgr: iterate over dependencies in deterministic order
The DependencySolve
r._visit( ) job iterates over each dependency as
computed by the DependencySolver._get_ dependency_ set() method. This
returns a set so the ordering is unspecified.It makes sense to make this part deterministic so that we always run
jobs in the same order. It also fixes random "problems" for integration
tests that check the verbatim copy of the output.Signed-off-by: Zygmunt Krynicki <email address hidden>
- 2039. By Zygmunt Krynicki
-
session: iterate over dependencies in deterministic order
There is one aspect of _recompute_
job_readiness( ) that is
not deterministic. The loop that checks if each direct dependency
ran correctly iterates over a set returned by job.get_direct_ dependencies( ) Being deterministic is a desirable property so let's fix this by
sorting the dependencies.Signed-off-by: Zygmunt Krynicki <email address hidden>
- 2040. By Zygmunt Krynicki
-
integration_tests: add smoke test for 'plainbox sru' command
Signed-off-by: Zygmunt Krynicki <email address hidden>
- 2041. By Zygmunt Krynicki
-
MANIFEST.in: put .xml and .txt files into source tarball
Signed-off-by: Zygmunt Krynicki <email address hidden>
- 2042. By Zygmunt Krynicki
-
daily-package-
testing: run unit and integration tests Signed-off-by: Zygmunt Krynicki <email address hidden>
- 2043. By Zygmunt Krynicki
-
exporter: text: add missing newline to each output line
Signed-off-by: Zygmunt Krynicki <email address hidden>
- 2044. By Zygmunt Krynicki
-
exporter: text: provide deterministic output
Signed-off-by: Zygmunt Krynicki <email address hidden>
- 2045. By Zygmunt Krynicki
-
exporter: prettify some of the canned output
Signed-off-by: Zygmunt Krynicki <email address hidden>
- 2046. By Zygmunt Krynicki
-
exporter: rfc822: provide deterministic output
Signed-off-by: Zygmunt Krynicki <email address hidden>
- 2047. By Zygmunt Krynicki
-
jobs: add explicit requires: environment.XXX for each $XXX used
The exceptions are $CHECKBOX_SHARE and $CHECKBOX_DATA as those are
generated internally by the job runner so are always available.Signed-off-by: Zygmunt Krynicki <email address hidden>
- 2048. By Zygmunt Krynicki
-
test-data: update test data after adding environment requirements
Signed-off-by: Zygmunt Krynicki <email address hidden>
- 2049. By Zygmunt Krynicki
-
jobs: usb: update requires to depend on correct packages
There are a number of changes but they can be classified into distinct
groups:Stuff that runs removable_
storage_ {watcher, test}. All of those jobs
should depend on python3-dbus, python3-gi, gir1.2-gudev-1.0 and one
of udisks or udisks2One shell job that uses udev and hdparm directly got those dependencies
One job uses keyboard_test, it depends on python3-gi and the gir file for
GTK whichc is in package gir1.2-gtk-3.0Signed-off-by: Zygmunt Krynicki <email address hidden>
- 2050. By Zygmunt Krynicki
-
test-data: update after declaring dependencies for usb jobs
Signed-off-by: Zygmunt Krynicki <email address hidden>
- 2051. By Zygmunt Krynicki
-
jobs: dmi_attachment: do not read private files
This job fails in plainbox because grub exits with error code 2. This
is caused by grub failing to open any of/sys/class/
dmi/id/ {board_ serial, product_ serial, product_ uuid} All of those files are only readable by root as they contain unique
identifiers that can be used to trace the user somehow.The new script does away with reading files it cannot read, it also
uses a slightly different syntax by having a space after the leading
colon (the filename)Signed-off-by: Zygmunt Krynicki <email address hidden>
- 2052. By Zygmunt Krynicki
-
test-data: update after fixing dmi_attachment
Signed-off-by: Zygmunt Krynicki <email address hidden>
- 2053. By Zygmunt Krynicki
-
jobs: attachment: fix acpi_sleep_
attachment if /proc/acpi/sleep is gone This job returns a non-zero exit status from [ if /proc/acpi/sleep
does not exist. This shows up in plainbox as a failed job.Since there is no way to express file dependencies (no path resource)
I've changed it to always succeedSigned-off-by: Zygmunt Krynicki <email address hidden>
- 2054. By Zygmunt Krynicki
-
test-data: update after fixing acpi_sleep_
attachment Signed-off-by: Zygmunt Krynicki <email address hidden>
Unmerged revisions
- 2054. By Zygmunt Krynicki
-
test-data: update after fixing acpi_sleep_
attachment Signed-off-by: Zygmunt Krynicki <email address hidden>
- 2053. By Zygmunt Krynicki
-
jobs: attachment: fix acpi_sleep_
attachment if /proc/acpi/sleep is gone This job returns a non-zero exit status from [ if /proc/acpi/sleep
does not exist. This shows up in plainbox as a failed job.Since there is no way to express file dependencies (no path resource)
I've changed it to always succeedSigned-off-by: Zygmunt Krynicki <email address hidden>
- 2052. By Zygmunt Krynicki
-
test-data: update after fixing dmi_attachment
Signed-off-by: Zygmunt Krynicki <email address hidden>
- 2051. By Zygmunt Krynicki
-
jobs: dmi_attachment: do not read private files
This job fails in plainbox because grub exits with error code 2. This
is caused by grub failing to open any of/sys/class/
dmi/id/ {board_ serial, product_ serial, product_ uuid} All of those files are only readable by root as they contain unique
identifiers that can be used to trace the user somehow.The new script does away with reading files it cannot read, it also
uses a slightly different syntax by having a space after the leading
colon (the filename)Signed-off-by: Zygmunt Krynicki <email address hidden>
- 2050. By Zygmunt Krynicki
-
test-data: update after declaring dependencies for usb jobs
Signed-off-by: Zygmunt Krynicki <email address hidden>
- 2049. By Zygmunt Krynicki
-
jobs: usb: update requires to depend on correct packages
There are a number of changes but they can be classified into distinct
groups:Stuff that runs removable_
storage_ {watcher, test}. All of those jobs
should depend on python3-dbus, python3-gi, gir1.2-gudev-1.0 and one
of udisks or udisks2One shell job that uses udev and hdparm directly got those dependencies
One job uses keyboard_test, it depends on python3-gi and the gir file for
GTK whichc is in package gir1.2-gtk-3.0Signed-off-by: Zygmunt Krynicki <email address hidden>
- 2048. By Zygmunt Krynicki
-
test-data: update test data after adding environment requirements
Signed-off-by: Zygmunt Krynicki <email address hidden>
- 2047. By Zygmunt Krynicki
-
jobs: add explicit requires: environment.XXX for each $XXX used
The exceptions are $CHECKBOX_SHARE and $CHECKBOX_DATA as those are
generated internally by the job runner so are always available.Signed-off-by: Zygmunt Krynicki <email address hidden>
- 2046. By Zygmunt Krynicki
-
exporter: rfc822: provide deterministic output
Signed-off-by: Zygmunt Krynicki <email address hidden>
- 2045. By Zygmunt Krynicki
-
exporter: prettify some of the canned output
Signed-off-by: Zygmunt Krynicki <email address hidden>
Preview Diff
1 | === modified file 'Vagrantfile' |
2 | --- Vagrantfile 2013-03-20 14:34:45 +0000 |
3 | +++ Vagrantfile 2013-04-04 16:49:24 +0000 |
4 | @@ -49,6 +49,7 @@ |
5 | # Later on those could be installed on demand to test how we behave without |
6 | # them but for now that's good enough. Little by little... |
7 | config.vm.provision :shell, :inline => "apt-get install --yes fwts" |
8 | + config.vm.provision :shell, :inline => "apt-get install --yes python3-dbus" |
9 | # Develop plainbox so that we have it in $PATH |
10 | config.vm.provision :shell, :inline => "cd /vagrant/plainbox/ && python3 setup.py develop" |
11 | # Create a cool symlink so that everyone knows where to go to |
12 | |
13 | === modified file 'jobs/info.txt.in' |
14 | --- jobs/info.txt.in 2012-12-17 21:41:58 +0000 |
15 | +++ jobs/info.txt.in 2013-04-04 16:49:24 +0000 |
16 | @@ -16,7 +16,7 @@ |
17 | |
18 | name: dmi_attachment |
19 | plugin: attachment |
20 | -command: grep -r . /sys/class/dmi/id/ 2>/dev/null |
21 | +command: for f in /sys/class/dmi/id/*; do [ -r $f -a -f $f ] && cat $f | sed -e "s/^/$(basename $f): /"; done |
22 | _description: Attaches info on DMI |
23 | |
24 | name: dmidecode_attachment |
25 | @@ -101,7 +101,7 @@ |
26 | |
27 | plugin: attachment |
28 | name: acpi_sleep_attachment |
29 | -command: [ -e /proc/acpi/sleep ] && cat /proc/acpi/sleep |
30 | +command: [ -e /proc/acpi/sleep ] && cat /proc/acpi/sleep || : |
31 | _description: Attaches the contents of /proc/acpi/sleep if it exists. |
32 | |
33 | plugin: local |
34 | |
35 | === modified file 'jobs/networking.txt.in' |
36 | --- jobs/networking.txt.in 2012-12-13 18:35:08 +0000 |
37 | +++ jobs/networking.txt.in 2013-04-04 16:49:24 +0000 |
38 | @@ -4,6 +4,7 @@ |
39 | device.category == 'NETWORK' or device.category == 'WIRELESS' |
40 | package.name == 'module-init-tools' |
41 | package.name == 'pciutils' |
42 | + package.name == 'python3-dbus' |
43 | command: network_device_info |
44 | _description: Test to detect the available network controllers |
45 | |
46 | @@ -75,6 +76,7 @@ |
47 | |
48 | plugin: shell |
49 | name: networking/ping |
50 | +requires: environment.CHECKBOX_SERVER != "" |
51 | command: internet_test $CHECKBOX_SERVER |
52 | _description: |
53 | Automated test case to verify availability of some system on the network |
54 | @@ -82,6 +84,9 @@ |
55 | |
56 | plugin: shell |
57 | name: networking/http |
58 | +requires: |
59 | + package.name == "wget" |
60 | + environment.TRANSFER_SERVER != "" |
61 | command: wget -SO /dev/null http://$TRANSFER_SERVER |
62 | _description: |
63 | Automated test case to make sure that it's possible to download files through HTTP |
64 | @@ -95,13 +100,17 @@ |
65 | |
66 | plugin: shell |
67 | name: networking/ssh |
68 | -requires: package.name == 'openssh-client' |
69 | +requires: |
70 | + package.name == 'openssh-client' |
71 | + environment.CHECKBOX_SERVER != "" |
72 | command: if [ $CHECKBOX_SERVER ]; then ssh -q -o 'StrictHostKeyChecking=no' -o "UserKnownHostsFile=/tmp/ssh_test_$$" -l ubuntu $CHECKBOX_SERVER "uname -a" && rm /tmp/ssh_test_$$; fi |
73 | _description: Verify that an installation of checkbox-server on the network can be reached over SSH. |
74 | |
75 | plugin: shell |
76 | name: networking/printer |
77 | -requires: package.name == 'cups-client' |
78 | +requires: |
79 | + package.name == 'cups-client' |
80 | + environment.CHECKBOX_SERVER != "" |
81 | command: network_printer_test -s $CHECKBOX_SERVER |
82 | _description: Try to enable a remote printer on the network and print a test page. |
83 | |
84 | |
85 | === modified file 'jobs/peripheral.txt.in' |
86 | --- jobs/peripheral.txt.in 2013-01-21 22:21:29 +0000 |
87 | +++ jobs/peripheral.txt.in 2013-04-04 16:49:24 +0000 |
88 | @@ -33,6 +33,9 @@ |
89 | plugin: shell |
90 | name: peripheral/external-usb-modem-http |
91 | depends: peripheral/external-usb-modem |
92 | +requires: |
93 | + package.name == "wget" |
94 | + environment.TRANSFER_SERVER != "" |
95 | command: wget -SO /dev/null http://$TRANSFER_SERVER |
96 | _description: |
97 | Automated test case to make sure that it's possible to download files through HTTP |
98 | |
99 | === modified file 'jobs/power-management.txt.in' |
100 | --- jobs/power-management.txt.in 2012-12-03 14:30:41 +0000 |
101 | +++ jobs/power-management.txt.in 2013-04-04 16:49:24 +0000 |
102 | @@ -164,6 +164,7 @@ |
103 | name: power-management/battery_drain_movie |
104 | requires: |
105 | package.name == 'upower' |
106 | + environment.MOVIE_VAR != '' |
107 | depends: power-management/unplug_ac |
108 | _description: Checks the battery drain while watching a movie. Reports time |
109 | until empty and capacity as well. Requires MOVIE_VAR to be set. |
110 | |
111 | === modified file 'jobs/suspend.txt.in' |
112 | --- jobs/suspend.txt.in 2013-03-29 18:21:40 +0000 |
113 | +++ jobs/suspend.txt.in 2013-04-04 16:49:24 +0000 |
114 | @@ -43,6 +43,7 @@ |
115 | package.name == 'bluez' |
116 | package.name == 'obexd-client' |
117 | device.category == 'BLUETOOTH' |
118 | + environment.BTDEVADDR != '' |
119 | command: |
120 | if [ -z "$BTDEVADDR" ] |
121 | then |
122 | @@ -69,6 +70,7 @@ |
123 | package.name == 'bluez' |
124 | package.name == 'obexftp' |
125 | device.category == 'BLUETOOTH' |
126 | + environment.BTDEVADDR != '' |
127 | command: |
128 | if [ -z "$BTDEVADDR" ] |
129 | then |
130 | @@ -95,6 +97,7 @@ |
131 | package.name == 'bluez' |
132 | package.name == 'obexftp' |
133 | device.category == 'BLUETOOTH' |
134 | + environment.BTDEVADDR != '' |
135 | command: |
136 | if [ -z "$BTDEVADDR" ] |
137 | then |
138 | @@ -121,6 +124,7 @@ |
139 | package.name == 'bluez' |
140 | package.name == 'obexftp' |
141 | device.category == 'BLUETOOTH' |
142 | + environment.BTDEVADDR != '' |
143 | command: |
144 | if [ -z "$BTDEVADDR" ] |
145 | then |
146 | @@ -312,6 +316,8 @@ |
147 | requires: |
148 | device.category == 'WIRELESS' |
149 | environment.ROUTERS == 'multiple' |
150 | + environment.WPA_BG_SSID != '' |
151 | + environment.WPA_BG_PSK != '' |
152 | user: root |
153 | environ: WPA_BG_SSID WPA_BG_PSK |
154 | command: trap "rm -f /etc/NetworkManager/system-connections/$WPA_BG_SSID" EXIT; create_connection $WPA_BG_SSID --security=wpa --key=$WPA_BG_PSK; internet_test --interface=`nmcli dev status | awk '/802-11-wireless/ {print $1}'` |
155 | @@ -325,6 +331,7 @@ |
156 | requires: |
157 | device.category == 'WIRELESS' |
158 | environment.ROUTERS == 'multiple' |
159 | + environment.OPEN_BG_SSID != '' |
160 | user: root |
161 | environ: OPEN_BG_SSID |
162 | command: trap "rm -f /etc/NetworkManager/system-connections/$OPEN_BG_SSID" EXIT; create_connection $OPEN_BG_SSID; internet_test --interface=`nmcli dev status | awk '/802-11-wireless/ {print $1}'` |
163 | @@ -338,6 +345,8 @@ |
164 | requires: |
165 | device.category == 'WIRELESS' |
166 | environment.ROUTERS == 'multiple' |
167 | + environment.WPA_N_SSID != '' |
168 | + environment.WPA_N_PSK != '' |
169 | user: root |
170 | environ: WPA_N_SSID WPA_N_PSK |
171 | command: trap "rm -f /etc/NetworkManager/system-connections/$WPA_N_SSID" EXIT; create_connection $WPA_N_SSID --security=wpa --key=$WPA_N_PSK; internet_test --interface=`nmcli dev status | awk '/802-11-wireless/ {print $1}'` |
172 | @@ -351,6 +360,7 @@ |
173 | requires: |
174 | device.category == 'WIRELESS' |
175 | environment.ROUTERS == 'multiple' |
176 | + environment.OPEN_N_SSID != '' |
177 | user: root |
178 | environ: OPEN_N_SSID |
179 | command: trap "rm -f /etc/NetworkManager/system-connections/$OPEN_N_SSID" EXIT; create_connection $OPEN_N_SSID; internet_test --interface=`nmcli dev status | awk '/802-11-wireless/ {print $1}'` |
180 | @@ -364,6 +374,8 @@ |
181 | requires: |
182 | device.category == 'WIRELESS' |
183 | environment.ROUTERS == 'multiple' |
184 | + environment.WPA_BG_SSID != '' |
185 | + environment.WPA_BG_PSK != '' |
186 | user: root |
187 | environ: WPA_BG_SSID WPA_BG_PSK |
188 | command: trap "rm -f /etc/NetworkManager/system-connections/$WPA_BG_SSID" EXIT; create_connection $WPA_BG_SSID --security=wpa --key=$WPA_BG_PSK; internet_test --interface=`nmcli dev status | awk '/802-11-wireless/ {print $1}'` |
189 | @@ -377,6 +389,7 @@ |
190 | requires: |
191 | device.category == 'WIRELESS' |
192 | environment.ROUTERS == 'multiple' |
193 | + environment.OPEN_BG_SSID != '' |
194 | user: root |
195 | environ: OPEN_BG_SSID |
196 | command: trap "rm -f /etc/NetworkManager/system-connections/$OPEN_BG_SSID" EXIT; create_connection $OPEN_BG_SSID; internet_test --interface=`nmcli dev status | awk '/802-11-wireless/ {print $1}'` |
197 | @@ -390,6 +403,8 @@ |
198 | requires: |
199 | device.category == 'WIRELESS' |
200 | environment.ROUTERS == 'multiple' |
201 | + environment.WPA_N_SSID != '' |
202 | + environment.WPA_N_PSK != '' |
203 | user: root |
204 | environ: WPA_N_SSID WPA_N_PSK |
205 | command: trap "rm -f /etc/NetworkManager/system-connections/$WPA_N_SSID" EXIT; create_connection $WPA_N_SSID --security=wpa --key=$WPA_N_PSK; internet_test --interface=`nmcli dev status | awk '/802-11-wireless/ {print $1}'` |
206 | @@ -403,6 +418,7 @@ |
207 | requires: |
208 | device.category == 'WIRELESS' |
209 | environment.ROUTERS == 'multiple' |
210 | + environment.OPEN_N_SSID != '' |
211 | user: root |
212 | environ: OPEN_N_SSID |
213 | command: trap "rm -f /etc/NetworkManager/system-connections/$OPEN_N_SSID" EXIT; create_connection $OPEN_N_SSID; internet_test --interface=`nmcli dev status | awk '/802-11-wireless/ {print $1}'` |
214 | @@ -416,6 +432,8 @@ |
215 | requires: |
216 | device.category == 'WIRELESS' |
217 | environment.ROUTERS == 'single' |
218 | + environment.ROUTER_SSID != '' |
219 | + environment.ROUTER_PSK != '' |
220 | user: root |
221 | environ: ROUTER_SSID ROUTER_PSK |
222 | command: trap "nmcli con delete id $ROUTER_SSID" EXIT; create_connection $ROUTER_SSID --security=wpa --key=$ROUTER_PSK && internet_test --interface=`nmcli dev status | awk '/802-11-wireless/ {print $1}'` |
223 | @@ -438,6 +456,7 @@ |
224 | requires: |
225 | device.category == 'WIRELESS' |
226 | environment.ROUTERS == 'single' |
227 | + environment.ROUTER_SSID != '' |
228 | user: root |
229 | environ: ROUTER_SSID |
230 | command: trap "nmcli con delete id $ROUTER_SSID" EXIT; create_connection $ROUTER_SSID && internet_test --interface=`nmcli dev status | awk '/802-11-wireless/ {print $1}'` |
231 | @@ -460,6 +479,8 @@ |
232 | requires: |
233 | device.category == 'WIRELESS' |
234 | environment.ROUTERS == 'single' |
235 | + environment.ROUTER_SSID != '' |
236 | + environment.ROUTER_PSK != '' |
237 | user: root |
238 | environ: ROUTER_SSID ROUTER_PSK |
239 | command: trap "nmcli con delete id $ROUTER_SSID" EXIT; create_connection $ROUTER_SSID --security=wpa --key=$ROUTER_PSK && internet_test --interface=`nmcli dev status | awk '/802-11-wireless/ {print $1}'` |
240 | @@ -482,6 +503,7 @@ |
241 | requires: |
242 | device.category == 'WIRELESS' |
243 | environment.ROUTERS == 'single' |
244 | + environment.ROUTER_SSID != '' |
245 | user: root |
246 | environ: ROUTER_SSID |
247 | command: trap "nmcli con delete id $ROUTER_SSID" EXIT; create_connection $ROUTER_SSID && internet_test --interface=`nmcli dev status | awk '/802-11-wireless/ {print $1}'` |
248 | @@ -529,6 +551,7 @@ |
249 | package.name == 'bluez' |
250 | package.name == 'obexd-client' |
251 | device.category == 'BLUETOOTH' |
252 | + environment.BTDEVADDR != '' |
253 | command: |
254 | if [ -z "$BTDEVADDR" ] |
255 | then |
256 | @@ -556,6 +579,7 @@ |
257 | package.name == 'bluez' |
258 | package.name == 'obexd-client' |
259 | device.category == 'BLUETOOTH' |
260 | + environment.BTDEVADDR != '' |
261 | command: |
262 | if [ -z "$BTDEVADDR" ] |
263 | then |
264 | @@ -583,6 +607,7 @@ |
265 | package.name == 'bluez' |
266 | package.name == 'obexftp' |
267 | device.category == 'BLUETOOTH' |
268 | + environment.BTDEVADDR != '' |
269 | command: |
270 | if [ -z "$BTDEVADDR" ] |
271 | then |
272 | @@ -610,6 +635,7 @@ |
273 | package.name == 'bluez' |
274 | package.name == 'obexftp' |
275 | device.category == 'BLUETOOTH' |
276 | + environment.BTDEVADDR != '' |
277 | command: |
278 | if [ -z "$BTDEVADDR" ] |
279 | then |
280 | @@ -637,6 +663,7 @@ |
281 | package.name == 'bluez' |
282 | package.name == 'obexftp' |
283 | device.category == 'BLUETOOTH' |
284 | + environment.BTDEVADDR != '' |
285 | command: |
286 | if [ -z "$BTDEVADDR" ] |
287 | then |
288 | @@ -664,6 +691,7 @@ |
289 | package.name == 'bluez' |
290 | package.name == 'obexftp' |
291 | device.category == 'BLUETOOTH' |
292 | + environment.BTDEVADDR != '' |
293 | command: |
294 | if [ -z "$BTDEVADDR" ] |
295 | then |
296 | @@ -691,6 +719,7 @@ |
297 | package.name == 'bluez' |
298 | package.name == 'obexftp' |
299 | device.category == 'BLUETOOTH' |
300 | + environment.BTDEVADDR != '' |
301 | command: |
302 | if [ -z "$BTDEVADDR" ] |
303 | then |
304 | @@ -718,6 +747,7 @@ |
305 | package.name == 'bluez' |
306 | package.name == 'obexftp' |
307 | device.category == 'BLUETOOTH' |
308 | + environment.BTDEVADDR != '' |
309 | command: |
310 | if [ -z "$BTDEVADDR" ] |
311 | then |
312 | |
313 | === modified file 'jobs/usb.txt.in' |
314 | --- jobs/usb.txt.in 2013-03-07 07:46:10 +0000 |
315 | +++ jobs/usb.txt.in 2013-04-04 16:49:24 +0000 |
316 | @@ -6,6 +6,11 @@ |
317 | plugin: manual |
318 | name: usb/disk_detect |
319 | depends: usb/detect |
320 | +requires: |
321 | + package.name == 'python3-dbus' |
322 | + package.name == 'python3-gi' |
323 | + package.name == 'gir1.2-gudev-1.0' |
324 | + package.name == 'udisks' or package.name == 'udisks2' |
325 | command: removable_storage_test -l usb |
326 | _description: |
327 | PURPOSE: |
328 | @@ -21,6 +26,9 @@ |
329 | plugin: manual |
330 | name: usb/HID |
331 | depends: usb/detect |
332 | +requires: |
333 | + package.name == 'python3-gi' |
334 | + package.name == 'gir1.2-gtk-3.0' |
335 | command: keyboard_test |
336 | _description: |
337 | PURPOSE: |
338 | @@ -35,6 +43,11 @@ |
339 | plugin: user-interact |
340 | name: usb/insert |
341 | depends: usb/detect |
342 | +requires: |
343 | + package.name == 'python3-dbus' |
344 | + package.name == 'python3-gi' |
345 | + package.name == 'gir1.2-gudev-1.0' |
346 | + package.name == 'udisks' or package.name == 'udisks2' |
347 | command: removable_storage_watcher insert usb |
348 | _description: |
349 | PURPOSE: |
350 | @@ -52,6 +65,10 @@ |
351 | name: usb3/insert |
352 | requires: |
353 | usb.usb3 == 'supported' |
354 | + package.name == 'python3-dbus' |
355 | + package.name == 'python3-gi' |
356 | + package.name == 'gir1.2-gudev-1.0' |
357 | + package.name == 'udisks' or package.name == 'udisks2' |
358 | command: removable_storage_watcher -m 500000000 insert usb |
359 | _description: |
360 | PURPOSE: |
361 | @@ -68,6 +85,11 @@ |
362 | plugin: user-interact |
363 | name: usb/remove |
364 | depends: usb/insert |
365 | +requires: |
366 | + package.name == 'python3-dbus' |
367 | + package.name == 'python3-gi' |
368 | + package.name == 'gir1.2-gudev-1.0' |
369 | + package.name == 'udisks' or package.name == 'udisks2' |
370 | command: removable_storage_watcher remove usb |
371 | _description: |
372 | PURPOSE: |
373 | @@ -85,6 +107,10 @@ |
374 | depends: usb3/insert |
375 | requires: |
376 | usb.usb3 == 'supported' |
377 | + package.name == 'python3-dbus' |
378 | + package.name == 'python3-gi' |
379 | + package.name == 'gir1.2-gudev-1.0' |
380 | + package.name == 'udisks' or package.name == 'udisks2' |
381 | command: removable_storage_watcher -m 500000000 remove usb |
382 | _description: |
383 | PURPOSE: |
384 | @@ -100,6 +126,11 @@ |
385 | plugin: manual |
386 | name: usb/storage-transfer |
387 | depends: usb/insert |
388 | +requires: |
389 | + package.name == 'python3-dbus' |
390 | + package.name == 'python3-gi' |
391 | + package.name == 'gir1.2-gudev-1.0' |
392 | + package.name == 'udisks' or package.name == 'udisks2' |
393 | user: root |
394 | command: removable_storage_test -s 268400000 usb |
395 | _description: |
396 | @@ -117,6 +148,10 @@ |
397 | name: usb3/storage-transfer |
398 | requires: |
399 | usb.usb3 == 'supported' |
400 | + package.name == 'python3-dbus' |
401 | + package.name == 'python3-gi' |
402 | + package.name == 'gir1.2-gudev-1.0' |
403 | + package.name == 'udisks' or package.name == 'udisks2' |
404 | depends: usb3/insert |
405 | user: root |
406 | command: removable_storage_test -s 268400000 -m 500000000 -p 7 usb |
407 | @@ -134,6 +169,11 @@ |
408 | plugin: shell |
409 | name: usb/storage-automated |
410 | depends: usb/insert |
411 | +requires: |
412 | + package.name == 'python3-dbus' |
413 | + package.name == 'python3-gi' |
414 | + package.name == 'gir1.2-gudev-1.0' |
415 | + package.name == 'udisks' or package.name == 'udisks2' |
416 | user: root |
417 | command: removable_storage_test -s 268400000 usb |
418 | _description: |
419 | @@ -143,6 +183,10 @@ |
420 | name: usb3/storage-automated |
421 | requires: |
422 | usb.usb3 == 'supported' |
423 | + package.name == 'python3-dbus' |
424 | + package.name == 'python3-gi' |
425 | + package.name == 'gir1.2-gudev-1.0' |
426 | + package.name == 'udisks' or package.name == 'udisks2' |
427 | depends: usb3/insert |
428 | user: root |
429 | command: removable_storage_test -s 268400000 -m 500000000 -p 7 usb |
430 | @@ -151,6 +195,11 @@ |
431 | |
432 | plugin: shell |
433 | name: usb/storage-preinserted |
434 | +requires: |
435 | + package.name == 'python3-dbus' |
436 | + package.name == 'python3-gi' |
437 | + package.name == 'gir1.2-gudev-1.0' |
438 | + package.name == 'udisks' or package.name == 'udisks2' |
439 | user: root |
440 | command: removable_storage_test -l usb && removable_storage_test -s 268400000 usb |
441 | _description: |
442 | @@ -163,6 +212,10 @@ |
443 | user: root |
444 | requires: |
445 | usb.usb3 == 'supported' |
446 | + package.name == 'python3-dbus' |
447 | + package.name == 'python3-gi' |
448 | + package.name == 'gir1.2-gudev-1.0' |
449 | + package.name == 'udisks' or package.name == 'udisks2' |
450 | command: removable_storage_test -l usb && removable_storage_test -s 268400000 -m 500000000 -p 7 usb |
451 | _description: |
452 | This is an automated version of usb3/storage-automated and assumes that the |
453 | @@ -194,6 +247,8 @@ |
454 | name: usb/usb3_read_performance_`ls /sys$path/block` |
455 | requires: |
456 | device.path == "$path" |
457 | + package.name == "udev" |
458 | + package.name == "hdparm" |
459 | block_device.`ls /sys$path/block`_state == 'removable' and block_device.`ls /sys$path/block`_usb3 == 'supported' |
460 | description: USB3 read performance test for $product |
461 | user: root |
462 | |
463 | === modified file 'jobs/user_apps.txt.in' |
464 | --- jobs/user_apps.txt.in 2012-07-25 19:08:46 +0000 |
465 | +++ jobs/user_apps.txt.in 2013-04-04 16:49:24 +0000 |
466 | @@ -66,6 +66,7 @@ |
467 | plugin: manual |
468 | name: software/nautilus_file_create |
469 | depends: software/nautilus_folder_create |
470 | +requires: environment.HOME != '' |
471 | command: nautilus $HOME/"Test Folder" |
472 | _description: |
473 | PURPOSE: |
474 | @@ -81,6 +82,7 @@ |
475 | plugin: manual |
476 | name: software/nautilus_file_copy |
477 | depends: software/nautilus_file_create |
478 | +requires: environment.HOME != '' |
479 | command: nautilus $HOME/"Test Folder" |
480 | _description: |
481 | PURPOSE: |
482 | @@ -98,6 +100,7 @@ |
483 | plugin: manual |
484 | name: software/nautilus_file_move |
485 | depends: software/nautilus_file_copy |
486 | +requires: environment.HOME != '' |
487 | command: nautilus $HOME/"Test Folder" |
488 | _description: |
489 | PURPOSE: |
490 | @@ -114,6 +117,7 @@ |
491 | plugin: manual |
492 | name: software/nautilus_file_delete |
493 | depends: software/nautilus_file_create |
494 | +requires: environment.HOME != '' |
495 | command: nautilus $HOME/"Test Folder" |
496 | _description: |
497 | PURPOSE: |
498 | |
499 | === modified file 'jobs/wireless.txt.in' |
500 | --- jobs/wireless.txt.in 2012-10-16 20:45:22 +0000 |
501 | +++ jobs/wireless.txt.in 2013-04-04 16:49:24 +0000 |
502 | @@ -38,6 +38,8 @@ |
503 | requires: |
504 | device.category == 'WIRELESS' |
505 | environment.ROUTERS == 'multiple' |
506 | + environment.WPA_BG_SSID != '' |
507 | + environment.WPA_BG_PSK != '' |
508 | user: root |
509 | environ: WPA_BG_SSID WPA_BG_PSK |
510 | command: trap "nmcli con delete id $WPA_BG_SSID" EXIT; create_connection $WPA_BG_SSID --security=wpa --key=$WPA_BG_PSK && internet_test --interface=`nmcli dev status | awk '/802-11-wireless/ {print $1}'` |
511 | @@ -50,6 +52,7 @@ |
512 | requires: |
513 | device.category == 'WIRELESS' |
514 | environment.ROUTERS == 'multiple' |
515 | + environment.OPEN_BG_SSID != '' |
516 | user: root |
517 | environ: OPEN_BG_SSID |
518 | command: trap "nmcli con delete id $OPEN_BG_SSID" EXIT; create_connection $OPEN_BG_SSID && internet_test --interface=`nmcli dev status | awk '/802-11-wireless/ {print $1}'` |
519 | @@ -62,6 +65,8 @@ |
520 | requires: |
521 | device.category == 'WIRELESS' |
522 | environment.ROUTERS == 'multiple' |
523 | + environment.WPA_N_SSID != '' |
524 | + environment.WPA_N_PSK != '' |
525 | user: root |
526 | environ: WPA_N_SSID WPA_N_PSK |
527 | command: trap "nmcli con delete id $WPA_N_SSID" EXIT; create_connection $WPA_N_SSID --security=wpa --key=$WPA_N_PSK && internet_test --interface=`nmcli dev status | awk '/802-11-wireless/ {print $1}'` |
528 | @@ -74,6 +79,7 @@ |
529 | requires: |
530 | device.category == 'WIRELESS' |
531 | environment.ROUTERS == 'multiple' |
532 | + environment.OPEN_N_SSID != '' |
533 | user: root |
534 | environ: OPEN_N_SSID |
535 | command: trap "nmcli con delete id $OPEN_N_SSID" EXIT; create_connection $OPEN_N_SSID && internet_test --interface=`nmcli dev status | awk '/802-11-wireless/ {print $1}'` |
536 | @@ -86,6 +92,8 @@ |
537 | requires: |
538 | device.category == 'WIRELESS' |
539 | environment.ROUTERS == 'single' |
540 | + environment.ROUTER_SSID != '' |
541 | + environment.ROUTER_PSK != '' |
542 | user: root |
543 | environ: ROUTER_SSID ROUTER_PSK |
544 | command: trap "nmcli con delete id $ROUTER_SSID" EXIT; create_connection $ROUTER_SSID --security=wpa --key=$ROUTER_PSK && internet_test --interface=`nmcli dev status | awk '/802-11-wireless/ {print $1}'` |
545 | @@ -107,6 +115,7 @@ |
546 | requires: |
547 | device.category == 'WIRELESS' |
548 | environment.ROUTERS == 'single' |
549 | + environment.ROUTER_SSID != '' |
550 | user: root |
551 | environ: ROUTER_SSID |
552 | command: trap "nmcli con delete id $ROUTER_SSID" EXIT; create_connection $ROUTER_SSID && internet_test --interface=`nmcli dev status | awk '/802-11-wireless/ {print $1}'` |
553 | @@ -128,6 +137,8 @@ |
554 | requires: |
555 | device.category == 'WIRELESS' |
556 | environment.ROUTERS == 'single' |
557 | + environment.ROUTER_SSID != '' |
558 | + environment.ROUTER_PSK != '' |
559 | user: root |
560 | environ: ROUTER_SSID ROUTER_PSK |
561 | command: trap "nmcli con delete id $ROUTER_SSID" EXIT; create_connection $ROUTER_SSID --security=wpa --key=$ROUTER_PSK && internet_test --interface=`nmcli dev status | awk '/802-11-wireless/ {print $1}'` |
562 | @@ -149,6 +160,7 @@ |
563 | requires: |
564 | device.category == 'WIRELESS' |
565 | environment.ROUTERS == 'single' |
566 | + environment.ROUTER_SSID != '' |
567 | user: root |
568 | environ: ROUTER_SSID |
569 | command: trap "nmcli con delete id $ROUTER_SSID" EXIT; create_connection $ROUTER_SSID && internet_test --interface=`nmcli dev status | awk '/802-11-wireless/ {print $1}'` |
570 | @@ -170,6 +182,9 @@ |
571 | requires: |
572 | package.name == 'iperf' |
573 | device.category == 'WIRELESS' |
574 | + environment.WPA_BG_SSID != '' |
575 | + environment.WPA_BG_PSK != '' |
576 | + environment.SERVER_IPERF != '' |
577 | user: root |
578 | environ: WPA_BG_SSID WPA_BG_PSK SERVER_IPERF |
579 | command: trap "nmcli con delete id $WPA_BG_SSID" EXIT; create_connection $WPA_BG_SSID --security=wpa --key=$WPA_BG_PSK && iperf -c $SERVER_IPERF -t 300 -i 30 |
580 | @@ -181,6 +196,9 @@ |
581 | requires: |
582 | package.name == 'iperf' |
583 | device.category == 'WIRELESS' |
584 | + environment.WPA_BG_SSID != '' |
585 | + environment.WPA_BG_PSK != '' |
586 | + environment.SERVER_IPERF != '' |
587 | user: root |
588 | environ: WPA_BG_SSID WPA_BG_PSK SERVER_IPERF |
589 | command: trap "nmcli con delete id $WPA_BG_SSID" EXIT; create_connection $WPA_BG_SSID --security=wpa --key=$WPA_BG_PSK && iperf -c $SERVER_IPERF -t 300 -i 30 -u -b 100m -p 5050 |
590 | @@ -189,7 +207,9 @@ |
591 | |
592 | plugin: shell |
593 | name: wireless/wireless_connection_open_a |
594 | -requires: device.category == 'WIRELESS' |
595 | +requires: |
596 | + device.category == 'WIRELESS' |
597 | + environment.OPEN_A_SSID != '' |
598 | user: root |
599 | environ: OPEN_A_SSID |
600 | command: trap "nmcli con delete id $OPEN_A_SSID" EXIT; create_connection $OPEN_A_SSID && internet_test --interface=`nmcli dev status | awk '/802-11-wireless/ {print $1}'` |
601 | @@ -200,7 +220,9 @@ |
602 | |
603 | plugin: shell |
604 | name: wireless/wireless_connection_open_b |
605 | -requires: device.category == 'WIRELESS' |
606 | +requires: |
607 | + device.category == 'WIRELESS' |
608 | + environment.OPEN_B_SSID != '' |
609 | user: root |
610 | environ: OPEN_B_SSID |
611 | command: trap "nmcli con delete id $OPEN_B_SSID" EXIT; create_connection $OPEN_B_SSID && internet_test --interface=`nmcli dev status | awk '/802-11-wireless/ {print $1}'` |
612 | @@ -211,7 +233,9 @@ |
613 | |
614 | plugin: shell |
615 | name: wireless/wireless_connection_open_g |
616 | -requires: device.category == 'WIRELESS' |
617 | +requires: |
618 | + device.category == 'WIRELESS' |
619 | + environment.OPEN_G_SSID != '' |
620 | user: root |
621 | environ: OPEN_G_SSID |
622 | command: trap "nmcli con delete id $OPEN_G_SSID" EXIT; create_connection $OPEN_G_SSID && internet_test --interface=`nmcli dev status | awk '/802-11-wireless/ {print $1}'` |
623 | |
624 | === modified file 'plainbox/MANIFEST.in' |
625 | --- plainbox/MANIFEST.in 2013-03-15 15:49:18 +0000 |
626 | +++ plainbox/MANIFEST.in 2013-04-04 16:49:24 +0000 |
627 | @@ -1,7 +1,7 @@ |
628 | include README.md |
629 | include COPYING |
630 | include mk-interesting-graphs.sh |
631 | -recursive-include plainbox/test-data/integration-tests *.json |
632 | +recursive-include plainbox/test-data/ *.json *.xml *.txt |
633 | recursive-include docs *.rst |
634 | include docs/conf.py |
635 | include plainbox/data/report/hardware-1_0.rng |
636 | |
637 | === modified file 'plainbox/daily-package-testing/Vagrantfile' |
638 | --- plainbox/daily-package-testing/Vagrantfile 2013-03-20 14:34:45 +0000 |
639 | +++ plainbox/daily-package-testing/Vagrantfile 2013-04-04 16:49:24 +0000 |
640 | @@ -45,4 +45,6 @@ |
641 | config.vm.provision :shell, :inline => "apt-get update" |
642 | # Install plainbox |
643 | config.vm.provision :shell, :inline => "apt-get install --yes plainbox" |
644 | + # Install python3-mock for testing |
645 | + config.vm.provision :shell, :inline => "apt-get install --yes python3-mock" |
646 | end |
647 | |
648 | === modified file 'plainbox/daily-package-testing/test-in-vagrant.sh' |
649 | --- plainbox/daily-package-testing/test-in-vagrant.sh 2013-03-15 17:27:19 +0000 |
650 | +++ plainbox/daily-package-testing/test-in-vagrant.sh 2013-04-04 16:49:24 +0000 |
651 | @@ -32,6 +32,25 @@ |
652 | echo "[$target] stdout: $(pastebinit vagrant-logs/$target.help.log)" |
653 | echo "[$target] stderr: $(pastebinit vagrant-logs/$target.help.err)" |
654 | fi |
655 | + # Test that plainbox self-test -u works |
656 | + if vagrant ssh $target -c 'plainbox self-test -u' >vagrant-logs/$target.unit-tests.log 2>vagrant-logs/$target.unit-tests.err; then |
657 | + echo "[$target] packaged PlainBox plainbox self-test -u: pass" |
658 | + else |
659 | + outcome=1 |
660 | + echo "[$target] packaged PlainBox plainbox self-test -u: pass" |
661 | + echo "[$target] stdout: $(pastebinit vagrant-logs/$target.unit-tests.log)" |
662 | + echo "[$target] stderr: $(pastebinit vagrant-logs/$target.unit-tests.err)" |
663 | + fi |
664 | + # Test that plainbox self-test -i works |
665 | + if vagrant ssh $target -c 'sudo plainbox self-test -i' >vagrant-logs/$target.integration-tests.log 2>vagrant-logs/$target.integration-tests.err; then |
666 | + echo "[$target] packaged PlainBox plainbox self-test -i: pass" |
667 | + else |
668 | + outcome=1 |
669 | + echo "[$target] packaged PlainBox plainbox self-test -i: pass" |
670 | + echo "[$target] stdout: $(pastebinit vagrant-logs/$target.integration-tests.log)" |
671 | + echo "[$target] stderr: $(pastebinit vagrant-logs/$target.integration-tests.err)" |
672 | + fi |
673 | + # All done |
674 | case $VAGRANT_DONE_ACTION in |
675 | suspend) |
676 | # Suspend the target to conserve resources |
677 | |
678 | === modified file 'plainbox/plainbox/impl/commands/run.py' |
679 | --- plainbox/plainbox/impl/commands/run.py 2013-04-02 23:30:49 +0000 |
680 | +++ plainbox/plainbox/impl/commands/run.py 2013-04-04 16:49:24 +0000 |
681 | @@ -27,7 +27,6 @@ |
682 | """ |
683 | |
684 | from argparse import FileType |
685 | -from io import RawIOBase |
686 | from logging import getLogger |
687 | from os.path import join |
688 | import sys |
689 | @@ -35,6 +34,7 @@ |
690 | from plainbox.impl.commands import PlainBoxCommand |
691 | from plainbox.impl.commands.checkbox import CheckBoxCommandMixIn |
692 | from plainbox.impl.depmgr import DependencyDuplicateError |
693 | +from plainbox.impl.exporter import ByteStringStreamTranslator |
694 | from plainbox.impl.exporter import get_all_exporters |
695 | from plainbox.impl.result import JobResult |
696 | from plainbox.impl.runner import JobRunner |
697 | @@ -45,37 +45,6 @@ |
698 | logger = getLogger("plainbox.commands.run") |
699 | |
700 | |
701 | -class ByteStringStreamTranslator(RawIOBase): |
702 | - """ |
703 | - This is a sort of "impedance matcher" that bridges the gap between |
704 | - something that expects to write strings to a stream and a stream |
705 | - that expects to receive bytes. Instead of using, for instance, an |
706 | - intermediate in-memory IO object, this decodes on the fly and |
707 | - has the same interface as a writable stream, so it can be initialized |
708 | - with the destination string stream and then passed to something |
709 | - (usually a dump-style function) that writes bytes. |
710 | - """ |
711 | - |
712 | - def __init__(self, dest_stream, encoding): |
713 | - """ Create a stream that will take bytes, decode them into strings |
714 | - according to the specified encoding, and then write them |
715 | - as bytes into the destination stream. |
716 | - :param dest_stream: the destination string stream. |
717 | - :param encoding: Encoding with which bytes data is encoded. |
718 | - It will be decoded using the same encoding to obtain |
719 | - the string to be written. |
720 | - """ |
721 | - self.dest_stream = dest_stream |
722 | - self.encoding = encoding |
723 | - |
724 | - def write(self, data): |
725 | - """ Writes to the stream, takes bytes and decodes them per the |
726 | - object's specified encoding prior to writing. |
727 | - :param data: the chunk of data to write. |
728 | - """ |
729 | - return self.dest_stream.write(data.decode(self.encoding)) |
730 | - |
731 | - |
732 | class RunCommand(PlainBoxCommand, CheckBoxCommandMixIn): |
733 | |
734 | def invoked(self, ns): |
735 | @@ -198,8 +167,8 @@ |
736 | print("[ Results ]".center(80, '=')) |
737 | #This requires a bit more finesse, as exporters output bytes |
738 | #and stdout needs a string. |
739 | - translating_stream = ByteStringStreamTranslator(ns.output_file, |
740 | - "utf-8") |
741 | + translating_stream = ByteStringStreamTranslator( |
742 | + ns.output_file, "UTF-8") |
743 | exporter.dump(data, translating_stream) |
744 | else: |
745 | print("Saving results to {}".format(ns.output_file.name)) |
746 | |
747 | === modified file 'plainbox/plainbox/impl/commands/sru.py' |
748 | --- plainbox/plainbox/impl/commands/sru.py 2013-03-21 09:48:53 +0000 |
749 | +++ plainbox/plainbox/impl/commands/sru.py 2013-04-04 16:49:24 +0000 |
750 | @@ -29,14 +29,15 @@ |
751 | from logging import getLogger |
752 | import os |
753 | |
754 | +from plainbox.impl.applogic import get_matching_job_list |
755 | +from plainbox.impl.checkbox import CheckBox, WhiteList |
756 | from plainbox.impl.commands import PlainBoxCommand |
757 | from plainbox.impl.depmgr import DependencyDuplicateError |
758 | +from plainbox.impl.exporter import ByteStringStreamTranslator |
759 | +from plainbox.impl.exporter.xml import XMLSessionStateExporter |
760 | from plainbox.impl.result import JobResult |
761 | from plainbox.impl.runner import JobRunner |
762 | from plainbox.impl.session import SessionState |
763 | -from plainbox.impl.exporter.xml import XMLSessionStateExporter |
764 | -from plainbox.impl.checkbox import CheckBox, WhiteList |
765 | -from plainbox.impl.applogic import get_matching_job_list |
766 | |
767 | |
768 | logger = getLogger("plainbox.commands.sru") |
769 | @@ -101,7 +102,8 @@ |
770 | print("Saving results to {0}".format(self.ns.fallback_file)) |
771 | data = self.exporter.get_session_data_subset(self.session) |
772 | with open(self.ns.fallback_file, "wt", encoding="UTF-8") as stream: |
773 | - self.exporter.dump(data, stream) |
774 | + translating_stream = ByteStringStreamTranslator(stream, "UTF-8") |
775 | + self.exporter.dump(data, translating_stream) |
776 | |
777 | def _run_all_jobs(self): |
778 | again = True |
779 | |
780 | === modified file 'plainbox/plainbox/impl/commands/test_run.py' |
781 | --- plainbox/plainbox/impl/commands/test_run.py 2013-04-02 23:30:49 +0000 |
782 | +++ plainbox/plainbox/impl/commands/test_run.py 2013-04-04 16:49:24 +0000 |
783 | @@ -25,20 +25,4 @@ |
784 | Test definitions for plainbox.impl.run module |
785 | """ |
786 | |
787 | -from unittest import TestCase |
788 | -from io import StringIO, BytesIO |
789 | - |
790 | -from plainbox.impl.commands.run import ByteStringStreamTranslator |
791 | - |
792 | - |
793 | -class TestRun(TestCase): |
794 | - |
795 | - def test_byte_string_translator(self): |
796 | - dest_stream = StringIO() |
797 | - source_stream = BytesIO(b'This is a bytes literal') |
798 | - encoding = 'utf-8' |
799 | - |
800 | - translator = ByteStringStreamTranslator(dest_stream, encoding) |
801 | - translator.write(source_stream.getvalue()) |
802 | - |
803 | - self.assertEqual('This is a bytes literal', dest_stream.getvalue()) |
804 | +# NOTE: this file is blank after some tests moved to other modules. |
805 | |
806 | === modified file 'plainbox/plainbox/impl/depmgr.py' |
807 | --- plainbox/plainbox/impl/depmgr.py 2013-03-19 22:36:23 +0000 |
808 | +++ plainbox/plainbox/impl/depmgr.py 2013-04-04 16:49:24 +0000 |
809 | @@ -268,7 +268,7 @@ |
810 | if trail is None: |
811 | trail = [job] |
812 | # Visit each dependency |
813 | - for dep_type, job_name in self._get_dependency_set(job): |
814 | + for dep_type, job_name in sorted(self._get_dependency_set(job)): |
815 | logger.debug("Found dependency %s: %s", dep_type, job_name) |
816 | # Dependency is just a name, we need to resolve it |
817 | # to a job instance. This can fail (missing dependencies) |
818 | |
819 | === modified file 'plainbox/plainbox/impl/exporter/__init__.py' |
820 | --- plainbox/plainbox/impl/exporter/__init__.py 2013-03-18 13:46:10 +0000 |
821 | +++ plainbox/plainbox/impl/exporter/__init__.py 2013-04-04 16:49:24 +0000 |
822 | @@ -28,6 +28,7 @@ |
823 | |
824 | from abc import ABCMeta, abstractmethod |
825 | from collections import OrderedDict |
826 | +from io import RawIOBase |
827 | from logging import getLogger |
828 | import base64 |
829 | |
830 | @@ -226,6 +227,42 @@ |
831 | # TODO: Add a way for the stream to be binary as well. |
832 | |
833 | |
834 | +class ByteStringStreamTranslator(RawIOBase): |
835 | + """ |
836 | + This is a sort of "impedance matcher" that bridges the gap between |
837 | + something that expects to write strings to a stream and a stream |
838 | + that expects to receive bytes. Instead of using, for instance, an |
839 | + intermediate in-memory IO object, this decodes on the fly and |
840 | + has the same interface as a writable stream, so it can be initialized |
841 | + with the destination string stream and then passed to something |
842 | + (usually a dump-style function) that writes bytes. |
843 | + """ |
844 | + |
845 | + def __init__(self, dest_stream, encoding): |
846 | + """ |
847 | + Create a stream that will take bytes, decode them into strings |
848 | + according to the specified encoding, and then write them |
849 | + as bytes into the destination stream. |
850 | + |
851 | + :param dest_stream: |
852 | + the destination string stream. |
853 | + |
854 | + :param encoding: |
855 | + Encoding with which bytes data is encoded. It will be decoded |
856 | + using the same encoding to obtain the string to be written. |
857 | + |
858 | + """ |
859 | + self.dest_stream = dest_stream |
860 | + self.encoding = encoding |
861 | + |
862 | + def write(self, data): |
863 | + """ Writes to the stream, takes bytes and decodes them per the |
864 | + object's specified encoding prior to writing. |
865 | + :param data: the chunk of data to write. |
866 | + """ |
867 | + return self.dest_stream.write(data.decode(self.encoding)) |
868 | + |
869 | + |
870 | def get_all_exporters(): |
871 | """ |
872 | Discover and load all exporter classes. |
873 | |
874 | === modified file 'plainbox/plainbox/impl/exporter/json.py' |
875 | --- plainbox/plainbox/impl/exporter/json.py 2013-04-02 23:30:48 +0000 |
876 | +++ plainbox/plainbox/impl/exporter/json.py 2013-04-04 16:49:24 +0000 |
877 | @@ -37,15 +37,19 @@ |
878 | |
879 | OPTION_MACHINE_JSON = 'machine-json' |
880 | |
881 | - SUPPORTED_OPTION_LIST = (SessionStateExporterBase.SUPPORTED_OPTION_LIST + |
882 | - (OPTION_MACHINE_JSON,)) |
883 | + SUPPORTED_OPTION_LIST = ( |
884 | + SessionStateExporterBase.SUPPORTED_OPTION_LIST + ( |
885 | + OPTION_MACHINE_JSON,)) |
886 | |
887 | def dump(self, data, stream): |
888 | if self.OPTION_MACHINE_JSON in self._option_list: |
889 | - encoder = json.JSONEncoder(ensure_ascii=False, |
890 | - indent=None, separators=(',', ':')) |
891 | + encoder = json.JSONEncoder( |
892 | + ensure_ascii=False, |
893 | + indent=None, |
894 | + separators=(',', ':')) |
895 | else: |
896 | - encoder = json.JSONEncoder(ensure_ascii=False, indent=4) |
897 | - |
898 | + encoder = json.JSONEncoder( |
899 | + ensure_ascii=False, |
900 | + indent=4) |
901 | for chunk in encoder.iterencode(data): |
902 | - stream.write(chunk.encode('utf-8')) |
903 | + stream.write(chunk.encode('UTF-8')) |
904 | |
905 | === modified file 'plainbox/plainbox/impl/exporter/rfc822.py' |
906 | --- plainbox/plainbox/impl/exporter/rfc822.py 2013-04-02 23:30:48 +0000 |
907 | +++ plainbox/plainbox/impl/exporter/rfc822.py 2013-04-04 16:49:24 +0000 |
908 | @@ -41,8 +41,8 @@ |
909 | def dump(self, data, stream): |
910 | entry = OrderedDict() |
911 | string_stream = StringIO() |
912 | - for job_name, job_data in data['result_map'].items(): |
913 | + for job_name, job_data in sorted(data['result_map'].items()): |
914 | entry['name'] = job_name |
915 | entry.update(job_data) |
916 | dump_rfc822_records(entry, string_stream) |
917 | - stream.write(string_stream.getvalue().encode('utf-8')) |
918 | + stream.write(string_stream.getvalue().encode('UTF-8')) |
919 | |
920 | === modified file 'plainbox/plainbox/impl/exporter/test_init.py' |
921 | --- plainbox/plainbox/impl/exporter/test_init.py 2013-03-03 16:40:22 +0000 |
922 | +++ plainbox/plainbox/impl/exporter/test_init.py 2013-04-04 16:49:24 +0000 |
923 | @@ -1,8 +1,9 @@ |
924 | # This file is part of Checkbox. |
925 | # |
926 | -# Copyright 2012 Canonical Ltd. |
927 | +# Copyright 2012, 2013 Canonical Ltd. |
928 | # Written by: |
929 | # Zygmunt Krynicki <zygmunt.krynicki@canonical.com> |
930 | +# Daniel Manrique <roadmr@ubuntu.com> |
931 | # |
932 | # Checkbox is free software: you can redistribute it and/or modify |
933 | # it under the terms of the GNU General Public License as published by |
934 | @@ -24,14 +25,16 @@ |
935 | Test definitions for plainbox.impl.exporter module |
936 | """ |
937 | |
938 | +from io import StringIO, BytesIO |
939 | from tempfile import TemporaryDirectory |
940 | from unittest import TestCase |
941 | |
942 | +from plainbox.impl.exporter import ByteStringStreamTranslator |
943 | from plainbox.impl.exporter import SessionStateExporterBase |
944 | from plainbox.impl.exporter import classproperty |
945 | -from plainbox.impl.session import SessionState |
946 | from plainbox.impl.job import JobDefinition |
947 | from plainbox.impl.result import JobResult, IOLogRecord |
948 | +from plainbox.impl.session import SessionState |
949 | from plainbox.impl.testing_utils import make_io_log, make_job, make_job_result |
950 | |
951 | |
952 | @@ -203,3 +206,16 @@ |
953 | (0, 'stdout', 'Zm9vCg=='), |
954 | (1, 'stderr', 'YmFyCg=='), |
955 | (2, 'stdout', 'cXV4eAo=')]) |
956 | + |
957 | + |
958 | +class ByteStringStreamTranslatorTests(TestCase): |
959 | + |
960 | + def test_smoke(self): |
961 | + dest_stream = StringIO() |
962 | + source_stream = BytesIO(b'This is a bytes literal') |
963 | + encoding = 'utf-8' |
964 | + |
965 | + translator = ByteStringStreamTranslator(dest_stream, encoding) |
966 | + translator.write(source_stream.getvalue()) |
967 | + |
968 | + self.assertEqual('This is a bytes literal', dest_stream.getvalue()) |
969 | |
970 | === modified file 'plainbox/plainbox/impl/exporter/test_json.py' |
971 | --- plainbox/plainbox/impl/exporter/test_json.py 2013-04-02 23:30:48 +0000 |
972 | +++ plainbox/plainbox/impl/exporter/test_json.py 2013-04-04 16:49:24 +0000 |
973 | @@ -44,10 +44,12 @@ |
974 | data = {'foo': 'bar'} |
975 | stream = BytesIO() |
976 | exporter.dump(data, stream) |
977 | - self.assertEqual(stream.getvalue(), ( |
978 | + expected_bytes = ( |
979 | '{\n' |
980 | ' "foo": "bar"\n' |
981 | - '}').encode('utf-8')) |
982 | + '}' |
983 | + ).encode('UTF-8') |
984 | + self.assertEqual(stream.getvalue(), expected_bytes) |
985 | |
986 | def test_machine_dump(self): |
987 | exporter = self.exporter_cls(option_list=[ |
988 | @@ -55,4 +57,7 @@ |
989 | data = {'foo': 'bar'} |
990 | stream = BytesIO() |
991 | exporter.dump(data, stream) |
992 | - self.assertEqual(stream.getvalue(), '{"foo":"bar"}'.encode('utf-8')) |
993 | + expected_bytes = ( |
994 | + '{"foo":"bar"}' |
995 | + ).encode('UTF-8') |
996 | + self.assertEqual(stream.getvalue(), expected_bytes) |
997 | |
998 | === modified file 'plainbox/plainbox/impl/exporter/test_rfc822.py' |
999 | --- plainbox/plainbox/impl/exporter/test_rfc822.py 2013-04-02 23:30:48 +0000 |
1000 | +++ plainbox/plainbox/impl/exporter/test_rfc822.py 2013-04-04 16:49:24 +0000 |
1001 | @@ -39,5 +39,9 @@ |
1002 | data = {'result_map': {'job_name': {'outcome': 'fail'}}} |
1003 | stream = BytesIO() |
1004 | exporter.dump(data, stream) |
1005 | - expected_bytes = "name: job_name\noutcome: fail\n\n".encode('utf-8') |
1006 | + expected_bytes = ( |
1007 | + "name: job_name\n" |
1008 | + "outcome: fail\n" |
1009 | + "\n" |
1010 | + ).encode('UTF-8') |
1011 | self.assertEqual(stream.getvalue(), expected_bytes) |
1012 | |
1013 | === modified file 'plainbox/plainbox/impl/exporter/test_text.py' |
1014 | --- plainbox/plainbox/impl/exporter/test_text.py 2013-04-02 23:30:48 +0000 |
1015 | +++ plainbox/plainbox/impl/exporter/test_text.py 2013-04-04 16:49:24 +0000 |
1016 | @@ -39,5 +39,5 @@ |
1017 | data = {'result_map': {'job_name': {'outcome': 'fail'}}} |
1018 | stream = BytesIO() |
1019 | exporter.dump(data, stream) |
1020 | - expected_bytes = "job_name: fail".encode('utf-8') |
1021 | + expected_bytes = "job_name: fail\n".encode('utf-8') |
1022 | self.assertEqual(stream.getvalue(), expected_bytes) |
1023 | |
1024 | === modified file 'plainbox/plainbox/impl/exporter/text.py' |
1025 | --- plainbox/plainbox/impl/exporter/text.py 2013-04-02 23:30:48 +0000 |
1026 | +++ plainbox/plainbox/impl/exporter/text.py 2013-04-04 16:49:24 +0000 |
1027 | @@ -36,6 +36,6 @@ |
1028 | """ |
1029 | |
1030 | def dump(self, data, stream): |
1031 | - for job_name, job_data in data['result_map'].items(): |
1032 | - stream.write("{}: {}".format( |
1033 | - job_name, job_data['outcome']).encode('utf-8')) |
1034 | + for job_name, job_data in sorted(data['result_map'].items()): |
1035 | + stream.write("{}: {}\n".format( |
1036 | + job_name, job_data['outcome']).encode('utf-8')) |
1037 | |
1038 | === modified file 'plainbox/plainbox/impl/integration_tests.py' |
1039 | --- plainbox/plainbox/impl/integration_tests.py 2013-03-15 15:49:18 +0000 |
1040 | +++ plainbox/plainbox/impl/integration_tests.py 2013-04-04 16:49:24 +0000 |
1041 | @@ -27,6 +27,7 @@ |
1042 | """ |
1043 | |
1044 | from tempfile import TemporaryDirectory |
1045 | +from unittest import TestCase |
1046 | import json |
1047 | import os |
1048 | import shutil |
1049 | @@ -40,11 +41,15 @@ |
1050 | from plainbox.testing_utils.testcases import TestCaseWithParameters |
1051 | |
1052 | |
1053 | -class IntegrationTests(TestCaseWithParameters): |
1054 | - |
1055 | - parameter_names = ('job_name',) |
1056 | +class XDGSandBoxMixIn: |
1057 | + """ |
1058 | + Mix-In for TestCase-like classes that defines setUp() and tearDown() so |
1059 | + that tests are executed with custom, isolated XDG_CACHE_HOME that is |
1060 | + removed once testing is complete. |
1061 | + """ |
1062 | |
1063 | def setUp(self): |
1064 | + super(XDGSandBoxMixIn, self).setUp() |
1065 | # session data are kept in XDG_CACHE_HOME/plainbox/.session |
1066 | # To avoid resuming a real session, we have to select a temporary |
1067 | # location instead |
1068 | @@ -52,8 +57,27 @@ |
1069 | self._env = os.environ |
1070 | os.environ['XDG_CACHE_HOME'] = self._sandbox |
1071 | |
1072 | + def tearDown(self): |
1073 | + shutil.rmtree(self._sandbox) |
1074 | + os.environ = self._env |
1075 | + super(XDGSandBoxMixIn, self).tearDown() |
1076 | + |
1077 | + |
1078 | +class CheckBoxJobResponse(XDGSandBoxMixIn, TestCaseWithParameters): |
1079 | + """ |
1080 | + Set of tests that check actual responses of checkbox jobs against baseline |
1081 | + values. The jobs are started with 'plainbox run' so this tests a lot of |
1082 | + infrastructure that is normally skipped. |
1083 | + |
1084 | + The tests are parametrized by job name, jobs are discovered by looking for |
1085 | + expected results in plainbox/test-data/integration-tests directory. |
1086 | + """ |
1087 | + |
1088 | + parameter_names = ('job_name',) |
1089 | + |
1090 | @classmethod |
1091 | - def _gen_job_name_values(cls, package='plainbox', root='test-data/integration-tests/'): |
1092 | + def _gen_job_name_values(cls, package='plainbox', |
1093 | + root='test-data/integration-tests/'): |
1094 | """ |
1095 | Discover job names for jobs that we have reference data for |
1096 | |
1097 | @@ -66,7 +90,8 @@ |
1098 | for item in cls._gen_job_name_values(package, resource_name): |
1099 | yield item |
1100 | elif resource_name.endswith('.json'): |
1101 | - yield resource_name[len('test-data/integration-tests/'):-len('.json')] |
1102 | + yield resource_name[ |
1103 | + len('test-data/integration-tests/'):-len('.json')] |
1104 | |
1105 | @classmethod |
1106 | def get_parameter_values(cls): |
1107 | @@ -101,12 +126,37 @@ |
1108 | # [ At this time TestIO and TemporaryDirectory are gone ] |
1109 | # Load the expected results and keep them in memory |
1110 | reference_path = resource_filename( |
1111 | - "plainbox", "test-data/integration-tests/{}.json".format(self.parameters.job_name)) |
1112 | + "plainbox", "test-data/integration-tests/{}.json".format( |
1113 | + self.parameters.job_name)) |
1114 | with open(reference_path, encoding='UTF-8') as stream: |
1115 | expected_result = json.load(stream) |
1116 | # Check that results match expected values |
1117 | self.assertEqual(actual_result, expected_result) |
1118 | |
1119 | - def tearDown(self): |
1120 | - shutil.rmtree(self._sandbox) |
1121 | - os.environ = self._env |
1122 | + |
1123 | +class CheckBoxSRUTests(XDGSandBoxMixIn, TestCase): |
1124 | + |
1125 | + def test_smoke(self): |
1126 | + # Create a scratch directory so that we can save results there. The |
1127 | + # shared directory is also used for running tests as some test jobs |
1128 | + # leave junk around the current directory. |
1129 | + with TemporaryDirectory() as scratch_dir: |
1130 | + # Redirect all standard IO so that the test is silent. |
1131 | + # Run the script, having relocated to the scratch directory |
1132 | + # Capture SystemExit that is always raised by main() so that |
1133 | + # we can observe the return code as well. |
1134 | + with TestIO(combined=True) as test_io, TestCwd(scratch_dir),\ |
1135 | + self.assertRaises(SystemExit) as call: |
1136 | + main(['sru', '0123456789ABCDE', '0123456789ABCDE.xml', |
1137 | + # Use the discard port to send data to nowhere in |
1138 | + # particular |
1139 | + '--destination=http://127.0.0.1:9/']) |
1140 | + # Check the return code for correctness |
1141 | + self.assertEqual(call.exception.args, (0,)) |
1142 | + # Check that the output is the same as reference baseline |
1143 | + reference_path = resource_filename( |
1144 | + "plainbox", "test-data/sru-virtualbox-precise.txt") |
1145 | + with open(reference_path, mode="rt", encoding='UTF-8') as stream: |
1146 | + expected_output = stream.read() |
1147 | + self.maxDiff = None |
1148 | + self.assertEqual(test_io.combined, expected_output) |
1149 | |
1150 | === modified file 'plainbox/plainbox/impl/session.py' |
1151 | --- plainbox/plainbox/impl/session.py 2013-04-03 12:05:43 +0000 |
1152 | +++ plainbox/plainbox/impl/session.py 2013-04-04 16:49:24 +0000 |
1153 | @@ -815,7 +815,7 @@ |
1154 | related_expression=exc.expression) |
1155 | job_state.readiness_inhibitor_list.append(inhibitor) |
1156 | # Check if all job dependencies ran successfully |
1157 | - for dep_name in job.get_direct_dependencies(): |
1158 | + for dep_name in sorted(job.get_direct_dependencies()): |
1159 | dep_job_state = self._job_state_map[dep_name] |
1160 | # If the dependency did not have a chance to run yet add the |
1161 | # PENDING_DEP inhibitor. |
1162 | |
1163 | === added file 'plainbox/plainbox/test-data/sru-virtualbox-precise.txt' |
1164 | --- plainbox/plainbox/test-data/sru-virtualbox-precise.txt 1970-01-01 00:00:00 +0000 |
1165 | +++ plainbox/plainbox/test-data/sru-virtualbox-precise.txt 2013-04-04 16:49:24 +0000 |
1166 | @@ -0,0 +1,171 @@ |
1167 | +- package: pass |
1168 | +- device: pass |
1169 | +- codecs_attachment: not-supported |
1170 | + * resource expression "device.driver == 'HDA Intel'" evaluates to false |
1171 | +- cpuinfo_attachment: pass |
1172 | +- dmesg_attachment: pass |
1173 | +- dmi_attachment: pass |
1174 | +- dmidecode_attachment: pass |
1175 | +- efi_attachment: pass |
1176 | +- lspci_attachment: pass |
1177 | +- meminfo_attachment: pass |
1178 | +- modprobe_attachment: pass |
1179 | +- modules_attachment: pass |
1180 | +- sysctl_attachment: pass |
1181 | +- sysfs_attachment: pass |
1182 | +- udev_attachment: pass |
1183 | +- lsmod_attachment: pass |
1184 | +- acpi_sleep_attachment: pass |
1185 | +- __audio__: pass |
1186 | +- __bluetooth__: pass |
1187 | +- __camera__: pass |
1188 | +- __cpu__: pass |
1189 | +- __disk__: pass |
1190 | +- __graphics__: pass |
1191 | +- __info__: pass |
1192 | +- __install__: pass |
1193 | +- __mediacard__: pass |
1194 | +- __memory__: pass |
1195 | +- __networking__: pass |
1196 | +- __power-management__: pass |
1197 | +- __suspend__: pass |
1198 | +- __usb__: pass |
1199 | +- __wireless__: pass |
1200 | +- power-management/fwts_wakealarm: pass |
1201 | +- power-management/fwts_wakealarm-log-attach: pass |
1202 | +- power-management/rtc: pass |
1203 | +- power-management/tickless_idle: pass |
1204 | +- cpu/scaling_test: pass |
1205 | +- cpu/scaling_test-log-attach: pass |
1206 | +- cpu/offlining_test: pass |
1207 | +- cpuinfo: pass |
1208 | +- cpu/topology: not-supported |
1209 | + * resource expression "int(cpuinfo.count) > 1 and (cpuinfo.platform == 'i386' or cpuinfo.platform == 'x86_64')" evaluates to false |
1210 | +- networking/detect: pass |
1211 | +- suspend/network_before_suspend: pass |
1212 | +- suspend/audio_before_suspend: not-supported |
1213 | + * resource expression "device.category == 'AUDIO'" evaluates to false |
1214 | +- suspend/cpu_before_suspend: pass |
1215 | +- suspend/memory_before_suspend: pass |
1216 | +- environment: pass |
1217 | +- suspend/bluetooth_obex_send_before_suspend: not-supported |
1218 | + * resource expression "package.name == 'bluez'" evaluates to false |
1219 | +- suspend/bluetooth_obex_browse_before_suspend: not-supported |
1220 | + * resource expression "package.name == 'bluez'" evaluates to false |
1221 | +- suspend/bluetooth_obex_get_before_suspend: not-supported |
1222 | + * resource expression "package.name == 'bluez'" evaluates to false |
1223 | +- sleep: pass |
1224 | +- suspend/suspend_advanced_auto: not-supported |
1225 | + * resource expression "sleep.mem == 'supported'" evaluates to false |
1226 | +- suspend/suspend_advanced: not-supported |
1227 | + * resource expression "sleep.mem == 'supported'" evaluates to false |
1228 | +- suspend/audio_after_suspend: not-supported |
1229 | + * resource expression "device.category == 'AUDIO'" evaluates to false |
1230 | + * required dependency 'suspend/audio_before_suspend' has failed |
1231 | + * required dependency 'suspend/suspend_advanced' has failed |
1232 | +- suspend/cpu_after_suspend_auto: not-supported |
1233 | + * required dependency 'suspend/suspend_advanced_auto' has failed |
1234 | +- suspend/memory_after_suspend_auto: not-supported |
1235 | + * required dependency 'suspend/suspend_advanced_auto' has failed |
1236 | +- suspend/wireless_connection_after_suspend_wpa_bg_auto: not-supported |
1237 | + * resource expression "device.category == 'WIRELESS'" evaluates to false |
1238 | + * required dependency 'suspend/suspend_advanced_auto' has failed |
1239 | +- suspend/wireless_connection_after_suspend_open_bg_auto: not-supported |
1240 | + * resource expression "device.category == 'WIRELESS'" evaluates to false |
1241 | + * required dependency 'suspend/suspend_advanced_auto' has failed |
1242 | +- suspend/wireless_connection_after_suspend_wpa_n_auto: not-supported |
1243 | + * resource expression "device.category == 'WIRELESS'" evaluates to false |
1244 | + * required dependency 'suspend/suspend_advanced_auto' has failed |
1245 | +- suspend/wireless_connection_after_suspend_open_n_auto: not-supported |
1246 | + * resource expression "device.category == 'WIRELESS'" evaluates to false |
1247 | + * required dependency 'suspend/suspend_advanced_auto' has failed |
1248 | +- suspend/bluetooth_obex_send_after_suspend_auto: not-supported |
1249 | + * resource expression "package.name == 'bluez'" evaluates to false |
1250 | + * required dependency 'suspend/suspend_advanced_auto' has failed |
1251 | +- suspend/bluetooth_obex_browse_after_suspend_auto: not-supported |
1252 | + * resource expression "package.name == 'bluez'" evaluates to false |
1253 | + * required dependency 'suspend/suspend_advanced_auto' has failed |
1254 | +- suspend/bluetooth_obex_get_after_suspend_auto: not-supported |
1255 | + * resource expression "package.name == 'bluez'" evaluates to false |
1256 | + * required dependency 'suspend/suspend_advanced_auto' has failed |
1257 | +- suspend/record_playback_after_suspend: not-supported |
1258 | + * resource expression "device.category == 'AUDIO'" evaluates to false |
1259 | + * required dependency 'suspend/suspend_advanced' has failed |
1260 | +- suspend/screenshot_after_suspend: not-supported |
1261 | + * resource expression "package.name == 'fswebcam'" evaluates to false |
1262 | + * required dependency 'suspend/suspend_advanced_auto' has failed |
1263 | +- screenshot_after_suspend.jpg: not-supported |
1264 | + * required dependency 'suspend/screenshot_after_suspend' has failed |
1265 | +- suspend/gpu_lockup_after_suspend: not-supported |
1266 | + * resource expression "package.name == 'wmctrl'" evaluates to false |
1267 | + * required dependency 'suspend/suspend_advanced_auto' has failed |
1268 | +- suspend/wifi_resume_time: not-supported |
1269 | + * resource expression "device.category == 'WIRELESS'" evaluates to false |
1270 | + * required dependency 'suspend/suspend_advanced' has failed |
1271 | +- suspend/network_resume_time: not-supported |
1272 | + * required dependency 'suspend/suspend_advanced' has failed |
1273 | +- bluetooth/detect-output: not-supported |
1274 | + * resource expression "package.name == 'bluez'" evaluates to false |
1275 | +- memory/info: fail |
1276 | +- memory/check: fail |
1277 | +- disk/read_performance: pass |
1278 | +- graphics/xorg-version: not-supported |
1279 | + * resource expression 'package.name == "x11-utils"' evaluates to false |
1280 | +- graphics/xorg-process: not-supported |
1281 | + * resource expression "package.name == 'xorg'" evaluates to false |
1282 | +- graphics/xorg-failsafe: not-supported |
1283 | + * resource expression "package.name == 'xorg'" evaluates to false |
1284 | +- graphics/compiz_check: not-supported |
1285 | + * resource expression "package.name == 'nux-tools'" evaluates to false |
1286 | +- graphics/screenshot: not-supported |
1287 | + * resource expression "package.name == 'fswebcam'" evaluates to false |
1288 | +- screenshot.jpg: not-supported |
1289 | + * required dependency 'graphics/screenshot' has failed |
1290 | +- graphics/screenshot_fullscreen_video: not-supported |
1291 | + * resource expression "package.name == 'fswebcam'" evaluates to false |
1292 | +- screenshot_fullscreen_video.jpg: not-supported |
1293 | + * required dependency 'graphics/screenshot_fullscreen_video' has failed |
1294 | +- camera/detect: not-supported |
1295 | + * resource expression "device.category == 'CAPTURE'" evaluates to false |
1296 | +- camera/multiple-resolution-images: not-supported |
1297 | + * resource expression "package.name == 'fswebcam' or package.name == 'gir1.2-gst-plugins-base-0.10' or package.name == 'gir1.2-gst-plugins-base-1.0'" evaluates to false |
1298 | + * required dependency 'camera/detect' has failed |
1299 | +- mediacard/sd-preinserted: not-supported |
1300 | + * resource expression "device.category == 'CARDREADER'" evaluates to false |
1301 | +- install/apt-get-gets-updates: pass |
1302 | +- audio/alsa_record_playback_automated: not-supported |
1303 | + * resource expression "package.name == 'python-gst0.10'" evaluates to false |
1304 | +- networking/internet: pass |
1305 | +- networking/ping: not-supported |
1306 | + * resource expression 'environment.CHECKBOX_SERVER != ""' evaluates to false |
1307 | +- networking/http: not-supported |
1308 | + * resource expression 'environment.TRANSFER_SERVER != ""' evaluates to false |
1309 | +- usb/detect: pass |
1310 | +- usb/storage-preinserted: not-supported |
1311 | + * resource expression "package.name == 'udisks' or package.name == 'udisks2'" evaluates to false |
1312 | +- cdimage: pass |
1313 | +- dpkg: pass |
1314 | +- gconf: not-supported |
1315 | + * resource expression 'package.name == "gconf2"' evaluates to false |
1316 | +- lsb: pass |
1317 | +- meminfo: pass |
1318 | +- module: pass |
1319 | +- dmi: pass |
1320 | +- efi: pass |
1321 | +- uname: pass |
1322 | +- block_device: pass |
1323 | +- xinput: not-supported |
1324 | + * resource expression 'package.name == "xinput"' evaluates to false |
1325 | +- wireless/wireless_scanning: not-supported |
1326 | + * resource expression "package.name == 'network-manager'" evaluates to false |
1327 | +- wireless/wireless_connection_wpa_bg: not-supported |
1328 | + * resource expression "device.category == 'WIRELESS'" evaluates to false |
1329 | +- wireless/wireless_connection_open_bg: not-supported |
1330 | + * resource expression "device.category == 'WIRELESS'" evaluates to false |
1331 | +- wireless/wireless_connection_wpa_n: not-supported |
1332 | + * resource expression "device.category == 'WIRELESS'" evaluates to false |
1333 | +- wireless/wireless_connection_open_n: not-supported |
1334 | + * resource expression "device.category == 'WIRELESS'" evaluates to false |
1335 | +- wireless/monitor_wireless_connection_udp: not-supported |
1336 | + * resource expression "package.name == 'iperf'" evaluates to false |
1337 | +Saving results to 0123456789ABCDE.xml |
1338 | |
1339 | === modified file 'scripts/network_device_info' |
1340 | --- scripts/network_device_info 2012-12-21 10:39:07 +0000 |
1341 | +++ scripts/network_device_info 2013-04-04 16:49:24 +0000 |
1342 | @@ -20,14 +20,14 @@ |
1343 | # |
1344 | # Copyright (C) 2012 Canonical, Ltd. |
1345 | |
1346 | -import os |
1347 | -import re |
1348 | +from subprocess import check_output, CalledProcessError, STDOUT |
1349 | import sys |
1350 | + |
1351 | import dbus |
1352 | -import sys |
1353 | + |
1354 | from checkbox.parsers.modinfo import ModinfoParser |
1355 | from checkbox.parsers.udevadm import UdevadmParser |
1356 | -from subprocess import check_output, CalledProcessError, STDOUT |
1357 | + |
1358 | |
1359 | # This example lists basic information about network interfaces known to NM |
1360 | devtypes = {1: "Ethernet", |
1361 | @@ -132,7 +132,7 @@ |
1362 | return None |
1363 | |
1364 | if not stream: |
1365 | - print ("Error: modinfo returned nothing", file=sys.stderr) |
1366 | + print("Error: modinfo returned nothing", file=sys.stderr) |
1367 | return None |
1368 | else: |
1369 | parser = ModinfoParser(stream) |
1370 | @@ -166,7 +166,7 @@ |
1371 | |
1372 | # Get a proxy for the base NetworkManager object |
1373 | proxy = bus.get_object("org.freedesktop.NetworkManager", |
1374 | - "/org/freedesktop/NetworkManager") |
1375 | + "/org/freedesktop/NetworkManager") |
1376 | manager = dbus.Interface(proxy, "org.freedesktop.NetworkManager") |
1377 | |
1378 | # Get all devices known to NM and print their properties |
1379 | @@ -193,11 +193,12 @@ |
1380 | two passed in lists, devices from Network Manager and devices from lspci. |
1381 | """ |
1382 | # now check that the count (by type) matches - WiFi |
1383 | - nm_type_devices = list(filter(lambda dev: dev.gettype() == devtype, |
1384 | - nm_devices)) |
1385 | + nm_type_devices = [dev for dev in nm_devices if dev.gettype() == devtype] |
1386 | udevtype = 'WIRELESS' if devtype == 'WiFi' else 'NETWORK' |
1387 | - udev_type_devices = list(filter(lambda dev: dev.category == udevtype, |
1388 | - udev_devices)) |
1389 | + udev_type_devices = [ |
1390 | + udev |
1391 | + for udev in udev_devices |
1392 | + if udev.category == udevtype] |
1393 | if len(nm_type_devices) != len(udev_type_devices): |
1394 | print("ERROR: %s devices missing: udev showed %d devices, but " |
1395 | "NetworkManager saw %d devices" % (devtype, |
So, we discussed how to arrange/split this if necessary. One thing we mentioned was having one commit for fixing each script, and one commit for each job file (*.txt.in).
In practice, I found it very easy to branch this and read each commit in turn, as they are quite small and very well separated logically. I don't think any further splitting is necessary and the whole branch achieves one purpose so this fits in well with how it's done. It already contains commits for each logical change to each script, and putting the job file fixes in only a few commits that touch many files is not as unwieldy as I thought, since the changes are logically related (i.e. adding explicit checks for environment variables to all the tests that need them).
This is just a comment since it's marked as work in progress, but this looks good in general and I'd +1 without problems once it's complete.