github.com/GuanceCloud/cliutils@v1.1.21/diskcache/drop_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  	"sync"
    12  	T "testing"
    13  	"time"
    14  
    15  	"github.com/GuanceCloud/cliutils/metrics"
    16  	"github.com/prometheus/client_golang/prometheus"
    17  	"github.com/stretchr/testify/assert"
    18  	"github.com/stretchr/testify/require"
    19  )
    20  
    21  func TestDropBatch(t *T.T) {
    22  	reg := prometheus.NewRegistry()
    23  	register(reg)
    24  
    25  	p := t.TempDir()
    26  	capacity := int64(32 * 1024 * 1024)
    27  	c, err := Open(WithPath(p),
    28  		WithBatchSize(4*1024*1024),
    29  		WithCapacity(capacity))
    30  	if err != nil {
    31  		t.Error(err)
    32  		return
    33  	}
    34  
    35  	sample := bytes.Repeat([]byte("hello"), 7351)
    36  	n := 0
    37  	for {
    38  		if err := c.Put(sample); err != nil {
    39  			t.Error(err)
    40  		}
    41  
    42  		n++
    43  
    44  		if int64(n*len(sample)) > capacity {
    45  			break
    46  		}
    47  	}
    48  
    49  	mfs, err := reg.Gather()
    50  	assert.NoError(t, err)
    51  
    52  	m := metrics.GetMetricOnLabels(mfs,
    53  		"diskcache_dropped_total",
    54  		c.path,
    55  		reasonExceedCapacity)
    56  
    57  	require.NotNil(t, m, "got metrics\n%s", metrics.MetricFamily2Text(mfs))
    58  
    59  	assert.Equal(t,
    60  		float64(1),
    61  		m.GetCounter().GetValue(),
    62  		"got metrics\n%s", metrics.MetricFamily2Text(mfs))
    63  
    64  	t.Cleanup(func() {
    65  		assert.NoError(t, c.Close())
    66  		ResetMetrics()
    67  	})
    68  }
    69  
    70  func TestDropDuringGet(t *T.T) {
    71  	reg := prometheus.NewRegistry()
    72  	register(reg)
    73  
    74  	p := t.TempDir()
    75  	capacity := int64(2 * 1024 * 1024)
    76  	c, err := Open(WithPath(p), WithBatchSize(1*1024*1024), WithCapacity(capacity))
    77  	assert.NoError(t, err)
    78  
    79  	sample := bytes.Repeat([]byte("hello"), 7351)
    80  	wg := sync.WaitGroup{}
    81  	wg.Add(1)
    82  	go func() { // fast put
    83  		defer wg.Done()
    84  		n := 0
    85  		for {
    86  			if err := c.Put(sample); err != nil {
    87  				t.Error(err)
    88  				return
    89  			}
    90  			n++
    91  
    92  			if int64(n*len(sample)) > capacity {
    93  				return
    94  			}
    95  		}
    96  	}()
    97  
    98  	time.Sleep(time.Second) // wait new data write
    99  
   100  	// slow get
   101  	i := 0
   102  	eof := 0
   103  	for {
   104  		time.Sleep(time.Millisecond * 100)
   105  		if err := c.Get(func(x []byte) error {
   106  			assert.Equal(t, sample, x)
   107  			return nil
   108  		}); err != nil {
   109  			if errors.Is(err, ErrEOF) {
   110  				t.Logf("[%s] read: %s", time.Now(), err)
   111  				time.Sleep(time.Second)
   112  				eof++
   113  				if eof > 5 {
   114  					break
   115  				}
   116  			} else {
   117  				t.Logf("%s", err)
   118  				time.Sleep(time.Second)
   119  			}
   120  		} else {
   121  			eof = 0 // reset EOF if put ok
   122  		}
   123  		i++
   124  	}
   125  
   126  	wg.Wait()
   127  
   128  	mfs, err := reg.Gather()
   129  	assert.NoError(t, err)
   130  
   131  	t.Logf("\n%s", metrics.MetricFamily2Text(mfs))
   132  
   133  	t.Cleanup(func() {
   134  		assert.NoError(t, c.Close())
   135  		ResetMetrics()
   136  	})
   137  }