Bug 1550034 - avoid most failures of the browser_startup_mainthreadio.js and browser_startup_content_mainthreadio.js tests. r=mconley a=test-only CLOSED TREE
authorFlorian Quèze <florian@queze.net>
Thu, 16 May 2019 17:56:57 +0000
changeset 532865 e3bc6067298eaab8fff7a772a849c7bb9607809d
parent 532864 0cfbe941a03853c551c17c551d06925dcdb598f1
child 533294 847755a7c3256dec59ea6936435b0cd5a2b1861e
push id11275
push userncsoregi@mozilla.com
push dateSun, 19 May 2019 07:18:54 +0000
treeherdermozilla-beta@e3bc6067298e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmconley, test-only
bugs1550034
milestone68.0
Bug 1550034 - avoid most failures of the browser_startup_mainthreadio.js and browser_startup_content_mainthreadio.js tests. r=mconley a=test-only CLOSED TREE 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.