Bug 1176824 - Intermittent browser_test_web_manifest.js. r=ckerschb, a=test-only
authorMarcos Caceres <marcos@marcosc.com>
Wed, 16 Mar 2016 16:07:00 +0100
changeset 323524 07ffad91cb33df1d72fd3d08ef6af24dd1554607
parent 323523 abf5a827bb806ebf91edef4e1562df5dcbab261b
child 323525 332ce77a41c79b38bcb280655f6323bb8f70ec5d
push id5913
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 16:57:49 +0000
treeherdermozilla-beta@dcaf0a6fa115 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersckerschb, test-only
bugs1176824
milestone47.0a2
Bug 1176824 - Intermittent browser_test_web_manifest.js. r=ckerschb, a=test-only
dom/security/test/csp/browser_test_web_manifest.js
--- a/dom/security/test/csp/browser_test_web_manifest.js
+++ b/dom/security/test/csp/browser_test_web_manifest.js
@@ -1,30 +1,28 @@
 /*
  * Description of the tests:
  *   These tests check for conformance to the CSP spec as they relate to Web Manifests.
  *
  *   In particular, the tests check that default-src and manifest-src directives are
  *   are respected by the ManifestObtainer.
  */
-/*globals Components*/
+/*globals Cu, is, ok*/
 'use strict';
 requestLongerTimeout(10); // e10s tests take time.
 const {
   ManifestObtainer
 } = Cu.import('resource://gre/modules/ManifestObtainer.jsm', {});
 const path = '/tests/dom/security/test/csp/';
 const testFile = `file=${path}file_web_manifest.html`;
 const remoteFile = `file=${path}file_web_manifest_remote.html`;
 const httpsManifest = `file=${path}file_web_manifest_https.html`;
-const mixedContent = `file=${path}file_web_manifest_mixed_content.html`;
 const server = 'file_testserver.sjs';
 const defaultURL = `http://example.org${path}${server}`;
