github.com/jbendotnet/noms@v0.0.0-20190904222105-c43e4293ea92/go/nbs/fd_cache_test.go (about) 1 // Copyright 2017 Attic Labs, Inc. All rights reserved. 2 // Licensed under the Apache License, version 2.0: 3 // http://www.apache.org/licenses/LICENSE-2.0 4 5 package nbs 6 7 import ( 8 "fmt" 9 "io/ioutil" 10 "os" 11 "path/filepath" 12 "sort" 13 "sync" 14 "testing" 15 16 "github.com/stretchr/testify/assert" 17 ) 18 19 func TestFDCache(t *testing.T) { 20 dir := makeTempDir(t) 21 defer os.RemoveAll(dir) 22 23 paths := [3]string{} 24 for i := range paths { 25 name := fmt.Sprintf("file%d", i) 26 paths[i] = filepath.Join(dir, name) 27 err := ioutil.WriteFile(paths[i], []byte(name), 0644) 28 assert.NoError(t, err) 29 } 30 31 refNoError := func(fc *fdCache, p string, assert *assert.Assertions) *os.File { 32 f, err := fc.RefFile(p) 33 assert.NoError(err) 34 assert.NotNil(f) 35 return f 36 } 37 38 t.Run("ConcurrentOpen", func(t *testing.T) { 39 assert := assert.New(t) 40 concurrency := 3 41 fc := newFDCache(3) 42 defer fc.Drop() 43 44 trigger := make(chan struct{}) 45 wg := sync.WaitGroup{} 46 for i := 0; i < concurrency; i++ { 47 wg.Add(1) 48 go func() { 49 defer wg.Done() 50 <-trigger 51 fc.RefFile(paths[0]) 52 }() 53 } 54 close(trigger) 55 wg.Wait() 56 57 present := fc.reportEntries() 58 if assert.Len(present, 1) { 59 ce := fc.cache[present[0]] 60 assert.EqualValues(concurrency, ce.refCount) 61 } 62 }) 63 64 t.Run("NoEvictions", func(t *testing.T) { 65 assert := assert.New(t) 66 fc := newFDCache(2) 67 defer fc.Drop() 68 f := refNoError(fc, paths[0], assert) 69 70 f2 := refNoError(fc, paths[1], assert) 71 assert.NotEqual(f, f2) 72 73 dup := refNoError(fc, paths[0], assert) 74 assert.Equal(f, dup) 75 }) 76 77 t.Run("Evictions", func(t *testing.T) { 78 assert := assert.New(t) 79 fc := newFDCache(1) 80 defer fc.Drop() 81 82 f0 := refNoError(fc, paths[0], assert) 83 f1 := refNoError(fc, paths[1], assert) 84 assert.NotEqual(f0, f1) 85 86 // f0 wasn't evicted, because that doesn't happen until UnrefFile() 87 dup := refNoError(fc, paths[0], assert) 88 assert.Equal(f0, dup) 89 90 expected := sort.StringSlice(paths[:2]) 91 sort.Sort(expected) 92 assert.EqualValues(expected, fc.reportEntries()) 93 94 // Unreffing f1 now should evict it 95 fc.UnrefFile(paths[1]) 96 assert.EqualValues(paths[:1], fc.reportEntries()) 97 98 // Bring f1 back so we can test multiple evictions in a row 99 f1 = refNoError(fc, paths[1], assert) 100 assert.NotEqual(f0, f1) 101 102 // After adding f3, we should be able to evict both f0 and f1 103 f2 := refNoError(fc, paths[2], assert) 104 assert.NotEqual(f0, f2) 105 assert.NotEqual(f1, f2) 106 107 fc.UnrefFile(paths[0]) 108 fc.UnrefFile(paths[0]) 109 fc.UnrefFile(paths[1]) 110 111 assert.EqualValues(paths[2:], fc.reportEntries()) 112 }) 113 }