func TestWebsockMux(t *testing.T) { sockReq, _ := req.NewSocket() sockRep, _ := rep.NewSocket() tran := NewTransport() l, e := tran.NewListener("ws://127.0.0.1:3336/mysock", sockReq) if e != nil { t.Errorf("Failed new Listener: %v", e) return } muxi, e := l.GetOption(OptionWebSocketMux) if e != nil { t.Errorf("Failed get mux: %v", e) } mux := muxi.(*http.ServeMux) mux.HandleFunc("/bogus", bogusHandler) d, e := tran.NewDialer("ws://127.0.0.1:3336/bogus", sockRep) if e != nil { t.Errorf("Failed new Dialer: %v", e) return } if e = l.Listen(); e != nil { t.Errorf("Listen failed") return } defer l.Close() p, e := d.Dial() if p != nil { defer p.Close() } if e == nil { t.Errorf("Dial passed, when should not have!") return } t.Logf("Got expected error %v", e) // Now let's try to use http client. resp, err := http.Get("http://127.0.0.1:3336/bogus") if err != nil { t.Errorf("Get of boguspath failed: %v", err) return } if resp.StatusCode != 200 { t.Errorf("Response code wrong: %d", resp.StatusCode) return } body, err := ioutil.ReadAll(resp.Body) if err != nil { t.Errorf("ReadAll Failed: %v", err) return } if string(body) != bogusstr { t.Errorf("Results mismatch: %s != %s", string(body), bogusstr) } t.Logf("Got body: %s", string(body)) }
// NewSocket allocates a new Socket. The Socket is the handle used to // access the underlying library. func NewSocket(d Domain, p Protocol) (*Socket, error) { var s Socket var err error s.proto = p s.dom = d switch p { case PUB: s.sock, err = pub.NewSocket() case SUB: s.sock, err = sub.NewSocket() case PUSH: s.sock, err = push.NewSocket() case PULL: s.sock, err = pull.NewSocket() case REQ: s.sock, err = req.NewSocket() case REP: s.sock, err = rep.NewSocket() case SURVEYOR: s.sock, err = surveyor.NewSocket() case RESPONDENT: s.sock, err = respondent.NewSocket() case PAIR: s.sock, err = pair.NewSocket() case BUS: s.sock, err = bus.NewSocket() default: err = mangos.ErrBadProto } if err != nil { return nil, err } switch d { case AF_SP: case AF_SP_RAW: err = s.sock.SetOption(mangos.OptionRaw, true) default: err = errBadDomain } if err != nil { s.sock.Close() return nil, err } // Compat mode sockets should timeout on send if we don't have any pipes if err = s.sock.SetOption(mangos.OptionWriteQLen, 0); err != nil { s.sock.Close() return nil, err } s.rto = -1 s.sto = -1 all.AddTransports(s.sock) return &s, nil }
func TestDeviceBadPair(t *testing.T) { s1, err := req.NewSocket() if err != nil { t.Errorf("Failed to open S1: %v", err) return } defer s1.Close() s2, err := pair.NewSocket() if err != nil { t.Errorf("Failed to open S2: %v", err) return } defer s2.Close() switch err := mangos.Device(s1, s2); err { case mangos.ErrBadProto: t.Logf("Got expected err: %v", err) return case nil: t.Errorf("Matching incompatible types succeeded") return default: t.Errorf("Got unexpected err: %v", err) return } }
func TestWebsockPath(t *testing.T) { sockReq, _ := req.NewSocket() sockRep, _ := rep.NewSocket() tran := NewTransport() l, e := tran.NewListener("ws://127.0.0.1:3335/mysock", sockReq) if e != nil { t.Errorf("Failed new Listener: %v", e) return } d, e := tran.NewDialer("ws://127.0.0.1:3335/boguspath", sockRep) if e != nil { t.Errorf("Failed new Dialer: %v", e) return } if e = l.Listen(); e != nil { t.Errorf("Listen failed") return } defer l.Close() p, e := d.Dial() if p != nil { defer p.Close() } if e == nil { t.Errorf("Dial passed, when should not have!") return } t.Logf("Got expected error %v", e) }
func newCmdClient(addr string) (mangos.Socket, error) { socket, err := req.NewSocket() if err != nil { return nil, err } if err := socket.SetOption(mangos.OptionSendDeadline, time.Second*3); err != nil { socket.Close() return nil, err } if err := socket.SetOption(mangos.OptionRecvDeadline, time.Second*3); err != nil { socket.Close() return nil, err } //socket.AddTransport(ipc.NewTransport()) socket.AddTransport(tcp.NewTransport()) if err := socket.Dial(addr); err != nil { socket.Close() return nil, err } return socket, nil }
// NewTranTest creates a TranTest. func NewTranTest(tran mangos.Transport, addr string) *TranTest { tt := &TranTest{addr: addr, tran: tran} if strings.HasPrefix(tt.addr, "tls+tcp://") || strings.HasPrefix(tt.addr, "wss://") { tt.cliCfg, _ = GetTLSConfig(false) tt.srvCfg, _ = GetTLSConfig(true) } tt.sockRep, _ = rep.NewSocket() tt.sockReq, _ = req.NewSocket() return tt }
func (rt *reqTest) Init(t *testing.T, addr string) bool { var err error if rt.Sock, err = req.NewSocket(); err != nil { rt.Errorf("NewSocket(): %v", err) return false } rt.cur = 0 rt.tot = 0 return rt.T.Init(t, addr) }
// NewClient creates and returns a new Client from the provided Benchmark // configuration. It returns an error if the Benchmark is not valid or it // can't communicate with any of the specified peers. func NewClient(b *Benchmark) (*Client, error) { if err := b.validate(); err != nil { return nil, err } brokerd, err := req.NewSocket() if err != nil { return nil, err } brokerd.AddTransport(tcp.NewTransport()) brokerd.SetOption(mangos.OptionSendDeadline, time.Duration(b.DaemonTimeout)*time.Second) brokerd.SetOption(mangos.OptionRecvDeadline, time.Duration(b.DaemonTimeout)*time.Second) if err := brokerd.Dial(fmt.Sprintf("tcp://%s", b.BrokerdHost)); err != nil { return nil, err } peerd := make(map[string]mangos.Socket, len(b.PeerHosts)) for _, peer := range b.PeerHosts { s, err := req.NewSocket() if err != nil { return nil, err } s.AddTransport(tcp.NewTransport()) s.SetOption(mangos.OptionSendDeadline, time.Duration(b.DaemonTimeout)*time.Second) s.SetOption(mangos.OptionRecvDeadline, time.Duration(b.DaemonTimeout)*time.Second) if err := s.Dial(fmt.Sprintf("tcp://%s", peer)); err != nil { return nil, err } peerd[peer] = s } return &Client{ brokerd: brokerd, peerd: peerd, Benchmark: b, }, nil }
func newSocket(url, protocol string) (sock mangos.Socket, err error) { var str string switch protocol { case "bus": sock, err = bus.NewSocket() str = "bus.NewSocket: " case "pair": sock, err = pair.NewSocket() str = "pair.NewSocket: " case "push": sock, err = push.NewSocket() str = "push.NewSocket: " case "pull": sock, err = pull.NewSocket() str = "pull.NewSocket: " case "pub": sock, err = pub.NewSocket() str = "pub.NewSocket: " case "sub": sock, err = sub.NewSocket() str = "sub.NewSocket: " case "request": sock, err = req.NewSocket() str = "request.NewSocket: " case "reply": sock, err = rep.NewSocket() str = "reply.NewSocket: " case "surveyor": sock, err = surveyor.NewSocket() str = "surveyor.NewSocket: " case "respondent": sock, err = respondent.NewSocket() str = "respondent.NewSocket: " } if err != nil { s := fmt.Sprintf(str+" %s", err) return nil, errors.New(s) } sock.AddTransport(ipc.NewTransport()) sock.AddTransport(tcp.NewTransport()) return sock, nil }
func clientWorker(url string, id int) { var sock mangos.Socket var m *mangos.Message var err error if sock, err = req.NewSocket(); err != nil { die("can't get new req socket: %s", err.Error()) } // Leave this in Cooked mode! sock.AddTransport(ipc.NewTransport()) sock.AddTransport(tcp.NewTransport()) if err = sock.Dial(url); err != nil { die("can't dial on req socket: %s", err.Error()) } // send an empty messsage m = mangos.NewMessage(1) if err = sock.SendMsg(m); err != nil { die("can't send request: %s", err.Error()) } if m, err = sock.RecvMsg(); err != nil { die("can't recv reply: %s", err.Error()) } sock.Close() if len(m.Body) != 4 { die("bad response len: %d", len(m.Body)) } worker := binary.BigEndian.Uint32(m.Body[0:]) L.Lock() fmt.Printf("Client: %4d Server: %4d\n", id, worker) L.Unlock() }
func node1(url string) { var sock mangos.Socket var err error var msg []byte if sock, err = req.NewSocket(); err != nil { die("can't get new req socket: %s", err.Error()) } sock.AddTransport(ipc.NewTransport()) sock.AddTransport(tcp.NewTransport()) if err = sock.Dial(url); err != nil { die("can't dial on req socket: %s", err.Error()) } fmt.Printf("NODE1: SENDING DATE REQUEST %s\n", "DATE") if err = sock.Send([]byte("DATE")); err != nil { die("can't send message on push socket: %s", err.Error()) } if msg, err = sock.Recv(); err != nil { die("can't receive date: %s", err.Error()) } fmt.Printf("NODE1: RECEIVED DATE %s\n", string(msg)) sock.Close() }
func TestDeviceReqRep(t *testing.T) { s1, err := req.NewSocket() if err != nil { t.Errorf("Failed to open S1: %v", err) return } defer s1.Close() s2, err := rep.NewSocket() if err != nil { t.Errorf("Failed to open S2: %v", err) return } defer s2.Close() switch err := mangos.Device(s1, s2); err { case nil: t.Logf("Matching req/rep ok!") return default: t.Errorf("Got unexpected err: %v", err) return } }
// Connect creates a connection to the jobqueue server, specific to a single // queue. Timeout determines how long to wait for a response from the server, // not only while connecting, but for all subsequent interactions with it using // the returned Client. func Connect(addr string, queue string, timeout time.Duration) (c *Client, err error) { sock, err := req.NewSocket() if err != nil { return } err = sock.SetOption(mangos.OptionRecvDeadline, timeout) if err != nil { return } sock.AddTransport(tcp.NewTransport()) err = sock.Dial("tcp://" + addr) if err != nil { return } // clients identify themselves (only for the purpose of calling methods that // require the client has previously used Require()) with a UUID; v4 is used // since speed doesn't matter: a typical client executable will only // Connect() once; on the other hand, we avoid any possible problem with // running on machines with low time resolution c = &Client{sock: sock, queue: queue, ch: new(codec.BincHandle), clientid: uuid.NewV4()} // Dial succeeds even when there's no server up, so we test the connection // works with a Ping() ok := c.Ping(timeout) if !ok { sock.Close() c = nil err = Error{queue, "Connect", "", ErrNoServer} } return }
func TestPortHook(t *testing.T) { t.Logf("Testing Add Hook") srvtest := &hooktest{allow: true, t: t} clitest := &hooktest{allow: true, t: t} addr := AddrTestTCP srvtest.expect = []hookinfo{{ action: mangos.PortActionAdd, addr: addr, server: true, isopen: true, }, { action: mangos.PortActionRemove, addr: addr, server: true, isopen: false, }} clitest.expect = []hookinfo{{ action: mangos.PortActionAdd, addr: addr, server: false, isopen: true, }, { action: mangos.PortActionRemove, addr: addr, server: false, isopen: false, }} sockreq, err := req.NewSocket() if err != nil { t.Errorf("NewSocket failed: %v", err) return } defer sockreq.Close() sockreq.AddTransport(tcp.NewTransport()) if sockreq.SetPortHook(clitest.Hook) != nil { t.Errorf("SetPortHook result not nil!") return } d, err := sockreq.NewDialer(addr, nil) if err != nil { t.Errorf("NewDialer failed: %v", err) return } sockrep, err := rep.NewSocket() if err != nil { t.Errorf("NewSocket failed: %v", err) return } defer sockrep.Close() sockrep.AddTransport(tcp.NewTransport()) if sockrep.SetPortHook(srvtest.Hook) != nil { t.Errorf("SetPortHook result not nil!") return } l, err := sockrep.NewListener(addr, nil) if err != nil { t.Errorf("NewListener failed: %v", err) return } if err := l.Listen(); err != nil { t.Errorf("Listen failed: %v", err) return } if err := d.Dial(); err != nil { t.Errorf("Dial failed: %v", err) return } // wait a second for connection to establish // could also issue a req/rep... t.Logf("Waiting a bit...") time.Sleep(100 * time.Millisecond) d.Close() l.Close() // shut down the server sockrep.Close() sockreq.Close() time.Sleep(100 * time.Millisecond) clitest.Lock() defer clitest.Unlock() srvtest.Lock() defer srvtest.Unlock() for i, info := range clitest.expect { t.Logf("Exp C[%d]: %s", i, info.String()) } for i, info := range clitest.calls { t.Logf("Got C[%d]: %s", i, info.String()) } for i, info := range srvtest.expect { t.Logf("Exp S[%d]: %s", i, info.String()) } for i, info := range srvtest.calls { t.Logf("Got S[%d]: %s", i, info.String()) } if len(srvtest.calls) != len(srvtest.expect) { t.Errorf("Server got wrong # calls, %d != %d", len(srvtest.calls), len(srvtest.expect)) return } for i := range srvtest.calls { if srvtest.calls[i].String() != srvtest.expect[i].String() { t.Errorf("Server hook %d wrong: %s != %s", i, srvtest.calls[i].String(), srvtest.expect[i].String()) } } if len(clitest.calls) != len(clitest.expect) { t.Errorf("Client got wrong # calls, %d != %d", len(clitest.calls), len(clitest.expect)) return } for i := range clitest.calls { if clitest.calls[i].String() != clitest.expect[i].String() { t.Errorf("Server hook %d wrong: %s != %s", i, clitest.calls[i].String(), clitest.expect[i].String()) } } }
func benchmarkReq(t *testing.B, url string, size int) { if strings.HasPrefix(url, "ipc://") && runtime.GOOS == "windows" { t.Skip("IPC not supported on Windows") return } srvopts := make(map[string]interface{}) cliopts := make(map[string]interface{}) if strings.HasPrefix(url, "wss://") || strings.HasPrefix(url, "tls+tcp://") { srvopts[mangos.OptionTLSConfig] = srvCfg cliopts[mangos.OptionTLSConfig] = cliCfg } srvrdy := make(chan struct{}) srvsock, err := rep.NewSocket() if err != nil || srvsock == nil { t.Errorf("Failed creating server socket: %v", err) return } defer srvsock.Close() all.AddTransports(srvsock) clisock, err := req.NewSocket() if err != nil || clisock == nil { t.Errorf("Failed creating client socket: %v", err) return } defer clisock.Close() all.AddTransports(clisock) go func() { var err error var msg *mangos.Message if err = srvsock.ListenOptions(url, srvopts); err != nil { t.Errorf("Server listen failed: %v", err) return } close(srvrdy) // echo server for { if msg, err = srvsock.RecvMsg(); err != nil { return } if err = srvsock.SendMsg(msg); err != nil { t.Errorf("Server send failed: %v", err) return } } }() if err = clisock.DialOptions(url, cliopts); err != nil { t.Errorf("Client dial failed: %v", err) return } <-srvrdy time.Sleep(time.Millisecond * 1000) t.ResetTimer() msg := make([]byte, size) for i := 0; i < t.N; i++ { if err = clisock.Send(msg); err != nil { t.Errorf("Client send failed: %v", err) return } if msg, err = clisock.Recv(); err != nil { t.Errorf("Client receive failed: %v", err) return } } if size > 128 { t.SetBytes(int64(size)) } t.StopTimer() }
package tcp import ( "bytes" "testing" "time" "github.com/go-mangos/mangos" "github.com/go-mangos/mangos/protocol/rep" "github.com/go-mangos/mangos/protocol/req" ) var tran = NewTransport() var sockRep, _ = rep.NewSocket() var sockReq, _ = req.NewSocket() func TestTCPListenAndAccept(t *testing.T) { addr := "tcp://127.0.0.1:3333" t.Logf("Establishing accepter") l, err := tran.NewListener(addr, sockRep) if err != nil { t.Errorf("NewListener failed: %v", err) return } defer l.Close() if err = l.Listen(); err != nil { t.Errorf("Listen failed: %v", err) return }
func testMaxRx(t *testing.T, addr string, tran mangos.Transport) { maxrx := 100 rp, err := rep.NewSocket() if err != nil { t.Errorf("Failed to make REP: %v", err) return } defer rp.Close() rp.AddTransport(tran) // Now try setting the option err = rp.SetOption(mangos.OptionMaxRecvSize, maxrx) if err != nil { t.Errorf("Failed set MaxRecvSize: %v", err) return } // At this point, we can issue requests on rq, and read them from rp. if err = rp.SetOption(mangos.OptionRecvDeadline, time.Millisecond*20); err != nil { t.Errorf("Failed set recv deadline") return } if err = rp.Listen(addr); err != nil { t.Errorf("Failed listen: %v", err) return } rq, err := req.NewSocket() if err != nil { t.Errorf("Failed to make REQ: %v", err) return } defer rq.Close() rq.AddTransport(tran) if err = rq.Dial(addr); err != nil { t.Errorf("Failed dial: %v", err) return } time.Sleep(time.Millisecond * 10) msg1 := make([]byte, maxrx+1) msg2 := make([]byte, maxrx+1) for i := 0; i < len(msg1); i++ { msg1[i] = 'A' + byte(i%26) msg2[i] = 'A' + byte(i%26) } // NB: maxrx *includes* the header. if err = rq.Send(msg1[:maxrx-8]); err != nil { t.Errorf("Failed first send: %v", err) return } v, err := rp.Recv() if err != nil { t.Errorf("Failed first recv: %v", err) return } else if !bytes.Equal(v, msg2[:maxrx-8]) { t.Errorf("Got wrong message: %v", v) return } else { t.Logf("Got good message") } if err = rq.Send(msg1); err != nil { t.Errorf("Failed send drop: %v", err) return } v, err = rp.Recv() switch err { case mangos.ErrRecvTimeout: // expected t.Logf("MaxRx honored") case nil: t.Errorf("Message not dropped: %v", v) default: t.Errorf("Got unexpected error: %v", err) } }
// This test verifies that we can use stock http server instances with // our own websocket handler. func TestWebsockHandler(t *testing.T) { sockReq, _ := req.NewSocket() sockRep, _ := rep.NewSocket() tran := NewTransport() l, e := tran.NewListener("ws://127.0.0.1:3337/mysock", sockReq) if e != nil { t.Errorf("Failed new Listener: %v", e) return } hi, e := l.GetOption(OptionWebSocketHandler) if e != nil { t.Errorf("Failed get WebSocketHandler: %v", e) } handler := hi.(http.Handler) mux := http.NewServeMux() mux.HandleFunc("/bogus", bogusHandler) mux.Handle("/mysock", handler) // Note that we are *counting* on this to die gracefully when our // program exits. There appears to be no way to shutdown http // instances gracefully. go http.ListenAndServe("127.0.0.1:3337", mux) d, e := tran.NewDialer("ws://127.0.0.1:3337/bogus", sockRep) if e != nil { t.Errorf("Failed new Dialer: %v", e) return } defer l.Close() p, e := d.Dial() if p != nil { defer p.Close() } if e == nil { t.Errorf("Dial passed, when should not have!") return } t.Logf("Got expected error %v", e) // Now let's try to use http client. resp, err := http.Get("http://127.0.0.1:3337/bogus") if err != nil { t.Errorf("Get of boguspath failed: %v", err) return } if resp.StatusCode != 200 { t.Errorf("Response code wrong: %d", resp.StatusCode) return } body, err := ioutil.ReadAll(resp.Body) if err != nil { t.Errorf("ReadAll Failed: %v", err) return } if string(body) != bogusstr { t.Errorf("Results mismatch: %s != %s", string(body), bogusstr) } t.Logf("Got body: %s", string(body)) }