mongo 2.14.1 → 2.15.0.alpha

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 (230) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/README.md +4 -1
  4. data/Rakefile +8 -15
  5. data/lib/mongo/auth/aws/conversation.rb +1 -4
  6. data/lib/mongo/auth/base.rb +13 -7
  7. data/lib/mongo/auth/conversation_base.rb +32 -0
  8. data/lib/mongo/auth/cr/conversation.rb +6 -29
  9. data/lib/mongo/auth/gssapi/conversation.rb +4 -15
  10. data/lib/mongo/auth/ldap/conversation.rb +3 -14
  11. data/lib/mongo/auth/sasl_conversation_base.rb +1 -13
  12. data/lib/mongo/auth/scram_conversation_base.rb +7 -34
  13. data/lib/mongo/auth/user/view.rb +16 -9
  14. data/lib/mongo/auth/x509/conversation.rb +4 -25
  15. data/lib/mongo/bulk_write.rb +21 -18
  16. data/lib/mongo/client.rb +82 -6
  17. data/lib/mongo/cluster/reapers/cursor_reaper.rb +6 -2
  18. data/lib/mongo/cluster.rb +19 -2
  19. data/lib/mongo/collection/view/aggregation.rb +1 -1
  20. data/lib/mongo/collection/view/change_stream.rb +1 -1
  21. data/lib/mongo/collection/view/iterable.rb +7 -17
  22. data/lib/mongo/collection/view/map_reduce.rb +2 -2
  23. data/lib/mongo/collection/view/readable.rb +42 -20
  24. data/lib/mongo/collection/view/writable.rb +14 -14
  25. data/lib/mongo/collection.rb +6 -6
  26. data/lib/mongo/cursor.rb +2 -12
  27. data/lib/mongo/database/view.rb +1 -1
  28. data/lib/mongo/database.rb +8 -3
  29. data/lib/mongo/error/bulk_write_error.rb +17 -3
  30. data/lib/mongo/error/internal_driver_error.rb +22 -0
  31. data/lib/mongo/error/operation_failure.rb +21 -2
  32. data/lib/mongo/error/parser.rb +65 -12
  33. data/lib/mongo/error/server_api_conflict.rb +23 -0
  34. data/lib/mongo/error/server_api_not_supported.rb +24 -0
  35. data/lib/mongo/error/unmet_dependency.rb +21 -0
  36. data/lib/mongo/error.rb +9 -1
  37. data/lib/mongo/index/view.rb +21 -11
  38. data/lib/mongo/monitoring/event/server_heartbeat_failed.rb +27 -16
  39. data/lib/mongo/monitoring/event/server_heartbeat_succeeded.rb +26 -15
  40. data/lib/mongo/monitoring.rb +13 -4
  41. data/lib/mongo/operation/collections_info/command.rb +2 -2
  42. data/lib/mongo/operation/collections_info.rb +18 -1
  43. data/lib/mongo/operation/context.rb +99 -0
  44. data/lib/mongo/operation/indexes.rb +15 -1
  45. data/lib/mongo/operation/insert/command.rb +2 -2
  46. data/lib/mongo/operation/insert/legacy.rb +2 -2
  47. data/lib/mongo/operation/insert/op_msg.rb +2 -2
  48. data/lib/mongo/operation/list_collections/result.rb +4 -1
  49. data/lib/mongo/operation/parallel_scan/command.rb +2 -1
  50. data/lib/mongo/operation/result.rb +2 -0
  51. data/lib/mongo/operation/shared/executable.rb +24 -14
  52. data/lib/mongo/operation/shared/executable_no_validate.rb +2 -2
  53. data/lib/mongo/operation/shared/op_msg_or_command.rb +1 -7
  54. data/lib/mongo/operation/shared/op_msg_or_find_command.rb +1 -7
  55. data/lib/mongo/operation/shared/polymorphic_operation.rb +39 -0
  56. data/lib/mongo/operation/shared/read_preference_supported.rb +36 -38
  57. data/lib/mongo/operation/shared/response_handling.rb +23 -23
  58. data/lib/mongo/operation/shared/sessions_supported.rb +15 -5
  59. data/lib/mongo/operation/shared/write.rb +8 -18
  60. data/lib/mongo/operation.rb +2 -2
  61. data/lib/mongo/protocol/compressed.rb +51 -5
  62. data/lib/mongo/protocol/message.rb +20 -2
  63. data/lib/mongo/protocol/msg.rb +38 -13
  64. data/lib/mongo/protocol/query.rb +11 -11
  65. data/lib/mongo/query_cache.rb +30 -0
  66. data/lib/mongo/retryable.rb +1 -1
  67. data/lib/mongo/server/app_metadata.rb +52 -18
  68. data/lib/mongo/server/connection.rb +5 -0
  69. data/lib/mongo/server/connection_base.rb +13 -10
  70. data/lib/mongo/server/connection_pool.rb +6 -2
  71. data/lib/mongo/server/description/features.rb +9 -8
  72. data/lib/mongo/server/description.rb +4 -0
  73. data/lib/mongo/server/monitor/app_metadata.rb +1 -1
  74. data/lib/mongo/server/monitor/connection.rb +9 -10
  75. data/lib/mongo/server/monitor.rb +20 -1
  76. data/lib/mongo/server/pending_connection.rb +24 -6
  77. data/lib/mongo/server/push_monitor.rb +11 -1
  78. data/lib/mongo/server.rb +7 -1
  79. data/lib/mongo/server_selector/secondary_preferred.rb +7 -2
  80. data/lib/mongo/session/session_pool.rb +4 -2
  81. data/lib/mongo/session.rb +2 -2
  82. data/lib/mongo/socket/ssl.rb +8 -0
  83. data/lib/mongo/socket.rb +29 -4
  84. data/lib/mongo/uri/options_mapper.rb +38 -0
  85. data/lib/mongo/utils.rb +15 -0
  86. data/lib/mongo/version.rb +1 -1
  87. data/lib/mongo.rb +23 -0
  88. data/spec/README.md +24 -1
  89. data/spec/integration/auth_spec.rb +25 -15
  90. data/spec/integration/bulk_write_error_message_spec.rb +41 -0
  91. data/spec/integration/change_stream_spec.rb +4 -4
  92. data/spec/integration/command_monitoring_spec.rb +2 -2
  93. data/spec/integration/connection_spec.rb +2 -0
  94. data/spec/integration/docs_examples_spec.rb +8 -1
  95. data/spec/integration/fork_reconnect_spec.rb +4 -1
  96. data/spec/integration/ocsp_verifier_spec.rb +13 -7
  97. data/spec/integration/operation_failure_code_spec.rb +1 -1
  98. data/spec/integration/operation_failure_message_spec.rb +90 -0
  99. data/spec/integration/query_cache_spec.rb +0 -45
  100. data/spec/integration/reconnect_spec.rb +1 -1
  101. data/spec/integration/snappy_compression_spec.rb +25 -0
  102. data/spec/integration/srv_monitoring_spec.rb +1 -1
  103. data/spec/integration/transactions_examples_spec.rb +6 -0
  104. data/spec/integration/zlib_compression_spec.rb +1 -1
  105. data/spec/integration/zstd_compression_spec.rb +26 -0
  106. data/spec/lite_spec_helper.rb +7 -1
  107. data/spec/mongo/address_spec.rb +15 -11
  108. data/spec/mongo/auth/ldap/conversation_spec.rb +1 -1
  109. data/spec/mongo/auth/ldap_spec.rb +5 -1
  110. data/spec/mongo/auth/scram_negotiation_spec.rb +1 -1
  111. data/spec/mongo/auth/scram_spec.rb +1 -1
  112. data/spec/mongo/auth/x509/conversation_spec.rb +3 -3
  113. data/spec/mongo/client_construction_spec.rb +207 -33
  114. data/spec/mongo/client_spec.rb +17 -0
  115. data/spec/mongo/cluster_spec.rb +1 -0
  116. data/spec/mongo/collection/view/explainable_spec.rb +1 -1
  117. data/spec/mongo/collection/view/readable_spec.rb +33 -19
  118. data/spec/mongo/collection_crud_spec.rb +4357 -0
  119. data/spec/mongo/collection_ddl_spec.rb +534 -0
  120. data/spec/mongo/collection_spec.rb +5 -4859
  121. data/spec/mongo/database_spec.rb +66 -4
  122. data/spec/mongo/error/bulk_write_error_spec.rb +3 -3
  123. data/spec/mongo/error/parser_spec.rb +37 -6
  124. data/spec/mongo/index/view_spec.rb +4 -0
  125. data/spec/mongo/monitoring/event/server_heartbeat_failed_spec.rb +1 -1
  126. data/spec/mongo/monitoring/event/server_heartbeat_succeeded_spec.rb +1 -1
  127. data/spec/mongo/operation/aggregate_spec.rb +2 -1
  128. data/spec/mongo/operation/collections_info_spec.rb +4 -1
  129. data/spec/mongo/operation/command_spec.rb +6 -3
  130. data/spec/mongo/operation/create_index_spec.rb +6 -3
  131. data/spec/mongo/operation/create_user_spec.rb +6 -3
  132. data/spec/mongo/operation/delete/bulk_spec.rb +9 -6
  133. data/spec/mongo/operation/delete_spec.rb +11 -7
  134. data/spec/mongo/operation/drop_index_spec.rb +6 -2
  135. data/spec/mongo/operation/find/legacy_spec.rb +3 -1
  136. data/spec/mongo/operation/get_more_spec.rb +3 -1
  137. data/spec/mongo/operation/indexes_spec.rb +5 -1
  138. data/spec/mongo/operation/insert/bulk_spec.rb +10 -7
  139. data/spec/mongo/operation/insert_spec.rb +15 -12
  140. data/spec/mongo/operation/map_reduce_spec.rb +5 -2
  141. data/spec/mongo/operation/read_preference_legacy_spec.rb +19 -9
  142. data/spec/mongo/operation/read_preference_op_msg_spec.rb +3 -3
  143. data/spec/mongo/operation/remove_user_spec.rb +6 -3
  144. data/spec/mongo/operation/result_spec.rb +1 -1
  145. data/spec/mongo/operation/update/bulk_spec.rb +9 -6
  146. data/spec/mongo/operation/update_spec.rb +10 -7
  147. data/spec/mongo/operation/update_user_spec.rb +4 -1
  148. data/spec/mongo/protocol/compressed_spec.rb +26 -12
  149. data/spec/mongo/query_cache_middleware_spec.rb +55 -0
  150. data/spec/mongo/retryable_spec.rb +3 -2
  151. data/spec/mongo/server/app_metadata_shared.rb +7 -33
  152. data/spec/mongo/server/app_metadata_spec.rb +2 -0
  153. data/spec/mongo/server/connection_pool/populator_spec.rb +3 -1
  154. data/spec/mongo/server/connection_pool_spec.rb +1 -1
  155. data/spec/mongo/server/connection_spec.rb +24 -17
  156. data/spec/mongo/server/monitor/connection_spec.rb +17 -7
  157. data/spec/mongo/server/monitor_spec.rb +9 -1
  158. data/spec/mongo/server_selector/secondary_preferred_spec.rb +6 -6
  159. data/spec/mongo/server_spec.rb +15 -2
  160. data/spec/mongo/socket/ssl_spec.rb +40 -0
  161. data/spec/mongo/socket_spec.rb +2 -2
  162. data/spec/mongo/tls_context_hooks_spec.rb +37 -0
  163. data/spec/runners/connection_string.rb +0 -4
  164. data/spec/runners/crud/requirement.rb +40 -3
  165. data/spec/runners/crud/verifier.rb +8 -0
  166. data/spec/runners/transactions/operation.rb +1 -1
  167. data/spec/runners/transactions/test.rb +1 -0
  168. data/spec/runners/unified/assertions.rb +249 -0
  169. data/spec/runners/unified/change_stream_operations.rb +26 -0
  170. data/spec/runners/unified/crud_operations.rb +199 -0
  171. data/spec/runners/unified/ddl_operations.rb +96 -0
  172. data/spec/runners/unified/entity_map.rb +39 -0
  173. data/spec/runners/unified/error.rb +25 -0
  174. data/spec/runners/unified/event_subscriber.rb +91 -0
  175. data/spec/runners/unified/exceptions.rb +21 -0
  176. data/spec/runners/unified/grid_fs_operations.rb +55 -0
  177. data/spec/runners/unified/support_operations.rb +250 -0
  178. data/spec/runners/unified/test.rb +393 -0
  179. data/spec/runners/unified/test_group.rb +28 -0
  180. data/spec/runners/unified/using_hash.rb +31 -0
  181. data/spec/runners/unified.rb +96 -0
  182. data/spec/shared/lib/mrss/cluster_config.rb +0 -3
  183. data/spec/shared/lib/mrss/docker_runner.rb +0 -3
  184. data/spec/shared/lib/mrss/lite_constraints.rb +0 -16
  185. data/spec/shared/lib/mrss/server_version_registry.rb +0 -3
  186. data/spec/shared/lib/mrss/spec_organizer.rb +0 -3
  187. data/spec/shared/shlib/server.sh +1 -1
  188. data/spec/spec_helper.rb +4 -1
  189. data/spec/spec_tests/crud_unified_spec.rb +10 -0
  190. data/spec/spec_tests/data/change_streams/change-streams.yml +0 -1
  191. data/spec/spec_tests/data/crud_unified/estimatedDocumentCount.yml +267 -0
  192. data/spec/spec_tests/data/retryable_reads/estimatedDocumentCount-4.9.yml +60 -0
  193. data/spec/spec_tests/data/retryable_reads/{estimatedDocumentCount.yml → estimatedDocumentCount-pre4.9.yml} +2 -0
  194. data/spec/spec_tests/data/retryable_reads/estimatedDocumentCount-serverErrors-4.9.yml +146 -0
  195. data/spec/spec_tests/data/retryable_reads/{estimatedDocumentCount-serverErrors.yml → estimatedDocumentCount-serverErrors-pre4.9.yml} +2 -0
  196. data/spec/spec_tests/data/retryable_reads/listIndexNames.yml +1 -1
  197. data/spec/spec_tests/data/unified/valid-fail/operation-failure.yml +31 -0
  198. data/spec/spec_tests/data/unified/valid-pass/poc-change-streams.yml +220 -0
  199. data/spec/spec_tests/data/unified/valid-pass/poc-command-monitoring.yml +102 -0
  200. data/spec/spec_tests/data/unified/valid-pass/poc-crud.yml +184 -0
  201. data/spec/spec_tests/data/unified/valid-pass/poc-gridfs.yml +155 -0
  202. data/spec/spec_tests/data/unified/valid-pass/poc-retryable-reads.yml +193 -0
  203. data/spec/spec_tests/data/unified/valid-pass/poc-retryable-writes.yml +210 -0
  204. data/spec/spec_tests/data/unified/valid-pass/poc-sessions.yml +215 -0
  205. data/spec/spec_tests/data/unified/valid-pass/poc-transactions-convenient-api.yml +235 -0
  206. data/spec/spec_tests/data/unified/valid-pass/poc-transactions-mongos-pin-auto.yml +169 -0
  207. data/spec/spec_tests/data/unified/valid-pass/poc-transactions.yml +170 -0
  208. data/spec/spec_tests/data/uri_options/compression-options.yml +1 -1
  209. data/spec/spec_tests/data/versioned_api/crud-api-version-1-strict.yml +416 -0
  210. data/spec/spec_tests/data/versioned_api/crud-api-version-1.yml +409 -0
  211. data/spec/spec_tests/data/versioned_api/runcommand-helper-no-api-version-declared.yml +67 -0
  212. data/spec/spec_tests/data/versioned_api/test-commands-deprecation-errors.yml +47 -0
  213. data/spec/spec_tests/data/versioned_api/test-commands-strict-mode.yml +44 -0
  214. data/spec/spec_tests/data/versioned_api/transaction-handling.yml +180 -0
  215. data/spec/spec_tests/unified_spec.rb +15 -0
  216. data/spec/spec_tests/uri_options_spec.rb +16 -0
  217. data/spec/spec_tests/versioned_api_spec.rb +10 -0
  218. data/spec/support/client_registry.rb +4 -8
  219. data/spec/support/client_registry_macros.rb +4 -4
  220. data/spec/support/common_shortcuts.rb +15 -1
  221. data/spec/support/shared/session.rb +2 -2
  222. data/spec/support/spec_config.rb +42 -11
  223. data/spec/support/utils.rb +64 -3
  224. data.tar.gz.sig +0 -0
  225. metadata +1005 -915
  226. metadata.gz.sig +0 -0
  227. data/lib/mongo/operation/shared/collections_info_or_list_collections.rb +0 -58
  228. data/lib/mongo/operation/shared/op_msg_or_list_indexes_command.rb +0 -47
  229. data/spec/integration/secondary_reads_spec.rb +0 -102
  230. data/spec/support/cluster_config.rb +0 -207
