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  }