########################################
# Evergreen Template for MongoDB Drivers
########################################

# When a task that used to pass starts to fail
# Go through all versions that may have been skipped to detect
# when the task started failing
stepback: true

# Mark a failure as a system/bootstrap failure (purple box) rather then a task
# failure by default.
# Actual testing tasks are marked with `type: test`
command_type: system

# Protect ourself against rogue test case, or curl gone wild, that runs forever
# Good rule of thumb: the averageish length a task takes, times 5
# That roughly accounts for variable system performance for various buildvariants
exec_timeout_secs: 1800 # 30 minutes is the longest we'll ever run

# What to do when evergreen hits the timeout (`post:` tasks are run automatically)
timeout:
  - command: shell.exec
    params:
      script: |
        ls -la

functions:
  "fetch source":
    # Executes git clone and applies the submitted patch, if any
    - command: git.get_project
      params:
        directory: "src"
    # Applies the subitted patch, if any
    # Deprecated. Should be removed. But still needed for certain agents (ZAP)
    - command: git.apply_patch
    # Make an evergreen exapanstion file with dynamic values
    - command: shell.exec
      params:
        working_dir: "src"
        script: |
           # Get the current unique version of this checkout
           if [ "${is_patch}" = "true" ]; then
              CURRENT_VERSION=$(git describe)-patch-${version_id}
           else
              CURRENT_VERSION=latest
           fi

           export DRIVERS_TOOLS="$(dirname $(pwd))/drivers-tools"
           export PROJECT_DIRECTORY="$(pwd)"

           # Python has cygwin path problems on Windows. Detect prospective mongo-orchestration home directory
           if [ "Windows_NT" = "$OS" ]; then # Magic variable in cygwin
              export DRIVERS_TOOLS=$(cygpath -m $DRIVERS_TOOLS)
              export PROJECT_DIRECTORY=$(cygpath -m $PROJECT_DIRECTORY)
           fi

           export MONGO_ORCHESTRATION_HOME="$DRIVERS_TOOLS/.evergreen/orchestration"
           export MONGODB_BINARIES="$DRIVERS_TOOLS/mongodb/bin"
           export UPLOAD_BUCKET="${project}"

           cat <<EOT > expansion.yml
           CURRENT_VERSION: "$CURRENT_VERSION"
           DRIVERS_TOOLS: "$DRIVERS_TOOLS"
           MONGO_ORCHESTRATION_HOME: "$MONGO_ORCHESTRATION_HOME"
           MONGODB_BINARIES: "$MONGODB_BINARIES"
           UPLOAD_BUCKET: "$UPLOAD_BUCKET"
           PROJECT_DIRECTORY: "$PROJECT_DIRECTORY"
           PREPARE_SHELL: |
              set -o errexit
              export DRIVERS_TOOLS="$DRIVERS_TOOLS"
              export MONGO_ORCHESTRATION_HOME="$MONGO_ORCHESTRATION_HOME"
              export MONGODB_BINARIES="$MONGODB_BINARIES"
              export UPLOAD_BUCKET="$UPLOAD_BUCKET"
              export PROJECT_DIRECTORY="$PROJECT_DIRECTORY"

              export TMPDIR="$MONGO_ORCHESTRATION_HOME/db"
              # Installation of cryptography requires a rust compiler on some machines
              export PATH="$MONGODB_BINARIES:/home/admin/.cargo/bin:$PATH"
              export PROJECT="${project}"
           EOT
           # See what we've done
           cat expansion.yml

    # Load the expansion file to make an evergreen variable with the current unique version
    - command: expansions.update
      params:
        file: src/expansion.yml

  "prepare resources":
    - command: shell.exec
      params:
        script: |
          set -o xtrace
          ${PREPARE_SHELL}
          rm -rf $DRIVERS_TOOLS
          if [ "${project}" = "drivers-tools" ]; then
            # If this was a patch build, doing a fresh clone would not actually test the patch
            cp -R ${PROJECT_DIRECTORY}/ $DRIVERS_TOOLS
          else
            git clone https://github.com/mongodb-labs/drivers-evergreen-tools.git $DRIVERS_TOOLS
          fi
          echo "{ \"releases\": { \"default\": \"$MONGODB_BINARIES\" }}" > $MONGO_ORCHESTRATION_HOME/orchestration.config

  "upload coverage" :
    - command: s3.put
      params:
        aws_key: ${aws_key}
        aws_secret: ${aws_secret}
        local_file:  src/.coverage
        optional: true
        # Upload the coverage report for all tasks in a single build to the same directory.
        remote_file: ${UPLOAD_BUCKET}/coverage/${revision}/${version_id}/coverage/coverage.${build_variant}.${task_name}
        bucket: mciuploads
        permissions: public-read
        content_type: text/html
        display_name: "Raw Coverage Report"

  "download and merge coverage" :
    - command: shell.exec
      params:
        silent: true
        working_dir: "src"
        script: |
          export AWS_ACCESS_KEY_ID=${aws_key}
          export AWS_SECRET_ACCESS_KEY=${aws_secret}

          # Download all the task coverage files.
          aws s3 cp --recursive s3://mciuploads/${UPLOAD_BUCKET}/coverage/${revision}/${version_id}/coverage/ coverage/
    - command: shell.exec
      params:
        working_dir: "src"
        script: |
          set -o xtrace
          ${PREPARE_SHELL}
          # Coverage combine merges (and removes) all the coverage files and
          # generates a new .coverage file in the current directory.
          ls -la coverage/
          /opt/python/3.6/bin/python3 -m coverage combine coverage/coverage.*
          /opt/python/3.6/bin/python3 -m coverage html -d htmlcov
    # Upload the resulting html coverage report.
    - command: shell.exec
      params:
        silent: true
        working_dir: "src"
        script: |
           export AWS_ACCESS_KEY_ID=${aws_key}
           export AWS_SECRET_ACCESS_KEY=${aws_secret}
           aws s3 cp htmlcov/ s3://mciuploads/${UPLOAD_BUCKET}/coverage/${revision}/${version_id}/htmlcov/ --recursive --acl public-read --region us-east-1
    # Attach the index.html with s3.put so it shows up in the Evergreen UI.
    - command: s3.put
      params:
        aws_key: ${aws_key}
        aws_secret: ${aws_secret}
        local_file:  src/htmlcov/index.html
        remote_file: ${UPLOAD_BUCKET}/coverage/${revision}/${version_id}/htmlcov/index.html
        bucket: mciuploads
        permissions: public-read
        content_type: text/html
        display_name: "Coverage Report HTML"


  "upload mo artifacts":
    - command: shell.exec
      params:
        script: |
          set -o xtrace
          ${PREPARE_SHELL}
          find $MONGO_ORCHESTRATION_HOME -name \*.log | xargs tar czf mongodb-logs.tar.gz
    - command: archive.targz_pack
      params:
        target: "mongo-coredumps.tgz"
        source_dir: "./"
        include:
          - "./**.core"
          - "./**.mdmp" # Windows: minidumps
    - command: s3.put
      params:
        aws_key: ${aws_key}
        aws_secret: ${aws_secret}
        local_file: mongo-coredumps.tgz
        remote_file: ${UPLOAD_BUCKET}/${build_variant}/${revision}/${version_id}/${build_id}/coredumps/${task_id}-${execution}-mongodb-coredumps.tar.gz
        bucket: mciuploads
        permissions: public-read
        content_type: ${content_type|application/gzip}
        display_name: Core Dumps - Execution
        optional: true
    - command: s3.put
      params:
        aws_key: ${aws_key}
        aws_secret: ${aws_secret}
        local_file: mongodb-logs.tar.gz
        remote_file: ${UPLOAD_BUCKET}/${build_variant}/${revision}/${version_id}/${build_id}/logs/${task_id}-${execution}-mongodb-logs.tar.gz
        bucket: mciuploads
        permissions: public-read
        content_type: ${content_type|application/x-gzip}
        display_name: "mongodb-logs.tar.gz"
    - command: s3.put
      params:
        aws_key: ${aws_key}
        aws_secret: ${aws_secret}
        local_file: drivers-tools/.evergreen/orchestration/server.log
        remote_file: ${UPLOAD_BUCKET}/${build_variant}/${revision}/${version_id}/${build_id}/logs/${task_id}-${execution}-orchestration.log
        bucket: mciuploads
        permissions: public-read
        content_type: ${content_type|text/plain}
        display_name: "orchestration.log"

  "upload working dir":
    - command: archive.targz_pack
      params:
        target: "working-dir.tar.gz"
        source_dir: ${PROJECT_DIRECTORY}/
        include:
          - "./**"
    - command: s3.put
      params:
        aws_key: ${aws_key}
        aws_secret: ${aws_secret}
        local_file: working-dir.tar.gz
        remote_file: ${UPLOAD_BUCKET}/${build_variant}/${revision}/${version_id}/${build_id}/artifacts/${task_id}-${execution}-working-dir.tar.gz
        bucket: mciuploads
        permissions: public-read
        content_type: ${content_type|application/x-gzip}
        display_name: "working-dir.tar.gz"
    - command: archive.targz_pack
      params:
        target: "drivers-dir.tar.gz"
        source_dir: ${DRIVERS_TOOLS}
        include:
          - "./**"
        exclude_files:
          # Windows cannot read the mongod *.lock files because they are locked.
          - "*.lock"
    - command: s3.put
      params:
        aws_key: ${aws_key}
        aws_secret: ${aws_secret}
        local_file: drivers-dir.tar.gz
        remote_file: ${UPLOAD_BUCKET}/${build_variant}/${revision}/${version_id}/${build_id}/artifacts/${task_id}-${execution}-drivers-dir.tar.gz
        bucket: mciuploads
        permissions: public-read
        content_type: ${content_type|application/x-gzip}
        display_name: "drivers-dir.tar.gz"

  "upload test results":
    - command: attach.results
      params:
        file_location: "${DRIVERS_TOOLS}/results.json"
    - command: attach.xunit_results
      params:
        file: "src/xunit-results/TEST-*.xml"

  "bootstrap mongo-orchestration":
    - command: shell.exec
      params:
        script: |
          set -o xtrace

          # Enable core dumps if enabled on the machine
          # Copied from https://github.com/mongodb/mongo/blob/master/etc/evergreen.yml
          if [ -f /proc/self/coredump_filter ]; then
            # Set the shell process (and its children processes) to dump ELF headers (bit 4),
            # anonymous shared mappings (bit 1), and anonymous private mappings (bit 0).
            echo 0x13 > /proc/self/coredump_filter

            if [ -f /sbin/sysctl ]; then
              # Check that the core pattern is set explicitly on our distro image instead
              # of being the OS's default value. This ensures that coredump names are consistent
              # across distros and can be picked up by Evergreen.
              core_pattern=$(/sbin/sysctl -n "kernel.core_pattern")
              if [ "$core_pattern" = "dump_%e.%p.core" ]; then
                echo "Enabling coredumps"
                ulimit -c unlimited
              fi
            fi
          fi

          if [ $(uname -s) = "Darwin" ]; then
              core_pattern_mac=$(/usr/sbin/sysctl -n "kern.corefile")
              if [ "$core_pattern_mac" = "dump_%N.%P.core" ]; then
                echo "Enabling coredumps"
                ulimit -c unlimited
              fi
          fi

          ${PREPARE_SHELL}
          MONGODB_VERSION=${VERSION} \
            TOPOLOGY=${TOPOLOGY} \
            AUTH=${AUTH} \
            SSL=${SSL} \
            STORAGE_ENGINE=${STORAGE_ENGINE} \
            DISABLE_TEST_COMMANDS=${DISABLE_TEST_COMMANDS} \
            ORCHESTRATION_FILE=${ORCHESTRATION_FILE} \
            REQUIRE_API_VERSION=${REQUIRE_API_VERSION} \
            LOAD_BALANCER=${LOAD_BALANCER} \
            bash ${DRIVERS_TOOLS}/.evergreen/run-orchestration.sh
    # run-orchestration generates expansion file with the MONGODB_URI for the cluster
    - command: expansions.update
      params:
        file: mo-expansion.yml
    - command: expansions.update
      params:
        updates:
          - key: MONGODB_STARTED
            value: "1"

  "bootstrap data lake":
    - command: shell.exec
      type: setup
      params:
        script: |
          set -o xtrace
          ${PREPARE_SHELL}
          # The mongohouse build script needs to be passed the VARIANT variable, see
          # https://github.com/10gen/mongohouse/blob/973cc11/evergreen.yaml#L65
          VARIANT=ubuntu1804 bash ${DRIVERS_TOOLS}/.evergreen/atlas_data_lake/build-mongohouse-local.sh
    - command: shell.exec
      type: setup
      params:
        background: true
        script: |
          set -o xtrace
          ${PREPARE_SHELL}
          bash ${DRIVERS_TOOLS}/.evergreen/atlas_data_lake/run-mongohouse-local.sh

  "stop mongo-orchestration":
    - command: shell.exec
      params:
        script: |
          set -o xtrace
          ${PREPARE_SHELL}
          bash ${DRIVERS_TOOLS}/.evergreen/stop-orchestration.sh

  "run mod_wsgi tests":
    - command: shell.exec
      type: test
      params:
        working_dir: "src"
        script: |
          set -o xtrace
          ${PREPARE_SHELL}
          PYTHON_BINARY=${PYTHON_BINARY} MOD_WSGI_VERSION=${MOD_WSGI_VERSION} PROJECT_DIRECTORY=${PROJECT_DIRECTORY} bash ${PROJECT_DIRECTORY}/.evergreen/run-mod-wsgi-tests.sh

  "run mockupdb tests":
    - command: shell.exec
      type: test
      params:
        working_dir: "src"
        script: |
          set -o xtrace
          ${PREPARE_SHELL}
          PYTHON_BINARY=${PYTHON_BINARY} bash ${PROJECT_DIRECTORY}/.evergreen/run-mockupdb-tests.sh

  "run doctests":
     - command: shell.exec
       type: test
       params:
         working_dir: "src"
         script: |
           set -o xtrace
           ${PREPARE_SHELL}
           PYTHON_BINARY=${PYTHON_BINARY} bash ${PROJECT_DIRECTORY}/.evergreen/run-doctests.sh

  "run tests":
    # If testing FLE, start the KMS mock servers, first create the virtualenv.
    - command: shell.exec
      params:
        script: |
          if [ -n "${test_encryption}" ]; then
            ${PREPARE_SHELL}
            cd ${DRIVERS_TOOLS}/.evergreen/csfle
            . ./activate_venv.sh
          fi
    # Run in the background so the mock servers don't block the EVG task.
    - command: shell.exec
      params:
        background: true
        script: |
          if [ -n "${test_encryption}" ]; then
            ${PREPARE_SHELL}
            cd ${DRIVERS_TOOLS}/.evergreen/csfle
            . ./activate_venv.sh
            # The -u options forces the stdout and stderr streams to be unbuffered.
            # TMPDIR is required to avoid "AF_UNIX path too long" errors.
            TMPDIR="$(dirname $DRIVERS_TOOLS)" python -u kms_kmip_server.py --ca_file ../x509gen/ca.pem --cert_file ../x509gen/server.pem  --port 5698 &
            python -u kms_http_server.py --ca_file ../x509gen/ca.pem --cert_file ../x509gen/expired.pem --port 8000 &
            python -u kms_http_server.py --ca_file ../x509gen/ca.pem --cert_file ../x509gen/wrong-host.pem --port 8001 &
            python -u kms_http_server.py --ca_file ../x509gen/ca.pem --cert_file ../x509gen/server.pem --port 8002 --require_client_cert &
          fi
    # Wait up to 10 seconds for the KMIP server to start.
    - command: shell.exec
      params:
        script: |
          if [ -n "${test_encryption}" ]; then
            ${PREPARE_SHELL}
            cd ${DRIVERS_TOOLS}/.evergreen/csfle
            . ./activate_venv.sh
            for i in $(seq 1 1 10); do
               sleep 1
               if python -u kms_kmip_client.py; then
                  echo 'KMS KMIP server started!'
                  exit 0
               fi
            done
            echo 'Failed to start KMIP server!'
            exit 1
          fi
    - command: shell.exec
      type: test
      params:
        silent: true
        working_dir: "src"
        script: |
          if [ -n "${test_encryption}" ]; then
            cat <<EOT > fle_creds.sh
            export FLE_AWS_KEY="${fle_aws_key}"
            export FLE_AWS_SECRET="${fle_aws_secret}"
            export FLE_AZURE_CLIENTID="${fle_azure_clientid}"
            export FLE_AZURE_TENANTID="${fle_azure_tenantid}"
            export FLE_AZURE_CLIENTSECRET="${fle_azure_clientsecret}"
            export FLE_GCP_EMAIL="${fle_gcp_email}"
            export FLE_GCP_PRIVATEKEY="${fle_gcp_privatekey}"
            # Needed for generating temporary aws credentials.
            export AWS_ACCESS_KEY_ID="${fle_aws_key}"
            export AWS_SECRET_ACCESS_KEY="${fle_aws_secret}"
            export AWS_DEFAULT_REGION=us-east-1
          EOT
          fi
    - command: shell.exec
      type: test
      params:
        working_dir: "src"
        script: |
          if [ -n "${set_xtrace_on}" ]; then
            set -o xtrace
            export SET_XTRACE_ON="${set_xtrace_on}"
          fi
          ${PREPARE_SHELL}
          if [ -n "${MONGODB_STARTED}" ]; then
            export PYMONGO_MUST_CONNECT=1
          fi
          if [ -n "${DISABLE_TEST_COMMANDS}" ]; then
            export PYMONGO_DISABLE_TEST_COMMANDS=1
          fi
          if [ -n "${test_encryption}" ]; then
            # Disable xtrace (just in case it was accidentally set).
            set +x
            . ./fle_creds.sh
            rm -f ./fle_creds.sh
            export LIBMONGOCRYPT_URL="${libmongocrypt_url}"
            export TEST_ENCRYPTION=1
          fi
          if [ -n "${test_pyopenssl}" ]; then
            export TEST_PYOPENSSL=1
          fi
          if [ -n "${SETDEFAULTENCODING}" ]; then
            export SETDEFAULTENCODING="${SETDEFAULTENCODING}"
          fi
          if [ -n "${test_loadbalancer}" ]; then
            export TEST_LOADBALANCER=1
            export LOAD_BALANCER=1
            export SINGLE_MONGOS_LB_URI="${SINGLE_MONGOS_LB_URI}"
            export MULTI_MONGOS_LB_URI="${MULTI_MONGOS_LB_URI}"
          fi
          if [ -n "${test_serverless}" ]; then
            export TEST_SERVERLESS=1
            export MONGODB_URI="${SINGLE_ATLASPROXY_SERVERLESS_URI}"
            export SERVERLESS_ATLAS_USER="${SERVERLESS_ATLAS_USER}"
            export SERVERLESS_ATLAS_PASSWORD="${SERVERLESS_ATLAS_PASSWORD}"
            export SINGLE_MONGOS_LB_URI="${SINGLE_ATLASPROXY_SERVERLESS_URI}"
            export MULTI_MONGOS_LB_URI="${MULTI_ATLASPROXY_SERVERLESS_URI}"
          fi

          PYTHON_BINARY=${PYTHON_BINARY} \
            GREEN_FRAMEWORK=${GREEN_FRAMEWORK} \
            C_EXTENSIONS=${C_EXTENSIONS} \
            COVERAGE=${COVERAGE} \
            COMPRESSORS=${COMPRESSORS} \
            AUTH=${AUTH} \
            SSL=${SSL} \
            DATA_LAKE=${DATA_LAKE} \
            MONGODB_API_VERSION=${MONGODB_API_VERSION} \
            bash ${PROJECT_DIRECTORY}/.evergreen/run-tests.sh

  "run enterprise auth tests":
    - command: shell.exec
      type: test
      params:
        silent: true
        working_dir: "src"
        script: |
          # DO NOT ECHO WITH XTRACE (which PREPARE_SHELL does)
          PYTHON_BINARY=${PYTHON_BINARY} SASL_HOST=${sasl_host} SASL_PORT=${sasl_port} SASL_USER=${sasl_user} SASL_PASS=${sasl_pass} SASL_DB=${sasl_db} PRINCIPAL=${principal} GSSAPI_DB=${gssapi_db} KEYTAB_BASE64=${keytab_base64} PROJECT_DIRECTORY=${PROJECT_DIRECTORY} bash ${PROJECT_DIRECTORY}/.evergreen/run-enterprise-auth-tests.sh

  "run atlas tests":
    - command: shell.exec
      type: test
      params:
        silent: true
        working_dir: "src"
        script: |
          cat <<EOT > prepare_atlas_connectivity.sh
          export ATLAS_FREE='${atlas_free}'
          export ATLAS_REPL='${atlas_repl}'
          export ATLAS_SHRD='${atlas_shrd}'
          export ATLAS_TLS11='${atlas_tls11}'
          export ATLAS_TLS12='${atlas_tls12}'
          export ATLAS_SERVERLESS='${atlas_serverless}'
          export ATLAS_SRV_FREE='${atlas_srv_free}'
          export ATLAS_SRV_REPL='${atlas_srv_repl}'
          export ATLAS_SRV_SHRD='${atlas_srv_shrd}'
          export ATLAS_SRV_TLS11='${atlas_srv_tls11}'
          export ATLAS_SRV_TLS12='${atlas_srv_tls12}'
          export ATLAS_SRV_SERVERLESS='${atlas_srv_serverless}'
          EOT
    - command: shell.exec
      type: test
      params:
        working_dir: "src"
        script: |
          # Disable xtrace (just in case it was accidentally set).
          set +x
          . ./prepare_atlas_connectivity.sh
          rm -f ./prepare_atlas_connectivity.sh

          PYTHON_BINARY=${PYTHON_BINARY} bash ${PROJECT_DIRECTORY}/.evergreen/run-atlas-tests.sh

  "add aws auth variables to file":
    - command: shell.exec
      type: test
      params:
        working_dir: "src"
        silent: true
        script: |
          cat <<EOF > ${DRIVERS_TOOLS}/.evergreen/auth_aws/aws_e2e_setup.json
          {
              "iam_auth_ecs_account" : "${iam_auth_ecs_account}",
              "iam_auth_ecs_secret_access_key" : "${iam_auth_ecs_secret_access_key}",
              "iam_auth_ecs_account_arn": "arn:aws:iam::557821124784:user/authtest_fargate_user",
              "iam_auth_ecs_cluster": "${iam_auth_ecs_cluster}",
              "iam_auth_ecs_task_definition": "${iam_auth_ecs_task_definition}",
              "iam_auth_ecs_subnet_a": "${iam_auth_ecs_subnet_a}",
              "iam_auth_ecs_subnet_b": "${iam_auth_ecs_subnet_b}",
              "iam_auth_ecs_security_group": "${iam_auth_ecs_security_group}",

              "iam_auth_assume_aws_account" : "${iam_auth_assume_aws_account}",
              "iam_auth_assume_aws_secret_access_key" : "${iam_auth_assume_aws_secret_access_key}",
              "iam_auth_assume_role_name" : "${iam_auth_assume_role_name}",

              "iam_auth_ec2_instance_account" : "${iam_auth_ec2_instance_account}",
              "iam_auth_ec2_instance_secret_access_key" : "${iam_auth_ec2_instance_secret_access_key}",
              "iam_auth_ec2_instance_profile" : "${iam_auth_ec2_instance_profile}"
          }
          EOF

  "run aws auth test with regular aws credentials":
    - command: shell.exec
      type: test
      params:
        working_dir: "src"
        script: |
          ${PREPARE_SHELL}
          cd ${DRIVERS_TOOLS}/.evergreen/auth_aws
          . ./activate_venv.sh
          mongo aws_e2e_regular_aws.js
    - command: shell.exec
      type: test
      params:
        working_dir: "src"
        silent: true
        script: |
          cat <<'EOF' > "${PROJECT_DIRECTORY}/prepare_mongodb_aws.sh"
            alias urlencode='${python3_binary} -c "import sys, urllib.parse as ulp; sys.stdout.write(ulp.quote_plus(sys.argv[1]))"'
            USER=$(urlencode ${iam_auth_ecs_account})
            PASS=$(urlencode ${iam_auth_ecs_secret_access_key})
            MONGODB_URI="mongodb://$USER:$PASS@localhost"
          EOF
    - command: shell.exec
      type: test
      params:
        working_dir: "src"
        script: |
          ${PREPARE_SHELL}
          PYTHON_BINARY=${PYTHON_BINARY} .evergreen/run-mongodb-aws-test.sh

  "run aws auth test with assume role credentials":
    - command: shell.exec
      type: test
      params:
        working_dir: "src"
        script: |
          ${PREPARE_SHELL}
          cd ${DRIVERS_TOOLS}/.evergreen/auth_aws
          . ./activate_venv.sh
          mongo aws_e2e_assume_role.js
    - command: shell.exec
      type: test
      params:
        working_dir: "src"
        silent: true
        script: |
          # DO NOT ECHO WITH XTRACE (which PREPARE_SHELL does)
          cat <<'EOF' > "${PROJECT_DIRECTORY}/prepare_mongodb_aws.sh"
            alias urlencode='${python3_binary} -c "import sys, urllib.parse as ulp; sys.stdout.write(ulp.quote_plus(sys.argv[1]))"'
            alias jsonkey='${python3_binary} -c "import json,sys;sys.stdout.write(json.load(sys.stdin)[sys.argv[1]])" < ${DRIVERS_TOOLS}/.evergreen/auth_aws/creds.json'
            USER=$(jsonkey AccessKeyId)
            USER=$(urlencode $USER)
            PASS=$(jsonkey SecretAccessKey)
            PASS=$(urlencode $PASS)
            SESSION_TOKEN=$(jsonkey SessionToken)
            SESSION_TOKEN=$(urlencode $SESSION_TOKEN)
            MONGODB_URI="mongodb://$USER:$PASS@localhost"
          EOF
    - command: shell.exec
      type: test
      params:
        working_dir: "src"
        script: |
          ${PREPARE_SHELL}
          PYTHON_BINARY=${PYTHON_BINARY} .evergreen/run-mongodb-aws-test.sh

  "run aws auth test with aws EC2 credentials":
    - command: shell.exec
      type: test
      params:
        working_dir: "src"
        script: |
          ${PREPARE_SHELL}
          if [ "${skip_EC2_auth_test}" = "true" ]; then
             echo "This platform does not support the EC2 auth test, skipping..."
             exit 0
          fi
          cd ${DRIVERS_TOOLS}/.evergreen/auth_aws
          . ./activate_venv.sh
          mongo aws_e2e_ec2.js
    - command: shell.exec
      type: test
      params:
        working_dir: "src"
        script: |
          ${PREPARE_SHELL}
          PYTHON_BINARY=${PYTHON_BINARY} ASSERT_NO_URI_CREDS=true .evergreen/run-mongodb-aws-test.sh

  "run aws auth test with aws credentials as environment variables":
    - command: shell.exec
      type: test
      params:
        working_dir: "src"
        silent: true
        script: |
          # DO NOT ECHO WITH XTRACE (which PREPARE_SHELL does)
          cat <<'EOF' > "${PROJECT_DIRECTORY}/prepare_mongodb_aws.sh"
            export AWS_ACCESS_KEY_ID=${iam_auth_ecs_account}
            export AWS_SECRET_ACCESS_KEY=${iam_auth_ecs_secret_access_key}
          EOF
    - command: shell.exec
      type: test
      params:
        working_dir: "src"
        script: |
          ${PREPARE_SHELL}
          PYTHON_BINARY=${PYTHON_BINARY} PROJECT_DIRECTORY=${PROJECT_DIRECTORY} ASSERT_NO_URI_CREDS=true .evergreen/run-mongodb-aws-test.sh

  "run aws auth test with aws credentials and session token as environment variables":
    - command: shell.exec
      type: test
      params:
        working_dir: "src"
        silent: true
        script: |
          # DO NOT ECHO WITH XTRACE (which PREPARE_SHELL does)
          cat <<'EOF' > "${PROJECT_DIRECTORY}/prepare_mongodb_aws.sh"
            alias jsonkey='${python3_binary} -c "import json,sys;sys.stdout.write(json.load(sys.stdin)[sys.argv[1]])" < ${DRIVERS_TOOLS}/.evergreen/auth_aws/creds.json'
            export AWS_ACCESS_KEY_ID=$(jsonkey AccessKeyId)
            export AWS_SECRET_ACCESS_KEY=$(jsonkey SecretAccessKey)
            export AWS_SESSION_TOKEN=$(jsonkey SessionToken)
          EOF
    - command: shell.exec
      type: test
      params:
        working_dir: "src"
        script: |
          ${PREPARE_SHELL}
          PYTHON_BINARY=${PYTHON_BINARY} ASSERT_NO_URI_CREDS=true .evergreen/run-mongodb-aws-test.sh

  "run aws ECS auth test":
    - command: shell.exec
      type: test
      params:
        working_dir: "src"
        script: |
          ${PREPARE_SHELL}
          if [ "${skip_ECS_auth_test}" = "true" ]; then
             echo "This platform does not support the ECS auth test, skipping..."
             exit 0
          fi
          cd ${DRIVERS_TOOLS}/.evergreen/auth_aws
          . ./activate_venv.sh
          cat <<EOF > setup.js
          const mongo_binaries = "$MONGODB_BINARIES";
          const project_dir = "$PROJECT_DIRECTORY";
          EOF

          mongo --nodb setup.js aws_e2e_ecs.js
          cd -

  "cleanup":
    - command: shell.exec
      params:
        script: |
          set -o xtrace
          ${PREPARE_SHELL}
          rm -rf $DRIVERS_TOOLS || true

  "fix absolute paths":
    - command: shell.exec
      params:
        script: |
          set -o xtrace
          ${PREPARE_SHELL}
          for filename in $(find ${DRIVERS_TOOLS} -name \*.json); do
            perl -p -i -e "s|ABSOLUTE_PATH_REPLACEMENT_TOKEN|${DRIVERS_TOOLS}|g" $filename
          done

  "windows fix":
    - command: shell.exec
      params:
        script: |
          set -o xtrace
          ${PREPARE_SHELL}
          for i in $(find ${DRIVERS_TOOLS}/.evergreen ${PROJECT_DIRECTORY}/.evergreen -name \*.sh); do
            cat $i | tr -d '\r' > $i.new
            mv $i.new $i
          done
          # Copy client certificate because symlinks do not work on Windows.
          cp ${DRIVERS_TOOLS}/.evergreen/x509gen/client.pem ${MONGO_ORCHESTRATION_HOME}/lib/client.pem

  "make files executable":
    - command: shell.exec
      params:
        script: |
          set -o xtrace
          ${PREPARE_SHELL}
          for i in $(find ${DRIVERS_TOOLS}/.evergreen ${PROJECT_DIRECTORY}/.evergreen -name \*.sh); do
            chmod +x $i
          done

  "init test-results":
    - command: shell.exec
      params:
        script: |
          set -o xtrace
          ${PREPARE_SHELL}
          echo '{"results": [{ "status": "FAIL", "test_file": "Build", "log_raw": "No test-results.json found was created"  } ]}' > ${PROJECT_DIRECTORY}/test-results.json

  "install dependencies":
    - command: shell.exec
      params:
        working_dir: "src"
        script: |
          set -o xtrace
          ${PREPARE_SHELL}
          file="${PROJECT_DIRECTORY}/.evergreen/install-dependencies.sh"
          # Don't use ${file} syntax here because evergreen treats it as an empty expansion.
          [ -f "$file" ] && bash $file || echo "$file not available, skipping"

  "run-ocsp-test":
    - command: shell.exec
      type: test
      params:
        working_dir: "src"
        script: |
          ${PREPARE_SHELL}
          PYTHON_BINARY=${PYTHON_BINARY} \
          CA_FILE="$DRIVERS_TOOLS/.evergreen/ocsp/${OCSP_ALGORITHM}/ca.pem" \
          OCSP_TLS_SHOULD_SUCCEED="${OCSP_TLS_SHOULD_SUCCEED}" \
          bash ${PROJECT_DIRECTORY}/.evergreen/run-ocsp-tests.sh

  run-valid-ocsp-server:
    - command: shell.exec
      params:
        script: |
          cd ${DRIVERS_TOOLS}/.evergreen/ocsp
          ${python3_binary} -m venv ./venv
          ./venv/${venv_bin_dir|bin}/pip3 install -r mock-ocsp-responder-requirements.txt
    - command: shell.exec
      params:
        background: true
        script: |
          cd ${DRIVERS_TOOLS}/.evergreen/ocsp
          ./venv/${venv_bin_dir|bin}/python ocsp_mock.py \
          --ca_file ${OCSP_ALGORITHM}/ca.pem \
          --ocsp_responder_cert ${OCSP_ALGORITHM}/ca.crt \
          --ocsp_responder_key ${OCSP_ALGORITHM}/ca.key \
          -p 8100 -v
  run-revoked-ocsp-server:
    - command: shell.exec
      params:
        script: |
          cd ${DRIVERS_TOOLS}/.evergreen/ocsp
          ${python3_binary} -m venv ./venv
          ./venv/${venv_bin_dir|bin}/pip3 install -r mock-ocsp-responder-requirements.txt
    - command: shell.exec
      params:
        background: true
        script: |
          cd ${DRIVERS_TOOLS}/.evergreen/ocsp
          ./venv/${venv_bin_dir|bin}/python ocsp_mock.py \
          --ca_file ${OCSP_ALGORITHM}/ca.pem \
          --ocsp_responder_cert ${OCSP_ALGORITHM}/ca.crt \
          --ocsp_responder_key ${OCSP_ALGORITHM}/ca.key \
          -p 8100 \
          -v \
          --fault revoked
  run-valid-delegate-ocsp-server:
    - command: shell.exec
      params:
        script: |
          cd ${DRIVERS_TOOLS}/.evergreen/ocsp
          ${python3_binary} -m venv ./venv
          ./venv/${venv_bin_dir|bin}/pip3 install -r mock-ocsp-responder-requirements.txt
    - command: shell.exec
      params:
        background: true
        script: |
          cd ${DRIVERS_TOOLS}/.evergreen/ocsp
          ./venv/${venv_bin_dir|bin}/python ocsp_mock.py \
          --ca_file ${OCSP_ALGORITHM}/ca.pem \
          --ocsp_responder_cert ${OCSP_ALGORITHM}/ocsp-responder.crt \
          --ocsp_responder_key ${OCSP_ALGORITHM}/ocsp-responder.key \
          -p 8100 -v
  run-revoked-delegate-ocsp-server:
    - command: shell.exec
      params:
        script: |
          cd ${DRIVERS_TOOLS}/.evergreen/ocsp
          ${python3_binary} -m venv ./venv
          ./venv/${venv_bin_dir|bin}/pip3 install -r mock-ocsp-responder-requirements.txt
    - command: shell.exec
      params:
        background: true
        script: |
          cd ${DRIVERS_TOOLS}/.evergreen/ocsp
          ./venv/${venv_bin_dir|bin}/python ocsp_mock.py \
          --ca_file ${OCSP_ALGORITHM}/ca.pem \
          --ocsp_responder_cert ${OCSP_ALGORITHM}/ocsp-responder.crt \
          --ocsp_responder_key ${OCSP_ALGORITHM}/ocsp-responder.key \
          -p 8100 \
          -v \
          --fault revoked

  "run load-balancer":
    - command: shell.exec
      params:
        script: |
          DRIVERS_TOOLS=${DRIVERS_TOOLS} MONGODB_URI=${MONGODB_URI} bash ${DRIVERS_TOOLS}/.evergreen/run-load-balancer.sh start
    - command: expansions.update
      params:
        file: lb-expansion.yml

  "stop load-balancer":
    - command: shell.exec
      params:
        script: |
          cd ${DRIVERS_TOOLS}/.evergreen
          DRIVERS_TOOLS=${DRIVERS_TOOLS} bash ${DRIVERS_TOOLS}/.evergreen/run-load-balancer.sh stop

  "teardown_docker":
    - command: shell.exec
      params:
        script: |
          # Remove all Docker images
          docker rmi -f $(docker images -a -q) &> /dev/null || true

  "build release":
    - command: shell.exec
      type: test
      params:
        working_dir: "src"
        script: |
          set -o xtrace
          ${PREPARE_SHELL}
          .evergreen/release.sh

  "upload release":
    - command: archive.targz_pack
      params:
        target: "release-files.tgz"
        source_dir: "src/dist"
        include:
          - "*"
    - command: s3.put
      params:
        aws_key: ${aws_key}
        aws_secret: ${aws_secret}
        local_file: release-files.tgz
        remote_file: ${UPLOAD_BUCKET}/release/${revision}/${task_id}-${execution}-release-files.tar.gz
        bucket: mciuploads
        permissions: public-read
        content_type: ${content_type|application/gzip}
        display_name: Release files

  "download and merge releases":
    - command: shell.exec
      params:
        silent: true
        script: |
          export AWS_ACCESS_KEY_ID=${aws_key}
          export AWS_SECRET_ACCESS_KEY=${aws_secret}

          # Download all the task coverage files.
          aws s3 cp --recursive s3://mciuploads/${UPLOAD_BUCKET}/release/${revision}/ release/
    - command: shell.exec
      params:
        shell: "bash"
        script: |
          set -o xtrace
          ${PREPARE_SHELL}
          # Combine releases into one directory.
          ls -la release/
          mkdir releases
          # Copy old manylinux release first since we want the newer manylinux
          # wheels to override them.
          mkdir old_manylinux
          if mv release/*old_manylinux* old_manylinux; then
            for REL in old_manylinux/*; do
              tar zxvf $REL -C releases/
            done
          fi
          for REL in release/*; do
            tar zxvf $REL -C releases/
          done
          # Build source distribution.
          cd src/
          /opt/python/3.6/bin/python3 setup.py sdist
          cp dist/* ../releases
    - command: archive.targz_pack
      params:
        target: "release-files-all.tgz"
        source_dir: "releases/"
        include:
          - "*"
    - command: s3.put
      params:
        aws_key: ${aws_key}
        aws_secret: ${aws_secret}
        local_file: release-files-all.tgz
        remote_file: ${UPLOAD_BUCKET}/release-all/${revision}/${task_id}-${execution}-release-files-all.tar.gz
        bucket: mciuploads
        permissions: public-read
        content_type: ${content_type|application/gzip}
        display_name: Release files all

pre:
  - func: "fetch source"
  - func: "prepare resources"
  - func: "windows fix"
  - func: "fix absolute paths"
  - func: "init test-results"
  - func: "make files executable"
  - func: "install dependencies"

post:
  # Disabled, causing timeouts
  # - func: "upload working dir"
  - func: "upload coverage"
  - func: "upload mo artifacts"
  - func: "upload test results"
  - func: "stop mongo-orchestration"
  - func: "cleanup"
  - func: "teardown_docker"

task_groups:
  - name: serverless_task_group
    setup_group_can_fail_task: true
    setup_group_timeout_secs: 1800 # 30 minutes
    setup_group:
      - func: "fetch source"
      - func: "prepare resources"
      - command: shell.exec
        params:
          shell: "bash"
          script: |
            ${PREPARE_SHELL}
            set +o xtrace
            LOADBALANCED=ON \
              SERVERLESS_DRIVERS_GROUP=${SERVERLESS_DRIVERS_GROUP} \
              SERVERLESS_API_PUBLIC_KEY=${SERVERLESS_API_PUBLIC_KEY} \
              SERVERLESS_API_PRIVATE_KEY=${SERVERLESS_API_PRIVATE_KEY} \
              bash ${DRIVERS_TOOLS}/.evergreen/serverless/create-instance.sh
      - command: expansions.update
        params:
          file: serverless-expansion.yml
    teardown_group:
      - command: shell.exec
        params:
          script: |
            ${PREPARE_SHELL}
            set +o xtrace
            SERVERLESS_DRIVERS_GROUP=${SERVERLESS_DRIVERS_GROUP} \
              SERVERLESS_API_PUBLIC_KEY=${SERVERLESS_API_PUBLIC_KEY} \
              SERVERLESS_API_PRIVATE_KEY=${SERVERLESS_API_PRIVATE_KEY} \
              SERVERLESS_INSTANCE_NAME=${SERVERLESS_INSTANCE_NAME} \
              bash ${DRIVERS_TOOLS}/.evergreen/serverless/delete-instance.sh
    tasks:
      - ".serverless"

tasks:
    # Wildcard task. Do you need to find out what tools are available and where?
    # Throw it here, and execute this task on all buildvariants
    - name: getdata
      commands:
        - command: shell.exec
          type: test
          params:
            script: |
               set -o xtrace
               . ${DRIVERS_TOOLS}/.evergreen/download-mongodb.sh || true
               get_distro || true
               echo $DISTRO
               echo $MARCH
               echo $OS
               uname -a || true
               ls /etc/*release* || true
               cc --version || true
               gcc --version || true
               clang --version || true
               gcov --version || true
               lcov --version || true
               llvm-cov --version || true
               echo $PATH
               ls -la /usr/local/Cellar/llvm/*/bin/ || true
               ls -la /usr/local/Cellar/ || true
               scan-build --version || true
               genhtml --version || true
               valgrind --version || true

    - name: "release-mac"
      tags: ["release_tag"]
      run_on: macos-1014
      commands:
        - func: "build release"
        - func: "upload release"

    - name: "release-windows"
      tags: ["release_tag"]
      run_on: windows-64-vsMulti-small
      commands:
        - func: "build release"
        - func: "upload release"

    - name: "release-manylinux"
      tags: ["release_tag"]
      run_on: ubuntu2004-large
      exec_timeout_secs: 216000  # 60 minutes (manylinux task is slow).
      commands:
        - func: "build release"
        - func: "upload release"

    - name: "release-old-manylinux"
      tags: ["release_tag"]
      run_on: ubuntu2004-large
      exec_timeout_secs: 216000  # 60 minutes (manylinux task is slow).
      commands:
        - command: shell.exec
          type: test
          params:
            working_dir: "src"
            script: |
              set -o xtrace
              ${PREPARE_SHELL}
              .evergreen/build-manylinux.sh BUILD_WITH_TAG
        - func: "upload release"

    - name: "release-combine"
      tags: ["release_tag"]
      run_on: ubuntu2004-small
      depends_on:
        - name: "*"
          variant: ".release_tag"
          patch_optional: true
      commands:
        - func: "download and merge releases"

