func TestProxy(t *testing.T) { apipe, b1pipe := net.Pipe() b2pipe, cpipe := net.Pipe() // A achan := make(chan chan string) axport := New(apipe, nil) axport.FromChan(achan) // B bchan := make(chan chan string) b1xport := New(b1pipe, nil) b2xport := New(b2pipe, nil) b1xport.ToChan(bchan) b2xport.FromChan(bchan) // C cchan := make(chan chan string) cxport := New(cpipe, nil) cxport.ToChan(cchan) victim := make(chan string) achan <- victim proxied := <-cchan want := "test" proxied <- want if got := <-victim; got != want { t.Errorf("got %q through proxy, want %q", got, want) } }
func TestClientMassError_json(t *testing.T) { cli, srv := net.Pipe() go ServeConn(srv) client := NewClient(cli) defer client.Close() for i := len(svcMsg); i < cap(svcMsg); i++ { svcMsg <- "" } defer func() { for len(svcMsg) > 0 { <-svcMsg } }() wanterr1 := NewError(-32603, "json: cannot unmarshal number into Go value of type string") wanterr2 := NewError(-32603, "some other Call failed to unmarshal Reply") call2 := client.Go("Svc.Msg", []string{"test"}, nil, nil) var badreply string err1 := client.Call("Svc.Sum", [2]int{}, &badreply) if err1 == nil || !reflect.DeepEqual(ServerError(err1), wanterr1) { t.Errorf("%serr1 = %v, wanterr1 = %v", caller(), err1, wanterr1) } <-call2.Done err2 := call2.Error if err2 == nil || !reflect.DeepEqual(ServerError(err2), wanterr2) { t.Errorf("%serr2 = %v, wanterr2 = %v", caller(), err2, wanterr2) } }
func TestNextError(t *testing.T) { t.Parallel() var want, got error pipe1, pipe2 := net.Pipe() tcpTsp := NewTCP(pipe1, stream.Receiving, nil, true) // Error from xml.Decoder should be returned go func() { _, err := pipe2.Write([]byte("</whoops>")) if err != nil { t.Errorf("An unexpected error occurred: %s", err) } }() _, got = tcpTsp.Next() if _, ok := got.(*xml.SyntaxError); !ok { t.Error("Error from xml.Decoder should be returned.") t.Errorf("Wanted xml.SyntaxError, Got:(%T)%s", got, got) } pipe1, pipe2 = net.Pipe() tcpTsp = NewTCP(pipe1, stream.Receiving, nil, true) go func() { _, err := pipe2.Write([]byte("<foo><bar></whoops>")) if err != nil { t.Errorf("An unexpected error occurred: %s", err) } }() _, got = tcpTsp.Next() if _, ok := got.(*xml.SyntaxError); !ok { t.Error("Error from xml.Decoder should be returned.") t.Errorf("Wanted xml.SyntaxError, Got:(%T)%s", got, got) } // Receiving an xml end element should return stream.ErrStreamClosed pipe1, pipe2 = net.Pipe() tcpTsp = NewTCP(pipe1, stream.Receiving, nil, true) go func() { _, err := pipe2.Write(stream.Header{}.WriteBytes()) if err != nil { t.Errorf("An unexpected error occurred: %s", err) } _, err = pipe2.Write([]byte("</stream:stream>")) if err != nil { t.Errorf("An unexpected error occurred: %s", err) } }() want = stream.ErrStreamClosed _, err := tcpTsp.Next() if err != nil { t.Errorf("Unexpected error: %s", err) } _, got = tcpTsp.Next() if !reflect.DeepEqual(want, got) { t.Error("Receiving an xml end element should return stream.ErrStreamClosed.") t.Errorf("\nWant:%s\nGot :%s", got, got) } }
func TestServer(t *testing.T) { errChan := make(chan error, 1) s := NewServer(errChan) // Subscribe to listen a channel var ch uint32 = 37 lis1, lis2 := net.Pipe() go s.Handle(lis2) reqData, err := api.WriteRequest(&api.Request{Channel: ch, Type: api.Listen}) if err != nil { t.Fatal("WriteRequest: ", err) } if _, err := lis1.Write(reqData); err != nil { t.Fatal("Write(reqData): ", err) } // Send payload to the channel send1, send2 := net.Pipe() go s.Handle(send2) payload := []byte("foo") if reqData, err = api.WriteRequest(&api.Request{Channel: ch, Type: api.Send, Data: payload}); err != nil { t.Fatal("WriteRequest: ", err) } if _, err := send1.Write(reqData); err != nil { t.Fatal("Write(reqData): ", err) } if err = send1.Close(); err != nil { t.Fatal("send1.Close(): ", err) } // Read response to the listener resp, err := api.ReadResponse(lis1) if err != nil { t.Fatal("ReadResponse: ", err) } if err = lis1.Close(); err != nil { t.Fatal("lis1.Close()") } // Check that the response matches if resp.Channel != ch { t.Fatalf("Unexpected channel: %d, want: %d", resp.Channel, ch) } if !bytes.Equal(resp.Data, payload) { t.Fatalf("Unexpected payload: %v, want: %v", resp.Data, payload) } // Make sure, there was no errors select { case err := <-errChan: t.Fatal("Error reported via errChan:", err) default: } }
func fightN(f1, f2 Factory, n int) []MatchResult { aiA := &aiAdapter{factory: f1, games: make(map[string]gameState)} aiB := &aiAdapter{factory: f2, games: make(map[string]gameState)} a1, a2 := net.Pipe() b1, b2 := net.Pipe() ca1, ca2 := rpc.StreamTransport(a1), rpc.StreamTransport(a2) cb1, cb2 := rpc.StreamTransport(b1), rpc.StreamTransport(b2) // Server-side srvA := botapi.Ai_ServerToClient(aiA) srvB := botapi.Ai_ServerToClient(aiB) serverConnA := rpc.NewConn(ca1, rpc.MainInterface(srvA.Client)) serverConnB := rpc.NewConn(cb1, rpc.MainInterface(srvB.Client)) defer serverConnA.Wait() defer serverConnB.Wait() // Client-side ctx := context.Background() clientConnA := rpc.NewConn(ca2) clientConnB := rpc.NewConn(cb2) defer clientConnA.Close() defer clientConnB.Close() clientA := localAI{botapi.Ai{Client: clientConnA.Bootstrap(ctx)}} clientB := localAI{botapi.Ai{Client: clientConnB.Bootstrap(ctx)}} matchRes := make([]MatchResult, n) // Run the game for i := 0; i < n; i++ { b := engine.EmptyBoard(engine.DefaultConfig) b.InitBoard(engine.DefaultConfig) for !b.IsFinished() { turnCtx, _ := context.WithTimeout(ctx, 30*time.Second) resA, _ := clientA.takeTurn(turnCtx, strconv.Itoa(i), b, engine.P1Faction) resB, _ := clientB.takeTurn(turnCtx, strconv.Itoa(i), b, engine.P2Faction) b.Update(resA, resB) } matchRes[i] = MatchResult{ P1Score: b.BotCount(1), P2Score: b.BotCount(2), } } return matchRes }
// TestNegotiateRevisionStopResponse tests that when the host sends // StopResponse, the renter continues processing the revision instead of // immediately terminating. func TestNegotiateRevisionStopResponse(t *testing.T) { // simulate a renter-host connection rConn, hConn := net.Pipe() // handle the host's half of the pipe go func() { defer hConn.Close() // read revision encoding.ReadObject(hConn, new(types.FileContractRevision), 1<<22) // write acceptance modules.WriteNegotiationAcceptance(hConn) // read txn signature encoding.ReadObject(hConn, new(types.TransactionSignature), 1<<22) // write StopResponse modules.WriteNegotiationStop(hConn) // write txn signature encoding.WriteObject(hConn, types.TransactionSignature{}) }() // since the host wrote StopResponse, we should proceed to validating the // transaction. This will return a known error because we are supplying an // empty revision. _, err := negotiateRevision(rConn, types.FileContractRevision{}, crypto.SecretKey{}) if err != types.ErrFileContractWindowStartViolation { t.Fatalf("expected %q, got \"%v\"", types.ErrFileContractWindowStartViolation, err) } rConn.Close() // same as above, but send an error instead of StopResponse. The error // should be returned by negotiateRevision immediately (if it is not, we // should expect to see a transaction validation error instead). rConn, hConn = net.Pipe() go func() { defer hConn.Close() encoding.ReadObject(hConn, new(types.FileContractRevision), 1<<22) modules.WriteNegotiationAcceptance(hConn) encoding.ReadObject(hConn, new(types.TransactionSignature), 1<<22) // write a sentinel error modules.WriteNegotiationRejection(hConn, errors.New("sentinel")) encoding.WriteObject(hConn, types.TransactionSignature{}) }() expectedErr := "host did not accept transaction signature: sentinel" _, err = negotiateRevision(rConn, types.FileContractRevision{}, crypto.SecretKey{}) if err == nil || err.Error() != expectedErr { t.Fatalf("expected %q, got \"%v\"", expectedErr, err) } rConn.Close() }
func BenchmarkWithHack(b *testing.B) { client, srv := net.Pipe() done := make(chan struct{}) req := []byte("GET /foo\nHost: /var/run/docker.sock\nUser-Agent: Docker\n") read := make([]byte, 4096) b.SetBytes(int64(len(req) * 30)) l := MalformedHostHeaderOverrideConn{client, true} go func() { for { if _, err := srv.Write(req); err != nil { srv.Close() break } l.first = true // make sure each subsequent run uses the hack parsing } close(done) }() for i := 0; i < b.N; i++ { for i := 0; i < 30; i++ { if n, err := l.Read(read); err != nil && err != io.EOF { b.Fatalf("read: %d - %d, err: %v\n%s", n, len(req), err, string(read[:n])) } } } l.Close() <-done }
func testMaliciousInput(t *testing.T, data []byte) { w, r := net.Pipe() defer w.Close() defer r.Close() go func() { // This io.Copy will discard all bytes from w until w is closed. // This is needed because sends on the net.Pipe are synchronous, so // the v3Conn will block if we don't read whatever it tries to send. // The reason this works is that ioutil.devNull implements ReadFrom // as an infinite loop, so it will Read continuously until it hits an // error (on w.Close()). _, _ = io.Copy(ioutil.Discard, w) }() go func() { // Write the malicious data. if _, err := w.Write(data); err != nil { panic(err) } // Sync and terminate if a panic did not occur to stop the server. // We append a 4-byte trailer to each to signify a zero length message. See // lib/pq.conn.sendSimpleMessage for a similar approach to simple messages. _, _ = w.Write([]byte{byte(clientMsgSync), 0x00, 0x00, 0x00, 0x04}) _, _ = w.Write([]byte{byte(clientMsgTerminate), 0x00, 0x00, 0x00, 0x04}) }() v3Conn := makeTestV3Conn(r) _ = v3Conn.serve(nil) }
func testClientHelloFailure(t *testing.T, serverConfig *Config, m handshakeMessage, expectedSubStr string) { // Create in-memory network connection, // send message to server. Should return // expected error. c, s := net.Pipe() go func() { cli := Client(c, testConfig) if ch, ok := m.(*clientHelloMsg); ok { cli.vers = ch.vers } cli.writeRecord(recordTypeHandshake, m.marshal()) c.Close() }() hs := serverHandshakeState{ c: Server(s, serverConfig), } _, err := hs.readClientHello() s.Close() if len(expectedSubStr) == 0 { if err != nil && err != io.EOF { t.Errorf("Got error: %s; expected to succeed", err) } } else if err == nil || !strings.Contains(err.Error(), expectedSubStr) { t.Errorf("Got error: %s; expected to match substring '%s'", err, expectedSubStr) } }
func TestServerDisconnect(t *testing.T) { spipe, cpipe := net.Pipe() cxport := New(cpipe, nil) sxport := New(spipe, nil) defer sxport.Close() // Client side client := make(chan string) cxport.ToChan(client) defer cxport.Close() // Disconnect the server spipe.Close() // Did the client channel get closed? select { case _, ok := <-client: if ok { t.Errorf("Real value received?!") return } case <-time.After(100 * time.Millisecond): t.Errorf("timeout waiting for client channel close") panic("for stack trace") } }
func TestConnPubKeyFilter(t *testing.T) { s1 := makeSwitch(1, "testing", "123.123.123", initSwitchFunc) s2 := makeSwitch(1, "testing", "123.123.123", initSwitchFunc) c1, c2 := net.Pipe() // set pubkey filter s1.SetPubKeyFilter(func(pubkey crypto.PubKeyEd25519) error { if bytes.Equal(pubkey.Bytes(), s2.nodeInfo.PubKey.Bytes()) { return fmt.Errorf("Error: pipe is blacklisted") } return nil }) // connect to good peer go s1.AddPeerWithConnection(c1, false) // AddPeer is blocking, requires handshake. go s2.AddPeerWithConnection(c2, true) // Wait for things to happen, peers to get added... time.Sleep(100 * time.Millisecond * time.Duration(4)) defer s1.Stop() defer s2.Stop() if s1.Peers().Size() != 0 { t.Errorf("Expected s1 not to connect to peers, got %d", s1.Peers().Size()) } if s2.Peers().Size() != 0 { t.Errorf("Expected s2 not to connect to peers, got %d", s2.Peers().Size()) } }
func TestBuffering(t *testing.T) { c, s := net.Pipe() done := make(chan bool) clientWCC := &writeCountingConn{Conn: c} serverWCC := &writeCountingConn{Conn: s} go func() { Server(serverWCC, testConfig).Handshake() serverWCC.Close() done <- true }() err := Client(clientWCC, testConfig).Handshake() if err != nil { t.Fatal(err) } clientWCC.Close() <-done if n := clientWCC.numWrites; n != 2 { t.Errorf("expected client handshake to complete with only two writes, but saw %d", n) } if n := serverWCC.numWrites; n != 2 { t.Errorf("expected server handshake to complete with only two writes, but saw %d", n) } }
func TestHandshakeServer(t *testing.T) { c, s := net.Pipe() srv := Server(s, testConfig) go func() { srv.Write([]byte("hello, world\n")) srv.Close() }() defer c.Close() for i, b := range serverScript { if i%2 == 0 { c.Write(b) continue } bb := make([]byte, len(b)) _, err := io.ReadFull(c, bb) if err != nil { t.Fatalf("#%d: %s", i, err) } } if !srv.haveVers || srv.vers != 0x0302 { t.Errorf("server version incorrect: %v %v", srv.haveVers, srv.vers) } // TODO: check protocol }
func BenchmarkPipeReadWriter(b *testing.B) { s, c := net.Pipe() ch_c_w := make(chanPayload, 1024) ch_s_w := make(chanPayload, 1024) ch_d := make(chanPayload, 1024) hf := NewMsgHeaderFactory(pbt.NewMsgProtobufFactory()) ep_c := NewEndPoint("c", c, ch_c_w, ch_d, hf, nil, nil) ep_s := NewEndPoint("s", s, ch_s_w, ch_s_w, hf, nil, nil) ep_c.Run() ep_s.Run() b.ResetTimer() b.RunParallel(func(pb *testing.PB) { req := pbt.NewResourceReq() req.Id = proto.Uint64(1) for pb.Next() { ch_c_w <- req <-ch_d } }) }
func BenchmarkPipeShareRouter(b *testing.B) { r, err := NewRouter(nil, ServiceProcessPayload) if err != nil { b.FailNow() } hf := NewMsgHeaderFactory(pbt.NewMsgProtobufFactory()) r.Run() <-time.Tick(1 * time.Millisecond) name := "scheduler" n := ConcurrentNum m := GoRoutineRequests for i := 0; i < n; i++ { c, s := net.Pipe() ep_c := r.newRouterEndPoint(name+string(i), c, hf) ep_s := r.newRouterEndPoint("client"+string(n), s, hf) r.AddEndPoint(ep_c) r.AddEndPoint(ep_s) } <-time.Tick(1 * time.Millisecond) testShareRouter(b, r, n, m) }
// NewPeer returns a peer for testing purposes. func NewPeer(id discover.NodeID, name string, caps []Cap) *Peer { pipe, _ := net.Pipe() conn := &conn{fd: pipe, transport: nil, id: id, caps: caps, name: name} peer := newPeer(conn, nil) close(peer.closed) // ensures Disconnect doesn't block return peer }
func startTLSServer(config *Config) (net.Conn, chan error) { errc := make(chan error, 1) tlsConfigServer, err := config.IncomingTLSConfig() if err != nil { errc <- err return nil, errc } client, server := net.Pipe() go func() { tlsServer := tls.Server(server, tlsConfigServer) if err := tlsServer.Handshake(); err != nil { errc <- err } close(errc) // Because net.Pipe() is unbuffered, if both sides // Close() simultaneously, we will deadlock as they // both send an alert and then block. So we make the // server read any data from the client until error or // EOF, which will allow the client to Close(), and // *then* we Close() the server. io.Copy(ioutil.Discard, tlsServer) tlsServer.Close() }() return client, errc }
// handleConnection creates and connects a non-buffered pipe to the already // existing server connection using a `net.Conn` from net.Pipe(). It then dials // the endpoint and finishes the user->endpoint piping by connecting the other // `net.Conn` to the client. // // NOTE: `net.Pipe()` is only neccessary for detecting a user hangup. Upon user // disconnect, we prevent a possible DOS by ending the `dial()` function's // ability to redial. // // go pipe(&cli, srv, "User") // pipe(srv, &cli, "Endpoint") // would be sufficient (following dial()) if we weren't concerned by the // extra connection attempts made by dial. func handleConnection(srv *net.Conn) { // Create and connect a non-buffered pipe to the already existing connection s, c := net.Pipe() config.Log.Debug("Piping user input to server...") go pipe(&s, srv, "User") config.Log.Debug("Piping server input to user...") go pipe(srv, &s, "Server") // dial the endpoint cli, err := dial(srv) if err != nil { config.Log.Error("Failed to contact endpoint - %v", err) // write back to redis client the error (http://redis.io/topics/protocol#resp-errors) (*srv).Write([]byte(fmt.Sprintf("-ERR Failed to contact endpoint - %v", err))) (*srv).Close() return } // Connect the non-buffered pipe to the dialed client config.Log.Debug("Piping client input to endpoint...") go pipe(&cli, &c, "Client") config.Log.Debug("Piping endpoint input to client...") pipe(&c, &cli, "Endpoint") config.Log.Debug("Piping session done") }
func BenchmarkNoHack(b *testing.B) { client, srv := net.Pipe() done := make(chan struct{}) req := []byte("GET /foo\nHost: /var/run/docker.sock\nUser-Agent: Docker\n") read := make([]byte, 4096) b.SetBytes(int64(len(req) * 30)) go func() { for { if _, err := srv.Write(req); err != nil { srv.Close() break } } close(done) }() for i := 0; i < b.N; i++ { for i := 0; i < 30; i++ { if _, err := client.Read(read); err != nil && err != io.EOF { b.Fatal(err) } } } client.Close() <-done }
func TestCall(t *testing.T) { cases := []struct { method string in interface{} want interface{} wanterr *Error }{ {"Svc.Sum", [2]int{}, 0.0, nil}, {"Svc.Sum", [2]int{3, 5}, 8.0, nil}, {"Svc.Sum", [2]int{-3, 5}, 2.0, nil}, {"Svc.Name", NameArg{"John", "Smith"}, map[string]interface{}{"Name": "John Smith"}, nil}, {"Svc.Err", struct{}{}, struct{}{}, NewError(-32000, "some issue")}, {"Svc.Err", []struct{}{}, struct{}{}, NewError(-32602, "json: cannot unmarshal array into Go value of type struct {}")}, {"Svc.Err2", struct{}{}, struct{}{}, NewError(42, "some issue")}, } for _, c := range cases { cli, srv := net.Pipe() go ServeConn(srv) client := NewClient(cli) defer client.Close() got := reflect.Zero(reflect.TypeOf(c.want)).Interface() err := client.Call(c.method, c.in, &got) if err == nil && c.wanterr != nil || err != nil && (c.wanterr == nil || *ServerError(err) != *c.wanterr) { t.Errorf("%s(%v), err = %v, wanterr = %v", c.method, c.in, err, c.wanterr) } if !reflect.DeepEqual(got, c.want) { t.Errorf("%s(%v)\n%s", c.method, c.in, dump(got, c.want)) } } }
func testClientScript(t *testing.T, name string, clientScript [][]byte, config *Config) { c, s := net.Pipe() cli := Client(c, config) go func() { cli.Write([]byte("hello\n")) cli.Close() c.Close() }() defer c.Close() for i, b := range clientScript { if i%2 == 1 { s.Write(b) continue } bb := make([]byte, len(b)) _, err := io.ReadFull(s, bb) if err != nil { t.Fatalf("%s #%d: %s", name, i, err) } if !bytes.Equal(b, bb) { t.Fatalf("%s #%d: mismatch on read: got:%x want:%x", name, i, bb, b) } } }
func TestServer(t *testing.T) { cli, srv := net.Pipe() defer cli.Close() go ServeConn(srv) dec := json.NewDecoder(cli) // Send hand-coded requests to server, parse responses. for i := 0; i < 10; i++ { fmt.Fprintf(cli, `{"jsonrpc": "2.0", "method": "Arith.Add", "id": "\u%04d", "params": {"A": %d, "B": %d}}`, i, i, i+1) var resp ArithAddResp err := dec.Decode(&resp) if err != nil { t.Fatalf("Decode: %s", err) } if resp.Error != nil { t.Fatalf("resp.Error: %s", resp.Error) } if resp.ID.(string) != string(i) { t.Fatalf("resp: bad id %q want %q", resp.ID.(string), string(i)) } if resp.Result.C != 2*i+1 { t.Fatalf("resp: bad result: %d+%d=%d", i, i+1, resp.Result.C) } } }
func TestHostnameInSNI(t *testing.T) { for _, tt := range hostnameInSNITests { c, s := net.Pipe() go func(host string) { Client(c, &Config{ServerName: host, InsecureSkipVerify: true}).Handshake() }(tt.in) var header [5]byte if _, err := io.ReadFull(s, header[:]); err != nil { t.Fatal(err) } recordLen := int(header[3])<<8 | int(header[4]) record := make([]byte, recordLen) if _, err := io.ReadFull(s, record[:]); err != nil { t.Fatal(err) } c.Close() s.Close() var m clientHelloMsg if !m.unmarshal(record) { t.Errorf("unmarshaling ClientHello for %q failed", tt.in) continue } if tt.in != tt.out && m.serverName == tt.in { t.Errorf("prohibited %q found in ClientHello: %x", tt.in, record) } if m.serverName != tt.out { t.Errorf("expected %q not found in ClientHello: %x", tt.out, record) } } }
func TestSend(t *testing.T) { client, server := net.Pipe() go doServiceHandshake(server, true, t) cn, err := NewConnectionFromNetConn("TestRPCService", client) c := cn.(*Conn) s := rpc.NewServer() var ts TestRPCService s.Register(&ts) go s.ServeCodec(bsonrpc.NewServerCodec(server)) var tp TestParam tp.Val1 = "Hello World" tp.Val2 = 10 ri := &skynet.RequestInfo{} ts.TestMethod = func(in skynet.ServiceRPCIn, out *skynet.ServiceRPCOut) (err error) { out.Out, err = bson.Marshal(&tp) var t TestParam if err != nil { return } if in.ClientID != c.clientID { return errors.New("Failed to set ClientID on request") } if in.Method != "Foo" { return errors.New("Failed to set Method on request") } if *in.RequestInfo != *ri { return errors.New("Failed to set RequestInfo on request") } err = bson.Unmarshal(in.In, &t) if err != nil { return } if t.Val1 != tp.Val1 || tp.Val2 != tp.Val2 { return errors.New("Request failed to send proper data") } return } err = c.Send(ri, "Foo", tp, &tp) if err != nil { t.Error(err) return } c.Close() server.Close() }
func TestCallTyped(t *testing.T) { cases := []struct { in NameArg want NameRes }{ {NameArg{}, NameRes{" "}}, {NameArg{"John", "Smith"}, NameRes{"John Smith"}}, } for _, c := range cases { cli, srv := net.Pipe() go ServeConn(srv) client := NewClient(cli) defer client.Close() var got NameRes err := client.Call("Svc.Name", c.in, &got) if err != nil { t.Errorf("Svc.Name(%v), err = %v", c.in, err) } if !reflect.DeepEqual(got, c.want) { t.Errorf("Svc.Name(%v)\n%s", c.in, dump(got, c.want)) } } }
func TestConnAddrFilter(t *testing.T) { s1 := makeSwitch(1, "testing", "123.123.123", initSwitchFunc) s2 := makeSwitch(1, "testing", "123.123.123", initSwitchFunc) c1, c2 := net.Pipe() s1.SetAddrFilter(func(addr net.Addr) error { if addr.String() == c1.RemoteAddr().String() { return fmt.Errorf("Error: pipe is blacklisted") } return nil }) // connect to good peer go s1.AddPeerWithConnection(c1, false) // AddPeer is blocking, requires handshake. go s2.AddPeerWithConnection(c2, true) // Wait for things to happen, peers to get added... time.Sleep(100 * time.Millisecond * time.Duration(4)) defer s1.Stop() defer s2.Stop() if s1.Peers().Size() != 0 { t.Errorf("Expected s1 not to connect to peers, got %d", s1.Peers().Size()) } if s2.Peers().Size() != 0 { t.Errorf("Expected s2 not to connect to peers, got %d", s2.Peers().Size()) } }
func (ln wslistener) ServeHTTP(w http.ResponseWriter, r *http.Request) { websocket.Handler(func(wcon *websocket.Conn) { // It appears we mustn't pass wcon to external users as is. // We'll pass a pipe instead, because the only way to know if a wcon // was closed remotely is to read from it until EOF. ch := make(chan struct{}) p1, p2 := net.Pipe() go func() { io.Copy(wcon, p1) wcon.Close() }() go func() { io.Copy(p1, wcon) p1.Close() close(ch) }() select { case ln.acceptCh <- p2: case <-ln.closeCh: } // As soon as we return from this function, websocket library will // close wcon. So we'll wait until p2 or wcon is closed. <-ch }).ServeHTTP(w, r) }
func runTest(t *testing.T, clientFunc, serverFunc endpointHandler) { c1, c2 := net.Pipe() serverDone := make(chan error, 1) clientDone := make(chan error, 1) go runEndpoint(c2, true, serverFunc, serverDone) go runEndpoint(c1, false, clientFunc, clientDone) timeout := time.After(50 * time.Millisecond) for clientDone != nil || serverDone != nil { select { case err := <-clientDone: if err != nil { t.Fatalf("Client error: %s", err) } clientDone = nil case err := <-serverDone: if err != nil { t.Fatalf("Server error: %s", err) } serverDone = nil case <-timeout: pprof.Lookup("goroutine").WriteTo(os.Stdout, 1) t.Fatalf("Timeout!") } } }
func Example_hash() { c1, c2 := net.Pipe() go server(c1) client(context.Background(), c2) // Output: // sha1: 0a0a9f2a6772942557ab5355d76af442f8f65e01 }
func TestStreamingCall(t *testing.T) { // Assume server is okay (TestServer is above). // Test client against server. cli, srv := net.Pipe() go ServeConn(srv) client := NewClient(cli) defer client.Close() args := &Args{7, 0} rowChan := make(chan *Reply, 10) c := client.StreamGo("Arith.Thrive", args, rowChan) // fetch all the rows count := 0 for row := range rowChan { if row.C != count { t.Fatal("unexpected value:", row.C) } count += 1 // log.Println("Values: ", row) } if c.Error != nil { t.Fatal("unexpected error:", c.Error.Error()) } if count != 7 { t.Fatal("Didn't receive the right number of packets back:", count) } }