-const remoteURL = `http://mochi.test:8888`;
-const secureURL = `https://example.com${path}${server}`;
+const secureURL = `https://example.com:443${path}${server}`;
 const tests = [
   // CSP block everything, so trying to load a manifest
   // will result in a policy violation.
   {
     expected: `default-src 'none' blocks fetching manifest.`,
     get tabURL() {
       let queryParts = [
         `csp=default-src 'none'`,
@@ -98,75 +96,44 @@ const tests = [
       is(topic, 'csp-on-violate-policy', this.expected);
     }
   },
   // CSP allows fetching from self, so manifest should load.
   {
     expected: `CSP manifest-src allows self`,
     get tabURL() {
       let queryParts = [
-        `manifest-src 'self'`,
+        `csp=manifest-src 'self'`,
         testFile
       ];
       return `${defaultURL}?${queryParts.join('&')}`;
     },
     run(manifest) {
       is(manifest.name, 'loaded', this.expected);
     }
   },
   // CSP allows fetching from example.org, so manifest should load.
   {
     expected: `CSP manifest-src allows http://example.org`,
     get tabURL() {
       let queryParts = [
-        `manifest-src http://example.org`,
+        `csp=manifest-src http://example.org`,
         testFile
       ];
       return `${defaultURL}?${queryParts.join('&')}`;
     },
     run(manifest) {
       is(manifest.name, 'loaded', this.expected);
     }
   },
-  // Check interaction with default-src and another origin,
-  // CSP allows fetching from example.org, so manifest should load.
-  {
-    expected: `CSP manifest-src overrides default-src of elsewhere.com`,
-    get tabURL() {
-      let queryParts = [
-        `default-src: http://elsewhere.com; manifest-src http://example.org`,
-        testFile
-      ];
-      return `${defaultURL}?${queryParts.join('&')}`;
-    },
-    run(manifest) {
-      is(manifest.name, 'loaded', this.expected);
-    }
-  },
-  // Check interaction with default-src none,
-  // CSP allows fetching manifest from example.org, so manifest should load.
-  {
-    expected: `CSP manifest-src overrides default-src`,
-    get tabURL() {
-      let queryParts = [
-        `default-src: 'none'; manifest-src 'self'`,
-        testFile
-      ];
-      return `${defaultURL}?${queryParts.join('&')}`;
-    },
-    run(manifest) {
-      is(manifest.name, 'loaded', this.expected);
-    }
-  },
-  // CSP allows fetching from mochi.test:8888, which has a
-  // CORS header set to '*'. So the manifest should load.
   {
     expected: `CSP manifest-src allows mochi.test:8888`,
     get tabURL() {
       let queryParts = [
+        `cors=*`,
         `csp=default-src *; manifest-src http://mochi.test:8888`,
         remoteFile
       ];
       return `${defaultURL}?${queryParts.join('&')}`;
     },
     run(manifest) {
       is(manifest.name, 'loaded', this.expected);
     }
@@ -197,68 +164,86 @@ const tests = [
         `csp=manifest-src 'self'`,
         remoteFile
       ];
       return `${defaultURL}?${queryParts.join('&')}`;
     },
     run(topic) {
       is(topic, 'csp-on-violate-policy', this.expected);
     }
-  }
+  },
+  // CSP allows fetching over TLS from example.org, so manifest should load.
+  {
+    expected: `CSP manifest-src allows example.com over TLS`,
+    get tabURL() {
+      let queryParts = [
+        'cors=*',
+        'csp=manifest-src https://example.com:443',
+        httpsManifest
+      ];
+      // secureURL loads https://example.com:443
+      // and gets manifest from https://example.org:443
+      return `${secureURL}?${queryParts.join('&')}`;
+    },
+    run(manifest) {
+      is(manifest.name, 'loaded', this.expected);
+    }
+  },
 ];
 //jscs:disable
 add_task(function* () {
   //jscs:enable
-  for (let test of tests) {
-    let tabOptions = {
-      gBrowser: gBrowser,
-      url: test.tabURL,
-    };
-    yield BrowserTestUtils.withNewTab(
-      tabOptions,
-      browser => testObtainingManifest(browser, test)
+  var testPromises = tests.map(
+      (test) => ([test, {gBrowser, url: test.tabURL, skipAnimation: true}])
+    ).map(
+      ([test, tabOptions]) => BrowserTestUtils.withNewTab(tabOptions, (browser) => testObtainingManifest(browser, test))
     );
-  }
+  yield Promise.all(testPromises);
+});
 
-  function* testObtainingManifest(aBrowser, aTest) {
-    const observer = (/blocks/.test(aTest.expected)) ? new NetworkObserver(aTest) : null;
-    let manifest;
-    // Expect an exception (from promise rejection) if there a content policy
-    // that is violated.
-    try {
-      manifest = yield ManifestObtainer.browserObtainManifest(aBrowser);
-    } catch (e) {
-      const msg = `Expected promise rejection obtaining.`;
-      ok(/blocked the loading of a resource/.test(e.message), msg);
-      if (observer) {
-        yield observer.finished;
-      }
+function* testObtainingManifest(aBrowser, aTest) {
+  const expectsBlocked = aTest.expected.includes('block');
+  const observer = (expectsBlocked) ? createNetObserver(aTest) : null;
+  // Expect an exception (from promise rejection) if there a content policy
+  // that is violated.
+  try {
+    const manifest = yield ManifestObtainer.browserObtainManifest(aBrowser);
+    aTest.run(manifest);
+  } catch (e) {
+    const wasBlocked = e.message.includes('blocked the loading of a resource');
+    ok(wasBlocked,`Expected promise rejection obtaining ${aTest.tabURL}: ${e.message}`);
+    if (observer) {
+      yield observer.untilFinished;
       return;
     }
-    // otherwise, we test manifest's content.
-    if (manifest) {
-      aTest.run(manifest);
-    }
+    throw e;
   }
-});
+}
 
-// Helper object used to observe policy violations. It waits 10 seconds
+// Helper object used to observe policy violations. It waits 1 seconds
 // for a response, and then times out causing its associated test to fail.
-function NetworkObserver(test) {
+function createNetObserver(test) {
   let finishedTest;
   let success = false;
-  this.finished = new Promise((resolver) => {
+  const finished = new Promise((resolver) => {
     finishedTest = resolver;
-  })
-  this.observe = function observer(subject, topic) {
-    SpecialPowers.removeObserver(this, 'csp-on-violate-policy');
-    test.run(topic);
-    finishedTest();
-    success = true;
-  };
-  SpecialPowers.addObserver(this, 'csp-on-violate-policy', false);
-  setTimeout(() => {
+  });
+  const timeoutId = setTimeout(() => {
     if (!success) {
       test.run('This test timed out.');
       finishedTest();
     }
   }, 1000);
+  var observer = {
+    get untilFinished(){
+      return finished;
+    },
+    observe(subject, topic) {
+      SpecialPowers.removeObserver(observer, 'csp-on-violate-policy');
+      test.run(topic);
+      finishedTest();
+      clearTimeout(timeoutId);
+      success = true;
+    },
+  };
+  SpecialPowers.addObserver(observer, 'csp-on-violate-policy', false);
+  return observer;
 }