From c967517f149d04c0f7d1540a4c72ddebfe842dc2 Mon Sep 17 00:00:00 2001 From: Gregory Szorc Date: Thu, 10 May 2012 12:21:21 -0700 Subject: [PATCH 1/2] Bug 753515 - Move json{Load,Save} from services-sync into services-common; r=mconnor --HG-- rename : services/sync/tests/unit/test_utils_json.js => services/common/tests/unit/test_utils_json.js --- services/common/tests/unit/head_helpers.js | 13 +++ .../tests/unit/test_utils_json.js | 46 ++++++---- services/common/tests/unit/xpcshell.ini | 1 + services/common/utils.js | 83 +++++++++++++++++++ services/sync/modules/util.js | 73 +--------------- services/sync/tests/unit/head_helpers.js | 14 ---- services/sync/tests/unit/xpcshell.ini | 1 - 7 files changed, 129 insertions(+), 102 deletions(-) rename services/{sync => common}/tests/unit/test_utils_json.js (65%) diff --git a/services/common/tests/unit/head_helpers.js b/services/common/tests/unit/head_helpers.js index dcecde3ef8f4..1873e74e858d 100644 --- a/services/common/tests/unit/head_helpers.js +++ b/services/common/tests/unit/head_helpers.js @@ -127,6 +127,19 @@ function readBytesFromInputStream(inputStream, count) { return new BinaryInputStream(inputStream).readBytes(count); } +/* + * Ensure exceptions from inside callbacks leads to test failures. + */ +function ensureThrows(func) { + return function() { + try { + func.apply(this, arguments); + } catch (ex) { + do_throw(ex); + } + }; +} + /** * Proxy auth helpers. */ diff --git a/services/sync/tests/unit/test_utils_json.js b/services/common/tests/unit/test_utils_json.js similarity index 65% rename from services/sync/tests/unit/test_utils_json.js rename to services/common/tests/unit/test_utils_json.js index 264dacceed78..d255fda3e420 100644 --- a/services/sync/tests/unit/test_utils_json.js +++ b/services/common/tests/unit/test_utils_json.js @@ -1,16 +1,18 @@ -_("Make sure json saves and loads from disk"); -Cu.import("resource://services-sync/util.js"); -Cu.import("resource://services-sync/constants.js"); +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + Cu.import("resource://gre/modules/FileUtils.jsm"); +Cu.import("resource://services-common/utils.js"); function run_test() { + initTestLogging(); run_next_test(); } add_test(function test_roundtrip() { _("Do a simple write of an array to json and read"); - Utils.jsonSave("foo", {}, ["v1", "v2"], ensureThrows(function() { - Utils.jsonLoad("foo", {}, ensureThrows(function(val) { + CommonUtils.jsonSave("foo", {}, ["v1", "v2"], ensureThrows(function() { + CommonUtils.jsonLoad("foo", {}, ensureThrows(function(val) { let foo = val; do_check_eq(typeof foo, "object"); do_check_eq(foo.length, 2); @@ -23,8 +25,8 @@ add_test(function test_roundtrip() { add_test(function test_string() { _("Try saving simple strings"); - Utils.jsonSave("str", {}, "hi", ensureThrows(function() { - Utils.jsonLoad("str", {}, ensureThrows(function(val) { + CommonUtils.jsonSave("str", {}, "hi", ensureThrows(function() { + CommonUtils.jsonLoad("str", {}, ensureThrows(function(val) { let str = val; do_check_eq(typeof str, "string"); do_check_eq(str.length, 2); @@ -37,8 +39,8 @@ add_test(function test_string() { add_test(function test_number() { _("Try saving a number"); - Utils.jsonSave("num", {}, 42, ensureThrows(function() { - Utils.jsonLoad("num", {}, ensureThrows(function(val) { + CommonUtils.jsonSave("num", {}, 42, ensureThrows(function() { + CommonUtils.jsonLoad("num", {}, ensureThrows(function(val) { let num = val; do_check_eq(typeof num, "number"); do_check_eq(num, 42); @@ -49,17 +51,17 @@ add_test(function test_number() { add_test(function test_nonexistent_file() { _("Try loading a non-existent file."); - Utils.jsonLoad("non-existent", {}, ensureThrows(function(val) { + CommonUtils.jsonLoad("non-existent", {}, ensureThrows(function(val) { do_check_eq(val, undefined); run_next_test(); - })); + })); }); add_test(function test_save_logging() { _("Verify that writes are logged."); let trace; - Utils.jsonSave("log", {_log: {trace: function(msg) { trace = msg; }}}, - "hi", ensureThrows(function () { + CommonUtils.jsonSave("log", {_log: {trace: function(msg) { trace = msg; }}}, + "hi", ensureThrows(function () { do_check_true(!!trace); run_next_test(); })); @@ -69,7 +71,7 @@ add_test(function test_load_logging() { _("Verify that reads and read errors are logged."); // Write a file with some invalid JSON - let filePath = "weave/log.json"; + let filePath = "log.json"; let file = FileUtils.getFile("ProfD", filePath.split("/"), true); let fos = Cc["@mozilla.org/network/file-output-stream;1"] .createInstance(Ci.nsIFileOutputStream); @@ -83,10 +85,18 @@ add_test(function test_load_logging() { stream.close(); let trace, debug; - Utils.jsonLoad("log", - {_log: {trace: function(msg) { trace = msg; }, - debug: function(msg) { debug = msg; }}}, - ensureThrows(function(val) { + let obj = { + _log: { + trace: function(msg) { + trace = msg; + }, + debug: function(msg) { + debug = msg; + } + } + }; + CommonUtils.jsonLoad("log", obj, ensureThrows(function(val) { + do_check_true(!val); do_check_true(!!trace); do_check_true(!!debug); run_next_test(); diff --git a/services/common/tests/unit/xpcshell.ini b/services/common/tests/unit/xpcshell.ini index a99814936a2d..52bcb7a723bd 100644 --- a/services/common/tests/unit/xpcshell.ini +++ b/services/common/tests/unit/xpcshell.ini @@ -7,6 +7,7 @@ tail = [test_utils_atob.js] [test_utils_encodeBase32.js] +[test_utils_json.js] [test_utils_makeURI.js] [test_utils_namedTimer.js] [test_utils_stackTrace.js] diff --git a/services/common/utils.js b/services/common/utils.js index 30697f026e8f..26d88b4c4d65 100644 --- a/services/common/utils.js +++ b/services/common/utils.js @@ -6,6 +6,8 @@ const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; const EXPORTED_SYMBOLS = ["CommonUtils"]; +Cu.import("resource://gre/modules/FileUtils.jsm"); +Cu.import("resource://gre/modules/NetUtil.jsm"); Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://services-common/log4moz.js"); @@ -300,6 +302,87 @@ let CommonUtils = { let over = len % 4; return over ? atob(b64.substr(0, len - over)) : atob(b64); }, + + /** + * Load a JSON file from disk in the profile directory. + * + * @param filePath + * JSON file path load from profile. Loaded file will be + * /.json. i.e. Do not specify the ".json" + * extension. + * @param that + * Object to use for logging and "this" for callback. + * @param callback + * Function to process json object as its first argument. If the file + * could not be loaded, the first argument will be undefined. + */ + jsonLoad: function jsonLoad(filePath, that, callback) { + let path = filePath + ".json"; + + if (that._log) { + that._log.trace("Loading json from disk: " + filePath); + } + + let file = FileUtils.getFile("ProfD", path.split("/"), true); + if (!file.exists()) { + callback.call(that); + return; + } + + let channel = NetUtil.newChannel(file); + channel.contentType = "application/json"; + + NetUtil.asyncFetch(channel, function (is, result) { + if (!Components.isSuccessCode(result)) { + callback.call(that); + return; + } + let string = NetUtil.readInputStreamToString(is, is.available()); + is.close(); + let json; + try { + json = JSON.parse(string); + } catch (ex) { + if (that._log) { + that._log.debug("Failed to load json: " + + CommonUtils.exceptionStr(ex)); + } + } + callback.call(that, json); + }); + }, + + /** + * Save a json-able object to disk in the profile directory. + * + * @param filePath + * JSON file path save to .json + * @param that + * Object to use for logging and "this" for callback + * @param obj + * Function to provide json-able object to save. If this isn't a + * function, it'll be used as the object to make a json string. + * @param callback + * Function called when the write has been performed. Optional. + */ + jsonSave: function jsonSave(filePath, that, obj, callback) { + let path = filePath + ".json"; + if (that._log) { + that._log.trace("Saving json to disk: " + path); + } + + let file = FileUtils.getFile("ProfD", path.split("/"), true); + let json = typeof obj == "function" ? obj.call(that) : obj; + let out = JSON.stringify(json); + + let fos = FileUtils.openSafeFileOutputStream(file); + let is = this._utf8Converter.convertToInputStream(out); + NetUtil.asyncCopy(is, fos, function (result) { + if (typeof callback == "function") { + callback.call(that); + } + }); + }, }; XPCOMUtils.defineLazyGetter(CommonUtils, "_utf8Converter", function() { diff --git a/services/sync/modules/util.js b/services/sync/modules/util.js index d55020242db1..5f279d83b25b 100644 --- a/services/sync/modules/util.js +++ b/services/sync/modules/util.js @@ -357,77 +357,12 @@ let Utils = { return Utils.encodeKeyBase32(atob(encodedKey)); }, - /** - * Load a json object from disk - * - * @param filePath - * Json file path load from weave/[filePath].json - * @param that - * Object to use for logging and "this" for callback - * @param callback - * Function to process json object as its first parameter - */ - jsonLoad: function Utils_jsonLoad(filePath, that, callback) { - filePath = "weave/" + filePath + ".json"; - if (that._log) - that._log.trace("Loading json from disk: " + filePath); - - let file = FileUtils.getFile("ProfD", filePath.split("/"), true); - if (!file.exists()) { - callback.call(that); - return; - } - - let channel = NetUtil.newChannel(file); - channel.contentType = "application/json"; - - NetUtil.asyncFetch(channel, function (is, result) { - if (!Components.isSuccessCode(result)) { - callback.call(that); - return; - } - let string = NetUtil.readInputStreamToString(is, is.available()); - is.close(); - let json; - try { - json = JSON.parse(string); - } catch (ex) { - if (that._log) - that._log.debug("Failed to load json: " + Utils.exceptionStr(ex)); - } - callback.call(that, json); - }); + jsonLoad: function jsonLoad(path, that, callback) { + CommonUtils.jsonLoad("weave/" + path, that, callback); }, - /** - * Save a json-able object to disk - * - * @param filePath - * Json file path save to weave/[filePath].json - * @param that - * Object to use for logging and "this" for callback - * @param obj - * Function to provide json-able object to save. If this isn't a - * function, it'll be used as the object to make a json string. - * @param callback - * Function called when the write has been performed. Optional. - */ - jsonSave: function Utils_jsonSave(filePath, that, obj, callback) { - filePath = "weave/" + filePath + ".json"; - if (that._log) - that._log.trace("Saving json to disk: " + filePath); - - let file = FileUtils.getFile("ProfD", filePath.split("/"), true); - let json = typeof obj == "function" ? obj.call(that) : obj; - let out = JSON.stringify(json); - - let fos = FileUtils.openSafeFileOutputStream(file); - let is = this._utf8Converter.convertToInputStream(out); - NetUtil.asyncCopy(is, fos, function (result) { - if (typeof callback == "function") { - callback.call(that); - } - }); + jsonSave: function jsonSave(path, that, obj, callback) { + CommonUtils.jsonSave("weave/" + path, that, obj, callback); }, getIcon: function(iconUri, defaultIcon) { diff --git a/services/sync/tests/unit/head_helpers.js b/services/sync/tests/unit/head_helpers.js index 27ae2ae0868e..e2373c0dc1a8 100644 --- a/services/sync/tests/unit/head_helpers.js +++ b/services/sync/tests/unit/head_helpers.js @@ -251,20 +251,6 @@ function SyncTestingInfrastructure(username, password, syncKey) { this.fakeCryptoService = new FakeCryptoService(); } -/* - * Ensure exceptions from inside callbacks leads to test failures. - */ -function ensureThrows(func) { - return function() { - try { - func.apply(this, arguments); - } catch (ex) { - do_throw(ex); - } - }; -} - - _("Setting the identity for passphrase"); Cu.import("resource://services-sync/identity.js"); diff --git a/services/sync/tests/unit/xpcshell.ini b/services/sync/tests/unit/xpcshell.ini index 29fd68e3130c..4d27d73fbbf8 100644 --- a/services/sync/tests/unit/xpcshell.ini +++ b/services/sync/tests/unit/xpcshell.ini @@ -18,7 +18,6 @@ tail = [test_utils_keyEncoding.js] [test_utils_getErrorString.js] [test_utils_getIcon.js] -[test_utils_json.js] [test_utils_lazyStrings.js] [test_utils_lock.js] [test_utils_makeGUID.js] From c4ebefe0f4877968c9b1f9fb1c116066ee9d86f4 Mon Sep 17 00:00:00 2001 From: Raymond Lee Date: Sat, 12 May 2012 02:40:09 +0800 Subject: [PATCH 2/2] Bug 721283 - TPS driver should unload observers on exit r=gps --- .../sync/tps/extensions/tps/modules/tps.jsm | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/services/sync/tps/extensions/tps/modules/tps.jsm b/services/sync/tps/extensions/tps/modules/tps.jsm index 3420a2e51eb8..cc8df5600c41 100644 --- a/services/sync/tps/extensions/tps/modules/tps.jsm +++ b/services/sync/tps/extensions/tps/modules/tps.jsm @@ -90,6 +90,13 @@ const SYNC_WIPE_SERVER = "wipe-server"; const SYNC_RESET_CLIENT = "reset-client"; const SYNC_START_OVER = "start-over"; +const OBSERVER_TOPICS = ["weave:engine:start-tracking", + "weave:engine:stop-tracking", + "weave:service:sync:finish", + "weave:service:sync:error", + "sessionstore-windows-restored", + "private-browsing"]; + let TPS = { _waitingForSync: false, @@ -184,6 +191,9 @@ let TPS = }, quit: function () { + OBSERVER_TOPICS.forEach(function(topic) { + Services.obs.removeObserver(this, topic); + }, this); Logger.close(); this.goQuitApplication(); }, @@ -565,13 +575,9 @@ let TPS = */ _executeTestPhase: function _executeTestPhase(file, phase, settings) { try { - // TODO Unregister observers on unload (bug 721283). - Services.obs.addObserver(this, "weave:engine:start-tracking", true); - Services.obs.addObserver(this, "weave:engine:stop-tracking", true); - Services.obs.addObserver(this, "weave:service:sync:finish", true); - Services.obs.addObserver(this, "weave:service:sync:error", true); - Services.obs.addObserver(this, "sessionstore-windows-restored", true); - Services.obs.addObserver(this, "private-browsing", true); + OBSERVER_TOPICS.forEach(function(topic) { + Services.obs.addObserver(this, topic, true); + }, this); // parse the test file Services.scriptloader.loadSubScript(file, this);