func sendAck(transp *mockTransport, seq uint32) { buf := streambuf.New(nil) buf.WriteByte('2') buf.WriteByte('A') buf.WriteNetUint32(seq) transp.sendBytes(buf.Bytes()) }
func TestSimpleEvent(t *testing.T) { transp := newMockTransport() client := newClientTestDriver( newLumberjackClient(transp, testMaxWindowSize, 5*time.Second)) event := common.MapStr{"name": "me", "line": 10} client.Publish([]common.MapStr{event}) // receive window message buf := streambuf.New(nil) win, err := recvMessage(buf, transp) assert.Nil(t, err) // receive data message msg, err := recvMessage(buf, transp) assert.Nil(t, err) // send ack sendAck(transp, 1) // stop test driver transp.Close() client.Stop() // validate assert.NotNil(t, win) assert.NotNil(t, msg) assert.Equal(t, 1, len(msg.events)) msg = msg.events[0] assert.Equal(t, "me", msg.doc["name"]) assert.Equal(t, 10.0, msg.doc["line"]) }
func (c *mockConn) sendACK(seq uint32) { buf := streambuf.New(nil) buf.WriteByte('2') buf.WriteByte('A') buf.WriteNetUint32(seq) c.conn.Write(buf.Bytes()) }
func testCloseAfterWindowSize(t *testing.T, factory clientFactory) { enableLogging([]string{"*"}) server := transptest.NewMockServerTCP(t, 100*time.Millisecond, "", nil) sock, transp, err := server.ConnectPair() if err != nil { t.Fatalf("Failed to connect server and client: %v", err) } client := factory(transp) conn := &mockConn{sock, streambuf.New(nil)} defer transp.Close() defer sock.Close() defer client.Stop() client.Publish([]common.MapStr{common.MapStr{ "type": "test", "message": "hello world", }}) _, err = conn.recvMessage() if err != nil { t.Fatalf("failed to read window size message: %v", err) } }
func (msg *udpMessage) addDatagram( header *mcUdpHeader, data []byte, ) *streambuf.Buffer { if msg.isComplete { return nil } if msg.numDatagrams == 1 { msg.isComplete = true return streambuf.NewFixed(data) } if msg.count < msg.numDatagrams { if msg.datagrams[header.seqNumber] != nil { return nil } msg.datagrams[header.seqNumber] = data msg.count++ } if msg.count < msg.numDatagrams { return nil } buffer := streambuf.New(nil) for _, payload := range msg.datagrams { buffer.Append(payload) } msg.isComplete = true msg.datagrams = nil buffer.Fix() return buffer }
func newTestParser(tst *testing.T, state parserState) *testParser { t := &testParser{ testing: tst, parser: newParser(&defaultTestParserConfig), buf: streambuf.New(nil), } return t }
func sockSendACK(out io.Writer, seq uint32) error { buf := streambuf.New(nil) buf.WriteByte('2') buf.WriteByte('A') buf.WriteNetUint32(seq) _, err := out.Write(buf.Bytes()) return err }
func prepareBinMessage( hdr *binHeader, extras []extraFn, key valueFn, value valueFn, ) (*streambuf.Buffer, error) { buf := streambuf.New(nil) gen := genBinMessage(hdr, extras, key, value) err := gen(buf) return buf, err }
// NewLine creates a new Line reader object func NewLine(input io.Reader, codec encoding.Encoding, bufferSize int) (*Line, error) { encoder := codec.NewEncoder() // Create newline char based on encoding nl, _, err := transform.Bytes(encoder, []byte{'\n'}) if err != nil { return nil, err } return &Line{ reader: input, codec: codec, bufferSize: bufferSize, nl: nl, decoder: codec.NewDecoder(), inBuffer: streambuf.New(nil), outBuffer: streambuf.New(nil), }, nil }
func (l *LineReader) init( input io.Reader, codec encoding.Encoding, bufferSize int, ) error { l.rawInput = input l.codec = codec l.bufferSize = bufferSize l.codec.NewEncoder() nl, _, err := transform.Bytes(l.codec.NewEncoder(), []byte{'\n'}) if err != nil { return err } l.nl = nl l.decoder = l.codec.NewDecoder() l.inBuffer = streambuf.New(nil) l.outBuffer = streambuf.New(nil) return nil }
func testStructuredEvent(t *testing.T, factory clientFactory) { enableLogging([]string{"*"}) server := transptest.NewMockServerTCP(t, 1*time.Second, "", nil) sock, transp, err := server.ConnectPair() if err != nil { t.Fatalf("Failed to connect server and client: %v", err) } client := factory(transp) conn := &mockConn{sock, streambuf.New(nil)} defer transp.Close() defer sock.Close() event := common.MapStr{ "type": "test", "name": "test", "struct": common.MapStr{ "field1": 1, "field2": true, "field3": []int{1, 2, 3}, "field4": []interface{}{ 1, "test", common.MapStr{ "sub": "field", }, }, "field5": common.MapStr{ "sub1": 2, }, }, } client.Publish([]common.MapStr{event}) win, err := conn.recvMessage() assert.Nil(t, err) msg, err := conn.recvMessage() assert.Nil(t, err) conn.sendACK(1) defer client.Stop() // validate assert.NotNil(t, win) assert.NotNil(t, msg) assert.Equal(t, 1, len(msg.events)) msg = msg.events[0] assert.Equal(t, "test", msg.doc["name"]) assert.Equal(t, 1.0, msg.doc.get("struct.field1")) assert.Equal(t, true, msg.doc.get("struct.field2")) assert.Equal(t, 2.0, msg.doc.get("struct.field5.sub1")) }
func (s *protocolServer) connectPair(compressLevel int) (*mockConn, *protocol, error) { client, transp, err := s.MockServer.ConnectPair() if err != nil { return nil, nil, err } proto, err := newClientProcol(transp, 100*time.Millisecond, compressLevel, "test") if err != nil { return nil, nil, err } conn := &mockConn{client, streambuf.New(nil)} return conn, proto, nil }
func (s *clientServer) connectPair(compressLevel int) (*mockConn, *client, error) { client, transp, err := s.mockServer.connectPair(100 * time.Millisecond) if err != nil { return nil, nil, err } lc, err := newLumberjackClient(transp, compressLevel, defaultMaxWindowSize, 100*time.Millisecond) if err != nil { return nil, nil, err } conn := &mockConn{client, streambuf.New(nil)} return conn, lc, nil }
func TestStructuredEvent(t *testing.T) { transp := newMockTransport() client := newClientTestDriver( newLumberjackClient(transp, testMaxWindowSize, 5*time.Second)) event := common.MapStr{ "name": "test", "struct": common.MapStr{ "field1": 1, "field2": true, "field3": []int{1, 2, 3}, "field4": []interface{}{ 1, "test", common.MapStr{ "sub": "field", }, }, "field5": common.MapStr{ "sub1": 2, }, }, } client.Publish([]common.MapStr{event}) buf := streambuf.New(nil) win, err := recvMessage(buf, transp) assert.Nil(t, err) msg, err := recvMessage(buf, transp) assert.Nil(t, err) sendAck(transp, 1) transp.Close() client.Stop() // validate assert.NotNil(t, win) assert.NotNil(t, msg) assert.Equal(t, 1, len(msg.events)) msg = msg.events[0] assert.Equal(t, "test", msg.doc["name"]) assert.Equal(t, 1.0, msg.doc.get("struct.field1")) assert.Equal(t, true, msg.doc.get("struct.field2")) assert.Equal(t, 2.0, msg.doc.get("struct.field5.sub1")) }
func testSimpleEvent(t *testing.T, factory clientFactory) { enableLogging([]string{"*"}) server := newMockServerTCP(t, 1*time.Second, "") sock, transp, err := server.connectPair(1 * time.Second) if err != nil { t.Fatalf("Failed to connect server and client: %v", err) } client := factory(transp) conn := &mockConn{sock, streambuf.New(nil)} defer transp.Close() defer sock.Close() event := common.MapStr{"name": "me", "line": 10} client.Publish([]common.MapStr{event}) // receive window message err = sock.SetReadDeadline(time.Now().Add(1 * time.Second)) win, err := conn.recvMessage() assert.Nil(t, err) // receive data message msg, err := conn.recvMessage() assert.Nil(t, err) // send ack conn.sendACK(1) client.Stop() // validate assert.NotNil(t, win) assert.NotNil(t, msg) assert.Equal(t, 1, len(msg.events)) msg = msg.events[0] assert.Equal(t, "me", msg.doc["name"]) assert.Equal(t, 10.0, msg.doc["line"]) }
func testConnectionType( t *testing.T, server *mockLSServer, makeOutputer func() outputs.BulkOutputer, ) { var result struct { err error win, data *message signal bool } var wg struct { ready sync.WaitGroup finish sync.WaitGroup } wg.ready.Add(1) // server signaling readiness to client worker wg.finish.Add(2) // server/client signaling test end // server loop go func() { defer wg.finish.Done() wg.ready.Done() client := server.accept() server.handshake(client) buf := streambuf.New(nil) result.win = server.readMessage(buf, client) result.data = server.readMessage(buf, client) server.sendACK(client, 1) result.err = server.err }() // worker loop go func() { defer wg.finish.Done() wg.ready.Wait() output := makeOutputer() signal := outputs.NewSyncSignal() output.PublishEvent(signal, testOptions, testEvent()) result.signal = signal.Wait() }() // wait shutdown wg.finish.Wait() server.Close() // validate output assert.Nil(t, result.err) assert.True(t, result.signal) data := result.data assert.NotNil(t, result.win) assert.NotNil(t, result.data) if data != nil { assert.Equal(t, 1, len(data.events)) data = data.events[0] assert.Equal(t, 10.0, data.doc["extra"]) assert.Equal(t, "message", data.doc["message"]) } }
func testMultiFailMaxTimeouts(t *testing.T, factory clientFactory) { enableLogging([]string{"*"}) server := newMockServerTCP(t, 100*time.Millisecond, "") transp, err := server.transp() if err != nil { t.Fatalf("Failed to connect server and client: %v", err) } N := 8 client := factory(transp) defer transp.Close() defer client.Stop() event := common.MapStr{"name": "me", "line": 10} for i := 0; i < N; i++ { await := server.await() err = transp.Connect(100 * time.Millisecond) if err != nil { t.Fatalf("Transport client Failed to connect: %v", err) } sock := <-await conn := &mockConn{sock, streambuf.New(nil)} // close socket only once test has finished // so no EOF error can be generated defer sock.Close() // publish event. With client returning on timeout, we have to send // messages again client.Publish([]common.MapStr{event}) // read window msg, err := conn.recvMessage() if err != nil { t.Errorf("Failed receiving window size: %v", err) break } if msg.code != 'W' { t.Errorf("expected window size message") break } // read message msg, err = conn.recvMessage() if err != nil { t.Errorf("Failed receiving data message: %v", err) break } if msg.code != 'C' { t.Errorf("expected data message") break } // do not respond -> enforce timeout // check connection being closed, // timeout required in case of sender not closing the connection // correctly sock.SetDeadline(time.Now().Add(30 * time.Second)) msg, err = conn.recvMessage() if msg != nil { t.Errorf("Received message on connection expected to be closed") break } if nerr, ok := err.(net.Error); ok && nerr.Timeout() { t.Errorf("Unexpected timeout error (client did not close connection in time?): %v", err) break } } client.Stop() returns := client.Returns() if len(returns) != N { t.Fatalf("PublishEvents did not return") } for _, ret := range returns { assert.Equal(t, 0, ret.n) assert.NotNil(t, ret.err) } }
func readMessage(buf *streambuf.Buffer) (*message, error) { if !buf.Avail(2) { return nil, nil } version, _ := buf.ReadNetUint8At(0) if version != '2' { return nil, errors.New("version error") } code, _ := buf.ReadNetUint8At(1) switch code { case 'W': if !buf.Avail(6) { return nil, nil } size, _ := buf.ReadNetUint32At(2) buf.Advance(6) buf.Reset() return &message{code: code, size: size}, buf.Err() case 'C': if !buf.Avail(6) { return nil, nil } len, _ := buf.ReadNetUint32At(2) if !buf.Avail(int(len) + 6) { return nil, nil } buf.Advance(6) tmp, _ := buf.Collect(int(len)) buf.Reset() dataBuf := streambuf.New(nil) // decompress data decomp, err := zlib.NewReader(streambuf.NewFixed(tmp)) if err != nil { return nil, err } // dataBuf.ReadFrom(streambuf.NewFixed(tmp)) dataBuf.ReadFrom(decomp) decomp.Close() // unpack data dataBuf.Fix() var events []*message for dataBuf.Len() > 0 { version, _ := dataBuf.ReadNetUint8() if version != '2' { return nil, errors.New("version error 2") } code, _ := dataBuf.ReadNetUint8() if code != 'J' { return nil, errors.New("expected json data frame") } seq, _ := dataBuf.ReadNetUint32() payloadLen, _ := dataBuf.ReadNetUint32() jsonRaw, _ := dataBuf.Collect(int(payloadLen)) var doc interface{} err = json.Unmarshal(jsonRaw, &doc) if err != nil { return nil, err } events = append(events, &message{ code: code, seq: seq, doc: doc.(map[string]interface{}), }) } return &message{code: 'C', events: events}, nil default: return nil, errors.New("unknown code") } }