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.
diff --git a/client_integration_darwin_test.go b/client_integration_darwin_test.go
index 6c72536..740ef41 100644
--- a/client_integration_darwin_test.go
+++ b/client_integration_darwin_test.go
@@ -5,8 +5,6 @@
 	"testing"
 )
 
-const sftpServer = "/usr/libexec/sftp-server"
-
 func TestClientStatVFS(t *testing.T) {
 	if *testServerImpl {
 		t.Skipf("go server does not support FXP_EXTENDED")
diff --git a/client_integration_linux_test.go b/client_integration_linux_test.go
index 1517998..0f63189 100644
--- a/client_integration_linux_test.go
+++ b/client_integration_linux_test.go
@@ -5,8 +5,6 @@
 	"testing"
 )
 
-const sftpServer = "/usr/lib/openssh/sftp-server"
-
 func TestClientStatVFS(t *testing.T) {
 	if *testServerImpl {
 		t.Skipf("go server does not support FXP_EXTENDED")
diff --git a/client_integration_test.go b/client_integration_test.go
index 08ee770..761a71b 100644
--- a/client_integration_test.go
+++ b/client_integration_test.go
@@ -8,7 +8,6 @@
 	"crypto/sha1"
 	"encoding"
 	"errors"
-	"flag"
 	"io"
 	"io/ioutil"
 	"math/rand"
@@ -20,13 +19,12 @@
 	"path/filepath"
 	"reflect"
 	"regexp"
+	"sort"
 	"strconv"
 	"testing"
 	"testing/quick"
 	"time"
 
-	"sort"
-
 	"github.com/kr/fs"
 )
 
@@ -38,10 +36,6 @@
 	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 @@
 	if err != nil {
 		t.Fatal(err)
 	}
+	f.Close()
 	defer os.Remove(f.Name())
 
 	want, err := os.Lstat(f.Name())
@@ -236,6 +231,7 @@
 	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 @@
 	if err != nil {
 		t.Fatal(err)
 	}
+	f.Close()
 	defer os.Remove(f.Name())
 
 	got, err := sftp.Open(f.Name())
@@ -517,6 +514,8 @@
 }
 
 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 @@
 	if err != nil {
 		t.Fatal(err)
 	}
+	f.Close()
+
 	if err := sftp.Remove(f.Name()); err != nil {
 		t.Fatal(err)
 	}
@@ -636,6 +637,8 @@
 	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 @@
 	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 @@
 	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 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 @@
 	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 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 @@
 	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 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 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 @@
 	defer sftp1.Close()
 	defer sftp2.Close()
 
-	dir := "/dev/"
+	dir := os.TempDir()
 
 	d, err := os.Open(dir)
 	if err != nil {
@@ -1127,17 +1142,13 @@
 // 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 @@
 
 // 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 @@
 // 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 @@
 
 // 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 @@
 
 // sftp/issue/234 - also affected Write
 func TestServerRoughDisconnect4(t *testing.T) {
+	skipIfWindows(t)
 	if *testServerImpl {
 		t.Skipf("skipping with -testserver")
 	}
@@ -1846,6 +1861,7 @@
 
 // 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 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 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 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 {
diff --git a/examples/sftp-server/README.md b/examples/go-sftp-server/README.md
similarity index 100%
rename from examples/sftp-server/README.md
rename to examples/go-sftp-server/README.md
diff --git a/examples/sftp-server/main.go b/examples/go-sftp-server/main.go
similarity index 100%
rename from examples/sftp-server/main.go
rename to examples/go-sftp-server/main.go
diff --git a/other_test.go b/other_test.go
deleted file mode 100644
index 1b84ccf..0000000
--- a/other_test.go
+++ /dev/null
@@ -1,5 +0,0 @@
-// +build !linux,!darwin
-
-package sftp
-
-const sftpServer = "/usr/bin/false" // unsupported
diff --git a/request-server_test.go b/request-server_test.go
index af68148..2f11789 100644
--- a/request-server_test.go
+++ b/request-server_test.go
@@ -32,6 +32,7 @@
 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
diff --git a/server_integration_test.go b/server_integration_test.go
index 7123695..f9ecaba 100644
--- a/server_integration_test.go
+++ b/server_integration_test.go
@@ -22,6 +22,7 @@
 	"path"
 	"path/filepath"
 	"regexp"
+	"runtime"
 	"strconv"
 	"strings"
 	"testing"
@@ -31,7 +32,40 @@
 	"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 @@
 	}
 	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 TestServerSymlink(t *testing.T) {
+	skipIfWindows(t) // No symlinks on windows.
 	listenerGo, hostGo, portGo := testServer(t, GOLANG_SFTP, READONLY)
 	defer listenerGo.Close()
 
diff --git a/server_test.go b/server_test.go
index 5568347..37d2642 100644
--- a/server_test.go
+++ b/server_test.go
@@ -226,6 +226,7 @@
 
 // test that server handles concurrent requests correctly
 func TestConcurrentRequests(t *testing.T) {
+	skipIfWindows(t)
 	client, server := clientServerPair(t)
 	defer client.Close()
 	defer server.Close()