services/sync/tests/unit/test_addons_engine.js

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

     1 /* Any copyright is dedicated to the Public Domain.
     2    http://creativecommons.org/publicdomain/zero/1.0/ */
     4 "use strict";
     6 Cu.import("resource://gre/modules/AddonManager.jsm");
     7 Cu.import("resource://gre/modules/Preferences.jsm");
     8 Cu.import("resource://gre/modules/Services.jsm");
     9 Cu.import("resource://services-common/async.js");
    10 Cu.import("resource://services-sync/addonsreconciler.js");
    11 Cu.import("resource://services-sync/engines/addons.js");
    12 Cu.import("resource://services-sync/service.js");
    13 Cu.import("resource://services-sync/util.js");
    14 Cu.import("resource://testing-common/services/sync/utils.js");
    16 let prefs = new Preferences();
    17 prefs.set("extensions.getAddons.get.url",
    18           "http://localhost:8888/search/guid:%IDS%");
    20 loadAddonTestFunctions();
    21 startupManager();
    23 let engineManager = Service.engineManager;
    25 engineManager.register(AddonsEngine);
    26 let engine = engineManager.get("addons");
    27 let reconciler = engine._reconciler;
    28 let tracker = engine._tracker;
    30 function advance_test() {
    31   reconciler._addons = {};
    32   reconciler._changes = [];
    34   let cb = Async.makeSpinningCallback();
    35   reconciler.saveState(null, cb);
    36   cb.wait();
    38   Svc.Prefs.reset("addons.ignoreRepositoryChecking");
    40   run_next_test();
    41 }
    43 // This is a basic sanity test for the unit test itself. If this breaks, the
    44 // add-ons API likely changed upstream.
    45 add_test(function test_addon_install() {
    46   _("Ensure basic add-on APIs work as expected.");
    48   let install = getAddonInstall("test_bootstrap1_1");
    49   do_check_neq(install, null);
    50   do_check_eq(install.type, "extension");
    51   do_check_eq(install.name, "Test Bootstrap 1");
    53   advance_test();
    54 });
    56 add_test(function test_find_dupe() {
    57   _("Ensure the _findDupe() implementation is sane.");
    59   // This gets invoked at the top of sync, which is bypassed by this
    60   // test, so we do it manually.
    61   engine._refreshReconcilerState();
    63   let addon = installAddon("test_bootstrap1_1");
    65   let record = {
    66     id:            Utils.makeGUID(),
    67     addonID:       addon.id,
    68     enabled:       true,
    69     applicationID: Services.appinfo.ID,
    70     source:        "amo"
    71   };
    73   let dupe = engine._findDupe(record);
    74   do_check_eq(addon.syncGUID, dupe);
    76   record.id = addon.syncGUID;
    77   dupe = engine._findDupe(record);
    78   do_check_eq(null, dupe);
    80   uninstallAddon(addon);
    81   advance_test();
    82 });
    84 add_test(function test_get_changed_ids() {
    85   _("Ensure getChangedIDs() has the appropriate behavior.");
    87   _("Ensure getChangedIDs() returns an empty object by default.");
    88   let changes = engine.getChangedIDs();
    89   do_check_eq("object", typeof(changes));
    90   do_check_eq(0, Object.keys(changes).length);
    92   _("Ensure tracker changes are populated.");
    93   let now = new Date();
    94   let changeTime = now.getTime() / 1000;
    95   let guid1 = Utils.makeGUID();
    96   tracker.addChangedID(guid1, changeTime);
    98   changes = engine.getChangedIDs();
    99   do_check_eq("object", typeof(changes));
   100   do_check_eq(1, Object.keys(changes).length);
   101   do_check_true(guid1 in changes);
   102   do_check_eq(changeTime, changes[guid1]);
   104   tracker.clearChangedIDs();
   106   _("Ensure reconciler changes are populated.");
   107   Svc.Prefs.set("addons.ignoreRepositoryChecking", true);
   108   let addon = installAddon("test_bootstrap1_1");
   109   tracker.clearChangedIDs(); // Just in case.
   110   changes = engine.getChangedIDs();
   111   do_check_eq("object", typeof(changes));
   112   do_check_eq(1, Object.keys(changes).length);
   113   do_check_true(addon.syncGUID in changes);
   114   _("Change time: " + changeTime + ", addon change: " + changes[addon.syncGUID]);
   115   do_check_true(changes[addon.syncGUID] >= changeTime);
   117   let oldTime = changes[addon.syncGUID];
   118   let guid2 = addon.syncGUID;
   119   uninstallAddon(addon);
   120   changes = engine.getChangedIDs();
   121   do_check_eq(1, Object.keys(changes).length);
   122   do_check_true(guid2 in changes);
   123   do_check_true(changes[guid2] > oldTime);
   125   _("Ensure non-syncable add-ons aren't picked up by reconciler changes.");
   126   reconciler._addons  = {};
   127   reconciler._changes = [];
   128   let record = {
   129     id:             "DUMMY",
   130     guid:           Utils.makeGUID(),
   131     enabled:        true,
   132     installed:      true,
   133     modified:       new Date(),
   134     type:           "UNSUPPORTED",
   135     scope:          0,
   136     foreignInstall: false
   137   };
   138   reconciler.addons["DUMMY"] = record;
   139   reconciler._addChange(record.modified, CHANGE_INSTALLED, record);
   141   changes = engine.getChangedIDs();
   142   _(JSON.stringify(changes));
   143   do_check_eq(0, Object.keys(changes).length);
   145   advance_test();
   146 });
   148 add_test(function test_disabled_install_semantics() {
   149   _("Ensure that syncing a disabled add-on preserves proper state.");
   151   // This is essentially a test for bug 712542, which snuck into the original
   152   // add-on sync drop. It ensures that when an add-on is installed that the
   153   // disabled state and incoming syncGUID is preserved, even on the next sync.
   155   Svc.Prefs.set("addons.ignoreRepositoryChecking", true);
   157   const USER       = "foo";
   158   const PASSWORD   = "password";
   159   const PASSPHRASE = "abcdeabcdeabcdeabcdeabcdea";
   160   const ADDON_ID   = "addon1@tests.mozilla.org";
   162   let server = new SyncServer();
   163   server.start();
   164   new SyncTestingInfrastructure(server.server, USER, PASSWORD, PASSPHRASE);
   166   generateNewKeys(Service.collectionKeys);
   168   let contents = {
   169     meta: {global: {engines: {addons: {version: engine.version,
   170                                       syncID:  engine.syncID}}}},
   171     crypto: {},
   172     addons: {}
   173   };
   175   server.registerUser(USER, "password");
   176   server.createContents(USER, contents);
   178   let amoServer = new HttpServer();
   179   amoServer.registerFile("/search/guid:addon1%40tests.mozilla.org",
   180                          do_get_file("addon1-search.xml"));
   182   let installXPI = ExtensionsTestPath("/addons/test_install1.xpi");
   183   amoServer.registerFile("/addon1.xpi", do_get_file(installXPI));
   184   amoServer.start(8888);
   186   // Insert an existing record into the server.
   187   let id = Utils.makeGUID();
   188   let now = Date.now() / 1000;
   190   let record = encryptPayload({
   191     id:            id,
   192     applicationID: Services.appinfo.ID,
   193     addonID:       ADDON_ID,
   194     enabled:       false,
   195     deleted:       false,
   196     source:        "amo",
   197   });
   198   let wbo = new ServerWBO(id, record, now - 2);
   199   server.insertWBO(USER, "addons", wbo);
   201   _("Performing sync of add-ons engine.");
   202   engine._sync();
   204   // At this point the non-restartless extension should be staged for install.
   206   // Don't need this server any more.
   207   let cb = Async.makeSpinningCallback();
   208   amoServer.stop(cb);
   209   cb.wait();
   211   // We ensure the reconciler has recorded the proper ID and enabled state.
   212   let addon = reconciler.getAddonStateFromSyncGUID(id);
   213   do_check_neq(null, addon);
   214   do_check_eq(false, addon.enabled);
   216   // We fake an app restart and perform another sync, just to make sure things
   217   // are sane.
   218   restartManager();
   220   engine._sync();
   222   // The client should not upload a new record. The old record should be
   223   // retained and unmodified.
   224   let collection = server.getCollection(USER, "addons");
   225   do_check_eq(1, collection.count());
   227   let payload = collection.payloads()[0];
   228   do_check_neq(null, collection.wbo(id));
   229   do_check_eq(ADDON_ID, payload.addonID);
   230   do_check_false(payload.enabled);
   232   server.stop(advance_test);
   233 });
   235 add_test(function cleanup() {
   236   // There's an xpcom-shutdown hook for this, but let's give this a shot.
   237   reconciler.stopListening();
   238   run_next_test();
   239 });
   241 function run_test() {
   242   initTestLogging("Trace");
   243   Log.repository.getLogger("Sync.Engine.Addons").level =
   244     Log.Level.Trace;
   245   Log.repository.getLogger("Sync.Store.Addons").level = Log.Level.Trace;
   246   Log.repository.getLogger("Sync.Tracker.Addons").level =
   247     Log.Level.Trace;
   248   Log.repository.getLogger("Sync.AddonsRepository").level =
   249     Log.Level.Trace;
   251   reconciler.startListening();
   253   // Don't flush to disk in the middle of an event listener!
   254   // This causes test hangs on WinXP.
   255   reconciler._shouldPersist = false;
   257   advance_test();
   258 }

mercurial