github.com/petermattis/pebble@v0.0.0-20190905164901-ab51a2166067/vfs/syncing_file_linux_test.go (about) 1 // Copyright 2019 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 // +build linux,!arm 6 7 package vfs 8 9 import ( 10 "fmt" 11 "io/ioutil" 12 "os" 13 "syscall" 14 "testing" 15 "unsafe" 16 ) 17 18 func TestSyncRangeSmokeTest(t *testing.T) { 19 testCases := []struct { 20 err error 21 expected bool 22 }{ 23 {nil, true}, 24 {syscall.EINVAL, true}, 25 {syscall.ENOSYS, false}, 26 } 27 for i, c := range testCases { 28 t.Run("", func(t *testing.T) { 29 ok := syncRangeSmokeTest(uintptr(i), 30 func(fd int, off int64, n int64, flags int) (err error) { 31 if i != fd { 32 t.Fatalf("expected fd %d, but got %d", i, fd) 33 } 34 return c.err 35 }) 36 if c.expected != ok { 37 t.Fatalf("expected %t, but got %t: %v", c.expected, ok, c.err) 38 } 39 }) 40 } 41 } 42 43 func BenchmarkDirectIOWrite(b *testing.B) { 44 const targetSize = 16 << 20 45 const alignment = 4096 46 47 var wsizes []int 48 if testing.Verbose() { 49 wsizes = []int{4 << 10, 8 << 10, 16 << 10, 32 << 10} 50 } else { 51 wsizes = []int{4096} 52 } 53 54 for _, wsize := range wsizes { 55 b.Run(fmt.Sprintf("wsize=%d", wsize), func(b *testing.B) { 56 tmpf, err := ioutil.TempFile("", "pebble-db-syncing-file-") 57 if err != nil { 58 b.Fatal(err) 59 } 60 filename := tmpf.Name() 61 _ = tmpf.Close() 62 defer os.Remove(filename) 63 64 var f *os.File 65 var size int 66 buf := make([]byte, wsize+alignment) 67 if a := uintptr(unsafe.Pointer(&buf[0])) & uintptr(alignment-1); a != 0 { 68 buf = buf[alignment-a:] 69 } 70 buf = buf[:wsize] 71 init := true 72 73 b.SetBytes(int64(len(buf))) 74 b.ResetTimer() 75 for i := 0; i < b.N; i++ { 76 if f == nil { 77 b.StopTimer() 78 f, err = os.OpenFile(filename, syscall.O_DIRECT|os.O_RDWR, 0666) 79 if err != nil { 80 b.Fatal(err) 81 } 82 if init { 83 for size = 0; size < targetSize; size += len(buf) { 84 if _, err := f.WriteAt(buf, int64(size)); err != nil { 85 b.Fatal(err) 86 } 87 } 88 } 89 if err := f.Sync(); err != nil { 90 b.Fatal(err) 91 } 92 size = 0 93 b.StartTimer() 94 } 95 if _, err := f.WriteAt(buf, int64(size)); err != nil { 96 b.Fatal(err) 97 } 98 size += len(buf) 99 if size >= targetSize { 100 _ = f.Close() 101 f = nil 102 } 103 } 104 b.StopTimer() 105 }) 106 } 107 }