85 lines
1.9 KiB
Go
85 lines
1.9 KiB
Go
//go:build windows
|
|
|
|
package winpwn
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
// TestNamedPipeServerClient exercises ServePipe/DialPipe end to end: a
|
|
// goroutine plays the server (CreateNamedPipe + ConnectNamedPipe, both
|
|
// overlapped), the test goroutine plays the client (CreateFile), and both
|
|
// sides talk over the resulting *Tube exactly like any other transport.
|
|
func TestNamedPipeServerClient(t *testing.T) {
|
|
pipeName := fmt.Sprintf("winpwn_test_%d", time.Now().UnixNano())
|
|
|
|
serverErr := make(chan error, 1)
|
|
serverMsg := make(chan []byte, 1)
|
|
go func() {
|
|
tube, err := ServePipe(pipeName)
|
|
if err != nil {
|
|
serverErr <- err
|
|
return
|
|
}
|
|
defer tube.Close()
|
|
|
|
got, err := tube.RecvLine()
|
|
if err != nil {
|
|
serverErr <- err
|
|
return
|
|
}
|
|
serverMsg <- got
|
|
|
|
if err := tube.SendLine([]byte("pong")); err != nil {
|
|
serverErr <- err
|
|
return
|
|
}
|
|
serverErr <- nil
|
|
}()
|
|
|
|
// ServePipe's CreateNamedPipe call may not have run yet; retry the
|
|
// dial briefly rather than racing it with a fixed sleep.
|
|
var client *Tube
|
|
var err error
|
|
for i := 0; i < 100; i++ {
|
|
client, err = DialPipe(pipeName)
|
|
if err == nil {
|
|
break
|
|
}
|
|
time.Sleep(20 * time.Millisecond)
|
|
}
|
|
if err != nil {
|
|
t.Fatalf("DialPipe: %v", err)
|
|
}
|
|
defer client.Close()
|
|
|
|
if err := client.SendLine([]byte("ping")); err != nil {
|
|
t.Fatalf("client SendLine: %v", err)
|
|
}
|
|
|
|
select {
|
|
case got := <-serverMsg:
|
|
if string(got) != "ping\n" {
|
|
t.Errorf("server received %q, want %q", got, "ping\n")
|
|
}
|
|
case err := <-serverErr:
|
|
t.Fatalf("server error: %v", err)
|
|
case <-time.After(5 * time.Second):
|
|
t.Fatal("timed out waiting for the server to receive the client's message")
|
|
}
|
|
|
|
got, err := client.RecvLine()
|
|
if err != nil {
|
|
t.Fatalf("client RecvLine: %v", err)
|
|
}
|
|
if string(got) != "pong\n" {
|
|
t.Errorf("client received %q, want %q", got, "pong\n")
|
|
}
|
|
|
|
if err := <-serverErr; err != nil {
|
|
t.Fatalf("server goroutine error: %v", err)
|
|
}
|
|
}
|