description: operation getMore
schemaVersion: '1.29'
createEntities:
  - client:
      id: &client0 client0
      useMultipleMongoses: false
      observeTracingMessages: {}
  - database:
      id: &database0 database0
      client: *client0
      databaseName: &database0Name operation-get-more
  - collection:
      id: &collection0 collection0
      database: *database0
      collectionName: &collection0Name test
initialData:
  - collectionName: *collection0Name
    databaseName: *database0Name
    documents:
      - { _id: 1 }
      - { _id: 2 }
      - { _id: 3 }
tests:
  - description: getMore is nested under its own operation span
    operations:
      - name: createFindCursor
        object: *collection0
        arguments:
          filter: {}
          batchSize: 2
        saveResultAsEntity: &cursor0 cursor0
      - name: iterateUntilDocumentOrError
        object: *cursor0
        expectResult: { _id: 1 }
      - name: iterateUntilDocumentOrError
        object: *cursor0
        expectResult: { _id: 2 }
      - name: iterateUntilDocumentOrError
        object: *cursor0
        expectResult: { _id: 3 }

    expectTracingMessages:
      - client: *client0
        ignoreExtraSpans: false
        spans:
          - name: find operation-get-more.test
            attributes:
              db.system.name: mongodb
              db.namespace: *database0Name
              db.collection.name: *collection0Name
              db.operation.name: find
              db.operation.summary: find operation-get-more.test
              # This find created a cursor with a non-zero id, since batchSize 2 leaves it open,
              # so cursor_id is required on the operation span as well as the command span.
              db.mongodb.cursor_id: { $$gte: 1 }
            # Negative assertion: this `nested` array lists the `find` command span and nothing
            # else. A driver that nests the getMore under the cursor-creating operation produces a
            # second entry here, which `ignoreExtraSpans: false` rejects, because the unified test
            # format spec states that ignoreExtraSpans applies at every level of the span tree.
            nested:
              - name: find
                attributes:
                  db.system.name: mongodb
                  db.namespace: *database0Name
                  db.collection.name: *collection0Name
                  db.command.name: find
                  network.transport: tcp
                  db.response.status_code: { $$exists: false }
                  exception.message: { $$exists: false }
                  exception.type: { $$exists: false }
                  exception.stacktrace: { $$exists: false }
                  server.address: { $$type: string }
                  server.port: { $$type: [ int, long ] }
                  db.query.summary: find operation-get-more.test
                  db.mongodb.cursor_id: { $$gte: 1 }
                  db.mongodb.server_connection_id:
                    $$type: [ int, long ]
                  db.mongodb.driver_connection_id:
                    $$type: [ int, long ]
          - name: getMore operation-get-more.test
            attributes:
              db.system.name: mongodb
              db.namespace: *database0Name
              db.collection.name: *collection0Name
              db.operation.name: getMore
              db.operation.summary: getMore operation-get-more.test
              # This operation operates on an existing cursor, so cursor_id is required here too.
              db.mongodb.cursor_id: { $$gte: 1 }
            nested:
              - name: getMore
                attributes:
                  db.system.name: mongodb
                  db.namespace: *database0Name
                  db.collection.name: *collection0Name
                  db.command.name: getMore
                  network.transport: tcp
                  db.response.status_code: { $$exists: false }
                  exception.message: { $$exists: false }
                  exception.type: { $$exists: false }
                  exception.stacktrace: { $$exists: false }
                  server.address: { $$type: string }
                  server.port: { $$type: [ int, long ] }
                  db.query.summary: getMore operation-get-more.test
                  # This getMore drains the cursor, so the server's reply carries cursor id 0.
                  # Asserting a lower bound of 1 is what pins the requirement: a driver that
                  # recorded the reply's 0 instead of the id it sent would fail here.
                  db.mongodb.cursor_id: { $$gte: 1 }
                  db.mongodb.server_connection_id:
                    $$type: [ int, long ]
                  db.mongodb.driver_connection_id:
                    $$type: [ int, long ]

  - description: cursor_id is omitted when the server returns cursor id 0
    operations:
      # No batchSize: all three documents come back in the first batch, the server replies with
      # cursor id 0, and no cursor is left open. The UTF `find` operation fully iterates, so a
      # driver that still issued a getMore here would also be caught by ignoreExtraSpans: false.
      - name: find
        object: *collection0
        arguments:
          filter: {}
        expectResult:
          - { _id: 1 }
          - { _id: 2 }
          - { _id: 3 }

    expectTracingMessages:
      - client: *client0
        ignoreExtraSpans: false
        spans:
          - name: find operation-get-more.test
            attributes:
              db.system.name: mongodb
              db.namespace: *database0Name
              db.collection.name: *collection0Name
              db.operation.name: find
              db.operation.summary: find operation-get-more.test
              # This find returned everything in the first batch, so no cursor was left open and
              # cursor_id must be omitted from the operation span as well as the command span.
              db.mongodb.cursor_id: { $$exists: false }
            nested:
              - name: find
                attributes:
                  db.system.name: mongodb
                  db.namespace: *database0Name
                  db.collection.name: *collection0Name
                  db.command.name: find
                  network.transport: tcp
                  db.response.status_code: { $$exists: false }
                  exception.message: { $$exists: false }
                  exception.type: { $$exists: false }
                  exception.stacktrace: { $$exists: false }
                  server.address: { $$type: string }
                  server.port: { $$type: [ int, long ] }
                  db.query.summary: find operation-get-more.test
                  # Cursor id 0 means no server-side cursor remains: the attribute must be
                  # omitted, not emitted as 0.
                  db.mongodb.cursor_id: { $$exists: false }
                  db.mongodb.server_connection_id:
                    $$type: [ int, long ]
                  db.mongodb.driver_connection_id:
                    $$type: [ int, long ]
