Merge lp:~zyga/checkbox/fix-exporter-crash into lp:checkbox

Proposed by Zygmunt Krynicki
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
Reviewer Review Type Date Requested Status
Checkbox Developers Pending
Review via email: mp+157074@code.launchpad.net

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).

To post a comment you must log in.
lp:~zyga/checkbox/fix-exporter-crash updated
2030. By Zygmunt Krynicki

vagrant: install python3-dbus

This package is needed by scripts that talk over dbus and have been
ported to python3

Signed-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 DependencySolver._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 udisks2

One 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.0

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>

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 succeed

Signed-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>

Revision history for this message
Daniel Manrique (roadmr) wrote :

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.

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 succeed

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>

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 udisks2

One 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.0

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>

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

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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,

Subscribers

People subscribed via source and target branches