Bug 1036751 - Test webapp runtime executable update. r=myk
authorMarco Castelluccio <mar.castelluccio@studenti.unina.it>
Sat, 12 Jul 2014 02:04:55 +0200
changeset 214510 9f869623bd08d47db2f246c52ab05964642fadc6
parent 214509 7ebd702e6442e43cefec06d319db29fe3cf1a101
child 214511 89076de4e3c3e10ec5f22cdc85a9f737b65888f8
push id3857
push userraliiev@mozilla.com
push dateTue, 02 Sep 2014 16:39:23 +0000
treeherdermozilla-beta@5638b907b505 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmyk
bugs1036751
milestone33.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 1036751 - Test webapp runtime executable update. r=myk
toolkit/webapps/moz.build
toolkit/webapps/tests/Makefile.in
toolkit/webapps/tests/TestWebappRT.cpp
toolkit/webapps/tests/chrome.ini
toolkit/webapps/tests/head.js
toolkit/webapps/tests/moz.build
toolkit/webapps/tests/test_webapp_runtime_executable_update.xul
--- a/toolkit/webapps/moz.build
+++ b/toolkit/webapps/moz.build
@@ -4,12 +4,12 @@
 # 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/.
 
 EXTRA_PP_JS_MODULES += [
     'NativeApp.jsm',
     'WebappOSUtils.jsm',
 ]
 
-MOCHITEST_CHROME_MANIFESTS += ['tests/chrome.ini']
+TEST_DIRS += ['tests']
 
 if CONFIG['MOZ_BUILD_APP'] == 'mobile/android':
     DEFINES['MOZ_FENNEC'] = True
new file mode 100644
--- /dev/null
+++ b/toolkit/webapps/tests/Makefile.in
@@ -0,0 +1,7 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# 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/.
+
+PROGRAMS_DEST = $(DEPTH)/_tests/testing/mochitest/chrome/$(relativesrcdir)
+
+include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/toolkit/webapps/tests/TestWebappRT.cpp
@@ -0,0 +1,7 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * 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/. */
+
+int main(int argc, char *argv[]) {
+  return 42;
+}
--- a/toolkit/webapps/tests/chrome.ini
+++ b/toolkit/webapps/tests/chrome.ini
@@ -24,8 +24,9 @@ skip-if = os == "win" && os_version == "
 [test_packaged_uninstall.xul]
 skip-if = os == "win" && os_version == "5.1" # see bug 981251
 [test_hosted_update_from_webapp_runtime.xul]
 skip-if = asan
 [test_packaged_update_from_webapp_runtime.xul]
 skip-if = asan
 [test_hosted_icons.xul]
 [test_packaged_icons.xul]
