aboutsummaryrefslogtreecommitdiff
path: root/kamon-core-tests
diff options
context:
space:
mode:
authorIvan Topolnjak <ivantopo@gmail.com>2018-09-17 12:00:37 +0200
committerIvan Topolnjak <ivantopo@gmail.com>2018-09-17 12:00:42 +0200
commit92876faf942e65eeece30fd9ab89f70759b79dab (patch)
treeba59ff4a4ee987a571f21e13d99214281535456d /kamon-core-tests
parent12d032dec55fbc65fb9db40e181a153f08639cf2 (diff)
downloadKamon-92876faf942e65eeece30fd9ab89f70759b79dab.tar.gz
Kamon-92876faf942e65eeece30fd9ab89f70759b79dab.tar.bz2
Kamon-92876faf942e65eeece30fd9ab89f70759b79dab.zip
create HTTP server metrics tests
Diffstat (limited to 'kamon-core-tests')
-rw-r--r--kamon-core-tests/src/test/scala/kamon/instrumentation/HttpServerInstrumentationSpec.scala151
1 files changed, 149 insertions, 2 deletions
diff --git a/kamon-core-tests/src/test/scala/kamon/instrumentation/HttpServerInstrumentationSpec.scala b/kamon-core-tests/src/test/scala/kamon/instrumentation/HttpServerInstrumentationSpec.scala
index d469725f..19e08666 100644
--- a/kamon-core-tests/src/test/scala/kamon/instrumentation/HttpServerInstrumentationSpec.scala
+++ b/kamon-core-tests/src/test/scala/kamon/instrumentation/HttpServerInstrumentationSpec.scala
@@ -1,13 +1,16 @@
package kamon.instrumentation
+import java.time.Duration
+
import kamon.context.Context
-import kamon.metric.Counter
+import kamon.metric.{Counter, Histogram, RangeSampler}
import kamon.testkit.{MetricInspection, SpanInspection}
+import org.scalatest.concurrent.Eventually
import org.scalatest.{Matchers, OptionValues, WordSpec}
import scala.collection.mutable
-class HttpServerInstrumentationSpec extends WordSpec with Matchers with SpanInspection with OptionValues with MetricInspection {
+class HttpServerInstrumentationSpec extends WordSpec with Matchers with SpanInspection with OptionValues with MetricInspection with Eventually {
"the HTTP server instrumentation" when {
"configured for context propagation" should {
@@ -21,6 +24,9 @@ class HttpServerInstrumentationSpec extends WordSpec with Matchers with SpanInsp
"tag" -> "value",
"none" -> "0011223344556677"
)
+
+ handler.send(fakeResponse(200, mutable.Map.empty), Context.Empty)
+ handler.doneSending(0L)
}
"use the configured HTTP propagation channel" in {
@@ -41,7 +47,130 @@ class HttpServerInstrumentationSpec extends WordSpec with Matchers with SpanInsp
val responseHeaders = mutable.Map.empty[String, String]
handler.send(fakeResponse(200, responseHeaders), handler.context.withTag("hello", "world"))
+ handler.doneSending(0L)
+ }
+ }
+
+ "configured for HTTP server metrics" should {
+ "track the number of open connections" in {
+ openConnections(8081).distribution()
+
+ httpServer().openConnection()
+ httpServer().openConnection()
+ val snapshotWithOpenConnections = openConnections(8081).distribution()
+ snapshotWithOpenConnections.min shouldBe 0
+ snapshotWithOpenConnections.max shouldBe 2
+
+ httpServer().closeConnection(Duration.ofSeconds(20), 10)
+ httpServer().closeConnection(Duration.ofSeconds(30), 15)
+
+ eventually {
+ val snapshotWithoutOpenConnections = openConnections(8081).distribution()
+ snapshotWithoutOpenConnections.min shouldBe 0
+ snapshotWithoutOpenConnections.max shouldBe 0
+ }
+ }
+
+ "track the distribution of number of requests handled per each connection" in {
+ connectionUsage(8081).distribution()
+
+ httpServer().openConnection()
+ httpServer().openConnection()
+ httpServer().closeConnection(Duration.ofSeconds(20), 10)
+ httpServer().closeConnection(Duration.ofSeconds(30), 15)
+
+ val connectionUsageSnapshot = connectionUsage(8081).distribution()
+ connectionUsageSnapshot.buckets.map(_.value) should contain allOf(
+ 10,
+ 15
+ )
+ }
+
+ "track the distribution of connection lifetime across all connections" in {
+ connectionLifetime(8081).distribution()
+
+ httpServer().openConnection()
+ httpServer().openConnection()
+ httpServer().closeConnection(Duration.ofSeconds(20), 10)
+ httpServer().closeConnection(Duration.ofSeconds(30), 15)
+
+ val connectionLifetimeSnapshot = connectionLifetime(8081).distribution()
+ connectionLifetimeSnapshot.buckets.map(_.value) should contain allOf(
+ 19998441472L, // 20 seconds with 1% precision
+ 29930553344L // 30 seconds with 1% precision
+ )
+ }
+
+ "track the number of active requests" in {
+ activeRequests(8081).distribution()
+
+ val handlerOne = httpServer().receive(fakeRequest("http://localhost:8080/", "/", "GET", Map.empty))
+ val handlerTwo = httpServer().receive(fakeRequest("http://localhost:8080/", "/", "GET", Map.empty))
+
+ val snapshotWithActiveRequests = activeRequests(8081).distribution()
+ snapshotWithActiveRequests.min shouldBe 0
+ snapshotWithActiveRequests.max shouldBe 2
+
+ handlerOne.send(fakeResponse(200, mutable.Map.empty), Context.Empty)
+ handlerTwo.send(fakeResponse(200, mutable.Map.empty), Context.Empty)
+ handlerOne.doneSending(0L)
+ handlerTwo.doneSending(0L)
+
+ eventually {
+ val snapshotWithoutActiveRequests = activeRequests(8081).distribution()
+ snapshotWithoutActiveRequests.min shouldBe 0
+ snapshotWithoutActiveRequests.max shouldBe 0
+ }
+ }
+
+ "track the distribution of sizes on incoming requests" in {
+ requestSize(8081).distribution()
+
+ httpServer().receive(fakeRequest("http://localhost:8080/", "/", "GET", Map.empty)).doneReceiving(300)
+ httpServer().receive(fakeRequest("http://localhost:8080/", "/", "GET", Map.empty)).doneReceiving(400)
+
+ val requestSizeSnapshot = requestSize(8081).distribution()
+ requestSizeSnapshot.buckets.map(_.value) should contain allOf(
+ 300,
+ 400
+ )
+ }
+
+ "track the distribution of sizes on outgoing responses" in {
+ responseSize(8081).distribution()
+
+ httpServer().receive(fakeRequest("http://localhost:8080/", "/", "GET", Map.empty)).doneSending(300)
+ httpServer().receive(fakeRequest("http://localhost:8080/", "/", "GET", Map.empty)).doneSending(400)
+
+ val requestSizeSnapshot = responseSize(8081).distribution()
+ requestSizeSnapshot.buckets.map(_.value) should contain allOf(
+ 300,
+ 400
+ )
+ }
+
+ "track the number of responses per status code" in {
+ // resets all counters
+ completedRequests(8081, 100).value()
+ completedRequests(8081, 200).value()
+ completedRequests(8081, 300).value()
+ completedRequests(8081, 400).value()
+ completedRequests(8081, 500).value()
+
+
+ val request = fakeRequest("http://localhost:8080/", "/", "GET", Map.empty)
+ httpServer().receive(request).send(fakeResponse(200, mutable.Map.empty), Context.Empty)
+ httpServer().receive(request).send(fakeResponse(302, mutable.Map.empty), Context.Empty)
+ httpServer().receive(request).send(fakeResponse(404, mutable.Map.empty), Context.Empty)
+ httpServer().receive(request).send(fakeResponse(504, mutable.Map.empty), Context.Empty)
+ httpServer().receive(request).send(fakeResponse(110, mutable.Map.empty), Context.Empty)
+
+ completedRequests(8081, 100).value() shouldBe 1L
+ completedRequests(8081, 200).value() shouldBe 1L
+ completedRequests(8081, 300).value() shouldBe 1L
+ completedRequests(8081, 400).value() shouldBe 1L
+ completedRequests(8081, 500).value() shouldBe 1L
}
}
@@ -165,4 +294,22 @@ class HttpServerInstrumentationSpec extends WordSpec with Matchers with SpanInsp
}
}
+ def openConnections(port: Int): RangeSampler =
+ HttpServer.Metrics.of(TestComponent, TestInterface, port).openConnections
+
+ def connectionUsage(port: Int): Histogram =
+ HttpServer.Metrics.of(TestComponent, TestInterface, port).connectionUsage
+
+ def connectionLifetime(port: Int): Histogram =
+ HttpServer.Metrics.of(TestComponent, TestInterface, port).connectionLifetime
+
+ def activeRequests(port: Int): RangeSampler =
+ HttpServer.Metrics.of(TestComponent, TestInterface, port).activeRequests
+
+ def requestSize(port: Int): Histogram =
+ HttpServer.Metrics.of(TestComponent, TestInterface, port).requestSize
+
+ def responseSize(port: Int): Histogram =
+ HttpServer.Metrics.of(TestComponent, TestInterface, port).responseSize
+
}