mongo 2.11.1 → 2.11.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +2 -1
  3. data.tar.gz.sig +2 -1
  4. data/Rakefile +24 -0
  5. data/lib/mongo/address.rb +53 -37
  6. data/lib/mongo/auth.rb +30 -10
  7. data/lib/mongo/auth/cr.rb +1 -0
  8. data/lib/mongo/auth/cr/conversation.rb +13 -13
  9. data/lib/mongo/auth/ldap.rb +2 -1
  10. data/lib/mongo/auth/ldap/conversation.rb +9 -12
  11. data/lib/mongo/auth/scram.rb +1 -0
  12. data/lib/mongo/auth/scram/conversation.rb +36 -27
  13. data/lib/mongo/auth/user.rb +7 -1
  14. data/lib/mongo/auth/x509.rb +2 -1
  15. data/lib/mongo/auth/x509/conversation.rb +9 -9
  16. data/lib/mongo/bulk_write/transformable.rb +3 -3
  17. data/lib/mongo/client.rb +17 -6
  18. data/lib/mongo/cluster.rb +67 -49
  19. data/lib/mongo/cluster/sdam_flow.rb +87 -3
  20. data/lib/mongo/collection/view/readable.rb +3 -1
  21. data/lib/mongo/collection/view/writable.rb +3 -3
  22. data/lib/mongo/cursor/builder/kill_cursors_command.rb +8 -1
  23. data/lib/mongo/cursor/builder/op_kill_cursors.rb +8 -1
  24. data/lib/mongo/database.rb +1 -1
  25. data/lib/mongo/grid/file.rb +5 -0
  26. data/lib/mongo/grid/file/chunk.rb +2 -0
  27. data/lib/mongo/grid/fs_bucket.rb +15 -13
  28. data/lib/mongo/grid/stream/write.rb +9 -3
  29. data/lib/mongo/protocol/serializers.rb +12 -2
  30. data/lib/mongo/server.rb +13 -6
  31. data/lib/mongo/server/connection.rb +15 -8
  32. data/lib/mongo/server/connection_base.rb +7 -4
  33. data/lib/mongo/server/description.rb +34 -21
  34. data/lib/mongo/server/monitor.rb +1 -1
  35. data/lib/mongo/server/monitor/connection.rb +2 -3
  36. data/lib/mongo/session.rb +10 -10
  37. data/lib/mongo/socket.rb +10 -1
  38. data/lib/mongo/uri.rb +1 -1
  39. data/lib/mongo/version.rb +1 -1
  40. data/mongo.gemspec +1 -1
  41. data/spec/README.md +13 -0
  42. data/spec/integration/auth_spec.rb +27 -8
  43. data/spec/integration/bson_symbol_spec.rb +34 -0
  44. data/spec/integration/client_construction_spec.rb +14 -0
  45. data/spec/integration/client_options_spec.rb +5 -5
  46. data/spec/integration/connection_spec.rb +57 -9
  47. data/spec/integration/crud_spec.rb +45 -0
  48. data/spec/integration/cursor_reaping_spec.rb +2 -1
  49. data/spec/integration/grid_fs_bucket_spec.rb +48 -0
  50. data/spec/integration/retryable_errors_spec.rb +2 -2
  51. data/spec/integration/zlib_compression_spec.rb +25 -0
  52. data/spec/lite_spec_helper.rb +1 -0
  53. data/spec/mongo/address_spec.rb +19 -13
  54. data/spec/mongo/auth/ldap/conversation_spec.rb +1 -1
  55. data/spec/mongo/auth/scram/conversation_spec.rb +25 -14
  56. data/spec/mongo/auth/user/view_spec.rb +39 -7
  57. data/spec/mongo/auth/user_spec.rb +12 -0
  58. data/spec/mongo/auth/x509/conversation_spec.rb +1 -1
  59. data/spec/mongo/bulk_write_spec.rb +2 -2
  60. data/spec/mongo/client_construction_spec.rb +3 -22
  61. data/spec/mongo/cluster_spec.rb +57 -0
  62. data/spec/mongo/collection/view/map_reduce_spec.rb +1 -1
  63. data/spec/mongo/collection_spec.rb +26 -2
  64. data/spec/mongo/cursor/builder/op_kill_cursors_spec.rb +56 -0
  65. data/spec/mongo/server/connection_spec.rb +76 -8
  66. data/spec/mongo/server/monitor/connection_spec.rb +14 -7
  67. data/spec/mongo/socket/ssl_spec.rb +132 -98
  68. data/spec/mongo/socket/tcp_spec.rb +1 -9
  69. data/spec/mongo/uri_spec.rb +1 -1
  70. data/spec/runners/sdam/verifier.rb +6 -3
  71. data/spec/spec_tests/data/sdam/rs/primary_address_change.yml +29 -0
  72. data/spec/spec_tests/data/sdam/rs/primary_mismatched_me.yml +27 -23
  73. data/spec/spec_tests/data/sdam/rs/primary_to_no_primary_mismatched_me.yml +56 -79
  74. data/spec/spec_tests/data/sdam/sharded/primary_address_change.yml +21 -0
  75. data/spec/spec_tests/data/sdam/sharded/primary_mismatched_me.yml +22 -0
  76. data/spec/spec_tests/data/sdam/single/primary_address_change.yml +24 -0
  77. data/spec/spec_tests/data/sdam/single/primary_mismatched_me.yml +25 -0
  78. data/spec/spec_tests/data/sdam_monitoring/replica_set_with_me_mismatch.yml +159 -0
  79. data/spec/spec_tests/data/sdam_monitoring/{replica_set_other_seed.yml → replica_set_with_primary_change.yml} +97 -101
  80. data/spec/spec_tests/data/sdam_monitoring/replica_set_with_primary_removal.yml +22 -18
  81. data/spec/spec_tests/data/sdam_monitoring/standalone_to_rs_with_me_mismatch.yml +90 -0
  82. data/spec/support/cluster_config.rb +36 -0
  83. data/spec/support/cluster_tools.rb +5 -3
  84. data/spec/support/command_monitoring.rb +1 -1
  85. data/spec/support/constraints.rb +18 -18
  86. data/spec/support/lite_constraints.rb +8 -0
  87. data/spec/support/server_discovery_and_monitoring.rb +2 -0
  88. data/spec/support/spec_config.rb +3 -3
  89. data/spec/support/utils.rb +11 -1
  90. metadata +661 -637
  91. metadata.gz.sig +0 -0
