From d22ccf68b21e75a6a2d43a658002b87bd5d0a2a1 Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Tue, 5 Mar 2019 22:21:10 +0100 Subject: [PATCH] tests: add TestConcurrentReadWrite Another attempt to find out what is going on behind https://github.com/rfjakob/gocryptfs/issues/363 --- tests/matrix/matrix_test.go | 63 +++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/tests/matrix/matrix_test.go b/tests/matrix/matrix_test.go index 226dfd8..b1d12fa 100644 --- a/tests/matrix/matrix_test.go +++ b/tests/matrix/matrix_test.go @@ -15,7 +15,9 @@ import ( "bytes" "flag" "fmt" + "io" "io/ioutil" + "log" "os" "os/exec" "runtime" @@ -186,6 +188,67 @@ func TestWrite10Tight(t *testing.T) { } } +// https://github.com/rfjakob/gocryptfs/issues/363 +// +// Note: this test calls log.Fatal() instead of t.Fatal() because apperently, +// calling t.Fatal() from a goroutine hangs the test. +func TestConcurrentReadWrite(t *testing.T) { + var wg sync.WaitGroup + fn := test_helpers.DefaultPlainDir + "/TestConcurrentReadWrite" + if f, err := os.Create(fn); err != nil { + t.Fatal(err) + } else { + f.Close() + } + buf := make([]byte, 100) + content := []byte("1234567890") + threads := 30 + loops := 30 + for i := 0; i < threads; i++ { + // Reader thread + wg.Add(1) + go func() { + fRd, err := os.Open(fn) + if err != nil { + log.Fatal(err) + } + for j := 0; j < loops; j++ { + n, err := fRd.ReadAt(buf, 0) + if err != nil && err != io.EOF { + log.Fatal(err) + } + if n != 0 && n != 10 { + log.Fatalf("strange read length: %d", n) + } + } + fRd.Close() + wg.Done() + }() + + // Writer thread + wg.Add(1) + go func() { + fWr, err := os.OpenFile(fn, os.O_RDWR, 0700) + if err != nil { + log.Fatal(err) + } + for j := 0; j < loops; j++ { + err = fWr.Truncate(0) + if err != nil { + log.Fatal(err) + } + _, err = fWr.WriteAt(content, 0) + if err != nil { + log.Fatal(err) + } + } + fWr.Close() + wg.Done() + }() + } + wg.Wait() +} + // Hint for calculating reference md5sums: // dd if=/dev/zero count=1 bs=XYZ | md5sum func TestTruncate(t *testing.T) {