|
1 const CC = Components.Constructor; |
|
2 |
|
3 const StreamCopier = CC("@mozilla.org/network/async-stream-copier;1", |
|
4 "nsIAsyncStreamCopier", |
|
5 "init"); |
|
6 |
|
7 const ScriptableInputStream = CC("@mozilla.org/scriptableinputstream;1", |
|
8 "nsIScriptableInputStream", |
|
9 "init"); |
|
10 |
|
11 const Pipe = CC("@mozilla.org/pipe;1", |
|
12 "nsIPipe", |
|
13 "init"); |
|
14 |
|
15 var pipe1; |
|
16 var pipe2; |
|
17 var copier; |
|
18 var test_result; |
|
19 var test_content; |
|
20 var test_source_closed; |
|
21 var test_sink_closed; |
|
22 var test_nr; |
|
23 |
|
24 var copyObserver = |
|
25 { |
|
26 onStartRequest: function(request, context) { }, |
|
27 |
|
28 onStopRequest: function(request, cx, statusCode) |
|
29 { |
|
30 // check status code |
|
31 do_check_eq(statusCode, test_result); |
|
32 |
|
33 // check number of copied bytes |
|
34 do_check_eq(pipe2.inputStream.available(), test_content.length); |
|
35 |
|
36 // check content |
|
37 var scinp = new ScriptableInputStream(pipe2.inputStream); |
|
38 var content = scinp.read(scinp.available()); |
|
39 do_check_eq(content, test_content); |
|
40 |
|
41 // check closed sink |
|
42 try { |
|
43 pipe2.outputStream.write("closedSinkTest", 14); |
|
44 do_check_false(test_sink_closed); |
|
45 } |
|
46 catch (ex) { |
|
47 do_check_true(test_sink_closed); |
|
48 } |
|
49 |
|
50 // check closed source |
|
51 try { |
|
52 pipe1.outputStream.write("closedSourceTest", 16); |
|
53 do_check_false(test_source_closed); |
|
54 } |
|
55 catch (ex) { |
|
56 do_check_true(test_source_closed); |
|
57 } |
|
58 |
|
59 do_timeout(0, do_test); |
|
60 }, |
|
61 |
|
62 QueryInterface: function(aIID) |
|
63 { |
|
64 if (aIID.equals(Ci.nsIRequestObserver) || |
|
65 aIID.equals(Ci.nsISupports)) |
|
66 return this; |
|
67 |
|
68 throw Cr.NS_ERROR_NO_INTERFACE; |
|
69 } |
|
70 }; |
|
71 |
|
72 function startCopier(closeSource, closeSink) { |
|
73 pipe1 = new Pipe(true /* nonBlockingInput */, |
|
74 true /* nonBlockingOutput */, |
|
75 0 /* segmentSize */, |
|
76 0xffffffff /* segmentCount */, |
|
77 null /* segmentAllocator */); |
|
78 |
|
79 pipe2 = new Pipe(true /* nonBlockingInput */, |
|
80 true /* nonBlockingOutput */, |
|
81 0 /* segmentSize */, |
|
82 0xffffffff /* segmentCount */, |
|
83 null /* segmentAllocator */); |
|
84 |
|
85 copier = new StreamCopier(pipe1.inputStream /* aSource */, |
|
86 pipe2.outputStream /* aSink */, |
|
87 null /* aTarget */, |
|
88 true /* aSourceBuffered */, |
|
89 true /* aSinkBuffered */, |
|
90 8192 /* aChunkSize */, |
|
91 closeSource /* aCloseSource */, |
|
92 closeSink /* aCloseSink */); |
|
93 |
|
94 copier.asyncCopy(copyObserver, null); |
|
95 } |
|
96 |
|
97 function do_test() { |
|
98 |
|
99 test_nr++; |
|
100 test_content = "test" + test_nr; |
|
101 |
|
102 switch (test_nr) { |
|
103 case 1: |
|
104 case 2: // close sink |
|
105 case 3: // close source |
|
106 case 4: // close both |
|
107 // test canceling transfer |
|
108 // use some undefined error code to check if it is successfully passed |
|
109 // to the request observer |
|
110 test_result = 0x87654321; |
|
111 |
|
112 test_source_closed = ((test_nr-1)>>1 != 0); |
|
113 test_sink_closed = ((test_nr-1)%2 != 0); |
|
114 |
|
115 startCopier(test_source_closed, test_sink_closed); |
|
116 pipe1.outputStream.write(test_content, test_content.length); |
|
117 pipe1.outputStream.flush(); |
|
118 do_timeout(20, |
|
119 function(){ |
|
120 copier.cancel(test_result); |
|
121 pipe1.outputStream.write("a", 1);}); |
|
122 break; |
|
123 case 5: |
|
124 case 6: // close sink |
|
125 case 7: // close source |
|
126 case 8: // close both |
|
127 // test copying with EOF on source |
|
128 test_result = 0; |
|
129 |
|
130 test_source_closed = ((test_nr-5)>>1 != 0); |
|
131 test_sink_closed = ((test_nr-5)%2 != 0); |
|
132 |
|
133 startCopier(test_source_closed, test_sink_closed); |
|
134 pipe1.outputStream.write(test_content, test_content.length); |
|
135 // we will close the source |
|
136 test_source_closed = true; |
|
137 pipe1.outputStream.close(); |
|
138 break; |
|
139 case 9: |
|
140 case 10: // close sink |
|
141 case 11: // close source |
|
142 case 12: // close both |
|
143 // test copying with error on sink |
|
144 // use some undefined error code to check if it is successfully passed |
|
145 // to the request observer |
|
146 test_result = 0x87654321; |
|
147 |
|
148 test_source_closed = ((test_nr-9)>>1 != 0); |
|
149 test_sink_closed = ((test_nr-9)%2 != 0); |
|
150 |
|
151 startCopier(test_source_closed, test_sink_closed); |
|
152 pipe1.outputStream.write(test_content, test_content.length); |
|
153 pipe1.outputStream.flush(); |
|
154 // we will close the sink |
|
155 test_sink_closed = true; |
|
156 do_timeout(20, |
|
157 function() |
|
158 { |
|
159 pipe2.outputStream |
|
160 .QueryInterface(Ci.nsIAsyncOutputStream) |
|
161 .closeWithStatus(test_result); |
|
162 pipe1.outputStream.write("a", 1);}); |
|
163 break; |
|
164 case 13: |
|
165 do_test_finished(); |
|
166 break; |
|
167 } |
|
168 } |
|
169 |
|
170 function run_test() { |
|
171 test_nr = 0; |
|
172 do_timeout(0, do_test); |
|
173 do_test_pending(); |
|
174 } |