@@ -0,0 +1,180 @@
1
+ description: "Transaction handling"
2
+
3
+ schemaVersion: "1.1"
4
+
5
+ runOnRequirements:
6
+ - minServerVersion: "4.9"
7
+ topologies: [ replicaset, sharded-replicaset ]
8
+
9
+ createEntities:
10
+ - client:
11
+ id: &client client
12
+ observeEvents:
13
+ - commandStartedEvent
14
+ serverApi:
15
+ version: "1"
16
+ - database:
17
+ id: &database database
18
+ client: *client
19
+ databaseName: &databaseName versioned-api-tests
20
+ - collection:
21
+ id: &collection collection
22
+ database: *database
23
+ collectionName: &collectionName test
24
+ - session:
25
+ id: &session session
26
+ client: *client
27
+
28
+ _yamlAnchors:
29
+ versions:
30
+ - &expectedApiVersion
31
+ apiVersion: "1"
32
+ apiStrict: { $$unsetOrMatches: false }
33
+ apiDeprecationErrors: { $$unsetOrMatches: false }
34
+ - &noApiVersion
35
+ apiVersion: { $$exists: false }
36
+ apiStrict: { $$exists: false }
37
+ apiDeprecationErrors: { $$exists: false }
38
+
39
+
40
+ initialData:
41
+ - collectionName: *collectionName
42
+ databaseName: *databaseName
43
+ documents:
44
+ - { _id: 1, x: 11 }
45
+ - { _id: 2, x: 22 }
46
+ - { _id: 3, x: 33 }
47
+ - { _id: 4, x: 44 }
48
+ - { _id: 5, x: 55 }
49
+
50
+ tests:
51
+ - description: "Only the first command in a transaction declares an API version"
52
+ runOnRequirements:
53
+ - topologies: [ replicaset, sharded-replicaset ]
54
+ operations:
55
+ - name: startTransaction
56
+ object: *session
57
+ - name: insertOne
58
+ object: *collection
59
+ arguments:
60
+ session: *session
61
+ document: { _id: 6, x: 66 }
62
+ expectResult: { $$unsetOrMatches: { insertedId: { $$unsetOrMatches: 6 } } }
63
+ - name: insertOne
64
+ object: *collection
65
+ arguments:
66
+ session: *session
67
+ document: { _id: 7, x: 77 }
68
+ expectResult: { $$unsetOrMatches: { insertedId: { $$unsetOrMatches: 7 } } }
69
+ - name: commitTransaction
70
+ object: *session
71
+ expectEvents:
72
+ - client: *client
73
+ events:
74
+ - commandStartedEvent:
75
+ command:
76
+ insert: *collectionName
77
+ documents: [ { _id: 6, x: 66 } ]
78
+ lsid: { $$sessionLsid: *session }
79
+ startTransaction: true
80
+ <<: *expectedApiVersion
81
+ - commandStartedEvent:
82
+ command:
83
+ insert: *collectionName
84
+ documents: [ { _id: 7, x: 77 } ]
85
+ lsid: { $$sessionLsid: *session }
86
+ <<: *noApiVersion
87
+ - commandStartedEvent:
88
+ command:
89
+ commitTransaction: 1
90
+ lsid: { $$sessionLsid: *session }
91
+ <<: *noApiVersion
92
+ - description: "Committing a transaction twice does not append server API options"
93
+ runOnRequirements:
94
+ - topologies: [ replicaset, sharded-replicaset ]
95
+ operations:
96
+ - name: startTransaction
97
+ object: *session
98
+ - name: insertOne
99
+ object: *collection
100
+ arguments:
101
+ session: *session
102
+ document: { _id: 6, x: 66 }
103
+ expectResult: { $$unsetOrMatches: { insertedId: { $$unsetOrMatches: 6 } } }
104
+ - name: insertOne
105
+ object: *collection
106
+ arguments:
107
+ session: *session
108
+ document: { _id: 7, x: 77 }
109
+ expectResult: { $$unsetOrMatches: { insertedId: { $$unsetOrMatches: 7 } } }
110
+ - name: commitTransaction
111
+ object: *session
112
+ - name: commitTransaction
113
+ object: *session
114
+ expectEvents:
115
+ - client: *client
116
+ events:
117
+ - commandStartedEvent:
118
+ command:
119
+ insert: *collectionName
120
+ documents: [ { _id: 6, x: 66 } ]
121
+ lsid: { $$sessionLsid: *session }
122
+ startTransaction: true
123
+ <<: *expectedApiVersion
124
+ - commandStartedEvent:
125
+ command:
126
+ insert: *collectionName
127
+ documents: [ { _id: 7, x: 77 } ]
128
+ lsid: { $$sessionLsid: *session }
129
+ <<: *noApiVersion
130
+ - commandStartedEvent:
131
+ command:
132
+ commitTransaction: 1
133
+ lsid: { $$sessionLsid: *session }
134
+ <<: *noApiVersion
135
+ - commandStartedEvent:
136
+ command:
137
+ commitTransaction: 1
138
+ lsid: { $$sessionLsid: *session }
139
+ <<: *noApiVersion
140
+ - description: "abortTransaction does not include an API version"
141
+ runOnRequirements:
142
+ - topologies: [ replicaset, sharded-replicaset ]
143
+ operations:
144
+ - name: startTransaction
145
+ object: *session
146
+ - name: insertOne
147
+ object: *collection
148
+ arguments:
149
+ session: *session
150
+ document: { _id: 6, x: 66 }
151
+ expectResult: { $$unsetOrMatches: { insertedId: { $$unsetOrMatches: 6 } } }
152
+ - name: insertOne
153
+ object: *collection
154
+ arguments:
155
+ session: *session
156
+ document: { _id: 7, x: 77 }
157
+ expectResult: { $$unsetOrMatches: { insertedId: { $$unsetOrMatches: 7 } } }
158
+ - name: abortTransaction
159
+ object: *session
160
+ expectEvents:
161
+ - client: *client
162
+ events:
163
+ - commandStartedEvent:
164
+ command:
165
+ insert: *collectionName
166
+ documents: [ { _id: 6, x: 66 } ]
167
+ lsid: { $$sessionLsid: *session }
168
+ startTransaction: true
169
+ <<: *expectedApiVersion
170
+ - commandStartedEvent:
171
+ command:
172
+ insert: *collectionName
173
+ documents: [ { _id: 7, x: 77 } ]
174
+ lsid: { $$sessionLsid: *session }
175
+ <<: *noApiVersion
176
+ - commandStartedEvent:
177
+ command:
178
+ abortTransaction: 1
179
+ lsid: { $$sessionLsid: *session }
180
+ <<: *noApiVersion
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ require 'runners/unified'
4
+
5
+ base = "#{CURRENT_PATH}/spec_tests/data/unified"
6
+ PASS_UNIFIED_TESTS = Dir.glob("#{base}/valid-pass/**/*.yml").sort
7
+ FAIL_UNIFIED_TESTS = Dir.glob("#{base}/valid-fail/**/*.yml").sort
8
+
9
+ describe 'Unified spec tests' do
10
+ define_unified_spec_tests(base, PASS_UNIFIED_TESTS)
11
+ end
12
+
13
+ describe 'Unified spec tests - expected failures' do
14
+ define_unified_spec_tests(base, FAIL_UNIFIED_TESTS, expect_failure: true)
15
+ end
@@ -50,6 +50,22 @@ describe 'URI options' do
50
50
  end
