github.com/GuanceCloud/cliutils@v1.1.21/diskcache/rotate_test.go (about)

     1  // Unless explicitly stated otherwise all files in this repository are licensed
     2  // under the MIT License.
     3  // This product includes software developed at Guance Cloud (https://www.guance.com/).
     4  // Copyright 2021-present Guance, Inc.
     5  
     6  package diskcache
     7  
     8  import (
     9  	"bytes"
    10  	"errors"
    11  	T "testing"
    12  
    13  	"github.com/GuanceCloud/cliutils/metrics"
    14  	"github.com/prometheus/client_golang/prometheus"
    15  	"github.com/stretchr/testify/assert"
    16  	"github.com/stretchr/testify/require"
    17  )
    18  
    19  func TestRotate(t *T.T) {
    20  	t.Run("rotate-on-0-datafile", func(t *T.T) {
    21  		p := t.TempDir()
    22  		c, err := Open(WithPath(p), WithBatchSize(1024*2))
    23  		if err != nil {
    24  			t.Error(err)
    25  			return
    26  		}
    27  
    28  		_1kb := make([]byte, 1024)
    29  
    30  		// put 3kb
    31  		for i := 0; i < 4; i++ {
    32  			assert.NoError(t, c.Put(_1kb))
    33  		}
    34  
    35  		for { // get them all
    36  			if err := c.Get(func(data []byte) error {
    37  				assert.Len(t, data, 1024)
    38  				return nil
    39  			}); err != nil {
    40  				if errors.Is(err, ErrEOF) {
    41  					break
    42  				} else {
    43  					assert.NoError(t, err)
    44  				}
    45  			}
    46  		}
    47  
    48  		t.Logf("cache: %s", c)
    49  
    50  		t.Logf("cache pos: %s", c.pos)
    51  
    52  		// rotate it
    53  		c.rotate()
    54  
    55  		pos, err := posFromFile(c.pos.fname)
    56  		assert.NoError(t, err)
    57  		t.Logf("pos: %s", pos)
    58  
    59  		assert.Equal(t, ":-1", c.pos.String(), "cache: %s", c)
    60  
    61  		t.Cleanup(func() {
    62  			assert.NoError(t, c.Close())
    63  			ResetMetrics()
    64  		})
    65  	})
    66  
    67  	t.Run("rotate", func(t *T.T) {
    68  		reg := prometheus.NewRegistry()
    69  		register(reg)
    70  
    71  		p := t.TempDir()
    72  		batchSize := int64(1024 * 1024)
    73  		c, err := Open(WithPath(p), WithBatchSize(batchSize))
    74  		if err != nil {
    75  			t.Error(err)
    76  			return
    77  		}
    78  
    79  		origFileCnt := len(c.dataFiles)
    80  		maxRotate := 3
    81  
    82  		t.Logf("files: %+#v", c.dataFiles)
    83  
    84  		sample := bytes.Repeat([]byte("hello"), 1000) // 5kb
    85  		total := 0
    86  		for {
    87  			require.NoError(t, c.Put(sample), "cache: %s", c)
    88  			total += len(sample)
    89  
    90  			// generate 3 batches
    91  			if int64(total) > int64(maxRotate)*batchSize {
    92  				break
    93  			}
    94  		}
    95  
    96  		t.Logf("data files: %+#v", c.dataFiles)
    97  
    98  		assert.Equal(t, origFileCnt+maxRotate, len(c.dataFiles))
    99  
   100  		readBytes := 0
   101  		fn := func(x []byte) error {
   102  			assert.Equal(t, sample, x)
   103  			readBytes += len(x)
   104  			return nil
   105  		}
   106  
   107  		for {
   108  			if len(c.dataFiles) == 0 {
   109  				break
   110  			}
   111  
   112  			if err := c.Get(fn); err != nil {
   113  				if errors.Is(err, ErrEOF) {
   114  					t.Logf("read EOF")
   115  				} else {
   116  					t.Error(err)
   117  				}
   118  				break
   119  			}
   120  		}
   121  
   122  		t.Logf("total read bytes: %d", readBytes)
   123  
   124  		mfs, err := reg.Gather()
   125  		require.NoError(t, err)
   126  		t.Logf("metrics \n%s", metrics.MetricFamily2Text(mfs))
   127  
   128  		t.Cleanup(func() {
   129  			assert.NoError(t, c.Close())
   130  			ResetMetrics()
   131  		})
   132  	})
   133  }