| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "google_apis/gcm/base/socket_stream.h" | 5 #include "google_apis/gcm/base/socket_stream.h" |
| 6 | 6 |
| 7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
| 10 #include "base/run_loop.h" | 10 #include "base/run_loop.h" |
| 11 #include "base/stl_util.h" | 11 #include "base/stl_util.h" |
| 12 #include "base/strings/string_piece.h" | 12 #include "base/strings/string_piece.h" |
| 13 #include "net/socket/socket_test_util.h" | 13 #include "net/socket/socket_test_util.h" |
| 14 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
| 15 | 15 |
| 16 namespace gcm { | 16 namespace gcm { |
| 17 namespace { | 17 namespace { |
| 18 | 18 |
| 19 typedef std::vector<net::MockRead> ReadList; | 19 typedef std::vector<net::MockRead> ReadList; |
| 20 typedef std::vector<net::MockWrite> WriteList; | 20 typedef std::vector<net::MockWrite> WriteList; |
| 21 | 21 |
| 22 const char kReadData[] = "read_data"; | 22 const char kReadData[] = "read_data"; |
| 23 const uint64 kReadDataSize = arraysize(kReadData) - 1; | 23 const int kReadDataSize = arraysize(kReadData) - 1; |
| 24 const char kReadData2[] = "read_alternate_data"; | 24 const char kReadData2[] = "read_alternate_data"; |
| 25 const uint64 kReadData2Size = arraysize(kReadData2) - 1; | 25 const int kReadData2Size = arraysize(kReadData2) - 1; |
| 26 const char kWriteData[] = "write_data"; | 26 const char kWriteData[] = "write_data"; |
| 27 const uint64 kWriteDataSize = arraysize(kWriteData) - 1; | 27 const int kWriteDataSize = arraysize(kWriteData) - 1; |
| 28 | 28 |
| 29 class GCMSocketStreamTest : public testing::Test { | 29 class GCMSocketStreamTest : public testing::Test { |
| 30 public: | 30 public: |
| 31 GCMSocketStreamTest(); | 31 GCMSocketStreamTest(); |
| 32 virtual ~GCMSocketStreamTest(); | 32 virtual ~GCMSocketStreamTest(); |
| 33 | 33 |
| 34 // Build a socket with the expected reads and writes. | 34 // Build a socket with the expected reads and writes. |
| 35 void BuildSocket(const ReadList& read_list, const WriteList& write_list); | 35 void BuildSocket(const ReadList& read_list, const WriteList& write_list); |
| 36 | 36 |
| 37 // Pump the message loop until idle. | 37 // Pump the message loop until idle. |
| 38 void PumpLoop(); | 38 void PumpLoop(); |
| 39 | 39 |
| 40 // Simulates a google::protobuf::io::CodedInputStream read. | 40 // Simulates a google::protobuf::io::CodedInputStream read. |
| 41 base::StringPiece DoInputStreamRead(uint64 bytes); | 41 base::StringPiece DoInputStreamRead(int bytes); |
| 42 // Simulates a google::protobuf::io::CodedOutputStream write. | 42 // Simulates a google::protobuf::io::CodedOutputStream write. |
| 43 uint64 DoOutputStreamWrite(const base::StringPiece& write_src); | 43 int DoOutputStreamWrite(const base::StringPiece& write_src); |
| 44 | 44 |
| 45 // Synchronous Refresh wrapper. | 45 // Synchronous Refresh wrapper. |
| 46 void WaitForData(size_t msg_size); | 46 void WaitForData(int msg_size); |
| 47 | 47 |
| 48 base::MessageLoop* message_loop() { return &message_loop_; }; | 48 base::MessageLoop* message_loop() { return &message_loop_; }; |
| 49 net::DelayedSocketData* data_provider() { return data_provider_.get(); } | 49 net::DelayedSocketData* data_provider() { return data_provider_.get(); } |
| 50 SocketInputStream* input_stream() { return socket_input_stream_.get(); } | 50 SocketInputStream* input_stream() { return socket_input_stream_.get(); } |
| 51 SocketOutputStream* output_stream() { return socket_output_stream_.get(); } | 51 SocketOutputStream* output_stream() { return socket_output_stream_.get(); } |
| 52 net::StreamSocket* socket() { return socket_.get(); } | 52 net::StreamSocket* socket() { return socket_.get(); } |
| 53 | 53 |
| 54 private: | 54 private: |
| 55 void OpenConnection(); | 55 void OpenConnection(); |
| 56 void ResetInputStream(); | 56 void ResetInputStream(); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 OpenConnection(); | 94 OpenConnection(); |
| 95 ResetInputStream(); | 95 ResetInputStream(); |
| 96 ResetOutputStream(); | 96 ResetOutputStream(); |
| 97 } | 97 } |
| 98 | 98 |
| 99 void GCMSocketStreamTest::PumpLoop() { | 99 void GCMSocketStreamTest::PumpLoop() { |
| 100 base::RunLoop run_loop; | 100 base::RunLoop run_loop; |
| 101 run_loop.RunUntilIdle(); | 101 run_loop.RunUntilIdle(); |
| 102 } | 102 } |
| 103 | 103 |
| 104 base::StringPiece GCMSocketStreamTest::DoInputStreamRead(uint64 bytes) { | 104 base::StringPiece GCMSocketStreamTest::DoInputStreamRead(int bytes) { |
| 105 uint64 total_bytes_read = 0; | 105 int total_bytes_read = 0; |
| 106 const void* initial_buffer = NULL; | 106 const void* initial_buffer = NULL; |
| 107 const void* buffer = NULL; | 107 const void* buffer = NULL; |
| 108 int size = 0; | 108 int size = 0; |
| 109 | 109 |
| 110 do { | 110 do { |
| 111 DCHECK(socket_input_stream_->GetState() == SocketInputStream::EMPTY || | 111 DCHECK(socket_input_stream_->GetState() == SocketInputStream::EMPTY || |
| 112 socket_input_stream_->GetState() == SocketInputStream::READY); | 112 socket_input_stream_->GetState() == SocketInputStream::READY); |
| 113 if (!socket_input_stream_->Next(&buffer, &size)) | 113 if (!socket_input_stream_->Next(&buffer, &size)) |
| 114 break; | 114 break; |
| 115 total_bytes_read += size; | 115 total_bytes_read += size; |
| 116 if (initial_buffer) { // Verify the buffer doesn't skip data. | 116 if (initial_buffer) { // Verify the buffer doesn't skip data. |
| 117 EXPECT_EQ(static_cast<const uint8*>(initial_buffer) + total_bytes_read, | 117 EXPECT_EQ(static_cast<const uint8*>(initial_buffer) + total_bytes_read, |
| 118 static_cast<const uint8*>(buffer) + size); | 118 static_cast<const uint8*>(buffer) + size); |
| 119 } else { | 119 } else { |
| 120 initial_buffer = buffer; | 120 initial_buffer = buffer; |
| 121 } | 121 } |
| 122 } while (total_bytes_read < bytes); | 122 } while (total_bytes_read < bytes); |
| 123 | 123 |
| 124 if (total_bytes_read > bytes) { | 124 if (total_bytes_read > bytes) { |
| 125 socket_input_stream_->BackUp(total_bytes_read - bytes); | 125 socket_input_stream_->BackUp(total_bytes_read - bytes); |
| 126 total_bytes_read = bytes; | 126 total_bytes_read = bytes; |
| 127 } | 127 } |
| 128 | 128 |
| 129 return base::StringPiece(static_cast<const char*>(initial_buffer), | 129 return base::StringPiece(static_cast<const char*>(initial_buffer), |
| 130 total_bytes_read); | 130 total_bytes_read); |
| 131 } | 131 } |
| 132 | 132 |
| 133 uint64 GCMSocketStreamTest::DoOutputStreamWrite( | 133 int GCMSocketStreamTest::DoOutputStreamWrite( |
| 134 const base::StringPiece& write_src) { | 134 const base::StringPiece& write_src) { |
| 135 DCHECK_EQ(socket_output_stream_->GetState(), SocketOutputStream::EMPTY); | 135 DCHECK_EQ(socket_output_stream_->GetState(), SocketOutputStream::EMPTY); |
| 136 uint64 total_bytes_written = 0; | 136 int total_bytes_written = 0; |
| 137 void* buffer = NULL; | 137 void* buffer = NULL; |
| 138 int size = 0; | 138 int size = 0; |
| 139 size_t bytes = write_src.size(); | 139 int bytes = write_src.size(); |
| 140 | 140 |
| 141 do { | 141 do { |
| 142 if (!socket_output_stream_->Next(&buffer, &size)) | 142 if (!socket_output_stream_->Next(&buffer, &size)) |
| 143 break; | 143 break; |
| 144 uint64 bytes_to_write = (static_cast<uint64>(size) < bytes ? size : bytes); | 144 int bytes_to_write = (size < bytes ? size : bytes); |
| 145 memcpy(buffer, | 145 memcpy(buffer, |
| 146 write_src.data() + total_bytes_written, | 146 write_src.data() + total_bytes_written, |
| 147 bytes_to_write); | 147 bytes_to_write); |
| 148 if (bytes_to_write < static_cast<uint64>(size)) | 148 if (bytes_to_write < size) |
| 149 socket_output_stream_->BackUp(size - bytes_to_write); | 149 socket_output_stream_->BackUp(size - bytes_to_write); |
| 150 total_bytes_written += bytes_to_write; | 150 total_bytes_written += bytes_to_write; |
| 151 } while (total_bytes_written < bytes); | 151 } while (total_bytes_written < bytes); |
| 152 | 152 |
| 153 base::RunLoop run_loop; | 153 base::RunLoop run_loop; |
| 154 if (socket_output_stream_->Flush(run_loop.QuitClosure()) == | 154 if (socket_output_stream_->Flush(run_loop.QuitClosure()) == |
| 155 net::ERR_IO_PENDING) { | 155 net::ERR_IO_PENDING) { |
| 156 run_loop.Run(); | 156 run_loop.Run(); |
| 157 } | 157 } |
| 158 | 158 |
| 159 return total_bytes_written; | 159 return total_bytes_written; |
| 160 } | 160 } |
| 161 | 161 |
| 162 void GCMSocketStreamTest::WaitForData(size_t msg_size) { | 162 void GCMSocketStreamTest::WaitForData(int msg_size) { |
| 163 while (input_stream()->UnreadByteCount() < msg_size) { | 163 while (input_stream()->UnreadByteCount() < msg_size) { |
| 164 base::RunLoop run_loop; | 164 base::RunLoop run_loop; |
| 165 if (input_stream()->Refresh(run_loop.QuitClosure(), | 165 if (input_stream()->Refresh(run_loop.QuitClosure(), |
| 166 msg_size - input_stream()->UnreadByteCount()) == | 166 msg_size - input_stream()->UnreadByteCount()) == |
| 167 net::ERR_IO_PENDING) { | 167 net::ERR_IO_PENDING) { |
| 168 run_loop.Run(); | 168 run_loop.Run(); |
| 169 } | 169 } |
| 170 if (input_stream()->GetState() == SocketInputStream::CLOSED) | 170 if (input_stream()->GetState() == SocketInputStream::CLOSED) |
| 171 return; | 171 return; |
| 172 } | 172 } |
| (...skipping 27 matching lines...) Expand all Loading... |
| 200 kReadDataSize)), | 200 kReadDataSize)), |
| 201 WriteList()); | 201 WriteList()); |
| 202 | 202 |
| 203 WaitForData(kReadDataSize); | 203 WaitForData(kReadDataSize); |
| 204 ASSERT_EQ(std::string(kReadData, kReadDataSize), | 204 ASSERT_EQ(std::string(kReadData, kReadDataSize), |
| 205 DoInputStreamRead(kReadDataSize)); | 205 DoInputStreamRead(kReadDataSize)); |
| 206 } | 206 } |
| 207 | 207 |
| 208 // A read that comes in two parts. | 208 // A read that comes in two parts. |
| 209 TEST_F(GCMSocketStreamTest, ReadPartialDataSync) { | 209 TEST_F(GCMSocketStreamTest, ReadPartialDataSync) { |
| 210 size_t first_read_len = kReadDataSize / 2; | 210 int first_read_len = kReadDataSize / 2; |
| 211 size_t second_read_len = kReadDataSize - first_read_len; | 211 int second_read_len = kReadDataSize - first_read_len; |
| 212 ReadList read_list; | 212 ReadList read_list; |
| 213 read_list.push_back( | 213 read_list.push_back( |
| 214 net::MockRead(net::SYNCHRONOUS, | 214 net::MockRead(net::SYNCHRONOUS, |
| 215 kReadData, | 215 kReadData, |
| 216 first_read_len)); | 216 first_read_len)); |
| 217 read_list.push_back( | 217 read_list.push_back( |
| 218 net::MockRead(net::SYNCHRONOUS, | 218 net::MockRead(net::SYNCHRONOUS, |
| 219 &kReadData[first_read_len], | 219 &kReadData[first_read_len], |
| 220 second_read_len)); | 220 second_read_len)); |
| 221 BuildSocket(read_list, WriteList()); | 221 BuildSocket(read_list, WriteList()); |
| 222 | 222 |
| 223 WaitForData(kReadDataSize); | 223 WaitForData(kReadDataSize); |
| 224 ASSERT_EQ(std::string(kReadData, kReadDataSize), | 224 ASSERT_EQ(std::string(kReadData, kReadDataSize), |
| 225 DoInputStreamRead(kReadDataSize)); | 225 DoInputStreamRead(kReadDataSize)); |
| 226 } | 226 } |
| 227 | 227 |
| 228 // A read where no data is available at first (IO_PENDING will be returned). | 228 // A read where no data is available at first (IO_PENDING will be returned). |
| 229 TEST_F(GCMSocketStreamTest, ReadAsync) { | 229 TEST_F(GCMSocketStreamTest, ReadAsync) { |
| 230 size_t first_read_len = kReadDataSize / 2; | 230 int first_read_len = kReadDataSize / 2; |
| 231 size_t second_read_len = kReadDataSize - first_read_len; | 231 int second_read_len = kReadDataSize - first_read_len; |
| 232 ReadList read_list; | 232 ReadList read_list; |
| 233 read_list.push_back( | 233 read_list.push_back( |
| 234 net::MockRead(net::SYNCHRONOUS, net::ERR_IO_PENDING)); | 234 net::MockRead(net::SYNCHRONOUS, net::ERR_IO_PENDING)); |
| 235 read_list.push_back( | 235 read_list.push_back( |
| 236 net::MockRead(net::ASYNC, kReadData, first_read_len)); | 236 net::MockRead(net::ASYNC, kReadData, first_read_len)); |
| 237 read_list.push_back( | 237 read_list.push_back( |
| 238 net::MockRead(net::ASYNC, &kReadData[first_read_len], second_read_len)); | 238 net::MockRead(net::ASYNC, &kReadData[first_read_len], second_read_len)); |
| 239 BuildSocket(read_list, WriteList()); | 239 BuildSocket(read_list, WriteList()); |
| 240 | 240 |
| 241 base::MessageLoop::current()->PostTask( | 241 base::MessageLoop::current()->PostTask( |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 397 TEST_F(GCMSocketStreamTest, WriteDisconnected) { | 397 TEST_F(GCMSocketStreamTest, WriteDisconnected) { |
| 398 BuildSocket(ReadList(), WriteList()); | 398 BuildSocket(ReadList(), WriteList()); |
| 399 socket()->Disconnect(); | 399 socket()->Disconnect(); |
| 400 DoOutputStreamWrite(base::StringPiece(kWriteData, kWriteDataSize)); | 400 DoOutputStreamWrite(base::StringPiece(kWriteData, kWriteDataSize)); |
| 401 ASSERT_EQ(SocketOutputStream::CLOSED, output_stream()->GetState()); | 401 ASSERT_EQ(SocketOutputStream::CLOSED, output_stream()->GetState()); |
| 402 ASSERT_EQ(net::ERR_CONNECTION_CLOSED, output_stream()->last_error()); | 402 ASSERT_EQ(net::ERR_CONNECTION_CLOSED, output_stream()->last_error()); |
| 403 } | 403 } |
| 404 | 404 |
| 405 } // namespace | 405 } // namespace |
| 406 } // namespace gcm | 406 } // namespace gcm |
| OLD | NEW |