prometheus

Форк
0
336 строк · 11.2 Кб
1
import moment from 'moment';
2

3
import {
4
  escapeHTML,
5
  metricToSeriesName,
6
  formatTime,
7
  parseTime,
8
  formatDuration,
9
  parseDuration,
10
  humanizeDuration,
11
  formatRelative,
12
  now,
13
  toQueryString,
14
  encodePanelOptionsToQueryString,
15
  parseOption,
16
  decodePanelOptionsFromQueryString,
17
  parsePrometheusFloat,
18
} from '.';
19
import { GraphDisplayMode, PanelType } from '../pages/graph/Panel';
20

21
describe('Utils', () => {
22
  describe('escapeHTML', (): void => {
23
    it('escapes html sequences', () => {
24
      expect(escapeHTML(`<strong>'example'&"another/example"</strong>`)).toEqual(
25
        '&lt;strong&gt;&#39;example&#39;&amp;&quot;another&#x2F;example&quot;&lt;&#x2F;strong&gt;'
26
      );
27
    });
28
  });
29

30
  describe('metricToSeriesName', () => {
31
    it('returns "{}" if labels is empty', () => {
32
      const labels = {};
33
      expect(metricToSeriesName(labels)).toEqual('{}');
34
    });
35
    it('returns "metric_name{}" if labels only contains __name__', () => {
36
      const labels = { __name__: 'metric_name' };
37
      expect(metricToSeriesName(labels)).toEqual('metric_name{}');
38
    });
39
    it('returns "{label1=value_1, ..., labeln=value_n} if there are many labels and no name', () => {
40
      const labels = { label1: 'value_1', label2: 'value_2', label3: 'value_3' };
41
      expect(metricToSeriesName(labels)).toEqual('{label1="value_1", label2="value_2", label3="value_3"}');
42
    });
43
    it('returns "metric_name{label1=value_1, ... ,labeln=value_n}" if there are many labels and a name', () => {
44
      const labels = {
45
        __name__: 'metric_name',
46
        label1: 'value_1',
47
        label2: 'value_2',
48
        label3: 'value_3',
49
      };
50
      expect(metricToSeriesName(labels)).toEqual('metric_name{label1="value_1", label2="value_2", label3="value_3"}');
51
    });
52
  });
53

54
  describe('Time format', () => {
55
    describe('formatTime', () => {
56
      it('returns a time string representing the time in seconds', () => {
57
        expect(formatTime(1572049380000)).toEqual('2019-10-26 00:23:00');
58
        expect(formatTime(0)).toEqual('1970-01-01 00:00:00');
59
      });
60
    });
61

62
    describe('parseTime', () => {
63
      it('returns a time string representing the time in seconds', () => {
64
        expect(parseTime('2019-10-26 00:23')).toEqual(1572049380000);
65
        expect(parseTime('1970-01-01 00:00')).toEqual(0);
66
        expect(parseTime('0001-01-01T00:00:00Z')).toEqual(-62135596800000);
67
      });
68
    });
69

70
    describe('parseDuration and formatDuration', () => {
71
      describe('should parse and format durations correctly', () => {
72
        const tests: { input: string; output: number; expectedString?: string }[] = [
73
          {
74
            input: '0',
75
            output: 0,
76
            expectedString: '0s',
77
          },
78
          {
79
            input: '0w',
80
            output: 0,
81
            expectedString: '0s',
82
          },
83
          {
84
            input: '0s',
85
            output: 0,
86
          },
87
          {
88
            input: '324ms',
89
            output: 324,
90
          },
91
          {
92
            input: '3s',
93
            output: 3 * 1000,
94
          },
95
          {
96
            input: '5m',
97
            output: 5 * 60 * 1000,
98
          },
99
          {
100
            input: '1h',
101
            output: 60 * 60 * 1000,
102
          },
103
          {
104
            input: '4d',
105
            output: 4 * 24 * 60 * 60 * 1000,
106
          },
107
          {
108
            input: '4d1h',
109
            output: 4 * 24 * 60 * 60 * 1000 + 1 * 60 * 60 * 1000,
110
          },
111
          {
112
            input: '14d',
113
            output: 14 * 24 * 60 * 60 * 1000,
114
            expectedString: '2w',
115
          },
116
          {
117
            input: '3w',
118
            output: 3 * 7 * 24 * 60 * 60 * 1000,
119
          },
120
          {
121
            input: '3w2d1h',
122
            output: 3 * 7 * 24 * 60 * 60 * 1000 + 2 * 24 * 60 * 60 * 1000 + 60 * 60 * 1000,
123
            expectedString: '23d1h',
124
          },
125
          {
126
            input: '1y2w3d4h5m6s7ms',
127
            output:
128
              1 * 365 * 24 * 60 * 60 * 1000 +
129
              2 * 7 * 24 * 60 * 60 * 1000 +
130
              3 * 24 * 60 * 60 * 1000 +
131
              4 * 60 * 60 * 1000 +
132
              5 * 60 * 1000 +
133
              6 * 1000 +
134
              7,
135
            expectedString: '382d4h5m6s7ms',
136
          },
137
        ];
138

139
        tests.forEach((t) => {
140
          it(t.input, () => {
141
            const d = parseDuration(t.input);
142
            expect(d).toEqual(t.output);
143
            expect(formatDuration(d!)).toEqual(t.expectedString || t.input);
144
          });
145
        });
146
      });
147

148
      describe('should fail to parse invalid durations', () => {
149
        const tests = ['1', '1y1m1d', '-1w', '1.5d', 'd', ''];
150

151
        tests.forEach((t) => {
152
          it(t, () => {
153
            expect(parseDuration(t)).toBe(null);
154
          });
155
        });
156
      });
157
    });
158

159
    describe('humanizeDuration', () => {
160
      it('humanizes zero', () => {
161
        expect(humanizeDuration(0)).toEqual('0s');
162
      });
163
      it('humanizes milliseconds', () => {
164
        expect(humanizeDuration(1.234567)).toEqual('1.235ms');
165
        expect(humanizeDuration(12.34567)).toEqual('12.346ms');
166
        expect(humanizeDuration(123.45678)).toEqual('123.457ms');
167
        expect(humanizeDuration(123)).toEqual('123.000ms');
168
      });
169
      it('humanizes seconds', () => {
170
        expect(humanizeDuration(12340)).toEqual('12.340s');
171
      });
172
      it('humanizes minutes', () => {
173
        expect(humanizeDuration(1234567)).toEqual('20m 34s');
174
      });
175

176
      it('humanizes hours', () => {
177
        expect(humanizeDuration(12345678)).toEqual('3h 25m 45s');
178
      });
179

180
      it('humanizes days', () => {
181
        expect(humanizeDuration(123456789)).toEqual('1d 10h 17m 36s');
182
        expect(humanizeDuration(123456789000)).toEqual('1428d 21h 33m 9s');
183
      });
184
      it('takes sign into account', () => {
185
        expect(humanizeDuration(-123456789000)).toEqual('-1428d 21h 33m 9s');
186
      });
187
    });
188

189
    describe('formatRelative', () => {
190
      it('renders never for pre-beginning-of-time strings', () => {
191
        expect(formatRelative('0001-01-01T00:00:00Z', now())).toEqual('Never');
192
      });
193
      it('renders a humanized duration for durations', () => {
194
        expect(formatRelative('2019-11-04T09:15:29.578701-07:00', parseTime('2019-11-04T09:15:35.8701-07:00'))).toEqual(
195
          '6.292s ago'
196
        );
197
        expect(formatRelative('2019-11-04T09:15:35.8701-07:00', parseTime('2019-11-04T09:15:29.578701-07:00'))).toEqual(
198
          '-6.292s ago'
199
        );
200
      });
201
    });
202
  });
203

204
  describe('URL Params', () => {
205
    const panels: any = [
206
      {
207
        key: '0',
208
        options: {
209
          endTime: 1572046620000,
210
          expr: 'rate(node_cpu_seconds_total{mode="system"}[1m])',
211
          range: 60 * 60 * 1000,
212
          resolution: null,
213
          displayMode: GraphDisplayMode.Lines,
214
          type: PanelType.Graph,
215
        },
216
      },
217
      {
218
        key: '1',
219
        options: {
220
          endTime: null,
221
          expr: 'node_filesystem_avail_bytes',
222
          range: 60 * 60 * 1000,
223
          resolution: null,
224
          displayMode: GraphDisplayMode.Lines,
225
          type: PanelType.Table,
226
        },
227
      },
228
    ];
229
    const query = `?g0.expr=rate(node_cpu_seconds_total%7Bmode%3D%22system%22%7D%5B1m%5D)&g0.tab=0&g0.display_mode=${GraphDisplayMode.Lines}&g0.show_exemplars=0&g0.range_input=1h&g0.end_input=2019-10-25%2023%3A37%3A00&g0.moment_input=2019-10-25%2023%3A37%3A00&g1.expr=node_filesystem_avail_bytes&g1.tab=1&g1.display_mode=${GraphDisplayMode.Lines}&g1.show_exemplars=0&g1.range_input=1h`;
230

231
    describe('decodePanelOptionsFromQueryString', () => {
232
      it('returns [] when query is empty', () => {
233
        expect(decodePanelOptionsFromQueryString('')).toEqual([]);
234
      });
235
      it('returns and array of parsed params when query string is non-empty', () => {
236
        expect(decodePanelOptionsFromQueryString(query)).toMatchObject(panels);
237
      });
238
    });
239

240
    describe('parseOption', () => {
241
      it('should return empty object for invalid param', () => {
242
        expect(parseOption('invalid_prop=foo')).toEqual({});
243
      });
244
      it('should parse expr param', () => {
245
        expect(parseOption('expr=foo')).toEqual({ expr: 'foo' });
246
      });
247
      it('should parse stacked', () => {
248
        expect(parseOption('stacked=1')).toEqual({ displayMode: GraphDisplayMode.Stacked });
249
      });
250
      it('should parse end_input', () => {
251
        expect(parseOption('end_input=2019-10-25%2023%3A37')).toEqual({ endTime: moment.utc('2019-10-25 23:37').valueOf() });
252
      });
253
      it('should parse moment_input', () => {
254
        expect(parseOption('moment_input=2019-10-25%2023%3A37')).toEqual({
255
          endTime: moment.utc('2019-10-25 23:37').valueOf(),
256
        });
257
      });
258

259
      describe('step_input', () => {
260
        it('should return step_input parsed if > 0', () => {
261
          expect(parseOption('step_input=2')).toEqual({ resolution: 2 });
262
        });
263
        it('should return empty object if step is equal 0', () => {
264
          expect(parseOption('step_input=0')).toEqual({});
265
        });
266
      });
267

268
      describe('range_input', () => {
269
        it('should return range parsed if its not null', () => {
270
          expect(parseOption('range_input=2h')).toEqual({ range: 2 * 60 * 60 * 1000 });
271
        });
272
        it('should return empty object for invalid value', () => {
273
          expect(parseOption('range_input=h')).toEqual({});
274
        });
275
      });
276

277
      describe('Parse type param', () => {
278
        it('should return panel type "graph" if tab=0', () => {
279
          expect(parseOption('tab=0')).toEqual({ type: PanelType.Graph });
280
        });
281
        it('should return panel type "table" if tab=1', () => {
282
          expect(parseOption('tab=1')).toEqual({ type: PanelType.Table });
283
        });
284
      });
285
    });
286

287
    describe('toQueryString', () => {
288
      it('should generate query string from panel options', () => {
289
        expect(
290
          toQueryString({
291
            id: 'asdf',
292
            key: '0',
293
            options: {
294
              expr: 'foo',
295
              type: PanelType.Graph,
296
              displayMode: GraphDisplayMode.Stacked,
297
              showExemplars: true,
298
              range: 0,
299
              endTime: null,
300
              resolution: 1,
301
            },
302
          })
303
        ).toEqual(
304
          `g0.expr=foo&g0.tab=0&g0.display_mode=${GraphDisplayMode.Stacked}&g0.show_exemplars=1&g0.range_input=0s&g0.step_input=1`
305
        );
306
      });
307
    });
308

309
    describe('encodePanelOptionsToQueryString', () => {
310
      it('returns ? when panels is empty', () => {
311
        expect(encodePanelOptionsToQueryString([])).toEqual('?');
312
      });
313
      it('returns an encoded query string otherwise', () => {
314
        expect(encodePanelOptionsToQueryString(panels)).toEqual(query);
315
      });
316
    });
317

318
    describe('parsePrometheusFloat', () => {
319
      it('returns Inf when param is Inf', () => {
320
        expect(parsePrometheusFloat('Inf')).toEqual('Inf');
321
      });
322
      it('returns +Inf when param is +Inf', () => {
323
        expect(parsePrometheusFloat('+Inf')).toEqual('+Inf');
324
      });
325
      it('returns -Inf when param is -Inf', () => {
326
        expect(parsePrometheusFloat('-Inf')).toEqual('-Inf');
327
      });
328
      it('returns 17 when param is 1.7e+01', () => {
329
        expect(parsePrometheusFloat('1.7e+01')).toEqual(17);
330
      });
331
      it('returns -17 when param is -1.7e+01', () => {
332
        expect(parsePrometheusFloat('-1.7e+01')).toEqual(-17);
333
      });
334
    });
335
  });
336
});
337

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.