services/sync/tests/unit/test_interval_triggers.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 Cu.import("resource://services-sync/constants.js");
     5 Cu.import("resource://services-sync/engines.js");
     6 Cu.import("resource://services-sync/engines/clients.js");
     7 Cu.import("resource://services-sync/util.js");
     8 Cu.import("resource://testing-common/services/sync/utils.js");
    10 Svc.DefaultPrefs.set("registerEngines", "");
    11 Cu.import("resource://services-sync/service.js");
    13 let scheduler = Service.scheduler;
    14 let clientsEngine = Service.clientsEngine;
    16 function promiseStopServer(server) {
    17   let deferred = Promise.defer();
    18   server.stop(deferred.resolve);
    19   return deferred.promise;
    20 }
    22 function sync_httpd_setup() {
    23   let global = new ServerWBO("global", {
    24     syncID: Service.syncID,
    25     storageVersion: STORAGE_VERSION,
    26     engines: {clients: {version: clientsEngine.version,
    27                         syncID: clientsEngine.syncID}}
    28   });
    29   let clientsColl = new ServerCollection({}, true);
    31   // Tracking info/collections.
    32   let collectionsHelper = track_collections_helper();
    33   let upd = collectionsHelper.with_updated_collection;
    35   return httpd_setup({
    36     "/1.1/johndoe/storage/meta/global": upd("meta", global.handler()),
    37     "/1.1/johndoe/info/collections": collectionsHelper.handler,
    38     "/1.1/johndoe/storage/crypto/keys":
    39       upd("crypto", (new ServerWBO("keys")).handler()),
    40     "/1.1/johndoe/storage/clients": upd("clients", clientsColl.handler())
    41   });
    42 }
    44 function setUp(server) {
    45   yield configureIdentity({username: "johndoe"});
    46   Service.serverURL = server.baseURI + "/";
    47   Service.clusterURL = server.baseURI + "/";
    48   generateNewKeys(Service.collectionKeys);
    49   let serverKeys = Service.collectionKeys.asWBO("crypto", "keys");
    50   serverKeys.encrypt(Service.identity.syncKeyBundle);
    51   serverKeys.upload(Service.resource(Service.cryptoKeysURL));
    52 }
    54 function run_test() {
    55   initTestLogging("Trace");
    57   Log.repository.getLogger("Sync.Service").level = Log.Level.Trace;
    58   Log.repository.getLogger("Sync.SyncScheduler").level = Log.Level.Trace;
    60   run_next_test();
    61 }
    63 add_identity_test(this, function test_successful_sync_adjustSyncInterval() {
    64   _("Test successful sync calling adjustSyncInterval");
    65   let syncSuccesses = 0;
    66   function onSyncFinish() {
    67     _("Sync success.");
    68     syncSuccesses++;
    69   };
    70   Svc.Obs.add("weave:service:sync:finish", onSyncFinish);
    72   let server = sync_httpd_setup();
    73   yield setUp(server);
    75   // Confirm defaults
    76   do_check_false(scheduler.idle);
    77   do_check_false(scheduler.numClients > 1);
    78   do_check_eq(scheduler.syncInterval, scheduler.singleDeviceInterval);
    79   do_check_false(scheduler.hasIncomingItems);
    81   _("Test as long as numClients <= 1 our sync interval is SINGLE_USER.");
    82   // idle == true && numClients <= 1 && hasIncomingItems == false
    83   scheduler.idle = true;
    84   Service.sync();
    85   do_check_eq(syncSuccesses, 1);
    86   do_check_true(scheduler.idle);
    87   do_check_false(scheduler.numClients > 1);
    88   do_check_false(scheduler.hasIncomingItems);
    89   do_check_eq(scheduler.syncInterval, scheduler.singleDeviceInterval);
    91   // idle == false && numClients <= 1 && hasIncomingItems == false
    92   scheduler.idle = false;
    93   Service.sync();
    94   do_check_eq(syncSuccesses, 2);
    95   do_check_false(scheduler.idle);
    96   do_check_false(scheduler.numClients > 1);
    97   do_check_false(scheduler.hasIncomingItems);
    98   do_check_eq(scheduler.syncInterval, scheduler.singleDeviceInterval);
   100   // idle == false && numClients <= 1 && hasIncomingItems == true
   101   scheduler.hasIncomingItems = true;
   102   Service.sync();
   103   do_check_eq(syncSuccesses, 3);
   104   do_check_false(scheduler.idle);
   105   do_check_false(scheduler.numClients > 1);
   106   do_check_true(scheduler.hasIncomingItems);
   107   do_check_eq(scheduler.syncInterval, scheduler.singleDeviceInterval);
   109   // idle == true && numClients <= 1 && hasIncomingItems == true
   110   scheduler.idle = true;
   111   Service.sync();
   112   do_check_eq(syncSuccesses, 4);
   113   do_check_true(scheduler.idle);
   114   do_check_false(scheduler.numClients > 1);
   115   do_check_true(scheduler.hasIncomingItems);
   116   do_check_eq(scheduler.syncInterval, scheduler.singleDeviceInterval);
   118   _("Test as long as idle && numClients > 1 our sync interval is idleInterval.");
   119   // idle == true && numClients > 1 && hasIncomingItems == true
   120   Service.clientsEngine._store.create({id: "foo", cleartext: "bar"});
   121   Service.sync();
   122   do_check_eq(syncSuccesses, 5);
   123   do_check_true(scheduler.idle);
   124   do_check_true(scheduler.numClients > 1);
   125   do_check_true(scheduler.hasIncomingItems);
   126   do_check_eq(scheduler.syncInterval, scheduler.idleInterval);
   128   // idle == true && numClients > 1 && hasIncomingItems == false
   129   scheduler.hasIncomingItems = false;
   130   Service.sync();
   131   do_check_eq(syncSuccesses, 6);
   132   do_check_true(scheduler.idle);
   133   do_check_true(scheduler.numClients > 1);
   134   do_check_false(scheduler.hasIncomingItems);
   135   do_check_eq(scheduler.syncInterval, scheduler.idleInterval);
   137   _("Test non-idle, numClients > 1, no incoming items => activeInterval.");
   138   // idle == false && numClients > 1 && hasIncomingItems == false
   139   scheduler.idle = false;
   140   Service.sync();
   141   do_check_eq(syncSuccesses, 7);
   142   do_check_false(scheduler.idle);
   143   do_check_true(scheduler.numClients > 1);
   144   do_check_false(scheduler.hasIncomingItems);
   145   do_check_eq(scheduler.syncInterval, scheduler.activeInterval);
   147   _("Test non-idle, numClients > 1, incoming items => immediateInterval.");
   148   // idle == false && numClients > 1 && hasIncomingItems == true
   149   scheduler.hasIncomingItems = true;
   150   Service.sync();
   151   do_check_eq(syncSuccesses, 8);
   152   do_check_false(scheduler.idle);
   153   do_check_true(scheduler.numClients > 1);
   154   do_check_false(scheduler.hasIncomingItems); //gets reset to false
   155   do_check_eq(scheduler.syncInterval, scheduler.immediateInterval);
   157   Svc.Obs.remove("weave:service:sync:finish", onSyncFinish);
   158   Service.startOver();
   159   yield promiseStopServer(server);
   160 });
   162 add_identity_test(this, function test_unsuccessful_sync_adjustSyncInterval() {
   163   _("Test unsuccessful sync calling adjustSyncInterval");
   165   let syncFailures = 0;
   166   function onSyncError() {
   167     _("Sync error.");
   168     syncFailures++;
   169   }
   170   Svc.Obs.add("weave:service:sync:error", onSyncError);
   172   _("Test unsuccessful sync calls adjustSyncInterval");
   173   // Force sync to fail.
   174   Svc.Prefs.set("firstSync", "notReady");
   176   let server = sync_httpd_setup();
   177   yield setUp(server);
   179   // Confirm defaults
   180   do_check_false(scheduler.idle);
   181   do_check_false(scheduler.numClients > 1);
   182   do_check_eq(scheduler.syncInterval, scheduler.singleDeviceInterval);
   183   do_check_false(scheduler.hasIncomingItems);
   185   _("Test as long as numClients <= 1 our sync interval is SINGLE_USER.");
   186   // idle == true && numClients <= 1 && hasIncomingItems == false
   187   scheduler.idle = true;
   188   Service.sync();
   189   do_check_eq(syncFailures, 1);
   190   do_check_true(scheduler.idle);
   191   do_check_false(scheduler.numClients > 1);
   192   do_check_false(scheduler.hasIncomingItems);
   193   do_check_eq(scheduler.syncInterval, scheduler.singleDeviceInterval);
   195   // idle == false && numClients <= 1 && hasIncomingItems == false
   196   scheduler.idle = false;
   197   Service.sync();
   198   do_check_eq(syncFailures, 2);
   199   do_check_false(scheduler.idle);
   200   do_check_false(scheduler.numClients > 1);
   201   do_check_false(scheduler.hasIncomingItems);
   202   do_check_eq(scheduler.syncInterval, scheduler.singleDeviceInterval);
   204   // idle == false && numClients <= 1 && hasIncomingItems == true
   205   scheduler.hasIncomingItems = true;
   206   Service.sync();
   207   do_check_eq(syncFailures, 3);
   208   do_check_false(scheduler.idle);
   209   do_check_false(scheduler.numClients > 1);
   210   do_check_true(scheduler.hasIncomingItems);
   211   do_check_eq(scheduler.syncInterval, scheduler.singleDeviceInterval);
   213   // idle == true && numClients <= 1 && hasIncomingItems == true
   214   scheduler.idle = true;
   215   Service.sync();
   216   do_check_eq(syncFailures, 4);
   217   do_check_true(scheduler.idle);
   218   do_check_false(scheduler.numClients > 1);
   219   do_check_true(scheduler.hasIncomingItems);
   220   do_check_eq(scheduler.syncInterval, scheduler.singleDeviceInterval);
   222   _("Test as long as idle && numClients > 1 our sync interval is idleInterval.");
   223   // idle == true && numClients > 1 && hasIncomingItems == true
   224   Service.clientsEngine._store.create({id: "foo", cleartext: "bar"});
   226   Service.sync();
   227   do_check_eq(syncFailures, 5);
   228   do_check_true(scheduler.idle);
   229   do_check_true(scheduler.numClients > 1);
   230   do_check_true(scheduler.hasIncomingItems);
   231   do_check_eq(scheduler.syncInterval, scheduler.idleInterval);
   233   // idle == true && numClients > 1 && hasIncomingItems == false
   234   scheduler.hasIncomingItems = false;
   235   Service.sync();
   236   do_check_eq(syncFailures, 6);
   237   do_check_true(scheduler.idle);
   238   do_check_true(scheduler.numClients > 1);
   239   do_check_false(scheduler.hasIncomingItems);
   240   do_check_eq(scheduler.syncInterval, scheduler.idleInterval);
   242   _("Test non-idle, numClients > 1, no incoming items => activeInterval.");
   243   // idle == false && numClients > 1 && hasIncomingItems == false
   244   scheduler.idle = false;
   245   Service.sync();
   246   do_check_eq(syncFailures, 7);
   247   do_check_false(scheduler.idle);
   248   do_check_true(scheduler.numClients > 1);
   249   do_check_false(scheduler.hasIncomingItems);
   250   do_check_eq(scheduler.syncInterval, scheduler.activeInterval);
   252   _("Test non-idle, numClients > 1, incoming items => immediateInterval.");
   253   // idle == false && numClients > 1 && hasIncomingItems == true
   254   scheduler.hasIncomingItems = true;
   255   Service.sync();
   256   do_check_eq(syncFailures, 8);
   257   do_check_false(scheduler.idle);
   258   do_check_true(scheduler.numClients > 1);
   259   do_check_false(scheduler.hasIncomingItems); //gets reset to false
   260   do_check_eq(scheduler.syncInterval, scheduler.immediateInterval);
   262   Service.startOver();
   263   Svc.Obs.remove("weave:service:sync:error", onSyncError);
   264   yield promiseStopServer(server);
   265 });
   267 add_identity_test(this, function test_back_triggers_sync() {
   268   let server = sync_httpd_setup();
   269   yield setUp(server);
   271   // Single device: no sync triggered.
   272   scheduler.idle = true;
   273   scheduler.observe(null, "active", Svc.Prefs.get("scheduler.idleTime"));
   274   do_check_false(scheduler.idle);
   276   // Multiple devices: sync is triggered.
   277   clientsEngine._store.create({id: "foo", cleartext: "bar"});
   278   scheduler.updateClientMode();
   280   let deferred = Promise.defer();
   281   Svc.Obs.add("weave:service:sync:finish", function onSyncFinish() {
   282     Svc.Obs.remove("weave:service:sync:finish", onSyncFinish);
   284     Service.recordManager.clearCache();
   285     Svc.Prefs.resetBranch("");
   286     scheduler.setDefaults();
   287     clientsEngine.resetClient();
   289     Service.startOver();
   290     server.stop(deferred.resolve);
   291   });
   293   scheduler.idle = true;
   294   scheduler.observe(null, "active", Svc.Prefs.get("scheduler.idleTime"));
   295   do_check_false(scheduler.idle);
   296   yield deferred.promise;
   297 });
   299 add_identity_test(this, function test_adjust_interval_on_sync_error() {
   300   let server = sync_httpd_setup();
   301   yield setUp(server);
   303   let syncFailures = 0;
   304   function onSyncError() {
   305     _("Sync error.");
   306     syncFailures++;
   307   }
   308   Svc.Obs.add("weave:service:sync:error", onSyncError);
   310   _("Test unsuccessful sync updates client mode & sync intervals");
   311   // Force a sync fail.
   312   Svc.Prefs.set("firstSync", "notReady");
   314   do_check_eq(syncFailures, 0);
   315   do_check_false(scheduler.numClients > 1);
   316   do_check_eq(scheduler.syncInterval, scheduler.singleDeviceInterval);
   318   clientsEngine._store.create({id: "foo", cleartext: "bar"});
   319   Service.sync();
   321   do_check_eq(syncFailures, 1);
   322   do_check_true(scheduler.numClients > 1);
   323   do_check_eq(scheduler.syncInterval, scheduler.activeInterval);
   325   Svc.Obs.remove("weave:service:sync:error", onSyncError);
   326   Service.startOver();
   327   yield promiseStopServer(server);
   328 });
   330 add_identity_test(this, function test_bug671378_scenario() {
   331   // Test scenario similar to bug 671378. This bug appeared when a score
   332   // update occurred that wasn't large enough to trigger a sync so
   333   // scheduleNextSync() was called without a time interval parameter,
   334   // setting nextSync to a non-zero value and preventing the timer from
   335   // being adjusted in the next call to scheduleNextSync().
   336   let server = sync_httpd_setup();
   337   yield setUp(server);
   339   let syncSuccesses = 0;
   340   function onSyncFinish() {
   341     _("Sync success.");
   342     syncSuccesses++;
   343   };
   344   Svc.Obs.add("weave:service:sync:finish", onSyncFinish);
   346   // After first sync call, syncInterval & syncTimer are singleDeviceInterval.
   347   Service.sync();
   348   do_check_eq(syncSuccesses, 1);
   349   do_check_false(scheduler.numClients > 1);
   350   do_check_eq(scheduler.syncInterval, scheduler.singleDeviceInterval);
   351   do_check_eq(scheduler.syncTimer.delay, scheduler.singleDeviceInterval);
   353   let deferred = Promise.defer();
   354   // Wrap scheduleNextSync so we are notified when it is finished.
   355   scheduler._scheduleNextSync = scheduler.scheduleNextSync;
   356   scheduler.scheduleNextSync = function() {
   357     scheduler._scheduleNextSync();
   359     // Check on sync:finish scheduleNextSync sets the appropriate
   360     // syncInterval and syncTimer values.
   361     if (syncSuccesses == 2) {
   362       do_check_neq(scheduler.nextSync, 0);
   363       do_check_eq(scheduler.syncInterval, scheduler.activeInterval);
   364       do_check_true(scheduler.syncTimer.delay <= scheduler.activeInterval);
   366       scheduler.scheduleNextSync = scheduler._scheduleNextSync;
   367       Svc.Obs.remove("weave:service:sync:finish", onSyncFinish);
   368       Service.startOver();
   369       server.stop(deferred.resolve);
   370     }
   371   };
   373   // Set nextSync != 0
   374   // syncInterval still hasn't been set by call to updateClientMode.
   375   // Explicitly trying to invoke scheduleNextSync during a sync
   376   // (to immitate a score update that isn't big enough to trigger a sync).
   377   Svc.Obs.add("weave:service:sync:start", function onSyncStart() {
   378     // Wait for other sync:start observers to be called so that
   379     // nextSync is set to 0.
   380     Utils.nextTick(function() {
   381       Svc.Obs.remove("weave:service:sync:start", onSyncStart);
   383       scheduler.scheduleNextSync();
   384       do_check_neq(scheduler.nextSync, 0);
   385       do_check_eq(scheduler.syncInterval, scheduler.singleDeviceInterval);
   386       do_check_eq(scheduler.syncTimer.delay, scheduler.singleDeviceInterval);
   387     });
   388   });
   390   clientsEngine._store.create({id: "foo", cleartext: "bar"});
   391   Service.sync();
   392   yield deferred.promise;
   393 });
   395 add_test(function test_adjust_timer_larger_syncInterval() {
   396   _("Test syncInterval > current timout period && nextSync != 0, syncInterval is NOT used.");
   397   clientsEngine._store.create({id: "foo", cleartext: "bar"});
   398   scheduler.updateClientMode();
   399   do_check_eq(scheduler.syncInterval, scheduler.activeInterval);
   401   scheduler.scheduleNextSync();
   403   // Ensure we have a small interval.
   404   do_check_neq(scheduler.nextSync, 0);
   405   do_check_eq(scheduler.syncTimer.delay, scheduler.activeInterval);
   407   // Make interval large again
   408   clientsEngine._wipeClient();
   409   scheduler.updateClientMode();
   410   do_check_eq(scheduler.syncInterval, scheduler.singleDeviceInterval);
   412   scheduler.scheduleNextSync();
   414   // Ensure timer delay remains as the small interval.
   415   do_check_neq(scheduler.nextSync, 0);
   416   do_check_true(scheduler.syncTimer.delay <= scheduler.activeInterval);
   418   //SyncSchedule.
   419   Service.startOver();
   420   run_next_test();
   421 });
   423 add_test(function test_adjust_timer_smaller_syncInterval() {
   424   _("Test current timout > syncInterval period && nextSync != 0, syncInterval is used.");
   425   scheduler.scheduleNextSync();
   427   // Ensure we have a large interval.
   428   do_check_neq(scheduler.nextSync, 0);
   429   do_check_eq(scheduler.syncTimer.delay, scheduler.singleDeviceInterval);
   431   // Make interval smaller
   432   clientsEngine._store.create({id: "foo", cleartext: "bar"});
   433   scheduler.updateClientMode();
   434   do_check_eq(scheduler.syncInterval, scheduler.activeInterval);
   436   scheduler.scheduleNextSync();
   438   // Ensure smaller timer delay is used.
   439   do_check_neq(scheduler.nextSync, 0);
   440   do_check_true(scheduler.syncTimer.delay <= scheduler.activeInterval);
   442   //SyncSchedule.
   443   Service.startOver();
   444   run_next_test();
   445 });

mercurial