@@ -18,47 +18,236 @@ package log
18
18
19
19
import (
20
20
"fmt"
21
+ "io/ioutil"
21
22
22
- tlogr "github.com/go-logr/logr/testing "
23
+ "github.com/go-logr/logr"
23
24
. "github.com/onsi/ginkgo"
24
25
. "github.com/onsi/gomega"
25
26
)
26
27
28
+ // fakeSyncWriter is a fake zap.SyncerWriter that lets us test if sync was called
29
+ type fakeSyncWriter bool
30
+
31
+ func (w * fakeSyncWriter ) Write (p []byte ) (int , error ) {
32
+ return len (p ), nil
33
+ }
34
+ func (w * fakeSyncWriter ) Sync () error {
35
+ * w = true
36
+ return nil
37
+ }
38
+
39
+ // logInfo is the information for a particular fakeLogger message
40
+ type logInfo struct {
41
+ name []string
42
+ tags []interface {}
43
+ msg string
44
+ }
45
+
46
+ // fakeLoggerRoot is the root object to which all fakeLoggers record their messages.
47
+ type fakeLoggerRoot struct {
48
+ messages []logInfo
49
+ }
50
+
51
+ // fakeLogger is a fake implementation of logr.Logger that records
52
+ // messages, tags, and names,
53
+ // just records the name.
54
+ type fakeLogger struct {
55
+ name []string
56
+ tags []interface {}
57
+
58
+ root * fakeLoggerRoot
59
+ }
60
+
61
+ func (f * fakeLogger ) WithName (name string ) logr.Logger {
62
+ names := append ([]string (nil ), f .name ... )
63
+ names = append (names , name )
64
+ return & fakeLogger {
65
+ name : names ,
66
+ tags : f .tags ,
67
+ root : f .root ,
68
+ }
69
+ }
70
+
71
+ func (f * fakeLogger ) WithValues (vals ... interface {}) logr.Logger {
72
+ tags := append ([]interface {}(nil ), f .tags ... )
73
+ tags = append (tags , vals ... )
74
+ return & fakeLogger {
75
+ name : f .name ,
76
+ tags : tags ,
77
+ root : f .root ,
78
+ }
79
+ }
80
+
81
+ func (f * fakeLogger ) Error (err error , msg string , vals ... interface {}) {
82
+ tags := append ([]interface {}(nil ), f .tags ... )
83
+ tags = append (tags , "error" , err )
84
+ tags = append (tags , vals ... )
85
+ f .root .messages = append (f .root .messages , logInfo {
86
+ name : append ([]string (nil ), f .name ... ),
87
+ tags : tags ,
88
+ msg : msg ,
89
+ })
90
+ }
91
+
92
+ func (f * fakeLogger ) Info (msg string , vals ... interface {}) {
93
+ tags := append ([]interface {}(nil ), f .tags ... )
94
+ tags = append (tags , vals ... )
95
+ f .root .messages = append (f .root .messages , logInfo {
96
+ name : append ([]string (nil ), f .name ... ),
97
+ tags : tags ,
98
+ msg : msg ,
99
+ })
100
+ }
101
+
102
+ func (f * fakeLogger ) Enabled () bool { return true }
103
+ func (f * fakeLogger ) V (lvl int ) logr.InfoLogger { return f }
104
+
27
105
var _ = Describe ("runtime log" , func () {
28
106
29
- Context ("Test Logger" , func () {
30
- It ("shoud set and fulfill with logger" , func () {
31
- logger := ZapLogger (false )
32
- Expect (logger ).NotTo (BeNil ())
33
- Log .WithName ("runtimeLog" ).WithValues ("newtag" , "newvalue" )
107
+ Describe ("top-level logger" , func () {
108
+ It ("hold newly created loggers until a logger is set" , func () {
109
+ By ("grabbing a new sub-logger and logging to it" )
110
+ l1 := Log .WithName ("runtimeLog" ).WithValues ("newtag" , "newvalue1" )
111
+ l1 .Info ("before msg" )
112
+
113
+ By ("actually setting the logger" )
114
+ logger := & fakeLogger {root : & fakeLoggerRoot {}}
34
115
SetLogger (logger )
35
- logger .WithName ("runtimeLog" ).WithValues ("newtag" , "newvalue" )
36
- Expect (Log .promise ).To (BeNil ())
37
- Expect (Log .Logger ).To (Equal (logger ))
38
- devLogger := ZapLogger (true )
39
- Expect (devLogger ).NotTo (BeNil ())
116
+
117
+ By ("grabbing another sub-logger and logging to both loggers" )
118
+ l2 := Log .WithName ("runtimeLog" ).WithValues ("newtag" , "newvalue2" )
119
+ l1 .Info ("after msg 1" )
120
+ l2 .Info ("after msg 2" )
121
+
122
+ By ("ensuring that messages after the logger was set were logged" )
123
+ Expect (logger .root .messages ).To (ConsistOf (
124
+ logInfo {name : []string {"runtimeLog" }, tags : []interface {}{"newtag" , "newvalue1" }, msg : "after msg 1" },
125
+ logInfo {name : []string {"runtimeLog" }, tags : []interface {}{"newtag" , "newvalue2" }, msg : "after msg 2" },
126
+ ))
127
+ })
128
+ })
129
+
130
+ Describe ("lazy logger initialization" , func () {
131
+ var (
132
+ root * fakeLoggerRoot
133
+ baseLog logr.Logger
134
+ delegLog * DelegatingLogger
135
+ )
136
+
137
+ BeforeEach (func () {
138
+ root = & fakeLoggerRoot {}
139
+ baseLog = & fakeLogger {root : root }
140
+ delegLog = NewDelegatingLogger (NullLogger {})
40
141
})
41
142
42
143
It ("should delegate with name" , func () {
43
- var name = "NoPromise"
44
- test := tlogr.NullLogger {}
45
- test .WithName (name )
46
- Log = & DelegatingLogger {
47
- Logger : tlogr.NullLogger {},
48
- }
49
- Log .WithName (name )
50
- Expect (Log .Logger ).To (Equal (test ))
144
+ By ("asking for a logger with a name before fulfill, and logging" )
145
+ befFulfill1 := delegLog .WithName ("before-fulfill" )
146
+ befFulfill2 := befFulfill1 .WithName ("two" )
147
+ befFulfill1 .Info ("before fulfill" )
148
+
149
+ By ("logging on the base logger before fulfill" )
150
+ delegLog .Info ("before fulfill base" )
151
+
152
+ By ("ensuring that no messages were actually recorded" )
153
+ Expect (root .messages ).To (BeEmpty ())
154
+
155
+ By ("fulfilling the promise" )
156
+ delegLog .Fulfill (baseLog )
157
+
158
+ By ("logging with the existing loggers after fulfilling" )
159
+ befFulfill1 .Info ("after 1" )
160
+ befFulfill2 .Info ("after 2" )
161
+
162
+ By ("grabbing a new sub-logger of a previously constructed logger and logging to it" )
163
+ befFulfill1 .WithName ("after-from-before" ).Info ("after 3" )
164
+
165
+ By ("logging with new loggers" )
166
+ delegLog .WithName ("after-fulfill" ).Info ("after 4" )
167
+
168
+ By ("ensuring that the messages are appropriately named" )
169
+ Expect (root .messages ).To (ConsistOf (
170
+ logInfo {name : []string {"before-fulfill" }, msg : "after 1" },
171
+ logInfo {name : []string {"before-fulfill" , "two" }, msg : "after 2" },
172
+ logInfo {name : []string {"before-fulfill" , "after-from-before" }, msg : "after 3" },
173
+ logInfo {name : []string {"after-fulfill" }, msg : "after 4" },
174
+ ))
51
175
})
52
176
53
177
It ("should delegate with tags" , func () {
54
- tags := []interface {}{"new" , "tags" }
55
- test := tlogr.NullLogger {}
56
- test .WithValues (tags )
57
- Log = & DelegatingLogger {
58
- Logger : tlogr.NullLogger {},
59
- }
60
- Log .WithValues (tags )
61
- Expect (Log .Logger ).To (Equal (test ))
178
+ By ("asking for a logger with a name before fulfill, and logging" )
179
+ befFulfill1 := delegLog .WithValues ("tag1" , "val1" )
180
+ befFulfill2 := befFulfill1 .WithValues ("tag2" , "val2" )
181
+ befFulfill1 .Info ("before fulfill" )
182
+
183
+ By ("logging on the base logger before fulfill" )
184
+ delegLog .Info ("before fulfill base" )
185
+
186
+ By ("ensuring that no messages were actually recorded" )
187
+ Expect (root .messages ).To (BeEmpty ())
188
+
189
+ By ("fulfilling the promise" )
190
+ delegLog .Fulfill (baseLog )
191
+
192
+ By ("logging with the existing loggers after fulfilling" )
193
+ befFulfill1 .Info ("after 1" )
194
+ befFulfill2 .Info ("after 2" )
195
+
196
+ By ("grabbing a new sub-logger of a previously constructed logger and logging to it" )
197
+ befFulfill1 .WithValues ("tag3" , "val3" ).Info ("after 3" )
198
+
199
+ By ("logging with new loggers" )
200
+ delegLog .WithValues ("tag3" , "val3" ).Info ("after 4" )
201
+
202
+ By ("ensuring that the messages are appropriately named" )
203
+ Expect (root .messages ).To (ConsistOf (
204
+ logInfo {tags : []interface {}{"tag1" , "val1" }, msg : "after 1" },
205
+ logInfo {tags : []interface {}{"tag1" , "val1" , "tag2" , "val2" }, msg : "after 2" },
206
+ logInfo {tags : []interface {}{"tag1" , "val1" , "tag3" , "val3" }, msg : "after 3" },
207
+ logInfo {tags : []interface {}{"tag3" , "val3" }, msg : "after 4" },
208
+ ))
209
+ })
210
+
211
+ It ("shouldn't fulfill twice" , func () {
212
+ By ("fulfilling once" )
213
+ delegLog .Fulfill (baseLog )
214
+
215
+ By ("logging a bit" )
216
+ delegLog .Info ("msg 1" )
217
+
218
+ By ("fulfilling with a new logger" )
219
+ delegLog .Fulfill (& fakeLogger {})
220
+
221
+ By ("logging some more" )
222
+ delegLog .Info ("msg 2" )
223
+
224
+ By ("checking that all log messages are present" )
225
+ Expect (root .messages ).To (ConsistOf (
226
+ logInfo {msg : "msg 1" },
227
+ logInfo {msg : "msg 2" },
228
+ ))
229
+ })
230
+ })
231
+
232
+ Describe ("Zap logger setup" , func () {
233
+ Context ("with the default output" , func () {
234
+ It ("shouldn't fail when setting up production" , func () {
235
+ Expect (ZapLogger (false )).NotTo (BeNil ())
236
+ })
237
+
238
+ It ("shouldn't fail when setting up development" , func () {
239
+ Expect (ZapLogger (true )).NotTo (BeNil ())
240
+ })
241
+ })
242
+
243
+ Context ("with custom non-sync output" , func () {
244
+ It ("shouldn't fail when setting up production" , func () {
245
+ Expect (ZapLoggerTo (ioutil .Discard , false )).NotTo (BeNil ())
246
+ })
247
+
248
+ It ("shouldn't fail when setting up development" , func () {
249
+ Expect (ZapLoggerTo (ioutil .Discard , true )).NotTo (BeNil ())
250
+ })
62
251
})
63
252
})
64
253
0 commit comments