From 6fed9dd0dd62718f78eca11e30a71c2712636fbd Mon Sep 17 00:00:00 2001 From: Mikhail Osipov Date: Wed, 16 Dec 2020 15:27:48 +0300 Subject: hook and socket args check fix, tests --- pkg/test/auth_test.go | 36 ++++++++++++++ pkg/test/env_test.go | 15 ++---- pkg/test/hook_test.go | 59 ++++++++++++++++++++++ pkg/test/proxy_test.go | 36 ++++++++++++++ pkg/test/test.go | 132 ++++++++++++++++++++++++++++++++++++++++++++++--- 5 files changed, 258 insertions(+), 20 deletions(-) create mode 100644 pkg/test/auth_test.go create mode 100644 pkg/test/hook_test.go create mode 100644 pkg/test/proxy_test.go (limited to 'pkg/test') diff --git a/pkg/test/auth_test.go b/pkg/test/auth_test.go new file mode 100644 index 0000000..cf5f28b --- /dev/null +++ b/pkg/test/auth_test.go @@ -0,0 +1,36 @@ +package test + +import ( + "testing" +) + +func TestAuthHook(t *testing.T) { + const msg = "Hello, World!" + + c, s := newClientServer(t) + defer closeClientServer(c, s) + + listen := xListen(t, "tcp", "127.0.0.1:0") + defer listen.Close() + + xaddr := c.AddListenTunnel("X", "-aes -auth dial,addr=%s", listen.Addr()) + taddr := c.AddListenTunnel("T", "auth aes dial,addr=%s", xaddr) + + c.Exec("set tunnel.X.secret secret") + c.Exec("set tunnel.T.secret secret") + + out := xDial(t, "tcp", taddr) + defer out.Close() + + in := xAccept(t, listen) + defer in.Close() + + xWrite(t, out, msg) + + buf := make([]byte, len(msg)) + xReadFull(t, in, buf) + + if r := string(buf); r != msg { + t.Fatalf("wrong reply: send '%s', recv '%s'", msg, r) + } +} diff --git a/pkg/test/env_test.go b/pkg/test/env_test.go index b03a5c5..5d6f03e 100644 --- a/pkg/test/env_test.go +++ b/pkg/test/env_test.go @@ -7,19 +7,10 @@ import ( func TestEnv(t *testing.T) { const msg = "Hello, World!" - c, s, err := newClientServer() - if err != nil { - t.Fatal(err) - } - - defer s.Stop() - defer c.Close() - - r, err := c.Send([]string{"echo", msg}) - if err != nil { - t.Fatal(err) - } + c, s := newClientServer(t) + defer closeClientServer(c, s) + r := c.Send("echo %s", msg) if r != msg { t.Errorf("wrong reply: send '%s', recv '%s'", msg, r) } diff --git a/pkg/test/hook_test.go b/pkg/test/hook_test.go new file mode 100644 index 0000000..06204bb --- /dev/null +++ b/pkg/test/hook_test.go @@ -0,0 +1,59 @@ +package test + +import ( + "testing" + + "encoding/hex" + "strings" +) + +func TestUpperHook(t *testing.T) { + const msg = "Hello, World!" + + c, s := newClientServer(t) + defer closeClientServer(c, s) + + tunnel := "add name %s listen,addr=127.0.0.1:0 upper loop" + c.Exec(tunnel, t.Name()) + + addr := c.Send("get tunnel.%s.listen", t.Name()) + + conn := xDial(t, "tcp", addr) + defer conn.Close() + + xWrite(t, conn, msg) + + buf := make([]byte, len(msg)) + xReadFull(t, conn, buf) + + if r := string(buf); r != strings.ToUpper(msg) { + t.Fatalf("wrong reply: send '%s', recv '%s'", msg, r) + } +} + +func TestHexHook(t *testing.T) { + const msg = "Hello, World!" + + c, s := newClientServer(t) + defer closeClientServer(c, s) + + listen := xListen(t, "tcp", "127.0.0.1:0") + defer listen.Close() + + addr := c.AddListenTunnel(t.Name(), "hex dial,addr=%s", listen.Addr()) + + out := xDial(t, "tcp", addr) + defer out.Close() + + in := xAccept(t, listen) + defer in.Close() + + xWrite(t, out, msg) + + buf := make([]byte, 2*len(msg)) + xReadFull(t, in, buf) + + if r := string(buf); r != hex.EncodeToString([]byte(msg)) { + t.Fatalf("wrong reply: send '%s', recv '%s'", msg, r) + } +} diff --git a/pkg/test/proxy_test.go b/pkg/test/proxy_test.go new file mode 100644 index 0000000..b2fb097 --- /dev/null +++ b/pkg/test/proxy_test.go @@ -0,0 +1,36 @@ +package test + +import ( + "testing" +) + +func TestProxyHook(t *testing.T) { + const msg = "Hello, World!" + + c, s := newClientServer(t) + defer closeClientServer(c, s) + + listen := xListen(t, "tcp", "127.0.0.1:0") + defer listen.Close() + + saddr := c.AddListenTunnel("S", "proxy") + caddr := c.AddListenTunnel("C", "proxy,addr=%s dial,addr=%s", listen.Addr(), saddr) + + c.Exec("set tunnel.S.proxy.auth user:password") + c.Exec("set tunnel.C.proxy.auth user:password") + + out := xDial(t, "tcp", caddr) + defer out.Close() + + in := xAccept(t, listen) + defer in.Close() + + xWrite(t, out, msg) + + buf := make([]byte, len(msg)) + xReadFull(t, in, buf) + + if r := string(buf); r != msg { + t.Fatalf("wrong reply: send '%s', recv '%s'", msg, r) + } +} diff --git a/pkg/test/test.go b/pkg/test/test.go index 6a2c776..89722fd 100644 --- a/pkg/test/test.go +++ b/pkg/test/test.go @@ -1,25 +1,44 @@ package test import ( + "fmt" + "io" + "net" "os" "path/filepath" - "strconv" + "strings" + "testing" + "time" "tunnel/pkg/client" "tunnel/pkg/server" ) -func getSocketPath() string { - s := "tunnel.test." + strconv.Itoa(os.Getpid()) +type env struct { + *testing.T +} + +func getSocketPath(id string) string { + s := fmt.Sprintf("tunnel.%d.test.%s", os.Getpid(), id) return filepath.Join(os.TempDir(), s) } -func newClientServer() (*client.Client, *server.Server, error) { - socket := getSocketPath() +type Client struct { + *client.Client + + t *testing.T +} + +type Server struct { + *server.Server +} + +func newClientServer(t *testing.T) (*Client, *Server) { + socket := getSocketPath(t.Name()) s, err := server.New(socket) if err != nil { - return nil, nil, err + t.Fatal(err) } go s.Serve() @@ -27,8 +46,105 @@ func newClientServer() (*client.Client, *server.Server, error) { c, err := client.New(socket) if err != nil { s.Stop() - return nil, nil, err + t.Fatal(err) + } + + return &Client{c, t}, &Server{s} +} + +func closeClientServer(c *Client, s *Server) { + c.Close() + s.Stop() +} + +func (c *Client) Send(format string, args ...interface{}) string { + s := fmt.Sprintf(format, args...) + t := strings.Split(s, " ") + + r, err := c.Client.Send(t) + if err != nil { + c.t.Fatal(err) } - return c, s, nil + return r +} + +func (c *Client) Exec(format string, args ...interface{}) { + s := c.Send(format, args...) + if s != "" { + c.t.Fatal(s) + } +} + +func (c *Client) AddListenTunnel(name string, format string, args ...interface{}) string { + t := append([]interface{}{name}, args...) + c.Exec("add name %s listen,addr=127.0.0.1:0 "+format, t...) + return c.Send("get tunnel.%s.listen", name) +} + +func xListen(t *testing.T, network, address string) net.Listener { + listen, err := net.Listen(network, address) + if err != nil { + t.Fatal(err) + } + return listen +} + +func xDial(t *testing.T, network, address string) net.Conn { + d := net.Dialer{Timeout: 100 * time.Millisecond} + conn, err := d.Dial(network, address) + if err != nil { + t.Fatal(err) + } + return conn +} + +func xAccept(t *testing.T, listen net.Listener) net.Conn { + var conn net.Conn + + c := make(chan error, 1) + go func() { + var err error + conn, err = listen.Accept() + c <- err + }() + + timer := time.NewTimer(100 * time.Millisecond) + select { + case err := <-c: + if err != nil { + t.Fatal(err) + } + case <-timer.C: + t.Fatal("accept timeout") + } + + return conn +} + +func xWrite(t *testing.T, conn net.Conn, i interface{}) { + var buf []byte + + switch v := i.(type) { + case string: + buf = []byte(v) + case []byte: + buf = v + default: + t.Fatalf("unexpected type %T", i) + } + + conn.SetDeadline(time.Now().Add(100 * time.Millisecond)) + if _, err := conn.Write(buf); err != nil { + t.Fatal("write to conn:", err) + } + conn.SetDeadline(time.Time{}) +} + +func xReadFull(t *testing.T, conn net.Conn, buf []byte) { + conn.SetDeadline(time.Now().Add(100 * time.Millisecond)) + if _, err := io.ReadFull(conn, buf); err != nil { + t.Fatal("read from conn:", err) + } + conn.SetDeadline(time.Time{}) } -- cgit v1.2.3-70-g09d2