test_nsIBufferedOutputStream_writeFrom_block.js (7617B)
1 "use strict"; 2 3 var CC = Components.Constructor; 4 5 var Pipe = CC("@mozilla.org/pipe;1", Ci.nsIPipe, "init"); 6 var BufferedOutputStream = CC( 7 "@mozilla.org/network/buffered-output-stream;1", 8 Ci.nsIBufferedOutputStream, 9 "init" 10 ); 11 var ScriptableInputStream = CC( 12 "@mozilla.org/scriptableinputstream;1", 13 Ci.nsIScriptableInputStream, 14 "init" 15 ); 16 17 // Verify that pipes behave as we expect. Subsequent tests assume 18 // pipes behave as demonstrated here. 19 add_test(function checkWouldBlockPipe() { 20 // Create a pipe with a one-byte buffer 21 var pipe = new Pipe(true, true, 1, 1); 22 23 // Writing two bytes should transfer only one byte, and 24 // return a partial count, not would-block. 25 Assert.equal(pipe.outputStream.write("xy", 2), 1); 26 Assert.equal(pipe.inputStream.available(), 1); 27 28 do_check_throws_nsIException( 29 () => pipe.outputStream.write("y", 1), 30 "NS_BASE_STREAM_WOULD_BLOCK" 31 ); 32 33 // Check that nothing was written to the pipe. 34 Assert.equal(pipe.inputStream.available(), 1); 35 run_next_test(); 36 }); 37 38 // A writeFrom to a buffered stream should return 39 // NS_BASE_STREAM_WOULD_BLOCK if no data was written. 40 add_test(function writeFromBlocksImmediately() { 41 // Create a full pipe for our output stream. This will 'would-block' when 42 // written to. 43 var outPipe = new Pipe(true, true, 1, 1); 44 Assert.equal(outPipe.outputStream.write("x", 1), 1); 45 46 // Create a buffered stream, and fill its buffer, so the next write will 47 // try to flush. 48 var buffered = new BufferedOutputStream(outPipe.outputStream, 10); 49 Assert.equal(buffered.write("0123456789", 10), 10); 50 51 // Create a pipe with some data to be our input stream for the writeFrom 52 // call. 53 var inPipe = new Pipe(true, true, 1, 1); 54 Assert.equal(inPipe.outputStream.write("y", 1), 1); 55 56 Assert.equal(inPipe.inputStream.available(), 1); 57 do_check_throws_nsIException( 58 () => buffered.writeFrom(inPipe.inputStream, 1), 59 "NS_BASE_STREAM_WOULD_BLOCK" 60 ); 61 62 // No data should have been consumed from the pipe. 63 Assert.equal(inPipe.inputStream.available(), 1); 64 65 run_next_test(); 66 }); 67 68 // A writeFrom to a buffered stream should return a partial count if any 69 // data is written, when the last Flush call can only flush a portion of 70 // the data. 71 add_test(function writeFromReturnsPartialCountOnPartialFlush() { 72 // Create a pipe for our output stream. This will accept five bytes, and 73 // then 'would-block'. 74 var outPipe = new Pipe(true, true, 5, 1); 75 76 // Create a reference to the pipe's readable end that can be used 77 // from JavaScript. 78 var outPipeReadable = new ScriptableInputStream(outPipe.inputStream); 79 80 // Create a buffered stream whose buffer is too large to be flushed 81 // entirely to the output pipe. 82 var buffered = new BufferedOutputStream(outPipe.outputStream, 7); 83 84 // Create a pipe to be our input stream for the writeFrom call. 85 var inPipe = new Pipe(true, true, 15, 1); 86 87 // Write some data to our input pipe, for the rest of the test to consume. 88 Assert.equal(inPipe.outputStream.write("0123456789abcde", 15), 15); 89 Assert.equal(inPipe.inputStream.available(), 15); 90 91 // Write from the input pipe to the buffered stream. The buffered stream 92 // will fill its seven-byte buffer; and then the flush will only succeed 93 // in writing five bytes to the output pipe. The writeFrom call should 94 // return the number of bytes it consumed from inputStream. 95 Assert.equal(buffered.writeFrom(inPipe.inputStream, 11), 7); 96 Assert.equal(outPipe.inputStream.available(), 5); 97 Assert.equal(inPipe.inputStream.available(), 8); 98 99 // The partially-successful Flush should have created five bytes of 100 // available space in the buffered stream's buffer, so we should be able 101 // to write five bytes to it without blocking. 102 Assert.equal(buffered.writeFrom(inPipe.inputStream, 5), 5); 103 Assert.equal(outPipe.inputStream.available(), 5); 104 Assert.equal(inPipe.inputStream.available(), 3); 105 106 // Attempting to write any more data should would-block. 107 do_check_throws_nsIException( 108 () => buffered.writeFrom(inPipe.inputStream, 1), 109 "NS_BASE_STREAM_WOULD_BLOCK" 110 ); 111 112 // No data should have been consumed from the pipe. 113 Assert.equal(inPipe.inputStream.available(), 3); 114 115 // Push the rest of the data through, checking that it all came through. 116 Assert.equal(outPipeReadable.available(), 5); 117 Assert.equal(outPipeReadable.read(5), "01234"); 118 // Flush returns NS_ERROR_FAILURE if it can't transfer the full amount. 119 do_check_throws_nsIException(() => buffered.flush(), "NS_ERROR_FAILURE"); 120 Assert.equal(outPipeReadable.available(), 5); 121 Assert.equal(outPipeReadable.read(5), "56789"); 122 buffered.flush(); 123 Assert.equal(outPipeReadable.available(), 2); 124 Assert.equal(outPipeReadable.read(2), "ab"); 125 Assert.equal(buffered.writeFrom(inPipe.inputStream, 3), 3); 126 buffered.flush(); 127 Assert.equal(outPipeReadable.available(), 3); 128 Assert.equal(outPipeReadable.read(3), "cde"); 129 130 run_next_test(); 131 }); 132 133 // A writeFrom to a buffered stream should return a partial count if any 134 // data is written, when the last Flush call blocks. 135 add_test(function writeFromReturnsPartialCountOnBlock() { 136 // Create a pipe for our output stream. This will accept five bytes, and 137 // then 'would-block'. 138 var outPipe = new Pipe(true, true, 5, 1); 139 140 // Create a reference to the pipe's readable end that can be used 141 // from JavaScript. 142 var outPipeReadable = new ScriptableInputStream(outPipe.inputStream); 143 144 // Create a buffered stream whose buffer is too large to be flushed 145 // entirely to the output pipe. 146 var buffered = new BufferedOutputStream(outPipe.outputStream, 7); 147 148 // Create a pipe to be our input stream for the writeFrom call. 149 var inPipe = new Pipe(true, true, 15, 1); 150 151 // Write some data to our input pipe, for the rest of the test to consume. 152 Assert.equal(inPipe.outputStream.write("0123456789abcde", 15), 15); 153 Assert.equal(inPipe.inputStream.available(), 15); 154 155 // Write enough from the input pipe to the buffered stream to fill the 156 // output pipe's buffer, and then flush it. Nothing should block or fail, 157 // but the output pipe should now be full. 158 Assert.equal(buffered.writeFrom(inPipe.inputStream, 5), 5); 159 buffered.flush(); 160 Assert.equal(outPipe.inputStream.available(), 5); 161 Assert.equal(inPipe.inputStream.available(), 10); 162 163 // Now try to write more from the input pipe than the buffered stream's 164 // buffer can hold. It will attempt to flush, but the output pipe will 165 // would-block without accepting any data. writeFrom should return the 166 // correct partial count. 167 Assert.equal(buffered.writeFrom(inPipe.inputStream, 10), 7); 168 Assert.equal(outPipe.inputStream.available(), 5); 169 Assert.equal(inPipe.inputStream.available(), 3); 170 171 // Attempting to write any more data should would-block. 172 do_check_throws_nsIException( 173 () => buffered.writeFrom(inPipe.inputStream, 3), 174 "NS_BASE_STREAM_WOULD_BLOCK" 175 ); 176 177 // No data should have been consumed from the pipe. 178 Assert.equal(inPipe.inputStream.available(), 3); 179 180 // Push the rest of the data through, checking that it all came through. 181 Assert.equal(outPipeReadable.available(), 5); 182 Assert.equal(outPipeReadable.read(5), "01234"); 183 // Flush returns NS_ERROR_FAILURE if it can't transfer the full amount. 184 do_check_throws_nsIException(() => buffered.flush(), "NS_ERROR_FAILURE"); 185 Assert.equal(outPipeReadable.available(), 5); 186 Assert.equal(outPipeReadable.read(5), "56789"); 187 Assert.equal(buffered.writeFrom(inPipe.inputStream, 3), 3); 188 buffered.flush(); 189 Assert.equal(outPipeReadable.available(), 5); 190 Assert.equal(outPipeReadable.read(5), "abcde"); 191 192 run_next_test(); 193 });