Skip to content

Commit

Permalink
Add File.ReadFrom test on a SectionReader
Browse files Browse the repository at this point in the history
This tests ReadFrom's determining concurrency from the estimated input
size. go test -cover -integration, before:

coverage: 77.3% of statements

After:

coverage: 79.2% of statements
  • Loading branch information
greatroar committed Dec 19, 2021
1 parent 42e9800 commit 31306ef
Showing 1 changed file with 48 additions and 5 deletions.
53 changes: 48 additions & 5 deletions client_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ func netPipe(t testing.TB) (io.ReadWriteCloser, io.ReadWriteCloser) {
return c1, r.Conn
}

func testClientGoSvr(t testing.TB, readonly bool, delay time.Duration) (*Client, *exec.Cmd) {
func testClientGoSvr(t testing.TB, readonly bool, delay time.Duration, opts ...ClientOption) (*Client, *exec.Cmd) {
c1, c2 := netPipe(t)

options := []ServerOption{WithDebug(os.Stderr)}
Expand All @@ -183,7 +183,7 @@ func testClientGoSvr(t testing.TB, readonly bool, delay time.Duration) (*Client,
wr = newDelayedWriter(wr, delay)
}

client, err := NewClientPipe(c2, wr)
client, err := NewClientPipe(c2, wr, opts...)
if err != nil {
t.Fatal(err)
}
Expand All @@ -194,13 +194,13 @@ func testClientGoSvr(t testing.TB, readonly bool, delay time.Duration) (*Client,

// testClient returns a *Client connected to a locally running sftp-server
// the *exec.Cmd returned must be defer Wait'd.
func testClient(t testing.TB, readonly bool, delay time.Duration) (*Client, *exec.Cmd) {
func testClient(t testing.TB, readonly bool, delay time.Duration, opts ...ClientOption) (*Client, *exec.Cmd) {
if !*testIntegration {
t.Skip("skipping integration test")
}

if *testServerImpl {
return testClientGoSvr(t, readonly, delay)
return testClientGoSvr(t, readonly, delay, opts...)
}

cmd := exec.Command(*testSftp, "-e", "-R", "-l", debuglevel) // log to stderr, read only
Expand Down Expand Up @@ -228,7 +228,7 @@ func testClient(t testing.TB, readonly bool, delay time.Duration) (*Client, *exe
t.Skipf("could not start sftp-server process: %v", err)
}

sftp, err := NewClientPipe(pr, pw)
sftp, err := NewClientPipe(pr, pw, opts...)
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -1489,6 +1489,49 @@ func TestClientReadFrom(t *testing.T) {
}
}

func TestClientReadFromSectionReader(t *testing.T) {
const (
packetSize = 1024
bufsize = 4 * packetSize
skip = 100
filesize = bufsize - skip
)

sftp, cmd := testClient(t, READWRITE, NODELAY, MaxPacketChecked(packetSize), UseConcurrentWrites(true))
defer cmd.Wait()
defer sftp.Close()

d, err := ioutil.TempDir("", "sftptest-readfrom-sectionreader")
if err != nil {
t.Fatal("cannot create temp dir:", err)
}
defer os.RemoveAll(d)

buf := bytes.NewReader(make([]byte, bufsize))
r := io.NewSectionReader(buf, 0, bufsize)

// Skip some bytes so that r.Size is no longer accurate.
// ReadFrom uses it to determine concurrency,
// but should not rely on it to determine how many bytes to send.
r.Seek(skip, io.SeekStart)

f := path.Join(d, "writeTest")
w, err := sftp.Create(f)
if err != nil {
t.Fatal(err)
}
defer w.Close()

n, err := w.ReadFrom(r)
assert.EqualValues(t, filesize, n)

fi, err := os.Stat(f)
if err != nil {
t.Fatal("unexpected error:", err)
}
assert.EqualValues(t, filesize, fi.Size())
}

// Issue #145 in github
// Deadlock in ReadFrom when network drops after 1 good packet.
// Deadlock would occur anytime desiredInFlight-inFlight==2 and 2 errors
Expand Down

0 comments on commit 31306ef

Please sign in to comment.