diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /dom/performance/tests | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip |
Add m-esr52 at 52.6.0
Diffstat (limited to 'dom/performance/tests')
15 files changed, 920 insertions, 0 deletions
diff --git a/dom/performance/tests/mochitest.ini b/dom/performance/tests/mochitest.ini new file mode 100644 index 000000000..18f7f0e45 --- /dev/null +++ b/dom/performance/tests/mochitest.ini @@ -0,0 +1,17 @@ +[DEFAULT] +support-files = + performance_observer.html + test_performance_observer.js + test_performance_user_timing.js + test_worker_performance_now.js + worker_performance_user_timing.js + worker_performance_observer.js + sharedworker_performance_user_timing.js + worker_performance_observer.html + +[test_performance_observer.html] +[test_performance_user_timing.html] +[test_worker_user_timing.html] +[test_worker_observer.html] +[test_sharedWorker_performance_user_timing.html] +[test_worker_performance_now.html] diff --git a/dom/performance/tests/performance_observer.html b/dom/performance/tests/performance_observer.html new file mode 100644 index 000000000..b8ced9296 --- /dev/null +++ b/dom/performance/tests/performance_observer.html @@ -0,0 +1,74 @@ +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<!DOCTYPE html> +<meta charset=utf-8> +<html> +<head> +<title>Test for performance observer</title> +<script> +'use strict'; +[ + "promise_test", "test", "setup", + "assert_true", "assert_equals", "assert_array_equals", + "assert_throws", "assert_unreached" +].forEach(func => { + window[func] = opener[func].bind(opener); +}); +function done() { + opener.add_completion_callback(() => { + self.close(); + }); + opener.done(); +} + +</script> +<script src="test_performance_observer.js"></script> +</head> +<body> +<div id="log"></div> +<script> +function makeXHR(aUrl) { + var xmlhttp = new XMLHttpRequest(); + xmlhttp.open("get", aUrl, true); + xmlhttp.send(); +} + +promise_test(t => { + var promise = new Promise(resolve => { + performance.clearResourceTimings(); + + var observer = new PerformanceObserver(list => resolve(list)); + observer.observe({entryTypes: ['resource']}); + t.add_cleanup(() => observer.disconnect()); + }); + + makeXHR("test-data.json"); + + return promise.then(list => { + assert_equals(list.getEntries().length, 1); + assert_array_equals(list.getEntries(), + performance.getEntriesByType("resource"), + "Observed 'resource' entries should equal to entries obtained by getEntriesByType."); + + // getEntries filtering tests + assert_array_equals(list.getEntries({name: "http://mochi.test:8888/tests/dom/base/test/test-data.json"}), + performance.getEntriesByName("http://mochi.test:8888/tests/dom/base/test/test-data.json"), + "getEntries with name filter should return correct results."); + assert_array_equals(list.getEntries({entryType: "resource"}), + performance.getEntriesByType("resource"), + "getEntries with entryType filter should return correct results."); + assert_array_equals(list.getEntries({initiatorType: "xmlhttprequest"}), + performance.getEntriesByType("resource"), + "getEntries with initiatorType filter should return correct results."); + assert_array_equals(list.getEntries({initiatorType: "link"}), + [], + "getEntries with non-existent initiatorType filter should return an empty array."); + }); +}, "resource-timing test"); + +done(); + +</script> +</body> diff --git a/dom/performance/tests/sharedworker_performance_user_timing.js b/dom/performance/tests/sharedworker_performance_user_timing.js new file mode 100644 index 000000000..ced3e95fa --- /dev/null +++ b/dom/performance/tests/sharedworker_performance_user_timing.js @@ -0,0 +1,30 @@ +var port; + +function ok(a, msg) { + dump("OK: " + !!a + " => " + a + " " + msg + "\n"); + port.postMessage({type: 'status', status: !!a, msg: a + ": " + msg }); +} + +function is(a, b, msg) { + dump("IS: " + (a===b) + " => " + a + " | " + b + " " + msg + "\n"); + port.postMessage({type: 'status', status: a === b, msg: a + " === " + b + ": " + msg }); +} + +function isnot(a, b, msg) { + dump("ISNOT: " + (a===b) + " => " + a + " | " + b + " " + msg + "\n"); + port.postMessage({type: 'status', status: a != b, msg: a + " != " + b + ": " + msg }); +} + +importScripts('test_performance_user_timing.js'); + +onconnect = function(evt) { + port = evt.ports[0]; + + for (var i = 0; i < steps.length; ++i) { + performance.clearMarks(); + performance.clearMeasures(); + steps[i](); + } + + port.postMessage({type: 'finish'}); +} diff --git a/dom/performance/tests/test_performance_observer.html b/dom/performance/tests/test_performance_observer.html new file mode 100644 index 000000000..d36878315 --- /dev/null +++ b/dom/performance/tests/test_performance_observer.html @@ -0,0 +1,17 @@ +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test for performance observer</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id=log></div> +<script> +'use strict'; +SpecialPowers.pushPrefEnv({"set": [["dom.enable_performance_observer", true]]}, + function() { + window.open("performance_observer.html"); + }); +</script> diff --git a/dom/performance/tests/test_performance_observer.js b/dom/performance/tests/test_performance_observer.js new file mode 100644 index 000000000..9716570e2 --- /dev/null +++ b/dom/performance/tests/test_performance_observer.js @@ -0,0 +1,226 @@ +setup({ explicit_done: true }); + +test(t => { + assert_throws({name: "TypeError"}, function() { + new PerformanceObserver(); + }, "PerformanceObserver constructor should throw TypeError if no argument is specified."); + + assert_throws({name: "TypeError"}, function() { + new PerformanceObserver({}); + }, "PerformanceObserver constructor should throw TypeError if the argument is not a function."); +}, "Test that PerformanceObserver constructor throws exception"); + +test(t => { + var observer = new PerformanceObserver(() => { + }); + + assert_throws({name: "TypeError"}, function() { + observer.observe(); + }, "observe() should throw TypeError exception if no option specified."); + + assert_throws({name: "TypeError"}, function() { + observer.observe({ unsupportedAttribute: "unsupported" }); + }, "obsrve() should throw TypeError exception if the option has no 'entryTypes' attribute."); + + assert_throws({name: "TypeError"}, function() { + observer.observe({ entryTypes: [] }); + }, "obsrve() should throw TypeError exception if 'entryTypes' attribute is an empty sequence."); + + assert_throws({name: "TypeError"}, function() { + observer.observe({ entryTypes: null }); + }, "obsrve() should throw TypeError exception if 'entryTypes' attribute is null."); + + assert_throws({name: "TypeError"}, function() { + observer.observe({ entryTypes: ["invalid"]}); + }, "obsrve() should throw TypeError exception if 'entryTypes' attribute value is invalid."); +}, "Test that PerformanceObserver.observe throws exception"); + +function promiseObserve(test, options) { + return new Promise(resolve => { + performance.clearMarks(); + performance.clearMeasures(); + + var observer = new PerformanceObserver(list => resolve(list)); + observer.observe(options); + test.add_cleanup(() => observer.disconnect()); + }); +} + +promise_test(t => { + var promise = promiseObserve(t, {entryTypes: ['mark', 'measure']}); + + performance.mark("test-start"); + performance.mark("test-end"); + performance.measure("test-measure", "test-start", "test-end"); + + return promise.then(list => { + assert_equals(list.getEntries().length, 3, + "There should be three observed entries."); + + var markEntries = list.getEntries().filter(entry => { + return entry.entryType == "mark"; + }); + assert_array_equals(markEntries, performance.getEntriesByType("mark"), + "Observed 'mark' entries should equal to entries obtained by getEntriesByType."); + + var measureEntries = list.getEntries().filter(entry => { + return entry.entryType == "measure"; + }); + assert_array_equals(measureEntries, performance.getEntriesByType("measure"), + "Observed 'measure' entries should equal to entries obtained by getEntriesByType."); + }); +}, "Test for user-timing with PerformanceObserver"); + +promise_test(t => { + var promise = new Promise((resolve, reject) => { + performance.clearMarks(); + performance.clearMeasures(); + + var observer = new PerformanceObserver(list => reject(list)); + observer.observe({entryTypes: ['mark', 'measure']}); + observer.disconnect(); + t.step_timeout(resolve, 100); + }); + + performance.mark("test-start"); + performance.mark("test-end"); + performance.measure("test-measure", "test-start", "test-end"); + + return promise.then(() => { + assert_equals(performance.getEntriesByType("mark").length, 2); + assert_equals(performance.getEntriesByType("measure").length, 1); + }, list => { + assert_unreached("Observer callback should never be called."); + }); + +}, "Nothing should be notified after disconnecting observer"); + +promise_test(t => { + var promise = promiseObserve(t, {entryTypes: ['mark']}); + + performance.mark("test"); + + return promise.then(list => { + assert_array_equals(list.getEntries({"entryType": "mark"}), + performance.getEntriesByType("mark"), + "getEntries with entryType filter should return correct results."); + + assert_array_equals(list.getEntries({"name": "test"}), + performance.getEntriesByName("test"), + "getEntries with name filter should return correct results."); + + assert_array_equals(list.getEntries({"name": "test", + "entryType": "mark"}), + performance.getEntriesByName("test"), + "getEntries with name and entryType filter should return correct results."); + + assert_array_equals(list.getEntries({"name": "invalid"}), + [], + "getEntries with non-existent name filter should return an empty array."); + + assert_array_equals(list.getEntries({"name": "test", + "entryType": "measure"}), + [], + "getEntries with name filter and non-existent entryType should return an empty array."); + + assert_array_equals(list.getEntries({"name": "invalid", + "entryType": "mark"}), + [], + "getEntries with non-existent name and entryType filter should return an empty array."); + + assert_array_equals(list.getEntries({initiatorType: "xmlhttprequest"}), + [], + "getEntries with initiatorType filter should return an empty array."); + }); +}, "Test for PerformanceObserverEntryList.getEntries"); + +promise_test(t => { + var promise = promiseObserve(t, {entryTypes: ['mark', 'measure']}); + + performance.mark("test"); + performance.measure("test-measure", "test", "test"); + + return promise.then(list => { + assert_array_equals(list.getEntriesByType("mark"), + performance.getEntriesByType("mark")); + assert_array_equals(list.getEntriesByType("measure"), + performance.getEntriesByType("measure")); + }); +}, "Test for PerformanceObserverEntryList.getEntriesByType"); + +promise_test(t => { + var promise = promiseObserve(t, {entryTypes: ['mark', 'measure']}); + + performance.mark("test"); + performance.measure("test-measure", "test", "test"); + + return promise.then(list => { + assert_array_equals(list.getEntriesByName("test"), + performance.getEntriesByName("test")); + assert_array_equals(list.getEntriesByName("test-measure"), + performance.getEntriesByName("test-measure")); + }); +}, "Test for PerformanceObserverEntryList.getEntriesByName"); + +promise_test(t => { + var promise = new Promise(resolve => { + performance.clearMarks(); + performance.clearMeasures(); + + var observer = new PerformanceObserver(list => resolve(list)); + observer.observe({entryTypes: ['mark', 'measure']}); + observer.observe({entryTypes: ['mark', 'measure']}); + t.add_cleanup(() => observer.disconnect()); + }); + + performance.mark("test-start"); + performance.mark("test-end"); + performance.measure("test-measure", "test-start", "test-end"); + + return promise.then(list => { + assert_equals(list.getEntries().length, 3, + "Observed user timing entries should have only three entries."); + }); +}, "Test that invoking observe method twice affects nothing"); + +promise_test(t => { + var promise = new Promise(resolve => { + performance.clearMarks(); + performance.clearMeasures(); + + var observer = new PerformanceObserver(list => resolve(list)); + observer.observe({entryTypes: ['mark', 'measure']}); + observer.observe({entryTypes: ['mark']}); + t.add_cleanup(() => observer.disconnect()); + }); + + performance.mark("test-start"); + performance.mark("test-end"); + performance.measure("test-measure", "test-start", "test-end"); + + return promise.then(list => { + assert_equals(list.getEntries().length, 2, + "Observed user timing entries should have only two entries."); + }); +}, "Test that observing filter is replaced by a new filter"); + +promise_test(t => { + var promise = new Promise(resolve => { + performance.clearMarks(); + performance.clearMeasures(); + + var observer = new PerformanceObserver(list => resolve(list)); + observer.observe({entryTypes: ['mark']}); + observer.observe({entryTypes: ['measure']}); + t.add_cleanup(() => observer.disconnect()); + }); + + performance.mark("test-start"); + performance.mark("test-end"); + performance.measure("test-measure", "test-start", "test-end"); + + return promise.then(list => { + assert_equals(list.getEntries().length, 1, + "Observed user timing entries should have only 1 entries."); + }); +}, "Test that observing filter is replaced by a new filter"); diff --git a/dom/performance/tests/test_performance_user_timing.html b/dom/performance/tests/test_performance_user_timing.html new file mode 100644 index 000000000..5f4123eae --- /dev/null +++ b/dom/performance/tests/test_performance_user_timing.html @@ -0,0 +1,45 @@ +<!DOCTYPE HTML> +<html> + <!-- + https://bugzilla.mozilla.org/show_bug.cgi?id=782751 + --> + <head> + <title>Test for Bug 782751</title> + <meta http-equiv="content-type" content="text/html; charset=UTF-8"> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="test_performance_user_timing.js"></script> + </head> + <body> + <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=782751">Mozilla Bug 782751 - User Timing API</a> + <div id="content"> + </div> + <pre id="test"> + <script class="testbody" type="text/javascript"> + var index = 0; + + function next() { + ok(true, "Begin!"); + var arr; + for (var i = 0; i < steps.length; ++i) { + try { + performance.clearMarks(); + performance.clearMeasures(); + performance.clearResourceTimings(); + is(performance.getEntriesByType("resource").length, 0, "clearing performance resource entries"); + is(performance.getEntriesByType("mark").length, 0, "clearing performance mark entries"); + is(performance.getEntriesByType("measure").length, 0, "clearing performance measure entries"); + steps[i](); + } catch(ex) { + ok(false, "Caught exception", ex); + } + } + + SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); + addLoadEvent(next); + </script> + </pre> + </body> +</html> diff --git a/dom/performance/tests/test_performance_user_timing.js b/dom/performance/tests/test_performance_user_timing.js new file mode 100644 index 000000000..3d05ebb77 --- /dev/null +++ b/dom/performance/tests/test_performance_user_timing.js @@ -0,0 +1,272 @@ +var steps = [ + // Test single mark addition + function () { + ok(true, "Running mark addition test"); + performance.mark("test"); + var marks = performance.getEntriesByType("mark"); + is(marks.length, 1, "Number of marks should be 1"); + var mark = marks[0]; + is(mark.name, "test", "mark name should be 'test'"); + is(mark.entryType, "mark", "mark type should be 'mark'"); + isnot(mark.startTime, 0, "mark start time should not be 0"); + is(mark.duration, 0, "mark duration should be 0"); + }, + // Test multiple mark addition + function () { + ok(true, "Running multiple mark with same name addition test"); + performance.mark("test"); + performance.mark("test"); + performance.mark("test"); + var marks_type = performance.getEntriesByType("mark"); + is(marks_type.length, 3, "Number of marks by type should be 3"); + var marks_name = performance.getEntriesByName("test"); + is(marks_name.length, 3, "Number of marks by name should be 3"); + var mark = marks_name[0]; + is(mark.name, "test", "mark name should be 'test'"); + is(mark.entryType, "mark", "mark type should be 'mark'"); + isnot(mark.startTime, 0, "mark start time should not be 0"); + is(mark.duration, 0, "mark duration should be 0"); + var times = []; + // This also tests the chronological ordering specified as + // required for getEntries in the performance timeline spec. + marks_name.forEach(function(s) { + times.forEach(function(time) { + ok(s.startTime >= time.startTime, + "Times should be equal or increasing between similarly named marks: " + s.startTime + " >= " + time.startTime); + }); + times.push(s); + }); + }, + // Test all marks removal + function () { + ok(true, "Running all mark removal test"); + performance.mark("test"); + performance.mark("test2"); + var marks = performance.getEntriesByType("mark"); + is(marks.length, 2, "number of marks before all removal"); + performance.clearMarks(); + marks = performance.getEntriesByType("mark"); + is(marks.length, 0, "number of marks after all removal"); + }, + // Test single mark removal + function () { + ok(true, "Running removal test (0 'test' marks with other marks)"); + performance.mark("test2"); + var marks = performance.getEntriesByType("mark"); + is(marks.length, 1, "number of marks before all removal"); + performance.clearMarks("test"); + marks = performance.getEntriesByType("mark"); + is(marks.length, 1, "number of marks after all removal"); + }, + // Test single mark removal + function () { + ok(true, "Running removal test (0 'test' marks with no other marks)"); + var marks = performance.getEntriesByType("mark"); + is(marks.length, 0, "number of marks before all removal"); + performance.clearMarks("test"); + marks = performance.getEntriesByType("mark"); + is(marks.length, 0, "number of marks after all removal"); + }, + function () { + ok(true, "Running removal test (1 'test' mark with other marks)"); + performance.mark("test"); + performance.mark("test2"); + var marks = performance.getEntriesByType("mark"); + is(marks.length, 2, "number of marks before all removal"); + performance.clearMarks("test"); + marks = performance.getEntriesByType("mark"); + is(marks.length, 1, "number of marks after all removal"); + }, + function () { + ok(true, "Running removal test (1 'test' mark with no other marks)"); + performance.mark("test"); + var marks = performance.getEntriesByType("mark"); + is(marks.length, 1, "number of marks before all removal"); + performance.clearMarks("test"); + marks = performance.getEntriesByType("mark"); + is(marks.length, 0, "number of marks after all removal"); + }, + function () { + ok(true, "Running removal test (2 'test' marks with other marks)"); + performance.mark("test"); + performance.mark("test"); + performance.mark("test2"); + var marks = performance.getEntriesByType("mark"); + is(marks.length, 3, "number of marks before all removal"); + performance.clearMarks("test"); + marks = performance.getEntriesByType("mark"); + is(marks.length, 1, "number of marks after all removal"); + }, + function () { + ok(true, "Running removal test (2 'test' marks with no other marks)"); + performance.mark("test"); + performance.mark("test"); + var marks = performance.getEntriesByType("mark"); + is(marks.length, 2, "number of marks before all removal"); + performance.clearMarks("test"); + marks = performance.getEntriesByType("mark"); + is(marks.length, 0, "number of marks after all removal"); + }, + // Test mark name being same as navigation timing parameter + function () { + ok(true, "Running mark name collision test"); + for (n in performance.timing) { + try { + if (n == "toJSON") { + ok(true, "Skipping toJSON entry in collision test"); + continue; + } + performance.mark(n); + ok(false, "Mark name collision test failed for name " + n + ", shouldn't make it here!"); + } catch (e) { + ok(e instanceof DOMException, "DOM exception thrown for mark named " + n); + is(e.code, e.SYNTAX_ERR, "DOM exception for name collision is syntax error"); + } + }; + }, + // Test measure + function () { + ok(true, "Running measure addition with no start/end time test"); + performance.measure("test"); + var measures = performance.getEntriesByType("measure"); + is(measures.length, 1, "number of measures should be 1"); + var measure = measures[0]; + is(measure.name, "test", "measure name should be 'test'"); + is(measure.entryType, "measure", "measure type should be 'measure'"); + is(measure.startTime, 0, "measure start time should be zero"); + ok(measure.duration >= 0, "measure duration should not be negative"); + }, + function () { + ok(true, "Running measure addition with only start time test"); + performance.mark("test1"); + performance.measure("test", "test1", undefined); + var measures = performance.getEntriesByName("test", "measure"); + var marks = performance.getEntriesByName("test1", "mark"); + var measure = measures[0]; + var mark = marks[0]; + is(measure.startTime, mark.startTime, "measure start time should be equal to the mark startTime"); + ok(measure.duration >= 0, "measure duration should not be negative"); + }, + function () { + ok(true, "Running measure addition with only end time test"); + performance.mark("test1"); + performance.measure("test", undefined, "test1"); + var measures = performance.getEntriesByName("test", "measure"); + var marks = performance.getEntriesByName("test1", "mark"); + var measure = measures[0]; + var mark = marks[0]; + ok(measure.duration >= 0, "measure duration should not be negative"); + }, + // Test measure picking latest version of similarly named tags + function () { + ok(true, "Running multiple mark with same name addition test"); + performance.mark("test"); + performance.mark("test"); + performance.mark("test"); + performance.mark("test2"); + var marks_name = performance.getEntriesByName("test"); + is(marks_name.length, 3, "Number of marks by name should be 3"); + var marks_name2 = performance.getEntriesByName("test2"); + is(marks_name2.length, 1, "Number of marks by name should be 1"); + var test_mark = marks_name2[0]; + performance.measure("test", "test", "test2"); + var measures_type = performance.getEntriesByType("measure"); + var last_mark = marks_name[marks_name.length - 1]; + is(measures_type.length, 1, "Number of measures by type should be 1"); + var measure = measures_type[0]; + is(measure.startTime, last_mark.startTime, "Measure start time should be the start time of the latest 'test' mark"); + // Tolerance testing to avoid oranges, since we're doing double math across two different languages. + ok(measure.duration - (test_mark.startTime - last_mark.startTime) < .00001, + "Measure duration ( " + measure.duration + ") should be difference between two marks"); + }, + function() { + ok(true, "Running measure addition with no start/end time test"); + performance.measure("test", "navigationStart"); + var measures = performance.getEntriesByType("measure"); + is(measures.length, 1, "number of measures should be 1"); + var measure = measures[0]; + is(measure.name, "test", "measure name should be 'test'"); + is(measure.entryType, "measure", "measure type should be 'measure'"); + is(measure.startTime, 0, "measure start time should be zero"); + ok(measure.duration >= 0, "measure duration should not be negative"); + }, + // Test all measure removal + function () { + ok(true, "Running all measure removal test"); + performance.measure("test"); + performance.measure("test2"); + var measures = performance.getEntriesByType("measure"); + is(measures.length, 2, "measure entries should be length 2"); + performance.clearMeasures(); + measures = performance.getEntriesByType("measure"); + is(measures.length, 0, "measure entries should be length 0"); + }, + // Test single measure removal + function () { + ok(true, "Running all measure removal test"); + performance.measure("test"); + performance.measure("test2"); + var measures = performance.getEntriesByType("measure"); + is(measures.length, 2, "measure entries should be length 2"); + performance.clearMeasures("test"); + measures = performance.getEntriesByType("measure"); + is(measures.length, 1, "measure entries should be length 1"); + }, + // Test measure with invalid start time mark name + function () { + ok(true, "Running measure invalid start test"); + try { + performance.measure("test", "notamark"); + ok(false, "invalid measure start time exception not thrown!"); + } catch (e) { + ok(e instanceof DOMException, "DOM exception thrown for invalid measure"); + is(e.code, e.SYNTAX_ERR, "DOM exception for invalid time is syntax error"); + } + }, + // Test measure with invalid end time mark name + function () { + ok(true, "Running measure invalid end test"); + try { + performance.measure("test", undefined, "notamark"); + ok(false, "invalid measure end time exception not thrown!"); + } catch (e) { + ok(e instanceof DOMException, "DOM exception thrown for invalid measure"); + is(e.code, e.SYNTAX_ERR, "DOM exception for invalid time is syntax error"); + } + }, + // Test measure name being same as navigation timing parameter + function () { + ok(true, "Running measure name collision test"); + for (n in performance.timing) { + try { + if (n == "toJSON") { + ok(true, "Skipping toJSON entry in collision test"); + continue; + } + performance.measure(n); + ok(false, "Measure name collision test failed for name " + n + ", shouldn't make it here!"); + } catch (e) { + ok(e instanceof DOMException, "DOM exception thrown for measure named " + n); + is(e.code, e.SYNTAX_ERR, "DOM exception for name collision is syntax error"); + } + }; + }, + // Test measure mark being a reserved name + function () { + ok(true, "Create measures using all reserved names"); + for (n in performance.timing) { + try { + if (n == "toJSON") { + ok(true, "Skipping toJSON entry in collision test"); + continue; + } + performance.measure("test", n); + ok(true, "Measure created from reserved name as starting time: " + n); + } catch (e) { + ok(["redirectStart", "redirectEnd", "unloadEventStart", "unloadEventEnd", "loadEventEnd"].indexOf(n) >= 0, + "Measure created from reserved name as starting time: " + n + " and threw expected error"); + } + }; + }, + // TODO: Test measure picking latest version of similarly named tags +]; diff --git a/dom/performance/tests/test_sharedWorker_performance_user_timing.html b/dom/performance/tests/test_sharedWorker_performance_user_timing.html new file mode 100644 index 000000000..0498672f3 --- /dev/null +++ b/dom/performance/tests/test_sharedWorker_performance_user_timing.html @@ -0,0 +1,27 @@ +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<!DOCTYPE HTML> +<html> + <head> + <title>Test for worker performance timing API</title> + <meta http-equiv="content-type" content="text/html; charset=UTF-8"> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + </head> + <body> + <script class="testbody" type="text/javascript"> + +var sw = new SharedWorker('sharedworker_performance_user_timing.js'); +sw.port.onmessage = function(event) { + if (event.data.type == 'finish') { + SimpleTest.finish(); + } else if (event.data.type == 'status') { + ok(event.data.status, event.data.msg); + } +} + +SimpleTest.waitForExplicitFinish(); + </script> + </body> +</html> diff --git a/dom/performance/tests/test_worker_observer.html b/dom/performance/tests/test_worker_observer.html new file mode 100644 index 000000000..b9ed0c964 --- /dev/null +++ b/dom/performance/tests/test_worker_observer.html @@ -0,0 +1,17 @@ +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test for performance observer in worker</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id=log></div> +<script> +'use strict'; +SpecialPowers.pushPrefEnv({"set": [["dom.enable_performance_observer", true]]}, + function() { + window.open("worker_performance_observer.html"); + }); +</script> diff --git a/dom/performance/tests/test_worker_performance_now.html b/dom/performance/tests/test_worker_performance_now.html new file mode 100644 index 000000000..ec84ccd10 --- /dev/null +++ b/dom/performance/tests/test_worker_performance_now.html @@ -0,0 +1,32 @@ +<!-- Any copyright is dedicated to the Public Domain. + - http://creativecommons.org/publicdomain/zero/1.0/ --> +<!DOCTYPE HTML> +<html> +<head> + <title>Validate Interfaces Exposed to Workers</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<script class="testbody" type="text/javascript"> + +SimpleTest.waitForExplicitFinish(); +var worker = new Worker('test_worker_performance_now.js'); +worker.onmessage = function(event) { + if (event.data.type == 'finish') { + SimpleTest.finish(); + + } else if (event.data.type == 'status') { + ok(event.data.status, event.data.msg); + + } else if (event.data.type == 'getOSCPU') { + worker.postMessage({ + type: 'returnOSCPU', + result: navigator.oscpu + }); + } +} + +</script> +</body> +</html> diff --git a/dom/performance/tests/test_worker_performance_now.js b/dom/performance/tests/test_worker_performance_now.js new file mode 100644 index 000000000..c2a905031 --- /dev/null +++ b/dom/performance/tests/test_worker_performance_now.js @@ -0,0 +1,76 @@ +function ok(a, msg) { + dump("OK: " + !!a + " => " + a + ": " + msg + "\n"); + postMessage({type: 'status', status: !!a, msg: a + ": " + msg }); +} + +function workerTestDone() { + postMessage({ type: 'finish' }); +} + +function workerTestGetOSCPU(cb) { + addEventListener('message', function workerTestGetOSCPUCB(e) { + if (e.data.type !== 'returnOSCPU') { + return; + } + removeEventListener('message', workerTestGetOSCPUCB); + cb(e.data.result); + }); + postMessage({ + type: 'getOSCPU' + }); +} + +ok(self.performance, "Performance object should exist."); +ok(typeof self.performance.now == 'function', "Performance object should have a 'now' method."); +var n = self.performance.now(), d = Date.now(); +ok(n >= 0, "The value of now() should be equal to or greater than 0."); +ok(self.performance.now() >= n, "The value of now() should monotonically increase."); + +// The spec says performance.now() should have micro-second resolution, but allows 1ms if the platform doesn't support it. +// Our implementation does provide micro-second resolution, except for windows XP combined with some HW properties +// where we can't use QueryPerformanceCounters (see comments at mozilla-central/xpcom/ds/TimeStamp_windows.cpp). +// This XP-low-res case results in about 15ms resolutions, and can be identified when perf.now() returns only integers. +// +// Since setTimeout might return too early/late, our goal is that perf.now() changed within 2ms +// (or 25ms for XP-low-res), rather than specific number of setTimeout(N) invocations. +// See bug 749894 (intermittent failures of this test) +var platformPossiblyLowRes; +workerTestGetOSCPU(function(oscpu) { + platformPossiblyLowRes = oscpu.indexOf("Windows NT 5.1") == 0; // XP only + setTimeout(checkAfterTimeout, 1); +}); +var allInts = (n % 1) == 0; // Indicator of limited HW resolution. +var checks = 0; + +function checkAfterTimeout() { + checks++; + var d2 = Date.now(); + var n2 = self.performance.now(); + + allInts = allInts && (n2 % 1) == 0; + var lowResCounter = platformPossiblyLowRes && allInts; + + if ( n2 == n && checks < 50 && // 50 is just a failsafe. Our real goals are 2ms or 25ms. + ( (d2 - d) < 2 // The spec allows 1ms resolution. We allow up to measured 2ms to ellapse. + || + lowResCounter && + (d2 - d) < 25 + ) + ) { + setTimeout(checkAfterTimeout, 1); + return; + } + + // Loose spec: 1ms resolution, or 15ms resolution for the XP-low-res case. + // We shouldn't test that dt is actually within 2/25ms since the iterations break if it isn't, and timeout could be late. + ok(n2 > n, "Loose - the value of now() should increase within 2ms (or 25ms if low-res counter) (delta now(): " + (n2 - n) + " ms)."); + + // Strict spec: if it's not the XP-low-res case, while the spec allows 1ms resolution, it prefers microseconds, which we provide. + // Since the fastest setTimeout return which I observed was ~500 microseconds, a microseconds counter should change in 1 iteretion. + ok(n2 > n && (lowResCounter || checks == 1), + "Strict - [if high-res counter] the value of now() should increase after one setTimeout (hi-res: " + (!lowResCounter) + + ", iters: " + checks + + ", dt: " + (d2 - d) + + ", now(): " + n2 + ")."); + workerTestDone(); +}; diff --git a/dom/performance/tests/test_worker_user_timing.html b/dom/performance/tests/test_worker_user_timing.html new file mode 100644 index 000000000..2bf465cbd --- /dev/null +++ b/dom/performance/tests/test_worker_user_timing.html @@ -0,0 +1,27 @@ +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<!DOCTYPE HTML> +<html> + <head> + <title>Test for worker performance timing API</title> + <meta http-equiv="content-type" content="text/html; charset=UTF-8"> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + </head> + <body> + <script class="testbody" type="text/javascript"> + +var worker = new Worker('worker_performance_user_timing.js'); +worker.onmessage = function(event) { + if (event.data.type == 'finish') { + SimpleTest.finish(); + } else if (event.data.type == 'status') { + ok(event.data.status, event.data.msg); + } +} + +SimpleTest.waitForExplicitFinish(); + </script> + </body> +</html> diff --git a/dom/performance/tests/worker_performance_observer.html b/dom/performance/tests/worker_performance_observer.html new file mode 100644 index 000000000..613762f52 --- /dev/null +++ b/dom/performance/tests/worker_performance_observer.html @@ -0,0 +1,32 @@ +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<!DOCTYPE html> +<meta charset=utf-8> +<html> +<head> +<title>Test for performance observer in worker</title> +</head> +<body> +<div id="log"></div> +<script> +[ + "async_test", "test", "setup", + "assert_true", "assert_equals", "assert_array_equals", + "assert_throws", "fetch_tests_from_worker" +].forEach(func => { + window[func] = opener[func].bind(opener); +}); + +function done() { + opener.add_completion_callback(() => { + self.close(); + }); + opener.done(); +} + +fetch_tests_from_worker(new Worker("worker_performance_observer.js")); +done(); +</script> +</body> diff --git a/dom/performance/tests/worker_performance_observer.js b/dom/performance/tests/worker_performance_observer.js new file mode 100644 index 000000000..8faf66f67 --- /dev/null +++ b/dom/performance/tests/worker_performance_observer.js @@ -0,0 +1,4 @@ +importScripts(['/resources/testharness.js']); +importScripts(['test_performance_observer.js']); + +done(); diff --git a/dom/performance/tests/worker_performance_user_timing.js b/dom/performance/tests/worker_performance_user_timing.js new file mode 100644 index 000000000..fa2f1afab --- /dev/null +++ b/dom/performance/tests/worker_performance_user_timing.js @@ -0,0 +1,24 @@ +function ok(a, msg) { + dump("OK: " + !!a + " => " + a + " " + msg + "\n"); + postMessage({type: 'status', status: !!a, msg: a + ": " + msg }); +} + +function is(a, b, msg) { + dump("IS: " + (a===b) + " => " + a + " | " + b + " " + msg + "\n"); + postMessage({type: 'status', status: a === b, msg: a + " === " + b + ": " + msg }); +} + +function isnot(a, b, msg) { + dump("ISNOT: " + (a===b) + " => " + a + " | " + b + " " + msg + "\n"); + postMessage({type: 'status', status: a != b, msg: a + " != " + b + ": " + msg }); +} + +importScripts(['test_performance_user_timing.js']); + +for (var i = 0; i < steps.length; ++i) { + performance.clearMarks(); + performance.clearMeasures(); + steps[i](); +} + +postMessage({type: 'finish'}); |