netwerk/test/unit/test_filestreams.js

Wed, 31 Dec 2014 13:27:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 13:27:57 +0100
branch
TOR_BUG_3246
changeset 6
8bccb770b82d
permissions
-rw-r--r--

Ignore runtime configuration files generated during quality assurance.

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

mercurial