123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- from unittest.mock import patch
- import pytest
- from minimetrics.core import CounterMetric, DistributionMetric, GaugeMetric, SetMetric
- from minimetrics.transport import EncodingError, MetricEnvelopeTransport, RelayStatsdEncoder
- from minimetrics.types import BucketKey, FlushedMetric
- def test_relay_encoder_with_counter():
- encoder = RelayStatsdEncoder()
- bucket_key = BucketKey(
- timestamp=1693994400,
- metric_type="c",
- metric_name="button_click",
- metric_unit="none",
- metric_tags=(
- ("browser", "Chrome"),
- ("browser.version", "1.0"),
- ),
- )
- metric = CounterMetric(first=2)
- flushed_metric = FlushedMetric(bucket_key=bucket_key, metric=metric)
- result = encoder.encode(flushed_metric)
- assert result == "button_click@none:2|c|#browser:Chrome,browser.version:1.0|T1693994400"
- def test_relay_encoder_with_distribution():
- encoder = RelayStatsdEncoder()
- bucket_key = BucketKey(
- timestamp=1693994400,
- metric_type="d",
- metric_name="execution_time",
- metric_unit="second",
- metric_tags=(
- ("browser", "Chrome"),
- ("browser.version", "1.0"),
- ),
- )
- metric = DistributionMetric(first=1.0)
- metric.add(0.5)
- metric.add(3.0)
- flushed_metric = FlushedMetric(bucket_key=bucket_key, metric=metric)
- result = encoder.encode(flushed_metric)
- assert (
- result
- == "execution_time@second:1.0:0.5:3.0|d|#browser:Chrome,browser.version:1.0|T1693994400"
- )
- def test_relay_encoder_with_set():
- encoder = RelayStatsdEncoder()
- bucket_key = BucketKey(
- timestamp=1693994400,
- metric_type="s",
- metric_name="users",
- metric_unit="none",
- metric_tags=(
- ("browser", "Chrome"),
- ("browser.version", "1.0"),
- ),
- )
- metric = SetMetric(first=123)
- metric.add(456)
- metric.add("riccardo")
- flushed_metric = FlushedMetric(bucket_key=bucket_key, metric=metric)
- result = encoder.encode(flushed_metric)
- pieces = result.split("|")
- m = pieces[0].split(":")
- assert m[0] == "users@none"
- assert sorted(m[1:]) == sorted(["123", "456", "3455635177"])
- assert pieces[1] == "s"
- assert pieces[2] == "#browser:Chrome,browser.version:1.0"
- assert pieces[3] == "T1693994400"
- def test_relay_encoder_with_gauge():
- encoder = RelayStatsdEncoder()
- bucket_key = BucketKey(
- timestamp=1693994400,
- metric_type="g",
- metric_name="startup_time",
- metric_unit="second",
- metric_tags=(
- ("browser", "Chrome"),
- ("browser.version", "1.0"),
- ),
- )
- metric = GaugeMetric(first=10.0)
- metric.add(5.0)
- metric.add(7.0)
- flushed_metric = FlushedMetric(bucket_key=bucket_key, metric=metric)
- result = encoder.encode(flushed_metric)
- assert (
- result
- == "startup_time@second:7.0:5.0:10.0:22.0:3|g|#browser:Chrome,browser.version:1.0|T1693994400"
- )
- def test_relay_encoder_with_invalid_chars():
- encoder = RelayStatsdEncoder()
- bucket_key = BucketKey(
- timestamp=1693994400,
- metric_type="c",
- metric_name="büttòn_click",
- metric_unit="second",
- metric_tags=(
- # Invalid tag key.
- ("browser\nname", "Chrome"),
- # Invalid tag value.
- ("browser.version", "\t1.\n0ô"),
- # Valid tag key and value.
- ("platform", "Android"),
- # Totally invalid tag key.
- ("\nöś", "Windows"),
- # Totally invalid tag value.
- ("version", "\n\t"),
- ),
- )
- metric = CounterMetric(first=1)
- flushed_metric = FlushedMetric(bucket_key=bucket_key, metric=metric)
- result = encoder.encode(flushed_metric)
- assert (
- result
- == "bttn_click@second:1|c|#browsername:Chrome,browser.version:1.0,platform:Android,version:|T1693994400"
- )
- bucket_key = BucketKey(
- timestamp=1693994400,
- metric_type="c",
- metric_name="üòë",
- metric_unit="second",
- metric_tags=(),
- )
- metric = CounterMetric(first=1)
- flushed_metric = FlushedMetric(bucket_key=bucket_key, metric=metric)
- with pytest.raises(EncodingError, match="The sanitized metric name üòë is empty"):
- encoder.encode(flushed_metric)
- def test_relay_encoder_with_multiple_metrics():
- encoder = RelayStatsdEncoder()
- flushed_metric_1 = FlushedMetric(
- bucket_key=BucketKey(
- timestamp=1693994400,
- metric_type="g",
- metric_name="startup_time",
- metric_unit="second",
- metric_tags=(
- ("browser", "Chrome"),
- ("browser.version", "1.0"),
- ),
- ),
- metric=GaugeMetric(first=10.0),
- )
- flushed_metric_2 = FlushedMetric(
- bucket_key=BucketKey(
- timestamp=1693994400,
- metric_type="c",
- metric_name="button_click",
- metric_unit="none",
- metric_tags=(
- ("browser", "Chrome"),
- ("browser.version", "1.0"),
- ),
- ),
- metric=CounterMetric(first=1),
- )
- flushed_metric_3 = FlushedMetric(
- bucket_key=BucketKey(
- timestamp=1693994400,
- metric_type="c",
- # This name will be completely scraped, resulting in no emission of the metric.
- metric_name="öüâ",
- metric_unit="none",
- metric_tags=(
- ("browser", "Chrome"),
- ("browser.version", "1.0"),
- ),
- ),
- metric=CounterMetric(first=1),
- )
- result = encoder.encode_multiple([flushed_metric_1, flushed_metric_2, flushed_metric_3])
- assert result == (
- "startup_time@second:10.0:10.0:10.0:10.0:1|g|#browser:Chrome,browser.version:1.0|T1693994400"
- + "\n"
- + "button_click@none:1|c|#browser:Chrome,browser.version:1.0|T1693994400"
- )
- @patch("minimetrics.transport.sentry_sdk")
- def test_send(sentry_sdk):
- flushed_metric = FlushedMetric(
- bucket_key=BucketKey(
- timestamp=1693994400,
- metric_type="c",
- metric_name="button_click",
- metric_unit="none",
- metric_tags=(
- ("browser", "Chrome"),
- ("browser.version", "1.0"),
- ),
- ),
- metric=CounterMetric(first=1),
- )
- transport = MetricEnvelopeTransport(RelayStatsdEncoder())
- transport.send([flushed_metric])
- args = sentry_sdk.Hub.current.client.transport.capture_envelope.call_args.args
- assert len(args) == 1
- arg = args[0]
- assert arg.items[0].type == "statsd"
- assert arg.items[0].data_category == "statsd"
|