aboutsummaryrefslogtreecommitdiff
path: root/kamon-core-tests/src
diff options
context:
space:
mode:
Diffstat (limited to 'kamon-core-tests/src')
-rw-r--r--kamon-core-tests/src/test/scala/kamon/context/BinaryPropagationSpec.scala12
-rw-r--r--kamon-core-tests/src/test/scala/kamon/context/HttpPropagationSpec.scala21
-rw-r--r--kamon-core-tests/src/test/scala/kamon/instrumentation/HttpServerInstrumentationSpec.scala13
-rw-r--r--kamon-core-tests/src/test/scala/kamon/tag/TagSetSpec.scala180
4 files changed, 204 insertions, 22 deletions
diff --git a/kamon-core-tests/src/test/scala/kamon/context/BinaryPropagationSpec.scala b/kamon-core-tests/src/test/scala/kamon/context/BinaryPropagationSpec.scala
index 5681d300..4fa7116d 100644
--- a/kamon-core-tests/src/test/scala/kamon/context/BinaryPropagationSpec.scala
+++ b/kamon-core-tests/src/test/scala/kamon/context/BinaryPropagationSpec.scala
@@ -6,6 +6,8 @@ import com.typesafe.config.ConfigFactory
import kamon.Kamon
import kamon.context.BinaryPropagation.{ByteStreamReader, ByteStreamWriter}
import kamon.context.Propagation.{EntryReader, EntryWriter}
+import kamon.tag.TagSet
+import kamon.tag.Lookups._
import org.scalatest.{Matchers, OptionValues, WordSpec}
import scala.util.Random
@@ -70,13 +72,14 @@ class BinaryPropagationSpec extends WordSpec with Matchers with OptionValues {
}
"round trip a Context that only has tags" in {
- val context = Context.of(Map("hello" -> "world", "kamon" -> "rulez"))
+ val context = Context.of(TagSet.from(Map("hello" -> "world", "kamon" -> "rulez")))
val writer = inspectableByteStreamWriter()
binaryPropagation.write(context, writer)
val rtContext = binaryPropagation.read(ByteStreamReader.of(writer.toByteArray))
rtContext.entries shouldBe empty
- rtContext.tags should contain theSameElementsAs (context.tags)
+ rtContext.tags.get(plain("hello")) shouldBe "world"
+ rtContext.tags.get(plain("kamon")) shouldBe "rulez"
}
"round trip a Context that only has entries" in {
@@ -91,7 +94,7 @@ class BinaryPropagationSpec extends WordSpec with Matchers with OptionValues {
}
"round trip a Context that with tags and entries" in {
- val context = Context.of(Map("hello" -> "world", "kamon" -> "rulez"))
+ val context = Context.of(TagSet.from(Map("hello" -> "world", "kamon" -> "rulez")))
.withKey(BinaryPropagationSpec.StringKey, "string-value")
.withKey(BinaryPropagationSpec.IntegerKey, 42)
@@ -99,7 +102,8 @@ class BinaryPropagationSpec extends WordSpec with Matchers with OptionValues {
binaryPropagation.write(context, writer)
val rtContext = binaryPropagation.read(ByteStreamReader.of(writer.toByteArray))
- rtContext.tags should contain theSameElementsAs (context.tags)
+ rtContext.tags.get(plain("hello")) shouldBe "world"
+ rtContext.tags.get(plain("kamon")) shouldBe "rulez"
rtContext.get(BinaryPropagationSpec.StringKey) shouldBe "string-value"
rtContext.get(BinaryPropagationSpec.IntegerKey) shouldBe 0 // there is no entry configuration for the integer key
}
diff --git a/kamon-core-tests/src/test/scala/kamon/context/HttpPropagationSpec.scala b/kamon-core-tests/src/test/scala/kamon/context/HttpPropagationSpec.scala
index fcddfe24..0cd10672 100644
--- a/kamon-core-tests/src/test/scala/kamon/context/HttpPropagationSpec.scala
+++ b/kamon-core-tests/src/test/scala/kamon/context/HttpPropagationSpec.scala
@@ -5,6 +5,8 @@ import kamon.Kamon
import kamon.context.HttpPropagation.{HeaderReader, HeaderWriter}
import kamon.context.Propagation.{EntryReader, EntryWriter}
import org.scalatest.{Matchers, OptionValues, WordSpec}
+import kamon.tag.Lookups._
+import kamon.tag.TagSet
import scala.collection.mutable
@@ -22,12 +24,11 @@ class HttpPropagationSpec extends WordSpec with Matchers with OptionValues {
"x-content-tags" -> "hello=world;correlation=1234",
"x-mapped-tag" -> "value"
)
+
val context = httpPropagation.read(headerReaderFromMap(headers))
- context.tags should contain only(
- "hello" -> "world",
- "correlation" -> "1234",
- "mappedTag" -> "value"
- )
+ context.tags.get(plain("hello")) shouldBe "world"
+ context.tags.get(plain("correlation")) shouldBe "1234"
+ context.tags.get(plain("mappedTag")) shouldBe "value"
}
"handle errors when reading HTTP headers" in {
@@ -48,9 +49,9 @@ class HttpPropagationSpec extends WordSpec with Matchers with OptionValues {
context.get(HttpPropagationSpec.StringKey) shouldBe "hey"
context.get(HttpPropagationSpec.IntegerKey) shouldBe 123
context.get(HttpPropagationSpec.OptionalKey) shouldBe empty
- context.getTag("hello").value shouldBe "world"
- context.getTag("correlation").value shouldBe "1234"
- context.getTag("unknown") shouldBe empty
+ context.getTag(plain("hello")) shouldBe "world"
+ context.getTag(option("correlation")).value shouldBe "1234"
+ context.getTag(option("unknown")) shouldBe empty
}
}
@@ -64,10 +65,10 @@ class HttpPropagationSpec extends WordSpec with Matchers with OptionValues {
"write context tags when available" in {
val headers = mutable.Map.empty[String, String]
- val context = Context.of(Map(
+ val context = Context.of(TagSet.from(Map(
"hello" -> "world",
"mappedTag" -> "value"
- ))
+ )))
httpPropagation.write(context, headerWriterFromMap(headers))
headers should contain only(
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 62eae45b..c7e856d0 100644
--- a/kamon-core-tests/src/test/scala/kamon/instrumentation/HttpServerInstrumentationSpec.scala
+++ b/kamon-core-tests/src/test/scala/kamon/instrumentation/HttpServerInstrumentationSpec.scala
@@ -4,6 +4,7 @@ import java.time.Duration
import kamon.context.Context
import kamon.metric.{Counter, Histogram, RangeSampler}
+import kamon.tag.Lookups._
import kamon.testkit.{MetricInspection, SpanInspection}
import org.scalatest.concurrent.Eventually
import org.scalatest.{Matchers, OptionValues, WordSpec}
@@ -20,10 +21,8 @@ class HttpServerInstrumentationSpec extends WordSpec with Matchers with SpanInsp
"custom-trace-id" -> "0011223344556677"
)))
- handler.context.tags should contain only(
- "tag" -> "value",
- "none" -> "0011223344556677"
- )
+ handler.context.tags.get(plain("tag")) shouldBe "value"
+ handler.context.tags.get(plain("none")) shouldBe "0011223344556677"
handler.send(fakeResponse(200, mutable.Map.empty), Context.Empty)
handler.doneSending(0L)
@@ -35,10 +34,8 @@ class HttpServerInstrumentationSpec extends WordSpec with Matchers with SpanInsp
"custom-trace-id" -> "0011223344556677"
)))
- handler.context.tags should contain only(
- "tag" -> "value",
- "none" -> "0011223344556677"
- )
+ handler.context.tags.get(plain("tag")) shouldBe "value"
+ handler.context.tags.get(plain("none")) shouldBe "0011223344556677"
val span = inspect(handler.span)
span.context().traceID.string shouldNot be("0011223344556677")
diff --git a/kamon-core-tests/src/test/scala/kamon/tag/TagSetSpec.scala b/kamon-core-tests/src/test/scala/kamon/tag/TagSetSpec.scala
new file mode 100644
index 00000000..cd23c58d
--- /dev/null
+++ b/kamon-core-tests/src/test/scala/kamon/tag/TagSetSpec.scala
@@ -0,0 +1,180 @@
+package kamon.tag
+
+import java.util.Optional
+
+import org.scalatest.{Matchers, WordSpec}
+
+import scala.collection.JavaConverters.mapAsJavaMapConverter
+
+class TagSetSpec extends WordSpec with Matchers {
+ import Lookups._
+
+ "Tags" should {
+ "silently drop null and unacceptable keys and/or values when constructed from the companion object builders" in {
+ TagSet.from(NullString, NullString).all().size shouldBe 0
+ TagSet.from(EmptyString, NullString).all().size shouldBe 0
+ TagSet.from(EmptyString, "value").all().size shouldBe 0
+ TagSet.from(NullString, "value").all().size shouldBe 0
+ TagSet.from("key", NullString).all().size shouldBe 0
+ TagSet.from("key", NullBoolean).all().size shouldBe 0
+ TagSet.from("key", NullLong).all().size shouldBe 0
+
+ TagSet.from(BadScalaTagMap).all().size shouldBe 0
+ TagSet.from(BadJavaTagMap).all().size shouldBe 0
+ }
+
+ "silently drop null keys and/or values when created with the .withTag, withTags or .and methods" in {
+ val tags = TagSet.from("initialKey", "initialValue")
+ .withTag(NullString, NullString)
+ .withTag(EmptyString, NullString)
+ .withTag(EmptyString, "value")
+ .withTag(NullString, "value")
+ .withTag("key", NullString)
+ .withTag("key", NullBoolean)
+ .withTag("key", NullLong)
+ .and(NullString, NullString)
+ .and(EmptyString, NullString)
+ .and(EmptyString, "value")
+ .and(NullString, "value")
+ .and("key", NullString)
+ .and("key", NullBoolean)
+ .and("key", NullLong)
+
+ tags.all().length shouldBe 1
+ tags.all().head.asInstanceOf[Tag.String].key shouldBe "initialKey"
+ tags.all().head.asInstanceOf[Tag.String].value shouldBe "initialValue"
+ }
+
+ "create a properly populated instance when valid pairs are provided" in {
+ TagSet.from("isAwesome", true).all().size shouldBe 1
+ TagSet.from("name", "kamon").all().size shouldBe 1
+ TagSet.from("age", 5L).all().size shouldBe 1
+
+ TagSet.from(GoodScalaTagMap).all().size shouldBe 3
+ TagSet.from(GoodJavaTagMap).all().size shouldBe 3
+
+ TagSet.from("initial", "initial")
+ .withTag("isAwesome", true)
+ .withTag("name", "Kamon")
+ .withTag("age", 5L)
+ .and("isAvailable", true)
+ .and("website", "kamon.io")
+ .and("supportedPlatforms", 1L)
+ .all().size shouldBe 7
+ }
+
+ "override pre-existent tags when merging with other Tags instance" in {
+ val leftTags = TagSet.from(GoodScalaTagMap)
+ val rightTags = TagSet
+ .from("name", "New Kamon")
+ .and("age", 42L)
+ .and("isAwesome", false) // just for testing :)
+
+ val tags = leftTags.withTags(rightTags)
+ tags.get(plain("name")) shouldBe "New Kamon"
+ tags.get(plainLong("age")) shouldBe 42L
+ tags.get(plainBoolean("isAwesome")) shouldBe false
+
+ val andTags = tags and leftTags
+ andTags.get(plain("name")) shouldBe "Kamon"
+ andTags.get(plainLong("age")) shouldBe 5L
+ andTags.get(plainBoolean("isAwesome")) shouldBe true
+ }
+
+ "provide typed access to the contained pairs when looking up values" in {
+ val tags = TagSet.from(GoodScalaTagMap)
+
+ tags.get(plain("name")) shouldBe "Kamon"
+ tags.get(plain("none")) shouldBe null
+ tags.get(option("name")) shouldBe Option("Kamon")
+ tags.get(option("none")) shouldBe None
+ tags.get(optional("name")) shouldBe Optional.of("Kamon")
+ tags.get(optional("none")) shouldBe Optional.empty()
+
+ tags.get(plainLong("age")) shouldBe 5L
+ tags.get(plainLong("nil")) shouldBe null
+ tags.get(longOption("age")) shouldBe Option(5L)
+ tags.get(longOption("nil")) shouldBe None
+ tags.get(longOptional("age")) shouldBe Optional.of(5L)
+ tags.get(longOptional("nil")) shouldBe Optional.empty()
+
+ tags.get(plainBoolean("isAwesome")) shouldBe true
+ tags.get(plainBoolean("isUnknown")) shouldBe null
+ tags.get(booleanOption("isAwesome")) shouldBe Some(true)
+ tags.get(booleanOption("isUnknown")) shouldBe None
+ tags.get(booleanOptional("isAwesome")) shouldBe Optional.of(true)
+ tags.get(booleanOptional("isUnknown")) shouldBe Optional.empty()
+
+ tags.get(coerce("age")) shouldBe "5"
+ tags.get(coerce("isAwesome")) shouldBe "true"
+ tags.get(coerce("unknown")) shouldBe "unknown"
+ }
+
+ "allow iterating over all contained tags" in {
+ val tags = TagSet.from(Map(
+ "age" -> 5L,
+ "name" -> "Kamon",
+ "isAwesome" -> true,
+ "hasTracing" -> true,
+ "website" -> "kamon.io",
+ "luckyNumber" -> 7L
+ ))
+
+ tags.iterator().length shouldBe 6
+ tags.iterator().find(matchPair("age", 5L)) shouldBe defined
+ tags.iterator().find(matchPair("luckyNumber", 7L)) shouldBe defined
+ tags.iterator().find(matchPair("hasTracing", true)) shouldBe defined
+ tags.iterator().find(matchPair("isAwesome", true)) shouldBe defined
+ tags.iterator().find(matchPair("website", "kamon.io")) shouldBe defined
+ tags.iterator().find(matchPair("name", "Kamon")) shouldBe defined
+ }
+
+ "be equal to other Tags instance with the same tags" in {
+ TagSet.from(GoodScalaTagMap) shouldBe TagSet.from(GoodScalaTagMap)
+ TagSet.from(GoodJavaTagMap) shouldBe TagSet.from(GoodJavaTagMap)
+ }
+
+ "have a readable toString implementation" in {
+ TagSet.from(GoodScalaTagMap).toString() should include("age=5")
+ TagSet.from(GoodScalaTagMap).toString() should include("name=Kamon")
+ TagSet.from(GoodScalaTagMap).toString() should include("isAwesome=true")
+ }
+ }
+
+ def matchPair(key: String, value: Any) = { tag: Tag => {
+ tag match {
+ case t: Tag.String => t.key == key && t.value == value
+ case t: Tag.Long => t.key == key && t.value == value
+ case t: Tag.Boolean => t.key == key && t.value == value
+ }
+
+ }}
+
+
+ val NullString: java.lang.String = null
+ val NullBoolean: java.lang.Boolean = NullString.asInstanceOf[java.lang.Boolean]
+ val NullLong: java.lang.Long = null
+ val EmptyString: java.lang.String = ""
+
+ val GoodScalaTagMap: Map[String, Any] = Map(
+ "age" -> 5L,
+ "name" -> "Kamon",
+ "isAwesome" -> true
+ )
+
+ val BadScalaTagMap: Map[String, Any] = Map(
+ NullString -> NullString,
+ EmptyString -> NullString,
+ NullString -> NullString,
+ EmptyString -> NullString,
+ EmptyString -> "value",
+ NullString -> "value",
+ "key" -> NullString,
+ "key" -> NullBoolean,
+ "key" -> NullLong
+ )
+
+ val GoodJavaTagMap = GoodScalaTagMap.asJava
+ val BadJavaTagMap = BadScalaTagMap.asJava
+
+}