51
51
 
52
52
  if test.options
53
+ if test.options['compressors'] && test.options['compressors'].include?('snappy')
54
+ before do
55
+ unless ENV.fetch('BUNDLE_GEMFILE', '') =~ /snappy/
56
+ skip "This test requires snappy compression"
57
+ end
58
+ end
59
+ end
60
+
61
+ if test.options['compressors'] && test.options['compressors'].include?('zstd')
62
+ before do
63
+ unless ENV.fetch('BUNDLE_GEMFILE', '') =~ /zstd/
64
+ skip "This test requires zstd compression"
65
+ end
66
+ end
67
+ end
68
+
53
69
  it 'creates a client with the correct options' do
54
70
  mapped = Mongo::URI::OptionsMapper.new.ruby_to_smc(test.client.options)
55
71
  expected = Mongo::ConnectionString.adjust_expected_mongo_client_options(
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+
3
+ require 'runners/unified'
4
+
5
+ base = "#{CURRENT_PATH}/spec_tests/data/versioned_api"
6
+ UNIFIED_TESTS = Dir.glob("#{base}/**/*.yml").sort
7
+
8
+ describe 'Versioned API spec tests' do
9
+ define_unified_spec_tests(base, UNIFIED_TESTS)
10
+ end
@@ -188,14 +188,10 @@ class ClientRegistry
188
188
  end
189
189
  private :new_global_client
190
190
 
191
- def new_local_client(*args, &block)
192
- if block_given?
193
- Mongo::Client.new(*args, &block)
194
- else
195
- Mongo::Client.new(*args).tap do |client|
196
- @lock.synchronize do
197
- @local_clients << client
198
- end
191
+ def new_local_client(*args)
192
+ Mongo::Client.new(*args).tap do |client|
193
+ @lock.synchronize do
194
+ @local_clients << client
199
195
  end
200
196
  end
201
197
  end
@@ -1,9 +1,9 @@
1
1
  module ClientRegistryMacros
2
- def new_local_client(address, options=nil, &block)
3
- ClientRegistry.instance.new_local_client(address, options, &block)
2
+ def new_local_client(address, options=nil)
3
+ ClientRegistry.instance.new_local_client(address, options)
4
4
  end
5
5
 
6
- def new_local_client_nmio(address, options=nil, &block)
6
+ def new_local_client_nmio(address, options=nil)
7
7
  # Avoid type converting options.
8
8
  base_options = {monitoring_io: false}
9
9
  if BSON::Document === options || options&.keys&.any? { |key| String === key }
@@ -14,7 +14,7 @@ module ClientRegistryMacros
14
14
  else
15
15
  base_options
16
16
  end
17
- new_local_client(address, options, &block)
17
+ new_local_client(address, options)
18
18
  end
19
19
 
20
20
  def close_local_clients
@@ -126,7 +126,19 @@ module CommonShortcuts
126
126
  process = ChildProcess.new(*args)
127
127
 
128
128
  process.io.inherit!
129
- process.start
129
+
130
+ retried = false
131
+ begin
132
+ process.start
133
+ rescue
134
+ if retried
135
+ raise
136
+ else
137
+ sleep 1
138
+ retried = true
139
+ retry
140
+ end
141
+ end
130
142
 
131
143
  begin
132
144
  sleep 0.4
@@ -210,6 +222,8 @@ module CommonShortcuts
210
222
  allow(cluster).to receive(:app_metadata)
211
223
  allow(cluster).to receive(:options).and_return({})
212
224
  allow(cluster).to receive(:run_sdam_flow)
225
+ allow(cluster).to receive(:monitor_app_metadata)
226
+ allow(cluster).to receive(:push_monitor_app_metadata)
213
227
  allow(cluster).to receive(:heartbeat_interval).and_return(10)
214
228
  server = Mongo::Server.new(address, cluster, monitoring, listeners,
215
229
  SpecConfig.instance.test_options.merge(monitoring_io: false))
@@ -54,9 +54,9 @@ shared_examples 'an operation using a session' do
54
54
  end
55
55
 
56
56
  it 'raises an exception' do
57
- expect {
57
+ expect do
58
58
  operation_result
59
- }.to raise_exception(Mongo::Error::InvalidSession)
59
+ end.to raise_exception(Mongo::Error::InvalidSession)
60
60
  end
61
61
  end
62
62
 
@@ -8,6 +8,7 @@ class SpecConfig
8
8
  # only loading the lite spec helper. Do I/O eagerly in accessor methods.
9
9
  def initialize
10
10
  @uri_options = {}
11
+ @ruby_options = {}
11
12
  if ENV['MONGODB_URI']
12
13
  @mongodb_uri = Mongo::URI.new(ENV['MONGODB_URI'])
13
14
  @uri_options = Mongo::Options::Mapper.transform_keys_to_symbols(@mongodb_uri.uri_options)
@@ -46,9 +47,19 @@ class SpecConfig
46
47
  end
47
48
 
48
49
  @ssl ||= false
50
+
51
+ if (server_api = ENV['SERVER_API']) && !server_api.empty?
52
+ @ruby_options[:server_api] = BSON::Document.new(YAML.load(server_api))
53
+ # Since the tests pass options provided by SpecConfig directly to
54
+ # internal driver objects (e.g. connections), transform server api
55
+ # parameters here as they would be transformed by Client constructor.
56
+ if (v = @ruby_options[:server_api][:version]).is_a?(Integer)
57
+ @ruby_options[:server_api][:version] = v.to_s
58
+ end
59
+ end
49
60
  end
50
61
 
51
- attr_reader :uri_options, :connect_options
62
+ attr_reader :uri_options, :ruby_options, :connect_options
52
63
 
53
64
  def addresses
54
65
  @addresses ||= begin
@@ -75,7 +86,7 @@ class SpecConfig
75
86
  # https://github.com/10gen/mongo-orchestration/issues/268
76
87
  client = Mongo::Client.new(addresses, Mongo::Options::Redacted.new(
77
88
  server_selection_timeout: 5.03,
78
- ).merge(ssl_options))
89
+ ).merge(ssl_options).merge(ruby_options))
79
90
 
