Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(194)

Side by Side Diff: content/browser/download/byte_stream_unittest.cc

Issue 10244001: Creation of ByteStream class. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed bug with zero length writes. Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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.
4
5 #include "content/browser/download/byte_stream.h"
6
7 #include <deque>
8
9 #include "base/bind.h"
10 #include "base/callback.h"
11 #include "base/location.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/message_loop.h"
14 #include "base/task_runner.h"
15 #include "net/base/io_buffer.h"
16 #include "testing/gmock/include/gmock/gmock.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18
19 using ::testing::_;
20 using ::testing::Return;
21 using ::testing::SaveArg;
22 using ::testing::StrictMock;
23
24 namespace tracked_objects {
25 class Location;
26 }
27
28 namespace {
29
30 class MockTaskRunner : public base::SequencedTaskRunner {
31 public:
32 MockTaskRunner();
33
34 // TaskRunner functions.
35 MOCK_METHOD3(PostDelayedTask, bool(const tracked_objects::Location&,
36 const base::Closure&, int64));
37 MOCK_METHOD3(PostDelayedTask, bool(const tracked_objects::Location&,
38 const base::Closure&, base::TimeDelta));
39
40 MOCK_METHOD3(PostNonNestableDelayedTask, bool(
41 const tracked_objects::Location&,
42 const base::Closure&,
43 int64 delay_ms));
44
45 MOCK_METHOD3(PostNonNestableDelayedTask, bool(
46 const tracked_objects::Location&,
47 const base::Closure&,
48 base::TimeDelta));
49
50 MOCK_CONST_METHOD0(RunsTasksOnCurrentThread, bool());
51
52 protected:
53 ~MockTaskRunner();
54 };
55
56 MockTaskRunner::MockTaskRunner() { }
57
58 MockTaskRunner::~MockTaskRunner() { }
59
60 void CountCallbacks(int* counter) {
61 ++*counter;
62 }
63
64 } // namespace
65
66 class ByteStreamTest : public testing::Test {
67 public:
68 ByteStreamTest();
69
70 // Create a new IO buffer of the given |buffer_size|. Details of the
71 // contents of the created buffer will be kept, and can be validated
72 // by ValidateIOBuffer.
73 scoped_refptr<net::IOBuffer> NewIOBuffer(size_t buffer_size) {
74 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(buffer_size));
75 char *bufferp = buffer->data();
76 for (size_t i = 0; i < buffer_size; i++)
77 bufferp[i] = (i + producing_seed_key_) % (1 << sizeof(char));
78 pointer_queue_.push_back(bufferp);
79 length_queue_.push_back(buffer_size);
80 ++producing_seed_key_;
81 return buffer;
82 }
83
84 // Create an IOBuffer of the appropriate size and add it to the
85 // ByteStream, returning the result of the ByteStream::Write.
86 // Separate function to avoid duplication of buffer_size in test
87 // calls.
88 bool Write(content::ByteStreamInput* byte_stream_input,
89 size_t buffer_size) {
90 return byte_stream_input->Write(NewIOBuffer(buffer_size), buffer_size);
91 }
92
93 // Validate that we have the IOBuffer we expect. This routine must be
94 // called on buffers that were allocated from NewIOBuffer, and in the
95 // order that they were allocated. Calls to NewIOBuffer &&
96 // ValidateIOBuffer may be interleaved.
97 bool ValidateIOBuffer(
98 scoped_refptr<net::IOBuffer> buffer, size_t buffer_size) {
99 char *bufferp = buffer->data();
100
101 char *expected_ptr = pointer_queue_.front();
102 size_t expected_length = length_queue_.front();
103 pointer_queue_.pop_front();
104 length_queue_.pop_front();
105 ++consuming_seed_key_;
106
107 EXPECT_EQ(expected_ptr, bufferp);
108 if (expected_ptr != bufferp)
109 return false;
110
111 EXPECT_EQ(expected_length, buffer_size);
112 if (expected_length != buffer_size)
113 return false;
114
115 for (size_t i = 0; i < buffer_size; i++) {
116 // Already incremented, so subtract one from the key.
117 EXPECT_EQ(static_cast<int>((i + consuming_seed_key_ - 1)
118 % (1 << sizeof(char))),
119 bufferp[i]);
120 if (static_cast<int>((i + consuming_seed_key_ - 1) %
121 (1 << sizeof(char))) != bufferp[i]) {
122 return false;
123 }
124 }
125 return true;
126 }
127
128 protected:
129 MessageLoop message_loop_;
130
131 private:
132 int producing_seed_key_;
133 int consuming_seed_key_;
134 std::deque<char*> pointer_queue_;
135 std::deque<size_t> length_queue_;
136 };
137
138 ByteStreamTest::ByteStreamTest()
139 : producing_seed_key_(0),
140 consuming_seed_key_(0) { }
141
142 // Confirm that filling and emptying the pipe works properly, and that
143 // we get full triggers when we expect.
144 TEST_F(ByteStreamTest, ByteStream_PushBack) {
145 scoped_ptr<content::ByteStreamInput> byte_stream_input;
146 scoped_ptr<content::ByteStreamOutput> byte_stream_output;
147 content::CreateByteStream(
148 message_loop_.message_loop_proxy(), message_loop_.message_loop_proxy(),
149 3 * 1024, &byte_stream_input, &byte_stream_output);
150
151 // Push a series of IO buffers on; test pushback happening and
152 // that it's advisory.
153 EXPECT_TRUE(Write(byte_stream_input.get(), 1024));
154 EXPECT_TRUE(Write(byte_stream_input.get(), 1024));
155 EXPECT_TRUE(Write(byte_stream_input.get(), 1024));
156 EXPECT_FALSE(Write(byte_stream_input.get(), 1));
157 EXPECT_FALSE(Write(byte_stream_input.get(), 1024));
158 // Flush
159 byte_stream_input->Close(content::DOWNLOAD_INTERRUPT_REASON_NONE);
160 message_loop_.RunAllPending();
161
162 // Pull the IO buffers out; do we get the same buffers and do they
163 // have the same contents?
164 scoped_refptr<net::IOBuffer> output_io_buffer;
165 size_t output_length;
166 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
167 byte_stream_output->Read(&output_io_buffer, &output_length));
168 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
169
170 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
171 byte_stream_output->Read(&output_io_buffer, &output_length));
172 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
173
174 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
175 byte_stream_output->Read(&output_io_buffer, &output_length));
176 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
177
178 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
179 byte_stream_output->Read(&output_io_buffer, &output_length));
180 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
181
182 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
183 byte_stream_output->Read(&output_io_buffer, &output_length));
184 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
185
186 EXPECT_EQ(content::ByteStreamOutput::STREAM_COMPLETE,
187 byte_stream_output->Read(&output_io_buffer, &output_length));
188 }
189
190 // Same as above, only use knowledge of the internals to confirm
191 // that we're getting pushback even when data's split across the two
192 // objects
193 TEST_F(ByteStreamTest, ByteStream_PushBackSplit) {
194 scoped_ptr<content::ByteStreamInput> byte_stream_input;
195 scoped_ptr<content::ByteStreamOutput> byte_stream_output;
196 content::CreateByteStream(
197 message_loop_.message_loop_proxy(), message_loop_.message_loop_proxy(),
198 9 * 1024, &byte_stream_input, &byte_stream_output);
199
200 // Push a series of IO buffers on; test pushback happening and
201 // that it's advisory.
202 EXPECT_TRUE(Write(byte_stream_input.get(), 1024));
203 message_loop_.RunAllPending();
204 EXPECT_TRUE(Write(byte_stream_input.get(), 1024));
205 message_loop_.RunAllPending();
206 EXPECT_TRUE(Write(byte_stream_input.get(), 1024));
207 message_loop_.RunAllPending();
208 EXPECT_TRUE(Write(byte_stream_input.get(), 1024));
209 message_loop_.RunAllPending();
210 EXPECT_FALSE(Write(byte_stream_input.get(), 6 * 1024));
211 message_loop_.RunAllPending();
212
213 // Pull the IO buffers out; do we get the same buffers and do they
214 // have the same contents?
215 scoped_refptr<net::IOBuffer> output_io_buffer;
216 size_t output_length;
217 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
218 byte_stream_output->Read(&output_io_buffer, &output_length));
219 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
220
221 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
222 byte_stream_output->Read(&output_io_buffer, &output_length));
223 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
224
225 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
226 byte_stream_output->Read(&output_io_buffer, &output_length));
227 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
228
229 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
230 byte_stream_output->Read(&output_io_buffer, &output_length));
231 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
232
233 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
234 byte_stream_output->Read(&output_io_buffer, &output_length));
235 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
236
237 EXPECT_EQ(content::ByteStreamOutput::STREAM_EMPTY,
238 byte_stream_output->Read(&output_io_buffer, &output_length));
239 }
240
241 // Confirm that a Close() notification transmits in-order
242 // with data on the pipe.
243 TEST_F(ByteStreamTest, ByteStream_CompleteTransmits) {
244 scoped_ptr<content::ByteStreamInput> byte_stream_input;
245 scoped_ptr<content::ByteStreamOutput> byte_stream_output;
246
247 scoped_refptr<net::IOBuffer> output_io_buffer;
248 size_t output_length;
249
250 // Empty stream, non-error case.
251 content::CreateByteStream(
252 message_loop_.message_loop_proxy(), message_loop_.message_loop_proxy(),
253 3 * 1024, &byte_stream_input, &byte_stream_output);
254 EXPECT_EQ(content::ByteStreamOutput::STREAM_EMPTY,
255 byte_stream_output->Read(&output_io_buffer, &output_length));
256 byte_stream_input->Close(content::DOWNLOAD_INTERRUPT_REASON_NONE);
257 message_loop_.RunAllPending();
258 ASSERT_EQ(content::ByteStreamOutput::STREAM_COMPLETE,
259 byte_stream_output->Read(&output_io_buffer, &output_length));
260 EXPECT_EQ(content::DOWNLOAD_INTERRUPT_REASON_NONE,
261 byte_stream_output->GetStatus());
262
263 // Non-empty stream, non-error case.
264 content::CreateByteStream(
265 message_loop_.message_loop_proxy(), message_loop_.message_loop_proxy(),
266 3 * 1024, &byte_stream_input, &byte_stream_output);
267 EXPECT_EQ(content::ByteStreamOutput::STREAM_EMPTY,
268 byte_stream_output->Read(&output_io_buffer, &output_length));
269 EXPECT_TRUE(Write(byte_stream_input.get(), 1024));
270 byte_stream_input->Close(content::DOWNLOAD_INTERRUPT_REASON_NONE);
271 message_loop_.RunAllPending();
272 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
273 byte_stream_output->Read(&output_io_buffer, &output_length));
274 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
275 ASSERT_EQ(content::ByteStreamOutput::STREAM_COMPLETE,
276 byte_stream_output->Read(&output_io_buffer, &output_length));
277 EXPECT_EQ(content::DOWNLOAD_INTERRUPT_REASON_NONE,
278 byte_stream_output->GetStatus());
279
280 // Empty stream, non-error case.
281 content::CreateByteStream(
282 message_loop_.message_loop_proxy(), message_loop_.message_loop_proxy(),
283 3 * 1024, &byte_stream_input, &byte_stream_output);
284 EXPECT_EQ(content::ByteStreamOutput::STREAM_EMPTY,
285 byte_stream_output->Read(&output_io_buffer, &output_length));
286 byte_stream_input->Close(
287 content::DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED);
288 message_loop_.RunAllPending();
289 ASSERT_EQ(content::ByteStreamOutput::STREAM_COMPLETE,
290 byte_stream_output->Read(&output_io_buffer, &output_length));
291 EXPECT_EQ(content::DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED,
292 byte_stream_output->GetStatus());
293
294 // Non-empty stream, non-error case.
295 content::CreateByteStream(
296 message_loop_.message_loop_proxy(), message_loop_.message_loop_proxy(),
297 3 * 1024, &byte_stream_input, &byte_stream_output);
298 EXPECT_EQ(content::ByteStreamOutput::STREAM_EMPTY,
299 byte_stream_output->Read(&output_io_buffer, &output_length));
300 EXPECT_TRUE(Write(byte_stream_input.get(), 1024));
301 byte_stream_input->Close(
302 content::DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED);
303 message_loop_.RunAllPending();
304 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
305 byte_stream_output->Read(&output_io_buffer, &output_length));
306 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
307 ASSERT_EQ(content::ByteStreamOutput::STREAM_COMPLETE,
308 byte_stream_output->Read(&output_io_buffer, &output_length));
309 EXPECT_EQ(content::DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED,
310 byte_stream_output->GetStatus());
311 }
312
313 // Confirm that callbacks on the sink side are triggered when they should be.
314 TEST_F(ByteStreamTest, ByteStream_SinkCallback) {
315 scoped_refptr<MockTaskRunner> task_runner(new StrictMock<MockTaskRunner>());
316
317 scoped_ptr<content::ByteStreamInput> byte_stream_input;
318 scoped_ptr<content::ByteStreamOutput> byte_stream_output;
319 content::CreateByteStream(
320 message_loop_.message_loop_proxy(), task_runner,
321 10000, &byte_stream_input, &byte_stream_output);
322
323 scoped_refptr<net::IOBuffer> output_io_buffer;
324 size_t output_length;
325 base::Closure intermediate_callback;
326
327 // Note that the specifics of when the callbacks are called with regard
328 // to how much data is pushed onto the pipe is not (currently) part
329 // of the interface contract. If it becomes part of the contract, the
330 // tests below should get much more precise.
331
332 // Confirm callback called when you add more than 33% of the buffer.
333
334 // Setup callback
335 int num_callbacks = 0;
336 byte_stream_output->RegisterCallback(
337 base::Bind(CountCallbacks, &num_callbacks));
338 EXPECT_CALL(*task_runner.get(), PostDelayedTask(_, _, 0))
339 .WillOnce(DoAll(SaveArg<1>(&intermediate_callback),
340 Return(true)));
341
342 EXPECT_TRUE(Write(byte_stream_input.get(), 4000));
343 message_loop_.RunAllPending();
344
345 // Check callback results match expectations.
346 ::testing::Mock::VerifyAndClearExpectations(task_runner.get());
347 EXPECT_EQ(0, num_callbacks);
348 intermediate_callback.Run();
349 EXPECT_EQ(1, num_callbacks);
350
351 // Check data and stream state.
352 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
353 byte_stream_output->Read(&output_io_buffer, &output_length));
354 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
355 EXPECT_EQ(content::ByteStreamOutput::STREAM_EMPTY,
356 byte_stream_output->Read(&output_io_buffer, &output_length));
357
358 // Confirm callback *isn't* called at less than 33% (by lack of
359 // unexpected call on task runner).
360 EXPECT_TRUE(Write(byte_stream_input.get(), 3000));
361 message_loop_.RunAllPending();
362
363 // This reflects an implementation artifact that data goes with callbacks,
364 // which should not be considered part of the interface guarantee.
365 EXPECT_EQ(content::ByteStreamOutput::STREAM_EMPTY,
366 byte_stream_output->Read(&output_io_buffer, &output_length));
367 }
368
369 // Confirm that callbacks on the source side are triggered when they should
370 // be.
371 TEST_F(ByteStreamTest, ByteStream_SourceCallback) {
372 scoped_refptr<MockTaskRunner> task_runner(new StrictMock<MockTaskRunner>());
373
374 scoped_ptr<content::ByteStreamInput> byte_stream_input;
375 scoped_ptr<content::ByteStreamOutput> byte_stream_output;
376 content::CreateByteStream(
377 task_runner, message_loop_.message_loop_proxy(),
378 10000, &byte_stream_input, &byte_stream_output);
379
380 scoped_refptr<net::IOBuffer> output_io_buffer;
381 size_t output_length;
382 base::Closure intermediate_callback;
383
384 // Note that the specifics of when the callbacks are called with regard
385 // to how much data is pulled from the pipe is not (currently) part
386 // of the interface contract. If it becomes part of the contract, the
387 // tests below should get much more precise.
388
389 // Confirm callback called when about 33% space available, and not
390 // at other transitions.
391
392 // Setup expectations and add data.
393 int num_callbacks = 0;
394 byte_stream_input->RegisterCallback(
395 base::Bind(CountCallbacks, &num_callbacks));
396 EXPECT_TRUE(Write(byte_stream_input.get(), 2000));
397 EXPECT_TRUE(Write(byte_stream_input.get(), 2001));
398 EXPECT_FALSE(Write(byte_stream_input.get(), 6000));
399
400 // Allow bytes to transition (needed for message passing implementation),
401 // and get and validate the data.
402 message_loop_.RunAllPending();
403 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
404 byte_stream_output->Read(&output_io_buffer, &output_length));
405 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
406
407 // Setup expectations.
408 EXPECT_CALL(*task_runner.get(), PostDelayedTask(_, _, 0))
409 .WillOnce(DoAll(SaveArg<1>(&intermediate_callback),
410 Return(true)));
411
412 // Grab data, triggering callback. Recorded on dispatch, but doesn't
413 // happen because it's caught by the mock.
414 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
415 byte_stream_output->Read(&output_io_buffer, &output_length));
416 ::testing::Mock::VerifyAndClearExpectations(task_runner.get());
417 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
418
419 // Confirm that the callback passed to the mock does what we expect.
420 EXPECT_EQ(0, num_callbacks);
421 intermediate_callback.Run();
422 EXPECT_EQ(1, num_callbacks);
423
424 // Same drill with final buffer.
425 EXPECT_CALL(*task_runner.get(), PostDelayedTask(_, _, 0))
426 .WillOnce(DoAll(SaveArg<1>(&intermediate_callback),
427 Return(true)));
428 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
429 byte_stream_output->Read(&output_io_buffer, &output_length));
430 ::testing::Mock::VerifyAndClearExpectations(task_runner.get());
431 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
432 EXPECT_EQ(content::ByteStreamOutput::STREAM_EMPTY,
433 byte_stream_output->Read(&output_io_buffer, &output_length));
434 EXPECT_EQ(1, num_callbacks);
435 intermediate_callback.Run();
436 // Should have updated the internal structures but not called the
437 // callback.
438 EXPECT_EQ(1, num_callbacks);
439 }
440
441 // Confirm that racing a change to a sink callback with a post results
442 // in the new callback being called.
443 TEST_F(ByteStreamTest, ByteStream_SinkInterrupt) {
444 scoped_refptr<MockTaskRunner> task_runner(new StrictMock<MockTaskRunner>());
445
446 scoped_ptr<content::ByteStreamInput> byte_stream_input;
447 scoped_ptr<content::ByteStreamOutput> byte_stream_output;
448 content::CreateByteStream(
449 message_loop_.message_loop_proxy(), task_runner,
450 10000, &byte_stream_input, &byte_stream_output);
451
452 scoped_refptr<net::IOBuffer> output_io_buffer;
453 size_t output_length;
454 base::Closure intermediate_callback;
455
456 // Setup expectations and record initial state.
457 int num_callbacks = 0;
458 byte_stream_output->RegisterCallback(
459 base::Bind(CountCallbacks, &num_callbacks));
460 EXPECT_CALL(*task_runner.get(), PostDelayedTask(_, _, 0))
461 .WillOnce(DoAll(SaveArg<1>(&intermediate_callback),
462 Return(true)));
463
464 // Add data, and pass it across.
465 EXPECT_TRUE(Write(byte_stream_input.get(), 4000));
466 message_loop_.RunAllPending();
467
468 // The task runner should have been hit, but the callback count
469 // isn't changed until we actually run the callback.
470 ::testing::Mock::VerifyAndClearExpectations(task_runner.get());
471 EXPECT_EQ(0, num_callbacks);
472
473 // If we change the callback now, the new one should be run
474 // (simulates race with post task).
475 int num_alt_callbacks = 0;
476 byte_stream_output->RegisterCallback(
477 base::Bind(CountCallbacks, &num_alt_callbacks));
478 intermediate_callback.Run();
479 EXPECT_EQ(0, num_callbacks);
480 EXPECT_EQ(1, num_alt_callbacks);
481
482 // Final cleanup.
483 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
484 byte_stream_output->Read(&output_io_buffer, &output_length));
485 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
486 EXPECT_EQ(content::ByteStreamOutput::STREAM_EMPTY,
487 byte_stream_output->Read(&output_io_buffer, &output_length));
488
489 }
490
491 // Confirm that racing a change to a source callback with a post results
492 // in the new callback being called.
493 TEST_F(ByteStreamTest, ByteStream_SourceInterrupt) {
494 scoped_refptr<MockTaskRunner> task_runner(new StrictMock<MockTaskRunner>());
495
496 scoped_ptr<content::ByteStreamInput> byte_stream_input;
497 scoped_ptr<content::ByteStreamOutput> byte_stream_output;
498 content::CreateByteStream(
499 task_runner, message_loop_.message_loop_proxy(),
500 10000, &byte_stream_input, &byte_stream_output);
501
502 scoped_refptr<net::IOBuffer> output_io_buffer;
503 size_t output_length;
504 base::Closure intermediate_callback;
505
506 // Setup state for test and record initiali expectations
507 int num_callbacks = 0;
508 byte_stream_input->RegisterCallback(
509 base::Bind(CountCallbacks, &num_callbacks));
510 EXPECT_TRUE(Write(byte_stream_input.get(), 2000));
511 EXPECT_TRUE(Write(byte_stream_input.get(), 2001));
512 EXPECT_FALSE(Write(byte_stream_input.get(), 6000));
513 message_loop_.RunAllPending();
514
515 // Initial get should not trigger callback.
516 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
517 byte_stream_output->Read(&output_io_buffer, &output_length));
518 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
519 message_loop_.RunAllPending();
520
521 // Setup expectations.
522 EXPECT_CALL(*task_runner.get(), PostDelayedTask(_, _, 0))
523 .WillOnce(DoAll(SaveArg<1>(&intermediate_callback),
524 Return(true)));
525
526 // Second get *should* trigger callback.
527 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
528 byte_stream_output->Read(&output_io_buffer, &output_length));
529 ::testing::Mock::VerifyAndClearExpectations(task_runner.get());
530 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
531
532 // Which should do the right thing when it's run.
533 int num_alt_callbacks = 0;
534 byte_stream_input->RegisterCallback(
535 base::Bind(CountCallbacks, &num_alt_callbacks));
536 intermediate_callback.Run();
537 EXPECT_EQ(0, num_callbacks);
538 EXPECT_EQ(1, num_alt_callbacks);
539
540 // Third get should also trigger callback.
541 EXPECT_CALL(*task_runner.get(), PostDelayedTask(_, _, 0))
542 .WillOnce(DoAll(SaveArg<1>(&intermediate_callback),
543 Return(true)));
544 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
545 byte_stream_output->Read(&output_io_buffer, &output_length));
546 ::testing::Mock::VerifyAndClearExpectations(task_runner.get());
547 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
548 EXPECT_EQ(content::ByteStreamOutput::STREAM_EMPTY,
549 byte_stream_output->Read(&output_io_buffer, &output_length));
550 }
551
552 // Confirm that callback is called on zero data transfer but source
553 // complete.
554 TEST_F(ByteStreamTest, ByteStream_ZeroCallback) {
555 scoped_refptr<MockTaskRunner> task_runner(new StrictMock<MockTaskRunner>());
556
557 scoped_ptr<content::ByteStreamInput> byte_stream_input;
558 scoped_ptr<content::ByteStreamOutput> byte_stream_output;
559 content::CreateByteStream(
560 message_loop_.message_loop_proxy(), task_runner,
561 10000, &byte_stream_input, &byte_stream_output);
562
563 base::Closure intermediate_callback;
564
565 // Setup expectations and record initial state.
566 int num_callbacks = 0;
567 byte_stream_output->RegisterCallback(
568 base::Bind(CountCallbacks, &num_callbacks));
569 EXPECT_CALL(*task_runner.get(), PostDelayedTask(_, _, 0))
570 .WillOnce(DoAll(SaveArg<1>(&intermediate_callback),
571 Return(true)));
572
573 // Immediately close the stream.
574 byte_stream_input->Close(content::DOWNLOAD_INTERRUPT_REASON_NONE);
575 ::testing::Mock::VerifyAndClearExpectations(task_runner.get());
576 intermediate_callback.Run();
577 EXPECT_EQ(1, num_callbacks);
578 }
579
580
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698