Save errno for logging before potentially overwriting it.
[chromium-blink-merge.git] / content / browser / byte_stream_unittest.cc
blobaac69050b8747b27154604ed152ccb76e0356d78
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/byte_stream.h"
7 #include <deque>
9 #include "base/bind.h"
10 #include "base/callback.h"
11 #include "base/memory/ref_counted.h"
12 #include "base/message_loop.h"
13 #include "base/test/test_simple_task_runner.h"
14 #include "net/base/io_buffer.h"
15 #include "testing/gtest/include/gtest/gtest.h"
17 namespace content {
18 namespace {
20 void CountCallbacks(int* counter) {
21 ++*counter;
24 } // namespace
26 class ByteStreamTest : public testing::Test {
27 public:
28 ByteStreamTest();
30 // Create a new IO buffer of the given |buffer_size|. Details of the
31 // contents of the created buffer will be kept, and can be validated
32 // by ValidateIOBuffer.
33 scoped_refptr<net::IOBuffer> NewIOBuffer(size_t buffer_size) {
34 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(buffer_size));
35 char *bufferp = buffer->data();
36 for (size_t i = 0; i < buffer_size; i++)
37 bufferp[i] = (i + producing_seed_key_) % (1 << sizeof(char));
38 pointer_queue_.push_back(bufferp);
39 length_queue_.push_back(buffer_size);
40 ++producing_seed_key_;
41 return buffer;
44 // Create an IOBuffer of the appropriate size and add it to the
45 // ByteStream, returning the result of the ByteStream::Write.
46 // Separate function to avoid duplication of buffer_size in test
47 // calls.
48 bool Write(ByteStreamWriter* byte_stream_input, size_t buffer_size) {
49 return byte_stream_input->Write(NewIOBuffer(buffer_size), buffer_size);
52 // Validate that we have the IOBuffer we expect. This routine must be
53 // called on buffers that were allocated from NewIOBuffer, and in the
54 // order that they were allocated. Calls to NewIOBuffer &&
55 // ValidateIOBuffer may be interleaved.
56 bool ValidateIOBuffer(
57 scoped_refptr<net::IOBuffer> buffer, size_t buffer_size) {
58 char *bufferp = buffer->data();
60 char *expected_ptr = pointer_queue_.front();
61 size_t expected_length = length_queue_.front();
62 pointer_queue_.pop_front();
63 length_queue_.pop_front();
64 ++consuming_seed_key_;
66 EXPECT_EQ(expected_ptr, bufferp);
67 if (expected_ptr != bufferp)
68 return false;
70 EXPECT_EQ(expected_length, buffer_size);
71 if (expected_length != buffer_size)
72 return false;
74 for (size_t i = 0; i < buffer_size; i++) {
75 // Already incremented, so subtract one from the key.
76 EXPECT_EQ(static_cast<int>((i + consuming_seed_key_ - 1)
77 % (1 << sizeof(char))),
78 bufferp[i]);
79 if (static_cast<int>((i + consuming_seed_key_ - 1) %
80 (1 << sizeof(char))) != bufferp[i]) {
81 return false;
84 return true;
87 protected:
88 base::MessageLoop message_loop_;
90 private:
91 int producing_seed_key_;
92 int consuming_seed_key_;
93 std::deque<char*> pointer_queue_;
94 std::deque<size_t> length_queue_;
97 ByteStreamTest::ByteStreamTest()
98 : producing_seed_key_(0),
99 consuming_seed_key_(0) { }
101 // Confirm that filling and emptying the stream works properly, and that
102 // we get full triggers when we expect.
103 TEST_F(ByteStreamTest, ByteStream_PushBack) {
104 scoped_ptr<ByteStreamWriter> byte_stream_input;
105 scoped_ptr<ByteStreamReader> byte_stream_output;
106 CreateByteStream(
107 message_loop_.message_loop_proxy(), message_loop_.message_loop_proxy(),
108 3 * 1024, &byte_stream_input, &byte_stream_output);
110 // Push a series of IO buffers on; test pushback happening and
111 // that it's advisory.
112 EXPECT_TRUE(Write(byte_stream_input.get(), 1024));
113 EXPECT_TRUE(Write(byte_stream_input.get(), 1024));
114 EXPECT_TRUE(Write(byte_stream_input.get(), 1024));
115 EXPECT_FALSE(Write(byte_stream_input.get(), 1));
116 EXPECT_FALSE(Write(byte_stream_input.get(), 1024));
117 // Flush
118 byte_stream_input->Close(DOWNLOAD_INTERRUPT_REASON_NONE);
119 message_loop_.RunUntilIdle();
121 // Pull the IO buffers out; do we get the same buffers and do they
122 // have the same contents?
123 scoped_refptr<net::IOBuffer> output_io_buffer;
124 size_t output_length;
125 EXPECT_EQ(ByteStreamReader::STREAM_HAS_DATA,
126 byte_stream_output->Read(&output_io_buffer, &output_length));
127 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
129 EXPECT_EQ(ByteStreamReader::STREAM_HAS_DATA,
130 byte_stream_output->Read(&output_io_buffer, &output_length));
131 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
133 EXPECT_EQ(ByteStreamReader::STREAM_HAS_DATA,
134 byte_stream_output->Read(&output_io_buffer, &output_length));
135 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
137 EXPECT_EQ(ByteStreamReader::STREAM_HAS_DATA,
138 byte_stream_output->Read(&output_io_buffer, &output_length));
139 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
141 EXPECT_EQ(ByteStreamReader::STREAM_HAS_DATA,
142 byte_stream_output->Read(&output_io_buffer, &output_length));
143 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
145 EXPECT_EQ(ByteStreamReader::STREAM_COMPLETE,
146 byte_stream_output->Read(&output_io_buffer, &output_length));
149 // Same as above, only use knowledge of the internals to confirm
150 // that we're getting pushback even when data's split across the two
151 // objects
152 TEST_F(ByteStreamTest, ByteStream_PushBackSplit) {
153 scoped_ptr<ByteStreamWriter> byte_stream_input;
154 scoped_ptr<ByteStreamReader> byte_stream_output;
155 CreateByteStream(
156 message_loop_.message_loop_proxy(), message_loop_.message_loop_proxy(),
157 9 * 1024, &byte_stream_input, &byte_stream_output);
159 // Push a series of IO buffers on; test pushback happening and
160 // that it's advisory.
161 EXPECT_TRUE(Write(byte_stream_input.get(), 1024));
162 message_loop_.RunUntilIdle();
163 EXPECT_TRUE(Write(byte_stream_input.get(), 1024));
164 message_loop_.RunUntilIdle();
165 EXPECT_TRUE(Write(byte_stream_input.get(), 1024));
166 message_loop_.RunUntilIdle();
167 EXPECT_TRUE(Write(byte_stream_input.get(), 1024));
168 message_loop_.RunUntilIdle();
169 EXPECT_FALSE(Write(byte_stream_input.get(), 6 * 1024));
170 message_loop_.RunUntilIdle();
172 // Pull the IO buffers out; do we get the same buffers and do they
173 // have the same contents?
174 scoped_refptr<net::IOBuffer> output_io_buffer;
175 size_t output_length;
176 EXPECT_EQ(ByteStreamReader::STREAM_HAS_DATA,
177 byte_stream_output->Read(&output_io_buffer, &output_length));
178 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
180 EXPECT_EQ(ByteStreamReader::STREAM_HAS_DATA,
181 byte_stream_output->Read(&output_io_buffer, &output_length));
182 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
184 EXPECT_EQ(ByteStreamReader::STREAM_HAS_DATA,
185 byte_stream_output->Read(&output_io_buffer, &output_length));
186 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
188 EXPECT_EQ(ByteStreamReader::STREAM_HAS_DATA,
189 byte_stream_output->Read(&output_io_buffer, &output_length));
190 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
192 EXPECT_EQ(ByteStreamReader::STREAM_HAS_DATA,
193 byte_stream_output->Read(&output_io_buffer, &output_length));
194 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
196 EXPECT_EQ(ByteStreamReader::STREAM_EMPTY,
197 byte_stream_output->Read(&output_io_buffer, &output_length));
200 // Confirm that a Close() notification transmits in-order
201 // with data on the stream.
202 TEST_F(ByteStreamTest, ByteStream_CompleteTransmits) {
203 scoped_ptr<ByteStreamWriter> byte_stream_input;
204 scoped_ptr<ByteStreamReader> byte_stream_output;
206 scoped_refptr<net::IOBuffer> output_io_buffer;
207 size_t output_length;
209 // Empty stream, non-error case.
210 CreateByteStream(
211 message_loop_.message_loop_proxy(), message_loop_.message_loop_proxy(),
212 3 * 1024, &byte_stream_input, &byte_stream_output);
213 EXPECT_EQ(ByteStreamReader::STREAM_EMPTY,
214 byte_stream_output->Read(&output_io_buffer, &output_length));
215 byte_stream_input->Close(DOWNLOAD_INTERRUPT_REASON_NONE);
216 message_loop_.RunUntilIdle();
217 ASSERT_EQ(ByteStreamReader::STREAM_COMPLETE,
218 byte_stream_output->Read(&output_io_buffer, &output_length));
219 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
220 byte_stream_output->GetStatus());
222 // Non-empty stream, non-error case.
223 CreateByteStream(
224 message_loop_.message_loop_proxy(), message_loop_.message_loop_proxy(),
225 3 * 1024, &byte_stream_input, &byte_stream_output);
226 EXPECT_EQ(ByteStreamReader::STREAM_EMPTY,
227 byte_stream_output->Read(&output_io_buffer, &output_length));
228 EXPECT_TRUE(Write(byte_stream_input.get(), 1024));
229 byte_stream_input->Close(DOWNLOAD_INTERRUPT_REASON_NONE);
230 message_loop_.RunUntilIdle();
231 EXPECT_EQ(ByteStreamReader::STREAM_HAS_DATA,
232 byte_stream_output->Read(&output_io_buffer, &output_length));
233 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
234 ASSERT_EQ(ByteStreamReader::STREAM_COMPLETE,
235 byte_stream_output->Read(&output_io_buffer, &output_length));
236 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
237 byte_stream_output->GetStatus());
239 // Empty stream, non-error case.
240 CreateByteStream(
241 message_loop_.message_loop_proxy(), message_loop_.message_loop_proxy(),
242 3 * 1024, &byte_stream_input, &byte_stream_output);
243 EXPECT_EQ(ByteStreamReader::STREAM_EMPTY,
244 byte_stream_output->Read(&output_io_buffer, &output_length));
245 byte_stream_input->Close(DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED);
246 message_loop_.RunUntilIdle();
247 ASSERT_EQ(ByteStreamReader::STREAM_COMPLETE,
248 byte_stream_output->Read(&output_io_buffer, &output_length));
249 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED,
250 byte_stream_output->GetStatus());
252 // Non-empty stream, non-error case.
253 CreateByteStream(
254 message_loop_.message_loop_proxy(), message_loop_.message_loop_proxy(),
255 3 * 1024, &byte_stream_input, &byte_stream_output);
256 EXPECT_EQ(ByteStreamReader::STREAM_EMPTY,
257 byte_stream_output->Read(&output_io_buffer, &output_length));
258 EXPECT_TRUE(Write(byte_stream_input.get(), 1024));
259 byte_stream_input->Close(DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED);
260 message_loop_.RunUntilIdle();
261 EXPECT_EQ(ByteStreamReader::STREAM_HAS_DATA,
262 byte_stream_output->Read(&output_io_buffer, &output_length));
263 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
264 ASSERT_EQ(ByteStreamReader::STREAM_COMPLETE,
265 byte_stream_output->Read(&output_io_buffer, &output_length));
266 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED,
267 byte_stream_output->GetStatus());
270 // Confirm that callbacks on the sink side are triggered when they should be.
271 TEST_F(ByteStreamTest, ByteStream_SinkCallback) {
272 scoped_refptr<base::TestSimpleTaskRunner> task_runner(
273 new base::TestSimpleTaskRunner());
275 scoped_ptr<ByteStreamWriter> byte_stream_input;
276 scoped_ptr<ByteStreamReader> byte_stream_output;
277 CreateByteStream(
278 message_loop_.message_loop_proxy(), task_runner,
279 10000, &byte_stream_input, &byte_stream_output);
281 scoped_refptr<net::IOBuffer> output_io_buffer;
282 size_t output_length;
284 // Note that the specifics of when the callbacks are called with regard
285 // to how much data is pushed onto the stream is not (currently) part
286 // of the interface contract. If it becomes part of the contract, the
287 // tests below should get much more precise.
289 // Confirm callback called when you add more than 33% of the buffer.
291 // Setup callback
292 int num_callbacks = 0;
293 byte_stream_output->RegisterCallback(
294 base::Bind(CountCallbacks, &num_callbacks));
296 EXPECT_TRUE(Write(byte_stream_input.get(), 4000));
297 message_loop_.RunUntilIdle();
299 EXPECT_EQ(0, num_callbacks);
300 task_runner->RunUntilIdle();
301 EXPECT_EQ(1, num_callbacks);
303 // Check data and stream state.
304 EXPECT_EQ(ByteStreamReader::STREAM_HAS_DATA,
305 byte_stream_output->Read(&output_io_buffer, &output_length));
306 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
307 EXPECT_EQ(ByteStreamReader::STREAM_EMPTY,
308 byte_stream_output->Read(&output_io_buffer, &output_length));
310 // Confirm callback *isn't* called at less than 33% (by lack of
311 // unexpected call on task runner).
312 EXPECT_TRUE(Write(byte_stream_input.get(), 3000));
313 message_loop_.RunUntilIdle();
315 // This reflects an implementation artifact that data goes with callbacks,
316 // which should not be considered part of the interface guarantee.
317 EXPECT_EQ(ByteStreamReader::STREAM_EMPTY,
318 byte_stream_output->Read(&output_io_buffer, &output_length));
321 // Confirm that callbacks on the source side are triggered when they should
322 // be.
323 TEST_F(ByteStreamTest, ByteStream_SourceCallback) {
324 scoped_refptr<base::TestSimpleTaskRunner> task_runner(
325 new base::TestSimpleTaskRunner());
327 scoped_ptr<ByteStreamWriter> byte_stream_input;
328 scoped_ptr<ByteStreamReader> byte_stream_output;
329 CreateByteStream(
330 task_runner, message_loop_.message_loop_proxy(),
331 10000, &byte_stream_input, &byte_stream_output);
333 scoped_refptr<net::IOBuffer> output_io_buffer;
334 size_t output_length;
336 // Note that the specifics of when the callbacks are called with regard
337 // to how much data is pulled from the stream is not (currently) part
338 // of the interface contract. If it becomes part of the contract, the
339 // tests below should get much more precise.
341 // Confirm callback called when about 33% space available, and not
342 // at other transitions.
344 // Add data.
345 int num_callbacks = 0;
346 byte_stream_input->RegisterCallback(
347 base::Bind(CountCallbacks, &num_callbacks));
348 EXPECT_TRUE(Write(byte_stream_input.get(), 2000));
349 EXPECT_TRUE(Write(byte_stream_input.get(), 2001));
350 EXPECT_FALSE(Write(byte_stream_input.get(), 6000));
352 // Allow bytes to transition (needed for message passing implementation),
353 // and get and validate the data.
354 message_loop_.RunUntilIdle();
355 EXPECT_EQ(ByteStreamReader::STREAM_HAS_DATA,
356 byte_stream_output->Read(&output_io_buffer, &output_length));
357 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
359 // Grab data, triggering callback. Recorded on dispatch, but doesn't
360 // happen because it's caught by the mock.
361 EXPECT_EQ(ByteStreamReader::STREAM_HAS_DATA,
362 byte_stream_output->Read(&output_io_buffer, &output_length));
363 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
365 // Confirm that the callback passed to the mock does what we expect.
366 EXPECT_EQ(0, num_callbacks);
367 task_runner->RunUntilIdle();
368 EXPECT_EQ(1, num_callbacks);
370 // Same drill with final buffer.
371 EXPECT_EQ(ByteStreamReader::STREAM_HAS_DATA,
372 byte_stream_output->Read(&output_io_buffer, &output_length));
373 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
374 EXPECT_EQ(ByteStreamReader::STREAM_EMPTY,
375 byte_stream_output->Read(&output_io_buffer, &output_length));
376 EXPECT_EQ(1, num_callbacks);
377 task_runner->RunUntilIdle();
378 // Should have updated the internal structures but not called the
379 // callback.
380 EXPECT_EQ(1, num_callbacks);
383 // Confirm that racing a change to a sink callback with a post results
384 // in the new callback being called.
385 TEST_F(ByteStreamTest, ByteStream_SinkInterrupt) {
386 scoped_refptr<base::TestSimpleTaskRunner> task_runner(
387 new base::TestSimpleTaskRunner());
389 scoped_ptr<ByteStreamWriter> byte_stream_input;
390 scoped_ptr<ByteStreamReader> byte_stream_output;
391 CreateByteStream(
392 message_loop_.message_loop_proxy(), task_runner,
393 10000, &byte_stream_input, &byte_stream_output);
395 scoped_refptr<net::IOBuffer> output_io_buffer;
396 size_t output_length;
397 base::Closure intermediate_callback;
399 // Record initial state.
400 int num_callbacks = 0;
401 byte_stream_output->RegisterCallback(
402 base::Bind(CountCallbacks, &num_callbacks));
404 // Add data, and pass it across.
405 EXPECT_TRUE(Write(byte_stream_input.get(), 4000));
406 message_loop_.RunUntilIdle();
408 // The task runner should have been hit, but the callback count
409 // isn't changed until we actually run the callback.
410 EXPECT_EQ(0, num_callbacks);
412 // If we change the callback now, the new one should be run
413 // (simulates race with post task).
414 int num_alt_callbacks = 0;
415 byte_stream_output->RegisterCallback(
416 base::Bind(CountCallbacks, &num_alt_callbacks));
417 task_runner->RunUntilIdle();
418 EXPECT_EQ(0, num_callbacks);
419 EXPECT_EQ(1, num_alt_callbacks);
421 // Final cleanup.
422 EXPECT_EQ(ByteStreamReader::STREAM_HAS_DATA,
423 byte_stream_output->Read(&output_io_buffer, &output_length));
424 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
425 EXPECT_EQ(ByteStreamReader::STREAM_EMPTY,
426 byte_stream_output->Read(&output_io_buffer, &output_length));
430 // Confirm that racing a change to a source callback with a post results
431 // in the new callback being called.
432 TEST_F(ByteStreamTest, ByteStream_SourceInterrupt) {
433 scoped_refptr<base::TestSimpleTaskRunner> task_runner(
434 new base::TestSimpleTaskRunner());
436 scoped_ptr<ByteStreamWriter> byte_stream_input;
437 scoped_ptr<ByteStreamReader> byte_stream_output;
438 CreateByteStream(
439 task_runner, message_loop_.message_loop_proxy(),
440 10000, &byte_stream_input, &byte_stream_output);
442 scoped_refptr<net::IOBuffer> output_io_buffer;
443 size_t output_length;
444 base::Closure intermediate_callback;
446 // Setup state for test.
447 int num_callbacks = 0;
448 byte_stream_input->RegisterCallback(
449 base::Bind(CountCallbacks, &num_callbacks));
450 EXPECT_TRUE(Write(byte_stream_input.get(), 2000));
451 EXPECT_TRUE(Write(byte_stream_input.get(), 2001));
452 EXPECT_FALSE(Write(byte_stream_input.get(), 6000));
453 message_loop_.RunUntilIdle();
455 // Initial get should not trigger callback.
456 EXPECT_EQ(ByteStreamReader::STREAM_HAS_DATA,
457 byte_stream_output->Read(&output_io_buffer, &output_length));
458 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
459 message_loop_.RunUntilIdle();
461 // Second get *should* trigger callback.
462 EXPECT_EQ(ByteStreamReader::STREAM_HAS_DATA,
463 byte_stream_output->Read(&output_io_buffer, &output_length));
464 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
466 // Which should do the right thing when it's run.
467 int num_alt_callbacks = 0;
468 byte_stream_input->RegisterCallback(
469 base::Bind(CountCallbacks, &num_alt_callbacks));
470 task_runner->RunUntilIdle();
471 EXPECT_EQ(0, num_callbacks);
472 EXPECT_EQ(1, num_alt_callbacks);
474 // Third get should also trigger callback.
475 EXPECT_EQ(ByteStreamReader::STREAM_HAS_DATA,
476 byte_stream_output->Read(&output_io_buffer, &output_length));
477 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
478 EXPECT_EQ(ByteStreamReader::STREAM_EMPTY,
479 byte_stream_output->Read(&output_io_buffer, &output_length));
482 // Confirm that callback is called on zero data transfer but source
483 // complete.
484 TEST_F(ByteStreamTest, ByteStream_ZeroCallback) {
485 scoped_refptr<base::TestSimpleTaskRunner> task_runner(
486 new base::TestSimpleTaskRunner());
488 scoped_ptr<ByteStreamWriter> byte_stream_input;
489 scoped_ptr<ByteStreamReader> byte_stream_output;
490 CreateByteStream(
491 message_loop_.message_loop_proxy(), task_runner,
492 10000, &byte_stream_input, &byte_stream_output);
494 base::Closure intermediate_callback;
496 // Record initial state.
497 int num_callbacks = 0;
498 byte_stream_output->RegisterCallback(
499 base::Bind(CountCallbacks, &num_callbacks));
501 // Immediately close the stream.
502 byte_stream_input->Close(DOWNLOAD_INTERRUPT_REASON_NONE);
503 task_runner->RunUntilIdle();
504 EXPECT_EQ(1, num_callbacks);
507 } // namespace content