1
0
mirror of https://github.com/golang/go synced 2024-11-18 10:14:45 -07:00

os: add a test case of copying a file itself via io.Copy

Change-Id: Ib9746cb4f27625cb22620271b280d2da242b2fba
Reviewed-on: https://go-review.googlesource.com/c/go/+/428437
Run-TryBot: Ian Lance Taylor <iant@google.com>
Run-TryBot: Andy Pan <panjf2000@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
This commit is contained in:
Andy Pan 2022-09-06 00:11:54 +08:00 committed by Gopher Robot
parent bca17d16ca
commit 86477e507f

View File

@ -13,6 +13,7 @@ import (
. "os" . "os"
"path/filepath" "path/filepath"
"strconv" "strconv"
"strings"
"syscall" "syscall"
"testing" "testing"
"time" "time"
@ -74,6 +75,56 @@ func TestCopyFileRange(t *testing.T) {
mustSeekStart(t, dst2) mustSeekStart(t, dst2)
mustContainData(t, dst2, data) // through traditional means mustContainData(t, dst2, data) // through traditional means
}) })
t.Run("CopyFileItself", func(t *testing.T) {
hook := hookCopyFileRange(t)
f, err := os.CreateTemp("", "file-readfrom-itself-test")
if err != nil {
t.Fatalf("failed to create tmp file: %v", err)
}
t.Cleanup(func() {
f.Close()
os.Remove(f.Name())
})
data := []byte("hello world!")
if _, err := f.Write(data); err != nil {
t.Fatalf("failed to create and feed the file: %v", err)
}
if err := f.Sync(); err != nil {
t.Fatalf("failed to save the file: %v", err)
}
// Rewind it.
if _, err := f.Seek(0, io.SeekStart); err != nil {
t.Fatalf("failed to rewind the file: %v", err)
}
// Read data from the file itself.
if _, err := io.Copy(f, f); err != nil {
t.Fatalf("failed to read from the file: %v", err)
}
if !hook.called || hook.written != 0 || hook.handled || hook.err != nil {
t.Fatalf("poll.CopyFileRange should be called and return the EINVAL error, but got hook.called=%t, hook.err=%v", hook.called, hook.err)
}
// Rewind it.
if _, err := f.Seek(0, io.SeekStart); err != nil {
t.Fatalf("failed to rewind the file: %v", err)
}
data2, err := io.ReadAll(f)
if err != nil {
t.Fatalf("failed to read from the file: %v", err)
}
// It should wind up a double of the original data.
if strings.Repeat(string(data), 2) != string(data2) {
t.Fatalf("data mismatch: %s != %s", string(data), string(data2))
}
})
t.Run("NotRegular", func(t *testing.T) { t.Run("NotRegular", func(t *testing.T) {
t.Run("BothPipes", func(t *testing.T) { t.Run("BothPipes", func(t *testing.T) {
hook := hookCopyFileRange(t) hook := hookCopyFileRange(t)
@ -344,6 +395,10 @@ type copyFileRangeHook struct {
srcfd int srcfd int
remain int64 remain int64
written int64
handled bool
err error
original func(dst, src *poll.FD, remain int64) (int64, bool, error) original func(dst, src *poll.FD, remain int64) (int64, bool, error)
} }
@ -354,7 +409,8 @@ func (h *copyFileRangeHook) install() {
h.dstfd = dst.Sysfd h.dstfd = dst.Sysfd
h.srcfd = src.Sysfd h.srcfd = src.Sysfd
h.remain = remain h.remain = remain
return h.original(dst, src, remain) h.written, h.handled, h.err = h.original(dst, src, remain)
return h.written, h.handled, h.err
} }
} }