def test_fallback_to_state_machine_label_parsing(self): from unittest.mock import patch from prometheus_client.openmetrics.parser import _parse_sample parse_sample_function = "prometheus_client.openmetrics.parser._parse_sample" parse_labels_function = "prometheus_client.openmetrics.parser._parse_labels" parse_remaining_function = "prometheus_client.openmetrics.parser._parse_remaining_text" state_machine_function = "prometheus_client.openmetrics.parser._parse_labels_with_state_machine" parse_sample_return_value = Sample("a_total", {"foo": "foo # bar"}, 1) with patch(parse_sample_function, return_value=parse_sample_return_value) as mock: families = text_string_to_metric_families("""# TYPE a counter # HELP a help a_total{foo="foo # bar"} 1 # EOF """) a = CounterMetricFamily("a", "help", labels=["foo"]) a.add_metric(["foo # bar"], 1) self.assertEqual([a], list(families)) mock.assert_called_once_with('a_total{foo="foo # bar"} 1') # First fallback case state_machine_return_values = [{"foo": "foo # bar"}, len('foo="foo # bar"}')] parse_remaining_values = [1, None, None] with patch(parse_labels_function) as mock1: with patch(state_machine_function, return_value=state_machine_return_values) as mock2: with patch(parse_remaining_function, return_value=parse_remaining_values) as mock3: sample = _parse_sample('a_total{foo="foo # bar"} 1') s = Sample("a_total", {"foo": "foo # bar"}, 1) self.assertEqual(s, sample) mock1.assert_not_called() mock2.assert_called_once_with('foo="foo # bar"} 1') mock3.assert_called_once_with('1') # Second fallback case state_machine_return_values = [{"le": "1.0"}, len('le="1.0"}')] parse_remaining_values = [0.0, Timestamp(123, 0), Exemplar({"a": "b"}, 0.5)] with patch(parse_labels_function) as mock1: with patch(state_machine_function, return_value=state_machine_return_values) as mock2: with patch(parse_remaining_function, return_value=parse_remaining_values) as mock3: sample = _parse_sample('a_bucket{le="1.0"} 0 123 # {a="b"} 0.5') s = Sample("a_bucket", {"le": "1.0"}, 0.0, Timestamp(123, 0), Exemplar({"a": "b"}, 0.5)) self.assertEqual(s, sample) mock1.assert_not_called() mock2.assert_called_once_with('le="1.0"} 0 123 # {a="b"} 0.5') mock3.assert_called_once_with('0 123 # {a="b"} 0.5') # No need to fallback case parse_labels_return_values = {"foo": "foo#bar"} parse_remaining_values = [1, None, None] with patch(parse_labels_function, return_value=parse_labels_return_values) as mock1: with patch(state_machine_function) as mock2: with patch(parse_remaining_function, return_value=parse_remaining_values) as mock3: sample = _parse_sample('a_total{foo="foo#bar"} 1') s = Sample("a_total", {"foo": "foo#bar"}, 1) self.assertEqual(s, sample) mock1.assert_called_once_with('foo="foo#bar"') mock2.assert_not_called() mock3.assert_called_once_with('1')
def collect(self): metric = Metric("ts", "help", 'unknown') metric.add_sample("ts", {"foo": "a"}, 0, 123.456) metric.add_sample("ts", {"foo": "b"}, 0, -123.456) metric.add_sample("ts", {"foo": "c"}, 0, 123) metric.add_sample("ts", {"foo": "d"}, 0, Timestamp(123, 456000000)) metric.add_sample("ts", {"foo": "e"}, 0, Timestamp(123, 456000)) metric.add_sample("ts", {"foo": "f"}, 0, Timestamp(123, 456)) yield metric
def test_info_timestamps(self): families = text_string_to_metric_families("""# TYPE a info # HELP a help a_info{a="1",foo="bar"} 1 1 a_info{a="2",foo="bar"} 1 0 # EOF """) imf = InfoMetricFamily("a", "help") imf.add_sample("a_info", {"a": "1", "foo": "bar"}, 1, Timestamp(1, 0)) imf.add_sample("a_info", {"a": "2", "foo": "bar"}, 1, Timestamp(0, 0)) self.assertEqual([imf], list(families))
def test_gaugehistogram_exemplars(self): families = text_string_to_metric_families("""# TYPE a gaugehistogram # HELP a help a_bucket{le="1.0"} 0 123 # {a="b"} 0.5 a_bucket{le="2.0"} 2 123 # {a="c"} 0.5 a_bucket{le="+Inf"} 3 123 # {a="d"} 4 123 # EOF """) hfm = GaugeHistogramMetricFamily("a", "help") hfm.add_sample("a_bucket", {"le": "1.0"}, 0.0, Timestamp(123, 0), Exemplar({"a": "b"}, 0.5)) hfm.add_sample("a_bucket", {"le": "2.0"}, 2.0, Timestamp(123, 0), Exemplar({"a": "c"}, 0.5)), hfm.add_sample("a_bucket", {"le": "+Inf"}, 3.0, Timestamp(123, 0), Exemplar({"a": "d"}, 4, Timestamp(123, 0))) self.assertEqual([hfm], list(families))
def test_duplicate_timestamps(self): families = text_string_to_metric_families("""# TYPE a gauge # HELP a help a{a="1",foo="bar"} 1 0.0000000000 a{a="1",foo="bar"} 2 0.0000000001 a{a="1",foo="bar"} 3 0.0000000010 a{a="2",foo="bar"} 4 0.0000000000 a{a="2",foo="bar"} 5 0.0000000001 # EOF """) imf = GaugeMetricFamily("a", "help") imf.add_sample("a", {"a": "1", "foo": "bar"}, 1, Timestamp(0, 0)) imf.add_sample("a", {"a": "1", "foo": "bar"}, 3, Timestamp(0, 1)) imf.add_sample("a", {"a": "2", "foo": "bar"}, 4, Timestamp(0, 0)) self.assertEqual([imf], list(families))
def test_counter_exemplars_empty_brackets(self): families = text_string_to_metric_families("""# TYPE a counter # HELP a help a_total{} 0 123 # {a="b"} 0.5 # EOF """) cfm = CounterMetricFamily("a", "help") cfm.add_sample("a_total", {}, 0.0, Timestamp(123, 0), Exemplar({"a": "b"}, 0.5)) self.assertEqual([cfm], list(families))
def test_timestamps(self): families = text_string_to_metric_families("""# TYPE a counter # HELP a help a_total{foo="1"} 1 000 a_total{foo="2"} 1 0.0 a_total{foo="3"} 1 1.1 a_total{foo="4"} 1 12345678901234567890.1234567890 a_total{foo="5"} 1 1.5e3 # TYPE b counter # HELP b help b_total 2 1234567890 # EOF """) a = CounterMetricFamily("a", "help", labels=["foo"]) a.add_metric(["1"], 1, timestamp=Timestamp(0, 0)) a.add_metric(["2"], 1, timestamp=Timestamp(0, 0)) a.add_metric(["3"], 1, timestamp=Timestamp(1, 100000000)) a.add_metric(["4"], 1, timestamp=Timestamp(12345678901234567890, 123456789)) a.add_metric(["5"], 1, timestamp=1500.0) b = CounterMetricFamily("b", "help") b.add_metric([], 2, timestamp=Timestamp(1234567890, 0)) self.assertEqual([a, b], list(families))
def test_histogram_exemplars(self): families = text_string_to_metric_families("""# TYPE a histogram # HELP a help a_bucket{le="1"} 0 # {a="b"} 0.5 a_bucket{le="2"} 2 # {a="c"} 0.5 a_bucket{le="+Inf"} 3 # {a="1234567890123456789012345678901234567890123456789012345678"} 4 123 # EOF """) hfm = HistogramMetricFamily("a", "help") hfm.add_sample("a_bucket", {"le": "1"}, 0.0, None, Exemplar({"a": "b"}, 0.5)) hfm.add_sample("a_bucket", {"le": "2"}, 2.0, None, Exemplar({"a": "c"}, 0.5)), hfm.add_sample( "a_bucket", {"le": "+Inf"}, 3.0, None, Exemplar( { "a": "1234567890123456789012345678901234567890123456789012345678" }, 4, Timestamp(123, 0))) self.assertEqual([hfm], list(families))