Merge lp:~brendan-donegan/ubuntu/raring/checkbox/0.15.4 into lp:ubuntu/raring/checkbox
- Raring (13.04)
- 0.15.4
- Merge into raring
Proposed by
Brendan Donegan
Status: | Merged |
---|---|
Merged at revision: | 1880 |
Proposed branch: | lp:~brendan-donegan/ubuntu/raring/checkbox/0.15.4 |
Merge into: | lp:ubuntu/raring/checkbox |
Diff against target: |
7070 lines (+2426/-817) 170 files modified
Vagrantfile (+14/-9) checkbox/parsers/tests/test_submission.py (+2/-2) checkbox/parsers/udevadm.py (+21/-0) debian/changelog (+18/-0) debian/po/ast.po (+2/-2) debian/po/cs.po (+2/-2) debian/po/de.po (+2/-2) debian/po/en_AU.po (+2/-2) debian/po/en_GB.po (+2/-2) debian/po/es.po (+2/-2) debian/po/fr.po (+2/-2) debian/po/gl.po (+2/-2) debian/po/he.po (+2/-2) debian/po/hu.po (+2/-2) debian/po/id.po (+2/-2) debian/po/it.po (+2/-2) debian/po/ja.po (+2/-2) debian/po/nl.po (+2/-2) debian/po/oc.po (+2/-2) debian/po/pl.po (+2/-2) debian/po/pt_BR.po (+2/-2) debian/po/ro.po (+2/-2) debian/po/ru.po (+2/-2) debian/po/tr.po (+2/-2) debian/po/uk.po (+2/-2) debian/po/zh_CN.po (+2/-2) debian/po/zh_TW.po (+2/-2) jobs/graphics.txt.in (+2/-1) jobs/input.txt.in (+1/-0) jobs/optical.txt.in (+4/-4) jobs/suspend.txt.in (+1/-1) plainbox/docs/changelog.rst (+32/-0) plainbox/docs/dev/architecture.rst (+337/-0) plainbox/docs/dev/index.rst (+14/-0) plainbox/docs/dev/intro.rst (+238/-0) plainbox/docs/dev/reference.rst (+154/-0) plainbox/docs/glossary.rst (+104/-0) plainbox/docs/index.rst (+46/-6) plainbox/docs/usage.rst (+69/-0) plainbox/plainbox/__init__.py (+4/-4) plainbox/plainbox/abc.py (+2/-4) plainbox/plainbox/impl/__init__.py (+6/-4) plainbox/plainbox/impl/box.py (+55/-14) plainbox/plainbox/impl/checkbox.py (+9/-9) plainbox/plainbox/impl/commands/__init__.py (+6/-6) plainbox/plainbox/impl/commands/selftest.py (+6/-6) plainbox/plainbox/impl/depmgr.py (+17/-15) plainbox/plainbox/impl/exporter/__init__.py (+20/-9) plainbox/plainbox/impl/exporter/json.py (+5/-6) plainbox/plainbox/impl/exporter/rfc822.py (+6/-6) plainbox/plainbox/impl/exporter/test_init.py (+16/-12) plainbox/plainbox/impl/exporter/text.py (+6/-6) plainbox/plainbox/impl/integration_tests.py (+20/-4) plainbox/plainbox/impl/job.py (+18/-8) plainbox/plainbox/impl/mock_job.py (+36/-0) plainbox/plainbox/impl/resource.py (+7/-7) plainbox/plainbox/impl/result.py (+42/-12) plainbox/plainbox/impl/rfc822.py (+10/-7) plainbox/plainbox/impl/runner.py (+76/-19) plainbox/plainbox/impl/session.py (+115/-52) plainbox/plainbox/impl/test_box.py (+110/-14) plainbox/plainbox/impl/test_job.py (+3/-3) plainbox/plainbox/impl/test_result.py (+22/-18) plainbox/plainbox/impl/test_runner.py (+5/-5) plainbox/plainbox/impl/test_session.py (+188/-14) plainbox/plainbox/impl/testing_utils.py (+18/-6) plainbox/plainbox/impl/utils.py.moved (+0/-58) plainbox/plainbox/public.py (+2/-2) plainbox/plainbox/testing_utils/__init__.py (+2/-4) plainbox/plainbox/testing_utils/cwd.py (+2/-2) plainbox/plainbox/testing_utils/io.py (+2/-2) plainbox/plainbox/testing_utils/testcases.py (+3/-3) plainbox/plainbox/tests.py (+2/-4) plainbox/plainbox/vendor/__init__.py (+28/-0) plainbox/plainbox/vendor/extcmd/__init__.py (+2/-2) plainbox/setup.py (+3/-0) po/ace.po (+4/-4) po/af.po (+4/-4) po/am.po (+4/-4) po/ar.po (+4/-4) po/ast.po (+4/-4) po/az.po (+4/-4) po/be.po (+4/-4) po/bg.po (+4/-4) po/bn.po (+4/-4) po/bo.po (+4/-4) po/br.po (+4/-4) po/bs.po (+4/-4) po/ca.po (+4/-4) po/ca@valencia.po (+4/-4) po/ckb.po (+4/-4) po/cs.po (+4/-4) po/cy.po (+4/-4) po/da.po (+4/-4) po/de.po (+5/-5) po/dv.po (+4/-4) po/el.po (+4/-4) po/en_AU.po (+4/-4) po/en_CA.po (+4/-4) po/en_GB.po (+4/-4) po/eo.po (+4/-4) po/es.po (+4/-4) po/et.po (+4/-4) po/eu.po (+4/-4) po/fa.po (+4/-4) po/fi.po (+4/-4) po/fr.po (+4/-4) po/ga.po (+4/-4) po/gd.po (+4/-4) po/gl.po (+4/-4) po/he.po (+4/-4) po/hi.po (+4/-4) po/hr.po (+4/-4) po/hu.po (+4/-4) po/hy.po (+4/-4) po/id.po (+4/-4) po/is.po (+4/-4) po/it.po (+4/-4) po/ja.po (+4/-4) po/jbo.po (+4/-4) po/ka.po (+4/-4) po/kk.po (+4/-4) po/km.po (+4/-4) po/kn.po (+4/-4) po/ko.po (+4/-4) po/ku.po (+4/-4) po/ky.po (+4/-4) po/lt.po (+4/-4) po/lv.po (+4/-4) po/mk.po (+4/-4) po/ml.po (+4/-4) po/mr.po (+4/-4) po/ms.po (+4/-4) po/my.po (+4/-4) po/nb.po (+4/-4) po/nds.po (+4/-4) po/ne.po (+4/-4) po/nl.po (+4/-4) po/nn.po (+4/-4) po/oc.po (+4/-4) po/pl.po (+4/-4) po/ps.po (+4/-4) po/pt.po (+4/-4) po/pt_BR.po (+4/-4) po/ro.po (+4/-4) po/ru.po (+4/-4) po/sd.po (+4/-4) po/shn.po (+4/-4) po/si.po (+4/-4) po/sk.po (+4/-4) po/sl.po (+4/-4) po/sq.po (+4/-4) po/sr.po (+4/-4) po/sv.po (+4/-4) po/ta.po (+4/-4) po/te.po (+4/-4) po/th.po (+4/-4) po/tr.po (+22/-7) po/ug.po (+4/-4) po/uk.po (+4/-4) po/ur.po (+4/-4) po/uz.po (+4/-4) po/vi.po (+4/-4) po/zh_CN.po (+4/-4) po/zh_HK.po (+4/-4) po/zh_TW.po (+4/-4) scripts/network_device_info (+56/-35) scripts/udev_resource (+1/-1) test (+4/-0) test-in-vagrant.sh (+9/-1) |
To merge this branch: | bzr merge lp:~brendan-donegan/ubuntu/raring/checkbox/0.15.4 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Daniel Manrique (community) | Approve | ||
Review via email: mp+152211@code.launchpad.net |
Commit message
Description of the change
checkbox (0.15.4) raring; urgency=low
* New upstream release (LP: #1152223)
[ Daniel Manrique ]
* Added pipefail option to a few jobs using ansi_parser (LP: #1131598)
[ Jeff Marcom ]
* jobs/input.txt.in Added job requirement for accelerometer test (LP: #1135832)
[Sylvain Pineau]
* scripts/
checkbox/
of lspci (LP: #1091633)
-- Brendan Donegan <email address hidden> Thu, 07 Mar 2013 15:43:13 +0000
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'Vagrantfile' | |||
2 | --- Vagrantfile 2013-02-22 16:26:25 +0000 | |||
3 | +++ Vagrantfile 2013-03-07 16:10:38 +0000 | |||
4 | @@ -5,24 +5,29 @@ | |||
5 | 5 | 5 | ||
6 | 6 | # Define a Ubuntu Server image (cloud) for the 12.10 release (quantal) | 6 | # Define a Ubuntu Server image (cloud) for the 12.10 release (quantal) |
7 | 7 | config.vm.define :quantal do |quantal_config| | 7 | config.vm.define :quantal do |quantal_config| |
10 | 8 | quantal_config.vm.box = "quantal-cloud-amd64" | 8 | quantal_config.vm.box = "quantal-cloud-i386" |
11 | 9 | quantal_config.vm.box_url = "http://cloud-images.ubuntu.com/vagrant/quantal/current/quantal-server-cloudimg-amd64-vagrant-disk1.box" | 9 | quantal_config.vm.box_url = "http://cloud-images.ubuntu.com/vagrant/quantal/current/quantal-server-cloudimg-i386-vagrant-disk1.box" |
12 | 10 | end | 10 | end |
13 | 11 | 11 | ||
14 | 12 | # Define a Ubuntu Server image (cloud) for the 12.04 release (precise) | 12 | # Define a Ubuntu Server image (cloud) for the 12.04 release (precise) |
15 | 13 | config.vm.define :precise do |precise_config| | 13 | config.vm.define :precise do |precise_config| |
18 | 14 | precise_config.vm.box = "precise-cloud-amd64" | 14 | precise_config.vm.box = "precise-cloud-i386" |
19 | 15 | precise_config.vm.box_url = "http://cloud-images.ubuntu.com/vagrant/precise/current/precise-server-cloudimg-amd64-vagrant-disk1.box" | 15 | precise_config.vm.box_url = "http://cloud-images.ubuntu.com/vagrant/precise/current/precise-server-cloudimg-i386-vagrant-disk1.box" |
20 | 16 | end | 16 | end |
21 | 17 | 17 | ||
22 | 18 | # For debugging and later future GUI testing | 18 | # For debugging and later future GUI testing |
23 | 19 | # config.vm.boot_mode = :gui | 19 | # config.vm.boot_mode = :gui |
24 | 20 | 20 | ||
28 | 21 | # Update to have the latest packages | 21 | # Update to have the latest packages, this is needed because the image comes |
29 | 22 | # Commented out for now, we don't really need it | 22 | # with an old (and no longer working) apt cache and links to many packages no |
30 | 23 | # config.vm.provision :shell, :inline => "apt-get update && apt-get dist-upgrade" | 23 | # longer work. |
31 | 24 | config.vm.provision :shell, :inline => "apt-get update && apt-get dist-upgrade --yes" | ||
32 | 24 | # Install dependencies from native packages | 25 | # Install dependencies from native packages |
34 | 25 | config.vm.provision :shell, :inline => "apt-get install --yes python3-setuptools python3-yaml python3-lxml" | 26 | config.vm.provision :shell, :inline => "apt-get install --yes python3-setuptools python3-lxml" |
35 | 27 | # Install python3-mock so that we can create mock objects for testing | ||
36 | 28 | config.vm.provision :shell, :inline => "apt-get install --yes python3-mock" | ||
37 | 29 | # Install policykit-1 so that we have pkexec | ||
38 | 30 | config.vm.provision :shell, :inline => "apt-get install --yes policykit-1" | ||
39 | 26 | # Install some checkbox script dependencies: | 31 | # Install some checkbox script dependencies: |
40 | 27 | # Later on those could be installed on demand to test how we behave without | 32 | # Later on those could be installed on demand to test how we behave without |
41 | 28 | # them but for now that's good enough. Little by little... | 33 | # them but for now that's good enough. Little by little... |
42 | @@ -38,5 +43,5 @@ | |||
43 | 38 | # Develop plainbox so that we have it in $PATH | 43 | # Develop plainbox so that we have it in $PATH |
44 | 39 | config.vm.provision :shell, :inline => "cd /vagrant/plainbox/ && python3 setup.py develop" | 44 | config.vm.provision :shell, :inline => "cd /vagrant/plainbox/ && python3 setup.py develop" |
45 | 40 | # Create a cool symlink so that everyone knows where to go to | 45 | # Create a cool symlink so that everyone knows where to go to |
47 | 41 | config.vm.provision :shell, :inline => "ln -s /vagrant /home/vagrant/checkbox" | 46 | config.vm.provision :shell, :inline => "ln -fs /vagrant /home/vagrant/checkbox" |
48 | 42 | end | 47 | end |
49 | 43 | 48 | ||
50 | === modified file 'checkbox/parsers/tests/test_submission.py' | |||
51 | --- checkbox/parsers/tests/test_submission.py 2012-10-12 21:39:01 +0000 | |||
52 | +++ checkbox/parsers/tests/test_submission.py 2013-03-07 16:10:38 +0000 | |||
53 | @@ -153,13 +153,13 @@ | |||
54 | 153 | """Device states can be in the udev element.""" | 153 | """Device states can be in the udev element.""" |
55 | 154 | result = self.getResult("submission_udev.xml") | 154 | result = self.getResult("submission_udev.xml") |
56 | 155 | self.assertTrue("device_states" in result) | 155 | self.assertTrue("device_states" in result) |
58 | 156 | self.assertEquals(len(result["device_states"]), 77) | 156 | self.assertEquals(len(result["device_states"]), 82) |
59 | 157 | 157 | ||
60 | 158 | def test_device_udevadm(self): | 158 | def test_device_udevadm(self): |
61 | 159 | """Device states can be in a udevadm info element.""" | 159 | """Device states can be in a udevadm info element.""" |
62 | 160 | result = self.getResult("submission_info_udevadm.xml") | 160 | result = self.getResult("submission_info_udevadm.xml") |
63 | 161 | self.assertTrue("device_states" in result) | 161 | self.assertTrue("device_states" in result) |
65 | 162 | self.assertEquals(len(result["device_states"]), 77) | 162 | self.assertEquals(len(result["device_states"]), 82) |
66 | 163 | 163 | ||
67 | 164 | def test_device_dmidecode(self): | 164 | def test_device_dmidecode(self): |
68 | 165 | """Device states can be in a dmidecode info element.""" | 165 | """Device states can be in a dmidecode info element.""" |
69 | 166 | 166 | ||
70 | === modified file 'checkbox/parsers/udevadm.py' | |||
71 | --- checkbox/parsers/udevadm.py 2012-11-12 09:59:00 +0000 | |||
72 | +++ checkbox/parsers/udevadm.py 2013-03-07 16:10:38 +0000 | |||
73 | @@ -92,8 +92,15 @@ | |||
74 | 92 | @property | 92 | @property |
75 | 93 | def category(self): | 93 | def category(self): |
76 | 94 | if "IFINDEX" in self._environment: | 94 | if "IFINDEX" in self._environment: |
77 | 95 | if "DEVTYPE" in self._environment: | ||
78 | 96 | devtype = self._environment["DEVTYPE"] | ||
79 | 97 | if devtype == "wlan": | ||
80 | 98 | return "WIRELESS" | ||
81 | 95 | return "NETWORK" | 99 | return "NETWORK" |
82 | 96 | 100 | ||
83 | 101 | if self.bus == "sound": | ||
84 | 102 | return "AUDIO" | ||
85 | 103 | |||
86 | 97 | if self.bus == "ieee80211": | 104 | if self.bus == "ieee80211": |
87 | 98 | return "WIRELESS" | 105 | return "WIRELESS" |
88 | 99 | 106 | ||
89 | @@ -383,6 +390,9 @@ | |||
90 | 383 | if self.driver == "floppy": | 390 | if self.driver == "floppy": |
91 | 384 | return "Platform Device" | 391 | return "Platform Device" |
92 | 385 | 392 | ||
93 | 393 | if "ID_MODEL_FROM_DATABASE" in self._environment: | ||
94 | 394 | return self._environment["ID_MODEL_FROM_DATABASE"] | ||
95 | 395 | |||
96 | 386 | return None | 396 | return None |
97 | 387 | 397 | ||
98 | 388 | @property | 398 | @property |
99 | @@ -407,6 +417,17 @@ | |||
100 | 407 | and "ID_VENDOR_ENC" in self._environment: | 417 | and "ID_VENDOR_ENC" in self._environment: |
101 | 408 | return decode_id(self._environment["ID_VENDOR_ENC"]) | 418 | return decode_id(self._environment["ID_VENDOR_ENC"]) |
102 | 409 | 419 | ||
103 | 420 | if "ID_VENDOR_FROM_DATABASE" in self._environment: | ||
104 | 421 | return self._environment["ID_VENDOR_FROM_DATABASE"] | ||
105 | 422 | |||
106 | 423 | return None | ||
107 | 424 | |||
108 | 425 | @property | ||
109 | 426 | def interface(self): | ||
110 | 427 | if self.category in ("NETWORK", "WIRELESS") \ | ||
111 | 428 | and "INTERFACE" in self._environment: | ||
112 | 429 | return self._environment["INTERFACE"] | ||
113 | 430 | |||
114 | 410 | return None | 431 | return None |
115 | 411 | 432 | ||
116 | 412 | 433 | ||
117 | 413 | 434 | ||
118 | === modified file 'debian/changelog' | |||
119 | --- debian/changelog 2013-02-22 16:41:55 +0000 | |||
120 | +++ debian/changelog 2013-03-07 16:10:38 +0000 | |||
121 | @@ -1,7 +1,25 @@ | |||
122 | 1 | checkbox (0.15.4) raring; urgency=low | ||
123 | 2 | |||
124 | 3 | * New upstream release (LP: #1152223) | ||
125 | 4 | |||
126 | 5 | [ Daniel Manrique ] | ||
127 | 6 | * Added pipefail option to a few jobs using ansi_parser (LP: #1131598) | ||
128 | 7 | |||
129 | 8 | [ Jeff Marcom ] | ||
130 | 9 | * jobs/input.txt.in Added job requirement for accelerometer test (LP: #1135832) | ||
131 | 10 | |||
132 | 11 | [Sylvain Pineau] | ||
133 | 12 | * scripts/network_device_info, scripts/udev_resource, | ||
134 | 13 | checkbox/parsers/udevadm.py: Use udev to categorise network devices instead | ||
135 | 14 | of lspci (LP: #1091633) | ||
136 | 15 | |||
137 | 16 | -- Brendan Donegan <brendan.donegan@ubuntu.com> Thu, 07 Mar 2013 15:43:13 +0000 | ||
138 | 17 | |||
139 | 1 | checkbox (0.15.3) raring; urgency=low | 18 | checkbox (0.15.3) raring; urgency=low |
140 | 2 | 19 | ||
141 | 3 | * New upstream release (LP: #1131801) | 20 | * New upstream release (LP: #1131801) |
142 | 4 | 21 | ||
143 | 22 | [ Daniel Manrique ] | ||
144 | 5 | * scripts/pts_run: modified to output the full log from phoronix-test-suite | 23 | * scripts/pts_run: modified to output the full log from phoronix-test-suite |
145 | 6 | (LP: #1102819) | 24 | (LP: #1102819) |
146 | 7 | 25 | ||
147 | 8 | 26 | ||
148 | === modified file 'debian/po/ast.po' | |||
149 | --- debian/po/ast.po 2013-02-22 16:26:25 +0000 | |||
150 | +++ debian/po/ast.po 2013-03-07 16:10:38 +0000 | |||
151 | @@ -14,8 +14,8 @@ | |||
152 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
153 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
154 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
157 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:35+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:42+0000\n" |
158 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
159 | 19 | 19 | ||
160 | 20 | #. Type: string | 20 | #. Type: string |
161 | 21 | #. Description | 21 | #. Description |
162 | 22 | 22 | ||
163 | === modified file 'debian/po/cs.po' | |||
164 | --- debian/po/cs.po 2013-02-22 16:26:25 +0000 | |||
165 | +++ debian/po/cs.po 2013-03-07 16:10:38 +0000 | |||
166 | @@ -14,8 +14,8 @@ | |||
167 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
168 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
169 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
172 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:35+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:42+0000\n" |
173 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
174 | 19 | 19 | ||
175 | 20 | #. Type: string | 20 | #. Type: string |
176 | 21 | #. Description | 21 | #. Description |
177 | 22 | 22 | ||
178 | === modified file 'debian/po/de.po' | |||
179 | --- debian/po/de.po 2013-02-22 16:26:25 +0000 | |||
180 | +++ debian/po/de.po 2013-03-07 16:10:38 +0000 | |||
181 | @@ -14,8 +14,8 @@ | |||
182 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
183 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
184 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
187 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:35+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:42+0000\n" |
188 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
189 | 19 | 19 | ||
190 | 20 | #. Type: string | 20 | #. Type: string |
191 | 21 | #. Description | 21 | #. Description |
192 | 22 | 22 | ||
193 | === modified file 'debian/po/en_AU.po' | |||
194 | --- debian/po/en_AU.po 2013-02-22 16:26:25 +0000 | |||
195 | +++ debian/po/en_AU.po 2013-03-07 16:10:38 +0000 | |||
196 | @@ -14,8 +14,8 @@ | |||
197 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
198 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
199 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
202 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:35+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:42+0000\n" |
203 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
204 | 19 | 19 | ||
205 | 20 | #. Type: string | 20 | #. Type: string |
206 | 21 | #. Description | 21 | #. Description |
207 | 22 | 22 | ||
208 | === modified file 'debian/po/en_GB.po' | |||
209 | --- debian/po/en_GB.po 2013-02-22 16:26:25 +0000 | |||
210 | +++ debian/po/en_GB.po 2013-03-07 16:10:38 +0000 | |||
211 | @@ -14,8 +14,8 @@ | |||
212 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
213 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
214 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
217 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:35+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:42+0000\n" |
218 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
219 | 19 | 19 | ||
220 | 20 | #. Type: string | 20 | #. Type: string |
221 | 21 | #. Description | 21 | #. Description |
222 | 22 | 22 | ||
223 | === modified file 'debian/po/es.po' | |||
224 | --- debian/po/es.po 2013-02-22 16:26:25 +0000 | |||
225 | +++ debian/po/es.po 2013-03-07 16:10:38 +0000 | |||
226 | @@ -14,8 +14,8 @@ | |||
227 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
228 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
229 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
232 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:35+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:42+0000\n" |
233 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
234 | 19 | 19 | ||
235 | 20 | #. Type: string | 20 | #. Type: string |
236 | 21 | #. Description | 21 | #. Description |
237 | 22 | 22 | ||
238 | === modified file 'debian/po/fr.po' | |||
239 | --- debian/po/fr.po 2013-02-22 16:26:25 +0000 | |||
240 | +++ debian/po/fr.po 2013-03-07 16:10:38 +0000 | |||
241 | @@ -14,8 +14,8 @@ | |||
242 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
243 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
244 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
247 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:35+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:42+0000\n" |
248 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
249 | 19 | 19 | ||
250 | 20 | #. Type: string | 20 | #. Type: string |
251 | 21 | #. Description | 21 | #. Description |
252 | 22 | 22 | ||
253 | === modified file 'debian/po/gl.po' | |||
254 | --- debian/po/gl.po 2013-02-22 16:26:25 +0000 | |||
255 | +++ debian/po/gl.po 2013-03-07 16:10:38 +0000 | |||
256 | @@ -14,8 +14,8 @@ | |||
257 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
258 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
259 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
262 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:35+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:42+0000\n" |
263 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
264 | 19 | 19 | ||
265 | 20 | #. Type: string | 20 | #. Type: string |
266 | 21 | #. Description | 21 | #. Description |
267 | 22 | 22 | ||
268 | === modified file 'debian/po/he.po' | |||
269 | --- debian/po/he.po 2013-02-22 16:26:25 +0000 | |||
270 | +++ debian/po/he.po 2013-03-07 16:10:38 +0000 | |||
271 | @@ -14,8 +14,8 @@ | |||
272 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
273 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
274 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
277 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:35+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:42+0000\n" |
278 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
279 | 19 | 19 | ||
280 | 20 | #. Type: string | 20 | #. Type: string |
281 | 21 | #. Description | 21 | #. Description |
282 | 22 | 22 | ||
283 | === modified file 'debian/po/hu.po' | |||
284 | --- debian/po/hu.po 2013-02-22 16:26:25 +0000 | |||
285 | +++ debian/po/hu.po 2013-03-07 16:10:38 +0000 | |||
286 | @@ -14,8 +14,8 @@ | |||
287 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
288 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
289 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
292 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:35+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:42+0000\n" |
293 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
294 | 19 | 19 | ||
295 | 20 | #. Type: string | 20 | #. Type: string |
296 | 21 | #. Description | 21 | #. Description |
297 | 22 | 22 | ||
298 | === modified file 'debian/po/id.po' | |||
299 | --- debian/po/id.po 2013-02-22 16:26:25 +0000 | |||
300 | +++ debian/po/id.po 2013-03-07 16:10:38 +0000 | |||
301 | @@ -14,8 +14,8 @@ | |||
302 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
303 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
304 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
307 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:35+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:42+0000\n" |
308 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
309 | 19 | 19 | ||
310 | 20 | #. Type: string | 20 | #. Type: string |
311 | 21 | #. Description | 21 | #. Description |
312 | 22 | 22 | ||
313 | === modified file 'debian/po/it.po' | |||
314 | --- debian/po/it.po 2013-02-22 16:26:25 +0000 | |||
315 | +++ debian/po/it.po 2013-03-07 16:10:38 +0000 | |||
316 | @@ -14,8 +14,8 @@ | |||
317 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
318 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
319 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
322 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:35+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:42+0000\n" |
323 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
324 | 19 | 19 | ||
325 | 20 | #. Type: string | 20 | #. Type: string |
326 | 21 | #. Description | 21 | #. Description |
327 | 22 | 22 | ||
328 | === modified file 'debian/po/ja.po' | |||
329 | --- debian/po/ja.po 2013-02-22 16:26:25 +0000 | |||
330 | +++ debian/po/ja.po 2013-03-07 16:10:38 +0000 | |||
331 | @@ -14,8 +14,8 @@ | |||
332 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
333 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
334 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
337 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:35+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:42+0000\n" |
338 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
339 | 19 | 19 | ||
340 | 20 | #. Type: string | 20 | #. Type: string |
341 | 21 | #. Description | 21 | #. Description |
342 | 22 | 22 | ||
343 | === modified file 'debian/po/nl.po' | |||
344 | --- debian/po/nl.po 2013-02-22 16:26:25 +0000 | |||
345 | +++ debian/po/nl.po 2013-03-07 16:10:38 +0000 | |||
346 | @@ -14,8 +14,8 @@ | |||
347 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
348 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
349 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
352 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:35+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:42+0000\n" |
353 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
354 | 19 | 19 | ||
355 | 20 | #. Type: string | 20 | #. Type: string |
356 | 21 | #. Description | 21 | #. Description |
357 | 22 | 22 | ||
358 | === modified file 'debian/po/oc.po' | |||
359 | --- debian/po/oc.po 2013-02-22 16:26:25 +0000 | |||
360 | +++ debian/po/oc.po 2013-03-07 16:10:38 +0000 | |||
361 | @@ -14,8 +14,8 @@ | |||
362 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
363 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
364 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
367 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:35+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:42+0000\n" |
368 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
369 | 19 | 19 | ||
370 | 20 | #. Type: string | 20 | #. Type: string |
371 | 21 | #. Description | 21 | #. Description |
372 | 22 | 22 | ||
373 | === modified file 'debian/po/pl.po' | |||
374 | --- debian/po/pl.po 2013-02-22 16:26:25 +0000 | |||
375 | +++ debian/po/pl.po 2013-03-07 16:10:38 +0000 | |||
376 | @@ -14,8 +14,8 @@ | |||
377 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
378 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
379 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
382 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:35+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:42+0000\n" |
383 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
384 | 19 | 19 | ||
385 | 20 | #. Type: string | 20 | #. Type: string |
386 | 21 | #. Description | 21 | #. Description |
387 | 22 | 22 | ||
388 | === modified file 'debian/po/pt_BR.po' | |||
389 | --- debian/po/pt_BR.po 2013-02-22 16:26:25 +0000 | |||
390 | +++ debian/po/pt_BR.po 2013-03-07 16:10:38 +0000 | |||
391 | @@ -14,8 +14,8 @@ | |||
392 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
393 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
394 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
397 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:35+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:42+0000\n" |
398 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
399 | 19 | 19 | ||
400 | 20 | #. Type: string | 20 | #. Type: string |
401 | 21 | #. Description | 21 | #. Description |
402 | 22 | 22 | ||
403 | === modified file 'debian/po/ro.po' | |||
404 | --- debian/po/ro.po 2013-02-22 16:26:25 +0000 | |||
405 | +++ debian/po/ro.po 2013-03-07 16:10:38 +0000 | |||
406 | @@ -14,8 +14,8 @@ | |||
407 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
408 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
409 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
412 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:35+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:42+0000\n" |
413 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
414 | 19 | 19 | ||
415 | 20 | #. Type: string | 20 | #. Type: string |
416 | 21 | #. Description | 21 | #. Description |
417 | 22 | 22 | ||
418 | === modified file 'debian/po/ru.po' | |||
419 | --- debian/po/ru.po 2013-02-22 16:26:25 +0000 | |||
420 | +++ debian/po/ru.po 2013-03-07 16:10:38 +0000 | |||
421 | @@ -14,8 +14,8 @@ | |||
422 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
423 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
424 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
427 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:35+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:42+0000\n" |
428 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
429 | 19 | 19 | ||
430 | 20 | #. Type: string | 20 | #. Type: string |
431 | 21 | #. Description | 21 | #. Description |
432 | 22 | 22 | ||
433 | === modified file 'debian/po/tr.po' | |||
434 | --- debian/po/tr.po 2013-02-22 16:26:25 +0000 | |||
435 | +++ debian/po/tr.po 2013-03-07 16:10:38 +0000 | |||
436 | @@ -14,8 +14,8 @@ | |||
437 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
438 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
439 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
442 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:35+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:42+0000\n" |
443 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
444 | 19 | 19 | ||
445 | 20 | #. Type: string | 20 | #. Type: string |
446 | 21 | #. Description | 21 | #. Description |
447 | 22 | 22 | ||
448 | === modified file 'debian/po/uk.po' | |||
449 | --- debian/po/uk.po 2013-02-22 16:26:25 +0000 | |||
450 | +++ debian/po/uk.po 2013-03-07 16:10:38 +0000 | |||
451 | @@ -14,8 +14,8 @@ | |||
452 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
453 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
454 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
457 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:35+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:42+0000\n" |
458 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
459 | 19 | 19 | ||
460 | 20 | #. Type: string | 20 | #. Type: string |
461 | 21 | #. Description | 21 | #. Description |
462 | 22 | 22 | ||
463 | === modified file 'debian/po/zh_CN.po' | |||
464 | --- debian/po/zh_CN.po 2013-02-22 16:26:25 +0000 | |||
465 | +++ debian/po/zh_CN.po 2013-03-07 16:10:38 +0000 | |||
466 | @@ -14,8 +14,8 @@ | |||
467 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
468 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
469 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
472 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:35+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:42+0000\n" |
473 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
474 | 19 | 19 | ||
475 | 20 | #. Type: string | 20 | #. Type: string |
476 | 21 | #. Description | 21 | #. Description |
477 | 22 | 22 | ||
478 | === modified file 'debian/po/zh_TW.po' | |||
479 | --- debian/po/zh_TW.po 2013-02-22 16:26:25 +0000 | |||
480 | +++ debian/po/zh_TW.po 2013-03-07 16:10:38 +0000 | |||
481 | @@ -14,8 +14,8 @@ | |||
482 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
483 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
484 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
487 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:35+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:42+0000\n" |
488 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
489 | 19 | 19 | ||
490 | 20 | #. Type: string | 20 | #. Type: string |
491 | 21 | #. Description | 21 | #. Description |
492 | 22 | 22 | ||
493 | === modified file 'jobs/graphics.txt.in' | |||
494 | --- jobs/graphics.txt.in 2012-12-12 12:59:22 +0000 | |||
495 | +++ jobs/graphics.txt.in 2013-03-07 16:10:38 +0000 | |||
496 | @@ -170,7 +170,7 @@ | |||
497 | 170 | plugin: shell | 170 | plugin: shell |
498 | 171 | name: graphics/screenshot | 171 | name: graphics/screenshot |
499 | 172 | requires: package.name == 'fswebcam' | 172 | requires: package.name == 'fswebcam' |
501 | 173 | command: camera_test still --device=/dev/external_webcam -f ${CHECKBOX_DATA}/screenshot.jpg -q 2>&1 | ansi_parser | 173 | command: set -o pipefail; camera_test still --device=/dev/external_webcam -f ${CHECKBOX_DATA}/screenshot.jpg -q 2>&1 | ansi_parser |
502 | 174 | _description: | 174 | _description: |
503 | 175 | PURPOSE: | 175 | PURPOSE: |
504 | 176 | Take a screengrab of the current screen (logged on Unity desktop) | 176 | Take a screengrab of the current screen (logged on Unity desktop) |
505 | @@ -191,6 +191,7 @@ | |||
506 | 191 | command: | 191 | command: |
507 | 192 | dbus-launch gsettings set org.gnome.totem repeat true | 192 | dbus-launch gsettings set org.gnome.totem repeat true |
508 | 193 | totem --fullscreen ${CHECKBOX_SHARE}/data/video/Ogg_Theora_Video.ogv 2>/dev/null & | 193 | totem --fullscreen ${CHECKBOX_SHARE}/data/video/Ogg_Theora_Video.ogv 2>/dev/null & |
509 | 194 | set -o pipefail | ||
510 | 194 | sleep 15 && camera_test still --device=/dev/external_webcam -f ${CHECKBOX_DATA}/screenshot_fullscreen_video.jpg -q 2>&1 | ansi_parser | 195 | sleep 15 && camera_test still --device=/dev/external_webcam -f ${CHECKBOX_DATA}/screenshot_fullscreen_video.jpg -q 2>&1 | ansi_parser |
511 | 195 | sleep 5 && totem --quit 2>/dev/null | 196 | sleep 5 && totem --quit 2>/dev/null |
512 | 196 | dbus-launch gsettings set org.gnome.totem repeat false | 197 | dbus-launch gsettings set org.gnome.totem repeat false |
513 | 197 | 198 | ||
514 | === modified file 'jobs/input.txt.in' | |||
515 | --- jobs/input.txt.in 2013-02-22 16:26:25 +0000 | |||
516 | +++ jobs/input.txt.in 2013-03-07 16:10:38 +0000 | |||
517 | @@ -44,6 +44,7 @@ | |||
518 | 44 | plugin: user-interact | 44 | plugin: user-interact |
519 | 45 | name: input/accelerometer | 45 | name: input/accelerometer |
520 | 46 | user: root | 46 | user: root |
521 | 47 | requires: module.name in ['hdaps', 'hp_accel'] | ||
522 | 47 | command: accelerometer_test -m | 48 | command: accelerometer_test -m |
523 | 48 | _description: | 49 | _description: |
524 | 49 | PURPOSE: | 50 | PURPOSE: |
525 | 50 | 51 | ||
526 | === modified file 'jobs/optical.txt.in' | |||
527 | --- jobs/optical.txt.in 2012-10-11 20:48:55 +0000 | |||
528 | +++ jobs/optical.txt.in 2013-03-07 16:10:38 +0000 | |||
529 | @@ -58,7 +58,7 @@ | |||
530 | 58 | name: optical/cdrom-write_`ls /sys$path/block` | 58 | name: optical/cdrom-write_`ls /sys$path/block` |
531 | 59 | requires: device.path == "$path" | 59 | requires: device.path == "$path" |
532 | 60 | user: root | 60 | user: root |
534 | 61 | command: optical_write_test /dev/`ls /sys$path/block` | ansi_parser | 61 | command: set -o pipefail; optical_write_test /dev/`ls /sys$path/block` | ansi_parser |
535 | 62 | description: | 62 | description: |
536 | 63 | PURPOSE: | 63 | PURPOSE: |
537 | 64 | This test will check your system's $product CD writing capabilities. This test requires a blank CD-R or CD+R. If you do not have a blank disk, skip this test. | 64 | This test will check your system's $product CD writing capabilities. This test requires a blank CD-R or CD+R. If you do not have a blank disk, skip this test. |
538 | @@ -80,7 +80,7 @@ | |||
539 | 80 | name: optical/cdrom-write-automated_`ls /sys$path/block` | 80 | name: optical/cdrom-write-automated_`ls /sys$path/block` |
540 | 81 | requires: device.path == "$path" | 81 | requires: device.path == "$path" |
541 | 82 | user: root | 82 | user: root |
543 | 83 | command: optical_write_test /dev/`ls /sys$path/block` | ansi_parser | 83 | command: set -o pipefail; optical_write_test /dev/`ls /sys$path/block` | ansi_parser |
544 | 84 | description: | 84 | description: |
545 | 85 | This is an automated version of optical/cdrom-write. It assumes you have already inserted a data CD into your optical drive prior to running Checkbox. | 85 | This is an automated version of optical/cdrom-write. It assumes you have already inserted a data CD into your optical drive prior to running Checkbox. |
546 | 86 | EOF | 86 | EOF |
547 | @@ -116,7 +116,7 @@ | |||
548 | 116 | name: optical/dvd-write_`ls /sys$path/block` | 116 | name: optical/dvd-write_`ls /sys$path/block` |
549 | 117 | requires: device.path == "$path" | 117 | requires: device.path == "$path" |
550 | 118 | user: root | 118 | user: root |
552 | 119 | command: optical_write_test /dev/`ls /sys$path/block` | ansi_parser | 119 | command: set -o pipefail; optical_write_test /dev/`ls /sys$path/block` | ansi_parser |
553 | 120 | description: | 120 | description: |
554 | 121 | PURPOSE: | 121 | PURPOSE: |
555 | 122 | This test will check your system's $product writing capabilities. This test requires a blank DVD-R or DVD+R. If you do not have a blank DVD disk, skip this test. | 122 | This test will check your system's $product writing capabilities. This test requires a blank DVD-R or DVD+R. If you do not have a blank DVD disk, skip this test. |
556 | @@ -140,7 +140,7 @@ | |||
557 | 140 | name: optical/dvd-write-automated_`ls /sys$path/block` | 140 | name: optical/dvd-write-automated_`ls /sys$path/block` |
558 | 141 | requires: device.path == "$path" | 141 | requires: device.path == "$path" |
559 | 142 | user: root | 142 | user: root |
561 | 143 | command: optical_write_test /dev/`ls /sys$path/block` | ansi_parser | 143 | command: set -o pipefail; optical_write_test /dev/`ls /sys$path/block` | ansi_parser |
562 | 144 | description: | 144 | description: |
563 | 145 | This is an automated version of optical/dvd-write. It assumes you have already inserted a data DVD into your optical drive prior to running Checkbox. | 145 | This is an automated version of optical/dvd-write. It assumes you have already inserted a data DVD into your optical drive prior to running Checkbox. |
564 | 146 | EOF | 146 | EOF |
565 | 147 | 147 | ||
566 | === modified file 'jobs/suspend.txt.in' | |||
567 | --- jobs/suspend.txt.in 2013-01-30 21:43:05 +0000 | |||
568 | +++ jobs/suspend.txt.in 2013-03-07 16:10:38 +0000 | |||
569 | @@ -790,7 +790,7 @@ | |||
570 | 790 | name: suspend/screenshot_after_suspend | 790 | name: suspend/screenshot_after_suspend |
571 | 791 | depends: suspend/suspend_advanced_auto | 791 | depends: suspend/suspend_advanced_auto |
572 | 792 | requires: package.name == 'fswebcam' | 792 | requires: package.name == 'fswebcam' |
574 | 793 | command: camera_test still --device=/dev/external_webcam -f ${CHECKBOX_DATA}/screenshot_after_suspend.jpg -q 2>&1 | ansi_parser | 793 | command: set -o pipefail; camera_test still --device=/dev/external_webcam -f ${CHECKBOX_DATA}/screenshot_after_suspend.jpg -q 2>&1 | ansi_parser |
575 | 794 | _description: | 794 | _description: |
576 | 795 | PURPOSE: | 795 | PURPOSE: |
577 | 796 | Take a screengrab of the current screen after suspend (logged on Unity desktop) | 796 | Take a screengrab of the current screen after suspend (logged on Unity desktop) |
578 | 797 | 797 | ||
579 | === added file 'plainbox/docs/changelog.rst' | |||
580 | --- plainbox/docs/changelog.rst 1970-01-01 00:00:00 +0000 | |||
581 | +++ plainbox/docs/changelog.rst 2013-03-07 16:10:38 +0000 | |||
582 | @@ -0,0 +1,32 @@ | |||
583 | 1 | ChangeLog | ||
584 | 2 | ========= | ||
585 | 3 | |||
586 | 4 | .. note:: | ||
587 | 5 | This changelog contains only a summary of changes. For a more accurate | ||
588 | 6 | accounting of development history please inspect the source history | ||
589 | 7 | directly. | ||
590 | 8 | |||
591 | 9 | PlainBox 0.3 (Unreleased) | ||
592 | 10 | ^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
593 | 11 | |||
594 | 12 | * Added support for all job types (manual, user-interact, user-verify, attachment, local) | ||
595 | 13 | * Added support for running as another user | ||
596 | 14 | * Added support for creating session checkpoints and resuming testing across reboots | ||
597 | 15 | * Added support for exporting test results to JSON, plain text and XML | ||
598 | 16 | * Added support for handling binary data (eg, binary attachments) | ||
599 | 17 | * Added support for using sub-commands to the main plainbox executable | ||
600 | 18 | * Added documentation to the project | ||
601 | 19 | * Numerous internal re-factorings, changes and improvements. | ||
602 | 20 | * Improved unit and integration testing coverage | ||
603 | 21 | |||
604 | 22 | PlainBox 0.2 | ||
605 | 23 | ^^^^^^^^^^^^ | ||
606 | 24 | |||
607 | 25 | * Last release made from the standalone github tree. | ||
608 | 26 | * Added support for discovering dependencies and automatic dependency | ||
609 | 27 | resolution (for both job dependencies and resource dependencies) | ||
610 | 28 | |||
611 | 29 | PlainBox 0.1 | ||
612 | 30 | ^^^^^^^^^^^^ | ||
613 | 31 | |||
614 | 32 | * Initial release | ||
615 | 0 | 33 | ||
616 | === added directory 'plainbox/docs/dev' | |||
617 | === added file 'plainbox/docs/dev/architecture.rst' | |||
618 | --- plainbox/docs/dev/architecture.rst 1970-01-01 00:00:00 +0000 | |||
619 | +++ plainbox/docs/dev/architecture.rst 2013-03-07 16:10:38 +0000 | |||
620 | @@ -0,0 +1,337 @@ | |||
621 | 1 | PlainBox Architecture | ||
622 | 2 | ===================== | ||
623 | 3 | |||
624 | 4 | This document explains the architecture of PlainBox internals. It should be | ||
625 | 5 | always up-to-date and accurate to the extent of the scope of this overview. | ||
626 | 6 | |||
627 | 7 | General design considerations | ||
628 | 8 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
629 | 9 | |||
630 | 10 | PlainBox is a reimplementation of CheckBox that replaces a reactor / event / | ||
631 | 11 | plugin architecture with a monolithic core and tightly integrated components. | ||
632 | 12 | |||
633 | 13 | The implementation models a few of the externally-visible concepts such as | ||
634 | 14 | jobs, resources and resource programs but also has some additional design that | ||
635 | 15 | was not present in CheckBox before. | ||
636 | 16 | |||
637 | 17 | The goal of the rewrite is to provide the right model and APIs for user | ||
638 | 18 | interfaces in order to build the kind of end-user solution that we could not | ||
639 | 19 | build with CheckBox. | ||
640 | 20 | |||
641 | 21 | This is expressed by additional functionality that is there only to provide the | ||
642 | 22 | higher layers with the right data (failure reason, descriptions, etc.). The | ||
643 | 23 | code is also intended to be highly testable. Test coverage at the time of | ||
644 | 24 | writing this document was exceeding 80% | ||
645 | 25 | |||
646 | 26 | The core requirement for the current phase of PlainBox development is feature | ||
647 | 27 | parity with CheckBox and gradual shift from one to another in the daily | ||
648 | 28 | responsibilities of the Hardware Certification team. Currently PlainBox | ||
649 | 29 | implements a large chunk of core / essential features from CheckBox. While not | ||
650 | 30 | all features are present the core is considered almost feature complete at this | ||
651 | 31 | stage. | ||
652 | 32 | |||
653 | 33 | Application Skeleton | ||
654 | 34 | ^^^^^^^^^^^^^^^^^^^^ | ||
655 | 35 | |||
656 | 36 | This skeleton represents a typical application based on PlainBox. It enumerates | ||
657 | 37 | the essential parts of the APIs from the point of view of an application | ||
658 | 38 | developer. | ||
659 | 39 | |||
660 | 40 | 1. Instantiate :class:`plainbox.impl.checkbox.CheckBox` then call | ||
661 | 41 | :meth:`plainbox.impl.checkbox.CheckBox.get_builtin_jobs()` to discover all | ||
662 | 42 | known jobs. In the future this might be replaced by a step that obtains jobs | ||
663 | 43 | from a named provider. | ||
664 | 44 | |||
665 | 45 | 3. Instantiate :class:`plainbox.impl.runner.JobRunner` so that we can run jobs | ||
666 | 46 | |||
667 | 47 | 4. Instantiate :class:`plainbox.impl.session.SessionState` so that we can keep | ||
668 | 48 | track of application state. | ||
669 | 49 | |||
670 | 50 | - Potentially restore an earlier, interrupted, testing session by calling | ||
671 | 51 | :meth:`plainbox.impl.session.SessionState.restore()` | ||
672 | 52 | |||
673 | 53 | - Potentially remove an earlier, interrupted, testing session by calling | ||
674 | 54 | :meth:`plainbox.impl.session.SessionState.discard()` | ||
675 | 55 | |||
676 | 56 | - Potentially start a new test session by calling | ||
677 | 57 | :meth:`plainbox.impl.session.SessionState.open()` | ||
678 | 58 | |||
679 | 59 | 5. Allow the user to select jobs that should be executed and update session | ||
680 | 60 | state by calling | ||
681 | 61 | :meth:`plainbox.impl.session.SessionState.update_desired_job_list()` | ||
682 | 62 | |||
683 | 63 | 6. For each job in :attr:`plainbox.impl.SessionState.run_list`: | ||
684 | 64 | |||
685 | 65 | 1. Check if we want to run the job (if we have a result for it from previous | ||
686 | 66 | runs) or if we must run it (for jobs that cannot be persisted across | ||
687 | 67 | suspend) | ||
688 | 68 | |||
689 | 69 | 2. Check if the job can be started by looking at | ||
690 | 70 | :meth:`plainbox.impl.session.JobState.can_start()` | ||
691 | 71 | |||
692 | 72 | - optionally query for additional data on why a job cannot be started and | ||
693 | 73 | present that to the user. | ||
694 | 74 | |||
695 | 75 | - optionally abort the sequence and go to step 5 or the outer loop. | ||
696 | 76 | |||
697 | 77 | 3. Call :meth:`plainbox.impl.runner.JobRunner.run_job()` with the current | ||
698 | 78 | job and store the result. | ||
699 | 79 | |||
700 | 80 | - optionally ask the user to perform some manipulation | ||
701 | 81 | |||
702 | 82 | - optionally ask the user to qualify the outcome | ||
703 | 83 | |||
704 | 84 | - optionally ask the user for additional comments | ||
705 | 85 | |||
706 | 86 | 4. Call :meth:`plainbox.impl.session.SessionState.update_job_result()` to | ||
707 | 87 | update readiness of jobs that depend on the outcome or output of current | ||
708 | 88 | job. | ||
709 | 89 | |||
710 | 90 | 5. Call :meth:`plainbox.impl.session.SessionState.checkpoint()` to ensure | ||
711 | 91 | that testing can resume after system crash or shutdown. | ||
712 | 92 | |||
713 | 93 | 7. Instantiate the selected state exporter, for example | ||
714 | 94 | :class:`plainbox.impl.exporters.json.JSONSessionStateExporter` so that we | ||
715 | 95 | can use it to save test results. | ||
716 | 96 | |||
717 | 97 | - optionally pass configuration options to customize the subset and the | ||
718 | 98 | presentation of the session state | ||
719 | 99 | |||
720 | 100 | 8. Call | ||
721 | 101 | :meth:`plainbox.impl.exporters.SessionStateExporterBase.get_session_data_subset()` | ||
722 | 102 | followed by :meth:`plainbox.impl.exporters.SessionStateExporterBase.dump()` | ||
723 | 103 | to save results to a file. | ||
724 | 104 | |||
725 | 105 | 9. Call :meth:`plainbox.impl.session.SessionState.close()` to remove any | ||
726 | 106 | nonvolatile temporary storage that was needed for the session. | ||
727 | 107 | |||
728 | 108 | Essential classes | ||
729 | 109 | ================= | ||
730 | 110 | |||
731 | 111 | :class:`~plainbox.impl.session.SessionState` | ||
732 | 112 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
733 | 113 | |||
734 | 114 | Class representing all state needed during a single program session. | ||
735 | 115 | |||
736 | 116 | Usage | ||
737 | 117 | ----- | ||
738 | 118 | |||
739 | 119 | The general idea is that you feed the session with a list of known jobs and | ||
740 | 120 | a subset of jobs that you want to run and in return get an ordered list of | ||
741 | 121 | jobs to run. | ||
742 | 122 | |||
743 | 123 | It is expected that the user will select / deselect and run jobs. This | ||
744 | 124 | class can react to both actions by recomputing the dependency graph and | ||
745 | 125 | updating the read states accordingly. | ||
746 | 126 | |||
747 | 127 | As the user runs subsequent jobs the results of those jobs are exposed to | ||
748 | 128 | the session with :meth:`update_job_result()`. This can cause subsequent | ||
749 | 129 | jobs to become available (not inhibited by anything). Note that there is no | ||
750 | 130 | notification of changes at this time. | ||
751 | 131 | |||
752 | 132 | The session does almost nothing by itself, it learns about everything by | ||
753 | 133 | observing job results coming from the job runner | ||
754 | 134 | (:class:`plainbox.impl.runner.JobRunner`) that applications need to | ||
755 | 135 | instantiate. | ||
756 | 136 | |||
757 | 137 | Suspend and resume | ||
758 | 138 | ------------------ | ||
759 | 139 | |||
760 | 140 | The session can save check-point data after each job is executed. This | ||
761 | 141 | allows the system to survive and continue after a catastrophic failure | ||
762 | 142 | (broken suspend, power failure) or continue across tests that require the | ||
763 | 143 | machine to reboot. | ||
764 | 144 | |||
765 | 145 | .. todo:: | ||
766 | 146 | |||
767 | 147 | Create a section on suspend/resume design | ||
768 | 148 | |||
769 | 149 | Implementation notes | ||
770 | 150 | -------------------- | ||
771 | 151 | |||
772 | 152 | Internally it ties into :class:`plainbox.impl.depmgr.DependencySolver` for | ||
773 | 153 | resolving dependencies. The way the session objects are used allows them to | ||
774 | 154 | return various problems back to the UI level - those are all the error | ||
775 | 155 | classes from :mod:`plainbox.impl.depmgr`: | ||
776 | 156 | |||
777 | 157 | - :class:`plainbox.impl.depmgr.DependencyCycleError` | ||
778 | 158 | |||
779 | 159 | - :class:`plainbox.impl.depmgr.DependencyDuplicateError` | ||
780 | 160 | |||
781 | 161 | - :class:`plainbox.impl.depmgr.DependencyMissingError` | ||
782 | 162 | |||
783 | 163 | Normally *none* of those errors should ever happen, they are only provided | ||
784 | 164 | so that we don't choke when a problem really happens. Everything is checked | ||
785 | 165 | and verified early before starting a job so typical unit and integration | ||
786 | 166 | testing should capture broken job definitions (for example, with cyclic | ||
787 | 167 | dependencies) being added to the repository. | ||
788 | 168 | |||
789 | 169 | Implementation issues | ||
790 | 170 | --------------------- | ||
791 | 171 | |||
792 | 172 | There are two issues that are known at this time: | ||
793 | 173 | |||
794 | 174 | * There is too much checkbox-specific knowledge which really belongs | ||
795 | 175 | elsewhere. We are working to remove that so that non-checkbox jobs | ||
796 | 176 | can be introduced later. There is a branch in progress that entirely | ||
797 | 177 | removes that and moves it to a new concept called SessionController. | ||
798 | 178 | In that design the session delegates understanding of results to a | ||
799 | 179 | per-job session controller and exposes some APIs to alter the state | ||
800 | 180 | that was previously internal (most notably a way to add new jobs and | ||
801 | 181 | resources). | ||
802 | 182 | |||
803 | 183 | * The way jobs are currently selected is unfortunate because of local jobs | ||
804 | 184 | that can add new jobs to the system. This causes considerable complexity | ||
805 | 185 | at the application level where the application must check if each | ||
806 | 186 | executed job is a 'local' job and re-compute the desired_job_list. This | ||
807 | 187 | should be replaced by a matcher function that can be passed to | ||
808 | 188 | SessionState once so that desired_job_list is re-evaluated internally | ||
809 | 189 | whenever job_list changes. | ||
810 | 190 | |||
811 | 191 | |||
812 | 192 | :class:`~plainbox.impl.job.JobDefinition` | ||
813 | 193 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
814 | 194 | |||
815 | 195 | :term:`CheckBox` has a concept of a :term:`job`. Jobs are named units of | ||
816 | 196 | testing work that can be executed. Typical jobs range from automated CPU power | ||
817 | 197 | management checks, BIOS tests, semi-automated peripherals testing to all manual | ||
818 | 198 | validation by following a script (intended for humans). | ||
819 | 199 | |||
820 | 200 | Jobs are distributed in plain text files, formated as a loose RFC822 documents | ||
821 | 201 | where typically a single text file contains a few dozen different jobs that | ||
822 | 202 | belong to one topic, for example, all bluetooth tests. | ||
823 | 203 | |||
824 | 204 | Tests have a number of properties that will not be discussed in detail here, | ||
825 | 205 | they are all documented in :class:`plainbox.impl.job.JobDefinition`. From the | ||
826 | 206 | architecture point of view the four essential properties of a job are *name*, | ||
827 | 207 | *plugin* and *requires* and *depends*. Those are discussed in detail below. | ||
828 | 208 | |||
829 | 209 | JobDefinition.name | ||
830 | 210 | ------------------ | ||
831 | 211 | |||
832 | 212 | The *name* field must be unique and is referred to by other parts of the system | ||
833 | 213 | (such as whitelists). Typically jobs follow a simple naming pattern | ||
834 | 214 | 'category/detail', eg, 'networking/modem_connection'. The name must be _unique_ | ||
835 | 215 | and this is enforced by the core. | ||
836 | 216 | |||
837 | 217 | JobDefinition.plugin | ||
838 | 218 | -------------------- | ||
839 | 219 | |||
840 | 220 | The *plugin* field is an archaism from CheckBox and a misnomer (as PlainBox | ||
841 | 221 | does not have any plugins). In the CheckBox architecture it would instruct the | ||
842 | 222 | core which plugin should process that job. In PlainBox it is a way to encode | ||
843 | 223 | what type of a job is being processed. There is a finite set of types that are | ||
844 | 224 | documented below. | ||
845 | 225 | |||
846 | 226 | plugin == "shell" | ||
847 | 227 | ################# | ||
848 | 228 | |||
849 | 229 | This value is used for fully automated jobs. Everything the job needs to do is | ||
850 | 230 | automated (preparation, execution, verification) and fully handled by the | ||
851 | 231 | command that is associated with a job. | ||
852 | 232 | |||
853 | 233 | plugin == "manual" | ||
854 | 234 | ################## | ||
855 | 235 | |||
856 | 236 | This value is used for fully manual jobs. It has no special handling in the core | ||
857 | 237 | apart from requiring a human-provided outcome (pass/fail classification) | ||
858 | 238 | |||
859 | 239 | plugin == "local" | ||
860 | 240 | ################# | ||
861 | 241 | |||
862 | 242 | This value is used for special job generator jobs. The output of such jobs is | ||
863 | 243 | interpreted as additional jobs and is identical in effect to loading such jobs | ||
864 | 244 | from a job definition file. | ||
865 | 245 | |||
866 | 246 | There are two practical uses for such jobs: | ||
867 | 247 | |||
868 | 248 | * Some local jobs are used to generate a number of jobs for each object. | ||
869 | 249 | This is needed where the tested machine may have a number of such objects | ||
870 | 250 | and each requires unique testing. A good example is a computer where all | ||
871 | 251 | network tests are explicitly "instantiated" for each network card | ||
872 | 252 | present. | ||
873 | 253 | |||
874 | 254 | This is a valid use case but is rather unfortunate for architecture of | ||
875 | 255 | PlainBox and there is a desire to replace it with equally-expressive | ||
876 | 256 | pattern jobs. The advantage is that unlike local jobs (which cannot be | ||
877 | 257 | "discovered" without enduring any potential side effects that may be | ||
878 | 258 | caused by the job script command) pattern jobs would allow the core to | ||
879 | 259 | determine the names of jobs that can be generated and, for example, | ||
880 | 260 | automatically determine that a pattern job needs to be executed as a | ||
881 | 261 | dependency of a phantom (yet undetermined) job with a given name. | ||
882 | 262 | |||
883 | 263 | The solution with "pattern" jobs may be executed in future phases of | ||
884 | 264 | PlainBox development. Currently there is no support for that at all. | ||
885 | 265 | |||
886 | 266 | Currently PlainBox cannot determine job dependencies across local jobs. | ||
887 | 267 | That is, unless a local job is explicitly requested (in the desired job | ||
888 | 268 | list) PlainBox will not be able to run a job that is generated by a local | ||
889 | 269 | job at all and will treat it as if that job never existed. | ||
890 | 270 | |||
891 | 271 | * Some local jobs are used to create a form of informal "category". | ||
892 | 272 | Typically all such jobs have a leading and trailing double underscore, | ||
893 | 273 | for example '__audio__'. This is currently being used by CheckBox for | ||
894 | 274 | building a hierarchical tree of tests that the user may select. | ||
895 | 275 | |||
896 | 276 | Since this has the same flaws as described above (for pattern jobs) it | ||
897 | 277 | will likely be replaced by an explicit category field that can be | ||
898 | 278 | specified each job. | ||
899 | 279 | |||
900 | 280 | plugin == "resource" | ||
901 | 281 | #################### | ||
902 | 282 | |||
903 | 283 | This value is used for special "data" or "environment" jobs. Their output is | ||
904 | 284 | parsed as a list of RFC822 records and is kept by the core during a testing session. | ||
905 | 285 | |||
906 | 286 | They are primarily used to determine if a given job can be started. For | ||
907 | 287 | example, a particular bluetooth test may use the _requires_ field to indicate | ||
908 | 288 | that it depends (via a resource dependency) on a job that enumerates devices | ||
909 | 289 | and that one of those devices must be a bluetooth device. | ||
910 | 290 | |||
911 | 291 | plugin == "user-interact" | ||
912 | 292 | ######################### | ||
913 | 293 | |||
914 | 294 | For all intents and purposes it is equivalent to "manual". The actual | ||
915 | 295 | difference is that a user is expected to perform some physical manipulation | ||
916 | 296 | before an automated test. | ||
917 | 297 | |||
918 | 298 | plugin == "user-verify" | ||
919 | 299 | ####################### | ||
920 | 300 | |||
921 | 301 | For all intents and purposes it is equivalent to "manual". The actual | ||
922 | 302 | difference is that a user is expected to perform manual verification after an | ||
923 | 303 | automated test. | ||
924 | 304 | |||
925 | 305 | JobDefinition.depends | ||
926 | 306 | --------------------- | ||
927 | 307 | |||
928 | 308 | The *depends* field is used to express dependencies between two jobs. If job A | ||
929 | 309 | has depends on job B then A cannot start if B is not both finished and | ||
930 | 310 | successful. PlainBox understands this dependency and can automatically sort and | ||
931 | 311 | execute jobs in proper order. In many places of the code this is referred to as | ||
932 | 312 | a "direct dependency" (in contrast to "resource dependency") | ||
933 | 313 | |||
934 | 314 | The actual syntax is not strictly specified, PlainBox interprets this field as | ||
935 | 315 | a list of tokens delimited by comma or any whitespace (including newlines). | ||
936 | 316 | |||
937 | 317 | A job may depend on any number of other jobs. There are a number of failure | ||
938 | 318 | modes associated with this feature, all of which are detected and handled by | ||
939 | 319 | PlainBox. Typically they only arise when during CheckBox job development | ||
940 | 320 | (editing actual job files) and are always a sign of a human error. No released | ||
941 | 321 | version of CheckBox or PlainBox should ever encounter any of those issues. | ||
942 | 322 | |||
943 | 323 | The actual problems are: | ||
944 | 324 | |||
945 | 325 | * dependency cycles, where job either directly or indirectly depends on | ||
946 | 326 | itself | ||
947 | 327 | |||
948 | 328 | * missing dependencies where some job refers to a job that is not defined | ||
949 | 329 | anywhere. | ||
950 | 330 | |||
951 | 331 | * duplicate jobs where two jobs with the same name (but different | ||
952 | 332 | definition) are being introduced to the system. | ||
953 | 333 | |||
954 | 334 | In all of those cases the core removes the offending job and tries to work | ||
955 | 335 | regardless of the problem. This is intended more as a development aid rather | ||
956 | 336 | than a reliability feature as no released versions of either project should | ||
957 | 337 | cause this problem. | ||
958 | 0 | 338 | ||
959 | === added file 'plainbox/docs/dev/index.rst' | |||
960 | --- plainbox/docs/dev/index.rst 1970-01-01 00:00:00 +0000 | |||
961 | +++ plainbox/docs/dev/index.rst 2013-03-07 16:10:38 +0000 | |||
962 | @@ -0,0 +1,14 @@ | |||
963 | 1 | Developers | ||
964 | 2 | ========== | ||
965 | 3 | |||
966 | 4 | The PlainBox project hopes to be a friendly developer environment. We invested | ||
967 | 5 | in a lot of tools to make your life easier. Despite being a business-centric | ||
968 | 6 | software project we welcome and encourage contributions from both Canonical and | ||
969 | 7 | Community members. | ||
970 | 8 | |||
971 | 9 | .. toctree:: | ||
972 | 10 | :maxdepth: 3 | ||
973 | 11 | |||
974 | 12 | intro.rst | ||
975 | 13 | architecture.rst | ||
976 | 14 | reference.rst | ||
977 | 0 | 15 | ||
978 | === added file 'plainbox/docs/dev/intro.rst' | |||
979 | --- plainbox/docs/dev/intro.rst 1970-01-01 00:00:00 +0000 | |||
980 | +++ plainbox/docs/dev/intro.rst 2013-03-07 16:10:38 +0000 | |||
981 | @@ -0,0 +1,238 @@ | |||
982 | 1 | Getting started with development | ||
983 | 2 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
984 | 3 | |||
985 | 4 | PlainBox uses python3 for development. The core is really system independent | ||
986 | 5 | but you will need Ubuntu to really make the best of it and experience it as we | ||
987 | 6 | do. We encourage everyone to use the most recent Ubuntu release for | ||
988 | 7 | development. Usually this brings the best, most recent tools without having to | ||
989 | 8 | search for software on the Internet. | ||
990 | 9 | |||
991 | 10 | PlainBox has almost no dependencies itself, almost, because we depend on the | ||
992 | 11 | mighty :term:`CheckBox` project to provide us with a lot of existing | ||
993 | 12 | infrastructure. Testing PlainBox requires additional packages and some | ||
994 | 13 | non-packaged software. You will typically want to install it and take advantage | ||
995 | 14 | of the integration we provide. | ||
996 | 15 | |||
997 | 16 | .. note:: | ||
998 | 17 | |||
999 | 18 | If you are working with the source please be aware that PlainBox requires | ||
1000 | 19 | an installed copy of CheckBox. CheckBox in turns is has many scripts that | ||
1001 | 20 | depend on various system packages, including python packages that cannot be | ||
1002 | 21 | installed from pypi. If you were planning on using :command:`virtualenv` | ||
1003 | 22 | then please make sure to create it with the ``--system-site-packages`` | ||
1004 | 23 | option. | ||
1005 | 24 | |||
1006 | 25 | Get the tools | ||
1007 | 26 | ------------- | ||
1008 | 27 | |||
1009 | 28 | First, you need to install the basic development tools: | ||
1010 | 29 | |||
1011 | 30 | .. code-block:: bash | ||
1012 | 31 | |||
1013 | 32 | $ sudo apt-get install bzr python3-setuptools python3-dev python3-doc python3-sphinx python-virtualenv | ||
1014 | 33 | |||
1015 | 34 | While developing PlainBox you will often need to run potentially dangerous | ||
1016 | 35 | commands on your system, such as asking it to suspend and wake up | ||
1017 | 36 | automatically. We also need to support a range of Ubuntu releases, going all | ||
1018 | 37 | the way back to Ubuntu 12.04. This may cause compatibility issues that are | ||
1019 | 38 | unnoticed all until they hit our CI system. To minimize this PlainBox uses | ||
1020 | 39 | :term:`Vagrant` to create lightweight execution environments that transparently | ||
1021 | 40 | share your source tree and allow you to quickly create and share testing | ||
1022 | 41 | environment that can be deployed by any developer in minutes. Vagrant uses | ||
1023 | 42 | :term:`VirtualBox` and while both are packaged in Ubuntu, unless you are | ||
1024 | 43 | running Ubuntu 13.04 you should download and install the software from their | ||
1025 | 44 | upstream projects. | ||
1026 | 45 | |||
1027 | 46 | If you are running Ubuntu 13.04 | ||
1028 | 47 | |||
1029 | 48 | .. code-block:: bash | ||
1030 | 49 | |||
1031 | 50 | $ sudo apt-get install vagrant | ||
1032 | 51 | |||
1033 | 52 | If you are running earlier version of Ubuntu follow those two links to get started: | ||
1034 | 53 | |||
1035 | 54 | * http://downloads.vagrantup.com/ | ||
1036 | 55 | * https://www.virtualbox.org/wiki/Downloads | ||
1037 | 56 | |||
1038 | 57 | If you have not installed VirtualBox before, you must add yourself to the | ||
1039 | 58 | ``vboxusers`` group, log out and log back in again. | ||
1040 | 59 | |||
1041 | 60 | .. code-block:: bash | ||
1042 | 61 | |||
1043 | 62 | $ sudo usermod -G vboxusers -a $USER | ||
1044 | 63 | |||
1045 | 64 | Get the source | ||
1046 | 65 | -------------- | ||
1047 | 66 | |||
1048 | 67 | Now that you have all the tools, you can get the source: | ||
1049 | 68 | |||
1050 | 69 | .. code-block:: bash | ||
1051 | 70 | |||
1052 | 71 | $ bzr branch lp:checkbox | ||
1053 | 72 | |||
1054 | 73 | .. note:: | ||
1055 | 74 | If you would rather use ``git`` you can also do that (and in fact, some of | ||
1056 | 75 | us already do). Head to `git-lp homepage <http://zyga.github.com/git-lp/>`_ | ||
1057 | 76 | and follow the guide there to use git-lp with this project. | ||
1058 | 77 | |||
1059 | 78 | Initialize virtualenv | ||
1060 | 79 | --------------------- | ||
1061 | 80 | |||
1062 | 81 | PlainBox will use a few unpackaged and bleeding-edge releases from :term:`pypi` | ||
1063 | 82 | those are installed by additional script. By default the script assumes you | ||
1064 | 83 | have a /ramdisk directory but you can pass any path as an argument for an | ||
1065 | 84 | alternate location. | ||
1066 | 85 | |||
1067 | 86 | .. code-block:: bash | ||
1068 | 87 | |||
1069 | 88 | $ ./mk-venv.sh | ||
1070 | 89 | |||
1071 | 90 | After everything is set up you can activate the virtualenv environment with the | ||
1072 | 91 | dot command. Note that there *is* a space between the dot and the forward | ||
1073 | 92 | slash. You can repeat this command in as many shells as you like. | ||
1074 | 93 | |||
1075 | 94 | .. code-block:: bash | ||
1076 | 95 | |||
1077 | 96 | $ . /ramdisk/venv/bin/activate | ||
1078 | 97 | |||
1079 | 98 | Once virtualenv is activated your shell prompt will be changed to reflect that. | ||
1080 | 99 | You should now be able to run :command:`plainbox --help` to ensure everything | ||
1081 | 100 | is working properly. | ||
1082 | 101 | |||
1083 | 102 | Initialize vagrant | ||
1084 | 103 | ------------------ | ||
1085 | 104 | |||
1086 | 105 | Vagrant allows us to ship a tiny text file :file:`Vagrantfile` that describes | ||
1087 | 106 | the development and testing environment. This file tells :command:`vagrant` how | ||
1088 | 107 | to prepare a virtual machine for testing. If you never used it before you may | ||
1089 | 108 | want to keep a tab open on `vagrant getting started guide | ||
1090 | 109 | <http:`http://docs.vagrantup.com/v1/docs/getting-started/index.html>`_ | ||
1091 | 110 | |||
1092 | 111 | We did all the hard work so that you don't have to, to get everything ready | ||
1093 | 112 | just run one command: | ||
1094 | 113 | |||
1095 | 114 | .. code-block:: bash | ||
1096 | 115 | |||
1097 | 116 | $ vagrant up | ||
1098 | 117 | |||
1099 | 118 | This will download vanilla Ubuntu cloud images, initialize VirtualBox, | ||
1100 | 119 | provision virtual machines (one for each supported Ubuntu release) and allow | ||
1101 | 120 | you to ssh into them for testing with one command. | ||
1102 | 121 | |||
1103 | 122 | This will take a moment, depending on the speed of your network. Once that is | ||
1104 | 123 | done you should be able to log into, say, ``precise`` and run | ||
1105 | 124 | :command:`plainbox --help` to see if everything is all right. | ||
1106 | 125 | |||
1107 | 126 | .. code-block:: bash | ||
1108 | 127 | |||
1109 | 128 | $ vagrant ssh precise | ||
1110 | 129 | vagrant@vagrant-ubuntu-precise-32:~$ plainbox --help | ||
1111 | 130 | usage: plainbox [-h] [-v] {run,special,self-test} ... | ||
1112 | 131 | |||
1113 | 132 | positional arguments: | ||
1114 | 133 | {run,special,self-test} | ||
1115 | 134 | run run a test job | ||
1116 | 135 | special special/internal commands | ||
1117 | 136 | self-test run integration tests | ||
1118 | 137 | |||
1119 | 138 | optional arguments: | ||
1120 | 139 | -h, --help show this help message and exit | ||
1121 | 140 | -v, --version show program's version number and exit | ||
1122 | 141 | $ exit | ||
1123 | 142 | |||
1124 | 143 | Running PlainBox tests | ||
1125 | 144 | ^^^^^^^^^^^^^^^^^^^^^^ | ||
1126 | 145 | |||
1127 | 146 | PlainBox is designed to be testable so it would be silly if it was hard to run | ||
1128 | 147 | tests. Actually, there are many different ways to run tests. They all run the | ||
1129 | 148 | same code so don't worry. | ||
1130 | 149 | |||
1131 | 150 | To test the current code you are working on you can: | ||
1132 | 151 | |||
1133 | 152 | - Run the :command:`./test-in-vagrant.sh` from the plainbox directory. This | ||
1134 | 153 | will take the longes but will go over *all* the tests on *all* the supported | ||
1135 | 154 | versions of Ubuntu. It will run CheckBox unit-tests, PlainBox unit-tests and | ||
1136 | 155 | it will even run integration tests that actually execute jobs. | ||
1137 | 156 | |||
1138 | 157 | - Run :command:`plainbox self-test --unit-tests` or | ||
1139 | 158 | :command:`plainbox self-test --integration-tests`. This will execute all the | ||
1140 | 159 | tests right on your machine, without any virtualization (well, unless you do | ||
1141 | 160 | that after running :command:`vagrant ssh`). Typically you would run unit | ||
1142 | 161 | tests while being in a ``virtualenv`` with the ``plainbox`` package in | ||
1143 | 162 | development mode, as created by running :command:`python setup.py develop` | ||
1144 | 163 | |||
1145 | 164 | - Run :command:`./setup.py test` this will install any required test | ||
1146 | 165 | dependencies from pypi and run unit tests. | ||
1147 | 166 | |||
1148 | 167 | - Run the script :command:`test-with-coverage.sh` while being in a virtualenv. | ||
1149 | 168 | This will also compute testing code coverage and is very much recommended | ||
1150 | 169 | while working on new code and tests. | ||
1151 | 170 | |||
1152 | 171 | Submitting Patches | ||
1153 | 172 | ^^^^^^^^^^^^^^^^^^ | ||
1154 | 173 | |||
1155 | 174 | We use `Launchpad <https://launchpad.net>`_ for most of our project management. | ||
1156 | 175 | All code changes should be submitted as merge requests. Launchpad has | ||
1157 | 176 | `extensive documentation <https://help.launchpad.net/>`_ on how to use various | ||
1158 | 177 | facilities it provides. | ||
1159 | 178 | |||
1160 | 179 | In general we are open to contributions but we reserve the right to reject | ||
1161 | 180 | patches if they don't fit into the needs of the :term:`Hardware Certification`. | ||
1162 | 181 | If you have an idea go and talk to us on :abbr:`IRC (Internet Relay Chat)` on | ||
1163 | 182 | the `#ubuntu-quality <irc://freenode.net:8001/#ubuntu-quality>`_ channel. | ||
1164 | 183 | |||
1165 | 184 | We have some basic rules patch acceptance: | ||
1166 | 185 | |||
1167 | 186 | 0. Be prepare to alter your changes. | ||
1168 | 187 | |||
1169 | 188 | This is a meta-rule. One of the points of code reviews is to improve the | ||
1170 | 189 | proposal. That implies the proposal may need to change. You must be prepared | ||
1171 | 190 | and able to change your code after getting feedback. | ||
1172 | 191 | |||
1173 | 192 | To do that efficiently you must structure your work in a way where each | ||
1174 | 193 | committed change works for you rather than against you. The rules listed | ||
1175 | 194 | below are a reflection of this. | ||
1176 | 195 | |||
1177 | 196 | 1. Each patch should be a single logical change that can be applied. | ||
1178 | 197 | |||
1179 | 198 | Don't clump lots of changes into one big patch. That will only delay review, | ||
1180 | 199 | make accepting feedback difficult and annoying. This may mean that the history | ||
1181 | 200 | has many small patches that can land in trunk in a FIFO mode. The oldest patch | ||
1182 | 201 | of your branch may be allowed to land and should make sense. This has | ||
1183 | 202 | implications on how general code editing should be performed. If you break some | ||
1184 | 203 | APIs then firsts introduce a working replacement, then change usage of the API | ||
1185 | 204 | and lastly remove any dead code. | ||
1186 | 205 | |||
1187 | 206 | 2. Don't keep junk patches in your branch. | ||
1188 | 207 | |||
1189 | 208 | Don't keep patches such as "fix typo" in your branch, that makes the review | ||
1190 | 209 | process more difficult as some reviewers will read your patches one by one. | ||
1191 | 210 | This is especially important if your changes are substantial. | ||
1192 | 211 | |||
1193 | 212 | 3. Don't merge with trunk, rebase on trunk. | ||
1194 | 213 | |||
1195 | 214 | This way you can keep your local delta as a collection of meaningful, | ||
1196 | 215 | readable patches. Reading the full diff and following the complex merge | ||
1197 | 216 | history (especially for long-lived branches) is difficult in practice. | ||
1198 | 217 | |||
1199 | 218 | 4. Keep unrelated changes in separate branches. | ||
1200 | 219 | |||
1201 | 220 | If you ware working on something and found a bug that needed immediate | ||
1202 | 221 | fixing, typo or anything else that is small and quick to fix, do it. Then | ||
1203 | 222 | take that patch out of your development branch and into a dedicated branch | ||
1204 | 223 | and propose it. As the small change is reviewed and lands you can remove | ||
1205 | 224 | that patch from your development branch. | ||
1206 | 225 | |||
1207 | 226 | This is intended to help both the developer and the reviewer. Seemingly | ||
1208 | 227 | trivial patches may turn out to be more complicated than initially assumed | ||
1209 | 228 | (and may have their own feedback cycle and iterations). The reviewer can | ||
1210 | 229 | focus on logical changes and not on a collection of unrelated alterations. | ||
1211 | 230 | Lastly we may need to apply some fixes to other supported branches and | ||
1212 | 231 | release those. | ||
1213 | 232 | |||
1214 | 233 | 5. Don't propose untested code. | ||
1215 | 234 | |||
1216 | 235 | We generally like tests for new code. This is not a super-strict requirement | ||
1217 | 236 | but unless writing tests is incredibly hard we'd rather wait. If testing is | ||
1218 | 237 | hard we'd rather invest some time in refactoring the code or building | ||
1219 | 238 | required support infrastructure. | ||
1220 | 0 | 239 | ||
1221 | === added file 'plainbox/docs/dev/reference.rst' | |||
1222 | --- plainbox/docs/dev/reference.rst 1970-01-01 00:00:00 +0000 | |||
1223 | +++ plainbox/docs/dev/reference.rst 2013-03-07 16:10:38 +0000 | |||
1224 | @@ -0,0 +1,154 @@ | |||
1225 | 1 | .. _code_reference: | ||
1226 | 2 | |||
1227 | 3 | .. toctree:: | ||
1228 | 4 | :maxdepth: 2 | ||
1229 | 5 | |||
1230 | 6 | Code reference | ||
1231 | 7 | ============== | ||
1232 | 8 | |||
1233 | 9 | .. note:: | ||
1234 | 10 | |||
1235 | 11 | Unless stated otherwise all API is unstable. PlainBox does not offer | ||
1236 | 12 | general API stability at this time. | ||
1237 | 13 | |||
1238 | 14 | .. automodule:: plainbox | ||
1239 | 15 | :members: | ||
1240 | 16 | :undoc-members: | ||
1241 | 17 | :show-inheritance: | ||
1242 | 18 | |||
1243 | 19 | .. automodule:: plainbox.public | ||
1244 | 20 | :members: | ||
1245 | 21 | :undoc-members: | ||
1246 | 22 | :show-inheritance: | ||
1247 | 23 | |||
1248 | 24 | .. automodule:: plainbox.abc | ||
1249 | 25 | :members: | ||
1250 | 26 | :undoc-members: | ||
1251 | 27 | :show-inheritance: | ||
1252 | 28 | |||
1253 | 29 | .. automodule:: plainbox.tests | ||
1254 | 30 | :members: | ||
1255 | 31 | :undoc-members: | ||
1256 | 32 | :show-inheritance: | ||
1257 | 33 | |||
1258 | 34 | .. automodule:: plainbox.testing_utils | ||
1259 | 35 | :members: | ||
1260 | 36 | :undoc-members: | ||
1261 | 37 | :show-inheritance: | ||
1262 | 38 | |||
1263 | 39 | .. automodule:: plainbox.testing_utils.cwd | ||
1264 | 40 | :members: | ||
1265 | 41 | :undoc-members: | ||
1266 | 42 | :show-inheritance: | ||
1267 | 43 | |||
1268 | 44 | .. automodule:: plainbox.testing_utils.io | ||
1269 | 45 | :members: | ||
1270 | 46 | :undoc-members: | ||
1271 | 47 | :show-inheritance: | ||
1272 | 48 | |||
1273 | 49 | .. automodule:: plainbox.testing_utils.testcases | ||
1274 | 50 | :members: | ||
1275 | 51 | :undoc-members: | ||
1276 | 52 | :show-inheritance: | ||
1277 | 53 | |||
1278 | 54 | .. automodule:: plainbox.vendor | ||
1279 | 55 | :members: | ||
1280 | 56 | |||
1281 | 57 | .. automodule:: plainbox.vendor.extcmd | ||
1282 | 58 | :members: | ||
1283 | 59 | :undoc-members: | ||
1284 | 60 | :show-inheritance: | ||
1285 | 61 | |||
1286 | 62 | .. automodule:: plainbox.impl | ||
1287 | 63 | :members: | ||
1288 | 64 | :undoc-members: | ||
1289 | 65 | :show-inheritance: | ||
1290 | 66 | |||
1291 | 67 | .. automodule:: plainbox.impl.commands | ||
1292 | 68 | :members: | ||
1293 | 69 | :undoc-members: | ||
1294 | 70 | :show-inheritance: | ||
1295 | 71 | |||
1296 | 72 | .. automodule:: plainbox.impl.commands.selftest | ||
1297 | 73 | :members: | ||
1298 | 74 | :undoc-members: | ||
1299 | 75 | :show-inheritance: | ||
1300 | 76 | |||
1301 | 77 | .. automodule:: plainbox.impl.exporter | ||
1302 | 78 | :members: | ||
1303 | 79 | :undoc-members: | ||
1304 | 80 | :show-inheritance: | ||
1305 | 81 | |||
1306 | 82 | .. automodule:: plainbox.impl.exporter.json | ||
1307 | 83 | :members: | ||
1308 | 84 | :undoc-members: | ||
1309 | 85 | :show-inheritance: | ||
1310 | 86 | |||
1311 | 87 | .. automodule:: plainbox.impl.exporter.rfc822 | ||
1312 | 88 | :members: | ||
1313 | 89 | :undoc-members: | ||
1314 | 90 | :show-inheritance: | ||
1315 | 91 | |||
1316 | 92 | .. automodule:: plainbox.impl.exporter.text | ||
1317 | 93 | :members: | ||
1318 | 94 | :undoc-members: | ||
1319 | 95 | :show-inheritance: | ||
1320 | 96 | |||
1321 | 97 | .. automodule:: plainbox.impl.box | ||
1322 | 98 | :members: | ||
1323 | 99 | :undoc-members: | ||
1324 | 100 | :show-inheritance: | ||
1325 | 101 | |||
1326 | 102 | .. automodule:: plainbox.impl.checkbox | ||
1327 | 103 | :members: | ||
1328 | 104 | :undoc-members: | ||
1329 | 105 | :show-inheritance: | ||
1330 | 106 | |||
1331 | 107 | .. automodule:: plainbox.impl.depmgr | ||
1332 | 108 | :members: | ||
1333 | 109 | :undoc-members: | ||
1334 | 110 | :show-inheritance: | ||
1335 | 111 | |||
1336 | 112 | .. automodule:: plainbox.impl.integration_tests | ||
1337 | 113 | :members: | ||
1338 | 114 | :undoc-members: | ||
1339 | 115 | :show-inheritance: | ||
1340 | 116 | |||
1341 | 117 | .. automodule:: plainbox.impl.job | ||
1342 | 118 | :members: | ||
1343 | 119 | :undoc-members: | ||
1344 | 120 | :show-inheritance: | ||
1345 | 121 | |||
1346 | 122 | .. automodule:: plainbox.impl.mock_job | ||
1347 | 123 | :members: | ||
1348 | 124 | :undoc-members: | ||
1349 | 125 | :show-inheritance: | ||
1350 | 126 | |||
1351 | 127 | .. automodule:: plainbox.impl.resource | ||
1352 | 128 | :members: | ||
1353 | 129 | :undoc-members: | ||
1354 | 130 | :show-inheritance: | ||
1355 | 131 | |||
1356 | 132 | .. automodule:: plainbox.impl.result | ||
1357 | 133 | :members: | ||
1358 | 134 | :undoc-members: | ||
1359 | 135 | :show-inheritance: | ||
1360 | 136 | |||
1361 | 137 | .. automodule:: plainbox.impl.rfc822 | ||
1362 | 138 | :members: | ||
1363 | 139 | :show-inheritance: | ||
1364 | 140 | |||
1365 | 141 | .. automodule:: plainbox.impl.runner | ||
1366 | 142 | :members: | ||
1367 | 143 | :undoc-members: | ||
1368 | 144 | :show-inheritance: | ||
1369 | 145 | |||
1370 | 146 | .. automodule:: plainbox.impl.session | ||
1371 | 147 | :members: | ||
1372 | 148 | :undoc-members: | ||
1373 | 149 | :show-inheritance: | ||
1374 | 150 | |||
1375 | 151 | .. automodule:: plainbox.impl.testing_utils | ||
1376 | 152 | :members: | ||
1377 | 153 | :undoc-members: | ||
1378 | 154 | :show-inheritance: | ||
1379 | 0 | 155 | ||
1380 | === added file 'plainbox/docs/glossary.rst' | |||
1381 | --- plainbox/docs/glossary.rst 1970-01-01 00:00:00 +0000 | |||
1382 | +++ plainbox/docs/glossary.rst 2013-03-07 16:10:38 +0000 | |||
1383 | @@ -0,0 +1,104 @@ | |||
1384 | 1 | Glossary | ||
1385 | 2 | ======== | ||
1386 | 3 | |||
1387 | 4 | .. glossary:: | ||
1388 | 5 | |||
1389 | 6 | hardware certification | ||
1390 | 7 | |||
1391 | 8 | A process of ensuring that a specific device works well with Ubuntu. | ||
1392 | 9 | For more details see our certification program: | ||
1393 | 10 | |||
1394 | 11 | http://www.canonical.com/engineering-services/certification/hardware-certification | ||
1395 | 12 | |||
1396 | 13 | hardware certification team | ||
1397 | 14 | |||
1398 | 15 | A team inside Canonical working on :term:`Hardware Certification`. | ||
1399 | 16 | |||
1400 | 17 | CheckBox | ||
1401 | 18 | |||
1402 | 19 | CheckBox is a hardware testing tool developed by Canonical for | ||
1403 | 20 | certifying hardware with Ubuntu. CheckBox is free software and is | ||
1404 | 21 | available at http://launchpad.net/checkbox. The ``checkbox`` package is | ||
1405 | 22 | pre-installed on all Ubuntu systems | ||
1406 | 23 | |||
1407 | 24 | PlainBox | ||
1408 | 25 | |||
1409 | 26 | PlainBox is a rewrite of CheckBox with the aim of improving internal | ||
1410 | 27 | architecture, testability, robustness, quality and speed. It is | ||
1411 | 28 | currently under active development. It is not pre-installed on Ubuntu. | ||
1412 | 29 | It is developed inside CheckBox code repository. | ||
1413 | 30 | |||
1414 | 31 | white list | ||
1415 | 32 | |||
1416 | 33 | White lists are text files used by CheckBox to select Jobs for | ||
1417 | 34 | execution. They can include simple regular expressions to match and | ||
1418 | 35 | pick many similar jobs at once. | ||
1419 | 36 | |||
1420 | 37 | job | ||
1421 | 38 | |||
1422 | 39 | Jobs are smallest units of testing that can be performed by either | ||
1423 | 40 | CheckBox or PlainBox. All jobs have an unique name. There are many | ||
1424 | 41 | types of jobs, some are fully automated others are fully manual. Some | ||
1425 | 42 | jobs are only an implementation detail and a part of the internal | ||
1426 | 43 | architecture of CheckBox | ||
1427 | 44 | |||
1428 | 45 | resources | ||
1429 | 46 | |||
1430 | 47 | Resources are collections of key-value data sets that are generated by | ||
1431 | 48 | special resource jobs. They are extensively used to indicate hardware | ||
1432 | 49 | or software dependencies. For example a bluetooth test may indicate it | ||
1433 | 50 | requires bluetooth hardware and appropriate software packages | ||
1434 | 51 | installed. | ||
1435 | 52 | |||
1436 | 53 | requirement program | ||
1437 | 54 | |||
1438 | 55 | Requirement programs are small (one to few lines) programs that use a | ||
1439 | 56 | subset of python to execute some code against resources. They are what | ||
1440 | 57 | actually describes the relationship of a Job to some Resources. For | ||
1441 | 58 | example a resource program ``package.name == "bluez"`` indicates that | ||
1442 | 59 | at least one resource generated by the ``package`` job has a key | ||
1443 | 60 | ``name`` equal to the string ``bluez``. | ||
1444 | 61 | |||
1445 | 62 | attachment | ||
1446 | 63 | |||
1447 | 64 | Attachments are a special type of a Job that can creates an attachment | ||
1448 | 65 | record in the submission.xml file. They are commonly used to include | ||
1449 | 66 | basic system information files and output of certain commands which can | ||
1450 | 67 | aid in system certification. | ||
1451 | 68 | |||
1452 | 69 | certification website | ||
1453 | 70 | |||
1454 | 71 | The website https://certification.canonical.com/ | ||
1455 | 72 | |||
1456 | 73 | Canonical ID | ||
1457 | 74 | |||
1458 | 75 | A number assigned to the specific device (laptop, desktop or server) by | ||
1459 | 76 | Canonical. This number is used on the Certification Website and by the | ||
1460 | 77 | Hardware Certification Team. It is an internal bookkeeping identifier | ||
1461 | 78 | used in our labs. | ||
1462 | 79 | |||
1463 | 80 | Secure ID | ||
1464 | 81 | |||
1465 | 82 | An identifier, similar to Canonical ID, used for hardware | ||
1466 | 83 | certification. This identifier is used when interacting with the | ||
1467 | 84 | Certification Website, it does not reveal anything about the actual | ||
1468 | 85 | hardware (like the manufacturer name or device name) | ||
1469 | 86 | |||
1470 | 87 | pypi | ||
1471 | 88 | |||
1472 | 89 | The Python Package Index where any developer can share their python | ||
1473 | 90 | programs and libraries. Pypi is available at: | ||
1474 | 91 | https://pypi.python.org/pypi. | ||
1475 | 92 | |||
1476 | 93 | Vagrant | ||
1477 | 94 | |||
1478 | 95 | Vagrant is command line program intended for software developers to | ||
1479 | 96 | quickly create portable virtual environments for testing their software | ||
1480 | 97 | in a production operating system. Vagrant is free software and is | ||
1481 | 98 | available at http://www.vagrantup.com/ | ||
1482 | 99 | |||
1483 | 100 | VirtualBox | ||
1484 | 101 | |||
1485 | 102 | VirtualBox is a free, powerful desktop vitalization software. | ||
1486 | 103 | VirtualBox is available in the Ubuntu Software Center and at | ||
1487 | 104 | https://www.virtualbox.org/ | ||
1488 | 0 | 105 | ||
1489 | === modified file 'plainbox/docs/index.rst' | |||
1490 | --- plainbox/docs/index.rst 2013-02-22 16:26:25 +0000 | |||
1491 | +++ plainbox/docs/index.rst 2013-03-07 16:10:38 +0000 | |||
1492 | @@ -3,15 +3,56 @@ | |||
1493 | 3 | You can adapt this file completely to your liking, but it should at least | 3 | You can adapt this file completely to your liking, but it should at least |
1494 | 4 | contain the root `toctree` directive. | 4 | contain the root `toctree` directive. |
1495 | 5 | 5 | ||
1500 | 6 | Welcome to PlainBox's documentation! | 6 | PlainBox |
1501 | 7 | ==================================== | 7 | ======== |
1502 | 8 | 8 | ||
1503 | 9 | Contents: | 9 | :term:`PlainBox` is a hardware testing tool useful for certifying laptops, |
1504 | 10 | desktops and servers with Ubuntu. It is a replacement for the current | ||
1505 | 11 | certification tool, :term:`CheckBox`. | ||
1506 | 12 | |||
1507 | 13 | PlainBox *complements* CheckBox. It uses all the hardware test definitions, | ||
1508 | 14 | scripts and libraries from CheckBox. PlainBox is currently in **alpha** stages, | ||
1509 | 15 | having mostly but not entirely complete core and a developer-centric command | ||
1510 | 16 | line interface. | ||
1511 | 17 | |||
1512 | 18 | Installation | ||
1513 | 19 | ^^^^^^^^^^^^ | ||
1514 | 20 | |||
1515 | 21 | PlainBox can be installed from a :abbr:`PPA (Personal Package Archive)` | ||
1516 | 22 | (recommended) or :abbr:`pypi (python package index)` on Ubuntu Precise (12.04) | ||
1517 | 23 | or newer. | ||
1518 | 24 | |||
1519 | 25 | .. code-block:: bash | ||
1520 | 26 | |||
1521 | 27 | $ sudo add-apt-repository ppa:checkbox-dev/ppa && sudo apt-get update && sudo apt-get install plainbox | ||
1522 | 28 | |||
1523 | 29 | |||
1524 | 30 | Testing your hardware | ||
1525 | 31 | ^^^^^^^^^^^^^^^^^^^^^ | ||
1526 | 32 | |||
1527 | 33 | To test your hardware with the default set of tests run this command. | ||
1528 | 34 | |||
1529 | 35 | .. code-block:: bash | ||
1530 | 36 | |||
1531 | 37 | $ plainbox run --whitelist=default --output-format=xml --output-file=submission.xml | ||
1532 | 38 | |||
1533 | 39 | The :file:`submission.xml` you get in the end can be submitted to the | ||
1534 | 40 | :term:`certification website`. For more details see :ref:`usage` | ||
1535 | 41 | |||
1536 | 42 | .. todo:: | ||
1537 | 43 | This example is bad because it is fake. We should improve the core so that | ||
1538 | 44 | a whitelist can referred to by name alone (not by a full path). | ||
1539 | 45 | |||
1540 | 46 | Table of contents | ||
1541 | 47 | ================= | ||
1542 | 10 | 48 | ||
1543 | 11 | .. toctree:: | 49 | .. toctree:: |
1544 | 12 | :maxdepth: 2 | 50 | :maxdepth: 2 |
1545 | 13 | 51 | ||
1547 | 14 | 52 | usage.rst | |
1548 | 53 | dev/index.rst | ||
1549 | 54 | glossary.rst | ||
1550 | 55 | changelog.rst | ||
1551 | 15 | 56 | ||
1552 | 16 | Indices and tables | 57 | Indices and tables |
1553 | 17 | ================== | 58 | ================== |
1554 | @@ -19,4 +60,3 @@ | |||
1555 | 19 | * :ref:`genindex` | 60 | * :ref:`genindex` |
1556 | 20 | * :ref:`modindex` | 61 | * :ref:`modindex` |
1557 | 21 | * :ref:`search` | 62 | * :ref:`search` |
1558 | 22 | |||
1559 | 23 | 63 | ||
1560 | === added file 'plainbox/docs/usage.rst' | |||
1561 | --- plainbox/docs/usage.rst 1970-01-01 00:00:00 +0000 | |||
1562 | +++ plainbox/docs/usage.rst 2013-03-07 16:10:38 +0000 | |||
1563 | @@ -0,0 +1,69 @@ | |||
1564 | 1 | .. _usage: | ||
1565 | 2 | |||
1566 | 3 | Usage | ||
1567 | 4 | ===== | ||
1568 | 5 | |||
1569 | 6 | Currently :term:`PlainBox` has no graphical user interface. To use it you need | ||
1570 | 7 | to use the command line. | ||
1571 | 8 | |||
1572 | 9 | Basically there is just one command that does everything we can do so far, that | ||
1573 | 10 | is :command:`plainbox run`. It has a number of options that tell it which | ||
1574 | 11 | :term:`job` to run and what to do with results. | ||
1575 | 12 | |||
1576 | 13 | PlainBox has built-in help system so running :command:`plainbox run --help` | ||
1577 | 14 | will give you instant information about all the various arguments and options | ||
1578 | 15 | that are available. This document is not intended to replace that. | ||
1579 | 16 | |||
1580 | 17 | Running a specific job | ||
1581 | 18 | ^^^^^^^^^^^^^^^^^^^^^^ | ||
1582 | 19 | |||
1583 | 20 | To run a specific :term:`job` pass it to the ``--include-pattern`` or ``-i`` | ||
1584 | 21 | option. | ||
1585 | 22 | |||
1586 | 23 | For example, to run the ``cpu/scaling_test`` job: | ||
1587 | 24 | |||
1588 | 25 | .. code-block:: bash | ||
1589 | 26 | |||
1590 | 27 | $ plainbox run -i cpu/scaling_test | ||
1591 | 28 | |||
1592 | 29 | .. note:: | ||
1593 | 30 | |||
1594 | 31 | The option ``-i`` can be provided any number of times. | ||
1595 | 32 | |||
1596 | 33 | Running jobs related to a specific area | ||
1597 | 34 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
1598 | 35 | |||
1599 | 36 | PlainBox has no concept of job categories but you can simulate that by | ||
1600 | 37 | running all jobs that follow a specific naming pattern. For example, to run | ||
1601 | 38 | all of the USB tests you can run the following command: | ||
1602 | 39 | |||
1603 | 40 | .. code-block:: bash | ||
1604 | 41 | |||
1605 | 42 | $ plainbox run -i 'usb/' | ||
1606 | 43 | |||
1607 | 44 | Running a white list | ||
1608 | 45 | ^^^^^^^^^^^^^^^^^^^^ | ||
1609 | 46 | |||
1610 | 47 | To run a :term:`white list` pass the ``--whitelist`` or ``-w`` option. | ||
1611 | 48 | |||
1612 | 49 | For example, to run the default white list run: | ||
1613 | 50 | |||
1614 | 51 | .. code-block:: bash | ||
1615 | 52 | |||
1616 | 53 | $ plainbox run -w default | ||
1617 | 54 | |||
1618 | 55 | Saving test results as XML | ||
1619 | 56 | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
1620 | 57 | |||
1621 | 58 | To send test results to the :term:`certification website` you need to pass two | ||
1622 | 59 | additional options: | ||
1623 | 60 | |||
1624 | 61 | 1. ``--output-format=xml`` | ||
1625 | 62 | 2. ``--output-file=NAME`` where *NAME* is a file name | ||
1626 | 63 | |||
1627 | 64 | For example, to get the default certification tests ready to be submitted | ||
1628 | 65 | run this command: | ||
1629 | 66 | |||
1630 | 67 | .. code-block:: bash | ||
1631 | 68 | |||
1632 | 69 | $ plainbox run -w default -f xml -o submission.xml | ||
1633 | 0 | 70 | ||
1634 | === modified file 'plainbox/plainbox/__init__.py' | |||
1635 | --- plainbox/plainbox/__init__.py 2012-11-29 00:59:03 +0000 | |||
1636 | +++ plainbox/plainbox/__init__.py 2013-03-07 16:10:38 +0000 | |||
1637 | @@ -18,13 +18,13 @@ | |||
1638 | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. |
1639 | 19 | 19 | ||
1640 | 20 | """ | 20 | """ |
1643 | 21 | plainbox | 21 | :mod:`plainbox` -- main package |
1644 | 22 | ======== | 22 | =============================== |
1645 | 23 | 23 | ||
1646 | 24 | Simple checkbox redesign, without the complex message passing | 24 | Simple checkbox redesign, without the complex message passing |
1647 | 25 | 25 | ||
1650 | 26 | All public API is in the 'public' module. | 26 | All public API is in :mod:`plainbox.public`. |
1651 | 27 | All abstract base classes are in the 'abc' module. | 27 | All abstract base classes are in :mod:`plainbox.abc`. |
1652 | 28 | """ | 28 | """ |
1653 | 29 | 29 | ||
1654 | 30 | import sys | 30 | import sys |
1655 | 31 | 31 | ||
1656 | === modified file 'plainbox/plainbox/abc.py' | |||
1657 | --- plainbox/plainbox/abc.py 2012-11-29 18:40:46 +0000 | |||
1658 | +++ plainbox/plainbox/abc.py 2013-03-07 16:10:38 +0000 | |||
1659 | @@ -18,10 +18,8 @@ | |||
1660 | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. |
1661 | 19 | 19 | ||
1662 | 20 | """ | 20 | """ |
1667 | 21 | plainbox.abc | 21 | :mod:`plainbox.abc` -- abstract base classes |
1668 | 22 | ============ | 22 | ============================================ |
1665 | 23 | |||
1666 | 24 | Abstract base classes used by plainbox | ||
1669 | 25 | 23 | ||
1670 | 26 | Those classes are actually implemented in the plainbox.impl package. This | 24 | Those classes are actually implemented in the plainbox.impl package. This |
1671 | 27 | module is here so that the essential API concepts are in a single spot and are | 25 | module is here so that the essential API concepts are in a single spot and are |
1672 | 28 | 26 | ||
1673 | === modified file 'plainbox/plainbox/impl/__init__.py' | |||
1674 | --- plainbox/plainbox/impl/__init__.py 2012-11-19 10:45:46 +0000 | |||
1675 | +++ plainbox/plainbox/impl/__init__.py 2013-03-07 16:10:38 +0000 | |||
1676 | @@ -18,10 +18,12 @@ | |||
1677 | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. |
1678 | 19 | 19 | ||
1679 | 20 | """ | 20 | """ |
1684 | 21 | plainbox.impl | 21 | :mod:`plainbox.impl` -- implementation package |
1685 | 22 | ============= | 22 | ============================================== |
1686 | 23 | 23 | ||
1687 | 24 | * THIS MODULE DOES NOT HAVE STABLE PUBLIC API * | 24 | .. warning:: |
1688 | 25 | |||
1689 | 26 | THIS MODULE DOES NOT HAVE STABLE PUBLIC API | ||
1690 | 25 | """ | 27 | """ |
1691 | 26 | 28 | ||
1692 | 27 | from functools import wraps | 29 | from functools import wraps |
1693 | 28 | 30 | ||
1694 | === modified file 'plainbox/plainbox/impl/box.py' | |||
1695 | --- plainbox/plainbox/impl/box.py 2013-02-22 16:26:25 +0000 | |||
1696 | +++ plainbox/plainbox/impl/box.py 2013-03-07 16:10:38 +0000 | |||
1697 | @@ -18,12 +18,12 @@ | |||
1698 | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. |
1699 | 19 | 19 | ||
1700 | 20 | """ | 20 | """ |
1707 | 21 | plainbox.impl.box | 21 | :mod:`plainbox.impl.box` -- command line interface |
1708 | 22 | ================= | 22 | ================================================== |
1709 | 23 | 23 | ||
1710 | 24 | Internal implementation of plainbox | 24 | .. warning:: |
1711 | 25 | 25 | ||
1712 | 26 | * THIS MODULE DOES NOT HAVE STABLE PUBLIC API * | 26 | THIS MODULE DOES NOT HAVE STABLE PUBLIC API |
1713 | 27 | """ | 27 | """ |
1714 | 28 | 28 | ||
1715 | 29 | from argparse import ArgumentParser | 29 | from argparse import ArgumentParser |
1716 | @@ -34,6 +34,7 @@ | |||
1717 | 34 | from logging import getLogger | 34 | from logging import getLogger |
1718 | 35 | from os.path import join | 35 | from os.path import join |
1719 | 36 | import argparse | 36 | import argparse |
1720 | 37 | import re | ||
1721 | 37 | import sys | 38 | import sys |
1722 | 38 | 39 | ||
1723 | 39 | from plainbox import __version__ as version | 40 | from plainbox import __version__ as version |
1724 | @@ -71,10 +72,16 @@ | |||
1725 | 71 | group.add_argument( | 72 | group.add_argument( |
1726 | 72 | '-i', '--include-pattern', action="append", | 73 | '-i', '--include-pattern', action="append", |
1727 | 73 | metavar='PATTERN', default=[], dest='include_pattern_list', | 74 | metavar='PATTERN', default=[], dest='include_pattern_list', |
1729 | 74 | help="Run jobs matching the given pattern") | 75 | help=("Run jobs matching the given regular expression. Matches " |
1730 | 76 | "from the start to the end of the line.")) | ||
1731 | 77 | group.add_argument( | ||
1732 | 78 | '-x', '--exclude-pattern', action="append", | ||
1733 | 79 | metavar="PATTERN", default=[], dest='exclude_pattern_list', | ||
1734 | 80 | help=("Do not run jobs matching the given regular expression. " | ||
1735 | 81 | "Matches from the start to the end of the line.")) | ||
1736 | 75 | # TODO: Find a way to handle the encoding of the file | 82 | # TODO: Find a way to handle the encoding of the file |
1737 | 76 | group.add_argument( | 83 | group.add_argument( |
1739 | 77 | '-W', '--whitelist', | 84 | '-w', '--whitelist', |
1740 | 78 | metavar="WHITELIST", | 85 | metavar="WHITELIST", |
1741 | 79 | type=FileType("rt"), | 86 | type=FileType("rt"), |
1742 | 80 | help="Load whitelist containing run patterns") | 87 | help="Load whitelist containing run patterns") |
1743 | @@ -88,18 +95,36 @@ | |||
1744 | 88 | def _get_matching_job_list(self, ns, job_list): | 95 | def _get_matching_job_list(self, ns, job_list): |
1745 | 89 | # Find jobs that matched patterns | 96 | # Find jobs that matched patterns |
1746 | 90 | matching_job_list = [] | 97 | matching_job_list = [] |
1747 | 98 | # Pre-seed the include pattern list with data read from | ||
1748 | 99 | # the whitelist file. | ||
1749 | 91 | if ns.whitelist: | 100 | if ns.whitelist: |
1752 | 92 | ns.include_pattern_list.extend([pattern.strip() for pattern in | 101 | ns.include_pattern_list.extend([ |
1753 | 93 | ns.whitelist.readlines()]) | 102 | pattern.strip() |
1754 | 103 | for pattern in ns.whitelist.readlines()]) | ||
1755 | 104 | # Decide which of the known jobs to include | ||
1756 | 94 | for job in job_list: | 105 | for job in job_list: |
1760 | 95 | for pattern in ns.include_pattern_list: | 106 | # Reject all jobs that match any of the exclude |
1761 | 96 | if fnmatch(job.name, pattern): | 107 | # patterns, matching strictly from the start to |
1762 | 97 | matching_job_list.append(job) | 108 | # the end of the line. |
1763 | 109 | for pattern in ns.exclude_pattern_list: | ||
1764 | 110 | if re.match(r"^{pattern}$".format(pattern=pattern), job.name): | ||
1765 | 98 | break | 111 | break |
1766 | 112 | else: | ||
1767 | 113 | # Then accept (include) all job that matches | ||
1768 | 114 | # any of include patterns, matching strictly | ||
1769 | 115 | # from the start to the end of the line. | ||
1770 | 116 | for pattern in ns.include_pattern_list: | ||
1771 | 117 | if re.match(r"^{pattern}$".format(pattern=pattern), | ||
1772 | 118 | job.name): | ||
1773 | 119 | matching_job_list.append(job) | ||
1774 | 120 | break | ||
1775 | 99 | return matching_job_list | 121 | return matching_job_list |
1776 | 100 | 122 | ||
1777 | 101 | 123 | ||
1778 | 102 | class SpecialCommand(PlainBoxCommand, CheckBoxCommandMixIn): | 124 | class SpecialCommand(PlainBoxCommand, CheckBoxCommandMixIn): |
1779 | 125 | """ | ||
1780 | 126 | Implementation of ``$ plainbox special`` | ||
1781 | 127 | """ | ||
1782 | 103 | 128 | ||
1783 | 104 | def invoked(self, ns): | 129 | def invoked(self, ns): |
1784 | 105 | job_list = self.get_job_list(ns) | 130 | job_list = self.get_job_list(ns) |
1785 | @@ -261,6 +286,17 @@ | |||
1786 | 261 | raise SystemExit(str(exc)) | 286 | raise SystemExit(str(exc)) |
1787 | 262 | return exporter | 287 | return exporter |
1788 | 263 | 288 | ||
1789 | 289 | def ask_for_resume(self, prompt=None, allowed=None): | ||
1790 | 290 | # FIXME: Add support/callbacks for a GUI | ||
1791 | 291 | if prompt is None: | ||
1792 | 292 | prompt = "Do you want to resume the previous session [Y/n]? " | ||
1793 | 293 | if allowed is None: | ||
1794 | 294 | allowed = ('', 'y', 'Y', 'n', 'N') | ||
1795 | 295 | answer = None | ||
1796 | 296 | while answer not in allowed: | ||
1797 | 297 | answer = input(prompt) | ||
1798 | 298 | return False if answer in ('n', 'N') else True | ||
1799 | 299 | |||
1800 | 264 | def _run_jobs(self, ns, job_list, exporter): | 300 | def _run_jobs(self, ns, job_list, exporter): |
1801 | 265 | # Compute the run list, this can give us notification about problems in | 301 | # Compute the run list, this can give us notification about problems in |
1802 | 266 | # the selected jobs. Currently we just display each problem | 302 | # the selected jobs. Currently we just display each problem |
1803 | @@ -268,8 +304,13 @@ | |||
1804 | 268 | print("[ Analyzing Jobs ]".center(80, '=')) | 304 | print("[ Analyzing Jobs ]".center(80, '=')) |
1805 | 269 | # Create a session that handles most of the stuff needed to run jobs | 305 | # Create a session that handles most of the stuff needed to run jobs |
1806 | 270 | session = SessionState(job_list) | 306 | session = SessionState(job_list) |
1807 | 271 | self._update_desired_job_list(session, matching_job_list) | ||
1808 | 272 | with session.open(): | 307 | with session.open(): |
1809 | 308 | if session.previous_session_file(): | ||
1810 | 309 | if self.ask_for_resume(): | ||
1811 | 310 | session.resume() | ||
1812 | 311 | else: | ||
1813 | 312 | session.clean() | ||
1814 | 313 | self._update_desired_job_list(session, matching_job_list) | ||
1815 | 273 | if (sys.stdin.isatty() and sys.stdout.isatty() and not | 314 | if (sys.stdin.isatty() and sys.stdout.isatty() and not |
1816 | 274 | ns.not_interactive): | 315 | ns.not_interactive): |
1817 | 275 | outcome_callback = self.ask_for_outcome | 316 | outcome_callback = self.ask_for_outcome |
1818 | 276 | 317 | ||
1819 | === modified file 'plainbox/plainbox/impl/checkbox.py' | |||
1820 | --- plainbox/plainbox/impl/checkbox.py 2013-02-22 16:26:25 +0000 | |||
1821 | +++ plainbox/plainbox/impl/checkbox.py 2013-03-07 16:10:38 +0000 | |||
1822 | @@ -18,12 +18,12 @@ | |||
1823 | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. |
1824 | 19 | 19 | ||
1825 | 20 | """ | 20 | """ |
1832 | 21 | plainbox.impl.checkbox | 21 | :mod:`plainbox.impl.checkbox` -- CheckBox integration |
1833 | 22 | ====================== | 22 | ===================================================== |
1834 | 23 | 23 | ||
1835 | 24 | Internal implementation of plainbox | 24 | .. warning:: |
1836 | 25 | 25 | ||
1837 | 26 | * THIS MODULE DOES NOT HAVE STABLE PUBLIC API * | 26 | THIS MODULE DOES NOT HAVE STABLE PUBLIC API |
1838 | 27 | """ | 27 | """ |
1839 | 28 | 28 | ||
1840 | 29 | import io | 29 | import io |
1841 | @@ -102,7 +102,7 @@ | |||
1842 | 102 | """ | 102 | """ |
1843 | 103 | Return the required value of CHECKBOX_SHARE environment variable. | 103 | Return the required value of CHECKBOX_SHARE environment variable. |
1844 | 104 | 104 | ||
1846 | 105 | ..note:: | 105 | .. note:: |
1847 | 106 | This variable is only required by one script. | 106 | This variable is only required by one script. |
1848 | 107 | It would be nice to remove this later on. | 107 | It would be nice to remove this later on. |
1849 | 108 | """ | 108 | """ |
1850 | @@ -119,7 +119,7 @@ | |||
1851 | 119 | This entry is required for CheckBox scripts to import the correct | 119 | This entry is required for CheckBox scripts to import the correct |
1852 | 120 | CheckBox python libraries. | 120 | CheckBox python libraries. |
1853 | 121 | 121 | ||
1855 | 122 | ..note:: | 122 | .. note:: |
1856 | 123 | The result may be None | 123 | The result may be None |
1857 | 124 | """ | 124 | """ |
1858 | 125 | # NOTE: When CheckBox is installed then all the scripts should not use | 125 | # NOTE: When CheckBox is installed then all the scripts should not use |
1859 | @@ -159,7 +159,7 @@ | |||
1860 | 159 | """ | 159 | """ |
1861 | 160 | Return an absolute path of the scripts directory | 160 | Return an absolute path of the scripts directory |
1862 | 161 | 161 | ||
1864 | 162 | ..note:: | 162 | .. note:: |
1865 | 163 | The scripts may not work without setting PYTHONPATH and | 163 | The scripts may not work without setting PYTHONPATH and |
1866 | 164 | CHECKBOX_SHARE. | 164 | CHECKBOX_SHARE. |
1867 | 165 | """ | 165 | """ |
1868 | 166 | 166 | ||
1869 | === modified file 'plainbox/plainbox/impl/commands/__init__.py' | |||
1870 | --- plainbox/plainbox/impl/commands/__init__.py 2013-01-30 21:43:05 +0000 | |||
1871 | +++ plainbox/plainbox/impl/commands/__init__.py 2013-03-07 16:10:38 +0000 | |||
1872 | @@ -18,12 +18,12 @@ | |||
1873 | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. |
1874 | 19 | 19 | ||
1875 | 20 | """ | 20 | """ |
1882 | 21 | plainbox.impl.commands | 21 | :mod:`plainbox.impl.commands` -- shared code for plainbox sub-commands |
1883 | 22 | ====================== | 22 | ====================================================================== |
1884 | 23 | 23 | ||
1885 | 24 | Internal implementation of plainbox | 24 | .. warning:: |
1886 | 25 | 25 | ||
1887 | 26 | * THIS MODULE DOES NOT HAVE STABLE PUBLIC API * | 26 | THIS MODULE DOES NOT HAVE STABLE PUBLIC API |
1888 | 27 | """ | 27 | """ |
1889 | 28 | 28 | ||
1890 | 29 | from abc import abstractmethod, ABCMeta | 29 | from abc import abstractmethod, ABCMeta |
1891 | 30 | 30 | ||
1892 | === modified file 'plainbox/plainbox/impl/commands/selftest.py' | |||
1893 | --- plainbox/plainbox/impl/commands/selftest.py 2013-02-08 17:02:12 +0000 | |||
1894 | +++ plainbox/plainbox/impl/commands/selftest.py 2013-03-07 16:10:38 +0000 | |||
1895 | @@ -19,12 +19,12 @@ | |||
1896 | 19 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. | 19 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. |
1897 | 20 | 20 | ||
1898 | 21 | """ | 21 | """ |
1905 | 22 | plainbox.impl.commands.selftest | 22 | :mod:`plainbox.impl.commands.selftest` -- selftest sub-command |
1906 | 23 | =============================== | 23 | ============================================================== |
1907 | 24 | 24 | ||
1908 | 25 | Internal implementation of plainbox | 25 | .. warning:: |
1909 | 26 | 26 | ||
1910 | 27 | * THIS MODULE DOES NOT HAVE STABLE PUBLIC API * | 27 | THIS MODULE DOES NOT HAVE STABLE PUBLIC API |
1911 | 28 | """ | 28 | """ |
1912 | 29 | from unittest.runner import TextTestRunner | 29 | from unittest.runner import TextTestRunner |
1913 | 30 | 30 | ||
1914 | 31 | 31 | ||
1915 | === modified file 'plainbox/plainbox/impl/depmgr.py' | |||
1916 | --- plainbox/plainbox/impl/depmgr.py 2012-11-29 18:59:46 +0000 | |||
1917 | +++ plainbox/plainbox/impl/depmgr.py 2013-03-07 16:10:38 +0000 | |||
1918 | @@ -18,12 +18,12 @@ | |||
1919 | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. |
1920 | 19 | 19 | ||
1921 | 20 | """ | 20 | """ |
1928 | 21 | plainbox.impl.depmgr | 21 | :mod:`plainbox.impl.depmgr` -- dependency solver |
1929 | 22 | ==================== | 22 | ================================================ |
1930 | 23 | 23 | ||
1931 | 24 | Internal implementation of plainbox | 24 | .. warning:: |
1932 | 25 | 25 | ||
1933 | 26 | * THIS MODULE DOES NOT HAVE STABLE PUBLIC API * | 26 | THIS MODULE DOES NOT HAVE STABLE PUBLIC API |
1934 | 27 | """ | 27 | """ |
1935 | 28 | 28 | ||
1936 | 29 | from abc import ABCMeta | 29 | from abc import ABCMeta |
1937 | @@ -148,15 +148,17 @@ | |||
1938 | 148 | @classmethod | 148 | @classmethod |
1939 | 149 | def resolve_dependencies(cls, job_list, visit_list=None): | 149 | def resolve_dependencies(cls, job_list, visit_list=None): |
1940 | 150 | """ | 150 | """ |
1950 | 151 | Solve the dependency graph expressed as a list of job definitions. The | 151 | Solve the dependency graph expressed as a list of job definitions. |
1951 | 152 | visit_list, if specified, allows to consider only a part of the graph | 152 | |
1952 | 153 | while still having access and knowledge of all jobs. | 153 | :param list job_list: list of known jobs |
1953 | 154 | 154 | :param list visit_list: (optional) list of jobs to solve | |
1954 | 155 | Returns the solution (a list of jobs to execute in order) | 155 | |
1955 | 156 | 156 | The visit_list, if specified, allows to consider only a part of the | |
1956 | 157 | raises DependencyCycleError if a cyclic dependency is present. | 157 | graph while still having access and knowledge of all jobs. |
1957 | 158 | 158 | ||
1958 | 159 | raises DependencyMissingErorr if a required job does not exist. | 159 | :returns list: the solution (a list of jobs to execute in order) |
1959 | 160 | :raises DependencyCycleError: if a cyclic dependency is present. | ||
1960 | 161 | :raises DependencyMissingErorr: if a required job does not exist. | ||
1961 | 160 | """ | 162 | """ |
1962 | 161 | return cls(job_list)._solve(visit_list) | 163 | return cls(job_list)._solve(visit_list) |
1963 | 162 | 164 | ||
1964 | 163 | 165 | ||
1965 | === modified file 'plainbox/plainbox/impl/exporter/__init__.py' | |||
1966 | --- plainbox/plainbox/impl/exporter/__init__.py 2013-02-22 16:26:25 +0000 | |||
1967 | +++ plainbox/plainbox/impl/exporter/__init__.py 2013-03-07 16:10:38 +0000 | |||
1968 | @@ -18,10 +18,12 @@ | |||
1969 | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. |
1970 | 19 | 19 | ||
1971 | 20 | """ | 20 | """ |
1976 | 21 | plainbox.impl.exporter | 21 | :mod:`plainbox.impl.exporter` -- shared code for session state exporters |
1977 | 22 | ====================== | 22 | ======================================================================== |
1978 | 23 | 23 | ||
1979 | 24 | * THIS MODULE DOES NOT HAVE STABLE PUBLIC API * | 24 | .. warning:: |
1980 | 25 | |||
1981 | 26 | THIS MODULE DOES NOT HAVE STABLE PUBLIC API | ||
1982 | 25 | """ | 27 | """ |
1983 | 26 | 28 | ||
1984 | 27 | from abc import ABCMeta, abstractmethod | 29 | from abc import ABCMeta, abstractmethod |
1985 | @@ -38,11 +40,6 @@ | |||
1986 | 38 | class classproperty: | 40 | class classproperty: |
1987 | 39 | """ | 41 | """ |
1988 | 40 | Class property. | 42 | Class property. |
1989 | 41 | |||
1990 | 42 | @property | ||
1991 | 43 | @classmethod | ||
1992 | 44 | def foo(cls): | ||
1993 | 45 | ... | ||
1994 | 46 | """ | 43 | """ |
1995 | 47 | # I wish it was in the standard library or that the composition worked | 44 | # I wish it was in the standard library or that the composition worked |
1996 | 48 | 45 | ||
1997 | @@ -75,6 +72,7 @@ | |||
1998 | 75 | OPTION_WITH_DESIRED_JOB_LIST = 'with-job-list' | 72 | OPTION_WITH_DESIRED_JOB_LIST = 'with-job-list' |
1999 | 76 | OPTION_WITH_RESOURCE_MAP = 'with-resource-map' | 73 | OPTION_WITH_RESOURCE_MAP = 'with-resource-map' |
2000 | 77 | OPTION_WITH_JOB_DEFS = 'with-job-defs' | 74 | OPTION_WITH_JOB_DEFS = 'with-job-defs' |
2001 | 75 | OPTION_WITH_ATTACHMENTS = 'with-attachments' | ||
2002 | 78 | 76 | ||
2003 | 79 | SUPPORTED_OPTION_LIST = ( | 77 | SUPPORTED_OPTION_LIST = ( |
2004 | 80 | OPTION_WITH_IO_LOG, | 78 | OPTION_WITH_IO_LOG, |
2005 | @@ -84,6 +82,7 @@ | |||
2006 | 84 | OPTION_WITH_JOB_LIST, | 82 | OPTION_WITH_JOB_LIST, |
2007 | 85 | OPTION_WITH_RESOURCE_MAP, | 83 | OPTION_WITH_RESOURCE_MAP, |
2008 | 86 | OPTION_WITH_JOB_DEFS, | 84 | OPTION_WITH_JOB_DEFS, |
2009 | 85 | OPTION_WITH_ATTACHMENTS, | ||
2010 | 87 | ) | 86 | ) |
2011 | 88 | 87 | ||
2012 | 89 | def __init__(self, option_list=None): | 88 | def __init__(self, option_list=None): |
2013 | @@ -133,6 +132,8 @@ | |||
2014 | 133 | # TODO: turn session._resource_map to a public property | 132 | # TODO: turn session._resource_map to a public property |
2015 | 134 | for resource_name, resource_list in session._resource_map.items() | 133 | for resource_name, resource_list in session._resource_map.items() |
2016 | 135 | } | 134 | } |
2017 | 135 | if self.OPTION_WITH_ATTACHMENTS in self._option_list: | ||
2018 | 136 | data['attachment_map'] = {} | ||
2019 | 136 | for job_name, job_state in session.job_state_map.items(): | 137 | for job_name, job_state in session.job_state_map.items(): |
2020 | 137 | if job_state.result.outcome is None: | 138 | if job_state.result.outcome is None: |
2021 | 138 | continue | 139 | continue |
2022 | @@ -151,6 +152,16 @@ | |||
2023 | 151 | continue | 152 | continue |
2024 | 152 | data['result_map'][job_name][prop] = \ | 153 | data['result_map'][job_name][prop] = \ |
2025 | 153 | getattr(job_state.result.job, prop) | 154 | getattr(job_state.result.job, prop) |
2026 | 155 | |||
2027 | 156 | # Add Attachements if requested | ||
2028 | 157 | if job_state.result.job.plugin == 'attachment': | ||
2029 | 158 | if self.OPTION_WITH_ATTACHMENTS in self._option_list: | ||
2030 | 159 | raw_bytes = b''.join((record[2] for record in | ||
2031 | 160 | job_state.result.io_log if record[1] == 'stdout')) | ||
2032 | 161 | data['attachment_map'][job_name] = \ | ||
2033 | 162 | base64.standard_b64encode(raw_bytes).decode('ASCII') | ||
2034 | 163 | continue # Don't add attachments IO logs to the result_map | ||
2035 | 164 | |||
2036 | 154 | # Add IO log if requested | 165 | # Add IO log if requested |
2037 | 155 | if self.OPTION_WITH_IO_LOG in self._option_list: | 166 | if self.OPTION_WITH_IO_LOG in self._option_list: |
2038 | 156 | # If requested, squash the IO log so that only textual data is | 167 | # If requested, squash the IO log so that only textual data is |
2039 | 157 | 168 | ||
2040 | === modified file 'plainbox/plainbox/impl/exporter/json.py' | |||
2041 | --- plainbox/plainbox/impl/exporter/json.py 2012-12-10 12:38:50 +0000 | |||
2042 | +++ plainbox/plainbox/impl/exporter/json.py 2013-03-07 16:10:38 +0000 | |||
2043 | @@ -18,12 +18,11 @@ | |||
2044 | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. |
2045 | 19 | 19 | ||
2046 | 20 | """ | 20 | """ |
2053 | 21 | plainbox.impl.exporter.json | 21 | :mod:`plainbox.impl.exporter.json` -- JSON exporter |
2054 | 22 | =========================== | 22 | =================================================== |
2055 | 23 | 23 | ||
2056 | 24 | Internal implementation of plainbox | 24 | .. warning:: |
2057 | 25 | 25 | THIS MODULE DOES NOT HAVE STABLE PUBLIC API | |
2052 | 26 | * THIS MODULE DOES NOT HAVE STABLE PUBLIC API * | ||
2058 | 27 | """ | 26 | """ |
2059 | 28 | 27 | ||
2060 | 29 | import json | 28 | import json |
2061 | 30 | 29 | ||
2062 | === modified file 'plainbox/plainbox/impl/exporter/rfc822.py' | |||
2063 | --- plainbox/plainbox/impl/exporter/rfc822.py 2013-01-04 13:31:02 +0000 | |||
2064 | +++ plainbox/plainbox/impl/exporter/rfc822.py 2013-03-07 16:10:38 +0000 | |||
2065 | @@ -18,12 +18,12 @@ | |||
2066 | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. |
2067 | 19 | 19 | ||
2068 | 20 | """ | 20 | """ |
2075 | 21 | plainbox.impl.exporter.rfc822 | 21 | :mod:`plainbox.impl.exporter.rfc822` -- RFC822 exporter |
2076 | 22 | =========================== | 22 | ======================================================= |
2077 | 23 | 23 | ||
2078 | 24 | Internal implementation of plainbox | 24 | .. warning:: |
2079 | 25 | 25 | ||
2080 | 26 | * THIS MODULE DOES NOT HAVE STABLE PUBLIC API * | 26 | THIS MODULE DOES NOT HAVE STABLE PUBLIC API |
2081 | 27 | """ | 27 | """ |
2082 | 28 | 28 | ||
2083 | 29 | 29 | ||
2084 | 30 | 30 | ||
2085 | === modified file 'plainbox/plainbox/impl/exporter/test_init.py' | |||
2086 | --- plainbox/plainbox/impl/exporter/test_init.py 2013-02-22 16:26:25 +0000 | |||
2087 | +++ plainbox/plainbox/impl/exporter/test_init.py 2013-03-07 16:10:38 +0000 | |||
2088 | @@ -24,6 +24,7 @@ | |||
2089 | 24 | Test definitions for plainbox.impl.exporter module | 24 | Test definitions for plainbox.impl.exporter module |
2090 | 25 | """ | 25 | """ |
2091 | 26 | 26 | ||
2092 | 27 | from tempfile import TemporaryDirectory | ||
2093 | 27 | from unittest import TestCase | 28 | from unittest import TestCase |
2094 | 28 | 29 | ||
2095 | 29 | from plainbox.impl.exporter import SessionStateExporterBase | 30 | from plainbox.impl.exporter import SessionStateExporterBase |
2096 | @@ -31,7 +32,7 @@ | |||
2097 | 31 | from plainbox.impl.session import SessionState | 32 | from plainbox.impl.session import SessionState |
2098 | 32 | from plainbox.impl.job import JobDefinition | 33 | from plainbox.impl.job import JobDefinition |
2099 | 33 | from plainbox.impl.result import JobResult, IOLogRecord | 34 | from plainbox.impl.result import JobResult, IOLogRecord |
2101 | 34 | from plainbox.impl.testing_utils import make_job, make_job_result | 35 | from plainbox.impl.testing_utils import make_io_log, make_job, make_job_result |
2102 | 35 | 36 | ||
2103 | 36 | 37 | ||
2104 | 37 | class ClassPropertyTests(TestCase): | 38 | class ClassPropertyTests(TestCase): |
2105 | @@ -95,7 +96,7 @@ | |||
2106 | 95 | } | 96 | } |
2107 | 96 | self.assertEqual(data, expected_data) | 97 | self.assertEqual(data, expected_data) |
2108 | 97 | 98 | ||
2110 | 98 | def make_realistic_test_session(self): | 99 | def make_realistic_test_session(self, session_dir): |
2111 | 99 | # Create a more realistic session with two jobs but with richer set | 100 | # Create a more realistic session with two jobs but with richer set |
2112 | 100 | # of data in the actual jobs and results. | 101 | # of data in the actual jobs and results. |
2113 | 101 | job_a = JobDefinition({ | 102 | job_a = JobDefinition({ |
2114 | @@ -115,17 +116,17 @@ | |||
2115 | 115 | 'job': job_a, | 116 | 'job': job_a, |
2116 | 116 | 'outcome': 'pass', | 117 | 'outcome': 'pass', |
2117 | 117 | 'return_code': 0, | 118 | 'return_code': 0, |
2121 | 118 | 'io_log': ( | 119 | 'io_log': make_io_log( |
2122 | 119 | IOLogRecord(0, 'stdout', b'testing\n'), | 120 | (IOLogRecord(0, 'stdout', b'testing\n'),), |
2123 | 120 | ) | 121 | session_dir) |
2124 | 121 | }) | 122 | }) |
2125 | 122 | result_b = JobResult({ | 123 | result_b = JobResult({ |
2126 | 123 | 'job': job_b, | 124 | 'job': job_b, |
2127 | 124 | 'outcome': 'pass', | 125 | 'outcome': 'pass', |
2128 | 125 | 'return_code': 0, | 126 | 'return_code': 0, |
2132 | 126 | 'io_log': ( | 127 | 'io_log': make_io_log( |
2133 | 127 | IOLogRecord(0, 'stdout', b'ready: yes\n'), | 128 | (IOLogRecord(0, 'stdout', b'ready: yes\n'),), |
2134 | 128 | ) | 129 | session_dir) |
2135 | 129 | }) | 130 | }) |
2136 | 130 | session.update_job_result(job_a, result_a) | 131 | session.update_job_result(job_a, result_a) |
2137 | 131 | session.update_job_result(job_b, result_b) | 132 | session.update_job_result(job_b, result_b) |
2138 | @@ -139,10 +140,11 @@ | |||
2139 | 139 | # - OPTION_FLATTEN_IO_LOG | 140 | # - OPTION_FLATTEN_IO_LOG |
2140 | 140 | # The implementation favours SQUASH_IO_LOG | 141 | # The implementation favours SQUASH_IO_LOG |
2141 | 141 | # and thus the code below tests that option | 142 | # and thus the code below tests that option |
2146 | 142 | exporter = self.TestSessionStateExporter( | 143 | with TemporaryDirectory() as scratch_dir: |
2147 | 143 | self.TestSessionStateExporter.supported_option_list) | 144 | exporter = self.TestSessionStateExporter( |
2148 | 144 | session = self.make_realistic_test_session() | 145 | self.TestSessionStateExporter.supported_option_list) |
2149 | 145 | data = exporter.get_session_data_subset(session) | 146 | session = self.make_realistic_test_session(scratch_dir) |
2150 | 147 | data = exporter.get_session_data_subset(session) | ||
2151 | 146 | expected_data = { | 148 | expected_data = { |
2152 | 147 | 'job_list': ['job_a', 'job_b'], | 149 | 'job_list': ['job_a', 'job_b'], |
2153 | 148 | 'run_list': ['job_b', 'job_a'], | 150 | 'run_list': ['job_b', 'job_a'], |
2154 | @@ -166,6 +168,8 @@ | |||
2155 | 166 | 'command': 'echo ready: yes', | 168 | 'command': 'echo ready: yes', |
2156 | 167 | 'io_log': ['cmVhZHk6IHllcwo='], | 169 | 'io_log': ['cmVhZHk6IHllcwo='], |
2157 | 168 | } | 170 | } |
2158 | 171 | }, | ||
2159 | 172 | 'attachment_map': { | ||
2160 | 169 | } | 173 | } |
2161 | 170 | } | 174 | } |
2162 | 171 | # This is just to make debugging easier | 175 | # This is just to make debugging easier |
2163 | 172 | 176 | ||
2164 | === modified file 'plainbox/plainbox/impl/exporter/text.py' | |||
2165 | --- plainbox/plainbox/impl/exporter/text.py 2012-12-10 12:38:50 +0000 | |||
2166 | +++ plainbox/plainbox/impl/exporter/text.py 2013-03-07 16:10:38 +0000 | |||
2167 | @@ -18,12 +18,12 @@ | |||
2168 | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. |
2169 | 19 | 19 | ||
2170 | 20 | """ | 20 | """ |
2177 | 21 | plainbox.impl.exporter.text | 21 | :mod:`plainbox.impl.exporter.text` -- plain text exporter |
2178 | 22 | =========================== | 22 | ========================================================= |
2179 | 23 | 23 | ||
2180 | 24 | Internal implementation of plainbox | 24 | .. warning:: |
2181 | 25 | 25 | ||
2182 | 26 | * THIS MODULE DOES NOT HAVE STABLE PUBLIC API * | 26 | THIS MODULE DOES NOT HAVE STABLE PUBLIC API |
2183 | 27 | """ | 27 | """ |
2184 | 28 | 28 | ||
2185 | 29 | 29 | ||
2186 | 30 | 30 | ||
2187 | === modified file 'plainbox/plainbox/impl/integration_tests.py' | |||
2188 | --- plainbox/plainbox/impl/integration_tests.py 2013-02-22 16:26:25 +0000 | |||
2189 | +++ plainbox/plainbox/impl/integration_tests.py 2013-03-07 16:10:38 +0000 | |||
2190 | @@ -18,16 +18,20 @@ | |||
2191 | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. |
2192 | 19 | 19 | ||
2193 | 20 | """ | 20 | """ |
2198 | 21 | plainbox.impl.integration_tests | 21 | :mod:`plainbox.impl.integration_tests` -- integration tests |
2199 | 22 | =============================== | 22 | =========================================================== |
2200 | 23 | 23 | ||
2201 | 24 | Integration tests for checkbox scripts | 24 | .. warning:: |
2202 | 25 | |||
2203 | 26 | THIS MODULE DOES NOT HAVE STABLE PUBLIC API | ||
2204 | 25 | """ | 27 | """ |
2205 | 26 | 28 | ||
2206 | 27 | from tempfile import TemporaryDirectory | 29 | from tempfile import TemporaryDirectory |
2207 | 28 | from unittest import TestCase | 30 | from unittest import TestCase |
2208 | 29 | import json | 31 | import json |
2209 | 30 | import os | 32 | import os |
2210 | 33 | import shutil | ||
2211 | 34 | import tempfile | ||
2212 | 31 | 35 | ||
2213 | 32 | from pkg_resources import resource_filename, resource_isdir, resource_listdir | 36 | from pkg_resources import resource_filename, resource_isdir, resource_listdir |
2214 | 33 | 37 | ||
2215 | @@ -41,6 +45,14 @@ | |||
2216 | 41 | 45 | ||
2217 | 42 | parameter_names = ('job_name',) | 46 | parameter_names = ('job_name',) |
2218 | 43 | 47 | ||
2219 | 48 | def setUp(self): | ||
2220 | 49 | # session data are kept in XDG_CACHE_HOME/plainbox/.session | ||
2221 | 50 | # To avoid resuming a real session, we have to select a temporary | ||
2222 | 51 | # location instead | ||
2223 | 52 | self._sandbox = tempfile.mkdtemp() | ||
2224 | 53 | self._env = os.environ | ||
2225 | 54 | os.environ['XDG_CACHE_HOME'] = self._sandbox | ||
2226 | 55 | |||
2227 | 44 | @classmethod | 56 | @classmethod |
2228 | 45 | def _gen_job_name_values(cls, package='plainbox', root='data/'): | 57 | def _gen_job_name_values(cls, package='plainbox', root='data/'): |
2229 | 46 | """ | 58 | """ |
2230 | @@ -94,3 +106,7 @@ | |||
2231 | 94 | expected_result = json.load(stream) | 106 | expected_result = json.load(stream) |
2232 | 95 | # Check that results match expected values | 107 | # Check that results match expected values |
2233 | 96 | self.assertEqual(actual_result, expected_result) | 108 | self.assertEqual(actual_result, expected_result) |
2234 | 109 | |||
2235 | 110 | def tearDown(self): | ||
2236 | 111 | shutil.rmtree(self._sandbox) | ||
2237 | 112 | os.environ = self._env | ||
2238 | 97 | 113 | ||
2239 | === modified file 'plainbox/plainbox/impl/job.py' | |||
2240 | --- plainbox/plainbox/impl/job.py 2013-02-22 16:26:25 +0000 | |||
2241 | +++ plainbox/plainbox/impl/job.py 2013-03-07 16:10:38 +0000 | |||
2242 | @@ -18,12 +18,12 @@ | |||
2243 | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. |
2244 | 19 | 19 | ||
2245 | 20 | """ | 20 | """ |
2252 | 21 | plainbox.impl.job | 21 | :mod:`plainbox.impl.job` -- job definition |
2253 | 22 | ================= | 22 | ========================================== |
2254 | 23 | 23 | ||
2255 | 24 | Internal implementation of plainbox | 24 | .. warning:: |
2256 | 25 | 25 | ||
2257 | 26 | * THIS MODULE DOES NOT HAVE STABLE PUBLIC API * | 26 | THIS MODULE DOES NOT HAVE STABLE PUBLIC API |
2258 | 27 | """ | 27 | """ |
2259 | 28 | 28 | ||
2260 | 29 | import collections | 29 | import collections |
2261 | @@ -41,6 +41,11 @@ | |||
2262 | 41 | 41 | ||
2263 | 42 | 42 | ||
2264 | 43 | class JobDefinition(IJobDefinition): | 43 | class JobDefinition(IJobDefinition): |
2265 | 44 | """ | ||
2266 | 45 | Job definition class. | ||
2267 | 46 | |||
2268 | 47 | Thin wrapper around the RFC822 record that defines a checkbox job definition | ||
2269 | 48 | """ | ||
2270 | 44 | 49 | ||
2271 | 45 | @property | 50 | @property |
2272 | 46 | def plugin(self): | 51 | def plugin(self): |
2273 | @@ -120,10 +125,15 @@ | |||
2274 | 120 | def _get_persistance_subset(self): | 125 | def _get_persistance_subset(self): |
2275 | 121 | state = {} | 126 | state = {} |
2276 | 122 | state['data'] = {} | 127 | state['data'] = {} |
2279 | 123 | state['data']['plugin'] = self.plugin | 128 | for key, value in self._data.items(): |
2280 | 124 | state['data']['name'] = self.name | 129 | state['data'][key] = value |
2281 | 125 | return state | 130 | return state |
2282 | 126 | 131 | ||
2283 | 132 | def __eq__(self, other): | ||
2284 | 133 | if not isinstance(other, JobDefinition): | ||
2285 | 134 | return False | ||
2286 | 135 | return self.get_checksum() == other.get_checksum() | ||
2287 | 136 | |||
2288 | 127 | def get_resource_program(self): | 137 | def get_resource_program(self): |
2289 | 128 | """ | 138 | """ |
2290 | 129 | Return a ResourceProgram based on the 'requires' expression. | 139 | Return a ResourceProgram based on the 'requires' expression. |
2291 | 130 | 140 | ||
2292 | === added file 'plainbox/plainbox/impl/mock_job.py' | |||
2293 | --- plainbox/plainbox/impl/mock_job.py 1970-01-01 00:00:00 +0000 | |||
2294 | +++ plainbox/plainbox/impl/mock_job.py 2013-03-07 16:10:38 +0000 | |||
2295 | @@ -0,0 +1,36 @@ | |||
2296 | 1 | # This file is part of Checkbox. | ||
2297 | 2 | # | ||
2298 | 3 | # Copyright 2013 Canonical Ltd. | ||
2299 | 4 | # Written by: | ||
2300 | 5 | # Zygmunt Krynicki <zygmunt.krynicki@canonical.com> | ||
2301 | 6 | # | ||
2302 | 7 | # Checkbox is free software: you can redistribute it and/or modify | ||
2303 | 8 | # it under the terms of the GNU General Public License as published by | ||
2304 | 9 | # the Free Software Foundation, either version 3 of the License, or | ||
2305 | 10 | # (at your option) any later version. | ||
2306 | 11 | # | ||
2307 | 12 | # Checkbox is distributed in the hope that it will be useful, | ||
2308 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
2309 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
2310 | 15 | # GNU General Public License for more details. | ||
2311 | 16 | # | ||
2312 | 17 | # You should have received a copy of the GNU General Public License | ||
2313 | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. | ||
2314 | 19 | |||
2315 | 20 | """ | ||
2316 | 21 | :mod:`plainbox.impl.mock_job` -- mock jobs | ||
2317 | 22 | ========================================== | ||
2318 | 23 | """ | ||
2319 | 24 | |||
2320 | 25 | from mock import Mock | ||
2321 | 26 | |||
2322 | 27 | from plainbox.impl.job import JobDefinition | ||
2323 | 28 | |||
2324 | 29 | |||
2325 | 30 | def MockJobDefinition(name,*args, **kwargs): | ||
2326 | 31 | """ | ||
2327 | 32 | Mock for JobDefinition class | ||
2328 | 33 | """ | ||
2329 | 34 | job = Mock(*args, spec_set=JobDefinition, **kwargs) | ||
2330 | 35 | job.name = name | ||
2331 | 36 | return job | ||
2332 | 0 | 37 | ||
2333 | === modified file 'plainbox/plainbox/impl/resource.py' | |||
2334 | --- plainbox/plainbox/impl/resource.py 2013-02-22 16:26:25 +0000 | |||
2335 | +++ plainbox/plainbox/impl/resource.py 2013-03-07 16:10:38 +0000 | |||
2336 | @@ -18,12 +18,12 @@ | |||
2337 | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. |
2338 | 19 | 19 | ||
2339 | 20 | """ | 20 | """ |
2346 | 21 | plainbox.impl.resource | 21 | :mod:`plainbox.impl.resource` -- job resources |
2347 | 22 | ====================== | 22 | ============================================== |
2348 | 23 | 23 | ||
2349 | 24 | Internal implementation of plainbox | 24 | .. warning:: |
2350 | 25 | 25 | ||
2351 | 26 | * THIS MODULE DOES NOT HAVE STABLE PUBLIC API * | 26 | THIS MODULE DOES NOT HAVE STABLE PUBLIC API |
2352 | 27 | """ | 27 | """ |
2353 | 28 | 28 | ||
2354 | 29 | import ast | 29 | import ast |
2355 | @@ -221,7 +221,7 @@ | |||
2356 | 221 | """ | 221 | """ |
2357 | 222 | A NodeVisitor subclass used to analyze requirement expressions. | 222 | A NodeVisitor subclass used to analyze requirement expressions. |
2358 | 223 | 223 | ||
2360 | 224 | ..warning:: | 224 | .. warning:: |
2361 | 225 | 225 | ||
2362 | 226 | Implementation of this class requires understanding of | 226 | Implementation of this class requires understanding of |
2363 | 227 | some of the lower levels of python. The general idea is | 227 | some of the lower levels of python. The general idea is |
2364 | 228 | 228 | ||
2365 | === modified file 'plainbox/plainbox/impl/result.py' | |||
2366 | --- plainbox/plainbox/impl/result.py 2013-02-22 16:26:25 +0000 | |||
2367 | +++ plainbox/plainbox/impl/result.py 2013-03-07 16:10:38 +0000 | |||
2368 | @@ -18,16 +18,19 @@ | |||
2369 | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. |
2370 | 19 | 19 | ||
2371 | 20 | """ | 20 | """ |
2378 | 21 | plainbox.impl.result | 21 | :mod:`plainbox.impl.result` -- job result |
2379 | 22 | ==================== | 22 | ========================================= |
2380 | 23 | 23 | ||
2381 | 24 | Internal implementation of plainbox | 24 | .. warning:: |
2382 | 25 | 25 | ||
2383 | 26 | * THIS MODULE DOES NOT HAVE STABLE PUBLIC API * | 26 | THIS MODULE DOES NOT HAVE STABLE PUBLIC API |
2384 | 27 | """ | 27 | """ |
2385 | 28 | 28 | ||
2386 | 29 | from collections import namedtuple | 29 | from collections import namedtuple |
2387 | 30 | import base64 | ||
2388 | 31 | import json | ||
2389 | 30 | import logging | 32 | import logging |
2390 | 33 | import os | ||
2391 | 31 | 34 | ||
2392 | 32 | from plainbox.abc import IJobResult | 35 | from plainbox.abc import IJobResult |
2393 | 33 | 36 | ||
2394 | @@ -48,6 +51,9 @@ | |||
2395 | 48 | 51 | ||
2396 | 49 | 52 | ||
2397 | 50 | class JobResult(IJobResult): | 53 | class JobResult(IJobResult): |
2398 | 54 | """ | ||
2399 | 55 | Result of running a JobDefinition. | ||
2400 | 56 | """ | ||
2401 | 51 | 57 | ||
2402 | 52 | # The outcome of a job is a one-word classification how how it ran. There | 58 | # The outcome of a job is a one-word classification how how it ran. There |
2403 | 53 | # are several values that were not used in the original implementation but | 59 | # are several values that were not used in the original implementation but |
2404 | @@ -112,7 +118,11 @@ | |||
2405 | 112 | 118 | ||
2406 | 113 | @property | 119 | @property |
2407 | 114 | def io_log(self): | 120 | def io_log(self): |
2409 | 115 | return self._data.get('io_log', ()) | 121 | if os.path.exists(self._data.get('io_log', '')): |
2410 | 122 | with open(self._data.get('io_log')) as f: | ||
2411 | 123 | return json.load(f, cls=IoLogDecoder) | ||
2412 | 124 | else: | ||
2413 | 125 | return () | ||
2414 | 116 | 126 | ||
2415 | 117 | @property | 127 | @property |
2416 | 118 | def return_code(self): | 128 | def return_code(self): |
2417 | @@ -121,11 +131,8 @@ | |||
2418 | 121 | def _get_persistance_subset(self): | 131 | def _get_persistance_subset(self): |
2419 | 122 | state = {} | 132 | state = {} |
2420 | 123 | state['data'] = {} | 133 | state['data'] = {} |
2426 | 124 | state['data']['job'] = self._data['job'] | 134 | for key, value in self._data.items(): |
2427 | 125 | state['data']['outcome'] = self._data.get('outcome', None) | 135 | state['data'][key] = value |
2423 | 126 | state['data']['comments'] = self._data.get('comments') | ||
2424 | 127 | state['data']['return_code'] = self._data.get('return_code') | ||
2425 | 128 | # io_log are stored on disk, see session.jobs_io_log_dir | ||
2428 | 129 | return state | 136 | return state |
2429 | 130 | 137 | ||
2430 | 131 | @classmethod | 138 | @classmethod |
2431 | @@ -134,3 +141,26 @@ | |||
2432 | 134 | Create a JobResult instance from JSON record | 141 | Create a JobResult instance from JSON record |
2433 | 135 | """ | 142 | """ |
2434 | 136 | return cls(record['data']) | 143 | return cls(record['data']) |
2435 | 144 | |||
2436 | 145 | |||
2437 | 146 | class IoLogEncoder(json.JSONEncoder): | ||
2438 | 147 | """ | ||
2439 | 148 | JSON Serialize helper to encode binary io logs | ||
2440 | 149 | """ | ||
2441 | 150 | |||
2442 | 151 | def default(self, obj): | ||
2443 | 152 | return base64.standard_b64encode(obj).decode('ASCII') | ||
2444 | 153 | |||
2445 | 154 | |||
2446 | 155 | class IoLogDecoder(json.JSONDecoder): | ||
2447 | 156 | """ | ||
2448 | 157 | JSON Decoder helper for io logs objects | ||
2449 | 158 | """ | ||
2450 | 159 | |||
2451 | 160 | def decode(self, obj): | ||
2452 | 161 | return tuple([IOLogRecord( | ||
2453 | 162 | # io logs namedtuple are recorded as list in json, using _asdict() | ||
2454 | 163 | # would require too much space for little benefit. | ||
2455 | 164 | # IOLogRecord are re created using the list ordering | ||
2456 | 165 | log[0], log[1], base64.standard_b64decode(log[2].encode('ASCII'))) | ||
2457 | 166 | for log in super().decode(obj)]) | ||
2458 | 137 | 167 | ||
2459 | === modified file 'plainbox/plainbox/impl/rfc822.py' | |||
2460 | --- plainbox/plainbox/impl/rfc822.py 2012-12-18 00:26:03 +0000 | |||
2461 | +++ plainbox/plainbox/impl/rfc822.py 2013-03-07 16:10:38 +0000 | |||
2462 | @@ -18,12 +18,14 @@ | |||
2463 | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. |
2464 | 19 | 19 | ||
2465 | 20 | """ | 20 | """ |
2468 | 21 | plainbox.impl.rfc822 | 21 | :mod:`plainbox.impl.rfc822` -- RFC822 parser |
2469 | 22 | ==================== | 22 | ============================================ |
2470 | 23 | 23 | ||
2471 | 24 | Implementation of rfc822 serializer and deserializer. | 24 | Implementation of rfc822 serializer and deserializer. |
2472 | 25 | 25 | ||
2474 | 26 | * THIS MODULE DOES NOT HAVE STABLE PUBLIC API * | 26 | .. warning:: |
2475 | 27 | |||
2476 | 28 | THIS MODULE DOES NOT HAVE STABLE PUBLIC API | ||
2477 | 27 | """ | 29 | """ |
2478 | 28 | 30 | ||
2479 | 29 | import logging | 31 | import logging |
2480 | @@ -37,10 +39,11 @@ | |||
2481 | 37 | """ | 39 | """ |
2482 | 38 | Simple class for tracking where something came from | 40 | Simple class for tracking where something came from |
2483 | 39 | 41 | ||
2488 | 40 | It has three attributes: | 42 | :ivar filename: the name of the file |
2489 | 41 | filename - the name of the file | 43 | |
2490 | 42 | line_start - the number of the line where the record begins | 44 | :ivar line_start: the number of the line where the record begins |
2491 | 43 | line_end - the number of the line where the record ends | 45 | |
2492 | 46 | :ivar line_end: the number of the line where the record ends | ||
2493 | 44 | """ | 47 | """ |
2494 | 45 | 48 | ||
2495 | 46 | __slots__ = ['filename', 'line_start', 'line_end'] | 49 | __slots__ = ['filename', 'line_start', 'line_end'] |
2496 | 47 | 50 | ||
2497 | === modified file 'plainbox/plainbox/impl/runner.py' | |||
2498 | --- plainbox/plainbox/impl/runner.py 2013-02-22 16:26:25 +0000 | |||
2499 | +++ plainbox/plainbox/impl/runner.py 2013-03-07 16:10:38 +0000 | |||
2500 | @@ -18,16 +18,17 @@ | |||
2501 | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. |
2502 | 19 | 19 | ||
2503 | 20 | """ | 20 | """ |
2510 | 21 | plainbox.impl.runner | 21 | :mod:`plainbox.impl.runner` -- job runner |
2511 | 22 | ==================== | 22 | ========================================= |
2512 | 23 | 23 | ||
2513 | 24 | Internal implementation of plainbox | 24 | .. warning:: |
2514 | 25 | 25 | ||
2515 | 26 | * THIS MODULE DOES NOT HAVE STABLE PUBLIC API * | 26 | THIS MODULE DOES NOT HAVE STABLE PUBLIC API |
2516 | 27 | """ | 27 | """ |
2517 | 28 | 28 | ||
2518 | 29 | import collections | 29 | import collections |
2519 | 30 | import datetime | 30 | import datetime |
2520 | 31 | import json | ||
2521 | 31 | import logging | 32 | import logging |
2522 | 32 | import os | 33 | import os |
2523 | 33 | import string | 34 | import string |
2524 | @@ -35,7 +36,7 @@ | |||
2525 | 35 | from plainbox.vendor import extcmd | 36 | from plainbox.vendor import extcmd |
2526 | 36 | 37 | ||
2527 | 37 | from plainbox.abc import IJobRunner | 38 | from plainbox.abc import IJobRunner |
2529 | 38 | from plainbox.impl.result import JobResult, IOLogRecord | 39 | from plainbox.impl.result import JobResult, IOLogRecord, IoLogEncoder |
2530 | 39 | 40 | ||
2531 | 40 | logger = logging.getLogger("plainbox.runner") | 41 | logger = logging.getLogger("plainbox.runner") |
2532 | 41 | 42 | ||
2533 | @@ -50,6 +51,15 @@ | |||
2534 | 50 | return ''.join(c if c in valid_chars else '_' for c in _string) | 51 | return ''.join(c if c in valid_chars else '_' for c in _string) |
2535 | 51 | 52 | ||
2536 | 52 | 53 | ||
2537 | 54 | def io_log_write(log, stream): | ||
2538 | 55 | """ | ||
2539 | 56 | JSON call to serialize io_log objects to disk | ||
2540 | 57 | """ | ||
2541 | 58 | json.dump( | ||
2542 | 59 | log, stream, ensure_ascii=False, indent=None, cls=IoLogEncoder, | ||
2543 | 60 | separators=(',', ':')) | ||
2544 | 61 | |||
2545 | 62 | |||
2546 | 53 | class CommandIOLogBuilder(extcmd.DelegateBase): | 63 | class CommandIOLogBuilder(extcmd.DelegateBase): |
2547 | 54 | """ | 64 | """ |
2548 | 55 | Delegate for extcmd that builds io_log entries. | 65 | Delegate for extcmd that builds io_log entries. |
2549 | @@ -146,15 +156,24 @@ | |||
2550 | 146 | def __init__(self, prompt): | 156 | def __init__(self, prompt): |
2551 | 147 | self._prompt = prompt | 157 | self._prompt = prompt |
2552 | 148 | self._lineno = collections.defaultdict(int) | 158 | self._lineno = collections.defaultdict(int) |
2553 | 159 | self._abort = False | ||
2554 | 149 | 160 | ||
2555 | 150 | def on_line(self, stream_name, line): | 161 | def on_line(self, stream_name, line): |
2556 | 162 | if self._abort: | ||
2557 | 163 | return | ||
2558 | 151 | self._lineno[stream_name] += 1 | 164 | self._lineno[stream_name] += 1 |
2562 | 152 | print("(job {}, <{}:{:05}>) {}".format( | 165 | try: |
2563 | 153 | self._prompt, stream_name, self._lineno[stream_name], | 166 | print("(job {}, <{}:{:05}>) {}".format( |
2564 | 154 | line.rstrip())) | 167 | self._prompt, stream_name, self._lineno[stream_name], |
2565 | 168 | line.decode('UTF-8').rstrip())) | ||
2566 | 169 | except UnicodeDecodeError: | ||
2567 | 170 | self._abort = True | ||
2568 | 155 | 171 | ||
2569 | 156 | 172 | ||
2570 | 157 | class JobRunner(IJobRunner): | 173 | class JobRunner(IJobRunner): |
2571 | 174 | """ | ||
2572 | 175 | Runner for jobs - executes jobs and produces results | ||
2573 | 176 | """ | ||
2574 | 158 | 177 | ||
2575 | 159 | def __init__(self, session_dir, jobs_io_log_dir, | 178 | def __init__(self, session_dir, jobs_io_log_dir, |
2576 | 160 | command_io_delegate=None, outcome_callback=None): | 179 | command_io_delegate=None, outcome_callback=None): |
2577 | @@ -173,6 +192,9 @@ | |||
2578 | 173 | self._outcome_callback = outcome_callback | 192 | self._outcome_callback = outcome_callback |
2579 | 174 | 193 | ||
2580 | 175 | def run_job(self, job): | 194 | def run_job(self, job): |
2581 | 195 | """ | ||
2582 | 196 | Run the specified job an return the result | ||
2583 | 197 | """ | ||
2584 | 176 | logger.info("Running %r", job) | 198 | logger.info("Running %r", job) |
2585 | 177 | func_name = "_plugin_" + job.plugin.replace('-', '_') | 199 | func_name = "_plugin_" + job.plugin.replace('-', '_') |
2586 | 178 | try: | 200 | try: |
2587 | @@ -189,6 +211,8 @@ | |||
2588 | 189 | def _plugin_shell(self, job): | 211 | def _plugin_shell(self, job): |
2589 | 190 | return self._just_run_command(job) | 212 | return self._just_run_command(job) |
2590 | 191 | 213 | ||
2591 | 214 | _plugin_attachment = _plugin_shell | ||
2592 | 215 | |||
2593 | 192 | def _plugin_resource(self, job): | 216 | def _plugin_resource(self, job): |
2594 | 193 | return self._just_run_command(job) | 217 | return self._just_run_command(job) |
2595 | 194 | 218 | ||
2596 | @@ -227,7 +251,7 @@ | |||
2597 | 227 | 'io_log': io_log | 251 | 'io_log': io_log |
2598 | 228 | }) | 252 | }) |
2599 | 229 | 253 | ||
2601 | 230 | def _get_script_env(self, job): | 254 | def _get_script_env(self, job, only_changes=True): |
2602 | 231 | """ | 255 | """ |
2603 | 232 | Compute the environment the script will be executed in | 256 | Compute the environment the script will be executed in |
2604 | 233 | """ | 257 | """ |
2605 | @@ -237,7 +261,17 @@ | |||
2606 | 237 | env['LANG'] = 'C.UTF-8' | 261 | env['LANG'] = 'C.UTF-8' |
2607 | 238 | # Allow the job to customize anything | 262 | # Allow the job to customize anything |
2608 | 239 | job.modify_execution_environment(env, self._session_dir) | 263 | job.modify_execution_environment(env, self._session_dir) |
2610 | 240 | return env | 264 | # If a differential environment is requested return only the subset |
2611 | 265 | # that has been altered. | ||
2612 | 266 | # | ||
2613 | 267 | # XXX: This will effectively give the root user our PATH which _may_ be | ||
2614 | 268 | # good bud _might_ be dangerous. This will need some peer review. | ||
2615 | 269 | if only_changes: | ||
2616 | 270 | return {key: value | ||
2617 | 271 | for key, value in env.items() | ||
2618 | 272 | if key not in os.environ or os.environ[key] != value} | ||
2619 | 273 | else: | ||
2620 | 274 | return env | ||
2621 | 241 | 275 | ||
2622 | 242 | def _run_command(self, job): | 276 | def _run_command(self, job): |
2623 | 243 | """ | 277 | """ |
2624 | @@ -278,7 +312,7 @@ | |||
2625 | 278 | # Send the third copy to the output writer that writes everything to | 312 | # Send the third copy to the output writer that writes everything to |
2626 | 279 | # disk. | 313 | # disk. |
2627 | 280 | delegate = extcmd.Chain([ | 314 | delegate = extcmd.Chain([ |
2629 | 281 | extcmd.Decode(ui_io_delegate), | 315 | ui_io_delegate, |
2630 | 282 | io_log_builder, | 316 | io_log_builder, |
2631 | 283 | output_writer]) | 317 | output_writer]) |
2632 | 284 | logger.debug("job[%s] extcmd delegate: %r", job.name, delegate) | 318 | logger.debug("job[%s] extcmd delegate: %r", job.name, delegate) |
2633 | @@ -291,14 +325,37 @@ | |||
2634 | 291 | # threads although all callbacks will be fired from a single | 325 | # threads although all callbacks will be fired from a single |
2635 | 292 | # thread (which is _not_ the main thread) | 326 | # thread (which is _not_ the main thread) |
2636 | 293 | logger.debug("job[%s] starting command: %s", job.name, job.command) | 327 | logger.debug("job[%s] starting command: %s", job.name, job.command) |
2642 | 294 | return_code = logging_popen.call( | 328 | # XXX: sadly using /bin/sh results in broken output |
2643 | 295 | # XXX: sadly using /bin/sh results in broken output | 329 | # XXX: maybe run it both ways and raise exceptions on differences? |
2644 | 296 | # XXX: maybe run it both ways and raise exceptions on differences? | 330 | cmd = ['bash', '-c', job.command] |
2645 | 297 | ['bash', '-c', job.command], | 331 | if job.user is not None: |
2646 | 298 | env=self._get_script_env(job)) | 332 | # When the job requires to run as root then elevate our permissions |
2647 | 333 | # via pkexec(1). Since pkexec resets environment we need to somehow | ||
2648 | 334 | # pass the extra things we require. To do that we use the env(1) | ||
2649 | 335 | # command and pass it the list of changed environment variables. | ||
2650 | 336 | # | ||
2651 | 337 | # The whole pkexec and env part gets prepended to the command we | ||
2652 | 338 | # were supposed to run. | ||
2653 | 339 | cmd = ['pkexec', '--user', job.user, 'env'] + [ | ||
2654 | 340 | "{key}={value}".format(key=key, value=value) | ||
2655 | 341 | for key, value in self._get_script_env( | ||
2656 | 342 | job, only_changes=True | ||
2657 | 343 | ).items() | ||
2658 | 344 | ] + cmd | ||
2659 | 345 | logging.debug("job[%s] executing %r", job.name, cmd) | ||
2660 | 346 | return_code = logging_popen.call(cmd) | ||
2661 | 347 | else: | ||
2662 | 348 | logging.debug("job[%s] executing %r", job.name, cmd) | ||
2663 | 349 | return_code = logging_popen.call( | ||
2664 | 350 | cmd, env=self._get_script_env(job)) | ||
2665 | 299 | logger.debug("job[%s] command return code: %r", | 351 | logger.debug("job[%s] command return code: %r", |
2666 | 300 | job.name, return_code) | 352 | job.name, return_code) |
2667 | 301 | # XXX: Perhaps handle process dying from signals here | 353 | # XXX: Perhaps handle process dying from signals here |
2668 | 302 | # When the process is killed proc.returncode is not set | 354 | # When the process is killed proc.returncode is not set |
2669 | 303 | # and another (cannot remember now) attribute is set | 355 | # and another (cannot remember now) attribute is set |
2671 | 304 | return return_code, io_log_builder.io_log | 356 | fjson = os.path.join(self._jobs_io_log_dir, "{}.json".format(slug)) |
2672 | 357 | with open(fjson, "wt") as stream: | ||
2673 | 358 | io_log_write(io_log_builder.io_log, stream) | ||
2674 | 359 | stream.flush() | ||
2675 | 360 | os.fsync(stream.fileno()) | ||
2676 | 361 | return return_code, fjson | ||
2677 | 305 | 362 | ||
2678 | === modified file 'plainbox/plainbox/impl/session.py' | |||
2679 | --- plainbox/plainbox/impl/session.py 2013-02-22 16:26:25 +0000 | |||
2680 | +++ plainbox/plainbox/impl/session.py 2013-03-07 16:10:38 +0000 | |||
2681 | @@ -18,12 +18,12 @@ | |||
2682 | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. |
2683 | 19 | 19 | ||
2684 | 20 | """ | 20 | """ |
2691 | 21 | plainbox.impl.session | 21 | :mod:`plainbox.impl.session` -- session state handling |
2692 | 22 | ===================== | 22 | ====================================================== |
2693 | 23 | 23 | ||
2694 | 24 | Internal implementation of plainbox | 24 | .. warning:: |
2695 | 25 | 25 | ||
2696 | 26 | * THIS MODULE DOES NOT HAVE STABLE PUBLIC API * | 26 | THIS MODULE DOES NOT HAVE STABLE PUBLIC API |
2697 | 27 | """ | 27 | """ |
2698 | 28 | import json | 28 | import json |
2699 | 29 | import logging | 29 | import logging |
2700 | @@ -165,7 +165,7 @@ | |||
2701 | 165 | """ | 165 | """ |
2702 | 166 | Class representing the state of a job in a session. | 166 | Class representing the state of a job in a session. |
2703 | 167 | 167 | ||
2705 | 168 | Contains two basic properties of each job (either of which can be None): | 168 | Contains two basic properties of each job: |
2706 | 169 | 169 | ||
2707 | 170 | * the readiness_inhibitor_list that prevent the job form starting | 170 | * the readiness_inhibitor_list that prevent the job form starting |
2708 | 171 | * the result (outcome) of the run (IJobResult) | 171 | * the result (outcome) of the run (IJobResult) |
2709 | @@ -223,7 +223,7 @@ | |||
2710 | 223 | return self._result | 223 | return self._result |
2711 | 224 | 224 | ||
2712 | 225 | def fset(self, value): | 225 | def fset(self, value): |
2714 | 226 | if value.job is not self.job: | 226 | if value.job.get_checksum() != self.job.get_checksum(): |
2715 | 227 | raise ValueError("result job does not match") | 227 | raise ValueError("result job does not match") |
2716 | 228 | self._result = value | 228 | self._result = value |
2717 | 229 | 229 | ||
2718 | @@ -278,53 +278,79 @@ | |||
2719 | 278 | """ | 278 | """ |
2720 | 279 | Class representing all state needed during a single program session. | 279 | Class representing all state needed during a single program session. |
2721 | 280 | 280 | ||
2722 | 281 | This is the central glue/entry-point for applications. It connects user | ||
2723 | 282 | intents to the rest of the system / plumbing and keeps all of the state in | ||
2724 | 283 | one place. | ||
2725 | 284 | |||
2726 | 281 | The set of utility methods and properties allow applications to easily | 285 | The set of utility methods and properties allow applications to easily |
2727 | 282 | handle the lower levels of dependencies, resources and ready states. | 286 | handle the lower levels of dependencies, resources and ready states. |
2728 | 283 | 287 | ||
2736 | 284 | Once instantiated with a list of known jobs it is ready to react to | 288 | SessionState has the following instance variables, all of which are |
2737 | 285 | UI-driven changes. It is expected that the user will select / unselect | 289 | currently exposed as properties. |
2738 | 286 | and run jobs. This class can react to both actions by recomputing the | 290 | |
2739 | 287 | dependency graph and updating the read states accordingly. | 291 | :ivar list job_list: A list of all known jobs |
2740 | 288 | 292 | ||
2741 | 289 | Ready states (one for each job) allow the UI to take simple decisions | 293 | Not all the jobs from this list are going to be executed (or selected |
2742 | 290 | (either can or cannot run) | 294 | for execution) by the user. |
2743 | 295 | |||
2744 | 296 | It may change at runtime because of local jobs. Note that in upcoming | ||
2745 | 297 | changes this will start out empty and will be changeable dynamically. | ||
2746 | 298 | It can still change due to local jobs but there is no API yes. | ||
2747 | 299 | |||
2748 | 300 | :ivar dict job_state_map: mapping that tracks the state of each job | ||
2749 | 301 | |||
2750 | 302 | Mapping from job name to :class:`JobState`. This basically has the test | ||
2751 | 303 | result and the inhibitor of each job. It also serves as a | ||
2752 | 304 | :attr:`plainbox.impl.job.JobDefinition.name`-> job lookup helper. | ||
2753 | 305 | |||
2754 | 306 | Directly exposed with the intent to fuel part of the UI. This is a way | ||
2755 | 307 | to get at the readiness state, result and readiness inhibitors, if any. | ||
2756 | 308 | |||
2757 | 309 | XXX: this can loose data job_list has jobs with the same name. It would | ||
2758 | 310 | be better to use job id as the keys here. A separate map could be used | ||
2759 | 311 | for the name->job lookup. This will be fixed when session controller | ||
2760 | 312 | branch lands in trunk as then jobs are dynamically added to the system | ||
2761 | 313 | one at a time and proper error conditions can be detected and reported. | ||
2762 | 314 | |||
2763 | 315 | :ivar list desired_job_list: subset of jobs selected for execution | ||
2764 | 316 | |||
2765 | 317 | This is used to compute :attr:`run_list`. It can only be changed by | ||
2766 | 318 | calling :meth:`update_desired_job_list()` which returns meaningful | ||
2767 | 319 | values so this is not a settable property. | ||
2768 | 320 | |||
2769 | 321 | :ivar list run_list: sorted list of jobs to execute | ||
2770 | 322 | |||
2771 | 323 | This is basically a superset of desired_job_list and a subset of | ||
2772 | 324 | job_list that is topologically sorted to allowing all desired jobs to | ||
2773 | 325 | run. This property is updated whenever desired_job_list is changed. | ||
2774 | 326 | |||
2775 | 327 | :ivar dict resource_map: all known resources | ||
2776 | 328 | |||
2777 | 329 | A mapping from resource name to a list of | ||
2778 | 330 | :class:`plainbox.impl.resource.Resource` objects. This encapsulates all | ||
2779 | 331 | "knowledge" about the system plainbox is running on. | ||
2780 | 332 | |||
2781 | 333 | It is needed to compute job readiness (as it stores resource data | ||
2782 | 334 | needed by resource programs). It is also available to exporters. | ||
2783 | 335 | |||
2784 | 336 | This is computed internally from the output of checkbox resource jobs, | ||
2785 | 337 | it can only be changed by calling :meth:`update_job_result()` | ||
2786 | 291 | """ | 338 | """ |
2787 | 292 | 339 | ||
2788 | 293 | session_data_filename = 'session.json' | 340 | session_data_filename = 'session.json' |
2789 | 294 | 341 | ||
2790 | 295 | def __init__(self, job_list): | 342 | def __init__(self, job_list): |
2791 | 296 | # The original list of job that the system knows about. | ||
2792 | 297 | # Not all jobs from this list are going to be executed | ||
2793 | 298 | # (or selected for execution) by the user. | ||
2794 | 299 | self._job_list = job_list | 343 | self._job_list = job_list |
2795 | 300 | # State of each job, see JobState for details but it basically | ||
2796 | 301 | # has the test result and the inhibitor of each job. It also serves | ||
2797 | 302 | # as a job.name -> job lookup helper. | ||
2798 | 303 | # | ||
2799 | 304 | # Directly exposed with the intent to fuel part of the UI. | ||
2800 | 305 | # | ||
2801 | 306 | # XXX: this can loose data job_list has jobs with the same name. It | ||
2802 | 307 | # would be better to use job id as the keys here. A separate map could | ||
2803 | 308 | # be used for the name->job lookup. | ||
2804 | 309 | self._job_state_map = {job.name: JobState(job) | 344 | self._job_state_map = {job.name: JobState(job) |
2805 | 310 | for job in self._job_list} | 345 | for job in self._job_list} |
2806 | 311 | # A subset of job_list that was selected by the user for execution. | ||
2807 | 312 | # Used to compute run_list. Can be changed at will during lifetime | ||
2808 | 313 | # of this object | ||
2809 | 314 | self._desired_job_list = [] | 346 | self._desired_job_list = [] |
2810 | 315 | # Copy of desired_job_list that was topologically sorted by the | ||
2811 | 316 | # dependency solver. Jobs must run in this order (although not all jobs | ||
2812 | 317 | # may actually run or will actually be successful) | ||
2813 | 318 | self._run_list = [] | 347 | self._run_list = [] |
2814 | 319 | # A collection of known resources. Mapping resource job name to a list | ||
2815 | 320 | # of resource objects. Needed to compute task readiness (as it stores | ||
2816 | 321 | # resource data needed by resource programs). Currently not exposed | ||
2817 | 322 | # outside of this class. | ||
2818 | 323 | self._resource_map = {} | 348 | self._resource_map = {} |
2819 | 324 | # Temporary directory used as 'scratch space' for running jobs. Removed | 349 | # Temporary directory used as 'scratch space' for running jobs. Removed |
2820 | 325 | # entirely when session is terminated. Internally this is exposed as | 350 | # entirely when session is terminated. Internally this is exposed as |
2821 | 326 | # $CHECKBOX_DATA to script environment. | 351 | # $CHECKBOX_DATA to script environment. |
2822 | 327 | self._session_dir = None | 352 | self._session_dir = None |
2823 | 353 | |||
2824 | 328 | # Directory used to store jobs IO logs. | 354 | # Directory used to store jobs IO logs. |
2825 | 329 | self._jobs_io_log_dir = None | 355 | self._jobs_io_log_dir = None |
2826 | 330 | 356 | ||
2827 | @@ -355,28 +381,34 @@ | |||
2828 | 355 | if self._session_dir is None: | 381 | if self._session_dir is None: |
2829 | 356 | xdg_cache_home = os.environ.get('XDG_CACHE_HOME') or \ | 382 | xdg_cache_home = os.environ.get('XDG_CACHE_HOME') or \ |
2830 | 357 | os.path.join(os.path.expanduser('~'), '.cache') | 383 | os.path.join(os.path.expanduser('~'), '.cache') |
2835 | 358 | temp_dir = os.path.join(xdg_cache_home, 'plainbox') | 384 | self._session_dir = os.path.join(xdg_cache_home, 'plainbox') |
2836 | 359 | if not os.path.isdir(temp_dir): | 385 | if not os.path.isdir(self._session_dir): |
2837 | 360 | os.makedirs(temp_dir) | 386 | os.makedirs(self._session_dir) |
2834 | 361 | self._session_dir = tempfile.mkdtemp(dir=temp_dir) | ||
2838 | 362 | if self._jobs_io_log_dir is None: | 387 | if self._jobs_io_log_dir is None: |
2839 | 363 | self._jobs_io_log_dir = os.path.join(self._session_dir, 'io-logs') | 388 | self._jobs_io_log_dir = os.path.join(self._session_dir, 'io-logs') |
2840 | 364 | if not os.path.isdir(self._jobs_io_log_dir): | 389 | if not os.path.isdir(self._jobs_io_log_dir): |
2841 | 365 | os.makedirs(self._jobs_io_log_dir) | 390 | os.makedirs(self._jobs_io_log_dir) |
2842 | 366 | return self | 391 | return self |
2843 | 367 | 392 | ||
2845 | 368 | def close(self): | 393 | def clean(self): |
2846 | 369 | """ | 394 | """ |
2853 | 370 | Close the session and remove temporary disk state. | 395 | Clean the session directory. |
2848 | 371 | |||
2849 | 372 | This function removes the directory created by .open() and all the data | ||
2850 | 373 | that was placed there. It is automatically called by __exit__, the | ||
2851 | 374 | context manager exit function. Care should be taken to ensure that all | ||
2852 | 375 | session data, particularly attachments, were saved before. | ||
2854 | 376 | """ | 396 | """ |
2855 | 377 | if self._session_dir is not None: | 397 | if self._session_dir is not None: |
2856 | 378 | shutil.rmtree(self._session_dir) | 398 | shutil.rmtree(self._session_dir) |
2857 | 379 | self._session_dir = None | 399 | self._session_dir = None |
2858 | 400 | self._jobs_io_log_dir = None | ||
2859 | 401 | self.open() | ||
2860 | 402 | |||
2861 | 403 | def close(self): | ||
2862 | 404 | """ | ||
2863 | 405 | Close the session. | ||
2864 | 406 | |||
2865 | 407 | It is automatically called by __exit__, the context manager exit | ||
2866 | 408 | function. | ||
2867 | 409 | """ | ||
2868 | 410 | self._session_dir = None | ||
2869 | 411 | self._jobs_io_log_dir = None | ||
2870 | 380 | 412 | ||
2871 | 381 | def update_desired_job_list(self, desired_job_list): | 413 | def update_desired_job_list(self, desired_job_list): |
2872 | 382 | """ | 414 | """ |
2873 | @@ -405,7 +437,7 @@ | |||
2874 | 405 | # resources or runtime complexity. | 437 | # resources or runtime complexity. |
2875 | 406 | try: | 438 | try: |
2876 | 407 | self._run_list = DependencySolver.resolve_dependencies( | 439 | self._run_list = DependencySolver.resolve_dependencies( |
2878 | 408 | self._job_list, desired_job_list) | 440 | self._job_list, self._desired_job_list) |
2879 | 409 | except DependencyError as exc: | 441 | except DependencyError as exc: |
2880 | 410 | # When a dependency error is detected remove the affected job | 442 | # When a dependency error is detected remove the affected job |
2881 | 411 | # form _desired_job_list and try again. | 443 | # form _desired_job_list and try again. |
2882 | @@ -457,11 +489,22 @@ | |||
2883 | 457 | # Update all job readiness state | 489 | # Update all job readiness state |
2884 | 458 | self._recompute_job_readiness() | 490 | self._recompute_job_readiness() |
2885 | 459 | 491 | ||
2886 | 492 | def previous_session_file(self): | ||
2887 | 493 | """ | ||
2888 | 494 | Check the filesystem for previous session data | ||
2889 | 495 | Returns the full pathname to the session file if it exists | ||
2890 | 496 | """ | ||
2891 | 497 | session_filename = os.path.join(self._session_dir, | ||
2892 | 498 | self.session_data_filename) | ||
2893 | 499 | if os.path.exists(session_filename): | ||
2894 | 500 | return session_filename | ||
2895 | 501 | else: | ||
2896 | 502 | return None | ||
2897 | 503 | |||
2898 | 460 | def persistent_save(self): | 504 | def persistent_save(self): |
2899 | 461 | """ | 505 | """ |
2900 | 462 | Save to disk the minimum needed to resume plainbox where it stopped | 506 | Save to disk the minimum needed to resume plainbox where it stopped |
2901 | 463 | """ | 507 | """ |
2902 | 464 | |||
2903 | 465 | # Ensure an atomic update of the session file: | 508 | # Ensure an atomic update of the session file: |
2904 | 466 | # - create a new temp file (on the same file system!) | 509 | # - create a new temp file (on the same file system!) |
2905 | 467 | # - write data to the temp file | 510 | # - write data to the temp file |
2906 | @@ -472,7 +515,6 @@ | |||
2907 | 472 | # directory containing the file has also reached disk. | 515 | # directory containing the file has also reached disk. |
2908 | 473 | # For that an explicit fsync() on a file descriptor for the directory | 516 | # For that an explicit fsync() on a file descriptor for the directory |
2909 | 474 | # is also needed. | 517 | # is also needed. |
2910 | 475 | |||
2911 | 476 | filename = os.path.join(self._session_dir, | 518 | filename = os.path.join(self._session_dir, |
2912 | 477 | self.session_data_filename) | 519 | self.session_data_filename) |
2913 | 478 | 520 | ||
2914 | @@ -493,6 +535,28 @@ | |||
2915 | 493 | os.fsync(session_dir_fd) | 535 | os.fsync(session_dir_fd) |
2916 | 494 | os.close(session_dir_fd) | 536 | os.close(session_dir_fd) |
2917 | 495 | 537 | ||
2918 | 538 | def resume(self): | ||
2919 | 539 | """ | ||
2920 | 540 | Erase the job_state_map and desired_job_list with the saved ones | ||
2921 | 541 | """ | ||
2922 | 542 | with open(self.previous_session_file(), 'r') as f: | ||
2923 | 543 | previous_session = json.load( | ||
2924 | 544 | f, object_hook=SessionStateEncoder().dict_to_object) | ||
2925 | 545 | self._job_state_map = previous_session._job_state_map | ||
2926 | 546 | desired_job_list = [] | ||
2927 | 547 | for job in previous_session._desired_job_list: | ||
2928 | 548 | if job in self._job_list: | ||
2929 | 549 | desired_job_list.extend( | ||
2930 | 550 | [j for j in self._job_list if j == job]) | ||
2931 | 551 | elif (previous_session._job_state_map[job.name].result.outcome != | ||
2932 | 552 | JobResult.OUTCOME_NONE): | ||
2933 | 553 | # Keep jobs results from the previous session without a | ||
2934 | 554 | # definition in the current job_list only if they have | ||
2935 | 555 | # a valid result | ||
2936 | 556 | desired_job_list.append(job) | ||
2937 | 557 | self.update_desired_job_list(desired_job_list) | ||
2938 | 558 | # FIXME: Restore io_logs from files | ||
2939 | 559 | |||
2940 | 496 | def _process_resource_result(self, result): | 560 | def _process_resource_result(self, result): |
2941 | 497 | new_resource_list = [] | 561 | new_resource_list = [] |
2942 | 498 | for record in self._gen_rfc822_records_from_io_log(result): | 562 | for record in self._gen_rfc822_records_from_io_log(result): |
2943 | @@ -686,7 +750,6 @@ | |||
2944 | 686 | job_state.readiness_inhibitor_list.append(inhibitor) | 750 | job_state.readiness_inhibitor_list.append(inhibitor) |
2945 | 687 | 751 | ||
2946 | 688 | def __enter__(self): | 752 | def __enter__(self): |
2947 | 689 | self.open() | ||
2948 | 690 | return self | 753 | return self |
2949 | 691 | 754 | ||
2950 | 692 | def __exit__(self, *args): | 755 | def __exit__(self, *args): |
2951 | 693 | 756 | ||
2952 | === modified file 'plainbox/plainbox/impl/test_box.py' | |||
2953 | --- plainbox/plainbox/impl/test_box.py 2013-02-22 16:26:25 +0000 | |||
2954 | +++ plainbox/plainbox/impl/test_box.py 2013-03-07 16:10:38 +0000 | |||
2955 | @@ -24,15 +24,91 @@ | |||
2956 | 24 | Test definitions for plainbox.impl.box module | 24 | Test definitions for plainbox.impl.box module |
2957 | 25 | """ | 25 | """ |
2958 | 26 | 26 | ||
2959 | 27 | import os | ||
2960 | 28 | import shutil | ||
2961 | 29 | import tempfile | ||
2962 | 30 | |||
2963 | 31 | from inspect import cleandoc | ||
2964 | 32 | from mock import Mock | ||
2965 | 27 | from unittest import TestCase | 33 | from unittest import TestCase |
2966 | 28 | from inspect import cleandoc | ||
2967 | 29 | |||
2968 | 30 | 34 | ||
2969 | 31 | from plainbox import __version__ as version | 35 | from plainbox import __version__ as version |
2971 | 32 | from plainbox.impl.box import main | 36 | from plainbox.impl.box import main, CheckBoxCommandMixIn |
2972 | 37 | from plainbox.impl.mock_job import MockJobDefinition | ||
2973 | 33 | from plainbox.testing_utils.io import TestIO | 38 | from plainbox.testing_utils.io import TestIO |
2974 | 34 | 39 | ||
2975 | 35 | 40 | ||
2976 | 41 | class MiscTests(TestCase): | ||
2977 | 42 | |||
2978 | 43 | def setUp(self): | ||
2979 | 44 | self.job_foo = MockJobDefinition(name='foo') | ||
2980 | 45 | self.job_bar = MockJobDefinition(name='bar') | ||
2981 | 46 | self.obj = CheckBoxCommandMixIn(Mock(name="checkbox")) | ||
2982 | 47 | |||
2983 | 48 | def test_matching_job_list(self): | ||
2984 | 49 | # Nothing gets selected automatically | ||
2985 | 50 | ns = Mock() | ||
2986 | 51 | ns.whitelist = None | ||
2987 | 52 | ns.include_pattern_list = [] | ||
2988 | 53 | ns.exclude_pattern_list = [] | ||
2989 | 54 | observed = self.obj._get_matching_job_list(ns, [ | ||
2990 | 55 | self.job_foo, self.job_bar]) | ||
2991 | 56 | self.assertEqual(observed, []) | ||
2992 | 57 | |||
2993 | 58 | def test_matching_job_list_including(self): | ||
2994 | 59 | # Including jobs with glob pattern works | ||
2995 | 60 | ns = Mock() | ||
2996 | 61 | ns.whitelist = None | ||
2997 | 62 | ns.include_pattern_list = ['f.+'] | ||
2998 | 63 | ns.exclude_pattern_list = [] | ||
2999 | 64 | observed = self.obj._get_matching_job_list(ns, [ | ||
3000 | 65 | self.job_foo, self.job_bar]) | ||
3001 | 66 | self.assertEqual(observed, [self.job_foo]) | ||
3002 | 67 | |||
3003 | 68 | def test_matching_job_list_excluding(self): | ||
3004 | 69 | # Excluding jobs with glob pattern works | ||
3005 | 70 | ns = Mock() | ||
3006 | 71 | ns.whitelist = None | ||
3007 | 72 | ns.include_pattern_list = ['.+'] | ||
3008 | 73 | ns.exclude_pattern_list = ['f.+'] | ||
3009 | 74 | observed = self.obj._get_matching_job_list(ns, [ | ||
3010 | 75 | self.job_foo, self.job_bar]) | ||
3011 | 76 | self.assertEqual(observed, [self.job_bar]) | ||
3012 | 77 | |||
3013 | 78 | def test_matching_job_list_whitelist(self): | ||
3014 | 79 | # whitelists contain list of include patterns | ||
3015 | 80 | # that are read and interpreted as usual | ||
3016 | 81 | whitelist = Mock() | ||
3017 | 82 | whitelist.readlines.return_value = ['foo'] | ||
3018 | 83 | ns = Mock() | ||
3019 | 84 | ns.whitelist = whitelist | ||
3020 | 85 | ns.include_pattern_list = [] | ||
3021 | 86 | ns.exclude_pattern_list = [] | ||
3022 | 87 | observed = self.obj._get_matching_job_list(ns, [ | ||
3023 | 88 | self.job_foo, self.job_bar]) | ||
3024 | 89 | self.assertEqual(observed, [self.job_foo]) | ||
3025 | 90 | |||
3026 | 91 | def test_no_prefix_matching_including(self): | ||
3027 | 92 | # Include patterns should only match whole job name | ||
3028 | 93 | ns = Mock() | ||
3029 | 94 | ns.whitelist = None | ||
3030 | 95 | ns.include_pattern_list = ['fo', 'ba.+'] | ||
3031 | 96 | ns.exclude_pattern_list = [] | ||
3032 | 97 | observed = self.obj._get_matching_job_list(ns, [self.job_foo, | ||
3033 | 98 | self.job_bar]) | ||
3034 | 99 | self.assertEqual(observed, [self.job_bar]) | ||
3035 | 100 | |||
3036 | 101 | def test_no_prefix_matching_excluding(self): | ||
3037 | 102 | # Exclude patterns should only match whole job name | ||
3038 | 103 | ns = Mock() | ||
3039 | 104 | ns.whitelist = None | ||
3040 | 105 | ns.include_pattern_list = ['.+'] | ||
3041 | 106 | ns.exclude_pattern_list = ['fo', 'ba.+'] | ||
3042 | 107 | observed = self.obj._get_matching_job_list(ns, [self.job_foo, | ||
3043 | 108 | self.job_bar]) | ||
3044 | 109 | self.assertEqual(observed, [self.job_foo]) | ||
3045 | 110 | |||
3046 | 111 | |||
3047 | 36 | class TestMain(TestCase): | 112 | class TestMain(TestCase): |
3048 | 37 | 113 | ||
3049 | 38 | def test_version(self): | 114 | def test_version(self): |
3050 | @@ -85,7 +161,7 @@ | |||
3051 | 85 | self.maxDiff = None | 161 | self.maxDiff = None |
3052 | 86 | expected = """ | 162 | expected = """ |
3053 | 87 | usage: plainbox special [-h] (-j | -e | -d) [--dot-resources] [-i PATTERN] | 163 | usage: plainbox special [-h] (-j | -e | -d) [--dot-resources] [-i PATTERN] |
3055 | 88 | [-W WHITELIST] | 164 | [-x PATTERN] [-w WHITELIST] |
3056 | 89 | 165 | ||
3057 | 90 | optional arguments: | 166 | optional arguments: |
3058 | 91 | -h, --help show this help message and exit | 167 | -h, --help show this help message and exit |
3059 | @@ -97,8 +173,12 @@ | |||
3060 | 97 | 173 | ||
3061 | 98 | job definition options: | 174 | job definition options: |
3062 | 99 | -i PATTERN, --include-pattern PATTERN | 175 | -i PATTERN, --include-pattern PATTERN |
3065 | 100 | Run jobs matching the given pattern | 176 | Run jobs matching the given regular expression. |
3066 | 101 | -W WHITELIST, --whitelist WHITELIST | 177 | Matches from the start to the end of the line. |
3067 | 178 | -x PATTERN, --exclude-pattern PATTERN | ||
3068 | 179 | Do not run jobs matching the given regular expression. | ||
3069 | 180 | Matches from the start to the end of the line. | ||
3070 | 181 | -w WHITELIST, --whitelist WHITELIST | ||
3071 | 102 | Load whitelist containing run patterns | 182 | Load whitelist containing run patterns |
3072 | 103 | """ | 183 | """ |
3073 | 104 | self.assertEqual(io.combined, cleandoc(expected) + "\n") | 184 | self.assertEqual(io.combined, cleandoc(expected) + "\n") |
3074 | @@ -110,7 +190,7 @@ | |||
3075 | 110 | self.assertEqual(call.exception.args, (2,)) | 190 | self.assertEqual(call.exception.args, (2,)) |
3076 | 111 | expected = """ | 191 | expected = """ |
3077 | 112 | usage: plainbox special [-h] (-j | -e | -d) [--dot-resources] [-i PATTERN] | 192 | usage: plainbox special [-h] (-j | -e | -d) [--dot-resources] [-i PATTERN] |
3079 | 113 | [-W WHITELIST] | 193 | [-x PATTERN] [-w WHITELIST] |
3080 | 114 | plainbox special: error: one of the arguments -j/--list-jobs -e/--list-expressions -d/--dot is required | 194 | plainbox special: error: one of the arguments -j/--list-jobs -e/--list-expressions -d/--dot is required |
3081 | 115 | """ | 195 | """ |
3082 | 116 | self.assertEqual(io.combined, cleandoc(expected) + "\n") | 196 | self.assertEqual(io.combined, cleandoc(expected) + "\n") |
3083 | @@ -130,7 +210,7 @@ | |||
3084 | 130 | def test_run_list_jobs_with_filtering(self): | 210 | def test_run_list_jobs_with_filtering(self): |
3085 | 131 | with TestIO() as io: | 211 | with TestIO() as io: |
3086 | 132 | with self.assertRaises(SystemExit) as call: | 212 | with self.assertRaises(SystemExit) as call: |
3088 | 133 | main(['special', '--include-pattern=usb3*', '--list-jobs']) | 213 | main(['special', '--include-pattern=usb3.+', '--list-jobs']) |
3089 | 134 | self.assertEqual(call.exception.args, (0,)) | 214 | self.assertEqual(call.exception.args, (0,)) |
3090 | 135 | # Test that usb3 insertion test was listed but the usb (2.0) test was not | 215 | # Test that usb3 insertion test was listed but the usb (2.0) test was not |
3091 | 136 | self.assertIn("usb3/insert", io.stdout.splitlines()) | 216 | self.assertIn("usb3/insert", io.stdout.splitlines()) |
3092 | @@ -181,6 +261,14 @@ | |||
3093 | 181 | 261 | ||
3094 | 182 | class TestRun(TestCase): | 262 | class TestRun(TestCase): |
3095 | 183 | 263 | ||
3096 | 264 | def setUp(self): | ||
3097 | 265 | # session data are kept in XDG_CACHE_HOME/plainbox/.session | ||
3098 | 266 | # To avoid resuming a real session, we have to select a temporary | ||
3099 | 267 | # location instead | ||
3100 | 268 | self._sandbox = tempfile.mkdtemp() | ||
3101 | 269 | self._env = os.environ | ||
3102 | 270 | os.environ['XDG_CACHE_HOME'] = self._sandbox | ||
3103 | 271 | |||
3104 | 184 | def test_help(self): | 272 | def test_help(self): |
3105 | 185 | with TestIO(combined=True) as io: | 273 | with TestIO(combined=True) as io: |
3106 | 186 | with self.assertRaises(SystemExit) as call: | 274 | with self.assertRaises(SystemExit) as call: |
3107 | @@ -189,7 +277,7 @@ | |||
3108 | 189 | self.maxDiff = None | 277 | self.maxDiff = None |
3109 | 190 | expected = """ | 278 | expected = """ |
3110 | 191 | usage: plainbox run [-h] [--not-interactive] [-n] [-f FORMAT] [-p OPTIONS] | 279 | usage: plainbox run [-h] [--not-interactive] [-n] [-f FORMAT] [-p OPTIONS] |
3112 | 192 | [-o FILE] [-i PATTERN] [-W WHITELIST] | 280 | [-o FILE] [-i PATTERN] [-x PATTERN] [-w WHITELIST] |
3113 | 193 | 281 | ||
3114 | 194 | optional arguments: | 282 | optional arguments: |
3115 | 195 | -h, --help show this help message and exit | 283 | -h, --help show this help message and exit |
3116 | @@ -211,8 +299,12 @@ | |||
3117 | 211 | 299 | ||
3118 | 212 | job definition options: | 300 | job definition options: |
3119 | 213 | -i PATTERN, --include-pattern PATTERN | 301 | -i PATTERN, --include-pattern PATTERN |
3122 | 214 | Run jobs matching the given pattern | 302 | Run jobs matching the given regular expression. |
3123 | 215 | -W WHITELIST, --whitelist WHITELIST | 303 | Matches from the start to the end of the line. |
3124 | 304 | -x PATTERN, --exclude-pattern PATTERN | ||
3125 | 305 | Do not run jobs matching the given regular expression. | ||
3126 | 306 | Matches from the start to the end of the line. | ||
3127 | 307 | -w WHITELIST, --whitelist WHITELIST | ||
3128 | 216 | Load whitelist containing run patterns | 308 | Load whitelist containing run patterns |
3129 | 217 | """ | 309 | """ |
3130 | 218 | self.assertEqual(io.combined, cleandoc(expected) + "\n") | 310 | self.assertEqual(io.combined, cleandoc(expected) + "\n") |
3131 | @@ -246,8 +338,12 @@ | |||
3132 | 246 | self.assertEqual(call.exception.args, (0,)) | 338 | self.assertEqual(call.exception.args, (0,)) |
3133 | 247 | expected = """ | 339 | expected = """ |
3134 | 248 | Each format may support a different set of options | 340 | Each format may support a different set of options |
3138 | 249 | json: with-io-log, squash-io-log, flatten-io-log, with-run-list, with-job-list, with-resource-map, with-job-defs, machine-json | 341 | json: with-io-log, squash-io-log, flatten-io-log, with-run-list, with-job-list, with-resource-map, with-job-defs, with-attachments, machine-json |
3139 | 250 | rfc822: with-io-log, squash-io-log, flatten-io-log, with-run-list, with-job-list, with-resource-map, with-job-defs | 342 | rfc822: with-io-log, squash-io-log, flatten-io-log, with-run-list, with-job-list, with-resource-map, with-job-defs, with-attachments |
3140 | 251 | text: with-io-log, squash-io-log, flatten-io-log, with-run-list, with-job-list, with-resource-map, with-job-defs | 343 | text: with-io-log, squash-io-log, flatten-io-log, with-run-list, with-job-list, with-resource-map, with-job-defs, with-attachments |
3141 | 252 | """ | 344 | """ |
3142 | 253 | self.assertEqual(io.combined, cleandoc(expected) + "\n") | 345 | self.assertEqual(io.combined, cleandoc(expected) + "\n") |
3143 | 346 | |||
3144 | 347 | def tearDown(self): | ||
3145 | 348 | shutil.rmtree(self._sandbox) | ||
3146 | 349 | os.environ = self._env | ||
3147 | 254 | 350 | ||
3148 | === modified file 'plainbox/plainbox/impl/test_job.py' | |||
3149 | --- plainbox/plainbox/impl/test_job.py 2013-02-22 16:26:25 +0000 | |||
3150 | +++ plainbox/plainbox/impl/test_job.py 2013-03-07 16:10:38 +0000 | |||
3151 | @@ -239,8 +239,7 @@ | |||
3152 | 239 | job_enc = job._get_persistance_subset() | 239 | job_enc = job._get_persistance_subset() |
3153 | 240 | self.assertEqual(job_enc['data']['plugin'], job.plugin) | 240 | self.assertEqual(job_enc['data']['plugin'], job.plugin) |
3154 | 241 | self.assertEqual(job_enc['data']['name'], job.name) | 241 | self.assertEqual(job_enc['data']['name'], job.name) |
3157 | 242 | with self.assertRaises(KeyError): | 242 | self.assertEqual(job_enc['data']['requires'], job.requires) |
3156 | 243 | job_enc['requires'] | ||
3158 | 244 | with self.assertRaises(KeyError): | 243 | with self.assertRaises(KeyError): |
3159 | 245 | job_enc['depends'] | 244 | job_enc['depends'] |
3160 | 246 | with self.assertRaises(KeyError): | 245 | with self.assertRaises(KeyError): |
3161 | @@ -280,7 +279,8 @@ | |||
3162 | 280 | "plugin": "user-verify" | 279 | "plugin": "user-verify" |
3163 | 281 | } | 280 | } |
3164 | 282 | }""" | 281 | }""" |
3166 | 283 | job_dec = json.loads(raw_json, object_hook=SessionStateEncoder().dict_to_object) | 282 | job_dec = json.loads(raw_json, |
3167 | 283 | object_hook=SessionStateEncoder().dict_to_object) | ||
3168 | 284 | self.assertIsInstance(job_dec, JobDefinition) | 284 | self.assertIsInstance(job_dec, JobDefinition) |
3169 | 285 | self.assertEqual(job_dec.name, "camera/still") | 285 | self.assertEqual(job_dec.name, "camera/still") |
3170 | 286 | self.assertEqual(job_dec.plugin, "user-verify") | 286 | self.assertEqual(job_dec.plugin, "user-verify") |
3171 | 287 | 287 | ||
3172 | === modified file 'plainbox/plainbox/impl/test_result.py' | |||
3173 | --- plainbox/plainbox/impl/test_result.py 2013-02-22 16:26:25 +0000 | |||
3174 | +++ plainbox/plainbox/impl/test_result.py 2013-03-07 16:10:38 +0000 | |||
3175 | @@ -25,10 +25,11 @@ | |||
3176 | 25 | """ | 25 | """ |
3177 | 26 | import json | 26 | import json |
3178 | 27 | 27 | ||
3179 | 28 | from tempfile import TemporaryDirectory | ||
3180 | 28 | from unittest import TestCase | 29 | from unittest import TestCase |
3181 | 29 | 30 | ||
3182 | 30 | from plainbox.impl.result import JobResult | 31 | from plainbox.impl.result import JobResult |
3184 | 31 | from plainbox.impl.testing_utils import make_job | 32 | from plainbox.impl.testing_utils import make_io_log, make_job |
3185 | 32 | from plainbox.impl.session import SessionStateEncoder | 33 | from plainbox.impl.session import SessionStateEncoder |
3186 | 33 | 34 | ||
3187 | 34 | 35 | ||
3188 | @@ -50,22 +51,24 @@ | |||
3189 | 50 | self.assertIsNone(result.return_code) | 51 | self.assertIsNone(result.return_code) |
3190 | 51 | 52 | ||
3191 | 52 | def test_everything(self): | 53 | def test_everything(self): |
3208 | 53 | result = JobResult({ | 54 | with TemporaryDirectory() as scratch_dir: |
3209 | 54 | 'job': self.job, | 55 | result = JobResult({ |
3210 | 55 | 'outcome': JobResult.OUTCOME_PASS, | 56 | 'job': self.job, |
3211 | 56 | 'comments': "it said blah", | 57 | 'outcome': JobResult.OUTCOME_PASS, |
3212 | 57 | 'io_log': ((0, 'stdout', b'blah\n'),), | 58 | 'comments': "it said blah", |
3213 | 58 | 'return_code': 0 | 59 | 'io_log': make_io_log(((0, 'stdout', b'blah\n'),), |
3214 | 59 | }) | 60 | scratch_dir), |
3215 | 60 | self.assertEqual(str(result), "A: pass") | 61 | 'return_code': 0 |
3216 | 61 | self.assertEqual(repr(result), ( | 62 | }) |
3217 | 62 | "<JobResult job:<JobDefinition name:'A' plugin:'dummy'>" | 63 | self.assertEqual(str(result), "A: pass") |
3218 | 63 | " outcome:'pass'>")) | 64 | self.assertEqual(repr(result), ( |
3219 | 64 | self.assertIs(result.job, self.job) | 65 | "<JobResult job:<JobDefinition name:'A' plugin:'dummy'>" |
3220 | 65 | self.assertEqual(result.outcome, JobResult.OUTCOME_PASS) | 66 | " outcome:'pass'>")) |
3221 | 66 | self.assertEqual(result.comments, "it said blah") | 67 | self.assertIs(result.job, self.job) |
3222 | 67 | self.assertEqual(result.io_log, ((0, 'stdout', b'blah\n'),)) | 68 | self.assertEqual(result.outcome, JobResult.OUTCOME_PASS) |
3223 | 68 | self.assertEqual(result.return_code, 0) | 69 | self.assertEqual(result.comments, "it said blah") |
3224 | 70 | self.assertEqual(result.io_log, ((0, 'stdout', b'blah\n'),)) | ||
3225 | 71 | self.assertEqual(result.return_code, 0) | ||
3226 | 69 | 72 | ||
3227 | 70 | def test_encode(self): | 73 | def test_encode(self): |
3228 | 71 | result = JobResult({ | 74 | result = JobResult({ |
3229 | @@ -99,7 +102,8 @@ | |||
3230 | 99 | "return_code": 0 | 102 | "return_code": 0 |
3231 | 100 | } | 103 | } |
3232 | 101 | }""" | 104 | }""" |
3234 | 102 | result_dec = json.loads(raw_json, object_hook=SessionStateEncoder().dict_to_object) | 105 | result_dec = json.loads(raw_json, |
3235 | 106 | object_hook=SessionStateEncoder().dict_to_object) | ||
3236 | 103 | self.assertIsInstance(result_dec, JobResult) | 107 | self.assertIsInstance(result_dec, JobResult) |
3237 | 104 | self.assertEqual(result_dec.job.name, "__audio__") | 108 | self.assertEqual(result_dec.job.name, "__audio__") |
3238 | 105 | self.assertEqual(result_dec.outcome, JobResult.OUTCOME_PASS) | 109 | self.assertEqual(result_dec.outcome, JobResult.OUTCOME_PASS) |
3239 | 106 | 110 | ||
3240 | === modified file 'plainbox/plainbox/impl/test_runner.py' | |||
3241 | --- plainbox/plainbox/impl/test_runner.py 2013-02-22 16:26:25 +0000 | |||
3242 | +++ plainbox/plainbox/impl/test_runner.py 2013-03-07 16:10:38 +0000 | |||
3243 | @@ -73,11 +73,11 @@ | |||
3244 | 73 | with TestIO(combined=False) as io: | 73 | with TestIO(combined=False) as io: |
3245 | 74 | obj = FallbackCommandOutputPrinter("example") | 74 | obj = FallbackCommandOutputPrinter("example") |
3246 | 75 | # Whatever gets printed by the job... | 75 | # Whatever gets printed by the job... |
3252 | 76 | obj.on_line('stdout', 'line 1\n') | 76 | obj.on_line('stdout', b'line 1\n') |
3253 | 77 | obj.on_line('stderr', 'line 1\n') | 77 | obj.on_line('stderr', b'line 1\n') |
3254 | 78 | obj.on_line('stdout', 'line 2\n') | 78 | obj.on_line('stdout', b'line 2\n') |
3255 | 79 | obj.on_line('stdout', 'line 3\n') | 79 | obj.on_line('stdout', b'line 3\n') |
3256 | 80 | obj.on_line('stderr', 'line 2\n') | 80 | obj.on_line('stderr', b'line 2\n') |
3257 | 81 | # Gets printed to stdout _only_, stderr is combined with stdout here | 81 | # Gets printed to stdout _only_, stderr is combined with stdout here |
3258 | 82 | self.assertEqual(io.stdout, ( | 82 | self.assertEqual(io.stdout, ( |
3259 | 83 | "(job example, <stdout:00001>) line 1\n" | 83 | "(job example, <stdout:00001>) line 1\n" |
3260 | 84 | 84 | ||
3261 | === modified file 'plainbox/plainbox/impl/test_session.py' | |||
3262 | --- plainbox/plainbox/impl/test_session.py 2013-02-22 16:26:25 +0000 | |||
3263 | +++ plainbox/plainbox/impl/test_session.py 2013-03-07 16:10:38 +0000 | |||
3264 | @@ -25,18 +25,22 @@ | |||
3265 | 25 | """ | 25 | """ |
3266 | 26 | 26 | ||
3267 | 27 | import json | 27 | import json |
3268 | 28 | import os | ||
3269 | 29 | import tempfile | ||
3270 | 30 | import shutil | ||
3271 | 28 | 31 | ||
3272 | 32 | from tempfile import TemporaryDirectory | ||
3273 | 29 | from unittest import TestCase | 33 | from unittest import TestCase |
3274 | 30 | 34 | ||
3275 | 35 | from plainbox.impl.depmgr import DependencyMissingError | ||
3276 | 31 | from plainbox.impl.resource import Resource | 36 | from plainbox.impl.resource import Resource |
3277 | 32 | from plainbox.impl.result import JobResult | 37 | from plainbox.impl.result import JobResult |
3278 | 33 | from plainbox.impl.session import JobReadinessInhibitor | 38 | from plainbox.impl.session import JobReadinessInhibitor |
3279 | 34 | from plainbox.impl.session import JobState | 39 | from plainbox.impl.session import JobState |
3280 | 35 | from plainbox.impl.session import SessionState | 40 | from plainbox.impl.session import SessionState |
3281 | 41 | from plainbox.impl.session import SessionStateEncoder | ||
3282 | 36 | from plainbox.impl.session import UndesiredJobReadinessInhibitor | 42 | from plainbox.impl.session import UndesiredJobReadinessInhibitor |
3286 | 37 | from plainbox.impl.session import SessionStateEncoder | 43 | from plainbox.impl.testing_utils import make_io_log, make_job, make_job_result |
3284 | 38 | from plainbox.impl.testing_utils import make_job | ||
3285 | 39 | from plainbox.impl.testing_utils import make_job_result | ||
3287 | 40 | 44 | ||
3288 | 41 | 45 | ||
3289 | 42 | class JobReadinessInhibitorTests(TestCase): | 46 | class JobReadinessInhibitorTests(TestCase): |
3290 | @@ -236,7 +240,8 @@ | |||
3291 | 236 | } | 240 | } |
3292 | 237 | } | 241 | } |
3293 | 238 | }""" | 242 | }""" |
3295 | 239 | job_dec = json.loads(raw_json, object_hook=SessionStateEncoder().dict_to_object) | 243 | job_dec = json.loads(raw_json, |
3296 | 244 | object_hook=SessionStateEncoder().dict_to_object) | ||
3297 | 240 | self.assertIsInstance(job_dec, JobState) | 245 | self.assertIsInstance(job_dec, JobState) |
3298 | 241 | self.assertEqual(repr(job_dec._result), | 246 | self.assertEqual(repr(job_dec._result), |
3299 | 242 | ("<JobResult job:<JobDefinition name:'X'" | 247 | ("<JobResult job:<JobDefinition name:'X'" |
3300 | @@ -271,6 +276,23 @@ | |||
3301 | 271 | self.assertIsNone(self.session_state.session_dir) | 276 | self.assertIsNone(self.session_state.session_dir) |
3302 | 272 | 277 | ||
3303 | 273 | 278 | ||
3304 | 279 | class RegressionTests(TestCase): | ||
3305 | 280 | # Tests for bugfixes | ||
3306 | 281 | |||
3307 | 282 | def test_crash_in_update_desired_job_list(self): | ||
3308 | 283 | # This checks if a DependencyError can cause crash | ||
3309 | 284 | # update_desired_job_list() with a ValueError, in certain conditions. | ||
3310 | 285 | A = make_job('A', depends='X') | ||
3311 | 286 | L = make_job('L', plugin='local') | ||
3312 | 287 | session = SessionState([A, L]) | ||
3313 | 288 | problems = session.update_desired_job_list([A, L]) | ||
3314 | 289 | # We should get exactly one DependencyMissingError related to job A and | ||
3315 | 290 | # the undefined job X (that is presumably defined by the local job L) | ||
3316 | 291 | self.assertEqual(len(problems), 1) | ||
3317 | 292 | self.assertIsInstance(problems[0], DependencyMissingError) | ||
3318 | 293 | self.assertIs(problems[0].affected_job, A) | ||
3319 | 294 | |||
3320 | 295 | |||
3321 | 274 | class SessionStateSpecialTests(TestCase): | 296 | class SessionStateSpecialTests(TestCase): |
3322 | 275 | 297 | ||
3323 | 276 | # NOTE: those tests are essential. They allow testing the behavior of | 298 | # NOTE: those tests are essential. They allow testing the behavior of |
3324 | @@ -326,6 +348,7 @@ | |||
3325 | 326 | self.job_Y = make_job("Y") | 348 | self.job_Y = make_job("Y") |
3326 | 327 | self.job_list = [self.job_A, self.job_R, self.job_X, self.job_Y] | 349 | self.job_list = [self.job_A, self.job_R, self.job_X, self.job_Y] |
3327 | 328 | self.session = SessionState(self.job_list) | 350 | self.session = SessionState(self.job_list) |
3328 | 351 | self.scratch_dir = TemporaryDirectory() | ||
3329 | 329 | 352 | ||
3330 | 330 | def job_state(self, name): | 353 | def job_state(self, name): |
3331 | 331 | # A helper function to avoid overly long expressions | 354 | # A helper function to avoid overly long expressions |
3332 | @@ -391,7 +414,8 @@ | |||
3333 | 391 | # session. | 414 | # session. |
3334 | 392 | result_R = JobResult({ | 415 | result_R = JobResult({ |
3335 | 393 | 'job': self.job_R, | 416 | 'job': self.job_R, |
3337 | 394 | 'io_log': ((0, 'stdout', b"attr: value\n"),) | 417 | 'io_log': make_io_log(((0, 'stdout', b"attr: value\n"),), |
3338 | 418 | self.scratch_dir) | ||
3339 | 395 | }) | 419 | }) |
3340 | 396 | self.session.update_job_result(self.job_R, result_R) | 420 | self.session.update_job_result(self.job_R, result_R) |
3341 | 397 | # The most obvious thing that can happen, is that the result is simply | 421 | # The most obvious thing that can happen, is that the result is simply |
3342 | @@ -439,12 +463,13 @@ | |||
3343 | 439 | # another proper record in that order. | 463 | # another proper record in that order. |
3344 | 440 | result_R = JobResult({ | 464 | result_R = JobResult({ |
3345 | 441 | 'job': self.job_R, | 465 | 'job': self.job_R, |
3352 | 442 | 'io_log': ( | 466 | 'io_log': make_io_log(( |
3353 | 443 | (0, 'stdout', b"attr: value-1\n"), | 467 | (0, 'stdout', b"attr: value-1\n"), |
3354 | 444 | (1, 'stdout', b"\n"), | 468 | (1, 'stdout', b"\n"), |
3355 | 445 | (1, 'stdout', b"I-sound-like-a-broken-record\n"), | 469 | (1, 'stdout', b"I-sound-like-a-broken-record\n"), |
3356 | 446 | (1, 'stdout', b"\n"), | 470 | (1, 'stdout', b"\n"), |
3357 | 447 | (1, 'stdout', b"attr: value-2\n")) | 471 | (1, 'stdout', b"attr: value-2\n")), |
3358 | 472 | self.scratch_dir) | ||
3359 | 448 | }) | 473 | }) |
3360 | 449 | # Since we cannot control the output of scripts and people indeed make | 474 | # Since we cannot control the output of scripts and people indeed make |
3361 | 450 | # mistakes a warning is issued but no exception is raised to the | 475 | # mistakes a warning is issued but no exception is raised to the |
3362 | @@ -521,7 +546,8 @@ | |||
3363 | 521 | self.session.update_desired_job_list([self.job_A]) | 546 | self.session.update_desired_job_list([self.job_A]) |
3364 | 522 | result_R = JobResult({ | 547 | result_R = JobResult({ |
3365 | 523 | 'job': self.job_R, | 548 | 'job': self.job_R, |
3367 | 524 | 'io_log': ((0, 'stdout', b'attr: wrong value\n'),) | 549 | 'io_log': make_io_log(((0, 'stdout', b'attr: wrong value\n'),), |
3368 | 550 | self.scratch_dir) | ||
3369 | 525 | }) | 551 | }) |
3370 | 526 | self.session.update_job_result(self.job_R, result_R) | 552 | self.session.update_job_result(self.job_R, result_R) |
3371 | 527 | # Now A is inhibited by FAILED_RESOURCE | 553 | # Now A is inhibited by FAILED_RESOURCE |
3372 | @@ -538,7 +564,8 @@ | |||
3373 | 538 | # presented to a session that has some resources from that job already. | 564 | # presented to a session that has some resources from that job already. |
3374 | 539 | result_R_old = JobResult({ | 565 | result_R_old = JobResult({ |
3375 | 540 | 'job': self.job_R, | 566 | 'job': self.job_R, |
3377 | 541 | 'io_log': ((0, 'stdout', b"attr: old value\n"),) | 567 | 'io_log': make_io_log(((0, 'stdout', b"attr: old value\n"),), |
3378 | 568 | self.scratch_dir) | ||
3379 | 542 | }) | 569 | }) |
3380 | 543 | self.session.update_job_result(self.job_R, result_R_old) | 570 | self.session.update_job_result(self.job_R, result_R_old) |
3381 | 544 | # So here the old result is stored into a new 'R' resource | 571 | # So here the old result is stored into a new 'R' resource |
3382 | @@ -547,7 +574,8 @@ | |||
3383 | 547 | # Now we present the second result for the same job | 574 | # Now we present the second result for the same job |
3384 | 548 | result_R_new = JobResult({ | 575 | result_R_new = JobResult({ |
3385 | 549 | 'job': self.job_R, | 576 | 'job': self.job_R, |
3387 | 550 | 'io_log': ((0, 'stdout', b"attr: new value\n"),) | 577 | 'io_log': make_io_log(((0, 'stdout', b"attr: new value\n"),), |
3388 | 578 | self.scratch_dir) | ||
3389 | 551 | }) | 579 | }) |
3390 | 552 | self.session.update_job_result(self.job_R, result_R_new) | 580 | self.session.update_job_result(self.job_R, result_R_new) |
3391 | 553 | # What should happen here is that the R resource is entirely replaced | 581 | # What should happen here is that the R resource is entirely replaced |
3392 | @@ -557,3 +585,149 @@ | |||
3393 | 557 | self.assertEqual(self.session._resource_map, expected_after) | 585 | self.assertEqual(self.session._resource_map, expected_after) |
3394 | 558 | 586 | ||
3395 | 559 | # TODO: add tests for local jobs | 587 | # TODO: add tests for local jobs |
3396 | 588 | |||
3397 | 589 | def tearDown(self): | ||
3398 | 590 | self.scratch_dir.cleanup() | ||
3399 | 591 | |||
3400 | 592 | |||
3401 | 593 | class SessionStateLocalStorageTests(TestCase): | ||
3402 | 594 | |||
3403 | 595 | def setUp(self): | ||
3404 | 596 | # session data are kept in XDG_CACHE_HOME/plainbox/.session | ||
3405 | 597 | # To avoid resuming a real session, we have to select a temporary | ||
3406 | 598 | # location instead | ||
3407 | 599 | self._sandbox = tempfile.mkdtemp() | ||
3408 | 600 | self._env = os.environ | ||
3409 | 601 | os.environ['XDG_CACHE_HOME'] = self._sandbox | ||
3410 | 602 | |||
3411 | 603 | def job_state(self, name): | ||
3412 | 604 | # A helper function to avoid overly long expressions | ||
3413 | 605 | return self.session.job_state_map[name] | ||
3414 | 606 | |||
3415 | 607 | def test_persistent_save(self): | ||
3416 | 608 | self.job_A = make_job("A") | ||
3417 | 609 | self.job_list = [self.job_A] | ||
3418 | 610 | self.session = SessionState(self.job_list) | ||
3419 | 611 | result_A = JobResult({ | ||
3420 | 612 | 'job': self.job_A, | ||
3421 | 613 | 'outcome': JobResult.OUTCOME_PASS, | ||
3422 | 614 | 'comments': 'All good', | ||
3423 | 615 | 'return_code': 0, | ||
3424 | 616 | 'io_log': ((0, 'stdout', "Success !\n"),) | ||
3425 | 617 | }) | ||
3426 | 618 | session_json_text = """{ | ||
3427 | 619 | "_job_state_map": { | ||
3428 | 620 | "A": { | ||
3429 | 621 | "_job": { | ||
3430 | 622 | "data": { | ||
3431 | 623 | "name": "A", | ||
3432 | 624 | "plugin": "dummy", | ||
3433 | 625 | "requires": null, | ||
3434 | 626 | "depends": null | ||
3435 | 627 | }, | ||
3436 | 628 | "_class_id": "JOB_DEFINITION" | ||
3437 | 629 | }, | ||
3438 | 630 | "_result": { | ||
3439 | 631 | "data": { | ||
3440 | 632 | "job": { | ||
3441 | 633 | "data": { | ||
3442 | 634 | "name": "A", | ||
3443 | 635 | "plugin": "dummy", | ||
3444 | 636 | "requires": null, | ||
3445 | 637 | "depends": null | ||
3446 | 638 | }, | ||
3447 | 639 | "_class_id": "JOB_DEFINITION" | ||
3448 | 640 | }, | ||
3449 | 641 | "outcome": "pass", | ||
3450 | 642 | "return_code": 0, | ||
3451 | 643 | "comments": "All good", | ||
3452 | 644 | "io_log": [ | ||
3453 | 645 | [ | ||
3454 | 646 | 0, | ||
3455 | 647 | "stdout", | ||
3456 | 648 | "Success !\\n" | ||
3457 | 649 | ] | ||
3458 | 650 | ] | ||
3459 | 651 | }, | ||
3460 | 652 | "_class_id": "JOB_RESULT" | ||
3461 | 653 | }, | ||
3462 | 654 | "_class_id": "JOB_STATE" | ||
3463 | 655 | } | ||
3464 | 656 | }, | ||
3465 | 657 | "_desired_job_list": [ | ||
3466 | 658 | { | ||
3467 | 659 | "data": { | ||
3468 | 660 | "name": "A", | ||
3469 | 661 | "plugin": "dummy", | ||
3470 | 662 | "requires": null, | ||
3471 | 663 | "depends": null | ||
3472 | 664 | }, | ||
3473 | 665 | "_class_id": "JOB_DEFINITION" | ||
3474 | 666 | } | ||
3475 | 667 | ], | ||
3476 | 668 | "_class_id": "SESSION_STATE" | ||
3477 | 669 | }""" | ||
3478 | 670 | self.session.open() | ||
3479 | 671 | self.session.update_desired_job_list([self.job_A]) | ||
3480 | 672 | self.session.update_job_result(self.job_A, result_A) | ||
3481 | 673 | self.session.persistent_save() | ||
3482 | 674 | session_file = self.session.previous_session_file() | ||
3483 | 675 | self.session.close() | ||
3484 | 676 | self.assertIsNotNone(session_file) | ||
3485 | 677 | with open(session_file) as f: | ||
3486 | 678 | raw_json = json.load(f) | ||
3487 | 679 | self.maxDiff = None | ||
3488 | 680 | self.assertEqual(raw_json, json.loads(session_json_text)) | ||
3489 | 681 | |||
3490 | 682 | def test_resume_session(self): | ||
3491 | 683 | # All of the tests below are using one session. The session has four | ||
3492 | 684 | # jobs, Job A depends on a resource provided by job R which has no | ||
3493 | 685 | # dependencies at all. Both Job X and Y depend on job A. | ||
3494 | 686 | # | ||
3495 | 687 | # A -(resource dependency)-> R | ||
3496 | 688 | # | ||
3497 | 689 | # X -(direct dependency) -> A | ||
3498 | 690 | # | ||
3499 | 691 | # Y -(direct dependency) -> A | ||
3500 | 692 | self.job_A = make_job("A", requires="R.attr == 'value'") | ||
3501 | 693 | self.job_A_expr = self.job_A.get_resource_program().expression_list[0] | ||
3502 | 694 | self.job_R = make_job("R", plugin="resource") | ||
3503 | 695 | self.job_X = make_job("X", depends='A') | ||
3504 | 696 | self.job_Y = make_job("Y", depends='A') | ||
3505 | 697 | self.job_list = [self.job_A, self.job_R, self.job_X, self.job_Y] | ||
3506 | 698 | # Create a new session (session_dir is empty) | ||
3507 | 699 | self.session = SessionState(self.job_list) | ||
3508 | 700 | result_R = JobResult({ | ||
3509 | 701 | 'job': self.job_R, | ||
3510 | 702 | 'io_log': make_io_log(((0, 'stdout', b"attr: value\n"),), | ||
3511 | 703 | self._sandbox) | ||
3512 | 704 | }) | ||
3513 | 705 | result_A = JobResult({ | ||
3514 | 706 | 'job': self.job_A, | ||
3515 | 707 | 'outcome': JobResult.OUTCOME_PASS | ||
3516 | 708 | }) | ||
3517 | 709 | result_X = JobResult({ | ||
3518 | 710 | 'job': self.job_X, | ||
3519 | 711 | 'outcome': JobResult.OUTCOME_PASS | ||
3520 | 712 | }) | ||
3521 | 713 | # Job Y can't start as it requires job A | ||
3522 | 714 | self.assertFalse(self.job_state('Y').can_start()) | ||
3523 | 715 | self.session.update_desired_job_list([self.job_X, self.job_Y]) | ||
3524 | 716 | self.session.open() | ||
3525 | 717 | self.session.update_job_result(self.job_R, result_R) | ||
3526 | 718 | self.session.update_job_result(self.job_A, result_A) | ||
3527 | 719 | self.session.update_job_result(self.job_X, result_X) | ||
3528 | 720 | self.session.persistent_save() | ||
3529 | 721 | self.session.close() | ||
3530 | 722 | # Create a new session (session_dir should contain session data) | ||
3531 | 723 | self.session = SessionState(self.job_list) | ||
3532 | 724 | self.session.open() | ||
3533 | 725 | # Resume the previous session | ||
3534 | 726 | self.session.resume() | ||
3535 | 727 | # This time job Y can start | ||
3536 | 728 | self.assertTrue(self.job_state('Y').can_start()) | ||
3537 | 729 | self.session.close() | ||
3538 | 730 | |||
3539 | 731 | def tearDown(self): | ||
3540 | 732 | shutil.rmtree(self._sandbox) | ||
3541 | 733 | os.environ = self._env | ||
3542 | 560 | 734 | ||
3543 | === modified file 'plainbox/plainbox/impl/testing_utils.py' | |||
3544 | --- plainbox/plainbox/impl/testing_utils.py 2013-01-30 21:43:05 +0000 | |||
3545 | +++ plainbox/plainbox/impl/testing_utils.py 2013-03-07 16:10:38 +0000 | |||
3546 | @@ -18,19 +18,31 @@ | |||
3547 | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. |
3548 | 19 | 19 | ||
3549 | 20 | """ | 20 | """ |
3556 | 21 | plainbox.impl.testing_utils | 21 | :mod:`plainbox.impl.testing_utils` -- plainbox specific test tools |
3557 | 22 | =========================== | 22 | ================================================================== |
3558 | 23 | 23 | ||
3559 | 24 | Internal implementation of plainbox | 24 | .. warning:: |
3560 | 25 | 25 | ||
3561 | 26 | * THIS MODULE DOES NOT HAVE STABLE PUBLIC API * | 26 | THIS MODULE DOES NOT HAVE STABLE PUBLIC API |
3562 | 27 | """ | 27 | """ |
3563 | 28 | 28 | ||
3564 | 29 | import inspect | 29 | import inspect |
3565 | 30 | from tempfile import NamedTemporaryFile | ||
3566 | 30 | 31 | ||
3567 | 31 | from plainbox.impl.job import JobDefinition | 32 | from plainbox.impl.job import JobDefinition |
3568 | 32 | from plainbox.impl.result import JobResult | 33 | from plainbox.impl.result import JobResult |
3569 | 33 | from plainbox.impl.rfc822 import Origin | 34 | from plainbox.impl.rfc822 import Origin |
3570 | 35 | from plainbox.impl.runner import io_log_write | ||
3571 | 36 | |||
3572 | 37 | |||
3573 | 38 | def make_io_log(io_log, io_log_dir): | ||
3574 | 39 | """ | ||
3575 | 40 | Make the io logs serialization to json and return the saved file pathname | ||
3576 | 41 | WARNING: The caller has to remove the file once done with it! | ||
3577 | 42 | """ | ||
3578 | 43 | with NamedTemporaryFile(mode='w+t', delete=False) as stream: | ||
3579 | 44 | io_log_write(io_log, stream) | ||
3580 | 45 | return stream.name | ||
3581 | 34 | 46 | ||
3582 | 35 | 47 | ||
3583 | 36 | def make_job(name, plugin="dummy", requires=None, depends=None): | 48 | def make_job(name, plugin="dummy", requires=None, depends=None): |
3584 | 37 | 49 | ||
3585 | === removed file 'plainbox/plainbox/impl/utils.py.moved' | |||
3586 | --- plainbox/plainbox/impl/utils.py.moved 2013-02-22 16:26:25 +0000 | |||
3587 | +++ plainbox/plainbox/impl/utils.py.moved 1970-01-01 00:00:00 +0000 | |||
3588 | @@ -1,58 +0,0 @@ | |||
3589 | 1 | # This file is part of Checkbox. | ||
3590 | 2 | # | ||
3591 | 3 | # Copyright 2012 Canonical Ltd. | ||
3592 | 4 | # Written by: | ||
3593 | 5 | # Zygmunt Krynicki <zygmunt.krynicki@canonical.com> | ||
3594 | 6 | # | ||
3595 | 7 | # Checkbox is free software: you can redistribute it and/or modify | ||
3596 | 8 | # it under the terms of the GNU General Public License as published by | ||
3597 | 9 | # the Free Software Foundation, either version 3 of the License, or | ||
3598 | 10 | # (at your option) any later version. | ||
3599 | 11 | # | ||
3600 | 12 | # Checkbox is distributed in the hope that it will be useful, | ||
3601 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
3602 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
3603 | 15 | # GNU General Public License for more details. | ||
3604 | 16 | # | ||
3605 | 17 | # You should have received a copy of the GNU General Public License | ||
3606 | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. | ||
3607 | 19 | |||
3608 | 20 | """ | ||
3609 | 21 | plainbox.impl.utils | ||
3610 | 22 | =================== | ||
3611 | 23 | |||
3612 | 24 | Internal implementation of plainbox | ||
3613 | 25 | |||
3614 | 26 | * THIS MODULE DOES NOT HAVE STABLE PUBLIC API * | ||
3615 | 27 | """ | ||
3616 | 28 | |||
3617 | 29 | from io import TextIOWrapper | ||
3618 | 30 | from logging import getLogger | ||
3619 | 31 | |||
3620 | 32 | from plainbox.impl.job import JobDefinition | ||
3621 | 33 | from plainbox.impl.rfc822 import load_rfc822_records | ||
3622 | 34 | |||
3623 | 35 | |||
3624 | 36 | logger = getLogger("plainbox.utils") | ||
3625 | 37 | |||
3626 | 38 | |||
3627 | 39 | def load(somewhere): | ||
3628 | 40 | if isinstance(somewhere, str): | ||
3629 | 41 | # Load data from a file with the given name | ||
3630 | 42 | filename = somewhere | ||
3631 | 43 | with open(filename, 'rt', encoding='UTF-8') as stream: | ||
3632 | 44 | return load(stream) | ||
3633 | 45 | if isinstance(somewhere, TextIOWrapper): | ||
3634 | 46 | stream = somewhere | ||
3635 | 47 | logger.debug("Loading jobs definitions from %r...", stream.name) | ||
3636 | 48 | record_list = load_rfc822_records(stream) | ||
3637 | 49 | job_list = [] | ||
3638 | 50 | for record in record_list: | ||
3639 | 51 | job = JobDefinition.from_rfc822_record(record) | ||
3640 | 52 | logger.debug("Loaded %r", job) | ||
3641 | 53 | job_list.append(job) | ||
3642 | 54 | return job_list | ||
3643 | 55 | else: | ||
3644 | 56 | raise TypeError( | ||
3645 | 57 | "Unsupported type of 'somewhere': {!r}".format( | ||
3646 | 58 | type(somewhere))) | ||
3647 | 59 | 0 | ||
3648 | === modified file 'plainbox/plainbox/public.py' | |||
3649 | --- plainbox/plainbox/public.py 2013-02-22 16:26:25 +0000 | |||
3650 | +++ plainbox/plainbox/public.py 2013-03-07 16:10:38 +0000 | |||
3651 | @@ -18,8 +18,8 @@ | |||
3652 | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. |
3653 | 19 | 19 | ||
3654 | 20 | """ | 20 | """ |
3657 | 21 | plainbox.public | 21 | :mod:`plainbox.public` -- public, stable API |
3658 | 22 | =============== | 22 | ============================================ |
3659 | 23 | 23 | ||
3660 | 24 | Public, high-level API for third party developers. | 24 | Public, high-level API for third party developers. |
3661 | 25 | 25 | ||
3662 | 26 | 26 | ||
3663 | === modified file 'plainbox/plainbox/testing_utils/__init__.py' | |||
3664 | --- plainbox/plainbox/testing_utils/__init__.py 2013-01-30 21:43:05 +0000 | |||
3665 | +++ plainbox/plainbox/testing_utils/__init__.py 2013-03-07 16:10:38 +0000 | |||
3666 | @@ -18,8 +18,6 @@ | |||
3667 | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. |
3668 | 19 | 19 | ||
3669 | 20 | """ | 20 | """ |
3674 | 21 | plainbox.testing_utils | 21 | :mod:`plainbox.testing_utils` - generic testing utilities |
3675 | 22 | ====================== | 22 | ========================================================= |
3672 | 23 | |||
3673 | 24 | Testing utilities for internals of plainbox | ||
3676 | 25 | """ | 23 | """ |
3677 | 26 | 24 | ||
3678 | === modified file 'plainbox/plainbox/testing_utils/cwd.py' | |||
3679 | --- plainbox/plainbox/testing_utils/cwd.py 2013-01-30 21:43:05 +0000 | |||
3680 | +++ plainbox/plainbox/testing_utils/cwd.py 2013-03-07 16:10:38 +0000 | |||
3681 | @@ -18,8 +18,8 @@ | |||
3682 | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. |
3683 | 19 | 19 | ||
3684 | 20 | """ | 20 | """ |
3687 | 21 | plainbox.testing_utils.cwd | 21 | :mod:`plainbox.testing_utils.cwd` -- tools for testing in another directory |
3688 | 22 | ========================== | 22 | =========================================================================== |
3689 | 23 | 23 | ||
3690 | 24 | Implementation of context managers for working in another directory | 24 | Implementation of context managers for working in another directory |
3691 | 25 | """ | 25 | """ |
3692 | 26 | 26 | ||
3693 | === modified file 'plainbox/plainbox/testing_utils/io.py' | |||
3694 | --- plainbox/plainbox/testing_utils/io.py 2013-01-30 21:43:05 +0000 | |||
3695 | +++ plainbox/plainbox/testing_utils/io.py 2013-03-07 16:10:38 +0000 | |||
3696 | @@ -18,8 +18,8 @@ | |||
3697 | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. |
3698 | 19 | 19 | ||
3699 | 20 | """ | 20 | """ |
3702 | 21 | plainbox.testing_utils.io | 21 | :mod:`plainbox.testing_utils.io` -- tools for testing IO |
3703 | 22 | ========================= | 22 | ======================================================== |
3704 | 23 | 23 | ||
3705 | 24 | Implementation of context managers for observing IO | 24 | Implementation of context managers for observing IO |
3706 | 25 | """ | 25 | """ |
3707 | 26 | 26 | ||
3708 | === modified file 'plainbox/plainbox/testing_utils/testcases.py' | |||
3709 | --- plainbox/plainbox/testing_utils/testcases.py 2013-01-30 21:43:05 +0000 | |||
3710 | +++ plainbox/plainbox/testing_utils/testcases.py 2013-03-07 16:10:38 +0000 | |||
3711 | @@ -18,8 +18,8 @@ | |||
3712 | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. |
3713 | 19 | 19 | ||
3714 | 20 | """ | 20 | """ |
3717 | 21 | plainbox.testing_utils.testcases | 21 | :mod:`plainbox.testing_utils.testcases` -- additional TestCase classes |
3718 | 22 | ================================ | 22 | ====================================================================== |
3719 | 23 | 23 | ||
3720 | 24 | Implementation of additional TestCase classes that aid in testing. | 24 | Implementation of additional TestCase classes that aid in testing. |
3721 | 25 | """ | 25 | """ |
3722 | @@ -114,7 +114,7 @@ | |||
3723 | 114 | parameter values, otherwise this test will behave as if it never existed | 114 | parameter values, otherwise this test will behave as if it never existed |
3724 | 115 | (analogous how multiplication by zero works). | 115 | (analogous how multiplication by zero works). |
3725 | 116 | 116 | ||
3727 | 117 | ..note:: | 117 | .. note:: |
3728 | 118 | Technical note for tinkerers and subclass authors. Python unittest | 118 | Technical note for tinkerers and subclass authors. Python unittest |
3729 | 119 | framework is pretty annoying to work with or extend. In practice you | 119 | framework is pretty annoying to work with or extend. In practice you |
3730 | 120 | should always keep the source code (of a particular python version) | 120 | should always keep the source code (of a particular python version) |
3731 | 121 | 121 | ||
3732 | === modified file 'plainbox/plainbox/tests.py' | |||
3733 | --- plainbox/plainbox/tests.py 2013-02-08 17:02:12 +0000 | |||
3734 | +++ plainbox/plainbox/tests.py 2013-03-07 16:10:38 +0000 | |||
3735 | @@ -18,10 +18,8 @@ | |||
3736 | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. |
3737 | 19 | 19 | ||
3738 | 20 | """ | 20 | """ |
3743 | 21 | plainbox.tests | 21 | :mod:`plainbox.tests` -- auxiliary test loaders for plainbox |
3744 | 22 | ============== | 22 | ============================================================ |
3741 | 23 | |||
3742 | 24 | Auxiliary test loader for plainbox | ||
3745 | 25 | """ | 23 | """ |
3746 | 26 | 24 | ||
3747 | 27 | from unittest.loader import defaultTestLoader | 25 | from unittest.loader import defaultTestLoader |
3748 | 28 | 26 | ||
3749 | === modified file 'plainbox/plainbox/vendor/__init__.py' | |||
3750 | --- plainbox/plainbox/vendor/__init__.py 2012-11-29 18:59:46 +0000 | |||
3751 | +++ plainbox/plainbox/vendor/__init__.py 2013-03-07 16:10:38 +0000 | |||
3752 | @@ -0,0 +1,28 @@ | |||
3753 | 1 | # This file is part of Checkbox. | ||
3754 | 2 | # | ||
3755 | 3 | # Copyright 2013 Canonical Ltd. | ||
3756 | 4 | # Written by: | ||
3757 | 5 | # Zygmunt Krynicki <zygmunt.krynicki@canonical.com> | ||
3758 | 6 | # | ||
3759 | 7 | # Checkbox is free software: you can redistribute it and/or modify | ||
3760 | 8 | # it under the terms of the GNU General Public License as published by | ||
3761 | 9 | # the Free Software Foundation, either version 3 of the License, or | ||
3762 | 10 | # (at your option) any later version. | ||
3763 | 11 | # | ||
3764 | 12 | # Checkbox is distributed in the hope that it will be useful, | ||
3765 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
3766 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
3767 | 15 | # GNU General Public License for more details. | ||
3768 | 16 | # | ||
3769 | 17 | # You should have received a copy of the GNU General Public License | ||
3770 | 18 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. | ||
3771 | 19 | |||
3772 | 20 | """ | ||
3773 | 21 | :mod:`plainbox.vendor` -- vendorized packages | ||
3774 | 22 | ============================================= | ||
3775 | 23 | |||
3776 | 24 | This module contains external packages that were vendorized (shipped with a | ||
3777 | 25 | tree of another project) to simplify dependency management. There is no problem | ||
3778 | 26 | with expressing those dependencies at pypi level but it would be annoying to | ||
3779 | 27 | have to first package and introduce them to Ubuntu. | ||
3780 | 28 | """ | ||
3781 | 0 | 29 | ||
3782 | === modified file 'plainbox/plainbox/vendor/extcmd/__init__.py' | |||
3783 | --- plainbox/plainbox/vendor/extcmd/__init__.py 2013-02-22 16:26:25 +0000 | |||
3784 | +++ plainbox/plainbox/vendor/extcmd/__init__.py 2013-03-07 16:10:38 +0000 | |||
3785 | @@ -18,8 +18,8 @@ | |||
3786 | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
3787 | 19 | 19 | ||
3788 | 20 | """ | 20 | """ |
3791 | 21 | extcmd - subprocess with advanced output processing | 21 | :mod:`plainbox.vendor.extcmd` - subprocess with advanced output processing |
3792 | 22 | =================================================== | 22 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
3793 | 23 | 23 | ||
3794 | 24 | Unlike subprocess, which just gives you a lump of output at the end, extcmd | 24 | Unlike subprocess, which just gives you a lump of output at the end, extcmd |
3795 | 25 | allows you to get callbacks (via a delegate class) on all IO. | 25 | allows you to get callbacks (via a delegate class) on all IO. |
3796 | 26 | 26 | ||
3797 | === modified file 'plainbox/setup.py' | |||
3798 | --- plainbox/setup.py 2013-02-22 16:26:25 +0000 | |||
3799 | +++ plainbox/setup.py 2013-03-07 16:10:38 +0000 | |||
3800 | @@ -31,6 +31,9 @@ | |||
3801 | 31 | author_email="zygmunt.krynicki@canonical.com", | 31 | author_email="zygmunt.krynicki@canonical.com", |
3802 | 32 | license="GPLv3+", | 32 | license="GPLv3+", |
3803 | 33 | description="Simple replacement for checkbox", | 33 | description="Simple replacement for checkbox", |
3804 | 34 | tests_require=[ | ||
3805 | 35 | 'mock', | ||
3806 | 36 | ], | ||
3807 | 34 | entry_points={ | 37 | entry_points={ |
3808 | 35 | 'console_scripts': [ | 38 | 'console_scripts': [ |
3809 | 36 | 'plainbox=plainbox.public:main', | 39 | 'plainbox=plainbox.public:main', |
3810 | 37 | 40 | ||
3811 | === modified file 'po/ace.po' | |||
3812 | --- po/ace.po 2013-02-22 16:26:25 +0000 | |||
3813 | +++ po/ace.po 2013-03-07 16:10:38 +0000 | |||
3814 | @@ -14,8 +14,8 @@ | |||
3815 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
3816 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
3817 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
3820 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:31+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:38+0000\n" |
3821 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
3822 | 19 | 19 | ||
3823 | 20 | #. Title of the user interface | 20 | #. Title of the user interface |
3824 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 |
3825 | @@ -964,7 +964,7 @@ | |||
3826 | 964 | msgstr "" | 964 | msgstr "" |
3827 | 965 | 965 | ||
3828 | 966 | #. description | 966 | #. description |
3830 | 967 | #: ../jobs/input.txt.in:23 | 967 | #: ../jobs/input.txt.in:22 |
3831 | 968 | msgid "" | 968 | msgid "" |
3832 | 969 | "PURPOSE:\n" | 969 | "PURPOSE:\n" |
3833 | 970 | " This test will test your pointing device\n" | 970 | " This test will test your pointing device\n" |
3834 | @@ -976,7 +976,7 @@ | |||
3835 | 976 | msgstr "" | 976 | msgstr "" |
3836 | 977 | 977 | ||
3837 | 978 | #. description | 978 | #. description |
3839 | 979 | #: ../jobs/input.txt.in:36 | 979 | #: ../jobs/input.txt.in:35 |
3840 | 980 | msgid "" | 980 | msgid "" |
3841 | 981 | "PURPOSE:\n" | 981 | "PURPOSE:\n" |
3842 | 982 | " This test will test your keyboard\n" | 982 | " This test will test your keyboard\n" |
3843 | 983 | 983 | ||
3844 | === modified file 'po/af.po' | |||
3845 | --- po/af.po 2013-02-22 16:26:25 +0000 | |||
3846 | +++ po/af.po 2013-03-07 16:10:38 +0000 | |||
3847 | @@ -14,8 +14,8 @@ | |||
3848 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
3849 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
3850 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
3853 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:31+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:38+0000\n" |
3854 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
3855 | 19 | 19 | ||
3856 | 20 | #. Title of the user interface | 20 | #. Title of the user interface |
3857 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 |
3858 | @@ -964,7 +964,7 @@ | |||
3859 | 964 | msgstr "" | 964 | msgstr "" |
3860 | 965 | 965 | ||
3861 | 966 | #. description | 966 | #. description |
3863 | 967 | #: ../jobs/input.txt.in:23 | 967 | #: ../jobs/input.txt.in:22 |
3864 | 968 | msgid "" | 968 | msgid "" |
3865 | 969 | "PURPOSE:\n" | 969 | "PURPOSE:\n" |
3866 | 970 | " This test will test your pointing device\n" | 970 | " This test will test your pointing device\n" |
3867 | @@ -976,7 +976,7 @@ | |||
3868 | 976 | msgstr "" | 976 | msgstr "" |
3869 | 977 | 977 | ||
3870 | 978 | #. description | 978 | #. description |
3872 | 979 | #: ../jobs/input.txt.in:36 | 979 | #: ../jobs/input.txt.in:35 |
3873 | 980 | msgid "" | 980 | msgid "" |
3874 | 981 | "PURPOSE:\n" | 981 | "PURPOSE:\n" |
3875 | 982 | " This test will test your keyboard\n" | 982 | " This test will test your keyboard\n" |
3876 | 983 | 983 | ||
3877 | === modified file 'po/am.po' | |||
3878 | --- po/am.po 2013-02-22 16:26:25 +0000 | |||
3879 | +++ po/am.po 2013-03-07 16:10:38 +0000 | |||
3880 | @@ -14,8 +14,8 @@ | |||
3881 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
3882 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
3883 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
3886 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:31+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:38+0000\n" |
3887 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
3888 | 19 | 19 | ||
3889 | 20 | #. Title of the user interface | 20 | #. Title of the user interface |
3890 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 |
3891 | @@ -964,7 +964,7 @@ | |||
3892 | 964 | msgstr "" | 964 | msgstr "" |
3893 | 965 | 965 | ||
3894 | 966 | #. description | 966 | #. description |
3896 | 967 | #: ../jobs/input.txt.in:23 | 967 | #: ../jobs/input.txt.in:22 |
3897 | 968 | msgid "" | 968 | msgid "" |
3898 | 969 | "PURPOSE:\n" | 969 | "PURPOSE:\n" |
3899 | 970 | " This test will test your pointing device\n" | 970 | " This test will test your pointing device\n" |
3900 | @@ -976,7 +976,7 @@ | |||
3901 | 976 | msgstr "" | 976 | msgstr "" |
3902 | 977 | 977 | ||
3903 | 978 | #. description | 978 | #. description |
3905 | 979 | #: ../jobs/input.txt.in:36 | 979 | #: ../jobs/input.txt.in:35 |
3906 | 980 | msgid "" | 980 | msgid "" |
3907 | 981 | "PURPOSE:\n" | 981 | "PURPOSE:\n" |
3908 | 982 | " This test will test your keyboard\n" | 982 | " This test will test your keyboard\n" |
3909 | 983 | 983 | ||
3910 | === modified file 'po/ar.po' | |||
3911 | --- po/ar.po 2013-02-22 16:26:25 +0000 | |||
3912 | +++ po/ar.po 2013-03-07 16:10:38 +0000 | |||
3913 | @@ -14,8 +14,8 @@ | |||
3914 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
3915 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
3916 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
3919 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:31+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:38+0000\n" |
3920 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
3921 | 19 | 19 | ||
3922 | 20 | #. Title of the user interface | 20 | #. Title of the user interface |
3923 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 |
3924 | @@ -1139,7 +1139,7 @@ | |||
3925 | 1139 | msgstr "" | 1139 | msgstr "" |
3926 | 1140 | 1140 | ||
3927 | 1141 | #. description | 1141 | #. description |
3929 | 1142 | #: ../jobs/input.txt.in:23 | 1142 | #: ../jobs/input.txt.in:22 |
3930 | 1143 | msgid "" | 1143 | msgid "" |
3931 | 1144 | "PURPOSE:\n" | 1144 | "PURPOSE:\n" |
3932 | 1145 | " This test will test your pointing device\n" | 1145 | " This test will test your pointing device\n" |
3933 | @@ -1151,7 +1151,7 @@ | |||
3934 | 1151 | msgstr "" | 1151 | msgstr "" |
3935 | 1152 | 1152 | ||
3936 | 1153 | #. description | 1153 | #. description |
3938 | 1154 | #: ../jobs/input.txt.in:36 | 1154 | #: ../jobs/input.txt.in:35 |
3939 | 1155 | msgid "" | 1155 | msgid "" |
3940 | 1156 | "PURPOSE:\n" | 1156 | "PURPOSE:\n" |
3941 | 1157 | " This test will test your keyboard\n" | 1157 | " This test will test your keyboard\n" |
3942 | 1158 | 1158 | ||
3943 | === modified file 'po/ast.po' | |||
3944 | --- po/ast.po 2013-02-22 16:26:25 +0000 | |||
3945 | +++ po/ast.po 2013-03-07 16:10:38 +0000 | |||
3946 | @@ -14,8 +14,8 @@ | |||
3947 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
3948 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
3949 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
3952 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:31+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:38+0000\n" |
3953 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
3954 | 19 | "Language: ast\n" | 19 | "Language: ast\n" |
3955 | 20 | 20 | ||
3956 | 21 | #. Title of the user interface | 21 | #. Title of the user interface |
3957 | @@ -1324,7 +1324,7 @@ | |||
3958 | 1324 | msgstr "Axunta'l rexistru de depuración del instalador si existe." | 1324 | msgstr "Axunta'l rexistru de depuración del instalador si existe." |
3959 | 1325 | 1325 | ||
3960 | 1326 | #. description | 1326 | #. description |
3962 | 1327 | #: ../jobs/input.txt.in:23 | 1327 | #: ../jobs/input.txt.in:22 |
3963 | 1328 | msgid "" | 1328 | msgid "" |
3964 | 1329 | "PURPOSE:\n" | 1329 | "PURPOSE:\n" |
3965 | 1330 | " This test will test your pointing device\n" | 1330 | " This test will test your pointing device\n" |
3966 | @@ -1343,7 +1343,7 @@ | |||
3967 | 1343 | " ¿Comportóse'l preséu de punteru s'esperaba?" | 1343 | " ¿Comportóse'l preséu de punteru s'esperaba?" |
3968 | 1344 | 1344 | ||
3969 | 1345 | #. description | 1345 | #. description |
3971 | 1346 | #: ../jobs/input.txt.in:36 | 1346 | #: ../jobs/input.txt.in:35 |
3972 | 1347 | msgid "" | 1347 | msgid "" |
3973 | 1348 | "PURPOSE:\n" | 1348 | "PURPOSE:\n" |
3974 | 1349 | " This test will test your keyboard\n" | 1349 | " This test will test your keyboard\n" |
3975 | 1350 | 1350 | ||
3976 | === modified file 'po/az.po' | |||
3977 | --- po/az.po 2013-02-22 16:26:25 +0000 | |||
3978 | +++ po/az.po 2013-03-07 16:10:38 +0000 | |||
3979 | @@ -14,8 +14,8 @@ | |||
3980 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
3981 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
3982 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
3985 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:31+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:38+0000\n" |
3986 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
3987 | 19 | 19 | ||
3988 | 20 | #. Title of the user interface | 20 | #. Title of the user interface |
3989 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 |
3990 | @@ -967,7 +967,7 @@ | |||
3991 | 967 | msgstr "" | 967 | msgstr "" |
3992 | 968 | 968 | ||
3993 | 969 | #. description | 969 | #. description |
3995 | 970 | #: ../jobs/input.txt.in:23 | 970 | #: ../jobs/input.txt.in:22 |
3996 | 971 | msgid "" | 971 | msgid "" |
3997 | 972 | "PURPOSE:\n" | 972 | "PURPOSE:\n" |
3998 | 973 | " This test will test your pointing device\n" | 973 | " This test will test your pointing device\n" |
3999 | @@ -979,7 +979,7 @@ | |||
4000 | 979 | msgstr "" | 979 | msgstr "" |
4001 | 980 | 980 | ||
4002 | 981 | #. description | 981 | #. description |
4004 | 982 | #: ../jobs/input.txt.in:36 | 982 | #: ../jobs/input.txt.in:35 |
4005 | 983 | msgid "" | 983 | msgid "" |
4006 | 984 | "PURPOSE:\n" | 984 | "PURPOSE:\n" |
4007 | 985 | " This test will test your keyboard\n" | 985 | " This test will test your keyboard\n" |
4008 | 986 | 986 | ||
4009 | === modified file 'po/be.po' | |||
4010 | --- po/be.po 2013-02-22 16:26:25 +0000 | |||
4011 | +++ po/be.po 2013-03-07 16:10:38 +0000 | |||
4012 | @@ -14,8 +14,8 @@ | |||
4013 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
4014 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
4015 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
4018 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:31+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:38+0000\n" |
4019 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
4020 | 19 | 19 | ||
4021 | 20 | #. Title of the user interface | 20 | #. Title of the user interface |
4022 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 |
4023 | @@ -971,7 +971,7 @@ | |||
4024 | 971 | msgstr "" | 971 | msgstr "" |
4025 | 972 | 972 | ||
4026 | 973 | #. description | 973 | #. description |
4028 | 974 | #: ../jobs/input.txt.in:23 | 974 | #: ../jobs/input.txt.in:22 |
4029 | 975 | msgid "" | 975 | msgid "" |
4030 | 976 | "PURPOSE:\n" | 976 | "PURPOSE:\n" |
4031 | 977 | " This test will test your pointing device\n" | 977 | " This test will test your pointing device\n" |
4032 | @@ -983,7 +983,7 @@ | |||
4033 | 983 | msgstr "" | 983 | msgstr "" |
4034 | 984 | 984 | ||
4035 | 985 | #. description | 985 | #. description |
4037 | 986 | #: ../jobs/input.txt.in:36 | 986 | #: ../jobs/input.txt.in:35 |
4038 | 987 | msgid "" | 987 | msgid "" |
4039 | 988 | "PURPOSE:\n" | 988 | "PURPOSE:\n" |
4040 | 989 | " This test will test your keyboard\n" | 989 | " This test will test your keyboard\n" |
4041 | 990 | 990 | ||
4042 | === modified file 'po/bg.po' | |||
4043 | --- po/bg.po 2013-02-22 16:26:25 +0000 | |||
4044 | +++ po/bg.po 2013-03-07 16:10:38 +0000 | |||
4045 | @@ -14,8 +14,8 @@ | |||
4046 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
4047 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
4048 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
4051 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:32+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:38+0000\n" |
4052 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
4053 | 19 | 19 | ||
4054 | 20 | #. Title of the user interface | 20 | #. Title of the user interface |
4055 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 |
4056 | @@ -968,7 +968,7 @@ | |||
4057 | 968 | msgstr "" | 968 | msgstr "" |
4058 | 969 | 969 | ||
4059 | 970 | #. description | 970 | #. description |
4061 | 971 | #: ../jobs/input.txt.in:23 | 971 | #: ../jobs/input.txt.in:22 |
4062 | 972 | msgid "" | 972 | msgid "" |
4063 | 973 | "PURPOSE:\n" | 973 | "PURPOSE:\n" |
4064 | 974 | " This test will test your pointing device\n" | 974 | " This test will test your pointing device\n" |
4065 | @@ -980,7 +980,7 @@ | |||
4066 | 980 | msgstr "" | 980 | msgstr "" |
4067 | 981 | 981 | ||
4068 | 982 | #. description | 982 | #. description |
4070 | 983 | #: ../jobs/input.txt.in:36 | 983 | #: ../jobs/input.txt.in:35 |
4071 | 984 | msgid "" | 984 | msgid "" |
4072 | 985 | "PURPOSE:\n" | 985 | "PURPOSE:\n" |
4073 | 986 | " This test will test your keyboard\n" | 986 | " This test will test your keyboard\n" |
4074 | 987 | 987 | ||
4075 | === modified file 'po/bn.po' | |||
4076 | --- po/bn.po 2013-02-22 16:26:25 +0000 | |||
4077 | +++ po/bn.po 2013-03-07 16:10:38 +0000 | |||
4078 | @@ -14,8 +14,8 @@ | |||
4079 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
4080 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
4081 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
4084 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:31+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:38+0000\n" |
4085 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
4086 | 19 | 19 | ||
4087 | 20 | #. Title of the user interface | 20 | #. Title of the user interface |
4088 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 |
4089 | @@ -1215,7 +1215,7 @@ | |||
4090 | 1215 | msgstr "ইনস্টলার ডিবাগ লগ বিদ্যমান থাকলে সংযুক্ত করা হয়।" | 1215 | msgstr "ইনস্টলার ডিবাগ লগ বিদ্যমান থাকলে সংযুক্ত করা হয়।" |
4091 | 1216 | 1216 | ||
4092 | 1217 | #. description | 1217 | #. description |
4094 | 1218 | #: ../jobs/input.txt.in:23 | 1218 | #: ../jobs/input.txt.in:22 |
4095 | 1219 | msgid "" | 1219 | msgid "" |
4096 | 1220 | "PURPOSE:\n" | 1220 | "PURPOSE:\n" |
4097 | 1221 | " This test will test your pointing device\n" | 1221 | " This test will test your pointing device\n" |
4098 | @@ -1234,7 +1234,7 @@ | |||
4099 | 1234 | " পয়েন্টকৃত ডিভাইসটি কি প্রত্যাশিত ভাবে কাজ করছে?" | 1234 | " পয়েন্টকৃত ডিভাইসটি কি প্রত্যাশিত ভাবে কাজ করছে?" |
4100 | 1235 | 1235 | ||
4101 | 1236 | #. description | 1236 | #. description |
4103 | 1237 | #: ../jobs/input.txt.in:36 | 1237 | #: ../jobs/input.txt.in:35 |
4104 | 1238 | msgid "" | 1238 | msgid "" |
4105 | 1239 | "PURPOSE:\n" | 1239 | "PURPOSE:\n" |
4106 | 1240 | " This test will test your keyboard\n" | 1240 | " This test will test your keyboard\n" |
4107 | 1241 | 1241 | ||
4108 | === modified file 'po/bo.po' | |||
4109 | --- po/bo.po 2013-02-22 16:26:25 +0000 | |||
4110 | +++ po/bo.po 2013-03-07 16:10:38 +0000 | |||
4111 | @@ -14,8 +14,8 @@ | |||
4112 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
4113 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
4114 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
4117 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:34+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:41+0000\n" |
4118 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
4119 | 19 | 19 | ||
4120 | 20 | #. Title of the user interface | 20 | #. Title of the user interface |
4121 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 |
4122 | @@ -964,7 +964,7 @@ | |||
4123 | 964 | msgstr "" | 964 | msgstr "" |
4124 | 965 | 965 | ||
4125 | 966 | #. description | 966 | #. description |
4127 | 967 | #: ../jobs/input.txt.in:23 | 967 | #: ../jobs/input.txt.in:22 |
4128 | 968 | msgid "" | 968 | msgid "" |
4129 | 969 | "PURPOSE:\n" | 969 | "PURPOSE:\n" |
4130 | 970 | " This test will test your pointing device\n" | 970 | " This test will test your pointing device\n" |
4131 | @@ -976,7 +976,7 @@ | |||
4132 | 976 | msgstr "" | 976 | msgstr "" |
4133 | 977 | 977 | ||
4134 | 978 | #. description | 978 | #. description |
4136 | 979 | #: ../jobs/input.txt.in:36 | 979 | #: ../jobs/input.txt.in:35 |
4137 | 980 | msgid "" | 980 | msgid "" |
4138 | 981 | "PURPOSE:\n" | 981 | "PURPOSE:\n" |
4139 | 982 | " This test will test your keyboard\n" | 982 | " This test will test your keyboard\n" |
4140 | 983 | 983 | ||
4141 | === modified file 'po/br.po' | |||
4142 | --- po/br.po 2013-02-22 16:26:25 +0000 | |||
4143 | +++ po/br.po 2013-03-07 16:10:38 +0000 | |||
4144 | @@ -14,8 +14,8 @@ | |||
4145 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
4146 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
4147 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
4150 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:32+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:38+0000\n" |
4151 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
4152 | 19 | 19 | ||
4153 | 20 | #. Title of the user interface | 20 | #. Title of the user interface |
4154 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 |
4155 | @@ -964,7 +964,7 @@ | |||
4156 | 964 | msgstr "" | 964 | msgstr "" |
4157 | 965 | 965 | ||
4158 | 966 | #. description | 966 | #. description |
4160 | 967 | #: ../jobs/input.txt.in:23 | 967 | #: ../jobs/input.txt.in:22 |
4161 | 968 | msgid "" | 968 | msgid "" |
4162 | 969 | "PURPOSE:\n" | 969 | "PURPOSE:\n" |
4163 | 970 | " This test will test your pointing device\n" | 970 | " This test will test your pointing device\n" |
4164 | @@ -976,7 +976,7 @@ | |||
4165 | 976 | msgstr "" | 976 | msgstr "" |
4166 | 977 | 977 | ||
4167 | 978 | #. description | 978 | #. description |
4169 | 979 | #: ../jobs/input.txt.in:36 | 979 | #: ../jobs/input.txt.in:35 |
4170 | 980 | msgid "" | 980 | msgid "" |
4171 | 981 | "PURPOSE:\n" | 981 | "PURPOSE:\n" |
4172 | 982 | " This test will test your keyboard\n" | 982 | " This test will test your keyboard\n" |
4173 | 983 | 983 | ||
4174 | === modified file 'po/bs.po' | |||
4175 | --- po/bs.po 2013-02-22 16:26:25 +0000 | |||
4176 | +++ po/bs.po 2013-03-07 16:10:38 +0000 | |||
4177 | @@ -14,8 +14,8 @@ | |||
4178 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
4179 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
4180 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
4183 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:32+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:38+0000\n" |
4184 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
4185 | 19 | 19 | ||
4186 | 20 | #. Title of the user interface | 20 | #. Title of the user interface |
4187 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 |
4188 | @@ -1271,7 +1271,7 @@ | |||
4189 | 1271 | msgstr "Prilaže instalerski debug dnevnik ako postoji." | 1271 | msgstr "Prilaže instalerski debug dnevnik ako postoji." |
4190 | 1272 | 1272 | ||
4191 | 1273 | #. description | 1273 | #. description |
4193 | 1274 | #: ../jobs/input.txt.in:23 | 1274 | #: ../jobs/input.txt.in:22 |
4194 | 1275 | msgid "" | 1275 | msgid "" |
4195 | 1276 | "PURPOSE:\n" | 1276 | "PURPOSE:\n" |
4196 | 1277 | " This test will test your pointing device\n" | 1277 | " This test will test your pointing device\n" |
4197 | @@ -1290,7 +1290,7 @@ | |||
4198 | 1290 | " Da li radi pokazivački uređaj kao što je očekivano?" | 1290 | " Da li radi pokazivački uređaj kao što je očekivano?" |
4199 | 1291 | 1291 | ||
4200 | 1292 | #. description | 1292 | #. description |
4202 | 1293 | #: ../jobs/input.txt.in:36 | 1293 | #: ../jobs/input.txt.in:35 |
4203 | 1294 | msgid "" | 1294 | msgid "" |
4204 | 1295 | "PURPOSE:\n" | 1295 | "PURPOSE:\n" |
4205 | 1296 | " This test will test your keyboard\n" | 1296 | " This test will test your keyboard\n" |
4206 | 1297 | 1297 | ||
4207 | === modified file 'po/ca.po' | |||
4208 | --- po/ca.po 2013-02-22 16:26:25 +0000 | |||
4209 | +++ po/ca.po 2013-03-07 16:10:38 +0000 | |||
4210 | @@ -14,8 +14,8 @@ | |||
4211 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
4212 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
4213 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
4216 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:32+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:38+0000\n" |
4217 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
4218 | 19 | 19 | ||
4219 | 20 | #~ msgid "$output" | 20 | #~ msgid "$output" |
4220 | 21 | #~ msgstr "$resultat" | 21 | #~ msgstr "$resultat" |
4221 | @@ -989,7 +989,7 @@ | |||
4222 | 989 | msgstr "" | 989 | msgstr "" |
4223 | 990 | 990 | ||
4224 | 991 | #. description | 991 | #. description |
4226 | 992 | #: ../jobs/input.txt.in:23 | 992 | #: ../jobs/input.txt.in:22 |
4227 | 993 | msgid "" | 993 | msgid "" |
4228 | 994 | "PURPOSE:\n" | 994 | "PURPOSE:\n" |
4229 | 995 | " This test will test your pointing device\n" | 995 | " This test will test your pointing device\n" |
4230 | @@ -1001,7 +1001,7 @@ | |||
4231 | 1001 | msgstr "" | 1001 | msgstr "" |
4232 | 1002 | 1002 | ||
4233 | 1003 | #. description | 1003 | #. description |
4235 | 1004 | #: ../jobs/input.txt.in:36 | 1004 | #: ../jobs/input.txt.in:35 |
4236 | 1005 | msgid "" | 1005 | msgid "" |
4237 | 1006 | "PURPOSE:\n" | 1006 | "PURPOSE:\n" |
4238 | 1007 | " This test will test your keyboard\n" | 1007 | " This test will test your keyboard\n" |
4239 | 1008 | 1008 | ||
4240 | === modified file 'po/ca@valencia.po' | |||
4241 | --- po/ca@valencia.po 2013-02-22 16:26:25 +0000 | |||
4242 | +++ po/ca@valencia.po 2013-03-07 16:10:38 +0000 | |||
4243 | @@ -14,8 +14,8 @@ | |||
4244 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
4245 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
4246 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
4249 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:35+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:42+0000\n" |
4250 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
4251 | 19 | 19 | ||
4252 | 20 | #. Title of the user interface | 20 | #. Title of the user interface |
4253 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 |
4254 | @@ -986,7 +986,7 @@ | |||
4255 | 986 | msgstr "" | 986 | msgstr "" |
4256 | 987 | 987 | ||
4257 | 988 | #. description | 988 | #. description |
4259 | 989 | #: ../jobs/input.txt.in:23 | 989 | #: ../jobs/input.txt.in:22 |
4260 | 990 | msgid "" | 990 | msgid "" |
4261 | 991 | "PURPOSE:\n" | 991 | "PURPOSE:\n" |
4262 | 992 | " This test will test your pointing device\n" | 992 | " This test will test your pointing device\n" |
4263 | @@ -998,7 +998,7 @@ | |||
4264 | 998 | msgstr "" | 998 | msgstr "" |
4265 | 999 | 999 | ||
4266 | 1000 | #. description | 1000 | #. description |
4268 | 1001 | #: ../jobs/input.txt.in:36 | 1001 | #: ../jobs/input.txt.in:35 |
4269 | 1002 | msgid "" | 1002 | msgid "" |
4270 | 1003 | "PURPOSE:\n" | 1003 | "PURPOSE:\n" |
4271 | 1004 | " This test will test your keyboard\n" | 1004 | " This test will test your keyboard\n" |
4272 | 1005 | 1005 | ||
4273 | === modified file 'po/ckb.po' | |||
4274 | --- po/ckb.po 2013-02-22 16:26:25 +0000 | |||
4275 | +++ po/ckb.po 2013-03-07 16:10:38 +0000 | |||
4276 | @@ -14,8 +14,8 @@ | |||
4277 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
4278 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
4279 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
4282 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:35+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:41+0000\n" |
4283 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
4284 | 19 | 19 | ||
4285 | 20 | #. Title of the user interface | 20 | #. Title of the user interface |
4286 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 |
4287 | @@ -964,7 +964,7 @@ | |||
4288 | 964 | msgstr "" | 964 | msgstr "" |
4289 | 965 | 965 | ||
4290 | 966 | #. description | 966 | #. description |
4292 | 967 | #: ../jobs/input.txt.in:23 | 967 | #: ../jobs/input.txt.in:22 |
4293 | 968 | msgid "" | 968 | msgid "" |
4294 | 969 | "PURPOSE:\n" | 969 | "PURPOSE:\n" |
4295 | 970 | " This test will test your pointing device\n" | 970 | " This test will test your pointing device\n" |
4296 | @@ -976,7 +976,7 @@ | |||
4297 | 976 | msgstr "" | 976 | msgstr "" |
4298 | 977 | 977 | ||
4299 | 978 | #. description | 978 | #. description |
4301 | 979 | #: ../jobs/input.txt.in:36 | 979 | #: ../jobs/input.txt.in:35 |
4302 | 980 | msgid "" | 980 | msgid "" |
4303 | 981 | "PURPOSE:\n" | 981 | "PURPOSE:\n" |
4304 | 982 | " This test will test your keyboard\n" | 982 | " This test will test your keyboard\n" |
4305 | 983 | 983 | ||
4306 | === modified file 'po/cs.po' | |||
4307 | --- po/cs.po 2013-02-22 16:26:25 +0000 | |||
4308 | +++ po/cs.po 2013-03-07 16:10:38 +0000 | |||
4309 | @@ -14,8 +14,8 @@ | |||
4310 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
4311 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
4312 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
4315 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:32+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:38+0000\n" |
4316 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
4317 | 19 | 19 | ||
4318 | 20 | #: ../gtk/checkbox-gtk.ui.h:2 ../checkbox_gtk/gtk_interface.py:561 | 20 | #: ../gtk/checkbox-gtk.ui.h:2 ../checkbox_gtk/gtk_interface.py:561 |
4319 | 21 | msgid "_Test" | 21 | msgid "_Test" |
4320 | @@ -1215,7 +1215,7 @@ | |||
4321 | 1215 | msgstr "Existuje-li, připojí ladicí záznam instalátoru" | 1215 | msgstr "Existuje-li, připojí ladicí záznam instalátoru" |
4322 | 1216 | 1216 | ||
4323 | 1217 | #. description | 1217 | #. description |
4325 | 1218 | #: ../jobs/input.txt.in:23 | 1218 | #: ../jobs/input.txt.in:22 |
4326 | 1219 | msgid "" | 1219 | msgid "" |
4327 | 1220 | "PURPOSE:\n" | 1220 | "PURPOSE:\n" |
4328 | 1221 | " This test will test your pointing device\n" | 1221 | " This test will test your pointing device\n" |
4329 | @@ -1234,7 +1234,7 @@ | |||
4330 | 1234 | " Fungovalo dotykové zařízení dle očekávání?" | 1234 | " Fungovalo dotykové zařízení dle očekávání?" |
4331 | 1235 | 1235 | ||
4332 | 1236 | #. description | 1236 | #. description |
4334 | 1237 | #: ../jobs/input.txt.in:36 | 1237 | #: ../jobs/input.txt.in:35 |
4335 | 1238 | msgid "" | 1238 | msgid "" |
4336 | 1239 | "PURPOSE:\n" | 1239 | "PURPOSE:\n" |
4337 | 1240 | " This test will test your keyboard\n" | 1240 | " This test will test your keyboard\n" |
4338 | 1241 | 1241 | ||
4339 | === modified file 'po/cy.po' | |||
4340 | --- po/cy.po 2013-02-22 16:26:25 +0000 | |||
4341 | +++ po/cy.po 2013-03-07 16:10:38 +0000 | |||
4342 | @@ -14,8 +14,8 @@ | |||
4343 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
4344 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
4345 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
4348 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:34+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:41+0000\n" |
4349 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
4350 | 19 | 19 | ||
4351 | 20 | #. Title of the user interface | 20 | #. Title of the user interface |
4352 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 |
4353 | @@ -964,7 +964,7 @@ | |||
4354 | 964 | msgstr "" | 964 | msgstr "" |
4355 | 965 | 965 | ||
4356 | 966 | #. description | 966 | #. description |
4358 | 967 | #: ../jobs/input.txt.in:23 | 967 | #: ../jobs/input.txt.in:22 |
4359 | 968 | msgid "" | 968 | msgid "" |
4360 | 969 | "PURPOSE:\n" | 969 | "PURPOSE:\n" |
4361 | 970 | " This test will test your pointing device\n" | 970 | " This test will test your pointing device\n" |
4362 | @@ -976,7 +976,7 @@ | |||
4363 | 976 | msgstr "" | 976 | msgstr "" |
4364 | 977 | 977 | ||
4365 | 978 | #. description | 978 | #. description |
4367 | 979 | #: ../jobs/input.txt.in:36 | 979 | #: ../jobs/input.txt.in:35 |
4368 | 980 | msgid "" | 980 | msgid "" |
4369 | 981 | "PURPOSE:\n" | 981 | "PURPOSE:\n" |
4370 | 982 | " This test will test your keyboard\n" | 982 | " This test will test your keyboard\n" |
4371 | 983 | 983 | ||
4372 | === modified file 'po/da.po' | |||
4373 | --- po/da.po 2013-02-22 16:26:25 +0000 | |||
4374 | +++ po/da.po 2013-03-07 16:10:38 +0000 | |||
4375 | @@ -14,8 +14,8 @@ | |||
4376 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
4377 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
4378 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
4381 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:32+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:38+0000\n" |
4382 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
4383 | 19 | "X-Poedit-Language: Danish\n" | 19 | "X-Poedit-Language: Danish\n" |
4384 | 20 | 20 | ||
4385 | 21 | #. Title of the user interface | 21 | #. Title of the user interface |
4386 | @@ -1131,7 +1131,7 @@ | |||
4387 | 1131 | msgstr "" | 1131 | msgstr "" |
4388 | 1132 | 1132 | ||
4389 | 1133 | #. description | 1133 | #. description |
4391 | 1134 | #: ../jobs/input.txt.in:23 | 1134 | #: ../jobs/input.txt.in:22 |
4392 | 1135 | msgid "" | 1135 | msgid "" |
4393 | 1136 | "PURPOSE:\n" | 1136 | "PURPOSE:\n" |
4394 | 1137 | " This test will test your pointing device\n" | 1137 | " This test will test your pointing device\n" |
4395 | @@ -1143,7 +1143,7 @@ | |||
4396 | 1143 | msgstr "" | 1143 | msgstr "" |
4397 | 1144 | 1144 | ||
4398 | 1145 | #. description | 1145 | #. description |
4400 | 1146 | #: ../jobs/input.txt.in:36 | 1146 | #: ../jobs/input.txt.in:35 |
4401 | 1147 | msgid "" | 1147 | msgid "" |
4402 | 1148 | "PURPOSE:\n" | 1148 | "PURPOSE:\n" |
4403 | 1149 | " This test will test your keyboard\n" | 1149 | " This test will test your keyboard\n" |
4404 | 1150 | 1150 | ||
4405 | === modified file 'po/de.po' | |||
4406 | --- po/de.po 2013-02-22 16:26:25 +0000 | |||
4407 | +++ po/de.po 2013-03-07 16:10:38 +0000 | |||
4408 | @@ -14,8 +14,8 @@ | |||
4409 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
4410 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
4411 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
4414 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:32+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:39+0000\n" |
4415 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
4416 | 19 | 19 | ||
4417 | 20 | #: ../gtk/checkbox-gtk.ui.h:2 ../checkbox_gtk/gtk_interface.py:561 | 20 | #: ../gtk/checkbox-gtk.ui.h:2 ../checkbox_gtk/gtk_interface.py:561 |
4418 | 21 | msgid "_Test" | 21 | msgid "_Test" |
4419 | @@ -83,7 +83,7 @@ | |||
4420 | 83 | 83 | ||
4421 | 84 | #: ../gtk/checkbox-gtk.ui.h:5 | 84 | #: ../gtk/checkbox-gtk.ui.h:5 |
4422 | 85 | msgid "_Skip this test" | 85 | msgid "_Skip this test" |
4424 | 86 | msgstr "Test _überspringen" | 86 | msgstr "_Diesen Test überspringen" |
4425 | 87 | 87 | ||
4426 | 88 | #: ../gtk/checkbox-gtk.ui.h:6 ../checkbox_cli/cli_interface.py:460 | 88 | #: ../gtk/checkbox-gtk.ui.h:6 ../checkbox_cli/cli_interface.py:460 |
4427 | 89 | #: ../checkbox_urwid/urwid_interface.py:289 | 89 | #: ../checkbox_urwid/urwid_interface.py:289 |
4428 | @@ -1425,7 +1425,7 @@ | |||
4429 | 1425 | "als Anlage bei, falls vorhanden." | 1425 | "als Anlage bei, falls vorhanden." |
4430 | 1426 | 1426 | ||
4431 | 1427 | #. description | 1427 | #. description |
4433 | 1428 | #: ../jobs/input.txt.in:23 | 1428 | #: ../jobs/input.txt.in:22 |
4434 | 1429 | msgid "" | 1429 | msgid "" |
4435 | 1430 | "PURPOSE:\n" | 1430 | "PURPOSE:\n" |
4436 | 1431 | " This test will test your pointing device\n" | 1431 | " This test will test your pointing device\n" |
4437 | @@ -1445,7 +1445,7 @@ | |||
4438 | 1445 | " Arbeitete das Zeigegerät so, wie es vorgesehen ist?" | 1445 | " Arbeitete das Zeigegerät so, wie es vorgesehen ist?" |
4439 | 1446 | 1446 | ||
4440 | 1447 | #. description | 1447 | #. description |
4442 | 1448 | #: ../jobs/input.txt.in:36 | 1448 | #: ../jobs/input.txt.in:35 |
4443 | 1449 | msgid "" | 1449 | msgid "" |
4444 | 1450 | "PURPOSE:\n" | 1450 | "PURPOSE:\n" |
4445 | 1451 | " This test will test your keyboard\n" | 1451 | " This test will test your keyboard\n" |
4446 | 1452 | 1452 | ||
4447 | === modified file 'po/dv.po' | |||
4448 | --- po/dv.po 2013-02-22 16:26:25 +0000 | |||
4449 | +++ po/dv.po 2013-03-07 16:10:38 +0000 | |||
4450 | @@ -14,8 +14,8 @@ | |||
4451 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
4452 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
4453 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
4456 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:32+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:38+0000\n" |
4457 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
4458 | 19 | 19 | ||
4459 | 20 | #. Title of the user interface | 20 | #. Title of the user interface |
4460 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 |
4461 | @@ -964,7 +964,7 @@ | |||
4462 | 964 | msgstr "" | 964 | msgstr "" |
4463 | 965 | 965 | ||
4464 | 966 | #. description | 966 | #. description |
4466 | 967 | #: ../jobs/input.txt.in:23 | 967 | #: ../jobs/input.txt.in:22 |
4467 | 968 | msgid "" | 968 | msgid "" |
4468 | 969 | "PURPOSE:\n" | 969 | "PURPOSE:\n" |
4469 | 970 | " This test will test your pointing device\n" | 970 | " This test will test your pointing device\n" |
4470 | @@ -976,7 +976,7 @@ | |||
4471 | 976 | msgstr "" | 976 | msgstr "" |
4472 | 977 | 977 | ||
4473 | 978 | #. description | 978 | #. description |
4475 | 979 | #: ../jobs/input.txt.in:36 | 979 | #: ../jobs/input.txt.in:35 |
4476 | 980 | msgid "" | 980 | msgid "" |
4477 | 981 | "PURPOSE:\n" | 981 | "PURPOSE:\n" |
4478 | 982 | " This test will test your keyboard\n" | 982 | " This test will test your keyboard\n" |
4479 | 983 | 983 | ||
4480 | === modified file 'po/el.po' | |||
4481 | --- po/el.po 2013-02-22 16:26:25 +0000 | |||
4482 | +++ po/el.po 2013-03-07 16:10:38 +0000 | |||
4483 | @@ -14,8 +14,8 @@ | |||
4484 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
4485 | 15 | "Content-Type: text/plain; charset=utf-8\n" | 15 | "Content-Type: text/plain; charset=utf-8\n" |
4486 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
4489 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:32+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:39+0000\n" |
4490 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
4491 | 19 | 19 | ||
4492 | 20 | #: ../gtk/checkbox-gtk.ui.h:2 ../checkbox_gtk/gtk_interface.py:561 | 20 | #: ../gtk/checkbox-gtk.ui.h:2 ../checkbox_gtk/gtk_interface.py:561 |
4493 | 21 | msgid "_Test" | 21 | msgid "_Test" |
4494 | @@ -1389,7 +1389,7 @@ | |||
4495 | 1389 | msgstr "Επισύναψη της καταγραφής αποσφαλμάτωσης του εγκαταστάτη αν υπάρχει." | 1389 | msgstr "Επισύναψη της καταγραφής αποσφαλμάτωσης του εγκαταστάτη αν υπάρχει." |
4496 | 1390 | 1390 | ||
4497 | 1391 | #. description | 1391 | #. description |
4499 | 1392 | #: ../jobs/input.txt.in:23 | 1392 | #: ../jobs/input.txt.in:22 |
4500 | 1393 | msgid "" | 1393 | msgid "" |
4501 | 1394 | "PURPOSE:\n" | 1394 | "PURPOSE:\n" |
4502 | 1395 | " This test will test your pointing device\n" | 1395 | " This test will test your pointing device\n" |
4503 | @@ -1409,7 +1409,7 @@ | |||
4504 | 1409 | " Λειτούργησε η συσκευή κατάδειξης όπως θα περιμένατε;" | 1409 | " Λειτούργησε η συσκευή κατάδειξης όπως θα περιμένατε;" |
4505 | 1410 | 1410 | ||
4506 | 1411 | #. description | 1411 | #. description |
4508 | 1412 | #: ../jobs/input.txt.in:36 | 1412 | #: ../jobs/input.txt.in:35 |
4509 | 1413 | msgid "" | 1413 | msgid "" |
4510 | 1414 | "PURPOSE:\n" | 1414 | "PURPOSE:\n" |
4511 | 1415 | " This test will test your keyboard\n" | 1415 | " This test will test your keyboard\n" |
4512 | 1416 | 1416 | ||
4513 | === modified file 'po/en_AU.po' | |||
4514 | --- po/en_AU.po 2013-02-22 16:26:25 +0000 | |||
4515 | +++ po/en_AU.po 2013-03-07 16:10:38 +0000 | |||
4516 | @@ -14,8 +14,8 @@ | |||
4517 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
4518 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
4519 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
4522 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:34+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:41+0000\n" |
4523 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
4524 | 19 | 19 | ||
4525 | 20 | #. Title of the user interface | 20 | #. Title of the user interface |
4526 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 |
4527 | @@ -1254,7 +1254,7 @@ | |||
4528 | 1254 | msgstr "Attaches the installer debug log if it exists." | 1254 | msgstr "Attaches the installer debug log if it exists." |
4529 | 1255 | 1255 | ||
4530 | 1256 | #. description | 1256 | #. description |
4532 | 1257 | #: ../jobs/input.txt.in:23 | 1257 | #: ../jobs/input.txt.in:22 |
4533 | 1258 | msgid "" | 1258 | msgid "" |
4534 | 1259 | "PURPOSE:\n" | 1259 | "PURPOSE:\n" |
4535 | 1260 | " This test will test your pointing device\n" | 1260 | " This test will test your pointing device\n" |
4536 | @@ -1273,7 +1273,7 @@ | |||
4537 | 1273 | " Did the pointing device work as expected?" | 1273 | " Did the pointing device work as expected?" |
4538 | 1274 | 1274 | ||
4539 | 1275 | #. description | 1275 | #. description |
4541 | 1276 | #: ../jobs/input.txt.in:36 | 1276 | #: ../jobs/input.txt.in:35 |
4542 | 1277 | msgid "" | 1277 | msgid "" |
4543 | 1278 | "PURPOSE:\n" | 1278 | "PURPOSE:\n" |
4544 | 1279 | " This test will test your keyboard\n" | 1279 | " This test will test your keyboard\n" |
4545 | 1280 | 1280 | ||
4546 | === modified file 'po/en_CA.po' | |||
4547 | --- po/en_CA.po 2013-02-22 16:26:25 +0000 | |||
4548 | +++ po/en_CA.po 2013-03-07 16:10:38 +0000 | |||
4549 | @@ -14,8 +14,8 @@ | |||
4550 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
4551 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
4552 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
4555 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:35+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:41+0000\n" |
4556 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
4557 | 19 | 19 | ||
4558 | 20 | #. Title of the user interface | 20 | #. Title of the user interface |
4559 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 |
4560 | @@ -964,7 +964,7 @@ | |||
4561 | 964 | msgstr "" | 964 | msgstr "" |
4562 | 965 | 965 | ||
4563 | 966 | #. description | 966 | #. description |
4565 | 967 | #: ../jobs/input.txt.in:23 | 967 | #: ../jobs/input.txt.in:22 |
4566 | 968 | msgid "" | 968 | msgid "" |
4567 | 969 | "PURPOSE:\n" | 969 | "PURPOSE:\n" |
4568 | 970 | " This test will test your pointing device\n" | 970 | " This test will test your pointing device\n" |
4569 | @@ -976,7 +976,7 @@ | |||
4570 | 976 | msgstr "" | 976 | msgstr "" |
4571 | 977 | 977 | ||
4572 | 978 | #. description | 978 | #. description |
4574 | 979 | #: ../jobs/input.txt.in:36 | 979 | #: ../jobs/input.txt.in:35 |
4575 | 980 | msgid "" | 980 | msgid "" |
4576 | 981 | "PURPOSE:\n" | 981 | "PURPOSE:\n" |
4577 | 982 | " This test will test your keyboard\n" | 982 | " This test will test your keyboard\n" |
4578 | 983 | 983 | ||
4579 | === modified file 'po/en_GB.po' | |||
4580 | --- po/en_GB.po 2013-02-22 16:26:25 +0000 | |||
4581 | +++ po/en_GB.po 2013-03-07 16:10:38 +0000 | |||
4582 | @@ -14,8 +14,8 @@ | |||
4583 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
4584 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
4585 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
4588 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:34+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:41+0000\n" |
4589 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
4590 | 19 | 19 | ||
4591 | 20 | #~ msgid "Do you see color bars and static?" | 20 | #~ msgid "Do you see color bars and static?" |
4592 | 21 | #~ msgstr "Do you see colour bars and static?" | 21 | #~ msgstr "Do you see colour bars and static?" |
4593 | @@ -1257,7 +1257,7 @@ | |||
4594 | 1257 | msgstr "Attaches the installer debug log if it exists." | 1257 | msgstr "Attaches the installer debug log if it exists." |
4595 | 1258 | 1258 | ||
4596 | 1259 | #. description | 1259 | #. description |
4598 | 1260 | #: ../jobs/input.txt.in:23 | 1260 | #: ../jobs/input.txt.in:22 |
4599 | 1261 | msgid "" | 1261 | msgid "" |
4600 | 1262 | "PURPOSE:\n" | 1262 | "PURPOSE:\n" |
4601 | 1263 | " This test will test your pointing device\n" | 1263 | " This test will test your pointing device\n" |
4602 | @@ -1276,7 +1276,7 @@ | |||
4603 | 1276 | " Did the pointing device work as expected?" | 1276 | " Did the pointing device work as expected?" |
4604 | 1277 | 1277 | ||
4605 | 1278 | #. description | 1278 | #. description |
4607 | 1279 | #: ../jobs/input.txt.in:36 | 1279 | #: ../jobs/input.txt.in:35 |
4608 | 1280 | msgid "" | 1280 | msgid "" |
4609 | 1281 | "PURPOSE:\n" | 1281 | "PURPOSE:\n" |
4610 | 1282 | " This test will test your keyboard\n" | 1282 | " This test will test your keyboard\n" |
4611 | 1283 | 1283 | ||
4612 | === modified file 'po/eo.po' | |||
4613 | --- po/eo.po 2013-02-22 16:26:25 +0000 | |||
4614 | +++ po/eo.po 2013-03-07 16:10:38 +0000 | |||
4615 | @@ -14,8 +14,8 @@ | |||
4616 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
4617 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
4618 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
4621 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:32+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:39+0000\n" |
4622 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
4623 | 19 | 19 | ||
4624 | 20 | #: ../checkbox/application.py:66 | 20 | #: ../checkbox/application.py:66 |
4625 | 21 | msgid "Usage: checkbox [OPTIONS]" | 21 | msgid "Usage: checkbox [OPTIONS]" |
4626 | @@ -1017,7 +1017,7 @@ | |||
4627 | 1017 | msgstr "" | 1017 | msgstr "" |
4628 | 1018 | 1018 | ||
4629 | 1019 | #. description | 1019 | #. description |
4631 | 1020 | #: ../jobs/input.txt.in:23 | 1020 | #: ../jobs/input.txt.in:22 |
4632 | 1021 | msgid "" | 1021 | msgid "" |
4633 | 1022 | "PURPOSE:\n" | 1022 | "PURPOSE:\n" |
4634 | 1023 | " This test will test your pointing device\n" | 1023 | " This test will test your pointing device\n" |
4635 | @@ -1029,7 +1029,7 @@ | |||
4636 | 1029 | msgstr "" | 1029 | msgstr "" |
4637 | 1030 | 1030 | ||
4638 | 1031 | #. description | 1031 | #. description |
4640 | 1032 | #: ../jobs/input.txt.in:36 | 1032 | #: ../jobs/input.txt.in:35 |
4641 | 1033 | msgid "" | 1033 | msgid "" |
4642 | 1034 | "PURPOSE:\n" | 1034 | "PURPOSE:\n" |
4643 | 1035 | " This test will test your keyboard\n" | 1035 | " This test will test your keyboard\n" |
4644 | 1036 | 1036 | ||
4645 | === modified file 'po/es.po' | |||
4646 | --- po/es.po 2013-02-22 16:26:25 +0000 | |||
4647 | +++ po/es.po 2013-03-07 16:10:38 +0000 | |||
4648 | @@ -14,8 +14,8 @@ | |||
4649 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
4650 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
4651 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
4654 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:34+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:41+0000\n" |
4655 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
4656 | 19 | 19 | ||
4657 | 20 | #: ../checkbox/application.py:70 | 20 | #: ../checkbox/application.py:70 |
4658 | 21 | msgid "Print version information and exit." | 21 | msgid "Print version information and exit." |
4659 | @@ -1418,7 +1418,7 @@ | |||
4660 | 1418 | msgstr "Adjunta el registro de depuración del instalador si existe." | 1418 | msgstr "Adjunta el registro de depuración del instalador si existe." |
4661 | 1419 | 1419 | ||
4662 | 1420 | #. description | 1420 | #. description |
4664 | 1421 | #: ../jobs/input.txt.in:23 | 1421 | #: ../jobs/input.txt.in:22 |
4665 | 1422 | msgid "" | 1422 | msgid "" |
4666 | 1423 | "PURPOSE:\n" | 1423 | "PURPOSE:\n" |
4667 | 1424 | " This test will test your pointing device\n" | 1424 | " This test will test your pointing device\n" |
4668 | @@ -1438,7 +1438,7 @@ | |||
4669 | 1438 | " ¿Se comportó el dispositivo de puntero como se esperaba?" | 1438 | " ¿Se comportó el dispositivo de puntero como se esperaba?" |
4670 | 1439 | 1439 | ||
4671 | 1440 | #. description | 1440 | #. description |
4673 | 1441 | #: ../jobs/input.txt.in:36 | 1441 | #: ../jobs/input.txt.in:35 |
4674 | 1442 | msgid "" | 1442 | msgid "" |
4675 | 1443 | "PURPOSE:\n" | 1443 | "PURPOSE:\n" |
4676 | 1444 | " This test will test your keyboard\n" | 1444 | " This test will test your keyboard\n" |
4677 | 1445 | 1445 | ||
4678 | === modified file 'po/et.po' | |||
4679 | --- po/et.po 2013-02-22 16:26:25 +0000 | |||
4680 | +++ po/et.po 2013-03-07 16:10:38 +0000 | |||
4681 | @@ -14,8 +14,8 @@ | |||
4682 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
4683 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
4684 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
4687 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:32+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:39+0000\n" |
4688 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
4689 | 19 | 19 | ||
4690 | 20 | #. Title of the user interface | 20 | #. Title of the user interface |
4691 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 |
4692 | @@ -964,7 +964,7 @@ | |||
4693 | 964 | msgstr "" | 964 | msgstr "" |
4694 | 965 | 965 | ||
4695 | 966 | #. description | 966 | #. description |
4697 | 967 | #: ../jobs/input.txt.in:23 | 967 | #: ../jobs/input.txt.in:22 |
4698 | 968 | msgid "" | 968 | msgid "" |
4699 | 969 | "PURPOSE:\n" | 969 | "PURPOSE:\n" |
4700 | 970 | " This test will test your pointing device\n" | 970 | " This test will test your pointing device\n" |
4701 | @@ -976,7 +976,7 @@ | |||
4702 | 976 | msgstr "" | 976 | msgstr "" |
4703 | 977 | 977 | ||
4704 | 978 | #. description | 978 | #. description |
4706 | 979 | #: ../jobs/input.txt.in:36 | 979 | #: ../jobs/input.txt.in:35 |
4707 | 980 | msgid "" | 980 | msgid "" |
4708 | 981 | "PURPOSE:\n" | 981 | "PURPOSE:\n" |
4709 | 982 | " This test will test your keyboard\n" | 982 | " This test will test your keyboard\n" |
4710 | 983 | 983 | ||
4711 | === modified file 'po/eu.po' | |||
4712 | --- po/eu.po 2013-02-22 16:26:25 +0000 | |||
4713 | +++ po/eu.po 2013-03-07 16:10:38 +0000 | |||
4714 | @@ -14,8 +14,8 @@ | |||
4715 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
4716 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
4717 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
4720 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:31+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:38+0000\n" |
4721 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
4722 | 19 | 19 | ||
4723 | 20 | #. Title of the user interface | 20 | #. Title of the user interface |
4724 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 |
4725 | @@ -964,7 +964,7 @@ | |||
4726 | 964 | msgstr "" | 964 | msgstr "" |
4727 | 965 | 965 | ||
4728 | 966 | #. description | 966 | #. description |
4730 | 967 | #: ../jobs/input.txt.in:23 | 967 | #: ../jobs/input.txt.in:22 |
4731 | 968 | msgid "" | 968 | msgid "" |
4732 | 969 | "PURPOSE:\n" | 969 | "PURPOSE:\n" |
4733 | 970 | " This test will test your pointing device\n" | 970 | " This test will test your pointing device\n" |
4734 | @@ -976,7 +976,7 @@ | |||
4735 | 976 | msgstr "" | 976 | msgstr "" |
4736 | 977 | 977 | ||
4737 | 978 | #. description | 978 | #. description |
4739 | 979 | #: ../jobs/input.txt.in:36 | 979 | #: ../jobs/input.txt.in:35 |
4740 | 980 | msgid "" | 980 | msgid "" |
4741 | 981 | "PURPOSE:\n" | 981 | "PURPOSE:\n" |
4742 | 982 | " This test will test your keyboard\n" | 982 | " This test will test your keyboard\n" |
4743 | 983 | 983 | ||
4744 | === modified file 'po/fa.po' | |||
4745 | --- po/fa.po 2013-02-22 16:26:25 +0000 | |||
4746 | +++ po/fa.po 2013-03-07 16:10:38 +0000 | |||
4747 | @@ -14,8 +14,8 @@ | |||
4748 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
4749 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
4750 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
4753 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:33+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:40+0000\n" |
4754 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
4755 | 19 | 19 | ||
4756 | 20 | #. Title of the user interface | 20 | #. Title of the user interface |
4757 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 |
4758 | @@ -964,7 +964,7 @@ | |||
4759 | 964 | msgstr "" | 964 | msgstr "" |
4760 | 965 | 965 | ||
4761 | 966 | #. description | 966 | #. description |
4763 | 967 | #: ../jobs/input.txt.in:23 | 967 | #: ../jobs/input.txt.in:22 |
4764 | 968 | msgid "" | 968 | msgid "" |
4765 | 969 | "PURPOSE:\n" | 969 | "PURPOSE:\n" |
4766 | 970 | " This test will test your pointing device\n" | 970 | " This test will test your pointing device\n" |
4767 | @@ -976,7 +976,7 @@ | |||
4768 | 976 | msgstr "" | 976 | msgstr "" |
4769 | 977 | 977 | ||
4770 | 978 | #. description | 978 | #. description |
4772 | 979 | #: ../jobs/input.txt.in:36 | 979 | #: ../jobs/input.txt.in:35 |
4773 | 980 | msgid "" | 980 | msgid "" |
4774 | 981 | "PURPOSE:\n" | 981 | "PURPOSE:\n" |
4775 | 982 | " This test will test your keyboard\n" | 982 | " This test will test your keyboard\n" |
4776 | 983 | 983 | ||
4777 | === modified file 'po/fi.po' | |||
4778 | --- po/fi.po 2013-02-22 16:26:25 +0000 | |||
4779 | +++ po/fi.po 2013-03-07 16:10:38 +0000 | |||
4780 | @@ -14,8 +14,8 @@ | |||
4781 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
4782 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
4783 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
4786 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:32+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:39+0000\n" |
4787 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
4788 | 19 | 19 | ||
4789 | 20 | #. Title of the user interface | 20 | #. Title of the user interface |
4790 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 |
4791 | @@ -1240,7 +1240,7 @@ | |||
4792 | 1240 | msgstr "" | 1240 | msgstr "" |
4793 | 1241 | 1241 | ||
4794 | 1242 | #. description | 1242 | #. description |
4796 | 1243 | #: ../jobs/input.txt.in:23 | 1243 | #: ../jobs/input.txt.in:22 |
4797 | 1244 | msgid "" | 1244 | msgid "" |
4798 | 1245 | "PURPOSE:\n" | 1245 | "PURPOSE:\n" |
4799 | 1246 | " This test will test your pointing device\n" | 1246 | " This test will test your pointing device\n" |
4800 | @@ -1260,7 +1260,7 @@ | |||
4801 | 1260 | " Toimiko osoitinlaite odotetulla tavalla?" | 1260 | " Toimiko osoitinlaite odotetulla tavalla?" |
4802 | 1261 | 1261 | ||
4803 | 1262 | #. description | 1262 | #. description |
4805 | 1263 | #: ../jobs/input.txt.in:36 | 1263 | #: ../jobs/input.txt.in:35 |
4806 | 1264 | msgid "" | 1264 | msgid "" |
4807 | 1265 | "PURPOSE:\n" | 1265 | "PURPOSE:\n" |
4808 | 1266 | " This test will test your keyboard\n" | 1266 | " This test will test your keyboard\n" |
4809 | 1267 | 1267 | ||
4810 | === modified file 'po/fr.po' | |||
4811 | --- po/fr.po 2013-02-22 16:26:25 +0000 | |||
4812 | +++ po/fr.po 2013-03-07 16:10:38 +0000 | |||
4813 | @@ -13,8 +13,8 @@ | |||
4814 | 13 | "MIME-Version: 1.0\n" | 13 | "MIME-Version: 1.0\n" |
4815 | 14 | "Content-Type: text/plain; charset=UTF-8\n" | 14 | "Content-Type: text/plain; charset=UTF-8\n" |
4816 | 15 | "Content-Transfer-Encoding: 8bit\n" | 15 | "Content-Transfer-Encoding: 8bit\n" |
4819 | 16 | "X-Launchpad-Export-Date: 2013-02-15 04:32+0000\n" | 16 | "X-Launchpad-Export-Date: 2013-02-23 04:39+0000\n" |
4820 | 17 | "X-Generator: Launchpad (build 16491)\n" | 17 | "X-Generator: Launchpad (build 16506)\n" |
4821 | 18 | 18 | ||
4822 | 19 | #. Title of the user interface | 19 | #. Title of the user interface |
4823 | 20 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 | 20 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 |
4824 | @@ -1363,7 +1363,7 @@ | |||
4825 | 1363 | msgstr "Joint le journal de débogage de l'installateur s'il existe." | 1363 | msgstr "Joint le journal de débogage de l'installateur s'il existe." |
4826 | 1364 | 1364 | ||
4827 | 1365 | #. description | 1365 | #. description |
4829 | 1366 | #: ../jobs/input.txt.in:23 | 1366 | #: ../jobs/input.txt.in:22 |
4830 | 1367 | msgid "" | 1367 | msgid "" |
4831 | 1368 | "PURPOSE:\n" | 1368 | "PURPOSE:\n" |
4832 | 1369 | " This test will test your pointing device\n" | 1369 | " This test will test your pointing device\n" |
4833 | @@ -1383,7 +1383,7 @@ | |||
4834 | 1383 | " Est-ce que le périphérique de pointage a fonctionné correctement ?" | 1383 | " Est-ce que le périphérique de pointage a fonctionné correctement ?" |
4835 | 1384 | 1384 | ||
4836 | 1385 | #. description | 1385 | #. description |
4838 | 1386 | #: ../jobs/input.txt.in:36 | 1386 | #: ../jobs/input.txt.in:35 |
4839 | 1387 | msgid "" | 1387 | msgid "" |
4840 | 1388 | "PURPOSE:\n" | 1388 | "PURPOSE:\n" |
4841 | 1389 | " This test will test your keyboard\n" | 1389 | " This test will test your keyboard\n" |
4842 | 1390 | 1390 | ||
4843 | === modified file 'po/ga.po' | |||
4844 | --- po/ga.po 2013-02-22 16:26:25 +0000 | |||
4845 | +++ po/ga.po 2013-03-07 16:10:38 +0000 | |||
4846 | @@ -14,8 +14,8 @@ | |||
4847 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
4848 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
4849 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
4852 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:32+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:39+0000\n" |
4853 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
4854 | 19 | 19 | ||
4855 | 20 | #. Title of the user interface | 20 | #. Title of the user interface |
4856 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 |
4857 | @@ -964,7 +964,7 @@ | |||
4858 | 964 | msgstr "" | 964 | msgstr "" |
4859 | 965 | 965 | ||
4860 | 966 | #. description | 966 | #. description |
4862 | 967 | #: ../jobs/input.txt.in:23 | 967 | #: ../jobs/input.txt.in:22 |
4863 | 968 | msgid "" | 968 | msgid "" |
4864 | 969 | "PURPOSE:\n" | 969 | "PURPOSE:\n" |
4865 | 970 | " This test will test your pointing device\n" | 970 | " This test will test your pointing device\n" |
4866 | @@ -976,7 +976,7 @@ | |||
4867 | 976 | msgstr "" | 976 | msgstr "" |
4868 | 977 | 977 | ||
4869 | 978 | #. description | 978 | #. description |
4871 | 979 | #: ../jobs/input.txt.in:36 | 979 | #: ../jobs/input.txt.in:35 |
4872 | 980 | msgid "" | 980 | msgid "" |
4873 | 981 | "PURPOSE:\n" | 981 | "PURPOSE:\n" |
4874 | 982 | " This test will test your keyboard\n" | 982 | " This test will test your keyboard\n" |
4875 | 983 | 983 | ||
4876 | === modified file 'po/gd.po' | |||
4877 | --- po/gd.po 2013-02-22 16:26:25 +0000 | |||
4878 | +++ po/gd.po 2013-03-07 16:10:38 +0000 | |||
4879 | @@ -14,8 +14,8 @@ | |||
4880 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
4881 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
4882 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
4885 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:32+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:39+0000\n" |
4886 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
4887 | 19 | 19 | ||
4888 | 20 | #. Title of the user interface | 20 | #. Title of the user interface |
4889 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 |
4890 | @@ -1295,7 +1295,7 @@ | |||
4891 | 1295 | msgstr "A' ceangal log dì-bhugaich an stàlaichear ma tha e ann." | 1295 | msgstr "A' ceangal log dì-bhugaich an stàlaichear ma tha e ann." |
4892 | 1296 | 1296 | ||
4893 | 1297 | #. description | 1297 | #. description |
4895 | 1298 | #: ../jobs/input.txt.in:23 | 1298 | #: ../jobs/input.txt.in:22 |
4896 | 1299 | msgid "" | 1299 | msgid "" |
4897 | 1300 | "PURPOSE:\n" | 1300 | "PURPOSE:\n" |
4898 | 1301 | " This test will test your pointing device\n" | 1301 | " This test will test your pointing device\n" |
4899 | @@ -1315,7 +1315,7 @@ | |||
4900 | 1315 | " An do dh'obraich an innleachd comharraich mar a bha dùil?" | 1315 | " An do dh'obraich an innleachd comharraich mar a bha dùil?" |
4901 | 1316 | 1316 | ||
4902 | 1317 | #. description | 1317 | #. description |
4904 | 1318 | #: ../jobs/input.txt.in:36 | 1318 | #: ../jobs/input.txt.in:35 |
4905 | 1319 | msgid "" | 1319 | msgid "" |
4906 | 1320 | "PURPOSE:\n" | 1320 | "PURPOSE:\n" |
4907 | 1321 | " This test will test your keyboard\n" | 1321 | " This test will test your keyboard\n" |
4908 | 1322 | 1322 | ||
4909 | === modified file 'po/gl.po' | |||
4910 | --- po/gl.po 2013-02-22 16:26:25 +0000 | |||
4911 | +++ po/gl.po 2013-03-07 16:10:38 +0000 | |||
4912 | @@ -15,8 +15,8 @@ | |||
4913 | 15 | "MIME-Version: 1.0\n" | 15 | "MIME-Version: 1.0\n" |
4914 | 16 | "Content-Type: text/plain; charset=UTF-8\n" | 16 | "Content-Type: text/plain; charset=UTF-8\n" |
4915 | 17 | "Content-Transfer-Encoding: 8bit\n" | 17 | "Content-Transfer-Encoding: 8bit\n" |
4918 | 18 | "X-Launchpad-Export-Date: 2013-02-15 04:32+0000\n" | 18 | "X-Launchpad-Export-Date: 2013-02-23 04:39+0000\n" |
4919 | 19 | "X-Generator: Launchpad (build 16491)\n" | 19 | "X-Generator: Launchpad (build 16506)\n" |
4920 | 20 | 20 | ||
4921 | 21 | #. Title of the user interface | 21 | #. Title of the user interface |
4922 | 22 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 | 22 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 |
4923 | @@ -1285,7 +1285,7 @@ | |||
4924 | 1285 | msgstr "Anexa o rexistro de depuración do instalador se existe." | 1285 | msgstr "Anexa o rexistro de depuración do instalador se existe." |
4925 | 1286 | 1286 | ||
4926 | 1287 | #. description | 1287 | #. description |
4928 | 1288 | #: ../jobs/input.txt.in:23 | 1288 | #: ../jobs/input.txt.in:22 |
4929 | 1289 | msgid "" | 1289 | msgid "" |
4930 | 1290 | "PURPOSE:\n" | 1290 | "PURPOSE:\n" |
4931 | 1291 | " This test will test your pointing device\n" | 1291 | " This test will test your pointing device\n" |
4932 | @@ -1305,7 +1305,7 @@ | |||
4933 | 1305 | " Comportouse o dispositivo de punteiro como se agardaba?" | 1305 | " Comportouse o dispositivo de punteiro como se agardaba?" |
4934 | 1306 | 1306 | ||
4935 | 1307 | #. description | 1307 | #. description |
4937 | 1308 | #: ../jobs/input.txt.in:36 | 1308 | #: ../jobs/input.txt.in:35 |
4938 | 1309 | msgid "" | 1309 | msgid "" |
4939 | 1310 | "PURPOSE:\n" | 1310 | "PURPOSE:\n" |
4940 | 1311 | " This test will test your keyboard\n" | 1311 | " This test will test your keyboard\n" |
4941 | 1312 | 1312 | ||
4942 | === modified file 'po/he.po' | |||
4943 | --- po/he.po 2013-02-22 16:26:25 +0000 | |||
4944 | +++ po/he.po 2013-03-07 16:10:38 +0000 | |||
4945 | @@ -14,8 +14,8 @@ | |||
4946 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
4947 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
4948 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
4951 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:32+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:39+0000\n" |
4952 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
4953 | 19 | 19 | ||
4954 | 20 | #: ../gtk/checkbox-gtk.ui.h:4 | 20 | #: ../gtk/checkbox-gtk.ui.h:4 |
4955 | 21 | msgid "_No" | 21 | msgid "_No" |
4956 | @@ -1095,7 +1095,7 @@ | |||
4957 | 1095 | msgstr "" | 1095 | msgstr "" |
4958 | 1096 | 1096 | ||
4959 | 1097 | #. description | 1097 | #. description |
4961 | 1098 | #: ../jobs/input.txt.in:23 | 1098 | #: ../jobs/input.txt.in:22 |
4962 | 1099 | msgid "" | 1099 | msgid "" |
4963 | 1100 | "PURPOSE:\n" | 1100 | "PURPOSE:\n" |
4964 | 1101 | " This test will test your pointing device\n" | 1101 | " This test will test your pointing device\n" |
4965 | @@ -1107,7 +1107,7 @@ | |||
4966 | 1107 | msgstr "" | 1107 | msgstr "" |
4967 | 1108 | 1108 | ||
4968 | 1109 | #. description | 1109 | #. description |
4970 | 1110 | #: ../jobs/input.txt.in:36 | 1110 | #: ../jobs/input.txt.in:35 |
4971 | 1111 | msgid "" | 1111 | msgid "" |
4972 | 1112 | "PURPOSE:\n" | 1112 | "PURPOSE:\n" |
4973 | 1113 | " This test will test your keyboard\n" | 1113 | " This test will test your keyboard\n" |
4974 | 1114 | 1114 | ||
4975 | === modified file 'po/hi.po' | |||
4976 | --- po/hi.po 2013-02-22 16:26:25 +0000 | |||
4977 | +++ po/hi.po 2013-03-07 16:10:38 +0000 | |||
4978 | @@ -14,8 +14,8 @@ | |||
4979 | 14 | "MIME-Version: 1.0\n" | 14 | "MIME-Version: 1.0\n" |
4980 | 15 | "Content-Type: text/plain; charset=UTF-8\n" | 15 | "Content-Type: text/plain; charset=UTF-8\n" |
4981 | 16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
4984 | 17 | "X-Launchpad-Export-Date: 2013-02-15 04:32+0000\n" | 17 | "X-Launchpad-Export-Date: 2013-02-23 04:39+0000\n" |
4985 | 18 | "X-Generator: Launchpad (build 16491)\n" | 18 | "X-Generator: Launchpad (build 16506)\n" |
4986 | 19 | 19 | ||
4987 | 20 | #. Title of the user interface | 20 | #. Title of the user interface |
4988 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 | 21 | #: ../gtk/checkbox-gtk.ui.h:1 ../qt/checkbox-qt.desktop.in.h:1 |
4989 | @@ -966,7 +966,7 @@ | |||
4990 | 966 | msgstr "" | 966 | msgstr "" |
4991 | 967 | 967 | ||
4992 | 968 | #. description | 968 | #. description |
4994 | 969 | #: ../jobs/input.txt.in:23 | 969 | #: ../jobs/input.txt.in:22 |
4995 | 970 | msgid "" | 970 | msgid "" |
4996 | 971 | "PURPOSE:\n" | 971 | "PURPOSE:\n" |
4997 | 972 | " This test will test your pointing device\n" | 972 | " This test will test your pointing device\n" |
4998 | @@ -978,7 +978,7 @@ | |||
4999 | 978 | msgstr "" | 978 | msgstr "" |
5000 | 979 | 979 |
The diff has been truncated for viewing.
Thanks, merged.