# Standard test tasks {{{

    - name: "mockupdb"
      tags: ["mockupdb"]
      commands:
        - func: "run mockupdb tests"

    - name: "doctests"
      tags: ["doctests"]
      commands:
        - func: "bootstrap mongo-orchestration"
          vars:
            VERSION: "latest"
            TOPOLOGY: "server"
        - func: "run doctests"

    - name: "test-3.6-standalone"
      tags: ["3.6", "standalone"]
      commands:
        - func: "bootstrap mongo-orchestration"
          vars:
            VERSION: "3.6"
            TOPOLOGY: "server"
        - func: "run tests"

    - name: "test-3.6-replica_set"
      tags: ["3.6", "replica_set"]
      commands:
        - func: "bootstrap mongo-orchestration"
          vars:
            VERSION: "3.6"
            TOPOLOGY: "replica_set"
        - func: "run tests"

    - name: "test-3.6-sharded_cluster"
      tags: ["3.6", "sharded_cluster"]
      commands:
        - func: "bootstrap mongo-orchestration"
          vars:
            VERSION: "3.6"
            TOPOLOGY: "sharded_cluster"
        - func: "run tests"

    - name: "test-4.0-standalone"
      tags: ["4.0", "standalone"]
      commands:
        - func: "bootstrap mongo-orchestration"
          vars:
            VERSION: "4.0"
            TOPOLOGY: "server"
        - func: "run tests"

    - name: "test-4.0-replica_set"
      tags: ["4.0", "replica_set"]
      commands:
        - func: "bootstrap mongo-orchestration"
          vars:
            VERSION: "4.0"
            TOPOLOGY: "replica_set"
        - func: "run tests"

    - name: "test-4.0-sharded_cluster"
      tags: ["4.0", "sharded_cluster"]
      commands:
        - func: "bootstrap mongo-orchestration"
          vars:
            VERSION: "4.0"
            TOPOLOGY: "sharded_cluster"
        - func: "run tests"

    - name: "test-4.2-standalone"
      tags: ["4.2", "standalone"]
      commands:
        - func: "bootstrap mongo-orchestration"
          vars:
            VERSION: "4.2"
            TOPOLOGY: "server"
        - func: "run tests"

    - name: "test-4.2-replica_set"
      tags: ["4.2", "replica_set"]
      commands:
        - func: "bootstrap mongo-orchestration"
          vars:
            VERSION: "4.2"
            TOPOLOGY: "replica_set"
        - func: "run tests"

    - name: "test-4.2-sharded_cluster"
      tags: ["4.2", "sharded_cluster"]
      commands:
        - func: "bootstrap mongo-orchestration"
          vars:
            VERSION: "4.2"
            TOPOLOGY: "sharded_cluster"
        - func: "run tests"

    - name: "test-4.4-standalone"
      tags: ["4.4", "standalone"]
      commands:
        - func: "bootstrap mongo-orchestration"
          vars:
            VERSION: "4.4"
            TOPOLOGY: "server"
        - func: "run tests"

    - name: "test-4.4-replica_set"
      tags: ["4.4", "replica_set"]
      commands:
        - func: "bootstrap mongo-orchestration"
          vars:
            VERSION: "4.4"
            TOPOLOGY: "replica_set"
        - func: "run tests"

    - name: "test-4.4-sharded_cluster"
      tags: ["4.4", "sharded_cluster"]
      commands:
        - func: "bootstrap mongo-orchestration"
          vars:
            VERSION: "4.4"
            TOPOLOGY: "sharded_cluster"
        - func: "run tests"

    - name: "test-5.0-standalone"
      tags: ["5.0", "standalone"]
      commands:
        - func: "bootstrap mongo-orchestration"
          vars:
            VERSION: "5.0"
            TOPOLOGY: "server"
        - func: "run tests"

    - name: "test-5.0-replica_set"
      tags: ["5.0", "replica_set"]
      commands:
        - func: "bootstrap mongo-orchestration"
          vars:
            VERSION: "5.0"
            TOPOLOGY: "replica_set"
        - func: "run tests"

    - name: "test-5.0-sharded_cluster"
      tags: ["5.0", "sharded_cluster"]
      commands:
        - func: "bootstrap mongo-orchestration"
          vars:
            VERSION: "5.0"
            TOPOLOGY: "sharded_cluster"
        - func: "run tests"

    - name: "test-latest-standalone"
      tags: ["latest", "standalone"]
      commands:
        - func: "bootstrap mongo-orchestration"
          vars:
            VERSION: "latest"
            TOPOLOGY: "server"
        - func: "run tests"

    - name: "test-latest-replica_set"
      tags: ["latest", "replica_set"]
      commands:
        - func: "bootstrap mongo-orchestration"
          vars:
            VERSION: "latest"
            TOPOLOGY: "replica_set"
        - func: "run tests"

    - name: "test-latest-sharded_cluster"
      tags: ["latest", "sharded_cluster"]
      commands:
        - func: "bootstrap mongo-orchestration"
          vars:
            VERSION: "latest"
            TOPOLOGY: "sharded_cluster"
        - func: "run tests"

    - name: "test-rapid-standalone"
      tags: ["rapid", "standalone"]
      commands:
        - func: "bootstrap mongo-orchestration"
          vars:
            VERSION: "rapid"
            TOPOLOGY: "server"
        - func: "run tests"

    - name: "test-rapid-replica_set"
      tags: ["rapid", "replica_set"]
      commands:
        - func: "bootstrap mongo-orchestration"
          vars:
            VERSION: "rapid"
            TOPOLOGY: "replica_set"
        - func: "run tests"

    - name: "test-rapid-sharded_cluster"
      tags: ["rapid", "sharded_cluster"]
      commands:
        - func: "bootstrap mongo-orchestration"
          vars:
            VERSION: "rapid"
            TOPOLOGY: "sharded_cluster"
        - func: "run tests"

    - name: "test-serverless"
      tags: ["serverless"]
      commands:
        - func: "run tests"

    - name: "test-enterprise-auth"
      tags: ["enterprise-auth"]
      commands:
        - func: "bootstrap mongo-orchestration"
          vars:
            VERSION: "latest"
            TOPOLOGY: "server"
        - func: "run enterprise auth tests"

    - name: "mod-wsgi-standalone"
      tags: ["mod_wsgi"]
      commands:
        - func: "bootstrap mongo-orchestration"
          vars:
            VERSION: "latest"
            TOPOLOGY: "server"
        - func: "run mod_wsgi tests"

    - name: "mod-wsgi-replica-set"
      tags: ["mod_wsgi"]
      commands:
        - func: "bootstrap mongo-orchestration"
          vars:
            VERSION: "latest"
            TOPOLOGY: "replica_set"
        - func: "run mod_wsgi tests"

    - name: "no-server"
      tags: ["no-server"]
      commands:
        - func: "run tests"
          vars:
            PYTHON_BINARY: /opt/python/3.6/bin/python3

    - name: "atlas-connect"
      tags: ["atlas-connect"]
      commands:
        - func: "run atlas tests"

    - name: atlas-data-lake-tests
      commands:
        - func: "bootstrap data lake"
        - func: "run tests"
          vars:
            DATA_LAKE: "true"

    - name: test-ocsp-rsa-valid-cert-server-staples
      tags: ["ocsp", "ocsp-rsa", "ocsp-staple"]
      commands:
        - func: run-valid-ocsp-server
          vars:
            OCSP_ALGORITHM: "rsa"
        - func: "bootstrap mongo-orchestration"
          vars:
            ORCHESTRATION_FILE: "rsa-basic-tls-ocsp-mustStaple.json"
        - func: run-ocsp-test
          vars:
            OCSP_ALGORITHM: "rsa"
            OCSP_TLS_SHOULD_SUCCEED: "true"

    - name: test-ocsp-rsa-invalid-cert-server-staples
      tags: ["ocsp", "ocsp-rsa", "ocsp-staple"]
      commands:
        - func: run-revoked-ocsp-server
          vars:
            OCSP_ALGORITHM: "rsa"
        - func: "bootstrap mongo-orchestration"
          vars:
            ORCHESTRATION_FILE: "rsa-basic-tls-ocsp-mustStaple.json"
        - func: run-ocsp-test
          vars:
            OCSP_ALGORITHM: "rsa"
            OCSP_TLS_SHOULD_SUCCEED: "false"

    - name: test-ocsp-rsa-valid-cert-server-does-not-staple
      tags: ["ocsp", "ocsp-rsa"]
      commands:
        - func: run-valid-ocsp-server
          vars:
            OCSP_ALGORITHM: "rsa"
        - func: "bootstrap mongo-orchestration"
          vars:
            ORCHESTRATION_FILE: "rsa-basic-tls-ocsp-disableStapling.json"
        - func: run-ocsp-test
          vars:
            OCSP_ALGORITHM: "rsa"
            OCSP_TLS_SHOULD_SUCCEED: "true"

    - name: test-ocsp-rsa-invalid-cert-server-does-not-staple
      tags: ["ocsp", "ocsp-rsa"]
      commands:
        - func: run-revoked-ocsp-server
          vars:
            OCSP_ALGORITHM: "rsa"
        - func: "bootstrap mongo-orchestration"
          vars:
            ORCHESTRATION_FILE: "rsa-basic-tls-ocsp-disableStapling.json"
        - func: run-ocsp-test
          vars:
            OCSP_ALGORITHM: "rsa"
            OCSP_TLS_SHOULD_SUCCEED: "false"

    - name: test-ocsp-rsa-soft-fail
      tags: ["ocsp", "ocsp-rsa"]
      commands:
        - func: "bootstrap mongo-orchestration"
          vars:
            ORCHESTRATION_FILE: "rsa-basic-tls-ocsp-disableStapling.json"
        - func: run-ocsp-test
          vars:
            OCSP_ALGORITHM: "rsa"
            OCSP_TLS_SHOULD_SUCCEED: "true"

    - name: test-ocsp-rsa-malicious-invalid-cert-mustStaple-server-does-not-staple
      tags: ["ocsp", "ocsp-rsa"]
      commands:
        - func: run-revoked-ocsp-server
          vars:
            OCSP_ALGORITHM: "rsa"
        - func: "bootstrap mongo-orchestration"
          vars:
            ORCHESTRATION_FILE: "rsa-basic-tls-ocsp-mustStaple-disableStapling.json"
        - func: run-ocsp-test
          vars:
            OCSP_ALGORITHM: "rsa"
            OCSP_TLS_SHOULD_SUCCEED: "false"

    - name: test-ocsp-rsa-malicious-no-responder-mustStaple-server-does-not-staple
      tags: ["ocsp", "ocsp-rsa"]
      commands:
        - func: "bootstrap mongo-orchestration"
          vars:
            ORCHESTRATION_FILE: "rsa-basic-tls-ocsp-mustStaple-disableStapling.json"
        - func: run-ocsp-test
          vars:
            OCSP_ALGORITHM: "rsa"
            OCSP_TLS_SHOULD_SUCCEED: "false"

    - name: test-ocsp-rsa-delegate-valid-cert-server-staples
      tags: ["ocsp", "ocsp-rsa", "ocsp-staple"]
      commands:
        - func: run-valid-delegate-ocsp-server
          vars:
            OCSP_ALGORITHM: "rsa"
        - func: "bootstrap mongo-orchestration"
          vars:
            ORCHESTRATION_FILE: "rsa-basic-tls-ocsp-mustStaple.json"
        - func: run-ocsp-test
          vars:
            OCSP_ALGORITHM: "rsa"
            OCSP_TLS_SHOULD_SUCCEED: "true"

    - name: test-ocsp-rsa-delegate-invalid-cert-server-staples
      tags: ["ocsp", "ocsp-rsa", "ocsp-staple"]
      commands:
        - func: run-revoked-delegate-ocsp-server
          vars:
            OCSP_ALGORITHM: "rsa"
        - func: "bootstrap mongo-orchestration"
          vars:
            ORCHESTRATION_FILE: "rsa-basic-tls-ocsp-mustStaple.json"
        - func: run-ocsp-test
          vars:
            OCSP_ALGORITHM: "rsa"
            OCSP_TLS_SHOULD_SUCCEED: "false"

    - name: test-ocsp-rsa-delegate-valid-cert-server-does-not-staple
      tags: ["ocsp", "ocsp-rsa"]
      commands:
        - func: run-valid-delegate-ocsp-server
          vars:
            OCSP_ALGORITHM: "rsa"
        - func: "bootstrap mongo-orchestration"
          vars:
            ORCHESTRATION_FILE: "rsa-basic-tls-ocsp-disableStapling.json"
        - func: run-ocsp-test
          vars:
            OCSP_ALGORITHM: "rsa"
            OCSP_TLS_SHOULD_SUCCEED: "true"

    - name: test-ocsp-rsa-delegate-invalid-cert-server-does-not-staple
      tags: ["ocsp", "ocsp-rsa"]
      commands:
        - func: run-revoked-delegate-ocsp-server
          vars:
            OCSP_ALGORITHM: "rsa"
        - func: "bootstrap mongo-orchestration"
          vars:
            ORCHESTRATION_FILE: "rsa-basic-tls-ocsp-disableStapling.json"
        - func: run-ocsp-test
          vars:
            OCSP_ALGORITHM: "rsa"
            OCSP_TLS_SHOULD_SUCCEED: "false"

    - name: test-ocsp-rsa-delegate-malicious-invalid-cert-mustStaple-server-does-not-staple
      tags: ["ocsp", "ocsp-rsa"]
      commands:
        - func: run-revoked-delegate-ocsp-server
          vars:
            OCSP_ALGORITHM: "rsa"
        - func: "bootstrap mongo-orchestration"
          vars:
            ORCHESTRATION_FILE: "rsa-basic-tls-ocsp-mustStaple-disableStapling.json"
        - func: run-ocsp-test
          vars:
            OCSP_ALGORITHM: "rsa"
            OCSP_TLS_SHOULD_SUCCEED: "false"

    - name: test-ocsp-ecdsa-valid-cert-server-staples
      tags: ["ocsp", "ocsp-ecdsa", "ocsp-staple"]
      commands:
        - func: run-valid-ocsp-server
          vars:
            OCSP_ALGORITHM: "ecdsa"
        - func: "bootstrap mongo-orchestration"
          vars:
            ORCHESTRATION_FILE: "ecdsa-basic-tls-ocsp-mustStaple.json"
        - func: run-ocsp-test
          vars:
            OCSP_ALGORITHM: "ecdsa"
            OCSP_TLS_SHOULD_SUCCEED: "true"

    - name: test-ocsp-ecdsa-invalid-cert-server-staples
      tags: ["ocsp", "ocsp-ecdsa", "ocsp-staple"]
      commands:
        - func: run-revoked-ocsp-server
          vars:
            OCSP_ALGORITHM: "ecdsa"
        - func: "bootstrap mongo-orchestration"
          vars:
            ORCHESTRATION_FILE: "ecdsa-basic-tls-ocsp-mustStaple.json"
        - func: run-ocsp-test
          vars:
            OCSP_ALGORITHM: "ecdsa"
            OCSP_TLS_SHOULD_SUCCEED: "false"

    - name: test-ocsp-ecdsa-valid-cert-server-does-not-staple
      tags: ["ocsp", "ocsp-ecdsa"]
      commands:
        - func: run-valid-ocsp-server
          vars:
            OCSP_ALGORITHM: "ecdsa"
        - func: "bootstrap mongo-orchestration"
          vars:
            ORCHESTRATION_FILE: "ecdsa-basic-tls-ocsp-disableStapling.json"
        - func: run-ocsp-test
          vars:
            OCSP_ALGORITHM: "ecdsa"
            OCSP_TLS_SHOULD_SUCCEED: "true"

    - name: test-ocsp-ecdsa-invalid-cert-server-does-not-staple
      tags: ["ocsp", "ocsp-ecdsa"]
      commands:
        - func: run-revoked-ocsp-server
          vars:
            OCSP_ALGORITHM: "ecdsa"
        - func: "bootstrap mongo-orchestration"
          vars:
            ORCHESTRATION_FILE: "ecdsa-basic-tls-ocsp-disableStapling.json"
        - func: run-ocsp-test
          vars:
            OCSP_ALGORITHM: "ecdsa"
            OCSP_TLS_SHOULD_SUCCEED: "false"

    - name: test-ocsp-ecdsa-soft-fail
      tags: ["ocsp", "ocsp-ecdsa"]
      commands:
        - func: "bootstrap mongo-orchestration"
          vars:
            ORCHESTRATION_FILE: "ecdsa-basic-tls-ocsp-disableStapling.json"
        - func: run-ocsp-test
          vars:
            OCSP_ALGORITHM: "ecdsa"
            OCSP_TLS_SHOULD_SUCCEED: "true"

    - name: test-ocsp-ecdsa-malicious-invalid-cert-mustStaple-server-does-not-staple
      tags: ["ocsp", "ocsp-ecdsa"]
      commands:
        - func: run-revoked-ocsp-server
          vars:
            OCSP_ALGORITHM: "ecdsa"
        - func: "bootstrap mongo-orchestration"
          vars:
            ORCHESTRATION_FILE: "ecdsa-basic-tls-ocsp-mustStaple-disableStapling.json"
        - func: run-ocsp-test
          vars:
            OCSP_ALGORITHM: "ecdsa"
            OCSP_TLS_SHOULD_SUCCEED: "false"

    - name: test-ocsp-ecdsa-malicious-no-responder-mustStaple-server-does-not-staple
      tags: ["ocsp", "ocsp-ecdsa"]
      commands:
        - func: "bootstrap mongo-orchestration"
          vars:
            ORCHESTRATION_FILE: "ecdsa-basic-tls-ocsp-mustStaple-disableStapling.json"
        - func: run-ocsp-test
          vars:
            OCSP_ALGORITHM: "ecdsa"
            OCSP_TLS_SHOULD_SUCCEED: "false"

    - name: test-ocsp-ecdsa-delegate-valid-cert-server-staples
      tags: ["ocsp", "ocsp-ecdsa", "ocsp-staple"]
      commands:
        - func: run-valid-delegate-ocsp-server
          vars:
            OCSP_ALGORITHM: "ecdsa"
        - func: "bootstrap mongo-orchestration"
          vars:
            ORCHESTRATION_FILE: "ecdsa-basic-tls-ocsp-mustStaple.json"
        - func: run-ocsp-test
          vars:
            OCSP_ALGORITHM: "ecdsa"
            OCSP_TLS_SHOULD_SUCCEED: "true"

    - name: test-ocsp-ecdsa-delegate-invalid-cert-server-staples
      tags: ["ocsp", "ocsp-ecdsa", "ocsp-staple"]
      commands:
        - func: run-revoked-delegate-ocsp-server
          vars:
            OCSP_ALGORITHM: "ecdsa"
        - func: "bootstrap mongo-orchestration"
          vars:
            ORCHESTRATION_FILE: "ecdsa-basic-tls-ocsp-mustStaple.json"
        - func: run-ocsp-test
          vars:
            OCSP_ALGORITHM: "ecdsa"
            OCSP_TLS_SHOULD_SUCCEED: "false"

    - name: test-ocsp-ecdsa-delegate-valid-cert-server-does-not-staple
      tags: ["ocsp", "ocsp-ecdsa"]
      commands:
        - func: run-valid-delegate-ocsp-server
          vars:
            OCSP_ALGORITHM: "ecdsa"
        - func: "bootstrap mongo-orchestration"
          vars:
            ORCHESTRATION_FILE: "ecdsa-basic-tls-ocsp-disableStapling.json"
        - func: run-ocsp-test
          vars:
            OCSP_ALGORITHM: "ecdsa"
            OCSP_TLS_SHOULD_SUCCEED: "true"

    - name: test-ocsp-ecdsa-delegate-invalid-cert-server-does-not-staple
      tags: ["ocsp", "ocsp-ecdsa"]
      commands:
        - func: run-revoked-delegate-ocsp-server
          vars:
            OCSP_ALGORITHM: "ecdsa"
        - func: "bootstrap mongo-orchestration"
          vars:
            ORCHESTRATION_FILE: "ecdsa-basic-tls-ocsp-disableStapling.json"
        - func: run-ocsp-test
          vars:
            OCSP_ALGORITHM: "ecdsa"
            OCSP_TLS_SHOULD_SUCCEED: "false"

    - name: test-ocsp-ecdsa-delegate-malicious-invalid-cert-mustStaple-server-does-not-staple
      tags: ["ocsp", "ocsp-ecdsa"]
      commands:
        - func: run-revoked-delegate-ocsp-server
          vars:
            OCSP_ALGORITHM: "ecdsa"
        - func: "bootstrap mongo-orchestration"
          vars:
            ORCHESTRATION_FILE: "ecdsa-basic-tls-ocsp-mustStaple-disableStapling.json"
        - func: run-ocsp-test
          vars:
            OCSP_ALGORITHM: "ecdsa"
            OCSP_TLS_SHOULD_SUCCEED: "false"

    - name: "aws-auth-test-4.4"
      commands:
        - func: "bootstrap mongo-orchestration"
          vars:
            AUTH: "auth"
            ORCHESTRATION_FILE: "auth-aws.json"
            TOPOLOGY: "server"
            VERSION: "4.4"
        - func: "add aws auth variables to file"
        - func: "run aws auth test with regular aws credentials"
        - func: "run aws auth test with assume role credentials"
        - func: "run aws auth test with aws credentials as environment variables"
        - func: "run aws auth test with aws credentials and session token as environment variables"
        - func: "run aws auth test with aws EC2 credentials"
        - func: "run aws ECS auth test"

    - name: "aws-auth-test-5.0"
      commands:
        - func: "bootstrap mongo-orchestration"
          vars:
            AUTH: "auth"
            ORCHESTRATION_FILE: "auth-aws.json"
            TOPOLOGY: "server"
            VERSION: "5.0"
        - func: "add aws auth variables to file"
        - func: "run aws auth test with regular aws credentials"
        - func: "run aws auth test with assume role credentials"
        - func: "run aws auth test with aws credentials as environment variables"
        - func: "run aws auth test with aws credentials and session token as environment variables"
        - func: "run aws auth test with aws EC2 credentials"
        - func: "run aws ECS auth test"

    - name: "aws-auth-test-latest"
      commands:
        - func: "bootstrap mongo-orchestration"
          vars:
            AUTH: "auth"
            ORCHESTRATION_FILE: "auth-aws.json"
            TOPOLOGY: "server"
            VERSION: "latest"
        - func: "add aws auth variables to file"
        - func: "run aws auth test with regular aws credentials"
        - func: "run aws auth test with assume role credentials"
        - func: "run aws auth test with aws credentials as environment variables"
        - func: "run aws auth test with aws credentials and session token as environment variables"
        - func: "run aws auth test with aws EC2 credentials"
        - func: "run aws ECS auth test"

    - name: load-balancer-test
      commands:
        - func: "bootstrap mongo-orchestration"
          vars:
            TOPOLOGY: "sharded_cluster"
            LOAD_BALANCER: true
        - func: "run load-balancer"
        - func: "run tests"

    - name: "test-fips-standalone"
      tags: ["fips"]
      commands:
        - func: "bootstrap mongo-orchestration"
          vars:
            VERSION: "latest"
            TOPOLOGY: "server"
            PYTHON_BINARY: "/opt/mongodbtoolchain/v3/bin/python3"
        - func: "run tests"
