summaryrefslogtreecommitdiffstats
path: root/services/sync/tps/extensions
diff options
context:
space:
mode:
Diffstat (limited to 'services/sync/tps/extensions')
-rw-r--r--services/sync/tps/extensions/mozmill/resource/driver/controller.js19
-rw-r--r--services/sync/tps/extensions/mozmill/resource/driver/elementslib.js16
-rw-r--r--services/sync/tps/extensions/mozmill/resource/driver/mozelement.js10
-rw-r--r--services/sync/tps/extensions/mozmill/resource/driver/mozmill.js6
-rw-r--r--services/sync/tps/extensions/mozmill/resource/modules/assertions.js7
-rw-r--r--services/sync/tps/extensions/mozmill/resource/modules/frame.js12
-rw-r--r--services/sync/tps/extensions/mozmill/resource/modules/windows.js6
-rw-r--r--services/sync/tps/extensions/mozmill/resource/stdlib/EventUtils.js4
-rw-r--r--services/sync/tps/extensions/mozmill/resource/stdlib/os.js8
-rw-r--r--services/sync/tps/extensions/mozmill/resource/stdlib/securable-module.js24
-rw-r--r--services/sync/tps/extensions/mozmill/resource/stdlib/utils.js12
-rw-r--r--services/sync/tps/extensions/tps/install.rdf2
-rw-r--r--services/sync/tps/extensions/tps/resource/auth/fxaccounts.jsm27
-rw-r--r--services/sync/tps/extensions/tps/resource/auth/sync.jsm4
-rw-r--r--services/sync/tps/extensions/tps/resource/modules/addons.jsm18
-rw-r--r--services/sync/tps/extensions/tps/resource/modules/bookmarks.jsm26
-rw-r--r--services/sync/tps/extensions/tps/resource/modules/forms.jsm214
-rw-r--r--services/sync/tps/extensions/tps/resource/modules/history.jsm27
-rw-r--r--services/sync/tps/extensions/tps/resource/modules/passwords.jsm2
-rw-r--r--services/sync/tps/extensions/tps/resource/modules/prefs.jsm2
-rw-r--r--services/sync/tps/extensions/tps/resource/modules/tabs.jsm10
-rw-r--r--services/sync/tps/extensions/tps/resource/modules/windows.jsm2
-rw-r--r--services/sync/tps/extensions/tps/resource/tps.jsm502
23 files changed, 310 insertions, 650 deletions
diff --git a/services/sync/tps/extensions/mozmill/resource/driver/controller.js b/services/sync/tps/extensions/mozmill/resource/driver/controller.js
index 8d66a41ae..d5948598e 100644
--- a/services/sync/tps/extensions/mozmill/resource/driver/controller.js
+++ b/services/sync/tps/extensions/mozmill/resource/driver/controller.js
@@ -5,9 +5,9 @@
var EXPORTED_SYMBOLS = ["MozMillController", "globalEventRegistry",
"sleep", "windowMap"];
-var Cc = Components.classes;
-var Ci = Components.interfaces;
-var Cu = Components.utils;
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
var EventUtils = {}; Cu.import('resource://mozmill/stdlib/EventUtils.js', EventUtils);
@@ -44,11 +44,7 @@ waitForEvents.prototype = {
node.firedEvents = {};
this.registry = {};
- if (!events) {
- return;
- }
- for (var key in events) {
- var e = events[key];
+ for each (var e in events) {
var listener = function (event) {
this.firedEvents[event.type] = true;
}
@@ -870,7 +866,7 @@ MozMillController.prototype.mouseMove = function (doc, start, dest) {
/**
* Drag an element to the specified offset on another element, firing mouse and
- * drag events. Adapted from EventUtils.js synthesizeDrop()
+ * drag events. Adapted from ChromeUtils.js synthesizeDrop()
*
* @deprecated Use the MozMillElement object
*
@@ -977,10 +973,7 @@ function browserAdditions (controller) {
return windows.map.hasPageLoaded(utils.getWindowId(win));
}, "Timeout", timeout, aInterval);
}
- catch (ex) {
- if (!(ex instanceof errors.TimeoutError)) {
- throw ex;
- }
+ catch (ex if ex instanceof errors.TimeoutError) {
timed_out = true;
}
finally {
diff --git a/services/sync/tps/extensions/mozmill/resource/driver/elementslib.js b/services/sync/tps/extensions/mozmill/resource/driver/elementslib.js
index 4bf35a384..f08cf42f3 100644
--- a/services/sync/tps/extensions/mozmill/resource/driver/elementslib.js
+++ b/services/sync/tps/extensions/mozmill/resource/driver/elementslib.js
@@ -6,9 +6,9 @@ var EXPORTED_SYMBOLS = ["ID", "Link", "XPath", "Selector", "Name", "Anon", "Anon
"Lookup", "_byID", "_byName", "_byAttrib", "_byAnonAttrib",
];
-var Cc = Components.classes;
-var Ci = Components.interfaces;
-var Cu = Components.utils;
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
@@ -304,7 +304,7 @@ var _returnResult = function (results) {
var _forChildren = function (element, name, value) {
var results = [];
- var nodes = Array.from(element.childNodes).filter(e => e);
+ var nodes = [e for each (e in element.childNodes) if (e)]
for (var i in nodes) {
var n = nodes[i];
@@ -318,7 +318,7 @@ var _forChildren = function (element, name, value) {
var _forAnonChildren = function (_document, element, name, value) {
var results = [];
- var nodes = Array.from(_document.getAnoymousNodes(element)).filter(e => e);
+ var nodes = [e for each (e in _document.getAnoymousNodes(element)) if (e)];
for (var i in nodes ) {
var n = nodes[i];
@@ -381,7 +381,7 @@ var _byAnonAttrib = function (_document, parent, attributes) {
}
}
- var nodes = Array.from(_document.getAnonymousNodes(parent)).filter(n => n.getAttribute);
+ var nodes = [n for each (n in _document.getAnonymousNodes(parent)) if (n.getAttribute)];
function resultsForNodes (nodes) {
for (var i in nodes) {
@@ -404,7 +404,7 @@ var _byAnonAttrib = function (_document, parent, attributes) {
resultsForNodes(nodes);
if (results.length == 0) {
- resultsForNodes(Array.from(parent.childNodes).filter(n => n != undefined && n.getAttribute));
+ resultsForNodes([n for each (n in parent.childNodes) if (n != undefined && n.getAttribute)])
}
return _returnResult(results)
@@ -440,7 +440,7 @@ function Lookup(_document, expression) {
throw new Error('Lookup constructor did not recieve enough arguments.');
}
- var expSplit = smartSplit(expression).filter(e => e != '');
+ var expSplit = [e for each (e in smartSplit(expression) ) if (e != '')];
expSplit.unshift(_document);
var nCases = {'id':_byID, 'name':_byName, 'attrib':_byAttrib, 'index':_byIndex};
diff --git a/services/sync/tps/extensions/mozmill/resource/driver/mozelement.js b/services/sync/tps/extensions/mozmill/resource/driver/mozelement.js
index 850c86523..0af204794 100644
--- a/services/sync/tps/extensions/mozmill/resource/driver/mozelement.js
+++ b/services/sync/tps/extensions/mozmill/resource/driver/mozelement.js
@@ -9,9 +9,9 @@ var EXPORTED_SYMBOLS = ["Elem", "Selector", "ID", "Link", "XPath", "Name", "Look
const NAMESPACE_XUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
-var Cc = Components.classes;
-var Ci = Components.interfaces;
-var Cu = Components.utils;
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
var EventUtils = {}; Cu.import('resource://mozmill/stdlib/EventUtils.js', EventUtils);
@@ -131,7 +131,7 @@ MozMillElement.prototype.__defineGetter__("element", function () {
/**
* Drag an element to the specified offset on another element, firing mouse and
- * drag events. Adapted from EventUtils.js synthesizeDrop()
+ * drag events. Adapted from ChromeUtils.js synthesizeDrop()
*
* By default it will drag the source element over the destination's element
* center with a "move" dropEffect.
@@ -218,7 +218,7 @@ MozMillElement.prototype.dragToElement = function(aElement, aOffsetX, aOffsetY,
EventUtils.synthesizeMouse(destNode, destCoords.x, destCoords.y,
{ type: "mousemove" }, destWindow);
- var event = destWindow.document.createEvent("DragEvent");
+ var event = destWindow.document.createEvent("DragEvents");
event.initDragEvent("dragenter", true, true, destWindow, 0, 0, 0, 0, 0,
false, false, false, false, 0, null, dataTransfer);
event.initDragEvent("dragover", true, true, destWindow, 0, 0, 0, 0, 0,
diff --git a/services/sync/tps/extensions/mozmill/resource/driver/mozmill.js b/services/sync/tps/extensions/mozmill/resource/driver/mozmill.js
index 1e422591f..283c9bfb4 100644
--- a/services/sync/tps/extensions/mozmill/resource/driver/mozmill.js
+++ b/services/sync/tps/extensions/mozmill/resource/driver/mozmill.js
@@ -13,9 +13,9 @@ var EXPORTED_SYMBOLS = ["controller", "utils", "elementslib", "os",
"firePythonCallback", "getAddons"
];
-var Cc = Components.classes;
-var Ci = Components.interfaces;
-var Cu = Components.utils;
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
Cu.import("resource://gre/modules/AddonManager.jsm");
diff --git a/services/sync/tps/extensions/mozmill/resource/modules/assertions.js b/services/sync/tps/extensions/mozmill/resource/modules/assertions.js
index c76f95747..b49502057 100644
--- a/services/sync/tps/extensions/mozmill/resource/modules/assertions.js
+++ b/services/sync/tps/extensions/mozmill/resource/modules/assertions.js
@@ -4,7 +4,7 @@
var EXPORTED_SYMBOLS = ['Assert', 'Expect'];
-var Cu = Components.utils;
+const Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
@@ -658,10 +658,7 @@ Expect.prototype.waitFor = function Expect_waitFor(aCallback, aMessage, aTimeout
try {
Assert.prototype.waitFor.apply(this, arguments);
}
- catch (ex) {
- if (!(ex instanceof errors.AssertionError)) {
- throw ex;
- }
+ catch (ex if ex instanceof errors.AssertionError) {
message = ex.message;
condition = false;
}
diff --git a/services/sync/tps/extensions/mozmill/resource/modules/frame.js b/services/sync/tps/extensions/mozmill/resource/modules/frame.js
index dae8276b6..799e81d55 100644
--- a/services/sync/tps/extensions/mozmill/resource/modules/frame.js
+++ b/services/sync/tps/extensions/mozmill/resource/modules/frame.js
@@ -5,9 +5,9 @@
var EXPORTED_SYMBOLS = ['Collector','Runner','events', 'runTestFile', 'log',
'timers', 'persisted', 'shutdownApplication'];
-var Cc = Components.classes;
-var Ci = Components.interfaces;
-var Cu = Components.utils;
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
const TIMEOUT_SHUTDOWN_HTTPD = 15000;
@@ -256,7 +256,7 @@ events.pass = function (obj) {
events.currentTest.__passes__.push(obj);
}
- for (var timer of timers) {
+ for each (var timer in timers) {
timer.actions.push(
{"currentTest": events.currentModule.__file__ + "::" + events.currentTest.__name__,
"obj": obj,
@@ -286,7 +286,7 @@ events.fail = function (obj) {
events.currentTest.__fails__.push(obj);
}
- for (var time of timers) {
+ for each (var time in timers) {
timer.actions.push(
{"currentTest": events.currentModule.__file__ + "::" + events.currentTest.__name__,
"obj": obj,
@@ -325,7 +325,7 @@ events.fireEvent = function (name, obj) {
}
}
- for (var listener of this.globalListeners) {
+ for each(var listener in this.globalListeners) {
listener(name, obj);
}
}
diff --git a/services/sync/tps/extensions/mozmill/resource/modules/windows.js b/services/sync/tps/extensions/mozmill/resource/modules/windows.js
index 1c75a2d3d..fe9cfaa01 100644
--- a/services/sync/tps/extensions/mozmill/resource/modules/windows.js
+++ b/services/sync/tps/extensions/mozmill/resource/modules/windows.js
@@ -4,9 +4,9 @@
var EXPORTED_SYMBOLS = ["init", "map"];
-var Cc = Components.classes;
-var Ci = Components.interfaces;
-var Cu = Components.utils;
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
// imports
var utils = {}; Cu.import('resource://mozmill/stdlib/utils.js', utils);
diff --git a/services/sync/tps/extensions/mozmill/resource/stdlib/EventUtils.js b/services/sync/tps/extensions/mozmill/resource/stdlib/EventUtils.js
index 7f08469f0..a821ab2e0 100644
--- a/services/sync/tps/extensions/mozmill/resource/stdlib/EventUtils.js
+++ b/services/sync/tps/extensions/mozmill/resource/stdlib/EventUtils.js
@@ -8,8 +8,8 @@ var EXPORTED_SYMBOLS = ["disableNonTestMouseEvents","sendMouseEvent", "sendChar"
"synthesizeText",
"synthesizeComposition", "synthesizeQuerySelectedText"];
-var Ci = Components.interfaces;
-var Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cc = Components.classes;
var window = Cc["@mozilla.org/appshell/appShellService;1"]
.getService(Ci.nsIAppShellService).hiddenDOMWindow;
diff --git a/services/sync/tps/extensions/mozmill/resource/stdlib/os.js b/services/sync/tps/extensions/mozmill/resource/stdlib/os.js
index ce88bea8a..fcda30572 100644
--- a/services/sync/tps/extensions/mozmill/resource/stdlib/os.js
+++ b/services/sync/tps/extensions/mozmill/resource/stdlib/os.js
@@ -4,9 +4,9 @@
var EXPORTED_SYMBOLS = ['listDirectory', 'getFileForPath', 'abspath', 'getPlatform'];
-var Cc = Components.classes;
-var Ci = Components.interfaces;
-var Cu = Components.utils;
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
@@ -37,7 +37,7 @@ function abspath(rel, file) {
file = file.parent;
}
- for (var p of relSplit) {
+ for each(var p in relSplit) {
if (p == '..') {
file = file.parent;
} else if (p == '.') {
diff --git a/services/sync/tps/extensions/mozmill/resource/stdlib/securable-module.js b/services/sync/tps/extensions/mozmill/resource/stdlib/securable-module.js
index 2648afd27..794c3e2c2 100644
--- a/services/sync/tps/extensions/mozmill/resource/stdlib/securable-module.js
+++ b/services/sync/tps/extensions/mozmill/resource/stdlib/securable-module.js
@@ -40,8 +40,6 @@
const Cu = Components.utils;
const Cr = Components.results;
- Cu.import("resource://gre/modules/NetUtil.jsm");
-
var exports = {};
var ios = Cc['@mozilla.org/network/io-service;1']
@@ -170,7 +168,8 @@
if (rootPaths) {
if (rootPaths.constructor.name != "Array")
rootPaths = [rootPaths];
- var fses = rootPaths.map(path => new exports.LocalFileSystem(path));
+ var fses = [new exports.LocalFileSystem(path)
+ for each (path in rootPaths)];
options.fs = new exports.CompositeFileSystem(fses);
} else
options.fs = new exports.LocalFileSystem();
@@ -315,26 +314,17 @@
else
baseURI = ios.newURI(base, null, null);
var newURI = ios.newURI(path, null, baseURI);
- var channel = NetUtil.newChannel({
- uri: newURI,
- loadUsingSystemPrincipal: true
- });
+ var channel = ios.newChannelFromURI(newURI);
try {
- channel.open2().close();
- } catch (e) {
- if (e.result != Cr.NS_ERROR_FILE_NOT_FOUND) {
- throw e;
- }
+ channel.open().close();
+ } catch (e if e.result == Cr.NS_ERROR_FILE_NOT_FOUND) {
return null;
}
return newURI.spec;
},
getFile: function getFile(path) {
- var channel = NetUtil.newChannel({
- uri: path,
- loadUsingSystemPrincipal: true
- });
- var iStream = channel.open2();
+ var channel = ios.newChannel(path, null, null);
+ var iStream = channel.open();
var ciStream = Cc["@mozilla.org/intl/converter-input-stream;1"].
createInstance(Ci.nsIConverterInputStream);
var bufLen = 0x8000;
diff --git a/services/sync/tps/extensions/mozmill/resource/stdlib/utils.js b/services/sync/tps/extensions/mozmill/resource/stdlib/utils.js
index 73e13e11f..3dcca76e0 100644
--- a/services/sync/tps/extensions/mozmill/resource/stdlib/utils.js
+++ b/services/sync/tps/extensions/mozmill/resource/stdlib/utils.js
@@ -10,16 +10,16 @@ var EXPORTED_SYMBOLS = ["applicationName", "assert", "Copy", "getBrowserObject",
"unwrapNode", "waitFor"
];
-var Cc = Components.classes;
-var Ci = Components.interfaces;
-var Cu = Components.utils;
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
Cu.import("resource://gre/modules/NetUtil.jsm");
Cu.import("resource://gre/modules/Services.jsm");
const applicationIdMap = {
- '{ec8030f7-c20a-464f-9b0e-13a3a9e97384}': 'Firefox'
+ '{8de7fcbb-c55c-4fbe-bfc5-fc555c87dbc4}': 'Firefox'
}
const applicationName = applicationIdMap[Services.appinfo.ID] || Services.appinfo.name;
@@ -83,7 +83,7 @@ function getWindows(type) {
}
function getMethodInWindows(methodName) {
- for (var w of getWindows()) {
+ for each (var w in getWindows()) {
if (w[methodName] != undefined) {
return w[methodName];
}
@@ -93,7 +93,7 @@ function getMethodInWindows(methodName) {
}
function getWindowByTitle(title) {
- for (var w of getWindows()) {
+ for each (var w in getWindows()) {
if (w.document.title && w.document.title == title) {
return w;
}
diff --git a/services/sync/tps/extensions/tps/install.rdf b/services/sync/tps/extensions/tps/install.rdf
index 3dcdc5e44..cc9491b07 100644
--- a/services/sync/tps/extensions/tps/install.rdf
+++ b/services/sync/tps/extensions/tps/install.rdf
@@ -12,7 +12,7 @@
<em:targetApplication>
<!-- Firefox -->
<Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
+ <em:id>{8de7fcbb-c55c-4fbe-bfc5-fc555c87dbc4}</em:id>
<em:minVersion>24.0.*</em:minVersion>
<em:maxVersion>31.0.*</em:maxVersion>
</Description>
diff --git a/services/sync/tps/extensions/tps/resource/auth/fxaccounts.jsm b/services/sync/tps/extensions/tps/resource/auth/fxaccounts.jsm
index 86d0ed113..f5daa14be 100644
--- a/services/sync/tps/extensions/tps/resource/auth/fxaccounts.jsm
+++ b/services/sync/tps/extensions/tps/resource/auth/fxaccounts.jsm
@@ -12,7 +12,6 @@ const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
Cu.import("resource://gre/modules/FxAccounts.jsm");
Cu.import("resource://gre/modules/FxAccountsClient.jsm");
-Cu.import("resource://gre/modules/FxAccountsConfig.jsm");
Cu.import("resource://services-common/async.js");
Cu.import("resource://services-sync/main.js");
Cu.import("resource://tps/logger.jsm");
@@ -68,10 +67,7 @@ var Authentication = {
Logger.AssertTrue(account["username"], "Username has been found");
Logger.AssertTrue(account["password"], "Password has been found");
- Logger.logInfo("Login user: " + account["username"]);
-
- // Required here since we don't go through the real login page
- Async.promiseSpinningly(FxAccountsConfig.ensureConfigured());
+ Logger.logInfo("Login user: " + account["username"] + '\n');
let client = new FxAccountsClient();
client.signIn(account["username"], account["password"], true).then(credentials => {
@@ -96,26 +92,5 @@ var Authentication = {
} catch (error) {
throw new Error("signIn() failed with: " + error.message);
}
- },
-
- /**
- * Sign out of Firefox Accounts. It also clears out the device ID, if we find one.
- */
- signOut() {
- if (Authentication.isLoggedIn) {
- let user = Authentication.getSignedInUser();
- if (!user) {
- throw new Error("Failed to get signed in user!");
- }
- let fxc = new FxAccountsClient();
- let { sessionToken, deviceId } = user;
- if (deviceId) {
- Logger.logInfo("Destroying device " + deviceId);
- Async.promiseSpinningly(fxc.signOutAndDestroyDevice(sessionToken, deviceId, { service: "sync" }));
- } else {
- Logger.logError("No device found.");
- Async.promiseSpinningly(fxc.signOut(sessionToken, { service: "sync" }));
- }
- }
}
};
diff --git a/services/sync/tps/extensions/tps/resource/auth/sync.jsm b/services/sync/tps/extensions/tps/resource/auth/sync.jsm
index 35ffeb269..676b17a91 100644
--- a/services/sync/tps/extensions/tps/resource/auth/sync.jsm
+++ b/services/sync/tps/extensions/tps/resource/auth/sync.jsm
@@ -80,9 +80,5 @@ var Authentication = {
}
return true;
- },
-
- signOut() {
- Weave.Service.logout();
}
};
diff --git a/services/sync/tps/extensions/tps/resource/modules/addons.jsm b/services/sync/tps/extensions/tps/resource/modules/addons.jsm
index 1570b42b1..5c308b5c2 100644
--- a/services/sync/tps/extensions/tps/resource/modules/addons.jsm
+++ b/services/sync/tps/extensions/tps/resource/modules/addons.jsm
@@ -3,13 +3,13 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
-var EXPORTED_SYMBOLS = ["Addon", "STATE_ENABLED", "STATE_DISABLED"];
+let EXPORTED_SYMBOLS = ["Addon", "STATE_ENABLED", "STATE_DISABLED"];
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
Cu.import("resource://gre/modules/AddonManager.jsm");
Cu.import("resource://gre/modules/addons/AddonRepository.jsm");
-Cu.import("resource://gre/modules/NetUtil.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://services-common/async.js");
Cu.import("resource://services-sync/addonutils.js");
Cu.import("resource://services-sync/util.js");
@@ -20,11 +20,15 @@ const STATE_ENABLED = 1;
const STATE_DISABLED = 2;
function GetFileAsText(file) {
- let channel = NetUtil.newChannel({
- uri: file,
- loadUsingSystemPrincipal: true
- });
- let inputStream = channel.open2();
+ let channel = Services.io.newChannel2(file,
+ null,
+ null,
+ null, // aLoadingNode
+ Services.scriptSecurityManager.getSystemPrincipal(),
+ null, // aTriggeringPrincipal
+ Ci.nsILoadInfo.SEC_NORMAL,
+ Ci.nsIContentPolicy.TYPE_OTHER);
+ let inputStream = channel.open();
if (channel instanceof Ci.nsIHttpChannel &&
channel.responseStatus != 200) {
return "";
diff --git a/services/sync/tps/extensions/tps/resource/modules/bookmarks.jsm b/services/sync/tps/extensions/tps/resource/modules/bookmarks.jsm
index 857c0c1e8..6a288bbec 100644
--- a/services/sync/tps/extensions/tps/resource/modules/bookmarks.jsm
+++ b/services/sync/tps/extensions/tps/resource/modules/bookmarks.jsm
@@ -13,7 +13,6 @@ var EXPORTED_SYMBOLS = ["PlacesItem", "Bookmark", "Separator", "Livemark",
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
Cu.import("resource://gre/modules/PlacesBackups.jsm");
-Cu.import("resource://gre/modules/PlacesSyncUtils.jsm");
Cu.import("resource://gre/modules/PlacesUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://services-common/async.js");
@@ -110,11 +109,6 @@ PlacesItem.prototype = {
return string;
},
- GetSyncId() {
- let guid = Async.promiseSpinningly(PlacesUtils.promiseItemGuid(this.props.item_id));
- return PlacesSyncUtils.bookmarks.guidToSyncId(guid);
- },
-
/**
* GetPlacesNodeId
*
@@ -438,19 +432,8 @@ Bookmark.prototype = {
* @return nothing
*/
SetKeyword: function(keyword) {
- if (keyword != null) {
- // Mirror logic from PlacesSyncUtils's updateBookmarkMetadata
- let entry = Async.promiseSpinningly(PlacesUtils.keywords.fetch({
- url: this.props.uri,
- }));
- if (entry) {
- Async.promiseSpinningly(PlacesUtils.keywords.remove(entry));
- }
- Async.promiseSpinningly(PlacesUtils.keywords.insert({
- keyword: keyword,
- url: this.props.uri
- }));
- }
+ if (keyword != null)
+ PlacesUtils.bookmarks.setKeywordForBookmark(this.props.item_id, keyword);
},
/**
@@ -559,11 +542,11 @@ Bookmark.prototype = {
Update: function() {
Logger.AssertTrue(this.props.item_id != -1 && this.props.item_id != null,
"Invalid item_id during Remove");
+ this.SetKeyword(this.updateProps.keyword);
this.SetDescription(this.updateProps.description);
this.SetLoadInSidebar(this.updateProps.loadInSidebar);
this.SetTitle(this.updateProps.title);
this.SetUri(this.updateProps.uri);
- this.SetKeyword(this.updateProps.keyword);
this.SetTags(this.updateProps.tags);
this.SetLocation(this.updateProps.location);
this.SetPosition(this.updateProps.position);
@@ -595,8 +578,7 @@ Bookmark.prototype = {
if (!this.CheckDescription(this.props.description))
return -1;
if (this.props.keyword != null) {
- let { keyword } = Async.promiseSpinningly(
- PlacesSyncUtils.bookmarks.fetch(this.GetSyncId()));
+ let keyword = PlacesUtils.bookmarks.getKeywordForBookmark(this.props.item_id);
if (keyword != this.props.keyword) {
Logger.logPotentialError("Incorrect keyword - expected: " +
this.props.keyword + ", actual: " + keyword +
diff --git a/services/sync/tps/extensions/tps/resource/modules/forms.jsm b/services/sync/tps/extensions/tps/resource/modules/forms.jsm
index deb1a28a5..ece2e14f7 100644
--- a/services/sync/tps/extensions/tps/resource/modules/forms.jsm
+++ b/services/sync/tps/extensions/tps/resource/modules/forms.jsm
@@ -13,45 +13,74 @@ const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
Cu.import("resource://tps/logger.jsm");
-Cu.import("resource://gre/modules/FormHistory.jsm");
-Cu.import("resource://gre/modules/Log.jsm");
+let formService = Cc["@mozilla.org/satchel/form-history;1"]
+ .getService(Ci.nsIFormHistory2);
/**
* FormDB
*
- * Helper object containing methods to interact with the FormHistory module.
+ * Helper object containing methods to interact with the moz_formhistory
+ * SQLite table.
*/
-var FormDB = {
- _update(data) {
- return new Promise((resolve, reject) => {
- let handlers = {
- handleError(error) {
- Logger.logError("Error occurred updating form history: " + Log.exceptionStr(error));
- reject(error);
- },
- handleCompletion(reason) {
- resolve();
- }
- }
- FormHistory.update(data, handlers);
- });
+let FormDB = {
+ /**
+ * makeGUID
+ *
+ * Generates a brand-new globally unique identifier (GUID). Borrowed
+ * from Weave's utils.js.
+ *
+ * @return the new guid
+ */
+ makeGUID: function makeGUID() {
+ // 70 characters that are not-escaped URL-friendly
+ const code =
+ "!()*-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~";
+
+ let guid = "";
+ let num = 0;
+ let val;
+
+ // Generate ten 70-value characters for a 70^10 (~61.29-bit) GUID
+ for (let i = 0; i < 10; i++) {
+ // Refresh the number source after using it a few times
+ if (i == 0 || i == 5)
+ num = Math.random();
+
+ // Figure out which code to use for the next GUID character
+ num *= 70;
+ val = Math.floor(num);
+ guid += code[val];
+ num -= val;
+ }
+
+ return guid;
},
/**
* insertValue
*
- * Adds the specified value for the specified fieldname into form history.
+ * Inserts the specified value for the specified fieldname into the
+ * moz_formhistory table.
*
* @param fieldname The form fieldname to insert
* @param value The form value to insert
* @param us The time, in microseconds, to use for the lastUsed
* and firstUsed columns
- * @return Promise<undefined>
+ * @return nothing
*/
- insertValue(fieldname, value, us) {
- let data = { op: "add", fieldname, value, timesUsed: 1,
- firstUsed: us, lastUsed: us }
- return this._update(data);
+ insertValue: function (fieldname, value, us) {
+ let query = this.createStatement(
+ "INSERT INTO moz_formhistory " +
+ "(fieldname, value, timesUsed, firstUsed, lastUsed, guid) VALUES " +
+ "(:fieldname, :value, :timesUsed, :firstUsed, :lastUsed, :guid)");
+ query.params.fieldname = fieldname;
+ query.params.value = value;
+ query.params.timesUsed = 1;
+ query.params.firstUsed = us;
+ query.params.lastUsed = us;
+ query.params.guid = this.makeGUID();
+ query.execute();
+ query.reset();
},
/**
@@ -61,10 +90,15 @@ var FormDB = {
*
* @param id The id of the row to update
* @param newvalue The new value to set
- * @return Promise<undefined>
+ * @return nothing
*/
- updateValue(id, newvalue) {
- return this._update({ op: "update", guid: id, value: newvalue });
+ updateValue: function (id, newvalue) {
+ let query = this.createStatement(
+ "UPDATE moz_formhistory SET value = :value WHERE id = :id");
+ query.params.id = id;
+ query.params.value = newvalue;
+ query.execute();
+ query.reset();
},
/**
@@ -75,44 +109,52 @@ var FormDB = {
*
* @param fieldname The fieldname of the row to query
* @param value The value of the row to query
- * @return Promise<null if no row is found with the specified fieldname and value,
- * or an object containing the row's guid, lastUsed, and firstUsed
- * values>
+ * @return null if no row is found with the specified fieldname and value,
+ * or an object containing the row's id, lastUsed, and firstUsed
+ * values
*/
- getDataForValue(fieldname, value) {
- return new Promise((resolve, reject) => {
- let result = null;
- let handlers = {
- handleResult(oneResult) {
- if (result != null) {
- reject("more than 1 result for this query");
- return;
- }
- result = oneResult;
- },
- handleError(error) {
- Logger.logError("Error occurred updating form history: " + Log.exceptionStr(error));
- reject(error);
- },
- handleCompletion(reason) {
- resolve(result);
- }
- }
- FormHistory.search(["guid", "lastUsed", "firstUsed"], { fieldname }, handlers);
- });
+ getDataForValue: function (fieldname, value) {
+ let query = this.createStatement(
+ "SELECT id, lastUsed, firstUsed FROM moz_formhistory WHERE " +
+ "fieldname = :fieldname AND value = :value");
+ query.params.fieldname = fieldname;
+ query.params.value = value;
+ if (!query.executeStep())
+ return null;
+
+ return {
+ id: query.row.id,
+ lastUsed: query.row.lastUsed,
+ firstUsed: query.row.firstUsed
+ };
},
/**
- * remove
+ * createStatement
*
- * Removes the specified GUID from the database.
+ * Creates a statement from a SQL string. This function is borrowed
+ * from Weave's forms.js.
*
- * @param guid The guid of the item to delete
- * @return Promise<>
+ * @param query The SQL query string
+ * @return the mozIStorageStatement created from the specified SQL
*/
- remove(guid) {
- return this._update({ op: "remove", guid });
- },
+ createStatement: function createStatement(query) {
+ try {
+ // Just return the statement right away if it's okay
+ return formService.DBConnection.createStatement(query);
+ }
+ catch(ex) {
+ // Assume guid column must not exist yet, so add it with an index
+ formService.DBConnection.executeSimpleSQL(
+ "ALTER TABLE moz_formhistory ADD COLUMN guid TEXT");
+ formService.DBConnection.executeSimpleSQL(
+ "CREATE INDEX IF NOT EXISTS moz_formhistory_guid_index " +
+ "ON moz_formhistory (guid)");
+ }
+
+ // Try creating the query now that the column exists
+ return formService.DBConnection.createStatement(query);
+ }
};
/**
@@ -162,18 +204,18 @@ FormData.prototype = {
Logger.AssertTrue(this.fieldname != null && this.value != null,
"Must specify both fieldname and value");
- return FormDB.getDataForValue(this.fieldname, this.value).then(formdata => {
- if (!formdata) {
- // this item doesn't exist yet in the db, so we need to insert it
- return FormDB.insertValue(this.fieldname, this.value,
- this.hours_to_us(this.date));
- } else {
- /* Right now, we ignore this case. If bug 552531 is ever fixed,
- we might need to add code here to update the firstUsed or
- lastUsed fields, as appropriate.
- */
- }
- });
+ let formdata = FormDB.getDataForValue(this.fieldname, this.value);
+ if (!formdata) {
+ // this item doesn't exist yet in the db, so we need to insert it
+ FormDB.insertValue(this.fieldname, this.value,
+ this.hours_to_us(this.date));
+ }
+ else {
+ /* Right now, we ignore this case. If bug 552531 is ever fixed,
+ we might need to add code here to update the firstUsed or
+ lastUsed fields, as appropriate.
+ */
+ }
},
/**
@@ -185,22 +227,21 @@ FormData.prototype = {
* @return true if this entry exists in the database, otherwise false
*/
Find: function() {
- return FormDB.getDataForValue(this.fieldname, this.value).then(formdata => {
- let status = formdata != null;
- if (status) {
- /*
- //form history dates currently not synced! bug 552531
- let us = this.hours_to_us(this.date);
- status = Logger.AssertTrue(
- us >= formdata.firstUsed && us <= formdata.lastUsed,
- "No match for with that date value");
-
- if (status)
- */
- this.id = formdata.guid;
- }
- return status;
- });
+ let formdata = FormDB.getDataForValue(this.fieldname, this.value);
+ let status = formdata != null;
+ if (status) {
+ /*
+ //form history dates currently not synced! bug 552531
+ let us = this.hours_to_us(this.date);
+ status = Logger.AssertTrue(
+ us >= formdata.firstUsed && us <= formdata.lastUsed,
+ "No match for with that date value");
+
+ if (status)
+ */
+ this.id = formdata.id;
+ }
+ return status;
},
/**
@@ -214,6 +255,7 @@ FormData.prototype = {
Remove: function() {
/* Right now Weave doesn't handle this correctly, see bug 568363.
*/
- return FormDB.remove(this.id);
+ formService.removeEntry(this.fieldname, this.value);
+ return true;
},
};
diff --git a/services/sync/tps/extensions/tps/resource/modules/history.jsm b/services/sync/tps/extensions/tps/resource/modules/history.jsm
index 78deb42ab..ab0514bcc 100644
--- a/services/sync/tps/extensions/tps/resource/modules/history.jsm
+++ b/services/sync/tps/extensions/tps/resource/modules/history.jsm
@@ -33,7 +33,7 @@ var DumpHistory = function TPS_History__DumpHistory() {
let node = root.getChild(i);
let uri = node.uri;
let curvisits = HistoryEntry._getVisits(uri);
- for (var visit of curvisits) {
+ for each (var visit in curvisits) {
Logger.logInfo("URI: " + uri + ", type=" + visit.type + ", date=" + visit.date, true);
}
}
@@ -70,8 +70,8 @@ var HistoryEntry = {
"WHERE place_id = (" +
"SELECT id " +
"FROM moz_places " +
- "WHERE url_hash = hash(:url) AND url = :url) " +
- "ORDER BY date DESC LIMIT 20");
+ "WHERE url = :url) " +
+ "ORDER BY date DESC LIMIT 10");
this.__defineGetter__("_visitStm", () => stm);
return stm;
},
@@ -110,7 +110,7 @@ var HistoryEntry = {
uri: uri,
visits: []
};
- for (let visit of item.visits) {
+ for each (visit in item.visits) {
place.visits.push({
visitDate: usSinceEpoch + (visit.date * 60 * 60 * 1000 * 1000),
transitionType: visit.type
@@ -150,8 +150,8 @@ var HistoryEntry = {
"History entry in test file must have both 'visits' " +
"and 'uri' properties");
let curvisits = this._getVisits(item.uri);
- for (let visit of curvisits) {
- for (let itemvisit of item.visits) {
+ for each (visit in curvisits) {
+ for each (itemvisit in item.visits) {
let expectedDate = itemvisit.date * 60 * 60 * 1000 * 1000
+ usSinceEpoch;
if (visit.type == itemvisit.type && visit.date == expectedDate) {
@@ -161,7 +161,7 @@ var HistoryEntry = {
}
let all_items_found = true;
- for (let itemvisit of item.visits) {
+ for each (itemvisit in item.visits) {
all_items_found = all_items_found && "found" in itemvisit;
Logger.logInfo("History entry for " + item.uri + ", type:" +
itemvisit.type + ", date:" + itemvisit.date +
@@ -189,16 +189,9 @@ var HistoryEntry = {
PlacesUtils.history.removePagesFromHost(item.host, false);
}
else if ("begin" in item && "end" in item) {
- let cb = Async.makeSpinningCallback();
- let msSinceEpoch = parseInt(usSinceEpoch / 1000);
- let filter = {
- beginDate: new Date(msSinceEpoch + (item.begin * 60 * 60 * 1000)),
- endDate: new Date(msSinceEpoch + (item.end * 60 * 60 * 1000))
- };
- PlacesUtils.history.removeVisitsByFilter(filter)
- .catch(ex => Logger.AssertTrue(false, "An error occurred while deleting history: " + ex))
- .then(result => {cb(null, result)}, err => {cb(err)});
- Async.waitForSyncCallback(cb);
+ PlacesUtils.history.removeVisitsByTimeframe(
+ usSinceEpoch + (item.begin * 60 * 60 * 1000 * 1000),
+ usSinceEpoch + (item.end * 60 * 60 * 1000 * 1000));
}
else {
Logger.AssertTrue(false, "invalid entry in delete history");
diff --git a/services/sync/tps/extensions/tps/resource/modules/passwords.jsm b/services/sync/tps/extensions/tps/resource/modules/passwords.jsm
index a84800bab..f7221224a 100644
--- a/services/sync/tps/extensions/tps/resource/modules/passwords.jsm
+++ b/services/sync/tps/extensions/tps/resource/modules/passwords.jsm
@@ -14,7 +14,7 @@ const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://tps/logger.jsm");
-var nsLoginInfo = new Components.Constructor(
+let nsLoginInfo = new Components.Constructor(
"@mozilla.org/login-manager/loginInfo;1",
Ci.nsILoginInfo,
"init");
diff --git a/services/sync/tps/extensions/tps/resource/modules/prefs.jsm b/services/sync/tps/extensions/tps/resource/modules/prefs.jsm
index 286c5a6b5..18a6e32ee 100644
--- a/services/sync/tps/extensions/tps/resource/modules/prefs.jsm
+++ b/services/sync/tps/extensions/tps/resource/modules/prefs.jsm
@@ -13,7 +13,7 @@ const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
const WEAVE_PREF_PREFIX = "services.sync.prefs.sync.";
-var prefs = Cc["@mozilla.org/preferences-service;1"]
+let prefs = Cc["@mozilla.org/preferences-service;1"]
.getService(Ci.nsIPrefBranch);
Cu.import("resource://tps/logger.jsm");
diff --git a/services/sync/tps/extensions/tps/resource/modules/tabs.jsm b/services/sync/tps/extensions/tps/resource/modules/tabs.jsm
index af983573f..a2ce1afc1 100644
--- a/services/sync/tps/extensions/tps/resource/modules/tabs.jsm
+++ b/services/sync/tps/extensions/tps/resource/modules/tabs.jsm
@@ -13,7 +13,7 @@ const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
Cu.import("resource://services-sync/main.js");
-var BrowserTabs = {
+let BrowserTabs = {
/**
* Add
*
@@ -49,12 +49,8 @@ var BrowserTabs = {
Find: function(uri, title, profile) {
// Find the uri in Weave's list of tabs for the given profile.
let engine = Weave.Service.engineManager.get("tabs");
- for (let [guid, client] of Object.entries(engine.getAllClients())) {
- if (!client.tabs) {
- continue;
- }
- for (let key in client.tabs) {
- let tab = client.tabs[key];
+ for (let [guid, client] in Iterator(engine.getAllClients())) {
+ for each (tab in client.tabs) {
let weaveTabUrl = tab.urlHistory[0];
if (uri == weaveTabUrl && profile == client.clientName)
if (title == undefined || title == tab.title)
diff --git a/services/sync/tps/extensions/tps/resource/modules/windows.jsm b/services/sync/tps/extensions/tps/resource/modules/windows.jsm
index d892aea56..62cc80d2c 100644
--- a/services/sync/tps/extensions/tps/resource/modules/windows.jsm
+++ b/services/sync/tps/extensions/tps/resource/modules/windows.jsm
@@ -14,7 +14,7 @@ const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
Cu.import("resource://services-sync/main.js");
-var BrowserWindows = {
+let BrowserWindows = {
/**
* Add
*
diff --git a/services/sync/tps/extensions/tps/resource/tps.jsm b/services/sync/tps/extensions/tps/resource/tps.jsm
index f4cc0214a..d3a8b0b7d 100644
--- a/services/sync/tps/extensions/tps/resource/tps.jsm
+++ b/services/sync/tps/extensions/tps/resource/tps.jsm
@@ -7,28 +7,20 @@
* listed symbols will exposed on import, and only when and where imported.
*/
-var EXPORTED_SYMBOLS = ["ACTIONS", "TPS"];
+let EXPORTED_SYMBOLS = ["ACTIONS", "TPS"];
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
-var module = this;
+let module = this;
// Global modules
-Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/AppConstants.jsm");
-Cu.import("resource://gre/modules/PlacesUtils.jsm");
-Cu.import("resource://gre/modules/FileUtils.jsm");
Cu.import("resource://services-common/async.js");
Cu.import("resource://services-sync/constants.js");
Cu.import("resource://services-sync/main.js");
Cu.import("resource://services-sync/util.js");
-Cu.import("resource://services-sync/telemetry.js");
-Cu.import("resource://services-sync/bookmark_validator.js");
-Cu.import("resource://services-sync/engines/passwords.js");
-Cu.import("resource://services-sync/engines/forms.js");
-Cu.import("resource://services-sync/engines/addons.js");
+
// TPS modules
Cu.import("resource://tps/logger.jsm");
@@ -50,11 +42,6 @@ var prefs = Cc["@mozilla.org/preferences-service;1"]
var mozmillInit = {};
Cu.import('resource://mozmill/driver/mozmill.js', mozmillInit);
-XPCOMUtils.defineLazyGetter(this, "fileProtocolHandler", () => {
- let fileHandler = Services.io.getProtocolHandler("file");
- return fileHandler.QueryInterface(Ci.nsIFileProtocolHandler);
-});
-
// Options for wiping data during a sync
const SYNC_RESET_CLIENT = "resetClient";
const SYNC_WIPE_CLIENT = "wipeClient";
@@ -90,7 +77,7 @@ const ACTIONS = [
const OBSERVER_TOPICS = ["fxaccounts:onlogin",
"fxaccounts:onlogout",
"private-browsing",
- "profile-before-change",
+ "quit-application-requested",
"sessionstore-windows-restored",
"weave:engine:start-tracking",
"weave:engine:stop-tracking",
@@ -102,19 +89,18 @@ const OBSERVER_TOPICS = ["fxaccounts:onlogin",
"weave:service:sync:start"
];
-var TPS = {
+let TPS = {
_currentAction: -1,
_currentPhase: -1,
_enabledEngines: null,
_errors: 0,
+ _finalPhase: false,
_isTracking: false,
_operations_pending: 0,
_phaseFinished: false,
_phaselist: {},
_setupComplete: false,
_syncActive: false,
- _syncCount: 0,
- _syncsReportedViaTelemetry: 0,
_syncErrors: 0,
_syncWipeAction: null,
_tabsAdded: 0,
@@ -122,11 +108,6 @@ var TPS = {
_test: null,
_triggeredSync: false,
_usSinceEpoch: 0,
- _requestedQuit: false,
- shouldValidateAddons: false,
- shouldValidateBookmarks: false,
- shouldValidatePasswords: false,
- shouldValidateForms: false,
_init: function TPS__init() {
// Check if Firefox Accounts is enabled
@@ -141,8 +122,6 @@ var TPS = {
Services.obs.addObserver(this, aTopic, true);
}, this);
- // Configure some logging prefs for Sync itself.
- Weave.Svc.Prefs.set("log.appender.dump", "Debug");
// Import the appropriate authentication module
if (this.fxaccounts_enabled) {
Cu.import("resource://tps/auth/fxaccounts.jsm", module);
@@ -152,16 +131,9 @@ var TPS = {
}
},
- DumpError(msg, exc = null) {
+ DumpError: function TPS__DumpError(msg) {
this._errors++;
- let errInfo;
- if (exc) {
- errInfo = Log.exceptionStr(exc); // includes details and stack-trace.
- } else {
- // always write a stack even if no error passed.
- errInfo = Log.stackTrace(new Error());
- }
- Logger.logError(`[phase ${this._currentPhase}] ${msg} - ${errInfo}`);
+ Logger.logError("[phase" + this._currentPhase + "] " + msg);
this.quit();
},
@@ -177,7 +149,14 @@ var TPS = {
Logger.logInfo("private browsing " + data);
break;
- case "profile-before-change":
+ case "quit-application-requested":
+ // Ensure that we eventually wipe the data on the server
+ if (this._errors || !this._phaseFinished || this._finalPhase) {
+ try {
+ this.WipeServer();
+ } catch (ex) {}
+ }
+
OBSERVER_TOPICS.forEach(function(topic) {
Services.obs.removeObserver(this, topic);
}, this);
@@ -253,7 +232,7 @@ var TPS = {
}
}
catch (e) {
- this.DumpError("Observer failed", e);
+ this.DumpError("Exception caught: " + Utils.exceptionStr(e));
return;
}
},
@@ -286,7 +265,6 @@ var TPS = {
},
quit: function TPS__quit() {
- this._requestedQuit = true;
this.goQuitApplication();
},
@@ -307,7 +285,7 @@ var TPS = {
HandleTabs: function (tabs, action) {
this._tabsAdded = tabs.length;
this._tabsFinished = 0;
- for (let tab of tabs) {
+ for each (let tab in tabs) {
Logger.logInfo("executing action " + action.toUpperCase() +
" on tab " + JSON.stringify(tab));
switch(action) {
@@ -352,7 +330,7 @@ var TPS = {
},
HandlePrefs: function (prefs, action) {
- for (let pref of prefs) {
+ for each (pref in prefs) {
Logger.logInfo("executing action " + action.toUpperCase() +
" on pref " + JSON.stringify(pref));
let preference = new Preference(pref);
@@ -371,25 +349,23 @@ var TPS = {
},
HandleForms: function (data, action) {
- this.shouldValidateForms = true;
- for (let datum of data) {
+ for each (datum in data) {
Logger.logInfo("executing action " + action.toUpperCase() +
" on form entry " + JSON.stringify(datum));
let formdata = new FormData(datum, this._usSinceEpoch);
switch(action) {
case ACTION_ADD:
- Async.promiseSpinningly(formdata.Create());
+ formdata.Create();
break;
case ACTION_DELETE:
- Async.promiseSpinningly(formdata.Remove());
+ formdata.Remove();
break;
case ACTION_VERIFY:
- Logger.AssertTrue(Async.promiseSpinningly(formdata.Find()),
- "form data not found");
+ Logger.AssertTrue(formdata.Find(), "form data not found");
break;
case ACTION_VERIFY_NOT:
- Logger.AssertTrue(!Async.promiseSpinningly(formdata.Find()),
- "form data found, but it shouldn't be present");
+ Logger.AssertTrue(!formdata.Find(),
+ "form data found, but it shouldn't be present");
break;
default:
Logger.AssertTrue(false, "invalid action: " + action);
@@ -401,7 +377,7 @@ var TPS = {
HandleHistory: function (entries, action) {
try {
- for (let entry of entries) {
+ for each (entry in entries) {
Logger.logInfo("executing action " + action.toUpperCase() +
" on history entry " + JSON.stringify(entry));
switch(action) {
@@ -433,32 +409,31 @@ var TPS = {
},
HandlePasswords: function (passwords, action) {
- this.shouldValidatePasswords = true;
try {
- for (let password of passwords) {
+ for each (password in passwords) {
let password_id = -1;
Logger.logInfo("executing action " + action.toUpperCase() +
" on password " + JSON.stringify(password));
- let passwordOb = new Password(password);
+ var password = new Password(password);
switch (action) {
case ACTION_ADD:
- Logger.AssertTrue(passwordOb.Create() > -1, "error adding password");
+ Logger.AssertTrue(password.Create() > -1, "error adding password");
break;
case ACTION_VERIFY:
- Logger.AssertTrue(passwordOb.Find() != -1, "password not found");
+ Logger.AssertTrue(password.Find() != -1, "password not found");
break;
case ACTION_VERIFY_NOT:
- Logger.AssertTrue(passwordOb.Find() == -1,
+ Logger.AssertTrue(password.Find() == -1,
"password found, but it shouldn't exist");
break;
case ACTION_DELETE:
- Logger.AssertTrue(passwordOb.Find() != -1, "password not found");
- passwordOb.Remove();
+ Logger.AssertTrue(password.Find() != -1, "password not found");
+ password.Remove();
break;
case ACTION_MODIFY:
- if (passwordOb.updateProps != null) {
- Logger.AssertTrue(passwordOb.Find() != -1, "password not found");
- passwordOb.Update();
+ if (password.updateProps != null) {
+ Logger.AssertTrue(password.Find() != -1, "password not found");
+ password.Update();
}
break;
default:
@@ -475,8 +450,7 @@ var TPS = {
},
HandleAddons: function (addons, action, state) {
- this.shouldValidateAddons = true;
- for (let entry of addons) {
+ for each (let entry in addons) {
Logger.logInfo("executing action " + action.toUpperCase() +
" on addon " + JSON.stringify(entry));
let addon = new Addon(this, entry);
@@ -505,12 +479,11 @@ var TPS = {
},
HandleBookmarks: function (bookmarks, action) {
- this.shouldValidateBookmarks = true;
try {
let items = [];
- for (let folder in bookmarks) {
+ for (folder in bookmarks) {
let last_item_pos = -1;
- for (let bookmark of bookmarks[folder]) {
+ for each (bookmark in bookmarks[folder]) {
Logger.clearPotentialError();
let placesItem;
bookmark['location'] = folder;
@@ -552,7 +525,7 @@ var TPS = {
}
if (action == ACTION_DELETE || action == ACTION_MODIFY) {
- for (let item of items) {
+ for each (item in items) {
Logger.logInfo("executing action " + action.toUpperCase() +
" on bookmark " + JSON.stringify(item));
switch(action) {
@@ -597,163 +570,10 @@ var TPS = {
Logger.logInfo("mozmill setTest: " + obj.name);
},
- Cleanup() {
- try {
- this.WipeServer();
- } catch (ex) {
- Logger.logError("Failed to wipe server: " + Log.exceptionStr(ex));
- }
- try {
- if (Authentication.isLoggedIn) {
- // signout and wait for Sync to completely reset itself.
- Logger.logInfo("signing out");
- let waiter = this.createEventWaiter("weave:service:start-over:finish");
- Authentication.signOut();
- waiter();
- Logger.logInfo("signout complete");
- }
- } catch (e) {
- Logger.logError("Failed to sign out: " + Log.exceptionStr(e));
- }
- },
-
- /**
- * Use Sync's bookmark validation code to see if we've corrupted the tree.
- */
- ValidateBookmarks() {
-
- let getServerBookmarkState = () => {
- let bookmarkEngine = Weave.Service.engineManager.get('bookmarks');
- let collection = bookmarkEngine.itemSource();
- let collectionKey = bookmarkEngine.service.collectionKeys.keyForCollection(bookmarkEngine.name);
- collection.full = true;
- let items = [];
- collection.recordHandler = function(item) {
- item.decrypt(collectionKey);
- items.push(item.cleartext);
- };
- collection.get();
- return items;
- };
- let serverRecordDumpStr;
- try {
- Logger.logInfo("About to perform bookmark validation");
- let clientTree = Async.promiseSpinningly(PlacesUtils.promiseBookmarksTree("", {
- includeItemIds: true
- }));
- let serverRecords = getServerBookmarkState();
- // We can't wait until catch to stringify this, since at that point it will have cycles.
- serverRecordDumpStr = JSON.stringify(serverRecords);
-
- let validator = new BookmarkValidator();
- let {problemData} = validator.compareServerWithClient(serverRecords, clientTree);
-
- for (let {name, count} of problemData.getSummary()) {
- // Exclude mobile showing up on the server hackily so that we don't
- // report it every time, see bug 1273234 and 1274394 for more information.
- if (name === "serverUnexpected" && problemData.serverUnexpected.indexOf("mobile") >= 0) {
- --count;
- }
- if (count) {
- // Log this out before we assert. This is useful in the context of TPS logs, since we
- // can see the IDs in the test files.
- Logger.logInfo(`Validation problem: "${name}": ${JSON.stringify(problemData[name])}`);
- }
- Logger.AssertEqual(count, 0, `Bookmark validation error of type ${name}`);
- }
- } catch (e) {
- // Dump the client records (should always be doable)
- DumpBookmarks();
- // Dump the server records if gotten them already.
- if (serverRecordDumpStr) {
- Logger.logInfo("Server bookmark records:\n" + serverRecordDumpStr + "\n");
- }
- this.DumpError("Bookmark validation failed", e);
- }
- Logger.logInfo("Bookmark validation finished");
- },
-
- ValidateCollection(engineName, ValidatorType) {
- let serverRecordDumpStr;
- let clientRecordDumpStr;
- try {
- Logger.logInfo(`About to perform validation for "${engineName}"`);
- let engine = Weave.Service.engineManager.get(engineName);
- let validator = new ValidatorType(engine);
- let serverRecords = validator.getServerItems(engine);
- let clientRecords = Async.promiseSpinningly(validator.getClientItems());
- try {
- // This substantially improves the logs for addons while not making a
- // substantial difference for the other two
- clientRecordDumpStr = JSON.stringify(clientRecords.map(r => {
- let res = validator.normalizeClientItem(r);
- delete res.original; // Try and prevent cyclic references
- return res;
- }));
- } catch (e) {
- // ignore the error, the dump string is just here to make debugging easier.
- clientRecordDumpStr = "<Cyclic value>";
- }
- try {
- serverRecordDumpStr = JSON.stringify(serverRecords);
- } catch (e) {
- // as above
- serverRecordDumpStr = "<Cyclic value>";
- }
- let { problemData } = validator.compareClientWithServer(clientRecords, serverRecords);
- for (let { name, count } of problemData.getSummary()) {
- if (count) {
- Logger.logInfo(`Validation problem: "${name}": ${JSON.stringify(problemData[name])}`);
- }
- Logger.AssertEqual(count, 0, `Validation error for "${engineName}" of type "${name}"`);
- }
- } catch (e) {
- // Dump the client records if possible
- if (clientRecordDumpStr) {
- Logger.logInfo(`Client state for ${engineName}:\n${clientRecordDumpStr}\n`);
- }
- // Dump the server records if gotten them already.
- if (serverRecordDumpStr) {
- Logger.logInfo(`Server state for ${engineName}:\n${serverRecordDumpStr}\n`);
- }
- this.DumpError(`Validation failed for ${engineName}`, e);
- }
- Logger.logInfo(`Validation finished for ${engineName}`);
- },
-
- ValidatePasswords() {
- return this.ValidateCollection("passwords", PasswordValidator);
- },
-
- ValidateForms() {
- return this.ValidateCollection("forms", FormValidator);
- },
-
- ValidateAddons() {
- return this.ValidateCollection("addons", AddonValidator);
- },
-
RunNextTestAction: function() {
try {
if (this._currentAction >=
- this._phaselist[this._currentPhase].length) {
- // Run necessary validations and then finish up
- if (this.shouldValidateBookmarks) {
- this.ValidateBookmarks();
- }
- if (this.shouldValidatePasswords) {
- this.ValidatePasswords();
- }
- if (this.shouldValidateForms) {
- this.ValidateForms();
- }
- if (this.shouldValidateAddons) {
- this.ValidateAddons();
- }
- // Force this early so that we run the validation and detect missing pings
- // *before* we start shutting down, since if we do it after, the python
- // code won't notice the failure.
- SyncTelemetry.shutdown();
+ this._phaselist["phase" + this._currentPhase].length) {
// we're all done
Logger.logInfo("test phase " + this._currentPhase + ": " +
(this._errors ? "FAIL" : "PASS"));
@@ -761,7 +581,7 @@ var TPS = {
this.quit();
return;
}
- this.seconds_since_epoch = prefs.getIntPref("tps.seconds_since_epoch", 0);
+
if (this.seconds_since_epoch)
this._usSinceEpoch = this.seconds_since_epoch * 1000 * 1000;
else {
@@ -769,7 +589,7 @@ var TPS = {
return;
}
- let phase = this._phaselist[this._currentPhase];
+ let phase = this._phaselist["phase" + this._currentPhase];
let action = phase[this._currentAction];
Logger.logInfo("starting action: " + action[0].name);
action[0].apply(this, action.slice(1));
@@ -781,64 +601,12 @@ var TPS = {
this._currentAction++;
}
catch(e) {
- if (Async.isShutdownException(e)) {
- if (this._requestedQuit) {
- Logger.logInfo("Sync aborted due to requested shutdown");
- } else {
- this.DumpError("Sync aborted due to shutdown, but we didn't request it");
- }
- } else {
- this.DumpError("RunNextTestAction failed", e);
- }
+ this.DumpError("Exception caught: " + Utils.exceptionStr(e));
return;
}
this.RunNextTestAction();
},
- _getFileRelativeToSourceRoot(testFileURL, relativePath) {
- let file = fileProtocolHandler.getFileFromURLSpec(testFileURL);
- let root = file // <root>/services/sync/tests/tps/test_foo.js
- .parent // <root>/services/sync/tests/tps
- .parent // <root>/services/sync/tests
- .parent // <root>/services/sync
- .parent // <root>/services
- .parent // <root>
- ;
- root.appendRelativePath(relativePath);
- return root;
- },
-
- // Attempt to load the sync_ping_schema.json and initialize `this.pingValidator`
- // based on the source of the tps file. Assumes that it's at "../unit/sync_ping_schema.json"
- // relative to the directory the tps test file (testFile) is contained in.
- _tryLoadPingSchema(testFile) {
- try {
- let schemaFile = this._getFileRelativeToSourceRoot(testFile,
- "services/sync/tests/unit/sync_ping_schema.json");
-
- let stream = Cc["@mozilla.org/network/file-input-stream;1"]
- .createInstance(Ci.nsIFileInputStream);
-
- let jsonReader = Cc["@mozilla.org/dom/json;1"]
- .createInstance(Components.interfaces.nsIJSON);
-
- stream.init(schemaFile, FileUtils.MODE_RDONLY, FileUtils.PERMS_FILE, 0);
- let schema = jsonReader.decodeFromStream(stream, stream.available());
- Logger.logInfo("Successfully loaded schema")
-
- // Importing resource://testing-common/* isn't possible from within TPS,
- // so we load Ajv manually.
- let ajvFile = this._getFileRelativeToSourceRoot(testFile, "testing/modules/ajv-4.1.1.js");
- let ajvURL = fileProtocolHandler.getURLSpecFromFile(ajvFile);
- let ns = {};
- Cu.import(ajvURL, ns);
- let ajv = new ns.Ajv({ async: "co*" });
- this.pingValidator = ajv.compile(schema);
- } catch (e) {
- this.DumpError(`Failed to load ping schema and AJV relative to "${testFile}".`, e);
- }
- },
-
/**
* Runs a single test phase.
*
@@ -872,8 +640,6 @@ var TPS = {
Logger.logInfo("Sync version: " + WEAVE_VERSION);
Logger.logInfo("Firefox buildid: " + Services.appinfo.appBuildID);
Logger.logInfo("Firefox version: " + Services.appinfo.version);
- Logger.logInfo("Firefox source revision: " + (AppConstants.SOURCE_REVISION_URL || "unknown"));
- Logger.logInfo("Firefox platform: " + AppConstants.platform);
Logger.logInfo('Firefox Accounts enabled: ' + this.fxaccounts_enabled);
// do some sync housekeeping
@@ -887,15 +653,12 @@ var TPS = {
this.waitForEvent("weave:service:ready");
}
- // We only want to do this if we modified the bookmarks this phase.
- this.shouldValidateBookmarks = false;
-
// Always give Sync an extra tick to initialize. If we waited for the
// service:ready event, this is required to ensure all handlers have
// executed.
Utils.nextTick(this._executeTestPhase.bind(this, file, phase, settings));
} catch(e) {
- this.DumpError("RunTestPhase failed", e);
+ this.DumpError("Exception caught: " + Utils.exceptionStr(e));
return;
}
},
@@ -907,28 +670,17 @@ var TPS = {
*/
_executeTestPhase: function _executeTestPhase(file, phase, settings) {
try {
- this.config = JSON.parse(prefs.getCharPref('tps.config'));
// parse the test file
Services.scriptloader.loadSubScript(file, this);
this._currentPhase = phase;
- if (this._currentPhase.startsWith("cleanup-")) {
- let profileToClean = Cc["@mozilla.org/toolkit/profile-service;1"]
- .getService(Ci.nsIToolkitProfileService)
- .selectedProfile.name;
- this.phases[this._currentPhase] = profileToClean;
- this.Phase(this._currentPhase, [[this.Cleanup]]);
- } else {
- // Don't bother doing this for cleanup phases.
- this._tryLoadPingSchema(file);
- }
- let this_phase = this._phaselist[this._currentPhase];
+ let this_phase = this._phaselist["phase" + this._currentPhase];
if (this_phase == undefined) {
this.DumpError("invalid phase " + this._currentPhase);
return;
}
- if (this.phases[this._currentPhase] == undefined) {
+ if (this.phases["phase" + this._currentPhase] == undefined) {
this.DumpError("no profile defined for phase " + this._currentPhase);
return;
}
@@ -937,7 +689,7 @@ var TPS = {
// care about.
if (settings.ignoreUnusedEngines && Array.isArray(this._enabledEngines)) {
let names = {};
- for (let name of this._enabledEngines) {
+ for each (let name in this._enabledEngines) {
names[name] = true;
}
@@ -948,63 +700,52 @@ var TPS = {
}
}
}
- Logger.logInfo("Starting phase " + this._currentPhase);
- Logger.logInfo("setting client.name to " + this.phases[this._currentPhase]);
- Weave.Svc.Prefs.set("client.name", this.phases[this._currentPhase]);
+ Logger.logInfo("Starting phase " + parseInt(phase, 10) + "/" +
+ Object.keys(this._phaselist).length);
- this._interceptSyncTelemetry();
+ Logger.logInfo("setting client.name to " + this.phases["phase" + this._currentPhase]);
+ Weave.Svc.Prefs.set("client.name", this.phases["phase" + this._currentPhase]);
- // start processing the test actions
- this._currentAction = 0;
- }
- catch(e) {
- this.DumpError("_executeTestPhase failed", e);
- return;
- }
- },
+ // TODO Phases should be defined in a data type that has strong
+ // ordering, not by lexical sorting.
+ let currentPhase = parseInt(this._currentPhase, 10);
- /**
- * Override sync telemetry functions so that we can detect errors generating
- * the sync ping, and count how many pings we report.
- */
- _interceptSyncTelemetry() {
- let originalObserve = SyncTelemetry.observe;
- let self = this;
- SyncTelemetry.observe = function() {
- try {
- originalObserve.apply(this, arguments);
- } catch (e) {
- self.DumpError("Error when generating sync telemetry", e);
+ // Login at the beginning of the test.
+ if (currentPhase <= 1) {
+ this_phase.unshift([this.Login]);
}
- };
- SyncTelemetry.submit = record => {
- Logger.logInfo("Intercepted sync telemetry submission: " + JSON.stringify(record));
- this._syncsReportedViaTelemetry += record.syncs.length + (record.discarded || 0);
- if (record.discarded) {
- if (record.syncs.length != SyncTelemetry.maxPayloadCount) {
- this.DumpError("Syncs discarded from ping before maximum payload count reached");
- }
+
+ // Wipe the server at the end of the final test phase.
+ if (currentPhase >= Object.keys(this.phases).length) {
+ this._finalPhase = true;
}
- // If this is the shutdown ping, check and see that the telemetry saw all the syncs.
- if (record.why === "shutdown") {
- // If we happen to sync outside of tps manually causing it, its not an
- // error in the telemetry, so we only complain if we didn't see all of them.
- if (this._syncsReportedViaTelemetry < this._syncCount) {
- this.DumpError(`Telemetry missed syncs: Saw ${this._syncsReportedViaTelemetry}, should have >= ${this._syncCount}.`);
- }
+
+ // If a custom server was specified, set it now
+ if (this.config["serverURL"]) {
+ Weave.Service.serverURL = this.config.serverURL;
+ prefs.setCharPref('tps.serverURL', this.config.serverURL);
}
- if (!record.syncs.length) {
- // Note: we're overwriting submit, so this is called even for pings that
- // may have no data (which wouldn't be submitted to telemetry and would
- // fail validation).
- return;
+
+ // Store account details as prefs so they're accessible to the Mozmill
+ // framework.
+ if (this.fxaccounts_enabled) {
+ prefs.setCharPref('tps.account.username', this.config.fx_account.username);
+ prefs.setCharPref('tps.account.password', this.config.fx_account.password);
}
- if (!this.pingValidator(record)) {
- // Note that we already logged the record.
- this.DumpError("Sync ping validation failed with errors: " + JSON.stringify(this.pingValidator.errors));
+ else {
+ prefs.setCharPref('tps.account.username', this.config.sync_account.username);
+ prefs.setCharPref('tps.account.password', this.config.sync_account.password);
+ prefs.setCharPref('tps.account.passphrase', this.config.sync_account.passphrase);
}
- };
+
+ // start processing the test actions
+ this._currentAction = 0;
+ }
+ catch(e) {
+ this.DumpError("Exception caught: " + Utils.exceptionStr(e));
+ return;
+ }
},
/**
@@ -1018,10 +759,6 @@ var TPS = {
* Array of functions/actions to perform.
*/
Phase: function Test__Phase(phasename, fnlist) {
- if (Object.keys(this._phaselist).length === 0) {
- // This is the first phase, add that we need to login.
- fnlist.unshift([this.Login]);
- }
this._phaselist[phasename] = fnlist;
},
@@ -1067,56 +804,28 @@ var TPS = {
},
/**
- * Return an object that when called, will block until the named event
- * is observed. This is similar to waitForEvent, although is typically safer
- * if you need to do some other work that may make the event fire.
- *
- * eg:
- * doSomething(); // causes the event to be fired.
- * waitForEvent("something");
- * is risky as the call to doSomething may trigger the event before the
- * waitForEvent call is made. Contrast with:
- *
- * let waiter = createEventWaiter("something"); // does *not* block.
- * doSomething(); // causes the event to be fired.
- * waiter(); // will return as soon as the event fires, even if it fires
- * // before this function is called.
- *
- * @param aEventName
- * String event to wait for.
- */
- createEventWaiter(aEventName) {
- Logger.logInfo("Setting up wait for " + aEventName + "...");
- let cb = Async.makeSpinningCallback();
- Svc.Obs.add(aEventName, cb);
- return function() {
- try {
- cb.wait();
- } finally {
- Svc.Obs.remove(aEventName, cb);
- Logger.logInfo(aEventName + " observed!");
- }
- }
- },
-
-
- /**
* Synchronously wait for the named event to be observed.
*
* When the event is observed, the function will wait an extra tick before
* returning.
*
- * Note that in general, you should probably use createEventWaiter unless you
- * are 100% sure that the event being waited on can only be sent after this
- * call adds the listener.
- *
* @param aEventName
* String event to wait for.
*/
waitForEvent: function waitForEvent(aEventName) {
- this.createEventWaiter(aEventName)();
+ Logger.logInfo("Waiting for " + aEventName + "...");
+ let cb = Async.makeSpinningCallback();
+ Svc.Obs.add(aEventName, cb);
+ cb.wait();
+ Svc.Obs.remove(aEventName, cb);
+ Logger.logInfo(aEventName + " observed!");
+
+ cb = Async.makeSpinningCallback();
+ Utils.nextTick(cb);
+ cb.wait();
},
+
/**
* Waits for Sync to logged in before returning
*/
@@ -1159,12 +868,6 @@ var TPS = {
this.waitForSetupComplete();
Logger.AssertEqual(Weave.Status.service, Weave.STATUS_OK, "Weave status OK");
this.waitForTracking();
- // If fxaccounts is enabled we get an initial sync at login time - let
- // that complete.
- if (this.fxaccounts_enabled) {
- this._triggeredSync = true;
- this.waitForSyncFinished();
- }
},
/**
@@ -1189,12 +892,10 @@ var TPS = {
}
this.Login(false);
- ++this._syncCount;
this._triggeredSync = true;
this.StartAsyncOperation();
Weave.Service.sync();
- Logger.logInfo("Sync is complete");
},
WipeServer: function TPS__WipeServer() {
@@ -1230,9 +931,6 @@ var Addons = {
verifyNot: function Addons__verifyNot(addons) {
TPS.HandleAddons(addons, ACTION_VERIFY_NOT);
},
- skipValidation() {
- TPS.shouldValidateAddons = false;
- }
};
var Bookmarks = {
@@ -1250,9 +948,6 @@ var Bookmarks = {
},
verifyNot: function Bookmarks__verifyNot(bookmarks) {
TPS.HandleBookmarks(bookmarks, ACTION_VERIFY_NOT);
- },
- skipValidation() {
- TPS.shouldValidateBookmarks = false;
}
};
@@ -1301,9 +996,6 @@ var Passwords = {
},
verifyNot: function Passwords__verifyNot(passwords) {
this.HandlePasswords(passwords, ACTION_VERIFY_NOT);
- },
- skipValidation() {
- TPS.shouldValidatePasswords = false;
}
};
@@ -1337,4 +1029,4 @@ var Windows = {
};
// Initialize TPS
-TPS._init();
+TPS._init(); \ No newline at end of file