mirror of
https://github.com/rwinkhart/go-winio.git
synced 2026-08-31 06:16:46 -04:00
This includes Reader, Writer, and Closer interfaces on top of Windows file handles in a way that does not block the system thread while the IO is outstanding. This also includes net.Listener and net.Conn for named pipes.
149 lines
2.6 KiB
Go
149 lines
2.6 KiB
Go
package winio
|
|
|
|
import (
|
|
"bufio"
|
|
"net"
|
|
"os"
|
|
"syscall"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
var testPipeName = `\\.\pipe\winiotestpipe`
|
|
|
|
func TestDialUnknownFailsImmediately(t *testing.T) {
|
|
_, err := DialPipe(testPipeName, nil)
|
|
if err.(*os.PathError).Err != syscall.ENOENT {
|
|
t.Fatalf("expected ENOENT got %v", err)
|
|
}
|
|
}
|
|
|
|
func TestDialListenerTimesOut(t *testing.T) {
|
|
l, err := ListenPipe(testPipeName, "")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer l.Close()
|
|
var d = time.Duration(10 * time.Millisecond)
|
|
_, err = DialPipe(testPipeName, &d)
|
|
if err != syscall.ETIMEDOUT {
|
|
t.Fatalf("expected ETIMEDOUT, got %v", err)
|
|
}
|
|
}
|
|
|
|
func TestDialAccessDeniedWithRestrictedSD(t *testing.T) {
|
|
l, err := ListenPipe(testPipeName, "D:P(A;;0x1200FF;;;WD)")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer l.Close()
|
|
_, err = DialPipe(testPipeName, nil)
|
|
if err.(*os.PathError).Err != syscall.ERROR_ACCESS_DENIED {
|
|
t.Fatalf("expected EACCES, got %v", err)
|
|
}
|
|
}
|
|
|
|
func getConnection() (client net.Conn, server net.Conn, err error) {
|
|
l, err := ListenPipe(testPipeName, "")
|
|
if err != nil {
|
|
return
|
|
}
|
|
defer l.Close()
|
|
|
|
type response struct {
|
|
c net.Conn
|
|
err error
|
|
}
|
|
ch := make(chan response)
|
|
go func() {
|
|
c, err := l.Accept()
|
|
ch <- response{c, err}
|
|
}()
|
|
|
|
c, err := DialPipe(testPipeName, nil)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
r := <-ch
|
|
if err = r.err; err != nil {
|
|
c.Close()
|
|
return
|
|
}
|
|
|
|
client = c
|
|
server = r.c
|
|
return
|
|
}
|
|
|
|
func TestReadTimeout(t *testing.T) {
|
|
c, s, err := getConnection()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer c.Close()
|
|
defer s.Close()
|
|
|
|
c.SetReadDeadline(time.Now().Add(10 * time.Millisecond))
|
|
|
|
buf := make([]byte, 10)
|
|
_, err = c.Read(buf)
|
|
if err != syscall.ETIMEDOUT {
|
|
t.Fatalf("expected ETIMEDOUT, got %v", err)
|
|
}
|
|
}
|
|
|
|
func server(l net.Listener) {
|
|
c, err := l.Accept()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer c.Close()
|
|
rw := bufio.NewReadWriter(bufio.NewReader(c), bufio.NewWriter(c))
|
|
s, err := rw.ReadString('\n')
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
_, err = rw.WriteString("got " + s)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
err = rw.Flush()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
func TestFullListenDialReadWrite(t *testing.T) {
|
|
l, err := ListenPipe(testPipeName, "")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
go server(l)
|
|
|
|
c, err := DialPipe(testPipeName, nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
rw := bufio.NewReadWriter(bufio.NewReader(c), bufio.NewWriter(c))
|
|
_, err = rw.WriteString("hello world\n")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
err = rw.Flush()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
s, err := rw.ReadString('\n')
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
ms := "got hello world\n"
|
|
if s != ms {
|
|
t.Errorf("expected '%s', got '%s'", ms, s)
|
|
}
|
|
}
|