~launchpad-pqm/launchpad/devel

14050.3.1 by Jeroen Vermeulen
Lint.
1
Hardware Database Device Tables
2
===============================
6130.3.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 1
3
4
These tables represent devices and complete systems in the database. They
6130.3.3 by Abel Deuring
implemented reviewer's comments
5
allow look up of devices by their bus IDs and by their human readable
6
vendor and product names. They also link devices to drivers.
6130.3.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 1
7
14050.3.1 by Jeroen Vermeulen
Lint.
8
HWVendorName
9
------------
6130.3.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 1
10
11
HWVendorName is a simple list of vendor names. A new entry is created by
6130.3.3 by Abel Deuring
implemented reviewer's comments
12
IHWVendorNameSet.create().
6130.3.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 1
13
11692.6.2 by Curtis Hovey
Use deglober to fixing simple glob imports in doctests.
14
    >>> from lp.hardwaredb.interfaces.hwdb import IHWVendorNameSet
6130.3.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 1
15
    >>> vendor_name_set = getUtility(IHWVendorNameSet)
16
    >>> intel_name = vendor_name_set.create(name='Intel')
17
    >>> print intel_name.name
18
    Intel
19
20
Each name in the table must be unique. The attempt to create a second
6130.3.3 by Abel Deuring
implemented reviewer's comments
21
row with the same name raises an IntegrityError error.
6130.3.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 1
22
5821.5.12 by James Henstridge
Fix hwdb-device-tables.txt test.
23
    >>> from storm.store import Store
24
    >>> store = Store.of(intel_name)
11666.3.5 by Curtis Hovey
Import layers from canonical.testing.layers.
25
    >>> from canonical.testing.layers import LaunchpadZopelessLayer
6130.3.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 1
26
    >>> LaunchpadZopelessLayer.txn.commit()
27
    >>> vendor_name_set.create('Intel')
5821.5.12 by James Henstridge
Fix hwdb-device-tables.txt test.
28
    <HWVendorName ...
29
    >>> store.flush()
6130.3.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 1
30
    Traceback (most recent call last):
31
    ...
5821.6.7 by James Henstridge
merge from rocketfuel
32
    IntegrityError: duplicate key... violates unique
6440.4.1 by Abel Deuring
case-insensitive uniqueness constraint for names in HWVendorName; case-insensitive lookup of names in HWVendorName
33
    constraint "hwvendorname__lc_vendor_name__idx"
6456.2.5 by Abel Deuring
RF merge; conflicts in hwdb-device-tables.txt resolved
34
    <BLANKLINE>
6440.4.1 by Abel Deuring
case-insensitive uniqueness constraint for names in HWVendorName; case-insensitive lookup of names in HWVendorName
35
    >>> LaunchpadZopelessLayer.txn.abort()
36
37
The database checks the uniqueness of the lower-case name, hence we
38
cannot insert another name like "INTEL" or "intel".
39
40
    >>> vendor_name_set.create('INTEL')
6456.2.5 by Abel Deuring
RF merge; conflicts in hwdb-device-tables.txt resolved
41
    <HWVendorName ...
42
    >>> store.flush()
6440.4.1 by Abel Deuring
case-insensitive uniqueness constraint for names in HWVendorName; case-insensitive lookup of names in HWVendorName
43
    Traceback (most recent call last):
44
    ...
6456.2.5 by Abel Deuring
RF merge; conflicts in hwdb-device-tables.txt resolved
45
    IntegrityError: duplicate key... violates unique
6440.4.1 by Abel Deuring
case-insensitive uniqueness constraint for names in HWVendorName; case-insensitive lookup of names in HWVendorName
46
    constraint "hwvendorname__lc_vendor_name__idx"
6456.2.5 by Abel Deuring
RF merge; conflicts in hwdb-device-tables.txt resolved
47
    <BLANKLINE>
6440.4.1 by Abel Deuring
case-insensitive uniqueness constraint for names in HWVendorName; case-insensitive lookup of names in HWVendorName
48
    >>> LaunchpadZopelessLayer.txn.abort()
49
50
    >>> vendor_name_set.create('intel')
6456.2.5 by Abel Deuring
RF merge; conflicts in hwdb-device-tables.txt resolved
51
    <HWVendorName ...
52
    >>> store.flush()
6440.4.1 by Abel Deuring
case-insensitive uniqueness constraint for names in HWVendorName; case-insensitive lookup of names in HWVendorName
53
    Traceback (most recent call last):
54
    ...
6456.2.5 by Abel Deuring
RF merge; conflicts in hwdb-device-tables.txt resolved
55
    IntegrityError: duplicate key... violates unique
6440.4.1 by Abel Deuring
case-insensitive uniqueness constraint for names in HWVendorName; case-insensitive lookup of names in HWVendorName
56
    constraint "hwvendorname__lc_vendor_name__idx"
6456.2.5 by Abel Deuring
RF merge; conflicts in hwdb-device-tables.txt resolved
57
    <BLANKLINE>
6440.4.1 by Abel Deuring
case-insensitive uniqueness constraint for names in HWVendorName; case-insensitive lookup of names in HWVendorName
58
    >>> LaunchpadZopelessLayer.txn.abort()
59
60
The lower-case uniqueness constraint works for latin characters with
61
diacritical marks too...
62
63
    >>> a_umlaut_upper = u'\N{LATIN CAPITAL LETTER A WITH DIAERESIS}'
64
    >>> a_umlaut_lower = u'\N{LATIN SMALL LETTER A WITH DIAERESIS}'
65
    >>> a_umlaut_name = vendor_name_set.create(name=a_umlaut_upper)
66
    >>> LaunchpadZopelessLayer.txn.commit()
67
    >>> print repr(a_umlaut_name.name)
68
    u'\xc4'
69
6456.2.5 by Abel Deuring
RF merge; conflicts in hwdb-device-tables.txt resolved
70
    >>> vendor_name_set.create(name=a_umlaut_lower)
71
    <HWVendorName ...
72
    >>> store.flush()
73
    Traceback (most recent call last):
74
    ...
75
    IntegrityError: duplicate key... violates unique
76
    constraint "hwvendorname__lc_vendor_name__idx"
77
    <BLANKLINE>
6440.4.1 by Abel Deuring
case-insensitive uniqueness constraint for names in HWVendorName; case-insensitive lookup of names in HWVendorName
78
    >>> LaunchpadZopelessLayer.txn.abort()
79
80
...as well as for Cyrillic characters...
81
82
    >>> cyrillic_de_upper = u'\N{CYRILLIC CAPITAL LETTER DE}'
83
    >>> cyrillic_de_lower = u'\N{CYRILLIC SMALL LETTER DE}'
84
    >>> cyrillic_de_name = vendor_name_set.create(name=cyrillic_de_upper)
85
    >>> print repr(cyrillic_de_name.name)
86
    u'\u0414'
87
6456.2.5 by Abel Deuring
RF merge; conflicts in hwdb-device-tables.txt resolved
88
    >>> vendor_name_set.create(name=cyrillic_de_lower)
89
    <HWVendorName ...
90
    >>> store.flush()
91
    Traceback (most recent call last):
92
    ...
93
    IntegrityError: duplicate key... violates unique
94
    constraint "hwvendorname__lc_vendor_name__idx"
95
    <BLANKLINE>
6440.4.1 by Abel Deuring
case-insensitive uniqueness constraint for names in HWVendorName; case-insensitive lookup of names in HWVendorName
96
    >>> LaunchpadZopelessLayer.txn.abort()
97
98
...and Greek characters.
99
100
    >>> alpha_upper = u'\N{GREEK CAPITAL LETTER ALPHA}'
101
    >>> alpha_lower = u'\N{GREEK SMALL LETTER ALPHA}'
102
    >>> cyrillic_de_name = vendor_name_set.create(name=alpha_upper)
103
    >>> print repr(cyrillic_de_name.name)
104
    u'\u0391'
105
6456.2.5 by Abel Deuring
RF merge; conflicts in hwdb-device-tables.txt resolved
106
    >>> vendor_name_set.create(name=alpha_lower)
107
    <HWVendorName ...
108
    >>> store.flush()
109
    Traceback (most recent call last):
110
    ...
111
    IntegrityError: duplicate key... violates unique
112
    constraint "hwvendorname__lc_vendor_name__idx"
5821.5.12 by James Henstridge
Fix hwdb-device-tables.txt test.
113
    <BLANKLINE>
6130.3.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 1
114
    >>> LaunchpadZopelessLayer.txn.abort()
115
6407.1.5 by Abel Deuring
implemented reviewer's comments
116
Existing IHWVendorName records are retrieved by IHWVendorName.getByName().
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
117
118
    >>> intel_name = vendor_name_set.getByName('Intel')
119
    >>> print intel_name.name
120
    Intel
121
6440.4.1 by Abel Deuring
case-insensitive uniqueness constraint for names in HWVendorName; case-insensitive lookup of names in HWVendorName
122
The capitalization of the name does not metter.
123
124
    >>> intel_name = vendor_name_set.getByName('INTEL')
125
    >>> print intel_name.name
126
    Intel
127
128
    >>> intel_name = vendor_name_set.getByName('intel')
129
    >>> print intel_name.name
130
    Intel
131
132
    >>> umlaut_name = vendor_name_set.getByName(
133
    ...     u'\N{LATIN CAPITAL LETTER A WITH DIAERESIS}')
134
    >>> print repr(umlaut_name.name)
135
    u'\xc4'
136
137
    >>> umlaut_name = vendor_name_set.getByName(
138
    ...     u'\N{LATIN SMALL LETTER A WITH DIAERESIS}')
139
    >>> print repr(umlaut_name.name)
140
    u'\xc4'
141
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
142
If no record matching the given name exists, IHWVendorName.getByName()
143
returns None.
144
145
    >>> print vendor_name_set.getByName('Babbage Computers')
146
    None
147
148
14050.3.1 by Jeroen Vermeulen
Lint.
149
HWVendorID
150
----------
6130.3.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 1
151
152
HWVendorID associates a bus, as enumerated by HWBus, with a bus-specific
153
vendor ID and a vendor name. We store the IDs as a string, because not all
154
all busses use numeric IDs. Numbers are represented as strings with
155
hexadecimal digits, prepended by '0x'.
156
11692.6.3 by Curtis Hovey
Fixed tests with multiple imports on the line.
157
    >>> from lp.hardwaredb.interfaces.hwdb import HWBus, IHWVendorIDSet
6130.3.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 1
158
    >>> vendor_id_set = getUtility(IHWVendorIDSet)
159
    >>> intel_pci_id = vendor_id_set.create(bus=HWBus.PCI,
6407.1.5 by Abel Deuring
implemented reviewer's comments
160
    ...                                     vendor_id='0x8086',
161
    ...                                     vendor_name=intel_name)
6130.3.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 1
162
    >>> print intel_pci_id.bus.title, intel_pci_id.vendor_id_for_bus
163
    PCI 0x8086
164
    >>> print intel_pci_id.vendor_name.name
165
    Intel
166
167
The tuple (bus, vendor id, vendor name) must be unique.
168
169
    >>> LaunchpadZopelessLayer.txn.commit()
170
    >>> vendor_id_set.create(bus=HWBus.PCI,
171
    ...                      vendor_id='0x8086',
172
    ...                      vendor_name=intel_name)
5821.5.12 by James Henstridge
Fix hwdb-device-tables.txt test.
173
    <HWVendorID ...
174
    >>> store.flush()
6130.3.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 1
175
    Traceback (most recent call last):
176
    ...
5821.6.7 by James Henstridge
merge from rocketfuel
177
    IntegrityError: duplicate key... violates unique
6130.3.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 1
178
    constraint "hwvendorid__bus_vendor_id__vendor_name__key"
5821.5.12 by James Henstridge
Fix hwdb-device-tables.txt test.
179
    <BLANKLINE>
6130.3.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 1
180
    >>> LaunchpadZopelessLayer.txn.abort()
181
182
We store the (bus specific) vendor ID as a string, but several busses
183
have stricter constraints for their vendor ID. The PCI and USB busses use
184
16 bit integers, the IEEE1394 bus uses 24 bit integers, the SCSI bus
185
uses ASCII strings with exactly 8 characters. The constructor of
186
HWVendorID ensures that the vendor IDs match the bus-specific format.
187
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
188
USB, PCI and PCCard IDs are represented as strings with a four-digit
189
hexadecimal number, prefixed by '0x'; the digits a..f must be lower
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
190
cases characters. Other ID values raise a ParameterError.
6130.3.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 1
191
192
The characters a..f are accepted as digits.
193
194
    >>> another_pci_vendor_id = vendor_id_set.create(bus=HWBus.PCI,
6407.1.5 by Abel Deuring
implemented reviewer's comments
195
    ...                                              vendor_id='0x10ae',
196
    ...                                              vendor_name=intel_name)
6130.3.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 1
197
    >>> print another_pci_vendor_id.bus.title
198
    PCI
199
    >>> print another_pci_vendor_id.vendor_id_for_bus
200
    0x10ae
201
    >>> print another_pci_vendor_id.vendor_name.name
202
    Intel
203
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
204
    >>> another_pci_vendor_id = vendor_id_set.create(bus=HWBus.PCCARD,
6407.1.5 by Abel Deuring
implemented reviewer's comments
205
    ...                                              vendor_id='0x10ae',
206
    ...                                              vendor_name=intel_name)
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
207
    >>> print another_pci_vendor_id.bus.title
6407.1.2 by Abel Deuring
updated hwdb-device-tables.txt to match the changed title of HWBus.PCCARD
208
    PC Card (32 bit)
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
209
    >>> print another_pci_vendor_id.vendor_id_for_bus
210
    0x10ae
211
    >>> print another_pci_vendor_id.vendor_name.name
212
    Intel
213
6130.3.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 1
214
    >>> another_usb_vendor_id = vendor_id_set.create(bus=HWBus.USB,
6407.1.5 by Abel Deuring
implemented reviewer's comments
215
    ...                                              vendor_id='0x10ae',
216
    ...                                              vendor_name=intel_name)
6130.3.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 1
217
    >>> print another_usb_vendor_id.bus.title
218
    USB
219
    >>> print another_usb_vendor_id.vendor_id_for_bus
220
    0x10ae
221
    >>> print another_usb_vendor_id.vendor_name.name
222
    Intel
223
224
A..F is rejected.
225
226
    >>> vendor_id_set.create(bus=HWBus.PCI,
227
    ...                      vendor_id='0x10AE',
228
    ...                      vendor_name=intel_name)
229
    Traceback (most recent call last):
230
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
231
    ParameterError: '0x10AE' is not a valid vendor ID for PCI
5821.5.12 by James Henstridge
Fix hwdb-device-tables.txt test.
232
    >>> from storm.tracer import debug; debug(True)
233
    >>> store.flush()
234
    >>> debug(False)
6130.3.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 1
235
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
236
    >>> vendor_id_set.create(bus=HWBus.PCCARD,
237
    ...                      vendor_id='0x10AE',
238
    ...                      vendor_name=intel_name)
239
    Traceback (most recent call last):
240
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
241
    ParameterError: '0x10AE' is not a valid vendor ID for PC Card (32 bit)
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
242
6130.3.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 1
243
    >>> vendor_id_set.create(bus=HWBus.USB,
244
    ...                      vendor_id='0x10AE',
245
    ...                      vendor_name=intel_name)
246
    Traceback (most recent call last):
247
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
248
    ParameterError: '0x10AE' is not a valid vendor ID for USB
6130.3.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 1
249
250
The ID must have the prefix "0x".
251
252
    >>> vendor_id_set.create(bus=HWBus.PCI,
253
    ...                      vendor_id='8086',
254
    ...                      vendor_name=intel_name)
255
    Traceback (most recent call last):
256
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
257
    ParameterError: '8086' is not a valid vendor ID for PCI
6130.3.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 1
258
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
259
    >>> vendor_id_set.create(bus=HWBus.PCCARD,
260
    ...                      vendor_id='8086',
261
    ...                      vendor_name=intel_name)
262
    Traceback (most recent call last):
263
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
264
    ParameterError: '8086' is not a valid vendor ID for PC Card (32 bit)
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
265
6130.3.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 1
266
    >>> vendor_id_set.create(bus=HWBus.USB,
267
    ...                      vendor_id='8086',
268
    ...                      vendor_name=intel_name)
269
    Traceback (most recent call last):
270
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
271
    ParameterError: '8086' is not a valid vendor ID for USB
6130.3.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 1
272
273
The number must have four digits.
274
275
    >>> vendor_id_set.create(bus=HWBus.PCI,
276
    ...                      vendor_id='0x123',
277
    ...                      vendor_name=intel_name)
278
    Traceback (most recent call last):
279
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
280
    ParameterError: '0x123' is not a valid vendor ID for PCI
6130.3.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 1
281
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
282
    >>> vendor_id_set.create(bus=HWBus.PCCARD,
283
    ...                      vendor_id='0x123',
284
    ...                      vendor_name=intel_name)
285
    Traceback (most recent call last):
286
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
287
    ParameterError: '0x123' is not a valid vendor ID for PC Card (32 bit)
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
288
6130.3.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 1
289
    >>> vendor_id_set.create(bus=HWBus.USB,
290
    ...                      vendor_id='0x123',
291
    ...                      vendor_name=intel_name)
292
    Traceback (most recent call last):
293
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
294
    ParameterError: '0x123' is not a valid vendor ID for USB
6130.3.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 1
295
296
    >>> vendor_id_set.create(bus=HWBus.PCI,
297
    ...                      vendor_id='0x12345',
298
    ...                      vendor_name=intel_name)
299
    Traceback (most recent call last):
300
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
301
    ParameterError: '0x12345' is not a valid vendor ID for PCI
6130.3.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 1
302
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
303
    >>> vendor_id_set.create(bus=HWBus.PCCARD,
304
    ...                      vendor_id='0x12345',
305
    ...                      vendor_name=intel_name)
306
    Traceback (most recent call last):
307
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
308
    ParameterError: '0x12345' is not a valid vendor ID for PC Card (32 bit)
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
309
6130.3.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 1
310
    >>> vendor_id_set.create(bus=HWBus.USB,
311
    ...                      vendor_id='0x12345',
312
    ...                      vendor_name=intel_name)
313
    Traceback (most recent call last):
314
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
315
    ParameterError: '0x12345' is not a valid vendor ID for USB
6130.3.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 1
316
317
Only hex digits are allowed.
318
319
    >>> vendor_id_set.create(bus=HWBus.PCI,
320
    ...                      vendor_id='0xblah',
321
    ...                      vendor_name=intel_name)
322
    Traceback (most recent call last):
323
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
324
    ParameterError: '0xblah' is not a valid vendor ID for PCI
6130.3.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 1
325
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
326
    >>> vendor_id_set.create(bus=HWBus.PCCARD,
327
    ...                      vendor_id='0xblah',
328
    ...                      vendor_name=intel_name)
329
    Traceback (most recent call last):
330
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
331
    ParameterError: '0xblah' is not a valid vendor ID for PC Card (32 bit)
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
332
6130.3.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 1
333
    >>> vendor_id_set.create(bus=HWBus.USB,
334
    ...                      vendor_id='0xblah',
335
    ...                      vendor_name=intel_name)
336
    Traceback (most recent call last):
337
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
338
    ParameterError: '0xblah' is not a valid vendor ID for USB
6130.3.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 1
339
340
IEEE1394 IDs are represented as strings with a six-digit hexadecimal
341
number, prefixed by '0x'; the digits a..f must be lower cases characters.
342
Other ID values raise a value error.
343
344
    >>> vendor_id_1394 = vendor_id_set.create(bus=HWBus.IEEE1394,
345
    ...                                       vendor_id='0x0010e0',
346
    ...                                       vendor_name=intel_name)
347
    >>> print vendor_id_1394.bus.title
348
    IEEE1394
349
    >>> print vendor_id_1394.vendor_id_for_bus
350
    0x0010e0
351
    >>> print vendor_id_1394.vendor_name.name
352
    Intel
353
354
A..F is rejected.
355
356
    >>> vendor_id_set.create(bus=HWBus.IEEE1394,
357
    ...                      vendor_id='0x0010E0',
358
    ...                      vendor_name=intel_name)
359
    Traceback (most recent call last):
360
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
361
    ParameterError: '0x0010E0' is not a valid vendor ID for IEEE1394
