| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2009 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 #ifndef NET_BASE_SOCKET_TEST_UTIL_H_ | |
| 6 #define NET_BASE_SOCKET_TEST_UTIL_H_ | |
| 7 | |
| 8 #include <string> | |
| 9 #include <vector> | |
| 10 | |
| 11 #include "base/basictypes.h" | |
| 12 #include "base/logging.h" | |
| 13 #include "net/base/address_list.h" | |
| 14 #include "net/base/client_socket_factory.h" | |
| 15 #include "net/base/net_errors.h" | |
| 16 #include "net/base/ssl_config_service.h" | |
| 17 | |
| 18 namespace net { | |
| 19 | |
| 20 class ClientSocket; | |
| 21 class SSLClientSocket; | |
| 22 | |
| 23 struct MockConnect { | |
| 24 // Asynchronous connection success. | |
| 25 MockConnect() : async(true), result(OK) { } | |
| 26 MockConnect(bool a, int r) : async(a), result(r) { } | |
| 27 | |
| 28 bool async; | |
| 29 int result; | |
| 30 }; | |
| 31 | |
| 32 struct MockRead { | |
| 33 // Read failure (no data). | |
| 34 MockRead(bool async, int result) : async(async) , result(result), data(NULL), | |
| 35 data_len(0) { } | |
| 36 | |
| 37 // Asynchronous read success (inferred data length). | |
| 38 explicit MockRead(const char* data) : async(true), result(0), data(data), | |
| 39 data_len(strlen(data)) { } | |
| 40 | |
| 41 // Read success (inferred data length). | |
| 42 MockRead(bool async, const char* data) : async(async), result(0), data(data), | |
| 43 data_len(strlen(data)) { } | |
| 44 | |
| 45 // Read success. | |
| 46 MockRead(bool async, const char* data, int data_len) : async(async), | |
| 47 result(0), data(data), data_len(data_len) { } | |
| 48 | |
| 49 bool async; | |
| 50 int result; | |
| 51 const char* data; | |
| 52 int data_len; | |
| 53 }; | |
| 54 | |
| 55 // MockWrite uses the same member fields as MockRead, but with different | |
| 56 // meanings. The expected input to MockTCPClientSocket::Write() is given | |
| 57 // by {data, data_len}, and the return value of Write() is controlled by | |
| 58 // {async, result}. | |
| 59 typedef MockRead MockWrite; | |
| 60 | |
| 61 struct MockWriteResult { | |
| 62 MockWriteResult(bool async, int result) : async(async), result(result) {} | |
| 63 | |
| 64 bool async; | |
| 65 int result; | |
| 66 }; | |
| 67 | |
| 68 class MockSocket { | |
| 69 public: | |
| 70 MockSocket() : unexpected_read_(true, ERR_UNEXPECTED) { | |
| 71 } | |
| 72 | |
| 73 virtual ~MockSocket() {} | |
| 74 virtual MockRead* GetNextRead() = 0; | |
| 75 virtual MockWriteResult OnWrite(const std::string& data) = 0; | |
| 76 virtual void Reset() = 0; | |
| 77 | |
| 78 MockConnect connect_data() const { return connect_; } | |
| 79 | |
| 80 protected: | |
| 81 MockRead* unexpected_read() { return &unexpected_read_; } | |
| 82 | |
| 83 private: | |
| 84 MockRead unexpected_read_; | |
| 85 MockConnect connect_; | |
| 86 | |
| 87 DISALLOW_COPY_AND_ASSIGN(MockSocket); | |
| 88 }; | |
| 89 | |
| 90 // MockSocket which responds based on static tables of mock reads and writes. | |
| 91 class StaticMockSocket : public MockSocket { | |
| 92 public: | |
| 93 StaticMockSocket() : reads_(NULL), read_index_(0), | |
| 94 writes_(NULL), write_index_(0) {} | |
| 95 StaticMockSocket(MockRead* r, MockWrite* w) : reads_(r), read_index_(0), | |
| 96 writes_(w), write_index_(0) {} | |
| 97 | |
| 98 // MockSocket methods: | |
| 99 virtual MockRead* GetNextRead(); | |
| 100 virtual MockWriteResult OnWrite(const std::string& data); | |
| 101 virtual void Reset(); | |
| 102 | |
| 103 private: | |
| 104 MockRead* reads_; | |
| 105 int read_index_; | |
| 106 MockWrite* writes_; | |
| 107 int write_index_; | |
| 108 | |
| 109 DISALLOW_COPY_AND_ASSIGN(StaticMockSocket); | |
| 110 }; | |
| 111 | |
| 112 // MockSocket which can make decisions about next mock reads based on | |
| 113 // received writes. It can also be used to enforce order of operations, | |
| 114 // for example that tested code must send the "Hello!" message before | |
| 115 // receiving response. This is useful for testing conversation-like | |
| 116 // protocols like FTP. | |
| 117 class DynamicMockSocket : public MockSocket { | |
| 118 public: | |
| 119 DynamicMockSocket(); | |
| 120 | |
| 121 // MockSocket methods: | |
| 122 virtual MockRead* GetNextRead(); | |
| 123 virtual MockWriteResult OnWrite(const std::string& data) = 0; | |
| 124 virtual void Reset(); | |
| 125 | |
| 126 protected: | |
| 127 // The next time there is a read from this socket, it will return |data|. | |
| 128 // Before calling SimulateRead next time, the previous data must be consumed. | |
| 129 void SimulateRead(const char* data); | |
| 130 | |
| 131 private: | |
| 132 MockRead read_; | |
| 133 bool has_read_; | |
| 134 bool consumed_read_; | |
| 135 | |
| 136 DISALLOW_COPY_AND_ASSIGN(DynamicMockSocket); | |
| 137 }; | |
| 138 | |
| 139 // MockSSLSockets only need to keep track of the return code from calls to | |
| 140 // Connect(). | |
| 141 struct MockSSLSocket { | |
| 142 MockSSLSocket(bool async, int result) : connect(async, result) { } | |
| 143 | |
| 144 MockConnect connect; | |
| 145 }; | |
| 146 | |
| 147 // Holds an array of Mock{SSL,}Socket elements. As Mock{TCP,SSL}ClientSocket | |
| 148 // objects get instantiated, they take their data from the i'th element of this | |
| 149 // array. | |
| 150 template<typename T> | |
| 151 class MockSocketArray { | |
| 152 public: | |
| 153 MockSocketArray() : next_index_(0) { | |
| 154 } | |
| 155 | |
| 156 T* GetNext() { | |
| 157 DCHECK(next_index_ < sockets_.size()); | |
| 158 return sockets_[next_index_++]; | |
| 159 } | |
| 160 | |
| 161 void Add(T* socket) { | |
| 162 DCHECK(socket); | |
| 163 sockets_.push_back(socket); | |
| 164 } | |
| 165 | |
| 166 void ResetNextIndex() { | |
| 167 next_index_ = 0; | |
| 168 } | |
| 169 | |
| 170 private: | |
| 171 // Index of the next |sockets| element to use. Not an iterator because those | |
| 172 // are invalidated on vector reallocation. | |
| 173 size_t next_index_; | |
| 174 | |
| 175 // Mock sockets to be returned. | |
| 176 std::vector<T*> sockets_; | |
| 177 }; | |
| 178 | |
| 179 // ClientSocketFactory which contains arrays of sockets of each type. | |
| 180 // You should first fill the arrays using AddMock{SSL,}Socket. When the factory | |
| 181 // is asked to create a socket, it takes next entry from appropriate array. | |
| 182 // You can use ResetNextMockIndexes to reset that next entry index for all mock | |
| 183 // socket types. | |
| 184 class MockClientSocketFactory : public ClientSocketFactory { | |
| 185 public: | |
| 186 void AddMockSocket(MockSocket* socket); | |
| 187 void AddMockSSLSocket(MockSSLSocket* socket); | |
| 188 void ResetNextMockIndexes(); | |
| 189 | |
| 190 // ClientSocketFactory | |
| 191 virtual ClientSocket* CreateTCPClientSocket(const AddressList& addresses); | |
| 192 virtual SSLClientSocket* CreateSSLClientSocket( | |
| 193 ClientSocket* transport_socket, | |
| 194 const std::string& hostname, | |
| 195 const SSLConfig& ssl_config); | |
| 196 | |
| 197 private: | |
| 198 MockSocketArray<MockSocket> mock_sockets_; | |
| 199 MockSocketArray<MockSSLSocket> mock_ssl_sockets_; | |
| 200 }; | |
| 201 | |
| 202 } // namespace net | |
| 203 | |
| 204 #endif // NET_BASE_SOCKET_TEST_UTIL_H_ | |
| OLD | NEW |