|
197 | 197 | end
|
198 | 198 | end
|
199 | 199 |
|
| 200 | + describe 'when there is an error during connection establishment' do |
| 201 | + require_topology :single |
| 202 | + |
| 203 | + # The push monitor creates sockets unpredictably and interferes with this |
| 204 | + # test. |
| 205 | + max_server_version '4.2' |
| 206 | + |
| 207 | + # When TLS is used there are two socket classes and we can't simply |
| 208 | + # mock the base Socket class. |
| 209 | + require_no_tls |
| 210 | + |
| 211 | + { |
| 212 | + SystemCallError => Mongo::Error::SocketError, |
| 213 | + Errno::ETIMEDOUT => Mongo::Error::SocketTimeoutError, |
| 214 | + }.each do |raw_error_cls, mapped_error_cls| |
| 215 | + context raw_error_cls.name do |
| 216 | + let(:socket) do |
| 217 | + double('mock socket').tap do |socket| |
| 218 | + allow(socket).to receive(:set_encoding) |
| 219 | + allow(socket).to receive(:setsockopt) |
| 220 | + allow(socket).to receive(:getsockopt) |
| 221 | + allow(socket).to receive(:connect) |
| 222 | + allow(socket).to receive(:close) |
| 223 | + socket.should receive(:write).and_raise(raw_error_cls, 'mocked failure') |
| 224 | + end |
| 225 | + end |
| 226 | + |
| 227 | + it 'marks server unknown' do |
| 228 | + server = client.cluster.next_primary |
| 229 | + client.cluster.servers.map(&:disconnect!) |
| 230 | + |
| 231 | + RSpec::Mocks.with_temporary_scope do |
| 232 | + |
| 233 | + Socket.should receive(:new).with(any_args).ordered.once.and_return(socket) |
| 234 | + |
| 235 | + lambda do |
| 236 | + client.command(ping: 1) |
| 237 | + end.should raise_error(mapped_error_cls, /mocked failure/) |
| 238 | + |
| 239 | + server.should be_unknown |
| 240 | + end |
| 241 | + end |
| 242 | + |
| 243 | + it 'recovers' do |
| 244 | + server = client.cluster.next_primary |
| 245 | + # If we do not kill the monitor, the client will recover automatically. |
| 246 | + |
| 247 | + RSpec::Mocks.with_temporary_scope do |
| 248 | + |
| 249 | + Socket.should receive(:new).with(any_args).ordered.once.and_return(socket) |
| 250 | + Socket.should receive(:new).with(any_args).ordered.once.and_call_original |
| 251 | + |
| 252 | + lambda do |
| 253 | + client.command(ping: 1) |
| 254 | + end.should raise_error(mapped_error_cls, /mocked failure/) |
| 255 | + |
| 256 | + client.command(ping: 1) |
| 257 | + end |
| 258 | + end |
| 259 | + end |
| 260 | + end |
| 261 | + |
| 262 | + after do |
| 263 | + # Since we stopped monitoring on the client, close it. |
| 264 | + ClientRegistry.instance.close_all_clients |
| 265 | + end |
| 266 | + end |
| 267 | + |
200 | 268 | describe 'when there is an error on monitoring connection' do
|
201 | 269 | clean_slate_for_all
|
202 | 270 |
|
|
0 commit comments