Files

138 lines
2.9 KiB
Go

// Copyright 2021 the Go-FUSE Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package benchmark
import (
"bytes"
"flag"
"fmt"
"os"
"os/exec"
"runtime"
"testing"
"time"
"github.com/hanzoai/go-fuse/v2/fs"
"github.com/hanzoai/go-fuse/v2/internal/testutil"
)
func BenchmarkGoFuseMemoryRead(b *testing.B) {
root := &readFS{}
mnt := setupFS(root, b.N, b)
benchmarkRead(mnt, b, "direct")
}
const blockSize = 128 * 1024 // Fuse default request size 128k
func benchmarkRead(mnt string, b *testing.B, ddflag string) {
var cmds []*exec.Cmd
readers := runtime.GOMAXPROCS(0)
for i := 0; i < readers; i++ {
cmd := exec.Command("dd",
fmt.Sprintf("if=%s/foo.txt", mnt),
"of=/dev/null",
fmt.Sprintf("bs=%d", blockSize),
fmt.Sprintf("count=%d", b.N))
if ddflag != "" {
cmd.Args = append(cmd.Args, "iflag="+ddflag)
}
if testutil.VerboseTest() {
cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout
} else {
buf := &bytes.Buffer{}
cmd.Stderr = buf
cmd.Stdout = buf
}
cmds = append(cmds, cmd)
}
b.SetBytes(int64(readers * blockSize))
b.ReportAllocs()
b.ResetTimer()
result := make(chan error, readers)
for _, cmd := range cmds {
go func(cmd *exec.Cmd) {
err := cmd.Run()
if buf, ok := cmd.Stdout.(*bytes.Buffer); ok && err != nil {
err = fmt.Errorf("%v: output=%s", err, buf.String())
}
result <- err
}(cmd)
}
failures := 0
for range cmds {
if err := <-result; err != nil {
b.Errorf("dd failed: %v", err)
failures++
}
}
if failures > 0 {
b.Errorf("%d out of %d commands", failures, readers)
}
b.StopTimer()
}
func BenchmarkGoFuseFDRead(b *testing.B) {
orig := b.TempDir()
fn := orig + "/foo.txt"
data := bytes.Repeat([]byte{42}, blockSize*b.N)
if err := os.WriteFile(fn, data, 0666); err != nil {
b.Fatal(err)
}
root, err := fs.NewLoopbackRoot(orig)
if err != nil {
b.Fatal(err)
}
mnt := setupFS(root, b.N, b)
benchmarkRead(mnt, b, "")
}
var libfusePath = flag.String("passthrough_hp", "", "path to libfuse's passthrough_hp")
func BenchmarkLibfuseHP(b *testing.B) {
orig := b.TempDir()
mnt := b.TempDir()
if *libfusePath == "" {
b.Skip("must set --passthrough_hp")
}
origFN := orig + "/foo.txt"
data := bytes.Repeat([]byte{42}, blockSize*b.N)
if err := os.WriteFile(origFN, data, 0666); err != nil {
b.Fatal(err)
}
fn := mnt + "/foo.txt"
cmd := exec.Command(*libfusePath, "--foreground")
if testutil.VerboseTest() {
cmd.Args = append(cmd.Args, "--debug", "--debug-fuse")
}
cmd.Args = append(cmd.Args, orig, mnt)
cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout
if err := cmd.Start(); err != nil {
b.Fatal(err)
}
b.Cleanup(func() { exec.Command("fusermount", "-u", mnt).Run() })
dt := time.Millisecond
for {
if _, err := os.Stat(fn); err == nil {
break
}
time.Sleep(dt)
dt *= 2
if dt > time.Second {
b.Fatal("file did not appear")
}
}
benchmarkRead(mnt, b, "")
}