netwerk/test/TestCacheCollisions.js

Thu, 15 Jan 2015 15:55:04 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:55:04 +0100
branch
TOR_BUG_9701
changeset 9
a63d609f5ebe
permissions
-rw-r--r--

Back out 97036ab72558 which inappropriately compared turds to third parties.

michael@0 1 var DEBUG = true;
michael@0 2
michael@0 3 var clientID = "HTTP";
michael@0 4 var nsICache = Components.interfaces.nsICache;
michael@0 5
michael@0 6 function getEventQueue()
michael@0 7 {
michael@0 8 var nsIEventQueueService = Components.interfaces.nsIEventQueueService;
michael@0 9 var CID = Components.classes["@mozilla.org/event-queue-service;1"];
michael@0 10 var service = CID.getService(nsIEventQueueService);
michael@0 11 return service.getSpecialEventQueue(nsIEventQueueService.CURRENT_THREAD_EVENT_QUEUE);
michael@0 12 }
michael@0 13
michael@0 14 var eventQueue = getEventQueue();
michael@0 15
michael@0 16 function getCacheService()
michael@0 17 {
michael@0 18 var nsCacheService = Components.classes["@mozilla.org/network/cache-service;1"];
michael@0 19 var service = nsCacheService.getService(Components.interfaces.nsICacheService);
michael@0 20 return service;
michael@0 21 }
michael@0 22
michael@0 23 function createCacheSession(clientID, storagePolicy, streamable)
michael@0 24 {
michael@0 25 var service = getCacheService();
michael@0 26 var session = service.createSession(clientID, storagePolicy, streamable);
michael@0 27 return session;
michael@0 28 }
michael@0 29
michael@0 30 function openCacheEntry(url, mode)
michael@0 31 {
michael@0 32 var session = createCacheSession(clientID, nsICache.STORE_ON_DISK, true);
michael@0 33 var entry = session.openCacheEntry(url, mode);
michael@0 34 return entry;
michael@0 35 }
michael@0 36
michael@0 37 function wrapInputStream(input)
michael@0 38 {
michael@0 39 var nsIScriptableInputStream = Components.interfaces.nsIScriptableInputStream;
michael@0 40 var factory = Components.classes["@mozilla.org/scriptableinputstream;1"];
michael@0 41 var wrapper = factory.createInstance(nsIScriptableInputStream);
michael@0 42 wrapper.init(input);
michael@0 43 return wrapper;
michael@0 44 }
michael@0 45
michael@0 46 function download(key)
michael@0 47 {
michael@0 48 var url = new java.net.URL(key);
michael@0 49 var data = "";
michael@0 50 var buffer = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 65536);
michael@0 51 var stream = url.openStream();
michael@0 52 while (true) {
michael@0 53 var count = stream.read(buffer);
michael@0 54 if (count <= 0)
michael@0 55 break;
michael@0 56 var str = new java.lang.String(buffer, 0, count);
michael@0 57 data += str;
michael@0 58 }
michael@0 59 stream.close();
michael@0 60 return data;
michael@0 61 }
michael@0 62
michael@0 63 function write(url, data)
michael@0 64 {
michael@0 65 var key = url.toString();
michael@0 66 var outputEntry = openCacheEntry(key, nsICache.ACCESS_WRITE);
michael@0 67 var output = outputEntry.transport.openOutputStream(0, -1, 0);
michael@0 68 var count = output.write(data, data.length);
michael@0 69
michael@0 70 // store some metadata.
michael@0 71 outputEntry.setMetaDataElement("size", data.length);
michael@0 72
michael@0 73 output.close();
michael@0 74 outputEntry.markValid();
michael@0 75 outputEntry.close();
michael@0 76
michael@0 77 return count;
michael@0 78 }
michael@0 79
michael@0 80 function CacheListener()
michael@0 81 {
michael@0 82 this.done = false;
michael@0 83 }
michael@0 84
michael@0 85 CacheListener.prototype = {
michael@0 86 QueryInterface : function(iid)
michael@0 87 {
michael@0 88 if (iid.equals(Components.interfaces.nsICacheListener))
michael@0 89 return this;
michael@0 90 throw Components.results.NS_NOINTERFACE;
michael@0 91 },
michael@0 92
michael@0 93 onCacheEntryAvailable : function(/* in nsICacheEntryDescriptor */ descriptor,
michael@0 94 /* in nsCacheAccessMode */ accessGranted,
michael@0 95 /* in nsresult */ status)
michael@0 96 {
michael@0 97 this.descriptor = descriptor;
michael@0 98 this.status = status;
michael@0 99 this.done = true;
michael@0 100 }
michael@0 101 };
michael@0 102
michael@0 103 function asyncOpenCacheEntry(url, mode)
michael@0 104 {
michael@0 105 var session = createCacheSession(clientID, nsICache.STORE_ON_DISK, true);
michael@0 106 var listener = new CacheListener();
michael@0 107 session.asyncOpenCacheEntry(url, mode, listener);
michael@0 108 while (!listener.done)
michael@0 109 eventQueue.processPendingEvents();
michael@0 110 return listener.descriptor;
michael@0 111 }
michael@0 112
michael@0 113 function asyncWrite(key, data)
michael@0 114 {
michael@0 115 var outputEntry = asyncOpenCacheEntry(key, nsICache.ACCESS_WRITE);
michael@0 116
michael@0 117 var output = outputEntry.transport.openOutputStream(0, -1, 0);
michael@0 118 var count = output.write(data, data.length);
michael@0 119
michael@0 120 // store some metadata.
michael@0 121 outputEntry.setMetaDataElement("size", data.length);
michael@0 122
michael@0 123 output.close();
michael@0 124 outputEntry.markValid();
michael@0 125 outputEntry.close();
michael@0 126
michael@0 127 return count;
michael@0 128 }
michael@0 129
michael@0 130 function StreamListener()
michael@0 131 {
michael@0 132 this.done = false;
michael@0 133 this.data = "";
michael@0 134 this.wrapper = null;
michael@0 135 }
michael@0 136
michael@0 137 StreamListener.prototype = {
michael@0 138 QueryInterface : function(iid)
michael@0 139 {
michael@0 140 if (iid.equals(Components.interfaces.nsIStreamListener) ||
michael@0 141 iid.equals(Components.interfaces.nsIStreamObserver))
michael@0 142 return this;
michael@0 143 throw Components.results.NS_NOINTERFACE;
michael@0 144 },
michael@0 145
michael@0 146 onStartRequest : function(request, context)
michael@0 147 {
michael@0 148 },
michael@0 149
michael@0 150 onStopRequest : function(request, context, statusCode, statusText)
michael@0 151 {
michael@0 152 this.statusCode = statusCode;
michael@0 153 this.done = true;
michael@0 154 },
michael@0 155
michael@0 156 onDataAvailable : function(request, context, input, offset, count)
michael@0 157 {
michael@0 158 if (this.wrapper == null)
michael@0 159 this.wrapper = wrapInputStream(input);
michael@0 160 input = this.wrapper;
michael@0 161 this.data += input.read(count);
michael@0 162 }
michael@0 163 };
michael@0 164
michael@0 165 function asyncRead(key)
michael@0 166 {
michael@0 167 var inputEntry = asyncOpenCacheEntry(key, nsICache.ACCESS_READ);
michael@0 168 var listener = new StreamListener();
michael@0 169 inputEntry.transport.asyncRead(listener, null, 0, inputEntry.dataSize, 0);
michael@0 170 while (!listener.done)
michael@0 171 eventQueue.processPendingEvents();
michael@0 172 inputEntry.close();
michael@0 173 return listener.data;
michael@0 174 }
michael@0 175
michael@0 176 function read(key)
michael@0 177 {
michael@0 178 var inputEntry = openCacheEntry(key, nsICache.ACCESS_READ);
michael@0 179 var input = wrapInputStream(inputEntry.transport.openInputStream(0, -1, 0));
michael@0 180 var data = input.read(input.available());
michael@0 181 input.close();
michael@0 182 inputEntry.close();
michael@0 183 return data;
michael@0 184 }
michael@0 185
michael@0 186 function readMetaData(key, element)
michael@0 187 {
michael@0 188 var inputEntry = openCacheEntry(key, nsICache.ACCESS_READ);
michael@0 189 var metadata = inputEntry.getMetaDataElement(element);
michael@0 190 inputEntry.close();
michael@0 191 return metadata;
michael@0 192 }
michael@0 193
michael@0 194 function doom(url)
michael@0 195 {
michael@0 196 var key = url.toString();
michael@0 197 var doomedEntry = openCacheEntry(key, nsICache.ACCESS_READ_WRITE);
michael@0 198 doomedEntry.doom();
michael@0 199 doomedEntry.close();
michael@0 200 }
michael@0 201
michael@0 202 // two keys which are known to collide right now.
michael@0 203 var key1 = "http://a772.g.akamai.net/7/772/51/7648437e551b56/www.apple.com/t/2001/us/en/i/2.gif";
michael@0 204 var key2 = "http://a772.g.akamai.net/7/772/51/70601300d0bde6/www.apple.com/t/2001/us/en/i/1right.gif";
michael@0 205
michael@0 206 function test()
michael@0 207 {
michael@0 208 // 1. generate a collision, and close the colliding entry first.
michael@0 209 var entry1 = asyncOpenCacheEntry(key1, nsICache.ACCESS_READ_WRITE);
michael@0 210 var data1 = key1;
michael@0 211 entry1.setMetaDataElement("size", data1.length);
michael@0 212 entry1.markValid();
michael@0 213 var output1 = entry1.transport.openOutputStream(0, -1, 0);
michael@0 214 output1.write(data1, data1.length);
michael@0 215
michael@0 216 var entry2 = asyncOpenCacheEntry(key2, nsICache.ACCESS_READ_WRITE);
michael@0 217 var data2 = key2;
michael@0 218 entry2.setMetaDataElement("size", data2.length);
michael@0 219 entry2.markValid();
michael@0 220 var output2 = entry2.transport.openOutputStream(0, -1, 0);
michael@0 221 output2.write(data2, data2.length);
michael@0 222
michael@0 223 output1.close();
michael@0 224 output2.close();
michael@0 225
michael@0 226 entry1.close();
michael@0 227 entry2.close();
michael@0 228 }
michael@0 229
michael@0 230 function median(array)
michael@0 231 {
michael@0 232 var cmp = function(x, y) { return x - y; }
michael@0 233 array.sort(cmp);
michael@0 234 var middle = Math.floor(array.length / 2);
michael@0 235 return array[middle];
michael@0 236 }
michael@0 237
michael@0 238 function sum(array)
michael@0 239 {
michael@0 240 var s = 0;
michael@0 241 var len = array.length;
michael@0 242 for (var i = 0; i < len; ++i)
michael@0 243 s += array[i];
michael@0 244 return s;
michael@0 245 }
michael@0 246
michael@0 247 function time()
michael@0 248 {
michael@0 249 var N = 50;
michael@0 250 var System = java.lang.System;
michael@0 251 var url = new java.net.URL("http://www.mozilla.org");
michael@0 252 var key = url.toString();
michael@0 253 var downloadTimes = new Array();
michael@0 254 for (var i = 0; i < N; ++i) {
michael@0 255 var begin = System.currentTimeMillis();
michael@0 256 download(url);
michael@0 257 var end = System.currentTimeMillis();
michael@0 258 downloadTimes.push(end - begin);
michael@0 259 }
michael@0 260 var downloadTotal = sum(downloadTimes);
michael@0 261 var downloadMean = downloadTotal / N;
michael@0 262 var downloadMedian = median(downloadTimes);
michael@0 263 print("" + N + " downloads took " + downloadTotal + " milliseconds.");
michael@0 264 print("mean = " + downloadMean + " milliseconds.");
michael@0 265 print("median = " + downloadMedian + " milliseconds.");
michael@0 266
michael@0 267 var readTimes = new Array();
michael@0 268 for (var i = 0; i < N; ++i) {
michael@0 269 var begin = System.currentTimeMillis();
michael@0 270 asyncRead(key);
michael@0 271 var end = System.currentTimeMillis();
michael@0 272 readTimes.push(end - begin);
michael@0 273 }
michael@0 274 var readTotal = sum(readTimes);
michael@0 275 var readMean = readTotal / N;
michael@0 276 var readMedian = median(readTimes);
michael@0 277 print("" + N + " reads took " + readTotal + " milliseconds.");
michael@0 278 print("mean = " + readMean + " milliseconds.");
michael@0 279 print("median = " + readMedian + " milliseconds.");
michael@0 280 }
michael@0 281
michael@0 282 // load the cache service before doing anything with Java...
michael@0 283 getCacheService();
michael@0 284
michael@0 285 if (DEBUG) {
michael@0 286 print("cache service loaded.");
michael@0 287 } else {
michael@0 288 print("running disk cache test.");
michael@0 289 test();
michael@0 290 print("disk cache test complete.");
michael@0 291 }

mercurial