Bug 897221 - Add test for UserAgentUpdates.jsm; r=fabrice
☠☠ backed out by 9e90a0bf43fc ☠ ☠
authorJim Chen <nchen@mozilla.com>
Mon, 09 Sep 2013 15:47:47 -0400
changeset 159182 88fd66b4944c215a02e1974e0f59259d2ccc138a
parent 159181 a8711da4abee6109bd8d7aa1c8981b7bd0c2f51b
child 159183 a085fcd7822c65133982e3a4abd9bd675aa2d5c1
push id2961
push userlsblakk@mozilla.com
push dateMon, 28 Oct 2013 21:59:28 +0000
treeherdermozilla-beta@73ef4f13486f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfabrice
bugs897221
milestone26.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 897221 - Add test for UserAgentUpdates.jsm; r=fabrice
netwerk/test/mochitests/Makefile.in
netwerk/test/mochitests/test_user_agent_updates.html
netwerk/test/mochitests/user_agent_update.sjs
--- a/netwerk/test/mochitests/Makefile.in
+++ b/netwerk/test/mochitests/Makefile.in
@@ -4,9 +4,11 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 MOCHITEST_FILES = \
   partial_content.sjs \
   test_partially_cached_content.html \
   user_agent.sjs \
   test_user_agent_overrides.html \
+  user_agent_update.sjs \
+  test_user_agent_updates.html \
   $(NULL)
