jsSelfProfiling.spec.tsx 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. import {resolveJSSelfProfilingStack} from 'sentry/utils/profiling/jsSelfProfiling';
  2. import {createFrameIndex} from 'sentry/utils/profiling/profile/utils';
  3. const toStackNames = (stack: ReadonlyArray<JSSelfProfiling.Frame>): string[] => {
  4. return stack.map(f => f.name);
  5. };
  6. describe('jsSelfProfiling', () => {
  7. describe('resolveJSSelfProfilingStack', () => {
  8. it('when thread is idle and sample has no associated stackId', () => {
  9. const trace: JSSelfProfiling.Trace = {
  10. frames: [],
  11. resources: [],
  12. samples: [{stackId: undefined, timestamp: 0}],
  13. stacks: [],
  14. };
  15. expect(resolveJSSelfProfilingStack(trace, undefined, {})).toEqual([]);
  16. });
  17. it('when stackId is set', () => {
  18. const trace: JSSelfProfiling.Trace = {
  19. frames: [
  20. {name: 'foo', line: 0, column: 0},
  21. {name: 'bar', line: 0, column: 0},
  22. {name: 'baz', line: 0, column: 0},
  23. {name: 'foobar', line: 0, column: 0},
  24. {name: 'foobarbaz', line: 0, column: 0},
  25. {name: 'foobarbazfoo', line: 0, column: 0},
  26. ],
  27. resources: [],
  28. samples: [{stackId: 5, timestamp: 0}],
  29. stacks: [
  30. {frameId: 0, parentId: undefined},
  31. {frameId: 1, parentId: undefined},
  32. {frameId: 2, parentId: undefined},
  33. {frameId: 3, parentId: 2},
  34. {frameId: 4, parentId: 3},
  35. {frameId: 5, parentId: 4},
  36. ],
  37. };
  38. expect(
  39. toStackNames(
  40. resolveJSSelfProfilingStack(trace, 5, createFrameIndex(trace.frames))
  41. )
  42. ).toEqual(['baz', 'foobar', 'foobarbaz', 'foobarbazfoo']);
  43. });
  44. it('when marker is present on the stack', () => {
  45. const trace: JSSelfProfiling.Trace = {
  46. frames: [
  47. {name: 'foo', line: 0, column: 0},
  48. {name: 'bar', line: 0, column: 0},
  49. {name: 'baz', line: 0, column: 0},
  50. {name: 'foobar', line: 0, column: 0},
  51. {name: 'foobarbaz', line: 0, column: 0},
  52. {name: 'foobarbazfoo', line: 0, column: 0},
  53. ],
  54. resources: [],
  55. samples: [{stackId: 5, timestamp: 0, marker: 'gc'}],
  56. stacks: [
  57. {frameId: 0, parentId: undefined},
  58. {frameId: 1, parentId: undefined},
  59. {frameId: 2, parentId: undefined},
  60. {frameId: 3, parentId: 2},
  61. {frameId: 4, parentId: 3},
  62. {frameId: 5, parentId: 4},
  63. ],
  64. };
  65. // I'm not sure I like passing the marker, the reason it's like this is that we usually loop through the samples and have the marker as
  66. // we execute resolveJSSelfProfilingStack, but I'm not sure we should do that and instead augment the resolved stack outside of the loop.
  67. // The nice thing about it is that it centralizes the stack logic and makes it easier to test.
  68. expect(
  69. toStackNames(
  70. resolveJSSelfProfilingStack(trace, 5, createFrameIndex(trace.frames), 'gc')
  71. )
  72. ).toEqual(['baz', 'foobar', 'foobarbaz', 'foobarbazfoo', 'Garbage Collection']);
  73. });
  74. it('when stack is empty, but browser was performing other operations', () => {
  75. const trace: JSSelfProfiling.Trace = {
  76. frames: [],
  77. resources: [],
  78. samples: [{stackId: 0, timestamp: 0, marker: 'paint'}],
  79. stacks: [{frameId: 0, parentId: undefined}],
  80. };
  81. expect(
  82. toStackNames(
  83. resolveJSSelfProfilingStack(trace, 0, createFrameIndex(trace.frames), 'paint')
  84. )
  85. ).toEqual(['Paint']);
  86. });
  87. });
  88. });