github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/atc/metric/emitter/newrelic_test.go (about) 1 package emitter_test 2 3 import ( 4 "compress/gzip" 5 "encoding/json" 6 "fmt" 7 "io/ioutil" 8 "net/http" 9 "time" 10 11 "code.cloudfoundry.org/lager" 12 "github.com/pf-qiu/concourse/v6/atc/metric" 13 "github.com/pf-qiu/concourse/v6/atc/metric/emitter" 14 15 . "github.com/onsi/ginkgo" 16 . "github.com/onsi/ginkgo/extensions/table" 17 . "github.com/onsi/gomega" 18 . "github.com/onsi/gomega/ghttp" 19 ) 20 21 var _ = Describe("NewRelicEmitter", func() { 22 23 var ( 24 testEmitter emitter.NewRelicEmitter 25 server *Server 26 client *http.Client 27 testEvent metric.Event 28 testLogger lager.Logger 29 ) 30 31 BeforeEach(func() { 32 testEvent = metric.Event{ 33 Name: "build started", 34 Value: 1, 35 } 36 37 testLogger = lager.NewLogger("newrelic") 38 39 server = NewServer() 40 41 client = &http.Client{ 42 Transport: &http.Transport{}, 43 Timeout: time.Minute, 44 } 45 }) 46 47 AfterEach(func() { 48 server.Close() 49 }) 50 51 Context("Emits metrics", func() { 52 Context("when batch size is 2", func() { 53 BeforeEach(func() { 54 testEmitter = emitter.NewRelicEmitter{ 55 NewRelicBatch: make([]emitter.NewRelicEvent, 0), 56 BatchDuration: 100 * time.Second, 57 BatchSize: 2, 58 LastEmitTime: time.Now(), 59 Url: server.URL(), 60 Client: client, 61 } 62 }) 63 It("should write one batch to NewRelic", func() { 64 server.RouteToHandler(http.MethodPost, "/", verifyEvents(2)) 65 for i := 0; i < 3; i++ { 66 testEmitter.Emit(testLogger, testEvent) 67 } 68 Eventually(server.ReceivedRequests).Should(HaveLen(1)) 69 Expect(testEmitter.NewRelicBatch).To(HaveLen(1)) 70 }) 71 It("should write two batches to NewRelic", func() { 72 server.RouteToHandler(http.MethodPost, "/", verifyEvents(2)) 73 server.RouteToHandler(http.MethodPost, "/", verifyEvents(2)) 74 for i := 0; i < 4; i++ { 75 testEmitter.Emit(testLogger, testEvent) 76 } 77 Eventually(server.ReceivedRequests).Should(HaveLen(2)) 78 Expect(testEmitter.NewRelicBatch).To(HaveLen(0)) 79 }) 80 It("should write no batches to NewRelic", func() { 81 testEmitter.Emit(testLogger, testEvent) 82 83 time.Sleep(500 * time.Millisecond) 84 Eventually(server.ReceivedRequests).Should(HaveLen(0)) 85 Expect(testEmitter.NewRelicBatch).To(HaveLen(1)) 86 }) 87 }) 88 Context("when batch duration is 1 millisecond", func() { 89 BeforeEach(func() { 90 testEmitter = emitter.NewRelicEmitter{ 91 NewRelicBatch: make([]emitter.NewRelicEvent, 0), 92 BatchDuration: 1 * time.Millisecond, 93 BatchSize: 100, 94 LastEmitTime: time.Now(), 95 Url: server.URL(), 96 Client: client, 97 } 98 }) 99 It("should write one batch to NewRelic", func() { 100 server.RouteToHandler(http.MethodPost, "/", verifyEvents(1)) 101 time.Sleep(1 * time.Millisecond) 102 testEmitter.Emit(testLogger, testEvent) 103 Eventually(server.ReceivedRequests).Should(HaveLen(1)) 104 Expect(testEmitter.NewRelicBatch).To(HaveLen(0)) 105 }) 106 It("should write two batches to NewRelic", func() { 107 server.RouteToHandler(http.MethodPost, "/", verifyEvents(1)) 108 server.RouteToHandler(http.MethodPost, "/", verifyEvents(1)) 109 for i := 0; i < 2; i++ { 110 time.Sleep(1 * time.Millisecond) 111 testEmitter.Emit(testLogger, testEvent) 112 } 113 Eventually(server.ReceivedRequests).Should(HaveLen(2)) 114 Expect(testEmitter.NewRelicBatch).To(HaveLen(0)) 115 }) 116 It("should write no batches to NewRelic", func() { 117 testEmitter.Emit(testLogger, testEvent) 118 Eventually(server.ReceivedRequests).Should(HaveLen(0)) 119 Expect(testEmitter.NewRelicBatch).To(HaveLen(1)) 120 121 }) 122 }) 123 124 DescribeTable("Compression", func(compressionState bool, expectedEncoding string) { 125 testEmitter = emitter.NewRelicEmitter{ 126 NewRelicBatch: make([]emitter.NewRelicEvent, 0), 127 BatchDuration: 100 * time.Second, 128 BatchSize: 1, 129 LastEmitTime: time.Now(), 130 Url: server.URL(), 131 Client: client, 132 DisableCompression: compressionState, 133 } 134 135 server.RouteToHandler(http.MethodPost, "/", verifyEvents(1)) 136 137 testEmitter.Emit(testLogger, testEvent) 138 Eventually(server.ReceivedRequests).Should(HaveLen(1)) 139 request := (server.ReceivedRequests())[0] 140 Expect(request.Header.Get("Content-Encoding")).To(Equal(expectedEncoding)) 141 }, 142 Entry("is enabled", false, "gzip"), 143 Entry("is disabled", true, ""), 144 ) 145 }) 146 147 Context("NewRelicConfiguration", func() { 148 It("sends events to configured endpoint", func() { 149 config := &emitter.NewRelicConfig{ 150 AccountID: "123456", 151 APIKey: "eu019347923874648573934074", 152 Url: server.URL(), 153 } 154 155 server.RouteToHandler(http.MethodPost, "/v1/accounts/123456/events", verifyEvents(1)) 156 157 e, _ := config.NewEmitter() 158 e.Emit(testLogger, testEvent) 159 160 newRelicEmitter := e.(*emitter.NewRelicEmitter) 161 Expect(newRelicEmitter.Url).To(Equal(fmt.Sprintf("%s/v1/accounts/123456/events", server.URL()))) 162 Eventually(server.ReceivedRequests).Should(HaveLen(1)) 163 }) 164 }) 165 }) 166 167 func verifyEvents(expectedEvents int) http.HandlerFunc { 168 return func(writer http.ResponseWriter, request *http.Request) { 169 var ( 170 givenBody []byte 171 err error 172 ) 173 174 if request.Header.Get("Content-Encoding") == "gzip" { 175 reader, err := gzip.NewReader(request.Body) 176 Expect(err).To(Not(HaveOccurred())) 177 givenBody, err = ioutil.ReadAll(reader) 178 Expect(err).To(Not(HaveOccurred())) 179 } else { 180 givenBody, err = ioutil.ReadAll(request.Body) 181 Expect(err).To(Not(HaveOccurred())) 182 } 183 184 var events []emitter.NewRelicEvent 185 err = json.Unmarshal(givenBody, &events) 186 Expect(err).To(Not(HaveOccurred())) 187 188 Expect(len(events)).To(BeNumerically("==", expectedEvents)) 189 190 for _, event := range events { 191 Expect(event["eventType"]).To(Equal("build_started")) 192 Expect(event["value"]).To(Equal(float64(1))) 193 } 194 195 writer.WriteHeader(http.StatusOK) 196 } 197 }