mongo 2.20.1 → 2.21.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (246) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -0
  3. data/Rakefile +2 -2
  4. data/lib/mongo/address.rb +22 -3
  5. data/lib/mongo/auth/aws/credentials_retriever.rb +70 -17
  6. data/lib/mongo/auth/base.rb +1 -1
  7. data/lib/mongo/bulk_write.rb +35 -2
  8. data/lib/mongo/client.rb +38 -6
  9. data/lib/mongo/client_encryption.rb +6 -3
  10. data/lib/mongo/cluster/reapers/cursor_reaper.rb +6 -1
  11. data/lib/mongo/cluster/sdam_flow.rb +20 -7
  12. data/lib/mongo/cluster.rb +14 -4
  13. data/lib/mongo/collection/helpers.rb +1 -1
  14. data/lib/mongo/collection/view/aggregation/behavior.rb +131 -0
  15. data/lib/mongo/collection/view/aggregation.rb +33 -99
  16. data/lib/mongo/collection/view/builder/aggregation.rb +1 -7
  17. data/lib/mongo/collection/view/change_stream.rb +80 -27
  18. data/lib/mongo/collection/view/iterable.rb +76 -60
  19. data/lib/mongo/collection/view/map_reduce.rb +25 -8
  20. data/lib/mongo/collection/view/readable.rb +79 -30
  21. data/lib/mongo/collection/view/writable.rb +109 -48
  22. data/lib/mongo/collection/view.rb +43 -3
  23. data/lib/mongo/collection.rb +158 -23
  24. data/lib/mongo/crypt/auto_encrypter.rb +4 -6
  25. data/lib/mongo/crypt/binding.rb +4 -4
  26. data/lib/mongo/crypt/context.rb +20 -14
  27. data/lib/mongo/crypt/encryption_io.rb +56 -26
  28. data/lib/mongo/crypt/explicit_encrypter.rb +49 -20
  29. data/lib/mongo/crypt/explicit_encryption_context.rb +17 -11
  30. data/lib/mongo/crypt/kms/azure/credentials_retriever.rb +22 -6
  31. data/lib/mongo/crypt/kms/gcp/credentials_retriever.rb +29 -4
  32. data/lib/mongo/csot_timeout_holder.rb +119 -0
  33. data/lib/mongo/cursor/kill_spec.rb +5 -2
  34. data/lib/mongo/cursor/nontailable.rb +27 -0
  35. data/lib/mongo/cursor.rb +86 -24
  36. data/lib/mongo/cursor_host.rb +82 -0
  37. data/lib/mongo/database/view.rb +81 -14
  38. data/lib/mongo/database.rb +88 -18
  39. data/lib/mongo/error/operation_failure.rb +209 -204
  40. data/lib/mongo/error/server_timeout_error.rb +12 -0
  41. data/lib/mongo/error/socket_timeout_error.rb +3 -1
  42. data/lib/mongo/error/timeout_error.rb +23 -0
  43. data/lib/mongo/error.rb +2 -0
  44. data/lib/mongo/grid/fs_bucket.rb +45 -12
  45. data/lib/mongo/grid/stream/read.rb +15 -1
  46. data/lib/mongo/grid/stream/write.rb +21 -4
  47. data/lib/mongo/index/view.rb +77 -16
  48. data/lib/mongo/operation/context.rb +40 -2
  49. data/lib/mongo/operation/create_search_indexes/op_msg.rb +2 -2
  50. data/lib/mongo/operation/delete/op_msg.rb +2 -1
  51. data/lib/mongo/operation/drop_search_index/op_msg.rb +2 -2
  52. data/lib/mongo/operation/find/op_msg.rb +45 -0
  53. data/lib/mongo/operation/get_more/op_msg.rb +33 -0
  54. data/lib/mongo/operation/insert/op_msg.rb +3 -2
  55. data/lib/mongo/operation/insert/result.rb +4 -2
  56. data/lib/mongo/operation/list_collections/result.rb +1 -1
  57. data/lib/mongo/operation/map_reduce/result.rb +1 -1
  58. data/lib/mongo/operation/op_msg_base.rb +3 -1
  59. data/lib/mongo/operation/result.rb +26 -5
  60. data/lib/mongo/operation/shared/executable.rb +12 -1
  61. data/lib/mongo/operation/shared/op_msg_executable.rb +4 -1
  62. data/lib/mongo/operation/shared/response_handling.rb +3 -3
  63. data/lib/mongo/operation/shared/sessions_supported.rb +1 -1
  64. data/lib/mongo/operation/shared/timed.rb +52 -0
  65. data/lib/mongo/operation/shared/write.rb +4 -1
  66. data/lib/mongo/operation/update/op_msg.rb +2 -1
  67. data/lib/mongo/operation/update_search_index/op_msg.rb +2 -2
  68. data/lib/mongo/operation.rb +1 -0
  69. data/lib/mongo/protocol/message.rb +1 -4
  70. data/lib/mongo/protocol/msg.rb +2 -2
  71. data/lib/mongo/retryable/read_worker.rb +69 -29
  72. data/lib/mongo/retryable/write_worker.rb +49 -18
  73. data/lib/mongo/retryable.rb +8 -2
  74. data/lib/mongo/server/connection.rb +11 -5
  75. data/lib/mongo/server/connection_base.rb +22 -2
  76. data/lib/mongo/server/connection_pool.rb +32 -14
  77. data/lib/mongo/server/description/features.rb +1 -1
  78. data/lib/mongo/server/description.rb +18 -5
  79. data/lib/mongo/server/monitor.rb +7 -4
  80. data/lib/mongo/server/pending_connection.rb +7 -3
  81. data/lib/mongo/server/{round_trip_time_averager.rb → round_trip_time_calculator.rb} +25 -7
  82. data/lib/mongo/server.rb +11 -6
  83. data/lib/mongo/server_selector/base.rb +25 -9
  84. data/lib/mongo/session.rb +78 -9
  85. data/lib/mongo/socket/ssl.rb +109 -17
  86. data/lib/mongo/socket/tcp.rb +40 -6
  87. data/lib/mongo/socket.rb +154 -25
  88. data/lib/mongo/uri/options_mapper.rb +1 -0
  89. data/lib/mongo/version.rb +1 -1
  90. data/lib/mongo.rb +1 -0
  91. data/spec/atlas/atlas_connectivity_spec.rb +4 -0
  92. data/spec/atlas/operations_spec.rb +4 -0
  93. data/spec/integration/client_side_encryption/auto_encryption_mongocryptd_spawn_spec.rb +2 -1
  94. data/spec/integration/client_side_encryption/auto_encryption_spec.rb +494 -487
  95. data/spec/integration/client_side_encryption/on_demand_aws_credentials_spec.rb +1 -1
  96. data/spec/integration/client_side_encryption/range_explicit_encryption_prose_spec.rb +66 -22
  97. data/spec/integration/client_side_operations_timeout/encryption_prose_spec.rb +131 -0
  98. data/spec/integration/connection_pool_populator_spec.rb +2 -0
  99. data/spec/integration/cursor_pinning_spec.rb +15 -60
  100. data/spec/integration/cursor_reaping_spec.rb +1 -1
  101. data/spec/integration/docs_examples_spec.rb +1 -1
  102. data/spec/integration/operation_failure_code_spec.rb +1 -1
  103. data/spec/integration/operation_failure_message_spec.rb +3 -3
  104. data/spec/integration/retryable_errors_spec.rb +2 -2
  105. data/spec/integration/sdam_error_handling_spec.rb +2 -1
  106. data/spec/integration/search_indexes_prose_spec.rb +4 -0
  107. data/spec/integration/server_spec.rb +4 -3
  108. data/spec/integration/transactions_api_examples_spec.rb +2 -0
  109. data/spec/kerberos/kerberos_spec.rb +4 -0
  110. data/spec/lite_spec_helper.rb +3 -1
  111. data/spec/mongo/auth/user/view_spec.rb +1 -1
  112. data/spec/mongo/caching_cursor_spec.rb +1 -1
  113. data/spec/mongo/client_encryption_spec.rb +1 -0
  114. data/spec/mongo/client_spec.rb +158 -4
  115. data/spec/mongo/collection/view/aggregation_spec.rb +14 -39
  116. data/spec/mongo/collection/view/change_stream_spec.rb +3 -3
  117. data/spec/mongo/collection_spec.rb +5 -6
  118. data/spec/mongo/crypt/auto_encrypter_spec.rb +14 -12
  119. data/spec/mongo/crypt/data_key_context_spec.rb +3 -1
  120. data/spec/mongo/crypt/explicit_encryption_context_spec.rb +2 -2
  121. data/spec/mongo/crypt/handle_spec.rb +1 -1
  122. data/spec/mongo/cursor_spec.rb +26 -9
  123. data/spec/mongo/error/operation_failure_heavy_spec.rb +2 -2
  124. data/spec/mongo/operation/context_spec.rb +79 -0
  125. data/spec/mongo/operation/create/op_msg_spec.rb +106 -110
  126. data/spec/mongo/operation/delete/op_msg_spec.rb +6 -5
  127. data/spec/mongo/operation/find/op_msg_spec.rb +66 -0
  128. data/spec/mongo/operation/get_more/op_msg_spec.rb +65 -0
  129. data/spec/mongo/operation/insert/op_msg_spec.rb +128 -131
  130. data/spec/mongo/operation/shared/csot/examples.rb +113 -0
  131. data/spec/mongo/query_cache_spec.rb +243 -225
  132. data/spec/mongo/retryable_spec.rb +1 -0
  133. data/spec/mongo/server/round_trip_time_calculator_spec.rb +120 -0
  134. data/spec/mongo/socket/ssl_spec.rb +0 -10
  135. data/spec/runners/change_streams/test.rb +2 -2
  136. data/spec/runners/crud/operation.rb +1 -1
  137. data/spec/runners/crud/verifier.rb +3 -1
  138. data/spec/runners/transactions/operation.rb +4 -6
  139. data/spec/runners/unified/ambiguous_operations.rb +13 -0
  140. data/spec/runners/unified/assertions.rb +4 -0
  141. data/spec/runners/unified/change_stream_operations.rb +14 -24
  142. data/spec/runners/unified/crud_operations.rb +82 -59
  143. data/spec/runners/unified/ddl_operations.rb +38 -7
  144. data/spec/runners/unified/grid_fs_operations.rb +37 -2
  145. data/spec/runners/unified/support_operations.rb +43 -4
  146. data/spec/runners/unified/test.rb +22 -10
  147. data/spec/runners/unified.rb +1 -1
  148. data/spec/solo/clean_exit_spec.rb +2 -0
  149. data/spec/spec_tests/client_side_operations_timeout_spec.rb +15 -0
  150. data/spec/spec_tests/data/change_streams_unified/change-streams-clusterTime.yml +3 -1
  151. data/spec/spec_tests/data/change_streams_unified/change-streams-disambiguatedPaths.yml +3 -1
  152. data/spec/spec_tests/data/change_streams_unified/change-streams-errors.yml +3 -1
  153. data/spec/spec_tests/data/change_streams_unified/change-streams-pre_and_post_images.yml +1 -1
  154. data/spec/spec_tests/data/change_streams_unified/change-streams-resume-allowlist.yml +1 -1
  155. data/spec/spec_tests/data/change_streams_unified/change-streams-resume-errorLabels.yml +1 -1
  156. data/spec/spec_tests/data/change_streams_unified/change-streams-showExpandedEvents.yml +1 -1
  157. data/spec/spec_tests/data/client_side_encryption/badQueries.yml +2 -1
  158. data/spec/spec_tests/data/client_side_encryption/timeoutMS.yml +67 -0
  159. data/spec/spec_tests/data/client_side_operations_timeout/bulkWrite.yml +87 -0
  160. data/spec/spec_tests/data/client_side_operations_timeout/change-streams.yml +358 -0
  161. data/spec/spec_tests/data/client_side_operations_timeout/close-cursors.yml +129 -0
  162. data/spec/spec_tests/data/client_side_operations_timeout/command-execution.yml +250 -0
  163. data/spec/spec_tests/data/client_side_operations_timeout/convenient-transactions.yml +113 -0
  164. data/spec/spec_tests/data/client_side_operations_timeout/cursors.yml +70 -0
  165. data/spec/spec_tests/data/client_side_operations_timeout/deprecated-options.yml +3982 -0
  166. data/spec/spec_tests/data/client_side_operations_timeout/error-transformations.yml +96 -0
  167. data/spec/spec_tests/data/client_side_operations_timeout/global-timeoutMS.yml +3236 -0
  168. data/spec/spec_tests/data/client_side_operations_timeout/gridfs-advanced.yml +207 -0
  169. data/spec/spec_tests/data/client_side_operations_timeout/gridfs-delete.yml +152 -0
  170. data/spec/spec_tests/data/client_side_operations_timeout/gridfs-download.yml +182 -0
  171. data/spec/spec_tests/data/client_side_operations_timeout/gridfs-find.yml +100 -0
  172. data/spec/spec_tests/data/client_side_operations_timeout/gridfs-upload.yml +249 -0
  173. data/spec/spec_tests/data/client_side_operations_timeout/legacy-timeouts.yml +204 -0
  174. data/spec/spec_tests/data/client_side_operations_timeout/non-tailable-cursors.yml +307 -0
  175. data/spec/spec_tests/data/client_side_operations_timeout/override-collection-timeoutMS.yml +1877 -0
  176. data/spec/spec_tests/data/client_side_operations_timeout/override-operation-timeoutMS.yml +1918 -0
  177. data/spec/spec_tests/data/client_side_operations_timeout/retryability-legacy-timeouts.yml +1676 -0
  178. data/spec/spec_tests/data/client_side_operations_timeout/retryability-timeoutMS.yml +2824 -0
  179. data/spec/spec_tests/data/client_side_operations_timeout/sessions-inherit-timeoutMS.yml +168 -0
  180. data/spec/spec_tests/data/client_side_operations_timeout/sessions-override-operation-timeoutMS.yml +171 -0
  181. data/spec/spec_tests/data/client_side_operations_timeout/sessions-override-timeoutMS.yml +168 -0
  182. data/spec/spec_tests/data/client_side_operations_timeout/tailable-awaitData.yml +247 -0
  183. data/spec/spec_tests/data/client_side_operations_timeout/tailable-non-awaitData.yml +181 -0
  184. data/spec/spec_tests/data/crud_unified/aggregate-write-readPreference.yml +4 -0
  185. data/spec/spec_tests/data/crud_unified/db-aggregate-write-readPreference.yml +4 -0
  186. data/spec/spec_tests/data/crud_unified/find-test-all-options.yml +29 -0
  187. data/spec/spec_tests/server_selection_rtt_spec.rb +6 -6
  188. data/spec/support/certificates/atlas-ocsp-ca.crt +81 -83
  189. data/spec/support/certificates/atlas-ocsp.crt +107 -107
  190. data/spec/support/cluster_tools.rb +3 -3
  191. data/spec/support/common_shortcuts.rb +2 -2
  192. data/spec/support/crypt/encrypted_fields/range-encryptedFields-Date.json +1 -1
  193. data/spec/support/crypt/encrypted_fields/range-encryptedFields-DecimalNoPrecision.json +1 -1
  194. data/spec/support/crypt/encrypted_fields/range-encryptedFields-DecimalPrecision.json +1 -1
  195. data/spec/support/crypt/encrypted_fields/range-encryptedFields-DoubleNoPrecision.json +1 -1
  196. data/spec/support/crypt/encrypted_fields/range-encryptedFields-DoublePrecision.json +1 -1
  197. data/spec/support/crypt/encrypted_fields/range-encryptedFields-Int.json +1 -1
  198. data/spec/support/crypt/encrypted_fields/range-encryptedFields-Long.json +1 -1
  199. data/spec/support/shared/session.rb +2 -2
  200. data/spec/support/spec_setup.rb +2 -2
  201. data/spec/support/utils.rb +3 -1
  202. metadata +78 -91
  203. data/spec/mongo/server/round_trip_time_averager_spec.rb +0 -48
  204. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Aggregate.yml +0 -242
  205. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Correctness.yml +0 -423
  206. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Delete.yml +0 -183
  207. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-FindOneAndUpdate.yml +0 -240
  208. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-InsertFind.yml +0 -236
  209. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Update.yml +0 -253
  210. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Aggregate.yml +0 -1688
  211. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Correctness.yml +0 -294
  212. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Delete.yml +0 -906
  213. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-FindOneAndUpdate.yml +0 -1685
  214. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-InsertFind.yml +0 -1681
  215. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Update.yml +0 -1698
  216. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Aggregate.yml +0 -330
  217. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Correctness.yml +0 -425
  218. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Delete.yml +0 -227
  219. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-FindOneAndUpdate.yml +0 -328
  220. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-InsertFind.yml +0 -320
  221. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Update.yml +0 -337
  222. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Aggregate.yml +0 -914
  223. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Correctness.yml +0 -293
  224. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Delete.yml +0 -519
  225. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-FindOneAndUpdate.yml +0 -912
  226. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-InsertFind.yml +0 -908
  227. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Update.yml +0 -925
  228. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Aggregate.yml +0 -326
  229. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Correctness.yml +0 -425
  230. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Delete.yml +0 -225
  231. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-FindOneAndUpdate.yml +0 -324
  232. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-InsertFind.yml +0 -320
  233. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Update.yml +0 -339
  234. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Aggregate.yml +0 -242
  235. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Correctness.yml +0 -424
  236. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Delete.yml +0 -183
  237. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-FindOneAndUpdate.yml +0 -240
  238. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-InsertFind.yml +0 -236
  239. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Update.yml +0 -255
  240. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Aggregate.yml +0 -242
  241. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Correctness.yml +0 -423
  242. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Delete.yml +0 -183
  243. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-FindOneAndUpdate.yml +0 -240
  244. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-InsertFind.yml +0 -236
  245. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Update.yml +0 -255
  246. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-WrongType.yml +0 -44
