command/server: tcp listener

This commit is contained in:
Mitchell Hashimoto 2015-03-13 09:37:32 -07:00
parent 9d5db1286d
commit 61224ce312
4 changed files with 110 additions and 0 deletions

View File

@ -0,0 +1,25 @@
package server
import (
"fmt"
"net"
)
// ListenerFactory is the factory function to create a listener.
type ListenerFactory func(map[string]string) (net.Listener, error)
// BuiltinListeners is the list of built-in listener types.
var BuiltinListeners = map[string]ListenerFactory{
"tcp": tcpListenerFactory,
}
// NewListener creates a new listener of the given type with the given
// configuration. The type is looked up in the BuiltinListeners map.
func NewListener(t string, config map[string]string) (net.Listener, error) {
f, ok := BuiltinListeners[t]
if !ok {
return nil, fmt.Errorf("unknown listener type: %s", t)
}
return f(config)
}

View File

@ -0,0 +1,20 @@
package server
import (
"fmt"
"net"
)
func tcpListenerFactory(config map[string]string) (net.Listener, error) {
addr, ok := config["address"]
if !ok {
return nil, fmt.Errorf("'address' must be set")
}
ln, err := net.Listen("tcp", addr)
if err != nil {
return nil, err
}
return ln, nil
}

View File

@ -0,0 +1,21 @@
package server
import (
"net"
"testing"
)
func TestTCPListener(t *testing.T) {
ln, err := tcpListenerFactory(map[string]string{
"address": "127.0.0.1:0",
})
if err != nil {
t.Fatalf("err: %s", err)
}
connFn := func(lnReal net.Listener) (net.Conn, error) {
return net.Dial("tcp", ln.Addr().String())
}
testListenerImpl(t, ln, connFn)
}

View File

@ -0,0 +1,44 @@
package server
import (
"bytes"
"io"
"net"
"testing"
"time"
)
type testListenerConnFn func(net.Listener) (net.Conn, error)
func testListenerImpl(t *testing.T, ln net.Listener, connFn testListenerConnFn) {
serverCh := make(chan net.Conn, 1)
go func() {
server, err := ln.Accept()
if err != nil {
t.Fatalf("err: %s", err)
}
serverCh <- server
}()
client, err := connFn(ln)
if err != nil {
t.Fatalf("err: %s", err)
}
server := <-serverCh
defer client.Close()
defer server.Close()
var buf bytes.Buffer
go io.Copy(&buf, server)
if _, err := client.Write([]byte("foo")); err != nil {
t.Fatalf("err: %s", err)
}
time.Sleep(100 * time.Millisecond)
if buf.String() != "foo" {
t.Fatalf("bad: %v", buf.String())
}
}