1 | """ |
---|
2 | Tests for allmydata.util.log. |
---|
3 | |
---|
4 | Ported to Python 3. |
---|
5 | """ |
---|
6 | |
---|
7 | from twisted.trial import unittest |
---|
8 | from twisted.python.failure import Failure |
---|
9 | |
---|
10 | from foolscap.logging import log |
---|
11 | |
---|
12 | from allmydata.util import log as tahoe_log |
---|
13 | |
---|
14 | |
---|
15 | class SampleError(Exception): |
---|
16 | pass |
---|
17 | |
---|
18 | |
---|
19 | class Log(unittest.TestCase): |
---|
20 | def setUp(self): |
---|
21 | self.messages = [] |
---|
22 | |
---|
23 | def msg(msg, facility, parent, *args, **kwargs): |
---|
24 | self.messages.append((msg, facility, parent, args, kwargs)) |
---|
25 | return "msg{}".format(len(self.messages)) |
---|
26 | |
---|
27 | self.patch(log, "msg", msg) |
---|
28 | |
---|
29 | def test_err(self): |
---|
30 | """Logging with log.err() causes tests to fail.""" |
---|
31 | try: |
---|
32 | raise SampleError("simple sample") |
---|
33 | except: |
---|
34 | f = Failure() |
---|
35 | tahoe_log.err(format="intentional sample error", |
---|
36 | failure=f, level=tahoe_log.OPERATIONAL, umid="wO9UoQ") |
---|
37 | result = self.flushLoggedErrors(SampleError) |
---|
38 | self.assertEqual(len(result), 1) |
---|
39 | |
---|
40 | def test_default_facility(self): |
---|
41 | """ |
---|
42 | If facility is passed to PrefixingLogMixin.__init__, it is used as |
---|
43 | default facility. |
---|
44 | """ |
---|
45 | class LoggingObject1(tahoe_log.PrefixingLogMixin): |
---|
46 | pass |
---|
47 | |
---|
48 | obj = LoggingObject1(facility="defaultfac") |
---|
49 | obj.log("hello") |
---|
50 | obj.log("world", facility="override") |
---|
51 | self.assertEqual(self.messages[-2][1], "defaultfac") |
---|
52 | self.assertEqual(self.messages[-1][1], "override") |
---|
53 | |
---|
54 | def test_with_prefix(self): |
---|
55 | """ |
---|
56 | If prefix is passed to PrefixingLogMixin.__init__, it is used in |
---|
57 | message rendering. |
---|
58 | """ |
---|
59 | class LoggingObject4(tahoe_log.PrefixingLogMixin): |
---|
60 | pass |
---|
61 | |
---|
62 | obj = LoggingObject4("fac", prefix="pre1") |
---|
63 | obj.log("hello") |
---|
64 | obj.log("world") |
---|
65 | self.assertEqual(self.messages[-2][0], '<LoggingObject4 #1>(pre1): hello') |
---|
66 | self.assertEqual(self.messages[-1][0], '<LoggingObject4 #1>(pre1): world') |
---|
67 | |
---|
68 | def test_with_bytes_prefix(self): |
---|
69 | """ |
---|
70 | If bytes prefix is passed to PrefixingLogMixin.__init__, it is used in |
---|
71 | message rendering. |
---|
72 | """ |
---|
73 | class LoggingObject5(tahoe_log.PrefixingLogMixin): |
---|
74 | pass |
---|
75 | |
---|
76 | obj = LoggingObject5("fac", prefix=b"pre1") |
---|
77 | obj.log("hello") |
---|
78 | obj.log("world") |
---|
79 | self.assertEqual(self.messages[-2][0], '<LoggingObject5 #1>(pre1): hello') |
---|
80 | self.assertEqual(self.messages[-1][0], '<LoggingObject5 #1>(pre1): world') |
---|
81 | |
---|
82 | def test_no_prefix(self): |
---|
83 | """ |
---|
84 | If no prefix is passed to PrefixingLogMixin.__init__, it is not used in |
---|
85 | message rendering. |
---|
86 | """ |
---|
87 | class LoggingObject2(tahoe_log.PrefixingLogMixin): |
---|
88 | pass |
---|
89 | |
---|
90 | obj = LoggingObject2() |
---|
91 | obj.log("hello") |
---|
92 | obj.log("world") |
---|
93 | self.assertEqual(self.messages[-2][0], '<LoggingObject2 #1>: hello') |
---|
94 | self.assertEqual(self.messages[-1][0], '<LoggingObject2 #1>: world') |
---|
95 | |
---|
96 | def test_numming(self): |
---|
97 | """ |
---|
98 | Objects inheriting from PrefixingLogMixin get a unique number from a |
---|
99 | class-specific counter. |
---|
100 | """ |
---|
101 | class LoggingObject3(tahoe_log.PrefixingLogMixin): |
---|
102 | pass |
---|
103 | |
---|
104 | obj = LoggingObject3() |
---|
105 | obj2 = LoggingObject3() |
---|
106 | obj.log("hello") |
---|
107 | obj2.log("world") |
---|
108 | self.assertEqual(self.messages[-2][0], '<LoggingObject3 #1>: hello') |
---|
109 | self.assertEqual(self.messages[-1][0], '<LoggingObject3 #2>: world') |
---|
110 | |
---|
111 | def test_parent_id(self): |
---|
112 | """ |
---|
113 | The parent message id can be passed in, otherwise the first message's |
---|
114 | id is used as the parent. |
---|
115 | |
---|
116 | This logic is pretty bogus, but that's what the code does. |
---|
117 | """ |
---|
118 | class LoggingObject1(tahoe_log.PrefixingLogMixin): |
---|
119 | pass |
---|
120 | |
---|
121 | obj = LoggingObject1() |
---|
122 | result = obj.log("zero") |
---|
123 | self.assertEqual(result, "msg1") |
---|
124 | obj.log("one", parent="par1") |
---|
125 | obj.log("two", parent="par2") |
---|
126 | obj.log("three") |
---|
127 | obj.log("four") |
---|
128 | self.assertEqual([m[2] for m in self.messages], |
---|
129 | [None, "par1", "par2", "msg1", "msg1"]) |
---|
130 | |
---|
131 | def test_grandparent_id(self): |
---|
132 | """ |
---|
133 | If grandparent message id is given, it's used as parent id of the first |
---|
134 | message. |
---|
135 | """ |
---|
136 | class LoggingObject1(tahoe_log.PrefixingLogMixin): |
---|
137 | pass |
---|
138 | |
---|
139 | obj = LoggingObject1(grandparentmsgid="grand") |
---|
140 | result = obj.log("zero") |
---|
141 | self.assertEqual(result, "msg1") |
---|
142 | obj.log("one", parent="par1") |
---|
143 | obj.log("two", parent="par2") |
---|
144 | obj.log("three") |
---|
145 | obj.log("four") |
---|
146 | self.assertEqual([m[2] for m in self.messages], |
---|
147 | ["grand", "par1", "par2", "msg1", "msg1"]) |
---|
148 | |
---|
149 | def test_native_string_keys(self): |
---|
150 | """Keyword argument keys are all native strings.""" |
---|
151 | class LoggingObject17(tahoe_log.PrefixingLogMixin): |
---|
152 | pass |
---|
153 | |
---|
154 | obj = LoggingObject17() |
---|
155 | # Native string by default: |
---|
156 | obj.log(hello="world") |
---|
157 | # Will be Unicode on Python 2: |
---|
158 | obj.log(**{"my": "message"}) |
---|
159 | for message in self.messages: |
---|
160 | for k in message[-1].keys(): |
---|
161 | self.assertIsInstance(k, str) |
---|