| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 "jingle/notifier/base/fake_ssl_client_socket.h" | 5 #include "jingle/notifier/base/fake_ssl_client_socket.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 MOCK_METHOD0(SetSubresourceSpeculation, void()); | 63 MOCK_METHOD0(SetSubresourceSpeculation, void()); |
| 64 MOCK_METHOD0(SetOmniboxSpeculation, void()); | 64 MOCK_METHOD0(SetOmniboxSpeculation, void()); |
| 65 MOCK_CONST_METHOD0(WasEverUsed, bool()); | 65 MOCK_CONST_METHOD0(WasEverUsed, bool()); |
| 66 MOCK_CONST_METHOD0(UsingTCPFastOpen, bool()); | 66 MOCK_CONST_METHOD0(UsingTCPFastOpen, bool()); |
| 67 MOCK_CONST_METHOD0(NumBytesRead, int64()); | 67 MOCK_CONST_METHOD0(NumBytesRead, int64()); |
| 68 MOCK_CONST_METHOD0(GetConnectTimeMicros, base::TimeDelta()); | 68 MOCK_CONST_METHOD0(GetConnectTimeMicros, base::TimeDelta()); |
| 69 }; | 69 }; |
| 70 | 70 |
| 71 // Break up |data| into a bunch of chunked MockReads/Writes and push | 71 // Break up |data| into a bunch of chunked MockReads/Writes and push |
| 72 // them onto |ops|. | 72 // them onto |ops|. |
| 73 void AddChunkedOps(base::StringPiece data, size_t chunk_size, bool async, | 73 void AddChunkedOps(base::StringPiece data, size_t chunk_size, net::IoMode mode, |
| 74 std::vector<net::MockRead>* ops) { | 74 std::vector<net::MockRead>* ops) { |
| 75 DCHECK_GT(chunk_size, 0U); | 75 DCHECK_GT(chunk_size, 0U); |
| 76 size_t offset = 0; | 76 size_t offset = 0; |
| 77 while (offset < data.size()) { | 77 while (offset < data.size()) { |
| 78 size_t bounded_chunk_size = std::min(data.size() - offset, chunk_size); | 78 size_t bounded_chunk_size = std::min(data.size() - offset, chunk_size); |
| 79 // We take advantage of the fact that MockWrite is typedefed to | 79 // We take advantage of the fact that MockWrite is typedefed to |
| 80 // MockRead. | 80 // MockRead. |
| 81 ops->push_back(net::MockRead(async, data.data() + offset, | 81 ops->push_back(net::MockRead(mode, data.data() + offset, |
| 82 bounded_chunk_size)); | 82 bounded_chunk_size)); |
| 83 offset += bounded_chunk_size; | 83 offset += bounded_chunk_size; |
| 84 } | 84 } |
| 85 } | 85 } |
| 86 | 86 |
| 87 class FakeSSLClientSocketTest : public testing::Test { | 87 class FakeSSLClientSocketTest : public testing::Test { |
| 88 protected: | 88 protected: |
| 89 FakeSSLClientSocketTest() | 89 FakeSSLClientSocketTest() |
| 90 : capturing_net_log_(net::CapturingNetLog::kUnbounded) {} | 90 : capturing_net_log_(net::CapturingNetLog::kUnbounded) {} |
| 91 | 91 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 102 static_socket_data_provider_.reset( | 102 static_socket_data_provider_.reset( |
| 103 new net::StaticSocketDataProvider( | 103 new net::StaticSocketDataProvider( |
| 104 reads->empty() ? NULL : &*reads->begin(), reads->size(), | 104 reads->empty() ? NULL : &*reads->begin(), reads->size(), |
| 105 writes->empty() ? NULL : &*writes->begin(), writes->size())); | 105 writes->empty() ? NULL : &*writes->begin(), writes->size())); |
| 106 static_socket_data_provider_->set_connect_data(mock_connect); | 106 static_socket_data_provider_->set_connect_data(mock_connect); |
| 107 mock_client_socket_factory_.AddSocketDataProvider( | 107 mock_client_socket_factory_.AddSocketDataProvider( |
| 108 static_socket_data_provider_.get()); | 108 static_socket_data_provider_.get()); |
| 109 } | 109 } |
| 110 | 110 |
| 111 void ExpectStatus( | 111 void ExpectStatus( |
| 112 bool async, int expected_status, int immediate_status, | 112 net::IoMode mode, int expected_status, int immediate_status, |
| 113 net::TestCompletionCallback* test_completion_callback) { | 113 net::TestCompletionCallback* test_completion_callback) { |
| 114 if (async) { | 114 if (mode == net::ASYNC) { |
| 115 EXPECT_EQ(net::ERR_IO_PENDING, immediate_status); | 115 EXPECT_EQ(net::ERR_IO_PENDING, immediate_status); |
| 116 int status = test_completion_callback->WaitForResult(); | 116 int status = test_completion_callback->WaitForResult(); |
| 117 EXPECT_EQ(expected_status, status); | 117 EXPECT_EQ(expected_status, status); |
| 118 } else { | 118 } else { |
| 119 EXPECT_EQ(expected_status, immediate_status); | 119 EXPECT_EQ(expected_status, immediate_status); |
| 120 } | 120 } |
| 121 } | 121 } |
| 122 | 122 |
| 123 // Sets up the mock socket to generate a successful handshake | 123 // Sets up the mock socket to generate a successful handshake |
| 124 // (sliced up according to the parameters) and makes sure the | 124 // (sliced up according to the parameters) and makes sure the |
| 125 // FakeSSLClientSocket behaves as expected. | 125 // FakeSSLClientSocket behaves as expected. |
| 126 void RunSuccessfulHandshakeTest( | 126 void RunSuccessfulHandshakeTest( |
| 127 bool async, size_t read_chunk_size, size_t write_chunk_size, | 127 net::IoMode mode, size_t read_chunk_size, size_t write_chunk_size, |
| 128 int num_resets) { | 128 int num_resets) { |
| 129 base::StringPiece ssl_client_hello = | 129 base::StringPiece ssl_client_hello = |
| 130 FakeSSLClientSocket::GetSslClientHello(); | 130 FakeSSLClientSocket::GetSslClientHello(); |
| 131 base::StringPiece ssl_server_hello = | 131 base::StringPiece ssl_server_hello = |
| 132 FakeSSLClientSocket::GetSslServerHello(); | 132 FakeSSLClientSocket::GetSslServerHello(); |
| 133 | 133 |
| 134 net::MockConnect mock_connect(async ? net::ASYNC : net::SYNCHRONOUS, | 134 net::MockConnect mock_connect(mode, net::OK); |
| 135 net::OK); | |
| 136 std::vector<net::MockRead> reads; | 135 std::vector<net::MockRead> reads; |
| 137 std::vector<net::MockWrite> writes; | 136 std::vector<net::MockWrite> writes; |
| 138 static const char kReadTestData[] = "read test data"; | 137 static const char kReadTestData[] = "read test data"; |
| 139 static const char kWriteTestData[] = "write test data"; | 138 static const char kWriteTestData[] = "write test data"; |
| 140 for (int i = 0; i < num_resets + 1; ++i) { | 139 for (int i = 0; i < num_resets + 1; ++i) { |
| 141 SCOPED_TRACE(i); | 140 SCOPED_TRACE(i); |
| 142 AddChunkedOps(ssl_server_hello, read_chunk_size, async, &reads); | 141 AddChunkedOps(ssl_server_hello, read_chunk_size, mode, &reads); |
| 143 AddChunkedOps(ssl_client_hello, write_chunk_size, async, &writes); | 142 AddChunkedOps(ssl_client_hello, write_chunk_size, mode, &writes); |
| 144 reads.push_back( | 143 reads.push_back( |
| 145 net::MockRead(async, kReadTestData, arraysize(kReadTestData))); | 144 net::MockRead(mode, kReadTestData, arraysize(kReadTestData))); |
| 146 writes.push_back( | 145 writes.push_back( |
| 147 net::MockWrite(async, kWriteTestData, arraysize(kWriteTestData))); | 146 net::MockWrite(mode, kWriteTestData, arraysize(kWriteTestData))); |
| 148 } | 147 } |
| 149 SetData(mock_connect, &reads, &writes); | 148 SetData(mock_connect, &reads, &writes); |
| 150 | 149 |
| 151 FakeSSLClientSocket fake_ssl_client_socket(MakeClientSocket()); | 150 FakeSSLClientSocket fake_ssl_client_socket(MakeClientSocket()); |
| 152 | 151 |
| 153 for (int i = 0; i < num_resets + 1; ++i) { | 152 for (int i = 0; i < num_resets + 1; ++i) { |
| 154 SCOPED_TRACE(i); | 153 SCOPED_TRACE(i); |
| 155 net::TestCompletionCallback test_completion_callback; | 154 net::TestCompletionCallback test_completion_callback; |
| 156 int status = fake_ssl_client_socket.Connect( | 155 int status = fake_ssl_client_socket.Connect( |
| 157 test_completion_callback.callback()); | 156 test_completion_callback.callback()); |
| 158 if (async) { | 157 if (mode == net::ASYNC) { |
| 159 EXPECT_FALSE(fake_ssl_client_socket.IsConnected()); | 158 EXPECT_FALSE(fake_ssl_client_socket.IsConnected()); |
| 160 } | 159 } |
| 161 ExpectStatus(async, net::OK, status, &test_completion_callback); | 160 ExpectStatus(mode, net::OK, status, &test_completion_callback); |
| 162 if (fake_ssl_client_socket.IsConnected()) { | 161 if (fake_ssl_client_socket.IsConnected()) { |
| 163 int read_len = arraysize(kReadTestData); | 162 int read_len = arraysize(kReadTestData); |
| 164 int read_buf_len = 2 * read_len; | 163 int read_buf_len = 2 * read_len; |
| 165 scoped_refptr<net::IOBuffer> read_buf( | 164 scoped_refptr<net::IOBuffer> read_buf( |
| 166 new net::IOBuffer(read_buf_len)); | 165 new net::IOBuffer(read_buf_len)); |
| 167 int read_status = fake_ssl_client_socket.Read( | 166 int read_status = fake_ssl_client_socket.Read( |
| 168 read_buf, read_buf_len, test_completion_callback.callback()); | 167 read_buf, read_buf_len, test_completion_callback.callback()); |
| 169 ExpectStatus(async, read_len, read_status, &test_completion_callback); | 168 ExpectStatus(mode, read_len, read_status, &test_completion_callback); |
| 170 | 169 |
| 171 scoped_refptr<net::IOBuffer> write_buf( | 170 scoped_refptr<net::IOBuffer> write_buf( |
| 172 new net::StringIOBuffer(kWriteTestData)); | 171 new net::StringIOBuffer(kWriteTestData)); |
| 173 int write_status = fake_ssl_client_socket.Write( | 172 int write_status = fake_ssl_client_socket.Write( |
| 174 write_buf, arraysize(kWriteTestData), | 173 write_buf, arraysize(kWriteTestData), |
| 175 test_completion_callback.callback()); | 174 test_completion_callback.callback()); |
| 176 ExpectStatus(async, arraysize(kWriteTestData), write_status, | 175 ExpectStatus(mode, arraysize(kWriteTestData), write_status, |
| 177 &test_completion_callback); | 176 &test_completion_callback); |
| 178 } else { | 177 } else { |
| 179 ADD_FAILURE(); | 178 ADD_FAILURE(); |
| 180 } | 179 } |
| 181 fake_ssl_client_socket.Disconnect(); | 180 fake_ssl_client_socket.Disconnect(); |
| 182 EXPECT_FALSE(fake_ssl_client_socket.IsConnected()); | 181 EXPECT_FALSE(fake_ssl_client_socket.IsConnected()); |
| 183 } | 182 } |
| 184 } | 183 } |
| 185 | 184 |
| 186 // Sets up the mock socket to generate an unsuccessful handshake | 185 // Sets up the mock socket to generate an unsuccessful handshake |
| 187 // FakeSSLClientSocket fails as expected. | 186 // FakeSSLClientSocket fails as expected. |
| 188 void RunUnsuccessfulHandshakeTestHelper( | 187 void RunUnsuccessfulHandshakeTestHelper( |
| 189 bool async, int error, HandshakeErrorLocation location) { | 188 net::IoMode mode, int error, HandshakeErrorLocation location) { |
| 190 DCHECK_NE(error, net::OK); | 189 DCHECK_NE(error, net::OK); |
| 191 base::StringPiece ssl_client_hello = | 190 base::StringPiece ssl_client_hello = |
| 192 FakeSSLClientSocket::GetSslClientHello(); | 191 FakeSSLClientSocket::GetSslClientHello(); |
| 193 base::StringPiece ssl_server_hello = | 192 base::StringPiece ssl_server_hello = |
| 194 FakeSSLClientSocket::GetSslServerHello(); | 193 FakeSSLClientSocket::GetSslServerHello(); |
| 195 | 194 |
| 196 net::MockConnect mock_connect(async ? net::ASYNC : net::SYNCHRONOUS, | 195 net::MockConnect mock_connect(mode, net::OK); |
| 197 net::OK); | |
| 198 std::vector<net::MockRead> reads; | 196 std::vector<net::MockRead> reads; |
| 199 std::vector<net::MockWrite> writes; | 197 std::vector<net::MockWrite> writes; |
| 200 const size_t kChunkSize = 1; | 198 const size_t kChunkSize = 1; |
| 201 AddChunkedOps(ssl_server_hello, kChunkSize, async, &reads); | 199 AddChunkedOps(ssl_server_hello, kChunkSize, mode, &reads); |
| 202 AddChunkedOps(ssl_client_hello, kChunkSize, async, &writes); | 200 AddChunkedOps(ssl_client_hello, kChunkSize, mode, &writes); |
| 203 switch (location) { | 201 switch (location) { |
| 204 case CONNECT_ERROR: | 202 case CONNECT_ERROR: |
| 205 mock_connect.result = error; | 203 mock_connect.result = error; |
| 206 writes.clear(); | 204 writes.clear(); |
| 207 reads.clear(); | 205 reads.clear(); |
| 208 break; | 206 break; |
| 209 case SEND_CLIENT_HELLO_ERROR: { | 207 case SEND_CLIENT_HELLO_ERROR: { |
| 210 // Use a fixed index for repeatability. | 208 // Use a fixed index for repeatability. |
| 211 size_t index = 100 % writes.size(); | 209 size_t index = 100 % writes.size(); |
| 212 writes[index].result = error; | 210 writes[index].result = error; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 225 reads[index].data_len = arraysize(kBadData); | 223 reads[index].data_len = arraysize(kBadData); |
| 226 } else { | 224 } else { |
| 227 reads[index].result = error; | 225 reads[index].result = error; |
| 228 reads[index].data = NULL; | 226 reads[index].data = NULL; |
| 229 reads[index].data_len = 0; | 227 reads[index].data_len = 0; |
| 230 } | 228 } |
| 231 reads.resize(index + 1); | 229 reads.resize(index + 1); |
| 232 if (error == | 230 if (error == |
| 233 net::ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ) { | 231 net::ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ) { |
| 234 static const char kDummyData[] = "DUMMY"; | 232 static const char kDummyData[] = "DUMMY"; |
| 235 reads.push_back(net::MockRead(async, kDummyData)); | 233 reads.push_back(net::MockRead(mode, kDummyData)); |
| 236 } | 234 } |
| 237 break; | 235 break; |
| 238 } | 236 } |
| 239 } | 237 } |
| 240 SetData(mock_connect, &reads, &writes); | 238 SetData(mock_connect, &reads, &writes); |
| 241 | 239 |
| 242 FakeSSLClientSocket fake_ssl_client_socket(MakeClientSocket()); | 240 FakeSSLClientSocket fake_ssl_client_socket(MakeClientSocket()); |
| 243 | 241 |
| 244 // The two errors below are interpreted by FakeSSLClientSocket as | 242 // The two errors below are interpreted by FakeSSLClientSocket as |
| 245 // an unexpected event. | 243 // an unexpected event. |
| 246 int expected_status = | 244 int expected_status = |
| 247 ((error == net::ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ) || | 245 ((error == net::ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ) || |
| 248 (error == ERR_MALFORMED_SERVER_HELLO)) ? | 246 (error == ERR_MALFORMED_SERVER_HELLO)) ? |
| 249 net::ERR_UNEXPECTED : error; | 247 net::ERR_UNEXPECTED : error; |
| 250 | 248 |
| 251 net::TestCompletionCallback test_completion_callback; | 249 net::TestCompletionCallback test_completion_callback; |
| 252 int status = fake_ssl_client_socket.Connect( | 250 int status = fake_ssl_client_socket.Connect( |
| 253 test_completion_callback.callback()); | 251 test_completion_callback.callback()); |
| 254 EXPECT_FALSE(fake_ssl_client_socket.IsConnected()); | 252 EXPECT_FALSE(fake_ssl_client_socket.IsConnected()); |
| 255 ExpectStatus(async, expected_status, status, &test_completion_callback); | 253 ExpectStatus(mode, expected_status, status, &test_completion_callback); |
| 256 EXPECT_FALSE(fake_ssl_client_socket.IsConnected()); | 254 EXPECT_FALSE(fake_ssl_client_socket.IsConnected()); |
| 257 } | 255 } |
| 258 | 256 |
| 259 void RunUnsuccessfulHandshakeTest( | 257 void RunUnsuccessfulHandshakeTest( |
| 260 int error, HandshakeErrorLocation location) { | 258 int error, HandshakeErrorLocation location) { |
| 261 RunUnsuccessfulHandshakeTestHelper(false, error, location); | 259 RunUnsuccessfulHandshakeTestHelper(net::SYNCHRONOUS, error, location); |
| 262 RunUnsuccessfulHandshakeTestHelper(true, error, location); | 260 RunUnsuccessfulHandshakeTestHelper(net::ASYNC, error, location); |
| 263 } | 261 } |
| 264 | 262 |
| 265 // MockTCPClientSocket needs a message loop. | 263 // MockTCPClientSocket needs a message loop. |
| 266 MessageLoop message_loop_; | 264 MessageLoop message_loop_; |
| 267 | 265 |
| 268 net::CapturingNetLog capturing_net_log_; | 266 net::CapturingNetLog capturing_net_log_; |
| 269 net::MockClientSocketFactory mock_client_socket_factory_; | 267 net::MockClientSocketFactory mock_client_socket_factory_; |
| 270 scoped_ptr<net::StaticSocketDataProvider> static_socket_data_provider_; | 268 scoped_ptr<net::StaticSocketDataProvider> static_socket_data_provider_; |
| 271 }; | 269 }; |
| 272 | 270 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 294 EXPECT_EQ(&net_log, &fake_ssl_client_socket.NetLog()); | 292 EXPECT_EQ(&net_log, &fake_ssl_client_socket.NetLog()); |
| 295 fake_ssl_client_socket.SetSubresourceSpeculation(); | 293 fake_ssl_client_socket.SetSubresourceSpeculation(); |
| 296 fake_ssl_client_socket.SetOmniboxSpeculation(); | 294 fake_ssl_client_socket.SetOmniboxSpeculation(); |
| 297 } | 295 } |
| 298 | 296 |
| 299 TEST_F(FakeSSLClientSocketTest, SuccessfulHandshakeSync) { | 297 TEST_F(FakeSSLClientSocketTest, SuccessfulHandshakeSync) { |
| 300 for (size_t i = 1; i < 100; i += 3) { | 298 for (size_t i = 1; i < 100; i += 3) { |
| 301 SCOPED_TRACE(i); | 299 SCOPED_TRACE(i); |
| 302 for (size_t j = 1; j < 100; j += 5) { | 300 for (size_t j = 1; j < 100; j += 5) { |
| 303 SCOPED_TRACE(j); | 301 SCOPED_TRACE(j); |
| 304 RunSuccessfulHandshakeTest(false, i, j, 0); | 302 RunSuccessfulHandshakeTest(net::SYNCHRONOUS, i, j, 0); |
| 305 } | 303 } |
| 306 } | 304 } |
| 307 } | 305 } |
| 308 | 306 |
| 309 TEST_F(FakeSSLClientSocketTest, SuccessfulHandshakeAsync) { | 307 TEST_F(FakeSSLClientSocketTest, SuccessfulHandshakeAsync) { |
| 310 for (size_t i = 1; i < 100; i += 7) { | 308 for (size_t i = 1; i < 100; i += 7) { |
| 311 SCOPED_TRACE(i); | 309 SCOPED_TRACE(i); |
| 312 for (size_t j = 1; j < 100; j += 9) { | 310 for (size_t j = 1; j < 100; j += 9) { |
| 313 SCOPED_TRACE(j); | 311 SCOPED_TRACE(j); |
| 314 RunSuccessfulHandshakeTest(true, i, j, 0); | 312 RunSuccessfulHandshakeTest(net::ASYNC, i, j, 0); |
| 315 } | 313 } |
| 316 } | 314 } |
| 317 } | 315 } |
| 318 | 316 |
| 319 TEST_F(FakeSSLClientSocketTest, ResetSocket) { | 317 TEST_F(FakeSSLClientSocketTest, ResetSocket) { |
| 320 RunSuccessfulHandshakeTest(true, 1, 2, 3); | 318 RunSuccessfulHandshakeTest(net::ASYNC, 1, 2, 3); |
| 321 } | 319 } |
| 322 | 320 |
| 323 TEST_F(FakeSSLClientSocketTest, UnsuccessfulHandshakeConnectError) { | 321 TEST_F(FakeSSLClientSocketTest, UnsuccessfulHandshakeConnectError) { |
| 324 RunUnsuccessfulHandshakeTest(net::ERR_ACCESS_DENIED, CONNECT_ERROR); | 322 RunUnsuccessfulHandshakeTest(net::ERR_ACCESS_DENIED, CONNECT_ERROR); |
| 325 } | 323 } |
| 326 | 324 |
| 327 TEST_F(FakeSSLClientSocketTest, UnsuccessfulHandshakeWriteError) { | 325 TEST_F(FakeSSLClientSocketTest, UnsuccessfulHandshakeWriteError) { |
| 328 RunUnsuccessfulHandshakeTest(net::ERR_OUT_OF_MEMORY, | 326 RunUnsuccessfulHandshakeTest(net::ERR_OUT_OF_MEMORY, |
| 329 SEND_CLIENT_HELLO_ERROR); | 327 SEND_CLIENT_HELLO_ERROR); |
| 330 } | 328 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 341 } | 339 } |
| 342 | 340 |
| 343 TEST_F(FakeSSLClientSocketTest, MalformedServerHello) { | 341 TEST_F(FakeSSLClientSocketTest, MalformedServerHello) { |
| 344 RunUnsuccessfulHandshakeTest(ERR_MALFORMED_SERVER_HELLO, | 342 RunUnsuccessfulHandshakeTest(ERR_MALFORMED_SERVER_HELLO, |
| 345 VERIFY_SERVER_HELLO_ERROR); | 343 VERIFY_SERVER_HELLO_ERROR); |
| 346 } | 344 } |
| 347 | 345 |
| 348 } // namespace | 346 } // namespace |
| 349 | 347 |
| 350 } // namespace notifier | 348 } // namespace notifier |
| OLD | NEW |