author | Gabriel Luong <gabriel.luong@gmail.com> |
Wed, 10 Jun 2015 00:18:46 -0700 | |
changeset 248116 | ae4f4b3fd22f0ff16501329eb980afce496aafa0 |
parent 248115 | f0c15d17566f5639ed85954ca24a64352407e6d9 |
child 248117 | 57ec499fafb57645f5aa26ab8a9e2247a258cfb2 |
push id | 60888 |
push user | kwierso@gmail.com |
push date | Thu, 11 Jun 2015 01:38:38 +0000 |
treeherder | mozilla-inbound@39e638ed06bf [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | fitzgen |
bugs | 1084525 |
milestone | 41.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/toolkit/devtools/server/actors/object.js +++ b/toolkit/devtools/server/actors/object.js @@ -140,16 +140,22 @@ ObjectActor.prototype = { promiseState.value = this.hooks.createValueGrip(value); } else if (state == "rejected") { promiseState.reason = this.hooks.createValueGrip(reason); } promiseState.creationTimestamp = Date.now() - PromiseDebugging.getPromiseLifetime(rawPromise); + // If the promise is not settled, avoid adding the timeToSettle property + // and catch the error thrown by PromiseDebugging.getTimeToSettle. + try { + promiseState.timeToSettle = PromiseDebugging.getTimeToSettle(rawPromise); + } catch(e) {} + return promiseState; }, /** * Releases this actor from the pool. */ release: function() { if (this.registeredPool.objectActors) {
--- a/toolkit/devtools/server/tests/unit/test_promises_actor_list_promises.js +++ b/toolkit/devtools/server/tests/unit/test_promises_actor_list_promises.js @@ -40,16 +40,18 @@ function* testListPromises(client, form, let promises = yield front.listPromises(); let found = false; for (let p of promises) { equal(p.type, "object", "Expect type to be Object"); equal(p.class, "Promise", "Expect class to be Promise"); equal(typeof p.promiseState.creationTimestamp, "number", "Expect creation timestamp to be a number"); + equal(typeof p.promiseState.timeToSettle, "number", + "Expect time to settle to be a number"); if (p.promiseState.state === "fulfilled" && p.promiseState.value === resolution) { found = true; } } ok(found, "Found our promise");
--- a/toolkit/devtools/server/tests/unit/test_promises_actor_onpromisesettled.js +++ b/toolkit/devtools/server/tests/unit/test_promises_actor_onpromisesettled.js @@ -64,22 +64,28 @@ function* testPromisesSettled(client, fo function oncePromiseSettled(front, resolution, resolveValue, rejectValue) { return new Promise(resolve => { events.on(front, "promises-settled", promises => { for (let p of promises) { equal(p.type, "object", "Expect type to be Object"); equal(p.class, "Promise", "Expect class to be Promise"); equal(typeof p.promiseState.creationTimestamp, "number", "Expect creation timestamp to be a number"); + equal(typeof p.promiseState.timeToSettle, "number", + "Expect time to settle to be a number"); if (p.promiseState.state === "fulfilled" && p.promiseState.value === resolution) { + equal(Math.floor(p.promiseState.timeToSettle), 0, + "Expect time to settle for resolved promise to be 0."); resolve(resolveValue); } else if (p.promiseState.state === "rejected" && p.promiseState.reason === resolution) { + equal(Math.floor(p.promiseState.timeToSettle), 0, + "Expect time to settle for rejected promise to be 0."); resolve(rejectValue); } else { dump("Found non-target promise\n"); } } }); }); }
new file mode 100644 --- /dev/null +++ b/toolkit/devtools/server/tests/unit/test_promises_object_timetosettle-01.js @@ -0,0 +1,78 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Test whether or not we get the time to settle depending on the state of the + * promise. + */ + +"use strict"; + +const { PromisesFront } = devtools.require("devtools/server/actors/promises"); + +let events = devtools.require("sdk/event/core"); + +add_task(function*() { + let client = yield startTestDebuggerServer("test-promises-timetosettle"); + let chromeActors = yield getChromeActors(client); + + ok(Promise.toString().contains("native code"), "Expect native DOM Promise."); + + yield testGetTimeToSettle(client, chromeActors, () => { + let p = new Promise(() => {}); + p.name = "p"; + let q = p.then(); + q.name = "q"; + + return p; + }); + + let response = yield listTabs(client); + let targetTab = findTab(response.tabs, "test-promises-timetosettle"); + ok(targetTab, "Found our target tab."); + + yield testGetTimeToSettle(client, targetTab, () => { + const debuggee = + DebuggerServer.getTestGlobal("test-promises-timetosettle"); + + let p = new debuggee.Promise(() => {}); + p.name = "p"; + let q = p.then(); + q.name = "q"; + + return p; + }); + + yield close(client); +}); + +function* testGetTimeToSettle(client, form, makePromises) { + let front = PromisesFront(client, form); + + yield front.attach(); + yield front.listPromises(); + + let onNewPromise = new Promise(resolve => { + events.on(front, "new-promises", promises => { + for (let p of promises) { + if (p.promiseState.state === "pending") { + ok(!p.promiseState.timeToSettle, + "Expect no time to settle for unsettled promise."); + } else { + ok(p.promiseState.timeToSettle, + "Expect time to settle for settled promise."); + equal(typeof p.promiseState.timeToSettle, "number", + "Expect time to settle to be a number."); + } + } + resolve(); + }); + }); + + let promise = makePromises(); + + yield onNewPromise; + yield front.detach(); + // Appease eslint + void promise; +}
new file mode 100644 --- /dev/null +++ b/toolkit/devtools/server/tests/unit/test_promises_object_timetosettle-02.js @@ -0,0 +1,69 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Test that we get the expected settlement time for promise time to settle. + */ + +"use strict"; + +const { PromisesFront } = devtools.require("devtools/server/actors/promises"); +const { setTimeout } = devtools.require("sdk/timers"); + +let events = devtools.require("sdk/event/core"); + +add_task(function*() { + let client = yield startTestDebuggerServer("test-promises-timetosettle"); + let chromeActors = yield getChromeActors(client); + + ok(Promise.toString().contains("native code"), "Expect native DOM Promise."); + + yield testGetTimeToSettle(client, chromeActors, + v => new Promise(resolve => setTimeout(() => resolve(v), 100))); + + let response = yield listTabs(client); + let targetTab = findTab(response.tabs, "test-promises-timetosettle"); + ok(targetTab, "Found our target tab."); + + yield testGetTimeToSettle(client, targetTab, v => { + const debuggee = + DebuggerServer.getTestGlobal("test-promises-timetosettle"); + return new debuggee.Promise(resolve => setTimeout(() => resolve(v), 100)); + }); + + yield close(client); +}); + +function* testGetTimeToSettle(client, form, makePromise) { + let front = PromisesFront(client, form); + let resolution = "MyLittleSecret" + Math.random(); + let found = false; + + yield front.attach(); + yield front.listPromises(); + + let onNewPromise = new Promise(resolve => { + events.on(front, "promises-settled", promises => { + for (let p of promises) { + if (p.promiseState.state === "fulfilled" && + p.promiseState.value === resolution) { + equal(Math.floor(p.promiseState.timeToSettle / 100) * 100, 100, + "Expect time to settle for resolved promise to be " + + "approximately 100ms."); + found = true; + resolve(); + } else { + dump("Found non-target promise.\n"); + } + } + }); + }); + + let promise = makePromise(resolution); + + yield onNewPromise; + ok(found, "Found our new promise."); + yield front.detach(); + // Appease eslint + void promise; +}
--- a/toolkit/devtools/server/tests/unit/xpcshell.ini +++ b/toolkit/devtools/server/tests/unit/xpcshell.ini @@ -81,16 +81,18 @@ support-files = [test_eval-04.js] [test_eval-05.js] [test_promises_actor_attach.js] [test_promises_actor_exist.js] [test_promises_actor_list_promises.js] [test_promises_actor_onnewpromise.js] [test_promises_actor_onpromisesettled.js] [test_promises_object_creationtimestamp.js] +[test_promises_object_timetosettle-01.js] +[test_promises_object_timetosettle-02.js] [test_protocol_abort.js] [test_protocol_async.js] [test_protocol_children.js] [test_protocol_formtype.js] [test_protocol_longstring.js] [test_protocol_simple.js] [test_protocol_unregister.js] [test_breakpoint-01.js]