toolkit/devtools/server/tests/unit/test_profiler_actor.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/toolkit/devtools/server/tests/unit/test_profiler_actor.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,167 @@
     1.4 +/* Any copyright is dedicated to the Public Domain.
     1.5 +   http://creativecommons.org/publicdomain/zero/1.0/ */
     1.6 +
     1.7 +"use strict";
     1.8 +
     1.9 +const Profiler = Cc["@mozilla.org/tools/profiler;1"].getService(Ci.nsIProfiler);
    1.10 +
    1.11 +function run_test()
    1.12 +{
    1.13 +  // Ensure the profiler is not running when the test starts (it could
    1.14 +  // happen if the MOZ_PROFILER_STARTUP environment variable is set)
    1.15 +  Profiler.StopProfiler();
    1.16 +  DebuggerServer.init(function () { return true; });
    1.17 +  DebuggerServer.addBrowserActors();
    1.18 +  var client = new DebuggerClient(DebuggerServer.connectPipe());
    1.19 +  client.connect(function () {
    1.20 +    client.listTabs(function(aResponse) {
    1.21 +      test_profiler_actor(client, aResponse.profilerActor);
    1.22 +    });
    1.23 +  });
    1.24 +  do_test_pending();
    1.25 +}
    1.26 +
    1.27 +function test_profiler_actor(aClient, aProfiler)
    1.28 +{
    1.29 +  aClient.request({ to: aProfiler, type: "isActive" }, function (aResponse) {
    1.30 +    do_check_false(aResponse.isActive);
    1.31 +
    1.32 +    aClient.request({ to: aProfiler, type: "getFeatures" }, function (aResponse) {
    1.33 +      var features = Profiler.GetFeatures([]);
    1.34 +      do_check_eq(aResponse.features.length, features.length);
    1.35 +      for (var i = 0; i < features.length; i++)
    1.36 +        do_check_eq(aResponse.features[i], features[i]);
    1.37 +
    1.38 +      aClient.request({ to: aProfiler, type: "startProfiler", features: ['jank', 'js'] }, function (aResponse) {
    1.39 +        do_check_eq(typeof aResponse.msg, "string");
    1.40 +        aClient.request({ to: aProfiler, type: "isActive" }, function (aResponse) {
    1.41 +          do_check_true(aResponse.isActive);
    1.42 +
    1.43 +          aClient.request({ to: aProfiler, type: "getResponsivenessTimes" }, function (aResponse) {
    1.44 +            do_check_eq(typeof aResponse.responsivenessTimes, "object");
    1.45 +
    1.46 +            aClient.request({ to: aProfiler, type: "getSharedLibraryInformation" }, function (aResponse) {
    1.47 +              do_check_eq(typeof aResponse.sharedLibraryInformation, "string");
    1.48 +              try {
    1.49 +                JSON.parse(aResponse.sharedLibraryInformation);
    1.50 +              } catch(e) {
    1.51 +                do_throw(e.toString(), Components.stack.caller);
    1.52 +              }
    1.53 +
    1.54 +              test_event_notifications(aClient, aProfiler);
    1.55 +            });
    1.56 +          });
    1.57 +        });
    1.58 +      });
    1.59 +    });
    1.60 +  });
    1.61 +}
    1.62 +
    1.63 +function test_event_notifications(aClient, aProfiler)
    1.64 +{
    1.65 +  aClient.request({ to: aProfiler, type: "registerEventNotifications", events: ["foo", "bar"] }, function (aResponse) {
    1.66 +    do_check_eq(typeof aResponse.registered, "object");
    1.67 +    do_check_eq(aResponse.registered.length, 2);
    1.68 +    do_check_eq(aResponse.registered[0], "foo");
    1.69 +    do_check_eq(aResponse.registered[1], "bar");
    1.70 +
    1.71 +    aClient.request({ to: aProfiler, type: "registerEventNotifications", events: ["foo"] }, function (aResponse) {
    1.72 +      do_check_eq(typeof aResponse.registered, "object");
    1.73 +      do_check_eq(aResponse.registered.length, 0);
    1.74 +
    1.75 +      aClient.addListener("eventNotification", function (aType, aData) {
    1.76 +        do_check_eq(aType, "eventNotification");
    1.77 +        do_check_eq(aData.event, "foo");
    1.78 +        do_check_eq(typeof aData.subject, "object");
    1.79 +        do_check_eq(aData.subject.foo, "foo");
    1.80 +        do_check_eq(aData.data, "foo");
    1.81 +      });
    1.82 +      var subject = { foo: "foo" };
    1.83 +      subject.wrappedJSObject = subject;
    1.84 +      Services.obs.notifyObservers(subject, "foo", "foo");
    1.85 +
    1.86 +      aClient.request({ to: aProfiler, type: "unregisterEventNotifications", events: ["foo", "bar", "qux"] }, function (aResponse) {
    1.87 +        do_check_eq(typeof aResponse.unregistered, "object");
    1.88 +        do_check_eq(aResponse.unregistered.length, 2);
    1.89 +        do_check_eq(aResponse.unregistered[0], "foo");
    1.90 +        do_check_eq(aResponse.unregistered[1], "bar");
    1.91 +
    1.92 +        // All events being now unregistered, sending an event shouldn't
    1.93 +        // do anything. If it does, the eventNotification listener above
    1.94 +        // will catch the event and fail on the aData.event test.
    1.95 +        Services.obs.notifyObservers(null, "bar", null);
    1.96 +
    1.97 +        test_profile(aClient, aProfiler);
    1.98 +      });
    1.99 +    });
   1.100 +  });
   1.101 +}
   1.102 +
   1.103 +function test_profile(aClient, aProfiler)
   1.104 +{
   1.105 +  // No idea why, but Components.stack.sourceLine returns null.
   1.106 +  var funcLine = Components.stack.lineNumber - 3;
   1.107 +  // Busy wait a few milliseconds
   1.108 +  var start = Date.now();
   1.109 +  var stack;
   1.110 +  while (Date.now() - start < 200) { stack = Components.stack; }
   1.111 +  aClient.request({ to: aProfiler, type: "getProfile" }, function (aResponse) {
   1.112 +    do_check_eq(typeof aResponse.profile, "object");
   1.113 +    do_check_eq(typeof aResponse.profile.meta, "object");
   1.114 +    do_check_eq(typeof aResponse.profile.meta.platform, "string");
   1.115 +    do_check_eq(typeof aResponse.profile.threads, "object");
   1.116 +    do_check_eq(typeof aResponse.profile.threads[0], "object");
   1.117 +    do_check_eq(typeof aResponse.profile.threads[0].samples, "object");
   1.118 +    do_check_neq(aResponse.profile.threads[0].samples.length, 0);
   1.119 +
   1.120 +    let location = stack.name + " (" + stack.filename + ":" + funcLine + ")";
   1.121 +    // At least one sample is expected to have been in the busy wait above.
   1.122 +    do_check_true(aResponse.profile.threads[0].samples.some(function(sample) {
   1.123 +      return typeof sample.frames == "object" &&
   1.124 +             sample.frames.length != 0 &&
   1.125 +             sample.frames.some(function(f) {
   1.126 +               return (f.line == stack.lineNumber) &&
   1.127 +                      (f.location == location);
   1.128 +             });
   1.129 +    }));
   1.130 +
   1.131 +    aClient.request({ to: aProfiler, type: "stopProfiler" }, function (aResponse) {
   1.132 +      do_check_eq(typeof aResponse.msg, "string");
   1.133 +      aClient.request({ to: aProfiler, type: "isActive" }, function (aResponse) {
   1.134 +        do_check_false(aResponse.isActive);
   1.135 +        aClient.close(function() {
   1.136 +          test_profiler_status();
   1.137 +        });
   1.138 +      });
   1.139 +    });
   1.140 +  });
   1.141 +}
   1.142 +
   1.143 +function test_profiler_status()
   1.144 +{
   1.145 +  var connectionClosed = DebuggerServer._connectionClosed;
   1.146 +  var client = new DebuggerClient(DebuggerServer.connectPipe());
   1.147 +
   1.148 +  client.connect(() => {
   1.149 +    client.listTabs((aResponse) => {
   1.150 +      DebuggerServer._connectionClosed = function (conn) {
   1.151 +        connectionClosed.call(this, conn);
   1.152 +
   1.153 +        // Check that closing the last (only?) connection stops the profiler.
   1.154 +        do_check_false(Profiler.IsActive());
   1.155 +        do_test_finished();
   1.156 +      }
   1.157 +
   1.158 +      var profiler = aResponse.profilerActor;
   1.159 +      do_check_false(Profiler.IsActive());
   1.160 +      client.request({
   1.161 +        to: profiler,
   1.162 +        type: "startProfiler",
   1.163 +        features: []
   1.164 +      }, function (aResponse) {
   1.165 +        do_check_true(Profiler.IsActive());
   1.166 +        client.close();
   1.167 +      });
   1.168 +    });
   1.169 +  });
   1.170 +}

mercurial