summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorJakob Unterwurzacher2021-03-30 14:58:18 +0200
committerJakob Unterwurzacher2021-03-30 15:11:28 +0200
commita2effaae390253bfbc2e9522dd4b5123a067f60f (patch)
tree0a383f26357b2943dc8f01ed269c817399c1506b /tests
parente0981ea59ba9224ddbd96a376fccea758e3e0d7c (diff)
tests: sharedstorage: add TestStaleHardlinks
Diffstat (limited to 'tests')
-rw-r--r--tests/sharedstorage/sharedstorage_test.go109
1 files changed, 94 insertions, 15 deletions
diff --git a/tests/sharedstorage/sharedstorage_test.go b/tests/sharedstorage/sharedstorage_test.go
index d2230a0..0fe7838 100644
--- a/tests/sharedstorage/sharedstorage_test.go
+++ b/tests/sharedstorage/sharedstorage_test.go
@@ -2,7 +2,10 @@
package sharedstorage
import (
+ "fmt"
+ "os"
"testing"
+ "time"
"golang.org/x/sys/unix"
@@ -11,11 +14,43 @@ import (
var flagSharestorage bool
+const cacheTime = time.Second
+
func TestMain(m *testing.M) {
+ ret := 0
flagSharestorage = false
- m.Run()
+ ret += m.Run()
flagSharestorage = true
- m.Run()
+ ret += m.Run()
+ os.Exit(ret)
+}
+
+type testCase struct {
+ t *testing.T
+
+ cipherdir string
+ mnt1 string
+ mnt2 string
+}
+
+func newTestCase(t *testing.T) *testCase {
+ tc := testCase{}
+ tc.cipherdir = test_helpers.InitFS(t)
+ tc.mnt1 = tc.cipherdir + ".mnt1"
+ tc.mnt2 = tc.cipherdir + ".mnt2"
+ mountSharedstorage(t, tc.cipherdir, tc.mnt1)
+ mountSharedstorage(t, tc.cipherdir, tc.mnt2)
+ t.Logf("newTestCase: sharedstorage=%v cipherdir=%q", flagSharestorage, tc.cipherdir)
+ return &tc
+}
+
+func (tc *testCase) cleanup() {
+ for _, mnt := range []string{tc.mnt1, tc.mnt2} {
+ err := test_helpers.UnmountErr(mnt)
+ if err != nil {
+ tc.t.Error(err)
+ }
+ }
}
// mountSharedstorage mounts `cipherdir` on `mnt` with or without the
@@ -28,34 +63,78 @@ func mountSharedstorage(t *testing.T, cipherdir string, mnt string) {
test_helpers.MountOrFatal(t, cipherdir, mnt, args...)
}
-func TestUnlink(t *testing.T) {
- cipherdir := test_helpers.InitFS(t)
- mnt1 := cipherdir + ".mnt1"
- mnt2 := cipherdir + ".mnt2"
- mountSharedstorage(t, cipherdir, mnt1)
- defer test_helpers.UnmountPanic(mnt1)
- mountSharedstorage(t, cipherdir, mnt2)
- defer test_helpers.UnmountPanic(mnt2)
+func TestDirUnlink(t *testing.T) {
+ tc := newTestCase(t)
+ defer tc.cleanup()
// Create dir via mnt1
- if err := unix.Mkdir(mnt1+"/foo", 0700); err != nil {
+ if err := unix.Mkdir(tc.mnt1+"/foo", 0700); err != nil {
t.Fatal(err)
}
// Replace dir with file via mnt2
- if err := unix.Rmdir(mnt2 + "/foo"); err != nil {
+ if err := unix.Rmdir(tc.mnt2 + "/foo"); err != nil {
t.Fatal(err)
}
- if fd, err := unix.Creat(mnt2+"/foo", 0600); err != nil {
+ if fd, err := unix.Creat(tc.mnt2+"/foo", 0600); err != nil {
t.Fatal(err)
} else {
unix.Close(fd)
}
// Try to unlink via mnt1
- if err := unix.Unlink(mnt1 + "/foo"); err != nil {
+ if err := unix.Unlink(tc.mnt1 + "/foo"); err != nil {
+ // Must work with -sharedstorage
+ if flagSharestorage {
+ t.Fatal(err)
+ } else {
+ // Must always work after cache timeout
+ time.Sleep(cacheTime)
+ if err := unix.Unlink(tc.mnt1 + "/foo"); err != nil {
+ t.Fatal(err)
+ }
+ }
+ }
+}
+
+// TestStaleHardlinks always failed before
+// https://review.gerrithub.io/c/hanwen/go-fuse/+/513646/2
+func TestStaleHardlinks(t *testing.T) {
+ tc := newTestCase(t)
+ defer tc.cleanup()
+
+ link0 := tc.mnt1 + "/link0"
+ if fd, err := unix.Creat(link0, 0600); err != nil {
+ t.Fatal(err)
+ } else {
+ unix.Close(fd)
+ }
+ // Create hardlinks via mnt1
+ for i := 1; i < 20; i++ {
+ linki := fmt.Sprintf(tc.mnt1+"/link%d", i)
+ if err := unix.Link(link0, linki); err != nil {
+ t.Fatal(err)
+ }
+ }
+ // Delete hardlinks via mnt2
+ for i := 1; i < 20; i++ {
+ linki := fmt.Sprintf(tc.mnt2+"/link%d", i)
+ if err := unix.Unlink(linki); err != nil {
+ t.Fatal(err)
+ }
+ }
+ // Open link0 via mnt1
+ fd, err := unix.Open(link0, unix.O_RDONLY, 0)
+ if err != nil {
+ // Must work with -sharedstorage
if flagSharestorage {
t.Fatal(err)
} else {
- t.Logf("Unlink failed as expected: errno %d / %v", err, err)
+ // Must always work after cache timeout
+ time.Sleep(cacheTime)
+ fd, err = unix.Open(link0, unix.O_RDONLY, 0)
+ if err != nil {
+ t.Fatal(err)
+ }
}
}
+ unix.Close(fd)
}