test_profiler_data.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /* Any copyright is dedicated to the Public Domain.
  2. http://creativecommons.org/publicdomain/zero/1.0/ */
  3. "use strict";
  4. /**
  5. * Tests if the profiler actor can correctly retrieve a profile after
  6. * it is activated.
  7. */
  8. const Profiler = Cc["@mozilla.org/tools/profiler;1"].getService(Ci.nsIProfiler);
  9. const INITIAL_WAIT_TIME = 100; // ms
  10. const MAX_WAIT_TIME = 20000; // ms
  11. function run_test()
  12. {
  13. get_chrome_actors((client, form) => {
  14. let actor = form.profilerActor;
  15. activate_profiler(client, actor, startTime => {
  16. test_data(client, actor, startTime, () => {
  17. deactivate_profiler(client, actor, () => {
  18. client.close().then(do_test_finished);
  19. });
  20. });
  21. });
  22. });
  23. do_test_pending();
  24. }
  25. function activate_profiler(client, actor, callback)
  26. {
  27. client.request({ to: actor, type: "startProfiler" }, response => {
  28. do_check_true(response.started);
  29. client.request({ to: actor, type: "isActive" }, response => {
  30. do_check_true(response.isActive);
  31. callback(response.currentTime);
  32. });
  33. });
  34. }
  35. function deactivate_profiler(client, actor, callback)
  36. {
  37. client.request({ to: actor, type: "stopProfiler" }, response => {
  38. do_check_false(response.started);
  39. client.request({ to: actor, type: "isActive" }, response => {
  40. do_check_false(response.isActive);
  41. callback();
  42. });
  43. });
  44. }
  45. function test_data(client, actor, startTime, callback)
  46. {
  47. function attempt(delay)
  48. {
  49. // No idea why, but Components.stack.sourceLine returns null.
  50. let funcLine = Components.stack.lineNumber - 3;
  51. // Spin for the requested time, then take a sample.
  52. let start = Date.now();
  53. let stack;
  54. do_print("Attempt: delay = " + delay);
  55. while (Date.now() - start < delay) { stack = Components.stack; }
  56. do_print("Attempt: finished waiting.");
  57. client.request({ to: actor, type: "getProfile", startTime }, response => {
  58. // Any valid getProfile response should have the following top
  59. // level structure.
  60. do_check_eq(typeof response.profile, "object");
  61. do_check_eq(typeof response.profile.meta, "object");
  62. do_check_eq(typeof response.profile.meta.platform, "string");
  63. do_check_eq(typeof response.profile.threads, "object");
  64. do_check_eq(typeof response.profile.threads[0], "object");
  65. do_check_eq(typeof response.profile.threads[0].samples, "object");
  66. // At this point, we may or may not have samples, depending on
  67. // whether the spin loop above has given the profiler enough time
  68. // to get started.
  69. if (response.profile.threads[0].samples.length == 0) {
  70. if (delay < MAX_WAIT_TIME) {
  71. // Double the spin-wait time and try again.
  72. do_print("Attempt: no samples, going around again.");
  73. return attempt(delay * 2);
  74. } else {
  75. // We've waited long enough, so just fail.
  76. do_print("Attempt: waited a long time, but no samples were collected.");
  77. do_print("Giving up.");
  78. do_check_true(false);
  79. return;
  80. }
  81. }
  82. // Now check the samples. At least one sample is expected to
  83. // have been in the busy wait above.
  84. let loc = stack.name + " (" + stack.filename + ":" + funcLine + ")";
  85. let thread0 = response.profile.threads[0];
  86. do_check_true(thread0.samples.data.some(sample => {
  87. let frames = getInflatedStackLocations(thread0, sample);
  88. return frames.length != 0 &&
  89. frames.some(location => (location == loc));
  90. }));
  91. callback();
  92. });
  93. }
  94. // Start off with a 100 millisecond delay.
  95. attempt(INITIAL_WAIT_TIME);
  96. }