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

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: Finished and polished rewrite. 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() {
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.
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::AddData.
91 // Separate function to avoid duplication of buffer_size in test
92 // calls.
93 bool AddData(content::ByteStreamInput* byte_stream_input,
94 int seed_key, size_t buffer_size) {
95 return byte_stream_input->AddData(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:
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) {
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(AddData(byte_stream_input.get(), 0, 1024));
142 EXPECT_TRUE(AddData(byte_stream_input.get(), 1, 1024));
143 EXPECT_TRUE(AddData(byte_stream_input.get(), 2, 1024));
144 EXPECT_FALSE(AddData(byte_stream_input.get(), 3, 1));
145 EXPECT_FALSE(AddData(byte_stream_input.get(), 4, 1024));
146 EXPECT_EQ(0u, byte_stream_output->BytesRead());
147 EXPECT_EQ(0u, byte_stream_output->BuffersRead());
148 // Flush
149 byte_stream_input->SourceComplete(content::DOWNLOAD_INTERRUPT_REASON_NONE);
150 message_loop_.RunAllPending();
151
152 // Pull the IO buffers out; do we get the same buffers and do they
153 // have the same contents?
154 scoped_refptr<net::IOBuffer> output_io_buffer;
155 size_t output_length;
156 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
157 byte_stream_output->GetData(&output_io_buffer, &output_length));
158 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, 0, output_length));
159 EXPECT_EQ(1024u, byte_stream_output->BytesRead());
160 EXPECT_EQ(1u, byte_stream_output->BuffersRead());
161
162 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
163 byte_stream_output->GetData(&output_io_buffer, &output_length));
164 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, 1, output_length));
165 EXPECT_EQ(2048u, byte_stream_output->BytesRead());
166 EXPECT_EQ(2u, byte_stream_output->BuffersRead());
167
168 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
169 byte_stream_output->GetData(&output_io_buffer, &output_length));
170 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, 2, output_length));
171 EXPECT_EQ(3072u, byte_stream_output->BytesRead());
172 EXPECT_EQ(3u, byte_stream_output->BuffersRead());
173
174 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
175 byte_stream_output->GetData(&output_io_buffer, &output_length));
176 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, 3, output_length));
177 EXPECT_EQ(3073u, byte_stream_output->BytesRead());
178 EXPECT_EQ(4u, byte_stream_output->BuffersRead());
179
180 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
181 byte_stream_output->GetData(&output_io_buffer, &output_length));
182 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, 4, output_length));
183 EXPECT_EQ(4097u, byte_stream_output->BytesRead());
184 EXPECT_EQ(5u, byte_stream_output->BuffersRead());
185
186 EXPECT_EQ(content::ByteStreamOutput::STREAM_COMPLETE,
187 byte_stream_output->GetData(&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, PushBackSplit) {
194 scoped_ptr<content::ByteStreamInput> byte_stream_input;
195 scoped_ptr<content::ByteStreamOutput> byte_stream_output;
196 content::CreateByteStream(
197 &byte_stream_input, &byte_stream_output,
198 message_loop_.message_loop_proxy(), message_loop_.message_loop_proxy(),
199 9 * 1024);
200
201 // Push a series of IO buffers on; test pushback happening and
202 // that it's advisory.
203 EXPECT_TRUE(AddData(byte_stream_input.get(), 0, 1024));
204 message_loop_.RunAllPending();
205 EXPECT_TRUE(AddData(byte_stream_input.get(), 1, 1024));
206 message_loop_.RunAllPending();
207 EXPECT_TRUE(AddData(byte_stream_input.get(), 2, 1024));
208 message_loop_.RunAllPending();
209 EXPECT_TRUE(AddData(byte_stream_input.get(), 3, 1024));
210 message_loop_.RunAllPending();
211 EXPECT_FALSE(AddData(byte_stream_input.get(), 4, 6 * 1024));
212 message_loop_.RunAllPending();
213 EXPECT_EQ(0u, byte_stream_output->BytesRead());
214 EXPECT_EQ(0u, byte_stream_output->BuffersRead());
215
216 // Pull the IO buffers out; do we get the same buffers and do they
217 // have the same contents?
218 scoped_refptr<net::IOBuffer> output_io_buffer;
219 size_t output_length;
220 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
221 byte_stream_output->GetData(&output_io_buffer, &output_length));
222 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, 0, output_length));
223 EXPECT_EQ(1024u, byte_stream_output->BytesRead());
224 EXPECT_EQ(1u, byte_stream_output->BuffersRead());
225
226 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
227 byte_stream_output->GetData(&output_io_buffer, &output_length));
228 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, 1, output_length));
229 EXPECT_EQ(2048u, byte_stream_output->BytesRead());
230 EXPECT_EQ(2u, byte_stream_output->BuffersRead());
231
232 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
233 byte_stream_output->GetData(&output_io_buffer, &output_length));
234 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, 2, output_length));
235 EXPECT_EQ(3072u, byte_stream_output->BytesRead());
236 EXPECT_EQ(3u, byte_stream_output->BuffersRead());
237
238 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
239 byte_stream_output->GetData(&output_io_buffer, &output_length));
240 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, 3, output_length));
241 EXPECT_EQ(4096u, byte_stream_output->BytesRead());
242 EXPECT_EQ(4u, byte_stream_output->BuffersRead());
243
244 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
245 byte_stream_output->GetData(&output_io_buffer, &output_length));
246 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, 4, output_length));
247 EXPECT_EQ(10240u, byte_stream_output->BytesRead());
248 EXPECT_EQ(5u, byte_stream_output->BuffersRead());
249
250 EXPECT_EQ(content::ByteStreamOutput::STREAM_EMPTY,
251 byte_stream_output->GetData(&output_io_buffer, &output_length));
252 }
253
254 // Confirm that a SourceComplete() notification transmits in-order
255 // with data on the pipe.
256 TEST_F(ByteStreamTest, CompleteTransmits) {
257 scoped_ptr<content::ByteStreamInput> byte_stream_input;
258 scoped_ptr<content::ByteStreamOutput> byte_stream_output;
259
260 scoped_refptr<net::IOBuffer> output_io_buffer;
261 size_t output_length;
262
263 // Empty stream, non-error case.
264 content::CreateByteStream(
265 &byte_stream_input, &byte_stream_output,
266 message_loop_.message_loop_proxy(), message_loop_.message_loop_proxy(),
267 3 * 1024);
268 EXPECT_EQ(content::ByteStreamOutput::STREAM_EMPTY,
269 byte_stream_output->GetData(&output_io_buffer, &output_length));
270 byte_stream_input->SourceComplete(content::DOWNLOAD_INTERRUPT_REASON_NONE);
271 message_loop_.RunAllPending();
272 ASSERT_EQ(content::ByteStreamOutput::STREAM_COMPLETE,
273 byte_stream_output->GetData(&output_io_buffer, &output_length));
274 EXPECT_EQ(content::DOWNLOAD_INTERRUPT_REASON_NONE,
275 byte_stream_output->GetSourceResult());
276
277 // Non-empty stream, non-error case.
278 content::CreateByteStream(
279 &byte_stream_input, &byte_stream_output,
280 message_loop_.message_loop_proxy(), message_loop_.message_loop_proxy(),
281 3 * 1024);
282 EXPECT_EQ(content::ByteStreamOutput::STREAM_EMPTY,
283 byte_stream_output->GetData(&output_io_buffer, &output_length));
284 EXPECT_TRUE(AddData(byte_stream_input.get(), 0, 1024));
285 byte_stream_input->SourceComplete(content::DOWNLOAD_INTERRUPT_REASON_NONE);
286 message_loop_.RunAllPending();
287 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
288 byte_stream_output->GetData(&output_io_buffer, &output_length));
289 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, 0, output_length));
290 ASSERT_EQ(content::ByteStreamOutput::STREAM_COMPLETE,
291 byte_stream_output->GetData(&output_io_buffer, &output_length));
292 EXPECT_EQ(content::DOWNLOAD_INTERRUPT_REASON_NONE,
293 byte_stream_output->GetSourceResult());
294
295 // Empty stream, non-error case.
296 content::CreateByteStream(
297 &byte_stream_input, &byte_stream_output,
298 message_loop_.message_loop_proxy(), message_loop_.message_loop_proxy(),
299 3 * 1024);
300 EXPECT_EQ(content::ByteStreamOutput::STREAM_EMPTY,
301 byte_stream_output->GetData(&output_io_buffer, &output_length));
302 byte_stream_input->SourceComplete(
303 content::DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED);
304 message_loop_.RunAllPending();
305 ASSERT_EQ(content::ByteStreamOutput::STREAM_COMPLETE,
306 byte_stream_output->GetData(&output_io_buffer, &output_length));
307 EXPECT_EQ(content::DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED,
308 byte_stream_output->GetSourceResult());
309
310 // Non-empty stream, non-error case.
311 content::CreateByteStream(
312 &byte_stream_input, &byte_stream_output,
313 message_loop_.message_loop_proxy(), message_loop_.message_loop_proxy(),
314 3 * 1024);
315 EXPECT_EQ(content::ByteStreamOutput::STREAM_EMPTY,
316 byte_stream_output->GetData(&output_io_buffer, &output_length));
317 EXPECT_TRUE(AddData(byte_stream_input.get(), 1, 1024));
318 byte_stream_input->SourceComplete(
319 content::DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED);
320 message_loop_.RunAllPending();
321 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
322 byte_stream_output->GetData(&output_io_buffer, &output_length));
323 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, 1, output_length));
324 ASSERT_EQ(content::ByteStreamOutput::STREAM_COMPLETE,
325 byte_stream_output->GetData(&output_io_buffer, &output_length));
326 EXPECT_EQ(content::DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED,
327 byte_stream_output->GetSourceResult());
328 }
329
330 // Confirm that callbacks on the sink side are triggered when they should be.
331 TEST_F(ByteStreamTest, SinkCallback) {
332 scoped_refptr<MockTaskRunner> task_runner(new StrictMock<MockTaskRunner>());
333 int null_callback_call_count_start = 0;
334
335 scoped_ptr<content::ByteStreamInput> byte_stream_input;
336 scoped_ptr<content::ByteStreamOutput> byte_stream_output;
337 content::CreateByteStream(
338 &byte_stream_input, &byte_stream_output,
339 message_loop_.message_loop_proxy(), task_runner,
340 10000);
341
342 scoped_refptr<net::IOBuffer> output_io_buffer;
343 size_t output_length;
344 base::Closure intermediate_callback;
345
346 // Note that the specifics of when the callbacks are called with regard
347 // to how much data is pushed onto the pipe is not (currently) part
348 // of the interface contract. If it becomes part of the contract, the
349 // tests below should get much more precise.
350
351 // Confirm callback called when you add more than 33% of the buffer.
352
353 // Setup callback
354 byte_stream_output->RegisterCallback(base::Bind(NullCallback));
355 null_callback_call_count_start = null_callback_call_count;
356 EXPECT_CALL(*task_runner.get(), PostDelayedTask(_, _, 0))
357 .WillOnce(DoAll(SaveArg<1>(&intermediate_callback),
358 Return(true)));
359 EXPECT_EQ(0u, byte_stream_output->NumSinkCallbacks());
360
361 EXPECT_TRUE(AddData(byte_stream_input.get(), 0, 4000));
362 message_loop_.RunAllPending();
363
364 // Check callback results match expectations.
365 ::testing::Mock::VerifyAndClearExpectations(task_runner.get());
366 EXPECT_EQ(null_callback_call_count_start, null_callback_call_count);
367 intermediate_callback.Run();
368 EXPECT_EQ(null_callback_call_count_start+1, null_callback_call_count);
369 EXPECT_EQ(1u, byte_stream_output->NumSinkCallbacks());
370
371 // Check data and stream state.
372 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
373 byte_stream_output->GetData(&output_io_buffer, &output_length));
374 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, 0, output_length));
375 EXPECT_EQ(content::ByteStreamOutput::STREAM_EMPTY,
376 byte_stream_output->GetData(&output_io_buffer, &output_length));
377
378 // Confirm callback *isn't* called at less than 33%
379 null_callback_call_count_start = null_callback_call_count;
380 EXPECT_EQ(1u, byte_stream_output->NumSinkCallbacks());
381 EXPECT_TRUE(AddData(byte_stream_input.get(), 1, 3000));
382 message_loop_.RunAllPending();
383 EXPECT_EQ(1u, byte_stream_output->NumSinkCallbacks());
384
385 // This reflects an implementation artifact that data goes with callbacks,
386 // which should not be considered part of the interface guarantee.
387 EXPECT_EQ(content::ByteStreamOutput::STREAM_EMPTY,
388 byte_stream_output->GetData(&output_io_buffer, &output_length));
389 }
390
391 // Confirm that callbacks on the source side are triggered when they should
392 // be.
393 TEST_F(ByteStreamTest, SourceCallback) {
394 scoped_refptr<MockTaskRunner> task_runner(new StrictMock<MockTaskRunner>());
395 int null_callback_call_count_start = 0;
396
397 scoped_ptr<content::ByteStreamInput> byte_stream_input;
398 scoped_ptr<content::ByteStreamOutput> byte_stream_output;
399 content::CreateByteStream(
400 &byte_stream_input, &byte_stream_output,
401 task_runner, message_loop_.message_loop_proxy(),
402 10000);
403
404 scoped_refptr<net::IOBuffer> output_io_buffer;
405 size_t output_length;
406 base::Closure intermediate_callback;
407
408 // Note that the specifics of when the callbacks are called with regard
409 // to how much data is pulled from the pipe is not (currently) part
410 // of the interface contract. If it becomes part of the contract, the
411 // tests below should get much more precise.
412
413 // Confirm callback called when about 33% space available, and not
414 // at other transitions.
415
416 // Setup expectations and add data.
417 byte_stream_input->RegisterCallback(base::Bind(NullCallback));
418 EXPECT_TRUE(AddData(byte_stream_input.get(), 0, 2000));
419 EXPECT_TRUE(AddData(byte_stream_input.get(), 1, 2001));
420 EXPECT_FALSE(AddData(byte_stream_input.get(), 2, 6000));
421 null_callback_call_count_start = null_callback_call_count;
422
423 // Allow bytes to transition (needed for message passing implementation),
424 // and get and validate the data.
425 message_loop_.RunAllPending();
426 EXPECT_EQ(0u, byte_stream_output->NumSourceCallbacks());
427 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
428 byte_stream_output->GetData(&output_io_buffer, &output_length));
429 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, 0, output_length));
430
431 // Setup expectations.
432 EXPECT_EQ(0u, byte_stream_output->NumSourceCallbacks());
433 EXPECT_CALL(*task_runner.get(), PostDelayedTask(_, _, 0))
434 .WillOnce(DoAll(SaveArg<1>(&intermediate_callback),
435 Return(true)));
436
437 // Grab data, triggering callback. Recorded on dispatch, but doesn't
438 // happen because it's caught by the mock.
439 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
440 byte_stream_output->GetData(&output_io_buffer, &output_length));
441 EXPECT_EQ(1u, byte_stream_output->NumSourceCallbacks());
442 ::testing::Mock::VerifyAndClearExpectations(task_runner.get());
443 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, 1, output_length));
444
445 // Confirm that the callback passed to the mock does what we expect.
446 EXPECT_EQ(null_callback_call_count_start, null_callback_call_count);
447 intermediate_callback.Run();
448 EXPECT_EQ(null_callback_call_count_start+1, null_callback_call_count);
449
450 // Same drill with final buffer.
451 EXPECT_CALL(*task_runner.get(), PostDelayedTask(_, _, 0))
452 .WillOnce(DoAll(SaveArg<1>(&intermediate_callback),
453 Return(true)));
454 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
455 byte_stream_output->GetData(&output_io_buffer, &output_length));
456 EXPECT_EQ(2u, byte_stream_output->NumSourceCallbacks());
457 ::testing::Mock::VerifyAndClearExpectations(task_runner.get());
458 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, 2, output_length));
459 EXPECT_EQ(content::ByteStreamOutput::STREAM_EMPTY,
460 byte_stream_output->GetData(&output_io_buffer, &output_length));
461 EXPECT_EQ(null_callback_call_count_start+1, null_callback_call_count);
462 }
463
464 // Confirm that racing a change to a sink callback with a post results
465 // in the new callback being called.
466 TEST_F(ByteStreamTest, SinkInterrupt) {
467 scoped_refptr<MockTaskRunner> task_runner(new StrictMock<MockTaskRunner>());
468 int null_callback_call_count_start = 0;
469 int alt_callback_call_count_start = 0;
470
471 scoped_ptr<content::ByteStreamInput> byte_stream_input;
472 scoped_ptr<content::ByteStreamOutput> byte_stream_output;
473 content::CreateByteStream(
474 &byte_stream_input, &byte_stream_output,
475 message_loop_.message_loop_proxy(), task_runner,
476 10000);
477
478 scoped_refptr<net::IOBuffer> output_io_buffer;
479 size_t output_length;
480 base::Closure intermediate_callback;
481
482 // Setup expectations and record initial state.
483 byte_stream_output->RegisterCallback(base::Bind(NullCallback));
484 null_callback_call_count_start = null_callback_call_count;
485 alt_callback_call_count_start = alt_callback_call_count;
486 EXPECT_CALL(*task_runner.get(), PostDelayedTask(_, _, 0))
487 .WillOnce(DoAll(SaveArg<1>(&intermediate_callback),
488 Return(true)));
489 EXPECT_EQ(0u, byte_stream_output->NumSinkCallbacks());
490
491 // Add data, and pass it across.
492 EXPECT_TRUE(AddData(byte_stream_input.get(), 0, 4000));
493 message_loop_.RunAllPending();
494
495 // The task runner should have been hit, but the callback count
496 // isn't changed until we actually run the callback.
497 ::testing::Mock::VerifyAndClearExpectations(task_runner.get());
498 EXPECT_EQ(null_callback_call_count_start, null_callback_call_count);
499
500 // If we change the callback now, the new one should be run
501 // (simulates race with post task).
502 byte_stream_output->RegisterCallback(base::Bind(AltCallback));
503 EXPECT_EQ(null_callback_call_count_start, null_callback_call_count);
504 EXPECT_EQ(alt_callback_call_count_start, alt_callback_call_count);
505 intermediate_callback.Run();
506 EXPECT_EQ(null_callback_call_count_start, null_callback_call_count);
507 EXPECT_EQ(alt_callback_call_count_start+1, alt_callback_call_count);
508 EXPECT_EQ(1u, byte_stream_output->NumSinkCallbacks());
509
510 // Final cleanup.
511 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
512 byte_stream_output->GetData(&output_io_buffer, &output_length));
513 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, 0, output_length));
514 EXPECT_EQ(content::ByteStreamOutput::STREAM_EMPTY,
515 byte_stream_output->GetData(&output_io_buffer, &output_length));
516
517 }
518
519 // Confirm that racing a change to a source callback with a post results
520 // in the new callback being called.
521 TEST_F(ByteStreamTest, SourceInterrupt) {
522 scoped_refptr<MockTaskRunner> task_runner(new StrictMock<MockTaskRunner>());
523 int null_callback_call_count_start = 0;
524 int alt_callback_call_count_start = 0;
525
526 scoped_ptr<content::ByteStreamInput> byte_stream_input;
527 scoped_ptr<content::ByteStreamOutput> byte_stream_output;
528 content::CreateByteStream(
529 &byte_stream_input, &byte_stream_output,
530 task_runner, message_loop_.message_loop_proxy(),
531 10000);
532
533 scoped_refptr<net::IOBuffer> output_io_buffer;
534 size_t output_length;
535 base::Closure intermediate_callback;
536
537 // Setup state for test and record initiali expectations
538 byte_stream_input->RegisterCallback(base::Bind(NullCallback));
539 EXPECT_TRUE(AddData(byte_stream_input.get(), 0, 2000));
540 EXPECT_TRUE(AddData(byte_stream_input.get(), 1, 2001));
541 EXPECT_FALSE(AddData(byte_stream_input.get(), 2, 6000));
542 null_callback_call_count_start = null_callback_call_count;
543 alt_callback_call_count_start = alt_callback_call_count;
544 message_loop_.RunAllPending();
545 EXPECT_EQ(0u, byte_stream_output->NumSourceCallbacks());
546
547 // Initial get should not trigger callback.
548 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
549 byte_stream_output->GetData(&output_io_buffer, &output_length));
550 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, 0, output_length));
551 message_loop_.RunAllPending();
552 EXPECT_EQ(0u, byte_stream_output->NumSourceCallbacks());
553
554 // Setup expectations.
555 EXPECT_CALL(*task_runner.get(), PostDelayedTask(_, _, 0))
556 .WillOnce(DoAll(SaveArg<1>(&intermediate_callback),
557 Return(true)));
558
559 // Second get *should* trigger callback.
560 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
561 byte_stream_output->GetData(&output_io_buffer, &output_length));
562 EXPECT_EQ(1u, byte_stream_output->NumSourceCallbacks());
563 ::testing::Mock::VerifyAndClearExpectations(task_runner.get());
564 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, 1, output_length));
565
566 // Which should do the right thing when it's run.
567 byte_stream_input->RegisterCallback(base::Bind(AltCallback));
568 EXPECT_EQ(null_callback_call_count_start, null_callback_call_count);
569 EXPECT_EQ(alt_callback_call_count_start, alt_callback_call_count);
570 intermediate_callback.Run();
571 EXPECT_EQ(null_callback_call_count_start, null_callback_call_count);
572 EXPECT_EQ(alt_callback_call_count_start+1, alt_callback_call_count);
573
574 // Third get should also trigger callback.
575 EXPECT_CALL(*task_runner.get(), PostDelayedTask(_, _, 0))
576 .WillOnce(DoAll(SaveArg<1>(&intermediate_callback),
577 Return(true)));
578 EXPECT_EQ(content::ByteStreamOutput::STREAM_HAS_DATA,
579 byte_stream_output->GetData(&output_io_buffer, &output_length));
580 EXPECT_EQ(2u, byte_stream_output->NumSourceCallbacks());
581 ::testing::Mock::VerifyAndClearExpectations(task_runner.get());
582 EXPECT_TRUE(ValidateIOBuffer(output_io_buffer, 2, output_length));
583 EXPECT_EQ(content::ByteStreamOutput::STREAM_EMPTY,
584 byte_stream_output->GetData(&output_io_buffer, &output_length));
585 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698