Bug 1188638 - Make sure all TPS test have loaded and run GC/CC between tests. r=blassey
authorBenoit Girard <b56girard@gmail.com>
Wed, 29 Jul 2015 16:53:34 -0400
changeset 995 11b48cfc4512
parent 994 869a812af5d2
child 996 c0039de7a1c6
push id684
push userb56girard@gmail.com
push dateFri, 14 Aug 2015 21:02:16 +0000
reviewersblassey
bugs1188638
Bug 1188638 - Make sure all TPS test have loaded and run GC/CC between tests. r=blassey
talos/page_load_test/tabswitch/bootstrap.js
--- a/talos/page_load_test/tabswitch/bootstrap.js
+++ b/talos/page_load_test/tabswitch/bootstrap.js
@@ -49,30 +49,39 @@ function whenDelayedStartupFinished(win,
   Services.obs.addObserver(function onStartup(subject) {
     if (win == subject) {
       Services.obs.removeObserver(onStartup, topic);
       executeSoon(callback);
     }
   }, topic, false);
 }
 
-function waitForTabLoads(browser, numTabs, callback) {
+function waitForTabLoads(browser, urls, callback) {
+  // Make sure we get load events for all the urls we need.
+  // Before we kept a count and sometimes received load events for other tabs
+  // and got a bad count.
+  var waitingToLoad = {};
+  for (var i = 0; i < urls.length; i++) {
+    waitingToLoad[urls[i]] = true;
+  }
   let listener = {
-    count: 0,
     QueryInterface: XPCOMUtils.generateQI(["nsIWebProgressListener",
                                            "nsISupportsWeakReference"]),
 
     onStateChange: function(aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
       let loadedState = Ci.nsIWebProgressListener.STATE_STOP |
         Ci.nsIWebProgressListener.STATE_IS_NETWORK;
       if ((aStateFlags & loadedState) == loadedState &&
           !aWebProgress.isLoadingDocument &&
           aWebProgress.DOMWindow == aWebProgress.DOMWindow.top) {
-        this.count++;
-        if (this.count == numTabs) {
+        delete waitingToLoad[aBrowser.currentURI.spec];
+        dump("Loaded: " + aBrowser.currentURI.spec + "\n");
+
+        aBrowser.messageManager.loadFrameScript("chrome://pageloader/content/talos-content.js", false);
+        if (Object.keys(waitingToLoad).length == 0) {
           browser.removeTabsProgressListener(listener);
           callback();
         }
       }
     },
 
     onLocationChange: function(aProgress, aRequest, aURI) {
     },
@@ -90,17 +99,17 @@ function loadTabs(urls, win, callback) {
 
   // We don't want to catch scrolling the tabstrip in our tests
   win.gBrowser.tabContainer.style.visibility = "hidden";
 
   let initialTab = win.gBrowser.selectedTab;
   // Set about:blank to be the first tab. This will allow us to use about:blank
   // to let paint event stabilize and make all tab switch more even.
   initialTab.linkedBrowser.loadURI("about:blank", null, null);
-  waitForTabLoads(win.gBrowser, urls.length, function() {
+  waitForTabLoads(win.gBrowser, urls, function() {
     let tabs = win.gBrowser.getTabsToTheEndFrom(initialTab);
     callback(tabs);
   });
   win.gBrowser.loadTabs(urls, true);
 
   aboutBlankTab = initialTab;
 }
 
@@ -108,56 +117,76 @@ function runTest(tabs, win, callback) {
   let startTab = win.gBrowser.selectedTab;
   let times = [];
   runTestHelper(startTab, tabs, 0, win, times, function() {
     callback(times);
   });
 }
 
 function runTestHelper(startTab, tabs, index, win, times, callback) {
+
   let tab = tabs[index];
 
-  if (typeof(Profiler) !== "undefined") {
-    Profiler.resume(tab.linkedBrowser.currentURI.spec);
-  }
-  let start = win.performance.now();
-  win.gBrowser.selectedTab = tab;
-  // This will fire when we're about to paint the tab switch
-  win.requestAnimationFrame(function() {
-    // This will fire on the next vsync tick after the tab has switched.
-    // If we have a sync transaction on the compositor, that time will
-    // be included here. It will not accuratly capture the composite time
-    // or the time of async transaction.
-    // XXX: This will need to be adjusted for e10s since we need to block
-    //      on the child/content having painted.
+  // Clean up garbage so GC/CC doesn't randomly occur during our test
+  // making the results noisy
+  win.QueryInterface(Ci.nsIInterfaceRequestor)
+     .getInterface(Ci.nsIDOMWindowUtils)
+     .garbageCollect();
+
+  forceContentGC(tab.linkedBrowser).then(function() {
+    if (typeof(Profiler) !== "undefined") {
+      Profiler.resume(tab.linkedBrowser.currentURI.spec);
+    }
+    let start = win.performance.now();
+    win.gBrowser.selectedTab = tab;
+    // This will fire when we're about to paint the tab switch
     win.requestAnimationFrame(function() {
-      times.push(win.performance.now() - start);
-      if (typeof(Profiler) !== "undefined") {
-        Profiler.pause(tab.linkedBrowser.currentURI.spec);
-      }
-
-      // Select about:blank which will let the browser reach a steady no
-      // painting state
-      win.gBrowser.selectedTab = aboutBlankTab;
+      // This will fire on the next vsync tick after the tab has switched.
+      // If we have a sync transaction on the compositor, that time will
+      // be included here. It will not accuratly capture the composite time
+      // or the time of async transaction.
+      // XXX: This will need to be adjusted for e10s since we need to block
+      //      on the child/content having painted.
+      win.requestAnimationFrame(function() {
+        times.push(win.performance.now() - start);
+        if (typeof(Profiler) !== "undefined") {
+          Profiler.pause(tab.linkedBrowser.currentURI.spec);
+        }
 
-      win.requestAnimationFrame(function() {
+        // Select about:blank which will let the browser reach a steady no
+        // painting state
+        win.gBrowser.selectedTab = aboutBlankTab;
+
         win.requestAnimationFrame(function() {
-          if (index == tabs.length - 1) {
-            callback();
-          } else {
-            runTestHelper(startTab, tabs, index + 1, win, times, function() {
+          win.requestAnimationFrame(function() {
+            if (index == tabs.length - 1) {
               callback();
-            });
-          }
+            } else {
+              runTestHelper(startTab, tabs, index + 1, win, times, function() {
+                callback();
+              });
+            }
+          });
         });
       });
     });
   });
 }
 
+function forceContentGC(browser) {
+  return new Promise((resolve) => {
+    let mm = browser.messageManager;
+    mm.addMessageListener("Talos:ForceGC:OK", function onTalosContentForceGC(msg) {
+      mm.removeMessageListener("Talos:ForceGC:OK", onTalosContentForceGC);
+      resolve();
+    });
+    mm.sendAsyncMessage("Talos:ForceGC");
+  });
+}
+
 function test(window) {
   let win = window.OpenBrowserWindow();
   let testURLs;
 
   try {
     let prefFile = Services.prefs.getCharPref("addon.test.tabswitch.urlfile");
     if (prefFile) {
       testURLs = handleFile(win, prefFile);