Bug 1550034 - avoid most failures of the browser_startup_mainthreadio.js and browser_startup_content_mainthreadio.js tests, r=mconley.
authorFlorian Quèze <florian@queze.net>
Thu, 16 May 2019 17:56:57 +0000
changeset 474223 742a8ae0110dc3d862a637e4348b587fe431938f
parent 474222 beb59fe4dd80fdf4fd6f65e916fd394350431a7d
child 474224 39446af6b4ad5d790bee4685c05952df3bd30c2f
push id36027
push usershindli@mozilla.com
push dateFri, 17 May 2019 16:24:38 +0000
treeherdermozilla-central@c94c54aff466 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmconley
bugs1550034
milestone68.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
Bug 1550034 - avoid most failures of the browser_startup_mainthreadio.js and browser_startup_content_mainthreadio.js tests, r=mconley. This patch contains the following changes: - upload a startup profile when there are unused mainthread I/O whitelist entries, - avoid 'unused whitelist entry' failures in devedition beta builds (where the IOInterposer is ifdef'ed out) while keeping coverage that ensures we are able to produce valid startup profiles, - completely disable on Windows Arm64 where the IO interposer is broken, - mark as ignoreIfUnused the whitelist entry that caused most intermittent failures. Differential Revision: https://phabricator.services.mozilla.com/D31268
browser/base/content/test/performance/browser_startup_content_mainthreadio.js
browser/base/content/test/performance/browser_startup_mainthreadio.js
browser/base/content/test/performance/io/browser.ini
--- a/browser/base/content/test/performance/browser_startup_content_mainthreadio.js
+++ b/browser/base/content/test/performance/browser_startup_content_mainthreadio.js
@@ -81,16 +81,17 @@ const processes = {
     { // bug 1357205
       path: "XREAppFeat:webcompat@mozilla.org.xpi",
       condition: !WIN,
       stat: 1,
     },
     { // bug 1357205
       path: "XREAppFeat:formautofill@mozilla.org.xpi",
       condition: !WIN,
+      ignoreIfUnused: true,
       stat: 1,
     },
   ],
   "Privileged Content": [
     {
       path: "GreD:omni.ja",
       condition: !WIN, // Visible on Windows with an open marker
       stat: 1,
@@ -339,16 +340,30 @@ add_task(async function() {
       }
       info(`(${marker.source}) ${marker.operation} - ${marker.filename}`);
       if (kDumpAllStacks) {
         info(getStackFromProfile(profile, marker.stackId).map(f => "  " + f)
                                                          .join("\n"));
       }
     }
 
+    if (!whitelist.length) {
+      continue;
+    }
+    // The I/O interposer is disabled if !RELEASE_OR_BETA, so we expect to have
+    // no I/O marker in that case, but it's good to keep the test running to check
+    // that we are still able to produce startup profiles.
+    is(markers.length > 0, !AppConstants.RELEASE_OR_BETA,
+       procName + " startup profiles should have IO markers in builds that are not RELEASE_OR_BETA");
+    if (!markers.length) {
+      // If a profile unexpectedly contains no I/O marker, avoid generating
+      // plenty of confusing "unused whitelist entry" failures.
+      continue;
+    }
+
     for (let entry of whitelist) {
       for (let op in entry) {
         if (["path", "condition", "ignoreIfUnused", "_used"].includes(op)) {
           continue;
         }
         let message = `${op} on ${entry.path} `;
         if (entry[op] == 0) {
           message += "as many times as expected";
@@ -356,28 +371,29 @@ add_task(async function() {
           message += `allowed ${entry[op]} more times`;
         } else {
           message += `${entry[op] * -1} more times than expected`;
         }
         ok(entry[op] >= 0, `${message} in ${procName} process`);
       }
       if (!("_used" in entry) && !entry.ignoreIfUnused) {
         ok(false, `unused whitelist entry ${procName}: ${entry.path}`);
+        shouldPass = false;
       }
     }
   }
 
   if (shouldPass) {
     ok(shouldPass, "No unexpected main thread I/O during startup");
   } else {
     const filename = "child-startup-mainthreadio-profile.json";
     let path = Cc["@mozilla.org/process/environment;1"]
                  .getService(Ci.nsIEnvironment)
                  .get("MOZ_UPLOAD_DIR");
     let encoder = new TextEncoder();
     let profilePath = OS.Path.join(path, filename);
     await OS.File.writeAtomic(profilePath,
                               encoder.encode(JSON.stringify(startupRecorder.data.profile)));
     ok(false,
-       "Found some unexpected main thread I/O during child process startup; " +
+       "Unexpected main thread I/O behavior during child process startup; " +
        "profile uploaded in " + filename);
   }
 });
--- a/browser/base/content/test/performance/browser_startup_mainthreadio.js
+++ b/browser/base/content/test/performance/browser_startup_mainthreadio.js
@@ -779,16 +779,17 @@ add_task(async function() {
   let profile = startupRecorder.data.profile.threads[0];
 
   let phases = {};
   {
     const nameCol = profile.markers.schema.name;
     const dataCol = profile.markers.schema.data;
 
     let markersForCurrentPhase = [];
+    let foundIOMarkers = false;
 
     for (let m of profile.markers.data) {
       let markerName = profile.stringTable[m[nameCol]];
       if (markerName.startsWith("startupRecorder:")) {
         phases[markerName.split("startupRecorder:")[1]] = markersForCurrentPhase;
         markersForCurrentPhase = [];
         continue;
       }
@@ -802,16 +803,28 @@ add_task(async function() {
       }
 
       let samples = markerData.stack.samples;
       let stack = samples.data[0][samples.schema.stack];
       markersForCurrentPhase.push({operation: markerData.operation,
                                    filename: markerData.filename,
                                    source: markerData.source,
                                    stackId: stack});
+      foundIOMarkers = true;
+    }
+
+    // The I/O interposer is disabled if !RELEASE_OR_BETA, so we expect to have
+    // no I/O marker in that case, but it's good to keep the test running to check
+    // that we are still able to produce startup profiles.
+    is(foundIOMarkers, !AppConstants.RELEASE_OR_BETA,
+       "The IO interposer should be enabled in builds that are not RELEASE_OR_BETA");
+    if (!foundIOMarkers) {
+      // If a profile unexpectedly contains no I/O marker, it's better to return
+      // early to avoid having plenty of confusing "unused whitelist entry" failures.
+      return;
     }
   }
 
   for (let phase in startupPhases) {
     startupPhases[phase] =
       startupPhases[phase].filter(entry => !("condition" in entry) || entry.condition);
     startupPhases[phase].forEach(entry => {
       entry.path = expandWhitelistPath(entry.path, entry.canonicalize);
@@ -894,28 +907,29 @@ add_task(async function() {
           message += `allowed ${entry[op]} more times`;
         } else {
           message += `${entry[op] * -1} more times than expected`;
         }
         ok(entry[op] >= 0, `${message} ${phase}`);
       }
       if (!("_used" in entry) && !entry.ignoreIfUnused) {
         ok(false, `unused whitelist entry ${phase}: ${entry.path}`);
+        shouldPass = false;
       }
     }
   }
 
   if (shouldPass) {
     ok(shouldPass, "No unexpected main thread I/O during startup");
   } else {
     const filename = "startup-mainthreadio-profile.json";
     let path = Cc["@mozilla.org/process/environment;1"]
                  .getService(Ci.nsIEnvironment)
                  .get("MOZ_UPLOAD_DIR");
     let encoder = new TextEncoder();
     let profilePath = OS.Path.join(path, filename);
     await OS.File.writeAtomic(profilePath,
                               encoder.encode(JSON.stringify(startupRecorder.data.profile)));
     ok(false,
-       "Found some unexpected main thread I/O during startup; profile uploaded in " +
+       "Unexpected main thread I/O behavior during startup; profile uploaded in " +
        filename);
   }
 });
--- a/browser/base/content/test/performance/io/browser.ini
+++ b/browser/base/content/test/performance/io/browser.ini
@@ -1,11 +1,13 @@
 [DEFAULT]
 # Currently disabled on debug due to debug-only failures, see bug 1549723.
-skip-if = debug || (os == "linux" && asan) # bug 1549729
+# Disabled on Linux asan due to bug 1549729.
+# Disabled on Windows Arm64 due to bug 1551493.
+skip-if = debug || (os == "linux" && asan) || (os == "win" && processor == "aarch64")
 # to avoid overhead when running the browser normally, startupRecorder.js will
 # do almost nothing unless browser.startup.record is true.
 # gfx.canvas.willReadFrequently.enable is just an optimization, but needs to be
 # set during early startup to have an impact as a canvas will be used by
 # startupRecorder.js
 prefs =
   # Skip migration work in BG__migrateUI for browser_startup.js since it isn't
   # representative of common startup, and triggers Places I/O.