OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "config.h" | 5 #include "config.h" |
6 #include "modules/fetch/DataConsumerTee.h" | 6 #include "modules/fetch/DataConsumerTee.h" |
7 | 7 |
8 #include "core/testing/DummyPageHolder.h" | 8 #include "core/testing/DummyPageHolder.h" |
9 #include "core/testing/NullExecutionContext.h" | 9 #include "core/testing/NullExecutionContext.h" |
10 #include "modules/fetch/DataConsumerHandleTestUtil.h" | 10 #include "modules/fetch/DataConsumerHandleTestUtil.h" |
11 #include "platform/Task.h" | 11 #include "platform/Task.h" |
12 #include "platform/ThreadSafeFunctional.h" | 12 #include "platform/ThreadSafeFunctional.h" |
13 #include "platform/WebThreadSupportingGC.h" | 13 #include "platform/WebThreadSupportingGC.h" |
14 #include "public/platform/Platform.h" | 14 #include "public/platform/Platform.h" |
15 #include "public/platform/WebThread.h" | 15 #include "public/platform/WebThread.h" |
16 #include "public/platform/WebTraceLocation.h" | 16 #include "public/platform/WebTraceLocation.h" |
17 #include "public/platform/WebWaitableEvent.h" | 17 #include "public/platform/WebWaitableEvent.h" |
18 #include "wtf/PassRefPtr.h" | 18 #include "wtf/PassRefPtr.h" |
19 #include "wtf/RefPtr.h" | 19 #include "wtf/RefPtr.h" |
20 | 20 |
21 #include <gtest/gtest.h> | 21 #include <gtest/gtest.h> |
22 #include <string.h> | 22 #include <string.h> |
23 #include <v8.h> | 23 #include <v8.h> |
24 | 24 |
25 namespace blink { | 25 namespace blink { |
26 namespace { | 26 namespace { |
27 | 27 |
| 28 using ::testing::InSequence; |
| 29 using ::testing::Return; |
| 30 using ::testing::StrictMock; |
| 31 using ::testing::_; |
| 32 using Checkpoint = StrictMock<::testing::MockFunction<void(int)>>; |
| 33 |
28 using Result = WebDataConsumerHandle::Result; | 34 using Result = WebDataConsumerHandle::Result; |
29 using Thread = DataConsumerHandleTestUtil::Thread; | 35 using Thread = DataConsumerHandleTestUtil::Thread; |
30 const WebDataConsumerHandle::Flags kNone = WebDataConsumerHandle::FlagNone; | 36 const WebDataConsumerHandle::Flags kNone = WebDataConsumerHandle::FlagNone; |
31 const Result kOk = WebDataConsumerHandle::Ok; | 37 const Result kOk = WebDataConsumerHandle::Ok; |
32 const Result kShouldWait = WebDataConsumerHandle::ShouldWait; | 38 const Result kShouldWait = WebDataConsumerHandle::ShouldWait; |
33 const Result kDone = WebDataConsumerHandle::Done; | 39 const Result kDone = WebDataConsumerHandle::Done; |
34 const Result kUnexpectedError = WebDataConsumerHandle::UnexpectedError; | 40 const Result kUnexpectedError = WebDataConsumerHandle::UnexpectedError; |
| 41 const FetchDataConsumerHandle::Reader::BlobSizePolicy kDisallowBlobWithInvalidSi
ze = FetchDataConsumerHandle::Reader::DisallowBlobWithInvalidSize; |
| 42 const FetchDataConsumerHandle::Reader::BlobSizePolicy kAllowBlobWithInvalidSize
= FetchDataConsumerHandle::Reader::AllowBlobWithInvalidSize; |
35 | 43 |
36 using Command = DataConsumerHandleTestUtil::Command; | 44 using Command = DataConsumerHandleTestUtil::Command; |
37 using Handle = DataConsumerHandleTestUtil::ReplayingHandle; | 45 using Handle = DataConsumerHandleTestUtil::ReplayingHandle; |
38 | 46 |
39 class HandleReader : public WebDataConsumerHandle::Client { | 47 class HandleReader : public WebDataConsumerHandle::Client { |
40 public: | 48 public: |
41 HandleReader() : m_finalResult(kOk) { } | 49 HandleReader() : m_finalResult(kOk) { } |
42 | 50 |
43 // Need to wait for the event signal after this function is called. | 51 // Need to wait for the event signal after this function is called. |
44 void start(PassOwnPtr<WebDataConsumerHandle> handle) | 52 void start(PassOwnPtr<WebDataConsumerHandle> handle) |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 m_reader = handle->obtainReader(this); | 138 m_reader = handle->obtainReader(this); |
131 } | 139 } |
132 | 140 |
133 OwnPtr<Thread> m_thread; | 141 OwnPtr<Thread> m_thread; |
134 OwnPtr<WebDataConsumerHandle::Reader> m_reader; | 142 OwnPtr<WebDataConsumerHandle::Reader> m_reader; |
135 String m_readString; | 143 String m_readString; |
136 Result m_finalResult; | 144 Result m_finalResult; |
137 OwnPtr<WebWaitableEvent> m_waitableEvent; | 145 OwnPtr<WebWaitableEvent> m_waitableEvent; |
138 }; | 146 }; |
139 | 147 |
| 148 template<typename Handle> |
140 class TeeCreationThread { | 149 class TeeCreationThread { |
141 public: | 150 public: |
142 void run(PassOwnPtr<WebDataConsumerHandle> src, OwnPtr<WebDataConsumerHandle
>* dest1, OwnPtr<WebDataConsumerHandle>* dest2) | 151 void run(PassOwnPtr<Handle> src, OwnPtr<Handle>* dest1, OwnPtr<Handle>* dest
2) |
143 { | 152 { |
144 m_thread = adoptPtr(new Thread("src thread", Thread::WithExecutionContex
t)); | 153 m_thread = adoptPtr(new Thread("src thread", Thread::WithExecutionContex
t)); |
145 m_waitableEvent = adoptPtr(Platform::current()->createWaitableEvent()); | 154 m_waitableEvent = adoptPtr(Platform::current()->createWaitableEvent()); |
146 m_thread->thread()->postTask(FROM_HERE, new Task(threadSafeBind(&TeeCrea
tionThread::runInternal, AllowCrossThreadAccess(this), src, AllowCrossThreadAcce
ss(dest1), AllowCrossThreadAccess(dest2)))); | 155 m_thread->thread()->postTask(FROM_HERE, new Task(threadSafeBind(&TeeCrea
tionThread<Handle>::runInternal, AllowCrossThreadAccess(this), src, AllowCrossTh
readAccess(dest1), AllowCrossThreadAccess(dest2)))); |
147 m_waitableEvent->wait(); | 156 m_waitableEvent->wait(); |
148 } | 157 } |
149 | 158 |
150 Thread* thread() { return m_thread.get(); } | 159 Thread* thread() { return m_thread.get(); } |
151 | 160 |
152 private: | 161 private: |
153 void runInternal(PassOwnPtr<WebDataConsumerHandle> src, OwnPtr<WebDataConsum
erHandle>* dest1, OwnPtr<WebDataConsumerHandle>* dest2) | 162 void runInternal(PassOwnPtr<Handle> src, OwnPtr<Handle>* dest1, OwnPtr<Handl
e>* dest2) |
154 { | 163 { |
155 DataConsumerTee::create(m_thread->executionContext(), src, dest1, dest2)
; | 164 DataConsumerTee::create(m_thread->executionContext(), src, dest1, dest2)
; |
156 m_waitableEvent->signal(); | 165 m_waitableEvent->signal(); |
157 } | 166 } |
158 | 167 |
159 OwnPtr<Thread> m_thread; | 168 OwnPtr<Thread> m_thread; |
160 OwnPtr<WebWaitableEvent> m_waitableEvent; | 169 OwnPtr<WebWaitableEvent> m_waitableEvent; |
161 }; | 170 }; |
162 | 171 |
| 172 // TODO(hiroshige): Merge similar classes into DataConsumerHandleTestUtil.h/cpp. |
| 173 class MockFetchDataConsumerHandle : public FetchDataConsumerHandle { |
| 174 public: |
| 175 static PassOwnPtr<StrictMock<MockFetchDataConsumerHandle>> create() { return
adoptPtr(new StrictMock<MockFetchDataConsumerHandle>); } |
| 176 MOCK_METHOD1(obtainReaderInternal, Reader*(Client*)); |
| 177 }; |
| 178 |
| 179 class MockFetchDataConsumerReader : public FetchDataConsumerHandle::Reader { |
| 180 public: |
| 181 static PassOwnPtr<StrictMock<MockFetchDataConsumerReader>> create() { return
adoptPtr(new StrictMock<MockFetchDataConsumerReader>); } |
| 182 |
| 183 using Result = WebDataConsumerHandle::Result; |
| 184 using Flags = WebDataConsumerHandle::Flags; |
| 185 MOCK_METHOD4(read, Result(void*, size_t, Flags, size_t*)); |
| 186 MOCK_METHOD3(beginRead, Result(const void**, Flags, size_t*)); |
| 187 MOCK_METHOD1(endRead, Result(size_t)); |
| 188 MOCK_METHOD1(drainAsBlobDataHandle, PassRefPtr<BlobDataHandle>(BlobSizePolic
y)); |
| 189 |
| 190 ~MockFetchDataConsumerReader() override |
| 191 { |
| 192 destruct(); |
| 193 } |
| 194 MOCK_METHOD0(destruct, void()); |
| 195 }; |
| 196 |
163 TEST(DataConsumerTeeTest, CreateDone) | 197 TEST(DataConsumerTeeTest, CreateDone) |
164 { | 198 { |
165 OwnPtr<Handle> src(Handle::create()); | 199 OwnPtr<Handle> src(Handle::create()); |
166 OwnPtr<WebDataConsumerHandle> dest1, dest2; | 200 OwnPtr<WebDataConsumerHandle> dest1, dest2; |
167 | 201 |
168 src->add(Command(Command::Done)); | 202 src->add(Command(Command::Done)); |
169 | 203 |
170 OwnPtr<TeeCreationThread> t = adoptPtr(new TeeCreationThread()); | 204 OwnPtr<TeeCreationThread<WebDataConsumerHandle>> t = adoptPtr(new TeeCreatio
nThread<WebDataConsumerHandle>()); |
171 t->run(src.release(), &dest1, &dest2); | 205 t->run(src.release(), &dest1, &dest2); |
172 | 206 |
173 ASSERT_TRUE(dest1); | 207 ASSERT_TRUE(dest1); |
174 ASSERT_TRUE(dest2); | 208 ASSERT_TRUE(dest2); |
175 | 209 |
176 HandleReader r1, r2; | 210 HandleReader r1, r2; |
177 r1.start(dest1.release()); | 211 r1.start(dest1.release()); |
178 r2.start(dest2.release()); | 212 r2.start(dest2.release()); |
179 | 213 |
180 r1.waitableEvent()->wait(); | 214 r1.waitableEvent()->wait(); |
(...skipping 12 matching lines...) Expand all Loading... |
193 OwnPtr<WebDataConsumerHandle> dest1, dest2; | 227 OwnPtr<WebDataConsumerHandle> dest1, dest2; |
194 | 228 |
195 src->add(Command(Command::Wait)); | 229 src->add(Command(Command::Wait)); |
196 src->add(Command(Command::Data, "hello, ")); | 230 src->add(Command(Command::Data, "hello, ")); |
197 src->add(Command(Command::Wait)); | 231 src->add(Command(Command::Wait)); |
198 src->add(Command(Command::Data, "world")); | 232 src->add(Command(Command::Data, "world")); |
199 src->add(Command(Command::Wait)); | 233 src->add(Command(Command::Wait)); |
200 src->add(Command(Command::Wait)); | 234 src->add(Command(Command::Wait)); |
201 src->add(Command(Command::Done)); | 235 src->add(Command(Command::Done)); |
202 | 236 |
203 OwnPtr<TeeCreationThread> t = adoptPtr(new TeeCreationThread()); | 237 OwnPtr<TeeCreationThread<WebDataConsumerHandle>> t = adoptPtr(new TeeCreatio
nThread<WebDataConsumerHandle>()); |
204 t->run(src.release(), &dest1, &dest2); | 238 t->run(src.release(), &dest1, &dest2); |
205 | 239 |
206 ASSERT_TRUE(dest1); | 240 ASSERT_TRUE(dest1); |
207 ASSERT_TRUE(dest2); | 241 ASSERT_TRUE(dest2); |
208 | 242 |
209 HandleReader r1, r2; | 243 HandleReader r1, r2; |
210 r1.start(dest1.release()); | 244 r1.start(dest1.release()); |
211 r2.start(dest2.release()); | 245 r2.start(dest2.release()); |
212 | 246 |
213 r1.waitableEvent()->wait(); | 247 r1.waitableEvent()->wait(); |
(...skipping 13 matching lines...) Expand all Loading... |
227 | 261 |
228 src->add(Command(Command::Wait)); | 262 src->add(Command(Command::Wait)); |
229 src->add(Command(Command::Data, "hello, ")); | 263 src->add(Command(Command::Data, "hello, ")); |
230 src->add(Command(Command::Wait)); | 264 src->add(Command(Command::Wait)); |
231 src->add(Command(Command::Wait)); | 265 src->add(Command(Command::Wait)); |
232 src->add(Command(Command::Wait)); | 266 src->add(Command(Command::Wait)); |
233 src->add(Command(Command::Data, "world")); | 267 src->add(Command(Command::Data, "world")); |
234 src->add(Command(Command::Wait)); | 268 src->add(Command(Command::Wait)); |
235 src->add(Command(Command::Done)); | 269 src->add(Command(Command::Done)); |
236 | 270 |
237 OwnPtr<TeeCreationThread> t = adoptPtr(new TeeCreationThread()); | 271 OwnPtr<TeeCreationThread<WebDataConsumerHandle>> t = adoptPtr(new TeeCreatio
nThread<WebDataConsumerHandle>()); |
238 t->run(src.release(), &dest1, &dest2); | 272 t->run(src.release(), &dest1, &dest2); |
239 | 273 |
240 ASSERT_TRUE(dest1); | 274 ASSERT_TRUE(dest1); |
241 ASSERT_TRUE(dest2); | 275 ASSERT_TRUE(dest2); |
242 | 276 |
243 HandleTwoPhaseReader r1, r2; | 277 HandleTwoPhaseReader r1, r2; |
244 r1.start(dest1.release()); | 278 r1.start(dest1.release()); |
245 r2.start(dest2.release()); | 279 r2.start(dest2.release()); |
246 | 280 |
247 r1.waitableEvent()->wait(); | 281 r1.waitableEvent()->wait(); |
248 r2.waitableEvent()->wait(); | 282 r2.waitableEvent()->wait(); |
249 | 283 |
250 EXPECT_EQ(kDone, r1.finalResult()); | 284 EXPECT_EQ(kDone, r1.finalResult()); |
251 EXPECT_EQ("hello, world", r1.readString()); | 285 EXPECT_EQ("hello, world", r1.readString()); |
252 | 286 |
253 EXPECT_EQ(kDone, r2.finalResult()); | 287 EXPECT_EQ(kDone, r2.finalResult()); |
254 EXPECT_EQ("hello, world", r2.readString()); | 288 EXPECT_EQ("hello, world", r2.readString()); |
255 } | 289 } |
256 | 290 |
257 TEST(DataConsumerTeeTest, Error) | 291 TEST(DataConsumerTeeTest, Error) |
258 { | 292 { |
259 OwnPtr<Handle> src(Handle::create()); | 293 OwnPtr<Handle> src(Handle::create()); |
260 OwnPtr<WebDataConsumerHandle> dest1, dest2; | 294 OwnPtr<WebDataConsumerHandle> dest1, dest2; |
261 | 295 |
262 src->add(Command(Command::Data, "hello, ")); | 296 src->add(Command(Command::Data, "hello, ")); |
263 src->add(Command(Command::Data, "world")); | 297 src->add(Command(Command::Data, "world")); |
264 src->add(Command(Command::Error)); | 298 src->add(Command(Command::Error)); |
265 | 299 |
266 OwnPtr<TeeCreationThread> t = adoptPtr(new TeeCreationThread()); | 300 OwnPtr<TeeCreationThread<WebDataConsumerHandle>> t = adoptPtr(new TeeCreatio
nThread<WebDataConsumerHandle>()); |
267 t->run(src.release(), &dest1, &dest2); | 301 t->run(src.release(), &dest1, &dest2); |
268 | 302 |
269 ASSERT_TRUE(dest1); | 303 ASSERT_TRUE(dest1); |
270 ASSERT_TRUE(dest2); | 304 ASSERT_TRUE(dest2); |
271 | 305 |
272 HandleReader r1, r2; | 306 HandleReader r1, r2; |
273 r1.start(dest1.release()); | 307 r1.start(dest1.release()); |
274 r2.start(dest2.release()); | 308 r2.start(dest2.release()); |
275 | 309 |
276 r1.waitableEvent()->wait(); | 310 r1.waitableEvent()->wait(); |
277 r2.waitableEvent()->wait(); | 311 r2.waitableEvent()->wait(); |
278 | 312 |
279 EXPECT_EQ(kUnexpectedError, r1.finalResult()); | 313 EXPECT_EQ(kUnexpectedError, r1.finalResult()); |
280 EXPECT_EQ(kUnexpectedError, r2.finalResult()); | 314 EXPECT_EQ(kUnexpectedError, r2.finalResult()); |
281 } | 315 } |
282 | 316 |
283 void postStop(Thread* thread) | 317 void postStop(Thread* thread) |
284 { | 318 { |
285 thread->executionContext()->stopActiveDOMObjects(); | 319 thread->executionContext()->stopActiveDOMObjects(); |
286 } | 320 } |
287 | 321 |
288 TEST(DataConsumerTeeTest, StopSource) | 322 TEST(DataConsumerTeeTest, StopSource) |
289 { | 323 { |
290 OwnPtr<Handle> src(Handle::create()); | 324 OwnPtr<Handle> src(Handle::create()); |
291 OwnPtr<WebDataConsumerHandle> dest1, dest2; | 325 OwnPtr<WebDataConsumerHandle> dest1, dest2; |
292 | 326 |
293 src->add(Command(Command::Data, "hello, ")); | 327 src->add(Command(Command::Data, "hello, ")); |
294 src->add(Command(Command::Data, "world")); | 328 src->add(Command(Command::Data, "world")); |
295 | 329 |
296 OwnPtr<TeeCreationThread> t = adoptPtr(new TeeCreationThread()); | 330 OwnPtr<TeeCreationThread<WebDataConsumerHandle>> t = adoptPtr(new TeeCreatio
nThread<WebDataConsumerHandle>()); |
297 t->run(src.release(), &dest1, &dest2); | 331 t->run(src.release(), &dest1, &dest2); |
298 | 332 |
299 ASSERT_TRUE(dest1); | 333 ASSERT_TRUE(dest1); |
300 ASSERT_TRUE(dest2); | 334 ASSERT_TRUE(dest2); |
301 | 335 |
302 HandleReader r1, r2; | 336 HandleReader r1, r2; |
303 r1.start(dest1.release()); | 337 r1.start(dest1.release()); |
304 r2.start(dest2.release()); | 338 r2.start(dest2.release()); |
305 | 339 |
306 // We can pass a raw pointer because the subsequent |wait| calls ensure | 340 // We can pass a raw pointer because the subsequent |wait| calls ensure |
307 // t->thread() is alive. | 341 // t->thread() is alive. |
308 t->thread()->thread()->postTask(FROM_HERE, new Task(threadSafeBind(postStop,
AllowCrossThreadAccess(t->thread())))); | 342 t->thread()->thread()->postTask(FROM_HERE, new Task(threadSafeBind(postStop,
AllowCrossThreadAccess(t->thread())))); |
309 | 343 |
310 r1.waitableEvent()->wait(); | 344 r1.waitableEvent()->wait(); |
311 r2.waitableEvent()->wait(); | 345 r2.waitableEvent()->wait(); |
312 | 346 |
313 EXPECT_EQ(kUnexpectedError, r1.finalResult()); | 347 EXPECT_EQ(kUnexpectedError, r1.finalResult()); |
314 EXPECT_EQ(kUnexpectedError, r2.finalResult()); | 348 EXPECT_EQ(kUnexpectedError, r2.finalResult()); |
315 } | 349 } |
316 | 350 |
317 TEST(DataConsumerTeeTest, DetachSource) | 351 TEST(DataConsumerTeeTest, DetachSource) |
318 { | 352 { |
319 OwnPtr<Handle> src(Handle::create()); | 353 OwnPtr<Handle> src(Handle::create()); |
320 OwnPtr<WebDataConsumerHandle> dest1, dest2; | 354 OwnPtr<WebDataConsumerHandle> dest1, dest2; |
321 | 355 |
322 src->add(Command(Command::Data, "hello, ")); | 356 src->add(Command(Command::Data, "hello, ")); |
323 src->add(Command(Command::Data, "world")); | 357 src->add(Command(Command::Data, "world")); |
324 | 358 |
325 OwnPtr<TeeCreationThread> t = adoptPtr(new TeeCreationThread()); | 359 OwnPtr<TeeCreationThread<WebDataConsumerHandle>> t = adoptPtr(new TeeCreatio
nThread<WebDataConsumerHandle>()); |
326 t->run(src.release(), &dest1, &dest2); | 360 t->run(src.release(), &dest1, &dest2); |
327 | 361 |
328 ASSERT_TRUE(dest1); | 362 ASSERT_TRUE(dest1); |
329 ASSERT_TRUE(dest2); | 363 ASSERT_TRUE(dest2); |
330 | 364 |
331 HandleReader r1, r2; | 365 HandleReader r1, r2; |
332 r1.start(dest1.release()); | 366 r1.start(dest1.release()); |
333 r2.start(dest2.release()); | 367 r2.start(dest2.release()); |
334 | 368 |
335 t = nullptr; | 369 t = nullptr; |
336 | 370 |
337 r1.waitableEvent()->wait(); | 371 r1.waitableEvent()->wait(); |
338 r2.waitableEvent()->wait(); | 372 r2.waitableEvent()->wait(); |
339 | 373 |
340 EXPECT_EQ(kUnexpectedError, r1.finalResult()); | 374 EXPECT_EQ(kUnexpectedError, r1.finalResult()); |
341 EXPECT_EQ(kUnexpectedError, r2.finalResult()); | 375 EXPECT_EQ(kUnexpectedError, r2.finalResult()); |
342 } | 376 } |
343 | 377 |
344 TEST(DataConsumerTeeTest, DetachSourceAfterReadingDone) | 378 TEST(DataConsumerTeeTest, DetachSourceAfterReadingDone) |
345 { | 379 { |
346 OwnPtr<Handle> src(Handle::create()); | 380 OwnPtr<Handle> src(Handle::create()); |
347 OwnPtr<WebDataConsumerHandle> dest1, dest2; | 381 OwnPtr<WebDataConsumerHandle> dest1, dest2; |
348 | 382 |
349 src->add(Command(Command::Data, "hello, ")); | 383 src->add(Command(Command::Data, "hello, ")); |
350 src->add(Command(Command::Data, "world")); | 384 src->add(Command(Command::Data, "world")); |
351 src->add(Command(Command::Done)); | 385 src->add(Command(Command::Done)); |
352 | 386 |
353 OwnPtr<TeeCreationThread> t = adoptPtr(new TeeCreationThread()); | 387 OwnPtr<TeeCreationThread<WebDataConsumerHandle>> t = adoptPtr(new TeeCreatio
nThread<WebDataConsumerHandle>()); |
354 t->run(src.release(), &dest1, &dest2); | 388 t->run(src.release(), &dest1, &dest2); |
355 | 389 |
356 ASSERT_TRUE(dest1); | 390 ASSERT_TRUE(dest1); |
357 ASSERT_TRUE(dest2); | 391 ASSERT_TRUE(dest2); |
358 | 392 |
359 HandleReader r1, r2; | 393 HandleReader r1, r2; |
360 r1.start(dest1.release()); | 394 r1.start(dest1.release()); |
361 r1.waitableEvent()->wait(); | 395 r1.waitableEvent()->wait(); |
362 | 396 |
363 EXPECT_EQ(kDone, r1.finalResult()); | 397 EXPECT_EQ(kDone, r1.finalResult()); |
(...skipping 10 matching lines...) Expand all Loading... |
374 | 408 |
375 TEST(DataConsumerTeeTest, DetachOneDestination) | 409 TEST(DataConsumerTeeTest, DetachOneDestination) |
376 { | 410 { |
377 OwnPtr<Handle> src(Handle::create()); | 411 OwnPtr<Handle> src(Handle::create()); |
378 OwnPtr<WebDataConsumerHandle> dest1, dest2; | 412 OwnPtr<WebDataConsumerHandle> dest1, dest2; |
379 | 413 |
380 src->add(Command(Command::Data, "hello, ")); | 414 src->add(Command(Command::Data, "hello, ")); |
381 src->add(Command(Command::Data, "world")); | 415 src->add(Command(Command::Data, "world")); |
382 src->add(Command(Command::Done)); | 416 src->add(Command(Command::Done)); |
383 | 417 |
384 OwnPtr<TeeCreationThread> t = adoptPtr(new TeeCreationThread()); | 418 OwnPtr<TeeCreationThread<WebDataConsumerHandle>> t = adoptPtr(new TeeCreatio
nThread<WebDataConsumerHandle>()); |
385 t->run(src.release(), &dest1, &dest2); | 419 t->run(src.release(), &dest1, &dest2); |
386 | 420 |
387 ASSERT_TRUE(dest1); | 421 ASSERT_TRUE(dest1); |
388 ASSERT_TRUE(dest2); | 422 ASSERT_TRUE(dest2); |
389 | 423 |
390 dest1 = nullptr; | 424 dest1 = nullptr; |
391 | 425 |
392 HandleReader r2; | 426 HandleReader r2; |
393 r2.start(dest2.release()); | 427 r2.start(dest2.release()); |
394 r2.waitableEvent()->wait(); | 428 r2.waitableEvent()->wait(); |
395 | 429 |
396 EXPECT_EQ(kDone, r2.finalResult()); | 430 EXPECT_EQ(kDone, r2.finalResult()); |
397 EXPECT_EQ("hello, world", r2.readString()); | 431 EXPECT_EQ("hello, world", r2.readString()); |
398 } | 432 } |
399 | 433 |
400 TEST(DataConsumerTeeTest, DetachBothDestinationsShouldStopSourceReader) | 434 TEST(DataConsumerTeeTest, DetachBothDestinationsShouldStopSourceReader) |
401 { | 435 { |
402 OwnPtr<Handle> src(Handle::create()); | 436 OwnPtr<Handle> src(Handle::create()); |
403 RefPtr<Handle::Context> context(src->context()); | 437 RefPtr<Handle::Context> context(src->context()); |
404 OwnPtr<WebDataConsumerHandle> dest1, dest2; | 438 OwnPtr<WebDataConsumerHandle> dest1, dest2; |
405 | 439 |
406 src->add(Command(Command::Data, "hello, ")); | 440 src->add(Command(Command::Data, "hello, ")); |
407 src->add(Command(Command::Data, "world")); | 441 src->add(Command(Command::Data, "world")); |
408 | 442 |
409 OwnPtr<TeeCreationThread> t = adoptPtr(new TeeCreationThread()); | 443 OwnPtr<TeeCreationThread<WebDataConsumerHandle>> t = adoptPtr(new TeeCreatio
nThread<WebDataConsumerHandle>()); |
410 t->run(src.release(), &dest1, &dest2); | 444 t->run(src.release(), &dest1, &dest2); |
411 | 445 |
412 ASSERT_TRUE(dest1); | 446 ASSERT_TRUE(dest1); |
413 ASSERT_TRUE(dest2); | 447 ASSERT_TRUE(dest2); |
414 | 448 |
415 dest1 = nullptr; | 449 dest1 = nullptr; |
416 dest2 = nullptr; | 450 dest2 = nullptr; |
417 | 451 |
418 // Collect garbage to finalize the source reader. | 452 // Collect garbage to finalize the source reader. |
419 Heap::collectAllGarbage(); | 453 Heap::collectAllGarbage(); |
420 context->detached()->wait(); | 454 context->detached()->wait(); |
421 } | 455 } |
422 | 456 |
| 457 TEST(FetchDataConsumerTeeTest, Create) |
| 458 { |
| 459 RefPtr<BlobDataHandle> blobDataHandle = BlobDataHandle::create(); |
| 460 OwnPtr<MockFetchDataConsumerHandle> src(MockFetchDataConsumerHandle::create(
)); |
| 461 OwnPtr<MockFetchDataConsumerReader> reader(MockFetchDataConsumerReader::crea
te()); |
| 462 |
| 463 Checkpoint checkpoint; |
| 464 InSequence s; |
| 465 EXPECT_CALL(checkpoint, Call(1)); |
| 466 EXPECT_CALL(*src, obtainReaderInternal(_)).WillOnce(Return(reader.get())); |
| 467 EXPECT_CALL(*reader, drainAsBlobDataHandle(kAllowBlobWithInvalidSize)).WillO
nce(Return(blobDataHandle)); |
| 468 EXPECT_CALL(*reader, destruct()); |
| 469 EXPECT_CALL(checkpoint, Call(2)); |
| 470 |
| 471 // |reader| is adopted by |obtainReader|. |
| 472 ASSERT_TRUE(reader.leakPtr()); |
| 473 |
| 474 OwnPtr<FetchDataConsumerHandle> dest1, dest2; |
| 475 OwnPtr<TeeCreationThread<FetchDataConsumerHandle>> t = adoptPtr(new TeeCreat
ionThread<FetchDataConsumerHandle>()); |
| 476 |
| 477 checkpoint.Call(1); |
| 478 t->run(src.release(), &dest1, &dest2); |
| 479 checkpoint.Call(2); |
| 480 |
| 481 ASSERT_TRUE(dest1); |
| 482 ASSERT_TRUE(dest2); |
| 483 EXPECT_EQ(blobDataHandle, dest1->obtainReader(nullptr)->drainAsBlobDataHandl
e(kAllowBlobWithInvalidSize)); |
| 484 EXPECT_EQ(blobDataHandle, dest2->obtainReader(nullptr)->drainAsBlobDataHandl
e(kAllowBlobWithInvalidSize)); |
| 485 } |
| 486 |
| 487 TEST(FetchDataConsumerTeeTest, CreateFromBlobWithInvalidSize) |
| 488 { |
| 489 RefPtr<BlobDataHandle> blobDataHandle = BlobDataHandle::create(BlobData::cre
ate(), -1); |
| 490 OwnPtr<MockFetchDataConsumerHandle> src(MockFetchDataConsumerHandle::create(
)); |
| 491 OwnPtr<MockFetchDataConsumerReader> reader(MockFetchDataConsumerReader::crea
te()); |
| 492 |
| 493 Checkpoint checkpoint; |
| 494 InSequence s; |
| 495 EXPECT_CALL(checkpoint, Call(1)); |
| 496 EXPECT_CALL(*src, obtainReaderInternal(_)).WillOnce(Return(reader.get())); |
| 497 EXPECT_CALL(*reader, drainAsBlobDataHandle(kAllowBlobWithInvalidSize)).WillO
nce(Return(blobDataHandle)); |
| 498 EXPECT_CALL(*reader, destruct()); |
| 499 EXPECT_CALL(checkpoint, Call(2)); |
| 500 |
| 501 // |reader| is adopted by |obtainReader|. |
| 502 ASSERT_TRUE(reader.leakPtr()); |
| 503 |
| 504 OwnPtr<FetchDataConsumerHandle> dest1, dest2; |
| 505 OwnPtr<TeeCreationThread<FetchDataConsumerHandle>> t = adoptPtr(new TeeCreat
ionThread<FetchDataConsumerHandle>()); |
| 506 |
| 507 checkpoint.Call(1); |
| 508 t->run(src.release(), &dest1, &dest2); |
| 509 checkpoint.Call(2); |
| 510 |
| 511 ASSERT_TRUE(dest1); |
| 512 ASSERT_TRUE(dest2); |
| 513 EXPECT_FALSE(dest1->obtainReader(nullptr)->drainAsBlobDataHandle(kDisallowBl
obWithInvalidSize)); |
| 514 EXPECT_EQ(blobDataHandle, dest1->obtainReader(nullptr)->drainAsBlobDataHandl
e(kAllowBlobWithInvalidSize)); |
| 515 EXPECT_FALSE(dest2->obtainReader(nullptr)->drainAsBlobDataHandle(kDisallowBl
obWithInvalidSize)); |
| 516 EXPECT_EQ(blobDataHandle, dest2->obtainReader(nullptr)->drainAsBlobDataHandl
e(kAllowBlobWithInvalidSize)); |
| 517 } |
| 518 |
| 519 TEST(FetchDataConsumerTeeTest, CreateDone) |
| 520 { |
| 521 OwnPtr<Handle> src(Handle::create()); |
| 522 OwnPtr<FetchDataConsumerHandle> dest1, dest2; |
| 523 |
| 524 src->add(Command(Command::Done)); |
| 525 |
| 526 OwnPtr<TeeCreationThread<FetchDataConsumerHandle>> t = adoptPtr(new TeeCreat
ionThread<FetchDataConsumerHandle>()); |
| 527 t->run(createFetchDataConsumerHandleFromWebHandle(src.release()), &dest1, &d
est2); |
| 528 |
| 529 ASSERT_TRUE(dest1); |
| 530 ASSERT_TRUE(dest2); |
| 531 |
| 532 EXPECT_FALSE(dest1->obtainReader(nullptr)->drainAsBlobDataHandle(kAllowBlobW
ithInvalidSize)); |
| 533 EXPECT_FALSE(dest2->obtainReader(nullptr)->drainAsBlobDataHandle(kAllowBlobW
ithInvalidSize)); |
| 534 |
| 535 HandleReader r1, r2; |
| 536 r1.start(dest1.release()); |
| 537 r2.start(dest2.release()); |
| 538 |
| 539 r1.waitableEvent()->wait(); |
| 540 r2.waitableEvent()->wait(); |
| 541 |
| 542 EXPECT_EQ(kDone, r1.finalResult()); |
| 543 EXPECT_EQ(String(), r1.readString()); |
| 544 |
| 545 EXPECT_EQ(kDone, r2.finalResult()); |
| 546 EXPECT_EQ(String(), r2.readString()); |
| 547 } |
| 548 |
423 } // namespace | 549 } // namespace |
424 } // namespace blink | 550 } // namespace blink |
OLD | NEW |