1 /* Any copyright is dedicated to the Public Domain.
2 http://creativecommons.org/publicdomain/zero/1.0/ */
6 // We need the profile directory so the test harness will clean up our test
10 const OUTPUT_STREAM_CONTRACT_ID = "@mozilla.org/network/file-output-stream;1";
11 const SAFE_OUTPUT_STREAM_CONTRACT_ID =
12 "@mozilla.org/network/safe-file-output-stream;1";
14 ////////////////////////////////////////////////////////////////////////////////
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.
23 * The file to modify in order for it to have a unique leafname.
25 function ensure_unique(aFile) {
26 ensure_unique.fileIndex = ensure_unique.fileIndex || 0;
28 var leafName = aFile.leafName;
29 while (aFile.clone().exists()) {
30 aFile.leafName = leafName + "_" + ensure_unique.fileIndex++;
35 * Tests for files being accessed at the right time. Streams that use
36 * DEFER_OPEN should only open or create the file when an operation is
37 * done, and not during Init().
39 * Note that for writing, we check for actual writing in test_NetUtil (async)
40 * and in sync_operations in this file (sync), whereas in this function we
41 * just check that the file is *not* created during init.
44 * The contract ID to use for the output stream
46 * Whether to check with DEFER_OPEN or not
47 * @param aTrickDeferredOpen
48 * Whether we try to 'trick' deferred opens by changing the file object before
49 * the actual open. The stream should have a clone, so changes to the file
50 * object after Init and before Open should not affect it.
52 function check_access(aContractId, aDeferOpen, aTrickDeferredOpen) {
53 const LEAF_NAME = "filestreams-test-file.tmp";
54 const TRICKY_LEAF_NAME = "BetYouDidNotExpectThat.tmp";
55 let file = Services.dirsvc.get("ProfD", Ci.nsIFile);
56 file.append(LEAF_NAME);
61 let ostream = Cc[aContractId].createInstance(Ci.nsIFileOutputStream);
66 aDeferOpen ? Ci.nsIFileOutputStream.DEFER_OPEN : 0
68 Assert.equal(aDeferOpen, !file.clone().exists()); // If defer, should not exist and vice versa
70 // File should appear when we do write to it.
71 if (aTrickDeferredOpen) {
72 // See |@param aDeferOpen| in the JavaDoc comment for this function
73 file.leafName = TRICKY_LEAF_NAME;
75 ostream.write("data", 4);
76 if (aTrickDeferredOpen) {
77 file.leafName = LEAF_NAME;
79 // We did a write, so the file should now exist
80 Assert.ok(file.clone().exists());
87 let istream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(
96 aDeferOpen ? Ci.nsIFileInputStream.DEFER_OPEN : 0
103 let fstream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(
104 Ci.nsIFileInputStream
106 fstream.init(file, -1, 0, 0);
112 // If the open is deferred, then Init should succeed even though the file we
113 // intend to read does not exist, and then trying to read from it should
114 // fail. The other case is where the open is not deferred, and there we should
115 // get an error when we Init (and also when we try to read).
117 (aDeferOpen && initOk && !getOk) || (!aDeferOpen && !initOk && !getOk)
123 * We test async operations in test_NetUtil.js, and here test for simple sync
124 * operations on input streams.
127 * Whether to use DEFER_OPEN in the streams.
129 function sync_operations(aDeferOpen) {
130 const TEST_DATA = "this is a test string";
131 const LEAF_NAME = "filestreams-test-file.tmp";
133 let file = Services.dirsvc.get("ProfD", Ci.nsIFile);
134 file.append(LEAF_NAME);
135 file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o666);
137 let ostream = Cc[OUTPUT_STREAM_CONTRACT_ID].createInstance(
138 Ci.nsIFileOutputStream
144 aDeferOpen ? Ci.nsIFileOutputStream.DEFER_OPEN : 0
147 ostream.write(TEST_DATA, TEST_DATA.length);
150 let fstream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(
151 Ci.nsIFileInputStream
153 fstream.init(file, -1, 0, aDeferOpen ? Ci.nsIFileInputStream.DEFER_OPEN : 0);
155 let cstream = Cc["@mozilla.org/intl/converter-input-stream;1"].createInstance(
156 Ci.nsIConverterInputStream
158 cstream.init(fstream, "UTF-8", 0, 0);
161 cstream.readString(-1, string);
165 Assert.equal(string.value, TEST_DATA);
168 ////////////////////////////////////////////////////////////////////////////////
171 function test_access() {
172 check_access(OUTPUT_STREAM_CONTRACT_ID, false, false);
175 function test_access_trick() {
176 check_access(OUTPUT_STREAM_CONTRACT_ID, false, true);
179 function test_access_defer() {
180 check_access(OUTPUT_STREAM_CONTRACT_ID, true, false);
183 function test_access_defer_trick() {
184 check_access(OUTPUT_STREAM_CONTRACT_ID, true, true);
187 function test_access_safe() {
188 check_access(SAFE_OUTPUT_STREAM_CONTRACT_ID, false, false);
191 function test_access_safe_trick() {
192 check_access(SAFE_OUTPUT_STREAM_CONTRACT_ID, false, true);
195 function test_access_safe_defer() {
196 check_access(SAFE_OUTPUT_STREAM_CONTRACT_ID, true, false);
199 function test_access_safe_defer_trick() {
200 check_access(SAFE_OUTPUT_STREAM_CONTRACT_ID, true, true);
203 function test_sync_operations() {
207 function test_sync_operations_deferred() {
208 sync_operations(true);
211 function do_test_zero_size_buffered(disableBuffering) {
212 const LEAF_NAME = "filestreams-test-file.tmp";
213 const BUFFERSIZE = 4096;
215 let file = Services.dirsvc.get("ProfD", Ci.nsIFile);
216 file.append(LEAF_NAME);
217 file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o666);
219 let fstream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(
220 Ci.nsIFileInputStream
226 Ci.nsIFileInputStream.CLOSE_ON_EOF | Ci.nsIFileInputStream.REOPEN_ON_REWIND
230 "@mozilla.org/network/buffered-input-stream;1"
231 ].createInstance(Ci.nsIBufferedInputStream);
232 buffered.init(fstream, BUFFERSIZE);
234 if (disableBuffering) {
235 buffered.QueryInterface(Ci.nsIStreamBufferAccess).disableBuffering();
238 // Scriptable input streams clamp read sizes to the return value of
239 // available(), so don't quite do what we want here.
240 let cstream = Cc["@mozilla.org/intl/converter-input-stream;1"].createInstance(
241 Ci.nsIConverterInputStream
243 cstream.init(buffered, "UTF-8", 0, 0);
245 Assert.equal(buffered.available(), 0);
247 // Now try reading from this stream
249 Assert.equal(cstream.readString(BUFFERSIZE, string), 0);
250 Assert.equal(string.value, "");
252 // Now check that available() throws
253 var exceptionThrown = false;
255 Assert.equal(buffered.available(), 0);
257 exceptionThrown = true;
259 Assert.ok(exceptionThrown);
261 // OK, now seek back to start
262 buffered.seek(Ci.nsISeekableStream.NS_SEEK_SET, 0);
264 // Now check that available() does not throw
265 exceptionThrown = false;
267 Assert.equal(buffered.available(), 0);
269 exceptionThrown = true;
271 Assert.ok(!exceptionThrown);
274 function test_zero_size_buffered() {
275 do_test_zero_size_buffered(false);
276 do_test_zero_size_buffered(true);
279 ////////////////////////////////////////////////////////////////////////////////
286 test_access_defer_trick,
288 test_access_safe_trick,
289 test_access_safe_defer,
290 test_access_safe_defer_trick,
291 test_sync_operations,
292 test_sync_operations_deferred,
293 test_zero_size_buffered,
296 function run_test() {
297 tests.forEach(function (test) {