# }}}
    - name: "coverage-report"
      tags: ["coverage"]
      depends_on:
        # BUILD-3165: We can't use "*" (all tasks) and specify "variant".
        # Instead list out all coverage tasks using tags.
        - name: ".standalone"
          variant: ".coverage_tag"
          # Run the coverage task even if some tasks fail.
          status: "*"
          # Run the coverage task even if some tasks are not scheduled in a patch build.
          patch_optional: true
        - name: ".replica_set"
          variant: ".coverage_tag"
          status: "*"
          patch_optional: true
        - name: ".sharded_cluster"
          variant: ".coverage_tag"
          status: "*"
          patch_optional: true
      commands:
        - func: "download and merge coverage"


axes:
  # Choice of distro
  - id: platform
    display_name: OS
    values:
      - id: awslinux
        display_name: "Amazon Linux 2018 (Enterprise)"
        run_on: amazon1-2018-test
        batchtime: 10080  # 7 days
        variables:
          python3_binary: "/opt/python/3.8/bin/python3"
          libmongocrypt_url: https://s3.amazonaws.com/mciuploads/libmongocrypt/linux-64-amazon-ami/master/latest/libmongocrypt.tar.gz
      - id: archlinux-test
        display_name: "Archlinux"
        run_on: archlinux-test
        batchtime: 10080  # 7 days
      - id: debian92
        display_name: "Debian 9.2"
        run_on: debian92-test
        batchtime: 10080  # 7 days
        variables:
          python3_binary: "/opt/python/3.8/bin/python3"
          libmongocrypt_url: https://s3.amazonaws.com/mciuploads/libmongocrypt/debian92/master/latest/libmongocrypt.tar.gz
      - id: macos-1014
        display_name: "macOS 10.14"
        run_on: macos-1014
        variables:
          skip_EC2_auth_test: true
          skip_ECS_auth_test: true
          python3_binary: /Library/Frameworks/Python.framework/Versions/3.8/bin/python3
          libmongocrypt_url: https://s3.amazonaws.com/mciuploads/libmongocrypt/macos/master/latest/libmongocrypt.tar.gz
      - id: rhel62
        display_name: "RHEL 6.2 (x86_64)"
        run_on: rhel62-small
        batchtime: 10080  # 7 days
        variables:
          libmongocrypt_url: https://s3.amazonaws.com/mciuploads/libmongocrypt/rhel-62-64-bit/master/latest/libmongocrypt.tar.gz
      # Note that rhel70 isn't currently used since it doesn't
      # have a system Python 3. We'll switch to rhel70 as our main test
      # system (using /opt/python) in a future change.
      - id: rhel70
        display_name: "RHEL 7.0"
        run_on: rhel70-small
        batchtime: 10080  # 7 days
        variables:
          libmongocrypt_url: https://s3.amazonaws.com/mciuploads/libmongocrypt/rhel-70-64-bit/master/latest/libmongocrypt.tar.gz
      - id: rhel70-fips
        display_name: "RHEL 7.0 FIPS"
        run_on: rhel70-fips
        batchtime: 10080  # 7 days
        variables:
          libmongocrypt_url: https://s3.amazonaws.com/mciuploads/libmongocrypt/rhel-70-64-bit/master/latest/libmongocrypt.tar.gz
      - id: ubuntu-16.04
        display_name: "Ubuntu 16.04"
        run_on: ubuntu1604-test
        batchtime: 10080  # 7 days
        variables:
          libmongocrypt_url: https://s3.amazonaws.com/mciuploads/libmongocrypt/ubuntu1604/master/latest/libmongocrypt.tar.gz
          python3_binary: "/opt/python/3.8/bin/python3"
      - id: ubuntu-18.04
        display_name: "Ubuntu 18.04"
        run_on: ubuntu1804-small
        batchtime: 10080  # 7 days
        variables:
          libmongocrypt_url: https://s3.amazonaws.com/mciuploads/libmongocrypt/ubuntu1804-64/master/latest/libmongocrypt.tar.gz
          python3_binary: "/opt/python/3.8/bin/python3"
      - id: ubuntu-20.04
        display_name: "Ubuntu 20.04"
        run_on: ubuntu2004-small
        batchtime: 10080  # 7 days
        variables:
          python3_binary: python3
      - id: ubuntu1804-zseries
        display_name: "Ubuntu 18.04 (zSeries)"
        run_on: ubuntu1804-zseries-small
        batchtime: 10080  # 7 days
      - id: ubuntu1804-power8
        display_name: "Ubuntu 18.04 (POWER8)"
        run_on: ubuntu1804-power8-small
        batchtime: 10080  # 7 days
      - id: ubuntu1804-arm64
        display_name: "Ubuntu 18.04 (ARM64)"
        run_on: ubuntu1804-arm64-small
        batchtime: 10080  # 7 days
        variables:
          libmongocrypt_url: https://s3.amazonaws.com/mciuploads/libmongocrypt/ubuntu1804-arm64/master/latest/libmongocrypt.tar.gz
      - id: windows-64-vsMulti-small
        display_name: "Windows 64"
        run_on: windows-64-vsMulti-small
        batchtime: 10080  # 7 days
        variables:
          skip_ECS_auth_test: true
          python3_binary: "C:/python/Python38/python.exe"
          venv_bin_dir: "Scripts"
          libmongocrypt_url: https://s3.amazonaws.com/mciuploads/libmongocrypt/windows-test/master/latest/libmongocrypt.tar.gz

  # Test with authentication?
  - id: auth
    display_name: Authentication
    values:
      - id: auth
        display_name: Auth
        variables:
           AUTH: "auth"
      - id: noauth
        display_name: NoAuth
        variables:
           AUTH: "noauth"

  # Test with SSL?
  - id: ssl
    display_name: SSL
    values:
      - id: ssl
        display_name: SSL
        variables:
           SSL: "ssl"
      - id: nossl
        display_name: NoSSL
        variables:
           SSL: "nossl"

  # Test with Auth + SSL (combined for convenience)?
  - id: auth-ssl
    display_name: Auth SSL
    values:
      - id: auth-ssl
        display_name: Auth SSL
        variables:
           AUTH: "auth"
           SSL: "ssl"
      - id: noauth-nossl
        display_name: NoAuth NoSSL
        variables:
           AUTH: "noauth"
           SSL: "nossl"

  # Choice of wire protocol compression support
  - id: compression
    display_name: Compression
    values:
      - id: snappy
        display_name: snappy compression
        variables:
            COMPRESSORS: "snappy"
      - id: zlib
        display_name: zlib compression
        variables:
            COMPRESSORS: "zlib"
      - id: zstd
        display_name: zstd compression
        variables:
            COMPRESSORS: "zstd"

  # Choice of MongoDB server version
  - id: mongodb-version
    display_name: "MongoDB"
    values:
      - id: "3.6"
        display_name: "MongoDB 3.6"
        variables:
          VERSION: "3.6"
      - id: "4.0"
        display_name: "MongoDB 4.0"
        variables:
          VERSION: "4.0"
      - id: "4.2"
        display_name: "MongoDB 4.2"
        variables:
          VERSION: "4.2"
      - id: "4.4"
        display_name: "MongoDB 4.4"
        variables:
          VERSION: "4.4"
      - id: "5.0"
        display_name: "MongoDB 5.0"
        variables:
          VERSION: "5.0"
      - id: "latest"
        display_name: "MongoDB latest"
        variables:
          VERSION: "latest"
      - id: "rapid"
        display_name: "MongoDB rapid"
        variables:
          VERSION: "rapid"

  # Choice of Python runtime version
  - id: python-version
    display_name: "Python"
    values:
      # Note: always display platform with python-version to avoid ambiguous display names.
      # Linux
      - id: "3.6"
        display_name: "Python 3.6"
        variables:
           PYTHON_BINARY: "/opt/python/3.6/bin/python3"
      - id: "3.7"
        display_name: "Python 3.7"
        variables:
          PYTHON_BINARY: "/opt/python/3.7/bin/python3"
      - id: "3.8"
        display_name: "Python 3.8"
        variables:
          PYTHON_BINARY: "/opt/python/3.8/bin/python3"
      - id: "3.9"
        display_name: "Python 3.9"
        variables:
          PYTHON_BINARY: "/opt/python/3.9/bin/python3"
      - id: "3.10"
        display_name: "Python 3.10"
        variables:
          PYTHON_BINARY: "/opt/python/3.10/bin/python3"
      - id: "pypy3.6"
        display_name: "PyPy 3.6"
        variables:
           PYTHON_BINARY: "/opt/python/pypy3.6/bin/pypy3"
      - id: "pypy3.7"
        display_name: "PyPy 3.7"
        variables:
           PYTHON_BINARY: "/opt/python/pypy3.7/bin/pypy3"
      - id: "pypy3.8"
        display_name: "PyPy 3.8"
        variables:
           PYTHON_BINARY: "/opt/python/pypy3.8/bin/pypy3"
      - id: "system-python3"
        display_name: "Python3"
        variables:
          PYTHON_BINARY: "python3"

  - id: python-version-windows
    display_name: "Python"
    values:
      - id: "3.6"
        display_name: "Python 3.6"
        variables:
          PYTHON_BINARY: "C:/python/Python36/python.exe"
      - id: "3.7"
        display_name: "Python 3.7"
        variables:
          PYTHON_BINARY: "C:/python/Python37/python.exe"
      - id: "3.8"
        display_name: "Python 3.8"
        variables:
          PYTHON_BINARY: "C:/python/Python38/python.exe"
      - id: "3.9"
        display_name: "Python 3.9"
        variables:
          PYTHON_BINARY: "C:/python/Python39/python.exe"
      - id: "3.10"
        display_name: "Python 3.10"
        variables:
          PYTHON_BINARY: "C:/python/Python310/python.exe"

  - id: python-version-windows-32
    display_name: "Python"
    values:
      - id: "3.6"
        display_name: "32-bit Python 3.6"
        variables:
          PYTHON_BINARY: "C:/python/32/Python36/python.exe"
      - id: "3.7"
        display_name: "32-bit Python 3.7"
        variables:
          PYTHON_BINARY: "C:/python/32/Python37/python.exe"
      - id: "3.8"
        display_name: "32-bit Python 3.8"
        variables:
          PYTHON_BINARY: "C:/python/32/Python38/python.exe"
      - id: "3.9"
        display_name: "32-bit Python 3.9"
        variables:
          PYTHON_BINARY: "C:/python/32/Python39/python.exe"
      - id: "3.10"
        display_name: "32-bit Python 3.10"
        variables:
          PYTHON_BINARY: "C:/python/32/Python310/python.exe"

  # Choice of mod_wsgi version
  - id: mod-wsgi-version
    display_name: "mod_wsgi version"
    values:
      - id: "3"
        display_name: "mod_wsgi 3.5"
        variables:
          MOD_WSGI_VERSION: "3"
      - id: "4"
        display_name: "mod_wsgi 4.x"
        variables:
          MOD_WSGI_VERSION: "4"

  # Choice of Python async framework
  - id: green-framework
    display_name: "Green Framework"
    values:
      - id: "eventlet"
        display_name: "Eventlet"
        variables:
          GREEN_FRAMEWORK: "eventlet"
      - id: "gevent"
        display_name: "Gevent"
        variables:
          GREEN_FRAMEWORK: "gevent"

  # Install and use the driver's C-extensions?
  - id: c-extensions
    display_name: "C Extensions"
    values:
      - id: "without-c-extensions"
        display_name: "Without C Extensions"
        variables:
          C_EXTENSIONS: "--no_ext"
      - id: "with-c-extensions"
        display_name: "With C Extensions"
        variables:
          C_EXTENSIONS: ""

  # Choice of MongoDB storage engine
  - id: storage-engine
    display_name: Storage
    values:
      - id: mmapv1
        display_name: MMAPv1
        variables:
           STORAGE_ENGINE: "mmapv1"
      - id: inmemory
        display_name: InMemory
        variables:
           STORAGE_ENGINE: "inmemory"

  # Run with test commands disabled on server?
  - id: disableTestCommands
    display_name: Disable test commands
    values:
      - id: disabled
        display_name: disabled
        variables:
           DISABLE_TEST_COMMANDS: "1"

  # Generate coverage report?
  - id: coverage
    display_name: "Coverage"
    values:
      - id: "coverage"
        display_name: "Coverage"
        tags: ["coverage_tag"]
        variables:
           COVERAGE: "coverage"

  # Run encryption tests?
  - id: encryption
    display_name: "Encryption"
    values:
      - id: "encryption"
        display_name: "Encryption"
        tags: ["encryption_tag"]
        variables:
          test_encryption: true
        batchtime: 10080  # 7 days

  # Run pyopenssl tests?
  - id: pyopenssl
    display_name: "PyOpenSSL"
    values:
      - id: "enabled"
        display_name: "PyOpenSSL"
        variables:
          test_pyopenssl: true
        batchtime: 10080  # 7 days

  - id: versionedApi
    display_name: "versionedApi"
    values:
      # Test against a cluster with requireApiVersion=1.
      - id: "requireApiVersion1"
        display_name: "requireApiVersion1"
        tags: [ "versionedApi_tag" ]
        variables:
          # REQUIRE_API_VERSION is set to make drivers-evergreen-tools
          # start a cluster with the requireApiVersion parameter.
          REQUIRE_API_VERSION: "1"
          # MONGODB_API_VERSION is the apiVersion to use in the test suite.
          MONGODB_API_VERSION: "1"
      # Test against a cluster with acceptApiVersion2 but without
      # requireApiVersion, and don't automatically add apiVersion to
      # clients created in the test suite.
      - id: "acceptApiVersion2"
        display_name: "acceptApiVersion2"
        tags: [ "versionedApi_tag" ]
        variables:
          ORCHESTRATION_FILE: "versioned-api-testing.json"

  # Run load balancer tests?
  - id: loadbalancer
    display_name: "Load Balancer"
    values:
      - id: "enabled"
        display_name: "Load Balancer"
        variables:
          test_loadbalancer: true
        batchtime: 10080  # 7 days

  - id: serverless
    display_name: "Serverless"
    values:
      - id: "enabled"
        display_name: "Serverless"
        variables:
          test_serverless: true
        batchtime: 10080  # 7 days

