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

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

Powered by Google App Engine
This is Rietveld 408576698