File: test_metric_initialization.py

package info (click to toggle)
prometheus-flask-exporter 0.23.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 896 kB
  • sloc: python: 2,889; sh: 709; makefile: 4
file content (103 lines) | stat: -rw-r--r-- 3,352 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
from abc import ABC, abstractmethod

from flask import request

from unittest_helper import BaseTestCase


# The class nesting avoids that the abstract base class will be tested (which is not possible because it is abstract..)
class MetricInitializationTest:
    class MetricInitializationTest(BaseTestCase, ABC):
        metric_suffix = None

        @property
        @abstractmethod
        def metric_type(self):
            pass

        def get_metric_decorator(self, metrics):
            return getattr(metrics, self.metric_type)

        def _test_metric_initialization(self, labels=None, initial_value_when_only_static_labels=True):
            metrics = self.metrics()
            metric_decorator = self.get_metric_decorator(metrics)

            test_path = '/test/1'

            @self.app.route(test_path)
            @metric_decorator('metric_1', 'Metric 1',
                              labels=labels,
                              initial_value_when_only_static_labels=initial_value_when_only_static_labels)
            def test1():
                return 'OK'

            if labels:
                # replace callable with the "expected" result
                if 'path' in labels:
                    labels['path'] = test_path

                label_value_pairs = labels.items()
            else:
                label_value_pairs = []

            prometheus_metric_name = 'metric_1'
            if self.metric_suffix:
                prometheus_metric_name += self.metric_suffix

            # test metric value before any incoming HTTP call
            self.assertMetric(prometheus_metric_name, '0.0', *label_value_pairs)

            self.client.get('/test/1')

            if self.metric_type == 'gauge':
                expected_metric_value = '0.0'
            else:
                expected_metric_value = '1.0'

            self.assertMetric(prometheus_metric_name, expected_metric_value, *label_value_pairs)

        def test_initial_value_no_labels(self):
            self._test_metric_initialization()

        def test_initial_value_only_static_labels(self):
            labels = {'label_name': 'label_value'}
            self._test_metric_initialization(labels)

        def test_initial_value_only_static_labels_no_initialization(self):
            labels = {'label_name': 'label_value'}
            self.assertRaises(AssertionError, self._test_metric_initialization, labels, initial_value_when_only_static_labels=False)

        def test_initial_value_callable_label(self):
            labels = {'path': lambda: request.path}
            self.assertRaises(AssertionError, self._test_metric_initialization, labels)



class HistogramInitializationTest(MetricInitializationTest.MetricInitializationTest):
    metric_suffix = '_count'

    @property
    def metric_type(self):
        return 'histogram'


class SummaryInitializationTest(MetricInitializationTest.MetricInitializationTest):
    metric_suffix = '_count'

    @property
    def metric_type(self):
        return 'summary'


class GaugeInitializationTest(MetricInitializationTest.MetricInitializationTest):
    @property
    def metric_type(self):
        return 'gauge'


class CounterInitializationTest(MetricInitializationTest.MetricInitializationTest):
    metric_suffix = '_total'

    @property
    def metric_type(self):
        return 'counter'