netwerk/test/unit/test_filestreams.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/netwerk/test/unit/test_filestreams.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,298 @@
     1.4 +/* Any copyright is dedicated to the Public Domain.
     1.5 +   http://creativecommons.org/publicdomain/zero/1.0/ */
     1.6 +
     1.7 +let Cc = Components.classes;
     1.8 +let Ci = Components.interfaces;
     1.9 +
    1.10 +// We need the profile directory so the test harness will clean up our test
    1.11 +// files.
    1.12 +do_get_profile();
    1.13 +
    1.14 +const OUTPUT_STREAM_CONTRACT_ID = "@mozilla.org/network/file-output-stream;1";
    1.15 +const SAFE_OUTPUT_STREAM_CONTRACT_ID = "@mozilla.org/network/safe-file-output-stream;1";
    1.16 +
    1.17 +////////////////////////////////////////////////////////////////////////////////
    1.18 +//// Helper Methods
    1.19 +
    1.20 +/**
    1.21 + * Generates a leafName for a file that does not exist, but does *not*
    1.22 + * create the file. Similar to createUnique except for the fact that createUnique
    1.23 + * does create the file.
    1.24 + *
    1.25 + * @param aFile
    1.26 + *        The file to modify in order for it to have a unique leafname.
    1.27 + */
    1.28 +function ensure_unique(aFile)
    1.29 +{
    1.30 +  ensure_unique.fileIndex = ensure_unique.fileIndex || 0;
    1.31 +
    1.32 +  var leafName = aFile.leafName;
    1.33 +  while (aFile.clone().exists()) {
    1.34 +    aFile.leafName = leafName + "_" + (ensure_unique.fileIndex++);
    1.35 +  }
    1.36 +}
    1.37 +
    1.38 +/**
    1.39 + * Tests for files being accessed at the right time. Streams that use
    1.40 + * DEFER_OPEN should only open or create the file when an operation is
    1.41 + * done, and not during Init().
    1.42 + *
    1.43 + * Note that for writing, we check for actual writing in test_NetUtil (async)
    1.44 + * and in sync_operations in this file (sync), whereas in this function we
    1.45 + * just check that the file is *not* created during init.
    1.46 + *
    1.47 + * @param aContractId
    1.48 + *        The contract ID to use for the output stream
    1.49 + * @param aDeferOpen
    1.50 + *        Whether to check with DEFER_OPEN or not
    1.51 + * @param aTrickDeferredOpen
    1.52 + *        Whether we try to 'trick' deferred opens by changing the file object before
    1.53 + *        the actual open. The stream should have a clone, so changes to the file
    1.54 + *        object after Init and before Open should not affect it.
    1.55 + */
    1.56 +function check_access(aContractId, aDeferOpen, aTrickDeferredOpen)
    1.57 +{
    1.58 +  const LEAF_NAME = "filestreams-test-file.tmp";
    1.59 +  const TRICKY_LEAF_NAME = "BetYouDidNotExpectThat.tmp";
    1.60 +  let file = Cc["@mozilla.org/file/directory_service;1"].
    1.61 +             getService(Ci.nsIProperties).
    1.62 +             get("ProfD", Ci.nsIFile);
    1.63 +  file.append(LEAF_NAME);
    1.64 +
    1.65 +  // Writing
    1.66 +
    1.67 +  ensure_unique(file);
    1.68 +  let ostream = Cc[aContractId].createInstance(Ci.nsIFileOutputStream);
    1.69 +  ostream.init(file, -1, -1, aDeferOpen ? Ci.nsIFileOutputStream.DEFER_OPEN : 0);
    1.70 +  do_check_eq(aDeferOpen, !file.clone().exists()); // If defer, should not exist and vice versa
    1.71 +  if (aDeferOpen) {
    1.72 +    // File should appear when we do write to it.
    1.73 +    if (aTrickDeferredOpen) {
    1.74 +      // See |@param aDeferOpen| in the JavaDoc comment for this function
    1.75 +      file.leafName = TRICKY_LEAF_NAME;
    1.76 +    }
    1.77 +    ostream.write("data", 4);
    1.78 +    if (aTrickDeferredOpen) {
    1.79 +      file.leafName = LEAF_NAME;
    1.80 +    }
    1.81 +    // We did a write, so the file should now exist
    1.82 +    do_check_true(file.clone().exists());
    1.83 +  }
    1.84 +  ostream.close();
    1.85 +
    1.86 +  // Reading
    1.87 +
    1.88 +  ensure_unique(file);
    1.89 +  let istream = Cc["@mozilla.org/network/file-input-stream;1"].
    1.90 +                createInstance(Ci.nsIFileInputStream);
    1.91 +  var initOk, getOk;
    1.92 +  try {
    1.93 +    istream.init(file, -1, 0, aDeferOpen ? Ci.nsIFileInputStream.DEFER_OPEN : 0);
    1.94 +    initOk = true;
    1.95 +  }
    1.96 +  catch(e) {
    1.97 +    initOk = false;
    1.98 +  }
    1.99 +  try {
   1.100 +    let fstream = Cc["@mozilla.org/network/file-input-stream;1"].
   1.101 +                  createInstance(Ci.nsIFileInputStream);
   1.102 +    fstream.init(aFile, -1, 0, 0);
   1.103 +    getOk = true;
   1.104 +  }
   1.105 +  catch(e) {
   1.106 +    getOk = false;
   1.107 +  }
   1.108 +
   1.109 +  // If the open is deferred, then Init should succeed even though the file we
   1.110 +  // intend to read does not exist, and then trying to read from it should
   1.111 +  // fail. The other case is where the open is not deferred, and there we should
   1.112 +  // get an error when we Init (and also when we try to read).
   1.113 +  do_check_true( (aDeferOpen && initOk && !getOk) ||
   1.114 +                 (!aDeferOpen && !initOk && !getOk) );
   1.115 +  istream.close();
   1.116 +}
   1.117 +
   1.118 +/**
   1.119 + * We test async operations in test_NetUtil.js, and here test for simple sync
   1.120 + * operations on input streams.
   1.121 + *
   1.122 + * @param aDeferOpen
   1.123 + *        Whether to use DEFER_OPEN in the streams.
   1.124 + */
   1.125 +function sync_operations(aDeferOpen)
   1.126 +{
   1.127 +  const TEST_DATA = "this is a test string";
   1.128 +  const LEAF_NAME = "filestreams-test-file.tmp";
   1.129 +
   1.130 +  let file = Cc["@mozilla.org/file/directory_service;1"].
   1.131 +             getService(Ci.nsIProperties).
   1.132 +             get("ProfD", Ci.nsIFile);
   1.133 +  file.append(LEAF_NAME);
   1.134 +  file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0666);
   1.135 +
   1.136 +  let ostream = Cc[OUTPUT_STREAM_CONTRACT_ID].
   1.137 +                createInstance(Ci.nsIFileOutputStream);
   1.138 +  ostream.init(file, -1, -1, aDeferOpen ? Ci.nsIFileOutputStream.DEFER_OPEN : 0);
   1.139 +
   1.140 +  ostream.write(TEST_DATA, TEST_DATA.length);
   1.141 +  ostream.close();
   1.142 +
   1.143 +  let fstream = Cc["@mozilla.org/network/file-input-stream;1"].
   1.144 +                createInstance(Ci.nsIFileInputStream);
   1.145 +  fstream.init(file, -1, 0, aDeferOpen ? Ci.nsIFileInputStream.DEFER_OPEN : 0);
   1.146 +
   1.147 +  let cstream = Cc["@mozilla.org/intl/converter-input-stream;1"].
   1.148 +                createInstance(Ci.nsIConverterInputStream);
   1.149 +  cstream.init(fstream, "UTF-8", 0, 0);
   1.150 +
   1.151 +  let string  = {};
   1.152 +  cstream.readString(-1, string);
   1.153 +  cstream.close();
   1.154 +  fstream.close();
   1.155 +
   1.156 +  do_check_eq(string.value, TEST_DATA);
   1.157 +}
   1.158 +
   1.159 +////////////////////////////////////////////////////////////////////////////////
   1.160 +//// Tests
   1.161 +
   1.162 +function test_access()
   1.163 +{
   1.164 +  check_access(OUTPUT_STREAM_CONTRACT_ID, false, false);
   1.165 +}
   1.166 +
   1.167 +function test_access_trick()
   1.168 +{
   1.169 +  check_access(OUTPUT_STREAM_CONTRACT_ID, false, true);
   1.170 +}
   1.171 +
   1.172 +function test_access_defer()
   1.173 +{
   1.174 +  check_access(OUTPUT_STREAM_CONTRACT_ID, true, false);
   1.175 +}
   1.176 +
   1.177 +function test_access_defer_trick()
   1.178 +{
   1.179 +  check_access(OUTPUT_STREAM_CONTRACT_ID, true, true);
   1.180 +}
   1.181 +
   1.182 +function test_access_safe()
   1.183 +{
   1.184 +  check_access(SAFE_OUTPUT_STREAM_CONTRACT_ID, false, false);
   1.185 +}
   1.186 +
   1.187 +function test_access_safe_trick()
   1.188 +{
   1.189 +  check_access(SAFE_OUTPUT_STREAM_CONTRACT_ID, false, true);
   1.190 +}
   1.191 +
   1.192 +function test_access_safe_defer()
   1.193 +{
   1.194 +  check_access(SAFE_OUTPUT_STREAM_CONTRACT_ID, true, false);
   1.195 +}
   1.196 +
   1.197 +function test_access_safe_defer_trick()
   1.198 +{
   1.199 +  check_access(SAFE_OUTPUT_STREAM_CONTRACT_ID, true, true);
   1.200 +}
   1.201 +
   1.202 +function test_sync_operations()
   1.203 +{
   1.204 +  sync_operations();
   1.205 +}
   1.206 +
   1.207 +function test_sync_operations_deferred()
   1.208 +{
   1.209 +  sync_operations(true);
   1.210 +}
   1.211 +
   1.212 +function do_test_zero_size_buffered(disableBuffering)
   1.213 +{
   1.214 +  const LEAF_NAME = "filestreams-test-file.tmp";
   1.215 +  const BUFFERSIZE = 4096;
   1.216 +
   1.217 +  let file = Cc["@mozilla.org/file/directory_service;1"].
   1.218 +             getService(Ci.nsIProperties).
   1.219 +             get("ProfD", Ci.nsIFile);
   1.220 +  file.append(LEAF_NAME);
   1.221 +  file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0666);
   1.222 +
   1.223 +  let fstream = Cc["@mozilla.org/network/file-input-stream;1"].
   1.224 +                createInstance(Ci.nsIFileInputStream);
   1.225 +  fstream.init(file, -1, 0,
   1.226 +               Ci.nsIFileInputStream.CLOSE_ON_EOF |
   1.227 +               Ci.nsIFileInputStream.REOPEN_ON_REWIND);
   1.228 +
   1.229 +  var buffered = Cc["@mozilla.org/network/buffered-input-stream;1"].
   1.230 +                   createInstance(Ci.nsIBufferedInputStream);
   1.231 +  buffered.init(fstream, BUFFERSIZE);
   1.232 +
   1.233 +  if (disableBuffering) {
   1.234 +      buffered.QueryInterface(Ci.nsIStreamBufferAccess).disableBuffering();
   1.235 +  }
   1.236 +
   1.237 +  // Scriptable input streams clamp read sizes to the return value of
   1.238 +  // available(), so don't quite do what we want here.
   1.239 +  let cstream = Cc["@mozilla.org/intl/converter-input-stream;1"].
   1.240 +                createInstance(Ci.nsIConverterInputStream);
   1.241 +  cstream.init(buffered, "UTF-8", 0, 0);
   1.242 +
   1.243 +  do_check_eq(buffered.available(), 0);
   1.244 +
   1.245 +  // Now try reading from this stream
   1.246 +  let string = {};
   1.247 +  do_check_eq(cstream.readString(BUFFERSIZE, string), 0);
   1.248 +  do_check_eq(string.value, "");
   1.249 +
   1.250 +  // Now check that available() throws
   1.251 +  var exceptionThrown = false;
   1.252 +  try {
   1.253 +    do_check_eq(buffered.available(), 0);
   1.254 +  } catch (e) {
   1.255 +    exceptionThrown = true;
   1.256 +  }
   1.257 +  do_check_true(exceptionThrown);
   1.258 +
   1.259 +  // OK, now seek back to start
   1.260 +  buffered.seek(Ci.nsISeekableStream.NS_SEEK_SET, 0);
   1.261 +
   1.262 +  // Now check that available() does not throw
   1.263 +  exceptionThrown = false;
   1.264 +  try {
   1.265 +    do_check_eq(buffered.available(), 0);
   1.266 +  } catch (e) {
   1.267 +    exceptionThrown = true;
   1.268 +  }
   1.269 +  do_check_false(exceptionThrown);
   1.270 +}
   1.271 +
   1.272 +function test_zero_size_buffered()
   1.273 +{
   1.274 +    do_test_zero_size_buffered(false);
   1.275 +    do_test_zero_size_buffered(true);
   1.276 +}
   1.277 +
   1.278 +////////////////////////////////////////////////////////////////////////////////
   1.279 +//// Test Runner
   1.280 +
   1.281 +let tests = [
   1.282 +  test_access,
   1.283 +  test_access_trick,
   1.284 +  test_access_defer,
   1.285 +  test_access_defer_trick,
   1.286 +  test_access_safe,
   1.287 +  test_access_safe_trick,
   1.288 +  test_access_safe_defer,
   1.289 +  test_access_safe_defer_trick,
   1.290 +  test_sync_operations,
   1.291 +  test_sync_operations_deferred,
   1.292 +  test_zero_size_buffered,
   1.293 +];
   1.294 +
   1.295 +function run_test()
   1.296 +{
   1.297 +  tests.forEach(function(test) {
   1.298 +    test();
   1.299 +  });
   1.300 +}
   1.301 +

mercurial