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

branch
TOR_BUG_3246
changeset 7
129ffea94266
equal deleted inserted replaced
-1:000000000000 0:0b4b32a5b25f
1 /* Any copyright is dedicated to the Public Domain.
2 http://creativecommons.org/publicdomain/zero/1.0/ */
3
4 "use strict";
5
6 const Profiler = Cc["@mozilla.org/tools/profiler;1"].getService(Ci.nsIProfiler);
7
8 function run_test()
9 {
10 // Ensure the profiler is not running when the test starts (it could
11 // happen if the MOZ_PROFILER_STARTUP environment variable is set)
12 Profiler.StopProfiler();
13 DebuggerServer.init(function () { return true; });
14 DebuggerServer.addBrowserActors();
15 var client = new DebuggerClient(DebuggerServer.connectPipe());
16 client.connect(function () {
17 client.listTabs(function(aResponse) {
18 test_profiler_actor(client, aResponse.profilerActor);
19 });
20 });
21 do_test_pending();
22 }
23
24 function test_profiler_actor(aClient, aProfiler)
25 {
26 aClient.request({ to: aProfiler, type: "isActive" }, function (aResponse) {
27 do_check_false(aResponse.isActive);
28
29 aClient.request({ to: aProfiler, type: "getFeatures" }, function (aResponse) {
30 var features = Profiler.GetFeatures([]);
31 do_check_eq(aResponse.features.length, features.length);
32 for (var i = 0; i < features.length; i++)
33 do_check_eq(aResponse.features[i], features[i]);
34
35 aClient.request({ to: aProfiler, type: "startProfiler", features: ['jank', 'js'] }, function (aResponse) {
36 do_check_eq(typeof aResponse.msg, "string");
37 aClient.request({ to: aProfiler, type: "isActive" }, function (aResponse) {
38 do_check_true(aResponse.isActive);
39
40 aClient.request({ to: aProfiler, type: "getResponsivenessTimes" }, function (aResponse) {
41 do_check_eq(typeof aResponse.responsivenessTimes, "object");
42
43 aClient.request({ to: aProfiler, type: "getSharedLibraryInformation" }, function (aResponse) {
44 do_check_eq(typeof aResponse.sharedLibraryInformation, "string");
45 try {
46 JSON.parse(aResponse.sharedLibraryInformation);
47 } catch(e) {
48 do_throw(e.toString(), Components.stack.caller);
49 }
50
51 test_event_notifications(aClient, aProfiler);
52 });
53 });
54 });
55 });
56 });
57 });
58 }
59
60 function test_event_notifications(aClient, aProfiler)
61 {
62 aClient.request({ to: aProfiler, type: "registerEventNotifications", events: ["foo", "bar"] }, function (aResponse) {
63 do_check_eq(typeof aResponse.registered, "object");
64 do_check_eq(aResponse.registered.length, 2);
65 do_check_eq(aResponse.registered[0], "foo");
66 do_check_eq(aResponse.registered[1], "bar");
67
68 aClient.request({ to: aProfiler, type: "registerEventNotifications", events: ["foo"] }, function (aResponse) {
69 do_check_eq(typeof aResponse.registered, "object");
70 do_check_eq(aResponse.registered.length, 0);
71
72 aClient.addListener("eventNotification", function (aType, aData) {
73 do_check_eq(aType, "eventNotification");
74 do_check_eq(aData.event, "foo");
75 do_check_eq(typeof aData.subject, "object");
76 do_check_eq(aData.subject.foo, "foo");
77 do_check_eq(aData.data, "foo");
78 });
79 var subject = { foo: "foo" };
80 subject.wrappedJSObject = subject;
81 Services.obs.notifyObservers(subject, "foo", "foo");
82
83 aClient.request({ to: aProfiler, type: "unregisterEventNotifications", events: ["foo", "bar", "qux"] }, function (aResponse) {
84 do_check_eq(typeof aResponse.unregistered, "object");
85 do_check_eq(aResponse.unregistered.length, 2);
86 do_check_eq(aResponse.unregistered[0], "foo");
87 do_check_eq(aResponse.unregistered[1], "bar");
88
89 // All events being now unregistered, sending an event shouldn't
90 // do anything. If it does, the eventNotification listener above
91 // will catch the event and fail on the aData.event test.
92 Services.obs.notifyObservers(null, "bar", null);
93
94 test_profile(aClient, aProfiler);
95 });
96 });
97 });
98 }
99
100 function test_profile(aClient, aProfiler)
101 {
102 // No idea why, but Components.stack.sourceLine returns null.
103 var funcLine = Components.stack.lineNumber - 3;
104 // Busy wait a few milliseconds
105 var start = Date.now();
106 var stack;
107 while (Date.now() - start < 200) { stack = Components.stack; }
108 aClient.request({ to: aProfiler, type: "getProfile" }, function (aResponse) {
109 do_check_eq(typeof aResponse.profile, "object");
110 do_check_eq(typeof aResponse.profile.meta, "object");
111 do_check_eq(typeof aResponse.profile.meta.platform, "string");
112 do_check_eq(typeof aResponse.profile.threads, "object");
113 do_check_eq(typeof aResponse.profile.threads[0], "object");
114 do_check_eq(typeof aResponse.profile.threads[0].samples, "object");
115 do_check_neq(aResponse.profile.threads[0].samples.length, 0);
116
117 let location = stack.name + " (" + stack.filename + ":" + funcLine + ")";
118 // At least one sample is expected to have been in the busy wait above.
119 do_check_true(aResponse.profile.threads[0].samples.some(function(sample) {
120 return typeof sample.frames == "object" &&
121 sample.frames.length != 0 &&
122 sample.frames.some(function(f) {
123 return (f.line == stack.lineNumber) &&
124 (f.location == location);
125 });
126 }));
127
128 aClient.request({ to: aProfiler, type: "stopProfiler" }, function (aResponse) {
129 do_check_eq(typeof aResponse.msg, "string");
130 aClient.request({ to: aProfiler, type: "isActive" }, function (aResponse) {
131 do_check_false(aResponse.isActive);
132 aClient.close(function() {
133 test_profiler_status();
134 });
135 });
136 });
137 });
138 }
139
140 function test_profiler_status()
141 {
142 var connectionClosed = DebuggerServer._connectionClosed;
143 var client = new DebuggerClient(DebuggerServer.connectPipe());
144
145 client.connect(() => {
146 client.listTabs((aResponse) => {
147 DebuggerServer._connectionClosed = function (conn) {
148 connectionClosed.call(this, conn);
149
150 // Check that closing the last (only?) connection stops the profiler.
151 do_check_false(Profiler.IsActive());
152 do_test_finished();
153 }
154
155 var profiler = aResponse.profilerActor;
156 do_check_false(Profiler.IsActive());
157 client.request({
158 to: profiler,
159 type: "startProfiler",
160 features: []
161 }, function (aResponse) {
162 do_check_true(Profiler.IsActive());
163 client.close();
164 });
165 });
166 });
167 }

mercurial