browser_perf-gc-snap.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /* Any copyright is dedicated to the Public Domain.
  2. http://creativecommons.org/publicdomain/zero/1.0/ */
  3. "use strict";
  4. /* eslint-disable */
  5. /**
  6. * Tests that the marker details on GC markers displays allocation
  7. * buttons and snaps to the correct range
  8. */
  9. function* spawnTest() {
  10. let { panel } = yield initPerformance(ALLOCS_URL);
  11. let { $, $$, EVENTS, PerformanceController, OverviewView, DetailsView, WaterfallView, MemoryCallTreeView } = panel.panelWin;
  12. let EPSILON = 0.00001;
  13. Services.prefs.setBoolPref(ALLOCATIONS_PREF, true);
  14. yield startRecording(panel);
  15. yield idleWait(1000);
  16. yield stopRecording(panel);
  17. injectGCMarkers(PerformanceController, WaterfallView);
  18. // Select everything
  19. let rendered = WaterfallView.once(EVENTS.UI_WATERFALL_RENDERED);
  20. OverviewView.setTimeInterval({ startTime: 0, endTime: Number.MAX_VALUE });
  21. yield rendered;
  22. let bars = $$(".waterfall-marker-bar");
  23. let gcMarkers = PerformanceController.getCurrentRecording().getMarkers();
  24. ok(gcMarkers.length === 9, "should have 9 GC markers");
  25. ok(bars.length === 9, "should have 9 GC markers rendered");
  26. /**
  27. * Check when it's the second marker of the first GC cycle.
  28. */
  29. let targetMarker = gcMarkers[1];
  30. let targetBar = bars[1];
  31. info(`Clicking GC Marker of type ${targetMarker.causeName} ${targetMarker.start}:${targetMarker.end}`);
  32. EventUtils.sendMouseEvent({ type: "mousedown" }, targetBar);
  33. let showAllocsButton;
  34. // On slower machines this can not be found immediately?
  35. yield waitUntil(() => showAllocsButton = $("#waterfall-details .custom-button[type='show-allocations']"));
  36. ok(showAllocsButton, "GC buttons when allocations are enabled");
  37. rendered = once(MemoryCallTreeView, EVENTS.UI_MEMORY_CALL_TREE_RENDERED);
  38. EventUtils.sendMouseEvent({ type: "click" }, showAllocsButton);
  39. yield rendered;
  40. is(OverviewView.getTimeInterval().startTime, 0, "When clicking first GC, should use 0 as start time");
  41. within(OverviewView.getTimeInterval().endTime, targetMarker.start, EPSILON, "Correct end time range");
  42. let duration = PerformanceController.getCurrentRecording().getDuration();
  43. rendered = once(WaterfallView, EVENTS.UI_WATERFALL_RENDERED);
  44. OverviewView.setTimeInterval({ startTime: 0, endTime: duration });
  45. yield DetailsView.selectView("waterfall");
  46. yield rendered;
  47. /**
  48. * Check when there is a previous GC cycle
  49. */
  50. bars = $$(".waterfall-marker-bar");
  51. targetMarker = gcMarkers[4];
  52. targetBar = bars[4];
  53. info(`Clicking GC Marker of type ${targetMarker.causeName} ${targetMarker.start}:${targetMarker.end}`);
  54. EventUtils.sendMouseEvent({ type: "mousedown" }, targetBar);
  55. // On slower machines this can not be found immediately?
  56. yield waitUntil(() => showAllocsButton = $("#waterfall-details .custom-button[type='show-allocations']"));
  57. ok(showAllocsButton, "GC buttons when allocations are enabled");
  58. rendered = once(MemoryCallTreeView, EVENTS.UI_MEMORY_CALL_TREE_RENDERED);
  59. EventUtils.sendMouseEvent({ type: "click" }, showAllocsButton);
  60. yield rendered;
  61. within(OverviewView.getTimeInterval().startTime, gcMarkers[2].end, EPSILON,
  62. "selection start range is last marker from previous GC cycle.");
  63. within(OverviewView.getTimeInterval().endTime, targetMarker.start, EPSILON,
  64. "selection end range is current GC marker's start time");
  65. /**
  66. * Now with allocations disabled
  67. */
  68. // Reselect the entire recording -- due to bug 1196945, the new recording
  69. // won't reset the selection
  70. duration = PerformanceController.getCurrentRecording().getDuration();
  71. rendered = once(WaterfallView, EVENTS.UI_WATERFALL_RENDERED);
  72. OverviewView.setTimeInterval({ startTime: 0, endTime: duration });
  73. yield rendered;
  74. Services.prefs.setBoolPref(ALLOCATIONS_PREF, false);
  75. yield startRecording(panel);
  76. rendered = once(WaterfallView, EVENTS.UI_WATERFALL_RENDERED);
  77. yield stopRecording(panel);
  78. yield rendered;
  79. injectGCMarkers(PerformanceController, WaterfallView);
  80. // Select everything
  81. rendered = WaterfallView.once(EVENTS.UI_WATERFALL_RENDERED);
  82. OverviewView.setTimeInterval({ startTime: 0, endTime: Number.MAX_VALUE });
  83. yield rendered;
  84. ok(true, "WaterfallView rendered after recording is stopped.");
  85. bars = $$(".waterfall-marker-bar");
  86. gcMarkers = PerformanceController.getCurrentRecording().getMarkers();
  87. EventUtils.sendMouseEvent({ type: "mousedown" }, bars[0]);
  88. showAllocsButton = $("#waterfall-details .custom-button[type='show-allocations']");
  89. ok(!showAllocsButton, "No GC buttons when allocations are disabled");
  90. yield teardown(panel);
  91. finish();
  92. }
  93. function injectGCMarkers(controller, waterfall) {
  94. // Push some fake GC markers into the recording
  95. let realMarkers = controller.getCurrentRecording().getMarkers();
  96. // Invalidate marker cache
  97. waterfall._cache.delete(realMarkers);
  98. realMarkers.length = 0;
  99. for (let gcMarker of GC_MARKERS) {
  100. realMarkers.push(gcMarker);
  101. }
  102. }
  103. var GC_MARKERS = [
  104. { causeName: "TOO_MUCH_MALLOC", cycle: 1 },
  105. { causeName: "TOO_MUCH_MALLOC", cycle: 1 },
  106. { causeName: "TOO_MUCH_MALLOC", cycle: 1 },
  107. { causeName: "ALLOC_TRIGGER", cycle: 2 },
  108. { causeName: "ALLOC_TRIGGER", cycle: 2 },
  109. { causeName: "ALLOC_TRIGGER", cycle: 2 },
  110. { causeName: "SET_NEW_DOCUMENT", cycle: 3 },
  111. { causeName: "SET_NEW_DOCUMENT", cycle: 3 },
  112. { causeName: "SET_NEW_DOCUMENT", cycle: 3 },
  113. ].map((marker, i) => {
  114. marker.name = "GarbageCollection";
  115. marker.start = 50 + (i * 10);
  116. marker.end = marker.start + 9;
  117. return marker;
  118. });
  119. /* eslint-enable */