mongo 2.9.2 → 2.10.0.rc0

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 (227) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/lib/mongo.rb +1 -0
  5. data/lib/mongo/auth/user/view.rb +4 -4
  6. data/lib/mongo/bulk_write.rb +14 -8
  7. data/lib/mongo/bulk_write/result.rb +1 -1
  8. data/lib/mongo/bulk_write/result_combiner.rb +2 -2
  9. data/lib/mongo/bulk_write/transformable.rb +17 -9
  10. data/lib/mongo/client.rb +107 -16
  11. data/lib/mongo/cluster.rb +47 -25
  12. data/lib/mongo/cluster/topology/replica_set_no_primary.rb +1 -1
  13. data/lib/mongo/cluster_time.rb +139 -0
  14. data/lib/mongo/collection.rb +84 -25
  15. data/lib/mongo/collection/view.rb +7 -3
  16. data/lib/mongo/collection/view/aggregation.rb +4 -4
  17. data/lib/mongo/collection/view/builder/aggregation.rb +31 -6
  18. data/lib/mongo/collection/view/builder/find_command.rb +4 -1
  19. data/lib/mongo/collection/view/builder/map_reduce.rb +4 -1
  20. data/lib/mongo/collection/view/change_stream.rb +54 -66
  21. data/lib/mongo/collection/view/iterable.rb +2 -2
  22. data/lib/mongo/collection/view/map_reduce.rb +6 -4
  23. data/lib/mongo/collection/view/readable.rb +36 -16
  24. data/lib/mongo/collection/view/writable.rb +68 -22
  25. data/lib/mongo/cursor.rb +87 -20
  26. data/lib/mongo/database.rb +47 -43
  27. data/lib/mongo/database/view.rb +54 -11
  28. data/lib/mongo/error.rb +13 -4
  29. data/lib/mongo/error/invalid_write_concern.rb +2 -2
  30. data/lib/mongo/error/operation_failure.rb +65 -11
  31. data/lib/mongo/error/parser.rb +41 -8
  32. data/lib/mongo/grid/fs_bucket.rb +26 -6
  33. data/lib/mongo/grid/stream/read.rb +9 -2
  34. data/lib/mongo/grid/stream/write.rb +21 -5
  35. data/lib/mongo/index/view.rb +3 -3
  36. data/lib/mongo/lint.rb +10 -3
  37. data/lib/mongo/operation.rb +2 -0
  38. data/lib/mongo/operation/aggregate/result.rb +19 -6
  39. data/lib/mongo/operation/collections_info.rb +1 -1
  40. data/lib/mongo/operation/get_more/result.rb +9 -0
  41. data/lib/mongo/operation/list_collections/command.rb +1 -3
  42. data/lib/mongo/operation/list_collections/op_msg.rb +1 -2
  43. data/lib/mongo/operation/parallel_scan/command.rb +4 -1
  44. data/lib/mongo/operation/parallel_scan/op_msg.rb +4 -1
  45. data/lib/mongo/operation/result.rb +27 -4
  46. data/lib/mongo/operation/shared/executable.rb +19 -5
  47. data/lib/mongo/operation/shared/executable_no_validate.rb +1 -2
  48. data/lib/mongo/operation/shared/executable_transaction_label.rb +0 -9
  49. data/lib/mongo/operation/shared/polymorphic_result.rb +9 -1
  50. data/lib/mongo/operation/shared/result/aggregatable.rb +2 -2
  51. data/lib/mongo/operation/shared/sessions_supported.rb +42 -32
  52. data/lib/mongo/operation/shared/specifiable.rb +40 -0
  53. data/lib/mongo/operation/shared/unpinnable.rb +39 -0
  54. data/lib/mongo/operation/shared/write.rb +1 -1
  55. data/lib/mongo/protocol/update.rb +6 -2
  56. data/lib/mongo/retryable.rb +79 -39
  57. data/lib/mongo/server/connection.rb +10 -3
  58. data/lib/mongo/server/description.rb +25 -1
  59. data/lib/mongo/server/monitor/connection.rb +1 -1
  60. data/lib/mongo/server_selector.rb +10 -0
  61. data/lib/mongo/server_selector/selectable.rb +172 -32
  62. data/lib/mongo/session.rb +654 -581
  63. data/lib/mongo/session/session_pool.rb +1 -1
  64. data/lib/mongo/socket.rb +7 -28
  65. data/lib/mongo/socket/ssl.rb +26 -1
  66. data/lib/mongo/socket/tcp.rb +3 -0
  67. data/lib/mongo/socket/unix.rb +3 -0
  68. data/lib/mongo/uri.rb +112 -265
  69. data/lib/mongo/uri/srv_protocol.rb +4 -1
  70. data/lib/mongo/version.rb +1 -1
  71. data/lib/mongo/write_concern.rb +10 -29
  72. data/lib/mongo/write_concern/acknowledged.rb +12 -0
  73. data/lib/mongo/write_concern/base.rb +17 -13
  74. data/lib/mongo/write_concern/unacknowledged.rb +12 -0
  75. data/spec/atlas/atlas_connectivity_spec.rb +7 -37
  76. data/spec/atlas/operations_spec.rb +25 -0
  77. data/spec/integration/change_stream_examples_spec.rb +45 -31
  78. data/spec/integration/change_stream_spec.rb +305 -5
  79. data/spec/integration/client_spec.rb +44 -0
  80. data/spec/integration/command_monitoring_spec.rb +1 -0
  81. data/spec/integration/command_spec.rb +7 -1
  82. data/spec/integration/mmapv1_spec.rb +28 -0
  83. data/spec/integration/mongos_pinning_spec.rb +34 -0
  84. data/spec/integration/operation_failure_code_spec.rb +2 -2
  85. data/spec/integration/{read_concern.rb → read_concern_spec.rb} +7 -1
  86. data/spec/integration/read_preference_spec.rb +485 -0
  87. data/spec/integration/retryable_writes_spec.rb +8 -19
  88. data/spec/integration/sdam_error_handling_spec.rb +1 -1
  89. data/spec/integration/sdam_events_spec.rb +2 -2
  90. data/spec/integration/server_description_spec.rb +14 -17
  91. data/spec/integration/server_selector_spec.rb +7 -3
  92. data/spec/integration/server_spec.rb +48 -0
  93. data/spec/integration/ssl_uri_options_spec.rb +1 -1
  94. data/spec/integration/step_down_spec.rb +10 -4
  95. data/spec/integration/transactions_examples_spec.rb +11 -10
  96. data/spec/lite_spec_helper.rb +19 -16
  97. data/spec/mongo/auth/scram/negotiation_spec.rb +11 -8
  98. data/spec/mongo/bulk_write/ordered_combiner_spec.rb +6 -6
  99. data/spec/mongo/bulk_write/unordered_combiner_spec.rb +4 -4
  100. data/spec/mongo/bulk_write_spec.rb +12 -2
  101. data/spec/mongo/client_construction_spec.rb +160 -8
  102. data/spec/mongo/client_spec.rb +5 -4
  103. data/spec/mongo/cluster_spec.rb +6 -6
  104. data/spec/mongo/cluster_time_spec.rb +148 -0
  105. data/spec/mongo/collection/view/aggregation_spec.rb +34 -15
  106. data/spec/mongo/collection/view/change_stream_spec.rb +62 -3
  107. data/spec/mongo/collection/view/map_reduce_spec.rb +7 -5
  108. data/spec/mongo/collection/view/readable_spec.rb +4 -4
  109. data/spec/mongo/collection_spec.rb +331 -14
  110. data/spec/mongo/cursor_spec.rb +117 -5
  111. data/spec/mongo/database_spec.rb +240 -8
  112. data/spec/mongo/error/operation_failure_spec.rb +47 -1
  113. data/spec/mongo/error/parser_spec.rb +160 -23
  114. data/spec/mongo/operation/insert/bulk_spec.rb +2 -1
  115. data/spec/mongo/operation/result_spec.rb +27 -0
  116. data/spec/mongo/operation/update/bulk_spec.rb +1 -0
  117. data/spec/mongo/retryable_spec.rb +2 -0
  118. data/spec/mongo/server/app_metadata_spec.rb +2 -2
  119. data/spec/mongo/server/connection_spec.rb +13 -17
  120. data/spec/mongo/server/monitor/connection_spec.rb +13 -10
  121. data/spec/mongo/server_selector_spec.rb +34 -2
  122. data/spec/mongo/session/session_pool_spec.rb +14 -3
  123. data/spec/mongo/session_spec.rb +3 -3
  124. data/spec/mongo/session_transaction_spec.rb +4 -3
  125. data/spec/mongo/socket/ssl_spec.rb +19 -5
  126. data/spec/mongo/socket_spec.rb +1 -62
  127. data/spec/mongo/uri/srv_protocol_spec.rb +14 -20
  128. data/spec/mongo/uri_option_parsing_spec.rb +94 -8
  129. data/spec/mongo/uri_spec.rb +23 -10
  130. data/spec/mongo/write_concern_spec.rb +56 -3
  131. data/spec/spec_tests/change_streams_spec.rb +2 -1
  132. data/spec/spec_tests/cmap_spec.rb +1 -1
  133. data/spec/spec_tests/crud_spec.rb +12 -2
  134. data/spec/spec_tests/data/change_streams/change-streams-errors.yml +24 -1
  135. data/spec/spec_tests/data/change_streams/change-streams.yml +172 -3
  136. data/spec/spec_tests/data/command_monitoring/bulkWrite.yml +1 -1
  137. data/spec/spec_tests/data/command_monitoring/updateMany.yml +0 -2
  138. data/spec/spec_tests/data/command_monitoring/updateOne.yml +0 -5
  139. data/spec/spec_tests/data/crud/read/aggregate-out.yml +0 -6
  140. data/spec/spec_tests/data/crud/read/count-empty.yml +29 -0
  141. data/spec/spec_tests/data/crud/write/bulkWrite-arrayFilters.yml +1 -0
  142. data/spec/spec_tests/data/crud/write/bulkWrite-collation.yml +101 -0
  143. data/spec/spec_tests/data/crud/write/bulkWrite.yml +401 -0
  144. data/spec/spec_tests/data/crud/write/insertMany.yml +58 -2
  145. data/spec/spec_tests/data/crud/write/updateMany-arrayFilters.yml +3 -0
  146. data/spec/spec_tests/data/crud/write/updateOne-arrayFilters.yml +6 -1
  147. data/spec/spec_tests/data/crud_v2/aggregate-merge.yml +103 -0
  148. data/spec/spec_tests/data/crud_v2/aggregate-out-readConcern.yml +110 -0
  149. data/spec/spec_tests/data/crud_v2/bulkWrite-arrayFilters.yml +81 -0
  150. data/spec/spec_tests/data/crud_v2/db-aggregate.yml +38 -0
  151. data/spec/spec_tests/data/crud_v2/updateWithPipelines.yml +92 -0
  152. data/spec/spec_tests/data/retryable_writes/insertOne-serverErrors.yml +2 -2
  153. data/spec/spec_tests/data/transactions/abort.yml +3 -0
  154. data/spec/spec_tests/data/transactions/bulk.yml +3 -8
  155. data/spec/spec_tests/data/transactions/causal-consistency.yml +3 -8
  156. data/spec/spec_tests/data/transactions/commit.yml +3 -1
  157. data/spec/spec_tests/data/transactions/count.yml +3 -0
  158. data/spec/spec_tests/data/transactions/delete.yml +3 -0
  159. data/spec/spec_tests/data/transactions/error-labels.yml +4 -1
  160. data/spec/spec_tests/data/transactions/errors-client.yml +56 -0
  161. data/spec/spec_tests/data/transactions/errors.yml +3 -0
  162. data/spec/spec_tests/data/transactions/findOneAndDelete.yml +3 -0
  163. data/spec/spec_tests/data/transactions/findOneAndReplace.yml +3 -0
  164. data/spec/spec_tests/data/transactions/findOneAndUpdate.yml +3 -0
  165. data/spec/spec_tests/data/transactions/insert.yml +3 -0
  166. data/spec/spec_tests/data/transactions/isolation.yml +3 -0
  167. data/spec/spec_tests/data/transactions/mongos-pin-auto.yml +1671 -0
  168. data/spec/spec_tests/data/transactions/mongos-recovery-token.yml +347 -0
  169. data/spec/spec_tests/data/transactions/pin-mongos.yml +557 -0
  170. data/spec/spec_tests/data/transactions/read-concern.yml +3 -0
  171. data/spec/spec_tests/data/transactions/read-pref.yml +3 -0
  172. data/spec/spec_tests/data/transactions/reads.yml +3 -0
  173. data/spec/spec_tests/data/transactions/retryable-abort.yml +5 -2
  174. data/spec/spec_tests/data/transactions/retryable-commit.yml +4 -1
  175. data/spec/spec_tests/data/transactions/retryable-writes.yml +3 -0
  176. data/spec/spec_tests/data/transactions/run-command.yml +3 -0
  177. data/spec/spec_tests/data/transactions/transaction-options.yml +6 -0
  178. data/spec/spec_tests/data/transactions/update.yml +3 -8
  179. data/spec/spec_tests/data/transactions/write-concern.yml +348 -38
  180. data/spec/spec_tests/data/transactions_api/callback-aborts.yml +6 -0
  181. data/spec/spec_tests/data/transactions_api/callback-commits.yml +5 -0
  182. data/spec/spec_tests/data/transactions_api/callback-retry.yml +7 -2
  183. data/spec/spec_tests/data/transactions_api/commit-retry.yml +70 -15
  184. data/spec/spec_tests/data/transactions_api/commit-transienttransactionerror-4.2.yml +3 -0
  185. data/spec/spec_tests/data/transactions_api/commit-transienttransactionerror.yml +3 -0
  186. data/spec/spec_tests/data/transactions_api/commit-writeconcernerror.yml +59 -109
  187. data/spec/spec_tests/data/transactions_api/commit.yml +5 -0
  188. data/spec/spec_tests/data/transactions_api/transaction-options.yml +10 -0
  189. data/spec/spec_tests/retryable_reads_spec.rb +5 -2
  190. data/spec/spec_tests/retryable_writes_spec.rb +5 -2
  191. data/spec/spec_tests/sdam_monitoring_spec.rb +3 -3
  192. data/spec/spec_tests/sdam_spec.rb +2 -2
  193. data/spec/spec_tests/transactions_api_spec.rb +1 -67
  194. data/spec/spec_tests/transactions_spec.rb +2 -66
  195. data/spec/support/authorization.rb +4 -0
  196. data/spec/support/change_streams.rb +30 -10
  197. data/spec/support/change_streams/operation.rb +27 -0
  198. data/spec/support/client_registry.rb +44 -25
  199. data/spec/support/cluster_config.rb +25 -14
  200. data/spec/support/cluster_tools.rb +32 -10
  201. data/spec/support/command_monitoring.rb +1 -1
  202. data/spec/support/common_shortcuts.rb +30 -0
  203. data/spec/support/connection_string.rb +8 -3
  204. data/spec/support/constraints.rb +34 -0
  205. data/spec/support/crud.rb +31 -16
  206. data/spec/support/crud/context.rb +23 -0
  207. data/spec/support/crud/operation.rb +311 -14
  208. data/spec/support/crud/spec.rb +2 -1
  209. data/spec/support/crud/test.rb +24 -27
  210. data/spec/support/crud/test_base.rb +22 -0
  211. data/spec/support/crud/verifier.rb +15 -1
  212. data/spec/support/event_subscriber.rb +12 -0
  213. data/spec/support/sdam_formatter_integration.rb +12 -6
  214. data/spec/support/shared/server_selector.rb +10 -0
  215. data/spec/support/shared/session.rb +13 -12
  216. data/spec/support/spec_config.rb +32 -22
  217. data/spec/support/spec_setup.rb +2 -2
  218. data/spec/support/transactions.rb +87 -0
  219. data/spec/support/transactions/context.rb +33 -0
  220. data/spec/support/transactions/operation.rb +99 -349
  221. data/spec/support/transactions/spec.rb +1 -3
  222. data/spec/support/transactions/test.rb +110 -49
  223. data/spec/support/utils.rb +74 -1
  224. metadata +52 -10
  225. metadata.gz.sig +0 -0
  226. data/spec/support/crud/read.rb +0 -265
  227. data/spec/support/crud/write.rb +0 -284
