mongo 2.10.5 → 2.11.0.rc0

Sign up to get free protection for your applications and to get access to all the features.
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