nwaku/vendor/nim-metrics/tests/main_tests.nim

331 lines
12 KiB
Nim

# nim-metrics
# Copyright (c) 2019 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license: [LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT
# * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
# at your option. This file may not be copied, modified, or distributed except according to those terms.
import net, os, unittest,
../metrics
when defined(metrics):
addExportBackend(
metricProtocol = STATSD,
netProtocol = UDP,
address = "127.0.0.1",
port = Port(8125)
)
addExportBackend(
metricProtocol = CARBON,
netProtocol = TCP,
address = "127.0.0.1",
port = Port(2003)
)
declareCounter globalCounter, "help"
declarePublicCounter globalPublicCounter, "help"
declareGauge globalGauge, "help"
declarePublicGauge globalPublicGauge, "help"
proc gcSafetyTest* {.gcsafe.} = # The test is successful if this proc compiles
globalCounter.inc 2
globalPublicCounter.inc(2)
globalGauge.set 10.0
globalGauge.inc
globalGauge.dec
globalPublicGauge.set(1)
suite "counter":
setup:
var registry = newRegistry()
declareCounter myCounter, "help", registry = registry
test "basic":
check myCounter.value == 0
myCounter.inc()
check myCounter.value == 1
myCounter.inc(7)
check myCounter.value == 8
myCounter.inc(0.5)
check myCounter.value == 8.5
myCounter.inc(-1) # you shouldn't be doing this - but we don't want metrics to crash the app
check myCounter.value == 8.5
# name validation (have to use the internal API to get past Nim's identifier validation)
when defined(metrics):
expect ValueError:
var tmp = newCounter("1337", "invalid name")
test "alternative API":
counter("one_off_counter").inc()
check counter("one_off_counter").value == 1
counter("one_off_counter").inc(0.5)
check counter("one_off_counter").value == 1.5
# confusing, but allowed
check gauge("one_off_counter").value == 0
# colons in name
counter("one:off:counter:colons").inc()
check counter("one:off:counter:colons").value == 1
test "exceptions":
proc f(switch: bool) =
if switch:
raise newException(ValueError, "exc1")
else:
raise newException(IndexError, "exc2")
expect IndexError:
myCounter.countExceptions(ValueError):
f(false)
check myCounter.value == 0
expect ValueError:
myCounter.countExceptions(ValueError):
f(true)
check myCounter.value == 1
expect IndexError:
myCounter.countExceptions:
f(false)
check myCounter.value == 2
myCounter.countExceptions:
discard
check myCounter.value == 2
test "labels":
declareCounter lCounter, "l help", @["foo", "bar"], registry
expect KeyError:
discard lCounter.value
# you can't access a labelled value before it was initialised
expect KeyError:
discard lCounter.value(@["a", "x"])
let labelValues = @["a", "x \"y\" \n\\z"]
lCounter.inc(labelValues = labelValues)
check lCounter.value(labelValues) == 1
# echo registry
# label validation
expect ValueError:
declareCounter invalid1, "invalid", @["123", "foo"]
expect ValueError:
declareCounter invalid2, "invalid", @["foo", "123"]
expect ValueError:
declareCounter invalid3, "invalid", @["foo", "__bar"]
# label names: array instead of sequence
declareCounter lCounter2, "l2 help", ["foo", "bar"], registry
let labelValues2 = ["a", "x \"y\" \n\\z"]
lCounter2.inc(labelValues = labelValues2)
check lCounter2.value(labelValues2) == 1
test "sample rate":
declareCounter sCounter, "counter with a sample rate set", registry = registry, sampleRate = 0.5
sCounter.inc()
# No sampling done on our side, just in sending the increments to a StatsD server
check sCounter.value == 1
test "names with colons":
declareCounter cCounter, "counter with colons in name", registry = registry, name = "foo:bar:baz"
cCounter.inc()
check cCounter.value == 1
check cCounter.valueByName("foo:bar:baz_total") == 1
# echo cCounter
var myName = "bla:bla"
declareCounter cCounter2, "another counter with colon in name", registry = registry, name = myName
cCounter2.inc()
check cCounter2.value == 1
check cCounter2.valueByName("bla:bla_total") == 1
# echo cCounter2
suite "gauge":
setup:
var registry = newRegistry()
declareGauge myGauge, "help", registry = registry
test "basic":
check myGauge.value == 0
myGauge.inc()
check myGauge.value == 1
myGauge.dec(3)
check myGauge.value == -2.0 # weird Nim bug if it's "-2"
myGauge.dec(0.1)
check myGauge.value == -2.1
myGauge.set(9.5)
check myGauge.value == 9.5
myGauge.set(1)
check myGauge.value == 1
test "alternative API":
gauge("one_off_gauge").set(1)
check gauge("one_off_gauge").value == 1
gauge("one_off_gauge").inc(0.5)
check gauge("one_off_gauge").value == 1.5
test "in progress":
myGauge.trackInProgress:
check myGauge.value == 1
check myGauge.value == 0
declareGauge lgauge, "help", @["foobar"], registry = registry
let labelValues = @["b"]
lgauge.trackInProgress(labelValues):
check lgauge.value(labelValues) == 1
check lgauge.value(labelValues) == 0
# echo registry
test "timing":
myGauge.time:
sleep(1000)
check myGauge.value == 0
check myGauge.value >= 1 # may be 2 inside a macOS Travis job
# echo registry
test "timing with labels":
declareGauge lgauge, "help", @["foobar"], registry = registry
let labelValues = @["b"]
lgauge.time(labelValues):
sleep(1000)
check lgauge.value(labelValues) >= 1
test "names with colons":
declareGauge cGauge, "gauge with colons in name", registry = registry, name = "foo:bar:baz"
cGauge.inc()
check cGauge.value == 1
check cGauge.valueByName("foo:bar:baz") == 1
# echo cGauge
suite "summary":
setup:
var registry = newRegistry()
declareSummary mySummary, "help", registry = registry
test "basic":
check mySummary.valueByName("mySummary_count") == 0
check mySummary.valueByName("mySummary_sum") == 0
mySummary.observe(10)
check mySummary.valueByName("mySummary_count") == 1
check mySummary.valueByName("mySummary_sum") == 10
mySummary.observe(0.5)
check mySummary.valueByName("mySummary_count") == 2
check mySummary.valueByName("mySummary_sum") == 10.5
test "alternative API":
summary("one_off_summary").observe(10)
check summary("one_off_summary").valueByName("one_off_summary_count") == 1
check summary("one_off_summary").valueByName("one_off_summary_sum") == 10
test "timing":
mySummary.time:
sleep(1000)
check mySummary.valueByName("mySummary_sum") == 0
check mySummary.valueByName("mySummary_sum") >= 1
test "timing with labels":
declareSummary lsummary, "help", ["foobar"], registry = registry
let labelValues = ["b"]
lsummary.time(labelValues):
sleep(1000)
check lsummary.valueByName("lsummary_sum", labelValues) >= 1
test "names with colons":
declareSummary cSummary, "summary with colons in name", registry = registry, name = "foo:bar:baz"
cSummary.observe(10)
check cSummary.valueByName("foo:bar:baz_count") == 1
check cSummary.valueByName("foo:bar:baz_sum") == 10
# echo cSummary
suite "histogram":
setup:
var registry = newRegistry()
declareHistogram myHistogram, "help", registry = registry
test "basic":
check myHistogram.valueByName("myHistogram_bucket", [], ["1.0"]) == 0
check myHistogram.valueByName("myHistogram_bucket", [], ["2.5"]) == 0
check myHistogram.valueByName("myHistogram_bucket", [], ["5.0"]) == 0
check myHistogram.valueByName("myHistogram_bucket", [], ["+Inf"]) == 0
check myHistogram.valueByName("myHistogram_count") == 0
check myHistogram.valueByName("myHistogram_sum") == 0
myHistogram.observe(2)
check myHistogram.valueByName("myHistogram_bucket", [], ["1.0"]) == 0
check myHistogram.valueByName("myHistogram_bucket", [], ["2.5"]) == 1
check myHistogram.valueByName("myHistogram_bucket", [], ["5.0"]) == 1
check myHistogram.valueByName("myHistogram_bucket", [], ["+Inf"]) == 1
check myHistogram.valueByName("myHistogram_count") == 1
check myHistogram.valueByName("myHistogram_sum") == 2
myHistogram.observe(2.5)
check myHistogram.valueByName("myHistogram_bucket", [], ["1.0"]) == 0
check myHistogram.valueByName("myHistogram_bucket", [], ["2.5"]) == 2
check myHistogram.valueByName("myHistogram_bucket", [], ["5.0"]) == 2
check myHistogram.valueByName("myHistogram_bucket", [], ["+Inf"]) == 2
check myHistogram.valueByName("myHistogram_count") == 2
check myHistogram.valueByName("myHistogram_sum") == 4.5
myHistogram.observe(Inf)
check myHistogram.valueByName("myHistogram_bucket", [], ["1.0"]) == 0
check myHistogram.valueByName("myHistogram_bucket", [], ["2.5"]) == 2
check myHistogram.valueByName("myHistogram_bucket", [], ["5.0"]) == 2
check myHistogram.valueByName("myHistogram_bucket", [], ["+Inf"]) == 3
check myHistogram.valueByName("myHistogram_count") == 3
check myHistogram.valueByName("myHistogram_sum") == Inf
declareHistogram h1, "help", registry = registry, buckets = [0.0, 1.0, 2.0]
check h1.valueByName("h1_bucket", [], ["0.0"]) == 0
check h1.valueByName("h1_bucket", [], ["1.0"]) == 0
check h1.valueByName("h1_bucket", [], ["2.0"]) == 0
check h1.valueByName("h1_bucket", [], ["+Inf"]) == 0
declareHistogram h2, "help", registry = registry, buckets = [0.0, 1.0, 2.0, Inf]
check h2.valueByName("h2_bucket", [], ["0.0"]) == 0
check h2.valueByName("h2_bucket", [], ["1.0"]) == 0
check h2.valueByName("h2_bucket", [], ["2.0"]) == 0
check h2.valueByName("h2_bucket", [], ["+Inf"]) == 0
expect ValueError:
declareHistogram h3, "help", registry = registry, buckets = []
expect ValueError:
declareHistogram h3, "help", registry = registry, buckets = [Inf]
expect ValueError:
declareHistogram h3, "help", registry = registry, buckets = [3.0, 1.0]
test "alternative API":
histogram("one_off_histogram").observe(2)
check histogram("one_off_histogram").valueByName("one_off_histogram_bucket", [], ["1.0"]) == 0
check histogram("one_off_histogram").valueByName("one_off_histogram_bucket", [], ["2.5"]) == 1
check histogram("one_off_histogram").valueByName("one_off_histogram_bucket", [], ["5.0"]) == 1
check histogram("one_off_histogram").valueByName("one_off_histogram_bucket", [], ["+Inf"]) == 1
check histogram("one_off_histogram").valueByName("one_off_histogram_count") == 1
check histogram("one_off_histogram").valueByName("one_off_histogram_sum") == 2
test "timing":
myHistogram.time:
sleep(1000)
check myHistogram.valueByName("myHistogram_sum") == 0
check myHistogram.valueByName("myHistogram_sum") >= 1
check myHistogram.valueByName("myHistogram_count") == 1
check myHistogram.valueByName("myHistogram_bucket", [], ["+Inf"]) == 1
test "timing with labels":
declareHistogram lhistogram, "help", ["foobar"], registry = registry
let labelValues = ["b"]
lhistogram.time(labelValues):
sleep(1000)
check lhistogram.valueByName("lhistogram_sum", labelValues) >= 1
check lhistogram.valueByName("lhistogram_count", labelValues) == 1
check lhistogram.valueByName("lhistogram_bucket", labelValues, ["+Inf"]) == 1
test "names with colons":
declareHistogram cHistogram, "histogram with colons in name", registry = registry, name = "foo:bar:baz"
cHistogram.observe(10)
check cHistogram.valueByName("foo:bar:baz_count") == 1
check cHistogram.valueByName("foo:bar:baz_sum") == 10
# echo cHistogram