@@ -137,8 +137,8 @@ describe Mongo::BulkWrite::UnorderedCombiner do
137
137
  [
138
138
  {
139
139
  update_one: [
140
- { 'q' => { _id: 0 }, 'u' => { '$set' => { name: 'test' }}, 'multi' => false, 'upsert' => false },
141
- { 'q' => { _id: 1 }, 'u' => { '$set' => { name: 'test' }}, 'multi' => false, 'upsert' => false }
140
+ { 'q' => { _id: 0 }, 'u' => { '$set' => { name: 'test' }}, },
141
+ { 'q' => { _id: 1 }, 'u' => { '$set' => { name: 'test' }}, },
142
142
  ]
143
143
  }
144
144
  ]
@@ -179,8 +179,8 @@ describe Mongo::BulkWrite::UnorderedCombiner do
179
179
  [
180
180
  {
181
181
  update_many: [
182
- { 'q' => { _id: 0 }, 'u' => { '$set' => { name: 'test' }}, 'multi' => true, 'upsert' => false },
183
- { 'q' => { _id: 1 }, 'u' => { '$set' => { name: 'test' }}, 'multi' => true, 'upsert' => false }
182
+ { 'q' => { _id: 0 }, 'u' => { '$set' => { name: 'test' }}, 'multi' => true, },
183
+ { 'q' => { _id: 1 }, 'u' => { '$set' => { name: 'test' }}, 'multi' => true, },
184
184
  ]
185
185
  }
186
186
  ]
