mirror of https://github.com/pkg/sftp.git
sftp: update tests to finish and not panic on windows
Many Unix assuptions have been made when testing. Previously running tests on windows threw a panic part way through the tests. After these changes many more tests pass when the fix was isolated to the test itself, and none panic. Some tests are skipped because they do make sense on windows (chmod, chown), while others are skipped just to how the test was implemented. Lastly, some of the external executables were hard coded. Change these to look paths in TestMain first. This is done to better support windows, where openssh may be installed and sftp and sftp-server may both be in the PATH.
This commit is contained in:
parent
08de04f133
commit
d8ec5de5ee
|
@ -5,8 +5,6 @@ import (
|
|||
"testing"
|
||||
)
|
||||
|
||||
const sftpServer = "/usr/libexec/sftp-server"
|
||||
|
||||
func TestClientStatVFS(t *testing.T) {
|
||||
if *testServerImpl {
|
||||
t.Skipf("go server does not support FXP_EXTENDED")
|
||||
|
|
|
@ -5,8 +5,6 @@ import (
|
|||
"testing"
|
||||
)
|
||||
|
||||
const sftpServer = "/usr/lib/openssh/sftp-server"
|
||||
|
||||
func TestClientStatVFS(t *testing.T) {
|
||||
if *testServerImpl {
|
||||
t.Skipf("go server does not support FXP_EXTENDED")
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
"crypto/sha1"
|
||||
"encoding"
|
||||
"errors"
|
||||
"flag"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
|
@ -20,13 +19,12 @@ import (
|
|||
"path/filepath"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"testing"
|
||||
"testing/quick"
|
||||
"time"
|
||||
|
||||
"sort"
|
||||
|
||||
"github.com/kr/fs"
|
||||
)
|
||||
|
||||
|
@ -38,10 +36,6 @@ const (
|
|||
debuglevel = "ERROR" // set to "DEBUG" for debugging
|
||||
)
|
||||
|
||||
var testServerImpl = flag.Bool("testserver", false, "perform integration tests against sftp package server instance")
|
||||
var testIntegration = flag.Bool("integration", false, "perform integration tests against sftp server process")
|
||||
var testSftp = flag.String("sftp", sftpServer, "location of the sftp server binary")
|
||||
|
||||
type delayedWrite struct {
|
||||
t time.Time
|
||||
b []byte
|
||||
|
@ -210,6 +204,7 @@ func TestClientLstat(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
f.Close()
|
||||
defer os.Remove(f.Name())
|
||||
|
||||
want, err := os.Lstat(f.Name())
|
||||
|
@ -236,6 +231,7 @@ func TestClientLstatIsNotExist(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
f.Close()
|
||||
os.Remove(f.Name())
|
||||
|
||||
if _, err := sftp.Lstat(f.Name()); !os.IsNotExist(err) {
|
||||
|
@ -291,6 +287,7 @@ func TestClientOpen(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
f.Close()
|
||||
defer os.Remove(f.Name())
|
||||
|
||||
got, err := sftp.Open(f.Name())
|
||||
|
@ -517,6 +514,8 @@ func TestClientFileStat(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestClientStatLink(t *testing.T) {
|
||||
skipIfWindows(t) // Windows does not support links.
|
||||
|
||||
sftp, cmd := testClient(t, READONLY, NO_DELAY)
|
||||
defer cmd.Wait()
|
||||
defer sftp.Close()
|
||||
|
@ -585,6 +584,8 @@ func TestClientRemove(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
f.Close()
|
||||
|
||||
if err := sftp.Remove(f.Name()); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -636,6 +637,8 @@ func TestClientRename(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
f.Close()
|
||||
|
||||
f2 := f.Name() + ".new"
|
||||
if err := sftp.Rename(f.Name(), f2); err != nil {
|
||||
t.Fatal(err)
|
||||
|
@ -657,6 +660,8 @@ func TestClientPosixRename(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
f.Close()
|
||||
|
||||
f2 := f.Name() + ".new"
|
||||
if err := sftp.PosixRename(f.Name(), f2); err != nil {
|
||||
t.Fatal(err)
|
||||
|
@ -682,10 +687,10 @@ func TestClientGetwd(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !path.IsAbs(rwd) {
|
||||
if !filepath.IsAbs(rwd) {
|
||||
t.Fatalf("Getwd: wanted absolute path, got %q", rwd)
|
||||
}
|
||||
if lwd != rwd {
|
||||
if filepath.ToSlash(lwd) != filepath.ToSlash(rwd) {
|
||||
t.Fatalf("Getwd: want %q, got %q", lwd, rwd)
|
||||
}
|
||||
}
|
||||
|
@ -731,6 +736,7 @@ func TestClientSymlink(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestClientChmod(t *testing.T) {
|
||||
skipIfWindows(t) // No UNIX permissions.
|
||||
sftp, cmd := testClient(t, READWRITE, NO_DELAY)
|
||||
defer cmd.Wait()
|
||||
defer sftp.Close()
|
||||
|
@ -739,6 +745,8 @@ func TestClientChmod(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
f.Close()
|
||||
|
||||
if err := sftp.Chmod(f.Name(), 0531); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -750,6 +758,7 @@ func TestClientChmod(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestClientChmodReadonly(t *testing.T) {
|
||||
skipIfWindows(t) // No UNIX permissions.
|
||||
sftp, cmd := testClient(t, READONLY, NO_DELAY)
|
||||
defer cmd.Wait()
|
||||
defer sftp.Close()
|
||||
|
@ -758,12 +767,15 @@ func TestClientChmodReadonly(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
f.Close()
|
||||
|
||||
if err := sftp.Chmod(f.Name(), 0531); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestClientChown(t *testing.T) {
|
||||
skipIfWindows(t) // No UNIX permissions.
|
||||
sftp, cmd := testClient(t, READWRITE, NO_DELAY)
|
||||
defer cmd.Wait()
|
||||
defer sftp.Close()
|
||||
|
@ -821,6 +833,7 @@ func TestClientChown(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestClientChownReadonly(t *testing.T) {
|
||||
skipIfWindows(t) // No UNIX permissions.
|
||||
sftp, cmd := testClient(t, READONLY, NO_DELAY)
|
||||
defer cmd.Wait()
|
||||
defer sftp.Close()
|
||||
|
@ -948,7 +961,9 @@ func TestClientTruncateReadonly(t *testing.T) {
|
|||
}
|
||||
|
||||
func sameFile(want, got os.FileInfo) bool {
|
||||
return want.Name() == got.Name() &&
|
||||
_, wantName := filepath.Split(want.Name())
|
||||
_, gotName := filepath.Split(got.Name())
|
||||
return wantName == gotName &&
|
||||
want.Size() == got.Size()
|
||||
}
|
||||
|
||||
|
@ -997,7 +1012,7 @@ func TestClientReadDir(t *testing.T) {
|
|||
defer sftp1.Close()
|
||||
defer sftp2.Close()
|
||||
|
||||
dir := "/dev/"
|
||||
dir := os.TempDir()
|
||||
|
||||
d, err := os.Open(dir)
|
||||
if err != nil {
|
||||
|
@ -1127,17 +1142,13 @@ func readHash(t *testing.T, r io.Reader) (string, int64) {
|
|||
// writeN writes n bytes of random data to w and returns the
|
||||
// hash of that data.
|
||||
func writeN(t *testing.T, w io.Writer, n int64) string {
|
||||
rand, err := os.Open("/dev/urandom")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer rand.Close()
|
||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
|
||||
h := sha1.New()
|
||||
|
||||
mw := io.MultiWriter(w, h)
|
||||
|
||||
written, err := io.CopyN(mw, rand, n)
|
||||
written, err := io.CopyN(mw, r, n)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -1733,6 +1744,7 @@ func TestGlobUNC(t *testing.T) {
|
|||
|
||||
// sftp/issue/42, abrupt server hangup would result in client hangs.
|
||||
func TestServerRoughDisconnect(t *testing.T) {
|
||||
skipIfWindows(t)
|
||||
if *testServerImpl {
|
||||
t.Skipf("skipping with -testserver")
|
||||
}
|
||||
|
@ -1757,6 +1769,7 @@ func TestServerRoughDisconnect(t *testing.T) {
|
|||
// due to broadcastErr filling up the request channel
|
||||
// this reproduces it about 50% of the time
|
||||
func TestServerRoughDisconnect2(t *testing.T) {
|
||||
skipIfWindows(t)
|
||||
if *testServerImpl {
|
||||
t.Skipf("skipping with -testserver")
|
||||
}
|
||||
|
@ -1784,6 +1797,7 @@ func TestServerRoughDisconnect2(t *testing.T) {
|
|||
|
||||
// sftp/issue/234 - abrupt shutdown during ReadFrom hangs client
|
||||
func TestServerRoughDisconnect3(t *testing.T) {
|
||||
skipIfWindows(t)
|
||||
if *testServerImpl {
|
||||
t.Skipf("skipping with -testserver")
|
||||
}
|
||||
|
@ -1811,6 +1825,7 @@ func TestServerRoughDisconnect3(t *testing.T) {
|
|||
|
||||
// sftp/issue/234 - also affected Write
|
||||
func TestServerRoughDisconnect4(t *testing.T) {
|
||||
skipIfWindows(t)
|
||||
if *testServerImpl {
|
||||
t.Skipf("skipping with -testserver")
|
||||
}
|
||||
|
@ -1846,6 +1861,7 @@ func TestServerRoughDisconnect4(t *testing.T) {
|
|||
|
||||
// sftp/issue/26 writing to a read only file caused client to loop.
|
||||
func TestClientWriteToROFile(t *testing.T) {
|
||||
skipIfWindows(t)
|
||||
sftp, cmd := testClient(t, READWRITE, NO_DELAY)
|
||||
defer cmd.Wait()
|
||||
defer sftp.Close()
|
||||
|
@ -1862,6 +1878,7 @@ func TestClientWriteToROFile(t *testing.T) {
|
|||
}
|
||||
|
||||
func benchmarkRead(b *testing.B, bufsize int, delay time.Duration) {
|
||||
skipIfWindows(b)
|
||||
size := 10*1024*1024 + 123 // ~10MiB
|
||||
|
||||
// open sftp client
|
||||
|
@ -2118,6 +2135,7 @@ func BenchmarkReadFrom4MiBDelay150Msec(b *testing.B) {
|
|||
}
|
||||
|
||||
func benchmarkCopyDown(b *testing.B, fileSize int64, delay time.Duration) {
|
||||
skipIfWindows(b)
|
||||
// Create a temp file and fill it with zero's.
|
||||
src, err := ioutil.TempFile("", "sftptest")
|
||||
if err != nil {
|
||||
|
@ -2191,6 +2209,7 @@ func BenchmarkCopyDown10MiBDelay150Msec(b *testing.B) {
|
|||
}
|
||||
|
||||
func benchmarkCopyUp(b *testing.B, fileSize int64, delay time.Duration) {
|
||||
skipIfWindows(b)
|
||||
// Create a temp file and fill it with zero's.
|
||||
src, err := ioutil.TempFile("", "sftptest")
|
||||
if err != nil {
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
// +build !linux,!darwin
|
||||
|
||||
package sftp
|
||||
|
||||
const sftpServer = "/usr/bin/false" // unsupported
|
|
@ -32,6 +32,7 @@ func (cs csPair) testHandler() *root {
|
|||
const sock = "/tmp/rstest.sock"
|
||||
|
||||
func clientRequestServerPair(t *testing.T) *csPair {
|
||||
skipIfWindows(t)
|
||||
ready := make(chan bool)
|
||||
os.Remove(sock) // either this or signal handling
|
||||
var server *RequestServer
|
||||
|
|
|
@ -22,6 +22,7 @@ import (
|
|||
"path"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
@ -31,7 +32,40 @@ import (
|
|||
"golang.org/x/crypto/ssh"
|
||||
)
|
||||
|
||||
var testSftpClientBin = flag.String("sftp_client", "/usr/bin/sftp", "location of the sftp client binary")
|
||||
func TestMain(m *testing.M) {
|
||||
sftpClientLocation, _ := exec.LookPath("sftp")
|
||||
testSftpClientBin = flag.String("sftp_client", sftpClientLocation, "location of the sftp client binary")
|
||||
flag.Parse()
|
||||
|
||||
lookSFTPServer := []string{
|
||||
"/usr/libexec/sftp-server",
|
||||
"/usr/lib/openssh/sftp-server",
|
||||
}
|
||||
sftpServer, _ := exec.LookPath("sftp-server")
|
||||
if len(sftpServer) == 0 {
|
||||
for _, location := range lookSFTPServer {
|
||||
if _, err := os.Stat(location); err == nil {
|
||||
sftpServer = location
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
testSftp = flag.String("sftp", sftpServer, "location of the sftp server binary")
|
||||
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
func skipIfWindows(t testing.TB) {
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("skipping test on windows")
|
||||
}
|
||||
}
|
||||
|
||||
var testServerImpl = flag.Bool("testserver", false, "perform integration tests against sftp package server instance")
|
||||
var testIntegration = flag.Bool("integration", false, "perform integration tests against sftp server process")
|
||||
var testSftp *string
|
||||
|
||||
var testSftpClientBin *string
|
||||
var sshServerDebugStream = ioutil.Discard
|
||||
var sftpServerDebugStream = ioutil.Discard
|
||||
var sftpClientDebugStream = ioutil.Discard
|
||||
|
@ -419,13 +453,17 @@ func runSftpClient(t *testing.T, script string, path string, host string, port i
|
|||
}
|
||||
cmd := exec.Command(*testSftpClientBin, args...)
|
||||
var stdout bytes.Buffer
|
||||
var stderr bytes.Buffer
|
||||
cmd.Stdin = bytes.NewBufferString(script)
|
||||
cmd.Stdout = &stdout
|
||||
cmd.Stderr = sftpClientDebugStream
|
||||
cmd.Stderr = &stderr
|
||||
if err := cmd.Start(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
err = cmd.Wait()
|
||||
if err != nil {
|
||||
err = fmt.Errorf("%v: %s", err, stderr.String())
|
||||
}
|
||||
return stdout.String(), err
|
||||
}
|
||||
|
||||
|
@ -532,6 +570,7 @@ func TestServerMkdirRmdir(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestServerSymlink(t *testing.T) {
|
||||
skipIfWindows(t) // No symlinks on windows.
|
||||
listenerGo, hostGo, portGo := testServer(t, GOLANG_SFTP, READONLY)
|
||||
defer listenerGo.Close()
|
||||
|
||||
|
|
|
@ -226,6 +226,7 @@ func TestInvalidExtendedPacket(t *testing.T) {
|
|||
|
||||
// test that server handles concurrent requests correctly
|
||||
func TestConcurrentRequests(t *testing.T) {
|
||||
skipIfWindows(t)
|
||||
client, server := clientServerPair(t)
|
||||
defer client.Close()
|
||||
defer server.Close()
|
||||
|
|
Loading…
Reference in New Issue