@@ -37,7 +37,7 @@ describe 'On-demand AWS Credentials' do
37
37
  it 'raises an error' do
38
38
  expect_any_instance_of(
39
39
  Mongo::Auth::Aws::CredentialsRetriever
40
- ).to receive(:credentials).with(no_args).once.and_raise(
40
+ ).to receive(:credentials).with(kind_of(Mongo::CsotTimeoutHolder)).once.and_raise(
41
41
  Mongo::Auth::Aws::CredentialsNotFound
42
42
  )
43
43
 
@@ -6,9 +6,7 @@ require 'spec_helper'
6
6
  # be revisited if these tests ever need to be significantly modified.
7
7
  # rubocop:disable RSpec/ExampleLength
8
8
  describe 'Range Explicit Encryption' do
9
- min_server_version '7.0.0-rc0'
10
- # https://jira.mongodb.org/browse/RUBY-3457
11
- max_server_version '7.99.99'
9
+ min_server_version '8.0.0-rc18'
12
10
 
13
11
  require_libmongocrypt
14
12
  include_context 'define shared FLE helpers'
@@ -56,7 +54,7 @@ describe 'Range Explicit Encryption' do
56
54
  value,
57
55
  {
58
56
  key_id: key1_id,
59
- algorithm: 'RangePreview',
57
+ algorithm: 'Range',
60
58
  contention_factor: 0,
61
59
  range_opts: range_opts
62
60
  }
