github.com/cockroachdb/pebble@v1.1.1-0.20240513155919-3622ade60459/flush_test.go (about) 1 // Copyright 2018 The LevelDB-Go and Pebble Authors. All rights reserved. Use 2 // of this source code is governed by a BSD-style license that can be found in 3 // the LICENSE file. 4 5 package pebble 6 7 import ( 8 "fmt" 9 "testing" 10 "time" 11 12 "github.com/cockroachdb/datadriven" 13 "github.com/cockroachdb/errors" 14 "github.com/cockroachdb/pebble/vfs" 15 "github.com/stretchr/testify/require" 16 ) 17 18 func TestManualFlush(t *testing.T) { 19 getOptions := func() *Options { 20 opts := &Options{ 21 FS: vfs.NewMem(), 22 L0CompactionThreshold: 10, 23 } 24 opts.DisableAutomaticCompactions = true 25 return opts 26 } 27 d, err := Open("", getOptions()) 28 require.NoError(t, err) 29 defer func() { 30 require.NoError(t, d.Close()) 31 }() 32 33 datadriven.RunTest(t, "testdata/manual_flush", func(t *testing.T, td *datadriven.TestData) string { 34 switch td.Cmd { 35 case "batch": 36 b := d.NewBatch() 37 if err := runBatchDefineCmd(td, b); err != nil { 38 return err.Error() 39 } 40 b.Commit(nil) 41 return "" 42 43 case "flush": 44 if err := d.Flush(); err != nil { 45 return err.Error() 46 } 47 48 d.mu.Lock() 49 s := d.mu.versions.currentVersion().String() 50 d.mu.Unlock() 51 return s 52 53 case "async-flush": 54 d.mu.Lock() 55 cur := d.mu.versions.currentVersion() 56 d.mu.Unlock() 57 58 if _, err := d.AsyncFlush(); err != nil { 59 return err.Error() 60 } 61 62 err := try(100*time.Microsecond, 20*time.Second, func() error { 63 d.mu.Lock() 64 defer d.mu.Unlock() 65 if cur == d.mu.versions.currentVersion() { 66 return errors.New("flush has not occurred") 67 } 68 return nil 69 }) 70 if err != nil { 71 return err.Error() 72 } 73 74 d.mu.Lock() 75 s := d.mu.versions.currentVersion().String() 76 d.mu.Unlock() 77 return s 78 79 case "reset": 80 if err := d.Close(); err != nil { 81 return err.Error() 82 } 83 d, err = Open("", getOptions()) 84 if err != nil { 85 return err.Error() 86 } 87 return "" 88 89 default: 90 return fmt.Sprintf("unknown command: %s", td.Cmd) 91 } 92 }) 93 } 94 95 // TestFlushDelRangeEmptyKey tests flushing a range tombstone that begins with 96 // an empty key. The empty key is a valid key but can be confused with nil. 97 func TestFlushDelRangeEmptyKey(t *testing.T) { 98 d, err := Open("", &Options{FS: vfs.NewMem()}) 99 require.NoError(t, err) 100 require.NoError(t, d.DeleteRange([]byte{}, []byte("z"), nil)) 101 require.NoError(t, d.Flush()) 102 require.NoError(t, d.Close()) 103 } 104 105 // TestFlushEmptyKey tests that flushing an empty key does not trigger that key 106 // order invariant assertions. 107 func TestFlushEmptyKey(t *testing.T) { 108 d, err := Open("", &Options{FS: vfs.NewMem()}) 109 require.NoError(t, err) 110 require.NoError(t, d.Set(nil, []byte("hello"), nil)) 111 require.NoError(t, d.Flush()) 112 val, closer, err := d.Get(nil) 113 require.NoError(t, err) 114 require.Equal(t, val, []byte("hello")) 115 require.NoError(t, closer.Close()) 116 require.NoError(t, d.Close()) 117 }