mongo 2.10.5 → 2.11.0.rc0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (191) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/CONTRIBUTING.md +1 -1
  5. data/lib/mongo.rb +2 -0
  6. data/lib/mongo/address.rb +4 -0
  7. data/lib/mongo/address/validator.rb +99 -0
  8. data/lib/mongo/auth.rb +7 -2
  9. data/lib/mongo/auth/user.rb +1 -7
  10. data/lib/mongo/background_thread.rb +135 -0
  11. data/lib/mongo/bulk_write/transformable.rb +3 -3
  12. data/lib/mongo/client.rb +74 -16
  13. data/lib/mongo/cluster.rb +193 -41
  14. data/lib/mongo/cluster/periodic_executor.rb +31 -43
  15. data/lib/mongo/cluster/sdam_flow.rb +26 -3
  16. data/lib/mongo/cluster/srv_monitor.rb +127 -0
  17. data/lib/mongo/collection/view/readable.rb +3 -5
  18. data/lib/mongo/collection/view/writable.rb +3 -3
  19. data/lib/mongo/cursor/builder/get_more_command.rb +1 -4
  20. data/lib/mongo/cursor/builder/kill_cursors_command.rb +5 -23
  21. data/lib/mongo/cursor/builder/op_get_more.rb +2 -2
  22. data/lib/mongo/cursor/builder/op_kill_cursors.rb +5 -24
  23. data/lib/mongo/error.rb +1 -0
  24. data/lib/mongo/error/auth_error.rb +1 -1
  25. data/lib/mongo/error/connection_check_out_timeout.rb +7 -8
  26. data/lib/mongo/error/invalid_address.rb +24 -0
  27. data/lib/mongo/error/notable.rb +2 -2
  28. data/lib/mongo/error/operation_failure.rb +3 -3
  29. data/lib/mongo/error/pool_closed_error.rb +11 -4
  30. data/lib/mongo/event.rb +1 -1
  31. data/lib/mongo/grid/file.rb +0 -5
  32. data/lib/mongo/grid/file/chunk.rb +0 -2
  33. data/lib/mongo/grid/fs_bucket.rb +13 -15
  34. data/lib/mongo/grid/stream/write.rb +3 -9
  35. data/lib/mongo/loggable.rb +5 -1
  36. data/lib/mongo/monitoring.rb +1 -0
  37. data/lib/mongo/monitoring/event/cmap/connection_check_out_failed.rb +7 -0
  38. data/lib/mongo/monitoring/event/cmap/connection_checked_in.rb +11 -3
  39. data/lib/mongo/monitoring/event/cmap/connection_checked_out.rb +11 -3
  40. data/lib/mongo/monitoring/event/cmap/pool_closed.rb +11 -3
  41. data/lib/mongo/monitoring/event/cmap/pool_created.rb +12 -3
  42. data/lib/mongo/monitoring/unified_sdam_log_subscriber.rb +62 -0
  43. data/lib/mongo/operation/shared/executable.rb +5 -10
  44. data/lib/mongo/operation/shared/sessions_supported.rb +1 -5
  45. data/lib/mongo/protocol/get_more.rb +1 -2
  46. data/lib/mongo/protocol/kill_cursors.rb +13 -6
  47. data/lib/mongo/protocol/serializers.rb +4 -20
  48. data/lib/mongo/retryable.rb +9 -34
  49. data/lib/mongo/semaphore.rb +1 -1
  50. data/lib/mongo/server.rb +113 -42
  51. data/lib/mongo/server/connection.rb +12 -5
  52. data/lib/mongo/server/connection_pool.rb +250 -40
  53. data/lib/mongo/server/connection_pool/populator.rb +58 -0
  54. data/lib/mongo/server/description.rb +9 -2
  55. data/lib/mongo/server/monitor.rb +68 -93
  56. data/lib/mongo/server/monitor/connection.rb +2 -0
  57. data/lib/mongo/server_selector/selectable.rb +13 -5
  58. data/lib/mongo/session.rb +0 -13
  59. data/lib/mongo/srv.rb +17 -0
  60. data/lib/mongo/srv/monitor.rb +96 -0
  61. data/lib/mongo/srv/resolver.rb +130 -0
  62. data/lib/mongo/srv/result.rb +126 -0
  63. data/lib/mongo/srv/warning_result.rb +35 -0
  64. data/lib/mongo/uri.rb +45 -55
  65. data/lib/mongo/uri/srv_protocol.rb +89 -42
  66. data/lib/mongo/version.rb +1 -1
  67. data/mongo.gemspec +3 -4
  68. data/spec/README.md +6 -1
  69. data/spec/enterprise_auth/kerberos_spec.rb +7 -6
  70. data/spec/integration/change_stream_examples_spec.rb +0 -4
  71. data/spec/integration/client_construction_spec.rb +14 -2
  72. data/spec/integration/connect_single_rs_name_spec.rb +2 -2
  73. data/spec/integration/connection_pool_populator_spec.rb +296 -0
  74. data/spec/integration/connection_spec.rb +31 -22
  75. data/spec/integration/cursor_reaping_spec.rb +1 -2
  76. data/spec/integration/docs_examples_spec.rb +0 -4
  77. data/spec/integration/heartbeat_events_spec.rb +17 -15
  78. data/spec/integration/reconnect_spec.rb +144 -1
  79. data/spec/integration/retryable_writes_errors_spec.rb +0 -4
  80. data/spec/integration/retryable_writes_spec.rb +36 -36
  81. data/spec/integration/sdam_error_handling_spec.rb +31 -25
  82. data/spec/integration/sdam_events_spec.rb +2 -6
  83. data/spec/integration/server_monitor_spec.rb +28 -0
  84. data/spec/integration/server_selector_spec.rb +7 -5
  85. data/spec/integration/srv_monitoring_spec.rb +360 -0
  86. data/spec/integration/step_down_spec.rb +4 -6
  87. data/spec/lite_spec_helper.rb +22 -0
  88. data/spec/mongo/address/validator_spec.rb +51 -0
  89. data/spec/mongo/auth/cr_spec.rb +1 -29
  90. data/spec/mongo/auth/ldap_spec.rb +1 -29
  91. data/spec/mongo/auth/scram/conversation_spec.rb +0 -2
  92. data/spec/mongo/auth/scram/negotiation_spec.rb +1 -1
  93. data/spec/mongo/auth/scram_spec.rb +1 -29
  94. data/spec/mongo/auth/user/view_spec.rb +1 -36
  95. data/spec/mongo/auth/user_spec.rb +0 -12
  96. data/spec/mongo/auth/x509_spec.rb +1 -29
  97. data/spec/mongo/bulk_write_spec.rb +2 -2
  98. data/spec/mongo/client_construction_spec.rb +56 -15
  99. data/spec/mongo/client_spec.rb +31 -27
  100. data/spec/mongo/cluster/periodic_executor_spec.rb +16 -0
  101. data/spec/mongo/cluster/srv_monitor_spec.rb +214 -0
  102. data/spec/mongo/cluster/topology/replica_set_spec.rb +16 -11
  103. data/spec/mongo/cluster/topology/sharded_spec.rb +12 -9
  104. data/spec/mongo/cluster/topology/single_spec.rb +20 -11
  105. data/spec/mongo/cluster_spec.rb +45 -29
  106. data/spec/mongo/collection/view/map_reduce_spec.rb +14 -9
  107. data/spec/mongo/collection/view/readable_spec.rb +0 -16
  108. data/spec/mongo/collection_spec.rb +0 -44
  109. data/spec/mongo/cursor/builder/get_more_command_spec.rb +2 -4
  110. data/spec/mongo/cursor/builder/op_get_more_spec.rb +2 -4
  111. data/spec/mongo/cursor_spec.rb +27 -7
  112. data/spec/mongo/monitoring/event/cmap/connection_checked_in_spec.rb +10 -3
  113. data/spec/mongo/monitoring/event/cmap/connection_checked_out_spec.rb +10 -3
  114. data/spec/mongo/monitoring/event/cmap/pool_closed_spec.rb +10 -3
  115. data/spec/mongo/monitoring/event/cmap/pool_created_spec.rb +10 -3
  116. data/spec/mongo/operation/delete/op_msg_spec.rb +17 -8
  117. data/spec/mongo/operation/insert/op_msg_spec.rb +50 -35
  118. data/spec/mongo/operation/update/op_msg_spec.rb +14 -7
  119. data/spec/mongo/retryable_spec.rb +52 -31
  120. data/spec/mongo/server/app_metadata_spec.rb +0 -8
  121. data/spec/mongo/server/connection_auth_spec.rb +5 -2
  122. data/spec/mongo/server/connection_pool/populator_spec.rb +101 -0
  123. data/spec/mongo/server/connection_pool_spec.rb +256 -107
  124. data/spec/mongo/server/connection_spec.rb +22 -33
  125. data/spec/mongo/server/description_spec.rb +42 -4
  126. data/spec/mongo/server/monitor/connection_spec.rb +22 -11
  127. data/spec/mongo/server/monitor_spec.rb +66 -107
  128. data/spec/mongo/server_spec.rb +82 -60
  129. data/spec/mongo/session/session_pool_spec.rb +1 -5
  130. data/spec/mongo/session_spec.rb +0 -4
  131. data/spec/mongo/socket/ssl_spec.rb +2 -2
  132. data/spec/mongo/srv/monitor_spec.rb +211 -0
  133. data/spec/mongo/srv/result_spec.rb +54 -0
  134. data/spec/mongo/uri/srv_protocol_spec.rb +30 -15
  135. data/spec/mongo/uri_spec.rb +125 -4
  136. data/spec/spec_helper.rb +6 -0
  137. data/spec/spec_tests/auth_spec.rb +39 -0
  138. data/spec/spec_tests/cmap_spec.rb +55 -8
  139. data/spec/spec_tests/connection_string_spec.rb +6 -31
  140. data/spec/spec_tests/data/auth/connection-string.yml +297 -0
  141. data/spec/spec_tests/data/cmap/pool-checkout-error-closed.yml +4 -1
  142. data/spec/spec_tests/data/cmap/pool-create-with-options.yml +1 -0
  143. data/spec/spec_tests/data/command_monitoring/insertMany.yml +1 -1
  144. data/spec/spec_tests/data/connection_string/invalid-uris.yml +20 -0
  145. data/spec/spec_tests/data/connection_string/valid-auth.yml +16 -0
  146. data/spec/spec_tests/data/connection_string/valid-warnings.yml +26 -30
  147. data/spec/spec_tests/data/transactions/abort.yml +3 -3
  148. data/spec/spec_tests/data/transactions/error-labels.yml +3 -3
  149. data/spec/spec_tests/data/transactions_api/callback-retry.yml +3 -3
  150. data/spec/spec_tests/data/uri_options/auth-options.yml +1 -1
  151. data/spec/spec_tests/max_staleness_spec.rb +7 -2
  152. data/spec/spec_tests/retryable_reads_spec.rb +0 -31
  153. data/spec/spec_tests/sdam_monitoring_spec.rb +12 -12
  154. data/spec/spec_tests/sdam_spec.rb +4 -7
  155. data/spec/spec_tests/server_selection_spec.rb +6 -2
  156. data/spec/spec_tests/transactions_spec.rb +0 -2
  157. data/spec/spec_tests/uri_options_spec.rb +4 -2
  158. data/spec/stress/connection_pool_stress_spec.rb +203 -0
  159. data/spec/stress/connection_pool_timing_spec.rb +181 -0
  160. data/spec/support/auth.rb +113 -0
  161. data/spec/support/background_thread_registry.rb +63 -0
  162. data/spec/support/client_registry.rb +11 -2
  163. data/spec/support/cluster_config.rb +65 -46
  164. data/spec/support/cluster_tools.rb +2 -2
  165. data/spec/support/cmap.rb +13 -14
  166. data/spec/support/cmap/verifier.rb +4 -5
  167. data/spec/support/command_monitoring.rb +0 -5
  168. data/spec/support/common_shortcuts.rb +101 -1
  169. data/spec/support/constraints.rb +25 -0
  170. data/spec/support/dns.rb +13 -0
  171. data/spec/support/event_subscriber.rb +0 -7
  172. data/spec/support/json_ext_formatter.rb +5 -1
  173. data/spec/support/lite_constraints.rb +22 -6
  174. data/spec/support/local_resource_registry.rb +34 -0
  175. data/spec/support/sdam_monitoring.rb +115 -0
  176. data/spec/support/spec_config.rb +20 -6
  177. data/spec/support/spec_setup.rb +2 -2
  178. data/spec/support/transactions.rb +1 -1
  179. data/spec/support/transactions/test.rb +1 -1
  180. data/spec/support/utils.rb +1 -16
  181. metadata +685 -659
  182. metadata.gz.sig +0 -0
  183. data/lib/mongo/event/description_changed.rb +0 -52
  184. data/spec/integration/bson_symbol_spec.rb +0 -34
  185. data/spec/integration/crud_spec.rb +0 -45
  186. data/spec/integration/get_more_spec.rb +0 -32
  187. data/spec/integration/grid_fs_bucket_spec.rb +0 -48
  188. data/spec/integration/retryable_errors_spec.rb +0 -265
  189. data/spec/integration/size_limit_spec.rb~12e1e9c4f... RUBY-2242 Fix zlib compression (#2021) +0 -98
  190. data/spec/mongo/cursor/builder/op_kill_cursors_spec.rb +0 -56
  191. data/spec/runners/sdam/verifier.rb +0 -88
@@ -0,0 +1,54 @@
1
+ require 'lite_spec_helper'
2
+
3
+ describe Mongo::Srv::Result do
4
+ let(:result) do
5
+ described_class.new('bar.com')
6
+ end
7
+
8
+ describe '#add_record' do
9
+ context 'when incoming hostname is in mixed case' do
10
+ let(:record) do
11
+ double('record').tap do |record|
12
+ allow(record).to receive(:target).and_return('FOO.bar.COM')
13
+ allow(record).to receive(:port).and_return(42)
14
+ allow(record).to receive(:ttl).and_return(1)
15
+ end
16
+ end
17
+
18
+ it 'stores hostname in lower case' do
19
+ result.add_record(record)
20
+ expect(result.address_strs).to eq(['foo.bar.com:42'])
21
+ end
22
+ end
23
+ end
24
+
25
+ describe '#normalize_hostname' do
26
+ let(:actual) do
27
+ result.send(:normalize_hostname, hostname)
28
+ end
29
+
30
+ context 'when hostname is in mixed case' do
31
+ let(:hostname) { 'FOO.bar.COM' }
32
+
33
+ it 'converts to lower case' do
34
+ expect(actual).to eq('foo.bar.com')
35
+ end
36
+ end
37
+
38
+ context 'when hostname has one trailing dot' do
39
+ let(:hostname) { 'foo.' }
40
+
41
+ it 'removes the trailing dot' do
42
+ expect(actual).to eq('foo')
43
+ end
44
+ end
45
+
46
+ context 'when hostname has multiple trailing dots' do
47
+ let(:hostname) { 'foo..' }
48
+
49
+ it 'returns hostname unchanged' do
50
+ expect(actual).to eq('foo..')
51
+ end
52
+ end
53
+ end
54
+ end
@@ -1,4 +1,4 @@
1
- require 'lite_spec_helper'
1
+ require 'spec_helper'
2
2
 
3
3
  describe Mongo::URI::SRVProtocol do
4
4
  clean_slate_for_all
@@ -588,7 +588,11 @@ describe Mongo::URI::SRVProtocol do
588
588
  end
589
589
 
590
590
  context 'auth mechanism provided' do
591
- let(:options) { "authMechanism=#{mechanism}" }
591
+ let(:options) { "authMechanism=#{mechanism}" }
592
+ let(:string) { "#{scheme}#{credentials}@#{servers}/?#{options}" }
593
+ let(:user) { 'tyler' }
594
+ let(:password) { 's3kr4t' }
595
+ let(:credentials) { "#{user}:#{password}" }
592
596
 
593
597
  context 'plain' do
594
598
  let(:mechanism) { 'PLAIN' }
@@ -603,7 +607,8 @@ describe Mongo::URI::SRVProtocol do
603
607
  end
604
608
 
605
609
  it 'is case-insensitive' do
606
- expect(new_local_client(string.downcase).options[:auth_mech]).to eq(expected)
610
+ client = new_local_client_nmio(string.downcase)
611
+ expect(client.options[:auth_mech]).to eq(expected)
607
612
  end
608
613
  end
609
614
 
@@ -620,13 +625,17 @@ describe Mongo::URI::SRVProtocol do
620
625
  end
621
626
 
622
627
  it 'is case-insensitive' do
623
- expect(new_local_client(string.downcase).options[:auth_mech]).to eq(expected)
628
+ client = new_local_client_nmio(string.downcase)
629
+ expect(client.options[:auth_mech]).to eq(expected)
624
630
  end
625
631
  end
626
632
 
627
633
  context 'gssapi' do
634
+ require_mongo_kerberos
635
+
628
636
  let(:mechanism) { 'GSSAPI' }
629
- let(:expected) { :gssapi }
637
+ let(:expected) { :gssapi }
638
+ let(:options) { "authMechanism=#{mechanism}&authSource=$external" }
630
639
 
631
640
  it 'sets the auth mechanism to :gssapi' do
632
641
  expect(uri.uri_options[:auth_mech]).to eq(expected)
@@ -637,7 +646,8 @@ describe Mongo::URI::SRVProtocol do
637
646
  end
638
647
 
639
648
  it 'is case-insensitive' do
640
- expect(new_local_client(string.downcase).options[:auth_mech]).to eq(expected)
649
+ client = new_local_client_nmio(string.downcase)
650
+ expect(client.options[:auth_mech]).to eq(expected)
641
651
  end
642
652
  end
643
653
 
@@ -654,13 +664,16 @@ describe Mongo::URI::SRVProtocol do
654
664
  end
655
665
 
656
666
  it 'is case-insensitive' do
657
- expect(new_local_client(string.downcase).options[:auth_mech]).to eq(expected)
667
+ client = new_local_client_nmio(string.downcase)
668
+ expect(client.options[:auth_mech]).to eq(expected)
658
669
  end
659
670
  end
660
671
 
661
672
  context 'mongodb-x509' do
662
- let(:mechanism) { 'MONGODB-X509' }
663
- let(:expected) { :mongodb_x509 }
673
+ let(:options) { "authMechanism=#{mechanism}&authSource=$external" }
674
+ let(:mechanism) { 'MONGODB-X509' }
675
+ let(:expected) { :mongodb_x509 }
676
+ let(:credentials) { user }
664
677
 
665
678
  it 'sets the auth mechanism to :mongodb_x509' do
666
679
  expect(uri.uri_options[:auth_mech]).to eq(expected)
@@ -671,14 +684,16 @@ describe Mongo::URI::SRVProtocol do
671
684
  end
672
685
 
673
686
  it 'is case-insensitive' do
674
- expect(new_local_client(string.downcase).options[:auth_mech]).to eq(expected)
687
+ client = new_local_client_nmio(string.downcase)
688
+ expect(client.options[:auth_mech]).to eq(expected)
675
689
  end
676
690
 
677
691
  context 'when a username is not provided' do
678
-
692
+ let(:string) { "#{scheme}#{servers}/?#{options}" }
679
693
  it 'recognizes the mechanism with no username' do
680
- expect(new_local_client(string.downcase).options[:auth_mech]).to eq(expected)
681
- expect(new_local_client(string.downcase).options[:user]).to be_nil
694
+ client = new_local_client_nmio(string.downcase)
695
+ expect(client.options[:auth_mech]).to eq(expected)
696
+ expect(client.options[:user]).to be_nil
682
697
  end
683
698
  end
684
699
  end
@@ -947,7 +962,7 @@ describe Mongo::URI::SRVProtocol do
947
962
  end
948
963
  end
949
964
 
950
- describe '#validate_hostname' do
965
+ describe '#validate_srv_hostname' do
951
966
  let(:valid_hostname) do
952
967
  end
953
968
 
@@ -956,7 +971,7 @@ describe Mongo::URI::SRVProtocol do
956
971
  end
957
972
 
958
973
  let(:validate) do
959
- dummy_uri.send(:validate_hostname, hostname)
974
+ dummy_uri.send(:validate_srv_hostname, hostname)
960
975
  end
961
976
 
962
977
  context 'when the hostname is valid' do
@@ -352,7 +352,7 @@ describe Mongo::URI do
352
352
  let(:servers) { '%2Ftmp%2Fmongodb-27017.sock' }
353
353
 
354
354
  it 'returns an array with the parsed server' do
355
- expect(uri.servers).to eq([URI::DEFAULT_PARSER.unescape(servers)])
355
+ expect(uri.servers).to eq([URI.unescape(servers)])
356
356
  end
357
357
  end
358
358
 
@@ -703,7 +703,11 @@ describe Mongo::URI do
703
703
  end
704
704
 
705
705
  context 'auth mechanism provided' do
706
- let(:options) { "authMechanism=#{mechanism}" }
706
+ let(:string) { "#{scheme}#{credentials}@#{servers}/?#{options}" }
707
+ let(:user) { 'tyler' }
708
+ let(:password) { 's3kr4t' }
709
+ let(:credentials) { "#{user}:#{password}" }
710
+ let(:options) { "authMechanism=#{mechanism}" }
707
711
 
708
712
  context 'plain' do
709
713
  let(:mechanism) { 'PLAIN' }
@@ -722,6 +726,16 @@ describe Mongo::URI do
722
726
  client = new_local_client_nmio(string.downcase)
723
727
  expect(client.options[:auth_mech]).to eq(expected)
724
728
  end
729
+
730
+ context 'when mechanism_properties are provided' do
731
+ let(:options) { "authMechanism=#{mechanism}&authMechanismProperties=CANONICALIZE_HOST_NAME:true" }
732
+
733
+ it 'does not allow a client to be created' do
734
+ expect {
735
+ new_local_client_nmio(string)
736
+ }.to raise_error(Mongo::Auth::InvalidConfiguration, /mechanism_properties are not supported/)
737
+ end
738
+ end
725
739
  end
726
740
 
727
741
  context 'mongodb-cr' do
@@ -741,9 +755,21 @@ describe Mongo::URI do
741
755
  client = new_local_client_nmio(string.downcase)
742
756
  expect(client.options[:auth_mech]).to eq(expected)
743
757
  end
758
+
759
+ context 'when mechanism_properties are provided' do
760
+ let(:options) { "authMechanism=#{mechanism}&authMechanismProperties=CANONICALIZE_HOST_NAME:true" }
761
+
762
+ it 'does not allow a client to be created' do
763
+ expect {
764
+ new_local_client_nmio(string)
765
+ }.to raise_error(Mongo::Auth::InvalidConfiguration, /mechanism_properties are not supported/)
766
+ end
767
+ end
744
768
  end
745
769
 
746
770
  context 'gssapi' do
771
+ require_mongo_kerberos
772
+
747
773
  let(:mechanism) { 'GSSAPI' }
748
774
  let(:expected) { :gssapi }
749
775
 
@@ -760,6 +786,25 @@ describe Mongo::URI do
760
786
  client = new_local_client_nmio(string.downcase)
761
787
  expect(client.options[:auth_mech]).to eq(expected)
762
788
  end
789
+
790
+ context 'when auth source is invalid' do
791
+ let(:options) { "authMechanism=#{mechanism}&authSource=foo" }
792
+
793
+ it 'does not allow a client to be created' do
794
+ expect {
795
+ new_local_client_nmio(string)
796
+ }.to raise_error(Mongo::Auth::InvalidConfiguration, /invalid auth source/)
797
+ end
798
+ end
799
+
800
+ context 'when mechanism_properties are provided' do
801
+ let(:options) { "authMechanism=#{mechanism}&authMechanismProperties=SERVICE_NAME:other,CANONICALIZE_HOST_NAME:true" }
802
+
803
+ it 'sets the options on a client created with the uri' do
804
+ client = new_local_client_nmio(string)
805
+ expect(client.options[:auth_mech_properties]).to eq({ 'canonicalize_host_name' => true, 'service_name' => 'other' })
806
+ end
807
+ end
763
808
  end
764
809
 
765
810
  context 'scram-sha-1' do
@@ -779,11 +824,22 @@ describe Mongo::URI do
779
824
  client = new_local_client_nmio(string.downcase)
780
825
  expect(client.options[:auth_mech]).to eq(expected)
781
826
  end
827
+
828
+ context 'when mechanism_properties are provided' do
829
+ let(:options) { "authMechanism=#{mechanism}&authMechanismProperties=CANONICALIZE_HOST_NAME:true" }
830
+
831
+ it 'does not allow a client to be created' do
832
+ expect {
833
+ new_local_client_nmio(string)
834
+ }.to raise_error(Mongo::Auth::InvalidConfiguration, /mechanism_properties are not supported/)
835
+ end
836
+ end
782
837
  end
783
838
 
784
839
  context 'mongodb-x509' do
785
840
  let(:mechanism) { 'MONGODB-X509' }
786
- let(:expected) { :mongodb_x509 }
841
+ let(:expected) { :mongodb_x509 }
842
+ let(:credentials) { user }
787
843
 
788
844
  it 'sets the auth mechanism to :mongodb_x509' do
789
845
  expect(uri.uri_options[:auth_mech]).to eq(expected)
@@ -799,7 +855,18 @@ describe Mongo::URI do
799
855
  expect(client.options[:auth_mech]).to eq(expected)
800
856
  end
801
857
 
858
+ context 'when auth source is invalid' do
859
+ let(:options) { "authMechanism=#{mechanism}&authSource=foo" }
860
+
861
+ it 'does not allow a client to be created' do
862
+ expect {
863
+ new_local_client_nmio(string)
864
+ }.to raise_error(Mongo::Auth::InvalidConfiguration, /invalid auth source/)
865
+ end
866
+ end
867
+
802
868
  context 'when a username is not provided' do
869
+ let(:string) { "#{scheme}#{servers}/?#{options}" }
803
870
 
804
871
  it 'recognizes the mechanism with no username' do
805
872
  client = new_local_client_nmio(string.downcase)
@@ -807,6 +874,61 @@ describe Mongo::URI do
807
874
  expect(client.options[:user]).to be_nil
808
875
  end
809
876
  end
877
+
878
+ context 'when a password is provided' do
879
+ let(:credentials) { "#{user}:#{password}"}
880
+ let(:password) { 's3kr4t' }
881
+
882
+ it 'does not allow a client to be created' do
883
+ expect {
884
+ new_local_client_nmio(string)
885
+ }.to raise_error(Mongo::Auth::InvalidConfiguration, /password is not supported/)
886
+ end
887
+ end
888
+
889
+ context 'when mechanism_properties are provided' do
890
+ let(:options) { "authMechanism=#{mechanism}&authMechanismProperties=CANONICALIZE_HOST_NAME:true" }
891
+
892
+ it 'does not allow a client to be created' do
893
+ expect {
894
+ new_local_client_nmio(string)
895
+ }.to raise_error(Mongo::Auth::InvalidConfiguration, /mechanism_properties are not supported/)
896
+ end
897
+ end
898
+ end
899
+ end
900
+
901
+ context 'auth mechanism is not provided' do
902
+ let(:string) { "#{scheme}#{credentials}@#{servers}/" }
903
+
904
+ context 'with no credentials' do
905
+ let(:string) { "#{scheme}#{servers}/" }
906
+
907
+ it 'sets user and password as nil' do
908
+ expect(uri.credentials[:user]).to be_nil
909
+ expect(uri.credentials[:password]).to be_nil
910
+ end
911
+
912
+ it 'sets the options on a client created with the uri' do
913
+ client = new_local_client_nmio(string)
914
+ expect(client.options[:user]).to be_nil
915
+ expect(client.options[:password]).to be_nil
916
+ end
917
+ end
918
+
919
+ context 'with empty credentials' do
920
+ let(:credentials) { '' }
921
+
922
+ it 'sets user as an empty string and password as nil' do
923
+ expect(uri.credentials[:user]).to eq('')
924
+ expect(uri.credentials[:password]).to be_nil
925
+ end
926
+
927
+ it 'does not allow a client to be created with default auth mechanism' do
928
+ expect {
929
+ new_local_client_nmio(string)
930
+ }.to raise_error(Mongo::Auth::InvalidConfiguration, /empty username is not supported/)
931
+ end
810
932
  end
811
933
  end
812
934
 
@@ -847,7 +969,6 @@ describe Mongo::URI do
847
969
  let(:options) do
848
970
  "authMechanismProperties=SERVICE_NAME:#{service_name}"
849
971
  end
850
-
851
972
  let(:service_name) { 'foo' }
852
973
  let(:expected) { Mongo::Options::Redacted.new({ service_name: service_name }) }
853
974
 
data/spec/spec_helper.rb CHANGED
@@ -12,6 +12,7 @@ require 'support/cluster_config'
12
12
  require 'support/cluster_tools'
13
13
  require 'rspec/retry'
14
14
  require 'support/monitoring_ext'
15
+ require 'support/local_resource_registry'
15
16
 
16
17
  RSpec.configure do |config|
17
18
  config.include(Authorization)
@@ -22,6 +23,11 @@ RSpec.configure do |config|
22
23
  kill_all_server_sessions
23
24
  end
24
25
  end
26
+
27
+ config.after do
28
+ LocalResourceRegistry.instance.close_all
29
+ ClientRegistry.instance.close_local_clients
30
+ end
25
31
  end
26
32
 
27
33
  # require all shared examples
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Auth' do
4
+ include Mongo::Auth
5
+
6
+ AUTH_TESTS.each do |file|
7
+ spec = Mongo::Auth::Spec.new(file)
8
+
9
+ context(spec.description) do
10
+ spec.tests.each_with_index do |test, index|
11
+ context test.description do
12
+ if test.description.downcase.include?("gssapi")
13
+ require_mongo_kerberos
14
+ end
15
+
16
+ context 'when the auth configuration is invalid', unless: test.valid? do
17
+ it 'raises an error' do
18
+ expect {
19
+ test.client
20
+ }.to raise_error(Mongo::Auth::InvalidConfiguration)
21
+ end
22
+ end
23
+
24
+ context 'when the auth configuration is valid' do
25
+ context 'with empty credentials', if: test.valid? && test.credential.nil? do
26
+ it 'creates a client with no credential information' do
27
+ expect(test.client).to have_blank_credentials
28
+ end
29
+ end
30
+
31
+ it 'creates a client with the correct credentials', if: test.valid? && test.credential do
32
+ expect(test.received_credential).to eq(test.expected_credential)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -1,6 +1,10 @@
1
- require 'lite_spec_helper'
1
+ require 'spec_helper'
2
+
3
+ # Temporary scopes in all of the tests are needed to exclude endSessions
4
+ # commands being sent during cleanup from interfering with assertions.
2
5
 
3
6
  describe 'Cmap' do
7
+ clean_slate
4
8
 
5
9
  declare_topology_double
6
10
 
@@ -8,21 +12,58 @@ describe 'Cmap' do
8
12
  double('cluster').tap do |cl|
9
13
  allow(cl).to receive(:topology).and_return(topology)
10
14
  allow(cl).to receive(:options).and_return({})
15
+ allow(cl).to receive(:app_metadata).and_return(Mongo::Server::AppMetadata.new({}))
16
+ allow(cl).to receive(:run_sdam_flow)
17
+ allow(cl).to receive(:update_cluster_time)
18
+ allow(cl).to receive(:cluster_time).and_return(nil)
11
19
  end
12
20
  end
13
21
 
22
+ let(:options) do
23
+ SpecConfig.instance.ssl_options.merge(SpecConfig.instance.compressor_options)
24
+ .merge(SpecConfig.instance.retry_writes_options).merge(SpecConfig.instance.auth_options)
25
+ .merge(monitoring_io: false)
26
+ end
27
+
14
28
  CMAP_TESTS.each do |file|
15
29
  spec = Mongo::Cmap::Spec.new(file)
16
30
 
17
31
  context("#{spec.description} (#{file.sub(%r'.*/data/cmap/', '')})") do
32
+
18
33
  before do
19
- spec.setup(cluster)
34
+ subscriber = EventSubscriber.new
35
+
36
+ monitoring = Mongo::Monitoring.new(monitoring: false)
37
+ monitoring.subscribe(Mongo::Monitoring::CONNECTION_POOL, subscriber)
38
+
39
+ @server = register_server(
40
+ Mongo::Server.new(
41
+ ClusterConfig.instance.primary_address,
42
+ cluster,
43
+ monitoring,
44
+ Mongo::Event::Listeners.new,
45
+ options.merge(spec.pool_options)
46
+ ).tap do |server|
47
+ allow(server).to receive(:description).and_return(ClusterConfig.instance.primary_description)
48
+ end
49
+ )
50
+ spec.setup(@server, subscriber)
51
+ end
52
+
53
+ after do
54
+ if @server && (pool = @server.instance_variable_get('@pool'))
55
+ begin
56
+ pool.disconnect!
57
+ rescue Mongo::Error::PoolClosedError
58
+ end
59
+ end
20
60
  end
21
61
 
22
62
  let!(:result) do
23
- mock_socket = double('socket')
24
- allow(mock_socket).to receive(:close)
25
- allow_any_instance_of(Mongo::Server::Connection).to receive(:do_connect).and_return(mock_socket)
63
+ socket = double('fake socket')
64
+ allow(socket).to receive(:close)
65
+
66
+ allow_any_instance_of(Mongo::Server::Connection).to receive(:do_connect).and_return(socket)
26
67
  spec.run
27
68
  end
28
69
 
@@ -31,18 +72,24 @@ describe 'Cmap' do
31
72
  end
32
73
 
33
74
  it 'raises the correct error' do
34
- expect(result['error']).to eq(spec.expected_error)
75
+ RSpec::Mocks.with_temporary_scope do
76
+ expect(result['error']).to eq(spec.expected_error)
77
+ end
35
78
  end
36
79
 
37
80
  let(:actual_events) { result['events'].freeze }
38
81
 
39
82
  it 'emits the correct number of events' do
40
- expect(actual_events.length).to eq(spec.expected_events.length)
83
+ RSpec::Mocks.with_temporary_scope do
84
+ expect(actual_events.length).to eq(spec.expected_events.length)
85
+ end
41
86
  end
42
87
 
43
88
  spec.expected_events.each_with_index do |expected_event, index|
44
89
  it "emits correct event #{index+1}" do
45
- verifier.verify_hashes(actual_events[index], expected_event)
90
+ RSpec::Mocks.with_temporary_scope do
91
+ verifier.verify_hashes(actual_events[index], expected_event)
92
+ end
46
93
  end
47
94
  end
48
95
  end