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

Side by Side Diff: net/socket/socket_bio_adapter_unittest.cc

Issue 2411033003: Drop buffers in idle SSLClientSockets (and SSLServerSockets). (Closed)
Patch Set: typo Created 4 years, 2 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
OLDNEW
(Empty)
1 // Copyright 2016 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 "net/socket/socket_bio_adapter.h"
6
7 #include <openssl/bio.h>
8 #include <openssl/err.h>
9 #include <openssl/ssl.h>
10 #include <string.h>
11
12 #include <memory>
13
14 #include "base/location.h"
15 #include "base/logging.h"
16 #include "base/macros.h"
17 #include "base/memory/ptr_util.h"
18 #include "base/run_loop.h"
19 #include "crypto/openssl_util.h"
20 #include "net/base/address_list.h"
21 #include "net/base/net_errors.h"
22 #include "net/log/net_log_source.h"
23 #include "net/socket/socket_test_util.h"
24 #include "net/socket/stream_socket.h"
25 #include "net/ssl/openssl_ssl_util.h"
26 #include "testing/gtest/include/gtest/gtest.h"
27
28 namespace net {
29
30 class SocketBIOAdapterTest : public testing::Test,
31 public SocketBIOAdapter::Delegate {
32 protected:
33 std::unique_ptr<StreamSocket> MakeTestSocket(SocketDataProvider* data) {
34 data->set_connect_data(MockConnect(SYNCHRONOUS, OK));
35 factory_.AddSocketDataProvider(data);
36 std::unique_ptr<StreamSocket> socket = factory_.CreateTransportClientSocket(
37 AddressList(), nullptr, nullptr, NetLogSource());
38 CHECK_EQ(OK, socket->Connect(net::CompletionCallback()));
39 return socket;
40 }
41
42 void set_reset_on_write_ready(
43 std::unique_ptr<SocketBIOAdapter>* reset_on_write_ready) {
44 reset_on_write_ready_ = reset_on_write_ready;
45 }
46
47 void ExpectReadError(BIO* bio,
48 int error,
49 const crypto::OpenSSLErrStackTracer& tracer) {
50 // BIO_read should fail.
51 char buf;
52 EXPECT_EQ(-1, BIO_read(bio, &buf, 1));
53 EXPECT_EQ(error, MapOpenSSLError(SSL_ERROR_SSL, tracer));
54 EXPECT_FALSE(BIO_should_read(bio));
55
56 // Repeating the operation should replay the error.
57 EXPECT_EQ(-1, BIO_read(bio, &buf, 1));
58 EXPECT_EQ(error, MapOpenSSLError(SSL_ERROR_SSL, tracer));
59 EXPECT_FALSE(BIO_should_read(bio));
60 }
61
62 void ExpectBlockingRead(BIO* bio, void* buf, int len) {
63 // BIO_read should return a retryable error.
64 EXPECT_EQ(-1, BIO_read(bio, buf, len));
65 EXPECT_TRUE(BIO_should_read(bio));
66 EXPECT_EQ(0u, ERR_peek_error());
67
68 // Repeating the operation has the same result.
69 EXPECT_EQ(-1, BIO_read(bio, buf, len));
70 EXPECT_TRUE(BIO_should_read(bio));
71 EXPECT_EQ(0u, ERR_peek_error());
72 }
73
74 void ExpectWriteError(BIO* bio,
75 int error,
76 const crypto::OpenSSLErrStackTracer& tracer) {
77 // BIO_write should fail.
78 char buf = '?';
79 EXPECT_EQ(-1, BIO_write(bio, &buf, 1));
80 EXPECT_EQ(error, MapOpenSSLError(SSL_ERROR_SSL, tracer));
81 EXPECT_FALSE(BIO_should_write(bio));
82
83 // Repeating the operation should replay the error.
84 EXPECT_EQ(-1, BIO_write(bio, &buf, 1));
85 EXPECT_EQ(error, MapOpenSSLError(SSL_ERROR_SSL, tracer));
86 EXPECT_FALSE(BIO_should_write(bio));
87 }
88
89 void ExpectBlockingWrite(BIO* bio, const void* buf, int len) {
90 // BIO_write should return a retryable error.
91 EXPECT_EQ(-1, BIO_write(bio, buf, len));
92 EXPECT_TRUE(BIO_should_write(bio));
93 EXPECT_EQ(0u, ERR_peek_error());
94
95 // Repeating the operation has the same result.
96 EXPECT_EQ(-1, BIO_write(bio, buf, len));
97 EXPECT_TRUE(BIO_should_write(bio));
98 EXPECT_EQ(0u, ERR_peek_error());
99 }
100
101 void WaitForReadReady() {
102 expect_read_ready_ = true;
103 base::RunLoop().RunUntilIdle();
104 EXPECT_FALSE(expect_read_ready_);
105 }
106
107 void WaitForWriteReady(SequencedSocketData* to_resume) {
108 expect_write_ready_ = true;
109 if (to_resume)
110 to_resume->Resume();
111 base::RunLoop().RunUntilIdle();
112 EXPECT_FALSE(expect_write_ready_);
113 }
114
115 void WaitForBothReady() {
116 expect_read_ready_ = true;
117 expect_write_ready_ = true;
118 base::RunLoop().RunUntilIdle();
119 EXPECT_FALSE(expect_read_ready_);
120 EXPECT_FALSE(expect_write_ready_);
121 }
122
123 // SocketBIOAdapter::Delegate implementation:
124 void OnReadReady() override {
125 EXPECT_TRUE(expect_read_ready_);
126 expect_read_ready_ = false;
127 }
128
129 void OnWriteReady() override {
130 EXPECT_TRUE(expect_write_ready_);
131 expect_write_ready_ = false;
132 if (reset_on_write_ready_)
133 reset_on_write_ready_->reset();
134 }
135
136 private:
137 bool expect_read_ready_ = false;
138 bool expect_write_ready_ = false;
139 MockClientSocketFactory factory_;
140 std::unique_ptr<SocketBIOAdapter>* reset_on_write_ready_ = nullptr;
141 };
142
143 // Test that data can be read synchronously.
144 TEST_F(SocketBIOAdapterTest, ReadSync) {
145 crypto::OpenSSLErrStackTracer tracer(FROM_HERE);
146
147 MockRead reads[] = {
148 MockRead(SYNCHRONOUS, 0, "hello"), MockRead(SYNCHRONOUS, 1, "world"),
149 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET, 2),
150 };
151
152 SequencedSocketData data(reads, arraysize(reads), nullptr, 0);
153 std::unique_ptr<StreamSocket> socket = MakeTestSocket(&data);
154 std::unique_ptr<SocketBIOAdapter> adapter =
155 base::MakeUnique<SocketBIOAdapter>(socket.get(), 100, 100, this);
156 BIO* bio = adapter->bio();
157 EXPECT_FALSE(adapter->HasPendingReadData());
158
159 // Read the data synchronously. Although the buffer has room for both,
160 // BIO_read only reports one socket-level Read.
161 char buf[10];
162 EXPECT_EQ(5, BIO_read(bio, buf, sizeof(buf)));
163 EXPECT_EQ(0, memcmp("hello", buf, 5));
164 EXPECT_FALSE(adapter->HasPendingReadData());
165
166 // Consume the next portion one byte at a time.
167 EXPECT_EQ(1, BIO_read(bio, buf, 1));
168 EXPECT_EQ('w', buf[0]);
169 EXPECT_TRUE(adapter->HasPendingReadData());
170
171 EXPECT_EQ(1, BIO_read(bio, buf, 1));
172 EXPECT_EQ('o', buf[0]);
173 EXPECT_TRUE(adapter->HasPendingReadData());
174
175 // The remainder may be consumed in a single BIO_read.
176 EXPECT_EQ(3, BIO_read(bio, buf, sizeof(buf)));
177 EXPECT_EQ(0, memcmp("rld", buf, 3));
178 EXPECT_FALSE(adapter->HasPendingReadData());
179
180 // The error is available synchoronously.
181 ExpectReadError(bio, ERR_CONNECTION_RESET, tracer);
182 }
183
184 // Test that data can be read asynchronously.
185 TEST_F(SocketBIOAdapterTest, ReadAsync) {
186 crypto::OpenSSLErrStackTracer tracer(FROM_HERE);
187
188 MockRead reads[] = {
189 MockRead(ASYNC, 0, "hello"), MockRead(ASYNC, 1, "world"),
190 MockRead(ASYNC, ERR_CONNECTION_RESET, 2),
191 };
192
193 SequencedSocketData data(reads, arraysize(reads), nullptr, 0);
194 std::unique_ptr<StreamSocket> socket = MakeTestSocket(&data);
195 std::unique_ptr<SocketBIOAdapter> adapter =
196 base::MakeUnique<SocketBIOAdapter>(socket.get(), 100, 100, this);
197 BIO* bio = adapter->bio();
198 EXPECT_FALSE(adapter->HasPendingReadData());
199
200 // Attempt to read data. It will fail but schedule a Read.
201 char buf[10];
202 ExpectBlockingRead(bio, buf, sizeof(buf));
203 EXPECT_FALSE(adapter->HasPendingReadData());
204
205 // After waiting, the data is available.
206 WaitForReadReady();
207 EXPECT_TRUE(adapter->HasPendingReadData());
208
209 // The first read is now available synchronously.
210 EXPECT_EQ(5, BIO_read(bio, buf, sizeof(buf)));
211 EXPECT_EQ(0, memcmp("hello", buf, 5));
212 EXPECT_FALSE(adapter->HasPendingReadData());
213
214 // The adapter does not schedule another Read until BIO_read is next called.
215 base::RunLoop().RunUntilIdle();
216 EXPECT_FALSE(adapter->HasPendingReadData());
217
218 // This time, under-request the data. The adapter should still read the full
219 // amount.
220 ExpectBlockingRead(bio, buf, 1);
221 EXPECT_FALSE(adapter->HasPendingReadData());
222 WaitForReadReady();
223 EXPECT_TRUE(adapter->HasPendingReadData());
224
225 // The next read is now available synchronously.
226 EXPECT_EQ(5, BIO_read(bio, buf, sizeof(buf)));
227 EXPECT_EQ(0, memcmp("world", buf, 5));
228 EXPECT_FALSE(adapter->HasPendingReadData());
229
230 // The error is not yet available.
231 ExpectBlockingRead(bio, buf, sizeof(buf));
232 WaitForReadReady();
233
234 // The error is now available synchoronously.
235 ExpectReadError(bio, ERR_CONNECTION_RESET, tracer);
236 }
237
238 // Test that synchronous EOF is mapped to ERR_CONNECTION_CLOSED.
239 TEST_F(SocketBIOAdapterTest, ReadEOFSync) {
240 crypto::OpenSSLErrStackTracer tracer(FROM_HERE);
241
242 MockRead reads[] = {
243 MockRead(SYNCHRONOUS, 0, 0),
244 };
245
246 SequencedSocketData data(reads, arraysize(reads), nullptr, 0);
247 std::unique_ptr<StreamSocket> socket = MakeTestSocket(&data);
248 std::unique_ptr<SocketBIOAdapter> adapter =
249 base::MakeUnique<SocketBIOAdapter>(socket.get(), 100, 100, this);
250
251 ExpectReadError(adapter->bio(), ERR_CONNECTION_CLOSED, tracer);
252 }
253
254 // Test that asynchronous EOF is mapped to ERR_CONNECTION_CLOSED.
255 TEST_F(SocketBIOAdapterTest, ReadEOFAsync) {
256 crypto::OpenSSLErrStackTracer tracer(FROM_HERE);
257
258 MockRead reads[] = {
259 MockRead(ASYNC, 0, 0),
260 };
261
262 SequencedSocketData data(reads, arraysize(reads), nullptr, 0);
263 std::unique_ptr<StreamSocket> socket = MakeTestSocket(&data);
264 std::unique_ptr<SocketBIOAdapter> adapter =
265 base::MakeUnique<SocketBIOAdapter>(socket.get(), 100, 100, this);
266
267 char buf;
268 ExpectBlockingRead(adapter->bio(), &buf, 1);
269 WaitForReadReady();
270 ExpectReadError(adapter->bio(), ERR_CONNECTION_CLOSED, tracer);
271 }
272
273 // Test that data can be written synchronously.
274 TEST_F(SocketBIOAdapterTest, WriteSync) {
275 crypto::OpenSSLErrStackTracer tracer(FROM_HERE);
276
277 MockWrite writes[] = {
278 MockWrite(SYNCHRONOUS, 0, "hello"),
279 MockWrite(SYNCHRONOUS, 1, "wor"),
280 MockWrite(SYNCHRONOUS, 2, "ld"),
281 MockWrite(SYNCHRONOUS, 3, "helloworld"),
282 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET, 4),
283 };
284
285 SequencedSocketData data(nullptr, 0, writes, arraysize(writes));
286 std::unique_ptr<StreamSocket> socket = MakeTestSocket(&data);
287 std::unique_ptr<SocketBIOAdapter> adapter =
288 base::MakeUnique<SocketBIOAdapter>(socket.get(), 10, 10, this);
289 BIO* bio = adapter->bio();
290
291 // Test data entering and leaving the buffer synchronously. The second write
292 // takes multiple iterations (events 0 to 2).
293 EXPECT_EQ(5, BIO_write(bio, "hello", 5));
294 EXPECT_EQ(5, BIO_write(bio, "world", 5));
295
296 // If writing larger than the buffer size, only part of the data is written
297 // (event 3).
298 EXPECT_EQ(10, BIO_write(bio, "helloworldhelloworld", 20));
299
300 // Writing "aaaaa" fails (event 4), but there is a write buffer, so errors
301 // are delayed.
302 EXPECT_EQ(5, BIO_write(bio, "aaaaa", 5));
303
304 // However once the error is registered, subsequent writes fail.
305 ExpectWriteError(bio, ERR_CONNECTION_RESET, tracer);
306 }
307
308 // Test that data can be written asynchronously.
309 TEST_F(SocketBIOAdapterTest, WriteAsync) {
310 crypto::OpenSSLErrStackTracer tracer(FROM_HERE);
311
312 MockWrite writes[] = {
313 MockWrite(ASYNC, 0, "aaa"),
314 MockWrite(ASYNC, ERR_IO_PENDING, 1), // pause
315 MockWrite(ASYNC, 2, "aabbbbb"),
316 MockWrite(ASYNC, 3, "ccc"),
317 MockWrite(ASYNC, 4, "ddd"),
318 MockWrite(ASYNC, ERR_IO_PENDING, 5), // pause
319 MockWrite(ASYNC, 6, "dd"),
320 MockWrite(SYNCHRONOUS, 7, "e"),
321 MockWrite(SYNCHRONOUS, 8, "e"),
322 MockWrite(ASYNC, 9, "e"),
323 MockWrite(ASYNC, 10, "ee"),
324 MockWrite(ASYNC, ERR_IO_PENDING, 11), // pause
325 MockWrite(ASYNC, ERR_CONNECTION_RESET, 12),
326 };
327
328 SequencedSocketData data(nullptr, 0, writes, arraysize(writes));
329 std::unique_ptr<StreamSocket> socket = MakeTestSocket(&data);
330 std::unique_ptr<SocketBIOAdapter> adapter =
331 base::MakeUnique<SocketBIOAdapter>(socket.get(), 10, 10, this);
332 BIO* bio = adapter->bio();
333
334 // Data which fits in the buffer is returned synchronously, even if not
335 // flushed synchronously.
336 EXPECT_EQ(5, BIO_write(bio, "aaaaa", 5));
337 EXPECT_EQ(5, BIO_write(bio, "bbbbb", 5));
338
339 // The buffer contains:
340 //
341 // [aaaaabbbbb]
342 // ^
343
344 // The buffer is full now, so the next write will block.
345 ExpectBlockingWrite(bio, "zzzzz", 5);
346
347 // Let the first socket write complete (event 0) and pause (event 1).
348 WaitForWriteReady(nullptr);
349 EXPECT_TRUE(data.IsPaused());
350
351 // The buffer contains:
352 //
353 // [...aabbbbb]
354 // ^
355
356 // The ring buffer now has 3 bytes of space with "aabbbbb" still to be
357 // written. Attempting to write 3 bytes means 3 succeed.
358 EXPECT_EQ(3, BIO_write(bio, "cccccccccc", 10));
359
360 // The buffer contains:
361 //
362 // [cccaabbbbb]
363 // ^
364
365 // Drain the buffer (events 2 and 3).
366 WaitForWriteReady(&data);
367
368 // The buffer is now empty.
369
370 // Now test something similar but arrange for a BIO_write (the 'e's below) to
371 // wrap around the buffer. Write five bytes into the buffer, flush the first
372 // three (event 4), and pause (event 5). OnWriteReady is not signaled because
373 // the buffer was not full.
374 EXPECT_EQ(5, BIO_write(bio, "ddddd", 5));
375 base::RunLoop().RunUntilIdle();
376 EXPECT_TRUE(data.IsPaused());
377
378 // The buffer contains:
379 //
380 // [...dd.....]
381 // ^
382
383 // The adapter maintains a ring buffer, so 8 bytes fit.
384 EXPECT_EQ(8, BIO_write(bio, "eeeeeeeeee", 10));
385
386 // The buffer contains:
387 //
388 // [eeeddeeeee]
389 // ^
390
391 // Drain to the end of the ring buffer, so it wraps around (events 6 to 10)
392 // and pause (event 11). Test that synchronous and asynchronous writes both
393 // drain. The start of the buffer has now wrapped around.
394 WaitForWriteReady(&data);
395 EXPECT_TRUE(data.IsPaused());
396
397 // The buffer contains:
398 //
399 // [eee.......]
400 // ^
401
402 // Test wrapping around works correctly and the buffer may be appended to.
403 EXPECT_EQ(7, BIO_write(bio, "fffffffff", 10));
404
405 // The buffer contains:
406 //
407 // [eeefffffff]
408 // ^
409
410 // The buffer is full now, so the next write will block.
411 ExpectBlockingWrite(bio, "zzzzz", 5);
412
413 // Release the write error (event 12). At this point future BIO_write calls
414 // fail.
415 WaitForWriteReady(&data);
416 ExpectWriteError(bio, ERR_CONNECTION_RESET, tracer);
417 }
418
419 // Test that a failed socket write is reported through BIO_read and prevents it
420 // from scheduling a socket read. See https://crbug.com/249848.
421 TEST_F(SocketBIOAdapterTest, WriteStopsRead) {
422 crypto::OpenSSLErrStackTracer tracer(FROM_HERE);
423
424 MockWrite writes[] = {
425 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET, 0),
426 };
427
428 SequencedSocketData data(nullptr, 0, writes, arraysize(writes));
429 std::unique_ptr<StreamSocket> socket = MakeTestSocket(&data);
430 std::unique_ptr<SocketBIOAdapter> adapter =
431 base::MakeUnique<SocketBIOAdapter>(socket.get(), 100, 100, this);
432 BIO* bio = adapter->bio();
433
434 // The write fails, but there is a write buffer, so errors are delayed.
435 EXPECT_EQ(5, BIO_write(bio, "aaaaa", 5));
436
437 // The write error is surfaced out of BIO_read. There are no MockReads, so
438 // this also tests that no socket reads are attempted.
439 ExpectReadError(bio, ERR_CONNECTION_RESET, tracer);
440 }
441
442 // Test that a synchronous failed socket write interrupts a blocked
443 // BIO_read. See https://crbug.com/249848.
444 TEST_F(SocketBIOAdapterTest, SyncWriteInterruptsRead) {
445 crypto::OpenSSLErrStackTracer tracer(FROM_HERE);
446
447 MockRead reads[] = {
448 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
449 };
450
451 MockWrite writes[] = {
452 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET, 1),
453 };
454
455 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
456 std::unique_ptr<StreamSocket> socket = MakeTestSocket(&data);
457 std::unique_ptr<SocketBIOAdapter> adapter =
458 base::MakeUnique<SocketBIOAdapter>(socket.get(), 100, 100, this);
459 BIO* bio = adapter->bio();
460
461 // Attempt to read from the transport. It will block indefinitely.
462 char buf;
463 ExpectBlockingRead(adapter->bio(), &buf, 1);
464
465 // Schedule a socket write.
466 EXPECT_EQ(5, BIO_write(bio, "aaaaa", 5));
467
468 // The write error triggers OnReadReady.
469 WaitForReadReady();
470
471 // The write error is surfaced out of BIO_read.
472 ExpectReadError(bio, ERR_CONNECTION_RESET, tracer);
473 }
474
475 // Test that an asynchronous failed socket write interrupts a blocked
476 // BIO_read. See https://crbug.com/249848.
477 TEST_F(SocketBIOAdapterTest, AsyncWriteInterruptsRead) {
478 crypto::OpenSSLErrStackTracer tracer(FROM_HERE);
479
480 MockRead reads[] = {
481 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
482 };
483
484 MockWrite writes[] = {
485 MockWrite(ASYNC, ERR_CONNECTION_RESET, 1),
486 };
487
488 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
489 std::unique_ptr<StreamSocket> socket = MakeTestSocket(&data);
490 std::unique_ptr<SocketBIOAdapter> adapter =
491 base::MakeUnique<SocketBIOAdapter>(socket.get(), 100, 100, this);
492 BIO* bio = adapter->bio();
493
494 // Attempt to read from the transport. It will block indefinitely.
495 char buf;
496 ExpectBlockingRead(adapter->bio(), &buf, 1);
497
498 // Schedule a socket write.
499 EXPECT_EQ(5, BIO_write(bio, "aaaaa", 5));
500
501 // The write error is signaled asynchronously and interrupts BIO_read, so
502 // OnReadReady is signaled. The write buffer was not full, so OnWriteReady is
503 // not signaled.
504 WaitForReadReady();
505
506 // The write error is surfaced out of BIO_read.
507 ExpectReadError(bio, ERR_CONNECTION_RESET, tracer);
508 }
509
510 // Test that an asynchronous failed socket write interrupts a blocked BIO_read,
511 // signaling both if the buffer was full. See https://crbug.com/249848.
512 TEST_F(SocketBIOAdapterTest, AsyncWriteInterruptsBoth) {
513 crypto::OpenSSLErrStackTracer tracer(FROM_HERE);
514
515 MockRead reads[] = {
516 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
517 };
518
519 MockWrite writes[] = {
520 MockWrite(ASYNC, ERR_CONNECTION_RESET, 1),
521 };
522
523 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
524 std::unique_ptr<StreamSocket> socket = MakeTestSocket(&data);
525 std::unique_ptr<SocketBIOAdapter> adapter =
526 base::MakeUnique<SocketBIOAdapter>(socket.get(), 5, 5, this);
527 BIO* bio = adapter->bio();
528
529 // Attempt to read from the transport. It will block indefinitely.
530 char buf;
531 ExpectBlockingRead(adapter->bio(), &buf, 1);
532
533 // Schedule a socket write.
534 EXPECT_EQ(5, BIO_write(bio, "aaaaa", 5));
535
536 // The write error is signaled asynchronously and interrupts BIO_read, so
537 // OnReadReady is signaled. The write buffer was full, so both OnWriteReady is
538 // also signaled.
539 WaitForBothReady();
540
541 // The write error is surfaced out of BIO_read.
542 ExpectReadError(bio, ERR_CONNECTION_RESET, tracer);
543 }
544
545 // Test that SocketBIOAdapter handles OnWriteReady deleting itself when both
546 // need to be signaled.
547 TEST_F(SocketBIOAdapterTest, DeleteOnWriteReady) {
548 crypto::OpenSSLErrStackTracer tracer(FROM_HERE);
549
550 MockRead reads[] = {
551 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
552 };
553
554 MockWrite writes[] = {
555 MockWrite(ASYNC, ERR_CONNECTION_RESET, 1),
556 };
557
558 SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
559 std::unique_ptr<StreamSocket> socket = MakeTestSocket(&data);
560 std::unique_ptr<SocketBIOAdapter> adapter =
561 base::MakeUnique<SocketBIOAdapter>(socket.get(), 5, 5, this);
562 BIO* bio = adapter->bio();
563
564 // Arrange for OnReadReady and OnWriteReady to both be signaled due to write
565 // error propagation (see the AsyncWriteInterruptsBoth test).
566 char buf;
567 ExpectBlockingRead(adapter->bio(), &buf, 1);
568 EXPECT_EQ(5, BIO_write(bio, "aaaaa", 5));
569
570 // Both OnWriteReady and OnReadReady would be signaled, but OnWriteReady
571 // deletes the adapter first.
572 set_reset_on_write_ready(&adapter);
573 WaitForWriteReady(nullptr);
574
575 EXPECT_FALSE(adapter);
576 }
577
578 // Test that using a BIO after the underlying adapter is destroyed fails
579 // gracefully.
580 TEST_F(SocketBIOAdapterTest, Detached) {
581 crypto::OpenSSLErrStackTracer tracer(FROM_HERE);
582
583 SequencedSocketData data(nullptr, 0, nullptr, 0);
584 std::unique_ptr<StreamSocket> socket = MakeTestSocket(&data);
585 std::unique_ptr<SocketBIOAdapter> adapter =
586 base::MakeUnique<SocketBIOAdapter>(socket.get(), 100, 100, this);
587
588 // Retain an additional reference to the BIO.
589 bssl::UniquePtr<BIO> bio(adapter->bio());
590 BIO_up_ref(bio.get());
591
592 // Release the adapter.
593 adapter.reset();
594
595 ExpectReadError(bio.get(), ERR_UNEXPECTED, tracer);
596 ExpectWriteError(bio.get(), ERR_UNEXPECTED, tracer);
597 }
598
599 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698