test.py 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. from __future__ import print_function
  2. import sys # noqa
  3. import json
  4. from tempfile import TemporaryFile
  5. import pytest # noqa
  6. from library.python.monlib.metric_registry import MetricRegistry, HistogramType
  7. from library.python.monlib.encoder import dump, dumps, TimePrecision, load, loads # noqa
  8. def test_common_labels(request):
  9. labels = {'my': 'label'}
  10. registry = MetricRegistry(labels)
  11. assert registry.common_labels == labels
  12. with pytest.raises(TypeError):
  13. MetricRegistry('foo')
  14. with pytest.raises(TypeError):
  15. MetricRegistry([])
  16. def test_json_serialization(request):
  17. registry = MetricRegistry()
  18. labels = {'foo': 'gauge'}
  19. g = registry.gauge(labels)
  20. g.set(10.0)
  21. g.set(20)
  22. c = registry.counter({'foo': 'counter'})
  23. c.inc()
  24. r = registry.rate({'foo': 'rate'})
  25. r.add(10)
  26. out = dumps(registry, format='json', precision=TimePrecision.Seconds)
  27. expected = json.loads("""{
  28. "sensors":
  29. [
  30. {
  31. "kind":"RATE",
  32. "labels":
  33. {
  34. "foo":"rate"
  35. },
  36. "value":10
  37. },
  38. {
  39. "kind":"COUNTER",
  40. "labels":
  41. {
  42. "foo":"counter"
  43. },
  44. "value":1
  45. },
  46. {
  47. "kind":"GAUGE",
  48. "labels":
  49. {
  50. "foo":"gauge"
  51. },
  52. "value":20
  53. }
  54. ]
  55. }
  56. """)
  57. j = json.loads(out)
  58. assert j == expected
  59. EXPECTED_EXPLICIT = json.loads("""
  60. {
  61. "sensors":
  62. [
  63. {
  64. "kind":"HIST",
  65. "labels":
  66. {
  67. "foo":"hist"
  68. },
  69. "hist":
  70. {
  71. "bounds":
  72. [
  73. 2,
  74. 10,
  75. 500
  76. ],
  77. "buckets":
  78. [
  79. 1,
  80. 0,
  81. 0
  82. ],
  83. "inf":1
  84. }
  85. }
  86. ]
  87. }
  88. """)
  89. EXPECTED_EXPONENTIAL = json.loads("""{
  90. "sensors":
  91. [
  92. {
  93. "kind":"HIST",
  94. "labels":
  95. {
  96. "foo":"hist"
  97. },
  98. "hist":
  99. {
  100. "bounds":
  101. [
  102. 3,
  103. 6,
  104. 12,
  105. 24,
  106. 48
  107. ],
  108. "buckets":
  109. [
  110. 1,
  111. 0,
  112. 0,
  113. 0,
  114. 0
  115. ],
  116. "inf":1
  117. }
  118. }
  119. ]
  120. }
  121. """)
  122. EXPECTED_LINEAR = json.loads("""
  123. { "sensors":
  124. [
  125. {
  126. "kind":"HIST",
  127. "labels":
  128. {
  129. "foo":"hist"
  130. },
  131. "hist":
  132. {
  133. "bounds":
  134. [
  135. 1
  136. ],
  137. "buckets":
  138. [
  139. 1
  140. ],
  141. "inf":1
  142. }
  143. }
  144. ]
  145. }""")
  146. @pytest.mark.parametrize('type,args,expected', [
  147. (HistogramType.Linear, dict(bucket_count=2, start_value=1, bucket_width=1), EXPECTED_LINEAR),
  148. (HistogramType.Explicit, dict(buckets=[2, 10, 500]), EXPECTED_EXPLICIT),
  149. (HistogramType.Exponential, dict(bucket_count=6, base=2, scale=3), EXPECTED_EXPONENTIAL),
  150. ])
  151. @pytest.mark.parametrize('rate', [True, False])
  152. def test_histograms(request, type, args, expected, rate):
  153. registry = MetricRegistry()
  154. labels = {'foo': 'hist'}
  155. h = registry.histogram_counter(labels, type, **args) if not rate else registry.histogram_rate(labels, type, **args)
  156. h.collect(1)
  157. h.collect(1000)
  158. s = dumps(registry, format='json')
  159. if rate:
  160. expected['sensors'][0]['kind'] = u'HIST_RATE'
  161. else:
  162. expected['sensors'][0]['kind'] = u'HIST'
  163. assert json.loads(s) == expected
  164. @pytest.mark.parametrize('fmt', ['json', 'spack'])
  165. def test_stream_load(request, fmt):
  166. expected = json.loads("""{"sensors":[{"kind":"GAUGE","labels":{"foo":"gauge"},"value":42}]}""")
  167. registry = MetricRegistry()
  168. labels = {'foo': 'gauge'}
  169. g = registry.gauge(labels)
  170. g.set(42)
  171. with TemporaryFile() as f:
  172. dump(registry, f, format=fmt)
  173. f.flush()
  174. f.seek(0, 0)
  175. s = load(f, from_format=fmt, to_format='json')
  176. assert json.loads(s) == expected
  177. @pytest.mark.parametrize('fmt', ['json', 'spack'])
  178. def test_stream_loads(request, fmt):
  179. expected = json.loads("""{"sensors":[{"kind":"GAUGE","labels":{"foo":"gauge"},"value":42}]}""")
  180. registry = MetricRegistry()
  181. labels = {'foo': 'gauge'}
  182. g = registry.gauge(labels)
  183. g.set(42)
  184. s = dumps(registry, format=fmt)
  185. j = loads(s, from_format=fmt, to_format='json')
  186. assert json.loads(j) == expected
  187. @pytest.mark.parametrize('fmt', ['json', 'spack'])
  188. def test_utf(request, fmt):
  189. expected = json.loads(u"""{"sensors":[{"kind":"GAUGE","labels":{"foo":"gaugeह", "bàr":"Münich"},"value":42}]}""")
  190. registry = MetricRegistry()
  191. labels = {'foo': u'gaugeह', u'bàr': u'Münich'}
  192. g = registry.gauge(labels)
  193. g.set(42)
  194. s = dumps(registry, format=fmt)
  195. j = loads(s, from_format=fmt, to_format='json')
  196. assert json.loads(j) == expected
  197. def test_gauge_sensors():
  198. registry = MetricRegistry()
  199. g = registry.gauge({'a': 'b'})
  200. ig = registry.int_gauge({'c': 'd'})
  201. g.set(2)
  202. assert g.add(3.5) == 5.5
  203. assert g.get() == 5.5
  204. ig.set(2)
  205. assert ig.inc() == 3
  206. assert ig.dec() == 2
  207. assert ig.add(3) == 5
  208. assert ig.get() == 5
  209. UNISTAT_DATA = """[
  210. ["signal1_max", 10],
  211. ["signal2_hgram", [[0, 100], [50, 200], [200, 300]]],
  212. ["prj=some-project;signal3_summ", 3],
  213. ["signal4_summ", 5]
  214. ]"""
  215. EXPECTED = json.loads("""
  216. {
  217. "sensors": [
  218. {
  219. "kind": "GAUGE",
  220. "labels": {
  221. "sensor": "signal1_max"
  222. },
  223. "value": 10
  224. },
  225. {
  226. "hist": {
  227. "buckets": [
  228. 0,
  229. 100,
  230. 200
  231. ],
  232. "bounds": [
  233. 0,
  234. 50,
  235. 200
  236. ],
  237. "inf": 300
  238. },
  239. "kind": "HIST_RATE",
  240. "labels": {
  241. "sensor": "signal2_hgram"
  242. }
  243. },
  244. {
  245. "kind": "RATE",
  246. "labels": {
  247. "sensor": "signal3_summ",
  248. "prj": "some-project"
  249. },
  250. "value": 3
  251. },
  252. {
  253. "kind": "RATE",
  254. "labels": {
  255. "sensor": "signal4_summ"
  256. },
  257. "value": 5
  258. }
  259. ]
  260. }""")
  261. def test_unistat_conversion(request):
  262. j = loads(UNISTAT_DATA, from_format='unistat', to_format='json')
  263. assert json.loads(j) == EXPECTED