netwerk/test/unit/test_filestreams.js

Thu, 15 Jan 2015 21:03:48 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 21:03:48 +0100
branch
TOR_BUG_9701
changeset 11
deefc01c0e14
permissions
-rw-r--r--

Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)

michael@0 1 /* Any copyright is dedicated to the Public Domain.
michael@0 2 http://creativecommons.org/publicdomain/zero/1.0/ */
michael@0 3
michael@0 4 let Cc = Components.classes;
michael@0 5 let Ci = Components.interfaces;
michael@0 6
michael@0 7 // We need the profile directory so the test harness will clean up our test
michael@0 8 // files.
michael@0 9 do_get_profile();
michael@0 10
michael@0 11 const OUTPUT_STREAM_CONTRACT_ID = "@mozilla.org/network/file-output-stream;1";
michael@0 12 const SAFE_OUTPUT_STREAM_CONTRACT_ID = "@mozilla.org/network/safe-file-output-stream;1";
michael@0 13
michael@0 14 ////////////////////////////////////////////////////////////////////////////////
michael@0 15 //// Helper Methods
michael@0 16
michael@0 17 /**
michael@0 18 * Generates a leafName for a file that does not exist, but does *not*
michael@0 19 * create the file. Similar to createUnique except for the fact that createUnique
michael@0 20 * does create the file.
michael@0 21 *
michael@0 22 * @param aFile
michael@0 23 * The file to modify in order for it to have a unique leafname.
michael@0 24 */
michael@0 25 function ensure_unique(aFile)
michael@0 26 {
michael@0 27 ensure_unique.fileIndex = ensure_unique.fileIndex || 0;
michael@0 28
michael@0 29 var leafName = aFile.leafName;
michael@0 30 while (aFile.clone().exists()) {
michael@0 31 aFile.leafName = leafName + "_" + (ensure_unique.fileIndex++);
michael@0 32 }
michael@0 33 }
michael@0 34
michael@0 35 /**
michael@0 36 * Tests for files being accessed at the right time. Streams that use
michael@0 37 * DEFER_OPEN should only open or create the file when an operation is
michael@0 38 * done, and not during Init().
michael@0 39 *
michael@0 40 * Note that for writing, we check for actual writing in test_NetUtil (async)
michael@0 41 * and in sync_operations in this file (sync), whereas in this function we
michael@0 42 * just check that the file is *not* created during init.
michael@0 43 *
michael@0 44 * @param aContractId
michael@0 45 * The contract ID to use for the output stream
michael@0 46 * @param aDeferOpen
michael@0 47 * Whether to check with DEFER_OPEN or not
michael@0 48 * @param aTrickDeferredOpen
michael@0 49 * Whether we try to 'trick' deferred opens by changing the file object before
michael@0 50 * the actual open. The stream should have a clone, so changes to the file
michael@0 51 * object after Init and before Open should not affect it.
michael@0 52 */
michael@0 53 function check_access(aContractId, aDeferOpen, aTrickDeferredOpen)
michael@0 54 {
michael@0 55 const LEAF_NAME = "filestreams-test-file.tmp";
michael@0 56 const TRICKY_LEAF_NAME = "BetYouDidNotExpectThat.tmp";
michael@0 57 let file = Cc["@mozilla.org/file/directory_service;1"].
michael@0 58 getService(Ci.nsIProperties).
michael@0 59 get("ProfD", Ci.nsIFile);
michael@0 60 file.append(LEAF_NAME);
michael@0 61
michael@0 62 // Writing
michael@0 63
michael@0 64 ensure_unique(file);
michael@0 65 let ostream = Cc[aContractId].createInstance(Ci.nsIFileOutputStream);
michael@0 66 ostream.init(file, -1, -1, aDeferOpen ? Ci.nsIFileOutputStream.DEFER_OPEN : 0);
michael@0 67 do_check_eq(aDeferOpen, !file.clone().exists()); // If defer, should not exist and vice versa
michael@0 68 if (aDeferOpen) {
michael@0 69 // File should appear when we do write to it.
michael@0 70 if (aTrickDeferredOpen) {
michael@0 71 // See |@param aDeferOpen| in the JavaDoc comment for this function
michael@0 72 file.leafName = TRICKY_LEAF_NAME;
michael@0 73 }
michael@0 74 ostream.write("data", 4);
michael@0 75 if (aTrickDeferredOpen) {
michael@0 76 file.leafName = LEAF_NAME;
michael@0 77 }
michael@0 78 // We did a write, so the file should now exist
michael@0 79 do_check_true(file.clone().exists());
michael@0 80 }
michael@0 81 ostream.close();
michael@0 82
michael@0 83 // Reading
michael@0 84
michael@0 85 ensure_unique(file);
michael@0 86 let istream = Cc["@mozilla.org/network/file-input-stream;1"].
michael@0 87 createInstance(Ci.nsIFileInputStream);
michael@0 88 var initOk, getOk;
michael@0 89 try {
michael@0 90 istream.init(file, -1, 0, aDeferOpen ? Ci.nsIFileInputStream.DEFER_OPEN : 0);
michael@0 91 initOk = true;
michael@0 92 }
michael@0 93 catch(e) {
michael@0 94 initOk = false;
michael@0 95 }
michael@0 96 try {
michael@0 97 let fstream = Cc["@mozilla.org/network/file-input-stream;1"].
michael@0 98 createInstance(Ci.nsIFileInputStream);
michael@0 99 fstream.init(aFile, -1, 0, 0);
michael@0 100 getOk = true;
michael@0 101 }
michael@0 102 catch(e) {
michael@0 103 getOk = false;
michael@0 104 }
michael@0 105
michael@0 106 // If the open is deferred, then Init should succeed even though the file we
michael@0 107 // intend to read does not exist, and then trying to read from it should
michael@0 108 // fail. The other case is where the open is not deferred, and there we should
michael@0 109 // get an error when we Init (and also when we try to read).
michael@0 110 do_check_true( (aDeferOpen && initOk && !getOk) ||
michael@0 111 (!aDeferOpen && !initOk && !getOk) );
michael@0 112 istream.close();
michael@0 113 }
michael@0 114
michael@0 115 /**
michael@0 116 * We test async operations in test_NetUtil.js, and here test for simple sync
michael@0 117 * operations on input streams.
michael@0 118 *
michael@0 119 * @param aDeferOpen
michael@0 120 * Whether to use DEFER_OPEN in the streams.
michael@0 121 */
michael@0 122 function sync_operations(aDeferOpen)
michael@0 123 {
michael@0 124 const TEST_DATA = "this is a test string";
michael@0 125 const LEAF_NAME = "filestreams-test-file.tmp";
michael@0 126
michael@0 127 let file = Cc["@mozilla.org/file/directory_service;1"].
michael@0 128 getService(Ci.nsIProperties).
michael@0 129 get("ProfD", Ci.nsIFile);
michael@0 130 file.append(LEAF_NAME);
michael@0 131 file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0666);
michael@0 132
michael@0 133 let ostream = Cc[OUTPUT_STREAM_CONTRACT_ID].
michael@0 134 createInstance(Ci.nsIFileOutputStream);
michael@0 135 ostream.init(file, -1, -1, aDeferOpen ? Ci.nsIFileOutputStream.DEFER_OPEN : 0);
michael@0 136
michael@0 137 ostream.write(TEST_DATA, TEST_DATA.length);
michael@0 138 ostream.close();
michael@0 139
michael@0 140 let fstream = Cc["@mozilla.org/network/file-input-stream;1"].
michael@0 141 createInstance(Ci.nsIFileInputStream);
michael@0 142 fstream.init(file, -1, 0, aDeferOpen ? Ci.nsIFileInputStream.DEFER_OPEN : 0);
michael@0 143
michael@0 144 let cstream = Cc["@mozilla.org/intl/converter-input-stream;1"].
michael@0 145 createInstance(Ci.nsIConverterInputStream);
michael@0 146 cstream.init(fstream, "UTF-8", 0, 0);
michael@0 147
michael@0 148 let string = {};
michael@0 149 cstream.readString(-1, string);
michael@0 150 cstream.close();
michael@0 151 fstream.close();
michael@0 152
michael@0 153 do_check_eq(string.value, TEST_DATA);
michael@0 154 }
michael@0 155
michael@0 156 ////////////////////////////////////////////////////////////////////////////////
michael@0 157 //// Tests
michael@0 158
michael@0 159 function test_access()
michael@0 160 {
michael@0 161 check_access(OUTPUT_STREAM_CONTRACT_ID, false, false);
michael@0 162 }
michael@0 163
michael@0 164 function test_access_trick()
michael@0 165 {
michael@0 166 check_access(OUTPUT_STREAM_CONTRACT_ID, false, true);
michael@0 167 }
michael@0 168
michael@0 169 function test_access_defer()
michael@0 170 {
michael@0 171 check_access(OUTPUT_STREAM_CONTRACT_ID, true, false);
michael@0 172 }
michael@0 173
michael@0 174 function test_access_defer_trick()
michael@0 175 {
michael@0 176 check_access(OUTPUT_STREAM_CONTRACT_ID, true, true);
michael@0 177 }
michael@0 178
michael@0 179 function test_access_safe()
michael@0 180 {
michael@0 181 check_access(SAFE_OUTPUT_STREAM_CONTRACT_ID, false, false);
michael@0 182 }
michael@0 183
michael@0 184 function test_access_safe_trick()
michael@0 185 {
michael@0 186 check_access(SAFE_OUTPUT_STREAM_CONTRACT_ID, false, true);
michael@0 187 }
michael@0 188
michael@0 189 function test_access_safe_defer()
michael@0 190 {
michael@0 191 check_access(SAFE_OUTPUT_STREAM_CONTRACT_ID, true, false);
michael@0 192 }
michael@0 193
michael@0 194 function test_access_safe_defer_trick()
michael@0 195 {
michael@0 196 check_access(SAFE_OUTPUT_STREAM_CONTRACT_ID, true, true);
michael@0 197 }
michael@0 198
michael@0 199 function test_sync_operations()
michael@0 200 {
michael@0 201 sync_operations();
michael@0 202 }
michael@0 203
michael@0 204 function test_sync_operations_deferred()
michael@0 205 {
michael@0 206 sync_operations(true);
michael@0 207 }
michael@0 208
michael@0 209 function do_test_zero_size_buffered(disableBuffering)
michael@0 210 {
michael@0 211 const LEAF_NAME = "filestreams-test-file.tmp";
michael@0 212 const BUFFERSIZE = 4096;
michael@0 213
michael@0 214 let file = Cc["@mozilla.org/file/directory_service;1"].
michael@0 215 getService(Ci.nsIProperties).
michael@0 216 get("ProfD", Ci.nsIFile);
michael@0 217 file.append(LEAF_NAME);
michael@0 218 file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0666);
michael@0 219
michael@0 220 let fstream = Cc["@mozilla.org/network/file-input-stream;1"].
michael@0 221 createInstance(Ci.nsIFileInputStream);
michael@0 222 fstream.init(file, -1, 0,
michael@0 223 Ci.nsIFileInputStream.CLOSE_ON_EOF |
michael@0 224 Ci.nsIFileInputStream.REOPEN_ON_REWIND);
michael@0 225
michael@0 226 var buffered = Cc["@mozilla.org/network/buffered-input-stream;1"].
michael@0 227 createInstance(Ci.nsIBufferedInputStream);
michael@0 228 buffered.init(fstream, BUFFERSIZE);
michael@0 229
michael@0 230 if (disableBuffering) {
michael@0 231 buffered.QueryInterface(Ci.nsIStreamBufferAccess).disableBuffering();
michael@0 232 }
michael@0 233
michael@0 234 // Scriptable input streams clamp read sizes to the return value of
michael@0 235 // available(), so don't quite do what we want here.
michael@0 236 let cstream = Cc["@mozilla.org/intl/converter-input-stream;1"].
michael@0 237 createInstance(Ci.nsIConverterInputStream);
michael@0 238 cstream.init(buffered, "UTF-8", 0, 0);
michael@0 239
michael@0 240 do_check_eq(buffered.available(), 0);
michael@0 241
michael@0 242 // Now try reading from this stream
michael@0 243 let string = {};
michael@0 244 do_check_eq(cstream.readString(BUFFERSIZE, string), 0);
michael@0 245 do_check_eq(string.value, "");
michael@0 246
michael@0 247 // Now check that available() throws
michael@0 248 var exceptionThrown = false;
michael@0 249 try {
michael@0 250 do_check_eq(buffered.available(), 0);
michael@0 251 } catch (e) {
michael@0 252 exceptionThrown = true;
michael@0 253 }
michael@0 254 do_check_true(exceptionThrown);
michael@0 255
michael@0 256 // OK, now seek back to start
michael@0 257 buffered.seek(Ci.nsISeekableStream.NS_SEEK_SET, 0);
michael@0 258
michael@0 259 // Now check that available() does not throw
michael@0 260 exceptionThrown = false;
michael@0 261 try {
michael@0 262 do_check_eq(buffered.available(), 0);
michael@0 263 } catch (e) {
michael@0 264 exceptionThrown = true;
michael@0 265 }
michael@0 266 do_check_false(exceptionThrown);
michael@0 267 }
michael@0 268
michael@0 269 function test_zero_size_buffered()
michael@0 270 {
michael@0 271 do_test_zero_size_buffered(false);
michael@0 272 do_test_zero_size_buffered(true);
michael@0 273 }
michael@0 274
michael@0 275 ////////////////////////////////////////////////////////////////////////////////
michael@0 276 //// Test Runner
michael@0 277
michael@0 278 let tests = [
michael@0 279 test_access,
michael@0 280 test_access_trick,
michael@0 281 test_access_defer,
michael@0 282 test_access_defer_trick,
michael@0 283 test_access_safe,
michael@0 284 test_access_safe_trick,
michael@0 285 test_access_safe_defer,
michael@0 286 test_access_safe_defer_trick,
michael@0 287 test_sync_operations,
michael@0 288 test_sync_operations_deferred,
michael@0 289 test_zero_size_buffered,
michael@0 290 ];
michael@0 291
michael@0 292 function run_test()
michael@0 293 {
michael@0 294 tests.forEach(function(test) {
michael@0 295 test();
michael@0 296 });
michael@0 297 }
michael@0 298

mercurial