6130.3.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 1
362
363
The ID must have the prefix "0x".
364
365
    >>> vendor_id_set.create(bus=HWBus.IEEE1394,
366
    ...                      vendor_id='0010E0',
367
    ...                      vendor_name=intel_name)
368
    Traceback (most recent call last):
369
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
370
    ParameterError: '0010E0' is not a valid vendor ID for IEEE1394
6130.3.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 1
371
372
The number must have six digits.
373
374
    >>> vendor_id_set.create(bus=HWBus.IEEE1394,
375
    ...                      vendor_id='0x12345',
376
    ...                      vendor_name=intel_name)
377
    Traceback (most recent call last):
378
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
379
    ParameterError: '0x12345' is not a valid vendor ID for IEEE1394
6130.3.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 1
380
381
    >>> vendor_id_set.create(bus=HWBus.IEEE1394,
382
    ...                      vendor_id='0x1234567',
383
    ...                      vendor_name=intel_name)
384
    Traceback (most recent call last):
385
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
386
    ParameterError: '0x1234567' is not a valid vendor ID for IEEE1394
6130.3.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 1
387
388
Only hex digits are allowed.
389
390
    >>> vendor_id_set.create(bus=HWBus.IEEE1394,
391
    ...                      vendor_id='0xfoobar',
392
    ...                      vendor_name=intel_name)
393
    Traceback (most recent call last):
394
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
395
    ParameterError: '0xfoobar' is not a valid vendor ID for IEEE1394
6130.3.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 1
396
397
SCSI vendor IDs are ASCII strings with exactly eight characters.
398
399
    >>> intel_scsi_id = vendor_id_set.create(bus=HWBus.SCSI,
400
    ...                                      vendor_id='INTEL   ',
401
    ...                                      vendor_name=intel_name)
402
    >>> print intel_scsi_id.bus.title
403
    SCSI
404
    >>> intel_scsi_id.vendor_id_for_bus
405
    u'INTEL   '
406
    >>> print intel_scsi_id.vendor_name.name
407
    Intel
408
409
Strings with less than eight characters are not allowed as SCSI vendor IDs...
410
411
    >>> vendor_id_set.create(bus=HWBus.SCSI,
412
    ...                      vendor_id='1234567',
413
    ...                      vendor_name=intel_name)
414
    Traceback (most recent call last):
415
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
416
    ParameterError: '1234567' is not a valid vendor ID for SCSI
6130.3.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 1
417
418
...as well as strings with more than eight characters.
419
420
    >>> vendor_id_set.create(bus=HWBus.SCSI,
421
    ...                      vendor_id='123456789',
422
    ...                      vendor_name=intel_name)
423
    Traceback (most recent call last):
424
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
425
    ParameterError: '123456789' is not a valid vendor ID for SCSI
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
426
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
427
HWVendorIDSet.getByBusAndVendorID() is used to look up a HWVendorID record.
428
429
    >>> vendor_id = vendor_id_set.getByBusAndVendorID(bus=HWBus.PCI,
430
    ...                                               vendor_id='0x8086')
431
    >>> print vendor_id.bus.title
432
    PCI
433
    >>> print vendor_id.vendor_name.name
434
    Intel
435
6407.1.5 by Abel Deuring
implemented reviewer's comments
436
If no record exists for the given bus and vendor ID,
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
437
HWVendorIDSet.getByBusAndVendorID() returns None.
438
6407.1.5 by Abel Deuring
implemented reviewer's comments
439
    >>> vendor_id = vendor_id_set.getByBusAndVendorID(bus=HWBus.PCI,
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
440
    ...                                               vendor_id='0xffff')
441
    >>> print vendor_id
442
    None
443
444
HWVendorIDSet.getByBusAndVendorID() performs the same validity tests of
6407.1.5 by Abel Deuring
implemented reviewer's comments
445
the vendor ID as HWVendorSet.create(): The vendor ID passed to
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
446
HWVendorIDSet.getByBusAndVendorID() must be a valid ID for the given bus.
447
448
    >>> vendor_id_set.getByBusAndVendorID(bus=HWBus.PCI, vendor_id='8086')
449
    Traceback (most recent call last):
450
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
451
    ParameterError: '8086' is not a valid vendor ID for PCI
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
452
7553.1.1 by Abel Deuring
webservice API for IHWVendorID
453
HWVendorIDSet.get() returns the HWVendorID record with the given ID...
454
455
    >>> vendor_id = vendor_id_set.get(1)
456
    >>> print vendor_id.bus.name, vendor_id.vendor_id_for_bus
457
    SYSTEM MSI
458
459
...or None, if no such record exists.
460
461
    >>> print vendor_id_set.get(1000000)
462
    None
463
464
HWVendorIDSet.idsForBus() returns all known HWVendorIDs for a given bus.
465
466
    >>> for vendor_id in vendor_id_set.idsForBus(HWBus.PCI):
467
    ...     print vendor_id.bus.name, vendor_id.vendor_id_for_bus
468
    PCI 0x10ae
469
    PCI 0x10de
470
    PCI 0x8086
471
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
472
14050.3.1 by Jeroen Vermeulen
Lint.
473
HWDevice
474
--------
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
475
476
A HWDevice instance stores core data about a hardware device: The bus
477
it can connect to, the vendor ID, the product ID, the human readable
478
product name, variant (see below), and the number of submissions with
479
a device.
480
481
Aside from "real" devices like keyboards, mice, hard disks, PCI cards,
482
i.e., "thingies" one can connect to and remove from a computer, we also
483
store data about "systems" (computers) and "components" in the HWDevice
6130.11.1 by Abel Deuring
implemented reviewer's comments
484
table. A component is a part that is "permanently built" into a system,
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
485
like a hard disk controller that is soldered onto the main board.
486
487
A new device record is created by IHWDeviceSet.create.
488
11692.6.2 by Curtis Hovey
Use deglober to fixing simple glob imports in doctests.
489
    >>> from lp.hardwaredb.interfaces.hwdb import IHWDeviceSet
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
490
    >>> device_set = getUtility(IHWDeviceSet)
491
    >>> product_name='82801GBM/GHM (ICH7 Family) USB2 EHCI Controller'
492
    >>> usb_controller = device_set.create(bus=HWBus.PCI,
493
    ...                                    vendor_id='0x8086',
494
    ...                                    product_id='0x27cc',
495
    ...                                    product_name=product_name)
496
497
Bus and vendor ID are not directly stored as HWDevice attributes; we can
7353.2.1 by Abel Deuring
Webservice API for IHWDevice
498
access them, as well as the vendor name, either via the attribute
499
bus_vendor, which references HWVendorID...
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
500
501
    >>> print usb_controller.bus_vendor.bus.title
502
    PCI
503
    >>> print usb_controller.bus_vendor.vendor_id_for_bus
504
    0x8086
505
    >>> print usb_controller.bus_vendor.vendor_name.name
506
    Intel
507
7353.2.1 by Abel Deuring
Webservice API for IHWDevice
508
...or via the (read-only) HWDevice properties bus, vendor_id, vendor_name.
509
510
    >>> print usb_controller.bus.title
511
    PCI
512
    >>> print usb_controller.vendor_id
513
    0x8086
514
    >>> print usb_controller.vendor_name
515
    Intel
516
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
517
Other attributes stored in HWDevice are the product ID, the product name,
518
the product variant and submissions. submissions is a counter of the
519
number of submissions with this device.
520
521
    >>> print usb_controller.bus_product_id
522
    0x27cc
523
    >>> print usb_controller.name
524
    82801GBM/GHM (ICH7 Family) USB2 EHCI Controller
525
    >>> print usb_controller.variant
526
    None
527
    >>> print usb_controller.submissions
528
    0
529
530
Like vendor IDs, product IDs of some busses have certain constraints.
531
USB and PCI product IDs are 16 bit integers; SCSI IDs are strings
532
with 16 characters. (Note that the IEEE1394 does _not_ define a product
533
ID.)
534
6407.1.5 by Abel Deuring
implemented reviewer's comments
535
USB, PCI and PCCard IDs are represented as strings with a four-digit
536
hexadecimal number, prefixed by '0x'; the digits a..f must be lower
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
537
cases characters. Other ID values raise a ParameterError.
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
538
539
    >>> another_pci_product = device_set.create(bus=HWBus.PCI,
540
    ...                                         vendor_id='0x8086',
541
    ...                                         product_id='0xabcd',
542
    ...                                         product_name='A PCI card')
543
    >>> print another_pci_product.bus_product_id
544
    0xabcd
545
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
546
    >>> another_pci_product = device_set.create(bus=HWBus.PCCARD,
547
    ...                                         vendor_id='0x8086',
548
    ...                                         product_id='0xabcd',
549
    ...                                         product_name='A PC Card')
550
    >>> print another_pci_product.bus_product_id
551
    0xabcd
552
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
553
    >>> another_usb_product = device_set.create(bus=HWBus.USB,
554
    ...                                         vendor_id='0x8086',
555
    ...                                         product_id='0xabcd',
556
    ...                                         product_name='A USB device')
557
    >>> print another_usb_product.bus_product_id
558
    0xabcd
559
560
A..F is rejected.
561
562
    >>> device_set.create(bus=HWBus.PCI,
563
    ...                   vendor_id='0x8086',
564
    ...                   product_id='0xABCD',
565
    ...                   product_name='A PCI card')
566
    Traceback (most recent call last):
567
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
568
    ParameterError: '0xABCD' is not a valid product ID for PCI
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
569
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
570
    >>> device_set.create(bus=HWBus.PCCARD,
571
    ...                   vendor_id='0x8086',
572
    ...                   product_id='0xABCD',
573
    ...                   product_name='A PC Card')
574
    Traceback (most recent call last):
575
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
576
    ParameterError: '0xABCD' is not a valid product ID for PC Card (32 bit)
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
577
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
578
    >>> device_set.create(bus=HWBus.USB,
579
    ...                   vendor_id='0x8086',
580
    ...                   product_id='0xABCD',
581
    ...                   product_name='A USB device')
582
    Traceback (most recent call last):
583
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
584
    ParameterError: '0xABCD' is not a valid product ID for USB
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
585
586
The ID must have the prefix "0x".
587
588
    >>> device_set.create(bus=HWBus.PCI,
589
    ...                   vendor_id='0x8086',
590
    ...                   product_id='1234',
591
    ...                   product_name='A PCI card')
592
    Traceback (most recent call last):
593
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
594
    ParameterError: '1234' is not a valid product ID for PCI
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
595
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
596
    >>> device_set.create(bus=HWBus.PCCARD,
597
    ...                   vendor_id='0x8086',
598
    ...                   product_id='1234',
599
    ...                   product_name='A PC Card')
600
    Traceback (most recent call last):
601
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
602
    ParameterError: '1234' is not a valid product ID for PC Card (32 bit)
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
603
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
604
    >>> device_set.create(bus=HWBus.USB,
605
    ...                   vendor_id='0x8086',
606
    ...                   product_id='1234',
607
    ...                   product_name='A USB device')
608
    Traceback (most recent call last):
609
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
610
    ParameterError: '1234' is not a valid product ID for USB
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
611
612
The number must have four digits.
613
614
    >>> device_set.create(bus=HWBus.PCI,
615
    ...                   vendor_id='0x8086',
616
    ...                   product_id='0x123',
617
    ...                   product_name='A PCI card')
618
    Traceback (most recent call last):
619
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
620
    ParameterError: '0x123' is not a valid product ID for PCI
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
621
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
622
    >>> device_set.create(bus=HWBus.PCCARD,
623
    ...                   vendor_id='0x8086',
624
    ...                   product_id='0x123',
625
    ...                   product_name='A PC Card')
626
    Traceback (most recent call last):
627
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
628
    ParameterError: '0x123' is not a valid product ID for PC Card (32 bit)
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
629
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
630
    >>> device_set.create(bus=HWBus.USB,
631
    ...                   vendor_id='0x8086',
632
    ...                   product_id='0x123',
633
    ...                   product_name='A USB device')
634
    Traceback (most recent call last):
635
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
636
    ParameterError: '0x123' is not a valid product ID for USB
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
637
638
    >>> device_set.create(bus=HWBus.PCI,
639
    ...                   vendor_id='0x8086',
640
    ...                   product_id='0x12345',
641
    ...                   product_name='A PCI card')
642
    Traceback (most recent call last):
643
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
644
    ParameterError: '0x12345' is not a valid product ID for PCI
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
645
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
646
    >>> device_set.create(bus=HWBus.PCCARD,
647
    ...                   vendor_id='0x8086',
648
    ...                   product_id='0x12345',
649
    ...                   product_name='A PC Card')
650
    Traceback (most recent call last):
651
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
652
    ParameterError: '0x12345' is not a valid product ID for PC Card (32 bit)
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
653
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
654
    >>> device_set.create(bus=HWBus.USB,
655
    ...                   vendor_id='0x8086',
656
    ...                   product_id='0x12345',
657
    ...                   product_name='A USB device')
658
    Traceback (most recent call last):
659
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
660
    ParameterError: '0x12345' is not a valid product ID for USB
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
661
662
Only hex digits are allowed.
663
664
    >>> device_set.create(bus=HWBus.PCI,
665
    ...                   vendor_id='0x8086',
666
    ...                   product_id='0xblah',
667
    ...                   product_name='A PCI card')
668
    Traceback (most recent call last):
669
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
670
    ParameterError: '0xblah' is not a valid product ID for PCI
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
671
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
672
    >>> device_set.create(bus=HWBus.PCCARD,
673
    ...                   vendor_id='0x8086',
674
    ...                   product_id='0xblah',
675
    ...                   product_name='A PC Card')
676
    Traceback (most recent call last):
677
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
678
    ParameterError: '0xblah' is not a valid product ID for PC Card (32 bit)
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
679
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
680
    >>> device_set.create(bus=HWBus.USB,
681
    ...                   vendor_id='0x8086',
682
    ...                   product_id='0xblah',
683
    ...                   product_name='A USB device')
684
    Traceback (most recent call last):
685
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
686
    ParameterError: '0xblah' is not a valid product ID for USB
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
687
688
SCSI product IDs are ASCII strings with 16 characters.
689
690
    >>> scsi_device = device_set.create(bus=HWBus.SCSI,
691
    ...                                 vendor_id='INTEL   ',
692
    ...                                 product_id='12345678901234  ',
693
    ...                                 product_name='A SCSI device')
694
    >>> scsi_device.bus_product_id
695
    u'12345678901234  '
696
697
Strings with less than 16 characters are not allowed as SCSI product IDs...
698
699
    >>> device_set.create(bus=HWBus.SCSI,
700
    ...                   vendor_id='INTEL   ',
701
    ...                   product_id='123456789012345',
702
    ...                   product_name='A SCSI device')
703
    Traceback (most recent call last):
704
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
705
    ParameterError: '123456789012345' is not a valid product ID for SCSI
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
706
6130.11.1 by Abel Deuring
implemented reviewer's comments
707
...as well as strings with more than 16 characters.
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
708
709
    >>> device_set.create(bus=HWBus.SCSI,
710
    ...                   vendor_id='INTEL   ',
711
    ...                   product_id='12345678901234567',
712
    ...                   product_name='A SCSI device')
713
    Traceback (most recent call last):
714
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
715
    ParameterError: '12345678901234567' is not a valid product ID for SCSI
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
716
717
14050.3.1 by Jeroen Vermeulen
Lint.
718
Unknown Vendor IDs
719
..................
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
720
6130.11.1 by Abel Deuring
implemented reviewer's comments
721
If IHWDevice.create is called with a vendor ID that for which there
722
is no IHWVendorID record, the latter is automatically created. Since
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
723
we do not pass the vendor name to IHWDevice.create, this method
724
cannot set the real vendor name for the new IHWVendorID record.
6130.11.1 by Abel Deuring
implemented reviewer's comments
725
Instead, the vendor name is set to "Unknown".
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
726
727
Reason: IHWDevice will be populated with data collected by the
728
HWDB client, which gets most of the device data from HAL, and HAL
729
quite often does not know the vendor name. Hence we will populate
730
and update IHWVendorID from sources like
731
732
http://www.linux-usb.org/usb.ids
733
http://www.pcidatabase.com/reports.php?type=csv
734
http://standards.ieee.org/regauth/oui/oui.txt
735
736
    >>> new_vendor_device = device_set.create(bus=HWBus.PCI,
737
    ...                                       vendor_id='0x4321',
738
    ...                                       product_id='0x8765',
739
    ...                                       product_name='mind sensor')
740
    >>> print new_vendor_device.bus_vendor.vendor_name.name
741
    Unknown
742
14050.3.1 by Jeroen Vermeulen
Lint.
743
744
Device Variants
745
...............
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
746
6130.11.1 by Abel Deuring
implemented reviewer's comments
747
While most devices can be uniquely identified by their vendor and product
748
IDs, there are some cases, where different devices have identical IDs:
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
749
750
(a) The IDs are assigned to a USB chipset that is used in different
751
    devices.
752
(b) A vendor may inadvertently "recycle" a product ID
753
(c) A chip manufacturer who does not have its own vendor ID may "forge"
754
    the vendor ID.
755
756
A real world example of the first case is the scanner chipset from
757
Plustek with the USB ID 0x07b3/0x0017. This chipset is used in devices
758
that differ for example in the maximum scan window size.
759
760
We do not necessarily know in advance that there are different devices
761
with identical IDs, so we may have a HWDevice record without the variant
762
attribute set.
763
764
    >>> plustek_name = vendor_name_set.create('Plustek')
765
    >>> plustek_usb_id = vendor_id_set.create(bus=HWBus.USB,
766
    ...                                       vendor_id='0x07b3',
767
    ...                                       vendor_name=plustek_name)
768
    >>> some_plustek_scanner = device_set.create(bus=HWBus.USB,
769
    ...                                          vendor_id='0x07b3',
770
    ...                                          product_id='0x0017',
771
    ...                                          product_name='some scanner')
772
    >>> print some_plustek_scanner.bus_vendor.vendor_id_for_bus
773
    0x07b3
774
    >>> print some_plustek_scanner.bus_vendor.vendor_name.name
775
    Plustek
776
    >>> print some_plustek_scanner.name
777
    some scanner
778
    >>> print some_plustek_scanner.variant
779
    None
780
6130.11.1 by Abel Deuring
implemented reviewer's comments
781
Once we know that (bus, vendor ID, product ID) does not uniquely
782
identify a device, we can disambiguate these devices by creating
783
IHWDevice records, where the attribute variant is, for example, set
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
784
to the product name.
785
786
    >>> optic_pro_ut12 = device_set.create(bus=HWBus.USB,
787
    ...                                    vendor_id='0x07b3',
788
    ...                                    product_id='0x0017',
789
    ...                                    variant='OpticPro UT12',
790
    ...                                    product_name='OpticPro UT12')
791
    >>> optic_pro_ut16 = device_set.create(bus=HWBus.USB,
792
    ...                                    vendor_id='0x07b3',
793
    ...                                    product_id='0x0017',
794
    ...                                    variant='OpticPro UT16',
795
    ...                                    product_name='OpticPro UT16')
796
797
For systems, we use HWBus.SYSTEM as the "bus name"; the HAL property
798
system.vendor is stored as the vendor ID and vendor name, and the HAL
799
property system.product is stored as the product ID and the product
800
name.
801
802
    >>> hal_vendor_name = 'Tonka'
803
    >>> hal_product_name = 'Tuffbook 2600'
804
    >>> tonka_name = vendor_name_set.create(name=hal_vendor_name)
805
    >>> tonka_system_id = vendor_id_set.create(bus=HWBus.SYSTEM,
806
    ...                                        vendor_id=hal_vendor_name,
807
    ...                                        vendor_name=tonka_name)
808
    >>> tuffbook_2600 = device_set.create(bus=HWBus.SYSTEM,
809
    ...                                   vendor_id=hal_vendor_name,
810
    ...                                   product_id=hal_product_name,
811
    ...                                   product_name=hal_product_name)
812
    >>> print tuffbook_2600.bus_vendor.bus.title
813
    System
814
    >>> print tuffbook_2600.bus_vendor.vendor_id_for_bus
815
    Tonka
816
    >>> print tuffbook_2600.bus_vendor.vendor_name.name
817
    Tonka
818
    >>> print tuffbook_2600.bus_product_id