80
91
  begin
81
92
  case client.cluster.topology.class.name
@@ -110,14 +121,6 @@ class SpecConfig
110
121
  !!(RUBY_PLATFORM =~ /\bjava\b/)
111
122
  end
112
123
 
113
- def linux?
114
- !!(RbConfig::CONFIG['host_os'].downcase =~ /\blinux/)
115
- end
116
-
117
- def macos?
118
- !!(RbConfig::CONFIG['host_os'].downcase =~ /\bdarwin/)
119
- end
120
-
121
124
  def platform
122
125
  RUBY_PLATFORM
123
126
  end
@@ -427,6 +430,20 @@ EOT
427
430
  {retry_writes: retry_writes?}
428
431
  end
429
432
 
433
+ # The options needed for a successful socket connection to the server(s).
434
+ # These exclude options needed to handshake (e.g. server api parameters).
435
+ def connection_options
436
+ ssl_options
437
+ end
438
+
439
+ # The options needed for successful monitoring of the server(s).
440
+ # These exclude options needed to perform operations (e.g. credentials).
441
+ def monitoring_options
442
+ ssl_options.merge(
443
+ server_api: ruby_options[:server_api],
444
+ )
445
+ end
446
+
430
447
  # Base test options.
431
448
  def base_test_options
432
449
  {
@@ -461,7 +478,9 @@ EOT
461
478
  # Uncomment to have exceptions in background threads log complete
462
479
  # backtraces.
463
480
  #bg_error_backtrace: true,
464
- }
481
+ }.merge(ruby_options).merge(
482
+ server_api: ruby_options[:server_api] && ::Utils.underscore_hash(ruby_options[:server_api])
483
+ )
465
484
  end
