aboutsummaryrefslogtreecommitdiff
path: root/kamon-testkit
diff options
context:
space:
mode:
authorIvan Topolnjak <ivantopo@gmail.com>2017-08-15 00:33:06 +0200
committerIvan Topolnjak <ivantopo@gmail.com>2017-08-15 00:33:06 +0200
commita90d4aa75e7fdf12a85177f4e81463439bfe5bb3 (patch)
tree2b815c06862332752ff4192c4bdceb4413cf2945 /kamon-testkit
parent86c72d622ac027dc96f9a744771c0a468d46dc60 (diff)
downloadKamon-a90d4aa75e7fdf12a85177f4e81463439bfe5bb3.tar.gz
Kamon-a90d4aa75e7fdf12a85177f4e81463439bfe5bb3.tar.bz2
Kamon-a90d4aa75e7fdf12a85177f4e81463439bfe5bb3.zip
separate the build into core, testkit and core-tests projects
Diffstat (limited to 'kamon-testkit')
-rw-r--r--kamon-testkit/src/main/scala/kamon/testkit/MetricInspection.scala45
-rw-r--r--kamon-testkit/src/main/scala/kamon/testkit/Reconfigure.scala26
-rw-r--r--kamon-testkit/src/main/scala/kamon/testkit/SpanBuilding.scala16
-rw-r--r--kamon-testkit/src/main/scala/kamon/testkit/SpanInspector.scala61
-rw-r--r--kamon-testkit/src/main/scala/kamon/testkit/TestSpanReporter.scala23
5 files changed, 171 insertions, 0 deletions
diff --git a/kamon-testkit/src/main/scala/kamon/testkit/MetricInspection.scala b/kamon-testkit/src/main/scala/kamon/testkit/MetricInspection.scala
new file mode 100644
index 00000000..d0681fb5
--- /dev/null
+++ b/kamon-testkit/src/main/scala/kamon/testkit/MetricInspection.scala
@@ -0,0 +1,45 @@
+package kamon.testkit
+
+import kamon.metric._
+import _root_.scala.collection.concurrent.TrieMap
+
+
+trait MetricInspection {
+
+ implicit class MetricSyntax(metric: Metric[_]) {
+ def valuesForTag(tag: String): Seq[String] = {
+ val instrumentsField = classOf[BaseMetric[_, _]].getDeclaredField("instruments")
+ instrumentsField.setAccessible(true)
+
+ val instruments = instrumentsField.get(metric).asInstanceOf[TrieMap[Map[String, String], _]]
+ val instrumentsWithTheTag = instruments.keys.filter(_.keys.find(_ == tag).nonEmpty)
+ instrumentsWithTheTag.map(t => t(tag)).toSeq
+ }
+ }
+
+ implicit class HistogramMetricSyntax(histogram: Histogram) {
+ def distribution(resetState: Boolean = true): Distribution =
+ histogram match {
+ case hm: HistogramMetric => hm.refine(Map.empty[String, String]).distribution(resetState)
+ case h: AtomicHdrHistogram => h.snapshot(resetState).distribution
+ case h: HdrHistogram => h.snapshot(resetState).distribution
+ }
+ }
+
+ implicit class MinMaxCounterMetricSyntax(mmCounter: MinMaxCounter) {
+ def distribution(resetState: Boolean = true): Distribution =
+ mmCounter match {
+ case mmcm: MinMaxCounterMetric => mmcm.refine(Map.empty[String, String]).distribution(resetState)
+ case mmc: SimpleMinMaxCounter => mmc.snapshot(resetState).distribution
+ }
+ }
+
+ implicit class CounterMetricSyntax(counter: Counter) {
+ def value(resetState: Boolean = true): Long =
+ counter match {
+ case cm: CounterMetric => cm.refine(Map.empty[String, String]).value(resetState)
+ case c: LongAdderCounter => c.snapshot(resetState).value
+ }
+ }
+}
+
diff --git a/kamon-testkit/src/main/scala/kamon/testkit/Reconfigure.scala b/kamon-testkit/src/main/scala/kamon/testkit/Reconfigure.scala
new file mode 100644
index 00000000..4b3b2cdb
--- /dev/null
+++ b/kamon-testkit/src/main/scala/kamon/testkit/Reconfigure.scala
@@ -0,0 +1,26 @@
+package kamon.testkit
+
+import com.typesafe.config.ConfigFactory
+import kamon.Kamon
+
+trait Reconfigure {
+
+ def enableFastSpanFlushing(): Unit = {
+ applyConfig("kamon.trace.tick-interval = 1 millisecond")
+ }
+
+ def sampleAlways(): Unit = {
+ applyConfig("kamon.trace.sampler = always")
+ }
+
+ def sampleNever(): Unit = {
+ applyConfig("kamon.trace.sampler = never")
+ }
+
+ private def applyConfig(configString: String): Unit = {
+ Kamon.reconfigure(ConfigFactory.parseString(configString).withFallback(Kamon.config()))
+ }
+
+
+
+}
diff --git a/kamon-testkit/src/main/scala/kamon/testkit/SpanBuilding.scala b/kamon-testkit/src/main/scala/kamon/testkit/SpanBuilding.scala
new file mode 100644
index 00000000..7a216ecc
--- /dev/null
+++ b/kamon-testkit/src/main/scala/kamon/testkit/SpanBuilding.scala
@@ -0,0 +1,16 @@
+package kamon.testkit
+
+import kamon.trace.SpanContext.SamplingDecision
+import kamon.trace.{IdentityProvider, SpanContext}
+
+trait SpanBuilding {
+ private val identityProvider = IdentityProvider.Default()
+
+ def createSpanContext(samplingDecision: SamplingDecision = SamplingDecision.Sample): SpanContext =
+ SpanContext(
+ traceID = identityProvider.traceIdGenerator().generate(),
+ spanID = identityProvider.spanIdGenerator().generate(),
+ parentID = identityProvider.spanIdGenerator().generate(),
+ samplingDecision = samplingDecision
+ )
+}
diff --git a/kamon-testkit/src/main/scala/kamon/testkit/SpanInspector.scala b/kamon-testkit/src/main/scala/kamon/testkit/SpanInspector.scala
new file mode 100644
index 00000000..f23fba98
--- /dev/null
+++ b/kamon-testkit/src/main/scala/kamon/testkit/SpanInspector.scala
@@ -0,0 +1,61 @@
+package kamon.testkit
+
+import kamon.trace.{Span, SpanContext}
+import kamon.trace.Span.FinishedSpan
+import kamon.util.Clock
+
+import scala.reflect.ClassTag
+import scala.util.Try
+
+class SpanInspector(span: Span) {
+ private val (realSpan, spanData) = Try {
+ val realSpan = span match {
+ case _: Span.Local => span
+ }
+
+ val spanData = invoke[Span.Local, FinishedSpan](realSpan, "toFinishedSpan", classOf[Long] -> Long.box(Clock.microTimestamp()))
+ (realSpan, spanData)
+ }.getOrElse((null, null))
+
+ def isEmpty: Boolean =
+ realSpan == null
+
+ def spanTag(key: String): Option[Span.TagValue] =
+ spanData.tags.get(key)
+
+ def spanTags(): Map[String, Span.TagValue] =
+ spanData.tags
+
+ def metricTags(): Map[String, String] =
+ getField[Span.Local, Map[String, String]](realSpan, "customMetricTags")
+
+ def startTimestamp(): Long =
+ getField[Span.Local, Long](realSpan, "startTimestampMicros")
+
+ def context(): SpanContext =
+ spanData.context
+
+ def operationName(): String =
+ spanData.operationName
+
+
+
+
+ private def getField[T, R](target: Any, fieldName: String)(implicit classTag: ClassTag[T]): R = {
+ val toFinishedSpanMethod = classTag.runtimeClass.getDeclaredField(fieldName)
+ toFinishedSpanMethod.setAccessible(true)
+ toFinishedSpanMethod.get(target).asInstanceOf[R]
+ }
+
+ private def invoke[T, R](target: Any, fieldName: String, parameters: (Class[_], AnyRef)*)(implicit classTag: ClassTag[T]): R = {
+ val parameterClasses = parameters.map(_._1)
+ val parameterInstances = parameters.map(_._2)
+ val toFinishedSpanMethod = classTag.runtimeClass.getDeclaredMethod(fieldName, parameterClasses: _*)
+ toFinishedSpanMethod.setAccessible(true)
+ toFinishedSpanMethod.invoke(target, parameterInstances: _*).asInstanceOf[R]
+ }
+}
+
+object SpanInspector {
+ def apply(span: Span): SpanInspector = new SpanInspector(span)
+}
diff --git a/kamon-testkit/src/main/scala/kamon/testkit/TestSpanReporter.scala b/kamon-testkit/src/main/scala/kamon/testkit/TestSpanReporter.scala
new file mode 100644
index 00000000..8ea2d433
--- /dev/null
+++ b/kamon-testkit/src/main/scala/kamon/testkit/TestSpanReporter.scala
@@ -0,0 +1,23 @@
+package kamon.testkit
+
+import java.util.concurrent.LinkedBlockingQueue
+
+import com.typesafe.config.Config
+import kamon.SpanReporter
+import kamon.trace.Span
+import kamon.trace.Span.FinishedSpan
+
+class TestSpanReporter() extends SpanReporter {
+ import scala.collection.JavaConverters._
+ private val reportedSpans = new LinkedBlockingQueue[FinishedSpan]()
+
+ override def reportSpans(spans: Seq[Span.FinishedSpan]): Unit =
+ reportedSpans.addAll(spans.asJava)
+
+ def nextSpan(): Option[FinishedSpan] =
+ Option(reportedSpans.poll())
+
+ override def start(): Unit = {}
+ override def stop(): Unit = {}
+ override def reconfigure(config: Config): Unit = {}
+}