github.com/GuanceCloud/cliutils@v1.1.21/diskcache/open_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  	"os"
    10  	"path/filepath"
    11  	"sync"
    12  	T "testing"
    13  	"time"
    14  
    15  	"github.com/stretchr/testify/assert"
    16  )
    17  
    18  func TestOpen(t *T.T) {
    19  	t.Run("reopen-with-or-without-pos", func(t *T.T) {
    20  		p := t.TempDir()
    21  
    22  		// lock then no-lock
    23  		c, err := Open(WithPath(p))
    24  		assert.NoError(t, err)
    25  		assert.NoError(t, c.Close())
    26  
    27  		c2, err := Open(WithPath(p), WithNoPos(true))
    28  		assert.NoError(t, err)
    29  		assert.NoError(t, c2.Close())
    30  
    31  		// no-lock then lock
    32  		c, err = Open(WithPath(p), WithNoPos(true))
    33  		assert.NoError(t, err)
    34  		assert.NoError(t, c.Close())
    35  
    36  		c2, err = Open(WithPath(p))
    37  		assert.NoError(t, err)
    38  		assert.NoError(t, c2.Close())
    39  	})
    40  
    41  	t.Run("reopen-with-or-without-lock", func(t *T.T) {
    42  		p := t.TempDir()
    43  
    44  		// lock then no-lock
    45  		c, err := Open(WithPath(p))
    46  		assert.NoError(t, err)
    47  		assert.NoError(t, c.Close())
    48  
    49  		c2, err := Open(WithPath(p), WithNoLock(true))
    50  		assert.NoError(t, err)
    51  		assert.NoError(t, c2.Close())
    52  
    53  		// no-lock then lock
    54  		c, err = Open(WithPath(p), WithNoLock(true))
    55  		assert.NoError(t, err)
    56  		assert.NoError(t, c.Close())
    57  
    58  		c2, err = Open(WithPath(p))
    59  		assert.NoError(t, err)
    60  		assert.NoError(t, c2.Close())
    61  	})
    62  
    63  	t.Run("open-with-lock", func(t *T.T) {
    64  		p := t.TempDir()
    65  		c, err := Open(WithPath(p))
    66  		assert.NoError(t, err)
    67  
    68  		fi, err := os.Stat(filepath.Join(p, ".lock"))
    69  		assert.NoError(t, err)
    70  
    71  		t.Logf("lock file info: %+#v", fi)
    72  
    73  		t.Cleanup(func() {
    74  			assert.NoError(t, c.Close())
    75  			os.RemoveAll(p)
    76  		})
    77  	})
    78  
    79  	t.Run("open-twice-with-error", func(t *T.T) {
    80  		p := t.TempDir()
    81  		c, err := Open(WithPath(p))
    82  		assert.NoError(t, err)
    83  
    84  		_, err = Open(WithPath(p))
    85  		assert.Error(t, err, "expect lock failed")
    86  
    87  		t.Logf("[expected] Open: %q", err)
    88  
    89  		t.Cleanup(func() {
    90  			assert.NoError(t, c.Close())
    91  			os.RemoveAll(p)
    92  		})
    93  	})
    94  
    95  	t.Run("multi-open-until-ok", func(t *T.T) {
    96  		p := t.TempDir()
    97  		c, err := Open(WithPath(p))
    98  		assert.NoError(t, err)
    99  
   100  		// hold the cache for 5 seconds
   101  		go func() {
   102  			time.Sleep(time.Second * 2)
   103  			assert.NoError(t, c.Close())
   104  			t.Logf("c Closed")
   105  		}()
   106  
   107  		var c2 *DiskCache
   108  		for { // retry until ok
   109  			c2, err = Open(WithPath(p))
   110  			if err != nil {
   111  				t.Logf("[expected] Open: %q, path: %s", err, p)
   112  				time.Sleep(time.Second)
   113  			} else {
   114  				break
   115  			}
   116  		}
   117  
   118  		t.Cleanup(func() {
   119  			assert.NoError(t, c2.Close())
   120  		})
   121  	})
   122  
   123  	t.Run("multi-open-wihout-lock", func(t *T.T) {
   124  		p := t.TempDir()
   125  		c, err := Open(WithPath(p), WithNoLock(true))
   126  		assert.NoError(t, err)
   127  
   128  		var wg sync.WaitGroup
   129  
   130  		wg.Add(1)
   131  		// hold the cache for 5 seconds
   132  		go func() {
   133  			defer wg.Done()
   134  			time.Sleep(time.Second * 5)
   135  			assert.NoError(t, c.Close())
   136  		}()
   137  
   138  		c2, err := Open(WithPath(p), WithNoLock(true))
   139  		assert.NoError(t, err) // no error on re-Open() without lock
   140  		defer c2.Close()
   141  
   142  		wg.Wait()
   143  	})
   144  
   145  	t.Run("test-empty-pos-file", func(t *T.T) {
   146  		p := t.TempDir()
   147  		posFile := filepath.Join(p, ".pos")
   148  
   149  		f, err := os.Create(posFile)
   150  		assert.NoError(t, err)
   151  
   152  		dq, err := Open(WithPath(p), WithCapacity(1<<29), WithNoFallbackOnError(true))
   153  		assert.NoError(t, err)
   154  		assert.NoError(t, dq.Close())
   155  
   156  		_, err = f.WriteString("1234")
   157  		assert.NoError(t, err)
   158  		assert.NoError(t, f.Sync())
   159  
   160  		dq, err = Open(WithPath(p), WithCapacity(1<<29), WithNoFallbackOnError(true))
   161  		assert.NoError(t, err)
   162  		assert.Equal(t, int64(0), dq.pos.Seek)
   163  		assert.NoError(t, dq.Close())
   164  
   165  		_, err = f.WriteString("5678")
   166  		assert.NoError(t, err)
   167  		assert.NoError(t, f.Sync())
   168  
   169  		dq, err = Open(WithPath(p), WithCapacity(1<<29), WithNoFallbackOnError(true))
   170  		assert.NoError(t, err)
   171  		assert.Equal(t, int64(0), dq.pos.Seek)
   172  		assert.NoError(t, dq.Close())
   173  
   174  		assert.NoError(t, f.Close())
   175  	})
   176  }
   177  
   178  func TestClose(t *T.T) {
   179  	t.Run("multl-close", func(t *T.T) {
   180  		p := t.TempDir()
   181  		c, err := Open(WithPath(p))
   182  		assert.NoError(t, err)
   183  
   184  		assert.NoError(t, c.Close())
   185  		assert.NoError(t, c.Close())
   186  
   187  		t.Cleanup(func() {
   188  			os.RemoveAll(p)
   189  		})
   190  	})
   191  }