466
485
 
467
486
  # Options for test suite clients.
@@ -535,6 +554,18 @@ EOT
535
554
  { role: Mongo::Auth::Roles::DATABASE_ADMIN, db: 'withTransaction-tests' },
536
555
  { role: Mongo::Auth::Roles::READ_WRITE, db: 'admin' },
537
556
  { role: Mongo::Auth::Roles::DATABASE_ADMIN, db: 'admin' },
557
+ { role: Mongo::Auth::Roles::READ_WRITE, db: 'command-monitoring-tests' },
558
+ { role: Mongo::Auth::Roles::DATABASE_ADMIN, db: 'command-monitoring-tests' },
559
+ { role: Mongo::Auth::Roles::READ_WRITE, db: 'session-tests' },
560
+ { role: Mongo::Auth::Roles::DATABASE_ADMIN, db: 'session-tests' },
561
+ { role: Mongo::Auth::Roles::READ_WRITE, db: 'gridfs-tests' },
562
+ { role: Mongo::Auth::Roles::DATABASE_ADMIN, db: 'gridfs-tests' },
563
+ { role: Mongo::Auth::Roles::READ_WRITE, db: 'change-stream-tests' },
564
+ { role: Mongo::Auth::Roles::DATABASE_ADMIN, db: 'change-stream-tests' },
565
+ { role: Mongo::Auth::Roles::READ_WRITE, db: 'change-stream-tests-2' },
566
+ { role: Mongo::Auth::Roles::DATABASE_ADMIN, db: 'change-stream-tests-2' },
567
+ { role: Mongo::Auth::Roles::READ_WRITE, db: 'retryable-writes-tests' },
568
+ { role: Mongo::Auth::Roles::DATABASE_ADMIN, db: 'retryable-writes-tests' },
538
569
  ]