819
    Tuffbook 2600
820
    >>> print tuffbook_2600.name
821
    Tuffbook 2600
822
823
The tuple (bus_vendor, bus_product_id, variant) must be unique.
824
The attempt to create two rows with the same data raises a
825
IntegrityError error.
826
827
    >>> LaunchpadZopelessLayer.txn.commit()
828
    >>> another_scanner = device_set.create(bus=HWBus.USB,
829
    ...                                     vendor_id='0x07b3',
830
    ...                                     product_id='0x0017',
831
    ...                                     product_name='some scanner')
5821.5.12 by James Henstridge
Fix hwdb-device-tables.txt test.
832
    >>> store.flush()
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
833
    Traceback (most recent call last):
834
    ...
5821.6.7 by James Henstridge
merge from rocketfuel
835
    IntegrityError: duplicate key... violates unique
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
836
    constraint "hwdevice__bus_vendor_id__bus_product_id__key"
5821.5.12 by James Henstridge
Fix hwdb-device-tables.txt test.
837
    <BLANKLINE>
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
838
    >>> LaunchpadZopelessLayer.txn.abort()
839
840
    >>> another_scanner = device_set.create(bus=HWBus.USB,
841
    ...                                     vendor_id='0x07b3',
842
    ...                                     product_id='0x0017',
843
    ...                                     variant='OpticPro UT16',
844
    ...                                     product_name='OpticPro UT16')
5821.5.12 by James Henstridge
Fix hwdb-device-tables.txt test.
845
    >>> store.flush()
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
846
    Traceback (most recent call last):
847
    ...
5821.6.7 by James Henstridge
merge from rocketfuel
848
    IntegrityError: duplicate key... violates unique
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
849
    constraint "hwdevice__bus_vendor_id__bus_product_id__variant__key"
5821.5.12 by James Henstridge
Fix hwdb-device-tables.txt test.
850
    <BLANKLINE>
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
851
    >>> LaunchpadZopelessLayer.txn.abort()
852
14050.3.1 by Jeroen Vermeulen
Lint.
853
Retrieving HWDevice records
854
...........................
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
855
6407.1.5 by Abel Deuring
implemented reviewer's comments
856
Existing HWDevice records can be retrieved by calling
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
857
HWDeviceSet.getByDeviceID()
858
859
    >>> device = device_set.getByDeviceID(HWBus.USB, '0x07b3', '0x0017')
860
    >>> print device.bus_vendor.bus.title
861
    USB
862
    >>> print device.bus_vendor.vendor_id_for_bus
863
    0x07b3
864
    >>> print device.bus_product_id
865
    0x0017
866
    >>> print device.name
867
    some scanner
868
6407.1.5 by Abel Deuring
implemented reviewer's comments
869
The call to HWDeviceSet.getByDeviceID() above did not specify a product
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
870
variant. In such a case, the record having variant==None is returned
871
872
    >>> print device.variant
873
    None
874
875
If a variant name is given, we get the HWDevice record of that variant.
876
877
    >>> device = device_set.getByDeviceID(HWBus.USB, '0x07b3', '0x0017',
878
    ...                                   'OpticPro UT16')
879
    >>> print device.bus_vendor.bus.title
880
    USB
881
    >>> print device.bus_vendor.vendor_id_for_bus
882
    0x07b3
883
    >>> print device.bus_product_id
884
    0x0017
885
    >>> print device.name
886
    OpticPro UT16
887
    >>> print device.variant
888
    OpticPro UT16
889
890
If the given parameters do not match any existing record, None is
891
returned.
892
893
    >>> print device_set.getByDeviceID(HWBus.PCI, '0x07b3', '0x0017',
894
    ...                                'OpticPro UT16')
895
    None
896
    >>> print device_set.getByDeviceID(HWBus.USB, '0xffff', '0x0017',
897
    ...                                'OpticPro UT16')
898
    None
899
    >>> print device_set.getByDeviceID(HWBus.PCI, '0x07b3', '0xffff',
900
    ...                                'OpticPro UT16')
901
    None
902
    >>> print device_set.getByDeviceID(HWBus.PCI, '0x07b3', '0x0017',
903
    ...                                'nonsense')
904
    None
905
906
The parameters vendor_id and product_id must be valid IDs for the
907
given bus.
908
909
    >>> device_set.getByDeviceID(HWBus.USB, '07b3', '0x0017')
910
    Traceback (most recent call last):
911
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
912
    ParameterError: '07b3' is not a valid vendor ID for USB
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
913
914
    >>> device_set.getByDeviceID(HWBus.USB, '0x07b3', '0017')
915
    Traceback (most recent call last):
916
    ...
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
917
    ParameterError: '0017' is not a valid product ID for USB
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
918
919
HWDeviceSet.getOrCreate() returns an existing record matching the given
920
parameters or creates a new one, if no existing record matches.
921
922
    >>> device2 = device_set.getOrCreate(bus=HWBus.USB,
923
    ...                                  vendor_id='0x07b3',
924
    ...                                  product_id='0x0017',
6407.1.5 by Abel Deuring
implemented reviewer's comments
925
    ...                                  product_name='OpticPro UT16',
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
926
    ...                                  variant='OpticPro UT16')
927
    >>> print device2.bus_vendor.bus.title
928
    USB
929
    >>> print device2.bus_vendor.vendor_id_for_bus
930
    0x07b3
931
    >>> print device2.bus_product_id
932
    0x0017
933
    >>> print device2.name
934
    OpticPro UT16
935
    >>> print device2.variant
936
    OpticPro UT16
937
    >>> print device2.id == device.id
938
    True
939
940
    >>> device3 = device_set.getByDeviceID(bus=HWBus.USB,
941
    ...                                    vendor_id='0x07b3',
942
    ...                                    product_id='0x0017',
943
    ...                                    variant='Some other scanner')
944
    >>> print device3
945
    None
946
    >>> device3 = device_set.getOrCreate(bus=HWBus.USB,
947
    ...                                  vendor_id='0x07b3',
948
    ...                                  product_id='0x0017',
6407.1.5 by Abel Deuring
implemented reviewer's comments
949
    ...                                  product_name='Some other scanner',
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
950
    ...                                  variant='Some other scanner')
951
    >>> print device3.bus_vendor.bus.title
952
    USB
953
    >>> print device3.bus_vendor.vendor_id_for_bus
954
    0x07b3
955
    >>> print device3.bus_product_id
956
    0x0017
957
    >>> print device3.name
958
    Some other scanner
959
    >>> print device3.variant
960
    Some other scanner
961
7353.2.1 by Abel Deuring
Webservice API for IHWDevice
962
    >>> device4 = device_set.getOrCreate(bus=HWBus.USB,
963
    ...                                  vendor_id='0x07b3',
964
    ...                                  product_id='0x0015',
965
    ...                                  product_name='OpticPro U24')
966
    >>> print device4.bus_vendor.bus.title
967
    USB
968
    >>> print device4.bus_vendor.vendor_id_for_bus
969
    0x07b3
970
    >>> print device4.bus_product_id
971
    0x0015
972
    >>> print device4.name
973
    OpticPro U24
974
    >>> print device4.variant
975
    None
976
977
978
HWDeviceSet.getByID() returns a HWDevice record with the given database ID.
979
980
    >>> device = device_set.getByID(1)
981
    >>> print device.id
982
    1
983
    >>> print device.vendor_id
984
    MSI
985
    >>> print device.bus_product_id
986
    MS-7369
987
988
HWDeviceSet.getByID() returns None if no record with the passed ID exists.
989
990
    >>> device = device_set.getByID(1000000)
991
    >>> print device
992
    None
993
994
HWDeviceSet.search() returns all devices with a given bus and vendor ID.
995
996
    >>> devices = device_set.search(bus=HWBus.USB, vendor_id='0x07b3')
997
    >>> for device in devices:
998
    ...     print device.bus.title, device.vendor_id, device.bus_product_id,
999
    ...     print device.variant
1000
    USB 0x07b3 0x0017 None
1001
    USB 0x07b3 0x0017 OpticPro UT12
1002
    USB 0x07b3 0x0017 OpticPro UT16
1003
    USB 0x07b3 0x0017 Some other scanner
1004
    USB 0x07b3 0x0015 None
1005
1006
Searching can be limited to a single product ID.
1007
1008
    >>> devices = device_set.search(
1009
    ...     bus=HWBus.USB, vendor_id='0x07b3', product_id='0x0017')
1010
    >>> for device in devices:
1011
    ...     print device.bus.title, device.vendor_id, device.bus_product_id,
1012
    ...     print device.variant
1013
    USB 0x07b3 0x0017 None
1014
    USB 0x07b3 0x0017 OpticPro UT12
1015
    USB 0x07b3 0x0017 OpticPro UT16
1016
    USB 0x07b3 0x0017 Some other scanner
1017
8063.1.1 by Abel Deuring
better error handling for webservice API queries for HWDB devices with invalid vendor or product IDs.
1018
HWDeviceSet.search() raises a ParameterError for vendor or product IDs
1019
that are not valid for the given bus.
1020
1021
    >>> devices = device_set.search(
1022
    ...     bus=HWBus.USB, vendor_id='invalid', product_id='0x0017')
1023
    Traceback (most recent call last):
1024
    ...
1025
    ParameterError: 'invalid' is not a valid vendor ID for USB
1026
1027
    >>> devices = device_set.search(
1028
    ...     bus=HWBus.USB, vendor_id='0x07b3', product_id='nonsense')
1029
    Traceback (most recent call last):
1030
    ...
1031
    ParameterError: 'nonsense' is not a valid product ID for USB
1032
7525.2.3 by Abel Deuring
Webservice API for HWDB submissions
1033
HWDevice.getSubmissions() returns submissions which contain this device.
1034
1035
We'll switch the DB user from hwdb-submission-processor to the ordinary
1036
Launchpad user, because the former has no access to the table
1037
distribution, which we want to access in this test.
1038
1039
    >>> LaunchpadZopelessLayer.switchDbUser('launchpad')
1040
    >>> sata_controller = device_set.getByDeviceID(
7525.2.5 by Abel Deuring
implemented reviewer's comments
1041
    ...     bus=HWBus.PCI, vendor_id='0x10de', product_id='0x045d')
7525.2.3 by Abel Deuring
Webservice API for HWDB submissions
1042
    >>> for submission in sata_controller.getSubmissions():
1043
    ...     print submission.submission_key
1044
    sample-submission
1045
7525.2.5 by Abel Deuring
implemented reviewer's comments
1046
We can limit the results to a specific driver. (See below for details about
7525.2.3 by Abel Deuring
Webservice API for HWDB submissions
1047
HWDriver.)
1048
11692.6.2 by Curtis Hovey
Use deglober to fixing simple glob imports in doctests.
1049
    >>> from lp.hardwaredb.interfaces.hwdb import IHWDriverSet
7525.2.3 by Abel Deuring
Webservice API for HWDB submissions
1050
    >>> ahci_driver = getUtility(IHWDriverSet).getByPackageAndName(
1051
    ...     'linux-image-2.6.24-19-generic', 'ahci')
1052
    >>> for submission in sata_controller.getSubmissions(
1053
    ...     driver=ahci_driver):
1054
    ...     print submission.submission_key
1055
    sample-submission
1056
1057
    >>> usb_storage_driver = getUtility(IHWDriverSet).getByPackageAndName(
1058
    ...     'linux-image-2.6.24-19-generic', 'usb-storage')
7525.2.5 by Abel Deuring
implemented reviewer's comments
1059
    >>> print list(sata_controller.getSubmissions(
1060
    ...     driver=usb_storage_driver))
1061
    []
7525.2.3 by Abel Deuring
Webservice API for HWDB submissions
1062
1063
We can limit the results to a specific distribution.
1064
7675.110.3 by Curtis Hovey
Ran the migration script to move registry code to lp.registry.
1065
    >>> from lp.registry.interfaces.distribution import (
7525.2.3 by Abel Deuring
Webservice API for HWDB submissions
1066
    ...     IDistributionSet)
1067
    >>> distribution_set = getUtility(IDistributionSet)
1068
    >>> ubuntu = distribution_set.getByName('ubuntu')
1069
    >>> for submission in sata_controller.getSubmissions(
1070
    ...     distribution=ubuntu):
1071
    ...     print submission.submission_key
1072
    sample-submission
1073
1074
    >>> debian = distribution_set.getByName('debian')
1075
    >>> sata_controller.getSubmissions(distribution=debian).count()
1076
    0
1077
1078
We can limit the results to a specific architecture.
1079
1080
    >>> for submission in sata_controller.getSubmissions(
1081
    ...     architecture='i386'):
1082
    ...     print submission.submission_key
1083
    sample-submission
1084
1085
    >>> sata_controller.getSubmissions(architecture='amd64').count()
1086
    0
1087
7734.1.1 by Tom Berger
allow searching submissions by distroseries + doctests
1088
We can limit the results to a specific distro series.
1089
1090
    >>> for submission in sata_controller.getSubmissions(
1091
    ...     distroseries=ubuntu['hoary']):
1092
    ...     print submission.submission_key
1093
    sample-submission
1094
1095
    >>> sata_controller.getSubmissions(distroseries=ubuntu['warty']).count()
1096
    0
1097
1098
We can even limit the results to a specific distro series and architecture.
1099
1100
    >>> for submission in sata_controller.getSubmissions(
1101
    ...     distroseries=ubuntu['hoary'], architecture='i386'):
1102
    ...     print submission.submission_key
1103
    sample-submission
1104
1105
    >>> sata_controller.getSubmissions(
1106
    ...     distroseries=ubuntu['hoary'], architecture='powerpc').count()
1107
    0
1108
7746.1.1 by Tom Berger
make it possible to filter submissions by owner
1109
We can also search for submissions from a particular user.
1110
11692.6.2 by Curtis Hovey
Use deglober to fixing simple glob imports in doctests.
1111
    >>> from lp.registry.interfaces.person import IPersonSet
7746.1.1 by Tom Berger
make it possible to filter submissions by owner
1112
    >>> owner = getUtility(IPersonSet).getByName('name12')
1113
    >>> for submission in sata_controller.getSubmissions(owner=owner):
1114
    ...     print submission.submission_key
1115
    sample-submission
1116
1117
    >>> not_owner = getUtility(IPersonSet).getByName('name20')
1118
    >>> sata_controller.getSubmissions(owner=not_owner).count()
1119
    0
1120
14022.3.13 by William Grant
Fix the two tests that break when switchDbUser does an implicit commit.
1121
    >>> import transaction
1122
    >>> transaction.abort()
7525.2.3 by Abel Deuring
Webservice API for HWDB submissions
1123
    >>> LaunchpadZopelessLayer.switchDbUser('hwdb-submission-processor')
1124
7604.2.1 by Abel Deuring
property 'drivers' added to IHWDevice
1125
HWDevice.drivers is the set of drivers that are associated via
1126
HWDeviceDriverLink (see below) with this device.
1127
1128
    >>> for driver in sata_controller.drivers:
1129
    ...     print driver.package_name, driver.name
1130
    linux-image-2.6.24-19-generic ahci
1131
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
1132
14050.3.1 by Jeroen Vermeulen
Lint.
1133
HWDeviceNameVariant
1134
-------------------
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
1135
1136
Many OEM products are sold by more than one vendor under different
1137
product names; some manufacturers sell the same device under
1138
different names in different parts of the world. The support status
1139
of such devices does not depend on the "publicly visible" vendor and
1140
product name, so we consider these devices to be identical. Users will
1141
nevertheless want to look up devices by the vendor and product name
1142
they see in a store. HWDeviceNameVariant allows us to assign alternative
1143
vendor and product names to a device.
1144
11692.6.2 by Curtis Hovey
Use deglober to fixing simple glob imports in doctests.
1145
    >>> from lp.hardwaredb.interfaces.hwdb import IHWDeviceNameVariantSet
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
1146
    >>> device_name_variant_set = getUtility(IHWDeviceNameVariantSet)
1147
    >>> variant = device_name_variant_set.create(device=optic_pro_ut16,
1148
    ...                                          vendor_name='Medion',
1149
    ...                                          product_name='MD 1234')
1150
    >>> print variant.device.bus_vendor.vendor_name.name
1151
    Plustek
1152
    >>> print variant.vendor_name.name
1153
    Medion
1154
    >>> print variant.product_name
1155
    MD 1234
1156
6130.11.1 by Abel Deuring
implemented reviewer's comments
1157
We count the number of submissions which told us an alternative device
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
1158
name.
1159
1160
    >>> print variant.submissions
1161
    0
1162
1163
The tuple (device, vendor_name, product_name) must be unique.
1164
The attempt to create two rows with the same data raises an
1165
IntegrityError error.
1166
1167
    >>> LaunchpadZopelessLayer.txn.commit()
1168
    >>> same_variant = device_name_variant_set.create(device=optic_pro_ut16,
1169
    ...                                               vendor_name='Medion',
1170
    ...                                               product_name='MD 1234')
5821.5.12 by James Henstridge
Fix hwdb-device-tables.txt test.
1171
    >>> store.flush()
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
1172
    Traceback (most recent call last):
1173
    ...
5821.6.7 by James Henstridge
merge from rocketfuel
1174
    IntegrityError: duplicate key... violates unique
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
1175
    constraint "hwdevicenamevariant__vendor_name__product_name__device__key"
5821.5.12 by James Henstridge
Fix hwdb-device-tables.txt test.
1176
    <BLANKLINE>
6130.10.1 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 2
1177
    >>> LaunchpadZopelessLayer.txn.abort()
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1178
1179
14050.3.1 by Jeroen Vermeulen
Lint.
1180
HWDriver
1181
--------
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1182
6407.1.5 by Abel Deuring
implemented reviewer's comments
1183
If a device is reported as having problems, then we are more
6130.10.3 by Abel Deuring
implemented reviewr's comments
1184
interested in which drivers are involved rather than the fact that
6407.1.5 by Abel Deuring
implemented reviewer's comments
1185
there are problems. The table HWDriver stores minimal data about
6130.10.3 by Abel Deuring
implemented reviewr's comments
1186
drivers: its package name, the driver name itself and the driver's
6407.1.5 by Abel Deuring
implemented reviewer's comments
1187
license. This data is linked to HWDevice records via the table
6130.10.3 by Abel Deuring
implemented reviewr's comments
1188
HWDeviceDriverLink (see below).
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1189
1190
The driver is not in every case a kernel driver, it may also be for
1191
example a Ghostscript driver of a printer or a Sane scanner backend.
1192
11692.6.2 by Curtis Hovey
Use deglober to fixing simple glob imports in doctests.
1193
    >>> from lp.hardwaredb.interfaces.hwdb import IHWDriverSet
7675.110.3 by Curtis Hovey
Ran the migration script to move registry code to lp.registry.
1194
    >>> from lp.registry.interfaces.product import License
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1195
    >>> driver_set = getUtility(IHWDriverSet)
1196
    >>> usb_driver = driver_set.create(package_name='linux-image-generic',
1197
    ...                                name='usb',
6130.10.5 by Abel Deuring
RF merge
1198
    ...                                license=License.GNU_GPL_V2)
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1199
    >>> print usb_driver.name
1200
    usb
1201
    >>> print usb_driver.package_name
1202
    linux-image-generic
1203
    >>> print usb_driver.license.title
6130.10.5 by Abel Deuring
RF merge
1204
    GNU GPL v2
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1205
1206
The submitted data does not need to contain package information for all
7353.2.4 by Abel Deuring
impleneted reviewr's comments
1207
drivers, hence the field package_name may be None or the empty string
8298.4.1 by Abel Deuring
fix for bug 369769: Create no longer HWDriver records where package_name is None
1208
(see below). In both cases, a HWDriver record is created where
1209
package_name is the empty string.
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1210
1211
    >>> driver2 = driver_set.create(package_name=None,
1212
    ...                             name='whatever',
6130.10.5 by Abel Deuring
RF merge
1213
    ...                             license=License.GNU_GPL_V2)
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1214
    >>> print driver2.name
1215
    whatever
8298.4.1 by Abel Deuring
fix for bug 369769: Create no longer HWDriver records where package_name is None
1216
    >>> print repr(driver2.package_name)
1217
    u''
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1218
    >>> print driver2.license.title