buildvariants:
- matrix_name: "tests-all"
  matrix_spec:
    platform:
      # OSes that support versions of MongoDB>=2.6 with SSL.
      - awslinux
    auth-ssl: "*"
  display_name: "${platform} ${auth-ssl}"
  tasks: &all-server-versions
    - ".rapid"
    - ".latest"
    - ".5.0"
    - ".4.4"
    - ".4.2"
    - ".4.0"
    - ".3.6"

- matrix_name: "tests-all-encryption"
  matrix_spec:
    platform:
      # OSes that support versions of MongoDB>=2.6 with SSL.
      - awslinux
    auth-ssl: "*"
    encryption: "*"
  display_name: "Encryption ${platform} ${auth-ssl}"
  tasks: &encryption-server-versions
    - ".latest"
    - ".5.0"
    - ".4.4"
    - ".4.2"
    - ".4.0"

- matrix_name: "tests-archlinux"
  matrix_spec:
    platform:
      # Archlinux supports MongoDB without SSL.
      # MongoDB 4.2 drops support for archlinux (generic linux builds).
      - archlinux-test
    auth: "*"
    ssl: "nossl"
  display_name: "${platform} ${auth} ${ssl}"
  tasks:
    - ".4.0"
    - ".3.6"

- matrix_name: "tests-fips"
  matrix_spec:
    platform:
      - rhel70-fips
    auth: "auth"
    ssl: "ssl"
  display_name: "${platform} ${auth} ${ssl}"
  tasks:
    - "test-fips-standalone"