539
570
  )
540
571
  end
@@ -34,16 +34,43 @@ module Utils
34
34
  #
35
35
  # For example, { 'fooBar' => { 'baz' => 'bingBing', :x => 1 } } converts to
36
36
  # { :foo_bar => { :baz => :bing_bing, :x => 1 } }.
37
- def snakeize_hash(value)
38
- return underscore(value) if value.is_a?(String)
37
+ module_function def shallow_underscore_hash(value)
39
38
  return value unless value.is_a?(Hash)
40
39
 
41
40
  value.reduce({}) do |hash, (k, v)|
42
41
  hash.tap do |h|
43
- h[underscore(k)] = snakeize_hash(v)
42
+ h[underscore(k)] = v
44
43
  end
45
44
  end
46
45
  end
46
+
47
+ # Creates a copy of a hash where all keys and string values are converted to
48
+ # snake-case symbols.
49
+ #
50
+ # For example, { 'fooBar' => { 'baz' => 'bingBing', :x => 1 } } converts to
51
+ # { :foo_bar => { :baz => :bing_bing, :x => 1 } }.
52
+ def snakeize_hash(value)
53
+ return underscore(value) if value.is_a?(String)
54
+ case value
55
+ when Array
56
+ value.map do |sub|
57
+ case sub
58
+ when Hash
59
+ snakeize_hash(sub)
60
+ else
61
+ sub
62
+ end
63
+ end
64
+ when Hash
65
+ value.reduce({}) do |hash, (k, v)|
66
+ hash.tap do |h|
67
+ h[underscore(k)] = snakeize_hash(v)
68
+ end
69
+ end
70
+ else
71
+ value
72
+ end
73
+ end
47
74
  module_function :snakeize_hash
