Merge lp:~gnuoy/ubuntu/utopic/python-logutils/fix-tests into lp:ubuntu/utopic/python-logutils
- Utopic (14.10)
- fix-tests
- Merge into utopic
Proposed by
Liam Young
Status: | Merged | ||||
---|---|---|---|---|---|
Merge reported by: | James Page | ||||
Merged at revision: | not available | ||||
Proposed branch: | lp:~gnuoy/ubuntu/utopic/python-logutils/fix-tests | ||||
Merge into: | lp:ubuntu/utopic/python-logutils | ||||
Diff against target: |
926 lines (+842/-4) 9 files modified
.pc/applied-patches (+2/-0) .pc/fix-dictconf-tests-on-python3.patch/tests/test_dictconfig.py (+688/-0) .pc/test-failures-fatal.patch/setup.py (+63/-0) debian/changelog (+7/-0) debian/patches/fix-dictconf-tests-on-python3.patch (+45/-0) debian/patches/series (+2/-0) debian/patches/test-failures-fatal.patch (+21/-0) setup.py (+3/-1) tests/test_dictconfig.py (+11/-3) |
||||
To merge this branch: | bzr merge lp:~gnuoy/ubuntu/utopic/python-logutils/fix-tests | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Liam Young (community) | Needs Resubmitting | ||
James Page | Needs Fixing | ||
Review via email: mp+225661@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
James Page (james-page) : | # |
review:
Needs Fixing
- 4. By Liam Young
-
* Fix series in changelog
* Improve changelog description by referencing changed files
* Add dep3 Forwarded field now a pull request has been submitted for these changes
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file '.pc/applied-patches' |
2 | --- .pc/applied-patches 2014-01-09 14:31:16 +0000 |
3 | +++ .pc/applied-patches 2014-07-16 11:40:18 +0000 |
4 | @@ -1,1 +1,3 @@ |
5 | no-network-access-during-doc-build.patch |
6 | +test-failures-fatal.patch |
7 | +fix-dictconf-tests-on-python3.patch |
8 | |
9 | === added directory '.pc/fix-dictconf-tests-on-python3.patch' |
10 | === added file '.pc/fix-dictconf-tests-on-python3.patch/.timestamp' |
11 | === added directory '.pc/fix-dictconf-tests-on-python3.patch/tests' |
12 | === added file '.pc/fix-dictconf-tests-on-python3.patch/tests/test_dictconfig.py' |
13 | --- .pc/fix-dictconf-tests-on-python3.patch/tests/test_dictconfig.py 1970-01-01 00:00:00 +0000 |
14 | +++ .pc/fix-dictconf-tests-on-python3.patch/tests/test_dictconfig.py 2014-07-16 11:40:18 +0000 |
15 | @@ -0,0 +1,688 @@ |
16 | +# |
17 | +# Copyright 2009-2013 by Vinay Sajip. See LICENSE.txt for details. |
18 | +# |
19 | +import logging |
20 | +from logutils.adapter import LoggerAdapter |
21 | +from logutils.dictconfig import dictConfig, named_handlers_supported |
22 | +from logutils.testing import TestHandler, Matcher |
23 | +import sys |
24 | +import unittest |
25 | + |
26 | +try: |
27 | + StandardError |
28 | +except NameError: |
29 | + StandardError = Exception |
30 | + |
31 | +class ExceptionFormatter(logging.Formatter): |
32 | + """A special exception formatter.""" |
33 | + def formatException(self, ei): |
34 | + return "Got a [%s]" % ei[0].__name__ |
35 | + |
36 | +def formatFunc(format, datefmt=None): |
37 | + return logging.Formatter(format, datefmt) |
38 | + |
39 | +def testHandler(): |
40 | + return TestHandler(Matcher()) |
41 | + |
42 | +def handlerFunc(): |
43 | + return logging.StreamHandler() |
44 | + |
45 | +class CustomHandler(logging.StreamHandler): |
46 | + pass |
47 | + |
48 | +class ConfigDictTest(unittest.TestCase): |
49 | + |
50 | + """Reading logging config from a dictionary.""" |
51 | + |
52 | + def setUp(self): |
53 | + self.logger = l = logging.getLogger() |
54 | + self.adapter = LoggerAdapter(l, {}) |
55 | + |
56 | + logger_dict = logging.getLogger().manager.loggerDict |
57 | + logging._acquireLock() |
58 | + try: |
59 | + self.saved_handlers = logging._handlers.copy() |
60 | + self.saved_handler_list = logging._handlerList[:] |
61 | + self.saved_loggers = logger_dict.copy() |
62 | + self.saved_level_names = logging._levelNames.copy() |
63 | + finally: |
64 | + logging._releaseLock() |
65 | + |
66 | + self.root_logger = logging.getLogger("") |
67 | + self.original_logging_level = self.root_logger.getEffectiveLevel() |
68 | + |
69 | + |
70 | + def tearDown(self): |
71 | + self.root_logger.setLevel(self.original_logging_level) |
72 | + logging._acquireLock() |
73 | + try: |
74 | + logging._levelNames.clear() |
75 | + logging._levelNames.update(self.saved_level_names) |
76 | + logging._handlers.clear() |
77 | + logging._handlers.update(self.saved_handlers) |
78 | + logging._handlerList[:] = self.saved_handler_list |
79 | + loggerDict = logging.getLogger().manager.loggerDict |
80 | + loggerDict.clear() |
81 | + loggerDict.update(self.saved_loggers) |
82 | + finally: |
83 | + logging._releaseLock() |
84 | + |
85 | + message_num = 0 |
86 | + |
87 | + def next_message(self): |
88 | + """Generate a message consisting solely of an auto-incrementing |
89 | + integer.""" |
90 | + self.message_num += 1 |
91 | + return "%d" % self.message_num |
92 | + |
93 | + # config0 is a standard configuration. |
94 | + config0 = { |
95 | + 'version': 1, |
96 | + 'formatters': { |
97 | + 'form1' : { |
98 | + 'format' : '%(levelname)s ++ %(message)s', |
99 | + }, |
100 | + }, |
101 | + 'handlers' : { |
102 | + 'hand1' : { |
103 | + '()': testHandler, |
104 | + 'formatter': 'form1', |
105 | + } |
106 | + }, |
107 | + 'root' : { |
108 | + 'level' : 'WARNING', |
109 | + 'handlers' : ['hand1'], |
110 | + }, |
111 | + } |
112 | + |
113 | + # config1 adds a little to the standard configuration. |
114 | + config1 = { |
115 | + 'version': 1, |
116 | + 'formatters': { |
117 | + 'form1' : { |
118 | + 'format' : '%(levelname)s ++ %(message)s', |
119 | + }, |
120 | + }, |
121 | + 'handlers' : { |
122 | + 'hand1' : { |
123 | + '()': testHandler, |
124 | + 'formatter': 'form1', |
125 | + } |
126 | + }, |
127 | + 'loggers' : { |
128 | + 'compiler.parser' : { |
129 | + 'level' : 'DEBUG', |
130 | + 'handlers' : ['hand1'], |
131 | + }, |
132 | + }, |
133 | + 'root' : { |
134 | + 'level' : 'WARNING', |
135 | + }, |
136 | + } |
137 | + |
138 | + # config2 has a subtle configuration error that should be reported |
139 | + config2 = { |
140 | + 'formatters': { |
141 | + 'form1' : { |
142 | + 'format' : '%(levelname)s ++ %(message)s', |
143 | + }, |
144 | + }, |
145 | + 'handlers' : { |
146 | + 'hand1' : { |
147 | + 'class' : 'logging.StreamHandler', |
148 | + 'formatter' : 'form1', |
149 | + 'level' : 'NOTSET', |
150 | + 'stream' : 'ext://sys.stdbout', |
151 | + }, |
152 | + }, |
153 | + 'loggers' : { |
154 | + 'compiler.parser' : { |
155 | + 'level' : 'DEBUG', |
156 | + 'handlers' : ['hand1'], |
157 | + }, |
158 | + }, |
159 | + 'root' : { |
160 | + 'level' : 'WARNING', |
161 | + }, |
162 | + } |
163 | + |
164 | + #As config1 but with a misspelt level on a handler |
165 | + config2a = { |
166 | + 'formatters': { |
167 | + 'form1' : { |
168 | + 'format' : '%(levelname)s ++ %(message)s', |
169 | + }, |
170 | + }, |
171 | + 'handlers' : { |
172 | + 'hand1' : { |
173 | + 'class' : 'logging.StreamHandler', |
174 | + 'formatter' : 'form1', |
175 | + 'level' : 'NTOSET', |
176 | + 'stream' : 'ext://sys.stdout', |
177 | + }, |
178 | + }, |
179 | + 'loggers' : { |
180 | + 'compiler.parser' : { |
181 | + 'level' : 'DEBUG', |
182 | + 'handlers' : ['hand1'], |
183 | + }, |
184 | + }, |
185 | + 'root' : { |
186 | + 'level' : 'WARNING', |
187 | + }, |
188 | + } |
189 | + |
190 | + |
191 | + #As config1 but with a misspelt level on a logger |
192 | + config2b = { |
193 | + 'formatters': { |
194 | + 'form1' : { |
195 | + 'format' : '%(levelname)s ++ %(message)s', |
196 | + }, |
197 | + }, |
198 | + 'handlers' : { |
199 | + 'hand1' : { |
200 | + 'class' : 'logging.StreamHandler', |
201 | + 'formatter' : 'form1', |
202 | + 'level' : 'NOTSET', |
203 | + 'stream' : 'ext://sys.stdout', |
204 | + }, |
205 | + }, |
206 | + 'loggers' : { |
207 | + 'compiler.parser' : { |
208 | + 'level' : 'DEBUG', |
209 | + 'handlers' : ['hand1'], |
210 | + }, |
211 | + }, |
212 | + 'root' : { |
213 | + 'level' : 'WRANING', |
214 | + }, |
215 | + } |
216 | + |
217 | + # config3 has a less subtle configuration error |
218 | + config3 = { |
219 | + 'formatters': { |
220 | + 'form1' : { |
221 | + 'format' : '%(levelname)s ++ %(message)s', |
222 | + }, |
223 | + }, |
224 | + 'handlers' : { |
225 | + 'hand1' : { |
226 | + 'class' : 'logging.StreamHandler', |
227 | + 'formatter' : 'misspelled_name', |
228 | + 'level' : 'NOTSET', |
229 | + 'stream' : 'ext://sys.stdout', |
230 | + }, |
231 | + }, |
232 | + 'loggers' : { |
233 | + 'compiler.parser' : { |
234 | + 'level' : 'DEBUG', |
235 | + 'handlers' : ['hand1'], |
236 | + }, |
237 | + }, |
238 | + 'root' : { |
239 | + 'level' : 'WARNING', |
240 | + }, |
241 | + } |
242 | + |
243 | + # config4 specifies a custom formatter class to be loaded |
244 | + config4 = { |
245 | + 'version': 1, |
246 | + 'formatters': { |
247 | + 'form1' : { |
248 | + '()' : __name__ + '.ExceptionFormatter', |
249 | + 'format' : '%(levelname)s:%(name)s:%(message)s', |
250 | + }, |
251 | + }, |
252 | + 'handlers' : { |
253 | + 'hand1' : { |
254 | + '()': testHandler, |
255 | + 'formatter': 'form1', |
256 | + } |
257 | + }, |
258 | + 'root' : { |
259 | + 'level' : 'NOTSET', |
260 | + 'handlers' : ['hand1'], |
261 | + }, |
262 | + } |
263 | + |
264 | + # As config4 but using an actual callable rather than a string |
265 | + config4a = { |
266 | + 'version': 1, |
267 | + 'formatters': { |
268 | + 'form1' : { |
269 | + '()' : ExceptionFormatter, |
270 | + 'format' : '%(levelname)s:%(name)s:%(message)s', |
271 | + }, |
272 | + 'form2' : { |
273 | + '()' : __name__ + '.formatFunc', |
274 | + 'format' : '%(levelname)s:%(name)s:%(message)s', |
275 | + }, |
276 | + 'form3' : { |
277 | + '()' : formatFunc, |
278 | + 'format' : '%(levelname)s:%(name)s:%(message)s', |
279 | + }, |
280 | + }, |
281 | + 'handlers' : { |
282 | + 'hand1' : { |
283 | + '()': testHandler, |
284 | + 'formatter': 'form1', |
285 | + }, |
286 | + 'hand2' : { |
287 | + '()' : handlerFunc, |
288 | + }, |
289 | + }, |
290 | + 'root' : { |
291 | + 'level' : 'NOTSET', |
292 | + 'handlers' : ['hand1'], |
293 | + }, |
294 | + } |
295 | + |
296 | + # config5 specifies a custom handler class to be loaded |
297 | + config5 = { |
298 | + 'version': 1, |
299 | + 'formatters': { |
300 | + 'form1' : { |
301 | + 'format' : '%(levelname)s ++ %(message)s', |
302 | + }, |
303 | + }, |
304 | + 'handlers' : { |
305 | + 'hand1' : { |
306 | + '()': testHandler, |
307 | + 'formatter': 'form1', |
308 | + } |
309 | + }, |
310 | + 'loggers' : { |
311 | + 'compiler.parser' : { |
312 | + 'level' : 'DEBUG', |
313 | + 'handlers' : ['hand1'], |
314 | + }, |
315 | + }, |
316 | + 'root' : { |
317 | + 'level' : 'WARNING', |
318 | + }, |
319 | + } |
320 | + |
321 | + # config6 specifies a custom handler class to be loaded |
322 | + # but has bad arguments |
323 | + config6 = { |
324 | + 'formatters': { |
325 | + 'form1' : { |
326 | + 'format' : '%(levelname)s ++ %(message)s', |
327 | + }, |
328 | + }, |
329 | + 'handlers' : { |
330 | + 'hand1' : { |
331 | + 'class' : __name__ + '.CustomHandler', |
332 | + 'formatter' : 'form1', |
333 | + 'level' : 'NOTSET', |
334 | + 'stream' : 'ext://sys.stdout', |
335 | + '9' : 'invalid parameter name', |
336 | + }, |
337 | + }, |
338 | + 'loggers' : { |
339 | + 'compiler.parser' : { |
340 | + 'level' : 'DEBUG', |
341 | + 'handlers' : ['hand1'], |
342 | + }, |
343 | + }, |
344 | + 'root' : { |
345 | + 'level' : 'WARNING', |
346 | + }, |
347 | + } |
348 | + |
349 | + #config 7 does not define compiler.parser but defines compiler.lexer |
350 | + #so compiler.parser should be disabled after applying it |
351 | + config7 = { |
352 | + 'version': 1, |
353 | + 'formatters': { |
354 | + 'form1' : { |
355 | + 'format' : '%(levelname)s ++ %(message)s', |
356 | + }, |
357 | + }, |
358 | + 'handlers' : { |
359 | + 'hand1' : { |
360 | + '()': testHandler, |
361 | + 'formatter': 'form1', |
362 | + } |
363 | + }, |
364 | + 'loggers' : { |
365 | + 'compiler.lexer' : { |
366 | + 'level' : 'DEBUG', |
367 | + 'handlers' : ['hand1'], |
368 | + }, |
369 | + }, |
370 | + 'root' : { |
371 | + 'level' : 'WARNING', |
372 | + }, |
373 | + } |
374 | + |
375 | + config8 = { |
376 | + 'version': 1, |
377 | + 'disable_existing_loggers' : False, |
378 | + 'formatters': { |
379 | + 'form1' : { |
380 | + 'format' : '%(levelname)s ++ %(message)s', |
381 | + }, |
382 | + }, |
383 | + 'handlers' : { |
384 | + 'hand1' : { |
385 | + '()': testHandler, |
386 | + 'formatter': 'form1', |
387 | + } |
388 | + }, |
389 | + 'loggers' : { |
390 | + 'compiler' : { |
391 | + 'level' : 'DEBUG', |
392 | + 'handlers' : ['hand1'], |
393 | + }, |
394 | + 'compiler.lexer' : { |
395 | + }, |
396 | + }, |
397 | + 'root' : { |
398 | + 'level' : 'WARNING', |
399 | + }, |
400 | + } |
401 | + |
402 | + config9 = { |
403 | + 'version': 1, |
404 | + 'formatters': { |
405 | + 'form1' : { |
406 | + 'format' : '%(levelname)s ++ %(message)s', |
407 | + }, |
408 | + }, |
409 | + 'handlers' : { |
410 | + 'hand1' : { |
411 | + '()': testHandler, |
412 | + 'formatter': 'form1', |
413 | + } |
414 | + }, |
415 | + 'loggers' : { |
416 | + 'compiler.parser' : { |
417 | + 'level' : 'WARNING', |
418 | + 'handlers' : ['hand1'], |
419 | + }, |
420 | + }, |
421 | + 'root' : { |
422 | + 'level' : 'NOTSET', |
423 | + }, |
424 | + } |
425 | + |
426 | + config9a = { |
427 | + 'version': 1, |
428 | + 'incremental' : True, |
429 | + 'handlers' : { |
430 | + 'hand1' : { |
431 | + 'level' : 'WARNING', |
432 | + }, |
433 | + }, |
434 | + 'loggers' : { |
435 | + 'compiler.parser' : { |
436 | + 'level' : 'INFO', |
437 | + }, |
438 | + }, |
439 | + } |
440 | + |
441 | + config9b = { |
442 | + 'version': 1, |
443 | + 'incremental' : True, |
444 | + 'handlers' : { |
445 | + 'hand1' : { |
446 | + 'level' : 'INFO', |
447 | + }, |
448 | + }, |
449 | + 'loggers' : { |
450 | + 'compiler.parser' : { |
451 | + 'level' : 'INFO', |
452 | + }, |
453 | + }, |
454 | + } |
455 | + |
456 | + #As config1 but with a filter added |
457 | + config10 = { |
458 | + 'version': 1, |
459 | + 'formatters': { |
460 | + 'form1' : { |
461 | + 'format' : '%(levelname)s ++ %(message)s', |
462 | + }, |
463 | + }, |
464 | + 'filters' : { |
465 | + 'filt1' : { |
466 | + 'name' : 'compiler.parser', |
467 | + }, |
468 | + }, |
469 | + 'handlers' : { |
470 | + 'hand1' : { |
471 | + '()': testHandler, |
472 | + 'formatter': 'form1', |
473 | + 'filters' : ['filt1'], |
474 | + } |
475 | + }, |
476 | + 'loggers' : { |
477 | + 'compiler.parser' : { |
478 | + 'level' : 'DEBUG', |
479 | + 'filters' : ['filt1'], |
480 | + }, |
481 | + }, |
482 | + 'root' : { |
483 | + 'level' : 'WARNING', |
484 | + 'handlers' : ['hand1'], |
485 | + }, |
486 | + } |
487 | + |
488 | + # As config10, but declaring a handler in a module using |
489 | + # absolute imports |
490 | + config11 = { |
491 | + 'version': 1, |
492 | + 'formatters': { |
493 | + 'form1' : { |
494 | + 'format' : '%(levelname)s ++ %(message)s', |
495 | + }, |
496 | + }, |
497 | + 'filters' : { |
498 | + 'filt1' : { |
499 | + 'name' : 'compiler.parser', |
500 | + }, |
501 | + }, |
502 | + 'handlers' : { |
503 | + 'hand1' : { |
504 | + '()': 'mytest.MyTestHandler', |
505 | + 'formatter': 'form1', |
506 | + 'filters' : ['filt1'], |
507 | + } |
508 | + }, |
509 | + 'loggers' : { |
510 | + 'compiler.parser' : { |
511 | + 'level' : 'DEBUG', |
512 | + 'filters' : ['filt1'], |
513 | + }, |
514 | + }, |
515 | + 'root' : { |
516 | + 'level' : 'WARNING', |
517 | + 'handlers' : ['hand1'], |
518 | + }, |
519 | + } |
520 | + |
521 | + def apply_config(self, conf): |
522 | + dictConfig(conf) |
523 | + |
524 | + def test_config0_ok(self): |
525 | + # A simple config which overrides the default settings. |
526 | + self.apply_config(self.config0) |
527 | + logger = logging.getLogger() |
528 | + # Won't output anything |
529 | + logger.info(self.next_message()) |
530 | + # Outputs a message |
531 | + logger.error(self.next_message()) |
532 | + h = logger.handlers[0] |
533 | + self.assertEqual(1, h.count) |
534 | + self.assertTrue(h.matchall([ |
535 | + dict(levelname='ERROR', message='2') |
536 | + ])) |
537 | + |
538 | + def test_config1_ok(self, config=config1): |
539 | + # A config defining a sub-parser as well. |
540 | + self.apply_config(config) |
541 | + logger = logging.getLogger("compiler.parser") |
542 | + # Both will output a message |
543 | + logger.info(self.next_message()) |
544 | + logger.error(self.next_message()) |
545 | + h = logger.handlers[0] |
546 | + self.assertTrue(h.matchall([ |
547 | + dict(levelname='INFO', message='1'), |
548 | + dict(levelname='ERROR', message='2'), |
549 | + ])) |
550 | + |
551 | + def test_config2_failure(self): |
552 | + # A simple config which overrides the default settings. |
553 | + self.assertRaises(StandardError, self.apply_config, self.config2) |
554 | + |
555 | + def test_config2a_failure(self): |
556 | + # A simple config which overrides the default settings. |
557 | + self.assertRaises(StandardError, self.apply_config, self.config2a) |
558 | + |
559 | + def test_config2b_failure(self): |
560 | + # A simple config which overrides the default settings. |
561 | + self.assertRaises(StandardError, self.apply_config, self.config2b) |
562 | + |
563 | + def test_config3_failure(self): |
564 | + # A simple config which overrides the default settings. |
565 | + self.assertRaises(StandardError, self.apply_config, self.config3) |
566 | + |
567 | + def test_config4_ok(self): |
568 | + # A config specifying a custom formatter class. |
569 | + self.apply_config(self.config4) |
570 | + logger = logging.getLogger() |
571 | + h = logger.handlers[0] |
572 | + try: |
573 | + raise RuntimeError() |
574 | + except RuntimeError: |
575 | + logging.exception("just testing") |
576 | + self.assertEquals(h.formatted[0], |
577 | + "ERROR:root:just testing\nGot a [RuntimeError]") |
578 | + |
579 | + def test_config4a_ok(self): |
580 | + # A config specifying a custom formatter class. |
581 | + self.apply_config(self.config4a) |
582 | + logger = logging.getLogger() |
583 | + h = logger.handlers[0] |
584 | + try: |
585 | + raise RuntimeError() |
586 | + except RuntimeError: |
587 | + logging.exception("just testing") |
588 | + self.assertEquals(h.formatted[0], |
589 | + "ERROR:root:just testing\nGot a [RuntimeError]") |
590 | + |
591 | + def test_config5_ok(self): |
592 | + self.test_config1_ok(config=self.config5) |
593 | + |
594 | + def test_config6_failure(self): |
595 | + self.assertRaises(StandardError, self.apply_config, self.config6) |
596 | + |
597 | + def test_config7_ok(self): |
598 | + self.apply_config(self.config1) |
599 | + logger = logging.getLogger("compiler.parser") |
600 | + # Both will output a message |
601 | + logger.info(self.next_message()) |
602 | + logger.error(self.next_message()) |
603 | + h = logger.handlers[0] |
604 | + self.assertTrue(h.matchall([ |
605 | + dict(levelname='INFO', message='1'), |
606 | + dict(levelname='ERROR', message='2'), |
607 | + ])) |
608 | + self.apply_config(self.config7) |
609 | + logger = logging.getLogger("compiler.parser") |
610 | + self.assertTrue(logger.disabled) |
611 | + logger = logging.getLogger("compiler.lexer") |
612 | + # Both will output a message |
613 | + h = logger.handlers[0] |
614 | + logger.info(self.next_message()) |
615 | + logger.error(self.next_message()) |
616 | + self.assertTrue(h.matchall([ |
617 | + dict(levelname='INFO', message='3'), |
618 | + dict(levelname='ERROR', message='4'), |
619 | + ])) |
620 | + |
621 | + #Same as test_config_7_ok but don't disable old loggers. |
622 | + def test_config_8_ok(self): |
623 | + self.apply_config(self.config1) |
624 | + logger = logging.getLogger("compiler.parser") |
625 | + # Both will output a message |
626 | + logger.info(self.next_message()) |
627 | + logger.error(self.next_message()) |
628 | + h = logger.handlers[0] |
629 | + self.assertTrue(h.matchall([ |
630 | + dict(levelname='INFO', message='1'), |
631 | + dict(levelname='ERROR', message='2'), |
632 | + ])) |
633 | + self.apply_config(self.config8) |
634 | + logger = logging.getLogger("compiler.parser") |
635 | + self.assertFalse(logger.disabled) |
636 | + toplogger = logging.getLogger("compiler") |
637 | + # Both will output a message |
638 | + logger.info(self.next_message()) |
639 | + logger.error(self.next_message()) |
640 | + logger = logging.getLogger("compiler.lexer") |
641 | + # Both will output a message |
642 | + logger.info(self.next_message()) |
643 | + logger.error(self.next_message()) |
644 | + h = toplogger.handlers[0] |
645 | + self.assertTrue(h.matchall([ |
646 | + dict(levelname='INFO', message='3'), |
647 | + dict(levelname='ERROR', message='4'), |
648 | + dict(levelname='INFO', message='5'), |
649 | + dict(levelname='ERROR', message='6'), |
650 | + ])) |
651 | + |
652 | + def test_config_9_ok(self): |
653 | + self.apply_config(self.config9) |
654 | + logger = logging.getLogger("compiler.parser") |
655 | + #Nothing will be output since both handler and logger are set to WARNING |
656 | + logger.info(self.next_message()) |
657 | + h = logger.handlers[0] |
658 | + self.assertEqual(0, h.count) |
659 | + self.apply_config(self.config9a) |
660 | + #Nothing will be output since both handler is still set to WARNING |
661 | + logger.info(self.next_message()) |
662 | + h = logger.handlers[0] |
663 | + nhs = named_handlers_supported() |
664 | + if nhs: |
665 | + self.assertEqual(0, h.count) |
666 | + else: |
667 | + self.assertEqual(1, h.count) |
668 | + self.apply_config(self.config9b) |
669 | + #Message should now be output |
670 | + logger.info(self.next_message()) |
671 | + if nhs: |
672 | + h = logger.handlers[0] |
673 | + self.assertTrue(h.matchall([ |
674 | + dict(levelname='INFO', message='3'), |
675 | + ])) |
676 | + else: |
677 | + self.assertEqual(2, h.count) |
678 | + |
679 | + def test_config_10_ok(self): |
680 | + self.apply_config(self.config10) |
681 | + logger = logging.getLogger("compiler.parser") |
682 | + logger.warning(self.next_message()) |
683 | + logger = logging.getLogger('compiler') |
684 | + #Not output, because filtered |
685 | + logger.warning(self.next_message()) |
686 | + logger = logging.getLogger('compiler.lexer') |
687 | + #Not output, because filtered |
688 | + logger.warning(self.next_message()) |
689 | + logger = logging.getLogger("compiler.parser.codegen") |
690 | + #Output, as not filtered |
691 | + logger.error(self.next_message()) |
692 | + h = logging.getLogger().handlers[0] |
693 | + self.assertTrue(h.matchall([ |
694 | + dict(levelname='WARNING', message='1'), |
695 | + dict(levelname='ERROR', message='4'), |
696 | + ])) |
697 | + |
698 | + def test_config_11_ok(self): |
699 | + self.apply_config(self.config11) |
700 | + h = logging.getLogger().handlers[0] |
701 | + self.assertEqual(h.__module__, 'mytest') |
702 | + self.assertEqual(h.__class__.__name__, 'MyTestHandler') |
703 | + |
704 | |
705 | === added directory '.pc/test-failures-fatal.patch' |
706 | === added file '.pc/test-failures-fatal.patch/.timestamp' |
707 | === added file '.pc/test-failures-fatal.patch/setup.py' |
708 | --- .pc/test-failures-fatal.patch/setup.py 1970-01-01 00:00:00 +0000 |
709 | +++ .pc/test-failures-fatal.patch/setup.py 2014-07-16 11:40:18 +0000 |
710 | @@ -0,0 +1,63 @@ |
711 | +# -*- coding: utf-8 -*- |
712 | + |
713 | +import distutils.core |
714 | +import logutils |
715 | +from os.path import join, dirname, abspath |
716 | +import re |
717 | + |
718 | + |
719 | +def description(): |
720 | + f = open(join(dirname(__file__), 'README.txt')) |
721 | + readme = f.read() |
722 | + f.close() |
723 | + regexp = r'^logutils\s*[\d.]*\s*\n=======+\s*\n(.*)Requirements ' |
724 | + reqts, = re.findall(regexp, readme, re.DOTALL) |
725 | + regexp = r'Availability & Documentation\s*\n-----+\s*\n(.*)' |
726 | + avail, = re.findall(regexp, readme, re.DOTALL) |
727 | + return reqts + avail |
728 | + |
729 | +class TestCommand(distutils.core.Command): |
730 | + user_options = [] |
731 | + |
732 | + def run(self): |
733 | + import sys |
734 | + import unittest |
735 | + |
736 | + sys.path.append(join(dirname(__file__), 'tests')) |
737 | + import logutil_tests |
738 | + loader = unittest.TestLoader() |
739 | + runner = unittest.TextTestRunner() |
740 | + runner.run(loader.loadTestsFromModule(logutil_tests)) |
741 | + |
742 | + def initialize_options(self): |
743 | + pass |
744 | + |
745 | + def finalize_options(self): |
746 | + pass |
747 | + |
748 | +distutils.core.setup( |
749 | + name='logutils', |
750 | + version=logutils.__version__, |
751 | + author='Vinay Sajip', |
752 | + author_email='vinay_sajip@red-dove.com', |
753 | + url='http://code.google.com/p/logutils/', |
754 | + description='Logging utilities', |
755 | + long_description = description(), |
756 | + license='Copyright (C) 2010-2013 by Vinay Sajip. All Rights Reserved. See LICENSE.txt for license.', |
757 | + classifiers=[ |
758 | + 'Development Status :: 5 - Production/Stable', |
759 | + 'Environment :: Console', |
760 | + 'Intended Audience :: Developers', |
761 | + 'License :: OSI Approved :: BSD License', |
762 | + 'Operating System :: OS Independent', |
763 | + 'Programming Language :: Python', |
764 | + "Programming Language :: Python :: 2", |
765 | + "Programming Language :: Python :: 3", |
766 | + 'Topic :: Software Development', |
767 | + ], |
768 | + packages=['logutils'], |
769 | + cmdclass={ |
770 | + 'test': TestCommand, |
771 | + }, |
772 | + |
773 | +) |
774 | |
775 | === modified file 'debian/changelog' |
776 | --- debian/changelog 2014-01-09 14:31:16 +0000 |
777 | +++ debian/changelog 2014-07-16 11:40:18 +0000 |
778 | @@ -1,3 +1,10 @@ |
779 | +python-logutils (0.3.3-1ubuntu1) utopic; urgency=medium |
780 | + |
781 | + * d/p/test-failures-fatal.patch: Make unit test failures fatal to build |
782 | + * d/p/fix-dictconf-tests-on-python3.patch: Fix tests failing with python3. |
783 | + |
784 | + -- Liam Young <liam.young@canonical.com> Fri, 04 Jul 2014 13:44:06 +0100 |
785 | + |
786 | python-logutils (0.3.3-1) unstable; urgency=medium |
787 | |
788 | * Initial release. (Closes: #734687) |
789 | |
790 | === added file 'debian/patches/fix-dictconf-tests-on-python3.patch' |
791 | --- debian/patches/fix-dictconf-tests-on-python3.patch 1970-01-01 00:00:00 +0000 |
792 | +++ debian/patches/fix-dictconf-tests-on-python3.patch 2014-07-16 11:40:18 +0000 |
793 | @@ -0,0 +1,45 @@ |
794 | +Description: Make refernces to _levelNames python2 specific as it does not exist in the python3 version of the module. |
795 | +Author: Liam Young <liam.young@canonical.com> |
796 | +Bug-Ubuntu: https://launchpad.net/bugs/1319909 |
797 | +Forwarded: https://bitbucket.org/vinay.sajip/logutils/pull-request/1/fix-python3-tests-and-make-test-failures/diff |
798 | +Last-Update: 2014-07-04 |
799 | + |
800 | +Index: python-logutils/tests/test_dictconfig.py |
801 | +=================================================================== |
802 | +--- python-logutils.orig/tests/test_dictconfig.py |
803 | ++++ python-logutils/tests/test_dictconfig.py |
804 | +@@ -27,6 +27,12 @@ def testHandler(): |
805 | + def handlerFunc(): |
806 | + return logging.StreamHandler() |
807 | + |
808 | ++def is_python2(): |
809 | ++ if sys.version_info >= (2, 0) and sys.version_info < (3, 0): |
810 | ++ return True |
811 | ++ else: |
812 | ++ return False |
813 | ++ |
814 | + class CustomHandler(logging.StreamHandler): |
815 | + pass |
816 | + |
817 | +@@ -44,7 +50,8 @@ class ConfigDictTest(unittest.TestCase): |
818 | + self.saved_handlers = logging._handlers.copy() |
819 | + self.saved_handler_list = logging._handlerList[:] |
820 | + self.saved_loggers = logger_dict.copy() |
821 | +- self.saved_level_names = logging._levelNames.copy() |
822 | ++ if is_python2(): |
823 | ++ self.saved_level_names = logging._levelNames.copy() |
824 | + finally: |
825 | + logging._releaseLock() |
826 | + |
827 | +@@ -56,8 +63,9 @@ class ConfigDictTest(unittest.TestCase): |
828 | + self.root_logger.setLevel(self.original_logging_level) |
829 | + logging._acquireLock() |
830 | + try: |
831 | +- logging._levelNames.clear() |
832 | +- logging._levelNames.update(self.saved_level_names) |
833 | ++ if is_python2(): |
834 | ++ logging._levelNames.clear() |
835 | ++ logging._levelNames.update(self.saved_level_names) |
836 | + logging._handlers.clear() |
837 | + logging._handlers.update(self.saved_handlers) |
838 | + logging._handlerList[:] = self.saved_handler_list |
839 | |
840 | === modified file 'debian/patches/series' |
841 | --- debian/patches/series 2014-01-09 14:31:16 +0000 |
842 | +++ debian/patches/series 2014-07-16 11:40:18 +0000 |
843 | @@ -1,1 +1,3 @@ |
844 | no-network-access-during-doc-build.patch |
845 | +test-failures-fatal.patch |
846 | +fix-dictconf-tests-on-python3.patch |
847 | |
848 | === added file 'debian/patches/test-failures-fatal.patch' |
849 | --- debian/patches/test-failures-fatal.patch 1970-01-01 00:00:00 +0000 |
850 | +++ debian/patches/test-failures-fatal.patch 2014-07-16 11:40:18 +0000 |
851 | @@ -0,0 +1,21 @@ |
852 | +Description: Test failures should be fatal to the build process |
853 | +Author: Liam Young <liam.young@canonical.com> |
854 | +Bug-Ubuntu: https://launchpad.net/bugs/1319909 |
855 | +Forwarded: https://bitbucket.org/vinay.sajip/logutils/pull-request/1/fix-python3-tests-and-make-test-failures/diff |
856 | +Last-Update: 2014-07-04 |
857 | + |
858 | +Index: python-logutils/setup.py |
859 | +=================================================================== |
860 | +--- python-logutils.orig/setup.py |
861 | ++++ python-logutils/setup.py |
862 | +@@ -27,7 +27,9 @@ class TestCommand(distutils.core.Command |
863 | + import logutil_tests |
864 | + loader = unittest.TestLoader() |
865 | + runner = unittest.TextTestRunner() |
866 | +- runner.run(loader.loadTestsFromModule(logutil_tests)) |
867 | ++ test_results = runner.run(loader.loadTestsFromModule(logutil_tests)) |
868 | ++ if not test_results.wasSuccessful(): |
869 | ++ sys.exit(1) |
870 | + |
871 | + def initialize_options(self): |
872 | + pass |
873 | |
874 | === modified file 'setup.py' |
875 | --- setup.py 2014-01-09 14:31:16 +0000 |
876 | +++ setup.py 2014-07-16 11:40:18 +0000 |
877 | @@ -27,7 +27,9 @@ |
878 | import logutil_tests |
879 | loader = unittest.TestLoader() |
880 | runner = unittest.TextTestRunner() |
881 | - runner.run(loader.loadTestsFromModule(logutil_tests)) |
882 | + test_results = runner.run(loader.loadTestsFromModule(logutil_tests)) |
883 | + if not test_results.wasSuccessful(): |
884 | + sys.exit(1) |
885 | |
886 | def initialize_options(self): |
887 | pass |
888 | |
889 | === modified file 'tests/test_dictconfig.py' |
890 | --- tests/test_dictconfig.py 2014-01-09 14:31:16 +0000 |
891 | +++ tests/test_dictconfig.py 2014-07-16 11:40:18 +0000 |
892 | @@ -27,6 +27,12 @@ |
893 | def handlerFunc(): |
894 | return logging.StreamHandler() |
895 | |
896 | +def is_python2(): |
897 | + if sys.version_info >= (2, 0) and sys.version_info < (3, 0): |
898 | + return True |
899 | + else: |
900 | + return False |
901 | + |
902 | class CustomHandler(logging.StreamHandler): |
903 | pass |
904 | |
905 | @@ -44,7 +50,8 @@ |
906 | self.saved_handlers = logging._handlers.copy() |
907 | self.saved_handler_list = logging._handlerList[:] |
908 | self.saved_loggers = logger_dict.copy() |
909 | - self.saved_level_names = logging._levelNames.copy() |
910 | + if is_python2(): |
911 | + self.saved_level_names = logging._levelNames.copy() |
912 | finally: |
913 | logging._releaseLock() |
914 | |
915 | @@ -56,8 +63,9 @@ |
916 | self.root_logger.setLevel(self.original_logging_level) |
917 | logging._acquireLock() |
918 | try: |
919 | - logging._levelNames.clear() |
920 | - logging._levelNames.update(self.saved_level_names) |
921 | + if is_python2(): |
922 | + logging._levelNames.clear() |
923 | + logging._levelNames.update(self.saved_level_names) |
924 | logging._handlers.clear() |
925 | logging._handlers.update(self.saved_handlers) |
926 | logging._handlerList[:] = self.saved_handler_list |
Thanks for the feedback. I've submitted the fixes upstream and updated the branch with your recommendations.