- matrix_name: "test-macos"
  matrix_spec:
    platform:
      # MacOS introduced SSL support with MongoDB >= 3.2.
      # Older server versions (2.6, 3.0) are supported without SSL.
      - macos-1014
    auth: "*"
    ssl: "*"
  exclude_spec:
    # No point testing with SSL without auth.
    - platform: macos-1014
      auth: "noauth"
      ssl: "ssl"
  display_name: "${platform} ${auth} ${ssl}"
  tasks:
    - ".latest"
    - ".5.0"
    - ".4.4"
    - ".4.2"
    - ".4.0"
    - ".3.6"

- matrix_name: "test-macos-encryption"
  matrix_spec:
    platform:
      - macos-1014
    auth: "auth"
    ssl: "nossl"
    encryption: "*"
  display_name: "Encryption ${platform} ${auth} ${ssl}"
  tasks: *encryption-server-versions

# Test one server version (4.2) with zSeries, POWER8, and ARM.
- matrix_name: "test-different-cpu-architectures"
  matrix_spec:
    platform:
      - ubuntu1804-zseries # Ubuntu 18 or RHEL 8.x?
      - ubuntu1804-power8 # Ubuntu 18 or RHEL 7?
      - ubuntu1804-arm64
    auth-ssl: "*"
  display_name: "${platform} ${auth-ssl}"
  tasks:
    - ".4.2"

