mongo 2.20.1 → 2.21.0

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 (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
@@ -0,0 +1,358 @@
1
+ description: "timeoutMS behaves correctly for change streams"
2
+
3
+ schemaVersion: "1.9"
4
+
5
+ runOnRequirements:
6
+ - minServerVersion: "4.4"
7
+ topologies: ["replicaset", "sharded"]
8
+
9
+ createEntities:
10
+ - client:
11
+ id: &failPointClient failPointClient
12
+ useMultipleMongoses: false
13
+ - client:
14
+ id: &client client
15
+ useMultipleMongoses: false
16
+ observeEvents:
17
+ - commandStartedEvent
18
+ # Drivers are not required to execute killCursors during resume attempts, so it should be ignored for command
19
+ # monitoring assertions.
20
+ ignoreCommandMonitoringEvents: ["killCursors"]
21
+ - database:
22
+ id: &database database
23
+ client: *client
24
+ databaseName: &databaseName test
25
+ - collection:
26
+ id: &collection collection
27
+ database: *database
28
+ collectionName: &collectionName coll
29
+
30
+ initialData:
31
+ - collectionName: *collectionName
32
+ databaseName: *databaseName
33
+ documents: []
34
+
35
+ tests:
36
+ - description: "error if maxAwaitTimeMS is greater than timeoutMS"
37
+ operations:
38
+ - name: createChangeStream
39
+ object: *collection
40
+ arguments:
41
+ pipeline: []
42
+ timeoutMS: 5
43
+ maxAwaitTimeMS: 10
44
+ expectError:
45
+ isClientError: true
46
+
47
+ - description: "error if maxAwaitTimeMS is equal to timeoutMS"
48
+ operations:
49
+ - name: createChangeStream
50
+ object: *collection
51
+ arguments:
52
+ pipeline: []
53
+ timeoutMS: 5
54
+ maxAwaitTimeMS: 5
55
+ expectError:
56
+ isClientError: true
57
+
58
+ - description: "timeoutMS applied to initial aggregate"
59
+ operations:
60
+ - name: failPoint
61
+ object: testRunner
62
+ arguments:
63
+ client: *failPointClient
64
+ failPoint:
65
+ configureFailPoint: failCommand
66
+ mode: { times: 1 }
67
+ data:
68
+ failCommands: ["aggregate"]
69
+ blockConnection: true
70
+ blockTimeMS: 55
71
+ - name: createChangeStream
72
+ object: *collection
73
+ arguments:
74
+ pipeline: []
75
+ timeoutMS: 50
76
+ expectError:
77
+ isTimeoutError: true
78
+ expectEvents:
79
+ - client: *client
80
+ events:
81
+ - commandStartedEvent:
82
+ commandName: aggregate
83
+ databaseName: *databaseName
84
+ command:
85
+ aggregate: *collectionName
86
+ maxTimeMS: { $$type: ["int", "long"] }
87
+
88
+ # If maxAwaitTimeMS is not set, timeoutMS should be refreshed for the getMore and the getMore should not have a
89
+ # maxTimeMS field. This test requires a high timeout because the server applies a default 1000ms maxAwaitTime. To
90
+ # ensure that the driver is refreshing the timeout between commands, the test blocks aggregate and getMore commands
91
+ # for 30ms each and creates/iterates a change stream with timeoutMS=1050. The initial aggregate will block for 30ms
92
+ # and the getMore will block for 1030ms.
93
+ - description: "timeoutMS is refreshed for getMore if maxAwaitTimeMS is not set"
94
+ operations:
95
+ - name: failPoint
96
+ object: testRunner
97
+ arguments:
98
+ client: *failPointClient
99
+ failPoint:
100
+ configureFailPoint: failCommand
101
+ mode: { times: 2 }
102
+ data:
103
+ failCommands: ["aggregate", "getMore"]
104
+ blockConnection: true
105
+ blockTimeMS: 30
106
+ - name: createChangeStream
107
+ object: *collection
108
+ arguments:
109
+ pipeline: []
110
+ timeoutMS: 1050
111
+ saveResultAsEntity: &changeStream changeStream
112
+ - name: iterateOnce
113
+ object: *changeStream
114
+ expectEvents:
115
+ - client: *client
116
+ events:
117
+ - commandStartedEvent:
118
+ commandName: aggregate
119
+ databaseName: *databaseName
120
+ command:
121
+ aggregate: *collectionName
122
+ maxTimeMS: { $$type: ["int", "long"] }
123
+ - commandStartedEvent:
124
+ commandName: getMore
125
+ databaseName: *databaseName
126
+ command:
127
+ getMore: { $$type: ["int", "long"] }
128
+ collection: *collectionName
129
+ maxTimeMS: { $$exists: false }
130
+
131
+ # If maxAwaitTimeMS is set, timeoutMS should still be refreshed for the getMore and the getMore command should have a
132
+ # maxTimeMS field.
133
+ - description: "timeoutMS is refreshed for getMore if maxAwaitTimeMS is set"
134
+ operations:
135
+ - name: failPoint
136
+ object: testRunner
137
+ arguments:
138
+ client: *failPointClient
139
+ failPoint:
140
+ configureFailPoint: failCommand
141
+ mode: { times: 2 }
142
+ data:
143
+ failCommands: ["aggregate", "getMore"]
144
+ blockConnection: true
145
+ # was 15, changed to 30 to account for jruby driver latency.
146
+ blockTimeMS: 30
147
+ - name: createChangeStream
148
+ object: *collection
149
+ arguments:
150
+ pipeline: []
151
+ # was 20, changed to 29 to account for native ruby driver latency.
152
+ # Changed again to 59 to account for additional jruby driver latency.
153
+ # The idea for this test is that each operation is delayed by 15ms
154
+ # (by failpoint). the timeout for each operation is set to (originally)
155
+ # 20ms, because if timeoutMS was not refreshed for getMore, it would timeout.
156
+ # However, we're tickling the 20ms timeout because the driver itself
157
+ # is taking more than 5ms to do its thing.
158
+ #
159
+ # Changing the blockTimeMS in the failpoint to 30ms, and then bumping
160
+ # the timeout to almost twice that (59ms) should give us the same
161
+ # effect in the test.
162
+ timeoutMS: 59
163
+ batchSize: 2
164
+ maxAwaitTimeMS: 1
165
+ saveResultAsEntity: &changeStream changeStream
166
+ - name: iterateOnce
167
+ object: *changeStream
168
+ expectEvents:
169
+ - client: *client
170
+ events:
171
+ - commandStartedEvent:
172
+ commandName: aggregate
173
+ databaseName: *databaseName
174
+ command:
175
+ aggregate: *collectionName
176
+ maxTimeMS: { $$type: ["int", "long"] }
177
+ - commandStartedEvent:
178
+ commandName: getMore
179
+ databaseName: *databaseName
180
+ command:
181
+ getMore: { $$type: ["int", "long"] }
182
+ collection: *collectionName
183
+ maxTimeMS: 1
184
+
185
+ # The timeout should be applied to the entire resume attempt, not individually to each command. The test creates a
186
+ # change stream with timeoutMS=20 which returns an empty initial batch and then sets a fail point to block both
187
+ # getMore and aggregate for 12ms each and fail with a resumable error. When the resume attempt happens, the getMore
188
+ # and aggregate block for longer than 20ms total, so it times out.
189
+ - description: "timeoutMS applies to full resume attempt in a next call"
190
+ operations:
191
+ - name: createChangeStream
192
+ object: *collection
193
+ arguments:
194
+ pipeline: []
195
+ # Originally set to 20, but the Ruby driver was too-often taking
196
+ # that much time, and causing the timing of the test to fail. Instead,
197
+ # bumped the timout to 23ms, which is just less than twice the
198
+ # blockTimeMS for the failpoint. It still failed on jruby, so the
199
+ # timeout (and blockTimeMS) were drastically increased to accomodate
200
+ # JRuby. This tests the same thing, but gives the driver a bit more
201
+ # breathing space.
202
+ timeoutMS: 99
203
+ saveResultAsEntity: &changeStream changeStream
204
+ - name: failPoint
205
+ object: testRunner
206
+ arguments:
207
+ client: *failPointClient
208
+ failPoint:
209
+ configureFailPoint: failCommand
210
+ mode: { times: 2 }
211
+ data:
212
+ failCommands: ["getMore", "aggregate"]
213
+ blockConnection: true
214
+ # Originally 12, bumped it to 50 to give the jruby driver a bit
215
+ # more breathing room.
216
+ blockTimeMS: 50
217
+ errorCode: 7 # HostNotFound - resumable but does not require an SDAM state change.
218
+ # failCommand doesn't correctly add the ResumableChangeStreamError by default. It needs to be specified
219
+ # manually here so the error is considered resumable. The failGetMoreAfterCursorCheckout fail point
220
+ # would add the label without this, but it does not support blockConnection functionality.
221
+ errorLabels: ["ResumableChangeStreamError"]
222
+ - name: iterateUntilDocumentOrError
223
+ object: *changeStream
224
+ expectError:
225
+ isTimeoutError: true
226
+ expectEvents:
227
+ - client: *client
228
+ events:
229
+ - commandStartedEvent:
230
+ commandName: aggregate
231
+ databaseName: *databaseName
232
+ command:
233
+ aggregate: *collectionName
234
+ maxTimeMS: { $$type: ["int", "long"] }
235
+ - commandStartedEvent:
236
+ commandName: getMore
237
+ databaseName: *databaseName
238
+ command:
239
+ getMore: { $$type: ["int", "long"] }
240
+ collection: *collectionName
241
+ maxTimeMS: { $$exists: false }
242
+ - commandStartedEvent:
243
+ commandName: aggregate
244
+ databaseName: *databaseName
245
+ command:
246
+ aggregate: *collectionName
247
+ maxTimeMS: { $$type: ["int", "long"] }
248
+
249
+ - description: "change stream can be iterated again if previous iteration times out"
250
+ operations:
251
+ - name: createChangeStream
252
+ object: *collection
253
+ arguments:
254
+ pipeline: []
255
+ # Specify a short maxAwaitTimeMS because otherwise the getMore on the new cursor will wait for 1000ms and
256
+ # time out.
257
+ maxAwaitTimeMS: 1
258
+ timeoutMS: 100
259
+ saveResultAsEntity: &changeStream changeStream
260
+ # Block getMore for 150ms to force the next() call to time out.
261
+ - name: failPoint
262
+ object: testRunner
263
+ arguments:
264
+ client: *failPointClient
265
+ failPoint:
266
+ configureFailPoint: failCommand
267
+ mode: { times: 1 }
268
+ data:
269
+ failCommands: ["getMore"]
270
+ blockConnection: true
271
+ blockTimeMS: 150
272
+ # The original aggregate didn't return any events so this should do a getMore and return a timeout error.
273
+ - name: iterateUntilDocumentOrError
274
+ object: *changeStream
275
+ expectError:
276
+ isTimeoutError: true
277
+ # The previous iteration attempt timed out so this should re-create the change stream. We use iterateOnce rather
278
+ # than iterateUntilDocumentOrError because there haven't been any events and we only want to assert that the
279
+ # cursor was re-created.
280
+ - name: iterateOnce
281
+ object: *changeStream
282
+ expectEvents:
283
+ - client: *client
284
+ events:
285
+ - commandStartedEvent:
286
+ commandName: aggregate
287
+ databaseName: *databaseName
288
+ command:
289
+ aggregate: *collectionName
290
+ maxTimeMS: { $$type: ["int", "long"] }
291
+ # The iterateUntilDocumentOrError operation should send a getMore.
292
+ - commandStartedEvent:
293
+ commandName: getMore
294
+ databaseName: *databaseName
295
+ command:
296
+ getMore: { $$type: ["int", "long"] }
297
+ collection: *collectionName
298
+ # The iterateOnce operation should re-create the cursor via an aggregate and then send a getMore to iterate
299
+ # the new cursor.
300
+ - commandStartedEvent:
301
+ commandName: aggregate
302
+ databaseName: *databaseName
303
+ command:
304
+ aggregate: *collectionName
305
+ maxTimeMS: { $$type: ["int", "long"] }
306
+ - commandStartedEvent:
307
+ commandName: getMore
308
+ databaseName: *databaseName
309
+ command:
310
+ getMore: { $$type: ["int", "long"] }
311
+ collection: *collectionName
312
+
313
+ # The timeoutMS value should be refreshed for getMore's. This is a failure test. The createChangeStream operation
314
+ # sets timeoutMS=10 and the getMore blocks for 15ms, causing iteration to fail with a timeout error.
315
+ - description: "timeoutMS is refreshed for getMore - failure"
316
+ operations:
317
+ - name: failPoint
318
+ object: testRunner
319
+ arguments:
320
+ client: *failPointClient
321
+ failPoint:
322
+ configureFailPoint: failCommand
323
+ mode: { times: 1 }
324
+ data:
325
+ failCommands: ["getMore"]
326
+ blockConnection: true
327
+ # blockTimeMS: 15
328
+ # Increase timeout
329
+ blockTimeMS: 30
330
+ - name: createChangeStream
331
+ object: *collection
332
+ arguments:
333
+ pipeline: []
334
+ # timeoutMS: 10
335
+ # Increase timeout
336
+ timeoutMS: 20
337
+ saveResultAsEntity: &changeStream changeStream
338
+ # The first iteration should do a getMore
339
+ - name: iterateUntilDocumentOrError
340
+ object: *changeStream
341
+ expectError:
342
+ isTimeoutError: true
343
+ expectEvents:
344
+ - client: *client
345
+ events:
346
+ - commandStartedEvent:
347
+ commandName: aggregate
348
+ databaseName: *databaseName
349
+ command:
350
+ aggregate: *collectionName
351
+ maxTimeMS: { $$type: ["int", "long"] }
352
+ # The iterateUntilDocumentOrError operation should send a getMore.
353
+ - commandStartedEvent:
354
+ commandName: getMore
355
+ databaseName: *databaseName
356
+ command:
357
+ getMore: { $$type: ["int", "long"] }
358
+ collection: *collectionName
@@ -0,0 +1,129 @@
1
+ description: "timeoutMS behaves correctly when closing cursors"
2
+
3
+ schemaVersion: "1.9"
4
+
5
+ runOnRequirements:
6
+ - minServerVersion: "4.4"
7
+
8
+ createEntities:
9
+ - client:
10
+ id: &failPointClient failPointClient
11
+ useMultipleMongoses: false
12
+ - client:
13
+ id: &client client
14
+ useMultipleMongoses: false
15
+ observeEvents:
16
+ - commandStartedEvent
17
+ - commandSucceededEvent
18
+ - commandFailedEvent
19
+ - database:
20
+ id: &database database
21
+ client: *client
22
+ databaseName: &databaseName test
23
+ - collection:
24
+ id: &collection collection
25
+ database: *database
26
+ collectionName: &collectionName coll
27
+
28
+ initialData:
29
+ - collectionName: *collectionName
30
+ databaseName: *databaseName
31
+ documents:
32
+ - { _id: 0 }
33
+ - { _id: 1 }
34
+ - { _id: 2 }
35
+
36
+ tests:
37
+ - description: "timeoutMS is refreshed for close"
38
+ operations:
39
+ - name: failPoint
40
+ object: testRunner
41
+ arguments:
42
+ client: *failPointClient
43
+ failPoint:
44
+ configureFailPoint: failCommand
45
+ mode: { times: 1 }
46
+ data:
47
+ failCommands: ["getMore"]
48
+ blockConnection: true
49
+ blockTimeMS: 50
50
+ - name: createFindCursor
51
+ object: *collection
52
+ arguments:
53
+ filter: {}
54
+ batchSize: 2
55
+ timeoutMS: 20
56
+ saveResultAsEntity: &cursor cursor
57
+ # Iterate the cursor three times. The third should do a getMore, which should fail with a timeout error.
58
+ - name: iterateUntilDocumentOrError
59
+ object: *cursor
60
+ - name: iterateUntilDocumentOrError
61
+ object: *cursor
62
+ - name: iterateUntilDocumentOrError
63
+ object: *cursor
64
+ expectError:
65
+ isTimeoutError: true
66
+ # All errors from close() are ignored, so we close the cursor here but assert that killCursors was executed
67
+ # successfully via command monitoring expectations below.
68
+ - name: close
69
+ object: *cursor
70
+ expectEvents:
71
+ - client: *client
72
+ events:
73
+ - commandStartedEvent:
74
+ commandName: find
75
+ - commandSucceededEvent:
76
+ commandName: find
77
+ - commandStartedEvent:
78
+ commandName: getMore
79
+ - commandFailedEvent:
80
+ commandName: getMore
81
+ - commandStartedEvent:
82
+ command:
83
+ killCursors: *collectionName
84
+ # The close() operation should inherit timeoutMS from the initial find().
85
+ maxTimeMS: { $$type: ["int", "long"] }
86
+ commandName: killCursors
87
+ - commandSucceededEvent:
88
+ commandName: killCursors
89
+
90
+ - description: "timeoutMS can be overridden for close"
91
+ operations:
92
+ - name: failPoint
93
+ object: testRunner
94
+ arguments:
95
+ client: *client
96
+ failPoint:
97
+ configureFailPoint: failCommand
98
+ mode: { times: 1 }
99
+ data:
100
+ failCommands: ["killCursors"]
101
+ blockConnection: true
102
+ blockTimeMS: 30
103
+ - name: createFindCursor
104
+ object: *collection
105
+ arguments:
106
+ filter: {}
107
+ batchSize: 2
108
+ timeoutMS: 20
109
+ saveResultAsEntity: &cursor cursor
110
+ - name: close
111
+ object: *cursor
112
+ arguments:
113
+ # timeoutMS: 40
114
+ # Increase timeout
115
+ timeoutMS: 50
116
+ expectEvents:
117
+ - client: *client
118
+ events:
119
+ - commandStartedEvent:
120
+ commandName: find
121
+ - commandSucceededEvent:
122
+ commandName: find
123
+ - commandStartedEvent:
124
+ command:
125
+ killCursors: *collectionName
126
+ maxTimeMS: { $$type: ["int", "long"] }
127
+ commandName: killCursors
128
+ - commandSucceededEvent:
129
+ commandName: killCursors