@@ -76,8 +74,8 @@ describe 'Range Explicit Encryption' do
76
74
  expr,
77
75
  {
78
76
  key_id: key1_id,
79
- algorithm: 'RangePreview',
80
- query_type: 'rangePreview',
77
+ algorithm: 'Range',
78
+ query_type: 'range',
81
79
  contention_factor: 0,
82
80
  range_opts: range_opts
83
81
  }
@@ -100,8 +98,8 @@ describe 'Range Explicit Encryption' do
100
98
  expr,
101
99
  {
102
100
  key_id: key1_id,
103
- algorithm: 'RangePreview',
104
- query_type: 'rangePreview',
101
+ algorithm: 'Range',
102
+ query_type: 'range',
105
103
  contention_factor: 0,
106
104
  range_opts: range_opts
107
105
  }
@@ -123,8 +121,8 @@ describe 'Range Explicit Encryption' do
123
121
  expr,
124
122
  {
125
123
  key_id: key1_id,
126
- algorithm: 'RangePreview',
127
- query_type: 'rangePreview',
124
+ algorithm: 'Range',
125
+ query_type: 'range',
128
126
  contention_factor: 0,
129
127
  range_opts: range_opts
130
128
  }
@@ -140,8 +138,8 @@ describe 'Range Explicit Encryption' do
140
138
  expr,
