github.com/osdi23p228/fabric@v0.0.0-20221218062954-77808885f5db/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/osdi23p228/fabric/common/flogging"
    15  	"github.com/osdi23p228/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  	err := levels.ActivateSpec("debug")
   203  	assert.NoError(t, err)
   204  	core := &flogging.Core{
   205  		LevelEnabler: zap.LevelEnablerFunc(func(l zapcore.Level) bool { return true }),
   206  		Levels:       levels,
   207  		Observer:     observer,
   208  	}
   209  
   210  	ce := core.Check(entry, checkedEntry)
   211  	assert.Exactly(t, ce, checkedEntry)
   212  
   213  	assert.Equal(t, 1, observer.CheckCallCount())
   214  	observedEntry, observedCE := observer.CheckArgsForCall(0)
   215  	assert.Equal(t, entry, observedEntry)
   216  	assert.Equal(t, ce, observedCE)
   217  }
   218  
   219  func TestObserverWriteEntry(t *testing.T) {
   220  	observer := &mock.Observer{}
   221  	entry := zapcore.Entry{
   222  		Level:   zapcore.DebugLevel,
   223  		Message: "message",
   224  	}
   225  	fields := []zapcore.Field{
   226  		{Key: "key1", Type: zapcore.SkipType},
   227  		{Key: "key2", Type: zapcore.SkipType},
   228  	}
   229  
   230  	levels := &flogging.LoggerLevels{}
   231  	err := levels.ActivateSpec("debug")
   232  	assert.NoError(t, err)
   233  	selector := &sw{}
   234  	output := &sw{}
   235  	core := &flogging.Core{
   236  		LevelEnabler: zap.LevelEnablerFunc(func(l zapcore.Level) bool { return true }),
   237  		Levels:       levels,
   238  		Selector:     selector,
   239  		Encoders: map[flogging.Encoding]zapcore.Encoder{
   240  			flogging.CONSOLE: zapcore.NewConsoleEncoder(zapcore.EncoderConfig{}),
   241  		},
   242  		Output:   output,
   243  		Observer: observer,
   244  	}
   245  
   246  	err = core.Write(entry, fields)
   247  	assert.NoError(t, err)
   248  
   249  	assert.Equal(t, 1, observer.WriteEntryCallCount())
   250  	observedEntry, observedFields := observer.WriteEntryArgsForCall(0)
   251  	assert.Equal(t, entry, observedEntry)
   252  	assert.Equal(t, fields, observedFields)
   253  }