@@ -80,7 +80,7 @@ describe Mongo::BulkWrite do
80
80
  end
81
81
 
82
82
  it 'sets the document index on the error' do
83
- expect(error.result[Mongo::Error::WRITE_ERRORS].first['index']).to eq(2)
83
+ expect(error.result['writeErrors'].first['index']).to eq(2)
84
84
  end
85
85
 
86
86
  context 'when a session is provided' do
@@ -1223,6 +1223,10 @@ describe Mongo::BulkWrite do
1223
1223
 
1224
1224
  context 'when write_concern is specified as an option' do
1225
1225
 
1226
+ # In a multi-sharded cluster, the write seems to go to a
1227
+ # different shard from the read
1228
+ require_no_multi_shard
1229
+
1226
1230
  let(:extra_options) do
1227
1231
  { write_concern: { w: 0 } }
1228
1232
  end
@@ -1844,7 +1848,7 @@ describe Mongo::BulkWrite do
1844
1848
 
1845
1849
  it 'sets the document index on the error' do
1846
1850
  requests.push({ insert_one: { _id: 5 }})
1847
- expect(error.result[Mongo::Error::WRITE_ERRORS].first['index']).to eq(batch_size)
1851
+ expect(error.result['writeErrors'].first['index']).to eq(batch_size)
1848
1852
  end
