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
@@ -28,17 +28,27 @@ describe Mongo::Cursor do
28
28
  end
29
29
 
30
30
  context 'cursor exhausted by initial result' do
31
+ before do
32
+ ClientRegistry.instance.close_all_clients
33
+ end
34
+
31
35
  let(:view) do
32
36
  Mongo::Collection::View.new(authorized_collection)
33
37
  end
34
38
 
35
39
  it 'does not schedule the finalizer' do
36
- expect(ObjectSpace).not_to receive(:define_finalizer)
37
- cursor
40
+ # Due to https://jira.mongodb.org/browse/RUBY-1772, restrict
41
+ # the scope of the assertion
42
+ RSpec::Mocks.with_temporary_scope do
43
+ expect(ObjectSpace).not_to receive(:define_finalizer)
44
+ cursor
45
+ end
38
46
  end
39
47
  end
40
48
 
41
49
  context 'cursor not exhausted by initial result' do
50
+ clean_slate
51
+
42
52
  let(:view) do
43
53
  Mongo::Collection::View.new(authorized_collection, {}, batch_size: 2)
44
54
  end
@@ -273,7 +283,7 @@ describe Mongo::Cursor do
273
283
  context 'when the cursor is not fully iterated and is garbage collected' do
274
284
 
275
285
  let(:documents) do
276
- (1..3).map{ |i| { field: "test#{i}" }}
286
+ (1..6).map{ |i| { field: "test#{i}" }}
277
287
  end
278
288
 
279
289
  let(:cluster) do
@@ -304,14 +314,42 @@ describe Mongo::Cursor do
304
314
  cluster.instance_variable_get(:@periodic_executor).flush
305
315
  expect {
306
316
  cursor.to_a
307
- }.to raise_exception(Mongo::Error::OperationFailure)
317
+ }.to raise_exception(Mongo::Error::OperationFailure, /[cC]ursor.*not found/)
308
318
  end
309
319
 
310
320
  context 'when the cursor is unregistered before the kill cursors operations are executed' do
311
321
 
312
322
  it 'does not send a kill cursors operation for the unregistered cursor' do
323
+ # We need to verify that the cursor was able to retrieve more documents
324
+ # from the server so that more than one batch is successfully received
325
+
313
326
  cluster.unregister_cursor(cursor.id)
314
- expect(cursor.to_a.size).to eq(documents.size)
327
+
328
+ # The initial read is done on an enum obtained from the cursor.
329
+ # The read below is done directly on the cursor. These are two
330
+ # different objects. In MRI, iterating like this yields all of the
331
+ # documents, hence we retrieved one document in the setup and
332
+ # we expect to retrieve the remaining 5 here. In JRuby it appears that
333
+ # the enum may buffers the first batch, such that the second document
334
+ # sometimes is lost to the iteration and we retrieve 4 documents below.
335
+ # But sometimes we get all 5 documents. In either case, all of the
336
+ # documents are retrieved via two batches thus fulfilling the
337
+ # requirement of the test to continue iterating the cursor.
338
+
339
+ =begin When repeated iteration of cursors is prohibited, these are the expectations
340
+ if BSON::Environment.jruby?
341
+ expected_counts = [4, 5]
342
+ else
343
+ expected_counts = [5]
344
+ end
345
+ =end
346
+
347
+ # Since currently repeated iteration of cursors is allowed, calling
348
+ # to_a on the cursor would perform such an iteration and return
349
+ # all documents of the initial read.
350
+ expected_counts = [6]
351
+
352
+ expect(expected_counts).to include(cursor.to_a.size)
315
353
  end
316
354
  end
317
355
  end