@@ -204,7 +204,7 @@ module Mongo
204
204
  connection.ismaster
205
205
  end
206
206
  if exc
207
- log_debug("Error running ismaster on #{server.address}: #{exc.class}: #{exc.message}")
207
+ log_debug("Error running ismaster on #{server.address}: #{exc.class}: #{exc}:\n#{exc.backtrace[0..5].join("\n")}")
208
208
  if monitoring.monitoring?
209
209
  monitoring.failed(
210
210
  Monitoring::SERVER_HEARTBEAT,
@@ -162,8 +162,7 @@ module Mongo
162
162
  # @since 2.0.0
163
163
  def connect!
164
164
  unless @socket
165
- socket = address.socket(socket_timeout, ssl_options,
166
- connect_timeout: address.connect_timeout)
165
+ socket = address.socket(socket_timeout, ssl_options, address.options)
167
166
  handshake!(socket)
168
167
  @socket = socket
169
168
  end
@@ -232,7 +231,7 @@ module Mongo
232
231
  log_warn("Asked to handshake with #{address} but there was no app metadata provided")
233
232
  end
234
233
  rescue => e
235
- log_warn("Failed to handshake with #{address}: #{e.class}: #{e}")
234
+ log_warn("Failed to handshake with #{address}: #{e.class}: #{e}:\n#{e.backtrace[0..5].join("\n")}")
236
235
  raise
237
236
  end
238
237
 
@@ -881,21 +881,21 @@ module Mongo
881
881
  end
882
882
  end
883
883
 
884
- # Validate the session.
884
+ # Validate the session for use by the specified client.
885
885
  #
886
- # @example
887
- # session.validate!(cluster)
886
+ # The session must not be ended and must have been created by a client
887
+ # with the same cluster as the client that the session is to be used with.
888
888
  #
889
- # @param [ Cluster ] cluster The cluster the session is attempted to be used with.
889
+ # @param [ Client ] client The client the session is to be used with.
890
890
  #
891
- # @return [ nil ] nil if the session is valid.
891
+ # @return [ Session ] self, if the session is valid.
892
892
  #
893
- # @raise [ Mongo::Error::InvalidSession ] Raise error if the session is not valid.
893
+ # @raise [ Mongo::Error::InvalidSession ] Exception raised if the session is not valid.
894
894
  #
895
895
  # @since 2.5.0
896
896
  # @api private
897
- def validate!(cluster)
898
- check_matching_cluster!(cluster)
897
+ def validate!(client)
898
+ check_matching_cluster!(client)
899
899
  check_if_ended!
900
900
  self
901
901
  end
@@ -1041,8 +1041,8 @@ module Mongo
1041
1041
  raise Mongo::Error::InvalidSession.new(SESSION_ENDED_ERROR_MSG) if ended?
1042
1042
  end
1043
1043
 
1044
- def check_matching_cluster!(cluster)
1045
- if @client.cluster != cluster
1044
+ def check_matching_cluster!(client)
1045
+ if @client.cluster != client.cluster
1046
1046
  raise Mongo::Error::InvalidSession.new(MISMATCHED_CLUSTER_ERROR_MSG)
1047
1047
  end
1048
1048
  end
@@ -63,7 +63,16 @@ module Mongo
63
63
  def alive?
64
64
  sock_arr = [ @socket ]
65
65
  if Kernel::select(sock_arr, nil, sock_arr, 0)
66
- eof?
66
+ # The eof? call is supposed to return immediately since select
67
+ # indicated the socket is readable. However, if @socket is an SSL
68
+ # socket, eof? can block anyway - see RUBY-2140.
69
+ begin
70
+ Timeout.timeout(0.1) do
71
+ eof?
72
+ end
73
+ rescue ::Timeout::Error
74
+ true
75
+ end
67
76
  else
68
77
  true
69
78
  end
@@ -454,7 +454,7 @@ module Mongo
454
454
  end
455
455
 
456
456
  def decode(value)
457
- ::URI.decode(value)
457
+ ::URI::DEFAULT_PARSER.unescape(value)
458
458
  end
459
459
 
460
460
  def encode(value)
@@ -17,5 +17,5 @@ module Mongo
17
17
  # The current version of the driver.
18
18
  #
19
19
  # @since 2.0.0
20
- VERSION = '2.11.1'.freeze
20
+ VERSION = '2.11.6'.freeze
21
21
  end
@@ -40,5 +40,5 @@ Gem::Specification.new do |s|
40
40
 
41
41
  s.required_ruby_version = ">= 2.3"
42
42
 
43
- s.add_dependency 'bson', '>=4.6.0', '<5.0.0'
43
+ s.add_dependency 'bson', '>=4.4.2', '<5.0.0'
44
44
  end
@@ -74,6 +74,19 @@ configuration is needed:
74
74
 
75
75
  rake
76
76
 
77
+ ### Replica Set With Arbiter
78
+
79
+ Some tests require an arbiter to be present in the replica set. Such a
80
+ deployment can be obtained by providing `--arbiter` argument to mlaunch:
81
+
82
+ mlaunch init --replicaset --arbiter --name ruby-driver-rs \
83
+ --dir /tmp/mdb-rs --setParameter enableTestCommands=1
84
+
85
+ To indicate to the test suite that the deployment contains an arbiter, set
86
+ HAVE_ARBITER environment variable as follows:
87
+
88
+ HAVE_ARBITER=1 rake
89
+
77
90
  ### Sharded Cluster
78
91
 
79
92
  A sharded cluster can be configured with mlaunch:
@@ -41,7 +41,7 @@ describe 'Auth' do
41
41
  it 'indicates scram-sha-1 was used' do
42
42
  expect do
43
43
  connection.connect!
44
- end.to raise_error(Mongo::Auth::Unauthorized, /User nonexistent_user \(mechanism: scram\) is not authorized to access admin.*\(used mechanism: SCRAM-SHA-1\)/)
44
+ end.to raise_error(Mongo::Auth::Unauthorized, /User nonexistent_user \(mechanism: scram\) is not authorized to access admin.*used mechanism: SCRAM-SHA-1/)
45
45
  end
46
46
  end
47
47
 
@@ -53,7 +53,7 @@ describe 'Auth' do
53
53
  it 'indicates scram-sha-1 was used' do
54
54
  expect do
55
55
  connection.connect!
56
- end.to raise_error(Mongo::Auth::Unauthorized, /User nonexistent_user \(mechanism: scram\) is not authorized to access admin.*\(used mechanism: SCRAM-SHA-1\)/)
56
+ end.to raise_error(Mongo::Auth::Unauthorized, /User nonexistent_user \(mechanism: scram\) is not authorized to access admin.*used mechanism: SCRAM-SHA-1/)
57
57
  end
58
58
  end
59
59
  end
@@ -73,7 +73,7 @@ describe 'Auth' do
73
73
  it 'indicates scram-sha-1 was used' do
74
74
  expect do
75
75
  connection.connect!
76
- end.to raise_error(Mongo::Auth::Unauthorized, /User existing_user \(mechanism: scram\) is not authorized to access admin.*\(used mechanism: SCRAM-SHA-1\)/)
76
+ end.to raise_error(Mongo::Auth::Unauthorized, /User existing_user \(mechanism: scram\) is not authorized to access admin.*used mechanism: SCRAM-SHA-1/)
77
77
  end
78
78
  end
79
79
 
@@ -85,7 +85,7 @@ describe 'Auth' do
85
85
  it 'indicates scram-sha-256 was used' do
86
86
  expect do
87
87
  connection.connect!
88
- end.to raise_error(Mongo::Auth::Unauthorized, /User existing_user \(mechanism: scram256\) is not authorized to access admin.*\(used mechanism: SCRAM-SHA-256\)/)
88
+ end.to raise_error(Mongo::Auth::Unauthorized, /User existing_user \(mechanism: scram256\) is not authorized to access admin.*used mechanism: SCRAM-SHA-256/)
89
89
  end
90
90
  end
91
91
  end
@@ -101,7 +101,7 @@ describe 'Auth' do
101
101
  it 'indicates scram-sha-1 was requested and used' do
102
102
  expect do
103
103
  connection.connect!
104
- end.to raise_error(Mongo::Auth::Unauthorized, /User nonexistent_user \(mechanism: scram\) is not authorized to access admin.*\(used mechanism: SCRAM-SHA-1\)/)
104
+ end.to raise_error(Mongo::Auth::Unauthorized, /User nonexistent_user \(mechanism: scram\) is not authorized to access admin.*used mechanism: SCRAM-SHA-1/)
105
105
  end
106
106
  end
107
107
 
@@ -114,7 +114,7 @@ describe 'Auth' do
114
114
  it 'indicates scram-sha-256 was requested and used' do
115
115
  expect do
116
116
  connection.connect!
117
- end.to raise_error(Mongo::Auth::Unauthorized, /User nonexistent_user \(mechanism: scram256\) is not authorized to access admin.*\(used mechanism: SCRAM-SHA-256\)/)
117
+ end.to raise_error(Mongo::Auth::Unauthorized, /User nonexistent_user \(mechanism: scram256\) is not authorized to access admin.*used mechanism: SCRAM-SHA-256/)
118
118
  end
119
119
  end
120
120
  end
@@ -123,10 +123,29 @@ describe 'Auth' do
123
123
  let(:options) { SpecConfig.instance.ssl_options.merge(
124
124
  user: 'nonexistent_user', password: 'foo') }
125
125
 
126
- it 'reports auth source used' do
126
+ it 'reports which server authentication was attempted against' do
127
127
  expect do
128
128
  connection.connect!
129
- end.to raise_error(Mongo::Auth::Unauthorized, /User nonexistent_user.*is not authorized to access admin \(auth source: admin\)/)
129
+ end.to raise_error(Mongo::Auth::Unauthorized, /used server: #{connection.address.to_s}/)
130
+ end
131
+
132
+ context 'with default auth source' do
133
+ it 'reports auth source used' do
134
+ expect do
135
+ connection.connect!
136
+ end.to raise_error(Mongo::Auth::Unauthorized, /auth source: admin/)
137
+ end
138
+ end
139
+
140
+ context 'with custom auth source' do
141
+ let(:options) { SpecConfig.instance.ssl_options.merge(
142
+ user: 'nonexistent_user', password: 'foo', auth_source: 'authdb') }
143
+
144
+ it 'reports auth source used' do
145
+ expect do
146
+ connection.connect!
147
+ end.to raise_error(Mongo::Auth::Unauthorized, /auth source: authdb/)
148
+ end
130
149
  end
131
150
  end
132
151
 
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Symbol encoding to BSON' do
4
+ let(:value) { :foo }
5
+
6
+ let(:hash) do
7
+ {'foo' => value}
8
+ end
9
+
10
+ let(:serialized) do
11
+ hash.to_bson.to_s
12
+ end
13
+
14
+ let(:expected) do
15
+ "\x12\x00\x00\x00\x0Efoo\x00\x04\x00\x00\x00foo\x00\x00".force_encoding('binary')
16
+ end
17
+
18
+ it 'encodes symbol to BSON symbol' do
19
+ serialized.should == expected
20
+ end
21
+
22
+ it 'round-trips symbol values' do
23
+ buffer = BSON::ByteBuffer.new(serialized)
24
+ Hash.from_bson(buffer).should == hash
25
+ end
26
+
27
+ it 'round-trips symbol values using the same byte buffer' do
28
+ if BSON::Environment.jruby?
29
+ pending 'https://jira.mongodb.org/browse/RUBY-2128'
30
+ end
31
+
32
+ Hash.from_bson(hash.to_bson).should == hash
33
+ end
34
+ end
@@ -82,6 +82,20 @@ describe 'Client construction' do
82
82
  expect(client.cluster.topology).to be_a(Mongo::Cluster::Topology::Single)
83
83
  expect(client.options[:connect]).to eq :direct
84
84
  end
85
+
86
+ context 'direct connection with mismached me' do
87
+ let(:address) { ClusterConfig.instance.alternate_address.to_s }
88
+
89
+ let(:client) do
90
+ new_local_client([address], SpecConfig.instance.test_options)
91
+ end
92
+
93
+ let(:server) { client.cluster.next_primary }
94
+
95
+ it 'sets server type to primary' do
96
+ expect(server.description).to be_primary
97
+ end
98
+ end
85
99
  end
86
100
 
87
101
  context 'in sharded topology' do
@@ -38,7 +38,7 @@ describe 'Client options' do
38
38
  end
39
39
  end
40
40
 
41
- shared_examples_for 'auth mechanism that uses database or default auth source' do |default_auth_source:|
41
+ shared_examples_for 'auth mechanism that uses database or default auth source' do |default_auth_source|
42
42
  context 'where no database is provided' do
43
43
  context 'with URI options' do
44
44
  let(:credentials) { "#{user}:#{pwd}@" }
@@ -198,7 +198,7 @@ describe 'Client options' do
198
198
  let(:auth_mech_sym) { :mongodb_cr }
199
199
 
200
200
  it_behaves_like 'a supported auth mechanism'
201
- it_behaves_like 'auth mechanism that uses database or default auth source', default_auth_source: 'admin'
201
+ it_behaves_like 'auth mechanism that uses database or default auth source', 'admin'
202
202
  it_behaves_like 'an auth mechanism that doesn\'t support auth_mech_properties'
203
203
  end
204
204
 
@@ -207,7 +207,7 @@ describe 'Client options' do
207
207
  let(:auth_mech_sym) { :scram }
208
208
 
209
209
  it_behaves_like 'a supported auth mechanism'
210
- it_behaves_like 'auth mechanism that uses database or default auth source', default_auth_source: 'admin'
210
+ it_behaves_like 'auth mechanism that uses database or default auth source', 'admin'
211
211
  it_behaves_like 'an auth mechanism that doesn\'t support auth_mech_properties'
212
212
  end
213
213
 
@@ -216,7 +216,7 @@ describe 'Client options' do
216
216
  let(:auth_mech_sym) { :scram256 }
217
217
 
218
218
  it_behaves_like 'a supported auth mechanism'
219
- it_behaves_like 'auth mechanism that uses database or default auth source', default_auth_source: 'admin'
219
+ it_behaves_like 'auth mechanism that uses database or default auth source', 'admin'
220
220
  it_behaves_like 'an auth mechanism that doesn\'t support auth_mech_properties'
221
221
  end
222
222
 
@@ -263,7 +263,7 @@ describe 'Client options' do
263
263
  let(:auth_mech_sym) { :plain }
264
264
 
265
265
  it_behaves_like 'a supported auth mechanism'
266
- it_behaves_like 'auth mechanism that uses database or default auth source', default_auth_source: '$external'
266
+ it_behaves_like 'auth mechanism that uses database or default auth source', '$external'
267
267
  it_behaves_like 'an auth mechanism with ssl'
268
268
  it_behaves_like 'an auth mechanism that doesn\'t support auth_mech_properties'
269
269
  end
@@ -12,17 +12,18 @@ describe 'Connections' do
12
12
  let(:server) { client.cluster.servers.first }
13
13
 
14
14
  describe '#connect!' do
15
- # On JRuby 9.2.7.0, this line:
16
- # expect_any_instance_of(Mongo::Socket).to receive(:write).and_raise(exception)
17
- # ... appears to produce a moment in which Mongo::Socket#write is undefined
18
- # entirely, resulting in this failure:
19
- # RSpec::Expectations::ExpectationNotMetError: expected Mongo::Error::SocketError, got #<NameError: undefined method `write' for class `Mongo::Socket'>
20
- fails_on_jruby
15
+
16
+ let(:connection) do
17
+ Mongo::Server::Connection.new(server, server.options)
18
+ end
21
19
 
22
20
  context 'network error during handshake' do
23
- let(:connection) do
24
- Mongo::Server::Connection.new(server, server.options)
25
- end
21
+ # On JRuby 9.2.7.0, this line:
22
+ # expect_any_instance_of(Mongo::Socket).to receive(:write).and_raise(exception)
23
+ # ... appears to produce a moment in which Mongo::Socket#write is undefined
24
+ # entirely, resulting in this failure:
25
+ # RSpec::Expectations::ExpectationNotMetError: expected Mongo::Error::SocketError, got #<NameError: undefined method `write' for class `Mongo::Socket'>
26
+ fails_on_jruby
26
27
 
27
28
  let(:exception) { Mongo::Error::SocketError }
28
29
 
@@ -120,6 +121,53 @@ describe 'Connections' do
120
121
  expect(client.cluster.topology).to be_a(Mongo::Cluster::Topology::ReplicaSetNoPrimary)
121
122
  end
122
123
  end
124
+
125
+ describe 'number of sockets created' do
126
+
127
+ before do
128
+ server
129
+ end
130
+
131
+ shared_examples_for 'is 1 per connection' do
132
+ it 'is 1 per connection' do
133
+ # Instantiating a connection object should not create any sockets
134
+ RSpec::Mocks.with_temporary_scope do
135
+ expect(socket_cls).not_to receive(:new)
136
+
137
+ connection
138
+ end
139
+
140
+ # When the connection connects, exactly one socket should be created
141
+ # (and subsequently connected)
142
+ RSpec::Mocks.with_temporary_scope do
143
+ expect(socket_cls).to receive(:new).and_call_original
144
+
145
+ connection.connect!
146
+ end
147
+ end
148
+ end
149
+
150
+ let(:socket_cls) { ::Socket }
151
+
152
+ it_behaves_like 'is 1 per connection'
153
+
154
+ context 'connection to Unix domain socket' do
155
+ # Server does not allow Unix socket connections when TLS is enabled
156
+ require_no_tls
157
+
158
+ let(:port) { SpecConfig.instance.any_port }
159
+
160
+ let(:client) do
161
+ new_local_client(["/tmp/mongodb-#{port}.sock"], connect: :direct).tap do |client|
162
+ stop_monitoring(client)
163
+ end
164
+ end
165
+
166
+ let(:socket_cls) { ::UNIXSocket }
167
+
168
+ it_behaves_like 'is 1 per connection'
169
+ end
170
+ end
123
171
  end
124
172
 
125
173
  describe 'wire protocol version range update' do
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'CRUD operations' do
4
+ let(:collection) { authorized_client['crud_integration'] }
5
+
6
+ before do
7
+ collection.delete_many
8
+ end
9
+
10
+ describe 'upsert' do
11
+ context 'with default write concern' do
12
+ it 'upserts' do
13
+ collection.count_documents({}).should == 0
14
+
15
+ res = collection.find(_id: 'foo').update_one({'$set' => {foo: 'bar'}}, upsert: true)
16
+
17
+ res.documents.first['upserted'].length.should == 1
18
+
19
+ collection.count_documents({}).should == 1
20
+ end
21
+ end
22
+
23
+ context 'unacknowledged write' do
24
+ let(:unack_collection) do
25
+ collection.with(write_concern: {w: 0})
26
+ end
27
+
28
+ before do
29
+ unack_collection.write_concern.acknowledged?.should be false
30
+ end
31
+
32
+ it 'upserts' do
33
+ unack_collection.count_documents({}).should == 0
34
+
35
+ res = unack_collection.find(_id: 'foo').update_one({'$set' => {foo: 'bar'}}, upsert: true)
36
+
37
+ # since write concern is unacknowledged, wait for the data to be
38
+ # persisted (hopefully)
39
+ sleep 0.25
40
+
41
+ unack_collection.count_documents({}).should == 1
42
+ end
43
+ end
44
+ end
45
+ end
@@ -59,7 +59,8 @@ describe 'Cursor reaping' do
59
59
  client.cluster.instance_variable_get('@periodic_executor').execute
60
60
 
61
61
  started_event = EventSubscriber.started_events.detect do |event|
62
- event.command['killCursors'] && event.command['cursors'].map(&:value).include?(cursor_id)
62
+ event.command['killCursors'] &&
63
+ event.command['cursors'].map { |c| Utils.int64_value(c) }.include?(cursor_id)
63
64
  end
64
65
 
65
66
  expect(started_event).not_to be_nil