|
1 |
| -# Copyright 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. |
| 1 | +# Copyright 2023-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved. |
2 | 2 | #
|
3 | 3 | # Redistribution and use in source and binary forms, with or without
|
4 | 4 | # modification, are permitted provided that the following conditions
|
@@ -74,6 +74,96 @@ def _metric_api_helper(self, metric, kind):
|
74 | 74 | self.assertEqual(metric.value(), value)
|
75 | 75 | logger.log_info("Set metric to : {}".format(metric.value()))
|
76 | 76 |
|
| 77 | + # Test observe value |
| 78 | + observe = 0.05 |
| 79 | + # Counter and gauge do not support observe |
| 80 | + with self.assertRaises(pb_utils.TritonModelException): |
| 81 | + metric.observe(observe) |
| 82 | + |
| 83 | + def _histogram_api_helper(self, metric, name, labels): |
| 84 | + def histogram_str_builder(name, type, labels, value, le=None): |
| 85 | + if type == "count" or type == "sum": |
| 86 | + return f"{name}_{type}{{{labels}}} {value}" |
| 87 | + elif type == "bucket": |
| 88 | + return f'{name}_bucket{{{labels},le="{le}"}} {value}' |
| 89 | + else: |
| 90 | + raise |
| 91 | + |
| 92 | + # Adding logger to test if custom metrics and logging work together |
| 93 | + # as they use the same message queue. |
| 94 | + logger = pb_utils.Logger |
| 95 | + |
| 96 | + # All values should be 0.0 before the test |
| 97 | + metrics = self._get_metrics() |
| 98 | + self.assertIn(histogram_str_builder(name, "count", labels, "0"), metrics) |
| 99 | + self.assertIn(histogram_str_builder(name, "sum", labels, "0"), metrics) |
| 100 | + self.assertIn( |
| 101 | + histogram_str_builder(name, "bucket", labels, "0", le="0.1"), metrics |
| 102 | + ) |
| 103 | + self.assertIn( |
| 104 | + histogram_str_builder(name, "bucket", labels, "0", le="1"), metrics |
| 105 | + ) |
| 106 | + self.assertIn( |
| 107 | + histogram_str_builder(name, "bucket", labels, "0", le="2.5"), metrics |
| 108 | + ) |
| 109 | + self.assertIn( |
| 110 | + histogram_str_builder(name, "bucket", labels, "0", le="5"), metrics |
| 111 | + ) |
| 112 | + self.assertIn( |
| 113 | + histogram_str_builder(name, "bucket", labels, "0", le="10"), metrics |
| 114 | + ) |
| 115 | + self.assertIn( |
| 116 | + histogram_str_builder(name, "bucket", labels, "0", le="+Inf"), metrics |
| 117 | + ) |
| 118 | + |
| 119 | + # Histogram does not support value |
| 120 | + with self.assertRaises(pb_utils.TritonModelException): |
| 121 | + metric.value() |
| 122 | + |
| 123 | + # Test increment value |
| 124 | + increment = 2023.0 |
| 125 | + # Histogram does not support increment |
| 126 | + with self.assertRaises(pb_utils.TritonModelException): |
| 127 | + metric.increment(increment) |
| 128 | + |
| 129 | + # Test set value |
| 130 | + value = 999.9 |
| 131 | + # Histogram does not support set |
| 132 | + with self.assertRaises(pb_utils.TritonModelException): |
| 133 | + metric.set(value) |
| 134 | + |
| 135 | + # Test observe value |
| 136 | + data = [0.05, 1.5, 6.0] |
| 137 | + for datum in data: |
| 138 | + metric.observe(datum) |
| 139 | + logger.log_info("Observe histogram metric with value : {}".format(datum)) |
| 140 | + |
| 141 | + metrics = self._get_metrics() |
| 142 | + self.assertIn( |
| 143 | + histogram_str_builder(name, "count", labels, str(len(data))), metrics |
| 144 | + ) |
| 145 | + self.assertIn( |
| 146 | + histogram_str_builder(name, "sum", labels, str(sum(data))), metrics |
| 147 | + ) |
| 148 | + self.assertIn( |
| 149 | + histogram_str_builder(name, "bucket", labels, "1", le="0.1"), metrics |
| 150 | + ) |
| 151 | + self.assertIn( |
| 152 | + histogram_str_builder(name, "bucket", labels, "1", le="1"), metrics |
| 153 | + ) |
| 154 | + self.assertIn( |
| 155 | + histogram_str_builder(name, "bucket", labels, "2", le="2.5"), metrics |
| 156 | + ) |
| 157 | + self.assertIn( |
| 158 | + histogram_str_builder(name, "bucket", labels, "2", le="5"), metrics |
| 159 | + ) |
| 160 | + self.assertIn( |
| 161 | + histogram_str_builder(name, "bucket", labels, "3", le="10"), metrics |
| 162 | + ) |
| 163 | + self.assertIn( |
| 164 | + histogram_str_builder(name, "bucket", labels, "3", le="+Inf"), metrics |
| 165 | + ) |
| 166 | + |
77 | 167 | def _dup_metric_helper(self, labels={}):
|
78 | 168 | # Adding logger to test if custom metrics and logging work together
|
79 | 169 | # as they use the same message queue.
|
@@ -128,14 +218,62 @@ def test_gauge_e2e(self):
|
128 | 218 | description="test metric gauge kind end to end",
|
129 | 219 | kind=pb_utils.MetricFamily.GAUGE,
|
130 | 220 | )
|
131 |
| - labels = {"example1": "counter_label1", "example2": "counter_label2"} |
| 221 | + labels = {"example1": "gauge_label1", "example2": "gauge_label2"} |
132 | 222 | metric = metric_family.Metric(labels=labels)
|
133 | 223 | self._metric_api_helper(metric, "gauge")
|
134 | 224 |
|
135 |
| - pattern = 'test_gauge_e2e{example1="counter_label1",example2="counter_label2"}' |
| 225 | + pattern = 'test_gauge_e2e{example1="gauge_label1",example2="gauge_label2"}' |
136 | 226 | metrics = self._get_metrics()
|
137 | 227 | self.assertIn(pattern, metrics)
|
138 | 228 |
|
| 229 | + def test_histogram_e2e(self): |
| 230 | + name = "test_histogram_e2e" |
| 231 | + metric_family = pb_utils.MetricFamily( |
| 232 | + name=name, |
| 233 | + description="test metric histogram kind end to end", |
| 234 | + kind=pb_utils.MetricFamily.HISTOGRAM, |
| 235 | + ) |
| 236 | + |
| 237 | + labels = {"example1": "histogram_label1", "example2": "histogram_label2"} |
| 238 | + buckets = [0.1, 1.0, 2.5, 5.0, 10.0] |
| 239 | + metric = metric_family.Metric(labels=labels, buckets=buckets) |
| 240 | + |
| 241 | + labels_str = 'example1="histogram_label1",example2="histogram_label2"' |
| 242 | + self._histogram_api_helper(metric, name, labels_str) |
| 243 | + |
| 244 | + metrics = self._get_metrics() |
| 245 | + count_pattern = f"{name}_count{{{labels_str}}}" |
| 246 | + sum_pattern = f"{name}_sum{{{labels_str}}}" |
| 247 | + bucket_pattern = f"{name}_bucket{{{labels_str}" |
| 248 | + self.assertEqual(metrics.count(count_pattern), 1) |
| 249 | + self.assertEqual(metrics.count(sum_pattern), 1) |
| 250 | + self.assertEqual(metrics.count(bucket_pattern), len(buckets) + 1) |
| 251 | + |
| 252 | + def test_histogram_args(self): |
| 253 | + name = "test_histogram_args" |
| 254 | + metric_family = pb_utils.MetricFamily( |
| 255 | + name=name, |
| 256 | + description="test metric histogram args", |
| 257 | + kind=pb_utils.MetricFamily.HISTOGRAM, |
| 258 | + ) |
| 259 | + |
| 260 | + # Test "None" value buckets |
| 261 | + with self.assertRaises(pb_utils.TritonModelException): |
| 262 | + metric_family.Metric(labels={}) |
| 263 | + with self.assertRaises(pb_utils.TritonModelException): |
| 264 | + metric_family.Metric(labels={}, buckets=None) |
| 265 | + |
| 266 | + # Test non-ascending order buckets |
| 267 | + with self.assertRaises(pb_utils.TritonModelException): |
| 268 | + metric_family.Metric(labels={}, buckets=[2.5, 0.1, 1.0, 10.0, 5.0]) |
| 269 | + |
| 270 | + # Test duplicate value buckets |
| 271 | + with self.assertRaises(pb_utils.TritonModelException): |
| 272 | + metric_family.Metric(labels={}, buckets=[1, 1, 2, 5, 5]) |
| 273 | + |
| 274 | + # Test empty list bucket |
| 275 | + metric_family.Metric(labels={}, buckets=[]) |
| 276 | + |
139 | 277 | def test_dup_metric_family_diff_kind(self):
|
140 | 278 | # Test that a duplicate metric family can't be added with a conflicting type/kind
|
141 | 279 | metric_family1 = pb_utils.MetricFamily(
|
|
0 commit comments