1849
1853
  end
1850
1854
 
@@ -1886,9 +1890,15 @@ describe Mongo::BulkWrite do
1886
1890
  end
1887
1891
 
1888
1892
  context 'when retryable writes are supported' do
1893
+ require_wired_tiger
1889
1894
  min_server_fcv '3.6'
1890
1895
  require_topology :replica_set, :sharded
1891
1896
 
1897
+ # In a multi-shard cluster, retries may go to a different server
1898
+ # than original command which these tests are not prepared to handle
1899
+ require_no_multi_shard
1900
+
1901
+
1892
1902
  let(:subscriber) { EventSubscriber.new }
1893
1903
 
1894
1904
  let(:client) do
@@ -653,7 +653,7 @@ describe Mongo::Client do
653
653
  end
654
654
 
655
655
  let(:expected_options) do
656
- Mongo::Options::Redacted.new(:write => { :w => 3 },
656
+ Mongo::Options::Redacted.new(write_concern: { :w => 3 },
657
657
  monitoring_io: false, :database => 'testdb', retry_writes: true,
658
658
  retry_reads: true)
659
659
  end
@@ -811,24 +811,38 @@ describe Mongo::Client do
811
811
  end
812
812
  end
813
813
 
814
- context 'when options are provided in the string and explicitly' do
814
+ context 'when options are provided in the URI and as Ruby options' do
815
815
 
816
816
  let!(:uri) do
817
817
  'mongodb://127.0.0.1:27017/testdb?w=3'
818
818
  end
819
819
 
820
820
  let(:client) do
821
- new_local_client_nmio(uri, :write => { :w => 4 })
821
+ new_local_client_nmio(uri, option_name => { :w => 4 })
822
822
  end
823
823
 
824
824
  let(:expected_options) do
825
- Mongo::Options::Redacted.new(:write => { :w => 4 },
825
+ Mongo::Options::Redacted.new(option_name => { :w => 4 },
826
826
  monitoring_io: false, :database => 'testdb', retry_writes: true,
827
827
  retry_reads: true)
828
828
  end
829
829
 
830
- it 'allows explicit options to take preference' do
831
- expect(client.options).to eq(expected_options)
830
+ shared_examples_for 'allows explicit options to take preference' do
831
+ it 'allows explicit options to take preference' do
832
+ expect(client.options).to eq(expected_options)
833
+ end
834
+ end
835
+
836
+ context 'when using :write' do
837
+ let(:option_name) { :write }
838
+
839
+ it_behaves_like 'allows explicit options to take preference'
840
+ end
841
+
842
+ context 'when using :write_concern' do
843
+ let(:option_name) { :write_concern }
844
+
845
+ it_behaves_like 'allows explicit options to take preference'
832
846
  end
833
847
  end
834
848
 
@@ -866,6 +880,26 @@ describe Mongo::Client do
866
880
  expect(client.options.keys).not_to include('invalid')
867
881
  end
868
882
  end
883
+
884
+ =begin WriteConcern object support
885
+ context 'when write concern is provided via a WriteConcern object' do
886
+
887
+ let(:client) do
888
+ new_local_client_nmio(['127.0.0.1:27017'], write_concern: wc)
889
+ end
890
+
891
+ let(:wc) { Mongo::WriteConcern.get(w: 2) }
892
+
893
+ it 'stores write concern options in client options' do
894
+ expect(client.options[:write_concern]).to eq(
895
+ Mongo::Options::Redacted.new(w: 2))
896
+ end
897
+
898
+ it 'caches write concern object' do
899
+ expect(client.write_concern).to be wc
900
+ end
901
+ end
902
+ =end
869
903
  end
870
904
  end
871
905
 
@@ -1090,7 +1124,12 @@ describe Mongo::Client do
1090
1124
  context 'when the write concern is changed' do
1091
1125
 
1092
1126
  let(:client) do
1093
- new_local_client(['127.0.0.1:27017'], :write => { :w => 1 }, :database => SpecConfig.instance.test_db)
1127
+ new_local_client(['127.0.0.1:27017'],
1128
+ {monitoring_io: false}.merge(client_options))
1129
+ end
1130
+
1131
+ let(:client_options) do
1132
+ { :write => { :w => 1 } }
1094
1133
  end
1095
1134
 
1096
1135
  context 'when the write concern has not been accessed' do
@@ -1123,6 +1162,116 @@ describe Mongo::Client do
1123
1162
  expect(get_last_error).to be_nil
1124
1163
  end
1125
1164
  end
1165
+
1166
+ context 'when write concern is given as :write' do
1167
+
1168
+ let(:client_options) do
1169
+ { :write => { :w => 1 } }
1170
+ end
1171
+
1172
+ it 'sets :write option' do
1173
+ expect(client.options[:write]).to eq(Mongo::Options::Redacted.new(w: 1))
1174
+ end
1175
+
1176
+ it 'does not set :write_concern option' do
1177
+ expect(client.options[:write_concern]).to be nil
1178
+ end
1179
+
1180
+ it 'returns correct write concern' do
1181
+ expect(client.write_concern).to be_a(Mongo::WriteConcern::Acknowledged)
1182
+ expect(client.write_concern.options).to eq(w: 1)
1183
+ end
1184
+ end
1185
+
1186
+ context 'when write concern is given as :write_concern' do
1187
+
1188
+ let(:client_options) do
1189
+ { :write_concern => { :w => 1 } }
1190
+ end
1191
+
1192
+ it 'sets :write_concern option' do
1193
+ expect(client.options[:write_concern]).to eq(Mongo::Options::Redacted.new(w: 1))
1194
+ end
1195
+
1196
+ it 'does not set :write option' do
1197
+ expect(client.options[:write]).to be nil
1198
+ end
1199
+
1200
+ it 'returns correct write concern' do
1201
+ expect(client.write_concern).to be_a(Mongo::WriteConcern::Acknowledged)
1202
+ expect(client.write_concern.options).to eq(w: 1)
1203
+ end
1204
+ end
1205
+
1206
+ context 'when write concern is given as both :write and :write_concern' do
1207
+ context 'with identical values' do
1208
+
1209
+ let(:client_options) do
1210
+ { write: {w: 1}, write_concern: { w: 1 } }
1211
+ end
1212
+
1213
+ it 'sets :write_concern option' do
1214
+ expect(client.options[:write_concern]).to eq(Mongo::Options::Redacted.new(w: 1))
1215
+ end
1216
+
1217
+ it 'sets :write option' do
1218
+ expect(client.options[:write]).to eq(Mongo::Options::Redacted.new(w: 1))
1219
+ end
1220
+
1221
+ it 'returns correct write concern' do
1222
+ expect(client.write_concern).to be_a(Mongo::WriteConcern::Acknowledged)
1223
+ expect(client.write_concern.options).to eq(w: 1)
1224
+ end
1225
+ end
1226
+
1227
+ context 'with different values' do
1228
+
1229
+ let(:client_options) do
1230
+ { write: {w: 1}, write_concern: { w: 2 } }
1231
+ end
1232
+
1233
+ it 'raises an exception' do
1234
+ expect do
1235
+ client
1236
+ end.to raise_error(ArgumentError, /If :write and :write_concern are both given, they must be identical/)
1237
+ end
1238
+ end
1239
+ end
1240
+
1241
+ context 'when #with uses a different write concern option name' do
1242
+
1243
+ context 'from :write_concern to :write' do
1244
+
1245
+ let(:client_options) do
1246
+ { :write_concern => { :w => 1 } }
1247
+ end
1248
+
1249
+ let!(:new_client) do
1250
+ client.with(:write => { :w => 2 })
1251
+ end
1252
+
1253
+ it 'uses the new option' do
1254
+ expect(new_client.options[:write]).to eq(Mongo::Options::Redacted.new(w: 2))
1255
+ expect(new_client.options[:write_concern]).to be nil
1256
+ end
1257
+ end
1258
+
1259
+ context 'from :write to :write_concern' do
1260
+
1261
+ let(:client_options) do
1262
+ { :write => { :w => 1 } }
1263
+ end
1264
+
1265
+ let!(:new_client) do
1266
+ client.with(:write_concern => { :w => 2 })
1267
+ end
1268
+
1269
+ it 'uses the new option' do
1270
+ expect(new_client.options[:write_concern]).to eq(Mongo::Options::Redacted.new(w: 2))
1271
+ expect(new_client.options[:write]).to be nil
1272
+ end
1273
+ end
1274
+ end
1126
1275
  end
1127
1276
 
1128
1277
  context 'when an invalid option is provided' do
@@ -1216,9 +1365,12 @@ describe Mongo::Client do
1216
1365
 
1217
1366
  it 'does not notify subscribers set up by sdam_proc' do
1218
1367
  client = new_local_client(['a'], sdam_proc: sdam_proc)
1219
- expect(subscriber.started_events.length).to eq 1
1368
+ expect(subscriber.started_events.length).to be > 0
1220
1369
  subscriber.started_events.clear
1221
1370
 
1371
+ # If this test takes longer than heartbeat interval,
1372
+ # subscriber may receive events from the original client.
1373
+
1222
1374
  new_client
1223
1375
  expect(subscriber.started_events.length).to eq 0
1224
1376
  end
@@ -505,7 +505,7 @@ describe Mongo::Client do
505
505
  let(:client_options) { {} }
506
506
 
507
507
  let(:client) do
508
- Mongo::Client.new(['127.0.0.1:27017'], {monitoring_io: false}.update(client_options))
508
+ new_local_client_nmio(['127.0.0.1:27017'], client_options)
509
509
  end
510
510
 
511
511
  it "defaults to #{default}" do
@@ -649,9 +649,10 @@ describe Mongo::Client do
649
649
  end
650
650
 
651
651
  it 'disconnects the cluster and returns true' do
652
- # note that disconnect! is called also in the after block
653
- expect(client.cluster).to receive(:disconnect!).and_call_original
654
- expect(client.close).to be(true)
652
+ RSpec::Mocks.with_temporary_scope do
653
+ expect(client.cluster).to receive(:disconnect!).and_call_original
654
+ expect(client.close(true)).to be(true)
655
+ end
655
656
  end
656
657
  end
657
658
 
@@ -74,7 +74,7 @@ describe Mongo::Cluster do
74
74
  describe '#has_readable_server?' do
75
75
 
76
76
  let(:selector) do
77
- Mongo::ServerSelector.get(mode: :primary)
77
+ Mongo::ServerSelector.primary
78
78
  end
79
79
 
80
80
  it 'delegates to the topology' do
@@ -92,7 +92,7 @@ describe Mongo::Cluster do
92
92
  describe '#inspect' do
93
93
 
94
94
  let(:preference) do
95
- Mongo::ServerSelector.get(ServerSelector::PRIMARY)
95
+ Mongo::ServerSelector.primary
96
96
  end
97
97
 
98
98
  it 'displays the cluster seeds and topology' do
@@ -104,7 +104,7 @@ describe Mongo::Cluster do
104
104
  describe '#replica_set_name' do
105
105
 
106
106
  let(:preference) do
107
- Mongo::ServerSelector.get(ServerSelector::PRIMARY)
107
+ Mongo::ServerSelector.primary
108
108
  end
109
109
 
110
110
  context 'when the option is provided' do
@@ -141,7 +141,7 @@ describe Mongo::Cluster do
141
141
  describe '#scan!' do
142
142
 
143
143
  let(:preference) do
144
- Mongo::ServerSelector.get(ServerSelector::PRIMARY)
144
+ Mongo::ServerSelector.primary
145
145
  end
146
146
 
147
147
  let(:known_servers) do
@@ -482,7 +482,7 @@ describe Mongo::Cluster do
482
482
  context 'when the cluster_time variable has a value' do
483
483
 
484
484
  before do
485
- cluster.instance_variable_set(:@cluster_time, BSON::Document.new(
485
+ cluster.instance_variable_set(:@cluster_time, Mongo::ClusterTime.new(
486
486
  Mongo::Cluster::CLUSTER_TIME => BSON::Timestamp.new(1, 1)))
487
487
  cluster.update_cluster_time(result)
488
488
  end
@@ -648,7 +648,7 @@ describe Mongo::Cluster do
648
648
  let(:client_options) { {} }
649
649
 
650
650
  let(:client) do
651
- Mongo::Client.new(['127.0.0.1:27017'], {monitoring_io: false}.update(client_options))
651
+ new_local_client_nmio(['127.0.0.1:27017'], client_options)
652
652
  end
653
653
 
654
654
  let(:cluster) do
@@ -0,0 +1,148 @@
1
+ require 'lite_spec_helper'
2
+
3
+ describe Mongo::ClusterTime do
4
+ describe '#>=' do
5
+ context 'equal but different objects' do
6
+ let(:one) { described_class.new(clusterTime: BSON::Timestamp.new(123, 456)) }
7
+ let(:two) { described_class.new(clusterTime: BSON::Timestamp.new(123, 456)) }
8
+
9
+ it 'is true' do
10
+ expect(one).to be >= two
11
+ end
12
+ end
13
+
14
+ context 'first is greater' do
15
+ let(:one) { described_class.new(clusterTime: BSON::Timestamp.new(124, 456)) }
16
+ let(:two) { described_class.new(clusterTime: BSON::Timestamp.new(123, 456)) }
17
+
18
+ it 'is true' do
19
+ expect(one).to be >= two
20
+ end
21
+ end
22
+
23
+ context 'second is greater' do
24
+ let(:one) { described_class.new(clusterTime: BSON::Timestamp.new(123, 456)) }
25
+ let(:two) { described_class.new(clusterTime: BSON::Timestamp.new(123, 457)) }
26
+
27
+ it 'is false' do
28
+ expect(one).not_to be >= two
29
+ end
30
+ end
31
+ end
32
+
33
+ describe '#>' do
34
+ context 'equal but different objects' do
35
+ let(:one) { described_class.new(clusterTime: BSON::Timestamp.new(123, 456)) }
36
+ let(:two) { described_class.new(clusterTime: BSON::Timestamp.new(123, 456)) }
37
+
38
+ it 'is false' do
39
+ expect(one).not_to be > two
40
+ end
41
+ end
42
+
43
+ context 'first is greater' do
44
+ let(:one) { described_class.new(clusterTime: BSON::Timestamp.new(124, 456)) }
45
+ let(:two) { described_class.new(clusterTime: BSON::Timestamp.new(123, 456)) }
46
+
47
+ it 'is true' do
48
+ expect(one).to be > two
49
+ end
50
+ end
51
+
52
+ context 'second is greater' do
53
+ let(:one) { described_class.new(clusterTime: BSON::Timestamp.new(123, 456)) }
54
+ let(:two) { described_class.new(clusterTime: BSON::Timestamp.new(123, 457)) }
55
+
56
+ it 'is false' do
57
+ expect(one).not_to be > two
58
+ end
59
+ end
60
+ end
61
+
62
+ describe '#<=' do
63
+ context 'equal but different objects' do
64
+ let(:one) { described_class.new(clusterTime: BSON::Timestamp.new(123, 456)) }
65
+ let(:two) { described_class.new(clusterTime: BSON::Timestamp.new(123, 456)) }
66
+
67
+ it 'is true' do
68
+ expect(one).to be <= two
69
+ end
70
+ end
71
+
72
+ context 'first is greater' do
73
+ let(:one) { described_class.new(clusterTime: BSON::Timestamp.new(124, 456)) }
74
+ let(:two) { described_class.new(clusterTime: BSON::Timestamp.new(123, 456)) }
75
+
76
+ it 'is false' do
77
+ expect(one).not_to be <= two
78
+ end
79
+ end
80
+
81
+ context 'second is greater' do
82
+ let(:one) { described_class.new(clusterTime: BSON::Timestamp.new(123, 456)) }
83
+ let(:two) { described_class.new(clusterTime: BSON::Timestamp.new(123, 457)) }
84
+
85
+ it 'is true' do
86
+ expect(one).to be <= two
87
+ end
88
+ end
89
+ end
90
+
91
+ describe '#<' do
92
+ context 'equal but different objects' do
93
+ let(:one) { described_class.new(clusterTime: BSON::Timestamp.new(123, 456)) }
94
+ let(:two) { described_class.new(clusterTime: BSON::Timestamp.new(123, 456)) }
95
+
96
+ it 'is false' do
97
+ expect(one).not_to be < two
98
+ end
99
+ end
100
+
101
+ context 'first is greater' do
102
+ let(:one) { described_class.new(clusterTime: BSON::Timestamp.new(124, 456)) }
103
+ let(:two) { described_class.new(clusterTime: BSON::Timestamp.new(123, 456)) }
104
+
105
+ it 'is false' do
106
+ expect(one).not_to be < two
107
+ end
108
+ end
109
+
110
+ context 'second is greater' do
111
+ let(:one) { described_class.new(clusterTime: BSON::Timestamp.new(123, 456)) }
112
+ let(:two) { described_class.new(clusterTime: BSON::Timestamp.new(123, 457)) }
113
+
114
+ it 'is true' do
115
+ expect(one).to be < two
116
+ end
117
+ end
118
+ end
119
+
120
+ describe '#==' do
121
+ context 'equal but different objects' do
122
+ let(:one) { described_class.new(clusterTime: BSON::Timestamp.new(123, 456)) }
123
+ let(:two) { described_class.new(clusterTime: BSON::Timestamp.new(123, 456)) }
124
+
125
+ it 'is true' do
126
+ expect(one).to be == two
127
+ end
128
+ end
129
+
130
+ context 'first is greater' do
131
+ let(:one) { described_class.new(clusterTime: BSON::Timestamp.new(124, 456)) }
132
+ let(:two) { described_class.new(clusterTime: BSON::Timestamp.new(123, 456)) }
133
+
134
+ it 'is false' do
135
+ expect(one).not_to be == two
136
+ end
137
+ end
138
+
139
+ context 'second is greater' do
140
+ let(:one) { described_class.new(clusterTime: BSON::Timestamp.new(123, 456)) }
141
+ let(:two) { described_class.new(clusterTime: BSON::Timestamp.new(123, 457)) }
142
+
143
+ it 'is false' do
144
+ expect(one).not_to be == two
145
+ end
146
+ end
147
+ end
148
+ end