48
75
 
49
76
  # Like snakeize_hash but does not recurse.
@@ -380,6 +407,40 @@ module Utils
380
407
  end
381
408
  module_function :match_with_type?
382
409
 
410
+ # Takes a timeout and a block. Waits up to the specified timeout until
411
+ # the value of the block is true. If timeout is reached, this method
412
+ # returns normally and does not raise an exception. The block is invoked
413
+ # every second or so.
414
+ module_function def wait_for_condition(timeout)
415
+ deadline = Process.clock_gettime(Process::CLOCK_MONOTONIC) + timeout
416
+ loop do
417
+ if yield
418
+ break
419
+ end
420
+ if Process.clock_gettime(Process::CLOCK_MONOTONIC) > deadline
421
+ break
422
+ end
423
+ sleep 1
424
+ end
425
+ end
426
+
427
+ module_function def ensure_port_free(port)
428
+ TCPServer.open(port) do
429
+ # Nothing
430
+ end
431
+ end
432
+
433
+ module_function def wait_for_port_free(port, timeout)
434
+ wait_for_condition(timeout) do
435
+ begin
436
+ ensure_port_free(port)
437
+ true
438
+ rescue Errno::EADDRINUSE
439
+ false
440
+ end
441
+ end
442
+ end
443
+
383
444
  module_function def get_ec2_metadata_token(ttl: 30, http: nil)
384
445
  http ||= Net::HTTP.new('169.254.169.254')
385
446
  req = Net::HTTP::Put.new('/latest/api/token',
data.tar.gz.sig CHANGED
Binary file