toolkit/modules/tests/xpcshell/test_DeferredTask.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* Any copyright is dedicated to the Public Domain.
     2    http://creativecommons.org/publicdomain/zero/1.0/ */
     4 /**
     5  * This file tests the DeferredTask.jsm module.
     6  */
     8 ////////////////////////////////////////////////////////////////////////////////
     9 /// Globals
    11 const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
    13 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
    15 XPCOMUtils.defineLazyModuleGetter(this, "DeferredTask",
    16                                   "resource://gre/modules/DeferredTask.jsm");
    17 XPCOMUtils.defineLazyModuleGetter(this, "Promise",
    18                                   "resource://gre/modules/Promise.jsm");
    20 /**
    21  * Due to the nature of this module, most of the tests are time-dependent.  All
    22  * the timeouts are designed to occur at multiples of this granularity value,
    23  * in milliseconds, that should be high enough to prevent intermittent failures,
    24  * but low enough to prevent an excessive overall test execution time.
    25  */
    26 const T = 100;
    28 /**
    29  * Waits for the specified timeout before resolving the returned promise.
    30  */
    31 function promiseTimeout(aTimeoutMs)
    32 {
    33   let deferred = Promise.defer();
    34   do_timeout(aTimeoutMs, deferred.resolve);
    35   return deferred.promise;
    36 }
    38 function run_test()
    39 {
    40   run_next_test();
    41 }
    43 ////////////////////////////////////////////////////////////////////////////////
    44 //// Tests
    46 /**
    47  * Creates a simple DeferredTask and executes it once.
    48  */
    49 add_test(function test_arm_simple()
    50 {
    51   new DeferredTask(run_next_test, 10).arm();
    52 });
    54 /**
    55  * Checks that the delay set for the task is respected.
    56  */
    57 add_test(function test_arm_delay_respected()
    58 {
    59   let executed1 = false;
    60   let executed2 = false;
    62   new DeferredTask(function () {
    63     executed1 = true;
    64     do_check_false(executed2);
    65   }, 1*T).arm();
    67   new DeferredTask(function () {
    68     executed2 = true;
    69     do_check_true(executed1);
    70     run_next_test();
    71   }, 2*T).arm();
    72 });
    74 /**
    75  * Checks that calling "arm" again does not introduce further delay.
    76  */
    77 add_test(function test_arm_delay_notrestarted()
    78 {
    79   let executed = false;
    81   // Create a task that will run later.
    82   let deferredTask = new DeferredTask(() => { executed = true; }, 4*T);
    83   deferredTask.arm();
    85   // Before the task starts, call "arm" again.
    86   do_timeout(2*T, () => deferredTask.arm());
    88   // The "arm" call should not have introduced further delays.
    89   do_timeout(5*T, function () {
    90     do_check_true(executed);
    91     run_next_test();
    92   });
    93 });
    95 /**
    96  * Checks that a task runs only once when armed multiple times synchronously.
    97  */
    98 add_test(function test_arm_coalesced()
    99 {
   100   let executed = false;
   102   let deferredTask = new DeferredTask(function () {
   103     do_check_false(executed);
   104     executed = true;
   105     run_next_test();
   106   }, 50);
   108   deferredTask.arm();
   109   deferredTask.arm();
   110 });
   112 /**
   113  * Checks that a task runs only once when armed multiple times synchronously,
   114  * even when it has been created with a delay of zero milliseconds.
   115  */
   116 add_test(function test_arm_coalesced_nodelay()
   117 {
   118   let executed = false;
   120   let deferredTask = new DeferredTask(function () {
   121     do_check_false(executed);
   122     executed = true;
   123     run_next_test();
   124   }, 0);
   126   deferredTask.arm();
   127   deferredTask.arm();
   128 });
   130 /**
   131  * Checks that a task can be armed again while running.
   132  */
   133 add_test(function test_arm_recursive()
   134 {
   135   let executed = false;
   137   let deferredTask = new DeferredTask(function () {
   138     if (!executed) {
   139       executed = true;
   140       deferredTask.arm();
   141     } else {
   142       run_next_test();
   143     }
   144   }, 50);
   146   deferredTask.arm();
   147 });
   149 /**
   150  * Checks that calling "arm" while an asynchronous task is running waits until
   151  * the task is finished before restarting the delay.
   152  */
   153 add_test(function test_arm_async()
   154 {
   155   let finishedExecution = false;
   156   let finishedExecutionAgain = false;
   158   // Create a task that will run later.
   159   let deferredTask = new DeferredTask(function () {
   160     yield promiseTimeout(4*T);
   161     if (!finishedExecution) {
   162       finishedExecution = true;
   163     } else if (!finishedExecutionAgain) {
   164       finishedExecutionAgain = true;
   165     }
   166   }, 2*T);
   167   deferredTask.arm();
   169   // While the task is running, call "arm" again.  This will result in a wait
   170   // of 2*T until the task finishes, then another 2*T for the normal task delay
   171   // specified on construction.
   172   do_timeout(4*T, function () {
   173     do_check_true(deferredTask.isRunning);
   174     do_check_false(finishedExecution);
   175     deferredTask.arm();
   176   });
   178   // This will fail in case the task was started without waiting 2*T after it
   179   // has finished.
   180   do_timeout(7*T, function () {
   181     do_check_false(deferredTask.isRunning);
   182     do_check_true(finishedExecution);
   183   });
   185   // This is in the middle of the second execution.
   186   do_timeout(10*T, function () {
   187     do_check_true(deferredTask.isRunning);
   188     do_check_false(finishedExecutionAgain);
   189   });
   191   // Wait enough time to verify that the task was executed as expected.
   192   do_timeout(13*T, function () {
   193     do_check_false(deferredTask.isRunning);
   194     do_check_true(finishedExecutionAgain);
   195     run_next_test();
   196   });
   197 });
   199 /**
   200  * Checks that an armed task can be disarmed.
   201  */
   202 add_test(function test_disarm()
   203 {
   204   // Create a task that will run later.
   205   let deferredTask = new DeferredTask(function () {
   206     do_throw("This task should not run.");
   207   }, 2*T);
   208   deferredTask.arm();
   210   // Disable execution later, but before the task starts.
   211   do_timeout(1*T, () => deferredTask.disarm());
   213   // Wait enough time to verify that the task did not run.
   214   do_timeout(3*T, run_next_test);
   215 });
   217 /**
   218  * Checks that calling "disarm" allows the delay to be restarted.
   219  */
   220 add_test(function test_disarm_delay_restarted()
   221 {
   222   let executed = false;
   224   let deferredTask = new DeferredTask(() => { executed = true; }, 4*T);
   225   deferredTask.arm();
   227   do_timeout(2*T, function () {
   228     deferredTask.disarm();
   229     deferredTask.arm();
   230   });
   232   do_timeout(5*T, function () {
   233     do_check_false(executed);
   234   });
   236   do_timeout(7*T, function () {
   237     do_check_true(executed);
   238     run_next_test();
   239   });
   240 });
   242 /**
   243  * Checks that calling "disarm" while an asynchronous task is running does not
   244  * prevent the task to finish.
   245  */
   246 add_test(function test_disarm_async()
   247 {
   248   let finishedExecution = false;
   250   let deferredTask = new DeferredTask(function () {
   251     deferredTask.arm();
   252     yield promiseTimeout(2*T);
   253     finishedExecution = true;
   254   }, 1*T);
   255   deferredTask.arm();
   257   do_timeout(2*T, function () {
   258     do_check_true(deferredTask.isRunning);
   259     do_check_true(deferredTask.isArmed);
   260     do_check_false(finishedExecution);
   261     deferredTask.disarm();
   262   });
   264   do_timeout(4*T, function () {
   265     do_check_false(deferredTask.isRunning);
   266     do_check_false(deferredTask.isArmed);
   267     do_check_true(finishedExecution);
   268     run_next_test();
   269   });
   270 });
   272 /**
   273  * Checks that calling "arm" immediately followed by "disarm" while an
   274  * asynchronous task is running does not cause it to run again.
   275  */
   276 add_test(function test_disarm_immediate_async()
   277 {
   278   let executed = false;
   280   let deferredTask = new DeferredTask(function () {
   281     do_check_false(executed);
   282     executed = true;
   283     yield promiseTimeout(2*T);
   284   }, 1*T);
   285   deferredTask.arm();
   287   do_timeout(2*T, function () {
   288     do_check_true(deferredTask.isRunning);
   289     do_check_false(deferredTask.isArmed);
   290     deferredTask.arm();
   291     deferredTask.disarm();
   292   });
   294   do_timeout(4*T, function () {
   295     do_check_true(executed);
   296     do_check_false(deferredTask.isRunning);
   297     do_check_false(deferredTask.isArmed);
   298     run_next_test();
   299   });
   300 });
   302 /**
   303  * Checks the isArmed and isRunning properties with a synchronous task.
   304  */
   305 add_test(function test_isArmed_isRunning()
   306 {
   307   let deferredTask = new DeferredTask(function () {
   308     do_check_true(deferredTask.isRunning);
   309     do_check_false(deferredTask.isArmed);
   310     deferredTask.arm();
   311     do_check_true(deferredTask.isArmed);
   312     deferredTask.disarm();
   313     do_check_false(deferredTask.isArmed);
   314     run_next_test();
   315   }, 50);
   317   do_check_false(deferredTask.isArmed);
   318   deferredTask.arm();
   319   do_check_true(deferredTask.isArmed);
   320   do_check_false(deferredTask.isRunning);
   321 });
   323 /**
   324  * Checks that the "finalize" method executes a synchronous task.
   325  */
   326 add_test(function test_finalize()
   327 {
   328   let executed = false;
   329   let timePassed = false;
   331   let deferredTask = new DeferredTask(function () {
   332     do_check_false(timePassed);
   333     executed = true;
   334   }, 2*T);
   335   deferredTask.arm();
   337   do_timeout(1*T, () => { timePassed = true; });
   339   // This should trigger the immediate execution of the task.
   340   deferredTask.finalize().then(function () {
   341     do_check_true(executed);
   342     run_next_test();
   343   });
   344 });
   346 /**
   347  * Checks that the "finalize" method executes the task again from start to
   348  * finish in case it is already running.
   349  */
   350 add_test(function test_finalize_executes_entirely()
   351 {
   352   let executed = false;
   353   let executedAgain = false;
   354   let timePassed = false;
   356   let deferredTask = new DeferredTask(function () {
   357     // The first time, we arm the timer again and set up the finalization.
   358     if (!executed) {
   359       deferredTask.arm();
   360       do_check_true(deferredTask.isArmed);
   361       do_check_true(deferredTask.isRunning);
   363       deferredTask.finalize().then(function () {
   364         // When we reach this point, the task must be finished.
   365         do_check_true(executedAgain);
   366         do_check_false(timePassed);
   367         do_check_false(deferredTask.isArmed);
   368         do_check_false(deferredTask.isRunning);
   369         run_next_test();
   370       });
   372       // The second execution triggered by the finalization waits 1*T for the
   373       // current task to finish (see the timeout below), but then it must not
   374       // wait for the 2*T specified on construction as normal task delay.  The
   375       // second execution will finish after the timeout below has passed again,
   376       // for a total of 2*T of wait time.
   377       do_timeout(3*T, () => { timePassed = true; });
   378     }
   380     yield promiseTimeout(1*T);
   382     // Just before finishing, indicate if we completed the second execution.
   383     if (executed) {
   384       do_check_true(deferredTask.isRunning);
   385       executedAgain = true;
   386     } else {
   387       executed = true;
   388     }
   389   }, 2*T);
   391   deferredTask.arm();
   392 });

mercurial