github.com/thanos-io/thanos@v0.32.5/pkg/ui/react-app/src/thanos/pages/blocks/helpers.test.tsx (about) 1 import { sortBlocks, isOverlapping, getFilteredBlockPools } from './helpers'; 2 3 // Number of blocks in data: 8. 4 const overlapCaseData = { 5 blocks: [ 6 { 7 compaction: { 8 level: 1, 9 sources: ['01EWZCKPP4K0WYRTZC9RPRM5QK'], 10 }, 11 minTime: 1608034200000, 12 maxTime: 1608034500000, 13 stats: { 14 numSamples: 6634538, 15 numSeries: 2334, 16 numChunks: 51057, 17 }, 18 thanos: { 19 downsample: { 20 resolution: 0, 21 }, 22 labels: { 23 monitor: 'prometheus_one', 24 }, 25 source: 'sidecar', 26 }, 27 ulid: '01EWZCKPP4K0WYRTZC9RPRM5QK', 28 version: 1, 29 }, 30 31 { 32 compaction: { 33 level: 1, 34 sources: ['01ESK5B1WQB6QEZQ4P0YCQXEC4'], 35 }, 36 minTime: 1608034200000, 37 maxTime: 1608034500000, 38 stats: { 39 numSamples: 6634538, 40 numSeries: 2334, 41 numChunks: 51057, 42 }, 43 thanos: { 44 downsample: { 45 resolution: 0, 46 }, 47 labels: { 48 monitor: 'prometheus_one', 49 }, 50 source: 'sidecar', 51 }, 52 ulid: '01ESK5B1WQB6QEZQ4P0YCQXEC4', 53 version: 1, 54 }, 55 { 56 compaction: { 57 level: 1, 58 sources: ['01ET8F8C73GGXH279R6YMTWFHY'], 59 }, 60 minTime: 1608034500000, 61 maxTime: 1608034800000, 62 stats: { 63 numSamples: 6979750, 64 numSeries: 2333, 65 numChunks: 58325, 66 }, 67 thanos: { 68 downsample: { 69 resolution: 0, 70 }, 71 labels: { 72 monitor: 'prometheus_one', 73 }, 74 source: 'sidecar', 75 }, 76 ulid: '01ET8F8C73GGXH279R6YMTWFHY', 77 version: 1, 78 }, 79 { 80 compaction: { 81 level: 1, 82 sources: ['01EWZCA2CFC5CPJE8CF9TXBW9H'], 83 }, 84 minTime: 1608034500000, 85 maxTime: 1608034800000, 86 stats: { 87 numSamples: 6979750, 88 numSeries: 2333, 89 numChunks: 58325, 90 }, 91 thanos: { 92 downsample: { 93 resolution: 0, 94 }, 95 labels: { 96 monitor: 'prometheus_one', 97 }, 98 source: 'sidecar', 99 }, 100 ulid: '01EWZCA2CFC5CPJE8CF9TXBW9H', 101 version: 1, 102 }, 103 { 104 compaction: { 105 level: 1, 106 sources: ['01EXYEAS52VZW5G1FPV4NPH2D1'], 107 }, 108 minTime: 1608034500000, 109 maxTime: 1608034800000, 110 stats: { 111 numSamples: 6979750, 112 numSeries: 2333, 113 numChunks: 58325, 114 }, 115 thanos: { 116 downsample: { 117 resolution: 0, 118 }, 119 labels: { 120 monitor: 'prometheus_one', 121 }, 122 source: 'sidecar', 123 }, 124 ulid: '01EXYEAS52VZW5G1FPV4NPH2D1', 125 version: 1, 126 }, 127 { 128 compaction: { 129 level: 1, 130 sources: ['01EWZCC9E998R19K8FKSTWP776'], 131 }, 132 minTime: 1608034400000, 133 maxTime: 1608034700000, 134 stats: { 135 numSamples: 6979750, 136 numSeries: 2333, 137 numChunks: 58325, 138 }, 139 thanos: { 140 downsample: { 141 resolution: 0, 142 }, 143 labels: { 144 monitor: 'prometheus_one', 145 }, 146 source: 'sidecar', 147 }, 148 ulid: '01EWZCC9E998R19K8FKSTWP776', 149 version: 1, 150 }, 151 { 152 compaction: { 153 level: 1, 154 sources: ['01EXYE0YB9JYCT48B6673H4YNS'], 155 }, 156 minTime: 1608034600000, 157 maxTime: 1608034800000, 158 stats: { 159 numSamples: 6979750, 160 numSeries: 2333, 161 numChunks: 58325, 162 }, 163 thanos: { 164 downsample: { 165 resolution: 0, 166 }, 167 labels: { 168 monitor: 'prometheus_one', 169 }, 170 source: 'sidecar', 171 }, 172 ulid: '01EXYE0YB9JYCT48B6673H4YNS', 173 version: 1, 174 }, 175 { 176 compaction: { 177 level: 1, 178 sources: ['01EEF8AGCHTPJ1MZ8KH0SEJZ4E'], 179 }, 180 minTime: 1608034250000, 181 maxTime: 1608034350000, 182 stats: { 183 numSamples: 6979750, 184 numSeries: 2333, 185 numChunks: 58325, 186 }, 187 thanos: { 188 downsample: { 189 resolution: 0, 190 }, 191 labels: { 192 monitor: 'prometheus_one', 193 }, 194 source: 'sidecar', 195 }, 196 ulid: '01EEF8AGCHTPJ1MZ8KH0SEJZ4E', 197 version: 1, 198 }, 199 ], 200 label: 'monitor', 201 }; 202 203 // Total number of blocks = 8 204 const blockPools = { 205 '1': { 206 '1-0': [ 207 [ 208 { 209 ulid: '01FV7ZG6MBEM5X5H08RXV27AJK', 210 minTime: 1644166200000, 211 maxTime: 1644166500000, 212 stats: { 213 numSamples: 168320, 214 numSeries: 2809, 215 numChunks: 2809, 216 }, 217 compaction: { 218 level: 1, 219 sources: ['01FV7ZG6MBEM5X5H08RXV27AJK'], 220 }, 221 version: 1, 222 thanos: { 223 labels: { 224 prometheus: 'prom-1', 225 }, 226 downsample: { 227 resolution: 0, 228 }, 229 source: 'sidecar', 230 segment_files: ['000001'], 231 files: [ 232 { 233 rel_path: 'chunks/000001', 234 size_bytes: 145198, 235 }, 236 { 237 rel_path: 'index', 238 size_bytes: 252717, 239 }, 240 { 241 rel_path: 'meta.json', 242 }, 243 ], 244 }, 245 }, 246 { 247 ulid: '01FV7ZSBKB4NN14FXD6WZ17EZP', 248 minTime: 1644166500000, 249 maxTime: 1644166800000, 250 stats: { 251 numSamples: 168320, 252 numSeries: 2809, 253 numChunks: 2809, 254 }, 255 compaction: { 256 level: 1, 257 sources: ['01FV7ZSBKB4NN14FXD6WZ17EZP'], 258 }, 259 version: 1, 260 thanos: { 261 labels: { 262 prometheus: 'prom-1', 263 }, 264 downsample: { 265 resolution: 0, 266 }, 267 source: 'sidecar', 268 segment_files: ['000001'], 269 files: [ 270 { 271 rel_path: 'chunks/000001', 272 size_bytes: 142780, 273 }, 274 { 275 rel_path: 'index', 276 size_bytes: 252717, 277 }, 278 { 279 rel_path: 'meta.json', 280 }, 281 ], 282 }, 283 }, 284 ], 285 ], 286 }, 287 '2': { 288 '1-0': [ 289 [ 290 { 291 ulid: '01FV7B65Z2KR15ZKC3E9HCCNXH', 292 minTime: 1644144900000, 293 maxTime: 1644145200000, 294 stats: { 295 numSamples: 171320, 296 numSeries: 2859, 297 numChunks: 2859, 298 }, 299 compaction: { 300 level: 1, 301 sources: ['01FV7B65Z2KR15ZKC3E9HCCNXH'], 302 }, 303 version: 1, 304 thanos: { 305 labels: { 306 prometheus: 'prom-2', 307 }, 308 downsample: { 309 resolution: 0, 310 }, 311 source: 'sidecar', 312 segment_files: ['000001'], 313 files: [ 314 { 315 rel_path: 'chunks/000001', 316 size_bytes: 152262, 317 }, 318 { 319 rel_path: 'index', 320 size_bytes: 257544, 321 }, 322 { 323 rel_path: 'meta.json', 324 }, 325 ], 326 }, 327 }, 328 { 329 ulid: '01FV7BFAY2ZFJ0PK3872CPZHY8', 330 minTime: 1644145200000, 331 maxTime: 1644145500000, 332 stats: { 333 numSamples: 171320, 334 numSeries: 2859, 335 numChunks: 2859, 336 }, 337 compaction: { 338 level: 1, 339 sources: ['01FV7BFAY2ZFJ0PK3872CPZHY8'], 340 }, 341 version: 1, 342 thanos: { 343 labels: { 344 prometheus: 'prom-2', 345 }, 346 downsample: { 347 resolution: 0, 348 }, 349 source: 'sidecar', 350 segment_files: ['000001'], 351 files: [ 352 { 353 rel_path: 'chunks/000001', 354 size_bytes: 164725, 355 }, 356 { 357 rel_path: 'index', 358 size_bytes: 257544, 359 }, 360 { 361 rel_path: 'meta.json', 362 }, 363 ], 364 }, 365 }, 366 ], 367 ], 368 }, 369 '3': { 370 '1-0': [ 371 [ 372 { 373 ulid: '01FT8X9MJF5G7PFRNGZBYT8SCS', 374 minTime: 1643123700000, 375 maxTime: 1643124000000, 376 stats: { 377 numSamples: 171320, 378 numSeries: 2859, 379 numChunks: 2859, 380 }, 381 compaction: { 382 level: 1, 383 sources: ['01FT8X9MJF5G7PFRNGZBYT8SCS'], 384 }, 385 version: 1, 386 thanos: { 387 labels: { 388 prometheus: 'prom-2 random:2', 389 }, 390 downsample: { 391 resolution: 0, 392 }, 393 source: 'sidecar', 394 segment_files: ['000001'], 395 files: [ 396 { 397 rel_path: 'chunks/000001', 398 size_bytes: 143670, 399 }, 400 { 401 rel_path: 'index', 402 size_bytes: 257574, 403 }, 404 { 405 rel_path: 'meta.json', 406 }, 407 ], 408 }, 409 }, 410 { 411 ulid: '01FT8XJSHDYNVJ0SWP2SGMC2DR', 412 minTime: 1643124000000, 413 maxTime: 1643124300000, 414 stats: { 415 numSamples: 171320, 416 numSeries: 2859, 417 numChunks: 2859, 418 }, 419 compaction: { 420 level: 1, 421 sources: ['01FT8XJSHDYNVJ0SWP2SGMC2DR'], 422 }, 423 version: 1, 424 thanos: { 425 labels: { 426 prometheus: 'prom-2 random:2', 427 }, 428 downsample: { 429 resolution: 0, 430 }, 431 source: 'sidecar', 432 segment_files: ['000001'], 433 files: [ 434 { 435 rel_path: 'chunks/000001', 436 size_bytes: 148750, 437 }, 438 { 439 rel_path: 'index', 440 size_bytes: 257574, 441 }, 442 { 443 rel_path: 'meta.json', 444 }, 445 ], 446 }, 447 }, 448 ], 449 ], 450 }, 451 '4': { 452 '1-0': [ 453 [ 454 { 455 ulid: '01FT8XJRPTQ9VP1K1Y3M3RHK4R', 456 minTime: 1643124000000, 457 maxTime: 1643124300000, 458 stats: { 459 numSamples: 171320, 460 numSeries: 2859, 461 numChunks: 2859, 462 }, 463 compaction: { 464 level: 1, 465 sources: ['01FT8XJRPTQ9VP1K1Y3M3RHK4R'], 466 }, 467 version: 1, 468 thanos: { 469 labels: { 470 prometheus: 'prom-1 random:1', 471 }, 472 downsample: { 473 resolution: 0, 474 }, 475 source: 'sidecar', 476 segment_files: ['000001'], 477 files: [ 478 { 479 rel_path: 'chunks/000001', 480 size_bytes: 210856, 481 }, 482 { 483 rel_path: 'index', 484 size_bytes: 257590, 485 }, 486 { 487 rel_path: 'meta.json', 488 }, 489 ], 490 }, 491 }, 492 { 493 ulid: '01FT8XVXNNJCT16QQTFYDKRG7W', 494 minTime: 1643124300000, 495 maxTime: 1643124600000, 496 stats: { 497 numSamples: 171320, 498 numSeries: 2859, 499 numChunks: 2859, 500 }, 501 compaction: { 502 level: 1, 503 sources: ['01FT8XVXNNJCT16QQTFYDKRG7W'], 504 }, 505 version: 1, 506 thanos: { 507 labels: { 508 prometheus: 'prom-1 random:1', 509 }, 510 downsample: { 511 resolution: 0, 512 }, 513 source: 'sidecar', 514 segment_files: ['000001'], 515 files: [ 516 { 517 rel_path: 'chunks/000001', 518 size_bytes: 224409, 519 }, 520 { 521 rel_path: 'index', 522 size_bytes: 257590, 523 }, 524 { 525 rel_path: 'meta.json', 526 }, 527 ], 528 }, 529 }, 530 ], 531 ], 532 }, 533 }; 534 535 // Total filtered blocks = 1 536 const filteredBlocks = [ 537 { 538 ulid: '01FV7B65Z2KR15ZKC3E9HCCNXH', 539 minTime: 1644144900000, 540 maxTime: 1644145200000, 541 stats: { 542 numSamples: 171320, 543 numSeries: 2859, 544 numChunks: 2859, 545 }, 546 compaction: { 547 level: 1, 548 sources: ['01FV7B65Z2KR15ZKC3E9HCCNXH'], 549 }, 550 version: 1, 551 thanos: { 552 labels: { 553 prometheus: 'prom-2', 554 }, 555 downsample: { 556 resolution: 0, 557 }, 558 source: 'sidecar', 559 segment_files: ['000001'], 560 files: [ 561 { 562 rel_path: 'chunks/000001', 563 size_bytes: 152262, 564 }, 565 { 566 rel_path: 'index', 567 size_bytes: 257544, 568 }, 569 { 570 rel_path: 'meta.json', 571 }, 572 ], 573 }, 574 }, 575 ]; 576 577 const sorted = sortBlocks(overlapCaseData.blocks, overlapCaseData.label, true); 578 const filteredBlockPools = getFilteredBlockPools(blockPools, filteredBlocks); 579 const source = 'prometheus_one'; 580 581 describe('overlapping blocks', () => { 582 it('has 1 source', () => { 583 expect(Object.keys(sorted)).toHaveLength(1); 584 }); 585 586 it('has 1 level-resolution', () => { 587 expect(Object.keys(sorted[source])).toHaveLength(1); 588 }); 589 590 const rows = Object.values(sorted[source])[0]; 591 it('has 5 rows', () => { 592 expect(rows).toHaveLength(5); 593 }); 594 595 it('renders 2 blocks in first row', () => { 596 expect(rows[0]).toHaveLength(2); 597 }); 598 599 it('renders 2 blocks in second row', () => { 600 expect(rows[1]).toHaveLength(2); 601 }); 602 603 it('renders 2 blocks in third row', () => { 604 expect(rows[2]).toHaveLength(2); 605 }); 606 607 it('renders 1 block in fourth row', () => { 608 expect(rows[3]).toHaveLength(1); 609 }); 610 611 it('renders 1 block in fifth row', () => { 612 expect(rows[4]).toHaveLength(1); 613 }); 614 }); 615 616 describe('isOverlapping helper', () => { 617 const b = overlapCaseData.blocks[0]; 618 it('should return true for perfectly overlapping blocks', () => { 619 expect(isOverlapping({ ...b, minTime: 10, maxTime: 20 }, { ...b, minTime: 10, maxTime: 20 })).toBe(true); 620 }); 621 622 it('should return true for partially overlapping blocks', () => { 623 expect(isOverlapping({ ...b, minTime: 10, maxTime: 20 }, { ...b, minTime: 15, maxTime: 25 })).toBe(true); 624 }); 625 626 it('should return false for non-overlapping blocks', () => { 627 expect(isOverlapping({ ...b, minTime: 10, maxTime: 20 }, { ...b, minTime: 30, maxTime: 40 })).toBe(false); 628 }); 629 630 it('should return false if second block starts where first ends (a.maxTime == b.minTime)', () => { 631 expect(isOverlapping({ ...b, minTime: 10, maxTime: 20 }, { ...b, minTime: 20, maxTime: 30 })).toBe(false); 632 }); 633 }); 634 635 describe('Block Pools', () => { 636 it('should have exactly 4 objects', () => { 637 expect(Object.keys(blockPools)).toHaveLength(4); 638 }); 639 }); 640 641 describe('Filtered block pools', () => { 642 const objectKeyArray = Object.keys(filteredBlockPools); 643 const filteredBlockPoolArray = 644 filteredBlockPools[objectKeyArray[0]][Object.keys(filteredBlockPools[objectKeyArray[0]])[0]][0]; 645 646 it('should have exactly one object', () => { 647 expect(objectKeyArray).toHaveLength(1); 648 }); 649 it('should have key equals 2', () => { 650 expect(objectKeyArray[0]).toEqual('2'); 651 }); 652 it('should contain contain blocks having same labels', () => { 653 expect(filteredBlockPoolArray[0].thanos.labels).toEqual(filteredBlockPoolArray[1].thanos.labels); 654 }); 655 it('should contain the first block having exactly the same labels as in filteredBlocks', () => { 656 expect(filteredBlockPoolArray[0].thanos.labels).toEqual(filteredBlocks[0].thanos.labels); 657 }); 658 });