6130.10.5 by Abel Deuring
RF merge
1219
    GNU GPL v2
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1220
8298.4.1 by Abel Deuring
fix for bug 369769: Create no longer HWDriver records where package_name is None
1221
    >>> driver_blank_package_name = driver_set.create(package_name='',
1222
    ...                                               name='bar',
1223
    ...                             license=License.GNU_GPL_V3)
1224
    >>> print driver_blank_package_name.name
1225
    bar
1226
    >>> print repr(driver_blank_package_name.package_name)
1227
    u''
1228
    >>> print driver_blank_package_name.license.title
1229
    GNU GPL v3
1230
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1231
Since we also do not always know the license of a driver, the license
1232
may too be None.
1233
7353.2.3 by Abel Deuring
Webservice API for table HWDriver
1234
    >>> driver3 = driver_set.create(package_name='',
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1235
    ...                             name='something_else',
1236
    ...                             license=None)
1237
    >>> print driver3.name
1238
    something_else
7353.2.3 by Abel Deuring
Webservice API for table HWDriver
1239
    >>> print repr(driver3.package_name)
1240
    u''
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1241
    >>> print driver3.license
1242
    None
1243
1244
The tuple (driver name, package name) must be unique.
1245
1246
    >>> LaunchpadZopelessLayer.txn.commit()
1247
    >>> driver = driver_set.create(package_name='linux-image-generic',
1248
    ...                            name='usb',
6130.10.5 by Abel Deuring
RF merge
1249
    ...                            license=License.GNU_GPL_V2)
5821.5.12 by James Henstridge
Fix hwdb-device-tables.txt test.
1250
    >>> store.flush()
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1251
    Traceback (most recent call last):
1252
    ...
5821.6.7 by James Henstridge
merge from rocketfuel
1253
    IntegrityError: duplicate key... violates unique
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1254
    constraint "hwdriver__package_name__name__key"
5821.5.12 by James Henstridge
Fix hwdb-device-tables.txt test.
1255
    <BLANKLINE>
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1256
    >>> LaunchpadZopelessLayer.txn.abort()
1257
1258
    >>> driver = driver_set.create(package_name=None,
1259
    ...                            name='whatever',
6130.10.5 by Abel Deuring
RF merge
1260
    ...                            license=License.GNU_GPL_V2)
5821.5.12 by James Henstridge
Fix hwdb-device-tables.txt test.
1261
    >>> store.flush()
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1262
    Traceback (most recent call last):
1263
    ...
5821.6.7 by James Henstridge
merge from rocketfuel
1264
    IntegrityError: duplicate key... violates unique
8298.4.1 by Abel Deuring
fix for bug 369769: Create no longer HWDriver records where package_name is None
1265
    constraint "hwdriver__package_name__name__key"
5821.5.12 by James Henstridge
Fix hwdb-device-tables.txt test.
1266
    <BLANKLINE>
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1267
    >>> LaunchpadZopelessLayer.txn.abort()
1268
6407.1.5 by Abel Deuring
implemented reviewer's comments
1269
An IHWDriver record is retrieved by calling
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
1270
IHWDriverSet.getByPackageAndName().
1271
1272
    >>> driver = driver_set.getByPackageAndName('linux-image-generic', 'usb')
1273
    >>> print driver.package_name
1274
    linux-image-generic
1275
    >>> print driver.name
1276
    usb
1277
8298.4.1 by Abel Deuring
fix for bug 369769: Create no longer HWDriver records where package_name is None
1278
If we want to search for a driver without a known package, we can
1279
pass None as well as the empty string.
1280
1281
    >>> driver = driver_set.getByPackageAndName('', 'whatever')
1282
    >>> print repr(driver.package_name)
1283
    u''
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
1284
    >>> print driver.name
1285
    whatever
1286
8298.4.1 by Abel Deuring
fix for bug 369769: Create no longer HWDriver records where package_name is None
1287
    >>> driver2 = driver_set.getByPackageAndName(None, 'whatever')
1288
    >>> driver2.id == driver.id
1289
    True
1290
6407.1.5 by Abel Deuring
implemented reviewer's comments
1291
If no existing record matches the parameters of the
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
1292
IHWDriverSet.getByPackageAndName() call, None is returned.
1293
1294
    >>> driver = driver_set.getByPackageAndName('nonsense', 'more nonsense')
1295
    >>> print driver
1296
    None
1297
1298
IHWDriverSet.getOrCreate() returns an existing record matching
1299
the given parameters or creates a new one, if no existing record matches.
1300
6407.1.3 by Abel Deuring
fixed a quite embarrasing bug in HWDriverSet.getOrCreate
1301
    >>> driver = driver_set.getOrCreate('linux-image-generic', 'usb')
1302
    >>> print driver.package_name
1303
    linux-image-generic
1304
    >>> print driver.name
1305
    usb
1306
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
1307
    >>> driver = driver_set.getByPackageAndName('linux-image-generic', 'foo')
1308
    >>> print driver
1309
    None
1310
    >>> driver = driver_set.getOrCreate('linux-image-generic', 'foo')
1311
    >>> print driver.name
1312
    foo
1313
    >>> print driver.package_name
1314
    linux-image-generic
1315
8298.4.1 by Abel Deuring
fix for bug 369769: Create no longer HWDriver records where package_name is None
1316
If we pass None as the value for package_name, we get records where
1317
package_name is None or the empty string.
1318
1319
    >>> driver = driver_set.getOrCreate(None, 'whatever')
1320
    >>> print repr(driver.package_name)
1321
    u''
1322
    >>> print driver.name
1323
    whatever
1324
1325
Older HWDriver records may store None as the package name. We can
1326
retrieve these records by passing None for package_name...
1327
10234.3.3 by Curtis Hovey
Migrated hardward database to lp. Updated test_doc to run the hwddb test.
1328
    >>> from lp.hardwaredb.model.hwdb import HWDriver
8298.4.1 by Abel Deuring
fix for bug 369769: Create no longer HWDriver records where package_name is None
1329
    >>> old_driver = HWDriver(package_name=None, name=u'foo', license=None)
1330
    >>> print old_driver.name
1331
    foo
1332
    >>> print old_driver.package_name
1333
    None
1334
1335
    >>> driver = driver_set.getOrCreate(None, 'foo')
1336
    >>> driver.id == old_driver.id
1337
    True
1338
1339
...as well as the empty string.
1340
1341
    >>> driver = driver_set.getOrCreate('', 'foo')
1342
    >>> driver.id == old_driver.id
1343
    True
1344
7353.2.3 by Abel Deuring
Webservice API for table HWDriver
1345
IHWDriverSet.search() returns a sequence of driver records matching the
1346
given parameters.
1347
1348
    >>> drivers = driver_set.search(package_name='linux-image-generic')
1349
    >>> for driver in drivers:
1350
    ...    print driver.package_name, driver.name
1351
    linux-image-generic usb
1352
    linux-image-generic foo
1353
1354
    >>> drivers = driver_set.search(name='usb')
1355
    >>> for driver in drivers:
1356
    ...    print driver.package_name, driver.name
1357
    linux-image-2.6.24-19-generic usb
1358
    linux-image-generic usb
1359
1360
    >>> drivers = driver_set.search(
1361
    ...     package_name='linux-image-2.6.24-19-generic', name='ahci')
1362
    >>> for driver in drivers:
1363
    ...    print driver.package_name, driver.name
1364
    linux-image-2.6.24-19-generic ahci
1365
7353.2.4 by Abel Deuring
impleneted reviewr's comments
1366
If package_name is an empty string, driver records are returned where
1367
the package name is not recorded (which is denoted by None or the
1368
empty string. See also bug 306265: Disallow the column value
1369
HWDriver.package_name=null).
7353.2.3 by Abel Deuring
Webservice API for table HWDriver
1370
1371
    >>> drivers = driver_set.search(package_name='')
1372
    >>> for driver in drivers:
1373
    ...    print repr(driver.package_name), driver.name
8298.4.1 by Abel Deuring
fix for bug 369769: Create no longer HWDriver records where package_name is None
1374
    u'' whatever
1375
    u'' bar
7353.2.3 by Abel Deuring
Webservice API for table HWDriver
1376
    u'' something_else
8298.4.1 by Abel Deuring
fix for bug 369769: Create no longer HWDriver records where package_name is None
1377
    None foo
7353.2.3 by Abel Deuring
Webservice API for table HWDriver
1378
1379
    >>> drivers = driver_set.search(package_name='', name='whatever')
1380
    >>> for driver in drivers:
8298.4.1 by Abel Deuring
fix for bug 369769: Create no longer HWDriver records where package_name is None
1381
    ...    print repr(driver.package_name), driver.name
1382
    u'' whatever
1383
1384
    >>> drivers = driver_set.search(package_name='', name='foo')
1385
    >>> for driver in drivers:
1386
    ...    print repr(driver.package_name), driver.name
1387
    None foo
1388
1389
If no parameters are specified, IHWDriverSet.search() returns all driver
7353.2.3 by Abel Deuring
Webservice API for table HWDriver
1390
records.
1391
1392
    >>> drivers = driver_set.search()
1393
    >>> for driver in drivers:
1394
    ...    print repr(driver.package_name), driver.name
1395
    u'linux-image-2.6.24-19-generic' ehci_hcd
1396
    u'linux-image-2.6.24-19-generic' usb
1397
    u'linux-image-2.6.24-19-generic' usb-storage
1398
    u'linux-image-2.6.24-19-generic' sd
1399
    u'linux-image-2.6.24-19-generic' hub
1400
    u'linux-image-2.6.24-19-generic' ahci
1401
    u'linux-image-2.6.24-19-generic' sr
1402
    u'linux-image-generic' usb
8298.4.1 by Abel Deuring
fix for bug 369769: Create no longer HWDriver records where package_name is None
1403
    u'' whatever
1404
    u'' bar
7353.2.3 by Abel Deuring
Webservice API for table HWDriver
1405
    u'' something_else
1406
    u'linux-image-generic' foo
8298.4.1 by Abel Deuring
fix for bug 369769: Create no longer HWDriver records where package_name is None
1407
    None foo
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
1408
7353.2.6 by Abel Deuring
added missing implementation to access a single HWDriver instance via the webservice API
1409
HWDriverSet.getByID() returns a HWDriver record with the given database ID.
1410
1411
    >>> driver = driver_set.getByID(1)
1412
    >>> print driver.id
1413
    1
1414
    >>> print driver.package_name
1415
    linux-image-2.6.24-19-generic
1416
    >>> print driver.name
1417
    ehci_hcd
1418
1419
HWDriverSet.getByID() returns None if no record with the passed ID exists.
1420
1421
    >>> driver = driver_set.getByID(1000000)
1422
    >>> print driver
1423
    None
1424
14022.3.13 by William Grant
Fix the two tests that break when switchDbUser does an implicit commit.
1425
    >>> transaction.abort()
7771.2.1 by Tom Berger
allow searching hwdb submissions by driver
1426
    >>> LaunchpadZopelessLayer.switchDbUser('launchpad')
1427
1428
We can search all the submissions related to a driver.
1429
1430
    >>> driver = driver_set.getByID(1)
1431
    >>> for submission in driver.getSubmissions():
1432
    ...     print submission.submission_key
1433
    sample-submission
1434
1435
We can limit our search to submissions for a particular distribution.
1436
1437
    >>> for submission in driver.getSubmissions(distribution=ubuntu):
1438
    ...     print submission.submission_key
1439
    sample-submission
1440
1441
    >>> print driver.getSubmissions(distribution=debian).count()
1442
    0
1443
1444
We can limit the results to a specific distro series.
1445
1446
    >>> for submission in driver.getSubmissions(
1447
    ...     distroseries=ubuntu['hoary']):
1448
    ...     print submission.submission_key
1449
    sample-submission
1450
1451
    >>> driver.getSubmissions(distroseries=ubuntu['warty']).count()
1452
    0
1453
1454
We can also limit the results to a specific distro series and architecture.
1455
1456
    >>> for submission in driver.getSubmissions(
1457
    ...     distroseries=ubuntu['hoary'], architecture='i386'):
1458
    ...     print submission.submission_key
1459
    sample-submission
1460
1461
    >>> driver.getSubmissions(
1462
    ...     distroseries=ubuntu['hoary'], architecture='powerpc').count()
1463
    0
1464
1465
And We can search for submissions from a particular user.
1466
1467
    >>> for submission in driver.getSubmissions(owner=owner):
1468
    ...     print submission.submission_key
1469
    sample-submission
1470
1471
    >>> driver.getSubmissions(owner=not_owner).count()
1472
    0
1473
14022.3.13 by William Grant
Fix the two tests that break when switchDbUser does an implicit commit.
1474
    >>> transaction.abort()
7771.2.1 by Tom Berger
allow searching hwdb submissions by driver
1475
    >>> LaunchpadZopelessLayer.switchDbUser('hwdb-submission-processor')
7353.2.4 by Abel Deuring
impleneted reviewr's comments
1476
1477
14050.3.1 by Jeroen Vermeulen
Lint.
1478
Driver names and package names
1479
------------------------------
8538.3.1 by Abel Deuring
Python classes for SQL views hwdrivername and hwdriverpackagename added
1480
1481
The same driver names can appear multiple times in HWDriver.
8538.3.2 by Abel Deuring
implemented reviewer's comments
1482
HWDriverSet.all_driver_names() returns a list of distinct driver
1483
names used in the table HWDriver.
8538.3.1 by Abel Deuring
Python classes for SQL views hwdrivername and hwdriverpackagename added
1484
1485
    >>> LaunchpadZopelessLayer.switchDbUser('launchpad')
8538.3.2 by Abel Deuring
implemented reviewer's comments
1486
    >>> for driver_name in driver_set.all_driver_names():
8538.3.1 by Abel Deuring
Python classes for SQL views hwdrivername and hwdriverpackagename added
1487
    ...     print driver_name.name
1488
    ahci
1489
    bar
1490
    ehci_hcd
1491
    hub
1492
    sd
1493
    something_else
1494
    sr
1495
    usb
1496
    usb-storage
1497
    whatever
1498
1499
Similary, the same package names appear more than once in HWDriver.
8538.3.2 by Abel Deuring
implemented reviewer's comments
1500
HWDriverSet.all_package_names() returns a list of distinct package
8687.7.1 by Abel Deuring
fixed an exception when the set distinct driver packages names is retrieved via the webservice API if the value package_name=None exists.
1501
names. Note that the package name value None (used in older submissions)
1502
is not included.
8538.3.1 by Abel Deuring
Python classes for SQL views hwdrivername and hwdriverpackagename added
1503
10234.3.3 by Curtis Hovey
Migrated hardward database to lp. Updated test_doc to run the hwddb test.
1504
    >>> from lp.hardwaredb.model.hwdb import HWDriver
8687.7.1 by Abel Deuring
fixed an exception when the set distinct driver packages names is retrieved via the webservice API if the value package_name=None exists.
1505
    >>> store.add(HWDriver(name='foo', package_name=None))
8687.7.3 by Abel Deuring
fixed a trivial test failure
1506
    <HWDriver at...
8538.3.2 by Abel Deuring
implemented reviewer's comments
1507
    >>> for package_name in driver_set.all_package_names():
8538.3.1 by Abel Deuring
Python classes for SQL views hwdrivername and hwdriverpackagename added
1508
    ...     print package_name.package_name
1509
    <BLANKLINE>
1510
    linux-image-2.6.24-19-generic
1511
    linux-image-generic
1512
1513
    >>> LaunchpadZopelessLayer.switchDbUser('hwdb-submission-processor')
1514
1515
14050.3.1 by Jeroen Vermeulen
Lint.
1516
HWDeviceDriverLink
1517
------------------
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1518
1519
This table links devices and drivers.
1520
11692.6.2 by Curtis Hovey
Use deglober to fixing simple glob imports in doctests.
1521
    >>> from lp.hardwaredb.interfaces.hwdb import IHWDeviceDriverLinkSet
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1522
    >>> device_driver_link_set = getUtility(IHWDeviceDriverLinkSet)
1523
    >>> usb_controller_usb_link = device_driver_link_set.create(
1524
    ...     device=usb_controller, driver=usb_driver)
1525
    >>> print usb_controller_usb_link.device.name
1526
    82801GBM/GHM (ICH7 Family) USB2 EHCI Controller
1527
    >>> print usb_controller_usb_link.driver.name
1528
    usb
1529
1530
A device may be linked to more than one driver. A USB2 host controller
1531
for example has two drivers, the "generic" USB driver and the ehci-hcd
1532
driver.
1533
1534
    >>> ehci_hcd_driver = driver_set.create(
1535
    ...     package_name='linux-image-generic', name='ehci_hcd',
6130.10.5 by Abel Deuring
RF merge
1536
    ...     license=License.GNU_GPL_V2)
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1537
    >>> usb_controller_ehci_hcd_link = device_driver_link_set.create(
1538
    ...     device=usb_controller, driver=ehci_hcd_driver)
1539
    >>> print usb_controller_ehci_hcd_link.device.name
1540
    82801GBM/GHM (ICH7 Family) USB2 EHCI Controller
1541
    >>> print usb_controller_ehci_hcd_link.driver.name
1542
    ehci_hcd
1543
1544
A scanner can be linked to the kernel driver for the physical interface
1545
and to its Sane backend.
1546
1547
    >>> scanner_usb_driver_link = device_driver_link_set.create(
1548
    ...     device=optic_pro_ut12, driver=usb_driver)
1549
    >>> print scanner_usb_driver_link.device.name
1550
    OpticPro UT12
1551
    >>> print scanner_usb_driver_link.driver.name
1552
    usb
1553
1554
    >>> sane_plustek_driver = driver_set.create(package_name='libsane',
1555
    ...                                         name='plustek',
6130.10.5 by Abel Deuring
RF merge
1556
    ...                                         license=License.GNU_GPL_V2)
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1557
    >>> scanner_sane_plustek_link = device_driver_link_set.create(
1558
    ...     device=optic_pro_ut12, driver=sane_plustek_driver)
1559
    >>> print scanner_sane_plustek_link.device.name
1560
    OpticPro UT12
1561
    >>> print scanner_sane_plustek_link.driver.name
1562
    plustek
1563
6130.10.3 by Abel Deuring
implemented reviewr's comments
1564
Devices can have alternative drivers. Let's assume that Plustek
1565
provides a closed-source driver for its scanners.
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1566
1567
    >>> closed_driver = driver_set.create(package_name='plustek-scanner',
1568
    ...                                   name='ut12',
1569
    ...                                   license=License.OTHER_PROPRIETARY)
1570
1571
Now we can link the OpticPro UT12 to the closed-source driver too.
1572
1573
    >>> link3 = device_driver_link_set.create(device=optic_pro_ut12,
1574
    ...                                         driver=closed_driver)
1575
    >>> print link3.device.name
1576
    OpticPro UT12
1577
    >>> print link3.driver.name
1578
    ut12
1579
1580
We have two cases, where we do not (or can not) store driver information
1581
for a HWDevice record:
1582
  - it does not make much sense to assign drivers to an entire system;
1583
  - HAL can list a device without providing driver information. This is
1584
    for example the case for an unsupported device.
1585
1586
Since the tables HWSubmissionDevice, HWTestAnswer and HWTestAnswerCount
1587
(see below) link to HWDeviceDriverLink, we need a record in the latter
1588
table, even when we do not know about a driver of a device or system.
1589
Thus we can create a HWDeviceDriverLink record, where driver is None.
1590
1591
    >>> tuffbook_2600_device_driver_link = device_driver_link_set.create(
1592
    ...     device=tuffbook_2600, driver=None)
1593
1594
The tuple (device, driver) must be unique.
1595
1596
    >>> LaunchpadZopelessLayer.txn.commit()
1597
    >>> device_driver_link_set.create(device=optic_pro_ut12,
1598
    ...                               driver=closed_driver)
5821.5.12 by James Henstridge
Fix hwdb-device-tables.txt test.
1599
    <HWDeviceDriverLink...
1600
    >>> store.flush()
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1601
    Traceback (most recent call last):
1602
    ...
5821.6.7 by James Henstridge
merge from rocketfuel
1603
    IntegrityError: duplicate key... violates unique
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1604
    constraint "hwdevicedriverlink__device__driver__key"
5821.5.12 by James Henstridge
Fix hwdb-device-tables.txt test.
1605
    <BLANKLINE>
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1606
    >>> LaunchpadZopelessLayer.txn.abort()
