// 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)) }
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)) }
// 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)) }
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() }
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()) }
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 }
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")) }) }
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 }
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()) }
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() } }
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 }
// 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()) }
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() }