Add streaming read and write benchmarks
Run using ./main_benchmark.bash Also, rewrite command line args handling
This commit is contained in:
parent
58d1e24b7c
commit
5f4c9240ca
@ -68,7 +68,7 @@ func (f *File) Open(ctx context.Context, req *fuse.OpenRequest, resp *fuse.OpenR
|
||||
|
||||
func (f *File) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error {
|
||||
|
||||
fmt.Printf("Read: o=%d l=%d\n", req.Offset, req.Size)
|
||||
cryptfs.Debug.Printf("Read: o=%d l=%d\n", req.Offset, req.Size)
|
||||
|
||||
// Read the backing ciphertext in one go
|
||||
iblocks := f.crfs.SplitRange(uint64(req.Offset), uint64(req.Size))
|
||||
|
@ -27,17 +27,17 @@ type nullTracer struct {}
|
||||
|
||||
func (nullTracer) Trace(op cluefs.FsOperTracer) {}
|
||||
|
||||
func NewFS(key [16]byte, backing string, useOpenssl bool) *FS {
|
||||
var nt nullTracer
|
||||
clfs, err := cluefs.NewClueFS(backing, nt)
|
||||
func NewFS(key [16]byte, backing string, useOpenssl bool) (*FS, error) {
|
||||
var tracer nullTracer
|
||||
clfs, err := cluefs.NewClueFS(backing, tracer)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return nil, err
|
||||
}
|
||||
return &FS {
|
||||
CryptFS: cryptfs.NewCryptFS(key, useOpenssl),
|
||||
ClueFS: clfs,
|
||||
backing: backing,
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (fs *FS) Root() (fusefs.Node, error) {
|
||||
|
41
main.go
41
main.go
@ -1,29 +1,46 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"flag"
|
||||
"os"
|
||||
"fmt"
|
||||
"github.com/rfjakob/gocryptfs/frontend"
|
||||
"bazil.org/fuse"
|
||||
fusefs "bazil.org/fuse/fs"
|
||||
"fmt"
|
||||
"github.com/rfjakob/cluefs/lib/cluefs"
|
||||
"github.com/rfjakob/gocryptfs/frontend"
|
||||
"os"
|
||||
|
||||
)
|
||||
|
||||
const (
|
||||
PROGRAM_NAME = "gocryptfs"
|
||||
USE_OPENSSL = true
|
||||
|
||||
ERREXIT_USAGE = 1
|
||||
ERREXIT_NEWFS = 2
|
||||
ERREXIT_MOUNT = 3
|
||||
ERREXIT_SERVE = 4
|
||||
ERREXIT_MOUNT2 = 5
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Parse command line arguments
|
||||
conf, err := cluefs.ParseArguments()
|
||||
if err != nil {
|
||||
os.Exit(1)
|
||||
flag.Parse()
|
||||
if flag.NArg() < 2 {
|
||||
fmt.Printf("NArg=%d\n", flag.NArg())
|
||||
fmt.Printf("usage: %s CIPHERDIR MOUNTPOINT\n", PROGRAM_NAME)
|
||||
os.Exit(ERREXIT_USAGE)
|
||||
}
|
||||
|
||||
cipherdir, _ := filepath.Abs(flag.Arg(0))
|
||||
mountpoint, err := filepath.Abs(flag.Arg(1))
|
||||
|
||||
// Create the file system object
|
||||
var key [16]byte
|
||||
cfs := frontend.NewFS(key, conf.GetShadowDir(), USE_OPENSSL)
|
||||
cfs, err := frontend.NewFS(key, cipherdir, USE_OPENSSL)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(ERREXIT_NEWFS)
|
||||
}
|
||||
|
||||
// Mount the file system
|
||||
mountOpts := []fuse.MountOption{
|
||||
@ -33,24 +50,24 @@ func main() {
|
||||
fuse.LocalVolume(),
|
||||
fuse.MaxReadahead(1024*1024),
|
||||
}
|
||||
conn, err := fuse.Mount(conf.GetMountPoint(), mountOpts...)
|
||||
conn, err := fuse.Mount(mountpoint, mountOpts...)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
os.Exit(ERREXIT_MOUNT)
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
// Start serving requests
|
||||
if err = fusefs.Serve(conn, cfs); err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
os.Exit(ERREXIT_SERVE)
|
||||
}
|
||||
|
||||
// Check for errors when mounting the file system
|
||||
<-conn.Ready
|
||||
if err = conn.MountError; err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
os.Exit(ERREXIT_MOUNT2)
|
||||
}
|
||||
|
||||
// We are done
|
||||
|
6
main_benchmark.bash
Executable file
6
main_benchmark.bash
Executable file
@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eux
|
||||
|
||||
go build
|
||||
go test -bench=.
|
149
main_test.go
Normal file
149
main_test.go
Normal file
@ -0,0 +1,149 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"io"
|
||||
"fmt"
|
||||
"time"
|
||||
"testing"
|
||||
"os"
|
||||
"os/exec"
|
||||
"io/ioutil"
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
)
|
||||
|
||||
const tmpDir = "test_tmp_dir/"
|
||||
const plainDir = tmpDir + "plain/"
|
||||
const cipherDir = tmpDir + "cipher/"
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
|
||||
fu := exec.Command("fusermount", "-u", plainDir)
|
||||
fu.Stdout = os.Stdout
|
||||
fu.Stderr = os.Stderr
|
||||
fu.Run()
|
||||
os.RemoveAll(tmpDir)
|
||||
|
||||
err := os.MkdirAll(plainDir, 0777)
|
||||
if err != nil {
|
||||
panic("Could not create plainDir")
|
||||
}
|
||||
|
||||
err = os.MkdirAll(cipherDir, 0777)
|
||||
if err != nil {
|
||||
panic("Could not create cipherDir")
|
||||
}
|
||||
|
||||
c := exec.Command("./gocryptfs", cipherDir, plainDir)
|
||||
c.Stdout = os.Stdout
|
||||
c.Stderr = os.Stderr
|
||||
go c.Run()
|
||||
|
||||
time.Sleep(3 * time.Second)
|
||||
|
||||
r := m.Run()
|
||||
|
||||
|
||||
fu.Run()
|
||||
os.Exit(r)
|
||||
}
|
||||
|
||||
func testWriteN(t *testing.T, fn string, n int, hashWant string) {
|
||||
file, err := os.Create(plainDir + fn)
|
||||
if err != nil {
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
d := make([]byte, n)
|
||||
written, err := file.Write(d)
|
||||
if err != nil || written != len(d) {
|
||||
fmt.Printf("err=\"%s\", written=%d\n", err, written)
|
||||
t.Fail()
|
||||
}
|
||||
file.Close()
|
||||
|
||||
buf, err := ioutil.ReadFile(plainDir + fn)
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
rawHash := md5.Sum(buf)
|
||||
hashActual := hex.EncodeToString(rawHash[:])
|
||||
if hashActual != hashWant {
|
||||
fmt.Printf("hashWant=%s hashActual=%s\n", hashWant, hashActual)
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
func TestWrite10(t *testing.T) {
|
||||
testWriteN(t, "10", 10, "a63c90cc3684ad8b0a2176a6a8fe9005")
|
||||
}
|
||||
|
||||
func TestWrite100(t *testing.T) {
|
||||
testWriteN(t, "100", 100, "6d0bb00954ceb7fbee436bb55a8397a9")
|
||||
}
|
||||
|
||||
func TestWrite1M(t *testing.T) {
|
||||
testWriteN(t, "1M", 1024*1024, "b6d81b360a5672d80c27430f39153e2c")
|
||||
}
|
||||
|
||||
func TestWrite1Mx100(t *testing.T) {
|
||||
testWriteN(t, "1Mx100", 1024*1024, "b6d81b360a5672d80c27430f39153e2c")
|
||||
// Read and check 100 times to catch race conditions
|
||||
var i int
|
||||
for i = 0; i < 100; i++ {
|
||||
buf, err := ioutil.ReadFile(plainDir + "1M")
|
||||
if err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
rawHash := md5.Sum(buf)
|
||||
hashActual := hex.EncodeToString(rawHash[:])
|
||||
if hashActual != "b6d81b360a5672d80c27430f39153e2c" {
|
||||
fmt.Printf("Read corruption in loop # %d\n", i)
|
||||
t.FailNow()
|
||||
} else {
|
||||
//fmt.Print(".")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkStreamWrite(t *testing.B) {
|
||||
buf := make([]byte, 1024*1024)
|
||||
t.SetBytes(int64(len(buf)))
|
||||
|
||||
file, err := os.Create(plainDir + "BenchmarkWrite")
|
||||
if err != nil {
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
t.ResetTimer()
|
||||
var i int
|
||||
for i = 0; i < t.N; i++ {
|
||||
written, err := file.Write(buf)
|
||||
if err != nil {
|
||||
fmt.Printf("err=\"%s\", written=%d\n", err.Error(), written)
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkStreamRead(t *testing.B) {
|
||||
buf := make([]byte, 1024*1024)
|
||||
t.SetBytes(int64(len(buf)))
|
||||
file, err := os.Open(plainDir + "BenchmarkWrite")
|
||||
if err != nil {
|
||||
t.FailNow()
|
||||
}
|
||||
t.ResetTimer()
|
||||
var i int
|
||||
for i = 0; i < t.N; i++ {
|
||||
_, err := file.Read(buf)
|
||||
if err == io.EOF {
|
||||
fmt.Printf("Test file too small\n")
|
||||
t.SkipNow()
|
||||
} else if err != nil {
|
||||
fmt.Println(err)
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user