func TestThatItSends(t *testing.T) {
	receivedChan := make(chan []byte, 2)

	expectedMessageString := "Some data"
	expectedMessage := testhelpers.MarshalledLogMessage(t, expectedMessageString, "myApp")
	otherMessageString := "Some more stuff"
	otherMessage := testhelpers.MarshalledLogMessage(t, otherMessageString, "myApp")

	testhelpers.AddWSSink(t, receivedChan, SERVER_PORT, TAIL_PATH+"?app=myApp", testhelpers.VALID_SPACE_AUTHENTICATION_TOKEN)
	WaitForWebsocketRegistration()

	dataReadChannel <- expectedMessage
	dataReadChannel <- otherMessage

	select {
	case <-time.After(1 * time.Second):
		t.Errorf("Did not get message 1.")
	case message := <-receivedChan:
		testhelpers.AssertProtoBufferMessageEquals(t, expectedMessageString, message)
	}

	select {
	case <-time.After(1 * time.Second):
		t.Errorf("Did not get message 2.")
	case message := <-receivedChan:
		testhelpers.AssertProtoBufferMessageEquals(t, otherMessageString, message)
	}
}
func TestAddingForAnotherApp(t *testing.T) {
	store := NewMessageStore(2)

	appId := "myApp"
	message, err := logmessage.ParseMessage(testhelpers.MarshalledLogMessage(t, "Message", appId))
	assert.NoError(t, err)
	store.Add(message, appId)

	anotherAppId := "anotherApp"
	anotherAppMessage, err := logmessage.ParseMessage(testhelpers.MarshalledLogMessage(t, "AnotherAppMessage", anotherAppId))
	assert.NoError(t, err)
	store.Add(anotherAppMessage, anotherAppId)

	messages, err := testhelpers.ParseDumpedMessages(store.DumpFor(appId))
	assert.NoError(t, err)

	assert.Equal(t, len(messages), 1)
	assert.Equal(t, message.GetRawMessage(), messages[0])

	messages, err = testhelpers.ParseDumpedMessages(store.DumpFor(anotherAppId))
	assert.NoError(t, err)

	assert.Equal(t, len(messages), 1)
	assert.Equal(t, anotherAppMessage.GetRawMessage(), messages[0])
}
func TestThatItSendsAllDataToAllSinks(t *testing.T) {
	client1ReceivedChan := make(chan []byte)
	client2ReceivedChan := make(chan []byte)

	testhelpers.AddWSSink(t, client1ReceivedChan, SERVER_PORT, TAIL_PATH+"?app=myApp", testhelpers.VALID_SPACE_AUTHENTICATION_TOKEN)
	testhelpers.AddWSSink(t, client2ReceivedChan, SERVER_PORT, TAIL_PATH+"?app=myApp", testhelpers.VALID_SPACE_AUTHENTICATION_TOKEN)
	WaitForWebsocketRegistration()

	expectedMessageString := "Some Data"
	expectedMarshalledProtoBuffer := testhelpers.MarshalledLogMessage(t, expectedMessageString, "myApp")

	dataReadChannel <- expectedMarshalledProtoBuffer

	select {
	case <-time.After(200 * time.Millisecond):
		t.Errorf("Did not get message from client 1.")
	case message := <-client1ReceivedChan:
		testhelpers.AssertProtoBufferMessageEquals(t, expectedMessageString, message)
	}

	select {
	case <-time.After(200 * time.Millisecond):
		t.Errorf("Did not get message from client 2.")
	case message := <-client2ReceivedChan:
		testhelpers.AssertProtoBufferMessageEquals(t, expectedMessageString, message)
	}
}
// *** Start Syslog Sink tests
func TestThatItSendsAllMessageToKnownDrains(t *testing.T) {
	client1ReceivedChan := make(chan []byte)

	fakeSyslogDrain, err := NewService(client1ReceivedChan, "127.0.0.1:34566")
	defer fakeSyslogDrain.Stop()
	assert.NoError(t, err)
	go fakeSyslogDrain.Serve()
	<-fakeSyslogDrain.readyChan

	expectedMessageString := "Some Data"
	expectedMarshalledProtoBuffer := testhelpers.MarshalledDrainedLogMessage(t, expectedMessageString, "myApp", "syslog://localhost:34566")

	expectedSecondMessageString := "Some Data Without a drainurl"
	expectedSecondMarshalledProtoBuffer := testhelpers.MarshalledLogMessage(t, expectedSecondMessageString, "myApp")

	dataReadChannel <- expectedMarshalledProtoBuffer

	select {
	case <-time.After(200 * time.Millisecond):
		t.Errorf("Did not get the first message")
	case message := <-client1ReceivedChan:
		assert.Contains(t, string(message), expectedMessageString)
	}

	dataReadChannel <- expectedSecondMarshalledProtoBuffer

	select {
	case <-time.After(200 * time.Millisecond):
		t.Errorf("Did not get the second message")
	case message := <-client1ReceivedChan:
		assert.Contains(t, string(message), expectedSecondMessageString)
	}
}
func TestItDumpsAllMessagesForAnAppUser(t *testing.T) {
	expectedMessageString := "Some data"
	expectedMessage := testhelpers.MarshalledLogMessage(t, expectedMessageString, "myApp")

	dataReadChannel <- expectedMessage

	req, err := http.NewRequest("GET", "http://localhost:"+SERVER_PORT+DUMP_PATH+"?app=myApp", nil)
	assert.NoError(t, err)
	req.Header.Add("Authorization", testhelpers.VALID_SPACE_AUTHENTICATION_TOKEN)

	resp, err := http.DefaultClient.Do(req)
	assert.NoError(t, err)

	assert.Equal(t, resp.Header.Get("Content-Type"), "application/octet-stream")
	assert.Equal(t, resp.StatusCode, 200)

	body, err := ioutil.ReadAll(resp.Body)
	assert.NoError(t, err)
	resp.Body.Close()

	messages, err := testhelpers.ParseDumpedMessages(body)
	assert.NoError(t, err)

	testhelpers.AssertProtoBufferMessageEquals(t, expectedMessageString, messages[len(messages)-1])
}
func TestThatItWorksLikeAChannel(t *testing.T) {
	inMessageChan := make(chan *logmessage.Message)
	outMessageChan := make(chan *logmessage.Message, 2)
	go OverwritingMessageChannel(inMessageChan, outMessageChan, nil)

	logMessage1, err := logmessage.ParseMessage(testhelpers.MarshalledLogMessage(t, "message 1", "appId"))
	assert.NoError(t, err)
	inMessageChan <- logMessage1
	readMessage := <-outMessageChan
	assert.Contains(t, string(readMessage.GetRawMessage()), "message 1")

	logMessage2, err := logmessage.ParseMessage(testhelpers.MarshalledLogMessage(t, "message 2", "appId"))
	assert.NoError(t, err)
	inMessageChan <- logMessage2
	readMessage2 := <-outMessageChan
	assert.Contains(t, string(readMessage2.GetRawMessage()), "message 2")

}
func TestThatItSendsStdOutAsInfo(t *testing.T) {
	sink, err := NewSyslogSink("appId", "syslog://localhost:24631", testhelpers.Logger())
	assert.NoError(t, err)
	closeChan := make(chan Sink)
	go sink.Run(closeChan)
	logMessage, err := logmessage.ParseMessage(testhelpers.MarshalledLogMessage(t, "hi", "appId"))
	assert.NoError(t, err)
	sink.Channel() <- logMessage
	data := <-dataReadChannel
	assert.Contains(t, string(data), "<6>")
	assert.Contains(t, string(data), "appId")
	assert.Contains(t, string(data), "hi")
}
// This test exists because the ring buffer will dump messages
// that actually exist.
func TestOnlyDumpsMessagesThatHaveALength(t *testing.T) {
	store := NewMessageStore(2)

	target := "appId"
	message, err := logmessage.ParseMessage(testhelpers.MarshalledLogMessage(t, "Hello world", target))
	assert.NoError(t, err)
	store.Add(message, target)

	messages, err := testhelpers.ParseDumpedMessages(store.DumpFor(target))
	assert.NoError(t, err)

	assert.Equal(t, len(messages), 1)
	assert.Equal(t, messages[0], message.GetRawMessage())
}
func TestRegisterAndFor(t *testing.T) {
	store := NewMessageStore(2)

	appId := "myApp"
	appMessageString := "AppMessage"
	appMessage := testhelpers.MarshalledLogMessage(t, appMessageString, "myApp")
	message, err := logmessage.ParseMessage(appMessage)

	store.Add(message, appId)

	messages, err := testhelpers.ParseDumpedMessages(store.DumpFor(appId))
	assert.NoError(t, err)

	assert.Equal(t, len(messages), 1)

	testhelpers.AssertProtoBufferMessageEquals(t, appMessageString, messages[0])
}
func TestDropUnmarshallableMessage(t *testing.T) {
	receivedChan := make(chan []byte)

	sink, _, _ := testhelpers.AddWSSink(t, receivedChan, SERVER_PORT, TAIL_PATH+"?app=myApp", testhelpers.VALID_SPACE_AUTHENTICATION_TOKEN)
	WaitForWebsocketRegistration()

	dataReadChannel <- make([]byte, 10)

	time.Sleep(1 * time.Millisecond)
	select {
	case msg1 := <-receivedChan:
		t.Errorf("We should not have received a message, but got: %v", msg1)
	default:
		//no communication. That's good!
	}

	sink.Close()
	expectedMessageString := "My important message"
	mySpaceMarshalledMessage := testhelpers.MarshalledLogMessage(t, expectedMessageString, "myApp")
	dataReadChannel <- mySpaceMarshalledMessage
}
func TestEndtoEndMessage(t *testing.T) {
	logger := gosteno.NewLogger("TestLogger")
	listener := agentlistener.NewAgentListener("localhost:3456", logger)
	dataChannel := listener.Start()
	sinkServer := sinkserver.NewSinkServer(messagestore.NewMessageStore(10), logger, testhelpers.SuccessfulAuthorizer, 30*time.Second)
	go sinkServer.Start(dataChannel, "localhost:8081")
	time.Sleep(1 * time.Millisecond)

	receivedChan := make(chan []byte)
	ws, _, _ := testhelpers.AddWSSink(t, receivedChan, "8081", "/tail/?app=myApp", testhelpers.VALID_SPACE_AUTHENTICATION_TOKEN)
	defer ws.Close()
	time.Sleep(50 * time.Millisecond)

	connection, err := net.Dial("udp", "localhost:3456")

	expectedMessageString := "Some Data"
	expectedMessage := testhelpers.MarshalledLogMessage(t, expectedMessageString, "myApp")

	_, err = connection.Write(expectedMessage)
	assert.NoError(t, err)

	testhelpers.AssertProtoBufferMessageEquals(t, expectedMessageString, <-receivedChan)
}
func TestKeepAlive(t *testing.T) {
	receivedChan := make(chan []byte)

	_, killKeepAliveChan, _ := testhelpers.AddWSSink(t, receivedChan, SERVER_PORT, TAIL_PATH+"?app=myApp", testhelpers.VALID_SPACE_AUTHENTICATION_TOKEN)
	WaitForWebsocketRegistration()

	killKeepAliveChan <- true

	time.Sleep(60 * time.Millisecond) //wait a little bit to make sure the keep-alive has successfully been stopped

	expectedMessageString := "My important message"
	myAppsMarshalledMessage := testhelpers.MarshalledLogMessage(t, expectedMessageString, "myApp")
	dataReadChannel <- myAppsMarshalledMessage

	time.Sleep(10 * time.Millisecond) //wait a little bit to give a potential message time to arrive

	select {
	case msg1 := <-receivedChan:
		t.Errorf("We should not have received a message, but got: %v", msg1)
	default:
		//no communication. That's good!
	}
}