1 package logrus
2
3 import (
4 "bytes"
5 "context"
6 "fmt"
7 "testing"
8 "time"
9
10 "github.com/stretchr/testify/assert"
11 )
12
13 func TestEntryWithError(t *testing.T) {
14
15 assert := assert.New(t)
16
17 defer func() {
18 ErrorKey = "error"
19 }()
20
21 err := fmt.Errorf("kaboom at layer %d", 4711)
22
23 assert.Equal(err, WithError(err).Data["error"])
24
25 logger := New()
26 logger.Out = &bytes.Buffer{}
27 entry := NewEntry(logger)
28
29 assert.Equal(err, entry.WithError(err).Data["error"])
30
31 ErrorKey = "err"
32
33 assert.Equal(err, entry.WithError(err).Data["err"])
34
35 }
36
37 func TestEntryWithContext(t *testing.T) {
38 assert := assert.New(t)
39 ctx := context.WithValue(context.Background(), "foo", "bar")
40
41 assert.Equal(ctx, WithContext(ctx).Context)
42
43 logger := New()
44 logger.Out = &bytes.Buffer{}
45 entry := NewEntry(logger)
46
47 assert.Equal(ctx, entry.WithContext(ctx).Context)
48 }
49
50 func TestEntryWithContextCopiesData(t *testing.T) {
51 assert := assert.New(t)
52
53
54 logger := New()
55 logger.Out = &bytes.Buffer{}
56 parentEntry := NewEntry(logger).WithField("parentKey", "parentValue")
57
58
59 ctx1 := context.WithValue(context.Background(), "foo", "bar")
60 childEntry1 := parentEntry.WithContext(ctx1)
61 assert.Equal(ctx1, childEntry1.Context)
62
63 ctx2 := context.WithValue(context.Background(), "bar", "baz")
64 childEntry2 := parentEntry.WithContext(ctx2)
65 assert.Equal(ctx2, childEntry2.Context)
66 assert.NotEqual(ctx1, ctx2)
67
68
69 assert.Equal("parentValue", childEntry1.Data["parentKey"])
70 assert.Equal("parentValue", childEntry2.Data["parentKey"])
71
72
73 childEntry1.Data["childKey"] = "childValue"
74
75
76 val, exists := childEntry1.Data["childKey"]
77 assert.True(exists)
78 assert.Equal("childValue", val)
79
80
81 val, exists = childEntry2.Data["childKey"]
82 assert.False(exists)
83 assert.Empty(val)
84
85
86 val, exists = parentEntry.Data["childKey"]
87 assert.False(exists)
88 assert.Empty(val)
89 }
90
91 func TestEntryWithTimeCopiesData(t *testing.T) {
92 assert := assert.New(t)
93
94
95 logger := New()
96 logger.Out = &bytes.Buffer{}
97 parentEntry := NewEntry(logger).WithField("parentKey", "parentValue")
98
99
100 childEntry1 := parentEntry.WithTime(time.Now().AddDate(0, 0, 1))
101 childEntry2 := parentEntry.WithTime(time.Now().AddDate(0, 0, 2))
102
103
104 assert.Equal("parentValue", childEntry1.Data["parentKey"])
105 assert.Equal("parentValue", childEntry2.Data["parentKey"])
106
107
108 childEntry1.Data["childKey"] = "childValue"
109
110
111 val, exists := childEntry1.Data["childKey"]
112 assert.True(exists)
113 assert.Equal("childValue", val)
114
115
116 val, exists = childEntry2.Data["childKey"]
117 assert.False(exists)
118 assert.Empty(val)
119
120
121 val, exists = parentEntry.Data["childKey"]
122 assert.False(exists)
123 assert.Empty(val)
124 }
125
126 func TestEntryPanicln(t *testing.T) {
127 errBoom := fmt.Errorf("boom time")
128
129 defer func() {
130 p := recover()
131 assert.NotNil(t, p)
132
133 switch pVal := p.(type) {
134 case *Entry:
135 assert.Equal(t, "kaboom", pVal.Message)
136 assert.Equal(t, errBoom, pVal.Data["err"])
137 default:
138 t.Fatalf("want type *Entry, got %T: %#v", pVal, pVal)
139 }
140 }()
141
142 logger := New()
143 logger.Out = &bytes.Buffer{}
144 entry := NewEntry(logger)
145 entry.WithField("err", errBoom).Panicln("kaboom")
146 }
147
148 func TestEntryPanicf(t *testing.T) {
149 errBoom := fmt.Errorf("boom again")
150
151 defer func() {
152 p := recover()
153 assert.NotNil(t, p)
154
155 switch pVal := p.(type) {
156 case *Entry:
157 assert.Equal(t, "kaboom true", pVal.Message)
158 assert.Equal(t, errBoom, pVal.Data["err"])
159 default:
160 t.Fatalf("want type *Entry, got %T: %#v", pVal, pVal)
161 }
162 }()
163
164 logger := New()
165 logger.Out = &bytes.Buffer{}
166 entry := NewEntry(logger)
167 entry.WithField("err", errBoom).Panicf("kaboom %v", true)
168 }
169
170 func TestEntryPanic(t *testing.T) {
171 errBoom := fmt.Errorf("boom again")
172
173 defer func() {
174 p := recover()
175 assert.NotNil(t, p)
176
177 switch pVal := p.(type) {
178 case *Entry:
179 assert.Equal(t, "kaboom", pVal.Message)
180 assert.Equal(t, errBoom, pVal.Data["err"])
181 default:
182 t.Fatalf("want type *Entry, got %T: %#v", pVal, pVal)
183 }
184 }()
185
186 logger := New()
187 logger.Out = &bytes.Buffer{}
188 entry := NewEntry(logger)
189 entry.WithField("err", errBoom).Panic("kaboom")
190 }
191
192 const (
193 badMessage = "this is going to panic"
194 panicMessage = "this is broken"
195 )
196
197 type panickyHook struct{}
198
199 func (p *panickyHook) Levels() []Level {
200 return []Level{InfoLevel}
201 }
202
203 func (p *panickyHook) Fire(entry *Entry) error {
204 if entry.Message == badMessage {
205 panic(panicMessage)
206 }
207
208 return nil
209 }
210
211 func TestEntryHooksPanic(t *testing.T) {
212 logger := New()
213 logger.Out = &bytes.Buffer{}
214 logger.Level = InfoLevel
215 logger.Hooks.Add(&panickyHook{})
216
217 defer func() {
218 p := recover()
219 assert.NotNil(t, p)
220 assert.Equal(t, panicMessage, p)
221
222 entry := NewEntry(logger)
223 entry.Info("another message")
224 }()
225
226 entry := NewEntry(logger)
227 entry.Info(badMessage)
228 }
229
230 func TestEntryWithIncorrectField(t *testing.T) {
231 assert := assert.New(t)
232
233 fn := func() {}
234
235 e := Entry{Logger: New()}
236 eWithFunc := e.WithFields(Fields{"func": fn})
237 eWithFuncPtr := e.WithFields(Fields{"funcPtr": &fn})
238
239 assert.Equal(eWithFunc.err, `can not add field "func"`)
240 assert.Equal(eWithFuncPtr.err, `can not add field "funcPtr"`)
241
242 eWithFunc = eWithFunc.WithField("not_a_func", "it is a string")
243 eWithFuncPtr = eWithFuncPtr.WithField("not_a_func", "it is a string")
244
245 assert.Equal(eWithFunc.err, `can not add field "func"`)
246 assert.Equal(eWithFuncPtr.err, `can not add field "funcPtr"`)
247
248 eWithFunc = eWithFunc.WithTime(time.Now())
249 eWithFuncPtr = eWithFuncPtr.WithTime(time.Now())
250
251 assert.Equal(eWithFunc.err, `can not add field "func"`)
252 assert.Equal(eWithFuncPtr.err, `can not add field "funcPtr"`)
253 }
254
255 func TestEntryLogfLevel(t *testing.T) {
256 logger := New()
257 buffer := &bytes.Buffer{}
258 logger.Out = buffer
259 logger.SetLevel(InfoLevel)
260 entry := NewEntry(logger)
261
262 entry.Logf(DebugLevel, "%s", "debug")
263 assert.NotContains(t, buffer.String(), "debug")
264
265 entry.Logf(WarnLevel, "%s", "warn")
266 assert.Contains(t, buffer.String(), "warn")
267 }
268
269 func TestEntryReportCallerRace(t *testing.T) {
270 logger := New()
271 entry := NewEntry(logger)
272
273
274
275 go func() {
276 entry.Info("should not race")
277 }()
278 go func() {
279 logger.SetReportCaller(true)
280 }()
281 go func() {
282 entry.Info("should not race")
283 }()
284 }
285
286 func TestEntryFormatterRace(t *testing.T) {
287 logger := New()
288 entry := NewEntry(logger)
289
290
291
292 go func() {
293 entry.Info("should not race")
294 }()
295 go func() {
296 logger.SetFormatter(&TextFormatter{})
297 }()
298 go func() {
299 entry.Info("should not race")
300 }()
301 }
302
View as plain text