Example #1
0
// A unsubscribing client should not be considered for message delivery
func TestQueue_sendMessageAfterUnsubscribe_messageReceivedSuccessfully(t *testing.T) {
	// Need gomega for async testing
	gomega.RegisterTestingT(t)

	testMessagePayload := []byte("Testing!")
	expectedMessagePayload := []byte("Testing!\r\n.\r\n")
	testMessage := message.NewHeaderlessMessage(&testMessagePayload)

	dummyMetricsPipe := make(chan<- *Metric, 10)
	dummyClosingPipe := make(chan<- *string)

	underTest := newMessageQueue(TEST_QUEUE_NAME, dummyMetricsPipe, dummyClosingPipe)

	writerBuffer1 := new(bytes.Buffer)
	dummyWriter1 := bufio.NewWriter(writerBuffer1)
	closedChannel1 := make(chan bool)
	dummyClient1 := Client{Name: "Test1", Writer: dummyWriter1, Closed: &closedChannel1}

	writerBuffer2 := new(bytes.Buffer)
	dummyWriter2 := bufio.NewWriter(writerBuffer2)
	closedChannel2 := make(chan bool)
	dummyClient2 := Client{Name: "Test2", Writer: dummyWriter2, Closed: &closedChannel2}

	// Add the subscription
	underTest.AddSubscriber(&dummyClient1)
	underTest.AddSubscriber(&dummyClient2)

	// Queue the message
	underTest.Publish(testMessage)

	// Bit of a hack - only one of the subscribers will get the message,
	// and we don't know which one
	gomega.Eventually(func() []byte {
		if writerBuffer1.String() == "" {
			return writerBuffer2.Bytes()
		} else {
			return writerBuffer1.Bytes()
		}
	}).Should(gomega.Equal(expectedMessagePayload))

	// We'll be reusing these buffers
	writerBuffer1.Reset()
	writerBuffer2.Reset()

	// Close one client
	*dummyClient1.Closed <- true

	// Should remove the client from the map
	gomega.Eventually(func() bool {
		return underTest.subscribers[dummyClient1.Name] == nil
	}).Should(gomega.BeTrue())

	// Now send a message - the remaining client should receive it without issue
	underTest.Publish(testMessage)

	gomega.Eventually(func() []byte {
		return writerBuffer2.Bytes()
	}).Should(gomega.Equal(expectedMessagePayload))

}
Example #2
0
func TestQueue_EvenNumberOfPushesAndPops_GivesZeroFinalLength(t *testing.T) {
	underTest := NewQueue("Test")
	numberOfRounds := 200

	for i := 0; i < numberOfRounds; i++ {
		dummyMessagePayLoad := []byte{byte(i)}
		dummyMessage := message.NewHeaderlessMessage(&dummyMessagePayLoad)
		underTest.InputChannel <- dummyMessage
	}

	gomega.Eventually(func() int {
		return underTest.length
	}).Should(gomega.Equal(numberOfRounds))

	for i := 0; i < numberOfRounds; i++ {
		message := <-underTest.OutputChannel
		if int((*message.Body)[0]) != i {
			t.Logf("Expected %d, got %d", i, int((*message.Body)[0]))
			t.FailNow()
		}
	}

	gomega.Eventually(func() int {
		return underTest.length
	}).Should(gomega.Equal(0))
}
Example #3
0
// Check that messages sent to a queue are eventually sent to consumers
func TestQueue_sendMessage_messageReceivedSuccessfully(t *testing.T) {
	// Need gomega for async testing
	gomega.RegisterTestingT(t)

	testMessagePayload := []byte("Testing!")
	expectedMessagePayload := []byte("Testing!\r\n.\r\n")
	testMessage := message.NewHeaderlessMessage(&testMessagePayload)

	dummyMetricsPipe := make(chan<- *Metric)
	dummyClosingPipe := make(chan<- *string)
	underTest := newMessageQueue(TEST_QUEUE_NAME, dummyMetricsPipe, dummyClosingPipe)

	writerBuffer := new(bytes.Buffer)
	dummyWriter := bufio.NewWriter(writerBuffer)
	closedChannel := make(chan bool)
	dummyClient := Client{Name: "Test", Writer: dummyWriter, Closed: &closedChannel}

	// Add the subscription
	underTest.AddSubscriber(&dummyClient)

	// Queue the message
	underTest.Publish(testMessage)

	gomega.Eventually(func() []byte {
		return writerBuffer.Bytes()
	}).Should(gomega.Equal(expectedMessagePayload))
}
Example #4
0
func TestQueue_xPendingMetrics_producesCorrectMetric(t *testing.T) {
	// Need gomega for async testing
	gomega.RegisterTestingT(t)

	numberOfMessagesToSend := 10

	testMessagePayload := []byte("Testing!")
	testMessage := message.NewHeaderlessMessage(&testMessagePayload)

	dummyMetricsPipe := make(chan *Metric)
	dummyClosingPipe := make(chan *string)
	underTest := newMessageQueue(TEST_QUEUE_NAME, dummyMetricsPipe, dummyClosingPipe)

	for i := 0; i < numberOfMessagesToSend; i++ {
		underTest.Publish(testMessage)
	}

	// Eventually, we should see `numberOfMessagesToSend` pending messages
	gomega.Eventually(func() int {
		metric := <-dummyMetricsPipe
		if strings.Contains(metric.Name, "pending") {
			return int(metric.Value)
		} else {
			return -1
		}
	}, "5s").Should(gomega.Equal(numberOfMessagesToSend))
}
func TestConnectionManager_whenInitialized_acceptsConnectionsCorrectly(t *testing.T) {
	gomega.RegisterTestingT(t)

	// Choose a high port, so we don't need sudo to run tests
	config := Config{}
	config.Port = 55555
	SetConfig(&config)

	underTest := NewConnectionManager()
	go underTest.Start()

	gomega.Eventually(func() net.Listener {
		return underTest.tcpLn
	}).ShouldNot(gomega.BeNil())

	testConn, err := net.Dial("tcp", "localhost:55555")
	if err != nil || testConn == nil {
		t.Fail()
	}

	fmt.Fprintf(testConn, "PINGREQ\n")
	response, err := bufio.NewReader(testConn).ReadString('\n')

	if err != nil || response != "PINGRESP\n" {
		t.Fail()
	}

	testConn.Close()
}
Example #6
0
func TestQueue_CloseQueueImmediately_ThrowsNoErrors(t *testing.T) {
	gomega.RegisterTestingT(t)
	underTest := NewQueue("Test")

	close(underTest.InputChannel)

	gomega.Eventually(func() bool {
		_, open := <-underTest.OutputChannel
		return open
	}).Should(gomega.BeFalse())
}
Example #7
0
func StartVagrant(provider string) (Agent, error) {
	if len(provider) == 0 {
		provider = "virtualbox"
	}
	command := exec.Command(fmt.Sprintf("./setup_%s.sh", provider))
	session, err := gexec.Start(command, ginkgo.GinkgoWriter, ginkgo.GinkgoWriter)
	if err != nil {
		return Agent{}, err
	}
	gomega.Eventually(session, 20*time.Minute).Should(gexec.Exit(0))

	return Agent{
		ID: agentID,
	}, nil
}
Example #8
0
func TestTokenRefresh(t *testing.T) {
	gomega.RegisterTestingT(t)
	Convey("Test making request", t, func() {
		setup(MockRoute{"GET", "/v2/organizations", listOrgsPayload})
		c := &Config{
			ApiAddress:   server.URL,
			LoginAddress: fakeUAAServer.URL,
			Username:     "******",
			Password:     "******",
		}
		client := NewClient(c)
		gomega.Consistently(client.GetToken()).Should(gomega.Equal("bearer foobar2"))
		gomega.Eventually(client.GetToken(), "3s").Should(gomega.Equal("bearer foobar3"))
	})
}
Example #9
0
func TestQueue_sendMessage_generatesMetrics(t *testing.T) {
	// More async testing
	gomega.RegisterTestingT(t)

	// We should receive metrics ending in these names from a queue during
	// normal operation
	expectedMetricNames := [...]string{"messagerate", "subscribers", "pending"}

	// Mocking
	dummyMetricsChannel := make(chan *Metric)
	dummyClosingChannel := make(chan *string)

	underTest := newMessageQueue(TEST_QUEUE_NAME, dummyMetricsChannel, dummyClosingChannel)

	// After a subscriber is added, we should start receiving metrics
	dummySubscriber := Client{Closed: new(chan bool)}
	underTest.AddSubscriber(&dummySubscriber)

	seenMetricNames := make(map[string]bool)
	go func() {
		for {
			metric := <-dummyMetricsChannel
			metricNameChunks := strings.Split(metric.Name, ".")
			finalMetricName := metricNameChunks[len(metricNameChunks)-1]
			seenMetricNames[finalMetricName] = true
		}
	}()

	// Check we've received metrics ending in all the expected names
	// NOTE: It might take longer than the default gomega 1 second timeout to
	// receive all the metrics we're expecting
	gomega.Eventually(func() bool {
		toReturn := true
		for _, metricName := range expectedMetricNames {
			if !seenMetricNames[metricName] {
				toReturn = false
			}
		}
		return toReturn
	}, "5s").Should(gomega.BeTrue()) //  Timeout upped to 5 seconds
}
Example #10
0
func TestMessageShipper_SuccessfullyForwardsMessages(t *testing.T) {
	gomega.RegisterTestingT(t)

	inputChannel := make(chan *message.Message, 0)

	writerBuffer := new(bytes.Buffer)
	dummyWriter := bufio.NewWriter(writerBuffer)
	closedChannel := make(chan bool)
	dummyClient := Client{Name: "Test", Writer: dummyWriter, Closed: &closedChannel}
	dummyMetricsChannel := make(chan *Metric)

	underTest := newMessageShipper(inputChannel, &dummyClient, dummyMetricsChannel, "test")

	testMessagePayload := []byte("This is a test!")
	expectedMessagePayload := []byte("This is a test!\r\n.\r\n")
	testMessage := message.NewHeaderlessMessage(&testMessagePayload)
	underTest.messageChannel <- testMessage

	gomega.Eventually(func() []byte {
		return writerBuffer.Bytes()
	}).Should(gomega.Equal(expectedMessagePayload))
}
func TestConnectionManager_disconnectCommand_removesClient(t *testing.T) {
	gomega.RegisterTestingT(t)

	underTest := ConnectionManager{}

	buf := new(bytes.Buffer)
	bufWriter := bufio.NewWriter(buf)
	mockClient := NewClient("Mock", bufWriter, nil)
	closedChannel := make(chan bool, 1)
	mockClient.Closed = &closedChannel

	t.Log("Disconnecting")

	var emptyMessage []byte

	underTest.parseClientCommand([]string{"disconnect"}, &emptyMessage, mockClient)

	gomega.Eventually(func() bool {
		closed := <-*(mockClient.Closed)
		return closed
	}).Should(gomega.BeTrue())
}
Example #12
0
func TestQueue_ReceiveBeforeSend_ReturnsExpectedResult(t *testing.T) {
	gomega.RegisterTestingT(t)

	underTest := NewQueue("TestQueue")

	var receivedMessage *message.Message
	go func() {
		receivedMessage = <-underTest.OutputChannel
	}()

	time.Sleep(time.Millisecond * 10)

	testMessagePayload := []byte("TestMessage")
	underTest.InputChannel <- (message.NewHeaderlessMessage(&testMessagePayload))

	gomega.Eventually(func() *message.Message {
		return receivedMessage
	}).Should(gomega.Not(gomega.BeNil()))

	if !bytes.Equal(*receivedMessage.Body, testMessagePayload) {
		t.Fail()
	}
}
Example #13
0
func tryEchoUDP(svc *kapi.Service) error {
	rawIP := svc.Spec.ClusterIP
	o.Expect(rawIP).NotTo(o.BeEmpty(), "The service should have a cluster IP set")
	ip := net.ParseIP(rawIP)
	o.Expect(ip).NotTo(o.BeNil(), "The service should have a valid cluster IP, but %q was not valid", rawIP)

	var udpPort int
	for _, port := range svc.Spec.Ports {
		if port.Protocol == "UDP" {
			udpPort = int(port.Port)
			break
		}
	}
	o.Expect(udpPort).NotTo(o.Equal(0), "The service should have a UDP port exposed")

	// For UDP, we just drop packets on the floor rather than queue them up
	readTimeout := 5 * time.Second

	expectedBuff := []byte("It's time to UDP!\n")
	o.Eventually(func() ([]byte, error) { return tryEchoUDPOnce(ip, udpPort, expectedBuff, readTimeout) }, 2*time.Minute, readTimeout).Should(o.Equal(expectedBuff))

	return nil
}
Example #14
0
// Reusing the same (closed) channel name shouldn't make us crash
// Wait between sub/unsub operations to make sure metrics are sent proparly
func TestQueueManager_queuesClosed_removedFromMap(t *testing.T) {
	config := Config{}
	SetConfig(&config)

	underTest := newQueueManager()

	// Create dummy clients
	dummyClient := Client{}
	dummyClient.Name = "Dummy"
	closedChannel := make(chan bool)
	dummyClient.Closed = &closedChannel

	// Subscribe
	underTest.Subscribe(TestQueueName, &dummyClient)

	// Close the queue
	*dummyClient.Closed <- true

	// Check that TestQueueName is removed from the QueueManager map
	gomega.Eventually(func() bool {
		return underTest.queues[TestQueueName] != nil
	}).Should(gomega.BeTrue())
}
Example #15
0
func TestMetricsManager_ReceivesBasicMetric_PublishesDownstreamAndSendsToStatsD(t *testing.T) {
	gomega.RegisterTestingT(t)

	// Listen on UDP
	var statsDBuffer [2048]byte
	var udpPacketsReceived int
	udpAddr, _ := net.ResolveUDPAddr("udp", ":0")
	udpConn, _ := net.ListenUDP("udp", udpAddr)

	// Don't care about the contents of the received messages - just the fact
	// that we received them. We trust the StatsD library
	go func() {
		for i := 0; i < 3; i++ {
			_, _, _ = udpConn.ReadFromUDP(statsDBuffer[0:])
			udpPacketsReceived++
		}
	}()

	config := Config{StatsDEndpoint: fmt.Sprintf("localhost:%d", udpConn.LocalAddr().(*net.UDPAddr).Port)}
	SetConfig(&config)

	qm := newQueueManager()

	// Listen to metrics queue
	writerBuffer := new(bytes.Buffer)
	dummyWriter := bufio.NewWriter(writerBuffer)
	closedChannel := make(chan bool)
	dummyClient := Client{Name: "Test", Writer: dummyWriter, Closed: &closedChannel}

	qm.Subscribe("metrics", &dummyClient)

	// Log one of each metric
	// Check we've received metrics both via UDP - and on the metrics channel
	testMetric := NewMetric("test", "guage", 123)
	qm.metricsManager.metricsChannel <- testMetric

	gomega.Eventually(func() int {
		return udpPacketsReceived
	}, "2s").Should(gomega.Equal(1))

	gomega.Eventually(func() []byte {
		return writerBuffer.Bytes()
	}).ShouldNot(gomega.BeNil())

	writerBuffer.Reset()

	testMetric2 := NewMetric("test", "counter", 123)
	qm.metricsManager.metricsChannel <- testMetric2

	gomega.Eventually(func() int {
		return udpPacketsReceived
	}, "2s").Should(gomega.Equal(2))

	gomega.Eventually(func() []byte {
		return writerBuffer.Bytes()
	}).ShouldNot(gomega.BeNil())

	writerBuffer.Reset()

	testMetric3 := NewMetric("test", "timing", 123)
	qm.metricsManager.metricsChannel <- testMetric3

	gomega.Eventually(func() int {
		return udpPacketsReceived
	}, "2s").Should(gomega.Equal(3))

	gomega.Eventually(func() []byte {
		return writerBuffer.Bytes()
	}).ShouldNot(gomega.BeNil())

	writerBuffer.Reset()
}