Beispiel #1
0
func (s *TestSuite) TestChannelsAfterReconnect(t *C) {
	/**
	 * Client send/recv chans should work after disconnect and reconnect.
	 */

	ws, err := client.NewWebsocketClient(s.logger, s.api, "agent", nil)
	t.Assert(err, IsNil)

	ws.Start()
	defer ws.Stop()
	defer ws.Disconnect()

	ws.Connect()
	c := <-mock.ClientConnectChan
	<-ws.ConnectChan() // connect ack

	// Send cmd and wait for reply to ensure we're fully connected.
	cmd := &proto.Cmd{
		User: "******",
		Ts:   time.Now(),
		Cmd:  "Status",
	}
	c.SendChan <- cmd
	got := test.WaitCmd(ws.RecvChan())
	t.Assert(len(got), Equals, 1)
	reply := cmd.Reply(nil, nil)
	ws.SendChan() <- reply
	data := test.WaitData(c.RecvChan)
	t.Assert(len(data), Equals, 1)

	// Disconnect client.
	mock.DisconnectClient(c)
	<-ws.ConnectChan() // disconnect ack

	// Reconnect client and send/recv again.
	ws.Connect()
	c = <-mock.ClientConnectChan
	<-ws.ConnectChan() // connect ack

	c.SendChan <- cmd
	got = test.WaitCmd(ws.RecvChan())
	t.Assert(len(got), Equals, 1)
	reply = cmd.Reply(nil, nil)
	ws.SendChan() <- reply
	data = test.WaitData(c.RecvChan)
	t.Assert(len(data), Equals, 1)
}
func (s *TestSuite) TestChannels(t *C) {
	/**
	 * Agent uses send/recv channels instead of "direct" interface.
	 */

	ws, err := client.NewWebsocketClient(s.logger, s.api, "agent")
	t.Assert(err, IsNil)

	// Start send/recv chans, but idle until successful Connect.
	ws.Start()
	defer ws.Stop()

	ws.Connect()
	c := <-mock.ClientConnectChan
	<-ws.ConnectChan()

	// API sends Cmd to client.
	cmd := &proto.Cmd{
		User: "******",
		Ts:   time.Now(),
		Cmd:  "Status",
	}
	c.SendChan <- cmd

	// If client's recvChan is working, it will receive the Cmd.
	got := test.WaitCmd(ws.RecvChan())
	t.Assert(len(got), Equals, 1)
	t.Assert(got[0], DeepEquals, *cmd)

	// Client sends Reply in response to Cmd.
	reply := cmd.Reply(nil, nil)
	ws.SendChan() <- reply

	// If client's sendChan is working, we/API will receive the Reply.
	data := test.WaitData(c.RecvChan)
	t.Assert(len(data), Equals, 1)

	// We're dealing with generic data again.
	m := data[0].(map[string]interface{})
	t.Assert(m["Cmd"], Equals, "Status")
	t.Assert(m["Error"], Equals, "")

	err = ws.Disconnect()
	t.Assert(err, IsNil)
}
Beispiel #3
0
func (s *TestSuite) TestSendBytes(t *C) {
	ws, err := client.NewWebsocketClient(s.logger, s.api, "agent", nil)
	t.Assert(err, IsNil)

	ws.ConnectOnce(5)
	c := <-mock.ClientConnectChan

	data := []byte(`["Hello"]`)
	err = ws.SendBytes(data, 5)
	t.Assert(err, IsNil)

	// Recv what we just sent.
	got := test.WaitData(c.RecvChan)
	t.Assert(len(got), Equals, 1)
	gotData := got[0].([]interface{})
	t.Check(gotData[0].(string), Equals, "Hello")

	ws.DisconnectOnce()
}
Beispiel #4
0
func (s *TestSuite) TestWssConnection(t *C) {
	/**
	 * This test ensures our slighly customized wss connectio handling works,
	 * i.e. that TLS works.  Only drawback is: client disables cert verification
	 * because the mock ws server uses a self-signed cert, but this only happens
	 * when the remote addr is localhost:8443, so it shouldn't affect real connections.
	 */
	ws, err := client.NewWebsocketClient(s.logger, s.apiWss, "agent", nil)
	t.Assert(err, IsNil)

	// Client sends state of connection (true=connected, false=disconnected)
	// on its ConnectChan.
	connected := false
	doneChan := make(chan bool)
	go func() {
		connected = <-ws.ConnectChan()
		doneChan <- true
	}()

	// Wait for connection in mock ws server.
	ws.Connect()
	c := <-mock.ClientConnectChanWss

	<-doneChan
	t.Check(connected, Equals, true)

	// Send a log entry.
	logEntry := &proto.LogEntry{
		Level:   2,
		Service: "qan",
		Msg:     "Hello",
	}
	err = ws.Send(logEntry, 5)
	t.Assert(err, IsNil)

	// Recv what we just sent.
	got := test.WaitData(c.RecvChanWss)
	t.Assert(len(got), Equals, 1)

	ws.Conn().Close()
}
Beispiel #5
0
func (s *TestSuite) TestCloseTimeout(t *C) {
	// https://jira.percona.com/browse/PCT-1045

	ws, err := client.NewWebsocketClient(s.logger, s.api, "agent", nil)
	t.Assert(err, IsNil)

	connected := false
	doneChan := make(chan bool)
	go func() {
		connected = <-ws.ConnectChan()
		doneChan <- true
	}()

	// Wait for connection in mock ws server.
	ws.Connect()
	c := <-mock.ClientConnectChan

	<-doneChan
	t.Check(connected, Equals, true)

	// Send a log entry.
	logEntry := &proto.LogEntry{
		Level:   2,
		Service: "qan",
		Msg:     "Hello",
	}
	err = ws.Send(logEntry, 1)
	t.Assert(err, IsNil)

	// Recv what we just sent.
	got := test.WaitData(c.RecvChan)
	t.Assert(len(got), Equals, 1)

	// Wait 1s for that ^ 1s timeout to pass.
	time.Sleep(1400 * time.Millisecond)

	err = ws.Disconnect()
	t.Check(err, IsNil)
}
Beispiel #6
0
func (s *TestSuite) TestSend(t *C) {
	/**
	 * LogRelay (logrelay/) uses "direct" interface, not send/recv chans.
	 */

	ws, err := client.NewWebsocketClient(s.logger, s.api, "agent", nil)
	t.Assert(err, IsNil)

	// Client sends state of connection (true=connected, false=disconnected)
	// on its ConnectChan.
	connected := false
	doneChan := make(chan bool)
	go func() {
		connected = <-ws.ConnectChan()
		doneChan <- true
	}()

	// Wait for connection in mock ws server.
	ws.Connect()
	c := <-mock.ClientConnectChan

	<-doneChan
	t.Check(connected, Equals, true)

	// Send a log entry.
	logEntry := &proto.LogEntry{
		Level:   2,
		Service: "qan",
		Msg:     "Hello",
	}
	err = ws.Send(logEntry, 5)
	t.Assert(err, IsNil)

	// Recv what we just sent.
	got := test.WaitData(c.RecvChan)
	t.Assert(len(got), Equals, 1)

	// We're dealing with generic data.
	m := got[0].(map[string]interface{})
	t.Check(m["Level"], Equals, float64(2))
	t.Check(m["Service"], Equals, "qan")
	t.Check(m["Msg"], Equals, "Hello")

	// Quick check that Conn() works.
	conn := ws.Conn()
	t.Check(conn, NotNil)

	// Status should report connected to the proper link.
	status := ws.Status()
	t.Check(status, DeepEquals, map[string]string{
		"ws":      "Connected " + URL,
		"ws-link": URL,
	})

	ws.Disconnect()

	select {
	case connected = <-ws.ConnectChan():
	case <-time.After(1 * time.Second):
		t.Error("No connected=false notify on Disconnect()")
	}

	// Status should report disconnected and still the proper link.
	status = ws.Status()
	t.Check(status, DeepEquals, map[string]string{
		"ws":      "Disconnected",
		"ws-link": URL,
	})
}