github.com/ssgreg/logf@v1.4.1/channel_test.go (about)

     1  package logf
     2  
     3  import (
     4  	"errors"
     5  	"runtime"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/stretchr/testify/assert"
    10  )
    11  
    12  func TestChannelWriterConfigDefaults(t *testing.T) {
    13  	cfg := ChannelWriterConfig{}
    14  	cfgWithDefaults := cfg.WithDefaults()
    15  
    16  	// Capacity, ErrorAppender, Appender must be configured by WithDefaults.
    17  	assert.True(t, cfgWithDefaults.Capacity > 0)
    18  	assert.NotNil(t, cfgWithDefaults.ErrorAppender)
    19  	assert.NotNil(t, cfgWithDefaults.Appender)
    20  
    21  	// EnableSyncOnError must not be changed.
    22  	assert.Equal(t, cfg.EnableSyncOnError, cfgWithDefaults.EnableSyncOnError)
    23  }
    24  
    25  func TestChannelWriterNewDefault(t *testing.T) {
    26  	w, close := NewChannelWriter.Default()
    27  	defer close()
    28  
    29  	cw := w.(*channelWriter)
    30  	// Capacity, ErrorAppender, Appender must be configured by WithDefaults.
    31  	assert.True(t, cw.Capacity > 0)
    32  	assert.NotNil(t, cw.ErrorAppender)
    33  	assert.NotNil(t, cw.Appender)
    34  	// EnableSyncOnError is false by default.
    35  	assert.False(t, cw.EnableSyncOnError)
    36  }
    37  
    38  func TestChannelWriterDoubleClose(t *testing.T) {
    39  	_, close := NewChannelWriter.Default()
    40  	defer close()
    41  	close()
    42  }
    43  
    44  func TestChannelWriterPanicOnWriteWhenClosed(t *testing.T) {
    45  	w, close := NewChannelWriter.Default()
    46  	close()
    47  
    48  	// Panic is expected calling WriteEnter after close.
    49  	assert.Panics(t, func() {
    50  		w.WriteEntry(Entry{})
    51  	})
    52  }
    53  
    54  func TestChannelWriterWrite(t *testing.T) {
    55  	appender := testAppender{}
    56  	errorAppender := testAppender{}
    57  
    58  	w, close := NewChannelWriter(ChannelWriterConfig{Appender: &appender, ErrorAppender: &errorAppender})
    59  	defer func() {
    60  		assert.NotEmpty(t, appender.Entries)
    61  		assert.EqualValues(t, 42, appender.Entries[0].LoggerID)
    62  		assert.True(t, appender.FlushCallCounter > 0 && appender.FlushCallCounter < 3, "expected one flush at exit (and sometimes additional flush on empty channel)")
    63  		assert.Equal(t, 1, appender.SyncCallCounter, "expected one sync at exit")
    64  	}()
    65  	defer close()
    66  
    67  	w.WriteEntry(Entry{LoggerID: 42, Level: LevelInfo})
    68  }
    69  
    70  func TestChannelWriterFlushOnEmptyChannel(t *testing.T) {
    71  	appender := testAppender{}
    72  	errorAppender := testAppender{}
    73  
    74  	w, close := NewChannelWriter(ChannelWriterConfig{Appender: &appender, ErrorAppender: &errorAppender})
    75  	defer func() {
    76  		assert.Len(t, appender.Entries, 1)
    77  		assert.EqualValues(t, 42, appender.Entries[0].LoggerID)
    78  		assert.True(t, appender.FlushCallCounter > 1 && appender.FlushCallCounter < 4, "expected one flush at exit, one on message add and additional flush on empty channel")
    79  		assert.Equal(t, 1, appender.SyncCallCounter, "expected one sync at exit")
    80  	}()
    81  	defer close()
    82  
    83  	w.WriteEntry(Entry{LoggerID: 42, Level: LevelInfo})
    84  	runtime.Gosched()
    85  	time.Sleep(time.Second)
    86  }
    87  
    88  func TestChannelWriterTestAppendError(t *testing.T) {
    89  	appendErr := errors.New("append error")
    90  
    91  	appender := testAppender{AppendError: appendErr}
    92  	errorAppender := testAppender{}
    93  
    94  	w, close := NewChannelWriter(ChannelWriterConfig{Appender: &appender, ErrorAppender: &errorAppender})
    95  	defer func() {
    96  		assert.Empty(t, appender.Entries, "no entries expected")
    97  		assert.Len(t, errorAppender.Entries, 1, "expected a error message in error appender")
    98  		assert.Equal(t, LevelError, errorAppender.Entries[0].Level)
    99  		assert.Equal(t, 1, errorAppender.FlushCallCounter, "expected one flush on message add")
   100  		assert.Equal(t, 1, errorAppender.SyncCallCounter, "expected one sync on message add")
   101  	}()
   102  	defer close()
   103  
   104  	w.WriteEntry(Entry{LoggerID: 42, Level: LevelInfo})
   105  }
   106  
   107  func TestChannelWriterTestFlushError(t *testing.T) {
   108  	flushErr := errors.New("flush error")
   109  
   110  	appender := testAppender{FlushError: flushErr}
   111  	errorAppender := testAppender{}
   112  
   113  	w, close := NewChannelWriter(ChannelWriterConfig{Appender: &appender, ErrorAppender: &errorAppender})
   114  	defer func() {
   115  		assert.Len(t, appender.Entries, 1)
   116  		assert.EqualValues(t, 42, appender.Entries[0].LoggerID)
   117  		assert.Equal(t, 0, appender.FlushCallCounter, "expected no flushes because of error")
   118  		assert.Equal(t, 1, appender.SyncCallCounter, "expected one sync at exit")
   119  
   120  		assert.Len(t, errorAppender.Entries, 1, "expected a error message in error appender")
   121  		assert.Equal(t, LevelError, errorAppender.Entries[0].Level)
   122  		assert.Equal(t, 1, errorAppender.FlushCallCounter, "expected one flush on message add")
   123  		assert.Equal(t, 1, errorAppender.SyncCallCounter, "expected one sync on message add")
   124  	}()
   125  	defer close()
   126  
   127  	w.WriteEntry(Entry{LoggerID: 42, Level: LevelInfo})
   128  }
   129  
   130  func TestChannelWriterTestSyncError(t *testing.T) {
   131  	syncErr := errors.New("sync error")
   132  
   133  	appender := testAppender{SyncError: syncErr}
   134  	errorAppender := testAppender{}
   135  
   136  	w, close := NewChannelWriter(ChannelWriterConfig{Appender: &appender, ErrorAppender: &errorAppender})
   137  	defer func() {
   138  		assert.Len(t, appender.Entries, 1)
   139  		assert.EqualValues(t, 42, appender.Entries[0].LoggerID)
   140  		assert.Equal(t, 1, appender.FlushCallCounter, "expected one flush at exit")
   141  		assert.Equal(t, 0, appender.SyncCallCounter, "expected no syncs because of error")
   142  
   143  		assert.Len(t, errorAppender.Entries, 1, "expected a error message in error appender")
   144  		assert.Equal(t, LevelError, errorAppender.Entries[0].Level)
   145  		assert.Equal(t, 1, errorAppender.FlushCallCounter, "expected one flush on message add")
   146  		assert.Equal(t, 1, errorAppender.SyncCallCounter, "expected one sync on message add")
   147  	}()
   148  	defer close()
   149  
   150  	w.WriteEntry(Entry{LoggerID: 42, Level: LevelInfo})
   151  }
   152  
   153  func TestChannelWriterTestAppendErrorAndErrorAppenderError(t *testing.T) {
   154  	appendErr := errors.New("append error")
   155  
   156  	appender := testAppender{AppendError: appendErr}
   157  	errorAppender := testAppender{AppendError: appendErr}
   158  
   159  	w, close := NewChannelWriter(ChannelWriterConfig{Appender: &appender, ErrorAppender: &errorAppender})
   160  	defer func() {
   161  		assert.Empty(t, appender.Entries, "no entries expected")
   162  		assert.Empty(t, errorAppender.Entries, "no entries expected")
   163  	}()
   164  	defer close()
   165  
   166  	w.WriteEntry(Entry{LoggerID: 42, Level: LevelInfo})
   167  }
   168  
   169  func TestChannelWriterSyncOnErrorWhenEnabled(t *testing.T) {
   170  	appender := testAppender{}
   171  	errorAppender := testAppender{}
   172  
   173  	w, close := NewChannelWriter(ChannelWriterConfig{Appender: &appender, ErrorAppender: &errorAppender, EnableSyncOnError: true})
   174  	defer func() {
   175  		assert.NotEmpty(t, appender.Entries)
   176  		assert.EqualValues(t, 42, appender.Entries[0].LoggerID)
   177  		assert.True(t, appender.FlushCallCounter > 1 && appender.FlushCallCounter < 4, "expected one flush at exit, one on message add (and sometimes additional flush on empty channel)")
   178  		assert.Equal(t, 2, appender.SyncCallCounter, "expected one sync at exit and one sync on message add")
   179  	}()
   180  	defer close()
   181  
   182  	w.WriteEntry(Entry{LoggerID: 42, Level: LevelError})
   183  }