---
description: hello-timeout

schemaVersion: "1.10"

runOnRequirements:
    # failCommand appName requirements
  - minServerVersion: "4.4"
    serverless: forbid
    topologies: [ single, replicaset, sharded ]

createEntities:
  - client:
      id: &setupClient setupClient
      useMultipleMongoses: false

initialData: &initialData
  - collectionName: &collectionName hello-timeout
    databaseName: &databaseName sdam-tests
    documents: []

tests:
  - description: Network timeout on Monitor handshake
    operations:
      # Configure the initial handshake to fail with a timeout.
      # Use times: 2 so that the RTT hello is blocked as well.
      - name: failPoint
        object: testRunner
        arguments:
          client: *setupClient
          failPoint:
            configureFailPoint: failCommand
            mode:
              times: 2
            data:
              failCommands:
                - hello
                - isMaster
              appName: timeoutMonitorHandshakeTest
              blockConnection: true
              blockTimeMS: 1000
      - name: createEntities
        object: testRunner
        arguments:
          entities:
            - client:
                id: &client client
                useMultipleMongoses: false
                observeEvents:
                  - commandStartedEvent
                  - serverDescriptionChangedEvent
                  - poolClearedEvent
                uriOptions:
                  retryWrites: false
                  connectTimeoutMS: 250
                  heartbeatFrequencyMS: 500
                  appname: timeoutMonitorHandshakeTest
            - database:
                id: &database database
                client: *client
                databaseName: *databaseName
            - collection:
                id: &collection collection
                database: *database
                collectionName: *collectionName
      # The network error on the initial handshake should mark the server
      # Unknown (emitting a ServerDescriptionChangedEvent) and clear the pool.
      - name: waitForEvent
        object: testRunner
        arguments:
          client: *client
          event:
            serverDescriptionChangedEvent:
              newDescription:
                type: Unknown
          count: 1
      # Perform an operation to ensure the node is discovered.
      - name: insertMany
        object: *collection
        arguments:
          documents:
            - _id: 1
            - _id: 2
      # We cannot assert the server was marked Unknown and pool was cleared an
      # exact number of times because the RTT hello may or may not have
      # triggered this failpoint as well.
      # - name: assertEventCount
      #   object: testRunner
      #   arguments:
      #     event: ServerMarkedUnknownEvent
      #     count: 1
      # - name: assertEventCount
      #   object: testRunner
      #   arguments:
      #     event: PoolClearedEvent
      #     count: 1
    expectEvents:
      - client: *client
        eventType: command
        events:
          - commandStartedEvent:
              command:
                insert: hello-timeout
                documents:
                  - _id: 1
                  - _id: 2
              commandName: insert
              databaseName: *databaseName
    outcome:
      - collectionName: *collectionName
        databaseName: *databaseName
        documents:
          - _id: 1
          - _id: 2

  - description: Network timeout on Monitor check
    operations:
      - name: createEntities
        object: testRunner
        arguments:
          entities:
            - client:
                id: &client client
                useMultipleMongoses: false
                observeEvents:
                  - commandStartedEvent
                  - serverDescriptionChangedEvent
                  - poolClearedEvent
                uriOptions:
                  retryWrites: false
                  connectTimeoutMS: 750
                  heartbeatFrequencyMS: 500
                  appname: timeoutMonitorCheckTest
            - database:
                id: &database database
                client: *client
                databaseName: *databaseName
            - collection:
                id: &collection collection
                database: *database
                collectionName: *collectionName
      # Perform an operation to ensure the node is discovered.
      - name: insertMany
        object: *collection
        arguments:
          documents:
            - _id: 1
            - _id: 2
      # Configure the next streaming hello check to fail with a timeout.
      # Use "times: 4" to increase the probability that the Monitor check times
      # out since the RTT hello may trigger this failpoint one or many times as
      # well.
      - name: failPoint
        object: testRunner
        arguments:
          failPoint:
            configureFailPoint: failCommand
            mode:
              times: 2
            data:
              failCommands:
                - hello
                - isMaster
              appName: timeoutMonitorCheckTest
              blockConnection: true
              # blockTimeMS is evaluated after the waiting for heartbeatFrequencyMS server-side, so this value only
              # needs to be greater than connectTimeoutMS. The driver will wait for (500+750)ms and the server will
              # respond after (500+1000)ms.
              blockTimeMS: 1000
          client: *setupClient
      - name: waitForEvent
        object: testRunner
        arguments:
          client: *client
          event:
            serverDescriptionChangedEvent:
              newDescription:
                type: Unknown
          count: 1
      # The network error on the next check should mark the server Unknown and
      # clear the pool.
      - name: waitForEvent
        object: testRunner
        arguments:
          client: *client
          event:
            poolClearedEvent: {}
          count: 1
      # Perform an operation to ensure the node is rediscovered.
      - name: insertMany
        object: *collection
        arguments:
          documents:
            - _id: 3
            - _id: 4
      # We cannot assert the server was marked Unknown and pool was cleared an
      # exact number of times because the RTT hello may have triggered this
      # failpoint one or many times as well.

    expectEvents:
      - client: *client
        eventType: command
        events:
          - commandStartedEvent:
              command:
                insert: hello-timeout
                documents:
                  - _id: 1
                  - _id: 2
              commandName: insert
              databaseName: *databaseName
          - commandStartedEvent:
              command:
                insert: hello-timeout
                documents:
                  - _id: 3
                  - _id: 4
              commandName: insert
              databaseName: *databaseName
    outcome:
      - collectionName: *collectionName
        databaseName: *databaseName
        documents:
          - _id: 1
          - _id: 2
          - _id: 3
          - _id: 4

  - description: Driver extends timeout while streaming
    operations:
      - name: createEntities
        object: testRunner
        arguments:
          entities:
            - client:
                id: &client client
                observeEvents:
                  - commandStartedEvent
                  - serverDescriptionChangedEvent
                  - poolClearedEvent
                uriOptions:
                  retryWrites: false
                  connectTimeoutMS: 250
                  heartbeatFrequencyMS: 500
                  appname: extendsTimeoutTest
            - database:
                id: &database database
                client: *client
                databaseName: *databaseName
            - collection:
                id: &collection collection
                database: *database
                collectionName: *collectionName
      # Perform an operation to ensure the node is discovered.
      - name: insertMany
        object: *collection
        arguments:
          documents:
            - _id: 1
            - _id: 2
      # Wait for multiple monitor checks to complete.
      - name: wait
        object: testRunner
        arguments:
          ms: 2000
      # Perform an operation to ensure the node is still selectable.
      - name: insertMany
        object: *collection
        arguments:
          documents:
            - _id: 3
            - _id: 4
      # Assert that the server was never marked Unknown and the pool was never
      # cleared.
      - name: assertEventCount
        object: testRunner
        arguments:
          client: *client
          event:
            serverDescriptionChangedEvent:
              newDescription:
                type: Unknown
          count: 0
      - name: assertEventCount
        object: testRunner
        arguments:
          client: *client
          event:
            poolClearedEvent: {}
          count: 0
    expectEvents:
      - client: *client
        eventType: command
        events:
          - commandStartedEvent:
              command:
                insert: hello-timeout
                documents:
                  - _id: 1
                  - _id: 2
              commandName: insert
              databaseName: *databaseName
          - commandStartedEvent:
              command:
                insert: hello-timeout
                documents:
                  - _id: 3
                  - _id: 4
              commandName: insert
              databaseName: *databaseName
    outcome:
      - collectionName: *collectionName
        databaseName: *databaseName
        documents:
          - _id: 1
          - _id: 2
          - _id: 3
          - _id: 4