1607
1608
    >>> device_driver_link_set.create(device=tuffbook_2600, driver=None)
5821.5.12 by James Henstridge
Fix hwdb-device-tables.txt test.
1609
    <HWDeviceDriverLink...
1610
    >>> store.flush()
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1611
    Traceback (most recent call last):
1612
    ...
5821.6.7 by James Henstridge
merge from rocketfuel
1613
    IntegrityError: duplicate key... violates unique
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1614
    constraint "hwdevicedriverlink__device__key"
5821.5.12 by James Henstridge
Fix hwdb-device-tables.txt test.
1615
    <BLANKLINE>
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1616
    >>> LaunchpadZopelessLayer.txn.abort()
1617
6407.1.5 by Abel Deuring
implemented reviewer's comments
1618
An IHWDeviceDriverLink record is retrieved by
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
1619
IHWDeviceDriverSet.getByDeviceAndDriver().
1620
1621
    >>> link = device_driver_link_set.getByDeviceAndDriver(optic_pro_ut12,
1622
    ...                                                    closed_driver)
1623
    >>> print link.device.name
1624
    OpticPro UT12
1625
    >>> print link.driver.name
1626
    ut12
1627
6407.1.5 by Abel Deuring
implemented reviewer's comments
1628
If no record exists for the given tuple (device, driver),
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
1629
IHWDeviceDriverSet.getByDeviceAndDriver() returns None.
1630
1631
    >>> link = device_driver_link_set.getByDeviceAndDriver(optic_pro_ut12,
1632
    ...                                                    ehci_hcd_driver)
1633
    >>> print link
1634
    None
1635
1636
HWDeviceDriverLinkSet.getOrCreate() returns an existing record matching
1637
the given parameters or creates a new one, if no existing record matches.
1638
6407.1.5 by Abel Deuring
implemented reviewer's comments
1639
    >>> link = device_driver_link_set.getOrCreate(optic_pro_ut12,
6407.1.1 by Abel Deuring
methods to retrieve data from HWDB device tables; HWBus.PPCARD added
1640
    ...                                           closed_driver)
1641
    >>> print link.device.name
1642
    OpticPro UT12
1643
    >>> print link.driver.name
1644
    ut12
1645
    >>> print link.id == link3.id
1646
    True
1647
    >>> link = device_driver_link_set.getByDeviceAndDriver(optic_pro_ut12,
1648
    ...                                                    None)
1649
    >>> print link
1650
    None
1651
    >>> link = device_driver_link_set.getOrCreate(optic_pro_ut12, None)
1652
    >>> print link.device.name
1653
    OpticPro UT12
1654
    >>> print link.driver
1655
    None
1656
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1657
14050.3.1 by Jeroen Vermeulen
Lint.
1658
HWDeviceClass
1659
-------------
6740.4.1 by Abel Deuring
core implementation of class HWDeviceClass
1660
1661
This table specifies the class or classes of a device. A device class
1662
describes the capabilities of a device, i.e, if it is a printer,
1663
input device, sound device etc. HWDeviceClass stores the main class of
6740.4.2 by Abel Deuring
implemented reviewer's comments
1664
a device, enumerated by HWMainClass, as well as a sub-class, enumerated
6740.4.1 by Abel Deuring
core implementation of class HWDeviceClass
1665
by HWSubClass. The required main class specifies the generic type of
6740.4.2 by Abel Deuring
implemented reviewer's comments
1666
a device, the optional sub-class a more detailed type.
6740.4.1 by Abel Deuring
core implementation of class HWDeviceClass
1667
9094.2.1 by Abel Deuring
allow arbitrary int values for HWDeviceClass.main_class and HWDeviceClass.sub_class; expose HWDeviceClass to the webservice.
1668
Note that this information is not very reliable for some devices.
1669
For example, the USB bus has no specification at all for scanners;
1670
many vendors use the "generic" class/sub-class 0/0 for their scanners,
1671
while other vendors use 0x10/0, at least for some of their scanners.
1672
1673
We have also hardware reports with obviously broken devices. For example
1674
some USB/WLAN adapters with vendor/product IDs 0x050d/0x705a and
1675
0x050d/0x905b claim that they implement the USB class 6, imaging.
1676
Similary, a number of PCI devices return clearly invalid class/subclass
1677
data.
1678
1679
Let's pretend that Plustek uses the inofficial class/subclass 0x10/0
1680
for their Optic Pro 12 scanner.
1681
9094.2.2 by Abel Deuring
implemented reviewer's comments
1682
    >>> device_class_optic_pro_ut12 = optic_pro_ut12.getOrCreateDeviceClass(
9094.2.1 by Abel Deuring
allow arbitrary int values for HWDeviceClass.main_class and HWDeviceClass.sub_class; expose HWDeviceClass to the webservice.
1683
    ...     main_class=0x10, sub_class=0)
1684
    >>> device_class_optic_pro_ut12.main_class
1685
    16
1686
    >>> device_class_optic_pro_ut12.sub_class
1687
    0
1688
1689
We can assign more than one class to devices. This should only be
1690
done for USB devices, which may have different classes for each
1691
of their interfaces. Let's add a second device class, "USB printer",
1692
for the scanner.
1693
9094.2.2 by Abel Deuring
implemented reviewer's comments
1694
    >>> device_class_printer = optic_pro_ut12.getOrCreateDeviceClass(
9094.2.1 by Abel Deuring
allow arbitrary int values for HWDeviceClass.main_class and HWDeviceClass.sub_class; expose HWDeviceClass to the webservice.
1695
    ...     main_class=0x07, sub_class=0x01)
1696
    >>> print device_class_printer.device.name
1697
    OpticPro UT12
1698
    >>> print device_class_printer.main_class
1699
    7
1700
    >>> print device_class_printer.sub_class
1701
    1
1702
1703
IHWDdevice.classes contains the set of classes defined for this device.
1704
1705
    >>> for device_class in optic_pro_ut12.classes:
1706
    ...     print device_class.main_class, device_class.sub_class
1707
    7 1
1708
    16 0
1709
1710
We get the device class data from HWDB submissiions. Some submissions
1711
contain devices with obviously broken device class information, like
1712
a PCI SCSI controller claiming to be a graphics card, or a USB WLAN
1713
adapter claiming to be an imaging device. If we notice such kind of
1714
broken device class data, we can remove it by calling
1715
IHWDevice.removeDeviceClass().
1716
1717
    >>> LaunchpadZopelessLayer.txn.commit()
1718
    >>> LaunchpadZopelessLayer.switchDbUser('launchpad')
1719
    >>> optic_pro_ut12.removeDeviceClass(main_class=0x07, sub_class=0x01)
1720
    >>> for device_class in optic_pro_ut12.classes:
1721
    ...     print device_class.main_class, device_class.sub_class
1722
    16 0
1723
1724
    >>> LaunchpadZopelessLayer.switchDbUser('hwdb-submission-processor')
6740.4.1 by Abel Deuring
core implementation of class HWDeviceClass
1725
1726
14050.3.1 by Jeroen Vermeulen
Lint.
1727
HWSubmissionDevice
1728
------------------
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1729
6407.1.5 by Abel Deuring
implemented reviewer's comments
1730
This table links devices listed in a submission to the
6130.10.3 by Abel Deuring
implemented reviewr's comments
1731
HWDeviceDriverLink table. Additionally it links a device of a
6456.1.1 by Abel Deuring
column hal_device_id added to HWSubmissionDevice
1732
submission to its parent device, as modeled by HAL. A submission
1733
may contain two or more identical devices. In order to unambiugously
1734
relate HWSubmissionDevice records to devices as represented in the
1735
submitted data, we store the attribute "id" of the HAL device node
1736
too.
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1737
1738
We need a submission to which we can link HWSubmissionDevice entries.
1739
11692.6.2 by Curtis Hovey
Use deglober to fixing simple glob imports in doctests.
1740
    >>> from lp.hardwaredb.interfaces.hwdb import IHWSubmissionSet
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1741
    >>> sample_submission = getUtility(IHWSubmissionSet).getBySubmissionKey(
1742
    ...     'test_submission_id_1')
1743
1744
A HWSubmissionDevice record for a system does not have any parent...
1745
11692.6.2 by Curtis Hovey
Use deglober to fixing simple glob imports in doctests.
1746
    >>> from lp.hardwaredb.interfaces.hwdb import IHWSubmissionDeviceSet
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1747
    >>> submission_device_set = getUtility(IHWSubmissionDeviceSet)
1748
    >>> submitted_tuffbook_2600 = submission_device_set.create(
1749
    ...     device_driver_link=tuffbook_2600_device_driver_link,
6456.1.1 by Abel Deuring
column hal_device_id added to HWSubmissionDevice
1750
    ...     submission=sample_submission, parent=None, hal_device_id=1)
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1751
    >>> print submitted_tuffbook_2600.device_driver_link.device.name
1752
    Tuffbook 2600
7525.3.1 by Abel Deuring
Webservice API for IHWSubmissionDevice
1753
    >>> print submitted_tuffbook_2600.device.name
1754
    Tuffbook 2600
1755
    >>> print submitted_tuffbook_2600.driver
1756
    None
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1757
    >>> print submitted_tuffbook_2600.submission.submission_key
1758
    test_submission_id_1
1759
    >>> print submitted_tuffbook_2600.parent
1760
    None
7525.3.1 by Abel Deuring
Webservice API for IHWSubmissionDevice
1761
    >>> print submitted_tuffbook_2600.hal_device_id
1762
    1
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1763
1764
...while ordinary device entries have the attribute parent set. The
6130.10.3 by Abel Deuring
implemented reviewr's comments
1765
parent/child relationship may extend to several "generations". For
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1766
example, our Inspiron 1234 has a USB host controller; its parent
1767
is the system itself.
1768
1769
    >>> submitted_usb_ehci_hcd_controller = submission_device_set.create(
1770
    ...      device_driver_link=usb_controller_ehci_hcd_link,
1771
    ...      submission=sample_submission,
6456.1.1 by Abel Deuring
column hal_device_id added to HWSubmissionDevice
1772
    ...      parent=submitted_tuffbook_2600,
1773
    ...      hal_device_id=2)
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1774
1775
For the "output aspect" of the USB controller, we have
1776
usb_controller_usb_link; its parent is submitted_usb_ehci_hcd_controller
1777
that we just have created.
1778
1779
    >>> submitted_usb_controller = submission_device_set.create(
1780
    ...      device_driver_link=usb_controller_usb_link,
1781
    ...      submission=sample_submission,
6456.2.5 by Abel Deuring
RF merge; conflicts in hwdb-device-tables.txt resolved
1782
    ...      parent=submitted_usb_ehci_hcd_controller,
6456.1.1 by Abel Deuring
column hal_device_id added to HWSubmissionDevice
1783
    ...      hal_device_id=3)
7525.3.1 by Abel Deuring
Webservice API for IHWSubmissionDevice
1784
    >>> print submitted_usb_controller.device_driver_link.device.name
1785
    82801GBM/GHM (ICH7 Family) USB2 EHCI Controller
1786
    >>> print submitted_usb_controller.device_driver_link.driver.name
1787
    usb
1788
    >>> print submitted_usb_controller.device.name
1789
    82801GBM/GHM (ICH7 Family) USB2 EHCI Controller
1790
    >>> print submitted_usb_controller.driver.name
1791
    usb
1792
    >>> print submitted_usb_controller.hal_device_id
1793
    3
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1794
1795
The USB controller is connected to an (often internal) USB hub. We don't
6130.10.3 by Abel Deuring
implemented reviewr's comments
1796
yet have HWDevice and HWDeviceDriverLink records for this hub, so we must
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1797
create them first.
1798
1799
    >>> usb_hub = device_set.create(bus=HWBus.USB,
1800
    ...                             vendor_id='0x8086',
1801
    ...                             product_id='0x1234',
1802
    ...                             product_name='Intel USB hub')
1803
    >>> usb_hub_driver_link = device_driver_link_set.create(
1804
    ...     device=usb_hub, driver=usb_driver)
1805
    >>> submitted_usb_hub = submission_device_set.create(
1806
    ...     device_driver_link=usb_hub_driver_link,
1807
    ...     submission=sample_submission,
6456.1.1 by Abel Deuring
column hal_device_id added to HWSubmissionDevice
1808
    ...     parent=submitted_usb_controller,
7525.3.1 by Abel Deuring
Webservice API for IHWSubmissionDevice
1809
    ...     hal_device_id=4)
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1810
1811
Finally, a scanner may be connected to the USB hub.
1812
1813
    >>> submitted_scanner_usb = submission_device_set.create(
1814
    ...     device_driver_link=scanner_usb_driver_link,
1815
    ...     submission=sample_submission,
6456.1.1 by Abel Deuring
column hal_device_id added to HWSubmissionDevice
1816
    ...     parent=submitted_usb_hub,
7525.3.1 by Abel Deuring
Webservice API for IHWSubmissionDevice
1817
    ...     hal_device_id=5)
6130.10.2 by Abel Deuring
SQLBase derived classes for HWDB device tables, part 3
1818
1819
    >>> submitted_scanner_sane = submission_device_set.create(
1820
    ...     device_driver_link=scanner_sane_plustek_link,
1821
    ...     submission=sample_submission,
6456.1.1 by Abel Deuring
column hal_device_id added to HWSubmissionDevice
1822
    ...     parent=submitted_scanner_usb,
7525.3.1 by Abel Deuring
Webservice API for IHWSubmissionDevice
1823
    ...     hal_device_id=6)
6456.1.1 by Abel Deuring
column hal_device_id added to HWSubmissionDevice
1824
6456.2.7 by Abel Deuring
Method added to HWSubmissionDeviceSet to retrieve devices of a submission
1825
IHWSubmissionDevice records belonging to a submission are retrieved by
7310.2.2 by Abel Deuring
implemented reviewer's comments
1826
IHWSubmissionDeviceSet.getDevices().
6456.2.7 by Abel Deuring
Method added to HWSubmissionDeviceSet to retrieve devices of a submission
1827
6456.2.9 by Abel Deuring
implemented reviewer's comments
1828
    >>> submitted_devices = submission_device_set.getDevices(
6456.2.7 by Abel Deuring
Method added to HWSubmissionDeviceSet to retrieve devices of a submission
1829
    ...     submission=sample_submission)
7310.2.2 by Abel Deuring
implemented reviewer's comments
1830
    >>> def print_device(submission_device, indent=0):
1831
    ...     if indent > 0:
7310.2.4 by Abel Deuring
changed formatting of a test output
1832
    ...         print '-' * indent + '>',
7310.2.2 by Abel Deuring
implemented reviewer's comments
1833
    ...     device = submission_device.device_driver_link.device
1834
    ...     driver = submission_device.device_driver_link.driver
1835
    ...     print device.bus_vendor.vendor_name.name, device.name,
1836
    ...     if driver is not None:
1837
    ...         print driver.name
1838
    ...     else:
1839
    ...         print '(no driver)'
1840
    ...     for sub_device in submitted_devices:
1841
    ...         if sub_device.parent == submission_device:
7310.2.4 by Abel Deuring
changed formatting of a test output
1842
    ...             print_device(sub_device, indent+1)
7310.2.2 by Abel Deuring
implemented reviewer's comments
1843
    >>> devices_without_parent = [
1844
    ...     device for device in submitted_devices if device.parent is None]
1845
    >>> root_device, = devices_without_parent
1846
    >>> print_device(root_device)
1847
    Tonka Tuffbook 2600 (no driver)
7310.2.4 by Abel Deuring
changed formatting of a test output
1848
    -> Intel 82801GBM/GHM (ICH7 Family) USB2 EHCI Controller ehci_hcd
1849
    --> Intel 82801GBM/GHM (ICH7 Family) USB2 EHCI Controller usb
1850
    ---> Unknown Intel USB hub usb
1851
    ----> Plustek OpticPro UT12 usb
1852
    -----> Plustek OpticPro UT12 plustek
7525.3.1 by Abel Deuring
Webservice API for IHWSubmissionDevice
1853
7525.4.1 by Abel Deuring
impleneted reviewer's comments
1854
A single IHWSubmissionDevice record is retrieved by
7525.3.2 by Abel Deuring
implemented reviewer's comments
1855
IHWSubmissionDeviceSet.get().
7525.3.1 by Abel Deuring
Webservice API for IHWSubmissionDevice
1856
7525.3.2 by Abel Deuring
implemented reviewer's comments
1857
    >>> submitted_device = submission_device_set.get(1)
7525.3.1 by Abel Deuring
Webservice API for IHWSubmissionDevice
1858
    >>> print_device(submitted_device)
1859
    MSI MS-7369 (no driver)
1860
7525.3.2 by Abel Deuring
implemented reviewer's comments
1861
This method returns None if a nonexistent ID is passed.
7525.3.1 by Abel Deuring
Webservice API for IHWSubmissionDevice
1862
7525.3.2 by Abel Deuring
implemented reviewer's comments
1863
    >>> print submission_device_set.get(1000000)