- matrix_name: "tests-python-version-ubuntu18-test-ssl"
  matrix_spec:
    platform: ubuntu-18.04
    python-version: "*"
    auth-ssl: "*"
    coverage: "*"
  display_name: "${python-version} ${platform} ${auth-ssl} ${coverage}"
  tasks: *all-server-versions

- matrix_name: "tests-pyopenssl"
  matrix_spec:
    platform: ubuntu-18.04
    python-version: "*"
    auth: "*"
    ssl: "ssl"
    pyopenssl: "*"
  # Only test "noauth" with Python 3.7.
  exclude_spec:
    platform: ubuntu-18.04
    python-version: ["3.6", "3.8", "3.9", "3.10", "pypy3.6", "pypy3.7", "pypy3.8"]
    auth: "noauth"
    ssl: "ssl"
    pyopenssl: "*"
  display_name: "PyOpenSSL ${platform} ${python-version} ${auth}"
  tasks:
    - '.replica_set'
    # Test standalone and sharded only on 5.0 and later.
    - '.5.0'

- matrix_name: "tests-pyopenssl-macOS"
  matrix_spec:
    platform: macos-1014
    auth: "auth"
    ssl: "ssl"
    pyopenssl: "*"
  display_name: "PyOpenSSL ${platform} ${auth}"
  tasks:
    - '.replica_set'

