...

Source file src/github.com/rs/zerolog/writer_test.go

Documentation: github.com/rs/zerolog

     1  //go:build !binary_log && !windows
     2  // +build !binary_log,!windows
     3  
     4  package zerolog
     5  
     6  import (
     7  	"bytes"
     8  	"errors"
     9  	"fmt"
    10  	"io"
    11  	"reflect"
    12  	"testing"
    13  )
    14  
    15  func TestMultiSyslogWriter(t *testing.T) {
    16  	sw := &syslogTestWriter{}
    17  	log := New(MultiLevelWriter(SyslogLevelWriter(sw)))
    18  	log.Debug().Msg("debug")
    19  	log.Info().Msg("info")
    20  	log.Warn().Msg("warn")
    21  	log.Error().Msg("error")
    22  	log.Log().Msg("nolevel")
    23  	want := []syslogEvent{
    24  		{"Debug", `{"level":"debug","message":"debug"}` + "\n"},
    25  		{"Info", `{"level":"info","message":"info"}` + "\n"},
    26  		{"Warning", `{"level":"warn","message":"warn"}` + "\n"},
    27  		{"Err", `{"level":"error","message":"error"}` + "\n"},
    28  		{"Info", `{"message":"nolevel"}` + "\n"},
    29  	}
    30  	if got := sw.events; !reflect.DeepEqual(got, want) {
    31  		t.Errorf("Invalid syslog message routing: want %v, got %v", want, got)
    32  	}
    33  }
    34  
    35  var writeCalls int
    36  
    37  type mockedWriter struct {
    38  	wantErr bool
    39  }
    40  
    41  func (c mockedWriter) Write(p []byte) (int, error) {
    42  	writeCalls++
    43  
    44  	if c.wantErr {
    45  		return -1, errors.New("Expected error")
    46  	}
    47  
    48  	return len(p), nil
    49  }
    50  
    51  // Tests that a new writer is only used if it actually works.
    52  func TestResilientMultiWriter(t *testing.T) {
    53  	tests := []struct {
    54  		name    string
    55  		writers []io.Writer
    56  	}{
    57  		{
    58  			name: "All valid writers",
    59  			writers: []io.Writer{
    60  				mockedWriter{
    61  					wantErr: false,
    62  				},
    63  				mockedWriter{
    64  					wantErr: false,
    65  				},
    66  			},
    67  		},
    68  		{
    69  			name: "All invalid writers",
    70  			writers: []io.Writer{
    71  				mockedWriter{
    72  					wantErr: true,
    73  				},
    74  				mockedWriter{
    75  					wantErr: true,
    76  				},
    77  			},
    78  		},
    79  		{
    80  			name: "First invalid writer",
    81  			writers: []io.Writer{
    82  				mockedWriter{
    83  					wantErr: true,
    84  				},
    85  				mockedWriter{
    86  					wantErr: false,
    87  				},
    88  			},
    89  		},
    90  		{
    91  			name: "First valid writer",
    92  			writers: []io.Writer{
    93  				mockedWriter{
    94  					wantErr: false,
    95  				},
    96  				mockedWriter{
    97  					wantErr: true,
    98  				},
    99  			},
   100  		},
   101  	}
   102  
   103  	for _, tt := range tests {
   104  		writers := tt.writers
   105  		multiWriter := MultiLevelWriter(writers...)
   106  
   107  		logger := New(multiWriter).With().Timestamp().Logger().Level(InfoLevel)
   108  		logger.Info().Msg("Test msg")
   109  
   110  		if len(writers) != writeCalls {
   111  			t.Errorf("Expected %d writers to have been called but only %d were.", len(writers), writeCalls)
   112  		}
   113  		writeCalls = 0
   114  	}
   115  }
   116  
   117  type testingLog struct {
   118  	testing.TB
   119  	buf bytes.Buffer
   120  }
   121  
   122  func (t *testingLog) Log(args ...interface{}) {
   123  	if _, err := t.buf.WriteString(fmt.Sprint(args...)); err != nil {
   124  		t.Error(err)
   125  	}
   126  }
   127  
   128  func (t *testingLog) Logf(format string, args ...interface{}) {
   129  	if _, err := t.buf.WriteString(fmt.Sprintf(format, args...)); err != nil {
   130  		t.Error(err)
   131  	}
   132  }
   133  
   134  func TestTestWriter(t *testing.T) {
   135  	tests := []struct {
   136  		name  string
   137  		write []byte
   138  		want  []byte
   139  	}{{
   140  		name:  "newline",
   141  		write: []byte("newline\n"),
   142  		want:  []byte("newline"),
   143  	}, {
   144  		name:  "oneline",
   145  		write: []byte("oneline"),
   146  		want:  []byte("oneline"),
   147  	}, {
   148  		name:  "twoline",
   149  		write: []byte("twoline\n\n"),
   150  		want:  []byte("twoline"),
   151  	}}
   152  
   153  	for _, tt := range tests {
   154  		t.Run(tt.name, func(t *testing.T) {
   155  			tb := &testingLog{TB: t} // Capture TB log buffer.
   156  			w := TestWriter{T: tb}
   157  
   158  			n, err := w.Write(tt.write)
   159  			if err != nil {
   160  				t.Error(err)
   161  			}
   162  			if n != len(tt.write) {
   163  				t.Errorf("Expected %d write length but got %d", len(tt.write), n)
   164  			}
   165  			p := tb.buf.Bytes()
   166  			if !bytes.Equal(tt.want, p) {
   167  				t.Errorf("Expected %q, got %q.", tt.want, p)
   168  			}
   169  
   170  			log := New(NewConsoleWriter(ConsoleTestWriter(t)))
   171  			log.Info().Str("name", tt.name).Msg("Success!")
   172  
   173  			tb.buf.Reset()
   174  		})
   175  	}
   176  
   177  }
   178  

View as plain text