func TestMkdir(t *testing.T) { tmp := tempdir.New(t) defer tmp.Cleanup() app := bazfstestutil.NewApp(t, tmp.Subdir("data")) defer app.Close() bazfstestutil.CreateVolume(t, app, "default") mnt := bazfstestutil.Mounted(t, app, "default") defer mnt.Close() p := path.Join(mnt.Dir, "sub") err := os.Mkdir(p, 0700) if err != nil { t.Fatalf("cannot mkdir sub: %v", err) } dirf, err := os.Open(mnt.Dir) if err != nil { t.Fatalf("cannot open root dir: %v", err) } defer dirf.Close() names, err := dirf.Readdirnames(10) if err != nil && err != io.EOF { t.Fatalf("cannot list root dir: %v", err) } if len(names) != 1 { t.Fatalf("unexpected content in root dir: %v", names) } if names[0] != "sub" { t.Errorf("unexpected file in root dir: %q", names[0]) } }
func TestJunkType(t *testing.T) { tmp := tempdir.New(t) defer tmp.Cleanup() setup_fs := func() fs.FS { chunkStore := &mock.InMemory{} dir := setup_dir(t, chunkStore, []*wire.Dirent{ &wire.Dirent{ Name: "junk", }, }) filesys, err := newFS(chunkStore, dir.Type.Dir) if err != nil { t.Fatalf("cannot serve snapshot as FUSE: %v", err) } return filesys } filesys := setup_fs() mnt, err := fstestutil.MountedT(t, filesys) if err != nil { t.Fatalf("Mount fail: %v\n", err) } defer mnt.Close() junk_path := path.Join(mnt.Dir, "junk") _, err = os.Stat(junk_path) if err == nil { t.Fatalf("junk getattr must fail") } else if err.(*os.PathError).Err != syscall.EIO { t.Errorf("junk stat gave bad error: %v", err) } }
func TestRemoveFile(t *testing.T) { tmp := tempdir.New(t) defer tmp.Cleanup() app := bazfstestutil.NewApp(t, tmp.Subdir("data")) defer app.Close() bazfstestutil.CreateVolume(t, app, "default") mnt := bazfstestutil.Mounted(t, app, "default") defer mnt.Close() p := path.Join(mnt.Dir, "hello") GREETING := "hello, world\n" err := ioutil.WriteFile(p, []byte(GREETING), 0644) if err != nil { t.Fatalf("cannot create hello: %v", err) } err = os.Remove(p) if err != nil { t.Fatalf("cannot delete hello: %v", err) } dirf, err := os.Open(mnt.Dir) if err != nil { t.Fatalf("cannot open root dir: %v", err) } defer dirf.Close() names, err := dirf.Readdirnames(10) if err != nil && err != io.EOF { t.Fatalf("cannot list root dir: %v", err) } if len(names) != 0 { t.Errorf("unexpected content in root dir: %v", names) } }
func TestStatFile(t *testing.T) { tmp := tempdir.New(t) defer tmp.Cleanup() app := bazfstestutil.NewApp(t, tmp.Subdir("data")) defer app.Close() bazfstestutil.CreateVolume(t, app, "default") mnt := bazfstestutil.Mounted(t, app, "default") defer mnt.Close() p := path.Join(mnt.Dir, "hello") f, err := os.Create(p) if err != nil { t.Fatalf("cannot create hello: %v", err) } defer f.Close() GREETING := "hello, world\n" n, err := f.Write([]byte(GREETING)) if err != nil { t.Fatalf("cannot write to hello: %v", err) } if n != len(GREETING) { t.Fatalf("bad length write to hello: %d != %d", n, len(GREETING)) } err = f.Close() if err != nil { t.Fatalf("closing hello failed: %v", err) } fi, err := os.Stat(p) if err != nil { t.Fatalf("cannot stat hello: %v", err) } mode := fi.Mode() if (mode & os.ModeType) != 0 { t.Errorf("hello is not a file: %#v", fi) } if mode.Perm() != 0644 { t.Errorf("file has weird access mode: %v", mode.Perm()) } switch stat := fi.Sys().(type) { case *syscall.Stat_t: if stat.Nlink != 1 { t.Errorf("file has wrong link count: %v", stat.Nlink) } if stat.Uid != uint32(syscall.Getuid()) { t.Errorf("file has wrong uid: %d", stat.Uid) } if stat.Gid != uint32(syscall.Getgid()) { t.Errorf("file has wrong gid: %d", stat.Gid) } if stat.Gid != uint32(syscall.Getgid()) { t.Errorf("file has wrong gid: %d", stat.Gid) } } if fi.Size() != int64(len(GREETING)) { t.Errorf("file has wrong size: %d != %d", fi.Size(), len(GREETING)) } }
func TestSimple(t *testing.T) { tmp := tempdir.New(t) defer tmp.Cleanup() app := bazfstestutil.NewApp(t, tmp.Subdir("data")) defer app.Close() bazfstestutil.CreateVolume(t, app, "default") mnt := bazfstestutil.Mounted(t, app, "default") defer mnt.Close() fi, err := os.Stat(mnt.Dir) if err != nil { t.Fatalf("root getattr failed with %v", err) } mode := fi.Mode() if (mode & os.ModeType) != os.ModeDir { t.Errorf("root is not a directory: %#v", fi) } if mode.Perm() != 0755 { t.Errorf("root has weird access mode: %v", mode.Perm()) } switch stat := fi.Sys().(type) { case *syscall.Stat_t: if stat.Nlink != 1 { t.Errorf("root has wrong link count: %v", stat.Nlink) } if stat.Uid != uint32(syscall.Getuid()) { t.Errorf("root has wrong uid: %d", stat.Uid) } if stat.Gid != uint32(syscall.Getgid()) { t.Errorf("root has wrong gid: %d", stat.Gid) } if stat.Gid != uint32(syscall.Getgid()) { t.Errorf("root has wrong gid: %d", stat.Gid) } } dirf, err := os.Open(mnt.Dir) if err != nil { t.Fatalf("cannot open root dir: %v", err) } defer dirf.Close() names, err := dirf.Readdirnames(10) if err != nil && err != io.EOF { t.Fatalf("cannot list root dir: %v", err) } if len(names) > 0 { t.Errorf("unexpected content in root dir: %v", names) } err = dirf.Close() if err != nil { t.Fatalf("closing root dir failed: %v", err) } }
func TestSnapRecord(t *testing.T) { tmp := tempdir.New(t) defer tmp.Cleanup() app := bazfstestutil.NewApp(t, tmp.Subdir("data")) defer app.Close() bazfstestutil.CreateVolume(t, app, "default") func() { mnt := bazfstestutil.Mounted(t, app, "default") defer mnt.Close() // write test data sub := path.Join(mnt.Dir, "greetings") err := os.Mkdir(sub, 0755) if err != nil { t.Fatalf("cannot make directory: %v", err) } p := path.Join(sub, "hello") f, err := os.Create(p) if err != nil { t.Fatalf("cannot create hello: %v", err) } defer f.Close() _, err = f.Write([]byte(GREETING)) if err != nil { t.Fatalf("cannot write to hello: %v", err) } err = f.Close() if err != nil { t.Fatalf("closing hello failed: %v", err) } // make a snapshot err = os.Mkdir(path.Join(mnt.Dir, ".snap", "mysnap"), 0755) if err != nil { t.Fatalf("snapshot failed: %v", err) } }() // mount again, to make sure cached dentry from Mkdir is flushed mnt := bazfstestutil.Mounted(t, app, "default") defer mnt.Close() // verify snapshot contents { data, err := ioutil.ReadFile(path.Join(mnt.Dir, ".snap", "mysnap", "greetings", "hello")) if err != nil { t.Fatalf("reading greeting failed: %v\n", err) } if g, e := string(data), GREETING; g != e { t.Errorf("wrong greeting: %q != %q", g, e) } } }
func TestRenameCrossDir(t *testing.T) { tmp := tempdir.New(t) defer tmp.Cleanup() app := bazfstestutil.NewApp(t, tmp.Subdir("data")) defer app.Close() bazfstestutil.CreateVolume(t, app, "default") mnt := bazfstestutil.Mounted(t, app, "default") defer mnt.Close() p := path.Join(mnt.Dir, "hello") GREETING := "hello, world\n" err := ioutil.WriteFile(p, []byte(GREETING), 0644) if err != nil { t.Fatalf("cannot create file: %v", err) } pd := path.Join(mnt.Dir, "subdir") err = os.Mkdir(pd, 0755) if err != nil { t.Fatalf("cannot mkdir: %v", err) } p2 := path.Join(pd, "cheers") err = os.Rename(p, p2) if err == nil { t.Fatalf("expected an error from rename: %v", err) } lerr, ok := err.(*os.LinkError) if !ok { t.Fatalf("expected a LinkError from rename: %v", err) } if g, e := lerr.Op, "rename"; g != e { t.Errorf("wrong LinkError.Op: %q != %q", g, e) } if g, e := lerr.Old, p; g != e { t.Errorf("wrong LinkError.Old: %q != %q", g, e) } if g, e := lerr.New, p2; g != e { t.Errorf("wrong LinkError.New: %q != %q", g, e) } if g, e := lerr.Err, syscall.EXDEV; g != e { t.Errorf("expected EXDEV: %T %v", lerr.Err, lerr.Err) } buf, err := ioutil.ReadFile(p) if err != nil { t.Fatalf("cannot read: %v", err) } if string(buf) != GREETING { t.Fatalf("hello content is wrong: %q", buf) } }
func benchmark(b *testing.B, fn func(b *testing.B, mnt string)) { tmp := tempdir.New(b) defer tmp.Cleanup() app := bazfstestutil.NewApp(b, tmp.Subdir("data")) defer app.Close() bazfstestutil.CreateVolume(b, app, "default") mnt := bazfstestutil.Mounted(b, app, "default") defer mnt.Close() fn(b, mnt.Dir) }
func TestTwoLevels(t *testing.T) { tmp := tempdir.New(t) defer tmp.Cleanup() setup_fs := func() fs.FS { chunkStore := &mock.InMemory{} greeting := setup_greeting(t, chunkStore) dir1 := setup_dir(t, chunkStore, []*wire.Dirent{ &wire.Dirent{ Name: "hello", Type: wire.Type{ File: &wire.File{ Manifest: wirecas.FromBlob(greeting), }, }, // Space: uint64(len(GREETING)), // Written: TIME_1, }, }) dir1.Name = "second" dir2 := setup_dir(t, chunkStore, []*wire.Dirent{dir1}) filesys, err := newFS(chunkStore, dir2.Type.Dir) if err != nil { t.Fatalf("cannot serve snapshot as FUSE: %v", err) } return filesys } filesys := setup_fs() mnt, err := fstestutil.MountedT(t, filesys) if err != nil { t.Fatalf("Mount fail: %v\n", err) } defer mnt.Close() hello_path := path.Join(mnt.Dir, "second", "hello") f, err := os.Open(hello_path) if err != nil { t.Fatalf("hello open failed with %v", err) } buf, err := ioutil.ReadAll(f) if err != nil { t.Errorf("hello read failed with %v", err) } if string(buf) != GREETING { t.Errorf("hello read wrong content: %q", string(buf)) } err = f.Close() if err != nil { t.Fatalf("hello close failed with %v", err) } }
func TestTruncate(t *testing.T) { tmp := tempdir.New(t) defer tmp.Cleanup() app := bazfstestutil.NewApp(t, tmp.Subdir("data")) defer app.Close() bazfstestutil.CreateVolume(t, app, "default") mnt := bazfstestutil.Mounted(t, app, "default") defer mnt.Close() p := path.Join(mnt.Dir, "hello") f, err := os.Create(p) if err != nil { t.Fatalf("cannot create hello: %v", err) } defer f.Close() GREETING := "hello, world\n" n, err := f.Write([]byte(GREETING)) if err != nil { t.Fatalf("cannot write to hello: %v", err) } if n != len(GREETING) { t.Fatalf("bad length write to hello: %d != %d", n, len(GREETING)) } err = f.Close() if err != nil { t.Fatalf("closing hello failed: %v", err) } err = os.Truncate(p, 3) if err != nil { t.Fatalf("truncate failed: %v", err) } f2, err := os.Open(p) if err != nil { t.Fatalf("cannot open hello: %v", err) } defer f2.Close() buf, err := ioutil.ReadAll(f2) if err != nil { t.Fatalf("cannot read from hello: %v", err) } if g, e := string(buf), GREETING[:3]; g != e { t.Fatalf("hello content is wrong: %q != %q", g, e) } err = f2.Close() if err != nil { t.Fatalf("closing hello failed: %v", err) } }
func TestRenameOverwrite(t *testing.T) { tmp := tempdir.New(t) defer tmp.Cleanup() app := bazfstestutil.NewApp(t, tmp.Subdir("data")) defer app.Close() bazfstestutil.CreateVolume(t, app, "default") mnt := bazfstestutil.Mounted(t, app, "default") defer mnt.Close() one := path.Join(mnt.Dir, "one") err := ioutil.WriteFile(one, []byte("foobar"), 0644) if err != nil { t.Fatalf("cannot create file: %v", err) } two := path.Join(mnt.Dir, "two") err = ioutil.WriteFile(two, []byte("xyzzy"), 0644) if err != nil { t.Fatalf("cannot create file: %v", err) } err = os.Rename(one, two) if err != nil { t.Fatalf("unexpected error from rename: %v", err) } dirf, err := os.Open(mnt.Dir) if err != nil { t.Fatalf("cannot open root dir: %v", err) } defer dirf.Close() names, err := dirf.Readdirnames(10) if err != nil && err != io.EOF { t.Fatalf("cannot list root dir: %v", err) } if len(names) != 1 { t.Errorf("unexpected content in root dir: %v", names) } if names[0] != "two" { t.Errorf("unexpected file in root dir: %q", names[0]) } buf, err := ioutil.ReadFile(two) if err != nil { t.Fatalf("cannot read: %v", err) } if string(buf) != "foobar" { t.Fatalf("two content is wrong: %q", buf) } }
func TestPing(t *testing.T) { tmp := tempdir.New(t) defer tmp.Cleanup() app1 := bazfstestutil.NewApp(t, tmp.Subdir("app1")) defer app1.Close() app2 := bazfstestutil.NewApp(t, tmp.Subdir("app2")) defer app2.Close() var wg sync.WaitGroup defer wg.Wait() web1 := httptest.ServeHTTP(t, &wg, app1) defer web1.Close() pub1 := (*peer.PublicKey)(app1.Keys.Sign.Pub) pub2 := (*peer.PublicKey)(app2.Keys.Sign.Pub) setup1 := func(tx *db.Tx) error { if _, err := tx.Peers().Make(pub2); err != nil { return err } return nil } if err := app1.DB.Update(setup1); err != nil { t.Fatalf("app1 setup: %v", err) } setup2 := func(tx *db.Tx) error { p, err := tx.Peers().Make(pub1) if err != nil { return err } if err := p.Locations().Set(web1.Addr().String()); err != nil { return err } return nil } if err := app2.DB.Update(setup2); err != nil { t.Fatalf("app2 setup location: %v", err) } client, err := app2.DialPeer(pub1) if err != nil { t.Fatalf("dial: %v", err) } defer client.Close() ctx := context.Background() if _, err := client.Ping(ctx, &wire.PingRequest{}); err != nil { t.Errorf("ping failed: %v", err) } }
func TestPersistentMkdir(t *testing.T) { tmp := tempdir.New(t) defer tmp.Cleanup() app := bazfstestutil.NewApp(t, tmp.Subdir("data")) defer app.Close() bazfstestutil.CreateVolume(t, app, "default") func() { mnt := bazfstestutil.Mounted(t, app, "default") defer mnt.Close() p := path.Join(mnt.Dir, "subdir") err := os.Mkdir(p, 0755) if err != nil { t.Fatalf("cannot create subdir: %v", err) } }() t.Logf("Unmounted to check persistency") time.Sleep(3 * time.Second) func() { mnt := bazfstestutil.Mounted(t, app, "default") defer mnt.Close() dirf, err := os.Open(mnt.Dir) if err != nil { t.Fatalf("cannot open root dir: %v", err) } defer dirf.Close() names, err := dirf.Readdirnames(10) if err != nil && err != io.EOF { t.Fatalf("cannot list root dir: %v", err) } if len(names) != 1 { t.Errorf("unexpected content in root dir: %v", names) } if len(names) > 0 && names[0] != "subdir" { t.Errorf("unexpected file in root dir: %q", names[0]) } p := path.Join(mnt.Dir, "subdir") fi, err := os.Stat(p) if err != nil { t.Fatalf("cannot stat subdir: %v", err) } if !fi.IsDir() { t.Fatalf("subdir is not a directory: %v", fi) } }() }
func TestAdd(t *testing.T) { temp := tempdir.New(t) defer temp.Cleanup() k, err := kvfiles.Open(temp.Path) if err != nil { t.Fatalf("kvfiles.Open fail: %v\n", err) } err = k.Put([]byte("quux"), []byte("foobar")) if err != nil { t.Fatalf("c.Put fail: %v\n", err) } }
func TestRemoveFileWhileOpen(t *testing.T) { tmp := tempdir.New(t) defer tmp.Cleanup() app := bazfstestutil.NewApp(t, tmp.Subdir("data")) defer app.Close() bazfstestutil.CreateVolume(t, app, "default") mnt := bazfstestutil.Mounted(t, app, "default") defer mnt.Close() p := path.Join(mnt.Dir, "hello") f, err := os.Create(p) if err != nil { t.Fatalf("cannot create hello: %v", err) } defer f.Close() err = os.Remove(p) if err != nil { t.Fatalf("cannot delete hello: %v", err) } // this must not resurrect a deleted file GREETING := "hello, world\n" n, err := f.Write([]byte(GREETING)) if err != nil { t.Fatalf("cannot write to hello: %v", err) } if n != len(GREETING) { t.Fatalf("bad length write to hello: %d != %d", n, len(GREETING)) } err = f.Close() if err != nil { t.Fatalf("closing hello failed: %v", err) } dirf, err := os.Open(mnt.Dir) if err != nil { t.Fatalf("cannot open root dir: %v", err) } defer dirf.Close() names, err := dirf.Readdirnames(10) if err != nil && err != io.EOF { t.Fatalf("cannot list root dir: %v", err) } if len(names) != 0 { t.Errorf("unexpected content in root dir: %v", names) } }
func TestSnapList(t *testing.T) { tmp := tempdir.New(t) defer tmp.Cleanup() app := bazfstestutil.NewApp(t, tmp.Subdir("data")) defer app.Close() bazfstestutil.CreateVolume(t, app, "default") mnt := bazfstestutil.Mounted(t, app, "default") defer mnt.Close() // make some snapshots { err := os.Mkdir(path.Join(mnt.Dir, ".snap", "snapone"), 0755) if err != nil { t.Fatalf("snapshot failed: %v", err) } err = os.Mkdir(path.Join(mnt.Dir, ".snap", "snaptwo"), 0755) if err != nil { t.Fatalf("snapshot failed: %v", err) } err = os.Mkdir(path.Join(mnt.Dir, ".snap", "alphabetical"), 0755) if err != nil { t.Fatalf("snapshot failed: %v", err) } } // list snapshots { fis, err := ioutil.ReadDir(path.Join(mnt.Dir, ".snap")) if err != nil { t.Fatalf("listing snapshots failed: %v\n", err) } for _, fi := range fis { if fi.Mode() != os.ModeDir|0555 { t.Errorf("snapshot has bad mode: %q is %#o", fi.Name(), fi.Mode()) } // TODO fi.ModTime() } if g, e := len(fis), 3; g != e { t.Fatalf("wrong number of snapshots: %d != %d: %v", g, e, fis) } expect := []string{"alphabetical", "snapone", "snaptwo"} for i, fi := range fis { if g, e := fi.Name(), expect[i]; g != e { t.Errorf("wrong snapshot entry: %q != %q", g, e) } } } }
func TestSharingAdd(t *testing.T) { tmp := tempdir.New(t) defer tmp.Cleanup() app, err := server.New(tmp.Path) if err != nil { t.Fatal(err) } var wg sync.WaitGroup defer wg.Wait() ctrl := controltest.ListenAndServe(t, &wg, app) defer ctrl.Close() secret := [32]byte{1, 2, 3, 4, 5} addReq := &wire.SharingKeyAddRequest{ Name: "foo", Secret: secret[:], } rpcConn, err := grpcunix.Dial(filepath.Join(app.DataDir, "control")) if err != nil { t.Fatal(err) } defer rpcConn.Close() rpcClient := wire.NewControlClient(rpcConn) ctx := context.Background() if _, err := rpcClient.SharingKeyAdd(ctx, addReq); err != nil { t.Fatalf("adding sharing key failed: %v", err) } check := func(tx *db.Tx) error { sharingKey, err := tx.SharingKeys().Get("foo") if err != nil { t.Fatalf("error checking sharing key: %v", err) } var key [32]byte sharingKey.Secret(&key) if g, e := key, secret; g != e { t.Errorf("wrong secret stored: %x != %x", g, e) } return nil } if err := app.DB.View(check); err != nil { t.Error(err) } }
func TestPeerAdd(t *testing.T) { tmp := tempdir.New(t) defer tmp.Cleanup() app, err := server.New(tmp.Path) if err != nil { t.Fatal(err) } var wg sync.WaitGroup defer wg.Wait() ctrl := controltest.ListenAndServe(t, &wg, app) defer ctrl.Close() pub := peer.PublicKey{1, 2, 3, 4, 5} addReq := &wire.PeerAddRequest{ Pub: pub[:], } rpcConn, err := grpcunix.Dial(filepath.Join(app.DataDir, "control")) if err != nil { t.Fatal(err) } defer rpcConn.Close() rpcClient := wire.NewControlClient(rpcConn) ctx := context.Background() if _, err := rpcClient.PeerAdd(ctx, addReq); err != nil { t.Fatalf("adding peer failed: %v", err) } getPeer := func(tx *db.Tx) error { p, err := tx.Peers().Get(&pub) if err != nil { t.Fatalf("checking stored peer: %v", err) } if g, e := *p.Pub(), pub; g != e { t.Errorf("wrong public key stored: %x != %x", g, e) } return nil } if err := app.DB.View(getPeer); err != nil { t.Fatal(err) } }
func TestRemoveNonexistent(t *testing.T) { tmp := tempdir.New(t) defer tmp.Cleanup() app := bazfstestutil.NewApp(t, tmp.Subdir("data")) defer app.Close() bazfstestutil.CreateVolume(t, app, "default") mnt := bazfstestutil.Mounted(t, app, "default") defer mnt.Close() p := path.Join(mnt.Dir, "does-not-exist") err := os.Remove(p) if err == nil { t.Fatalf("deleting non-existent file should have failed") } if !os.IsNotExist(err) { t.Fatalf("deleting non-existent file gave wrong error: %v", err) } }
func TestSharingAddBadNameEmpty(t *testing.T) { tmp := tempdir.New(t) defer tmp.Cleanup() app, err := server.New(tmp.Path) if err != nil { t.Fatal(err) } var wg sync.WaitGroup defer wg.Wait() ctrl := controltest.ListenAndServe(t, &wg, app) defer ctrl.Close() secret := [32]byte{1, 2, 3, 4, 5} addReq := &wire.SharingKeyAddRequest{ Name: "", Secret: secret[:], } rpcConn, err := grpcunix.Dial(filepath.Join(app.DataDir, "control")) if err != nil { t.Fatal(err) } defer rpcConn.Close() rpcClient := wire.NewControlClient(rpcConn) ctx := context.Background() _, err = rpcClient.SharingKeyAdd(ctx, addReq) if err == nil { t.Fatalf("expected error from SharingKeyAdd with empty name") } if err := checkRPCError(err, codes.InvalidArgument, "invalid sharing key name"); err != nil { t.Error(err) } if err := app.DB.View(checkNoSharingKey("foo")); err != nil { t.Error(err) } }
func TestSharingAddBadSecretShort(t *testing.T) { tmp := tempdir.New(t) defer tmp.Cleanup() app, err := server.New(tmp.Path) if err != nil { t.Fatal(err) } var wg sync.WaitGroup defer wg.Wait() ctrl := controltest.ListenAndServe(t, &wg, app) defer ctrl.Close() tooShort := make([]byte, 33) addReq := &wire.SharingKeyAddRequest{ Name: "foo", Secret: tooShort, } rpcConn, err := grpcunix.Dial(filepath.Join(app.DataDir, "control")) if err != nil { t.Fatal(err) } defer rpcConn.Close() rpcClient := wire.NewControlClient(rpcConn) ctx := context.Background() _, err = rpcClient.SharingKeyAdd(ctx, addReq) if err == nil { t.Fatalf("expected error from SharingKeyAdd with too short secret") } if err := checkRPCError(err, codes.InvalidArgument, "sharing key must be exactly 32 bytes"); err != nil { t.Error(err) } if err := app.DB.View(checkNoSharingKey("foo")); err != nil { t.Error(err) } }
func TestGet(t *testing.T) { temp := tempdir.New(t) defer temp.Cleanup() c, err := kvfiles.Open(temp.Path) if err != nil { t.Fatalf("kvfiles.Open fail: %v\n", err) } err = c.Put([]byte("quux"), []byte("foobar")) if err != nil { t.Fatalf("c.Put fail: %v\n", err) } data, err := c.Get([]byte("quux")) if err != nil { t.Fatalf("c.Get failed: %v", err) } if g, e := string(data), "foobar"; g != e { t.Fatalf("c.Get gave wrong content: %q != %q", g, e) } }
func TestGetNotFoundError(t *testing.T) { temp := tempdir.New(t) defer temp.Cleanup() c, err := kvfiles.Open(temp.Path) if err != nil { t.Fatalf("kvfiles.Open fail: %v\n", err) } const KEY = "\x8d\xf3\x1f\x60\xd6\xae\xab\xd0\x1b\x7d\xc8\x3f\x27\x7d\x0e\x24\xcb\xe1\x04\xf7\x29\x0f\xf8\x90\x77\xa7\xeb\x58\x64\x60\x68\xed\xfe\x1a\x83\x02\x28\x66\xc4\x6f\x65\xfb\x91\x61\x2e\x51\x6e\x0e\xcf\xa5\xcb\x25\xfc\x16\xb3\x7d\x2c\x8d\x73\x73\x2f\xe7\x4c\xb2" _, err = c.Get([]byte(KEY)) if err == nil { t.Fatalf("c.Get should have failed") } nf, ok := err.(kv.NotFoundError) if !ok { t.Fatalf("c.Get error is of wrong type: %T: %v", err, err) } if g, w := string(nf.Key), KEY; g != w { t.Errorf("NotFoundError Key is wrong: %x != %x", g, w) } }
func TestPeerAddBadPubLong(t *testing.T) { tmp := tempdir.New(t) defer tmp.Cleanup() app, err := server.New(tmp.Path) if err != nil { t.Fatal(err) } var wg sync.WaitGroup defer wg.Wait() ctrl := controltest.ListenAndServe(t, &wg, app) defer ctrl.Close() tooLong := make([]byte, 33) addReq := &wire.PeerAddRequest{ Pub: tooLong, } rpcConn, err := grpcunix.Dial(filepath.Join(app.DataDir, "control")) if err != nil { t.Fatal(err) } defer rpcConn.Close() rpcClient := wire.NewControlClient(rpcConn) ctx := context.Background() _, err = rpcClient.PeerAdd(ctx, addReq) if err == nil { t.Fatalf("expected error from PeerAdd with too long public key") } if err := checkRPCError(err, codes.InvalidArgument, "bad peer public key: peer public key must be exactly 32 bytes"); err != nil { t.Error(err) } if err := checkHasNoPeers(app); err != nil { t.Error(err) } }
func TestPeerAddBadPubSelf(t *testing.T) { tmp := tempdir.New(t) defer tmp.Cleanup() app, err := server.New(tmp.Path) if err != nil { t.Fatal(err) } var wg sync.WaitGroup defer wg.Wait() ctrl := controltest.ListenAndServe(t, &wg, app) defer ctrl.Close() addReq := &wire.PeerAddRequest{ Pub: app.Keys.Sign.Pub[:], } rpcConn, err := grpcunix.Dial(filepath.Join(app.DataDir, "control")) if err != nil { t.Fatal(err) } defer rpcConn.Close() rpcClient := wire.NewControlClient(rpcConn) ctx := context.Background() _, err = rpcClient.PeerAdd(ctx, addReq) if err == nil { t.Fatalf("expected error from PeerAdd with its own public key") } if err := checkRPCError(err, codes.InvalidArgument, "cannot add self as peer"); err != nil { t.Error(err) } if err := checkHasNoPeers(app); err != nil { t.Error(err) } }
func TestSyncSimple(t *testing.T) { tmp := tempdir.New(t) defer tmp.Cleanup() app1 := bazfstestutil.NewApp(t, tmp.Subdir("app1")) defer app1.Close() app2 := bazfstestutil.NewApp(t, tmp.Subdir("app2")) defer app2.Close() pub1 := (*peer.PublicKey)(app1.Keys.Sign.Pub) const ( volumeName1 = "testvol1" volumeName2 = "testvol2" ) connectVolume(t, app1, volumeName1, app2, volumeName2) var wg sync.WaitGroup defer wg.Wait() web1 := httptest.ServeHTTP(t, &wg, app1) defer web1.Close() setLocation(t, app2, app1.Keys.Sign.Pub, web1.Addr()) const ( filename = "greeting" input = "hello, world" ) func() { mnt := bazfstestutil.Mounted(t, app1, volumeName1) defer mnt.Close() if err := ioutil.WriteFile(path.Join(mnt.Dir, filename), []byte(input), 0644); err != nil { t.Fatalf("cannot create file: %v", err) } }() // trigger sync ctrl := controltest.ListenAndServe(t, &wg, app2) defer ctrl.Close() rpcConn, err := grpcunix.Dial(filepath.Join(app2.DataDir, "control")) if err != nil { t.Fatal(err) } defer rpcConn.Close() rpcClient := wire.NewControlClient(rpcConn) ctx := context.Background() req := &wire.VolumeSyncRequest{ VolumeName: volumeName2, Pub: pub1[:], } if _, err := rpcClient.VolumeSync(ctx, req); err != nil { t.Fatalf("error while syncing: %v", err) } mnt := bazfstestutil.Mounted(t, app2, volumeName2) defer mnt.Close() buf, err := ioutil.ReadFile(path.Join(mnt.Dir, filename)) if err != nil { t.Fatalf("cannot read file: %v", err) } if g, e := string(buf), input; g != e { t.Fatalf("wrong content: %q != %q", g, e) } }
func TestRenameOverwriteWhileOpen(t *testing.T) { tmp := tempdir.New(t) defer tmp.Cleanup() app := bazfstestutil.NewApp(t, tmp.Subdir("data")) defer app.Close() bazfstestutil.CreateVolume(t, app, "default") func() { mnt := bazfstestutil.Mounted(t, app, "default") defer mnt.Close() one := path.Join(mnt.Dir, "one") two := path.Join(mnt.Dir, "two") err := ioutil.WriteFile(one, []byte("foobar"), 0644) if err != nil { t.Fatalf("cannot create file: %v", err) } f, err := os.Create(two) if err != nil { t.Fatalf("cannot create hello: %v", err) } defer f.Close() err = os.Rename(one, two) if err != nil { t.Fatalf("unexpected error from rename: %v", err) } // this must not resurrect a deleted file GREETING := "hello, world\n" n, err := f.Write([]byte(GREETING)) if err != nil { t.Fatalf("cannot write to hello: %v", err) } if n != len(GREETING) { t.Fatalf("bad length write to hello: %d != %d", n, len(GREETING)) } err = f.Close() if err != nil { t.Fatalf("closing hello failed: %v", err) } }() t.Logf("Unmounted to flush cache") func() { mnt := bazfstestutil.Mounted(t, app, "default") defer mnt.Close() dirf, err := os.Open(mnt.Dir) if err != nil { t.Fatalf("cannot open root dir: %v", err) } defer dirf.Close() names, err := dirf.Readdirnames(10) if err != nil && err != io.EOF { t.Fatalf("cannot list root dir: %v", err) } if len(names) != 1 { t.Errorf("unexpected content in root dir: %v", names) } if names[0] != "two" { t.Errorf("unexpected file in root dir: %q", names[0]) } two := path.Join(mnt.Dir, "two") buf, err := ioutil.ReadFile(two) if err != nil { t.Fatalf("cannot read: %v", err) } if string(buf) != "foobar" { t.Fatalf("two content is wrong: %q", buf) } }() }
func TestAppend(t *testing.T) { tmp := tempdir.New(t) defer tmp.Cleanup() app := bazfstestutil.NewApp(t, tmp.Subdir("data")) defer app.Close() bazfstestutil.CreateVolume(t, app, "default") mnt := bazfstestutil.Mounted(t, app, "default") defer mnt.Close() p := path.Join(mnt.Dir, "hello") f, err := os.Create(p) if err != nil { t.Fatalf("cannot create hello: %v", err) } defer f.Close() GREETING := "hello, world\n" n, err := f.Write([]byte(GREETING)) if err != nil { t.Fatalf("cannot write to hello: %v", err) } if n != len(GREETING) { t.Fatalf("bad length write to hello: %d != %d", n, len(GREETING)) } err = f.Close() if err != nil { t.Fatalf("closing hello failed: %v", err) } f2, err := os.OpenFile(p, os.O_WRONLY|os.O_APPEND, 0666) if err != nil { t.Fatalf("cannot open hello again: %v", err) } defer f2.Close() GREETING2 := "more\n" n, err = f2.Write([]byte(GREETING2)) if err != nil { t.Fatalf("cannot append to hello: %v", err) } if n != len(GREETING2) { t.Fatalf("bad length append to hello: %d != %d", n, len(GREETING2)) } err = f2.Close() if err != nil { t.Fatalf("closing hello failed: %v", err) } f3, err := os.Open(p) if err != nil { t.Fatalf("cannot open hello: %v", err) } defer f3.Close() buf, err := ioutil.ReadAll(f3) if err != nil { t.Fatalf("cannot read from hello: %v", err) } if string(buf) != GREETING+GREETING2 { t.Fatalf("hello content is wrong: %q", buf) } err = f3.Close() if err != nil { t.Fatalf("closing hello failed: %v", err) } }
func TestRename(t *testing.T) { tmp := tempdir.New(t) defer tmp.Cleanup() app := bazfstestutil.NewApp(t, tmp.Subdir("data")) defer app.Close() bazfstestutil.CreateVolume(t, app, "default") mnt := bazfstestutil.Mounted(t, app, "default") defer mnt.Close() p := path.Join(mnt.Dir, "hello") f, err := os.Create(p) if err != nil { t.Fatalf("cannot create hello: %v", err) } defer f.Close() GREETING := "hello, world\n" n, err := f.Write([]byte(GREETING)) if err != nil { t.Fatalf("cannot write to hello: %v", err) } if n != len(GREETING) { t.Fatalf("bad length write to hello: %d != %d", n, len(GREETING)) } err = f.Close() if err != nil { t.Fatalf("closing hello failed: %v", err) } p2 := path.Join(mnt.Dir, "bye") err = os.Rename(p, p2) if err != nil { t.Fatalf("unexpected error from rename: %v", err) } dirf, err := os.Open(mnt.Dir) if err != nil { t.Fatalf("cannot open root dir: %v", err) } defer dirf.Close() names, err := dirf.Readdirnames(10) if err != nil && err != io.EOF { t.Fatalf("cannot list root dir: %v", err) } if len(names) != 1 { t.Errorf("unexpected content in root dir: %v", names) } if names[0] != "bye" { t.Errorf("unexpected file in root dir: %q", names[0]) } f, err = os.Open(p2) if err != nil { t.Fatalf("cannot open bye: %v", err) } defer f.Close() buf, err := ioutil.ReadAll(f) if err != nil { t.Fatalf("cannot read from bye: %v", err) } if string(buf) != GREETING { t.Fatalf("bye content is wrong: %q", buf) } err = f.Close() if err != nil { t.Fatalf("closing bye failed: %v", err) } }
func TestHello(t *testing.T) { tmp := tempdir.New(t) defer tmp.Cleanup() filesys := setup_fs(t) mnt, err := fstestutil.MountedT(t, filesys) if err != nil { t.Fatalf("Mount fail: %v\n", err) } defer mnt.Close() fi, err := os.Stat(mnt.Dir) if err != nil { t.Fatalf("root getattr failed with %v", err) } mode := fi.Mode() if (mode & os.ModeType) != os.ModeDir { t.Errorf("root is not a directory: %#v", fi) } if mode.Perm() != 0555 { t.Errorf("root has weird access mode: %v", mode.Perm()) } switch stat := fi.Sys().(type) { case *syscall.Stat_t: if stat.Nlink != 1 { t.Errorf("root has wrong link count: %v", stat.Nlink) } if stat.Uid != uint32(syscall.Getuid()) { t.Errorf("root has wrong uid: %d", stat.Uid) } if stat.Gid != uint32(syscall.Getgid()) { t.Errorf("root has wrong gid: %d", stat.Gid) } if stat.Gid != uint32(syscall.Getgid()) { t.Errorf("root has wrong gid: %d", stat.Gid) } } f, err := os.Create(path.Join(mnt.Dir, "does-not-exist-yet")) if err == nil { f.Close() t.Errorf("root must be read-only") } else if err.(*os.PathError).Err != syscall.EROFS { t.Errorf("file create gave bad error: %v", err) } hello_path := path.Join(mnt.Dir, "hello") fi, err = os.Stat(hello_path) if err != nil { t.Fatalf("hello getattr failed with %v", err) } if fi.Name() != "hello" { t.Errorf("hello has weird name: %q", fi.Name()) } if fi.Size() != 13 { t.Errorf("hello has weird size: %v", fi.Size()) } // if fi.ModTime() != TIME_1 { // t.Errorf("hello has weird time: %v != %v", fi.ModTime(), TIME_1) // } mode = fi.Mode() if (mode & os.ModeType) != 0 { t.Errorf("hello is not a file: %#v", fi) } if mode.Perm() != 0444 { t.Errorf("hello has weird access mode: %v", mode.Perm()) } switch stat := fi.Sys().(type) { case *syscall.Stat_t: if stat.Nlink != 1 { t.Errorf("hello has wrong link count: %v", stat.Nlink) } if stat.Uid != uint32(syscall.Getuid()) { t.Errorf("hello has wrong uid: %d", stat.Uid) } if stat.Gid != uint32(syscall.Getgid()) { t.Errorf("hello has wrong gid: %d", stat.Gid) } if stat.Gid != uint32(syscall.Getgid()) { t.Errorf("hello has wrong gid: %d", stat.Gid) } if stat.Blocks != 1 { t.Errorf("hello has weird blockcount: %v", stat.Blocks) } } f, err = os.Create(hello_path) if err == nil { f.Close() t.Errorf("hello must be read-only") } else if err.(*os.PathError).Err != syscall.EACCES { t.Errorf("hello open for write gave bad error: %v", err) } f, err = os.Open(hello_path) if err != nil { t.Fatalf("hello open failed with %v", err) } buf, err := ioutil.ReadAll(f) if err != nil { t.Errorf("hello read failed with %v", err) } if string(buf) != GREETING { t.Errorf("hello read wrong content: %q", string(buf)) } err = f.Close() if err != nil { t.Fatalf("hello close failed with %v", err) } }