new file mode 100644
--- /dev/null
+++ b/netwerk/test/mochitests/test_user_agent_updates.html
@@ -0,0 +1,221 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=897221
+-->
+<head>
+  <title>Test for User Agent Updates</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=897221">Mozilla Bug 897221</a>
+<p id="display"></p>
+<div id="content" style="display: none"></div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+const PREF_UPDATES = "general.useragent.updates.";
+const PREF_UPDATES_ENABLED = PREF_UPDATES + "enabled";
+const PREF_UPDATES_URL = PREF_UPDATES + "url";
+const PREF_UPDATES_INTERVAL = PREF_UPDATES + "interval";
+const PREF_UPDATES_TIMEOUT = PREF_UPDATES + "timeout";
+
+const KEY_PREFDIR = "PrefD";
+const KEY_APPDIR = "XCurProcD";
+const FILE_UPDATES = "ua-update.json";
+
+const DEFAULT_UA = navigator.userAgent;
+const UA_OVERRIDE = "DummyUserAgent";
+const UA_ALT_OVERRIDE = "AltUserAgent";
+
+function getUA(host) {
+  var url = location.pathname;
+  url = host + url.slice(0, url.lastIndexOf('/')) + '/user_agent.sjs';
+
+  var xhr = new XMLHttpRequest();
+  xhr.open('GET', url, false); // sync request
+  xhr.send();
+  is(xhr.status, 200, 'request failed');
+  is(typeof xhr.response, 'string', 'invalid response');
+  return xhr.response;
+}
+
+const OVERRIDES = [
+  {
+    domain: 'example.org',
+    override: '%DATE%',
+    host: 'http://example.org'
+  },
+  {
+    domain: 'test1.example.org',
+    override: '%PRODUCT%',
+    expected: SpecialPowers.Services.appinfo.name,
+    host: 'http://test1.example.org'
+  },
+  {
+    domain: 'test2.example.org',
+    override: '%APP_ID%',
+    expected: SpecialPowers.Services.appinfo.ID,
+    host: 'http://test2.example.org'
+  },
+  {
+    domain: 'sub1.test1.example.org',
+    override: '%APP_VERSION%',
+    expected: SpecialPowers.Services.appinfo.version,
+    host: 'http://sub1.test1.example.org'
+  },
+  {
+    domain: 'sub2.test1.example.org',
+    override: '%BUILD_ID%',
+    expected: SpecialPowers.Services.appinfo.appBuildID,
+    host: 'http://sub2.test1.example.org'
+  },
+  {
+    domain: 'sub1.test2.example.org',
+    override: '%OS%',
+    expected: SpecialPowers.Services.appinfo.OS,
+    host: 'http://sub1.test2.example.org'
+  },
+];
+
+function getUpdateURL() {
+  var url = location.pathname;
+  url = location.origin + url.slice(0, url.lastIndexOf('/')) + '/user_agent_update.sjs?';
+
+  var overrides = {};
+  overrides[location.hostname] = UA_OVERRIDE;
+  OVERRIDES.forEach(function (val) {
+    overrides[val.domain] = val.override;
+  });
+  url = url + encodeURIComponent(JSON.stringify(overrides)).replace(/%25/g, '%');
+  return url;
+}
+
+function testDownload(callback) {
+  var startTime = Date.now();
+  var url = getUpdateURL();
+  isnot(navigator.userAgent, UA_OVERRIDE, 'UA already overridden');
+  info('Waiting for UA update: ' + url);
+  SpecialPowers.pushPrefEnv({
+    set: [
+      [PREF_UPDATES_ENABLED, true],
+      [PREF_UPDATES_URL, url],
+      [PREF_UPDATES_TIMEOUT, 10000],
+      [PREF_UPDATES_INTERVAL, 1] // 1 second interval
+    ]
+  }, function waitForUpdate() setTimeout(function () {
+    if (navigator.userAgent !== UA_OVERRIDE) {
+      waitForUpdate();
+      return;
+    }
+    info('Overrode navigator UA');
+    is(getUA(location.origin), UA_OVERRIDE, 'Header UA not overridden');
+
+    var updateTime = parseInt(getUA('http://example.org'));
+    ok(startTime <= updateTime, 'Update was before start time');
+    ok(updateTime <= Date.now(), 'Update was after present time');
+
+    OVERRIDES.forEach(function (val) {
+      val.expected && is(getUA(val.host), val.expected,
+        'Incorrect URL parameter: ' + val.override);
+    });
+    callback();
+  }, 100));
+}
+
+function testProfileLoad(callback) {
+  var file = FU.getFile(KEY_APPDIR, [FILE_UPDATES]).path;
+  var encoder = SpecialPowers.wrap(new TextEncoder());
+  var overrides = {};
+  overrides[location.hostname] = UA_ALT_OVERRIDE;
+  var bytes = encoder.encode(JSON.stringify(overrides));
+  OSF.writeAtomic(file, bytes, {tmpPath: file + ".tmp"}).then(
+    () => {
+      SpecialPowers.pushPrefEnv({
+        set: [[PREF_UPDATES_ENABLED, true]]
+      }, function () {
+        // initialize UserAgentOverrides.jsm and
+        // UserAgentUpdates.jsm and load saved file
+        UAO.init();
+        (function waitForLoad() {
+          if (navigator.userAgent !== UA_ALT_OVERRIDE) {
+            setTimeout(waitForLoad, 100);
+            return;
+          }
+          is(getUA(location.origin), UA_ALT_OVERRIDE, 'Did not apply saved override');
+          saveFilePreviousSize = file.fileSize;
+          callback();
+        })();
+      });
+    },
+    (reason) => {
+      throw reason
+    }
+  );
+}
+
+function testProfileSave(callback) {
+  info('Waiting for saving to profile');
+  var file = FU.getFile(KEY_PREFDIR, [FILE_UPDATES]).path;
+  (function waitForSave() {
+    OSF.exists(file).then(
+      (exists) => {
+        if (!exists) {
+          setTimeout(waitForSave, 100);
+          return;
+        }
+        return OSF.read(file).then(
+          (bytes) => {
+            info('Saved new overrides');
+            var decoder = SpecialPowers.wrap(new TextDecoder());
+            var overrides = JSON.parse(decoder.decode(bytes));
+            is(overrides[location.hostname], UA_OVERRIDE, 'Incorrect saved override');
+            OVERRIDES.forEach(function (val) {
+              val.expected && is(overrides[val.domain], val.expected,
+                'Incorrect saved override: ' + val.override);
+            });
+            callback();
+          }
+        );
+      }
+    ).then(null,
+      (reason) => {
+        throw reason
+      }
+    );
+  })();
+}
+
+SimpleTest.waitForExplicitFinish();
+
+SpecialPowers.Cu.import("resource://gre/modules/FileUtils.jsm", window);
+var FU = SpecialPowers.wrap(FileUtils);
+
+SpecialPowers.Cu.import("resource://gre/modules/osfile.jsm", window);
+var OSF = SpecialPowers.wrap(OS).File;
+
+// Enter update timer manager test mode
+(SpecialPowers.Cc["@mozilla.org/updates/timer-manager;1"].getService(
+  SpecialPowers.Ci.nsIObserver)).observe(null, "utm-test-init", "");
+
+SpecialPowers.Cu.import('resource://gre/modules/UserAgentOverrides.jsm', window);
+var UAO = SpecialPowers.wrap(UserAgentOverrides);
+UAO.uninit();
+
+var saveFilePreviousSize = 0;
+
+// testProfileLoad, testDownload, and testProfileSave must run in this order
+//  because testDownload depends on testProfileLoad to call UAO.init()
+//  and testProfileSave depends on testDownload to save overrides to the profile
+testProfileLoad(function()
+  testDownload(function()
+    testProfileSave(SimpleTest.finish)
+  )
+);
+
+</script>
+</pre>
+</body>
+</html>
+
new file mode 100644
--- /dev/null
+++ b/netwerk/test/mochitests/user_agent_update.sjs
@@ -0,0 +1,11 @@
+
+function handleRequest(request, response)
+{
+  // avoid confusing cache behaviors
+  response.setHeader("Cache-Control", "no-cache", false);
+  response.setHeader("Content-Type", "application/json", false);
+
+  // used by test_user_agent_updates test
+  response.write(decodeURIComponent(request.queryString));
+}
+