github.com/nikandfor/tlog@v0.21.5-0.20231108111739-3ef89426a96d/tlio/writers_test.go (about)

     1  package tlio
     2  
     3  import (
     4  	"encoding/hex"
     5  	"io"
     6  	"testing"
     7  
     8  	"github.com/nikandfor/assert"
     9  	"github.com/nikandfor/errors"
    10  
    11  	"github.com/nikandfor/tlog"
    12  	"github.com/nikandfor/tlog/low"
    13  	"github.com/nikandfor/tlog/tlwire"
    14  )
    15  
    16  type errWriter struct {
    17  	io.Writer
    18  	nerr int
    19  	err  error
    20  }
    21  
    22  func TestReWriter(t *testing.T) {
    23  	var files []*low.Buf
    24  
    25  	ewr := errWriter{
    26  		err: errors.New("some"),
    27  	}
    28  
    29  	var b low.Buf
    30  	var e tlwire.Encoder
    31  
    32  	w := NewReWriter(func(have io.Writer, err error) (io.Writer, error) {
    33  		var b low.Buf
    34  
    35  		files = append(files, &b)
    36  
    37  		ewr.Writer = &b
    38  
    39  		return &ewr, nil
    40  	})
    41  
    42  	encode := func(kvs []interface{}) (err error) {
    43  		b = b[:0]
    44  
    45  		defer func() {
    46  			p := recover()
    47  			if p == nil {
    48  				return
    49  			}
    50  
    51  			t.Logf("hex dump:\n%s", hex.Dump(b))
    52  			t.Logf("dump:\n%s", tlwire.Dump(b))
    53  
    54  			panic(p)
    55  		}()
    56  
    57  		b = e.AppendMap(b, -1)
    58  		b = tlog.AppendKVs(b, kvs)
    59  		b = e.AppendBreak(b)
    60  
    61  		_, err = w.Write(b)
    62  
    63  		return
    64  	}
    65  
    66  	err := encode([]interface{}{"key", "value"})
    67  	assert.NoError(t, err)
    68  
    69  	ewr.nerr++
    70  
    71  	err = encode([]interface{}{"key2", "value2"})
    72  	assert.NoError(t, err)
    73  
    74  	err = encode([]interface{}{"label", "label"})
    75  	assert.NoError(t, err)
    76  
    77  	ewr.nerr++
    78  
    79  	err = encode([]interface{}{"key3", "value3"})
    80  	assert.NoError(t, err)
    81  
    82  	ewr.nerr++
    83  
    84  	err = encode([]interface{}{"label", "label2"})
    85  	assert.NoError(t, err)
    86  
    87  	err = encode([]interface{}{"key4", "value4"})
    88  	assert.NoError(t, err)
    89  
    90  	ewr.nerr++
    91  	ewr.nerr++
    92  
    93  	err = encode([]interface{}{"label", "label3"})
    94  	assert.Error(t, err, ewr.err.Error())
    95  
    96  	err = encode([]interface{}{"key5", "value5"})
    97  	assert.NoError(t, err)
    98  
    99  	ewr.nerr++
   100  	ewr.nerr++
   101  
   102  	err = encode([]interface{}{"key6", "value6"})
   103  	assert.Error(t, err, ewr.err.Error())
   104  
   105  	ewr.nerr++
   106  
   107  	err = encode([]interface{}{"key7", "value7"})
   108  	assert.NoError(t, err)
   109  
   110  	exp := []*low.Buf{
   111  		newfile([][]interface{}{
   112  			{"key", "value"},
   113  		}),
   114  		newfile([][]interface{}{
   115  			{"key2", "value2"},
   116  			{"label", "label"},
   117  		}),
   118  		newfile([][]interface{}{
   119  			{"key3", "value3"},
   120  		}),
   121  		newfile([][]interface{}{
   122  			{"label", "label2"},
   123  			{"key4", "value4"},
   124  		}),
   125  		newfile([][]interface{}{
   126  			{"key5", "value5"},
   127  		}),
   128  		newfile([][]interface{}{}),
   129  		newfile([][]interface{}{
   130  			{"key7", "value7"},
   131  		}),
   132  	}
   133  
   134  	assert.Equal(t, exp, files)
   135  
   136  	if t.Failed() {
   137  		for i, f := range files {
   138  			t.Logf("dump %d:\n%s", i, tlwire.Dump(*f))
   139  		}
   140  	}
   141  }
   142  
   143  func newfile(events [][]interface{}) *low.Buf {
   144  	var b low.Buf
   145  
   146  	var e tlwire.Encoder
   147  
   148  	for _, evs := range events {
   149  		b = e.AppendMap(b, -1)
   150  		b = tlog.AppendKVs(b, evs)
   151  		b = e.AppendBreak(b)
   152  	}
   153  
   154  	return &b
   155  }
   156  
   157  func (w *errWriter) Write(p []byte) (n int, err error) {
   158  	if w.nerr != 0 && w.err != nil {
   159  		err = w.err
   160  		w.nerr--
   161  
   162  		return
   163  	}
   164  
   165  	return w.Writer.Write(p)
   166  }
   167  
   168  func BenchmarkReWriter(b *testing.B) {
   169  	b.ReportAllocs()
   170  
   171  	w := NewReWriter(func(io.Writer, error) (io.Writer, error) {
   172  		return io.Discard, nil
   173  	})
   174  
   175  	l := tlog.New(w)
   176  	tlog.LoggerSetTimeNow(l, nil, nil)
   177  
   178  	l.SetLabels(
   179  		"a", "b",
   180  		"c", 4,
   181  		"d", "")
   182  
   183  	for i := 0; i < b.N; i++ {
   184  		l.Printw("message", "a", i+1000, "b", i+1001)
   185  	}
   186  }