mongo 2.11.0.rc0 → 2.11.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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/Rakefile +2 -0
- data/lib/mongo/auth.rb +11 -2
- data/lib/mongo/auth/cr/conversation.rb +1 -1
- data/lib/mongo/auth/ldap/conversation.rb +1 -1
- data/lib/mongo/auth/scram/conversation.rb +4 -1
- data/lib/mongo/auth/user.rb +15 -1
- data/lib/mongo/auth/user/view.rb +10 -4
- data/lib/mongo/auth/x509.rb +11 -1
- data/lib/mongo/auth/x509/conversation.rb +15 -6
- data/lib/mongo/background_thread.rb +28 -13
- data/lib/mongo/client.rb +23 -15
- data/lib/mongo/collection/view/change_stream.rb +5 -1
- data/lib/mongo/collection/view/readable.rb +5 -2
- data/lib/mongo/collection/view/writable.rb +3 -1
- data/lib/mongo/cursor/builder/get_more_command.rb +4 -1
- data/lib/mongo/cursor/builder/kill_cursors_command.rb +16 -5
- data/lib/mongo/cursor/builder/op_get_more.rb +2 -2
- data/lib/mongo/cursor/builder/op_kill_cursors.rb +17 -5
- data/lib/mongo/error/operation_failure.rb +3 -3
- data/lib/mongo/monitoring/command_log_subscriber.rb +5 -3
- data/lib/mongo/monitoring/event/command_started.rb +13 -3
- data/lib/mongo/monitoring/publishable.rb +4 -2
- data/lib/mongo/operation/create_user/command.rb +1 -0
- data/lib/mongo/operation/remove_user/command.rb +1 -0
- data/lib/mongo/operation/update_user/command.rb +1 -0
- data/lib/mongo/protocol/get_more.rb +2 -1
- data/lib/mongo/protocol/kill_cursors.rb +6 -13
- data/lib/mongo/protocol/serializers.rb +10 -4
- data/lib/mongo/retryable.rb +1 -1
- data/lib/mongo/server/connection.rb +6 -2
- data/lib/mongo/server/connection_base.rb +2 -1
- data/lib/mongo/server/monitor.rb +1 -1
- data/lib/mongo/server/pending_connection.rb +6 -0
- data/lib/mongo/socket/ssl.rb +1 -1
- data/lib/mongo/uri.rb +5 -41
- data/lib/mongo/version.rb +1 -1
- data/mongo.gemspec +11 -2
- data/spec/README.md +105 -9
- data/spec/USERS.md +72 -0
- data/spec/integration/auth_spec.rb +20 -6
- data/spec/integration/client_construction_spec.rb +3 -1
- data/spec/integration/client_options_spec.rb +437 -0
- data/spec/integration/command_monitoring_spec.rb +4 -1
- data/spec/integration/connection_pool_populator_spec.rb +4 -0
- data/spec/integration/connection_spec.rb +4 -2
- data/spec/integration/cursor_reaping_spec.rb +1 -1
- data/spec/integration/get_more_spec.rb +32 -0
- data/spec/integration/retryable_errors_spec.rb +99 -0
- data/spec/integration/retryable_writes_errors_spec.rb +11 -10
- data/spec/lite_spec_helper.rb +2 -1
- data/spec/mongo/auth/scram_spec.rb +1 -0
- data/spec/mongo/auth/user/view_spec.rb +102 -1
- data/spec/mongo/auth/user_spec.rb +56 -15
- data/spec/mongo/auth/x509_spec.rb +31 -1
- data/spec/mongo/bulk_write_spec.rb +2 -2
- data/spec/mongo/collection/view/change_stream_spec.rb +2 -2
- data/spec/mongo/collection/view/readable_spec.rb +8 -4
- data/spec/mongo/cursor/builder/get_more_command_spec.rb +4 -2
- data/spec/mongo/cursor/builder/op_get_more_spec.rb +4 -2
- data/spec/mongo/cursor_spec.rb +3 -3
- data/spec/mongo/retryable_spec.rb +31 -52
- data/spec/mongo/server/connection_auth_spec.rb +3 -0
- data/spec/mongo/server/connection_pool_spec.rb +4 -0
- data/spec/mongo/server/connection_spec.rb +12 -4
- data/spec/mongo/server/monitor_spec.rb +19 -1
- data/spec/mongo/socket/ssl_spec.rb +1 -1
- data/spec/mongo/uri/srv_protocol_spec.rb +0 -13
- data/spec/mongo/uri_option_parsing_spec.rb +0 -8
- data/spec/mongo/uri_spec.rb +6 -20
- data/spec/runners/connection_string.rb +116 -0
- data/spec/runners/read_write_concern_document.rb +67 -0
- data/spec/spec_tests/change_streams_spec.rb +17 -2
- data/spec/spec_tests/connection_string_spec.rb +2 -59
- data/spec/spec_tests/data/change_streams/change-streams-errors.yml +3 -3
- data/spec/spec_tests/data/change_streams/change-streams.yml +88 -20
- data/spec/spec_tests/data/cmap/connection-must-have-id.yml +6 -0
- data/spec/spec_tests/data/cmap/connection-must-order-ids.yml +6 -0
- data/spec/spec_tests/data/cmap/pool-checkin-destroy-closed.yml +3 -0
- data/spec/spec_tests/data/cmap/pool-checkin-destroy-stale.yml +3 -0
- data/spec/spec_tests/data/cmap/pool-checkin-make-available.yml +3 -0
- data/spec/spec_tests/data/cmap/pool-checkin.yml +1 -0
- data/spec/spec_tests/data/cmap/pool-checkout-connection.yml +2 -0
- data/spec/spec_tests/data/cmap/pool-checkout-error-closed.yml +5 -0
- data/spec/spec_tests/data/cmap/pool-checkout-multiple.yml +3 -0
- data/spec/spec_tests/data/cmap/pool-checkout-no-idle.yml +4 -0
- data/spec/spec_tests/data/cmap/pool-checkout-no-stale.yml +4 -0
- data/spec/spec_tests/data/cmap/pool-close-destroy-conns.yml +2 -0
- data/spec/spec_tests/data/cmap/pool-create-max-size.yml +15 -0
- data/spec/spec_tests/data/cmap/pool-create-min-size.yml +4 -0
- data/spec/spec_tests/data/cmap/wait-queue-fairness.yml +31 -1
- data/spec/spec_tests/data/cmap/wait-queue-timeout.yml +5 -0
- data/spec/spec_tests/data/read_write_concern/connection-string/read-concern.yml +32 -0
- data/spec/spec_tests/data/read_write_concern/connection-string/write-concern.yml +82 -0
- data/spec/spec_tests/data/read_write_concern/document/read-concern.yml +37 -0
- data/spec/spec_tests/data/read_write_concern/document/write-concern.yml +100 -0
- data/spec/spec_tests/data/retryable_reads/aggregate-merge.yml +39 -0
- data/spec/spec_tests/data/retryable_reads/aggregate-serverErrors.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/changeStreams-client.watch-serverErrors.yml +2 -2
- data/spec/spec_tests/data/retryable_reads/changeStreams-client.watch.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/changeStreams-db.coll.watch-serverErrors.yml +2 -2
- data/spec/spec_tests/data/retryable_reads/changeStreams-db.coll.watch.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/changeStreams-db.watch-serverErrors.yml +2 -2
- data/spec/spec_tests/data/retryable_reads/changeStreams-db.watch.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/count-serverErrors.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/countDocuments-serverErrors.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/distinct-serverErrors.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/estimatedDocumentCount-serverErrors.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/find-serverErrors.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/findOne-serverErrors.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/gridfs-download-serverErrors.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/gridfs-downloadByName-serverErrors.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/listCollectionNames-serverErrors.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/listCollectionObjects-serverErrors.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/listCollections-serverErrors.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/listDatabaseNames-serverErrors.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/listDatabaseObjects-serverErrors.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/listDatabases-serverErrors.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/listIndexNames-serverErrors.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/listIndexes-serverErrors.yml +1 -1
- data/spec/spec_tests/data/transactions/read-concern.yml +6 -6
- data/spec/spec_tests/data/transactions/transaction-options-repl.yml +117 -0
- data/spec/spec_tests/data/transactions/transaction-options.yml +14 -121
- data/spec/spec_tests/data/transactions/write-concern.yml +3 -0
- data/spec/spec_tests/data/transactions_api/transaction-options.yml +11 -12
- data/spec/spec_tests/dns_seedlist_discovery_spec.rb +17 -7
- data/spec/spec_tests/read_write_concern_connection_string_spec.rb +8 -0
- data/spec/spec_tests/read_write_concern_document_spec.rb +74 -0
- data/spec/spec_tests/retryable_reads_spec.rb +32 -1
- data/spec/spec_tests/uri_options_spec.rb +4 -2
- data/spec/support/auth.rb +5 -14
- data/spec/support/certificates/client-x509.crt +78 -0
- data/spec/support/certificates/client-x509.key +27 -0
- data/spec/support/certificates/client-x509.pem +105 -0
- data/spec/support/change_streams.rb +8 -11
- data/spec/support/client_registry.rb +26 -12
- data/spec/support/cluster_tools.rb +2 -2
- data/spec/support/cmap.rb +11 -7
- data/spec/support/command_monitoring.rb +8 -8
- data/spec/support/connection_string.rb +56 -28
- data/spec/support/constraints.rb +8 -0
- data/spec/support/crud/spec.rb +5 -8
- data/spec/support/event_subscriber.rb +7 -0
- data/spec/support/gridfs.rb +4 -7
- data/spec/support/server_discovery_and_monitoring.rb +3 -8
- data/spec/support/server_selection.rb +4 -9
- data/spec/support/server_selection_rtt.rb +4 -7
- data/spec/support/spec_config.rb +47 -19
- data/spec/support/spec_setup.rb +5 -0
- data/spec/support/utils.rb +46 -8
- metadata +637 -597
- metadata.gz.sig +0 -0
| @@ -11,10 +11,40 @@ describe Mongo::Auth::X509 do | |
| 11 11 | 
             
              end
         | 
