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

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: Rebased to LKGR. 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
« no previous file with comments | « content/browser/download/byte_stream.cc ('k') | content/content_browser.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 EXPECT_CALL(*task_runner.get(), RunsTasksOnCurrentThread())
317 .WillRepeatedly(Return(true));
318
319 scoped_ptr<content::ByteStreamInput> byte_stream_input;
320 scoped_ptr<content::ByteStreamOutput> byte_stream_output;
321 content::CreateByteStream(
322 message_loop_.message_loop_proxy(), task_runner,
323 10000, &byte_stream_input, &byte_stream_output);
324
325 scoped_refptr<net::IOBuffer> output_io_buffer;
326 size_t output_length;
327 base::Closure intermediate_callback;
328
329 // Note that the specifics of when the callbacks are called with regard
330 // to how much data is pushed onto the pipe is not (currently) part
331 // of the interface contract. If it becomes part of the contract, the
332 // tests below should get much more precise.
333
334 // Confirm callback called when you add more than 33% of the buffer.
335
336 // Setup callback
337 int num_callbacks = 0;
338 byte_stream_output->RegisterCallback(
339 base::Bind(CountCallbacks, &num_callbacks));
340 EXPECT_CALL(*task_runner.get(), PostDelayedTask(_, _, 0))
341 .WillOnce(DoAll(SaveArg<1>(&intermediate_callback),
342 Return(true)));
343
344 EXPECT_TRUE(Write(byte_stream_input.get(), 4000));
345 message_loop_.RunAllPending();
346
347 // Check callback results match expectations.
348 ::testing::Mock::VerifyAndClearExpectations(task_runner.get());
349 EXPECT_CALL(*task_runner.get(), RunsTasksOnCurrentThread())
350 .WillRepeatedly(Return(true));
351 EXPECT_EQ(0, num_callbacks);
352 intermediate_callback.Run();
353 EXPECT_EQ(1, num_callbacks);
354
355 // Check data and stream state.
356 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
357 byte_stream_output->Read(&output_io_buffer, &output_length));
358 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
359 EXPECT_EQ(content::ByteStreamOutput::STREAM_EMPTY,
360 byte_stream_output->Read(&output_io_buffer, &output_length));
361
362 // Confirm callback *isn't* called at less than 33% (by lack of
363 // unexpected call on task runner).
364 EXPECT_TRUE(Write(byte_stream_input.get(), 3000));
365 message_loop_.RunAllPending();
366
367 // This reflects an implementation artifact that data goes with callbacks,
368 // which should not be considered part of the interface guarantee.
369 EXPECT_EQ(content::ByteStreamOutput::STREAM_EMPTY,
370 byte_stream_output->Read(&output_io_buffer, &output_length));
371 }
372
373 // Confirm that callbacks on the source side are triggered when they should
374 // be.
375 TEST_F(ByteStreamTest, ByteStream_SourceCallback) {
376 scoped_refptr<MockTaskRunner> task_runner(new StrictMock<MockTaskRunner>());
377 EXPECT_CALL(*task_runner.get(), RunsTasksOnCurrentThread())
378 .WillRepeatedly(Return(true));
379
380 scoped_ptr<content::ByteStreamInput> byte_stream_input;
381 scoped_ptr<content::ByteStreamOutput> byte_stream_output;
382 content::CreateByteStream(
383 task_runner, message_loop_.message_loop_proxy(),
384 10000, &byte_stream_input, &byte_stream_output);
385
386 scoped_refptr<net::IOBuffer> output_io_buffer;
387 size_t output_length;
388 base::Closure intermediate_callback;
389
390 // Note that the specifics of when the callbacks are called with regard
391 // to how much data is pulled from the pipe is not (currently) part
392 // of the interface contract. If it becomes part of the contract, the
393 // tests below should get much more precise.
394
395 // Confirm callback called when about 33% space available, and not
396 // at other transitions.
397
398 // Setup expectations and add data.
399 int num_callbacks = 0;
400 byte_stream_input->RegisterCallback(
401 base::Bind(CountCallbacks, &num_callbacks));
402 EXPECT_TRUE(Write(byte_stream_input.get(), 2000));
403 EXPECT_TRUE(Write(byte_stream_input.get(), 2001));
404 EXPECT_FALSE(Write(byte_stream_input.get(), 6000));
405
406 // Allow bytes to transition (needed for message passing implementation),
407 // and get and validate the data.
408 message_loop_.RunAllPending();
409 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
410 byte_stream_output->Read(&output_io_buffer, &output_length));
411 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
412
413 // Setup expectations.
414 EXPECT_CALL(*task_runner.get(), PostDelayedTask(_, _, 0))
415 .WillOnce(DoAll(SaveArg<1>(&intermediate_callback),
416 Return(true)));
417
418 // Grab data, triggering callback. Recorded on dispatch, but doesn't
419 // happen because it's caught by the mock.
420 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
421 byte_stream_output->Read(&output_io_buffer, &output_length));
422 ::testing::Mock::VerifyAndClearExpectations(task_runner.get());
423 EXPECT_CALL(*task_runner.get(), RunsTasksOnCurrentThread())
424 .WillRepeatedly(Return(true));
425 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
426
427 // Confirm that the callback passed to the mock does what we expect.
428 EXPECT_EQ(0, num_callbacks);
429 intermediate_callback.Run();
430 EXPECT_EQ(1, num_callbacks);
431
432 // Same drill with final buffer.
433 EXPECT_CALL(*task_runner.get(), PostDelayedTask(_, _, 0))
434 .WillOnce(DoAll(SaveArg<1>(&intermediate_callback),
435 Return(true)));
436 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
437 byte_stream_output->Read(&output_io_buffer, &output_length));
438 ::testing::Mock::VerifyAndClearExpectations(task_runner.get());
439 EXPECT_CALL(*task_runner.get(), RunsTasksOnCurrentThread())
440 .WillRepeatedly(Return(true));
441 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
442 EXPECT_EQ(content::ByteStreamOutput::STREAM_EMPTY,
443 byte_stream_output->Read(&output_io_buffer, &output_length));
444 EXPECT_EQ(1, num_callbacks);
445 intermediate_callback.Run();
446 // Should have updated the internal structures but not called the
447 // callback.
448 EXPECT_EQ(1, num_callbacks);
449 }
450
451 // Confirm that racing a change to a sink callback with a post results
452 // in the new callback being called.
453 TEST_F(ByteStreamTest, ByteStream_SinkInterrupt) {
454 scoped_refptr<MockTaskRunner> task_runner(new StrictMock<MockTaskRunner>());
455 EXPECT_CALL(*task_runner.get(), RunsTasksOnCurrentThread())
456 .WillRepeatedly(Return(true));
457
458 scoped_ptr<content::ByteStreamInput> byte_stream_input;
459 scoped_ptr<content::ByteStreamOutput> byte_stream_output;
460 content::CreateByteStream(
461 message_loop_.message_loop_proxy(), task_runner,
462 10000, &byte_stream_input, &byte_stream_output);
463
464 scoped_refptr<net::IOBuffer> output_io_buffer;
465 size_t output_length;
466 base::Closure intermediate_callback;
467
468 // Setup expectations and record initial state.
469 int num_callbacks = 0;
470 byte_stream_output->RegisterCallback(
471 base::Bind(CountCallbacks, &num_callbacks));
472 EXPECT_CALL(*task_runner.get(), PostDelayedTask(_, _, 0))
473 .WillOnce(DoAll(SaveArg<1>(&intermediate_callback),
474 Return(true)));
475
476 // Add data, and pass it across.
477 EXPECT_TRUE(Write(byte_stream_input.get(), 4000));
478 message_loop_.RunAllPending();
479
480 // The task runner should have been hit, but the callback count
481 // isn't changed until we actually run the callback.
482 ::testing::Mock::VerifyAndClearExpectations(task_runner.get());
483 EXPECT_CALL(*task_runner.get(), RunsTasksOnCurrentThread())
484 .WillRepeatedly(Return(true));
485 EXPECT_EQ(0, num_callbacks);
486
487 // If we change the callback now, the new one should be run
488 // (simulates race with post task).
489 int num_alt_callbacks = 0;
490 byte_stream_output->RegisterCallback(
491 base::Bind(CountCallbacks, &num_alt_callbacks));
492 intermediate_callback.Run();
493 EXPECT_EQ(0, num_callbacks);
494 EXPECT_EQ(1, num_alt_callbacks);
495
496 // Final cleanup.
497 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
498 byte_stream_output->Read(&output_io_buffer, &output_length));
499 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
500 EXPECT_EQ(content::ByteStreamOutput::STREAM_EMPTY,
501 byte_stream_output->Read(&output_io_buffer, &output_length));
502
503 }
504
505 // Confirm that racing a change to a source callback with a post results
506 // in the new callback being called.
507 TEST_F(ByteStreamTest, ByteStream_SourceInterrupt) {
508 scoped_refptr<MockTaskRunner> task_runner(new StrictMock<MockTaskRunner>());
509 EXPECT_CALL(*task_runner.get(), RunsTasksOnCurrentThread())
510 .WillRepeatedly(Return(true));
511
512 scoped_ptr<content::ByteStreamInput> byte_stream_input;
513 scoped_ptr<content::ByteStreamOutput> byte_stream_output;
514 content::CreateByteStream(
515 task_runner, message_loop_.message_loop_proxy(),
516 10000, &byte_stream_input, &byte_stream_output);
517
518 scoped_refptr<net::IOBuffer> output_io_buffer;
519 size_t output_length;
520 base::Closure intermediate_callback;
521
522 // Setup state for test and record initiali expectations
523 int num_callbacks = 0;
524 byte_stream_input->RegisterCallback(
525 base::Bind(CountCallbacks, &num_callbacks));
526 EXPECT_TRUE(Write(byte_stream_input.get(), 2000));
527 EXPECT_TRUE(Write(byte_stream_input.get(), 2001));
528 EXPECT_FALSE(Write(byte_stream_input.get(), 6000));
529 message_loop_.RunAllPending();
530
531 // Initial get should not trigger callback.
532 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
533 byte_stream_output->Read(&output_io_buffer, &output_length));
534 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
535 message_loop_.RunAllPending();
536
537 // Setup expectations.
538 EXPECT_CALL(*task_runner.get(), PostDelayedTask(_, _, 0))
539 .WillOnce(DoAll(SaveArg<1>(&intermediate_callback),
540 Return(true)));
541
542 // Second get *should* trigger callback.
543 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
544 byte_stream_output->Read(&output_io_buffer, &output_length));
545 ::testing::Mock::VerifyAndClearExpectations(task_runner.get());
546 EXPECT_CALL(*task_runner.get(), RunsTasksOnCurrentThread())
547 .WillRepeatedly(Return(true));
548 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
549
550 // Which should do the right thing when it's run.
551 int num_alt_callbacks = 0;
552 byte_stream_input->RegisterCallback(
553 base::Bind(CountCallbacks, &num_alt_callbacks));
554 intermediate_callback.Run();
555 EXPECT_EQ(0, num_callbacks);
556 EXPECT_EQ(1, num_alt_callbacks);
557
558 // Third get should also trigger callback.
559 EXPECT_CALL(*task_runner.get(), PostDelayedTask(_, _, 0))
560 .WillOnce(DoAll(SaveArg<1>(&intermediate_callback),
561 Return(true)));
562 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
563 byte_stream_output->Read(&output_io_buffer, &output_length));
564 ::testing::Mock::VerifyAndClearExpectations(task_runner.get());
565 EXPECT_CALL(*task_runner.get(), RunsTasksOnCurrentThread())
566 .WillRepeatedly(Return(true));
567 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, output_length));
568 EXPECT_EQ(content::ByteStreamOutput::STREAM_EMPTY,
569 byte_stream_output->Read(&output_io_buffer, &output_length));
570 }
571
572 // Confirm that callback is called on zero data transfer but source
573 // complete.
574 TEST_F(ByteStreamTest, ByteStream_ZeroCallback) {
575 scoped_refptr<MockTaskRunner> task_runner(new StrictMock<MockTaskRunner>());
576 EXPECT_CALL(*task_runner.get(), RunsTasksOnCurrentThread())
577 .WillRepeatedly(Return(true));
578
579 scoped_ptr<content::ByteStreamInput> byte_stream_input;
580 scoped_ptr<content::ByteStreamOutput> byte_stream_output;
581 content::CreateByteStream(
582 message_loop_.message_loop_proxy(), task_runner,
583 10000, &byte_stream_input, &byte_stream_output);
584
585 base::Closure intermediate_callback;
586
587 // Setup expectations and record initial state.
588 int num_callbacks = 0;
589 byte_stream_output->RegisterCallback(
590 base::Bind(CountCallbacks, &num_callbacks));
591 EXPECT_CALL(*task_runner.get(), PostDelayedTask(_, _, 0))
592 .WillOnce(DoAll(SaveArg<1>(&intermediate_callback),
593 Return(true)));
594
595 // Immediately close the stream.
596 byte_stream_input->Close(content::DOWNLOAD_INTERRUPT_REASON_NONE);
597 ::testing::Mock::VerifyAndClearExpectations(task_runner.get());
598 EXPECT_CALL(*task_runner.get(), RunsTasksOnCurrentThread())
599 .WillRepeatedly(Return(true));
600 intermediate_callback.Run();
601 EXPECT_EQ(1, num_callbacks);
602 }
603
604
OLDNEW
« no previous file with comments | « content/browser/download/byte_stream.cc ('k') | content/content_browser.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698