aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Unterwurzacher2015-09-06 11:42:01 +0200
committerJakob Unterwurzacher2015-09-06 11:42:01 +0200
commit5f4c9240ca1092b47553fe34b9cc1b7836222b6a (patch)
tree4dd15443b1dd881f7df3ba9d8c4eb81364d0ab65
parent58d1e24b7c4eb69376dd0ec230c42ea9aeb70f2d (diff)
Add streaming read and write benchmarks
Run using ./main_benchmark.bash Also, rewrite command line args handling
-rw-r--r--frontend/fe_file.go2
-rw-r--r--frontend/fe_fs.go10
-rw-r--r--main.go41
-rwxr-xr-xmain_benchmark.bash6
-rw-r--r--main_test.go149
5 files changed, 190 insertions, 18 deletions
diff --git a/frontend/fe_file.go b/frontend/fe_file.go
index b417227..4679589 100644
--- a/frontend/fe_file.go
+++ b/frontend/fe_file.go
@@ -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))
diff --git a/frontend/fe_fs.go b/frontend/fe_fs.go
index 4d49194..d1fa5b1 100644
--- a/frontend/fe_fs.go
+++ b/frontend/fe_fs.go
@@ -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) {
diff --git a/main.go b/main.go
index 3ad0fa4..3619bb7 100644
--- a/main.go
+++ b/main.go
@@ -1,29 +1,46 @@
package main
import (
- "bazil.org/fuse"
- fusefs "bazil.org/fuse/fs"
+ "path/filepath"
+ "flag"
+ "os"
"fmt"
- "github.com/rfjakob/cluefs/lib/cluefs"
"github.com/rfjakob/gocryptfs/frontend"
- "os"
+ "bazil.org/fuse"
+ fusefs "bazil.org/fuse/fs"
+
)
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
diff --git a/main_benchmark.bash b/main_benchmark.bash
new file mode 100755
index 0000000..447581a
--- /dev/null
+++ b/main_benchmark.bash
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+set -eux
+
+go build
+go test -bench=.
diff --git a/main_test.go b/main_test.go
new file mode 100644
index 0000000..f17b5f5
--- /dev/null
+++ b/main_test.go
@@ -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()
+ }
+ }
+}