github.com/mailru/activerecord@v1.12.2/pkg/iproto/util/bufio/bufio_test.go (about)

     1  package bufio
     2  
     3  import (
     4  	"bufio"
     5  	"bytes"
     6  	"fmt"
     7  	"io"
     8  	"math"
     9  	"testing"
    10  )
    11  
    12  func TestAcquireReaderSize(t *testing.T) {
    13  	str := "hello, world"
    14  	size := minPooledSize
    15  
    16  	// Prepare two sources that consists of odd and even bytes of str
    17  	// plus size-1 trailing trash bytes. This is done for bufio.Reader
    18  	// fill underlying buffer with one byte from str per one Read() call.
    19  	var b1, b2 []byte
    20  	for i := 0; i < len(str); i++ {
    21  		switch i % 2 {
    22  		case 0:
    23  			b1 = append(b1, str[i])
    24  			b1 = append(b1, bytes.Repeat([]byte{'-'}, size-1)...)
    25  		case 1:
    26  			b2 = append(b2, str[i])
    27  			b2 = append(b2, bytes.Repeat([]byte{'-'}, size-1)...)
    28  		}
    29  	}
    30  	s1 := bytes.NewReader(b1)
    31  	s2 := bytes.NewReader(b2)
    32  
    33  	buf := &bytes.Buffer{}
    34  
    35  	// Put source bufio.Writer in the pool.
    36  	// We expect that this writer will be reused in all cases below.
    37  	initial := AcquireReaderSize(nil, size)
    38  	ReleaseReader(initial, size)
    39  
    40  	var (
    41  		r   *bufio.Reader
    42  		src io.Reader
    43  	)
    44  	for i := 0; buf.Len() < len(str); i++ {
    45  		// Detect which action we should perform next.
    46  		switch i % 2 {
    47  		case 0:
    48  			src = s1
    49  		case 1:
    50  			src = s2
    51  		}
    52  
    53  		// Get the reader. Expect that we reuse initial reader.
    54  		if r = AcquireReaderSize(src, size); r != initial {
    55  			t.Errorf("%dth AcquireWriterSize did not returned initial writer", i)
    56  		}
    57  
    58  		// Write byte to the writer.
    59  		b, err := r.ReadByte()
    60  		if err != nil {
    61  			t.Errorf("%dth ReadBytes unexpected error: %s", i, err)
    62  			break
    63  		}
    64  
    65  		buf.WriteByte(b)
    66  
    67  		// Put writer back to be resued in next iteration.
    68  		ReleaseReader(r, size)
    69  	}
    70  
    71  	if buf.String() != str {
    72  		t.Errorf("unexpected contents of buf: %s; want %s", buf.String(), str)
    73  	}
    74  }
    75  
    76  func TestAcquireWriterSize(t *testing.T) {
    77  	buf1 := &bytes.Buffer{}
    78  	buf2 := &bytes.Buffer{}
    79  	str := "hello, world!"
    80  	size := minPooledSize
    81  
    82  	// Put source bufio.Writer in the pool.
    83  	// We expect that this writer will be reused in all cases below.
    84  	initial := AcquireWriterSize(nil, size)
    85  	ReleaseWriter(initial, size)
    86  
    87  	var (
    88  		w     *bufio.Writer
    89  		dest  io.Writer
    90  		flush bool
    91  	)
    92  	for i, j := 0, 0; j < len(str); i++ {
    93  		// Detect which action we should perform next.
    94  		var inc int
    95  		switch i % 3 {
    96  		case 0:
    97  			dest = buf1
    98  			flush = true
    99  		case 1:
   100  			dest = buf2
   101  			flush = true
   102  		default:
   103  			dest = io.Discard
   104  			flush = false
   105  			inc = 1
   106  		}
   107  		// Get the writer. Expect that we reuse initial.
   108  		if w = AcquireWriterSize(dest, size); w != initial {
   109  			t.Errorf("%dth AcquireWriterSize did not returned initial writer", i)
   110  
   111  		}
   112  		// Write byte to the writer.
   113  		_ = w.WriteByte(str[j])
   114  		if flush {
   115  			w.Flush()
   116  		}
   117  		// Put writer back to be resued in next iteration.
   118  		ReleaseWriter(w, size)
   119  
   120  		// Maybe take the next char in str.
   121  		j += inc
   122  	}
   123  
   124  	if buf1.String() != str {
   125  		t.Errorf("unexpected contents of buf1: %s; want %s", buf1.String(), str)
   126  	}
   127  	if buf2.String() != str {
   128  		t.Errorf("unexpected contents of buf2: %s; want %s", buf2.String(), str)
   129  	}
   130  }
   131  
   132  func TestCeilToPowerOfTwo(t *testing.T) {
   133  	for _, test := range []struct {
   134  		in, out int
   135  	}{
   136  		{
   137  			in:  1,
   138  			out: 1,
   139  		},
   140  		{
   141  			in:  0,
   142  			out: 0,
   143  		},
   144  		{
   145  			in:  3,
   146  			out: 4,
   147  		},
   148  		{
   149  			in:  5,
   150  			out: 8,
   151  		},
   152  		{
   153  			in:  math.MaxInt32 >> 1,
   154  			out: math.MaxInt32>>1 + 1,
   155  		},
   156  	} {
   157  		t.Run(fmt.Sprintf("%v=>%v", test.in, test.out), func(t *testing.T) {
   158  			if out := ceilToPowerOfTwo(test.in); out != test.out {
   159  				t.Errorf("ceilToPowerOfTwo(%v) = %v; want %v", test.in, out, test.out)
   160  			}
   161  		})
   162  	}
   163  }