+[test_webapp_runtime_executable_update.xul]
--- a/toolkit/webapps/tests/head.js
+++ b/toolkit/webapps/tests/head.js
@@ -150,41 +150,43 @@ function TestAppInfo(aApp, aIsPackaged) 
 
   if (LINUX) {
     this.installPath = OS.Path.join(OS.Constants.Path.homeDir,
                                     "." + this.uniqueName);
     this.exePath = OS.Path.join(this.installPath, "webapprt-stub");
 
     this.iconFile = OS.Path.join(this.installPath, "icon.png");
 
+    this.webappINI = OS.Path.join(this.installPath, "webapp.ini");
+
     let xdg_data_home = Cc["@mozilla.org/process/environment;1"].
                         getService(Ci.nsIEnvironment).
                         get("XDG_DATA_HOME");
     if (!xdg_data_home) {
       xdg_data_home = OS.Path.join(OS.Constants.Path.homeDir, ".local", "share");
     }
 
     let desktopINI = OS.Path.join(xdg_data_home, "applications",
                                   "owa-" + this.uniqueName + ".desktop");
 
     this.installedFiles = [
       OS.Path.join(this.installPath, "webapp.json"),
-      OS.Path.join(this.installPath, "webapp.ini"),
+      this.webappINI,
       this.iconFile,
       this.exePath,
       desktopINI,
     ];
     this.tempUpdatedFiles = [
       OS.Path.join(this.installPath, "update", "icon.png"),
       OS.Path.join(this.installPath, "update", "webapp.json"),
       OS.Path.join(this.installPath, "update", "webapp.ini"),
     ];
     this.updatedFiles = [
       OS.Path.join(this.installPath, "webapp.json"),
-      OS.Path.join(this.installPath, "webapp.ini"),
+      this.webappINI,
       this.iconFile,
       desktopINI,
     ];
 
     if (this.isPackaged) {
       let appZipPath = OS.Path.join(this.installPath, "application.zip");
       this.installedFiles.push(appZipPath);
       this.tempUpdatedFiles.push(appZipPath);
@@ -210,24 +212,26 @@ function TestAppInfo(aApp, aIsPackaged) 
     });
   } else if (WIN) {
     this.installPath = OS.Path.join(OS.Constants.Path.winAppDataDir,
                                     this.uniqueName);
     this.exePath = OS.Path.join(this.installPath, aApp.name + ".exe");
 
     this.iconFile = OS.Path.join(this.installPath, "chrome", "icons", "default", "default.ico");
 
+    this.webappINI = OS.Path.join(this.installPath, "webapp.ini");
+
     let desktopShortcut = OS.Path.join(OS.Constants.Path.desktopDir,
                                        aApp.name + ".lnk");
     let startMenuShortcut = OS.Path.join(OS.Constants.Path.winStartMenuProgsDir,
                                          aApp.name + ".lnk");
 
     this.installedFiles = [
       OS.Path.join(this.installPath, "webapp.json"),
-      OS.Path.join(this.installPath, "webapp.ini"),
+      this.webappINI,
       OS.Path.join(this.installPath, "uninstall", "shortcuts_log.ini"),
       OS.Path.join(this.installPath, "uninstall", "uninstall.log"),
       OS.Path.join(this.installPath, "uninstall", "webapp-uninstaller.exe"),
       this.iconFile,
       this.exePath,
       desktopShortcut,
       startMenuShortcut,
     ];
@@ -236,17 +240,17 @@ function TestAppInfo(aApp, aIsPackaged) 
       OS.Path.join(this.installPath, "update", "webapp.json"),
       OS.Path.join(this.installPath, "update", "webapp.ini"),
       OS.Path.join(this.installPath, "update", "uninstall", "shortcuts_log.ini"),
       OS.Path.join(this.installPath, "update", "uninstall", "uninstall.log"),
       OS.Path.join(this.installPath, "update", "uninstall", "webapp-uninstaller.exe"),
     ];
     this.updatedFiles = [
       OS.Path.join(this.installPath, "webapp.json"),
-      OS.Path.join(this.installPath, "webapp.ini"),
+      this.webappINI,
       OS.Path.join(this.installPath, "uninstall", "shortcuts_log.ini"),
       OS.Path.join(this.installPath, "uninstall", "uninstall.log"),
       this.iconFile,
       desktopShortcut,
       startMenuShortcut,
     ];
 
     if (this.isPackaged) {
@@ -307,36 +311,38 @@ function TestAppInfo(aApp, aIsPackaged) 
   } else if (MAC) {
     this.installPath = OS.Path.join(OS.Constants.Path.homeDir,
                                     "Applications",
                                     aApp.name + ".app");
     this.exePath = OS.Path.join(this.installPath, "Contents", "MacOS", "webapprt");
 
     this.iconFile = OS.Path.join(this.installPath, "Contents", "Resources", "appicon.icns");
 
+    this.webappINI = OS.Path.join(this.installPath, "Contents", "MacOS", "webapp.ini");
+
     let appProfileDir = OS.Path.join(OS.Constants.Path.macUserLibDir,
                                      "Application Support",
                                      this.uniqueName);
 
     this.installedFiles = [
       OS.Path.join(this.installPath, "Contents", "Info.plist"),
-      OS.Path.join(this.installPath, "Contents", "MacOS", "webapp.ini"),
+      this.webappINI,
       OS.Path.join(appProfileDir, "webapp.json"),
       this.iconFile,
       this.exePath,
     ];
     this.tempUpdatedFiles = [
       OS.Path.join(this.installPath, "update", "Contents", "Info.plist"),
       OS.Path.join(this.installPath, "update", "Contents", "MacOS", "webapp.ini"),
       OS.Path.join(this.installPath, "update", "Contents", "Resources", "appicon.icns"),
       OS.Path.join(this.installPath, "update", "webapp.json")
     ];
     this.updatedFiles = [
       OS.Path.join(this.installPath, "Contents", "Info.plist"),
-      OS.Path.join(this.installPath, "Contents", "MacOS", "webapp.ini"),
+      this.webappINI,
       OS.Path.join(appProfileDir, "webapp.json"),
       this.iconFile,
     ];
 
     if (this.isPackaged) {
       let appZipPath = OS.Path.join(this.installPath, "Contents", "Resources", "application.zip");
       this.installedFiles.push(appZipPath);
       this.tempUpdatedFiles.push(appZipPath);
new file mode 100644
--- /dev/null
+++ b/toolkit/webapps/tests/moz.build
@@ -0,0 +1,9 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# 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_CHROME_MANIFESTS += ['chrome.ini']
+SOURCES += ['TestWebappRT.cpp' ]
+SIMPLE_PROGRAMS += ['TestWebappRT']
copy from toolkit/webapps/tests/test_hosted_launch.xul
copy to toolkit/webapps/tests/test_webapp_runtime_executable_update.xul
--- a/toolkit/webapps/tests/test_hosted_launch.xul
+++ b/toolkit/webapps/tests/test_webapp_runtime_executable_update.xul
@@ -1,30 +1,32 @@
 <?xml version="1.0"?>
 <?xml-stylesheet type="text/css" href="chrome://global/skin"?>
 <?xml-stylesheet type="text/css" href="/tests/SimpleTest/test.css"?>
 <!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=981249
+https://bugzilla.mozilla.org/show_bug.cgi?id=1036751
 -->
-<window title="Mozilla Bug 981249"
+<window title="Mozilla Bug 1036751"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/chrome-harness.js"></script>
   <script type="application/javascript" src="head.js"/>
 
   <!-- test results are displayed in the html:body -->
   <body xmlns="http://www.w3.org/1999/xhtml">
-  <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=981249"
-     target="_blank">Mozilla Bug 981249</a>
+  <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1036751"
+     target="_blank">Mozilla Bug 1036751</a>
   </body>
 
 <script type="application/javascript">
 <![CDATA[
 
-/** Test for Bug 981249 **/
+/** Test for Bug 1036751 **/
 
 "use strict";
 
 SimpleTest.waitForExplicitFinish();
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/NativeApp.jsm");
 Cu.import("resource://gre/modules/WebappOSUtils.jsm");
@@ -43,16 +45,30 @@ let app = {
   categories: [],
   installOrigin: "http://127.0.0.1:8888/",
   receipts: [],
   installTime: Date.now(),
 };
 
 let testAppInfo = new TestAppInfo(app);
 
+function runProcess() {
+    let deferred = Promise.defer();
+
+    testAppInfo.appProcess.runAsync([], 0, (aSubject, aTopic) => {
+      if (aTopic == "process-finished") {
+        deferred.resolve(aSubject.exitValue);
+      } else if (aTopic == "process-failed") {
+        deferred.reject(aSubject.exitValue);
+      }
+    });
+
+    return deferred.promise;
+}
+
 let runTest = Task.async(function*() {
   // Get to a clean state before the test
   yield testAppInfo.cleanup();
 
   SimpleTest.registerCleanupFunction(() => testAppInfo.cleanup());
 
   setDryRunPref();
 
@@ -71,29 +87,68 @@ let runTest = Task.async(function*() {
   // Install application
   info("Test installation");
   yield nativeApp.install(app, manifest);
   while (!WebappOSUtils.isLaunchable(app)) {
     yield wait(1000);
   }
   ok(true, "App launchable");
 
+  let fakeInstallDir;
+  if (MAC) {
+    fakeInstallDir = getFile(testAppInfo.installPath, "Contents", "MacOS");
+  } else {
+    fakeInstallDir = getFile(OS.Constants.Path.profileDir, "fakeInstallDir");
+    fakeInstallDir.createUnique(Ci.nsIFile.DIRECTORY_TYPE, 0o755);
+  }
+
+  let fakeAppIniFile = fakeInstallDir.clone();
+  fakeAppIniFile.append("application.ini");
+
+  let iniFile = getFile(testAppInfo.webappINI);
+
+  let iniWriter = Cc["@mozilla.org/xpcom/ini-processor-factory;1"].
+                  getService(Ci.nsIINIParserFactory).
+                  createINIParser(iniFile).
+                  QueryInterface(Ci.nsIINIParserWriter);
+  iniWriter.setString("WebappRT", "InstallDir", fakeInstallDir.path);
+  iniWriter.writeFile();
+
+  let appIniWriter = Cc["@mozilla.org/xpcom/ini-processor-factory;1"].
+                     getService(Ci.nsIINIParserFactory).
+                     createINIParser(fakeAppIniFile).
+                     QueryInterface(Ci.nsIINIParserWriter);
+  appIniWriter.setString("App", "BuildID", "aBuildID");
+  appIniWriter.writeFile();
+
+  let exeName = "webapprt-stub";
+  if (WIN) {
+    exeName += ".exe";
+  }
+
+  let stubExeName = "TestWebappRT";
+  if (WIN) {
+    stubExeName += ".exe";
+  }
+
   let exeFile = getFile(testAppInfo.exePath);
 
-  ok(exeFile.isExecutable(), "webapprt executable is executable");
+  let stubExeFile = getFile(getTestFilePath(stubExeName));
+  stubExeFile.copyTo(fakeInstallDir, exeName);
 
-  let appClosed = false;
+  if (MAC) {
+    stubExeFile.copyTo(getFile(testAppInfo.installPath, "Contents", "MacOS"), "firefox-bin");
+  }
 
-  testAppInfo.appProcess.init(exeFile)
-  testAppInfo.appProcess.runAsync([], 0, () => appClosed = true);
+  testAppInfo.appProcess.init(exeFile);
 
-  while (!(yield wasAppSJSAccessed()) && !appClosed) {
-    yield wait(1000);
+  if (WIN) {
+    is((yield runProcess()), 0, "Webapp runtime executable has been replaced");
   }
-  ok(!appClosed, "App was launched and is still running");
+  is((yield runProcess()), 42, "Webapp runtime executable has been replaced");
 
   SimpleTest.finish();
 });
 
 runTest().catch((e) => {
   ok(false, "Error during test: " + e);
   SimpleTest.finish();
 });