- matrix_name: "tests-pyopenssl-windows"
  matrix_spec:
    platform: windows-64-vsMulti-small
    python-version-windows: "*"
    auth: "auth"
    ssl: "ssl"
    pyopenssl: "*"
  display_name: "PyOpenSSL ${platform} ${python-version-windows} ${auth}"
  tasks:
    - '.replica_set'

- matrix_name: "tests-python-version-ubuntu18-test-encryption"
  matrix_spec:
    platform: ubuntu-18.04
    python-version: "*"
    auth-ssl: noauth-nossl
# TODO: dependency error for 'coverage-report' task:
# dependency tests-python-version-rhel62-test-encryption_.../test-2.6-standalone is not present in the project config
#    coverage: "*"
    encryption: "*"
  display_name: "Encryption ${python-version} ${platform} ${auth-ssl}"
  tasks: *encryption-server-versions

- matrix_name: "tests-python-version-ubuntu18-without-c-extensions"
  matrix_spec:
    platform: ubuntu-18.04
    python-version: "*"
    c-extensions: without-c-extensions
    auth-ssl: noauth-nossl
    coverage: "*"
  exclude_spec:
   # These interpreters are always tested without extensions.
   - platform: ubuntu-18.04
     python-version: ["pypy3.6", "pypy3.7", "pypy3.8"]
     c-extensions: "*"
     auth-ssl: "*"
     coverage: "*"
  display_name: "${c-extensions} ${python-version} ${platform} ${auth} ${ssl} ${coverage}"
  tasks: *all-server-versions

