test.py 6.5 KB

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