github.com/yacovm/fabric@v2.0.0-alpha.0.20191128145320-c5d4087dc723+incompatible/common/flogging/core_test.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package flogging_test 8 9 import ( 10 "bytes" 11 "errors" 12 "testing" 13 14 "github.com/hyperledger/fabric/common/flogging" 15 "github.com/hyperledger/fabric/common/flogging/mock" 16 "github.com/stretchr/testify/assert" 17 "go.uber.org/zap" 18 "go.uber.org/zap/buffer" 19 "go.uber.org/zap/zapcore" 20 ) 21 22 func TestCoreWith(t *testing.T) { 23 core := &flogging.Core{ 24 Encoders: map[flogging.Encoding]zapcore.Encoder{}, 25 Observer: &mock.Observer{}, 26 } 27 clone := core.With([]zapcore.Field{zap.String("key", "value")}) 28 assert.Equal(t, core, clone) 29 30 jsonEncoder := zapcore.NewJSONEncoder(zapcore.EncoderConfig{}) 31 consoleEncoder := zapcore.NewConsoleEncoder(zapcore.EncoderConfig{}) 32 core = &flogging.Core{ 33 Encoders: map[flogging.Encoding]zapcore.Encoder{ 34 flogging.JSON: jsonEncoder, 35 flogging.CONSOLE: consoleEncoder, 36 }, 37 } 38 decorated := core.With([]zapcore.Field{zap.String("key", "value")}) 39 40 // verify the objects differ 41 assert.NotEqual(t, core, decorated) 42 43 // verify the objects only differ by the encoded fields 44 jsonEncoder.AddString("key", "value") 45 consoleEncoder.AddString("key", "value") 46 assert.Equal(t, core, decorated) 47 } 48 49 func TestCoreCheck(t *testing.T) { 50 var enabledArgs []zapcore.Level 51 levels := &flogging.LoggerLevels{} 52 err := levels.ActivateSpec("warning") 53 assert.NoError(t, err) 54 core := &flogging.Core{ 55 LevelEnabler: zap.LevelEnablerFunc(func(l zapcore.Level) bool { 56 enabledArgs = append(enabledArgs, l) 57 return l >= zapcore.WarnLevel 58 }), 59 Levels: levels, 60 } 61 62 // not enabled 63 ce := core.Check(zapcore.Entry{Level: zapcore.DebugLevel}, nil) 64 assert.Nil(t, ce) 65 ce = core.Check(zapcore.Entry{Level: zapcore.InfoLevel}, nil) 66 assert.Nil(t, ce) 67 68 // enabled 69 ce = core.Check(zapcore.Entry{Level: zapcore.WarnLevel}, nil) 70 assert.NotNil(t, ce) 71 72 assert.Equal(t, enabledArgs, []zapcore.Level{zapcore.DebugLevel, zapcore.InfoLevel, zapcore.WarnLevel}) 73 } 74 75 type sw struct { 76 bytes.Buffer 77 writeErr error 78 syncCalled bool 79 syncErr error 80 } 81 82 func (s *sw) Sync() error { 83 s.syncCalled = true 84 return s.syncErr 85 } 86 87 func (s *sw) Write(b []byte) (int, error) { 88 if s.writeErr != nil { 89 return 0, s.writeErr 90 } 91 return s.Buffer.Write(b) 92 } 93 94 func (s *sw) Encoding() flogging.Encoding { 95 return flogging.CONSOLE 96 } 97 98 func TestCoreWrite(t *testing.T) { 99 encoderConfig := zap.NewDevelopmentEncoderConfig() 100 encoderConfig.EncodeTime = nil 101 102 output := &sw{} 103 core := &flogging.Core{ 104 Encoders: map[flogging.Encoding]zapcore.Encoder{ 105 flogging.CONSOLE: zapcore.NewConsoleEncoder(encoderConfig), 106 }, 107 Selector: output, 108 Output: output, 109 } 110 111 entry := zapcore.Entry{ 112 Level: zapcore.InfoLevel, 113 Message: "this is a message", 114 } 115 err := core.Write(entry, nil) 116 assert.NoError(t, err) 117 assert.Equal(t, "INFO\tthis is a message\n", output.String()) 118 119 output.writeErr = errors.New("super-loose") 120 err = core.Write(entry, nil) 121 assert.EqualError(t, err, "super-loose") 122 } 123 124 func TestCoreWriteSync(t *testing.T) { 125 encoderConfig := zap.NewDevelopmentEncoderConfig() 126 encoderConfig.EncodeTime = nil 127 128 output := &sw{} 129 core := &flogging.Core{ 130 Encoders: map[flogging.Encoding]zapcore.Encoder{ 131 flogging.CONSOLE: zapcore.NewConsoleEncoder(encoderConfig), 132 }, 133 Selector: output, 134 Output: output, 135 } 136 137 entry := zapcore.Entry{ 138 Level: zapcore.DebugLevel, 139 Message: "no bugs for me", 140 } 141 err := core.Write(entry, nil) 142 assert.NoError(t, err) 143 assert.False(t, output.syncCalled) 144 145 entry = zapcore.Entry{ 146 Level: zapcore.PanicLevel, 147 Message: "gah!", 148 } 149 err = core.Write(entry, nil) 150 assert.NoError(t, err) 151 assert.True(t, output.syncCalled) 152 } 153 154 type brokenEncoder struct{ zapcore.Encoder } 155 156 func (b *brokenEncoder) EncodeEntry(zapcore.Entry, []zapcore.Field) (*buffer.Buffer, error) { 157 return nil, errors.New("broken encoder") 158 } 159 160 func TestCoreWriteEncodeFail(t *testing.T) { 161 output := &sw{} 162 core := &flogging.Core{ 163 Encoders: map[flogging.Encoding]zapcore.Encoder{ 164 flogging.CONSOLE: &brokenEncoder{}, 165 }, 166 Selector: output, 167 Output: output, 168 } 169 170 entry := zapcore.Entry{ 171 Level: zapcore.DebugLevel, 172 Message: "no bugs for me", 173 } 174 err := core.Write(entry, nil) 175 assert.EqualError(t, err, "broken encoder") 176 } 177 178 func TestCoreSync(t *testing.T) { 179 syncWriter := &sw{} 180 core := &flogging.Core{ 181 Output: syncWriter, 182 } 183 184 err := core.Sync() 185 assert.NoError(t, err) 186 assert.True(t, syncWriter.syncCalled) 187 188 syncWriter.syncErr = errors.New("bummer") 189 err = core.Sync() 190 assert.EqualError(t, err, "bummer") 191 } 192 193 func TestObserverCheck(t *testing.T) { 194 observer := &mock.Observer{} 195 entry := zapcore.Entry{ 196 Level: zapcore.DebugLevel, 197 Message: "message", 198 } 199 checkedEntry := &zapcore.CheckedEntry{} 200 201 levels := &flogging.LoggerLevels{} 202 levels.ActivateSpec("debug") 203 core := &flogging.Core{ 204 LevelEnabler: zap.LevelEnablerFunc(func(l zapcore.Level) bool { return true }), 205 Levels: levels, 206 Observer: observer, 207 } 208 209 ce := core.Check(entry, checkedEntry) 210 assert.Exactly(t, ce, checkedEntry) 211 212 assert.Equal(t, 1, observer.CheckCallCount()) 213 observedEntry, observedCE := observer.CheckArgsForCall(0) 214 assert.Equal(t, entry, observedEntry) 215 assert.Equal(t, ce, observedCE) 216 } 217 218 func TestObserverWriteEntry(t *testing.T) { 219 observer := &mock.Observer{} 220 entry := zapcore.Entry{ 221 Level: zapcore.DebugLevel, 222 Message: "message", 223 } 224 fields := []zapcore.Field{ 225 {Key: "key1", Type: zapcore.SkipType}, 226 {Key: "key2", Type: zapcore.SkipType}, 227 } 228 229 levels := &flogging.LoggerLevels{} 230 levels.ActivateSpec("debug") 231 selector := &sw{} 232 output := &sw{} 233 core := &flogging.Core{ 234 LevelEnabler: zap.LevelEnablerFunc(func(l zapcore.Level) bool { return true }), 235 Levels: levels, 236 Selector: selector, 237 Encoders: map[flogging.Encoding]zapcore.Encoder{ 238 flogging.CONSOLE: zapcore.NewConsoleEncoder(zapcore.EncoderConfig{}), 239 }, 240 Output: output, 241 Observer: observer, 242 } 243 244 err := core.Write(entry, fields) 245 assert.NoError(t, err) 246 247 assert.Equal(t, 1, observer.WriteEntryCallCount()) 248 observedEntry, observedFields := observer.WriteEntryArgsForCall(0) 249 assert.Equal(t, entry, observedEntry) 250 assert.Equal(t, fields, observedFields) 251 }