- matrix_name: "tests-python-version-ubuntu18-compression"
  matrix_spec:
    platform: ubuntu-18.04
    python-version: "*"
    c-extensions: "*"
    compression: "*"
  exclude_spec:
   # These interpreters are always tested without extensions.
   - platform: ubuntu-18.04
     python-version: ["pypy3.6", "pypy3.7", "pypy3.8"]
     c-extensions: "with-c-extensions"
     compression: "*"
  display_name: "${compression} ${c-extensions} ${python-version} ${platform}"
  tasks:
    - "test-latest-standalone"
    - "test-5.0-standalone"
    - "test-4.4-standalone"
    - "test-4.2-standalone"
  rules:
    # Server versions 3.6 and 4.0 support snappy and zlib.
    - if:
        python-version: "*"
        c-extensions: "*"
        compression: ["snappy", "zlib"]
      then:
        add_tasks:
          - "test-4.0-standalone"
          - "test-3.6-standalone"

- matrix_name: "tests-python-version-green-framework-ubuntu18"
  matrix_spec:
    platform: ubuntu-18.04
    python-version: "*"
    green-framework: "*"
    auth-ssl: "*"
  exclude_spec:
   # Don't test green frameworks on these Python versions.
   - platform: ubuntu-18.04
     python-version: ["pypy3.6", "pypy3.7", "pypy3.8", "system-python3"]
     green-framework: "*"
     auth-ssl: "*"
  display_name: "${green-framework} ${python-version} ${platform} ${auth-ssl}"
  tasks: *all-server-versions

- matrix_name: "tests-windows-python-version"
  matrix_spec:
    platform: windows-64-vsMulti-small
    python-version-windows: "*"
    auth-ssl: "*"
  display_name: "${platform} ${python-version-windows} ${auth-ssl}"
  tasks: *all-server-versions

- matrix_name: "tests-windows-python-version-32-bit"
  matrix_spec:
    platform: windows-64-vsMulti-small
    python-version-windows-32: "*"
    auth-ssl: "*"
  display_name: "${platform} ${python-version-windows-32} ${auth-ssl}"
  tasks: *all-server-versions

- matrix_name: "tests-python-version-supports-openssl-102-test-ssl"
  matrix_spec:
    platform: awslinux
    # Python 3.10+ requires OpenSSL 1.1.1+
    python-version: ["3.6", "3.7", "3.8", "3.9", "pypy3.6", "pypy3.7", "pypy3.8"]
    auth-ssl: "*"
  display_name: "OpenSSL 1.0.2 ${python-version} ${platform} ${auth-ssl}"
  tasks:
     - ".latest"

- matrix_name: "tests-windows-encryption"
  matrix_spec:
    platform: windows-64-vsMulti-small
    python-version-windows: "*"
    auth-ssl: "*"
    encryption: "*"
  display_name: "Encryption ${platform} ${python-version-windows} ${auth-ssl}"
  tasks: *encryption-server-versions

# Storage engine tests on Ubuntu 18.04 (x86_64) with Python 3.6.
- matrix_name: "tests-storage-engines"
  matrix_spec:
    platform: ubuntu-18.04
    storage-engine: "*"
    python-version: 3.6
  display_name: "Storage ${storage-engine} ${python-version} ${platform}"
  rules:
    - if:
        platform: ubuntu-18.04
        storage-engine: ["inmemory"]
        python-version: "*"
      then:
        add_tasks:
          - "test-latest-standalone"
          - "test-5.0-standalone"
          - "test-4.4-standalone"
          - "test-4.2-standalone"
          - "test-4.0-standalone"
          - "test-3.6-standalone"
    - if:
        # MongoDB 4.2 drops support for MMAPv1
        platform: ubuntu-18.04
        storage-engine: ["mmapv1"]
        python-version: "*"
      then:
        add_tasks:
          - "test-4.0-standalone"
          - "test-4.0-replica_set"
          - "test-3.6-standalone"
          - "test-3.6-replica_set"

# enableTestCommands=0 tests on Ubuntu18 (x86_64) with Python 3.6.
- matrix_name: "test-disableTestCommands"
  matrix_spec:
    platform: ubuntu-18.04
    disableTestCommands: "*"
    python-version: "3.6"
  display_name: "Disable test commands ${python-version} ${platform}"
  tasks:
     - ".latest"

- matrix_name: "test-linux-enterprise-auth"
  matrix_spec:
    platform: ubuntu-18.04
    python-version: "*"
    auth: "auth"
  display_name: "Enterprise ${auth} ${platform} ${python-version}"
  tasks:
     - name: "test-enterprise-auth"

- matrix_name: "tests-windows-enterprise-auth"
  matrix_spec:
    platform: windows-64-vsMulti-small
    python-version-windows: "*"
    auth: "auth"
  display_name: "Enterprise ${auth} ${platform} ${python-version-windows}"
  tasks:
     - name: "test-enterprise-auth"

- matrix_name: "tests-mod-wsgi"
  matrix_spec:
    platform: ubuntu-18.04
    python-version: ["3.6", "3.7", "3.8", "3.9", "3.10"]
    mod-wsgi-version: "*"
  exclude_spec:
   # mod-wsgi 3.5 won't build against CPython 3.8+
   - platform: ubuntu-18.04
     python-version: ["3.8", "3.9", "3.10"]
     mod-wsgi-version: "3"
  display_name: "${mod-wsgi-version} ${python-version} ${platform}"
  tasks:
     - name: "mod-wsgi-standalone"
     - name: "mod-wsgi-replica-set"

- matrix_name: "mockupdb-tests"
  matrix_spec:
    platform: ubuntu-18.04
    python-version: 3.6
  display_name: "MockupDB Tests"
  tasks:
     - name: "mockupdb"

- matrix_name: "tests-doctests"
  matrix_spec:
    platform: ubuntu-18.04
    python-version: ["3.8"]
  display_name: "Doctests ${python-version} ${platform}"
  tasks:
     - name: "doctests"

- name: "no-server"
  display_name: "No server test"
  run_on:
    - ubuntu1804-test
  tasks:
    - name: "no-server"
  expansions:
    set_xtrace_on: on

- name: "Coverage Report"
  display_name: "Coverage Report"
  run_on:
    - ubuntu1804-test
  tasks:
     - name: "coverage-report"
  expansions:
    set_xtrace_on: on

- matrix_name: "atlas-connect"
  matrix_spec:
    platform: ubuntu-18.04
    python-version: "*"
  display_name: "Atlas connect ${python-version} ${platform}"
  tasks:
    - name: "atlas-connect"

- matrix_name: "serverless"
  matrix_spec:
    platform: ubuntu-18.04
    python-version: "*"
    auth-ssl: auth-ssl
    serverless: "*"
  exclude_spec:
   - platform: ubuntu-18.04
     python-version: ["system-python3"]
     auth-ssl: auth-ssl
     serverless: "*"
  display_name: "Serverless ${python-version} ${platform}"
  tasks:
    - "serverless_task_group"

- matrix_name: "data-lake-spec-tests"
  matrix_spec:
    platform: ubuntu-18.04
    python-version: ["3.6", "3.10"]
    auth: "auth"
    c-extensions: "*"
  display_name: "Atlas Data Lake ${python-version} ${c-extensions}"
  tasks:
    - name: atlas-data-lake-tests

- matrix_name: "stable-api-tests"
  matrix_spec:
    platform: ubuntu-18.04
    python-version: ["3.6", "3.10"]
    auth: "auth"
    versionedApi: "*"
  display_name: "Versioned API ${versionedApi} ${python-version}"
  batchtime: 10080  # 7 days
  tasks:
    # Versioned API was introduced in MongoDB 4.7
    - "test-latest-standalone"
    - "test-5.0-standalone"

- matrix_name: "ocsp-test"
  matrix_spec:
    # OCSP stapling is not supported on Ubuntu 18.04.
    # See https://jira.mongodb.org/browse/SERVER-51364.
    platform: ubuntu-20.04
    python-version: ["3.6", "3.10", "pypy3.6", "pypy3.8"]
    mongodb-version: ["4.4", "5.0", "latest"]
    auth: "noauth"
    ssl: "ssl"
  display_name: "OCSP test ${platform} ${python-version} ${mongodb-version}"
  batchtime: 20160 # 14 days
  tasks:
    - name: ".ocsp"

- matrix_name: "ocsp-test-windows"
  matrix_spec:
    platform: windows-64-vsMulti-small
    python-version-windows: ["3.6", "3.10"]
    mongodb-version: ["4.4", "5.0", "latest"]
    auth: "noauth"
    ssl: "ssl"
  display_name: "OCSP test ${platform} ${python-version-windows} ${mongodb-version}"
  batchtime: 20160 # 14 days
  tasks:
    # Windows MongoDB servers do not staple OCSP responses and only support RSA.
    - name: ".ocsp-rsa !.ocsp-staple"

- matrix_name: "ocsp-test-macos"
  matrix_spec:
    platform: macos-1014
    mongodb-version: ["4.4", "5.0", "latest"]
    auth: "noauth"
    ssl: "ssl"
  display_name: "OCSP test ${platform} ${mongodb-version}"
  batchtime: 20160 # 14 days
  tasks:
    # macOS MongoDB servers do not staple OCSP responses and only support RSA.
    - name: ".ocsp-rsa !.ocsp-staple"

- matrix_name: "aws-auth-test"
  matrix_spec:
    platform: [ubuntu-18.04, macos-1014]
    python-version: ["system-python3"]
  display_name: "MONGODB-AWS Auth ${platform} ${python-version}"
  tasks:
    - name: "aws-auth-test-4.4"
    - name: "aws-auth-test-5.0"
    - name: "aws-auth-test-latest"

- matrix_name: "aws-auth-test-windows"
  matrix_spec:
    platform: [windows-64-vsMulti-small]
    python-version-windows: "*"
  display_name: "MONGODB-AWS Auth ${platform} ${python-version-windows}"
  tasks:
    - name: "aws-auth-test-4.4"
    - name: "aws-auth-test-5.0"
    - name: "aws-auth-test-latest"

- matrix_name: "load-balancer"
  matrix_spec:
    platform: ubuntu-18.04
    mongodb-version: ["rapid", "latest"]
    auth-ssl: "*"
    python-version: "*"
    loadbalancer: "*"
  display_name: "Load Balancer ${platform} ${python-version} ${mongodb-version} ${auth-ssl}"
  tasks:
    - name: "load-balancer-test"

- name: Release
  display_name: Release
  batchtime: 20160 # 14 days
  tags: ["release_tag"]
  tasks:
  - ".release_tag"

      # Platform notes
      # i386 builds of OpenSSL or Cyrus SASL are not available
      # Ubuntu16.04 ppc64le is only supported by MongoDB 3.4+
      # Ubuntu16.04 aarch64 is only supported by MongoDB 3.4+
      # Ubuntu16.04 s390x is only supported by MongoDB 3.4+
      # Ubuntu16.04 (x86) only supports MongoDB 3.2+
      # Debian 8.1 only supports MongoDB 3.4+
      # SUSE12 s390x is only supported by MongoDB 3.4+
      # No enterprise build for Archlinux, SSL not available
      # RHEL 7 only supports 2.6+
      # RHEL 7.1 ppc64le is only supported by MongoDB 3.2+
      # RHEL 7.2 s390x is only supported by MongoDB 3.4+
      # Solaris MongoDB SSL builds are not available
      # Darwin MongoDB SSL builds are not available for 2.6
      # SUSE12 x86_64 is only supported by MongoDB 3.2+
      # vim: set et sw=2 ts=2 :
