diff options
Diffstat (limited to 'mobile/android/tests/browser/chrome/test_awsy_lite.html')
-rw-r--r-- | mobile/android/tests/browser/chrome/test_awsy_lite.html | 258 |
1 files changed, 258 insertions, 0 deletions
diff --git a/mobile/android/tests/browser/chrome/test_awsy_lite.html b/mobile/android/tests/browser/chrome/test_awsy_lite.html new file mode 100644 index 000000000..066aaf2ea --- /dev/null +++ b/mobile/android/tests/browser/chrome/test_awsy_lite.html @@ -0,0 +1,258 @@ +<!DOCTYPE HTML> +<html> +<!-- + This test reports Firefox memory use to Perfherder. + + Inspired by https://areweslimyet.com/mobile + + https://bugzilla.mozilla.org/show_bug.cgi?id=1233220 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1233220</title> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/MemoryStats.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://global/skin"/> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> + <script type="application/javascript;version=1.8" src="head.js"></script> + <script type="application/javascript;version=1.8"> + + "use strict"; + + const { interfaces: Ci, utils: Cu, classes: Cc } = Components; + + var kUrls = [ + "http://mochi.test:8888/chrome/mobile/android/tests/browser/chrome/tp5/baidu.com/www.baidu.com/s@wd=mozilla.html", + "http://mochi.test:8888/chrome/mobile/android/tests/browser/chrome/tp5/twitter.com/twitter.com/ICHCheezburger.html", + "http://mochi.test:8888/chrome/mobile/android/tests/browser/chrome/tp5/msn.com/www.msn.com/index.html", + "http://mochi.test:8888/chrome/mobile/android/tests/browser/chrome/tp5/163.com/www.163.com/index.html", + "http://mochi.test:8888/chrome/mobile/android/tests/browser/chrome/tp5/bbc.co.uk/www.bbc.co.uk/news/index.html" + ]; + + var gTabsOpened = 0; + var gWindow = null; + var gLastTab = null; + var gResults = []; + + Cu.import("resource://gre/modules/Services.jsm"); + + var BrowserApp = Services.wm.getMostRecentWindow("navigator:browser").BrowserApp; + SimpleTest.waitForExplicitFinish(); + SimpleTest.requestLongerTimeout(3); // several long waits and GCs make for a long-running test + SimpleTest.requestCompleteLog(); // so that "PERFHERDER_DATA" can be scraped from the log + + function checkpoint(aName) { + var mrm = Cc["@mozilla.org/memory-reporter-manager;1"].getService(Ci.nsIMemoryReporterManager); + gResults.push( { name: aName, resident: mrm.resident } ); + info(`${aName} | Resident Memory: ${mrm.resident}`); + } + + var browserListener = { + onOpenWindow: function(aWindow) { + var win = aWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindow); + win.addEventListener("UIReady", function listener(aEvent) { + win.removeEventListener("UIReady", listener, false); + attachTo(win); + }, false); + }, + + onCloseWindow: function(aWindow) { + detachFrom(aWindow); + }, + + onWindowTitleChange: function(aWindow, aTitle) { + } + }; + + function doFullGc(aCallback, aIterations) { + var threadMan = Cc["@mozilla.org/thread-manager;1"].getService(Ci.nsIThreadManager); + var domWindowUtils = gWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIDOMWindowUtils); + + function runSoon(f) { + threadMan.mainThread.dispatch({ run: f }, Ci.nsIThread.DISPATCH_NORMAL); + } + + function cc() { + if (domWindowUtils.cycleCollect) { + domWindowUtils.cycleCollect(); + } + Services.obs.notifyObservers(null, "child-cc-request", null); + } + + function minimizeInner() { + // In order of preference: schedulePreciseShrinkingGC, schedulePreciseGC + // garbageCollect + if (++j <= aIterations) { + var schedGC = Cu.schedulePreciseShrinkingGC; + if (!schedGC) { + schedGC = Cu.schedulePreciseGC; + } + + Services.obs.notifyObservers(null, "child-gc-request", null); + + if (schedGC) { + schedGC.call(Cu, { callback: function () { + runSoon(function () { cc(); runSoon(minimizeInner); }); + } }); + } else { + if (domWindowUtils.garbageCollect) { + domWindowUtils.garbageCollect(); + } + runSoon(function () { cc(); runSoon(minimizeInner); }); + } + } else { + runSoon(aCallback); + } + } + + var j = 0; + minimizeInner(); + } + + function attachTo(aWindow) { + if (gWindow != null) { + info("attempting to attach to a second window [" + aWindow + "] while already attached to one window [" + gWindow + "]"); + return; + } + gWindow = aWindow; + setTimeout(startTest, 0); + } + + function detachFrom(aWindow) { + if (gWindow == aWindow) { + gWindow = null; + } + } + + function startup() { + var enumerator = Services.wm.getEnumerator("navigator:browser"); + while (enumerator.hasMoreElements()) { + // potential race condition here - the window may not be ready yet at + // this point, so ideally we would test for that. but i can't find a + // property that reflects whether or not UIReady has been fired, so + // for now just assume the window is ready + attachTo(enumerator.getNext().QueryInterface(Ci.nsIDOMWindow)); + } + Services.wm.addListener(browserListener); + } + + function startTest() { + checkpoint("Fresh start"); + setTimeout(settle, 30000); + } + + function settle() { + checkpoint("Fresh start [+30s]"); + openTab(); + } + + function openTab() { + var urlIndex = gTabsOpened++; + if (urlIndex >= kUrls.length) { + checkpoint("After tabs"); + setTimeout(postOpening, 30000); + return; + } + + info("opening tab with url [" + kUrls[urlIndex] + "]"); + gLastTab = BrowserApp.addTab(kUrls[urlIndex], { selected: true }); + setTimeout(waitForTab, 10000); + } + + function waitForTab() { + if (gLastTab.browser.contentDocument.readyState === "complete") { + gLastTab = null; + openTab(); + } else { + setTimeout(waitForTab, 10000); + } + } + + function postOpening() { + checkpoint("After tabs [+30s]"); + doFullGc(() => closeTabs()); + } + + function closeTabs() { + checkpoint("After tabs [+30s, forced GC]"); + var tabCount = BrowserApp.tabs.length; + for (var i = 1; i < tabCount; i++) { + BrowserApp.closeTab(BrowserApp.tabs[i]); + } + + var closeListener = { + observe: function(aSubject, aTopic, aData) { + tabCount--; + dump("tab count dropped to [" + tabCount + "]"); + if (tabCount == 1) { + Services.obs.removeObserver(this, "Tab:Closed", false); + setTimeout(tabsClosed, 0); + } + } + }; + Services.obs.addObserver(closeListener, "Tab:Closed", false); + } + + function tabsClosed() { + checkpoint("Tabs closed"); + setTimeout(postClosing, 30000); + } + + function postClosing() { + checkpoint("Tabs closed [+30s]"); + doFullGc(() => { + checkpoint("Tabs closed [+30s, forced GC]"); + finalReport(); + ok(true, "memory logging complete -- view results in Perfherder"); + SimpleTest.finish(); + }); + } + + function geomean(aProperty) { + // https://en.wikipedia.org/wiki/Geometric_mean#Relationship_with_arithmetic_mean_of_logarithms + var logsum = 0; + var i; + for (i = 0; i < gResults.length; i++) { + var result = gResults[i]; + logsum += Math.log(result[aProperty]); + } + return Math.round(Math.exp(logsum/gResults.length)); + } + + function finalReport() { + var i; + var perfherder = "PERFHERDER_DATA: "; + perfherder += "{\"framework\": {\"name\": \"awsy\"}, "; + perfherder += "\"suites\": ["; + perfherder += "{\"name\": \"Resident Memory\", "; + perfherder += "\"subtests\": ["; + for (i = 0; i < gResults.length; i++) { + var result = gResults[i]; + if (i > 0) { + perfherder += ", "; + } + perfherder += `{\"name\": \"${result.name}\", \"value\": ${result.resident}}`; + } + perfherder += "], "; // end subtests + perfherder += "\"value\": "+geomean("resident"); + perfherder += "}"; // end Resident Memory suite + perfherder += "]"; // end suites + perfherder += "}"; // end PERFHERDER_DATA + info(perfherder); + } + + startup(); + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1233220">Mozilla Bug 1233220</a> +<br> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> |