sampledProfile.spec.tsx 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. import {SampledProfile} from 'sentry/utils/profiling/profile/sampledProfile';
  2. import {createFrameIndex} from 'sentry/utils/profiling/profile/utils';
  3. import {firstCallee, makeTestingBoilerplate} from './profile.spec';
  4. describe('SampledProfile', () => {
  5. it('imports the base properties', () => {
  6. const trace: Profiling.SampledProfile = {
  7. name: 'profile',
  8. startValue: 0,
  9. endValue: 1000,
  10. unit: 'milliseconds',
  11. threadID: 0,
  12. type: 'sampled',
  13. weights: [],
  14. samples: [],
  15. };
  16. const profile = SampledProfile.FromProfile(trace, createFrameIndex('mobile', []));
  17. expect(profile.duration).toBe(1000);
  18. expect(profile.name).toBe(trace.name);
  19. expect(profile.threadId).toBe(trace.threadID);
  20. expect(profile.startedAt).toBe(0);
  21. expect(profile.endedAt).toBe(1000);
  22. });
  23. it('tracks discarded samples', () => {
  24. const trace: Profiling.SampledProfile = {
  25. name: 'profile',
  26. startValue: 0,
  27. endValue: 1000,
  28. unit: 'milliseconds',
  29. threadID: 0,
  30. type: 'sampled',
  31. weights: [0],
  32. samples: [[0]],
  33. };
  34. const profile = SampledProfile.FromProfile(
  35. trace,
  36. createFrameIndex('mobile', [{name: 'f0'}])
  37. );
  38. expect(profile.stats.discardedSamplesCount).toBe(1);
  39. });
  40. it('tracks negative samples', () => {
  41. const trace: Profiling.SampledProfile = {
  42. name: 'profile',
  43. startValue: 0,
  44. endValue: 1000,
  45. unit: 'milliseconds',
  46. threadID: 0,
  47. type: 'sampled',
  48. weights: [0, -1],
  49. samples: [[0], [0]],
  50. };
  51. const profile = SampledProfile.FromProfile(
  52. trace,
  53. createFrameIndex('mobile', [{name: 'f0'}])
  54. );
  55. expect(profile.stats.negativeSamplesCount).toBe(1);
  56. });
  57. it('rebuilds the stack', () => {
  58. const trace: Profiling.SampledProfile = {
  59. name: 'profile',
  60. startValue: 0,
  61. endValue: 1000,
  62. unit: 'milliseconds',
  63. threadID: 0,
  64. type: 'sampled',
  65. weights: [1, 1],
  66. samples: [
  67. [0, 1],
  68. [0, 1],
  69. ],
  70. };
  71. const {open, close, openSpy, closeSpy, timings} = makeTestingBoilerplate();
  72. const profile = SampledProfile.FromProfile(
  73. trace,
  74. createFrameIndex('mobile', [{name: 'f0'}, {name: 'f1'}])
  75. );
  76. profile.forEach(open, close);
  77. expect(timings).toEqual([
  78. ['f0', 'open'],
  79. ['f1', 'open'],
  80. ['f1', 'close'],
  81. ['f0', 'close'],
  82. ]);
  83. expect(openSpy).toHaveBeenCalledTimes(2);
  84. expect(closeSpy).toHaveBeenCalledTimes(2);
  85. const root = firstCallee(profile.appendOrderTree);
  86. expect(root.totalWeight).toEqual(2);
  87. expect(firstCallee(root).totalWeight).toEqual(2);
  88. expect(root.selfWeight).toEqual(0);
  89. expect(firstCallee(root).selfWeight).toEqual(2);
  90. });
  91. it('marks direct recursion', () => {
  92. const trace: Profiling.SampledProfile = {
  93. name: 'profile',
  94. startValue: 0,
  95. endValue: 1000,
  96. unit: 'milliseconds',
  97. threadID: 0,
  98. type: 'sampled',
  99. weights: [1],
  100. samples: [[0, 0]],
  101. };
  102. const profile = SampledProfile.FromProfile(
  103. trace,
  104. createFrameIndex('mobile', [{name: 'f0'}, {name: 'f1'}])
  105. );
  106. expect(firstCallee(firstCallee(profile.appendOrderTree)).isRecursive()).toBe(true);
  107. });
  108. it('marks indirect recursion', () => {
  109. const trace: Profiling.SampledProfile = {
  110. name: 'profile',
  111. startValue: 0,
  112. endValue: 1000,
  113. unit: 'milliseconds',
  114. threadID: 0,
  115. type: 'sampled',
  116. weights: [1],
  117. samples: [[0, 1, 0]],
  118. };
  119. const profile = SampledProfile.FromProfile(
  120. trace,
  121. createFrameIndex('mobile', [{name: 'f0'}, {name: 'f1'}])
  122. );
  123. expect(
  124. firstCallee(firstCallee(firstCallee(profile.appendOrderTree))).isRecursive()
  125. ).toBe(true);
  126. });
  127. it('tracks minFrameDuration', () => {
  128. const trace: Profiling.SampledProfile = {
  129. name: 'profile',
  130. startValue: 0,
  131. endValue: 1000,
  132. unit: 'milliseconds',
  133. threadID: 0,
  134. type: 'sampled',
  135. weights: [0.5, 2],
  136. samples: [
  137. [0, 1],
  138. [0, 2],
  139. ],
  140. };
  141. const profile = SampledProfile.FromProfile(
  142. trace,
  143. createFrameIndex('mobile', [{name: 'f0'}, {name: 'f1'}, {name: 'f2'}])
  144. );
  145. expect(profile.minFrameDuration).toBe(0.5);
  146. });
  147. });