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

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

Issue 7399025: Fix instability in SSL client/server sockets (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Update FakeSocketTest. Created 9 years, 5 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
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 // This test suite uses SSLClientSocket to test the implementation of 5 // This test suite uses SSLClientSocket to test the implementation of
6 // SSLServerSocket. In order to establish connections between the sockets 6 // SSLServerSocket. In order to establish connections between the sockets
7 // we need two additional classes: 7 // we need two additional classes:
8 // 1. FakeSocket 8 // 1. FakeSocket
9 // Connects SSL socket to FakeDataChannel. This class is just a stub. 9 // Connects SSL socket to FakeDataChannel. This class is just a stub.
10 // 10 //
11 // 2. FakeDataChannel 11 // 2. FakeDataChannel
12 // Implements the actual exchange of data between two FakeSockets. 12 // Implements the actual exchange of data between two FakeSockets.
13 // 13 //
14 // Implementations of these two classes are included in this file. 14 // Implementations of these two classes are included in this file.
15 15
16 #include "net/socket/ssl_server_socket.h" 16 #include "net/socket/ssl_server_socket.h"
17 17
18 #include <stdlib.h>
19
18 #include <queue> 20 #include <queue>
19 21
20 #include "base/file_path.h" 22 #include "base/file_path.h"
21 #include "base/file_util.h" 23 #include "base/file_util.h"
24 #include "base/message_loop.h"
22 #include "base/path_service.h" 25 #include "base/path_service.h"
23 #include "crypto/nss_util.h" 26 #include "crypto/nss_util.h"
24 #include "crypto/rsa_private_key.h" 27 #include "crypto/rsa_private_key.h"
25 #include "net/base/address_list.h" 28 #include "net/base/address_list.h"
26 #include "net/base/cert_status_flags.h" 29 #include "net/base/cert_status_flags.h"
27 #include "net/base/cert_verifier.h" 30 #include "net/base/cert_verifier.h"
28 #include "net/base/host_port_pair.h" 31 #include "net/base/host_port_pair.h"
29 #include "net/base/io_buffer.h" 32 #include "net/base/io_buffer.h"
30 #include "net/base/ip_endpoint.h" 33 #include "net/base/ip_endpoint.h"
31 #include "net/base/net_errors.h" 34 #include "net/base/net_errors.h"
32 #include "net/base/net_log.h" 35 #include "net/base/net_log.h"
33 #include "net/base/ssl_config_service.h" 36 #include "net/base/ssl_config_service.h"
34 #include "net/base/ssl_info.h" 37 #include "net/base/ssl_info.h"
35 #include "net/base/x509_certificate.h" 38 #include "net/base/x509_certificate.h"
36 #include "net/socket/client_socket_factory.h" 39 #include "net/socket/client_socket_factory.h"
37 #include "net/socket/socket_test_util.h" 40 #include "net/socket/socket_test_util.h"
38 #include "net/socket/ssl_client_socket.h" 41 #include "net/socket/ssl_client_socket.h"
39 #include "net/socket/stream_socket.h" 42 #include "net/socket/stream_socket.h"
40 #include "testing/gtest/include/gtest/gtest.h" 43 #include "testing/gtest/include/gtest/gtest.h"
41 #include "testing/platform_test.h" 44 #include "testing/platform_test.h"
42 45
43 namespace net { 46 namespace net {
44 47
45 namespace { 48 namespace {
46 49
47 class FakeDataChannel { 50 class FakeDataChannel {
48 public: 51 public:
49 FakeDataChannel() : read_callback_(NULL), read_buf_len_(0) { 52 FakeDataChannel()
53 : read_callback_(NULL),
54 read_buf_len_(0),
55 ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)) {
willchan no longer on Chromium 2011/07/21 08:16:06 Need compiler_specific.h for this macro.
Sergey Ulanov 2011/07/21 17:11:12 Done.
50 } 56 }
51 57
52 virtual int Read(IOBuffer* buf, int buf_len, 58 virtual int Read(IOBuffer* buf, int buf_len,
53 CompletionCallback* callback) { 59 CompletionCallback* callback) {
54 if (data_.empty()) { 60 if (data_.empty()) {
55 read_callback_ = callback; 61 read_callback_ = callback;
56 read_buf_ = buf; 62 read_buf_ = buf;
57 read_buf_len_ = buf_len; 63 read_buf_len_ = buf_len;
58 return net::ERR_IO_PENDING; 64 return net::ERR_IO_PENDING;
59 } 65 }
60 return PropogateData(buf, buf_len); 66 return PropogateData(buf, buf_len);
61 } 67 }
62 68
63 virtual int Write(IOBuffer* buf, int buf_len, 69 virtual int Write(IOBuffer* buf, int buf_len,
64 CompletionCallback* callback) { 70 CompletionCallback* callback) {
65 data_.push(new net::DrainableIOBuffer(buf, buf_len)); 71 data_.push(new net::DrainableIOBuffer(buf, buf_len));
66 DoReadCallback(); 72 MessageLoop::current()->PostTask(
73 FROM_HERE, task_factory_.NewRunnableMethod(
74 &FakeDataChannel::DoReadCallback));
wtc 2011/07/21 00:27:12 willchan: can you review the use of ScopedRunnable
Sergey Ulanov 2011/07/21 00:51:15 Because DoReadCallback() calls callback on the soc
willchan no longer on Chromium 2011/07/21 08:16:06 Looks reasonable to me.
67 return buf_len; 75 return buf_len;
68 } 76 }
69 77
70 private: 78 private:
71 void DoReadCallback() { 79 void DoReadCallback() {
72 if (!read_callback_) 80 if (!read_callback_ || !data_.size())
wtc 2011/07/21 00:27:12 Nit: some people prefer data_.empty(). Why do you
Sergey Ulanov 2011/07/21 00:51:15 Done.
73 return; 81 return;
74 82
75 int copied = PropogateData(read_buf_, read_buf_len_); 83 int copied = PropogateData(read_buf_, read_buf_len_);
76 net::CompletionCallback* callback = read_callback_; 84 net::CompletionCallback* callback = read_callback_;
77 read_callback_ = NULL; 85 read_callback_ = NULL;
78 read_buf_ = NULL; 86 read_buf_ = NULL;
79 read_buf_len_ = 0; 87 read_buf_len_ = 0;
80 callback->Run(copied); 88 callback->Run(copied);
81 } 89 }
82 90
83 int PropogateData(scoped_refptr<net::IOBuffer> read_buf, int read_buf_len) { 91 int PropogateData(scoped_refptr<net::IOBuffer> read_buf, int read_buf_len) {
84 scoped_refptr<net::DrainableIOBuffer> buf = data_.front(); 92 scoped_refptr<net::DrainableIOBuffer> buf = data_.front();
85 int copied = std::min(buf->BytesRemaining(), read_buf_len); 93 int copied = std::min(buf->BytesRemaining(), read_buf_len);
86 memcpy(read_buf->data(), buf->data(), copied); 94 memcpy(read_buf->data(), buf->data(), copied);
87 buf->DidConsume(copied); 95 buf->DidConsume(copied);
88 96
89 if (!buf->BytesRemaining()) 97 if (!buf->BytesRemaining())
90 data_.pop(); 98 data_.pop();
91 return copied; 99 return copied;
92 } 100 }
93 101
94 net::CompletionCallback* read_callback_; 102 net::CompletionCallback* read_callback_;
95 scoped_refptr<net::IOBuffer> read_buf_; 103 scoped_refptr<net::IOBuffer> read_buf_;
96 int read_buf_len_; 104 int read_buf_len_;
97 105
98 std::queue<scoped_refptr<net::DrainableIOBuffer> > data_; 106 std::queue<scoped_refptr<net::DrainableIOBuffer> > data_;
99 107
108 ScopedRunnableMethodFactory<FakeDataChannel> task_factory_;
109
100 DISALLOW_COPY_AND_ASSIGN(FakeDataChannel); 110 DISALLOW_COPY_AND_ASSIGN(FakeDataChannel);
101 }; 111 };
102 112
103 class FakeSocket : public StreamSocket { 113 class FakeSocket : public StreamSocket {
104 public: 114 public:
105 FakeSocket(FakeDataChannel* incoming_channel, 115 FakeSocket(FakeDataChannel* incoming_channel,
106 FakeDataChannel* outgoing_channel) 116 FakeDataChannel* outgoing_channel)
107 : incoming_(incoming_channel), 117 : incoming_(incoming_channel),
108 outgoing_(outgoing_channel) { 118 outgoing_(outgoing_channel) {
109 } 119 }
110 120
111 virtual ~FakeSocket() { 121 virtual ~FakeSocket() {
112 122
113 } 123 }
114 124
115 virtual int Read(IOBuffer* buf, int buf_len, 125 virtual int Read(IOBuffer* buf, int buf_len,
116 CompletionCallback* callback) { 126 CompletionCallback* callback) {
127 // Read random number of bytes.
128 buf_len = rand() % buf_len + 1;
117 return incoming_->Read(buf, buf_len, callback); 129 return incoming_->Read(buf, buf_len, callback);
118 } 130 }
119 131
120 virtual int Write(IOBuffer* buf, int buf_len, 132 virtual int Write(IOBuffer* buf, int buf_len,
121 CompletionCallback* callback) { 133 CompletionCallback* callback) {
134 // Write random number of bytes.
135 buf_len = rand() % buf_len + 1;
wtc 2011/07/21 00:27:12 Are you using rand() instead of base::RandInt() be
122 return outgoing_->Write(buf, buf_len, callback); 136 return outgoing_->Write(buf, buf_len, callback);
123 } 137 }
124 138
125 virtual bool SetReceiveBufferSize(int32 size) { 139 virtual bool SetReceiveBufferSize(int32 size) {
126 return true; 140 return true;
127 } 141 }
128 142
129 virtual bool SetSendBufferSize(int32 size) { 143 virtual bool SetSendBufferSize(int32 size) {
130 return true; 144 return true;
131 } 145 }
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 FakeSocket client(&channel_1, &channel_2); 211 FakeSocket client(&channel_1, &channel_2);
198 FakeSocket server(&channel_2, &channel_1); 212 FakeSocket server(&channel_2, &channel_1);
199 213
200 const char kTestData[] = "testing123"; 214 const char kTestData[] = "testing123";
201 const int kTestDataSize = strlen(kTestData); 215 const int kTestDataSize = strlen(kTestData);
202 const int kReadBufSize = 1024; 216 const int kReadBufSize = 1024;
203 scoped_refptr<net::IOBuffer> write_buf = new net::StringIOBuffer(kTestData); 217 scoped_refptr<net::IOBuffer> write_buf = new net::StringIOBuffer(kTestData);
204 scoped_refptr<net::IOBuffer> read_buf = new net::IOBuffer(kReadBufSize); 218 scoped_refptr<net::IOBuffer> read_buf = new net::IOBuffer(kReadBufSize);
205 219
206 // Write then read. 220 // Write then read.
207 EXPECT_EQ(kTestDataSize, server.Write(write_buf, kTestDataSize, NULL)); 221 int written = server.Write(write_buf, kTestDataSize, NULL);
208 EXPECT_EQ(kTestDataSize, client.Read(read_buf, kReadBufSize, NULL)); 222 EXPECT_GT(written, 0);
209 EXPECT_EQ(0, memcmp(kTestData, read_buf->data(), kTestDataSize)); 223 EXPECT_LE(written, kTestDataSize);
224
225 int read = client.Read(read_buf, kReadBufSize, NULL);
wtc 2011/07/21 00:27:12 Nit: name these local variables nwritten and nread
226 EXPECT_GT(read, 0);
227 EXPECT_LE(read, written);
228 EXPECT_EQ(0, memcmp(kTestData, read_buf->data(), read));
210 229
211 // Read then write. 230 // Read then write.
212 TestCompletionCallback callback; 231 TestCompletionCallback callback;
213 EXPECT_EQ(net::ERR_IO_PENDING, 232 EXPECT_EQ(net::ERR_IO_PENDING,
214 server.Read(read_buf, kReadBufSize, &callback)); 233 server.Read(read_buf, kReadBufSize, &callback));
215 EXPECT_EQ(kTestDataSize, client.Write(write_buf, kTestDataSize, NULL)); 234
216 EXPECT_EQ(kTestDataSize, callback.WaitForResult()); 235 written = client.Write(write_buf, kTestDataSize, NULL);
217 EXPECT_EQ(0, memcmp(kTestData, read_buf->data(), kTestDataSize)); 236 EXPECT_GT(written, 0);
237 EXPECT_LE(written, kTestDataSize);
238
239 read = callback.WaitForResult();
240 EXPECT_GT(read, 0);
241 EXPECT_LE(read, written);
242 EXPECT_EQ(0, memcmp(kTestData, read_buf->data(), read));
218 } 243 }
219 244
220 class SSLServerSocketTest : public PlatformTest { 245 class SSLServerSocketTest : public PlatformTest {
221 public: 246 public:
222 SSLServerSocketTest() 247 SSLServerSocketTest()
223 : socket_factory_(net::ClientSocketFactory::GetDefaultFactory()) { 248 : socket_factory_(net::ClientSocketFactory::GetDefaultFactory()) {
224 } 249 }
225 250
226 protected: 251 protected:
227 void Initialize() { 252 void Initialize() {
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 EXPECT_GT(read_callback.WaitForResult(), 0); 400 EXPECT_GT(read_callback.WaitForResult(), 0);
376 } 401 }
377 if (client_ret == net::ERR_IO_PENDING) { 402 if (client_ret == net::ERR_IO_PENDING) {
378 EXPECT_GT(write_callback.WaitForResult(), 0); 403 EXPECT_GT(write_callback.WaitForResult(), 0);
379 } 404 }
380 EXPECT_EQ(0, memcmp(write_buf->data(), read_buf->data(), write_buf->size())); 405 EXPECT_EQ(0, memcmp(write_buf->data(), read_buf->data(), write_buf->size()));
381 } 406 }
382 #endif 407 #endif
383 408
384 } // namespace net 409 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698