7525.3.1 by Abel Deuring
Webservice API for IHWSubmissionDevice
1864
    None
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
1865
1866
14050.3.1 by Jeroen Vermeulen
Lint.
1867
Statistical functions
1868
---------------------
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
1869
8311.2.2 by Abel Deuring
changed the function num_devices_in_submissions and num_submissions_with_device into mehtods of HWSubmissionDeviceSet resp. HWSubmissionSet
1870
HWSubmissionDeviceSet.numDevicesInSubmissions() returns how often a
1871
device appears in HWDB submissions.
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
1872
8311.2.2 by Abel Deuring
changed the function num_devices_in_submissions and num_submissions_with_device into mehtods of HWSubmissionDeviceSet resp. HWSubmissionSet
1873
    >>> print submission_device_set.numDevicesInSubmissions(
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
1874
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ')
1875
    1
1876
1877
If a device appears more than once in a submission, it is counted as often
1878
as it appears in the submission. We have currently only unique devices
1879
in the existing data, so let's add another IDE disk to submission 2.
1880
1881
    >>> ide_disk = device_set.getByDeviceID(
1882
    ...     HWBus.IDE, 'SEAGATE', 'ST3250820NS     ')
1883
    >>> # We'll use the same parent as that of the existing IDE disk.
1884
    >>> parent = getUtility(IHWSubmissionDeviceSet).get(17)
1885
    >>> submission = getUtility(IHWSubmissionSet).getBySubmissionKey(
1886
    ...     'sample-submission')
1887
    >>> # The value of hal_device_id is arbitrary: It is intended for
1888
    >>> # for consistency checks and debugging.
1889
    >>> factory.makeHWSubmissionDevice(submission, ide_disk, None, parent, 1)
1890
    <HWSubmissionDevice at...
1891
1892
The number returned for the query "count the number of Seagate
1893
ST3250820NS" disks increased.
1894
8311.2.2 by Abel Deuring
changed the function num_devices_in_submissions and num_submissions_with_device into mehtods of HWSubmissionDeviceSet resp. HWSubmissionSet
1895
    >>> print submission_device_set.numDevicesInSubmissions(
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
1896
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ')
1897
    2
1898
1899
Note that we did _not_ add a HWSubmissionDevice entry for the device
1900
driven by the kernel's sd driver. So, when we query the number of
1901
disks driven by the sd driver, we'll get 1 as without the recently
1902
added device.
1903
8311.2.2 by Abel Deuring
changed the function num_devices_in_submissions and num_submissions_with_device into mehtods of HWSubmissionDeviceSet resp. HWSubmissionSet
1904
    >>> print submission_device_set.numDevicesInSubmissions(
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
1905
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
1906
    ...     driver_name='sd')
1907
    1
1908
8697.19.1 by Abel Deuring
allow driver-only queries for HWDB statistics methods.
1909
Let's now create another HWDB submission, and let's add
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
1910
HWSubmissionDevice entries for the disk and the new submission, both
1911
for the "plain" disk and for the disk driven by the sd driver.
1912
1913
    >>> LaunchpadZopelessLayer.txn.commit()
1914
    >>> LaunchpadZopelessLayer.switchDbUser('launchpad')
1915
    >>> # Set the emailaddress and hence the owner to a non-default
1916
    >>> # value so that we have submissions with different owners.
1917
    >>> submission = factory.makeHWSubmission(
1918
    ...     emailaddress='foo.bar@canonical.com')
1919
    >>> LaunchpadZopelessLayer.txn.commit()
1920
    >>> LaunchpadZopelessLayer.switchDbUser('hwdb-submission-processor')
1921
    >>> first_device = factory.makeHWSubmissionDevice(
1922
    ...     submission, ide_disk, None, None, 1)
1923
    >>> driver = getUtility(IHWDriverSet).getOrCreate(
1924
    ...     'linux-image-generic', 'sd')
1925
    >>> factory.makeHWSubmissionDevice(
1926
    ...     submission, ide_disk, driver, first_device, 2)
1927
    <HWSubmissionDevice at...
10234.3.3 by Curtis Hovey
Migrated hardward database to lp. Updated test_doc to run the hwddb test.
1928
    >>> from lp.hardwaredb.interfaces.hwdb import (
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
1929
    ...    HWSubmissionProcessingStatus)
1930
    >>> # We consider only submissions in the status PROCESSED for
1931
    >>> # statistics.
1932
    >>> submission.status = HWSubmissionProcessingStatus.PROCESSED
1933
    >>> LaunchpadZopelessLayer.txn.commit()
1934
8311.2.3 by Abel Deuring
implemented revier's comments
1935
The number of all ST3250820NS disks and of those disks driven by
1936
the sd driver has now increased by 1.
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
1937
8311.2.2 by Abel Deuring
changed the function num_devices_in_submissions and num_submissions_with_device into mehtods of HWSubmissionDeviceSet resp. HWSubmissionSet
1938
    >>> print submission_device_set.numDevicesInSubmissions(
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
1939
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ')
1940
    3
8311.2.2 by Abel Deuring
changed the function num_devices_in_submissions and num_submissions_with_device into mehtods of HWSubmissionDeviceSet resp. HWSubmissionSet
1941
    >>> print submission_device_set.numDevicesInSubmissions(
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
1942
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
1943
    ...     driver_name='sd')
1944
    2
1945
1946
We can optionally specify a driver's package name too.
1947
8311.2.2 by Abel Deuring
changed the function num_devices_in_submissions and num_submissions_with_device into mehtods of HWSubmissionDeviceSet resp. HWSubmissionSet
1948
    >>> print submission_device_set.numDevicesInSubmissions(
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
1949
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
1950
    ...     driver_name='sd', package_name='linux-image-2.6.24-19-generic')
1951
    1
8311.2.2 by Abel Deuring
changed the function num_devices_in_submissions and num_submissions_with_device into mehtods of HWSubmissionDeviceSet resp. HWSubmissionSet
1952
    >>> print submission_device_set.numDevicesInSubmissions(
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
1953
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
1954
    ...     driver_name='sd', package_name='nonsense')
1955
    0
1956
1957
And we can query for devices having any driver from a given package too.
1958
8311.2.2 by Abel Deuring
changed the function num_devices_in_submissions and num_submissions_with_device into mehtods of HWSubmissionDeviceSet resp. HWSubmissionSet
1959
    >>> print submission_device_set.numDevicesInSubmissions(
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
1960
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
1961
    ...     package_name='linux-image-2.6.24-19-generic')
1962
    1
8311.2.2 by Abel Deuring
changed the function num_devices_in_submissions and num_submissions_with_device into mehtods of HWSubmissionDeviceSet resp. HWSubmissionSet
1963
    >>> print submission_device_set.numDevicesInSubmissions(
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
1964
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
1965
    ...     package_name='nonsense')
1966
    0
1967
8697.19.1 by Abel Deuring
allow driver-only queries for HWDB statistics methods.
1968
We can also get the number of all devices controlled by a given driver.
1969
1970
    >>> print submission_device_set.numDevicesInSubmissions(
1971
    ...     driver_name='sd')
1972
    6
1973
1974
We can limit this count to a given package.
1975
1976
    >>> print submission_device_set.numDevicesInSubmissions(
1977
    ...     driver_name='sd', package_name='linux-image-2.6.24-19-generic')
1978
    5
1979
1980
While the parameters for a device or a driver are optional, specifying
1981
neither of them leads to an error.
1982
1983
    >>> submission_device_set.numDevicesInSubmissions()
1984
    Traceback (most recent call last):
1985
    ...
1986
    ParameterError: Specify (bus, vendor_id, product_id) or driver_name.
1987
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
1988
We can additionally query for devices in submissions made for a given
1989
distribution. The device from the new submission we just created is
1990
not counted here, because we created the new submission for a new
1991
distribution.
1992
1993
    >>> LaunchpadZopelessLayer.switchDbUser('launchpad')
8311.2.2 by Abel Deuring
changed the function num_devices_in_submissions and num_submissions_with_device into mehtods of HWSubmissionDeviceSet resp. HWSubmissionSet
1994
    >>> print submission_device_set.numDevicesInSubmissions(
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
1995
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
1996
    ...     distro_target=ubuntu)
1997
    2
8311.2.2 by Abel Deuring
changed the function num_devices_in_submissions and num_submissions_with_device into mehtods of HWSubmissionDeviceSet resp. HWSubmissionSet
1998
    >>> print submission_device_set.numDevicesInSubmissions(
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
1999
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2000
    ...     distro_target=debian)
2001
    0
2002
2003
Similary, we can limit the count to devices mentioned in submissions
2004
made for a given distroseries.
2005
8311.2.2 by Abel Deuring
changed the function num_devices_in_submissions and num_submissions_with_device into mehtods of HWSubmissionDeviceSet resp. HWSubmissionSet
2006
    >>> print submission_device_set.numDevicesInSubmissions(
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
2007
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2008
    ...     distro_target=ubuntu['hoary'])
2009
    2
8311.2.2 by Abel Deuring
changed the function num_devices_in_submissions and num_submissions_with_device into mehtods of HWSubmissionDeviceSet resp. HWSubmissionSet
2010
    >>> print submission_device_set.numDevicesInSubmissions(
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
2011
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2012
    ...     distro_target=ubuntu['warty'])
2013
    0
2014
2015
And we can also search for devices mentioned in submissions made on a
2016
given processor architecture.
2017
8311.2.2 by Abel Deuring
changed the function num_devices_in_submissions and num_submissions_with_device into mehtods of HWSubmissionDeviceSet resp. HWSubmissionSet
2018
    >>> print submission_device_set.numDevicesInSubmissions(
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
2019
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2020
    ...     distro_target=ubuntu['hoary']['i386'])
2021
    2
8311.2.2 by Abel Deuring
changed the function num_devices_in_submissions and num_submissions_with_device into mehtods of HWSubmissionDeviceSet resp. HWSubmissionSet
2022
    >>> print submission_device_set.numDevicesInSubmissions(
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
2023
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2024
    ...     distro_target=ubuntu['hoary']['hppa'])
2025
    0
2026
2027
We can also query the number of devices controlled by a given driver
2028
for a distrotarget.
2029
8311.2.2 by Abel Deuring
changed the function num_devices_in_submissions and num_submissions_with_device into mehtods of HWSubmissionDeviceSet resp. HWSubmissionSet
2030
    >>> print submission_device_set.numDevicesInSubmissions(
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
2031
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2032
    ...     driver_name='sd', distro_target=ubuntu['hoary']['i386'])
2033
    1
8311.2.2 by Abel Deuring
changed the function num_devices_in_submissions and num_submissions_with_device into mehtods of HWSubmissionDeviceSet resp. HWSubmissionSet
2034
    >>> print submission_device_set.numDevicesInSubmissions(
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
2035
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2036
    ...     driver_name='nonsense', distro_target=ubuntu['hoary']['i386'])
2037
    0
2038
2039
And we can additionally specify a package name.
2040
8311.2.2 by Abel Deuring
changed the function num_devices_in_submissions and num_submissions_with_device into mehtods of HWSubmissionDeviceSet resp. HWSubmissionSet
2041
    >>> print submission_device_set.numDevicesInSubmissions(
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
2042
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2043
    ...     driver_name='sd', package_name='linux-image-2.6.24-19-generic',
2044
    ...     distro_target=ubuntu['hoary']['i386'])
2045
    1
8311.2.2 by Abel Deuring
changed the function num_devices_in_submissions and num_submissions_with_device into mehtods of HWSubmissionDeviceSet resp. HWSubmissionSet
2046
    >>> print submission_device_set.numDevicesInSubmissions(
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
2047
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2048
    ...     driver_name='sd', package_name='nonsense',
2049
    ...     distro_target=ubuntu['hoary']['i386'])
2050
    0
2051
8311.2.2 by Abel Deuring
changed the function num_devices_in_submissions and num_submissions_with_device into mehtods of HWSubmissionDeviceSet resp. HWSubmissionSet
2052
HWSubmissionSet.numSubmissionsWithDevice() returns all submissions
2053
mentioning a given device and all processed submissions.
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
2054
2055
We have currently two processed submissions, both containing the
2056
Seagate ST3250820NS disk. Let's add another submission for hoary/i386
2057
and mark it as "processed" so that we have one processed submission
2058
that does not contain this disk.
2059
2060
    >>> submission = factory.makeHWSubmission(
2061
    ...     distroarchseries=ubuntu['hoary']['i386'])
2062
    >>> submission.status = HWSubmissionProcessingStatus.PROCESSED
2063
8311.2.2 by Abel Deuring
changed the function num_devices_in_submissions and num_submissions_with_device into mehtods of HWSubmissionDeviceSet resp. HWSubmissionSet
2064
    >>> submission_set = getUtility(IHWSubmissionSet)
2065
    >>> print submission_set.numSubmissionsWithDevice(
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
2066
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ')
2067
    (2L, 3L)
2068
2069
We can limit the results to a given driver...
2070
8311.2.2 by Abel Deuring
changed the function num_devices_in_submissions and num_submissions_with_device into mehtods of HWSubmissionDeviceSet resp. HWSubmissionSet
2071
    >>> print submission_set.numSubmissionsWithDevice(
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
2072
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2073
    ...     driver_name='sd')
2074
    (2L, 3L)
8311.2.2 by Abel Deuring
changed the function num_devices_in_submissions and num_submissions_with_device into mehtods of HWSubmissionDeviceSet resp. HWSubmissionSet
2075
    >>> print submission_set.numSubmissionsWithDevice(
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
2076
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2077
    ...     driver_name='usb')
2078
    (0L, 3L)
2079
8697.19.1 by Abel Deuring
allow driver-only queries for HWDB statistics methods.
2080
...or we can ask for all submissions containing any device controlled
2081
by a given driver.
2082
2083
    >>> print submission_set.numSubmissionsWithDevice(
2084
    ...     driver_name='sd')
2085
    (2L, 3L)
2086
2087
While the parameters for a device or a driver are optional, specifying
2088
neither of them leads to an error.
2089
2090
    >>> print submission_set.numSubmissionsWithDevice()
2091
    Traceback (most recent call last):
2092
    ...
2093
    ParameterError: Specify (bus, vendor_id, product_id) or driver_name.
2094
2095
This count can be limited to a given package.
2096
2097
    >>> print submission_set.numSubmissionsWithDevice(
2098
    ...     driver_name='sd', package_name='linux-image-2.6.24-19-generic')
2099
    (1L, 3L)
2100
2101
We can also limit the count to a distibution...
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
2102
8311.2.2 by Abel Deuring
changed the function num_devices_in_submissions and num_submissions_with_device into mehtods of HWSubmissionDeviceSet resp. HWSubmissionSet
2103
    >>> print submission_set.numSubmissionsWithDevice(
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
2104
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2105
    ...     distro_target=ubuntu)
2106
    (1L, 2L)
8311.2.2 by Abel Deuring
changed the function num_devices_in_submissions and num_submissions_with_device into mehtods of HWSubmissionDeviceSet resp. HWSubmissionSet
2107
    >>> print submission_set.numSubmissionsWithDevice(
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
2108
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2109
    ...     distro_target=debian)
2110
    (0L, 0L)
2111
2112
...to a distroseries...
2113
8311.2.2 by Abel Deuring
changed the function num_devices_in_submissions and num_submissions_with_device into mehtods of HWSubmissionDeviceSet resp. HWSubmissionSet
2114
    >>> print submission_set.numSubmissionsWithDevice(
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
2115
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2116
    ...     distro_target=ubuntu['hoary'])
2117
    (1L, 2L)
8311.2.2 by Abel Deuring
changed the function num_devices_in_submissions and num_submissions_with_device into mehtods of HWSubmissionDeviceSet resp. HWSubmissionSet
2118
    >>> print submission_set.numSubmissionsWithDevice(
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
2119
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2120
    ...     distro_target=ubuntu['warty'])
2121
    (0L, 0L)
2122
2123
...or to a distroarchseries.
2124
8311.2.2 by Abel Deuring
changed the function num_devices_in_submissions and num_submissions_with_device into mehtods of HWSubmissionDeviceSet resp. HWSubmissionSet
2125
    >>> print submission_set.numSubmissionsWithDevice(
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
2126
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2127
    ...     distro_target=ubuntu['hoary']['i386'])
2128
    (1L, 2L)
8311.2.2 by Abel Deuring
changed the function num_devices_in_submissions and num_submissions_with_device into mehtods of HWSubmissionDeviceSet resp. HWSubmissionSet
2129
    >>> print submission_set.numSubmissionsWithDevice(
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
2130
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2131
    ...     distro_target=ubuntu['hoary']['hppa'])
2132
    (0L, 0L)
2133
2134
We can specify a distro target as well as a driver or package name.
2135
8311.2.2 by Abel Deuring
changed the function num_devices_in_submissions and num_submissions_with_device into mehtods of HWSubmissionDeviceSet resp. HWSubmissionSet
2136
    >>> print submission_set.numSubmissionsWithDevice(
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
2137
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2138
    ...     driver_name='sd', distro_target=ubuntu['hoary']['i386'])
2139
    (1L, 2L)
8311.2.2 by Abel Deuring
changed the function num_devices_in_submissions and num_submissions_with_device into mehtods of HWSubmissionDeviceSet resp. HWSubmissionSet
2140
    >>> print submission_set.numSubmissionsWithDevice(
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
2141
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2142
    ...     driver_name='nosense', distro_target=ubuntu['hoary']['i386'])
2143
    (0L, 2L)
2144
8311.2.2 by Abel Deuring
changed the function num_devices_in_submissions and num_submissions_with_device into mehtods of HWSubmissionDeviceSet resp. HWSubmissionSet
2145
    >>> print submission_set.numSubmissionsWithDevice(
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
2146
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2147
    ...     package_name='linux-image-2.6.24-19-generic',
2148
    ...     distro_target=ubuntu['hoary']['i386'])
2149
    (1L, 2L)
8311.2.2 by Abel Deuring
changed the function num_devices_in_submissions and num_submissions_with_device into mehtods of HWSubmissionDeviceSet resp. HWSubmissionSet
2150
    >>> print submission_set.numSubmissionsWithDevice(
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
2151
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2152
    ...     package_name='nonsense', distro_target=ubuntu['hoary']['i386'])
2153
    (0L, 2L)
2154
8311.2.2 by Abel Deuring
changed the function num_devices_in_submissions and num_submissions_with_device into mehtods of HWSubmissionDeviceSet resp. HWSubmissionSet
2155
    >>> print submission_set.numSubmissionsWithDevice(
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
2156
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2157
    ...     driver_name='sd', package_name='linux-image-2.6.24-19-generic',
2158
    ...     distro_target=ubuntu['hoary']['i386'])
2159
    (1L, 2L)
8311.2.2 by Abel Deuring
changed the function num_devices_in_submissions and num_submissions_with_device into mehtods of HWSubmissionDeviceSet resp. HWSubmissionSet
2160
    >>> print submission_set.numSubmissionsWithDevice(
8311.2.1 by Abel Deuring
Functions to count how often a given device appears in HWDB subissions and how many HWDB submissions contain a given device.
2161
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2162
    ...     driver_name='nonsense',
2163
    ...     package_name='linux-image-2.6.24-19-generic',
2164
    ...     distro_target=ubuntu['hoary']['i386'])
2165
    (0L, 2L)
8366.1.1 by Abel Deuring
HWSubmission.numDeviceOwners() added, counting the the number of device owners.
2166
2167
HWSubmission.numDeviceOwners() returns the number of device owners.
2168
Note that we identify owners by the email address as queried by the
2169
HWDB client, not by HWSubmission.owner.
2170
2171
We have currently three submissions from two submitters, and submissions
8697.19.1 by Abel Deuring
allow driver-only queries for HWDB statistics methods.
2172
from both submitters mention the Seagate ST3250820NS disk. Let's add
8366.1.1 by Abel Deuring
HWSubmission.numDeviceOwners() added, counting the the number of device owners.
2173
another, empty, submission for hoary/i386 from another submitter.
2174
2175
    >>> submission = factory.makeHWSubmission(
2176
    ...     emailaddress='charles@babbage.com',
2177
    ...     distroarchseries=ubuntu['hoary']['i386'])
2178
    >>> submission.status = HWSubmissionProcessingStatus.PROCESSED
2179
2180
Now we have three submitters, two of them own our Seagate disk.
2181
2182
    >>> submission_set.numOwnersOfDevice(
2183
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ')
2184
    (2L, 3L)
2185
8697.19.1 by Abel Deuring
allow driver-only queries for HWDB statistics methods.
2186
We can limit the results to a given driver.
8366.1.1 by Abel Deuring
HWSubmission.numDeviceOwners() added, counting the the number of device owners.
2187
2188
    >>> print submission_set.numOwnersOfDevice(
2189
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2190
    ...     driver_name='sd')
2191
    (2L, 3L)
2192
    >>> print submission_set.numOwnersOfDevice(
2193
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2194
    ...     driver_name='usb')
2195
    (0L, 3L)
2196
8697.19.1 by Abel Deuring
allow driver-only queries for HWDB statistics methods.
2197
We can also ask for submitters who use a given driver with any device.
2198
2199
    >>> print submission_set.numOwnersOfDevice(
2200
    ...     driver_name='sd')
2201
    (2L, 3L)
2202
2203
This count can be limited to a given package.
2204
2205
    >>> print submission_set.numOwnersOfDevice(
2206
    ...     driver_name='sd', package_name='linux-image-2.6.24-19-generic')
2207
    (1L, 3L)
2208
2209
While the parameters for a device or a driver are optional, specifying
2210
neither of them leads to an error.
2211
2212
    >>> print submission_set.numOwnersOfDevice()
2213
    Traceback (most recent call last):
2214
    ...
2215
    ParameterError: Specify (bus, vendor_id, product_id) or driver_name.
2216
2217
We can limit the count to a distibution...
8366.1.1 by Abel Deuring
HWSubmission.numDeviceOwners() added, counting the the number of device owners.
2218
2219
    >>> print submission_set.numOwnersOfDevice(
2220
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2221
    ...     distro_target=ubuntu)
2222
    (1L, 2L)
2223
    >>> print submission_set.numOwnersOfDevice(
2224
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2225
    ...     distro_target=debian)
2226
    (0L, 0L)
2227
2228
...to a distroseries...
2229
2230
    >>> print submission_set.numOwnersOfDevice(
2231
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2232
    ...     distro_target=ubuntu['hoary'])
2233
    (1L, 2L)
2234
    >>> print submission_set.numOwnersOfDevice(
2235
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2236
    ...     distro_target=ubuntu['warty'])
2237
    (0L, 0L)
2238
2239
...or to a distroarchseries.
2240
2241
    >>> print submission_set.numOwnersOfDevice(
2242
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2243
    ...     distro_target=ubuntu['hoary']['i386'])
2244
    (1L, 2L)
2245
    >>> print submission_set.numOwnersOfDevice(
2246
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2247
    ...     distro_target=ubuntu['hoary']['hppa'])
2248
    (0L, 0L)
2249
2250
We can specify a distro target as well as a driver or package name.
2251
2252
    >>> print submission_set.numOwnersOfDevice(
2253
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2254
    ...     driver_name='sd', distro_target=ubuntu['hoary']['i386'])
2255
    (1L, 2L)
2256
    >>> print submission_set.numOwnersOfDevice(
2257
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2258
    ...     driver_name='nosense', distro_target=ubuntu['hoary']['i386'])
2259
    (0L, 2L)
2260
2261
    >>> print submission_set.numOwnersOfDevice(
2262
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2263
    ...     package_name='linux-image-2.6.24-19-generic',
2264
    ...     distro_target=ubuntu['hoary']['i386'])
2265
    (1L, 2L)
2266
    >>> print submission_set.numOwnersOfDevice(
2267
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2268
    ...     package_name='nonsense', distro_target=ubuntu['hoary']['i386'])
2269
    (0L, 2L)
2270
2271
    >>> print submission_set.numOwnersOfDevice(
2272
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2273
    ...     driver_name='sd', package_name='linux-image-2.6.24-19-generic',
2274
    ...     distro_target=ubuntu['hoary']['i386'])
2275
    (1L, 2L)
2276
    >>> print submission_set.numOwnersOfDevice(
2277
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2278
    ...     driver_name='nonsense',
2279
    ...     package_name='linux-image-2.6.24-19-generic',
2280
    ...     distro_target=ubuntu['hoary']['i386'])
2281
    (0L, 2L)
8451.2.1 by Abel Deuring
Method added to retrieve a list of device owners who are affected by bugs
2282
2283
14050.3.1 by Jeroen Vermeulen
Lint.
2284
Relations between bugs and HWDB submissions
2285
-------------------------------------------
8451.2.1 by Abel Deuring
Method added to retrieve a list of device owners who are affected by bugs
2286
2287
We can query which owners of a device, or which people owning a device
2288
controlled by a given driver, are related to a set of bugs. We must
2289
specify a device's bus, vendor ID and product ID and one or more bugs.
2290
2291
By default, only bug reporters are looked up. Sample Person has made
2292
a hardware report containing the IDE disk Seagate ST3250820NS, and
2293
he has filed bug 1.
2294
8523.3.1 by Gavin Panella
Bugs tree reorg after automated migration.
2295
    >>> from lp.bugs.interfaces.bug import IBugSet
8451.2.1 by Abel Deuring
Method added to retrieve a list of device owners who are affected by bugs
2296
    >>> bug_set = getUtility(IBugSet)
2297
    >>> bug_one = bug_set.get(1)
2298
    >>> print bug_one.owner.displayname
2299
    Sample Person
8451.2.2 by Abel Deuring
allow to call deviceDriverOwnersAffectedByBugs only with a driver
2300
    >>> for person in submission_set.deviceDriverOwnersAffectedByBugs(
8451.2.1 by Abel Deuring
Method added to retrieve a list of device owners who are affected by bugs
2301
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2302
    ...     bug_ids=[1]):
2303
    ...     print person.displayname
2304
    Sample Person
2305
2306
If Foo Bar says that he is affected by this bug, he will be listed
2307
too, since he too owns the Seagate disk.
2308
2309
    >>> foo_bar = getUtility(IPersonSet).getByEmail('foo.bar@canonical.com')
2310
    >>> bug_one = bug_set.get(1)
2311
    >>> bug_one.markUserAffected(foo_bar)
8451.2.2 by Abel Deuring
allow to call deviceDriverOwnersAffectedByBugs only with a driver
2312
    >>> for person in submission_set.deviceDriverOwnersAffectedByBugs(
8451.2.1 by Abel Deuring
Method added to retrieve a list of device owners who are affected by bugs
2313
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2314
    ...     bug_ids=[1], affected_by_bug=True):
2315
    ...     print person.displayname
2316
    Foo Bar
2317
    Sample Person
2318
2319
When he says that he is not affected by the bug, he will no longer
2320
be listed.
2321
2322
    >>> bug_one.markUserAffected(foo_bar, False)
8451.2.2 by Abel Deuring
allow to call deviceDriverOwnersAffectedByBugs only with a driver
2323
    >>> for person in submission_set.deviceDriverOwnersAffectedByBugs(
8451.2.1 by Abel Deuring
Method added to retrieve a list of device owners who are affected by bugs
2324
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2325
    ...     bug_ids=[1], affected_by_bug=True):
2326
    ...     print person.displayname
2327
    Sample Person
2328
8451.2.3 by Abel Deuring
implemented reviewer's comments
2329
By setting the parameter subscribed_to_bug to True, we can also look
2330
for bug subscribers who own a given device.
8451.2.1 by Abel Deuring
Method added to retrieve a list of device owners who are affected by bugs
2331
2332
    >>> bug_one.subscribe(foo_bar, subscribed_by=foo_bar)
11536.1.2 by Gavin Panella
Fix many tests, and a bug or two.
2333
    <lp.bugs.model.bugsubscription.BugSubscription ...>
8451.2.2 by Abel Deuring
allow to call deviceDriverOwnersAffectedByBugs only with a driver
2334
    >>> for person in submission_set.deviceDriverOwnersAffectedByBugs(
8451.2.1 by Abel Deuring
Method added to retrieve a list of device owners who are affected by bugs
2335
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2336
    ...     bug_ids=[1], subscribed_to_bug=True):
2337
    ...     print person.displayname
2338
    Foo Bar
2339
    Sample Person
2340
2341
    >>> bug_one.unsubscribe(foo_bar, unsubscribed_by=foo_bar)
8451.2.2 by Abel Deuring
allow to call deviceDriverOwnersAffectedByBugs only with a driver
2342
    >>> for person in submission_set.deviceDriverOwnersAffectedByBugs(
8451.2.1 by Abel Deuring
Method added to retrieve a list of device owners who are affected by bugs
2343
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2344
    ...     bug_ids=[1], subscribed_to_bug=True):
2345
    ...     print person.displayname
2346
    Sample Person
2347
2348
We can specify more than one bug ID. If we specify bugs 1 and 3,
8451.2.2 by Abel Deuring
allow to call deviceDriverOwnersAffectedByBugs only with a driver
2349
deviceDriverOwnersAffectedByBugs() returns again Sample Person and
8451.2.1 by Abel Deuring
Method added to retrieve a list of device owners who are affected by bugs
2350
Foo Bar.
2351
2352
    >>> bug_three = bug_set.get(3)
2353
    >>> print bug_three.owner.displayname
2354
    Foo Bar
8451.2.2 by Abel Deuring
allow to call deviceDriverOwnersAffectedByBugs only with a driver
2355
    >>> for person in submission_set.deviceDriverOwnersAffectedByBugs(
8451.2.1 by Abel Deuring
Method added to retrieve a list of device owners who are affected by bugs
2356
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2357
    ...     bug_ids=[1, 3]):
2358
    ...     print person.displayname
2359
    Foo Bar
2360
    Sample Person
2361
2362
Instead of passing a seqence of bug IDs, we can also specify one or
2363
more bug tags.
2364
8426.9.15 by Gavin Panella
Fix an HWDB test that specified tags to search for without an any() or all() combinator.
2365
    >>> from canonical.launchpad.searchbuilder import any
11716.1.15 by Curtis Hovey
Fixed multiline import statements in doctests.
2366
    >>> from lp.bugs.interfaces.bugtask import (
11716.1.12 by Curtis Hovey
Sorted imports in doctests.
2367
    ...     BugTaskSearchParams,
2368
    ...     IBugTaskSet,
2369
    ...     )
8426.9.15 by Gavin Panella
Fix an HWDB test that specified tags to search for without an any() or all() combinator.
2370
8451.2.1 by Abel Deuring
Method added to retrieve a list of device owners who are affected by bugs
2371
    >>> bugtask_set = getUtility(IBugTaskSet)
2372
    >>> bugtasks = bugtask_set.search(
8426.9.15 by Gavin Panella
Fix an HWDB test that specified tags to search for without an any() or all() combinator.
2373
    ...     BugTaskSearchParams(user=foo_bar, tag=any('pebcak')))
8451.2.3 by Abel Deuring
implemented reviewer's comments
2374
    >>> owners = set(bugtask.bug.owner for bugtask in bugtasks)
8451.2.1 by Abel Deuring
Method added to retrieve a list of device owners who are affected by bugs
2375
    >>> for owner in owners:
8451.2.3 by Abel Deuring
implemented reviewer's comments
2376
    ...     print owner.displayname
8451.2.1 by Abel Deuring
Method added to retrieve a list of device owners who are affected by bugs
2377
    Sample Person
2378
    >>> bugtasks = bugtask_set.search(
8426.9.15 by Gavin Panella
Fix an HWDB test that specified tags to search for without an any() or all() combinator.
2379
    ...     BugTaskSearchParams(user=foo_bar, tag=any('crash')))
8451.2.3 by Abel Deuring
implemented reviewer's comments
2380
    >>> owners = set(bugtask.bug.owner for bugtask in bugtasks)
8451.2.1 by Abel Deuring
Method added to retrieve a list of device owners who are affected by bugs
2381
    >>> for owner in owners:
8451.2.3 by Abel Deuring
implemented reviewer's comments
2382
    ...     print owner.displayname
8451.2.1 by Abel Deuring
Method added to retrieve a list of device owners who are affected by bugs
2383
    Foo Bar
2384
8451.2.2 by Abel Deuring
allow to call deviceDriverOwnersAffectedByBugs only with a driver
2385
    >>> for person in submission_set.deviceDriverOwnersAffectedByBugs(
8451.2.1 by Abel Deuring
Method added to retrieve a list of device owners who are affected by bugs
2386
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2387
    ...     bug_tags=['pebcak']):
2388
    ...     print person.displayname
2389
    Sample Person
2390
8451.2.2 by Abel Deuring
allow to call deviceDriverOwnersAffectedByBugs only with a driver
2391
    >>> for person in submission_set.deviceDriverOwnersAffectedByBugs(
8451.2.1 by Abel Deuring
Method added to retrieve a list of device owners who are affected by bugs
2392
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2393
    ...     bug_tags=['pebcak', 'crash']):
2394
    ...     print person.displayname
2395
    Foo Bar
2396
    Sample Person
2397
8451.2.2 by Abel Deuring
allow to call deviceDriverOwnersAffectedByBugs only with a driver
2398
    >>> submission_set.deviceDriverOwnersAffectedByBugs(
8451.2.1 by Abel Deuring
Method added to retrieve a list of device owners who are affected by bugs
2399
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2400
    ...     bug_tags=['lunch-money']).count()
2401
    0
2402
8451.2.3 by Abel Deuring
implemented reviewer's comments
2403
We can limit the result to owners who use a device with a given driver
2404
by providing a driver_name parameter...
8451.2.1 by Abel Deuring
Method added to retrieve a list of device owners who are affected by bugs
2405
8451.2.2 by Abel Deuring
allow to call deviceDriverOwnersAffectedByBugs only with a driver
2406
    >>> for person in submission_set.deviceDriverOwnersAffectedByBugs(
8451.2.1 by Abel Deuring
Method added to retrieve a list of device owners who are affected by bugs
2407
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2408
    ...     driver_name='sd', bug_tags=['pebcak', 'crash']):
2409
    ...     print person.displayname
2410
    Foo Bar
2411
    Sample Person
2412
8451.2.2 by Abel Deuring
allow to call deviceDriverOwnersAffectedByBugs only with a driver
2413
    >>> print submission_set.deviceDriverOwnersAffectedByBugs(
8451.2.1 by Abel Deuring
Method added to retrieve a list of device owners who are affected by bugs
2414
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2415
    ...     driver_name='nonsense', bug_tags=['pebcak', 'crash']).count()
2416
    0
2417
8451.2.3 by Abel Deuring
implemented reviewer's comments
2418
...or a given package name by providing a package_name parameter.
8451.2.1 by Abel Deuring
Method added to retrieve a list of device owners who are affected by bugs
2419
8451.2.2 by Abel Deuring
allow to call deviceDriverOwnersAffectedByBugs only with a driver
2420
    >>> for person in submission_set.deviceDriverOwnersAffectedByBugs(
8451.2.1 by Abel Deuring
Method added to retrieve a list of device owners who are affected by bugs
2421
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2422
    ...     package_name='linux-image-2.6.24-19-generic',
2423
    ...     bug_tags=['pebcak', 'crash']):
2424
    ...     print person.displayname
2425
    Sample Person
2426
8451.2.2 by Abel Deuring
allow to call deviceDriverOwnersAffectedByBugs only with a driver
2427
    >>> print submission_set.deviceDriverOwnersAffectedByBugs(
8451.2.1 by Abel Deuring
Method added to retrieve a list of device owners who are affected by bugs
2428
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2429
    ...     package_name='nonsense', bug_tags=['pebcak', 'crash']).count()
2430
    0
2431
2432
Owners of private submissions are only included if the optional parameter
2433
`user` is the owner or an admin.
2434
2435
    >>> private_submission = factory.makeHWSubmission(
2436
    ...     emailaddress='no-priv@canonical.com', private=True)
2437
    >>> LaunchpadZopelessLayer.txn.commit()
2438
    >>> LaunchpadZopelessLayer.switchDbUser('hwdb-submission-processor')
2439
    >>> first_device = factory.makeHWSubmissionDevice(
2440
    ...     private_submission, ide_disk, None, None, 1)
2441
    >>> LaunchpadZopelessLayer.txn.commit()
2442
    >>> LaunchpadZopelessLayer.switchDbUser('launchpad')
2443
    >>> no_priv = getUtility(IPersonSet).getByEmail('no-priv@canonical.com')
2444
    >>> bug_one.subscribe(no_priv, subscribed_by=no_priv)
11536.1.2 by Gavin Panella
Fix many tests, and a bug or two.
2445
    <lp.bugs.model.bugsubscription.BugSubscription ...>
8451.2.2 by Abel Deuring
allow to call deviceDriverOwnersAffectedByBugs only with a driver
2446
    >>> for person in submission_set.deviceDriverOwnersAffectedByBugs(
8451.2.1 by Abel Deuring
Method added to retrieve a list of device owners who are affected by bugs
2447
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2448
    ...     bug_ids=[1], subscribed_to_bug=True, user=no_priv):
2449
    ...     print person.displayname
2450
    No Privileges Person
2451
    Sample Person
2452
8451.2.2 by Abel Deuring
allow to call deviceDriverOwnersAffectedByBugs only with a driver
2453
    >>> for person in submission_set.deviceDriverOwnersAffectedByBugs(
8451.2.1 by Abel Deuring
Method added to retrieve a list of device owners who are affected by bugs
2454
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2455
    ...     bug_ids=[1], subscribed_to_bug=True, user=foo_bar):
2456
    ...     print person.displayname
2457
    No Privileges Person
2458
    Sample Person
2459
2460
    >>> sample_person = getUtility(IPersonSet).getByEmail(
2461
    ...     'test@canonical.com')
8451.2.2 by Abel Deuring
allow to call deviceDriverOwnersAffectedByBugs only with a driver
2462
    >>> for person in submission_set.deviceDriverOwnersAffectedByBugs(
8451.2.1 by Abel Deuring
Method added to retrieve a list of device owners who are affected by bugs
2463
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2464
    ...     bug_ids=[1], subscribed_to_bug=True, user=sample_person):
2465
    ...     print person.displayname
2466
    Sample Person
2467
8451.2.2 by Abel Deuring
allow to call deviceDriverOwnersAffectedByBugs only with a driver
2468
    >>> for person in submission_set.deviceDriverOwnersAffectedByBugs(
8451.2.1 by Abel Deuring
Method added to retrieve a list of device owners who are affected by bugs
2469
    ...     bus=HWBus.IDE, vendor_id='SEAGATE', product_id='ST3250820NS     ',
2470
    ...     bug_ids=[1], subscribed_to_bug=True):
2471
    ...     print person.displayname
2472
    Sample Person
8451.2.2 by Abel Deuring
allow to call deviceDriverOwnersAffectedByBugs only with a driver
2473
2474
14050.3.1 by Jeroen Vermeulen
Lint.
2475
Searching for drivers instead of devices
2476
........................................
8451.2.2 by Abel Deuring
allow to call deviceDriverOwnersAffectedByBugs only with a driver
2477
2478
We can also look for people using a given driver and being affected by a
2479
bug.
2480
2481
    >>> for person in submission_set.deviceDriverOwnersAffectedByBugs(
2482
    ...     driver_name='sd', bug_ids=[1]):
2483
    ...     print person.displayname
2484
    Sample Person
2485
2486
If Foo Bar says that he is affected by this bug, he will be listed
2487
too, since his machine too uses the sd driver.
2488
2489
    >>> bug_one.markUserAffected(foo_bar)
2490
    >>> for person in submission_set.deviceDriverOwnersAffectedByBugs(
2491
    ...     driver_name='sd', bug_ids=[1], affected_by_bug=True):
2492
    ...     print person.displayname
2493
    Foo Bar
2494
    Sample Person
2495
2496
He is also listed, if he subscribes to bug 1.
2497
2498
    >>> bug_one.markUserAffected(foo_bar, False)
2499
    >>> bug_one.subscribe(foo_bar, subscribed_by=foo_bar)
11536.1.2 by Gavin Panella
Fix many tests, and a bug or two.
2500
    <lp.bugs.model.bugsubscription.BugSubscription ...>
8451.2.2 by Abel Deuring
allow to call deviceDriverOwnersAffectedByBugs only with a driver
2501
    >>> for person in submission_set.deviceDriverOwnersAffectedByBugs(
2502
    ...     driver_name='sd', bug_ids=[1], subscribed_to_bug=True):
2503
    ...     print person.displayname
2504
    Foo Bar
2505
    Sample Person
2506
2507
We can specify more than one bug ID. If we specify bugs 1 and 3,
2508
deviceDriverOwnersAffectedByBugs() returns again Sample Person and
2509
Foo Bar.
2510
2511
    >>> bug_one.unsubscribe(foo_bar, unsubscribed_by=foo_bar)
2512
    >>> for person in submission_set.deviceDriverOwnersAffectedByBugs(
2513
    ...     driver_name='sd', bug_ids=[1, 3]):
2514
    ...     print person.displayname
2515
    Foo Bar
2516
    Sample Person
2517
8451.2.3 by Abel Deuring
implemented reviewer's comments
2518
Instead of passing a sequence of bug IDs, we can also specify one or
8451.2.2 by Abel Deuring
allow to call deviceDriverOwnersAffectedByBugs only with a driver
2519
more bug tags.
2520
2521
    >>> for person in submission_set.deviceDriverOwnersAffectedByBugs(
2522
    ...     driver_name='sd', bug_tags=['pebcak']):
2523
    ...     print person.displayname
2524
    Sample Person
2525
2526
    >>> for person in submission_set.deviceDriverOwnersAffectedByBugs(
2527
    ...     driver_name='sd', bug_tags=['pebcak', 'crash']):
2528
    ...     print person.displayname
2529
    Foo Bar
2530
    Sample Person
2531
2532
    >>> submission_set.deviceDriverOwnersAffectedByBugs(
2533
    ...     driver_name='sd', bug_tags=['lunch-money']).count()
2534
    0
2535
8451.4.5 by Deryck Hodge
Update an older method to use And for bug_ids and bug_tags
2536
We can also query for both bug ids and bug tags together.
2537
2538
    >>> for person in submission_set.deviceDriverOwnersAffectedByBugs(
2539
    ...     driver_name='sd', bug_ids=[2], bug_tags=['pebcak']):
2540
    ...     print person.displayname
2541
    Sample Person
2542
2543
Also, confirm that nothing is returned where there is no matching
2544
tag on a given bug id.
2545
2546
    >>> print len(list(submission_set.deviceDriverOwnersAffectedByBugs(
2547
    ...     driver_name='sd', bug_ids=[3], bug_tags=['pebcak'])))
2548
    0
2549
8451.2.2 by Abel Deuring
allow to call deviceDriverOwnersAffectedByBugs only with a driver
2550
If neither a device nor a driver name is specified,
2551
deviceDriverOwnersAffectedByBugs() raises an error.
2552
2553
    >>> submission_set.deviceDriverOwnersAffectedByBugs(
2554
    ...     bug_tags=['lunch-money'])
2555
    Traceback (most recent call last):
2556
    ...
2557
    ParameterError: Specify (bus, vendor_id, product_id) or driver_name.
2558
2559
If one of the parameters bus, vendor_id, product_id is supplied, the
2560
others must be supplied too.
2561
2562
    >>> submission_set.deviceDriverOwnersAffectedByBugs(
2563
    ...     bus=HWBus.IDE, bug_ids=[1], subscribed_to_bug=True)
2564
    Traceback (most recent call last):
2565
    ...
2566
    ParameterError: Either specify bus, vendor_id and product_id or none
2567
    of them.
8451.4.1 by Deryck Hodge
Enabling deviceDriversByOwner for HWSubmissionSet and the
2568
2569
For a given bug, we can get a list of devices by device owner.
2570
The result is a tuple of (owner_id, bus_number, vender_id, product_id).
2571
2572
    >>> sample_person = getUtility(IPersonSet).getByName('name12')
2573
8451.4.5 by Deryck Hodge
Update an older method to use And for bug_ids and bug_tags
2574
    >>> for entry in submission_set.hwInfoByBugRelatedUsers(
8451.4.1 by Deryck Hodge
Enabling deviceDriversByOwner for HWSubmissionSet and the
2575
    ...     bug_ids=[1]):
2576
    ...     print entry
2577
    (u'name12', <DBItem HWBus.SYSTEM, (0) System>, u'MSI', u'MS-7369')
2578
    (u'name12', <DBItem HWBus.SYSTEM, (0) System>, u'Tonka', u'Tuffbook 2600')
2579
    (u'name12', <DBItem HWBus.PCI, (1) PCI>, u'0x10de', u'0x0455')
2580
    (u'name12', <DBItem HWBus.PCI, (1) PCI>, u'0x10de', u'0x045d')
2581
    (u'name12', <DBItem HWBus.PCI, (1) PCI>, u'0x8086', u'0x27cc')
2582
    (u'name12', <DBItem HWBus.USB, (2) USB>, u'0x04b4', u'0x6560')
2583
    (u'name12', <DBItem HWBus.USB, (2) USB>, u'0x07b3', u'0x0017')
2584
    (u'name12', <DBItem HWBus.USB, (2) USB>, u'0x0dda', u'0x2026')
2585
    (u'name12', <DBItem HWBus.USB, (2) USB>, u'0x8086', u'0x1234')
2586
    (u'name12', <DBItem HWBus.IDE, (7) IDE>, u'Optiarc', u'DVD RW AD-7170S ')
2587
    (u'name12', <DBItem HWBus.IDE, (7) IDE>, u'SEAGATE', u'ST3250820NS     ')
2588
2589
This method can also take a list of bugs.
2590
8451.4.5 by Deryck Hodge
Update an older method to use And for bug_ids and bug_tags
2591
    >>> for entry in submission_set.hwInfoByBugRelatedUsers(
8451.4.1 by Deryck Hodge
Enabling deviceDriversByOwner for HWSubmissionSet and the
2592
    ...     bug_ids=[1, 3]):
2593
    ...     print entry
2594
    (u'name12', <DBItem HWBus.SYSTEM, (0) System>, u'MSI', u'MS-7369')
2595
    (u'name12', <DBItem HWBus.SYSTEM, (0) System>, u'Tonka', u'Tuffbook 2600')
2596
    (u'name12', <DBItem HWBus.PCI, (1) PCI>, u'0x10de', u'0x0455')
2597
    (u'name12', <DBItem HWBus.PCI, (1) PCI>, u'0x10de', u'0x045d')
2598
    (u'name12', <DBItem HWBus.PCI, (1) PCI>, u'0x8086', u'0x27cc')
2599
    (u'name12', <DBItem HWBus.USB, (2) USB>, u'0x04b4', u'0x6560')
2600
    (u'name12', <DBItem HWBus.USB, (2) USB>, u'0x07b3', u'0x0017')
2601
    (u'name12', <DBItem HWBus.USB, (2) USB>, u'0x0dda', u'0x2026')
2602
    (u'name12', <DBItem HWBus.USB, (2) USB>, u'0x8086', u'0x1234')
2603
    (u'name12', <DBItem HWBus.IDE, (7) IDE>, u'Optiarc', u'DVD RW AD-7170S ')
2604
    (u'name12', <DBItem HWBus.IDE, (7) IDE>, u'SEAGATE', u'ST3250820NS     ')
2605
    (u'name16', <DBItem HWBus.IDE, (7) IDE>, u'SEAGATE', u'ST3250820NS     ')
2606
2607
We can also query for bug tags instead of bug numbers.
2608
8451.4.5 by Deryck Hodge
Update an older method to use And for bug_ids and bug_tags
2609
    >>> for entry in submission_set.hwInfoByBugRelatedUsers(
8451.4.1 by Deryck Hodge
Enabling deviceDriversByOwner for HWSubmissionSet and the
2610
    ...     bug_tags=['pebcak']):
2611
    ...     print entry
2612
    (u'name12', <DBItem HWBus.SYSTEM, (0) System>, u'MSI', u'MS-7369')
2613
    (u'name12', <DBItem HWBus.SYSTEM, (0) System>, u'Tonka', u'Tuffbook 2600')
2614
    (u'name12', <DBItem HWBus.PCI, (1) PCI>, u'0x10de', u'0x0455')
2615
    (u'name12', <DBItem HWBus.PCI, (1) PCI>, u'0x10de', u'0x045d')
2616
    (u'name12', <DBItem HWBus.PCI, (1) PCI>, u'0x8086', u'0x27cc')
2617
    (u'name12', <DBItem HWBus.USB, (2) USB>, u'0x04b4', u'0x6560')
2618
    (u'name12', <DBItem HWBus.USB, (2) USB>, u'0x07b3', u'0x0017')
2619
    (u'name12', <DBItem HWBus.USB, (2) USB>, u'0x0dda', u'0x2026')
2620
    (u'name12', <DBItem HWBus.USB, (2) USB>, u'0x8086', u'0x1234')
2621
    (u'name12', <DBItem HWBus.IDE, (7) IDE>, u'Optiarc', u'DVD RW AD-7170S ')
2622
    (u'name12', <DBItem HWBus.IDE, (7) IDE>, u'SEAGATE', u'ST3250820NS     ')
2623
8451.4.5 by Deryck Hodge
Update an older method to use And for bug_ids and bug_tags
2624
    >>> for entry in submission_set.hwInfoByBugRelatedUsers(
8451.4.1 by Deryck Hodge
Enabling deviceDriversByOwner for HWSubmissionSet and the
2625
    ...     bug_tags=['pebcak', 'crash']):
2626
    ...     print entry
2627
    (u'name12', <DBItem HWBus.SYSTEM, (0) System>, u'MSI', u'MS-7369')
2628
    (u'name12', <DBItem HWBus.SYSTEM, (0) System>, u'Tonka', u'Tuffbook 2600')
2629
    (u'name12', <DBItem HWBus.PCI, (1) PCI>, u'0x10de', u'0x0455')
2630
    (u'name12', <DBItem HWBus.PCI, (1) PCI>, u'0x10de', u'0x045d')
2631
    (u'name12', <DBItem HWBus.PCI, (1) PCI>, u'0x8086', u'0x27cc')
2632
    (u'name12', <DBItem HWBus.USB, (2) USB>, u'0x04b4', u'0x6560')
2633
    (u'name12', <DBItem HWBus.USB, (2) USB>, u'0x07b3', u'0x0017')
2634
    (u'name12', <DBItem HWBus.USB, (2) USB>, u'0x0dda', u'0x2026')
2635
    (u'name12', <DBItem HWBus.USB, (2) USB>, u'0x8086', u'0x1234')
2636
    (u'name12', <DBItem HWBus.IDE, (7) IDE>, u'Optiarc', u'DVD RW AD-7170S ')
2637
    (u'name12', <DBItem HWBus.IDE, (7) IDE>, u'SEAGATE', u'ST3250820NS     ')
2638
    (u'name16', <DBItem HWBus.IDE, (7) IDE>, u'SEAGATE', u'ST3250820NS     ')
2639
8451.4.4 by Deryck Hodge
Add a test for And handling of bug_ids and bug_tags.
2640
We can also query for both bug ids and bug tags together.
2641
8451.4.5 by Deryck Hodge
Update an older method to use And for bug_ids and bug_tags
2642
    >>> for entry in submission_set.hwInfoByBugRelatedUsers(
8451.4.4 by Deryck Hodge
Add a test for And handling of bug_ids and bug_tags.
2643
    ...     bug_ids=[2], bug_tags=['pebcak']):
2644
    ...     print entry
2645
    (u'name12', <DBItem HWBus.SYSTEM, (0) System>, u'MSI', u'MS-7369')
2646
    (u'name12', <DBItem HWBus.SYSTEM, (0) System>, u'Tonka', u'Tuffbook 2600')
2647
    (u'name12', <DBItem HWBus.PCI, (1) PCI>, u'0x10de', u'0x0455')
2648
    (u'name12', <DBItem HWBus.PCI, (1) PCI>, u'0x10de', u'0x045d')
2649
    (u'name12', <DBItem HWBus.PCI, (1) PCI>, u'0x8086', u'0x27cc')
2650
    (u'name12', <DBItem HWBus.USB, (2) USB>, u'0x04b4', u'0x6560')
2651
    (u'name12', <DBItem HWBus.USB, (2) USB>, u'0x07b3', u'0x0017')
2652
    (u'name12', <DBItem HWBus.USB, (2) USB>, u'0x0dda', u'0x2026')
2653
    (u'name12', <DBItem HWBus.USB, (2) USB>, u'0x8086', u'0x1234')
2654
    (u'name12', <DBItem HWBus.IDE, (7) IDE>, u'Optiarc', u'DVD RW AD-7170S ')
2655
    (u'name12', <DBItem HWBus.IDE, (7) IDE>, u'SEAGATE', u'ST3250820NS     ')
2656
2657
Also, confirm that nothing is returned where there is no matching
2658
tag on a given bug id.
2659
8451.4.5 by Deryck Hodge
Update an older method to use And for bug_ids and bug_tags
2660
    >>> print len(submission_set.hwInfoByBugRelatedUsers(
8451.4.4 by Deryck Hodge
Add a test for And handling of bug_ids and bug_tags.
2661
    ...     bug_ids=[3], bug_tags=['pebcak']))
2662
    0
2663
8451.4.1 by Deryck Hodge
Enabling deviceDriversByOwner for HWSubmissionSet and the
2664
This method can also be used to list devices where the
2665
device owner is affected by the bug.
2666
2667
    >>> bug_one.markUserAffected(foo_bar)
2668
8451.4.5 by Deryck Hodge
Update an older method to use And for bug_ids and bug_tags
2669
    >>> for entry in submission_set.hwInfoByBugRelatedUsers(
8451.4.1 by Deryck Hodge
Enabling deviceDriversByOwner for HWSubmissionSet and the
2670
    ...     bug_ids=[1], affected_by_bug=True):
2671
    ...     print entry
2672
    (u'name12', <DBItem HWBus.SYSTEM, (0) System>, u'MSI', u'MS-7369')
2673
    (u'name12', <DBItem HWBus.SYSTEM, (0) System>, u'Tonka', u'Tuffbook 2600')
2674
    (u'name12', <DBItem HWBus.PCI, (1) PCI>, u'0x10de', u'0x0455')
2675
    (u'name12', <DBItem HWBus.PCI, (1) PCI>, u'0x10de', u'0x045d')
2676
    (u'name12', <DBItem HWBus.PCI, (1) PCI>, u'0x8086', u'0x27cc')
2677
    (u'name12', <DBItem HWBus.USB, (2) USB>, u'0x04b4', u'0x6560')
2678
    (u'name12', <DBItem HWBus.USB, (2) USB>, u'0x07b3', u'0x0017')
2679
    (u'name12', <DBItem HWBus.USB, (2) USB>, u'0x0dda', u'0x2026')
2680
    (u'name12', <DBItem HWBus.USB, (2) USB>, u'0x8086', u'0x1234')
2681
    (u'name12', <DBItem HWBus.IDE, (7) IDE>, u'Optiarc', u'DVD RW AD-7170S ')
2682
    (u'name12', <DBItem HWBus.IDE, (7) IDE>, u'SEAGATE', u'ST3250820NS     ')
2683
    (u'name16', <DBItem HWBus.IDE, (7) IDE>, u'SEAGATE', u'ST3250820NS     ')
2684
2685
    >>> bug_one.markUserAffected(foo_bar, False)
2686
2687
We can also check for when the user is subscribed to the bug.
2688
2689
    >>> bug_one.subscribe(foo_bar, subscribed_by=foo_bar)
11536.1.2 by Gavin Panella
Fix many tests, and a bug or two.
2690
    <lp.bugs.model.bugsubscription.BugSubscription ...>
8451.4.1 by Deryck Hodge
Enabling deviceDriversByOwner for HWSubmissionSet and the
2691
8451.4.5 by Deryck Hodge
Update an older method to use And for bug_ids and bug_tags
2692
    >>> for entry in submission_set.hwInfoByBugRelatedUsers(
8451.4.1 by Deryck Hodge
Enabling deviceDriversByOwner for HWSubmissionSet and the
2693
    ...     bug_ids=[1], subscribed_to_bug=True):
2694
    ...     print entry
2695
    (u'name12', <DBItem HWBus.SYSTEM, (0) System>, u'MSI', u'MS-7369')
2696
    (u'name12', <DBItem HWBus.SYSTEM, (0) System>, u'Tonka', u'Tuffbook 2600')
2697
    (u'name12', <DBItem HWBus.PCI, (1) PCI>, u'0x10de', u'0x0455')
2698
    (u'name12', <DBItem HWBus.PCI, (1) PCI>, u'0x10de', u'0x045d')
2699
    (u'name12', <DBItem HWBus.PCI, (1) PCI>, u'0x8086', u'0x27cc')
2700
    (u'name12', <DBItem HWBus.USB, (2) USB>, u'0x04b4', u'0x6560')
2701
    (u'name12', <DBItem HWBus.USB, (2) USB>, u'0x07b3', u'0x0017')
2702
    (u'name12', <DBItem HWBus.USB, (2) USB>, u'0x0dda', u'0x2026')
2703
    (u'name12', <DBItem HWBus.USB, (2) USB>, u'0x8086', u'0x1234')
2704
    (u'name12', <DBItem HWBus.IDE, (7) IDE>, u'Optiarc', u'DVD RW AD-7170S ')
2705
    (u'name12', <DBItem HWBus.IDE, (7) IDE>, u'SEAGATE', u'ST3250820NS     ')
2706
    (u'name16', <DBItem HWBus.IDE, (7) IDE>, u'SEAGATE', u'ST3250820NS     ')
2707
2708
    >>> bug_one.unsubscribe(foo_bar, unsubscribed_by=foo_bar)
2709
2710
Data from private submissions is not included by default.
2711
The owner of a private submission can see his or her submission.
2712
2713
    >>> bug_one.subscribe(no_priv, subscribed_by=no_priv)
11536.1.2 by Gavin Panella
Fix many tests, and a bug or two.
2714
    <lp.bugs.model.bugsubscription.BugSubscription ...>
8451.4.1 by Deryck Hodge
Enabling deviceDriversByOwner for HWSubmissionSet and the
2715
8451.4.5 by Deryck Hodge
Update an older method to use And for bug_ids and bug_tags
2716
    >>> for entry in submission_set.hwInfoByBugRelatedUsers(
8451.4.1 by Deryck Hodge
Enabling deviceDriversByOwner for HWSubmissionSet and the
2717
    ...     bug_ids=[1], subscribed_to_bug=True, user=no_priv):
2718
    ...     print entry
2719
    (u'name12', <DBItem HWBus.SYSTEM, (0) System>, u'MSI', u'MS-7369')
2720
    (u'name12', <DBItem HWBus.SYSTEM, (0) System>, u'Tonka', u'Tuffbook 2600')
2721
    (u'name12', <DBItem HWBus.PCI, (1) PCI>, u'0x10de', u'0x0455')
2722
    (u'name12', <DBItem HWBus.PCI, (1) PCI>, u'0x10de', u'0x045d')
2723
    (u'name12', <DBItem HWBus.PCI, (1) PCI>, u'0x8086', u'0x27cc')
2724
    (u'name12', <DBItem HWBus.USB, (2) USB>, u'0x04b4', u'0x6560')
2725
    (u'name12', <DBItem HWBus.USB, (2) USB>, u'0x07b3', u'0x0017')
2726
    (u'name12', <DBItem HWBus.USB, (2) USB>, u'0x0dda', u'0x2026')
2727
    (u'name12', <DBItem HWBus.USB, (2) USB>, u'0x8086', u'0x1234')
2728
    (u'name12', <DBItem HWBus.IDE, (7) IDE>, u'Optiarc', u'DVD RW AD-7170S ')
2729
    (u'name12', <DBItem HWBus.IDE, (7) IDE>, u'SEAGATE', u'ST3250820NS     ')
2730
    (u'no-priv', <DBItem HWBus.IDE, (7) IDE>, u'SEAGATE', u'ST3250820NS     ')
2731
2732
An admin can also see no_priv's private entry.
2733
8451.4.5 by Deryck Hodge
Update an older method to use And for bug_ids and bug_tags
2734
    >>> for entry in submission_set.hwInfoByBugRelatedUsers(
8451.4.1 by Deryck Hodge
Enabling deviceDriversByOwner for HWSubmissionSet and the
2735
    ...     bug_ids=[1], subscribed_to_bug=True, user=foo_bar):
2736
    ...     print entry
2737
    (u'name12', <DBItem HWBus.SYSTEM, (0) System>, u'MSI', u'MS-7369')
2738
    (u'name12', <DBItem HWBus.SYSTEM, (0) System>, u'Tonka', u'Tuffbook 2600')
2739
    (u'name12', <DBItem HWBus.PCI, (1) PCI>, u'0x10de', u'0x0455')
2740
    (u'name12', <DBItem HWBus.PCI, (1) PCI>, u'0x10de', u'0x045d')
2741
    (u'name12', <DBItem HWBus.PCI, (1) PCI>, u'0x8086', u'0x27cc')
2742
    (u'name12', <DBItem HWBus.USB, (2) USB>, u'0x04b4', u'0x6560')
2743
    (u'name12', <DBItem HWBus.USB, (2) USB>, u'0x07b3', u'0x0017')
2744
    (u'name12', <DBItem HWBus.USB, (2) USB>, u'0x0dda', u'0x2026')
2745
    (u'name12', <DBItem HWBus.USB, (2) USB>, u'0x8086', u'0x1234')
2746
    (u'name12', <DBItem HWBus.IDE, (7) IDE>, u'Optiarc', u'DVD RW AD-7170S ')
2747
    (u'name12', <DBItem HWBus.IDE, (7) IDE>, u'SEAGATE', u'ST3250820NS     ')
2748
    (u'no-priv', <DBItem HWBus.IDE, (7) IDE>, u'SEAGATE', u'ST3250820NS     ')
2749
2750
But sample_person cannot see the private entry because she
2751
is not the owner or an admin.
2752
8451.4.5 by Deryck Hodge
Update an older method to use And for bug_ids and bug_tags
2753
    >>> for entry in submission_set.hwInfoByBugRelatedUsers(
8451.4.1 by Deryck Hodge
Enabling deviceDriversByOwner for HWSubmissionSet and the
2754
    ...     bug_ids=[1], subscribed_to_bug=True, user=sample_person):
2755
    ...     print entry
2756
    (u'name12', <DBItem HWBus.SYSTEM, (0) System>, u'MSI', u'MS-7369')
2757
    (u'name12', <DBItem HWBus.SYSTEM, (0) System>, u'Tonka', u'Tuffbook 2600')
2758
    (u'name12', <DBItem HWBus.PCI, (1) PCI>, u'0x10de', u'0x0455')
2759
    (u'name12', <DBItem HWBus.PCI, (1) PCI>, u'0x10de', u'0x045d')
2760
    (u'name12', <DBItem HWBus.PCI, (1) PCI>, u'0x8086', u'0x27cc')
2761
    (u'name12', <DBItem HWBus.USB, (2) USB>, u'0x04b4', u'0x6560')
2762
    (u'name12', <DBItem HWBus.USB, (2) USB>, u'0x07b3', u'0x0017')
2763
    (u'name12', <DBItem HWBus.USB, (2) USB>, u'0x0dda', u'0x2026')
2764
    (u'name12', <DBItem HWBus.USB, (2) USB>, u'0x8086', u'0x1234')
2765
    (u'name12', <DBItem HWBus.IDE, (7) IDE>, u'Optiarc', u'DVD RW AD-7170S ')
2766
    (u'name12', <DBItem HWBus.IDE, (7) IDE>, u'SEAGATE', u'ST3250820NS     ')
2767
2768
    >>> bug_one.unsubscribe(no_priv, unsubscribed_by=no_priv)