@@ -460,4 +498,78 @@ describe Mongo::Cursor do
460
498
  expect(cursor.inspect).to match(/.*#{view.inspect}.*/)
461
499
  end
462
500
  end
501
+
502
+ describe '#to_a' do
503
+
504
+ let(:view) do
505
+ Mongo::Collection::View.new(authorized_collection, {}, batch_size: 10)
506
+ end
507
+
508
+ let(:query_spec) do
509
+ { :selector => {}, :options => {}, :db_name => SpecConfig.instance.test_db,
510
+ :coll_name => authorized_collection.name }
511
+ end
512
+
513
+ let(:reply) do
514
+ view.send(:send_initial_query, authorized_primary)
515
+ end
516
+
517
+ let(:cursor) do
518
+ described_class.new(view, reply, authorized_primary)
519
+ end
520
+
521
+ context 'after partially iterating the cursor' do
522
+ before do
523
+ authorized_collection.drop
524
+ docs = []
525
+ 100.times do |i|
526
+ docs << {a: i}
527
+ end
528
+ authorized_collection.insert_many(docs)
529
+ end
530
+
531
+ context 'after #each was called once' do
532
+ before do
533
+ cursor.each do |doc|
534
+ break
535
+ end
536
+ end
537
+
538
+ it 'iterates from the beginning of the view' do
539
+ expect(cursor.to_a.map { |doc| doc['a'] }).to eq((0..99).to_a)
540
+ end
541
+ end
542
+
543
+ context 'after exactly one batch was iterated' do
544
+ before do
545
+ cursor.each_with_index do |doc, i|
546
+ break if i == 9
547
+ end
548
+ end
549
+
550
+ it 'iterates from the beginning of the view' do
551
+ expect(cursor.to_a.map { |doc| doc['a'] }).to eq((0..99).to_a)
552
+ end
553
+ end
554
+
555
+ context 'after two batches were iterated' do
556
+ before do
557
+ cursor.each_with_index do |doc, i|
558
+ break if i == 19
559
+ end
560
+ end
561
+
562
+ =begin Behavior of pre-2.10 driver:
563
+ it 'skips the second batch' do
564
+ expect(cursor.to_a.map { |doc| doc['a'] }).to eq((0..9).to_a + (20..99).to_a)
565
+ end
566
+ =end
567
+ it 'raises NotImplementedError' do
568
+ expect do
569
+ cursor.to_a
570
+ end.to raise_error(NotImplementedError, 'Cannot restart iteration of a cursor which issued a getMore')
571
+ end
572
+ end
573
+ end
574
+ end
463
575
  end
@@ -96,12 +96,25 @@ describe Mongo::Database do
96
96
  database[:users].create
97
97
  end
98
98
 
99
+ let(:actual) do
100
+ database.collection_names
101
+ end
102
+
99
103
  it 'returns the stripped names of the collections' do
100
- expect(database.collection_names).to include('users')
104
+ expect(actual).to include('users')
101
105
  end
102
106
 
103
107
  it 'does not include system collections' do
104
- expect(database.collection_names).to_not include('system.indexes')
108
+ expect(actual).to_not include('version')
109
+ expect(actual).to_not include('system.version')
110
+ end
111
+
112
+ context 'on 2.6 server' do
113
+ max_server_version '2.6'
114
+ end
115
+
116
+ it 'does not include collections with $ in names' do
117
+ expect(actual.none? { |name| name.include?('$') }).to be true
105
118
  end
106
119
 
107
120
  context 'when provided a session' do
@@ -136,7 +149,9 @@ describe Mongo::Database do
136
149
  end
137
150
 
138
151
  it 'returns all collections' do
139
- expect(database.collection_names(batch_size: 1).select { |c| c =~ /dalmatians/}.size).to eq(2)
152
+ collection_names = database.collection_names(batch_size: 1)
153
+ expect(collection_names).to include('0_dalmatians')
154
+ expect(collection_names).to include('1_dalmatians')
140
155
  end
141
156
 
142
157
  end
@@ -155,15 +170,15 @@ describe Mongo::Database do
155
170
  end
156
171
 
157
172
  before do
158
- database[:users].drop
159
- database[:users].create
173
+ database[:acol].drop
174
+ database[:acol].create
160
175
  end
161
176
 
162
177
  context 'server 3.0+' do
163
178
  min_server_fcv '3.0'
164
179
 
165
180
  it 'returns a list of the collections info' do
166
- expect(result).to include('users')
181
+ expect(result).to include('acol')
167
182
  end
168
183
  end
169
184
 
@@ -171,7 +186,37 @@ describe Mongo::Database do
171
186
  max_server_fcv '2.6'
172
187
 
173
188
  it 'returns a list of the collections info' do
174
- expect(result).to include("#{SpecConfig.instance.test_db}.users")
189
+ expect(result).to include("#{SpecConfig.instance.test_db}.acol")
190
+ end
191
+ end
192
+
193
+ it 'does not include collections with $ in names' do
194
+ expect(result.none? { |name| name.include?('$') }).to be true
195
+ end
196
+
197
+ context 'on admin database' do
198
+ let(:database) do
199
+ described_class.new(root_authorized_client, 'admin')
200
+ end
201
+
202
+ it 'does not include system collections' do
203
+ expect(result.none? { |name| name =~ /(^|\.)system\./ }).to be true
204
+ end
205
+
206
+ context 'server 3.0+' do
207
+ min_server_fcv '3.0'
208
+
209
+ it 'returns results' do
210
+ expect(result).to include('acol')
211
+ end
212
+ end
213
+
214
+ context 'server 2.6-' do
215
+ max_server_version '2.6'
216
+
217
+ it 'returns results' do
218
+ expect(result).to include('admin.acol')
219
+ end
175
220
  end
176
221
  end
177
222
  end
@@ -197,8 +242,21 @@ describe Mongo::Database do
197
242
  expect(database.collections).to include(collection)
198
243
  end
199
244
 
245
+ it 'does not include collections with $ in names' do
246
+ expect(database.collections.none? { |c| c.name.include?('$') }).to be true
247
+ end
248
+ end
249
+
250
+ context 'on admin database' do
251
+
252
+ let(:database) do
253
+ described_class.new(root_authorized_client, 'admin')
254
+ end
255
+
200
256
  it 'does not include the system collections' do
201
- expect(database.collections.collect(&:name).none? { |name| name =~ /system\.|\$/ }).to be(true)
257
+ collection_names = database.collections.map(&:name)
258
+ expect(collection_names).not_to include('system.version')
259
+ expect(collection_names.none? { |name| name =~ /(^|\.)system\./ }).to be true
202
260
  end
203
261
  end
204
262
 
@@ -631,4 +689,178 @@ describe Mongo::Database do
631
689
  end
632
690
  end
633
691
  end
692
+
693
+ describe '#write_concern' do
694
+
695
+ let(:client) do
696
+ new_local_client(['127.0.0.1:27017'],
697
+ {monitoring_io: false}.merge(client_options))
698
+ end
699
+
700
+ let(:database) { client.database }
701
+
702
+ context 'when client write concern uses :write' do
703
+
704
+ let(:client_options) do
705
+ { :write => { :w => 1 } }
706
+ end
707
+
708
+ it 'is the correct write concern' do
709
+ expect(database.write_concern).to be_a(Mongo::WriteConcern::Acknowledged)
710
+ expect(database.write_concern.options).to eq(w: 1)
711
+ end
712
+ end
713
+
714
+ context 'when client write concern uses :write_concern' do
715
+
716
+ let(:client_options) do
717
+ { :write_concern => { :w => 1 } }
718
+ end
719
+
720
+ it 'is the correct write concern' do
721
+ expect(database.write_concern).to be_a(Mongo::WriteConcern::Acknowledged)
722
+ expect(database.write_concern.options).to eq(w: 1)
723
+ end
724
+ end
725
+ end
726
+
727
+ describe '#aggregate' do
728
+ min_server_fcv '3.6'
729
+
730
+ let(:client) do
731
+ root_authorized_admin_client
732
+ end
733
+
734
+ let(:database) { client.database }
735
+
736
+ let(:pipeline) do
737
+ [{'$currentOp' => {}}]
738
+ end
739
+
740
+ describe 'updating cluster time' do
741
+ # The shared examples use their own client which we cannot override
742
+ # from here, and it uses the wrong credentials for admin database which
743
+ # is the one we need for our pipeline when auth is on.
744
+ require_no_auth
745
+
746
+ let(:database_via_client) do
747
+ client.use(:admin).database
748
+ end
749
+
750
+ let(:operation) do
751
+ database_via_client.aggregate(pipeline).first
752
+ end
753
+
754
+ let(:operation_with_session) do
755
+ database_via_client.aggregate(pipeline, session: session).first
756
+ end
757
+
758
+ let(:second_operation) do
759
+ database_via_client.aggregate(pipeline, session: session).first
760
+ end
761
+
762
+ it_behaves_like 'an operation updating cluster time'
763
+ end
764
+
765
+ it 'returns an Aggregation object' do
766
+ expect(database.aggregate(pipeline)).to be_a(Mongo::Collection::View::Aggregation)
767
+ end
768
+
769
+ context 'when options are provided' do
770
+
771
+ let(:options) do
772
+ { :allow_disk_use => true, :bypass_document_validation => true }
773
+ end
774
+
775
+ it 'sets the options on the Aggregation object' do
776
+ expect(database.aggregate(pipeline, options).options).to eq(BSON::Document.new(options))
777
+ end
778
+
779
+ context 'when the :comment option is provided' do
780
+
781
+ let(:options) do
782
+ { :comment => 'testing' }
783
+ end
784
+
785
+ it 'sets the options on the Aggregation object' do
786
+ expect(database.aggregate(pipeline, options).options).to eq(BSON::Document.new(options))
787
+ end
788
+ end
789
+
790
+ context 'when a session is provided' do
791
+
792
+ let(:session) do
793
+ client.start_session
794
+ end
795
+
796
+ let(:operation) do
797
+ database.aggregate(pipeline, session: session).to_a
798
+ end
799
+
800
+ let(:failed_operation) do
801
+ database.aggregate([ { '$invalid' => 1 }], session: session).to_a
802
+ end
803
+
804
+ it_behaves_like 'an operation using a session'
805
+ it_behaves_like 'a failed operation using a session'
806
+ end
807
+
808
+ context 'when a hint is provided' do
809
+
810
+ let(:options) do
811
+ { 'hint' => { 'y' => 1 } }
812
+ end
813
+
814
+ it 'sets the options on the Aggregation object' do
815
+ expect(database.aggregate(pipeline, options).options).to eq(options)
816
+ end
817
+ end
818
+
819
+ context 'when collation is provided' do
820
+
821
+ let(:pipeline) do
822
+ [{ "$currentOp" => {} }]
823
+ end
824
+
825
+ let(:options) do
826
+ { collation: { locale: 'en_US', strength: 2 } }
827
+ end
828
+
829
+ let(:result) do
830
+ database.aggregate(pipeline, options).collect { |doc| doc.keys.grep(/host/).first }
831
+ end
832
+
833
+ context 'when the server selected supports collations' do
834
+ min_server_fcv '3.4'
835
+
836
+ it 'applies the collation' do
837
+ expect(result.uniq).to eq(['host'])
838
+ end
839
+ end
840
+
841
+ context 'when the server selected does not support collations' do
842
+ max_server_version '3.2'
843
+
844
+ it 'raises an exception' do
845
+ expect {
846
+ result
847
+ }.to raise_exception(Mongo::Error::UnsupportedCollation)
848
+ end
849
+
850
+ context 'when a String key is used' do
851
+
852
+ let(:options) do
853
+ { 'collation' => { locale: 'en_US', strength: 2 } }
854
+ end
855
+
856
+ it 'raises an exception' do
857
+ expect {
858
+ result
859
+ }.to raise_exception(Mongo::Error::UnsupportedCollation)
860
+ end
861
+ end
862
+ end
863
+ end
864
+ end
865
+ end
634
866
  end