Merge lp:~adeuring/launchpad/bug-460976-noise-reduction-for-hwdb-processing-log into lp:launchpad/db-devel
- bug-460976-noise-reduction-for-hwdb-processing-log
- Merge into db-devel
Proposed by
Abel Deuring
Status: | Merged |
---|---|
Merged at revision: | not available |
Proposed branch: | lp:~adeuring/launchpad/bug-460976-noise-reduction-for-hwdb-processing-log |
Merge into: | lp:launchpad/db-devel |
Diff against target: |
671 lines 5 files modified
lib/canonical/launchpad/scripts/hwdbsubmissions.py (+69/-14) lib/canonical/launchpad/scripts/tests/test_hwdb_submission_parser.py (+121/-96) lib/canonical/launchpad/scripts/tests/test_hwdb_submission_processing.py (+14/-5) lib/lp/testing/__init__.py (+67/-0) lib/lp/testing/tests/test_inlinetests.py (+20/-0) |
To merge this branch: | bzr merge lp:~adeuring/launchpad/bug-460976-noise-reduction-for-hwdb-processing-log |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Eleanor Berger (community) | code | Approve | |
Review via email: mp+13950@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
Abel Deuring (adeuring) wrote : | # |
Revision history for this message
Eleanor Berger (intellectronica) : | # |
review:
Approve
(code)
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'lib/canonical/launchpad/scripts/hwdbsubmissions.py' | |||
2 | --- lib/canonical/launchpad/scripts/hwdbsubmissions.py 2009-10-22 11:08:18 +0000 | |||
3 | +++ lib/canonical/launchpad/scripts/hwdbsubmissions.py 2009-10-26 12:05:33 +0000 | |||
4 | @@ -1228,9 +1228,11 @@ | |||
5 | 1228 | def checkUdevUsbProperties(self, udev_data): | 1228 | def checkUdevUsbProperties(self, udev_data): |
6 | 1229 | """Validation of udev USB devices. | 1229 | """Validation of udev USB devices. |
7 | 1230 | 1230 | ||
11 | 1231 | USB devices must have the properties DEVTYPE (value | 1231 | USB devices must either have the three properties DEVTYPE |
12 | 1232 | 'usb_device' or 'usb_interface'), PRODUCT and TYPE. PRODUCT | 1232 | (value 'usb_device' or 'usb_interface'), PRODUCT and TYPE, |
13 | 1233 | must be a tuple of three integers in hexadecimal | 1233 | or they must have none of them. |
14 | 1234 | |||
15 | 1235 | PRODUCT must be a tuple of three integers in hexadecimal | ||
16 | 1234 | representation, separates by '/'. TYPE must be a a tuple of | 1236 | representation, separates by '/'. TYPE must be a a tuple of |
17 | 1235 | three integers in decimal representation, separated by '/'. | 1237 | three integers in decimal representation, separated by '/'. |
18 | 1236 | usb_interface nodes must additionally have a property | 1238 | usb_interface nodes must additionally have a property |
19 | @@ -1245,6 +1247,10 @@ | |||
20 | 1245 | property_names = set(properties) | 1247 | property_names = set(properties) |
21 | 1246 | existing_usb_properties = property_names.intersection( | 1248 | existing_usb_properties = property_names.intersection( |
22 | 1247 | UDEV_USB_DEVICE_PROPERTIES) | 1249 | UDEV_USB_DEVICE_PROPERTIES) |
23 | 1250 | |||
24 | 1251 | if len(existing_usb_properties) == 0: | ||
25 | 1252 | continue | ||
26 | 1253 | |||
27 | 1248 | if existing_usb_properties != UDEV_USB_DEVICE_PROPERTIES: | 1254 | if existing_usb_properties != UDEV_USB_DEVICE_PROPERTIES: |
28 | 1249 | missing_properties = UDEV_USB_DEVICE_PROPERTIES.difference( | 1255 | missing_properties = UDEV_USB_DEVICE_PROPERTIES.difference( |
29 | 1250 | existing_usb_properties) | 1256 | existing_usb_properties) |
30 | @@ -1365,7 +1371,8 @@ | |||
31 | 1365 | if ('udev' in parsed_data['hardware'] | 1371 | if ('udev' in parsed_data['hardware'] |
32 | 1366 | and not self.checkConsistentUdevDeviceData( | 1372 | and not self.checkConsistentUdevDeviceData( |
33 | 1367 | parsed_data['hardware']['udev'], | 1373 | parsed_data['hardware']['udev'], |
35 | 1368 | parsed_data['hardware']['sysfs-attributes'])): | 1374 | parsed_data['hardware']['sysfs-attributes'], |
36 | 1375 | parsed_data['hardware']['dmi'],)): | ||
37 | 1369 | return False | 1376 | return False |
38 | 1370 | duplicate_ids = self.findDuplicateIDs(parsed_data) | 1377 | duplicate_ids = self.findDuplicateIDs(parsed_data) |
39 | 1371 | if duplicate_ids: | 1378 | if duplicate_ids: |
40 | @@ -1962,6 +1969,40 @@ | |||
41 | 1962 | 1969 | ||
42 | 1963 | info.bus == 'video4linux' is used for the "input aspect" | 1970 | info.bus == 'video4linux' is used for the "input aspect" |
43 | 1964 | of video devices. | 1971 | of video devices. |
44 | 1972 | |||
45 | 1973 | 'ac97' is used in submissions with udev data for a sub-node | ||
46 | 1974 | of sound devices. | ||
47 | 1975 | |||
48 | 1976 | 'hid' is used in submissions with udev data for a sub-node | ||
49 | 1977 | of USB input devices. | ||
50 | 1978 | |||
51 | 1979 | 'drm_minor', 'pci_express', 'tifm_adapter', 'gameport', | ||
52 | 1980 | 'spi_host', 'tifm', 'wlan' are used in submissions with | ||
53 | 1981 | udev data for sub-nodes of PCI devices. | ||
54 | 1982 | |||
55 | 1983 | 'pcmcia_socket' is used in submissions with udev data for | ||
56 | 1984 | a sub-node of PC Card and PCMCIA bridges. | ||
57 | 1985 | |||
58 | 1986 | 'ieee80211' is used in submissions with udev data for | ||
59 | 1987 | sub-nodes IEEE 802.11 WLAN devices. | ||
60 | 1988 | |||
61 | 1989 | 'host', 'link' are used in submissions with udev data for | ||
62 | 1990 | sub.nodes of bluetooth devices. | ||
63 | 1991 | |||
64 | 1992 | 'usb_host' and 'usbmon' are used in submissions with udev | ||
65 | 1993 | data for sub-nodes of USB controllers. | ||
66 | 1994 | |||
67 | 1995 | 'usb_endpoint', 'usb-serial', 'lirc' are used in | ||
68 | 1996 | submissions with udev data for sub-nodes of USB devices. | ||
69 | 1997 | |||
70 | 1998 | 'enclosure' is used in submissions with udev data for a | ||
71 | 1999 | sub.node of SCSI devices. | ||
72 | 2000 | |||
73 | 2001 | 'graphics' is used in submissions with udev data for a | ||
74 | 2002 | sub-node of graphics cards. | ||
75 | 2003 | |||
76 | 2004 | 'hwmon' is is used in submissions with udev data in | ||
77 | 2005 | many sub-nodes. | ||
78 | 1965 | """ | 2006 | """ |
79 | 1966 | # The root node is always a real device, but its raw_bus | 2007 | # The root node is always a real device, but its raw_bus |
80 | 1967 | # property can have different values: None or 'Unknown' in | 2008 | # property can have different values: None or 'Unknown' in |
81 | @@ -1974,13 +2015,15 @@ | |||
82 | 1974 | # This set of buses is only used once; it's easier to have it | 2015 | # This set of buses is only used once; it's easier to have it |
83 | 1975 | # here than to put it elsewhere and have to document its | 2016 | # here than to put it elsewhere and have to document its |
84 | 1976 | # location and purpose. | 2017 | # location and purpose. |
92 | 1977 | if bus in (None, 'disk', 'drm', 'dvb', 'memstick_host', 'net', | 2018 | if bus in (None, 'ac97', 'disk', 'drm', 'drm_minor', 'dvb', |
93 | 1978 | 'partition', 'scsi_disk', 'scsi_generic', 'scsi_host', | 2019 | 'enclosure', 'gameport', 'graphics', 'hid', 'host', |
94 | 1979 | 'scsi_target', 'sound', 'spi_transport', 'ssb', 'tty', | 2020 | 'hwmon', 'ieee80211', 'link', 'lirc', 'memstick_host', |
95 | 1980 | 'usb', 'usb_interface', 'video4linux', ): | 2021 | 'net', 'partition', 'pci_express', 'pcmcia_socket', |
96 | 1981 | # | 2022 | 'scsi_disk', 'scsi_generic', 'scsi_host', 'scsi_target', |
97 | 1982 | # The computer itself is the only HAL device without the | 2023 | 'sound', 'spi_host', 'spi_transport', 'ssb', 'tifm', |
98 | 1983 | # info.bus property that we treat as a real device. | 2024 | 'tifm_adapter', 'tty', 'usb', 'usb-serial', 'usb_endpoint', |
99 | 2025 | 'usb_host', 'usb_interface', 'usbmon', 'video4linux', | ||
100 | 2026 | 'wlan'): | ||
101 | 1984 | return False | 2027 | return False |
102 | 1985 | elif bus == 'usb_device': | 2028 | elif bus == 'usb_device': |
103 | 1986 | vendor_id = self.usb_vendor_id | 2029 | vendor_id = self.usb_vendor_id |
104 | @@ -2088,6 +2131,16 @@ | |||
105 | 2088 | for CPUs, power supply etc. Except for the main sytsem, none | 2131 | for CPUs, power supply etc. Except for the main sytsem, none |
106 | 2089 | of them provides a vendor or product id, so we ignore them. | 2132 | of them provides a vendor or product id, so we ignore them. |
107 | 2090 | 2133 | ||
108 | 2134 | raw_bus == 'video_output', 'thermal', 'vtconsole', 'bdi', | ||
109 | 2135 | 'mem', 'ppp', 'vc', 'dmi', 'hidraw', 'hwmon', 'heci', 'rfkill', | ||
110 | 2136 | 'i2c-adapter', 'ttm', 'ppdev', 'printer' is used in submissions | ||
111 | 2137 | with udev data for virtual devices. | ||
112 | 2138 | |||
113 | 2139 | 'pci_bus' is used in submissions with udev data for a node | ||
114 | 2140 | describing a PCI bus. | ||
115 | 2141 | |||
116 | 2142 | 'leds' is used in submissions with udev data to describe LEDs. | ||
117 | 2143 | |||
118 | 2091 | XXX Abel Deuring 2008-05-06: IEEE1394 devices are a bit | 2144 | XXX Abel Deuring 2008-05-06: IEEE1394 devices are a bit |
119 | 2092 | nasty: The standard does not define any specification | 2145 | nasty: The standard does not define any specification |
120 | 2093 | for product IDs or product names, hence HAL often uses | 2146 | for product IDs or product names, hence HAL often uses |
121 | @@ -2115,9 +2168,11 @@ | |||
122 | 2115 | # The root node is course a real device; storing data | 2168 | # The root node is course a real device; storing data |
123 | 2116 | # about other devices with the bus "unkown" is pointless. | 2169 | # about other devices with the bus "unkown" is pointless. |
124 | 2117 | return False | 2170 | return False |
128 | 2118 | if bus in ('backlight', 'bluetooth', 'ieee1394', 'input', 'misc', | 2171 | if bus in ('backlight', 'bdi', 'bluetooth', 'dmi', 'heci', 'hidraw', |
129 | 2119 | 'mmc', 'mmc_host', 'pcmcia', 'platform', 'pnp', | 2172 | 'hwmon', 'i2c-adapter', 'ieee1394', 'input', 'leds', 'mem', |
130 | 2120 | 'power_supply'): | 2173 | 'misc', 'mmc', 'mmc_host', 'pci_bus', 'pcmcia', 'platform', |
131 | 2174 | 'pnp', 'power_supply', 'ppdev', 'ppp', 'printer', 'rfkill', | ||
132 | 2175 | 'thermal', 'ttm', 'vc', 'video_output', 'vtconsole'): | ||
133 | 2121 | return False | 2176 | return False |
134 | 2122 | 2177 | ||
135 | 2123 | # We identify devices by bus, vendor ID and product ID; | 2178 | # We identify devices by bus, vendor ID and product ID; |
136 | 2124 | 2179 | ||
137 | === modified file 'lib/canonical/launchpad/scripts/tests/test_hwdb_submission_parser.py' | |||
138 | --- lib/canonical/launchpad/scripts/tests/test_hwdb_submission_parser.py 2009-10-21 16:49:03 +0000 | |||
139 | +++ lib/canonical/launchpad/scripts/tests/test_hwdb_submission_parser.py 2009-10-26 12:05:33 +0000 | |||
140 | @@ -23,6 +23,7 @@ | |||
141 | 23 | ROOT_UDI) | 23 | ROOT_UDI) |
142 | 24 | from canonical.testing import BaseLayer | 24 | from canonical.testing import BaseLayer |
143 | 25 | 25 | ||
144 | 26 | from lp.testing import validate_mock_class | ||
145 | 26 | 27 | ||
146 | 27 | class SubmissionParserTestParseSoftware(SubmissionParser): | 28 | class SubmissionParserTestParseSoftware(SubmissionParser): |
147 | 28 | """A Variant used to test SubmissionParser._parseSoftware. | 29 | """A Variant used to test SubmissionParser._parseSoftware. |
148 | @@ -1928,27 +1929,41 @@ | |||
149 | 1928 | "'/devices/pci0000:00/0000:00:1f.2'") | 1929 | "'/devices/pci0000:00/0000:00:1f.2'") |
150 | 1929 | 1930 | ||
151 | 1930 | def testCheckUdevUsbProperties(self): | 1931 | def testCheckUdevUsbProperties(self): |
153 | 1931 | """Test of SubmissionParser.checkUdevUsbProperties().""" | 1932 | """Test of SubmissionParser.checkUdevUsbProperties(). |
154 | 1933 | |||
155 | 1934 | udev nodes for USB devices must define the three properties | ||
156 | 1935 | DEVTYPE, PRODUCT, TYPE or none of them. | ||
157 | 1936 | """ | ||
158 | 1932 | parser = SubmissionParser() | 1937 | parser = SubmissionParser() |
159 | 1933 | self.assertTrue(parser.checkUdevUsbProperties( | 1938 | self.assertTrue(parser.checkUdevUsbProperties( |
160 | 1934 | [self.udev_root_device, self.udev_usb_device, | 1939 | [self.udev_root_device, self.udev_usb_device, |
161 | 1935 | self.udev_usb_interface])) | 1940 | self.udev_usb_interface])) |
162 | 1936 | 1941 | ||
163 | 1942 | for property_name in ('DEVTYPE', 'PRODUCT', 'TYPE'): | ||
164 | 1943 | del self.udev_usb_device['E'][property_name] | ||
165 | 1944 | self.assertTrue(parser.checkUdevUsbProperties( | ||
166 | 1945 | [self.udev_root_device, self.udev_usb_device, | ||
167 | 1946 | self.udev_usb_interface])) | ||
168 | 1947 | |||
169 | 1937 | def testCheckUdevUsbProperties_missing_required_property(self): | 1948 | def testCheckUdevUsbProperties_missing_required_property(self): |
170 | 1938 | """Test of SubmissionParser.checkUdevUsbProperties(). | 1949 | """Test of SubmissionParser.checkUdevUsbProperties(). |
171 | 1939 | 1950 | ||
174 | 1940 | A USB device that does not have a required property makes a | 1951 | A USB device where some but not all of the properties DEVTYPE, |
175 | 1941 | submission invalid. | 1952 | PRODUCT, TYPE are defined makes a submission invalid. |
176 | 1942 | """ | 1953 | """ |
186 | 1943 | del self.udev_usb_device['E']['DEVTYPE'] | 1954 | for property_name in ('DEVTYPE', 'PRODUCT', 'TYPE'): |
187 | 1944 | parser = SubmissionParser(self.log) | 1955 | saved_property = self.udev_usb_device['E'].pop(property_name) |
188 | 1945 | parser.submission_key = 'USB device without DEVTYPE property' | 1956 | parser = SubmissionParser(self.log) |
189 | 1946 | self.assertFalse(parser.checkUdevUsbProperties( | 1957 | parser.submission_key = ( |
190 | 1947 | [self.udev_root_device, self.udev_usb_device])) | 1958 | 'USB device without %s property' % property_name) |
191 | 1948 | self.assertErrorMessage( | 1959 | self.assertFalse(parser.checkUdevUsbProperties( |
192 | 1949 | parser.submission_key, | 1960 | [self.udev_root_device, self.udev_usb_device])) |
193 | 1950 | "USB udev device found without required properties: " | 1961 | self.assertErrorMessage( |
194 | 1951 | "set(['DEVTYPE']) '/devices/pci0000:00/0000:00:1d.1/usb3/3-2'") | 1962 | parser.submission_key, |
195 | 1963 | "USB udev device found without required properties: " | ||
196 | 1964 | "set(['%s']) '/devices/pci0000:00/0000:00:1d.1/usb3/3-2'" | ||
197 | 1965 | % property_name) | ||
198 | 1966 | self.udev_usb_device['E'][property_name] = saved_property | ||
199 | 1952 | 1967 | ||
200 | 1953 | def testCheckUdevUsbProperties_with_invalid_product_id(self): | 1968 | def testCheckUdevUsbProperties_with_invalid_product_id(self): |
201 | 1954 | """Test of SubmissionParser.checkUdevUsbProperties(). | 1969 | """Test of SubmissionParser.checkUdevUsbProperties(). |
202 | @@ -2102,7 +2117,7 @@ | |||
203 | 2102 | 2117 | ||
204 | 2103 | All shortcut methods return True. | 2118 | All shortcut methods return True. |
205 | 2104 | """ | 2119 | """ |
207 | 2105 | def checkUdevDictsHavePathKey(self, udev_data): | 2120 | def checkUdevDictsHavePathKey(self, udev_nodes): |
208 | 2106 | """See `SubmissionParser`.""" | 2121 | """See `SubmissionParser`.""" |
209 | 2107 | return True | 2122 | return True |
210 | 2108 | 2123 | ||
211 | @@ -2114,7 +2129,7 @@ | |||
212 | 2114 | """See `SubmissionParser`.""" | 2129 | """See `SubmissionParser`.""" |
213 | 2115 | return True | 2130 | return True |
214 | 2116 | 2131 | ||
216 | 2117 | def checkUdevScsiProperties(self, udev_data, syfs_data): | 2132 | def checkUdevScsiProperties(self, udev_data, sysfs_data): |
217 | 2118 | """See `SubmissionParser`.""" | 2133 | """See `SubmissionParser`.""" |
218 | 2119 | return True | 2134 | return True |
219 | 2120 | 2135 | ||
220 | @@ -2122,6 +2137,8 @@ | |||
221 | 2122 | """See `SubmissionParser`.""" | 2137 | """See `SubmissionParser`.""" |
222 | 2123 | return True | 2138 | return True |
223 | 2124 | 2139 | ||
224 | 2140 | validate_mock_class(UdevTestSubmissionParser) | ||
225 | 2141 | |||
226 | 2125 | def testCheckConsistentUdevDeviceData(self): | 2142 | def testCheckConsistentUdevDeviceData(self): |
227 | 2126 | """Test of SubmissionParser.checkConsistentUdevDeviceData(),""" | 2143 | """Test of SubmissionParser.checkConsistentUdevDeviceData(),""" |
228 | 2127 | parser = self.UdevTestSubmissionParser() | 2144 | parser = self.UdevTestSubmissionParser() |
229 | @@ -2137,10 +2154,12 @@ | |||
230 | 2137 | self.UdevTestSubmissionParser): | 2154 | self.UdevTestSubmissionParser): |
231 | 2138 | """A SubmissionPaser where checkUdevDictsHavePathKey() fails.""" | 2155 | """A SubmissionPaser where checkUdevDictsHavePathKey() fails.""" |
232 | 2139 | 2156 | ||
234 | 2140 | def checkUdevDictsHavePathKey(self, udev_data): | 2157 | def checkUdevDictsHavePathKey(self, udev_nodes): |
235 | 2141 | """See `SubmissionParser`.""" | 2158 | """See `SubmissionParser`.""" |
236 | 2142 | return False | 2159 | return False |
237 | 2143 | 2160 | ||
238 | 2161 | validate_mock_class(SubmissionParserUdevPathCheckFails) | ||
239 | 2162 | |||
240 | 2144 | parser = SubmissionParserUdevPathCheckFails() | 2163 | parser = SubmissionParserUdevPathCheckFails() |
241 | 2145 | self.assertFalse(parser.checkConsistentUdevDeviceData( | 2164 | self.assertFalse(parser.checkConsistentUdevDeviceData( |
242 | 2146 | None, None, None)) | 2165 | None, None, None)) |
243 | @@ -2158,6 +2177,8 @@ | |||
244 | 2158 | """See `SubmissionParser`.""" | 2177 | """See `SubmissionParser`.""" |
245 | 2159 | return False | 2178 | return False |
246 | 2160 | 2179 | ||
247 | 2180 | validate_mock_class(SubmissionParserUdevPciCheckFails) | ||
248 | 2181 | |||
249 | 2161 | parser = SubmissionParserUdevPciCheckFails() | 2182 | parser = SubmissionParserUdevPciCheckFails() |
250 | 2162 | self.assertFalse(parser.checkConsistentUdevDeviceData( | 2183 | self.assertFalse(parser.checkConsistentUdevDeviceData( |
251 | 2163 | None, None, None)) | 2184 | None, None, None)) |
252 | @@ -2175,6 +2196,8 @@ | |||
253 | 2175 | """See `SubmissionParser`.""" | 2196 | """See `SubmissionParser`.""" |
254 | 2176 | return False | 2197 | return False |
255 | 2177 | 2198 | ||
256 | 2199 | validate_mock_class(SubmissionParserUdevUsbCheckFails) | ||
257 | 2200 | |||
258 | 2178 | parser = SubmissionParserUdevUsbCheckFails() | 2201 | parser = SubmissionParserUdevUsbCheckFails() |
259 | 2179 | self.assertFalse(parser.checkConsistentUdevDeviceData( | 2202 | self.assertFalse(parser.checkConsistentUdevDeviceData( |
260 | 2180 | None, None, None)) | 2203 | None, None, None)) |
261 | @@ -2192,6 +2215,8 @@ | |||
262 | 2192 | """See `SubmissionParser`.""" | 2215 | """See `SubmissionParser`.""" |
263 | 2193 | return False | 2216 | return False |
264 | 2194 | 2217 | ||
265 | 2218 | validate_mock_class(SubmissionParserUdevUsbCheckFails) | ||
266 | 2219 | |||
267 | 2195 | parser = SubmissionParserUdevUsbCheckFails() | 2220 | parser = SubmissionParserUdevUsbCheckFails() |
268 | 2196 | self.assertFalse(parser.checkConsistentUdevDeviceData( | 2221 | self.assertFalse(parser.checkConsistentUdevDeviceData( |
269 | 2197 | None, None, None)) | 2222 | None, None, None)) |
270 | @@ -2209,55 +2234,38 @@ | |||
271 | 2209 | """See `SubmissionParser`.""" | 2234 | """See `SubmissionParser`.""" |
272 | 2210 | return False | 2235 | return False |
273 | 2211 | 2236 | ||
274 | 2237 | validate_mock_class(SubmissionParserUdevUsbCheckFails) | ||
275 | 2238 | |||
276 | 2212 | parser = SubmissionParserUdevUsbCheckFails() | 2239 | parser = SubmissionParserUdevUsbCheckFails() |
277 | 2213 | self.assertFalse(parser.checkConsistentUdevDeviceData( | 2240 | self.assertFalse(parser.checkConsistentUdevDeviceData( |
278 | 2214 | None, None, None)) | 2241 | None, None, None)) |
279 | 2215 | 2242 | ||
282 | 2216 | def _setupConsistencyCheckParser(self): | 2243 | class MockSubmissionParser(SubmissionParser): |
283 | 2217 | """Prepare and return a SubmissionParser instance. | 2244 | """A SubmissionParser variant for testing checkCOnsistentData() |
284 | 2218 | 2245 | ||
285 | 2219 | All "method substitutes" return a valid result. | 2246 | All "method substitutes" return a valid result. |
286 | 2220 | """ | 2247 | """ |
288 | 2221 | test = self | 2248 | |
289 | 2222 | def findDuplicateIDs(self, parsed_data): | 2249 | def findDuplicateIDs(self, parsed_data): |
290 | 2223 | test.assertTrue(isinstance(self, SubmissionParser)) | ||
291 | 2224 | return set() | 2250 | return set() |
292 | 2225 | 2251 | ||
293 | 2226 | def findInvalidIDReferences(self, parsed_data): | 2252 | def findInvalidIDReferences(self, parsed_data): |
294 | 2227 | test.assertTrue(isinstance(self, SubmissionParser)) | ||
295 | 2228 | return set() | 2253 | return set() |
296 | 2229 | 2254 | ||
297 | 2230 | def getUDIDeviceMap(self, devices): | 2255 | def getUDIDeviceMap(self, devices): |
298 | 2231 | test.assertTrue(isinstance(self, SubmissionParser)) | ||
299 | 2232 | return {} | 2256 | return {} |
300 | 2233 | 2257 | ||
301 | 2234 | def getUDIChildren(self, udi_device_map): | 2258 | def getUDIChildren(self, udi_device_map): |
302 | 2235 | test.assertTrue(isinstance(self, SubmissionParser)) | ||
303 | 2236 | return {} | 2259 | return {} |
304 | 2237 | 2260 | ||
307 | 2238 | def checkHALDevicesParentChildConsistency(self, devices): | 2261 | def checkHALDevicesParentChildConsistency(self, udi_children): |
306 | 2239 | test.assertTrue(isinstance(self, SubmissionParser)) | ||
308 | 2240 | return [] | 2262 | return [] |
309 | 2241 | 2263 | ||
311 | 2242 | def checkConsistentUdevDeviceData(self, udev_data, sysfs_data): | 2264 | def checkConsistentUdevDeviceData( |
312 | 2265 | self, udev_data, sysfs_data, dmi_data): | ||
313 | 2243 | return True | 2266 | return True |
314 | 2244 | 2267 | ||
331 | 2245 | parser = SubmissionParser(self.log) | 2268 | validate_mock_class(MockSubmissionParser) |
316 | 2246 | parser.findDuplicateIDs = ( | ||
317 | 2247 | lambda parsed_data: findDuplicateIDs(parser, parsed_data)) | ||
318 | 2248 | parser.findInvalidIDReferences = ( | ||
319 | 2249 | lambda parsed_data: findInvalidIDReferences(parser, parsed_data)) | ||
320 | 2250 | parser.getUDIDeviceMap = ( | ||
321 | 2251 | lambda devices: getUDIDeviceMap(parser, devices)) | ||
322 | 2252 | parser.getUDIChildren = ( | ||
323 | 2253 | lambda udi_device_map: getUDIChildren(parser, udi_device_map)) | ||
324 | 2254 | parser.checkHALDevicesParentChildConsistency = ( | ||
325 | 2255 | lambda udi_children: checkHALDevicesParentChildConsistency( | ||
326 | 2256 | parser, udi_children)) | ||
327 | 2257 | parser.checkConsistentUdevDeviceData = ( | ||
328 | 2258 | lambda udev_data, sysfs_data: checkConsistentUdevDeviceData( | ||
329 | 2259 | parser, udev_data, sysfs_data)) | ||
330 | 2260 | return parser | ||
332 | 2261 | 2269 | ||
333 | 2262 | def assertErrorMessage(self, submission_key, log_message): | 2270 | def assertErrorMessage(self, submission_key, log_message): |
334 | 2263 | """Search for message in the log entries for submission_key. | 2271 | """Search for message in the log entries for submission_key. |
335 | @@ -2309,7 +2317,7 @@ | |||
336 | 2309 | 2317 | ||
337 | 2310 | def testConsistencyCheck(self): | 2318 | def testConsistencyCheck(self): |
338 | 2311 | """Test of SubmissionParser.checkConsistency.""" | 2319 | """Test of SubmissionParser.checkConsistency.""" |
340 | 2312 | parser = self._setupConsistencyCheckParser() | 2320 | parser = self.MockSubmissionParser() |
341 | 2313 | result = parser.checkConsistency({'hardware': | 2321 | result = parser.checkConsistency({'hardware': |
342 | 2314 | {'hal': {'devices': []}}}) | 2322 | {'hal': {'devices': []}}}) |
343 | 2315 | self.assertEqual(result, True, | 2323 | self.assertEqual(result, True, |
344 | @@ -2318,45 +2326,53 @@ | |||
345 | 2318 | 2326 | ||
346 | 2319 | def testConsistencyCheckValidUdevData(self): | 2327 | def testConsistencyCheckValidUdevData(self): |
347 | 2320 | """Test of SubmissionParser.checkConsistency.""" | 2328 | """Test of SubmissionParser.checkConsistency.""" |
349 | 2321 | parser = self._setupConsistencyCheckParser() | 2329 | parser = self.MockSubmissionParser() |
350 | 2322 | self.assertTrue(parser.checkConsistency( | 2330 | self.assertTrue(parser.checkConsistency( |
351 | 2323 | { | 2331 | { |
352 | 2324 | 'hardware': { | 2332 | 'hardware': { |
355 | 2325 | 'udev': [], | 2333 | 'udev': None, |
356 | 2326 | 'sysfs-attributes': [] | 2334 | 'sysfs-attributes': None, |
357 | 2335 | 'dmi': None, | ||
358 | 2327 | } | 2336 | } |
359 | 2328 | } | 2337 | } |
360 | 2329 | )) | 2338 | )) |
361 | 2330 | 2339 | ||
362 | 2331 | def testConsistencyCheck_invalid_udev_data(self): | 2340 | def testConsistencyCheck_invalid_udev_data(self): |
363 | 2332 | """Test of SubmissionParser.checkConsistency.""" | 2341 | """Test of SubmissionParser.checkConsistency.""" |
371 | 2333 | def checkConsistentUdevDeviceData(self, udev_data, sysfs_data): | 2342 | class MockSubmissionParserBadUdevDeviceData( |
372 | 2334 | return False | 2343 | self.MockSubmissionParser): |
373 | 2335 | 2344 | """A parser where checkConsistentUdevDeviceData() fails.""" | |
374 | 2336 | parser = self._setupConsistencyCheckParser() | 2345 | |
375 | 2337 | parser.checkConsistentUdevDeviceData = ( | 2346 | def checkConsistentUdevDeviceData(self, udev_data, sysfs_data, |
376 | 2338 | lambda udev_data, sysfs_data: checkConsistentUdevDeviceData( | 2347 | dmi_data): |
377 | 2339 | parser, udev_data, sysfs_data)) | 2348 | return False |
378 | 2349 | |||
379 | 2350 | validate_mock_class(MockSubmissionParserBadUdevDeviceData) | ||
380 | 2351 | |||
381 | 2352 | parser = MockSubmissionParserBadUdevDeviceData() | ||
382 | 2340 | self.assertFalse(parser.checkConsistency( | 2353 | self.assertFalse(parser.checkConsistency( |
383 | 2341 | { | 2354 | { |
384 | 2342 | 'hardware': { | 2355 | 'hardware': { |
387 | 2343 | 'udev': [{}], | 2356 | 'udev': None, |
388 | 2344 | 'sysfs-attributes': [] | 2357 | 'sysfs-attributes': None, |
389 | 2358 | 'dmi': None, | ||
390 | 2345 | } | 2359 | } |
391 | 2346 | } | 2360 | } |
392 | 2347 | )) | 2361 | )) |
393 | 2348 | 2362 | ||
394 | 2349 | def testConsistencyCheckWithDuplicateIDs(self): | 2363 | def testConsistencyCheckWithDuplicateIDs(self): |
395 | 2350 | """SubmissionParser.checkConsistency detects duplicate IDs.""" | 2364 | """SubmissionParser.checkConsistency detects duplicate IDs.""" |
402 | 2351 | test = self | 2365 | class MockSubmissionParserDuplicateIds( |
403 | 2352 | def findDuplicateIDs(self, parsed_data): | 2366 | self.MockSubmissionParser): |
404 | 2353 | test.assertTrue(isinstance(self, SubmissionParser)) | 2367 | """A parser where findDuplicateIDs() fails.""" |
405 | 2354 | return set([1]) | 2368 | |
406 | 2355 | 2369 | def findDuplicateIDs(self, parsed_data): | |
407 | 2356 | parser = self._setupConsistencyCheckParser() | 2370 | return set([1]) |
408 | 2371 | |||
409 | 2372 | validate_mock_class(MockSubmissionParserDuplicateIds) | ||
410 | 2373 | |||
411 | 2374 | parser = MockSubmissionParserDuplicateIds(self.log) | ||
412 | 2357 | parser.submission_key = 'Consistency check detects duplicate IDs' | 2375 | parser.submission_key = 'Consistency check detects duplicate IDs' |
413 | 2358 | parser.findDuplicateIDs = ( | ||
414 | 2359 | lambda parsed_data: findDuplicateIDs(parser, parsed_data)) | ||
415 | 2360 | result = parser.checkConsistency({'hardware': | 2376 | result = parser.checkConsistency({'hardware': |
416 | 2361 | {'hal': {'devices': []}}}) | 2377 | {'hal': {'devices': []}}}) |
417 | 2362 | self.assertEqual(result, False, | 2378 | self.assertEqual(result, False, |
418 | @@ -2366,15 +2382,16 @@ | |||
419 | 2366 | 2382 | ||
420 | 2367 | def testConsistencyCheckWithInvalidIDReferences(self): | 2383 | def testConsistencyCheckWithInvalidIDReferences(self): |
421 | 2368 | """SubmissionParser.checkConsistency detects invalid ID references.""" | 2384 | """SubmissionParser.checkConsistency detects invalid ID references.""" |
428 | 2369 | test = self | 2385 | class MockSubmissionParserInvalidIDReferences( |
429 | 2370 | def findInvalidIDReferences(self, parsed_data): | 2386 | self.MockSubmissionParser): |
430 | 2371 | test.assertTrue(isinstance(self, SubmissionParser)) | 2387 | """A parser where findInvalidIDReferences() fails.""" |
431 | 2372 | return set([1]) | 2388 | def findInvalidIDReferences(self, parsed_data): |
432 | 2373 | 2389 | return set([1]) | |
433 | 2374 | parser = self._setupConsistencyCheckParser() | 2390 | |
434 | 2391 | validate_mock_class(MockSubmissionParserInvalidIDReferences) | ||
435 | 2392 | |||
436 | 2393 | parser = MockSubmissionParserInvalidIDReferences(self.log) | ||
437 | 2375 | parser.submission_key = 'Consistency check detects invalid ID refs' | 2394 | parser.submission_key = 'Consistency check detects invalid ID refs' |
438 | 2376 | parser.findInvalidIDReferences = ( | ||
439 | 2377 | lambda parsed_data: findInvalidIDReferences(parser, parsed_data)) | ||
440 | 2378 | result = parser.checkConsistency({'hardware': | 2395 | result = parser.checkConsistency({'hardware': |
441 | 2379 | {'hal': {'devices': []}}}) | 2396 | {'hal': {'devices': []}}}) |
442 | 2380 | self.assertEqual(result, False, | 2397 | self.assertEqual(result, False, |
443 | @@ -2384,16 +2401,18 @@ | |||
444 | 2384 | 2401 | ||
445 | 2385 | def testConsistencyCheckWithDuplicateUDI(self): | 2402 | def testConsistencyCheckWithDuplicateUDI(self): |
446 | 2386 | """SubmissionParser.checkConsistency detects duplicate UDIs.""" | 2403 | """SubmissionParser.checkConsistency detects duplicate UDIs.""" |
454 | 2387 | test = self | 2404 | class MockSubmissionParserUDIDeviceMapFails( |
455 | 2388 | def getUDIDeviceMap(self, parsed_data): | 2405 | self.MockSubmissionParser): |
456 | 2389 | test.assertTrue(isinstance(self, SubmissionParser)) | 2406 | """A parser where getUDIDeviceMap() fails.""" |
457 | 2390 | raise ValueError( | 2407 | |
458 | 2391 | 'Duplicate UDI: /org/freedesktop/Hal/devices/computer') | 2408 | def getUDIDeviceMap(self, devices): |
459 | 2392 | 2409 | raise ValueError( | |
460 | 2393 | parser = self._setupConsistencyCheckParser() | 2410 | 'Duplicate UDI: /org/freedesktop/Hal/devices/computer') |
461 | 2411 | |||
462 | 2412 | validate_mock_class(MockSubmissionParserUDIDeviceMapFails) | ||
463 | 2413 | |||
464 | 2414 | parser = MockSubmissionParserUDIDeviceMapFails(self.log) | ||
465 | 2394 | parser.submission_key = 'Consistency check detects invalid ID refs' | 2415 | parser.submission_key = 'Consistency check detects invalid ID refs' |
466 | 2395 | parser.getUDIDeviceMap = ( | ||
467 | 2396 | lambda devices: getUDIDeviceMap(parser, devices)) | ||
468 | 2397 | result = parser.checkConsistency({'hardware': | 2416 | result = parser.checkConsistency({'hardware': |
469 | 2398 | {'hal': {'devices': []}}}) | 2417 | {'hal': {'devices': []}}}) |
470 | 2399 | self.assertEqual(result, False, | 2418 | self.assertEqual(result, False, |
471 | @@ -2404,15 +2423,17 @@ | |||
472 | 2404 | 2423 | ||
473 | 2405 | def testConsistencyCheckChildUDIWithoutParent(self): | 2424 | def testConsistencyCheckChildUDIWithoutParent(self): |
474 | 2406 | """SubmissionParser.checkConsistency detects "orphaned" devices.""" | 2425 | """SubmissionParser.checkConsistency detects "orphaned" devices.""" |
481 | 2407 | test = self | 2426 | class MockSubmissionParserUDIChildrenFails( |
482 | 2408 | def getUDIChildren(self, udi_device_map): | 2427 | self.MockSubmissionParser): |
483 | 2409 | test.assertTrue(isinstance(self, SubmissionParser)) | 2428 | """A parser where getUDIChildren() fails.""" |
484 | 2410 | raise ValueError('Unknown parent UDI /foo in <device id="3">') | 2429 | |
485 | 2411 | 2430 | def getUDIChildren(self, udi_device_map): | |
486 | 2412 | parser = self._setupConsistencyCheckParser() | 2431 | raise ValueError('Unknown parent UDI /foo in <device id="3">') |
487 | 2432 | |||
488 | 2433 | validate_mock_class(MockSubmissionParserUDIChildrenFails) | ||
489 | 2434 | |||
490 | 2435 | parser = MockSubmissionParserUDIChildrenFails(self.log) | ||
491 | 2413 | parser.submission_key = 'Consistency check detects invalid ID refs' | 2436 | parser.submission_key = 'Consistency check detects invalid ID refs' |
492 | 2414 | parser.getUDIChildren = ( | ||
493 | 2415 | lambda udi_device_map: getUDIChildren(parser, udi_device_map)) | ||
494 | 2416 | result = parser.checkConsistency({'hardware': | 2437 | result = parser.checkConsistency({'hardware': |
495 | 2417 | {'hal': {'devices': []}}}) | 2438 | {'hal': {'devices': []}}}) |
496 | 2418 | self.assertEqual(result, False, | 2439 | self.assertEqual(result, False, |
497 | @@ -2423,17 +2444,21 @@ | |||
498 | 2423 | 2444 | ||
499 | 2424 | def testConsistencyCheckCircularParentChildRelation(self): | 2445 | def testConsistencyCheckCircularParentChildRelation(self): |
500 | 2425 | """SubmissionParser.checkConsistency detects "orphaned" devices.""" | 2446 | """SubmissionParser.checkConsistency detects "orphaned" devices.""" |
507 | 2426 | test = self | 2447 | class MockSubmissionParserHALDevicesParentChildConsistency( |
508 | 2427 | def checkHALDevicesParentChildConsistency(self, devices): | 2448 | self.MockSubmissionParser): |
509 | 2428 | test.assertTrue(isinstance(self, SubmissionParser)) | 2449 | """A parser where checkHALDevicesParentChildConsistency() fails. |
510 | 2429 | return ['/foo', '/bar'] | 2450 | """ |
511 | 2430 | 2451 | ||
512 | 2431 | parser = self._setupConsistencyCheckParser() | 2452 | def checkHALDevicesParentChildConsistency(self, udi_children): |
513 | 2453 | return ['/foo', '/bar'] | ||
514 | 2454 | |||
515 | 2455 | validate_mock_class( | ||
516 | 2456 | MockSubmissionParserHALDevicesParentChildConsistency) | ||
517 | 2457 | |||
518 | 2458 | parser = MockSubmissionParserHALDevicesParentChildConsistency( | ||
519 | 2459 | self.log) | ||
520 | 2432 | parser.submission_key = ('Consistency check detects circular ' | 2460 | parser.submission_key = ('Consistency check detects circular ' |
521 | 2433 | 'parent-child relationships') | 2461 | 'parent-child relationships') |
522 | 2434 | parser.checkHALDevicesParentChildConsistency = ( | ||
523 | 2435 | lambda devices: checkHALDevicesParentChildConsistency( | ||
524 | 2436 | parser, devices)) | ||
525 | 2437 | result = parser.checkConsistency({'hardware': | 2462 | result = parser.checkConsistency({'hardware': |
526 | 2438 | {'hal': {'devices': []}}}) | 2463 | {'hal': {'devices': []}}}) |
527 | 2439 | self.assertEqual(result, False, | 2464 | self.assertEqual(result, False, |
528 | 2440 | 2465 | ||
529 | === modified file 'lib/canonical/launchpad/scripts/tests/test_hwdb_submission_processing.py' | |||
530 | --- lib/canonical/launchpad/scripts/tests/test_hwdb_submission_processing.py 2009-10-22 11:08:18 +0000 | |||
531 | +++ lib/canonical/launchpad/scripts/tests/test_hwdb_submission_processing.py 2009-10-26 12:05:33 +0000 | |||
532 | @@ -1672,8 +1672,14 @@ | |||
533 | 1672 | parser = SubmissionParser(self.log) | 1672 | parser = SubmissionParser(self.log) |
534 | 1673 | 1673 | ||
535 | 1674 | ignored_buses = ( | 1674 | ignored_buses = ( |
538 | 1675 | 'drm', 'dvb', 'memstick_host', 'net', 'scsi_generic', 'scsi_host', | 1675 | 'ac97', 'disk', 'drm', 'drm_minor', 'dvb', 'enclosure', |
539 | 1676 | 'sound', 'ssb', 'tty', 'usb', 'video4linux', ) | 1676 | 'gameport', 'hid', 'host', 'ieee80211', 'link', 'lirc', |
540 | 1677 | 'memstick_host', 'net', 'partition', 'pci_express', | ||
541 | 1678 | 'pcmcia_socket', 'scsi_disk', 'scsi_generic', 'scsi_host', | ||
542 | 1679 | 'scsi_target', 'sound', 'spi_host', 'spi_transport', 'ssb', | ||
543 | 1680 | 'tifm', 'tifm_adapter', 'tty', 'usb', 'usb-serial', | ||
544 | 1681 | 'usb_endpoint', 'usb_host', 'usb_interface', 'video4linux', | ||
545 | 1682 | 'wlan') | ||
546 | 1677 | for tested_bus in ignored_buses: | 1683 | for tested_bus in ignored_buses: |
547 | 1678 | properties['info.bus'] = (tested_bus, 'str') | 1684 | properties['info.bus'] = (tested_bus, 'str') |
548 | 1679 | parser.buildHalDeviceList(parsed_data) | 1685 | parser.buildHalDeviceList(parsed_data) |
549 | @@ -2004,9 +2010,12 @@ | |||
550 | 2004 | } | 2010 | } |
551 | 2005 | parser = SubmissionParser(self.log) | 2011 | parser = SubmissionParser(self.log) |
552 | 2006 | properties = devices[0]['properties'] | 2012 | properties = devices[0]['properties'] |
556 | 2007 | for bus in ('backlight', 'bluetooth', 'ieee1394', 'input', 'misc', | 2013 | for bus in ('backlight', 'bdi', 'bluetooth', 'dmi', 'heci', 'hidraw', |
557 | 2008 | 'mmc', 'mmc_host', 'pcmcia', 'platform', 'pnp', | 2014 | 'hwmon', 'i2c-adapter', 'ieee1394', 'input', 'leds', 'mem', |
558 | 2009 | 'power_supply', 'unknown'): | 2015 | 'misc', 'mmc', 'mmc_host', 'pci_bus', 'pcmcia', 'platform', |
559 | 2016 | 'pnp', 'power_supply', 'ppdev', 'ppp', 'printer', 'rfkill', | ||
560 | 2017 | 'thermal', 'ttm', 'unknown', 'vc', 'video_output', | ||
561 | 2018 | 'vtconsole'): | ||
562 | 2010 | properties['info.bus'] = (bus, 'str') | 2019 | properties['info.bus'] = (bus, 'str') |
563 | 2011 | parser.buildHalDeviceList(parsed_data) | 2020 | parser.buildHalDeviceList(parsed_data) |
564 | 2012 | device = parser.devices[self.UDI_SATA_CONTROLLER] | 2021 | device = parser.devices[self.UDI_SATA_CONTROLLER] |
565 | 2013 | 2022 | ||
566 | === modified file 'lib/lp/testing/__init__.py' | |||
567 | --- lib/lp/testing/__init__.py 2009-10-23 11:07:32 +0000 | |||
568 | +++ lib/lp/testing/__init__.py 2009-10-26 12:05:33 +0000 | |||
569 | @@ -8,6 +8,7 @@ | |||
570 | 8 | from datetime import datetime, timedelta | 8 | from datetime import datetime, timedelta |
571 | 9 | from pprint import pformat | 9 | from pprint import pformat |
572 | 10 | import copy | 10 | import copy |
573 | 11 | from inspect import getargspec, getmembers, getmro, isclass, ismethod | ||
574 | 11 | import os | 12 | import os |
575 | 12 | import shutil | 13 | import shutil |
576 | 13 | import subprocess | 14 | import subprocess |
577 | @@ -793,3 +794,69 @@ | |||
578 | 793 | tree.unlock() | 794 | tree.unlock() |
579 | 794 | 795 | ||
580 | 795 | return contents | 796 | return contents |
581 | 797 | |||
582 | 798 | def validate_mock_class(mock_class): | ||
583 | 799 | """Validate method signatures in mock classes derived from real classes. | ||
584 | 800 | |||
585 | 801 | We often use mock classes in tests which are derived from real | ||
586 | 802 | classes. | ||
587 | 803 | |||
588 | 804 | This function ensures that methods redefined in the mock | ||
589 | 805 | class have the same signature as the corresponding methods of | ||
590 | 806 | the base class. | ||
591 | 807 | |||
592 | 808 | >>> class A: | ||
593 | 809 | ... | ||
594 | 810 | ... def method_one(self, a): | ||
595 | 811 | ... pass | ||
596 | 812 | |||
597 | 813 | >>> | ||
598 | 814 | >>> class B(A): | ||
599 | 815 | ... def method_one(self, a): | ||
600 | 816 | ... pass | ||
601 | 817 | >>> validate_mock_class(B) | ||
602 | 818 | |||
603 | 819 | If a class derived from A defines method_one with a different | ||
604 | 820 | signature, we get an AssertionError. | ||
605 | 821 | |||
606 | 822 | >>> class C(A): | ||
607 | 823 | ... def method_one(self, a, b): | ||
608 | 824 | ... pass | ||
609 | 825 | >>> validate_mock_class(C) | ||
610 | 826 | Traceback (most recent call last): | ||
611 | 827 | ... | ||
612 | 828 | AssertionError: Different method signature for method_one:... | ||
613 | 829 | |||
614 | 830 | Even a parameter name must not be modified. | ||
615 | 831 | |||
616 | 832 | >>> class D(A): | ||
617 | 833 | ... def method_one(self, b): | ||
618 | 834 | ... pass | ||
619 | 835 | >>> validate_mock_class(D) | ||
620 | 836 | Traceback (most recent call last): | ||
621 | 837 | ... | ||
622 | 838 | AssertionError: Different method signature for method_one:... | ||
623 | 839 | |||
624 | 840 | If validate_mock_class() for anything but a class, we get an | ||
625 | 841 | AssertionError. | ||
626 | 842 | |||
627 | 843 | >>> validate_mock_class('a string') | ||
628 | 844 | Traceback (most recent call last): | ||
629 | 845 | ... | ||
630 | 846 | AssertionError: validate_mock_class() must be called for a class | ||
631 | 847 | """ | ||
632 | 848 | assert isclass(mock_class), ( | ||
633 | 849 | "validate_mock_class() must be called for a class") | ||
634 | 850 | base_classes = getmro(mock_class) | ||
635 | 851 | for name, obj in getmembers(mock_class): | ||
636 | 852 | if ismethod(obj): | ||
637 | 853 | for base_class in base_classes[1:]: | ||
638 | 854 | if name in base_class.__dict__: | ||
639 | 855 | mock_args = getargspec(obj) | ||
640 | 856 | real_args = getargspec(base_class.__dict__[name]) | ||
641 | 857 | if mock_args != real_args: | ||
642 | 858 | raise AssertionError( | ||
643 | 859 | 'Different method signature for %s: %r %r' % ( | ||
644 | 860 | name, mock_args, real_args)) | ||
645 | 861 | else: | ||
646 | 862 | break | ||
647 | 796 | 863 | ||
648 | === added file 'lib/lp/testing/tests/test_inlinetests.py' | |||
649 | --- lib/lp/testing/tests/test_inlinetests.py 1970-01-01 00:00:00 +0000 | |||
650 | +++ lib/lp/testing/tests/test_inlinetests.py 2009-10-26 12:05:33 +0000 | |||
651 | @@ -0,0 +1,20 @@ | |||
652 | 1 | # Copyright 2009 Canonical Ltd. This software is licensed under the | ||
653 | 2 | # GNU Affero General Public License version 3 (see the file LICENSE). | ||
654 | 3 | |||
655 | 4 | """Run the doc string tests.""" | ||
656 | 5 | |||
657 | 6 | import doctest | ||
658 | 7 | |||
659 | 8 | from zope.testing.doctest import NORMALIZE_WHITESPACE, ELLIPSIS | ||
660 | 9 | |||
661 | 10 | from canonical.launchpad.testing.systemdocs import LayeredDocFileSuite | ||
662 | 11 | from canonical.testing import BaseLayer | ||
663 | 12 | from lp import testing | ||
664 | 13 | |||
665 | 14 | def test_suite(): | ||
666 | 15 | suite = LayeredDocFileSuite( | ||
667 | 16 | layer=BaseLayer) | ||
668 | 17 | suite.addTest(doctest.DocTestSuite( | ||
669 | 18 | testing, optionflags=NORMALIZE_WHITESPACE|ELLIPSIS)) | ||
670 | 19 | return suite | ||
671 | 20 |
The property BaseDevice.raw_bus is used to determine if a udev/HAL node represents a real, physical device or if it defines only an "aspect" of a physical device (property BaseDevice. is_real_ device) . It is also used to determine if the submitted data contains enough details, like a vendor and product ID, for the given kind of device so that we can store it in our database (property BaseDevice. has_reliable_ data).
In submissions with udev data we have a number of raw_bus values not used in HAL for nodes that either represent physical devices for which we don't have enough data or that represent only "aspects" or real devices. This leads to lots of warnings in the processing log.
This branch update BaseDevice. has_reliable_ data and BaseDevice. is_real_ device so that udev nodes with the "new" values of baseDevice.raw_bus are treated properly and do not produced warnings in the processing log.
test: ./bin/test --test= test_hwdb_ submission_ processing
= Launchpad lint =
Checking for conflicts. and issues in doctests and templates.
Running jslint, xmllint, pyflakes, and pylint.
Using normal rules.
Linting changed files: /launchpad/ scripts/ hwdbsubmissions .py /launchpad/ scripts/ tests/test_ hwdb_submission _processing. py
lib/canonical
lib/canonical
== Pyflakes notices ==
lib/canonical/ launchpad/ scripts/ hwdbsubmissions .py
22: redefinition of unused 'etree' from line 20
== Pylint notices ==
lib/canonical/ launchpad/ scripts/ hwdbsubmissions .py cElementTree' (No module named etree)
20: [F0401] Unable to import 'xml.etree.
This branch is based on lp:~adeuring/launchpad/bug-460935-hwdb-better-consistency-check-udev-usb-devices, which is reviewed but is mot yet merged. The diff against this brnach:
=== modified file 'lib/canonical/ launchpad/ scripts/ hwdbsubmissions .py' launchpad/ scripts/ hwdbsubmissions .py 2009-10-26 10:01:51 +0000 launchpad/ scripts/ hwdbsubmissions .py 2009-10-26 11:35:15 +0000
--- lib/canonical/
+++ lib/canonical/
@@ -1969,6 +1969,40 @@
of video devices.
+
+ 'ac97' is used in submissions with udev data for a sub-node
+ of sound devices.
+
+ 'hid' is used in submissions with udev data for a sub-node
+ of USB input devices.
+
+ 'drm_minor', 'pci_express', 'tifm_adapter', 'gameport',
+ 'spi_host', 'tifm', 'wlan' are used in submissions with
+ udev data for sub-nodes of PCI devices.
+
+ 'pcmcia_socket' is used in submissions with udev data for
+ a sub-node of PC Card and PCMCIA bridges.
+
+ 'ieee80211' is used in submissions with udev data for
+ sub-nodes IEEE 802.11 WLAN devices.
+
+ 'host', 'link' are used in submissions with udev data for
+ sub.nodes of bluetooth devices.
+
+ 'usb_host' and 'usbmon' are used in submissions with udev
+ data for sub-nodes of USB controllers.
+
+ 'usb_endpoint', 'usb-serial', 'lirc' are used in
+ submissions with udev data for sub-nodes of USB devices.
+
+ 'enclosure' is used in submissions with udev data for a
+ ...