image/test/unit/async_load_tests.js

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /*
     2  * Test to ensure that image loading/decoding notifications are always
     3  * delivered async, and in the order we expect.
     4  *
     5  * Must be included from a file that has a uri of the image to test defined in
     6  * var uri.
     7  */
     9 const Cc = Components.classes;
    10 const Ci = Components.interfaces;
    11 const Cu = Components.utils;
    12 const Cr = Components.results;
    14 Cu.import("resource://testing-common/httpd.js");
    16 var server = new HttpServer();
    17 server.registerDirectory("/", do_get_file(''));
    18 server.registerContentType("sjs", "sjs");
    19 server.start(-1);
    22 load('image_load_helpers.js');
    24 var requests = [];
    26 // Return a closure that holds on to the listener from the original
    27 // imgIRequest, and compares its results to the cloned one.
    28 function getCloneStopCallback(original_listener)
    29 {
    30   return function cloneStop(listener) {
    31     do_check_eq(original_listener.state, listener.state);
    33     // Sanity check to make sure we didn't accidentally use the same listener
    34     // twice.
    35     do_check_neq(original_listener, listener);
    36     do_test_finished();
    37   }
    38 }
    40 // Make sure that cloned requests get all the same callbacks as the original,
    41 // but they aren't synchronous right now.
    42 function checkClone(other_listener, aRequest)
    43 {
    44   do_test_pending();
    46   // For as long as clone notification is synchronous, we can't test the clone state reliably.
    47   var listener = new ImageListener(null, function(foo, bar) { do_test_finished(); } /*getCloneStopCallback(other_listener)*/);
    48   listener.synchronous = false;
    49   var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
    50                 .createScriptedObserver(listener);
    51   var clone = aRequest.clone(outer);
    52   requests.push(clone);
    53 }
    55 // Ensure that all the callbacks were called on aRequest.
    56 function checkSizeAndLoad(listener, aRequest)
    57 {
    58   do_check_neq(listener.state & SIZE_AVAILABLE, 0);
    59   do_check_neq(listener.state & LOAD_COMPLETE, 0);
    61   do_test_finished();
    62 }
    64 function secondLoadDone(oldlistener, aRequest)
    65 {
    66   do_test_pending();
    68   try {
    69     var staticrequest = aRequest.getStaticRequest();
    71     // For as long as clone notification is synchronous, we can't test the
    72     // clone state reliably.
    73     var listener = new ImageListener(null, checkSizeAndLoad);
    74     listener.synchronous = false;
    75     var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
    76                   .createScriptedObserver(listener);
    77     var staticrequestclone = staticrequest.clone(outer);
    78     requests.push(staticrequestclone);
    79   } catch(e) {
    80     // We can't create a static request. Most likely the request we started
    81     // with didn't load successfully.
    82     do_test_finished();
    83   }
    85   run_loadImageWithChannel_tests();
    87   do_test_finished();
    88 }
    90 // Load the request a second time. This should come from the image cache, and
    91 // therefore would be at most risk of being served synchronously.
    92 function checkSecondLoad()
    93 {
    94   do_test_pending();
    96   var listener = new ImageListener(checkClone, secondLoadDone);
    97   var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
    98                 .createScriptedObserver(listener);
    99   requests.push(gCurrentLoader.loadImageXPCOM(uri, null, null, null, null, outer, null, 0, null, null));
   100   listener.synchronous = false;
   101 }
   103 function firstLoadDone(oldlistener, aRequest)
   104 {
   105   checkSecondLoad(uri);
   107   do_test_finished();
   108 }
   110 // Return a closure that allows us to check the stream listener's status when the
   111 // image starts loading.
   112 function getChannelLoadImageStartCallback(streamlistener)
   113 {
   114   return function channelLoadStart(imglistener, aRequest) {
   115     // We must not have received all status before we get this start callback.
   116     // If we have, we've broken people's expectations by delaying events from a
   117     // channel we were given.
   118     do_check_eq(streamlistener.requestStatus & STOP_REQUEST, 0);
   120     checkClone(imglistener, aRequest);
   121   }
   122 }
   124 // Return a closure that allows us to check the stream listener's status when the
   125 // image finishes loading.
   126 function getChannelLoadImageStopCallback(streamlistener, next)
   127 {
   128   return function channelLoadStop(imglistener, aRequest) {
   130     next();
   132     do_test_finished();
   133   }
   134 }
   136 // Load the request a second time. This should come from the image cache, and
   137 // therefore would be at most risk of being served synchronously.
   138 function checkSecondChannelLoad()
   139 {
   140   do_test_pending();
   142   var ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);  
   143   var channel = ioService.newChannelFromURI(uri);
   144   var channellistener = new ChannelListener();
   145   channel.asyncOpen(channellistener, null);
   147   var listener = new ImageListener(getChannelLoadImageStartCallback(channellistener),
   148                                    getChannelLoadImageStopCallback(channellistener,
   149                                                                    all_done_callback));
   150   var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
   151                 .createScriptedObserver(listener);
   152   var outlistener = {};
   153   requests.push(gCurrentLoader.loadImageWithChannelXPCOM(channel, outer, null, outlistener));
   154   channellistener.outputListener = outlistener.value;
   156   listener.synchronous = false;
   157 }
   159 function run_loadImageWithChannel_tests()
   160 {
   161   // To ensure we're testing what we expect to, create a new loader and cache.
   162   gCurrentLoader = Cc["@mozilla.org/image/loader;1"].createInstance(Ci.imgILoader);
   164   do_test_pending();
   166   var ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);  
   167   var channel = ioService.newChannelFromURI(uri);
   168   var channellistener = new ChannelListener();
   169   channel.asyncOpen(channellistener, null);
   171   var listener = new ImageListener(getChannelLoadImageStartCallback(channellistener),
   172                                    getChannelLoadImageStopCallback(channellistener,
   173                                                                    checkSecondChannelLoad));
   174   var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
   175                 .createScriptedObserver(listener);
   176   var outlistener = {};
   177   requests.push(gCurrentLoader.loadImageWithChannelXPCOM(channel, outer, null, outlistener));
   178   channellistener.outputListener = outlistener.value;
   180   listener.synchronous = false;
   181 }
   183 function all_done_callback()
   184 {
   185   server.stop(function() { do_test_finished(); });
   186 }
   188 function startImageCallback(otherCb)
   189 {
   190   return function(listener, request)
   191   {
   192     // Make sure we can load the same image immediately out of the cache.
   193     do_test_pending();
   194     var listener2 = new ImageListener(null, function(foo, bar) { do_test_finished(); });
   195     var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
   196                   .createScriptedObserver(listener2);
   197     requests.push(gCurrentLoader.loadImageXPCOM(uri, null, null, null, null, outer, null, 0, null, null));
   198     listener2.synchronous = false;
   200     // Now that we've started another load, chain to the callback.
   201     otherCb(listener, request);
   202   }
   203 }
   205 var gCurrentLoader;
   207 function cleanup()
   208 {
   209   for (var i = 0; i < requests.length; ++i) {
   210     requests[i].cancelAndForgetObserver(0);
   211   }
   212 }
   214 function run_test()
   215 {
   216   do_register_cleanup(cleanup);
   218   gCurrentLoader = Cc["@mozilla.org/image/loader;1"].createInstance(Ci.imgILoader);
   220   do_test_pending();
   221   var listener = new ImageListener(startImageCallback(checkClone), firstLoadDone);
   222   var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
   223                 .createScriptedObserver(listener);
   224   var req = gCurrentLoader.loadImageXPCOM(uri, null, null, null, null, outer, null, 0, null, null);
   225   requests.push(req);
   227   // Ensure that we don't cause any mayhem when we lock an image.
   228   req.lockImage();
   230   listener.synchronous = false;
   231 }

mercurial