| 12 12 |  | 
| 13 13 | 
             
              let(:user) do
         | 
| 14 | 
            -
                Mongo::Auth::User.new(database:  | 
| 14 | 
            +
                Mongo::Auth::User.new(database: '$external')
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              describe '#initialize' do
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                context 'when user specifies database $external' do
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                  let(:user) do
         | 
| 22 | 
            +
                    Mongo::Auth::User.new(database: '$external')
         | 
| 23 | 
            +
                  end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                  it 'works' do
         | 
| 26 | 
            +
                    described_class.new(user)
         | 
| 27 | 
            +
                  end
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                context 'when user specifies database other than $external' do
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                  let(:user) do
         | 
| 33 | 
            +
                    Mongo::Auth::User.new(database: 'foo')
         | 
| 34 | 
            +
                  end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                  it 'raises InvalidConfiguration' do
         | 
| 37 | 
            +
                    expect do
         | 
| 38 | 
            +
                      described_class.new(user)
         | 
| 39 | 
            +
                    end.to raise_error(Mongo::Auth::InvalidConfiguration, /User specifies auth source 'foo', but the only valid auth source for X.509 is '\$external'/)
         | 
| 40 | 
            +
                  end
         | 
| 41 | 
            +
                end
         | 
| 15 42 | 
             
              end
         | 
| 16 43 |  | 
| 17 44 | 
             
              describe '#login' do
         | 
| 45 | 
            +
                # When x509 auth is configured, the login would work and this test
         | 
| 46 | 
            +
                # requires the login to fail.
         | 
| 47 | 
            +
                require_no_x509_auth
         | 
| 18 48 |  | 
| 19 49 | 
             
                context 'when the user is not authorized for the database' do
         | 
| 20 50 |  | 
| @@ -1924,11 +1924,11 @@ describe Mongo::BulkWrite do | |
| 1924 1924 | 
             
                        end
         | 
| 1925 1925 |  | 
| 1926 1926 | 
             
                        let(:first_txn_number) do
         | 
| 1927 | 
            -
                          started_events[-2].command['txnNumber']. | 
| 1927 | 
            +
                          started_events[-2].command['txnNumber'].value
         | 
| 1928 1928 | 
             
                        end
         | 
| 1929 1929 |  | 
| 1930 1930 | 
             
                        let(:second_txn_number) do
         | 
| 1931 | 
            -
                          started_events[-1].command['txnNumber']. | 
| 1931 | 
            +
                          started_events[-1].command['txnNumber'].value
         | 
| 1932 1932 | 
             
                        end
         | 
| 1933 1933 |  | 
| 1934 1934 | 
             
                        it 'inserts the documents' do
         | 
| @@ -118,8 +118,8 @@ describe Mongo::Collection::View::ChangeStream do | |
| 118 118 |  | 
| 119 119 | 
             
                context 'when full_document is not provided' do
         | 
| 120 120 |  | 
| 121 | 
            -
                  it " | 
| 122 | 
            -
                    expect(change_stream_document | 
| 121 | 
            +
                  it "does not set fullDocument" do
         | 
| 122 | 
            +
                    expect(change_stream_document).not_to have_key(:fullDocument)
         | 
| 123 123 | 
             
                  end
         | 
| 124 124 | 
             
                end
         | 
| 125 125 |  | 
| @@ -641,8 +641,10 @@ describe Mongo::Collection::View::Readable do | |
| 641 641 | 
             
                      view.distinct(nil)
         | 
| 642 642 | 
             
                    end
         | 
| 643 643 |  | 
| 644 | 
            -
                    it ' | 
| 645 | 
            -
                      expect | 
| 644 | 
            +
                    it 'raises ArgumentError' do
         | 
| 645 | 
            +
                      expect do
         | 
| 646 | 
            +
                        distinct
         | 
| 647 | 
            +
                      end.to raise_error(ArgumentError, 'Field name for distinct operation must be not nil')
         | 
| 646 648 | 
             
                    end
         | 
| 647 649 | 
             
                  end
         | 
| 648 650 |  | 
| @@ -696,8 +698,10 @@ describe Mongo::Collection::View::Readable do | |
| 696 698 | 
             
                      view.distinct(nil)
         | 
| 697 699 | 
             
                    end
         | 
| 698 700 |  | 
| 699 | 
            -
                    it ' | 
| 700 | 
            -
                      expect | 
| 701 | 
            +
                    it 'raises ArgumentError' do
         | 
| 702 | 
            +
                      expect do
         | 
| 703 | 
            +
                        distinct
         | 
| 704 | 
            +
                      end.to raise_error(ArgumentError, 'Field name for distinct operation must be not nil')
         | 
| 701 705 | 
             
                    end
         | 
| 702 706 | 
             
                  end
         | 
| 703 707 | 
             
                end
         | 
| @@ -5,7 +5,9 @@ describe Mongo::Cursor::Builder::GetMoreCommand do | |
| 5 5 | 
             
              describe '#specification' do
         | 
| 6 6 |  | 
| 7 7 | 
             
                let(:reply) do
         | 
| 8 | 
            -
                  Mongo::Protocol::Reply.allocate
         | 
| 8 | 
            +
                  Mongo::Protocol::Reply.allocate.tap do |reply|
         | 
| 9 | 
            +
                    allow(reply).to receive(:cursor_id).and_return(8000)
         | 
| 10 | 
            +
                  end
         | 
| 9 11 | 
             
                end
         | 
| 10 12 |  | 
| 11 13 | 
             
                let(:result) do
         | 
| @@ -54,7 +56,7 @@ describe Mongo::Cursor::Builder::GetMoreCommand do | |
| 54 56 | 
             
                  end
         | 
| 55 57 |  | 
| 56 58 | 
             
                  it 'includes getMore with cursor id' do
         | 
| 57 | 
            -
                    expect(selector[:getMore]).to eq( | 
| 59 | 
            +
                    expect(selector[:getMore]).to eq(BSON::Int64.new(8000))
         | 
| 58 60 | 
             
                  end
         | 
| 59 61 |  | 
| 60 62 | 
             
                  it 'includes the collection name' do
         | 
| @@ -5,7 +5,9 @@ describe Mongo::Cursor::Builder::OpGetMore do | |
| 5 5 | 
             
              describe '#specification' do
         | 
| 6 6 |  | 
| 7 7 | 
             
                let(:reply) do
         | 
| 8 | 
            -
                  Mongo::Protocol::Reply.allocate
         | 
| 8 | 
            +
                  Mongo::Protocol::Reply.allocate.tap do |reply|
         | 
| 9 | 
            +
                    allow(reply).to receive(:cursor_id).and_return(8000)
         | 
| 10 | 
            +
                  end
         | 
| 9 11 | 
             
                end
         | 
| 10 12 |  | 
| 11 13 | 
             
                let(:result) do
         | 
| @@ -38,7 +40,7 @@ describe Mongo::Cursor::Builder::OpGetMore do | |
| 38 40 | 
             
                end
         | 
| 39 41 |  | 
| 40 42 | 
             
                it 'includes the cursor id' do
         | 
| 41 | 
            -
                  expect(specification[:cursor_id]).to eq( | 
| 43 | 
            +
                  expect(specification[:cursor_id]).to eq(BSON::Int64.new(8000))
         | 
| 42 44 | 
             
                end
         | 
| 43 45 |  | 
| 44 46 | 
             
                it 'includes the database name' do
         | 
    
        data/spec/mongo/cursor_spec.rb
    CHANGED
    
    | @@ -318,7 +318,7 @@ describe Mongo::Cursor do | |
| 318 318 | 
             
                    Mongo::Collection::View.new(
         | 
| 319 319 | 
             
                        authorized_collection,
         | 
| 320 320 | 
             
                        {},
         | 
| 321 | 
            -
                        :batch_size => 2
         | 
| 321 | 
            +
                        :batch_size => 2,
         | 
| 322 322 | 
             
                    )
         | 
| 323 323 | 
             
                  end
         | 
| 324 324 |  | 
| @@ -329,9 +329,9 @@ describe Mongo::Cursor do | |
| 329 329 |  | 
| 330 330 | 
             
                  it 'schedules a kill cursors op' do
         | 
| 331 331 | 
             
                    cluster.instance_variable_get(:@periodic_executor).flush
         | 
| 332 | 
            -
                    expect  | 
| 332 | 
            +
                    expect do
         | 
| 333 333 | 
             
                      cursor.to_a
         | 
| 334 | 
            -
                     | 
| 334 | 
            +
                    end.to raise_exception(Mongo::Error::OperationFailure, /[cC]ursor.*not found/)
         | 
| 335 335 | 
             
                  end
         | 
| 336 336 |  | 
| 337 337 | 
             
                  context 'when the cursor is unregistered before the kill cursors operations are executed' do
         | 
| @@ -175,83 +175,62 @@ describe Mongo::Retryable do | |
| 175 175 |  | 
| 176 176 | 
             
                context 'when an operation failure occurs' do
         | 
| 177 177 |  | 
| 178 | 
            -
                  context 'when the  | 
| 178 | 
            +
                  context 'when the operation failure is not retryable' do
         | 
| 179 | 
            +
             | 
| 180 | 
            +
                    let(:error) do
         | 
| 181 | 
            +
                      Mongo::Error::OperationFailure.new('not authorized')
         | 
| 182 | 
            +
                    end
         | 
| 179 183 |  | 
| 180 184 | 
             
                    before do
         | 
| 181 | 
            -
                      expect(operation).to receive(:execute).and_raise( | 
| 182 | 
            -
                      expect(cluster).to receive(:sharded?).and_return(false)
         | 
| 185 | 
            +
                      expect(operation).to receive(:execute).and_raise(error).ordered
         | 
| 183 186 | 
             
                    end
         | 
| 184 187 |  | 
| 185 | 
            -
                    it 'raises  | 
| 188 | 
            +
                    it 'raises the exception' do
         | 
| 186 189 | 
             
                      expect {
         | 
| 187 190 | 
             
                        read_operation
         | 
| 188 191 | 
             
                      }.to raise_error(Mongo::Error::OperationFailure)
         | 
| 189 192 | 
             
                    end
         | 
| 190 193 | 
             
                  end
         | 
| 191 194 |  | 
| 192 | 
            -
                  context 'when the  | 
| 195 | 
            +
                  context 'when the operation failure is retryable' do
         | 
| 193 196 |  | 
| 194 | 
            -
                     | 
| 197 | 
            +
                    let(:error) do
         | 
| 198 | 
            +
                      Mongo::Error::OperationFailure.new('not master')
         | 
| 199 | 
            +
                    end
         | 
| 195 200 |  | 
| 196 | 
            -
             | 
| 197 | 
            -
                        Mongo::Error::OperationFailure.new('not authorized')
         | 
| 198 | 
            -
                      end
         | 
| 201 | 
            +
                    context 'when the retry succeeds' do
         | 
| 199 202 |  | 
| 200 203 | 
             
                      before do
         | 
| 204 | 
            +
                        expect(retryable).to receive(:select_server).ordered
         | 
| 201 205 | 
             
                        expect(operation).to receive(:execute).and_raise(error).ordered
         | 
| 202 | 
            -
                        expect( | 
| 206 | 
            +
                        expect(client).to receive(:read_retry_interval).and_return(0.1).ordered
         | 
| 207 | 
            +
                        expect(retryable).to receive(:select_server).ordered
         | 
| 208 | 
            +
                        expect(operation).to receive(:execute).and_return(true).ordered
         | 
| 203 209 | 
             
                      end
         | 
| 204 210 |  | 
| 205 | 
            -
                      it ' | 
| 206 | 
            -
                        expect  | 
| 207 | 
            -
                          read_operation
         | 
| 208 | 
            -
                        }.to raise_error(Mongo::Error::OperationFailure)
         | 
| 211 | 
            +
                      it 'returns the result' do
         | 
| 212 | 
            +
                        expect(read_operation).to be true
         | 
| 209 213 | 
             
                      end
         | 
| 210 214 | 
             
                    end
         | 
| 211 215 |  | 
| 212 | 
            -
                    context 'when the  | 
| 216 | 
            +
                    context 'when the retry fails once and then succeeds' do
         | 
| 217 | 
            +
                      let(:max_read_retries) { 2 }
         | 
| 213 218 |  | 
| 214 | 
            -
                       | 
| 215 | 
            -
                         | 
| 216 | 
            -
             | 
| 217 | 
            -
             | 
| 218 | 
            -
                      context 'when the retry succeeds' do
         | 
| 219 | 
            +
                      before do
         | 
| 220 | 
            +
                        expect(retryable).to receive(:select_server).ordered
         | 
| 221 | 
            +
                        expect(operation).to receive(:execute).and_raise(error).ordered
         | 
| 219 222 |  | 
| 220 | 
            -
                         | 
| 221 | 
            -
             | 
| 222 | 
            -
             | 
| 223 | 
            -
                          expect(cluster).to receive(:sharded?).and_return(true)
         | 
| 224 | 
            -
                          expect(client).to receive(:read_retry_interval).and_return(0.1).ordered
         | 
| 225 | 
            -
                          expect(retryable).to receive(:select_server).ordered
         | 
| 226 | 
            -
                          expect(operation).to receive(:execute).and_return(true).ordered
         | 
| 227 | 
            -
                        end
         | 
| 223 | 
            +
                        expect(client).to receive(:read_retry_interval).and_return(0.1).ordered
         | 
| 224 | 
            +
                        expect(retryable).to receive(:select_server).ordered
         | 
| 225 | 
            +
                        expect(operation).to receive(:execute).and_raise(error).ordered
         | 
| 228 226 |  | 
| 229 | 
            -
                         | 
| 230 | 
            -
             | 
| 231 | 
            -
                         | 
| 227 | 
            +
                        expect(client).to receive(:read_retry_interval).and_return(0.1).ordered
         | 
| 228 | 
            +
                        expect(retryable).to receive(:select_server).ordered
         | 
| 229 | 
            +
                        expect(operation).to receive(:execute).and_return(true).ordered
         | 
| 232 230 | 
             
                      end
         | 
| 233 231 |  | 
| 234 | 
            -
                       | 
| 235 | 
            -
                         | 
| 236 | 
            -
             | 
| 237 | 
            -
                        before do
         | 
| 238 | 
            -
                          expect(retryable).to receive(:select_server).ordered
         | 
| 239 | 
            -
                          expect(operation).to receive(:execute).and_raise(error).ordered
         | 
| 240 | 
            -
             | 
| 241 | 
            -
                          expect(cluster).to receive(:sharded?).and_return(true)
         | 
| 242 | 
            -
                          expect(client).to receive(:read_retry_interval).and_return(0.1).ordered
         | 
| 243 | 
            -
                          expect(retryable).to receive(:select_server).ordered
         | 
| 244 | 
            -
                          expect(operation).to receive(:execute).and_raise(error).ordered
         | 
| 245 | 
            -
             | 
| 246 | 
            -
                          expect(cluster).to receive(:sharded?).and_return(true)
         | 
| 247 | 
            -
                          expect(client).to receive(:read_retry_interval).and_return(0.1).ordered
         | 
| 248 | 
            -
                          expect(retryable).to receive(:select_server).ordered
         | 
| 249 | 
            -
                          expect(operation).to receive(:execute).and_return(true).ordered
         | 
| 250 | 
            -
                        end
         | 
| 251 | 
            -
             | 
| 252 | 
            -
                        it 'returns the result' do
         | 
| 253 | 
            -
                          expect(read_operation).to be true
         | 
| 254 | 
            -
                        end
         | 
| 232 | 
            +
                      it 'returns the result' do
         | 
| 233 | 
            +
                        expect(read_operation).to be true
         | 
| 255 234 | 
             
                      end
         | 
| 256 235 | 
             
                    end
         | 
| 257 236 | 
             
                  end
         | 
| @@ -46,6 +46,7 @@ describe Mongo::Server::Connection, retry: 3 do | |
| 46 46 | 
             
              end
         | 
| 47 47 |  | 
| 48 48 | 
             
              describe '#auth_mechanism' do
         | 
| 49 | 
            +
                require_no_x509_auth
         | 
| 49 50 |  | 
| 50 51 | 
             
                let(:connection) do
         | 
| 51 52 | 
             
                  described_class.new(server, server.options)
         | 
| @@ -87,6 +88,8 @@ describe Mongo::Server::Connection, retry: 3 do | |
| 87 88 | 
             
                end
         | 
| 88 89 |  | 
| 89 90 | 
             
                context 'when the ismaster response indicates the auth mechanism is :scram' do
         | 
| 91 | 
            +
                  require_no_x509_auth
         | 
| 92 | 
            +
             | 
| 90 93 | 
             
                  let(:features) do
         | 
| 91 94 | 
             
                    Mongo::Server::Description::Features.new(0..7)
         | 
| 92 95 | 
             
                  end
         | 
| @@ -24,6 +24,10 @@ describe Mongo::Server::ConnectionPool do | |
| 24 24 |  | 
| 25 25 | 
             
              declare_topology_double
         | 
| 26 26 |  | 
| 27 | 
            +
              let(:app_metadata) do
         | 
| 28 | 
            +
                Mongo::Server::AppMetadata.new(server_options)
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
             | 
| 27 31 | 
             
              let(:cluster) do
         | 
| 28 32 | 
             
                double('cluster').tap do |cl|
         | 
| 29 33 | 
             
                  allow(cl).to receive(:topology).and_return(topology)
         | 
| @@ -289,6 +289,7 @@ describe Mongo::Server::Connection, retry: 3 do | |
| 289 289 | 
             
                end
         | 
| 290 290 |  | 
| 291 291 | 
             
                context 'when user credentials exist' do
         | 
| 292 | 
            +
                  require_no_x509_auth
         | 
| 292 293 |  | 
| 293 294 | 
             
                  let(:server) { monitored_server }
         | 
| 294 295 |  | 
| @@ -458,9 +459,11 @@ describe Mongo::Server::Connection, retry: 3 do | |
| 458 459 | 
             
                  described_class.new(
         | 
| 459 460 | 
             
                    server,
         | 
| 460 461 | 
             
                    SpecConfig.instance.test_options.merge(
         | 
| 461 | 
            -
                      : | 
| 462 | 
            -
             | 
| 463 | 
            -
                      : | 
| 462 | 
            +
                      :database => SpecConfig.instance.test_user.database,
         | 
| 463 | 
            +
                    ).merge(SpecConfig.instance.credentials_or_x509(
         | 
| 464 | 
            +
                      user: SpecConfig.instance.test_user.name,
         | 
| 465 | 
            +
                      password: SpecConfig.instance.test_user.password,
         | 
| 466 | 
            +
                    ))
         | 
| 464 467 | 
             
                  )
         | 
| 465 468 | 
             
                end
         | 
| 466 469 |  | 
| @@ -657,7 +660,9 @@ describe Mongo::Server::Connection, retry: 3 do | |
| 657 660 | 
             
                    end
         | 
| 658 661 |  | 
| 659 662 | 
             
                    it 'checks the size against the max bson size' do
         | 
| 660 | 
            -
                       | 
| 663 | 
            +
                      # 100 works for non-x509 auth.
         | 
| 664 | 
            +
                      # 10 is needed for x509 auth due to smaller payloads, apparently.
         | 
| 665 | 
            +
                      expect_any_instance_of(Mongo::Server).to receive(:max_bson_object_size).at_least(:once).and_return(10)
         | 
| 661 666 | 
             
                      expect do
         | 
| 662 667 | 
             
                        reply
         | 
| 663 668 | 
             
                      end.to raise_exception(Mongo::Error::MaxBSONSize)
         | 
| @@ -950,6 +955,7 @@ describe Mongo::Server::Connection, retry: 3 do | |
| 950 955 | 
             
                end
         | 
| 951 956 |  | 
| 952 957 | 
             
                context 'when authentication options are provided' do
         | 
| 958 | 
            +
                  require_no_x509_auth
         | 
| 953 959 |  | 
| 954 960 | 
             
                  let(:connection) do
         | 
| 955 961 | 
             
                    described_class.new(
         | 
| @@ -1100,6 +1106,8 @@ describe Mongo::Server::Connection, retry: 3 do | |
| 1100 1106 | 
             
                end
         | 
| 1101 1107 |  | 
| 1102 1108 | 
             
                context 'when auth options differ from server' do
         | 
| 1109 | 
            +
                  require_no_x509_auth
         | 
| 1110 | 
            +
             | 
| 1103 1111 | 
             
                  let(:connection) do
         | 
| 1104 1112 | 
             
                    described_class.new(server, server.options.merge(user: 'foo'))
         | 
| 1105 1113 | 
             
                  end
         | 
| @@ -158,7 +158,7 @@ describe Mongo::Server::Monitor do | |
| 158 158 | 
             
              end
         | 
| 159 159 | 
             
            =end
         | 
| 160 160 |  | 
| 161 | 
            -
              describe '# | 
| 161 | 
            +
              describe '#run!' do
         | 
| 162 162 |  | 
| 163 163 | 
             
                let!(:thread) do
         | 
| 164 164 | 
             
                  monitor.run!
         | 
| @@ -182,6 +182,24 @@ describe Mongo::Server::Monitor do | |
| 182 182 | 
             
                    expect(monitor.restart!).not_to be(thread)
         | 
| 183 183 | 
             
                  end
         | 
| 184 184 | 
             
                end
         | 
| 185 | 
            +
             | 
| 186 | 
            +
                context 'when running after a stop' do
         | 
| 187 | 
            +
                  it 'starts the thread' do
         | 
| 188 | 
            +
                    ClientRegistry.instance.close_all_clients
         | 
| 189 | 
            +
                    thread
         | 
| 190 | 
            +
                    sleep 0.5
         | 
| 191 | 
            +
             | 
| 192 | 
            +
                    RSpec::Mocks.with_temporary_scope do
         | 
| 193 | 
            +
                      expect(monitor.connection).to receive(:disconnect!).and_call_original
         | 
| 194 | 
            +
                      monitor.stop!
         | 
| 195 | 
            +
                      sleep 0.5
         | 
| 196 | 
            +
                      expect(thread.alive?).to be false
         | 
| 197 | 
            +
                      new_thread = monitor.run!
         | 
| 198 | 
            +
                      sleep 0.5
         | 
| 199 | 
            +
                      expect(new_thread.alive?).to be(true)
         | 
| 200 | 
            +
                    end
         | 
| 201 | 
            +
                  end
         | 
| 202 | 
            +
                end
         | 
| 185 203 | 
             
              end
         | 
| 186 204 |  | 
| 187 205 | 
             
              describe '#stop' do
         | 
| @@ -225,7 +225,7 @@ describe Mongo::Socket::SSL, retry: 3 do | |
| 225 225 | 
             
                context 'when a certificate is passed, but it is not of the right type' do
         | 
| 226 226 |  | 
| 227 227 | 
             
                  let(:options) do
         | 
| 228 | 
            -
                    cert = "This is a string, not  | 
| 228 | 
            +
                    cert = "This is a string, not an X.509 Certificate"
         | 
| 229 229 | 
             
                    {
         | 
| 230 230 | 
             
                      :ssl => true,
         | 
| 231 231 | 
             
                      :ssl_cert_object => cert,
         | 
| @@ -713,19 +713,6 @@ describe Mongo::URI::SRVProtocol do | |
| 713 713 | 
             
                        expect(client.options[:auth_source]).to eq(source)
         | 
| 714 714 | 
             
                      end
         | 
| 715 715 | 
             
                    end
         | 
| 716 | 
            -
             | 
| 717 | 
            -
                    context '$external' do
         | 
| 718 | 
            -
                      let(:source) { '$external' }
         | 
| 719 | 
            -
                      let(:expected) { :external }
         | 
| 720 | 
            -
             | 
| 721 | 
            -
                      it 'sets the auth source to :external' do
         | 
| 722 | 
            -
                        expect(uri.uri_options[:auth_source]).to eq(expected)
         | 
| 723 | 
            -
                      end
         | 
| 724 | 
            -
             | 
| 725 | 
            -
                      it 'sets the options on a client created with the uri' do
         | 
| 726 | 
            -
                        expect(client.options[:auth_source]).to eq(expected)
         | 
| 727 | 
            -
                      end
         | 
| 728 | 
            -
                    end
         | 
| 729 716 | 
             
                  end
         | 
| 730 717 |  | 
| 731 718 | 
             
                  context 'auth mechanism properties provided' do
         | 
| @@ -242,14 +242,6 @@ describe Mongo::URI do | |
| 242 242 |  | 
| 243 243 | 
             
                it_behaves_like 'a string option'
         | 
| 244 244 |  | 
| 245 | 
            -
                context '$external' do
         | 
| 246 | 
            -
                  let(:string) { "mongodb://example.com/?#{uri_option}=$external" }
         | 
| 247 | 
            -
             | 
| 248 | 
            -
                  it 'is converted to ;external' do
         | 
| 249 | 
            -
                    expect(uri.uri_options[ruby_option]).to eq(:external)
         | 
| 250 | 
            -
                  end
         | 
| 251 | 
            -
                end
         | 
| 252 | 
            -
             | 
| 253 245 | 
             
                context 'empty' do
         | 
| 254 246 | 
             
                  let(:string) { "mongodb://example.com/?#{uri_option}=" }
         | 
| 255 247 |  | 
    
        data/spec/mongo/uri_spec.rb
    CHANGED
    
    | @@ -729,7 +729,7 @@ describe Mongo::URI do | |
| 729 729 |  | 
| 730 730 | 
             
                    context 'when mechanism_properties are provided' do
         | 
| 731 731 | 
             
                      let(:options) { "authMechanism=#{mechanism}&authMechanismProperties=CANONICALIZE_HOST_NAME:true" }
         | 
| 732 | 
            -
             | 
| 732 | 
            +
             | 
| 733 733 | 
             
                      it 'does not allow a client to be created' do
         | 
| 734 734 | 
             
                        expect {
         | 
| 735 735 | 
             
                          new_local_client_nmio(string)
         | 
| @@ -758,7 +758,7 @@ describe Mongo::URI do | |
| 758 758 |  | 
| 759 759 | 
             
                    context 'when mechanism_properties are provided' do
         | 
| 760 760 | 
             
                      let(:options) { "authMechanism=#{mechanism}&authMechanismProperties=CANONICALIZE_HOST_NAME:true" }
         | 
| 761 | 
            -
             | 
| 761 | 
            +
             | 
| 762 762 | 
             
                      it 'does not allow a client to be created' do
         | 
| 763 763 | 
             
                        expect {
         | 
| 764 764 | 
             
                          new_local_client_nmio(string)
         | 
| @@ -799,7 +799,7 @@ describe Mongo::URI do | |
| 799 799 |  | 
| 800 800 | 
             
                    context 'when mechanism_properties are provided' do
         | 
| 801 801 | 
             
                      let(:options) { "authMechanism=#{mechanism}&authMechanismProperties=SERVICE_NAME:other,CANONICALIZE_HOST_NAME:true" }
         | 
| 802 | 
            -
             | 
| 802 | 
            +
             | 
| 803 803 | 
             
                      it 'sets the options on a client created with the uri' do
         | 
| 804 804 | 
             
                        client = new_local_client_nmio(string)
         | 
| 805 805 | 
             
                        expect(client.options[:auth_mech_properties]).to eq({ 'canonicalize_host_name' => true, 'service_name' => 'other' })
         | 
| @@ -827,7 +827,7 @@ describe Mongo::URI do | |
| 827 827 |  | 
| 828 828 | 
             
                    context 'when mechanism_properties are provided' do
         | 
| 829 829 | 
             
                      let(:options) { "authMechanism=#{mechanism}&authMechanismProperties=CANONICALIZE_HOST_NAME:true" }
         | 
| 830 | 
            -
             | 
| 830 | 
            +
             | 
| 831 831 | 
             
                      it 'does not allow a client to be created' do
         | 
| 832 832 | 
             
                        expect {
         | 
| 833 833 | 
             
                          new_local_client_nmio(string)
         | 
| @@ -878,7 +878,7 @@ describe Mongo::URI do | |
| 878 878 | 
             
                    context 'when a password is provided' do
         | 
| 879 879 | 
             
                      let(:credentials) { "#{user}:#{password}"}
         | 
| 880 880 | 
             
                      let(:password) { 's3kr4t' }
         | 
| 881 | 
            -
             | 
| 881 | 
            +
             | 
| 882 882 | 
             
                      it 'does not allow a client to be created' do
         | 
| 883 883 | 
             
                        expect {
         | 
| 884 884 | 
             
                          new_local_client_nmio(string)
         | 
| @@ -888,7 +888,7 @@ describe Mongo::URI do | |
| 888 888 |  | 
| 889 889 | 
             
                    context 'when mechanism_properties are provided' do
         | 
| 890 890 | 
             
                      let(:options) { "authMechanism=#{mechanism}&authMechanismProperties=CANONICALIZE_HOST_NAME:true" }
         | 
| 891 | 
            -
             | 
| 891 | 
            +
             | 
| 892 892 | 
             
                      it 'does not allow a client to be created' do
         | 
| 893 893 | 
             
                        expect {
         | 
| 894 894 | 
             
                          new_local_client_nmio(string)
         | 
| @@ -947,20 +947,6 @@ describe Mongo::URI do | |
| 947 947 | 
             
                      expect(client.options[:auth_source]).to eq(source)
         | 
| 948 948 | 
             
                    end
         | 
| 949 949 | 
             
                  end
         | 
| 950 | 
            -
             | 
| 951 | 
            -
                  context '$external' do
         | 
| 952 | 
            -
                    let(:source) { '$external' }
         | 
| 953 | 
            -
                    let(:expected) { :external }
         | 
| 954 | 
            -
             | 
| 955 | 
            -
                    it 'sets the auth source to :external' do
         | 
| 956 | 
            -
                      expect(uri.uri_options[:auth_source]).to eq(expected)
         | 
| 957 | 
            -
                    end
         | 
| 958 | 
            -
             | 
| 959 | 
            -
                    it 'sets the options on a client created with the uri' do
         | 
| 960 | 
            -
                      client = new_local_client_nmio(string)
         | 
| 961 | 
            -
                      expect(client.options[:auth_source]).to eq(expected)
         | 
| 962 | 
            -
                    end
         | 
| 963 | 
            -
                  end
         | 
| 964 950 | 
             
                end
         | 
| 965 951 |  | 
| 966 952 | 
             
                context 'auth mechanism properties provided' do
         |