blob: 54d17a3f013829498af3deaa96843bae66d4282a [file] [log] [blame]
Neal Norwitzb4a2df02003-01-02 14:56:39 +00001#!/usr/bin/env python
2#
Vinay Sajip7dc8ec92004-06-02 10:51:05 +00003# Copyright 2001-2004 by Vinay Sajip. All Rights Reserved.
Neal Norwitzb4a2df02003-01-02 14:56:39 +00004#
5# Permission to use, copy, modify, and distribute this software and its
6# documentation for any purpose and without fee is hereby granted,
7# provided that the above copyright notice appear in all copies and that
8# both that copyright notice and this permission notice appear in
9# supporting documentation, and that the name of Vinay Sajip
10# not be used in advertising or publicity pertaining to distribution
11# of the software without specific, written prior permission.
12# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
13# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
14# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
15# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
16# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
17# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18#
19# This file is part of the Python logging distribution. See
20# http://www.red-dove.com/python_logging.html
21#
22"""Test harness for the logging module. Run all tests.
23
24Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
25"""
26
Guido van Rossum2a1d5162003-01-21 21:05:22 +000027import select
Neal Norwitzb4a2df02003-01-02 14:56:39 +000028import os, sys, string, struct, types, cPickle, cStringIO
Vinay Sajip22b25aa2006-01-16 21:24:38 +000029import socket, tempfile, threading, time
Neal Norwitzb4a2df02003-01-02 14:56:39 +000030import logging, logging.handlers, logging.config
31
Neal Norwitzb4a2df02003-01-02 14:56:39 +000032BANNER = "-- %-10s %-6s ---------------------------------------------------\n"
33
Guido van Rossum376e6362003-04-25 14:22:00 +000034FINISH_UP = "Finish up, it's closing time. Messages should bear numbers 0 through 24."
35
Neal Norwitzb4a2df02003-01-02 14:56:39 +000036#----------------------------------------------------------------------------
37# Log receiver
38#----------------------------------------------------------------------------
39
40TIMEOUT = 10
41
42from SocketServer import ThreadingTCPServer, StreamRequestHandler
43
44class LogRecordStreamHandler(StreamRequestHandler):
45 """
46 Handler for a streaming logging request. It basically logs the record
47 using whatever logging policy is configured locally.
48 """
49
50 def handle(self):
51 """
52 Handle multiple requests - each expected to be a 4-byte length,
53 followed by the LogRecord in pickle format. Logs the record
54 according to whatever policy is configured locally.
55 """
56 while 1:
57 try:
58 chunk = self.connection.recv(4)
59 if len(chunk) < 4:
60 break
61 slen = struct.unpack(">L", chunk)[0]
Neal Norwitzb4a2df02003-01-02 14:56:39 +000062 chunk = self.connection.recv(slen)
63 while len(chunk) < slen:
64 chunk = chunk + self.connection.recv(slen - len(chunk))
65 obj = self.unPickle(chunk)
Raymond Hettinger6f3eaa62003-06-27 21:43:39 +000066 record = logging.makeLogRecord(obj)
Neal Norwitzb4a2df02003-01-02 14:56:39 +000067 self.handleLogRecord(record)
68 except:
69 raise
70
71 def unPickle(self, data):
72 return cPickle.loads(data)
73
74 def handleLogRecord(self, record):
75 logname = "logrecv.tcp." + record.name
Guido van Rossum376e6362003-04-25 14:22:00 +000076 #If the end-of-messages sentinel is seen, tell the server to terminate
77 if record.msg == FINISH_UP:
78 self.server.abort = 1
Neal Norwitzb4a2df02003-01-02 14:56:39 +000079 record.msg = record.msg + " (via " + logname + ")"
80 logger = logging.getLogger(logname)
81 logger.handle(record)
82
Brett Cannonf9addb62003-04-30 05:32:32 +000083# The server sets socketDataProcessed when it's done.
84socketDataProcessed = threading.Event()
Guido van Rossum376e6362003-04-25 14:22:00 +000085
Neal Norwitzb4a2df02003-01-02 14:56:39 +000086class LogRecordSocketReceiver(ThreadingTCPServer):
87 """
88 A simple-minded TCP socket-based logging receiver suitable for test
89 purposes.
90 """
91
92 allow_reuse_address = 1
93
94 def __init__(self, host='localhost',
95 port=logging.handlers.DEFAULT_TCP_LOGGING_PORT,
96 handler=LogRecordStreamHandler):
97 ThreadingTCPServer.__init__(self, (host, port), handler)
98 self.abort = 0
99 self.timeout = 1
100
101 def serve_until_stopped(self):
102 abort = 0
103 while not abort:
Guido van Rossum2a1d5162003-01-21 21:05:22 +0000104 rd, wr, ex = select.select([self.socket.fileno()],
Neal Norwitzb4a2df02003-01-02 14:56:39 +0000105 [], [],
106 self.timeout)
107 if rd:
108 self.handle_request()
109 abort = self.abort
Guido van Rossum376e6362003-04-25 14:22:00 +0000110 #notify the main thread that we're about to exit
Brett Cannonf9addb62003-04-30 05:32:32 +0000111 socketDataProcessed.set()
Martin v. Löwisf6848882006-01-29 19:55:18 +0000112 # close the listen socket
113 self.server_close()
Neal Norwitzb4a2df02003-01-02 14:56:39 +0000114
Guido van Rossum2a1d5162003-01-21 21:05:22 +0000115 def process_request(self, request, client_address):
116 #import threading
117 t = threading.Thread(target = self.finish_request,
118 args = (request, client_address))
119 t.start()
120
Neal Norwitzb4a2df02003-01-02 14:56:39 +0000121def runTCP(tcpserver):
122 tcpserver.serve_until_stopped()
123
124#----------------------------------------------------------------------------
125# Test 0
126#----------------------------------------------------------------------------
127
128msgcount = 0
129
130def nextmessage():
131 global msgcount
132 rv = "Message %d" % msgcount
133 msgcount = msgcount + 1
134 return rv
135
136def test0():
137 ERR = logging.getLogger("ERR")
138 ERR.setLevel(logging.ERROR)
139 INF = logging.getLogger("INF")
140 INF.setLevel(logging.INFO)
141 INF_ERR = logging.getLogger("INF.ERR")
142 INF_ERR.setLevel(logging.ERROR)
143 DEB = logging.getLogger("DEB")
144 DEB.setLevel(logging.DEBUG)
145
146 INF_UNDEF = logging.getLogger("INF.UNDEF")
147 INF_ERR_UNDEF = logging.getLogger("INF.ERR.UNDEF")
148 UNDEF = logging.getLogger("UNDEF")
149
150 GRANDCHILD = logging.getLogger("INF.BADPARENT.UNDEF")
151 CHILD = logging.getLogger("INF.BADPARENT")
152
153 #These should log
154 ERR.log(logging.FATAL, nextmessage())
155 ERR.error(nextmessage())
156
157 INF.log(logging.FATAL, nextmessage())
158 INF.error(nextmessage())
159 INF.warn(nextmessage())
160 INF.info(nextmessage())
161
162 INF_UNDEF.log(logging.FATAL, nextmessage())
163 INF_UNDEF.error(nextmessage())
164 INF_UNDEF.warn (nextmessage())
165 INF_UNDEF.info (nextmessage())
166
167 INF_ERR.log(logging.FATAL, nextmessage())
168 INF_ERR.error(nextmessage())
169
170 INF_ERR_UNDEF.log(logging.FATAL, nextmessage())
171 INF_ERR_UNDEF.error(nextmessage())
172
173 DEB.log(logging.FATAL, nextmessage())
174 DEB.error(nextmessage())
175 DEB.warn (nextmessage())
176 DEB.info (nextmessage())
177 DEB.debug(nextmessage())
178
179 UNDEF.log(logging.FATAL, nextmessage())
180 UNDEF.error(nextmessage())
181 UNDEF.warn (nextmessage())
182 UNDEF.info (nextmessage())
183
184 GRANDCHILD.log(logging.FATAL, nextmessage())
185 CHILD.log(logging.FATAL, nextmessage())
186
187 #These should not log
188 ERR.warn(nextmessage())
189 ERR.info(nextmessage())
190 ERR.debug(nextmessage())
191
192 INF.debug(nextmessage())
193 INF_UNDEF.debug(nextmessage())
194
195 INF_ERR.warn(nextmessage())
196 INF_ERR.info(nextmessage())
197 INF_ERR.debug(nextmessage())
198 INF_ERR_UNDEF.warn(nextmessage())
199 INF_ERR_UNDEF.info(nextmessage())
200 INF_ERR_UNDEF.debug(nextmessage())
201
Guido van Rossum376e6362003-04-25 14:22:00 +0000202 INF.info(FINISH_UP)
Neal Norwitzb4a2df02003-01-02 14:56:39 +0000203
204#----------------------------------------------------------------------------
205# Test 1
206#----------------------------------------------------------------------------
207
208#
209# First, we define our levels. There can be as many as you want - the only
210# limitations are that they should be integers, the lowest should be > 0 and
211# larger values mean less information being logged. If you need specific
212# level values which do not fit into these limitations, you can use a
213# mapping dictionary to convert between your application levels and the
214# logging system.
215#
216SILENT = 10
217TACITURN = 9
218TERSE = 8
219EFFUSIVE = 7
220SOCIABLE = 6
221VERBOSE = 5
222TALKATIVE = 4
223GARRULOUS = 3
224CHATTERBOX = 2
225BORING = 1
226
227LEVEL_RANGE = range(BORING, SILENT + 1)
228
229#
230# Next, we define names for our levels. You don't need to do this - in which
231# case the system will use "Level n" to denote the text for the level.
232#
233my_logging_levels = {
234 SILENT : 'Silent',
235 TACITURN : 'Taciturn',
236 TERSE : 'Terse',
237 EFFUSIVE : 'Effusive',
238 SOCIABLE : 'Sociable',
239 VERBOSE : 'Verbose',
240 TALKATIVE : 'Talkative',
241 GARRULOUS : 'Garrulous',
242 CHATTERBOX : 'Chatterbox',
243 BORING : 'Boring',
244}
245
246#
247# Now, to demonstrate filtering: suppose for some perverse reason we only
248# want to print out all except GARRULOUS messages. Let's create a filter for
249# this purpose...
250#
251class SpecificLevelFilter(logging.Filter):
252 def __init__(self, lvl):
253 self.level = lvl
254
255 def filter(self, record):
256 return self.level != record.levelno
257
258class GarrulousFilter(SpecificLevelFilter):
259 def __init__(self):
260 SpecificLevelFilter.__init__(self, GARRULOUS)
261
262#
263# Now, let's demonstrate filtering at the logger. This time, use a filter
264# which excludes SOCIABLE and TACITURN messages. Note that GARRULOUS events
265# are still excluded.
266#
267class VerySpecificFilter(logging.Filter):
268 def filter(self, record):
269 return record.levelno not in [SOCIABLE, TACITURN]
270
271def message(s):
272 sys.stdout.write("%s\n" % s)
273
274SHOULD1 = "This should only be seen at the '%s' logging level (or lower)"
275
276def test1():
277#
278# Now, tell the logging system to associate names with our levels.
279#
280 for lvl in my_logging_levels.keys():
281 logging.addLevelName(lvl, my_logging_levels[lvl])
282
283#
284# Now, define a test function which logs an event at each of our levels.
285#
286
287 def doLog(log):
288 for lvl in LEVEL_RANGE:
289 log.log(lvl, SHOULD1, logging.getLevelName(lvl))
290
291 log = logging.getLogger("")
292 hdlr = log.handlers[0]
293#
294# Set the logging level to each different value and call the utility
295# function to log events.
296# In the output, you should see that each time round the loop, the number of
297# logging events which are actually output decreases.
298#
299 for lvl in LEVEL_RANGE:
300 message("-- setting logging level to '%s' -----" %
301 logging.getLevelName(lvl))
302 log.setLevel(lvl)
303 doLog(log)
304 #
305 # Now, we demonstrate level filtering at the handler level. Tell the
306 # handler defined above to filter at level 'SOCIABLE', and repeat the
307 # above loop. Compare the output from the two runs.
308 #
309 hdlr.setLevel(SOCIABLE)
310 message("-- Filtering at handler level to SOCIABLE --")
311 for lvl in LEVEL_RANGE:
312 message("-- setting logging level to '%s' -----" %
313 logging.getLevelName(lvl))
314 log.setLevel(lvl)
315 doLog(log)
316
317 hdlr.setLevel(0) #turn off level filtering at the handler
318
319 garr = GarrulousFilter()
320 hdlr.addFilter(garr)
321 message("-- Filtering using GARRULOUS filter --")
322 for lvl in LEVEL_RANGE:
323 message("-- setting logging level to '%s' -----" %
324 logging.getLevelName(lvl))
325 log.setLevel(lvl)
326 doLog(log)
327 spec = VerySpecificFilter()
328 log.addFilter(spec)
329 message("-- Filtering using specific filter for SOCIABLE, TACITURN --")
330 for lvl in LEVEL_RANGE:
331 message("-- setting logging level to '%s' -----" %
332 logging.getLevelName(lvl))
333 log.setLevel(lvl)
334 doLog(log)
335
336 log.removeFilter(spec)
337 hdlr.removeFilter(garr)
338 #Undo the one level which clashes...for regression tests
339 logging.addLevelName(logging.DEBUG, "DEBUG")
340
341#----------------------------------------------------------------------------
342# Test 2
343#----------------------------------------------------------------------------
344
345MSG = "-- logging %d at INFO, messages should be seen every 10 events --"
346def test2():
347 logger = logging.getLogger("")
348 sh = logger.handlers[0]
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000349 sh.close()
Neal Norwitzb4a2df02003-01-02 14:56:39 +0000350 logger.removeHandler(sh)
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000351 mh = logging.handlers.MemoryHandler(10,logging.WARNING, sh)
Neal Norwitzb4a2df02003-01-02 14:56:39 +0000352 logger.setLevel(logging.DEBUG)
353 logger.addHandler(mh)
354 message("-- logging at DEBUG, nothing should be seen yet --")
355 logger.debug("Debug message")
356 message("-- logging at INFO, nothing should be seen yet --")
357 logger.info("Info message")
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000358 message("-- logging at WARNING, 3 messages should be seen --")
Neal Norwitzb4a2df02003-01-02 14:56:39 +0000359 logger.warn("Warn message")
360 for i in xrange(102):
361 message(MSG % i)
362 logger.info("Info index = %d", i)
363 mh.close()
364 logger.removeHandler(mh)
365 logger.addHandler(sh)
366
367#----------------------------------------------------------------------------
368# Test 3
369#----------------------------------------------------------------------------
370
371FILTER = "a.b"
372
373def doLog3():
374 logging.getLogger("a").info("Info 1")
375 logging.getLogger("a.b").info("Info 2")
376 logging.getLogger("a.c").info("Info 3")
377 logging.getLogger("a.b.c").info("Info 4")
378 logging.getLogger("a.b.c.d").info("Info 5")
379 logging.getLogger("a.bb.c").info("Info 6")
380 logging.getLogger("b").info("Info 7")
381 logging.getLogger("b.a").info("Info 8")
382 logging.getLogger("c.a.b").info("Info 9")
383 logging.getLogger("a.bb").info("Info 10")
384
385def test3():
386 root = logging.getLogger()
387 root.setLevel(logging.DEBUG)
388 hand = root.handlers[0]
389 message("Unfiltered...")
390 doLog3()
391 message("Filtered with '%s'..." % FILTER)
392 filt = logging.Filter(FILTER)
393 hand.addFilter(filt)
394 doLog3()
395 hand.removeFilter(filt)
396
397#----------------------------------------------------------------------------
Vinay Sajip22b25aa2006-01-16 21:24:38 +0000398# Test 4
399#----------------------------------------------------------------------------
400
Vinay Sajip568482a2006-01-20 18:29:36 +0000401# config0 is a standard configuration.
Vinay Sajip22b25aa2006-01-16 21:24:38 +0000402config0 = """
403[loggers]
404keys=root
405
406[handlers]
407keys=hand1
408
409[formatters]
410keys=form1
411
412[logger_root]
413level=NOTSET
414handlers=hand1
415
416[handler_hand1]
417class=StreamHandler
418level=NOTSET
419formatter=form1
420args=(sys.stdout,)
421
422[formatter_form1]
423format=%(levelname)s:%(name)s:%(message)s
424datefmt=
425"""
426
427# config1 adds a little to the standard configuration.
428config1 = """
429[loggers]
430keys=root,parser
431
432[handlers]
433keys=hand1
434
435[formatters]
436keys=form1
437
438[logger_root]
439level=NOTSET
440handlers=hand1
441
442[logger_parser]
443level=DEBUG
444handlers=hand1
445propagate=1
446qualname=compiler.parser
447
448[handler_hand1]
449class=StreamHandler
450level=NOTSET
451formatter=form1
452args=(sys.stdout,)
453
454[formatter_form1]
455format=%(levelname)s:%(name)s:%(message)s
456datefmt=
457"""
458
459# config2 has a subtle configuration error that should be reported
460config2 = string.replace(config1, "sys.stdout", "sys.stbout")
461
462# config3 has a less subtle configuration error
463config3 = string.replace(
464 config1, "formatter=form1", "formatter=misspelled_name")
465
466def test4():
467 for i in range(4):
468 conf = globals()['config%d' % i]
469 sys.stdout.write('config%d: ' % i)
470 loggerDict = logging.getLogger().manager.loggerDict
471 saved_handlers = logging._handlers.copy()
472 saved_loggers = loggerDict.copy()
473 try:
474 fn = tempfile.mktemp(".ini")
475 f = open(fn, "w")
476 f.write(conf)
477 f.close()
478 try:
479 logging.config.fileConfig(fn)
480 except:
481 t = sys.exc_info()[0]
482 message(str(t))
483 else:
484 message('ok.')
485 os.remove(fn)
486 finally:
487 logging._handlers.clear()
488 logging._handlers.update(saved_handlers)
489 loggerDict = logging.getLogger().manager.loggerDict
490 loggerDict.clear()
491 loggerDict.update(saved_loggers)
492
493#----------------------------------------------------------------------------
Vinay Sajip568482a2006-01-20 18:29:36 +0000494# Test 5
495#----------------------------------------------------------------------------
496
497test5_config = """
498[loggers]
499keys=root
500
501[handlers]
502keys=hand1
503
504[formatters]
505keys=form1
506
507[logger_root]
508level=NOTSET
509handlers=hand1
510
511[handler_hand1]
512class=StreamHandler
513level=NOTSET
514formatter=form1
515args=(sys.stdout,)
516
517[formatter_form1]
518class=test.test_logging.FriendlyFormatter
519format=%(levelname)s:%(name)s:%(message)s
520datefmt=
521"""
522
523class FriendlyFormatter (logging.Formatter):
524 def formatException(self, ei):
525 return "%s... Don't panic!" % str(ei[0])
526
527
528def test5():
529 loggerDict = logging.getLogger().manager.loggerDict
530 saved_handlers = logging._handlers.copy()
531 saved_loggers = loggerDict.copy()
532 try:
533 fn = tempfile.mktemp(".ini")
534 f = open(fn, "w")
535 f.write(test5_config)
536 f.close()
537 logging.config.fileConfig(fn)
538 try:
539 raise KeyError
540 except KeyError:
541 logging.exception("just testing")
542 os.remove(fn)
543 finally:
544 logging._handlers.clear()
545 logging._handlers.update(saved_handlers)
546 loggerDict = logging.getLogger().manager.loggerDict
547 loggerDict.clear()
548 loggerDict.update(saved_loggers)
549
550
551
552#----------------------------------------------------------------------------
Neal Norwitzb4a2df02003-01-02 14:56:39 +0000553# Test Harness
554#----------------------------------------------------------------------------
555def banner(nm, typ):
556 sep = BANNER % (nm, typ)
557 sys.stdout.write(sep)
558 sys.stdout.flush()
559
Tim Peters36f7e932003-07-23 00:05:07 +0000560def test_main_inner():
Neal Norwitzb4a2df02003-01-02 14:56:39 +0000561 rootLogger = logging.getLogger("")
562 rootLogger.setLevel(logging.DEBUG)
563 hdlr = logging.StreamHandler(sys.stdout)
564 fmt = logging.Formatter(logging.BASIC_FORMAT)
565 hdlr.setFormatter(fmt)
566 rootLogger.addHandler(hdlr)
567
568 #Set up a handler such that all events are sent via a socket to the log
569 #receiver (logrecv).
570 #The handler will only be added to the rootLogger for some of the tests
Vinay Sajip6887c922004-08-04 08:29:14 +0000571 shdlr = logging.handlers.SocketHandler('localhost',
Neal Norwitzb4a2df02003-01-02 14:56:39 +0000572 logging.handlers.DEFAULT_TCP_LOGGING_PORT)
573
574 #Configure the logger for logrecv so events do not propagate beyond it.
575 #The sockLogger output is buffered in memory until the end of the test,
576 #and printed at the end.
577 sockOut = cStringIO.StringIO()
578 sockLogger = logging.getLogger("logrecv")
579 sockLogger.setLevel(logging.DEBUG)
580 sockhdlr = logging.StreamHandler(sockOut)
581 sockhdlr.setFormatter(logging.Formatter(
582 "%(name)s -> %(levelname)s: %(message)s"))
583 sockLogger.addHandler(sockhdlr)
584 sockLogger.propagate = 0
585
586 #Set up servers
587 threads = []
588 tcpserver = LogRecordSocketReceiver()
Guido van Rossum2a1d5162003-01-21 21:05:22 +0000589 #sys.stdout.write("About to start TCP server...\n")
Neal Norwitzb4a2df02003-01-02 14:56:39 +0000590 threads.append(threading.Thread(target=runTCP, args=(tcpserver,)))
591
592 for thread in threads:
593 thread.start()
594 try:
595 banner("log_test0", "begin")
596
Vinay Sajip6887c922004-08-04 08:29:14 +0000597 rootLogger.addHandler(shdlr)
Neal Norwitzb4a2df02003-01-02 14:56:39 +0000598 test0()
Vinay Sajip6887c922004-08-04 08:29:14 +0000599 shdlr.close()
600 rootLogger.removeHandler(shdlr)
Neal Norwitzb4a2df02003-01-02 14:56:39 +0000601
602 banner("log_test0", "end")
603
Vinay Sajip568482a2006-01-20 18:29:36 +0000604 for t in range(1,6):
605 banner("log_test%d" % t, "begin")
606 globals()['test%d' % t]()
607 banner("log_test%d" % t, "end")
Vinay Sajip22b25aa2006-01-16 21:24:38 +0000608
Neal Norwitzb4a2df02003-01-02 14:56:39 +0000609 finally:
Guido van Rossum376e6362003-04-25 14:22:00 +0000610 #wait for TCP receiver to terminate
Guido van Rossum376e6362003-04-25 14:22:00 +0000611 socketDataProcessed.wait()
Guido van Rossumecf0f022003-04-26 00:21:31 +0000612 for thread in threads:
613 thread.join()
Guido van Rossum2a1d5162003-01-21 21:05:22 +0000614 banner("logrecv output", "begin")
615 sys.stdout.write(sockOut.getvalue())
616 sockOut.close()
Vinay Sajip6887c922004-08-04 08:29:14 +0000617 sockLogger.removeHandler(sockhdlr)
618 sockhdlr.close()
Guido van Rossum2a1d5162003-01-21 21:05:22 +0000619 banner("logrecv output", "end")
620 sys.stdout.flush()
Vinay Sajip6887c922004-08-04 08:29:14 +0000621 try:
622 hdlr.close()
623 except:
624 pass
625 rootLogger.removeHandler(hdlr)
Neal Norwitzb4a2df02003-01-02 14:56:39 +0000626
Tim Peters36f7e932003-07-23 00:05:07 +0000627def test_main():
628 import locale
629 # Set the locale to the platform-dependent default. I have no idea
630 # why the test does this, but in any case we save the current locale
631 # first so we can restore it at the end.
632 try:
633 original_locale = locale.setlocale(locale.LC_ALL)
634 locale.setlocale(locale.LC_ALL, '')
635 except (ValueError, locale.Error):
636 # this happens on a Solaris box which only supports "C" locale
637 # or a Mac OS X box which supports very little locale stuff at all
638 original_locale = None
639
Tim Peters0cdc3d82005-12-30 20:46:23 +0000640 # Save and restore the original root logger level across the tests.
641 # Otherwise, e.g., if any test using cookielib runs after test_logging,
642 # cookielib's debug-level logger tries to log messages, leading to
643 # confusing:
644 # No handlers could be found for logger "cookielib"
645 # output while the tests are running.
646 root_logger = logging.getLogger("")
647 original_logging_level = root_logger.getEffectiveLevel()
Tim Peters36f7e932003-07-23 00:05:07 +0000648 try:
649 test_main_inner()
650 finally:
Tim Peters9390dd52003-07-23 00:30:11 +0000651 if original_locale is not None:
Tim Peters36f7e932003-07-23 00:05:07 +0000652 locale.setlocale(locale.LC_ALL, original_locale)
Tim Peters0cdc3d82005-12-30 20:46:23 +0000653 root_logger.setLevel(original_logging_level)
Jeremy Hylton096d9862003-07-18 03:19:20 +0000654
Neal Norwitzb4a2df02003-01-02 14:56:39 +0000655if __name__ == "__main__":
656 sys.stdout.write("test_logging\n")
657 test_main()