taildrop: fix TestResume (#9874)

Previously, the test simply relied on:
	defer close()
to cleanup file handles.

This works fine on Unix-based systems,
but not on Windows, which dislikes deleting files
where an open file handle continues to exist.

Fix the test by explicitly closing the file handle
after we are done with the resource.

Updates tailscale/corp#14772

Signed-off-by: Joe Tsai <joetsai@digital-static.net>
This commit is contained in:
Joe Tsai 2023-10-18 18:07:30 -07:00 committed by GitHub
parent cf27761265
commit d603d18956
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -15,7 +15,6 @@
) )
func TestResume(t *testing.T) { func TestResume(t *testing.T) {
t.Skip("currently failing on Windows")
oldBlockSize := blockSize oldBlockSize := blockSize
defer func() { blockSize = oldBlockSize }() defer func() { blockSize = oldBlockSize }()
blockSize = 256 blockSize = 256
@ -29,11 +28,14 @@ func TestResume(t *testing.T) {
t.Run("resume-noexist", func(t *testing.T) { t.Run("resume-noexist", func(t *testing.T) {
r := io.Reader(bytes.NewReader(want)) r := io.Reader(bytes.NewReader(want))
next, close, err := m.HashPartialFile("", "foo") next, close, err := m.HashPartialFile("", "foo")
must.Do(err) must.Do(err)
defer close() defer close()
offset, r, err := ResumeReader(r, next) offset, r, err := ResumeReader(r, next)
must.Do(err) must.Do(err)
must.Do(close()) // Windows wants the file handle to be closed to rename it.
must.Get(m.PutFile("", "foo", r, offset, -1)) must.Get(m.PutFile("", "foo", r, offset, -1))
got := must.Get(os.ReadFile(must.Get(joinDir(m.opts.Dir, "foo")))) got := must.Get(os.ReadFile(must.Get(joinDir(m.opts.Dir, "foo"))))
if !bytes.Equal(got, want) { if !bytes.Equal(got, want) {
@ -43,25 +45,30 @@ func TestResume(t *testing.T) {
t.Run("resume-retry", func(t *testing.T) { t.Run("resume-retry", func(t *testing.T) {
rn := rand.New(rand.NewSource(0)) rn := rand.New(rand.NewSource(0))
for { for i := 0; true; i++ {
r := io.Reader(bytes.NewReader(want)) r := io.Reader(bytes.NewReader(want))
next, close, err := m.HashPartialFile("", "foo")
next, close, err := m.HashPartialFile("", "bar")
must.Do(err) must.Do(err)
defer close() defer close()
offset, r, err := ResumeReader(r, next) offset, r, err := ResumeReader(r, next)
must.Do(err) must.Do(err)
must.Do(close()) // Windows wants the file handle to be closed to rename it.
numWant := rn.Int63n(min(int64(len(want))-offset, 1000) + 1) numWant := rn.Int63n(min(int64(len(want))-offset, 1000) + 1)
if offset < int64(len(want)) { if offset < int64(len(want)) {
r = io.MultiReader(io.LimitReader(r, numWant), iotest.ErrReader(io.ErrClosedPipe)) r = io.MultiReader(io.LimitReader(r, numWant), iotest.ErrReader(io.ErrClosedPipe))
} }
if _, err := m.PutFile("", "foo", r, offset, -1); err == nil { if _, err := m.PutFile("", "bar", r, offset, -1); err == nil {
break break
} }
if i > 1000 {
t.Fatalf("too many iterations to complete the test")
}
} }
got := must.Get(os.ReadFile(must.Get(joinDir(m.opts.Dir, "foo")))) got := must.Get(os.ReadFile(must.Get(joinDir(m.opts.Dir, "bar"))))
if !bytes.Equal(got, want) { if !bytes.Equal(got, want) {
t.Errorf("content mismatches") t.Errorf("content mismatches")
} }
}) })
} }