141
139
  {
142
140
  key_id: key1_id,
143
- algorithm: 'RangePreview',
144
- query_type: 'rangePreview',
141
+ algorithm: 'Range',
142
+ query_type: 'range',
145
143
  contention_factor: 0,
146
144
  range_opts: range_opts
147
145
  }
@@ -163,7 +161,7 @@ describe 'Range Explicit Encryption' do
163
161
  value_converter.call(201),
164
162
  {
165
163
  key_id: key1_id,
166
- algorithm: 'RangePreview',
164
+ algorithm: 'Range',
167
165
  contention_factor: 0,
168
166
  range_opts: range_opts
169
167
  }
@@ -183,7 +181,7 @@ describe 'Range Explicit Encryption' do
183
181
  value,
184
182
  {
185
183
  key_id: key1_id,
186
- algorithm: 'RangePreview',
184
+ algorithm: 'Range',
187
185
  contention_factor: 0,
188
186
  range_opts: range_opts
189
187
  }
@@ -198,7 +196,7 @@ describe 'Range Explicit Encryption' do
198
196
  value_converter.call(6),
199
197
  {
200
198
  key_id: key1_id,
201
- algorithm: 'RangePreview',
199
+ algorithm: 'Range',
202
200
  contention_factor: 0,
203
201
  range_opts: {
204
202
  min: value_converter.call(0),
@@ -244,7 +242,7 @@ describe 'Range Explicit Encryption' do
244
242
  insert_payload = client_encryption.encrypt(
245
243
  num,
246
244
  key_id: key1_id,
247
- algorithm: 'RangePreview',
245
+ algorithm: 'Range',
248
246
  contention_factor: 0,
249
247
  range_opts: range_opts
250
248
  )
@@ -290,7 +288,7 @@ describe 'Range Explicit Encryption' do
290
288
  insert_payload = client_encryption.encrypt(
291
289
  BSON::Int64.new(num),
292
290
  key_id: key1_id,
293
- algorithm: 'RangePreview',
291
+ algorithm: 'Range',
294
292
  contention_factor: 0,
295
293
  range_opts: range_opts
296
294
  )
@@ -337,7 +335,7 @@ describe 'Range Explicit Encryption' do
337
335
  insert_payload = client_encryption.encrypt(
338
336
  num,
339
337
  key_id: key1_id,
340
- algorithm: 'RangePreview',
338
+ algorithm: 'Range',
341
339
  contention_factor: 0,
342
340
  range_opts: range_opts
343
341
  )
@@ -381,7 +379,7 @@ describe 'Range Explicit Encryption' do
381
379
  insert_payload = client_encryption.encrypt(
382
380
  num,
383
381
  key_id: key1_id,
384
- algorithm: 'RangePreview',
382
+ algorithm: 'Range',
385
383
  contention_factor: 0,
386
384
  range_opts: range_opts
387
385
  )
@@ -427,7 +425,7 @@ describe 'Range Explicit Encryption' do
427
425
  insert_payload = client_encryption.encrypt(
428
426
  Time.new(num),
429
427
  key_id: key1_id,
430
- algorithm: 'RangePreview',
428
+ algorithm: 'Range',
431
429
  contention_factor: 0,
432
430
  range_opts: range_opts
433
431
  )
@@ -476,7 +474,7 @@ describe 'Range Explicit Encryption' do
476
474
  insert_payload = client_encryption.encrypt(
477
475
  BSON::Decimal128.new(num),
478
476
  key_id: key1_id,
479
- algorithm: 'RangePreview',
477
+ algorithm: 'Range',
480
478
  contention_factor: 0,
481
479
  range_opts: range_opts
482
480
  )
@@ -522,7 +520,7 @@ describe 'Range Explicit Encryption' do
522
520
  insert_payload = client_encryption.encrypt(
523
521
  BSON::Decimal128.new(num),
524
522
  key_id: key1_id,
525
- algorithm: 'RangePreview',
523
+ algorithm: 'Range',
526
524
  contention_factor: 0,
527
525
  range_opts: range_opts
528
526
  )
@@ -535,5 +533,51 @@ describe 'Range Explicit Encryption' do
535
533
 
536
534
  include_examples 'common cases'
537
535
  end
536
+
537
+ describe 'Range Explicit Encryption applies defaults' do
538
+ let(:payload_defaults) do
539
+ client_encryption.encrypt(
540
+ 123,
541
+ key_id: key1_id,
542
+ algorithm: 'Range',
543
+ contention_factor: 0,
544
+ range_opts: {
545
+ min: 0,
546
+ max: 1000
547
+ }
548
+ )
549
+ end
550
+
551
+ it 'uses libmongocrypt default' do
552
+ payload = client_encryption.encrypt(
553
+ 123,
554
+ key_id: key1_id,
555
+ algorithm: 'Range',
556
+ contention_factor: 0,
557
+ range_opts: {
558
+ min: 0,
559
+ max: 1000,
560
+ sparsity: 2,
561
+ trim_factor: 6
562
+ }
563
+ )
564
+ expect(payload.to_s.size).to eq(payload_defaults.to_s.size)
565
+ end
566
+
567
+ it 'accepts trim_factor 0' do
568
+ payload = client_encryption.encrypt(
569
+ 123,
570
+ key_id: key1_id,
571
+ algorithm: 'Range',
572
+ contention_factor: 0,
573
+ range_opts: {
574
+ min: 0,
575
+ max: 1000,
576
+ trim_factor: 0
577
+ }
578
+ )
579
+ expect(payload.to_s.size).to eq(payload_defaults.to_s.size)
580
+ end
581
+ end
538
582
  end
539
583
  # rubocop:enable RSpec/ExampleLength
@@ -0,0 +1,131 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'CSOT for encryption' do
6
+ require_libmongocrypt
7
+ require_no_multi_mongos
8
+ min_server_fcv '4.2'
9
+
10
+ include_context 'define shared FLE helpers'
11
+ include_context 'with local kms_providers'
12
+
13
+ let(:subscriber) { Mrss::EventSubscriber.new }
14
+
15
+ describe 'mongocryptd' do
16
+ before do
17
+ Process.spawn(
18
+ 'mongocryptd',
19
+ '--pidfilepath=bypass-spawning-mongocryptd.pid', '--port=23000', '--idleShutdownTimeoutSecs=60',
20
+ %i[ out err ] => '/dev/null'
21
+ )
22
+ end
23
+
24
+ let(:client) do
25
+ Mongo::Client.new('mongodb://localhost:23000/?timeoutMS=1000').tap do |client|
26
+ client.subscribe(Mongo::Monitoring::COMMAND, subscriber)
27
+ end
28
+ end
29
+
30
+ let(:ping_command) do
31
+ subscriber.started_events.find do |event|
32
+ event.command_name == 'ping'
33
+ end&.command
34
+ end
35
+
36
+ after do
37
+ client.close
38
+ end
39
+
40
+ it 'does not set maxTimeMS for commands sent to mongocryptd' do
41
+ expect do
42
+ client.use('admin').command(ping: 1)
43
+ end.to raise_error(Mongo::Error::OperationFailure)
44
+
45
+ expect(ping_command).not_to have_key('maxTimeMS')
46
+ end
47
+ end
48
+
49
+ describe 'ClientEncryption' do
50
+ let(:key_vault_client) do
51
+ ClientRegistry.instance.new_local_client(
52
+ SpecConfig.instance.addresses,
53
+ SpecConfig.instance.test_options.merge(timeout_ms: 20)
54
+ )
55
+ end
56
+
57
+ let(:client_encryption) do
58
+ Mongo::ClientEncryption.new(
59
+ key_vault_client,
60
+ key_vault_namespace: key_vault_namespace,
61
+ kms_providers: local_kms_providers
62
+ )
63
+ end
64
+
65
+ describe '#createDataKey' do
66
+ before do
67
+ authorized_client.use(key_vault_db)[key_vault_coll].drop
68
+ authorized_client.use(key_vault_db)[key_vault_coll].create
69
+ authorized_client.use(:admin).command({
70
+ configureFailPoint: 'failCommand',
71
+ mode: {
72
+ times: 1
73
+ },
74
+ data: {
75
+ failCommands: [ 'insert' ],
76
+ blockConnection: true,
77
+ blockTimeMS: 30
78
+ }
79
+ })
80
+ end
81
+
82
+ after do
83
+ authorized_client.use(:admin).command({
84
+ configureFailPoint: 'failCommand',
85
+ mode: 'off',
86
+ })
87
+ key_vault_client.close
88
+ end
89
+
90
+ it 'fails with timeout error' do
91
+ expect do
92
+ client_encryption.create_data_key('local')
93
+ end.to raise_error(Mongo::Error::TimeoutError)
94
+ end
95
+ end
96
+
97
+ describe '#encrypt' do
98
+ let!(:data_key_id) do
99
+ client_encryption.create_data_key('local')
100
+ end
101
+
102
+ before do
103
+ authorized_client.use(:admin).command({
104
+ configureFailPoint: 'failCommand',
105
+ mode: {
106
+ times: 1
107
+ },
108
+ data: {
109
+ failCommands: [ 'find' ],
110
+ blockConnection: true,
111
+ blockTimeMS: 30
112
+ }
113
+ })
114
+ end
115
+
116
+ after do
117
+ authorized_client.use(:admin).command({
118
+ configureFailPoint: 'failCommand',
119
+ mode: 'off',
120
+ })
121
+ end
122
+
123
+ it 'fails with timeout error' do
124
+ expect do
125
+ client_encryption.encrypt('hello', key_id: data_key_id,
126
+ algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic')
127
+ end.to raise_error(Mongo::Error::TimeoutError)
128
+ end
129
+ end
130
+ end
131
+ end
@@ -26,6 +26,8 @@ describe 'Connection pool populator integration' do
26
26
 
27
27
  declare_topology_double
28
28
 
29
+ retry_test
30
+
29
31
  let(:app_metadata) do
30
32
  Mongo::Server::AppMetadata.new(options)
31
33
  end
@@ -52,73 +52,28 @@ describe 'Cursor pinning' do
52
52
  context 'lb' do
53
53
  require_topology :load_balanced
54
54
 
55
- # In load-balanced topology, we cannot create new connections to a
56
- # particular service.
55
+ # In load-balanced topology, a cursor retains the connection used to create
56
+ # it until the cursor is closed.
57
57
 
58
- context 'when no connection is available' do
58
+ context 'when connection is available' do
59
+ require_multi_mongos
59
60
 
60
- it 'raises ConnectionCheckOutTimeout' do
61
- server.pool.size.should == 0
61
+ let(:client) { authorized_client.with(max_pool_size: 2) }
62
62
 
63
+ it 'does not return connection to the pool if cursor not drained' do
64
+ expect(server.pool).not_to receive(:check_in)
63
65
  enum = collection.find({}, batch_size: 1).to_enum
64
- # Still zero because we haven't iterated
65
- server.pool.size.should == 0
66
-
66
+ # Get the first element only; cursor is not drained, so there should
67
+ # be no check_in of the connection.
67
68
  enum.next
68
- server.pool.size.should == 1
69
-
70
- # Grab the connection that was used
71
- server.with_connection do
72
- # This requires a new connection, but we cannot make one.
73
- lambda do
74
- enum.next
75
- end.should raise_error(Mongo::Error::ConnectionCheckOutTimeout)
76
-
77
- server.pool.size.should == 1
78
- end
79
69
  end
80
- end
81
-
82
- context 'when connection is available' do
83
- require_multi_mongos
84
-
85
- let(:client) { authorized_client.with(max_pool_size: 4) }
86
-
87
- it 'uses the available connection' do
88
- server.pool.size.should == 0
89
-
90
- # Create 4 connections.
91
-
92
- enums = []
93
- connections = []
94
- connection_ids = []
95
-
96
- 4.times do
97
- view = collection.find({}, batch_size: 1)
98
- enum = view.to_enum
99
-
100
- enum.next
101
-
102
- enums << enum
103
- connection_ids << view.cursor.initial_result.connection_global_id
104
- connections << server.pool.check_out
105
- end
106
-
107
- connection_ids.uniq.length.should be > 1
108
-
109
- server.pool.size.should == 4
110
-
111
- connections.each do |c|
112
- server.pool.check_in(c)
113
- end
114
70
 
115
- # At this point, in theory, all connections are equally likely to
116
- # be chosen, but we have cursors referencing more than one
117
- # distinct service.
118
- # Iterate each cursor to ensure they all continue to work.
119
- enums.each do |enum|
120
- enum.next
121
- end
71
+ it 'returns connection to the pool when cursor is drained' do
72
+ view = collection.find({}, batch_size: 1)
73
+ enum = view.to_enum
74
+ expect_any_instance_of(Mongo::Cursor).to receive(:check_in_connection)
75
+ # Drain the cursor
76
+ enum.each { |it| it.nil? }
122
77
  end
123
78
  end
124
79
  end
@@ -24,7 +24,7 @@ describe 'Cursor reaping' do
24
24
  let(:subscriber) { Mrss::EventSubscriber.new }
25
25
 
26
26
  let(:client) do
27
- authorized_client.tap do |client|
27
+ authorized_client.with(max_pool_size: 10).tap do |client|
28
28
  client.subscribe(Mongo::Monitoring::COMMAND, subscriber)
29
29
  end
30
30
  end
@@ -9,7 +9,7 @@ describe 'aggregation examples in Ruby' do
9
9
  # the tests in this file.
10
10
  begin
11
11
  ClientRegistry.instance.global_client('authorized')['_placeholder'].create
12
- rescue Mongo::Error::OperationFailure => e
12
+ rescue Mongo::Error::OperationFailure::Family => e
13
13
  # Collection already exists
14
14
  if e.code != 48
15
15
  raise
@@ -17,7 +17,7 @@ describe 'OperationFailure code' do
17
17
  collection.insert_one(_id: 1)
18
18
  collection.insert_one(_id: 1)
19
19
  fail('Should have raised')
20
- rescue Mongo::Error::OperationFailure => e
20
+ rescue Mongo::Error::OperationFailure::Family => e
21
21
  expect(e.code).to eq(11000)
22
22
  # 4.0 and 4.2 sharded clusters set code name.
23
23
  # 4.0 and 4.2 replica sets and standalones do not,
@@ -22,7 +22,7 @@ describe 'OperationFailure message' do
22
22
  begin
23
23
  client.command(bogus_command: nil)
24
24
  fail('Should have raised')
25
- rescue Mongo::Error::OperationFailure => e
25
+ rescue Mongo::Error::OperationFailure::Family => e
26
26
  e.code_name.should == 'CommandNotFound'
27
27
  e.message.should =~ %r,\A\[59:CommandNotFound\]: no such (?:command|cmd): '?bogus_command'?,
28
28
  end
@@ -36,7 +36,7 @@ describe 'OperationFailure message' do
36
36
  begin
37
37
  client.command(bogus_command: nil)
38
38
  fail('Should have raised')
39
- rescue Mongo::Error::OperationFailure => e
39
+ rescue Mongo::Error::OperationFailure::Family => e
40
40
  e.code_name.should be nil
41
41
  e.message.should =~ %r,\A\[59\]: no such (?:command|cmd): '?bogus_command'?,
42
42
  end
@@ -53,7 +53,7 @@ describe 'OperationFailure message' do
53
53
  collection.insert_one(_id: 1)
54
54
  collection.insert_one(_id: 1)
55
55
  fail('Should have raised')
56
- rescue Mongo::Error::OperationFailure => e
56
+ rescue Mongo::Error::OperationFailure::Family => e
57
57
  e.code_name.should be nil
58
58
  e.message.should =~ %r,\A\[11000\]: (?:insertDocument :: caused by :: 11000 )?E11000 duplicate key error (?:collection|index):,
59
59
  end
@@ -83,7 +83,7 @@ describe 'Failing retryable operations' do
83
83
 
84
84
  begin
85
85
  collection.find(a: 1).to_a
86
- rescue Mongo::Error::OperationFailure => exception
86
+ rescue Mongo::Error::OperationFailure::Family => exception
87
87
  else
88
88
  fail('Expected operation to fail')
89
89
  end
@@ -128,7 +128,7 @@ describe 'Failing retryable operations' do
128
128
 
129
129
  begin
130
130
  collection.insert_one(a: 1)
131
- rescue Mongo::Error::OperationFailure => exception
131
+ rescue Mongo::Error::OperationFailure::Family => exception
132
132
  else
133
133
  fail('Expected operation to fail')
134
134
  end
@@ -420,7 +420,8 @@ describe 'SDAM error handling' do
420
420
  expect_server_state_change
421
421
  end
422
422
 
423
- it_behaves_like 'marks server unknown and clears connection pool'
423
+ # https://jira.mongodb.org/browse/RUBY-2523
424
+ # it_behaves_like 'marks server unknown and clears connection pool'
424
425
 
425
426
  after do
426
427
  admin_client.command(configureFailPoint: 'failCommand', mode: 'off')
@@ -87,6 +87,10 @@ describe 'Mongo::Collection#search_indexes prose tests' do
87
87
  let(:definition) { { 'mappings' => { 'dynamic' => false } } }
88
88
  let(:create_index) { helper.collection.search_indexes.create_one(definition, name: name) }
89
89
 
90
+ after do
91
+ client.close
92
+ end
93
+
90
94
  # Case 1: Driver can successfully create and list search indexes
91
95
  context 'when creating and listing search indexes' do
92
96
  let(:index) { helper.wait_for(name).first }
@@ -6,6 +6,7 @@ require 'spec_helper'
6
6
  describe 'Server' do
7
7
  let(:client) { authorized_client }
8
8
 
9
+ let(:context) { Mongo::Operation::Context.new(client: client) }
9
10
  let(:server) { client.cluster.next_primary }
10
11
 
11
12
  let(:collection) { client['collection'] }
@@ -15,7 +16,7 @@ describe 'Server' do
15
16
  context 'it performs read operations and receives the correct result type' do
16
17
  context 'normal server' do
17
18
  it 'can be used for reads' do
18
- result = view.send(:send_initial_query, server)
19
+ result = view.send(:send_initial_query, server, context)
19
20
  expect(result).to be_a(Mongo::Operation::Find::Result)
20
21
  end
21
22
  end
@@ -35,7 +36,7 @@ describe 'Server' do
35
36
 
36
37
  it 'can be used for reads' do
37
38
  # See also RUBY-3102.
38
- result = view.send(:send_initial_query, server)
39
+ result = view.send(:send_initial_query, server, context)
39
40
  expect(result).to be_a(Mongo::Operation::Find::Result)
40
41
  end
41
42
  end
@@ -57,7 +58,7 @@ describe 'Server' do
57
58
  it 'is unusable' do
58
59
  # See also RUBY-3102.
59
60
  lambda do
60
- view.send(:send_initial_query, server)
61
+ view.send(:send_initial_query, server, context)
61
62
  end.should raise_error(Mongo::Error::ServerNotUsable)
62
63
  end
63
64
  end
@@ -58,5 +58,7 @@ describe 'Transactions API examples' do
58
58
 
59
59
  # End Transactions withTxn API Example 1
60
60
 
61
+ # Do not leak clients.
62
+ client.close
61
63
  end
62
64
  end
@@ -20,6 +20,10 @@ describe 'kerberos authentication' do
20
20
  end
21
21
  end
22
22
 
23
+ after do
24
+ client&.close
25
+ end
26
+
23
27
  let(:user) do
24
28
  "#{require_env_value('SASL_USER')}%40#{realm}"
25
29
  end
@@ -22,7 +22,9 @@ CMAP_TESTS = Dir.glob("#{CURRENT_PATH}/spec_tests/data/cmap/*.yml").sort.select
22
22
  !defined?(JRUBY_VERSION) || !f.include?('pool-checkout-minPoolSize-connection-maxConnecting.yml')
23
23
  end
24
24
  AUTH_TESTS = Dir.glob("#{CURRENT_PATH}/spec_tests/data/auth/*.yml").sort
25
- CLIENT_SIDE_ENCRYPTION_TESTS = Dir.glob("#{CURRENT_PATH}/spec_tests/data/client_side_encryption/*.yml").sort
25
+ CLIENT_SIDE_ENCRYPTION_TESTS = Dir.glob("#{CURRENT_PATH}/spec_tests/data/client_side_encryption/*.yml").sort.delete_if do |spec|
26
+ ![ 1, '1', 'yes', 'true' ].include?(ENV['CSOT_SPEC_TESTS']) && spec =~ /.*timeoutMS.yml$/
27
+ end
26
28
 
27
29
  # Disable output buffering: https://www.rubyguides.com/2019/02/ruby-io/
28
30
  STDOUT.sync = true
@@ -526,7 +526,7 @@ describe Mongo::Auth::User::View do
526
526
  it "raises and reports the write concern error correctly" do
527
527
  begin
528
528
  view.send(method, input)
529
- rescue Mongo::Error::OperationFailure => e
529
+ rescue Mongo::Error::OperationFailure::Family => e
530
530
  expect(e.write_concern_error?).to be true
531
531
  expect(e.write_concern_error_document).to eq(
532
532
  "code" => 64,
@@ -23,7 +23,7 @@ describe Mongo::CachingCursor do
23
23
  end
24
24
 
25
25
  let(:reply) do
26
- view.send(:send_initial_query, server)
26
+ view.send(:send_initial_query, server, Mongo::Operation::Context.new(client: authorized_client))
27
27
  end
28
28
 
29
29
  let(:cursor) do
@@ -303,6 +303,7 @@ describe Mongo::ClientEncryption do
303
303
  end
304
304
 
305
305
  it 'raises a KmsError' do
306
+ skip 'https://jira.mongodb.org/browse/RUBY-3375'
306
307
  expect do
307
308
  data_key_id
308
309
  end.to raise_error(Mongo::Error::KmsError, /Error while connecting to socket/)