1/* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17import {TIME_UNIT_TO_NANO} from 'common/time_units'; 18import {ParserBuilder} from 'test/unit/parser_builder'; 19import {TimestampConverterUtils} from 'test/unit/timestamp_converter_utils'; 20import {TraceBuilder} from 'test/unit/trace_builder'; 21import {TraceUtils} from 'test/unit/trace_utils'; 22import {UnitTestUtils} from 'test/unit/utils'; 23import {FrameMapBuilder} from './frame_map_builder'; 24import {AbsoluteFrameIndex} from './index_types'; 25import {Trace} from './trace'; 26import {TraceType} from './trace_type'; 27 28describe('Trace', () => { 29 let trace: Trace<string>; 30 31 const time9 = TimestampConverterUtils.makeRealTimestamp(9n); 32 const time10 = TimestampConverterUtils.makeRealTimestamp(10n); 33 const time11 = TimestampConverterUtils.makeRealTimestamp(11n); 34 const time12 = TimestampConverterUtils.makeRealTimestamp(12n); 35 const time13 = TimestampConverterUtils.makeRealTimestamp(13n); 36 const time14 = TimestampConverterUtils.makeRealTimestamp(14n); 37 const time15 = TimestampConverterUtils.makeRealTimestamp(15n); 38 39 beforeAll(() => { 40 // Time: 10 11 12 13 41 // Entry: 0 1-2 3 4 42 // | | | | 43 // Frame: 0 1 2 3 4-5 6 44 trace = new TraceBuilder<string>() 45 .setEntries(['entry-0', 'entry-1', 'entry-2', 'entry-3', 'entry-4']) 46 .setTimestamps([time10, time11, time11, time12, time13]) 47 .setFrame(0, 0) 48 .setFrame(1, 1) 49 .setFrame(2, 1) 50 .setFrame(3, 4) 51 .setFrame(3, 5) 52 .setFrame(4, 6) 53 .build(); 54 }); 55 56 it('getEntry()', async () => { 57 expect(await trace.getEntry(0).getValue()).toEqual('entry-0'); 58 expect(await trace.getEntry(4).getValue()).toEqual('entry-4'); 59 expect(() => { 60 trace.getEntry(5); 61 }).toThrow(); 62 63 expect(await trace.getEntry(-1).getValue()).toEqual('entry-4'); 64 expect(await trace.getEntry(-5).getValue()).toEqual('entry-0'); 65 expect(() => { 66 trace.getEntry(-6); 67 }).toThrow(); 68 }); 69 70 it('getFrame()', async () => { 71 expect(await TraceUtils.extractFrames(trace.getFrame(0))).toEqual( 72 new Map<AbsoluteFrameIndex, string[]>([[0, ['entry-0']]]), 73 ); 74 expect(await TraceUtils.extractFrames(trace.getFrame(1))).toEqual( 75 new Map<AbsoluteFrameIndex, string[]>([[1, ['entry-1', 'entry-2']]]), 76 ); 77 expect(await TraceUtils.extractFrames(trace.getFrame(2))).toEqual( 78 new Map<AbsoluteFrameIndex, string[]>([[2, []]]), 79 ); 80 expect(await TraceUtils.extractFrames(trace.getFrame(3))).toEqual( 81 new Map<AbsoluteFrameIndex, string[]>([[3, []]]), 82 ); 83 expect(await TraceUtils.extractFrames(trace.getFrame(4))).toEqual( 84 new Map<AbsoluteFrameIndex, string[]>([[4, ['entry-3']]]), 85 ); 86 expect(await TraceUtils.extractFrames(trace.getFrame(5))).toEqual( 87 new Map<AbsoluteFrameIndex, string[]>([[5, ['entry-3']]]), 88 ); 89 expect(await TraceUtils.extractFrames(trace.getFrame(6))).toEqual( 90 new Map<AbsoluteFrameIndex, string[]>([[6, ['entry-4']]]), 91 ); 92 }); 93 94 it('findClosestEntry()', async () => { 95 // empty 96 expect(trace.sliceEntries(0, 0).findClosestEntry(time10)).toBeUndefined(); 97 98 // slice 99 const slice = trace.sliceEntries(1, -1); 100 expect(await slice.findClosestEntry(time9)?.getValue()).toEqual('entry-1'); 101 expect(await slice.findClosestEntry(time10)?.getValue()).toEqual('entry-1'); 102 expect(await slice.findClosestEntry(time11)?.getValue()).toEqual('entry-1'); 103 expect(await slice.findClosestEntry(time12)?.getValue()).toEqual('entry-3'); 104 expect(await slice.findClosestEntry(time13)?.getValue()).toEqual('entry-3'); 105 expect(await slice.findClosestEntry(time14)?.getValue()).toEqual('entry-3'); 106 107 // full trace 108 expect(await trace.findClosestEntry(time9)?.getValue()).toEqual('entry-0'); 109 expect(await trace.findClosestEntry(time10)?.getValue()).toEqual('entry-0'); 110 expect(await trace.findClosestEntry(time11)?.getValue()).toEqual('entry-1'); 111 expect(await trace.findClosestEntry(time12)?.getValue()).toEqual('entry-3'); 112 expect(await trace.findClosestEntry(time13)?.getValue()).toEqual('entry-4'); 113 expect(await trace.findClosestEntry(time14)?.getValue()).toEqual('entry-4'); 114 }); 115 116 it('findFirstGreaterOrEqualEntry()', async () => { 117 // empty 118 expect( 119 trace.sliceEntries(0, 0).findFirstGreaterOrEqualEntry(time10), 120 ).toBeUndefined(); 121 122 // slice 123 const slice = trace.sliceEntries(1, -1); 124 expect(await slice.findFirstGreaterOrEqualEntry(time9)?.getValue()).toEqual( 125 'entry-1', 126 ); 127 expect( 128 await slice.findFirstGreaterOrEqualEntry(time10)?.getValue(), 129 ).toEqual('entry-1'); 130 expect( 131 await slice.findFirstGreaterOrEqualEntry(time11)?.getValue(), 132 ).toEqual('entry-1'); 133 expect( 134 await slice.findFirstGreaterOrEqualEntry(time12)?.getValue(), 135 ).toEqual('entry-3'); 136 expect(await slice.findFirstGreaterOrEqualEntry(time13)).toBeUndefined(); 137 138 // full trace 139 expect(await trace.findFirstGreaterOrEqualEntry(time9)?.getValue()).toEqual( 140 'entry-0', 141 ); 142 expect( 143 await trace.findFirstGreaterOrEqualEntry(time10)?.getValue(), 144 ).toEqual('entry-0'); 145 expect( 146 await trace.findFirstGreaterOrEqualEntry(time11)?.getValue(), 147 ).toEqual('entry-1'); 148 expect( 149 await trace.findFirstGreaterOrEqualEntry(time12)?.getValue(), 150 ).toEqual('entry-3'); 151 expect( 152 await trace.findFirstGreaterOrEqualEntry(time13)?.getValue(), 153 ).toEqual('entry-4'); 154 expect(await trace.findFirstGreaterOrEqualEntry(time14)).toBeUndefined(); 155 }); 156 157 it('findFirstGreaterEntry()', async () => { 158 // empty 159 expect( 160 trace.sliceEntries(0, 0).findFirstGreaterEntry(time10), 161 ).toBeUndefined(); 162 163 // slice 164 const slice = trace.sliceEntries(1, -1); 165 expect(await slice.findFirstGreaterEntry(time9)?.getValue()).toEqual( 166 'entry-1', 167 ); 168 expect(await slice.findFirstGreaterEntry(time10)?.getValue()).toEqual( 169 'entry-1', 170 ); 171 expect(await slice.findFirstGreaterEntry(time11)?.getValue()).toEqual( 172 'entry-3', 173 ); 174 expect(slice.findFirstGreaterEntry(time12)).toBeUndefined(); 175 176 // full trace 177 expect(await trace.findFirstGreaterEntry(time9)?.getValue()).toEqual( 178 'entry-0', 179 ); 180 expect(await trace.findFirstGreaterEntry(time10)?.getValue()).toEqual( 181 'entry-1', 182 ); 183 expect(await trace.findFirstGreaterEntry(time11)?.getValue()).toEqual( 184 'entry-3', 185 ); 186 expect(await trace.findFirstGreaterEntry(time12)?.getValue()).toEqual( 187 'entry-4', 188 ); 189 expect(trace.findFirstGreaterEntry(time13)).toBeUndefined(); 190 }); 191 192 it('findLastLowerOrEqualEntry()', async () => { 193 // empty 194 expect( 195 trace.sliceEntries(0, 0).findLastLowerOrEqualEntry(time10), 196 ).toBeUndefined(); 197 198 // slice 199 const slice = trace.sliceEntries(1, -1); 200 expect(slice.findLastLowerOrEqualEntry(time9)).toBeUndefined(); 201 expect(slice.findLastLowerOrEqualEntry(time10)).toBeUndefined(); 202 expect(await slice.findLastLowerOrEqualEntry(time11)?.getValue()).toEqual( 203 'entry-2', 204 ); 205 expect(await slice.findLastLowerOrEqualEntry(time12)?.getValue()).toEqual( 206 'entry-3', 207 ); 208 expect(await slice.findLastLowerOrEqualEntry(time13)?.getValue()).toEqual( 209 'entry-3', 210 ); 211 212 // full trace 213 expect(trace.findLastLowerOrEqualEntry(time9)).toBeUndefined(); 214 expect(await trace.findLastLowerOrEqualEntry(time10)?.getValue()).toEqual( 215 'entry-0', 216 ); 217 expect(await trace.findLastLowerOrEqualEntry(time11)?.getValue()).toEqual( 218 'entry-2', 219 ); 220 expect(await trace.findLastLowerOrEqualEntry(time12)?.getValue()).toEqual( 221 'entry-3', 222 ); 223 expect(await trace.findLastLowerOrEqualEntry(time13)?.getValue()).toEqual( 224 'entry-4', 225 ); 226 expect(await trace.findLastLowerOrEqualEntry(time14)?.getValue()).toEqual( 227 'entry-4', 228 ); 229 }); 230 231 it('findLastLowerEntry()', async () => { 232 // empty 233 expect(trace.sliceEntries(0, 0).findLastLowerEntry(time10)).toBeUndefined(); 234 235 // slice 236 const slice = trace.sliceEntries(1, -1); 237 expect(slice.findLastLowerEntry(time9)).toBeUndefined(); 238 expect(slice.findLastLowerEntry(time10)).toBeUndefined(); 239 expect(slice.findLastLowerEntry(time11)).toBeUndefined(); 240 expect(await slice.findLastLowerEntry(time12)?.getValue()).toEqual( 241 'entry-2', 242 ); 243 expect(await slice.findLastLowerEntry(time13)?.getValue()).toEqual( 244 'entry-3', 245 ); 246 expect(await slice.findLastLowerEntry(time14)?.getValue()).toEqual( 247 'entry-3', 248 ); 249 expect(await slice.findLastLowerEntry(time15)?.getValue()).toEqual( 250 'entry-3', 251 ); 252 253 // full trace 254 expect(trace.findLastLowerEntry(time9)).toBeUndefined(); 255 expect(trace.findLastLowerEntry(time10)).toBeUndefined(); 256 expect(await trace.findLastLowerEntry(time11)?.getValue()).toEqual( 257 'entry-0', 258 ); 259 expect(await trace.findLastLowerEntry(time12)?.getValue()).toEqual( 260 'entry-2', 261 ); 262 expect(await trace.findLastLowerEntry(time13)?.getValue()).toEqual( 263 'entry-3', 264 ); 265 expect(await trace.findLastLowerEntry(time14)?.getValue()).toEqual( 266 'entry-4', 267 ); 268 expect(await trace.findLastLowerEntry(time15)?.getValue()).toEqual( 269 'entry-4', 270 ); 271 }); 272 273 // Hint: look at frame mapping specified in test's set up to fully understand the assertions 274 it('sliceEntries()', async () => { 275 const slice = trace.sliceEntries(1, 4); 276 277 const expectedEntriesFull = ['entry-1', 'entry-2', 'entry-3']; 278 const expectedFramesEmpty = new Map<AbsoluteFrameIndex, string[]>(); 279 const expectedFramesFull = new Map<AbsoluteFrameIndex, string[]>([ 280 [1, ['entry-1', 'entry-2']], 281 [2, []], 282 [3, []], 283 [4, ['entry-3']], 284 [5, ['entry-3']], 285 ]); 286 287 // empty 288 { 289 expect(await TraceUtils.extractFrames(slice.sliceEntries(1, 1))).toEqual( 290 expectedFramesEmpty, 291 ); 292 expect(await TraceUtils.extractEntries(slice.sliceEntries(1, 1))).toEqual( 293 [], 294 ); 295 296 expect( 297 await TraceUtils.extractFrames(slice.sliceEntries(-1, -1)), 298 ).toEqual(expectedFramesEmpty); 299 expect( 300 await TraceUtils.extractEntries(slice.sliceEntries(-1, -1)), 301 ).toEqual([]); 302 303 expect(await TraceUtils.extractFrames(slice.sliceEntries(2, 1))).toEqual( 304 expectedFramesEmpty, 305 ); 306 expect(await TraceUtils.extractEntries(slice.sliceEntries(2, 1))).toEqual( 307 [], 308 ); 309 310 expect( 311 await TraceUtils.extractFrames(slice.sliceEntries(-1, -2)), 312 ).toEqual(expectedFramesEmpty); 313 expect( 314 await TraceUtils.extractEntries(slice.sliceEntries(-1, -2)), 315 ).toEqual([]); 316 } 317 318 // full 319 { 320 expect(await TraceUtils.extractEntries(slice.sliceEntries())).toEqual( 321 expectedEntriesFull, 322 ); 323 expect(await TraceUtils.extractFrames(slice.sliceEntries())).toEqual( 324 expectedFramesFull, 325 ); 326 327 expect(await TraceUtils.extractEntries(slice.sliceEntries(0))).toEqual( 328 expectedEntriesFull, 329 ); 330 expect(await TraceUtils.extractFrames(slice.sliceEntries(0))).toEqual( 331 expectedFramesFull, 332 ); 333 334 expect(await TraceUtils.extractEntries(slice.sliceEntries(0, 3))).toEqual( 335 expectedEntriesFull, 336 ); 337 expect(await TraceUtils.extractFrames(slice.sliceEntries(0, 3))).toEqual( 338 expectedFramesFull, 339 ); 340 341 expect(await TraceUtils.extractEntries(slice.sliceEntries(-3))).toEqual( 342 expectedEntriesFull, 343 ); 344 expect(await TraceUtils.extractFrames(slice.sliceEntries(-3))).toEqual( 345 expectedFramesFull, 346 ); 347 348 expect( 349 await TraceUtils.extractEntries(slice.sliceEntries(-3, 3)), 350 ).toEqual(expectedEntriesFull); 351 expect(await TraceUtils.extractFrames(slice.sliceEntries(-3, 3))).toEqual( 352 expectedFramesFull, 353 ); 354 } 355 356 // slice away front (positive index) 357 { 358 expect(await TraceUtils.extractEntries(slice.sliceEntries(1))).toEqual([ 359 'entry-2', 360 'entry-3', 361 ]); 362 expect(await TraceUtils.extractFrames(slice.sliceEntries(1))).toEqual( 363 new Map<AbsoluteFrameIndex, string[]>([ 364 [1, ['entry-2']], 365 [2, []], 366 [3, []], 367 [4, ['entry-3']], 368 [5, ['entry-3']], 369 ]), 370 ); 371 372 expect(await TraceUtils.extractEntries(slice.sliceEntries(2))).toEqual([ 373 'entry-3', 374 ]); 375 expect(await TraceUtils.extractFrames(slice.sliceEntries(2))).toEqual( 376 new Map<AbsoluteFrameIndex, string[]>([ 377 [4, ['entry-3']], 378 [5, ['entry-3']], 379 ]), 380 ); 381 382 expect(await TraceUtils.extractEntries(slice.sliceEntries(3))).toEqual( 383 [], 384 ); 385 expect(await TraceUtils.extractFrames(slice.sliceEntries(3))).toEqual( 386 expectedFramesEmpty, 387 ); 388 389 expect(await TraceUtils.extractEntries(slice.sliceEntries(4))).toEqual( 390 [], 391 ); 392 expect(await TraceUtils.extractFrames(slice.sliceEntries(4))).toEqual( 393 expectedFramesEmpty, 394 ); 395 396 expect( 397 await TraceUtils.extractEntries(slice.sliceEntries(1000000)), 398 ).toEqual([]); 399 expect( 400 await TraceUtils.extractFrames(slice.sliceEntries(1000000)), 401 ).toEqual(expectedFramesEmpty); 402 } 403 404 // slice away front (negative index) 405 { 406 expect(await TraceUtils.extractEntries(slice.sliceEntries(-3))).toEqual( 407 expectedEntriesFull, 408 ); 409 expect(await TraceUtils.extractFrames(slice.sliceEntries(-3))).toEqual( 410 expectedFramesFull, 411 ); 412 413 expect(await TraceUtils.extractEntries(slice.sliceEntries(-2))).toEqual([ 414 'entry-2', 415 'entry-3', 416 ]); 417 expect(await TraceUtils.extractFrames(slice.sliceEntries(-2))).toEqual( 418 new Map<AbsoluteFrameIndex, string[]>([ 419 [1, ['entry-2']], 420 [2, []], 421 [3, []], 422 [4, ['entry-3']], 423 [5, ['entry-3']], 424 ]), 425 ); 426 427 expect(await TraceUtils.extractEntries(slice.sliceEntries(-1))).toEqual([ 428 'entry-3', 429 ]); 430 expect(await TraceUtils.extractFrames(slice.sliceEntries(-1))).toEqual( 431 new Map<AbsoluteFrameIndex, string[]>([ 432 [4, ['entry-3']], 433 [5, ['entry-3']], 434 ]), 435 ); 436 } 437 438 // slice away back (positive index) 439 { 440 expect( 441 await TraceUtils.extractEntries(slice.sliceEntries(undefined, 2)), 442 ).toEqual(['entry-1', 'entry-2']); 443 expect( 444 await TraceUtils.extractFrames(slice.sliceEntries(undefined, 2)), 445 ).toEqual( 446 new Map<AbsoluteFrameIndex, string[]>([[1, ['entry-1', 'entry-2']]]), 447 ); 448 449 expect( 450 await TraceUtils.extractEntries(slice.sliceEntries(undefined, 1)), 451 ).toEqual(['entry-1']); 452 expect( 453 await TraceUtils.extractFrames(slice.sliceEntries(undefined, 1)), 454 ).toEqual(new Map<AbsoluteFrameIndex, string[]>([[1, ['entry-1']]])); 455 456 expect( 457 await TraceUtils.extractEntries(slice.sliceEntries(undefined, 0)), 458 ).toEqual([]); 459 expect( 460 await TraceUtils.extractFrames(slice.sliceEntries(undefined, 0)), 461 ).toEqual(expectedFramesEmpty); 462 } 463 464 // slice away back (negative index) 465 { 466 expect( 467 await TraceUtils.extractEntries(slice.sliceEntries(undefined, -1)), 468 ).toEqual(['entry-1', 'entry-2']); 469 expect( 470 await TraceUtils.extractFrames(slice.sliceEntries(undefined, -1)), 471 ).toEqual( 472 new Map<AbsoluteFrameIndex, string[]>([[1, ['entry-1', 'entry-2']]]), 473 ); 474 475 expect( 476 await TraceUtils.extractEntries(slice.sliceEntries(undefined, -2)), 477 ).toEqual(['entry-1']); 478 expect( 479 await TraceUtils.extractFrames(slice.sliceEntries(undefined, -2)), 480 ).toEqual(new Map<AbsoluteFrameIndex, string[]>([[1, ['entry-1']]])); 481 482 expect( 483 await TraceUtils.extractEntries(slice.sliceEntries(undefined, -3)), 484 ).toEqual([]); 485 expect( 486 await TraceUtils.extractFrames(slice.sliceEntries(undefined, -3)), 487 ).toEqual(expectedFramesEmpty); 488 489 expect( 490 await TraceUtils.extractEntries(slice.sliceEntries(undefined, -4)), 491 ).toEqual([]); 492 expect( 493 await TraceUtils.extractFrames(slice.sliceEntries(undefined, -4)), 494 ).toEqual(expectedFramesEmpty); 495 496 expect( 497 await TraceUtils.extractEntries( 498 slice.sliceEntries(undefined, -1000000), 499 ), 500 ).toEqual([]); 501 expect( 502 await TraceUtils.extractFrames(slice.sliceEntries(undefined, -1000000)), 503 ).toEqual(expectedFramesEmpty); 504 } 505 }); 506 507 // Hint: look at frame mapping specified in test's set up to fully understand the assertions 508 it('sliceTime()', async () => { 509 const slice = trace.sliceTime(time11, time13); // drop first + last entries 510 511 const expectedEntriesFull = ['entry-1', 'entry-2', 'entry-3']; 512 const expectedFramesEmpty = new Map<AbsoluteFrameIndex, string[]>(); 513 const expectedFramesFull = new Map<AbsoluteFrameIndex, string[]>([ 514 [1, ['entry-1', 'entry-2']], 515 [2, []], 516 [3, []], 517 [4, ['entry-3']], 518 [5, ['entry-3']], 519 ]); 520 521 // empty 522 { 523 expect( 524 await TraceUtils.extractEntries(slice.sliceTime(time11, time11)), 525 ).toEqual([]); 526 expect( 527 await TraceUtils.extractFrames(slice.sliceTime(time11, time11)), 528 ).toEqual(expectedFramesEmpty); 529 530 expect( 531 await TraceUtils.extractEntries(slice.sliceTime(time11, time10)), 532 ).toEqual([]); 533 expect( 534 await TraceUtils.extractFrames(slice.sliceTime(time11, time10)), 535 ).toEqual(expectedFramesEmpty); 536 537 expect( 538 await TraceUtils.extractEntries(slice.sliceTime(time9, time10)), 539 ).toEqual([]); 540 expect( 541 await TraceUtils.extractFrames(slice.sliceTime(time9, time10)), 542 ).toEqual(expectedFramesEmpty); 543 544 expect( 545 await TraceUtils.extractEntries(slice.sliceTime(time10, time9)), 546 ).toEqual([]); 547 expect( 548 await TraceUtils.extractFrames(slice.sliceTime(time10, time9)), 549 ).toEqual(expectedFramesEmpty); 550 551 expect( 552 await TraceUtils.extractEntries(slice.sliceTime(time14, time15)), 553 ).toEqual([]); 554 expect( 555 await TraceUtils.extractFrames(slice.sliceTime(time14, time15)), 556 ).toEqual(expectedFramesEmpty); 557 558 expect( 559 await TraceUtils.extractEntries(slice.sliceTime(time15, time14)), 560 ).toEqual([]); 561 expect( 562 await TraceUtils.extractFrames(slice.sliceTime(time15, time14)), 563 ).toEqual(expectedFramesEmpty); 564 } 565 566 // full 567 { 568 expect(await TraceUtils.extractEntries(slice.sliceTime())).toEqual( 569 expectedEntriesFull, 570 ); 571 expect(await TraceUtils.extractFrames(slice.sliceTime())).toEqual( 572 expectedFramesFull, 573 ); 574 575 expect(await TraceUtils.extractEntries(slice.sliceTime(time9))).toEqual( 576 expectedEntriesFull, 577 ); 578 expect(await TraceUtils.extractFrames(slice.sliceTime(time9))).toEqual( 579 expectedFramesFull, 580 ); 581 582 expect(await TraceUtils.extractEntries(slice.sliceTime(time10))).toEqual( 583 expectedEntriesFull, 584 ); 585 expect(await TraceUtils.extractFrames(slice.sliceTime(time10))).toEqual( 586 expectedFramesFull, 587 ); 588 589 expect( 590 await TraceUtils.extractEntries(slice.sliceTime(undefined, time14)), 591 ).toEqual(expectedEntriesFull); 592 expect( 593 await TraceUtils.extractFrames(slice.sliceTime(undefined, time14)), 594 ).toEqual(expectedFramesFull); 595 596 expect( 597 await TraceUtils.extractEntries(slice.sliceTime(undefined, time15)), 598 ).toEqual(expectedEntriesFull); 599 expect( 600 await TraceUtils.extractFrames(slice.sliceTime(undefined, time15)), 601 ).toEqual(expectedFramesFull); 602 603 expect( 604 await TraceUtils.extractEntries(slice.sliceTime(time10, time14)), 605 ).toEqual(expectedEntriesFull); 606 expect( 607 await TraceUtils.extractFrames(slice.sliceTime(time10, time14)), 608 ).toEqual(expectedFramesFull); 609 } 610 611 // middle 612 { 613 expect( 614 await TraceUtils.extractEntries(slice.sliceTime(time12, time13)), 615 ).toEqual(['entry-3']); 616 expect( 617 await TraceUtils.extractFrames(slice.sliceTime(time12, time13)), 618 ).toEqual( 619 new Map<AbsoluteFrameIndex, string[]>([ 620 [4, ['entry-3']], 621 [5, ['entry-3']], 622 ]), 623 ); 624 } 625 626 // slice away front 627 { 628 expect(await TraceUtils.extractEntries(slice.sliceTime(time12))).toEqual([ 629 'entry-3', 630 ]); 631 expect(await TraceUtils.extractFrames(slice.sliceTime(time12))).toEqual( 632 new Map<AbsoluteFrameIndex, string[]>([ 633 [4, ['entry-3']], 634 [5, ['entry-3']], 635 ]), 636 ); 637 638 expect(await TraceUtils.extractEntries(slice.sliceTime(time13))).toEqual( 639 [], 640 ); 641 expect(await TraceUtils.extractFrames(slice.sliceTime(time13))).toEqual( 642 expectedFramesEmpty, 643 ); 644 645 expect(await TraceUtils.extractEntries(slice.sliceTime(time14))).toEqual( 646 [], 647 ); 648 expect(await TraceUtils.extractFrames(slice.sliceTime(time14))).toEqual( 649 expectedFramesEmpty, 650 ); 651 652 expect(await TraceUtils.extractEntries(slice.sliceTime(time15))).toEqual( 653 [], 654 ); 655 expect(await TraceUtils.extractFrames(slice.sliceTime(time15))).toEqual( 656 expectedFramesEmpty, 657 ); 658 } 659 660 // slice away back 661 { 662 expect( 663 await TraceUtils.extractEntries(slice.sliceTime(undefined, time12)), 664 ).toEqual(['entry-1', 'entry-2']); 665 expect( 666 await TraceUtils.extractFrames(slice.sliceTime(undefined, time12)), 667 ).toEqual( 668 new Map<AbsoluteFrameIndex, string[]>([[1, ['entry-1', 'entry-2']]]), 669 ); 670 671 expect( 672 await TraceUtils.extractEntries(slice.sliceTime(undefined, time11)), 673 ).toEqual([]); 674 expect( 675 await TraceUtils.extractFrames(slice.sliceTime(undefined, time11)), 676 ).toEqual(expectedFramesEmpty); 677 678 expect( 679 await TraceUtils.extractEntries(slice.sliceTime(undefined, time10)), 680 ).toEqual([]); 681 expect( 682 await TraceUtils.extractFrames(slice.sliceTime(undefined, time10)), 683 ).toEqual(expectedFramesEmpty); 684 685 expect( 686 await TraceUtils.extractEntries(slice.sliceTime(undefined, time9)), 687 ).toEqual([]); 688 expect( 689 await TraceUtils.extractFrames(slice.sliceTime(undefined, time9)), 690 ).toEqual(expectedFramesEmpty); 691 } 692 }); 693 694 // Hint: look at frame mapping specified in test's set up to fully understand the assertions 695 it('sliceFrames()', async () => { 696 const slice = trace.sliceEntries(1, -1); 697 698 // empty 699 { 700 const expectedEntries = new Array<string>(); 701 const expectedFrames = new Map<AbsoluteFrameIndex, string[]>([]); 702 expect(await TraceUtils.extractEntries(slice.sliceFrames(1, 1))).toEqual( 703 expectedEntries, 704 ); 705 expect(await TraceUtils.extractFrames(slice.sliceFrames(1, 1))).toEqual( 706 expectedFrames, 707 ); 708 expect(await TraceUtils.extractEntries(slice.sliceFrames(5, 1))).toEqual( 709 expectedEntries, 710 ); 711 expect(await TraceUtils.extractFrames(slice.sliceFrames(5, 1))).toEqual( 712 expectedFrames, 713 ); 714 expect(await TraceUtils.extractEntries(slice.sliceFrames(3, 2))).toEqual( 715 expectedEntries, 716 ); 717 expect(await TraceUtils.extractFrames(slice.sliceFrames(3, 2))).toEqual( 718 expectedFrames, 719 ); 720 } 721 722 // middle 723 { 724 expect(await TraceUtils.extractEntries(slice.sliceFrames(2, 3))).toEqual( 725 [], 726 ); 727 expect(await TraceUtils.extractFrames(slice.sliceFrames(2, 3))).toEqual( 728 new Map<AbsoluteFrameIndex, string[]>([[2, []]]), 729 ); 730 expect(await TraceUtils.extractEntries(slice.sliceFrames(2, 4))).toEqual( 731 [], 732 ); 733 expect(await TraceUtils.extractFrames(slice.sliceFrames(2, 4))).toEqual( 734 new Map<AbsoluteFrameIndex, string[]>([ 735 [2, []], 736 [3, []], 737 ]), 738 ); 739 expect(await TraceUtils.extractEntries(slice.sliceFrames(2, 5))).toEqual([ 740 'entry-3', 741 ]); 742 expect(await TraceUtils.extractFrames(slice.sliceFrames(2, 5))).toEqual( 743 new Map<AbsoluteFrameIndex, string[]>([ 744 [2, []], 745 [3, []], 746 [4, ['entry-3']], 747 ]), 748 ); 749 } 750 751 // full 752 { 753 const expectedEntries = ['entry-1', 'entry-2', 'entry-3']; 754 const expectedFrames = new Map<AbsoluteFrameIndex, string[]>([ 755 [1, ['entry-1', 'entry-2']], 756 [2, []], 757 [3, []], 758 [4, ['entry-3']], 759 [5, ['entry-3']], 760 ]); 761 expect(await TraceUtils.extractEntries(slice.sliceFrames())).toEqual( 762 expectedEntries, 763 ); 764 expect(await TraceUtils.extractFrames(slice.sliceFrames())).toEqual( 765 expectedFrames, 766 ); 767 expect(await TraceUtils.extractEntries(slice.sliceFrames(0))).toEqual( 768 expectedEntries, 769 ); 770 expect(await TraceUtils.extractFrames(slice.sliceFrames(0))).toEqual( 771 expectedFrames, 772 ); 773 expect( 774 await TraceUtils.extractEntries(slice.sliceFrames(undefined, 6)), 775 ).toEqual(expectedEntries); 776 expect( 777 await TraceUtils.extractFrames(slice.sliceFrames(undefined, 6)), 778 ).toEqual(expectedFrames); 779 expect(await TraceUtils.extractEntries(slice.sliceFrames(1, 6))).toEqual( 780 expectedEntries, 781 ); 782 expect(await TraceUtils.extractFrames(slice.sliceFrames(1, 6))).toEqual( 783 expectedFrames, 784 ); 785 expect(await TraceUtils.extractEntries(slice.sliceFrames(0, 7))).toEqual( 786 expectedEntries, 787 ); 788 expect(await TraceUtils.extractFrames(slice.sliceFrames(0, 7))).toEqual( 789 expectedFrames, 790 ); 791 } 792 793 // slice away front 794 { 795 expect(await TraceUtils.extractEntries(slice.sliceFrames(2))).toEqual([ 796 'entry-3', 797 ]); 798 expect(await TraceUtils.extractFrames(slice.sliceFrames(2))).toEqual( 799 new Map<AbsoluteFrameIndex, string[]>([ 800 [2, []], 801 [3, []], 802 [4, ['entry-3']], 803 [5, ['entry-3']], 804 ]), 805 ); 806 expect(await TraceUtils.extractEntries(slice.sliceFrames(4))).toEqual([ 807 'entry-3', 808 ]); 809 expect(await TraceUtils.extractFrames(slice.sliceFrames(4))).toEqual( 810 new Map<AbsoluteFrameIndex, string[]>([ 811 [4, ['entry-3']], 812 [5, ['entry-3']], 813 ]), 814 ); 815 expect(await TraceUtils.extractEntries(slice.sliceFrames(5))).toEqual([ 816 'entry-3', 817 ]); 818 expect(await TraceUtils.extractFrames(slice.sliceFrames(5))).toEqual( 819 new Map<AbsoluteFrameIndex, string[]>([[5, ['entry-3']]]), 820 ); 821 expect(await TraceUtils.extractEntries(slice.sliceFrames(6))).toEqual([]); 822 expect(await TraceUtils.extractFrames(slice.sliceFrames(6))).toEqual( 823 new Map<AbsoluteFrameIndex, string[]>([]), 824 ); 825 expect(await TraceUtils.extractEntries(slice.sliceFrames(1000))).toEqual( 826 [], 827 ); 828 expect(await TraceUtils.extractFrames(slice.sliceFrames(1000))).toEqual( 829 new Map<AbsoluteFrameIndex, string[]>([]), 830 ); 831 } 832 833 // slice away back 834 { 835 expect( 836 await TraceUtils.extractEntries(slice.sliceFrames(undefined, 6)), 837 ).toEqual(['entry-1', 'entry-2', 'entry-3']); 838 expect( 839 await TraceUtils.extractFrames(slice.sliceFrames(undefined, 6)), 840 ).toEqual( 841 new Map<AbsoluteFrameIndex, string[]>([ 842 [1, ['entry-1', 'entry-2']], 843 [2, []], 844 [3, []], 845 [4, ['entry-3']], 846 [5, ['entry-3']], 847 ]), 848 ); 849 expect( 850 await TraceUtils.extractEntries(slice.sliceFrames(undefined, 5)), 851 ).toEqual(['entry-1', 'entry-2', 'entry-3']); 852 expect( 853 await TraceUtils.extractFrames(slice.sliceFrames(undefined, 5)), 854 ).toEqual( 855 new Map<AbsoluteFrameIndex, string[]>([ 856 [1, ['entry-1', 'entry-2']], 857 [2, []], 858 [3, []], 859 [4, ['entry-3']], 860 ]), 861 ); 862 expect( 863 await TraceUtils.extractEntries(slice.sliceFrames(undefined, 4)), 864 ).toEqual(['entry-1', 'entry-2']); 865 expect( 866 await TraceUtils.extractFrames(slice.sliceFrames(undefined, 4)), 867 ).toEqual( 868 new Map<AbsoluteFrameIndex, string[]>([ 869 [1, ['entry-1', 'entry-2']], 870 [2, []], 871 [3, []], 872 ]), 873 ); 874 expect( 875 await TraceUtils.extractEntries(slice.sliceFrames(undefined, 3)), 876 ).toEqual(['entry-1', 'entry-2']); 877 expect( 878 await TraceUtils.extractFrames(slice.sliceFrames(undefined, 3)), 879 ).toEqual( 880 new Map<AbsoluteFrameIndex, string[]>([ 881 [1, ['entry-1', 'entry-2']], 882 [2, []], 883 ]), 884 ); 885 expect( 886 await TraceUtils.extractEntries(slice.sliceFrames(undefined, 2)), 887 ).toEqual(['entry-1', 'entry-2']); 888 expect( 889 await TraceUtils.extractFrames(slice.sliceFrames(undefined, 2)), 890 ).toEqual( 891 new Map<AbsoluteFrameIndex, string[]>([[1, ['entry-1', 'entry-2']]]), 892 ); 893 expect( 894 await TraceUtils.extractEntries(slice.sliceFrames(undefined, 1)), 895 ).toEqual([]); 896 expect( 897 await TraceUtils.extractFrames(slice.sliceFrames(undefined, 1)), 898 ).toEqual(new Map<AbsoluteFrameIndex, string[]>()); 899 expect( 900 await TraceUtils.extractEntries(slice.sliceFrames(undefined, 0)), 901 ).toEqual([]); 902 expect( 903 await TraceUtils.extractFrames(slice.sliceFrames(undefined, 0)), 904 ).toEqual(new Map<AbsoluteFrameIndex, string[]>()); 905 } 906 }); 907 908 it('can slice full trace', async () => { 909 // entries 910 expect(await TraceUtils.extractEntries(trace.sliceEntries(1, 1))).toEqual( 911 [], 912 ); 913 expect(await TraceUtils.extractEntries(trace.sliceEntries())).toEqual([ 914 'entry-0', 915 'entry-1', 916 'entry-2', 917 'entry-3', 918 'entry-4', 919 ]); 920 expect(await TraceUtils.extractEntries(trace.sliceEntries(2))).toEqual([ 921 'entry-2', 922 'entry-3', 923 'entry-4', 924 ]); 925 expect(await TraceUtils.extractEntries(trace.sliceEntries(-3))).toEqual([ 926 'entry-2', 927 'entry-3', 928 'entry-4', 929 ]); 930 expect( 931 await TraceUtils.extractEntries(trace.sliceEntries(undefined, 3)), 932 ).toEqual(['entry-0', 'entry-1', 'entry-2']); 933 expect( 934 await TraceUtils.extractEntries(trace.sliceEntries(undefined, -2)), 935 ).toEqual(['entry-0', 'entry-1', 'entry-2']); 936 expect(await TraceUtils.extractEntries(trace.sliceEntries(1, 4))).toEqual([ 937 'entry-1', 938 'entry-2', 939 'entry-3', 940 ]); 941 942 // time 943 const time12 = TimestampConverterUtils.makeRealTimestamp(12n); 944 const time13 = TimestampConverterUtils.makeRealTimestamp(13n); 945 expect( 946 await TraceUtils.extractEntries(trace.sliceTime(time12, time12)), 947 ).toEqual([]); 948 expect(await TraceUtils.extractEntries(trace.sliceTime())).toEqual([ 949 'entry-0', 950 'entry-1', 951 'entry-2', 952 'entry-3', 953 'entry-4', 954 ]); 955 expect( 956 await TraceUtils.extractEntries(trace.sliceTime(time12, time13)), 957 ).toEqual(['entry-3']); 958 expect(await TraceUtils.extractEntries(trace.sliceTime(time12))).toEqual([ 959 'entry-3', 960 'entry-4', 961 ]); 962 expect( 963 await TraceUtils.extractEntries(trace.sliceTime(undefined, time12)), 964 ).toEqual(['entry-0', 'entry-1', 'entry-2']); 965 966 // frames 967 expect(await TraceUtils.extractEntries(trace.sliceFrames(1, 1))).toEqual( 968 [], 969 ); 970 expect(await TraceUtils.extractEntries(trace.sliceFrames())).toEqual([ 971 'entry-0', 972 'entry-1', 973 'entry-2', 974 'entry-3', 975 'entry-4', 976 ]); 977 expect(await TraceUtils.extractEntries(trace.sliceFrames(2))).toEqual([ 978 'entry-3', 979 'entry-4', 980 ]); 981 expect( 982 await TraceUtils.extractEntries(trace.sliceFrames(undefined, 5)), 983 ).toEqual(['entry-0', 'entry-1', 'entry-2', 'entry-3']); 984 expect(await TraceUtils.extractEntries(trace.sliceFrames(2, 5))).toEqual([ 985 'entry-3', 986 ]); 987 }); 988 989 it('can slice empty trace', async () => { 990 const empty = trace.sliceEntries(0, 0); 991 992 // entries 993 expect(await TraceUtils.extractEntries(empty.sliceEntries())).toEqual([]); 994 expect(await TraceUtils.extractEntries(empty.sliceEntries(1))).toEqual([]); 995 expect(await TraceUtils.extractEntries(empty.sliceEntries(1, 2))).toEqual( 996 [], 997 ); 998 999 // time 1000 const time12 = TimestampConverterUtils.makeRealTimestamp(12n); 1001 const time13 = TimestampConverterUtils.makeRealTimestamp(13n); 1002 expect(await TraceUtils.extractEntries(empty.sliceTime())).toEqual([]); 1003 expect(await TraceUtils.extractEntries(empty.sliceTime(time12))).toEqual( 1004 [], 1005 ); 1006 expect( 1007 await TraceUtils.extractEntries(empty.sliceTime(time12, time13)), 1008 ).toEqual([]); 1009 1010 // frames 1011 expect(await TraceUtils.extractEntries(empty.sliceFrames())).toEqual([]); 1012 expect(await TraceUtils.extractEntries(empty.sliceFrames(1))).toEqual([]); 1013 expect(await TraceUtils.extractEntries(empty.sliceFrames(1, 2))).toEqual( 1014 [], 1015 ); 1016 }); 1017 1018 it('forEachEntry()', async () => { 1019 expect(await TraceUtils.extractEntries(trace)).toEqual([ 1020 'entry-0', 1021 'entry-1', 1022 'entry-2', 1023 'entry-3', 1024 'entry-4', 1025 ]); 1026 }); 1027 1028 it('forEachTimestamp()', () => { 1029 expect(TraceUtils.extractTimestamps(trace)).toEqual([ 1030 time10, 1031 time11, 1032 time11, 1033 time12, 1034 time13, 1035 ]); 1036 expect(TraceUtils.extractTimestamps(trace.sliceEntries(1, -1))).toEqual([ 1037 time11, 1038 time11, 1039 time12, 1040 ]); 1041 }); 1042 1043 // Hint: look at frame mapping specified in test's set up to fully understand the assertions 1044 it('forEachFrame()', async () => { 1045 // full trace 1046 { 1047 const expected = new Map<AbsoluteFrameIndex, string[]>([ 1048 [0, ['entry-0']], 1049 [1, ['entry-1', 'entry-2']], 1050 [2, []], 1051 [3, []], 1052 [4, ['entry-3']], 1053 [5, ['entry-3']], 1054 [6, ['entry-4']], 1055 ]); 1056 expect(await TraceUtils.extractFrames(trace)).toEqual(expected); 1057 } 1058 // slice 1059 { 1060 const slice = trace.sliceFrames(1, 5); 1061 const expected = new Map<AbsoluteFrameIndex, string[]>([ 1062 [1, ['entry-1', 'entry-2']], 1063 [2, []], 1064 [3, []], 1065 [4, ['entry-3']], 1066 ]); 1067 expect(await TraceUtils.extractFrames(slice)).toEqual(expected); 1068 } 1069 }); 1070 1071 it('updates frames range when slicing', () => { 1072 expect(trace.sliceEntries(0).getFramesRange()).toEqual({start: 0, end: 7}); 1073 expect(trace.sliceEntries(1).getFramesRange()).toEqual({start: 1, end: 7}); 1074 expect(trace.sliceEntries(2).getFramesRange()).toEqual({start: 1, end: 7}); 1075 expect(trace.sliceEntries(3).getFramesRange()).toEqual({start: 4, end: 7}); 1076 expect(trace.sliceEntries(4).getFramesRange()).toEqual({start: 6, end: 7}); 1077 expect(trace.sliceEntries(5).getFramesRange()).toEqual(undefined); 1078 1079 expect(trace.sliceEntries(undefined, 5).getFramesRange()).toEqual({ 1080 start: 0, 1081 end: 7, 1082 }); 1083 expect(trace.sliceEntries(undefined, 4).getFramesRange()).toEqual({ 1084 start: 0, 1085 end: 6, 1086 }); 1087 expect(trace.sliceEntries(undefined, 3).getFramesRange()).toEqual({ 1088 start: 0, 1089 end: 2, 1090 }); 1091 expect(trace.sliceEntries(undefined, 2).getFramesRange()).toEqual({ 1092 start: 0, 1093 end: 2, 1094 }); 1095 expect(trace.sliceEntries(undefined, 1).getFramesRange()).toEqual({ 1096 start: 0, 1097 end: 1, 1098 }); 1099 expect(trace.sliceEntries(undefined, 0).getFramesRange()).toEqual( 1100 undefined, 1101 ); 1102 }); 1103 1104 it('can handle some trace entries with unavailable frame info', async () => { 1105 // Entry: 0 1 2 3 4 1106 // | | 1107 // Frame: 0 2 1108 // Time: 10 11 12 13 14 1109 const trace = new TraceBuilder<string>() 1110 .setEntries(['entry-0', 'entry-1', 'entry-2', 'entry-3', 'entry-4']) 1111 .setTimestamps([time10, time11, time12, time13, time14]) 1112 .setFrame(1, 0) 1113 .setFrame(3, 2) 1114 .build(); 1115 1116 // Slice entries 1117 expect(await TraceUtils.extractEntries(trace.sliceEntries())).toEqual([ 1118 'entry-0', 1119 'entry-1', 1120 'entry-2', 1121 'entry-3', 1122 'entry-4', 1123 ]); 1124 expect(await TraceUtils.extractFrames(trace.sliceEntries())).toEqual( 1125 new Map<AbsoluteFrameIndex, string[]>([ 1126 [0, ['entry-1']], 1127 [1, []], 1128 [2, ['entry-3']], 1129 ]), 1130 ); 1131 1132 expect(await TraceUtils.extractEntries(trace.sliceEntries(1))).toEqual([ 1133 'entry-1', 1134 'entry-2', 1135 'entry-3', 1136 'entry-4', 1137 ]); 1138 expect(await TraceUtils.extractFrames(trace.sliceEntries(1))).toEqual( 1139 new Map<AbsoluteFrameIndex, string[]>([ 1140 [0, ['entry-1']], 1141 [1, []], 1142 [2, ['entry-3']], 1143 ]), 1144 ); 1145 1146 expect(await TraceUtils.extractEntries(trace.sliceEntries(2))).toEqual([ 1147 'entry-2', 1148 'entry-3', 1149 'entry-4', 1150 ]); 1151 expect(await TraceUtils.extractFrames(trace.sliceEntries(2))).toEqual( 1152 new Map<AbsoluteFrameIndex, string[]>([[2, ['entry-3']]]), 1153 ); 1154 1155 expect(await TraceUtils.extractEntries(trace.sliceEntries(3))).toEqual([ 1156 'entry-3', 1157 'entry-4', 1158 ]); 1159 expect(await TraceUtils.extractFrames(trace.sliceEntries(3))).toEqual( 1160 new Map<AbsoluteFrameIndex, string[]>([[2, ['entry-3']]]), 1161 ); 1162 1163 expect(await TraceUtils.extractEntries(trace.sliceEntries(4))).toEqual([ 1164 'entry-4', 1165 ]); 1166 expect(await TraceUtils.extractFrames(trace.sliceEntries(4))).toEqual( 1167 new Map<AbsoluteFrameIndex, string[]>(), 1168 ); 1169 1170 // Slice time 1171 expect(await TraceUtils.extractEntries(trace.sliceTime())).toEqual([ 1172 'entry-0', 1173 'entry-1', 1174 'entry-2', 1175 'entry-3', 1176 'entry-4', 1177 ]); 1178 expect(await TraceUtils.extractFrames(trace.sliceTime())).toEqual( 1179 new Map<AbsoluteFrameIndex, string[]>([ 1180 [0, ['entry-1']], 1181 [1, []], 1182 [2, ['entry-3']], 1183 ]), 1184 ); 1185 1186 expect(await TraceUtils.extractEntries(trace.sliceTime(time11))).toEqual([ 1187 'entry-1', 1188 'entry-2', 1189 'entry-3', 1190 'entry-4', 1191 ]); 1192 expect(await TraceUtils.extractFrames(trace.sliceTime(time11))).toEqual( 1193 new Map<AbsoluteFrameIndex, string[]>([ 1194 [0, ['entry-1']], 1195 [1, []], 1196 [2, ['entry-3']], 1197 ]), 1198 ); 1199 1200 expect(await TraceUtils.extractEntries(trace.sliceTime(time12))).toEqual([ 1201 'entry-2', 1202 'entry-3', 1203 'entry-4', 1204 ]); 1205 expect(await TraceUtils.extractFrames(trace.sliceTime(time12))).toEqual( 1206 new Map<AbsoluteFrameIndex, string[]>([[2, ['entry-3']]]), 1207 ); 1208 1209 expect(await TraceUtils.extractEntries(trace.sliceTime(time13))).toEqual([ 1210 'entry-3', 1211 'entry-4', 1212 ]); 1213 expect(await TraceUtils.extractFrames(trace.sliceTime(time13))).toEqual( 1214 new Map<AbsoluteFrameIndex, string[]>([[2, ['entry-3']]]), 1215 ); 1216 1217 expect(await TraceUtils.extractEntries(trace.sliceTime(time14))).toEqual([ 1218 'entry-4', 1219 ]); 1220 expect(await TraceUtils.extractFrames(trace.sliceTime(time14))).toEqual( 1221 new Map<AbsoluteFrameIndex, string[]>(), 1222 ); 1223 1224 // Slice frames 1225 expect(await TraceUtils.extractEntries(trace.sliceFrames())).toEqual([ 1226 'entry-1', 1227 'entry-2', 1228 'entry-3', 1229 ]); 1230 expect(await TraceUtils.extractFrames(trace.sliceFrames())).toEqual( 1231 new Map<AbsoluteFrameIndex, string[]>([ 1232 [0, ['entry-1']], 1233 [1, []], 1234 [2, ['entry-3']], 1235 ]), 1236 ); 1237 1238 expect(await TraceUtils.extractEntries(trace.sliceFrames(1))).toEqual([ 1239 'entry-3', 1240 ]); 1241 expect(await TraceUtils.extractFrames(trace.sliceFrames(1))).toEqual( 1242 new Map<AbsoluteFrameIndex, string[]>([ 1243 [1, []], 1244 [2, ['entry-3']], 1245 ]), 1246 ); 1247 1248 expect( 1249 await TraceUtils.extractEntries(trace.sliceFrames(undefined, 2)), 1250 ).toEqual(['entry-1']); 1251 expect( 1252 await TraceUtils.extractFrames(trace.sliceFrames(undefined, 2)), 1253 ).toEqual( 1254 new Map<AbsoluteFrameIndex, string[]>([ 1255 [0, ['entry-1']], 1256 [1, []], 1257 ]), 1258 ); 1259 }); 1260 1261 it('can handle unavailable frame info', async () => { 1262 const trace = new TraceBuilder<string>() 1263 .setTimestamps([time10, time11, time12]) 1264 .setEntries(['entry-0', 'entry-1', 'entry-2']) 1265 .setFrameMap(undefined) 1266 .build(); 1267 1268 expect(await trace.getEntry(0).getValue()).toEqual('entry-0'); 1269 expect(await TraceUtils.extractEntries(trace)).toEqual([ 1270 'entry-0', 1271 'entry-1', 1272 'entry-2', 1273 ]); 1274 expect(await TraceUtils.extractEntries(trace.sliceEntries(1, 2))).toEqual([ 1275 'entry-1', 1276 ]); 1277 expect( 1278 await TraceUtils.extractEntries(trace.sliceTime(time11, time12)), 1279 ).toEqual(['entry-1']); 1280 1281 expect(() => { 1282 trace.getFrame(0); 1283 }).toThrow(); 1284 expect(() => { 1285 trace.sliceFrames(0, 1000); 1286 }).toThrow(); 1287 }); 1288 1289 it('can handle empty frame info', async () => { 1290 // empty trace 1291 { 1292 const trace = new TraceBuilder<string>() 1293 .setEntries([]) 1294 .setTimestamps([]) 1295 .setFrameMap(new FrameMapBuilder(0, 0).build()) 1296 .build(); 1297 1298 expect(await TraceUtils.extractEntries(trace)).toEqual([]); 1299 expect(await TraceUtils.extractFrames(trace)).toEqual( 1300 new Map<AbsoluteFrameIndex, string[]>(), 1301 ); 1302 1303 expect(await TraceUtils.extractEntries(trace.sliceEntries(1))).toEqual( 1304 [], 1305 ); 1306 expect(await TraceUtils.extractFrames(trace.sliceEntries(1))).toEqual( 1307 new Map<AbsoluteFrameIndex, string[]>(), 1308 ); 1309 1310 expect(await TraceUtils.extractEntries(trace.sliceTime(time11))).toEqual( 1311 [], 1312 ); 1313 expect(await TraceUtils.extractFrames(trace.sliceTime(time11))).toEqual( 1314 new Map<AbsoluteFrameIndex, string[]>(), 1315 ); 1316 1317 expect(await TraceUtils.extractEntries(trace.sliceFrames())).toEqual([]); 1318 expect(await TraceUtils.extractFrames(trace.sliceFrames())).toEqual( 1319 new Map<AbsoluteFrameIndex, string[]>(), 1320 ); 1321 } 1322 // non-empty trace 1323 { 1324 const trace = new TraceBuilder<string>() 1325 .setEntries(['entry-0', 'entry-1', 'entry-2']) 1326 .setTimestamps([time10, time11, time12]) 1327 .setFrameMap(new FrameMapBuilder(3, 0).build()) 1328 .build(); 1329 1330 expect(await TraceUtils.extractEntries(trace)).toEqual([ 1331 'entry-0', 1332 'entry-1', 1333 'entry-2', 1334 ]); 1335 expect(await TraceUtils.extractFrames(trace)).toEqual( 1336 new Map<AbsoluteFrameIndex, string[]>(), 1337 ); 1338 1339 expect(await TraceUtils.extractEntries(trace.sliceEntries(1))).toEqual([ 1340 'entry-1', 1341 'entry-2', 1342 ]); 1343 expect(await TraceUtils.extractFrames(trace.sliceEntries(1))).toEqual( 1344 new Map<AbsoluteFrameIndex, string[]>(), 1345 ); 1346 1347 expect(await TraceUtils.extractEntries(trace.sliceTime(time11))).toEqual([ 1348 'entry-1', 1349 'entry-2', 1350 ]); 1351 expect(await TraceUtils.extractFrames(trace.sliceTime(time11))).toEqual( 1352 new Map<AbsoluteFrameIndex, string[]>(), 1353 ); 1354 1355 expect(await TraceUtils.extractEntries(trace.sliceFrames())).toEqual([]); 1356 expect(await TraceUtils.extractFrames(trace.sliceFrames())).toEqual( 1357 new Map<AbsoluteFrameIndex, string[]>(), 1358 ); 1359 } 1360 }); 1361 1362 it('isDump()', () => { 1363 const trace = new TraceBuilder<string>() 1364 .setEntries(['entry-0']) 1365 .setTimestamps([time10]) 1366 .build(); 1367 expect(trace.isDump()).toBeTrue(); 1368 expect(trace.isDumpWithoutTimestamp()).toBeFalse(); 1369 }); 1370 1371 it('isDumpWithoutTimestamp()', () => { 1372 const trace = new TraceBuilder<string>() 1373 .setEntries(['entry-0']) 1374 .setTimestamps([TimestampConverterUtils.makeZeroTimestamp()]) 1375 .build(); 1376 expect(trace.isDumpWithoutTimestamp()).toBeTrue(); 1377 }); 1378 1379 it('updates corruptedState on failure to parse entry', async () => { 1380 const trace = new TraceBuilder<string>() 1381 .setParser( 1382 new ParserBuilder<string>() 1383 .setIsCorrupted(true) 1384 .setEntries(['entry-0']) 1385 .setTimestamps([TimestampConverterUtils.makeZeroTimestamp()]) 1386 .build(), 1387 ) 1388 .build(); 1389 expect(trace.isCorrupted()).toBeFalse(); 1390 expect(trace.getCorruptedReason()).toBeUndefined(); 1391 1392 expectAsync(trace.getEntry(0).getValue()).toBeRejected(); 1393 try { 1394 await trace.getEntry(0).getValue(); 1395 } catch (e) { 1396 expect(trace.isCorrupted()).toBeTrue(); 1397 expect(trace.getCorruptedReason()).toEqual( 1398 'Cannot parse entry at index 0', 1399 ); 1400 } 1401 }); 1402 1403 it('spansMultipleDates()', () => { 1404 const emptyTrace = UnitTestUtils.makeEmptyTrace( 1405 TraceType.TEST_TRACE_STRING, 1406 ); 1407 expect(emptyTrace.spansMultipleDates()).toBeFalse(); 1408 1409 const traceWithElapsedTimestamps = new TraceBuilder<string>() 1410 .setEntries(['entry-0', 'entry-1']) 1411 .setTimestamps([ 1412 TimestampConverterUtils.makeElapsedTimestamp(0n), 1413 TimestampConverterUtils.makeElapsedTimestamp( 1414 BigInt(TIME_UNIT_TO_NANO.d), 1415 ), 1416 ]) 1417 .build(); 1418 expect(traceWithElapsedTimestamps.spansMultipleDates()).toBeFalse(); 1419 1420 const traceWithRealTimestampsOneDate = new TraceBuilder<string>() 1421 .setEntries(['entry-0', 'entry-1']) 1422 .setTimestamps([time10, time15]) 1423 .build(); 1424 expect(traceWithRealTimestampsOneDate.spansMultipleDates()).toBeFalse(); 1425 1426 const traceWitMultipleDates = new TraceBuilder<string>() 1427 .setEntries(['entry-0', 'entry-1']) 1428 .setTimestamps([ 1429 TimestampConverterUtils.makeRealTimestamp( 1430 BigInt(TIME_UNIT_TO_NANO.h * 23), 1431 ), 1432 TimestampConverterUtils.makeRealTimestamp( 1433 BigInt(TIME_UNIT_TO_NANO.h * 25), 1434 ), 1435 ]) 1436 .build(); 1437 expect(traceWitMultipleDates.spansMultipleDates()).toBeTrue(); 1438 }); 1439}); 1440