From fe1b07d4d5f83c5830df0f1d427c1c5bb984a767 Mon Sep 17 00:00:00 2001 From: Iris Ho Date: Tue, 6 May 2025 16:42:54 -0700 Subject: [PATCH 01/22] WIP --- .evergreen/config.yml | 9 +++ .evergreen/scripts/resync_all_specs.sh | 94 ++++++++++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100755 .evergreen/scripts/resync_all_specs.sh diff --git a/.evergreen/config.yml b/.evergreen/config.yml index 46c86103ad..71e54185fc 100644 --- a/.evergreen/config.yml +++ b/.evergreen/config.yml @@ -42,3 +42,12 @@ post: - func: "upload mo artifacts" - func: "upload test results" - func: "cleanup" + +tasks: + - name: resync_specs + commands: + - command: subprocess.exec + params: + binary: bash + args: + - .evergreen/scripts/resync_all_specs.sh diff --git a/.evergreen/scripts/resync_all_specs.sh b/.evergreen/scripts/resync_all_specs.sh new file mode 100755 index 0000000000..51c034d908 --- /dev/null +++ b/.evergreen/scripts/resync_all_specs.sh @@ -0,0 +1,94 @@ +#!/bin/bash +# Run spec syncing script and create PR + +SPEC_DEST="../../test" +SRC_URL="https://github.com/mongodb/specifications.git" +# needs to be set for resunc-specs.sh +SPEC_SRC="../../../specifications" +SCRIPT="../resync-specs.sh" +BRANCH_NAME="spec-resync-"$(date '+%m-%d-%Y') + +# List of directories to skip +SKIP_DIRECTORIES=("asynchronous" "__pycache__") +# we have a list of specs that we manually override *if the git diff is that specific line, then don't change it +# *ask in python channel +SKIP_FILES=() +# ask steve for how to create PR from evergreen account(?) +# for now, treat it like a command line thing and git add *, git commit, git push + +# Clone the repo if the directory does not exist +if [[ ! -d $SPEC_SRC ]]; then + git clone $SRC_URL $SPEC_SRC + if [[ $? -ne 0 ]]; then + echo "Error: Failed to clone repository." + exit 1 + fi +fi + +# Set environment variable to the cloned repo for resync-specs.sh +export MDB_SPECS="$SPEC_SRC" + +# Check that resync script exists and is executable +if [[ ! -x $SCRIPT ]]; then + echo "Error: $SCRIPT not found or is not executable." + exit 1 +fi + +# List to store names of specs that were changed or errored during change +changed_specs=() +errored_specs=() + +# Create branch and switch to it +git checkout -b $BRANCH_NAME 2>/dev/null || git checkout $BRANCH_NAME + +for item in "$SPEC_DEST"/*; do + item_name=$(basename "$item") + if [[ " ${SKIP_DIRECTORIES[*]} " =~ ${item_name} ]]; then + continue + fi + + # Check that item is not a python file + if [[ $item != *.py ]]; then + + output=$(./$SCRIPT "$item_name" 2>&1) + + # Check if the script ran successfully + if [[ $? -ne 0 ]]; then + errored_specs+=("$item_name") + else + # if script had output, then changes were made + if [[ -n "$output" ]]; then + changed_specs+=("$item_name") + fi + fi + fi +done + +pr_body="Spec sync results:\n\n" +# Output the list of changed specs +if [[ ${#changed_specs[@]} -gt 0 ]]; then + pr_body+="The following specs were changed:\n" + for spec in "${changed_specs[@]}"; do + pr_body+=" - $spec\n" + done +else + pr_body+="No changes detected in any specs.\n" +fi + +# Output the list of errored specs +if [[ ${#errored_specs[@]} -gt 0 ]]; then + pr_body+="\nThe following spec syncs encountered errors:\n" + for spec in "${errored_specs[@]}"; do + pr_body+=" - $spec\n" + done +else + pr_body+="\nNo errors were encountered in any specs syncs.\n" +fi + +# Output the PR body (optional step for verification) +echo -e "$pr_body" + +git add $SPEC_DEST +git commit -m $BRANCH_NAME +git push -u origin $BRANCH_NAME +#gh pr create --title "[Spec Resync] $(date '+%m-%d-%Y')" --body "Resyncing specs for review" --base main --head $BRANCH_NAME --draft From f822f31187d3d5c49500b4b43da520cdcd4bdbea Mon Sep 17 00:00:00 2001 From: Iris Ho Date: Thu, 8 May 2025 10:54:40 -0700 Subject: [PATCH 02/22] trying to get it to work locally? --- .evergreen/config.yml | 2 +- .evergreen/scripts/create-pr.sh | 40 +++++++++++++++++++ ...esync_all_specs.sh => resync-all-specs.sh} | 16 +++++--- 3 files changed, 51 insertions(+), 7 deletions(-) create mode 100755 .evergreen/scripts/create-pr.sh rename .evergreen/scripts/{resync_all_specs.sh => resync-all-specs.sh} (90%) diff --git a/.evergreen/config.yml b/.evergreen/config.yml index 71e54185fc..7d4e8dfe18 100644 --- a/.evergreen/config.yml +++ b/.evergreen/config.yml @@ -50,4 +50,4 @@ tasks: params: binary: bash args: - - .evergreen/scripts/resync_all_specs.sh + - .evergreen/scripts/resync-all-specs.sh diff --git a/.evergreen/scripts/create-pr.sh b/.evergreen/scripts/create-pr.sh new file mode 100755 index 0000000000..c247b1a7c4 --- /dev/null +++ b/.evergreen/scripts/create-pr.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash + +# Get a github access token for the git checkout. +echo "Getting github token..." +# clone drivers-evergreen-tools to get this get-access-token script... +tools="../../../drivers-evergreen-tools" +git clone https://github.com/mongodb-labs/drivers-evergreen-tools.git $tools + +owner="mongodb" +repo="mongo-python-driver" +token=$(bash $tools/.evergreen/github_app/get-access-token.sh $repo $owner) +if [ -z "${token}" ]; then + echo "Failed to get github access token!" + exit 1 +fi +echo "Getting github token... done." + +# Make the git checkout and create a new branch. +echo "Creating the git checkout..." +branch="spec-resync-"$(date '+%m-%d-%Y') +body="$(cat spec_sync.txt)" + +git config user.email "167856002+mongodb-dbx-release-bot[bot]@users.noreply.github.com" +git config user.name "mongodb-dbx-release-bot[bot]" +git remote set-url origin https://x-access-token:${token}@github.com/$owner/$repo.git +git checkout -b $branch "origin/main" +echo "Creating the git checkout... done." + +git push origin $branch +resp=$(curl -L \ + -X POST \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer $token" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + -d "{\"title\":\"[Spec Resync] $(date '+%m-%d-%Y')\",\"body\":\"${body}\",\"head\":\"${branch}\",\"base\":\"main\"}" \ + --url https://api.github.com/repos/$owner/$repo/pulls) +echo $resp | jq '.html_url' +echo "Creating the PR... done." + +rm -rf $dirname diff --git a/.evergreen/scripts/resync_all_specs.sh b/.evergreen/scripts/resync-all-specs.sh similarity index 90% rename from .evergreen/scripts/resync_all_specs.sh rename to .evergreen/scripts/resync-all-specs.sh index 51c034d908..75c8a6d8f1 100755 --- a/.evergreen/scripts/resync_all_specs.sh +++ b/.evergreen/scripts/resync-all-specs.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Run spec syncing script and create PR SPEC_DEST="../../test" @@ -39,7 +39,7 @@ changed_specs=() errored_specs=() # Create branch and switch to it -git checkout -b $BRANCH_NAME 2>/dev/null || git checkout $BRANCH_NAME +#git checkout -b $BRANCH_NAME 2>/dev/null || git checkout $BRANCH_NAME for item in "$SPEC_DEST"/*; do item_name=$(basename "$item") @@ -86,9 +86,13 @@ else fi # Output the PR body (optional step for verification) -echo -e "$pr_body" +echo "$pr_body" >> spec_sync.txt -git add $SPEC_DEST -git commit -m $BRANCH_NAME -git push -u origin $BRANCH_NAME +# call scrypt to create PR for us +./create-pr.sh + +rm spec_sync.txt +#git add $SPEC_DEST +#git commit -m $BRANCH_NAME +#git push -u origin $BRANCH_NAME #gh pr create --title "[Spec Resync] $(date '+%m-%d-%Y')" --body "Resyncing specs for review" --base main --head $BRANCH_NAME --draft From 6909518c7063a5236f75fad9cca1b5148ac296e5 Mon Sep 17 00:00:00 2001 From: Iris Ho Date: Mon, 12 May 2025 10:49:25 -0700 Subject: [PATCH 03/22] wip --- .evergreen/config.yml | 9 +++++++++ .evergreen/resync-specs.sh | 1 + .evergreen/scripts/create-pr.sh | 20 ++++++++++++++------ .evergreen/scripts/resync-all-specs.sh | 15 ++++++++------- 4 files changed, 32 insertions(+), 13 deletions(-) diff --git a/.evergreen/config.yml b/.evergreen/config.yml index 7d4e8dfe18..2edf027121 100644 --- a/.evergreen/config.yml +++ b/.evergreen/config.yml @@ -51,3 +51,12 @@ tasks: binary: bash args: - .evergreen/scripts/resync-all-specs.sh + working_dir: src + +buildvariants: + - name: resync_specs + display_name: "Resync Specs" + run_on: rhel80-small + patchable: true + tasks: + - name: resync_specs diff --git a/.evergreen/resync-specs.sh b/.evergreen/resync-specs.sh index 1f70940aa0..d4e785c39d 100755 --- a/.evergreen/resync-specs.sh +++ b/.evergreen/resync-specs.sh @@ -3,6 +3,7 @@ set -eu PYMONGO=$(dirname "$(cd "$(dirname "$0")"; pwd)") SPECS=${MDB_SPECS:-~/Work/specifications} +echo "$SPECS" help (){ echo "Usage: resync_specs.sh [-bcsp] spec" diff --git a/.evergreen/scripts/create-pr.sh b/.evergreen/scripts/create-pr.sh index c247b1a7c4..0973cd452b 100755 --- a/.evergreen/scripts/create-pr.sh +++ b/.evergreen/scripts/create-pr.sh @@ -1,16 +1,24 @@ #!/usr/bin/env bash -# Get a github access token for the git checkout. -echo "Getting github token..." # clone drivers-evergreen-tools to get this get-access-token script... -tools="../../../drivers-evergreen-tools" +tools="../drivers-evergreen-tools" git clone https://github.com/mongodb-labs/drivers-evergreen-tools.git $tools +body="$(cat "$1")" + +pushd $tools/.evergreen/github_app + +# Get a github access token for the git checkout. +echo "Getting github token..." owner="mongodb" repo="mongo-python-driver" -token=$(bash $tools/.evergreen/github_app/get-access-token.sh $repo $owner) + +./setup-secrets.sh +echo "finish setting up secrets" +token=$(bash ./get-access-token.sh $repo $owner) if [ -z "${token}" ]; then echo "Failed to get github access token!" + popd exit 1 fi echo "Getting github token... done." @@ -18,12 +26,12 @@ echo "Getting github token... done." # Make the git checkout and create a new branch. echo "Creating the git checkout..." branch="spec-resync-"$(date '+%m-%d-%Y') -body="$(cat spec_sync.txt)" git config user.email "167856002+mongodb-dbx-release-bot[bot]@users.noreply.github.com" git config user.name "mongodb-dbx-release-bot[bot]" git remote set-url origin https://x-access-token:${token}@github.com/$owner/$repo.git -git checkout -b $branch "origin/main" +git checkout -b $branch "origin/master" +git add echo "Creating the git checkout... done." git push origin $branch diff --git a/.evergreen/scripts/resync-all-specs.sh b/.evergreen/scripts/resync-all-specs.sh index 75c8a6d8f1..4563dd3171 100755 --- a/.evergreen/scripts/resync-all-specs.sh +++ b/.evergreen/scripts/resync-all-specs.sh @@ -1,11 +1,11 @@ #!/usr/bin/env bash # Run spec syncing script and create PR -SPEC_DEST="../../test" +SPEC_DEST="test" SRC_URL="https://github.com/mongodb/specifications.git" # needs to be set for resunc-specs.sh -SPEC_SRC="../../../specifications" -SCRIPT="../resync-specs.sh" +SPEC_SRC="../specifications" +SCRIPT=".evergreen/resync-specs.sh" BRANCH_NAME="spec-resync-"$(date '+%m-%d-%Y') # List of directories to skip @@ -49,9 +49,9 @@ for item in "$SPEC_DEST"/*; do # Check that item is not a python file if [[ $item != *.py ]]; then - - output=$(./$SCRIPT "$item_name" 2>&1) - + echo " doing $item_name" +# output=$(./$SCRIPT "$item_name" 2>&1) + output=$($SCRIPT "$item_name") # Check if the script ran successfully if [[ $? -ne 0 ]]; then errored_specs+=("$item_name") @@ -86,10 +86,11 @@ else fi # Output the PR body (optional step for verification) +echo "$pr_body" echo "$pr_body" >> spec_sync.txt # call scrypt to create PR for us -./create-pr.sh +.evergreen/scripts/create-pr.sh spec_sync.txt rm spec_sync.txt #git add $SPEC_DEST From 73139a4bc93240622432a651aeb6b4344b6fbca8 Mon Sep 17 00:00:00 2001 From: Iris Ho Date: Thu, 5 Jun 2025 09:13:40 -0700 Subject: [PATCH 04/22] still a wip --- .evergreen/resync-specs.sh | 10 ++++++---- .evergreen/scripts/create-pr.sh | 17 ++++++++++------- .evergreen/scripts/resync-all-specs.sh | 15 ++++++++++----- 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/.evergreen/resync-specs.sh b/.evergreen/resync-specs.sh index d4e785c39d..ce6852c246 100755 --- a/.evergreen/resync-specs.sh +++ b/.evergreen/resync-specs.sh @@ -3,7 +3,6 @@ set -eu PYMONGO=$(dirname "$(cd "$(dirname "$0")"; pwd)") SPECS=${MDB_SPECS:-~/Work/specifications} -echo "$SPECS" help (){ echo "Usage: resync_specs.sh [-bcsp] spec" @@ -46,9 +45,12 @@ then fi # Ensure the JSON files are up to date. -cd $SPECS/source -make -cd - +if ! [ -n "${CI:-}" ] +then + cd $SPECS/source + make + cd - +fi # cpjson unified-test-format/tests/invalid unified-test-format/invalid # * param1: Path to spec tests dir in specifications repo # * param2: Path to where the corresponding tests live in Python. diff --git a/.evergreen/scripts/create-pr.sh b/.evergreen/scripts/create-pr.sh index 0973cd452b..397f6d91e2 100755 --- a/.evergreen/scripts/create-pr.sh +++ b/.evergreen/scripts/create-pr.sh @@ -1,20 +1,23 @@ #!/usr/bin/env bash -# clone drivers-evergreen-tools to get this get-access-token script... tools="../drivers-evergreen-tools" git clone https://github.com/mongodb-labs/drivers-evergreen-tools.git $tools body="$(cat "$1")" pushd $tools/.evergreen/github_app -# Get a github access token for the git checkout. -echo "Getting github token..." - owner="mongodb" repo="mongo-python-driver" -./setup-secrets.sh -echo "finish setting up secrets" +echo "bootstrapping?" +# Bootstrap the app. +source utils.sh +bootstrap drivers/release-bot + +# Run the app. + +# Get a github access token for the git checkout. +echo "Getting github token..." token=$(bash ./get-access-token.sh $repo $owner) if [ -z "${token}" ]; then echo "Failed to get github access token!" @@ -31,7 +34,7 @@ git config user.email "167856002+mongodb-dbx-release-bot[bot]@users.noreply.gith git config user.name "mongodb-dbx-release-bot[bot]" git remote set-url origin https://x-access-token:${token}@github.com/$owner/$repo.git git checkout -b $branch "origin/master" -git add +git add ./test echo "Creating the git checkout... done." git push origin $branch diff --git a/.evergreen/scripts/resync-all-specs.sh b/.evergreen/scripts/resync-all-specs.sh index 4563dd3171..9a0392c754 100755 --- a/.evergreen/scripts/resync-all-specs.sh +++ b/.evergreen/scripts/resync-all-specs.sh @@ -1,11 +1,11 @@ #!/usr/bin/env bash # Run spec syncing script and create PR -SPEC_DEST="test" +SPEC_DEST="$(realpath -s "./test")" SRC_URL="https://github.com/mongodb/specifications.git" # needs to be set for resunc-specs.sh -SPEC_SRC="../specifications" -SCRIPT=".evergreen/resync-specs.sh" +SPEC_SRC="$(realpath -s "../specifications")" +SCRIPT="$(realpath -s ".evergreen/resync-specs.sh")" BRANCH_NAME="spec-resync-"$(date '+%m-%d-%Y') # List of directories to skip @@ -27,6 +27,7 @@ fi # Set environment variable to the cloned repo for resync-specs.sh export MDB_SPECS="$SPEC_SRC" +echo "$SPEC_SRC" # Check that resync script exists and is executable if [[ ! -x $SCRIPT ]]; then @@ -51,13 +52,15 @@ for item in "$SPEC_DEST"/*; do if [[ $item != *.py ]]; then echo " doing $item_name" # output=$(./$SCRIPT "$item_name" 2>&1) - output=$($SCRIPT "$item_name") + $SCRIPT "$item_name" # Check if the script ran successfully if [[ $? -ne 0 ]]; then + echo "an error occurred" errored_specs+=("$item_name") else # if script had output, then changes were made if [[ -n "$output" ]]; then + echo "success" changed_specs+=("$item_name") fi fi @@ -86,9 +89,11 @@ else fi # Output the PR body (optional step for verification) -echo "$pr_body" +echo -e "$pr_body" echo "$pr_body" >> spec_sync.txt +git diff + # call scrypt to create PR for us .evergreen/scripts/create-pr.sh spec_sync.txt From b3a2b2958a2ad2f728a2231c31acc90304761842 Mon Sep 17 00:00:00 2001 From: Iris Ho Date: Tue, 6 May 2025 16:42:54 -0700 Subject: [PATCH 05/22] WIP --- .evergreen/config.yml | 9 +++ .evergreen/scripts/resync_all_specs.sh | 94 ++++++++++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100755 .evergreen/scripts/resync_all_specs.sh diff --git a/.evergreen/config.yml b/.evergreen/config.yml index 46c86103ad..71e54185fc 100644 --- a/.evergreen/config.yml +++ b/.evergreen/config.yml @@ -42,3 +42,12 @@ post: - func: "upload mo artifacts" - func: "upload test results" - func: "cleanup" + +tasks: + - name: resync_specs + commands: + - command: subprocess.exec + params: + binary: bash + args: + - .evergreen/scripts/resync_all_specs.sh diff --git a/.evergreen/scripts/resync_all_specs.sh b/.evergreen/scripts/resync_all_specs.sh new file mode 100755 index 0000000000..51c034d908 --- /dev/null +++ b/.evergreen/scripts/resync_all_specs.sh @@ -0,0 +1,94 @@ +#!/bin/bash +# Run spec syncing script and create PR + +SPEC_DEST="../../test" +SRC_URL="https://github.com/mongodb/specifications.git" +# needs to be set for resunc-specs.sh +SPEC_SRC="../../../specifications" +SCRIPT="../resync-specs.sh" +BRANCH_NAME="spec-resync-"$(date '+%m-%d-%Y') + +# List of directories to skip +SKIP_DIRECTORIES=("asynchronous" "__pycache__") +# we have a list of specs that we manually override *if the git diff is that specific line, then don't change it +# *ask in python channel +SKIP_FILES=() +# ask steve for how to create PR from evergreen account(?) +# for now, treat it like a command line thing and git add *, git commit, git push + +# Clone the repo if the directory does not exist +if [[ ! -d $SPEC_SRC ]]; then + git clone $SRC_URL $SPEC_SRC + if [[ $? -ne 0 ]]; then + echo "Error: Failed to clone repository." + exit 1 + fi +fi + +# Set environment variable to the cloned repo for resync-specs.sh +export MDB_SPECS="$SPEC_SRC" + +# Check that resync script exists and is executable +if [[ ! -x $SCRIPT ]]; then + echo "Error: $SCRIPT not found or is not executable." + exit 1 +fi + +# List to store names of specs that were changed or errored during change +changed_specs=() +errored_specs=() + +# Create branch and switch to it +git checkout -b $BRANCH_NAME 2>/dev/null || git checkout $BRANCH_NAME + +for item in "$SPEC_DEST"/*; do + item_name=$(basename "$item") + if [[ " ${SKIP_DIRECTORIES[*]} " =~ ${item_name} ]]; then + continue + fi + + # Check that item is not a python file + if [[ $item != *.py ]]; then + + output=$(./$SCRIPT "$item_name" 2>&1) + + # Check if the script ran successfully + if [[ $? -ne 0 ]]; then + errored_specs+=("$item_name") + else + # if script had output, then changes were made + if [[ -n "$output" ]]; then + changed_specs+=("$item_name") + fi + fi + fi +done + +pr_body="Spec sync results:\n\n" +# Output the list of changed specs +if [[ ${#changed_specs[@]} -gt 0 ]]; then + pr_body+="The following specs were changed:\n" + for spec in "${changed_specs[@]}"; do + pr_body+=" - $spec\n" + done +else + pr_body+="No changes detected in any specs.\n" +fi + +# Output the list of errored specs +if [[ ${#errored_specs[@]} -gt 0 ]]; then + pr_body+="\nThe following spec syncs encountered errors:\n" + for spec in "${errored_specs[@]}"; do + pr_body+=" - $spec\n" + done +else + pr_body+="\nNo errors were encountered in any specs syncs.\n" +fi + +# Output the PR body (optional step for verification) +echo -e "$pr_body" + +git add $SPEC_DEST +git commit -m $BRANCH_NAME +git push -u origin $BRANCH_NAME +#gh pr create --title "[Spec Resync] $(date '+%m-%d-%Y')" --body "Resyncing specs for review" --base main --head $BRANCH_NAME --draft From 49685ae20acedf7a13f5666addec35128ee777a0 Mon Sep 17 00:00:00 2001 From: Iris Ho Date: Thu, 8 May 2025 10:54:40 -0700 Subject: [PATCH 06/22] trying to get it to work locally? --- .evergreen/config.yml | 2 +- .evergreen/scripts/create-pr.sh | 40 +++++++++++++++++++ ...esync_all_specs.sh => resync-all-specs.sh} | 16 +++++--- 3 files changed, 51 insertions(+), 7 deletions(-) create mode 100755 .evergreen/scripts/create-pr.sh rename .evergreen/scripts/{resync_all_specs.sh => resync-all-specs.sh} (90%) diff --git a/.evergreen/config.yml b/.evergreen/config.yml index 71e54185fc..7d4e8dfe18 100644 --- a/.evergreen/config.yml +++ b/.evergreen/config.yml @@ -50,4 +50,4 @@ tasks: params: binary: bash args: - - .evergreen/scripts/resync_all_specs.sh + - .evergreen/scripts/resync-all-specs.sh diff --git a/.evergreen/scripts/create-pr.sh b/.evergreen/scripts/create-pr.sh new file mode 100755 index 0000000000..c247b1a7c4 --- /dev/null +++ b/.evergreen/scripts/create-pr.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash + +# Get a github access token for the git checkout. +echo "Getting github token..." +# clone drivers-evergreen-tools to get this get-access-token script... +tools="../../../drivers-evergreen-tools" +git clone https://github.com/mongodb-labs/drivers-evergreen-tools.git $tools + +owner="mongodb" +repo="mongo-python-driver" +token=$(bash $tools/.evergreen/github_app/get-access-token.sh $repo $owner) +if [ -z "${token}" ]; then + echo "Failed to get github access token!" + exit 1 +fi +echo "Getting github token... done." + +# Make the git checkout and create a new branch. +echo "Creating the git checkout..." +branch="spec-resync-"$(date '+%m-%d-%Y') +body="$(cat spec_sync.txt)" + +git config user.email "167856002+mongodb-dbx-release-bot[bot]@users.noreply.github.com" +git config user.name "mongodb-dbx-release-bot[bot]" +git remote set-url origin https://x-access-token:${token}@github.com/$owner/$repo.git +git checkout -b $branch "origin/main" +echo "Creating the git checkout... done." + +git push origin $branch +resp=$(curl -L \ + -X POST \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer $token" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + -d "{\"title\":\"[Spec Resync] $(date '+%m-%d-%Y')\",\"body\":\"${body}\",\"head\":\"${branch}\",\"base\":\"main\"}" \ + --url https://api.github.com/repos/$owner/$repo/pulls) +echo $resp | jq '.html_url' +echo "Creating the PR... done." + +rm -rf $dirname diff --git a/.evergreen/scripts/resync_all_specs.sh b/.evergreen/scripts/resync-all-specs.sh similarity index 90% rename from .evergreen/scripts/resync_all_specs.sh rename to .evergreen/scripts/resync-all-specs.sh index 51c034d908..75c8a6d8f1 100755 --- a/.evergreen/scripts/resync_all_specs.sh +++ b/.evergreen/scripts/resync-all-specs.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Run spec syncing script and create PR SPEC_DEST="../../test" @@ -39,7 +39,7 @@ changed_specs=() errored_specs=() # Create branch and switch to it -git checkout -b $BRANCH_NAME 2>/dev/null || git checkout $BRANCH_NAME +#git checkout -b $BRANCH_NAME 2>/dev/null || git checkout $BRANCH_NAME for item in "$SPEC_DEST"/*; do item_name=$(basename "$item") @@ -86,9 +86,13 @@ else fi # Output the PR body (optional step for verification) -echo -e "$pr_body" +echo "$pr_body" >> spec_sync.txt -git add $SPEC_DEST -git commit -m $BRANCH_NAME -git push -u origin $BRANCH_NAME +# call scrypt to create PR for us +./create-pr.sh + +rm spec_sync.txt +#git add $SPEC_DEST +#git commit -m $BRANCH_NAME +#git push -u origin $BRANCH_NAME #gh pr create --title "[Spec Resync] $(date '+%m-%d-%Y')" --body "Resyncing specs for review" --base main --head $BRANCH_NAME --draft From 076ed93fe555c807f541e1cdc536202619196e8e Mon Sep 17 00:00:00 2001 From: Iris Ho Date: Mon, 12 May 2025 10:49:25 -0700 Subject: [PATCH 07/22] wip --- .evergreen/config.yml | 9 +++++++++ .evergreen/resync-specs.sh | 1 + .evergreen/scripts/create-pr.sh | 20 ++++++++++++++------ .evergreen/scripts/resync-all-specs.sh | 15 ++++++++------- 4 files changed, 32 insertions(+), 13 deletions(-) diff --git a/.evergreen/config.yml b/.evergreen/config.yml index 7d4e8dfe18..2edf027121 100644 --- a/.evergreen/config.yml +++ b/.evergreen/config.yml @@ -51,3 +51,12 @@ tasks: binary: bash args: - .evergreen/scripts/resync-all-specs.sh + working_dir: src + +buildvariants: + - name: resync_specs + display_name: "Resync Specs" + run_on: rhel80-small + patchable: true + tasks: + - name: resync_specs diff --git a/.evergreen/resync-specs.sh b/.evergreen/resync-specs.sh index 1f70940aa0..d4e785c39d 100755 --- a/.evergreen/resync-specs.sh +++ b/.evergreen/resync-specs.sh @@ -3,6 +3,7 @@ set -eu PYMONGO=$(dirname "$(cd "$(dirname "$0")"; pwd)") SPECS=${MDB_SPECS:-~/Work/specifications} +echo "$SPECS" help (){ echo "Usage: resync_specs.sh [-bcsp] spec" diff --git a/.evergreen/scripts/create-pr.sh b/.evergreen/scripts/create-pr.sh index c247b1a7c4..0973cd452b 100755 --- a/.evergreen/scripts/create-pr.sh +++ b/.evergreen/scripts/create-pr.sh @@ -1,16 +1,24 @@ #!/usr/bin/env bash -# Get a github access token for the git checkout. -echo "Getting github token..." # clone drivers-evergreen-tools to get this get-access-token script... -tools="../../../drivers-evergreen-tools" +tools="../drivers-evergreen-tools" git clone https://github.com/mongodb-labs/drivers-evergreen-tools.git $tools +body="$(cat "$1")" + +pushd $tools/.evergreen/github_app + +# Get a github access token for the git checkout. +echo "Getting github token..." owner="mongodb" repo="mongo-python-driver" -token=$(bash $tools/.evergreen/github_app/get-access-token.sh $repo $owner) + +./setup-secrets.sh +echo "finish setting up secrets" +token=$(bash ./get-access-token.sh $repo $owner) if [ -z "${token}" ]; then echo "Failed to get github access token!" + popd exit 1 fi echo "Getting github token... done." @@ -18,12 +26,12 @@ echo "Getting github token... done." # Make the git checkout and create a new branch. echo "Creating the git checkout..." branch="spec-resync-"$(date '+%m-%d-%Y') -body="$(cat spec_sync.txt)" git config user.email "167856002+mongodb-dbx-release-bot[bot]@users.noreply.github.com" git config user.name "mongodb-dbx-release-bot[bot]" git remote set-url origin https://x-access-token:${token}@github.com/$owner/$repo.git -git checkout -b $branch "origin/main" +git checkout -b $branch "origin/master" +git add echo "Creating the git checkout... done." git push origin $branch diff --git a/.evergreen/scripts/resync-all-specs.sh b/.evergreen/scripts/resync-all-specs.sh index 75c8a6d8f1..4563dd3171 100755 --- a/.evergreen/scripts/resync-all-specs.sh +++ b/.evergreen/scripts/resync-all-specs.sh @@ -1,11 +1,11 @@ #!/usr/bin/env bash # Run spec syncing script and create PR -SPEC_DEST="../../test" +SPEC_DEST="test" SRC_URL="https://github.com/mongodb/specifications.git" # needs to be set for resunc-specs.sh -SPEC_SRC="../../../specifications" -SCRIPT="../resync-specs.sh" +SPEC_SRC="../specifications" +SCRIPT=".evergreen/resync-specs.sh" BRANCH_NAME="spec-resync-"$(date '+%m-%d-%Y') # List of directories to skip @@ -49,9 +49,9 @@ for item in "$SPEC_DEST"/*; do # Check that item is not a python file if [[ $item != *.py ]]; then - - output=$(./$SCRIPT "$item_name" 2>&1) - + echo " doing $item_name" +# output=$(./$SCRIPT "$item_name" 2>&1) + output=$($SCRIPT "$item_name") # Check if the script ran successfully if [[ $? -ne 0 ]]; then errored_specs+=("$item_name") @@ -86,10 +86,11 @@ else fi # Output the PR body (optional step for verification) +echo "$pr_body" echo "$pr_body" >> spec_sync.txt # call scrypt to create PR for us -./create-pr.sh +.evergreen/scripts/create-pr.sh spec_sync.txt rm spec_sync.txt #git add $SPEC_DEST From 07ea1f64d58d75c84759797d374c58aa89cf3aa3 Mon Sep 17 00:00:00 2001 From: Iris Ho Date: Thu, 5 Jun 2025 09:13:40 -0700 Subject: [PATCH 08/22] still a wip --- .evergreen/resync-specs.sh | 10 ++++++---- .evergreen/scripts/create-pr.sh | 17 ++++++++++------- .evergreen/scripts/resync-all-specs.sh | 15 ++++++++++----- 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/.evergreen/resync-specs.sh b/.evergreen/resync-specs.sh index d4e785c39d..ce6852c246 100755 --- a/.evergreen/resync-specs.sh +++ b/.evergreen/resync-specs.sh @@ -3,7 +3,6 @@ set -eu PYMONGO=$(dirname "$(cd "$(dirname "$0")"; pwd)") SPECS=${MDB_SPECS:-~/Work/specifications} -echo "$SPECS" help (){ echo "Usage: resync_specs.sh [-bcsp] spec" @@ -46,9 +45,12 @@ then fi # Ensure the JSON files are up to date. -cd $SPECS/source -make -cd - +if ! [ -n "${CI:-}" ] +then + cd $SPECS/source + make + cd - +fi # cpjson unified-test-format/tests/invalid unified-test-format/invalid # * param1: Path to spec tests dir in specifications repo # * param2: Path to where the corresponding tests live in Python. diff --git a/.evergreen/scripts/create-pr.sh b/.evergreen/scripts/create-pr.sh index 0973cd452b..397f6d91e2 100755 --- a/.evergreen/scripts/create-pr.sh +++ b/.evergreen/scripts/create-pr.sh @@ -1,20 +1,23 @@ #!/usr/bin/env bash -# clone drivers-evergreen-tools to get this get-access-token script... tools="../drivers-evergreen-tools" git clone https://github.com/mongodb-labs/drivers-evergreen-tools.git $tools body="$(cat "$1")" pushd $tools/.evergreen/github_app -# Get a github access token for the git checkout. -echo "Getting github token..." - owner="mongodb" repo="mongo-python-driver" -./setup-secrets.sh -echo "finish setting up secrets" +echo "bootstrapping?" +# Bootstrap the app. +source utils.sh +bootstrap drivers/release-bot + +# Run the app. + +# Get a github access token for the git checkout. +echo "Getting github token..." token=$(bash ./get-access-token.sh $repo $owner) if [ -z "${token}" ]; then echo "Failed to get github access token!" @@ -31,7 +34,7 @@ git config user.email "167856002+mongodb-dbx-release-bot[bot]@users.noreply.gith git config user.name "mongodb-dbx-release-bot[bot]" git remote set-url origin https://x-access-token:${token}@github.com/$owner/$repo.git git checkout -b $branch "origin/master" -git add +git add ./test echo "Creating the git checkout... done." git push origin $branch diff --git a/.evergreen/scripts/resync-all-specs.sh b/.evergreen/scripts/resync-all-specs.sh index 4563dd3171..9a0392c754 100755 --- a/.evergreen/scripts/resync-all-specs.sh +++ b/.evergreen/scripts/resync-all-specs.sh @@ -1,11 +1,11 @@ #!/usr/bin/env bash # Run spec syncing script and create PR -SPEC_DEST="test" +SPEC_DEST="$(realpath -s "./test")" SRC_URL="https://github.com/mongodb/specifications.git" # needs to be set for resunc-specs.sh -SPEC_SRC="../specifications" -SCRIPT=".evergreen/resync-specs.sh" +SPEC_SRC="$(realpath -s "../specifications")" +SCRIPT="$(realpath -s ".evergreen/resync-specs.sh")" BRANCH_NAME="spec-resync-"$(date '+%m-%d-%Y') # List of directories to skip @@ -27,6 +27,7 @@ fi # Set environment variable to the cloned repo for resync-specs.sh export MDB_SPECS="$SPEC_SRC" +echo "$SPEC_SRC" # Check that resync script exists and is executable if [[ ! -x $SCRIPT ]]; then @@ -51,13 +52,15 @@ for item in "$SPEC_DEST"/*; do if [[ $item != *.py ]]; then echo " doing $item_name" # output=$(./$SCRIPT "$item_name" 2>&1) - output=$($SCRIPT "$item_name") + $SCRIPT "$item_name" # Check if the script ran successfully if [[ $? -ne 0 ]]; then + echo "an error occurred" errored_specs+=("$item_name") else # if script had output, then changes were made if [[ -n "$output" ]]; then + echo "success" changed_specs+=("$item_name") fi fi @@ -86,9 +89,11 @@ else fi # Output the PR body (optional step for verification) -echo "$pr_body" +echo -e "$pr_body" echo "$pr_body" >> spec_sync.txt +git diff + # call scrypt to create PR for us .evergreen/scripts/create-pr.sh spec_sync.txt From f4b3ddcfec49ab9128f635b7a3363bff8083442b Mon Sep 17 00:00:00 2001 From: Iris Ho Date: Mon, 23 Jun 2025 10:46:46 -0700 Subject: [PATCH 09/22] add patch file, use comment bot, still a wip --- .evergreen/config.yml | 1 + .evergreen/scripts/create-pr.sh | 43 ++++++++----- .evergreen/scripts/resync-all-specs.sh | 44 ++++++------- .evergreen/specs.patch | 88 ++++++++++++++++++++++++++ 4 files changed, 137 insertions(+), 39 deletions(-) create mode 100644 .evergreen/specs.patch diff --git a/.evergreen/config.yml b/.evergreen/config.yml index 2edf027121..9cd214e40a 100644 --- a/.evergreen/config.yml +++ b/.evergreen/config.yml @@ -49,6 +49,7 @@ tasks: - command: subprocess.exec params: binary: bash + include_expansions_in_env: [AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN] args: - .evergreen/scripts/resync-all-specs.sh working_dir: src diff --git a/.evergreen/scripts/create-pr.sh b/.evergreen/scripts/create-pr.sh index 397f6d91e2..0a477ab265 100755 --- a/.evergreen/scripts/create-pr.sh +++ b/.evergreen/scripts/create-pr.sh @@ -9,15 +9,17 @@ pushd $tools/.evergreen/github_app owner="mongodb" repo="mongo-python-driver" -echo "bootstrapping?" # Bootstrap the app. +echo "bootstrapping" source utils.sh -bootstrap drivers/release-bot +bootstrap drivers/comment-bot # Run the app. +source ./secrets-export.sh # Get a github access token for the git checkout. echo "Getting github token..." + token=$(bash ./get-access-token.sh $repo $owner) if [ -z "${token}" ]; then echo "Failed to get github access token!" @@ -25,27 +27,36 @@ if [ -z "${token}" ]; then exit 1 fi echo "Getting github token... done." +popd # Make the git checkout and create a new branch. echo "Creating the git checkout..." branch="spec-resync-"$(date '+%m-%d-%Y') -git config user.email "167856002+mongodb-dbx-release-bot[bot]@users.noreply.github.com" -git config user.name "mongodb-dbx-release-bot[bot]" +#git config user.email "167856002+mongodb-dbx-release-bot[bot]@users.noreply.github.com" +#git config user.name "mongodb-dbx-release-bot[bot]" git remote set-url origin https://x-access-token:${token}@github.com/$owner/$repo.git git checkout -b $branch "origin/master" git add ./test +git apply -R .evergreen/specs.patch +git commit -am "resyncing specs test?" echo "Creating the git checkout... done." -git push origin $branch -resp=$(curl -L \ - -X POST \ - -H "Accept: application/vnd.github+json" \ - -H "Authorization: Bearer $token" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - -d "{\"title\":\"[Spec Resync] $(date '+%m-%d-%Y')\",\"body\":\"${body}\",\"head\":\"${branch}\",\"base\":\"main\"}" \ - --url https://api.github.com/repos/$owner/$repo/pulls) -echo $resp | jq '.html_url' -echo "Creating the PR... done." - -rm -rf $dirname +echo "THIS IS THE BODY" +echo "$body" +#git push origin $branch +#resp=$(curl -L \ +# -X POST \ +# -H "Accept: application/vnd.github+json" \ +# -H "Authorization: Bearer $token" \ +# -H "X-GitHub-Api-Version: 2022-11-28" \ +# -d "{\"title\":\"[Spec Resync] $(date '+%m-%d-%Y')\",\"body\":\"${body}\",\"head\":\"${branch}\",\"base\":\"master\"}" \ +# --url https://api.github.com/repos/$owner/$repo/pulls) +#echo $resp +#echo $resp | jq '.html_url' +#echo "Creating the PR... done." + +rm -rf $tools + +# use file names or reg-ex patterns +# or automate which version of the spec we support (like schema version) diff --git a/.evergreen/scripts/resync-all-specs.sh b/.evergreen/scripts/resync-all-specs.sh index 9a0392c754..bd823eb337 100755 --- a/.evergreen/scripts/resync-all-specs.sh +++ b/.evergreen/scripts/resync-all-specs.sh @@ -1,11 +1,10 @@ #!/usr/bin/env bash # Run spec syncing script and create PR - SPEC_DEST="$(realpath -s "./test")" SRC_URL="https://github.com/mongodb/specifications.git" # needs to be set for resunc-specs.sh SPEC_SRC="$(realpath -s "../specifications")" -SCRIPT="$(realpath -s ".evergreen/resync-specs.sh")" +SCRIPT="$(realpath -s "./.evergreen/resync-specs.sh")" BRANCH_NAME="spec-resync-"$(date '+%m-%d-%Y') # List of directories to skip @@ -27,7 +26,7 @@ fi # Set environment variable to the cloned repo for resync-specs.sh export MDB_SPECS="$SPEC_SRC" -echo "$SPEC_SRC" + # Check that resync script exists and is executable if [[ ! -x $SCRIPT ]]; then @@ -35,6 +34,8 @@ if [[ ! -x $SCRIPT ]]; then exit 1 fi +git pull + # List to store names of specs that were changed or errored during change changed_specs=() errored_specs=() @@ -51,48 +52,45 @@ for item in "$SPEC_DEST"/*; do # Check that item is not a python file if [[ $item != *.py ]]; then echo " doing $item_name" -# output=$(./$SCRIPT "$item_name" 2>&1) - $SCRIPT "$item_name" + output=$($SCRIPT "$item_name" 2>&1) # Check if the script ran successfully if [[ $? -ne 0 ]]; then echo "an error occurred" - errored_specs+=("$item_name") - else - # if script had output, then changes were made - if [[ -n "$output" ]]; then - echo "success" - changed_specs+=("$item_name") - fi + errored_specs+=($"$item_name\n\`\`\`$output\`\`\`\n\n") fi fi done -pr_body="Spec sync results:\n\n" # Output the list of changed specs -if [[ ${#changed_specs[@]} -gt 0 ]]; then - pr_body+="The following specs were changed:\n" - for spec in "${changed_specs[@]}"; do - pr_body+=" - $spec\n" - done -else - pr_body+="No changes detected in any specs.\n" +if git diff --quiet && [[ ${#errored_specs[@]} -eq 0 ]]; then + # no changes made and no errors + exit 0 +fi + +pr_body=$'Spec sync results:\n\n' +if ! git diff --quiet; then + pr_body+=$'The following specs were changed:\n' + pr_body+="$(git diff --name-only | awk -F'/' '{print $2}' | sort | uniq)" fi # Output the list of errored specs if [[ ${#errored_specs[@]} -gt 0 ]]; then - pr_body+="\nThe following spec syncs encountered errors:\n" + pr_body+=$"\n\nThe following spec syncs encountered errors:\n" for spec in "${errored_specs[@]}"; do pr_body+=" - $spec\n" done else - pr_body+="\nNo errors were encountered in any specs syncs.\n" + pr_body+=$"\nNo errors were encountered in any specs syncs.\n" fi # Output the PR body (optional step for verification) -echo -e "$pr_body" +echo "PR body" +echo "$pr_body" echo "$pr_body" >> spec_sync.txt +echo "BEGINNING OF DIFF" git diff +echo "END OF DIFF" # call scrypt to create PR for us .evergreen/scripts/create-pr.sh spec_sync.txt diff --git a/.evergreen/specs.patch b/.evergreen/specs.patch new file mode 100644 index 0000000000..c7eb9852ee --- /dev/null +++ b/.evergreen/specs.patch @@ -0,0 +1,88 @@ +diff --git a/test/load_balancer/cursors.json b/test/load_balancer/cursors.json +index 27aaddd5..b11bf2c6 100644 +--- a/test/load_balancer/cursors.json ++++ b/test/load_balancer/cursors.json +@@ -385,7 +385,7 @@ + ] + }, + { +- "description": "pinned connections are returned after an network error during getMore", ++ "description": "pinned connections are not returned after an network error during getMore", + "operations": [ + { + "name": "failPoint", +@@ -449,7 +449,7 @@ + "object": "testRunner", + "arguments": { + "client": "client0", +- "connections": 0 ++ "connections": 1 + } + }, + { +@@ -677,7 +677,7 @@ + ] + }, + { +- "description": "pinned connections are returned to the pool after a non-network error on getMore", ++ "description": "pinned connections are not returned to the pool after a non-network error on getMore", + "operations": [ + { + "name": "failPoint", +@@ -733,7 +733,7 @@ + "object": "testRunner", + "arguments": { + "client": "client0", +- "connections": 0 ++ "connections": 1 + } + }, + { +diff --git a/test/server_selection_logging/operation-id.json b/test/server_selection_logging/operation-id.json +index ccc26231..72ebff60 100644 +--- a/test/server_selection_logging/operation-id.json ++++ b/test/server_selection_logging/operation-id.json +@@ -197,7 +197,7 @@ + } + }, + { +- "level": "debug", ++ "level": "info", + "component": "serverSelection", + "data": { + "message": "Waiting for suitable server to become available", +@@ -383,7 +383,7 @@ + } + }, + { +- "level": "debug", ++ "level": "info", + "component": "serverSelection", + "data": { + "message": "Waiting for suitable server to become available", +diff --git a/test/server_selection_logging/replica-set.json b/test/server_selection_logging/replica-set.json +index 830b1ea5..5eba784b 100644 +--- a/test/server_selection_logging/replica-set.json ++++ b/test/server_selection_logging/replica-set.json +@@ -184,7 +184,7 @@ + } + }, + { +- "level": "debug", ++ "level": "info", + "component": "serverSelection", + "data": { + "message": "Waiting for suitable server to become available", +diff --git a/test/server_selection_logging/sharded.json b/test/server_selection_logging/sharded.json +index 346c050f..d42fba91 100644 +--- a/test/server_selection_logging/sharded.json ++++ b/test/server_selection_logging/sharded.json +@@ -193,7 +193,7 @@ + } + }, + { +- "level": "debug", ++ "level": "info", + "component": "serverSelection", + "data": { + "message": "Waiting for suitable server to become available", From 925aeb5e35ecda08758aff37b80d118fd8fa9221 Mon Sep 17 00:00:00 2001 From: Iris Ho Date: Wed, 25 Jun 2025 14:29:11 -0700 Subject: [PATCH 10/22] fun fact, using a python script is actually *way* easier --- .evergreen/config.yml | 3 +- .evergreen/scripts/create-pr.sh | 23 +- .evergreen/scripts/resync-all-specs.py | 102 ++ .evergreen/scripts/resync-all-specs.sh | 83 +- .evergreen/specs.patch | 1239 ++++++++++++++++++++++++ 5 files changed, 1367 insertions(+), 83 deletions(-) create mode 100644 .evergreen/scripts/resync-all-specs.py diff --git a/.evergreen/config.yml b/.evergreen/config.yml index 9cd214e40a..e5719061ca 100644 --- a/.evergreen/config.yml +++ b/.evergreen/config.yml @@ -58,6 +58,7 @@ buildvariants: - name: resync_specs display_name: "Resync Specs" run_on: rhel80-small - patchable: true + cron: '0 9 * * MON' + patchable: false tasks: - name: resync_specs diff --git a/.evergreen/scripts/create-pr.sh b/.evergreen/scripts/create-pr.sh index 0a477ab265..4897cbe785 100755 --- a/.evergreen/scripts/create-pr.sh +++ b/.evergreen/scripts/create-pr.sh @@ -44,17 +44,18 @@ echo "Creating the git checkout... done." echo "THIS IS THE BODY" echo "$body" -#git push origin $branch -#resp=$(curl -L \ -# -X POST \ -# -H "Accept: application/vnd.github+json" \ -# -H "Authorization: Bearer $token" \ -# -H "X-GitHub-Api-Version: 2022-11-28" \ -# -d "{\"title\":\"[Spec Resync] $(date '+%m-%d-%Y')\",\"body\":\"${body}\",\"head\":\"${branch}\",\"base\":\"master\"}" \ -# --url https://api.github.com/repos/$owner/$repo/pulls) -#echo $resp -#echo $resp | jq '.html_url' -#echo "Creating the PR... done." +git push origin $branch +echo "{\"title\":\"[Spec Resync] $(date '+%m-%d-%Y')\",\"body\":\"$(cat "$1")\",\"head\":\"${branch}\",\"base\":\"master\"}" +resp=$(curl -L \ + -X POST \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer $token" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + -d "{\"title\":\"[Spec Resync] $(date '+%m-%d-%Y')\",\"body\":\"$(cat "$1")\",\"head\":\"${branch}\",\"base\":\"master\"}" \ + --url https://api.github.com/repos/$owner/$repo/pulls) +echo $resp +echo $resp | jq '.html_url' +echo "Creating the PR... done." rm -rf $tools diff --git a/.evergreen/scripts/resync-all-specs.py b/.evergreen/scripts/resync-all-specs.py new file mode 100644 index 0000000000..1bc07433bf --- /dev/null +++ b/.evergreen/scripts/resync-all-specs.py @@ -0,0 +1,102 @@ +from __future__ import annotations + +import argparse +import os +import pathlib +import subprocess + + +def resync_specs(directory: pathlib.Path, errored: dict[str, str]) -> list[str]: + for spec in os.scandir(directory): + if not spec.is_dir(): + continue + + if spec.name in ["asynchronous"]: + continue + process = subprocess.run( + ["bash", "./.evergreen/resync-specs.sh", spec.name], # noqa: S603, S607 + capture_output=True, + text=True, + check=False, + ) + + if process.returncode != 0: + errored[spec.name] = process.stderr + + process = subprocess.run( + ["git diff --name-only | awk -F'/' '{print $2}' | sort | uniq"], # noqa: S607 + shell=True, # noqa: S602 + capture_output=True, + text=True, + check=True, + ) + # return successfully synced specs + return process.stdout.strip().split() + + +def check_new_spec_directories(directory: pathlib.Path) -> list[str]: + spec_dir = pathlib.Path(os.environ["MDB_SPECS"]) / "source" + spec_set = { + entry.name.replace("-", "_") + for entry in os.scandir(spec_dir) + if entry.is_dir() + and (pathlib.Path(entry.path) / "tests").is_dir() + and len(list(os.scandir(pathlib.Path(entry.path) / "tests"))) > 1 + } + test_set = {entry.name.replace("-", "_") for entry in os.scandir(directory) if entry.is_dir()} + known_mappings = { + "ocsp_support": "ocsp", + "client_side_operations_timeout": "csot", + "mongodb_handshake": "handshake", + "load_balancers": "load_balancer", + "atlas_data_lake_testing": "atlas", + "connection_monitoring_and_pooling": "connection_monitoring", + "command_logging_and_monitoring": "command_logging", + "initial_dns_seedlist_discovery": "srv_seedlist", + "server_discovery_and_monitoring": "sdam_monitoring", + } + + for k, v in known_mappings.items(): + if k in spec_set: + spec_set.remove(k) + spec_set.add(v) + return list(spec_set - test_set) + + +def write_summary(succeeded: list[str], errored: dict[str, str], new: list[str]) -> None: + pr_body = "" + if len(succeeded) > 0: + pr_body += "The following specs were changed:\n- " + pr_body += "\n -".join(new) + pr_body += "\n" + if len(errored) > 0: + pr_body += "\n\nThe following spec syncs encountered errors:" + for k, v in errored.items(): + pr_body += f"\n- {k}\n```{v}\n```" + pr_body += "\n" + if len(new) > 0: + pr_body += "\n\nThe following directories are in the specification repository and not in our test directory:" + pr_body += "\n -".join(new) + pr_body += "\n" + + if pr_body != "": + with open("spec_sync.txt", "w") as f: + # replacements made for to be json + f.write(pr_body.replace("\n", "\\n").replace("\t", "\\t")) + + +def main(): + directory = pathlib.Path("./test") + errored: dict[str, str] = {} + succeeded = resync_specs(directory, errored) + new = check_new_spec_directories(directory) + write_summary(succeeded, errored, new) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description="Python Script to resync all specs and generate summary for PR." + ) + parser.add_argument("filename", help="Name of file for the summary to be written into.") + args = parser.parse_args() + main() diff --git a/.evergreen/scripts/resync-all-specs.sh b/.evergreen/scripts/resync-all-specs.sh index ae69b69234..217628d554 100755 --- a/.evergreen/scripts/resync-all-specs.sh +++ b/.evergreen/scripts/resync-all-specs.sh @@ -1,5 +1,7 @@ #!/usr/bin/env bash # Run spec syncing script and create PR + +# SETUP SPEC_DEST="$(realpath -s "./test")" SRC_URL="https://github.com/mongodb/specifications.git" # needs to be set for resunc-specs.sh @@ -7,15 +9,7 @@ SPEC_SRC="$(realpath -s "../specifications")" SCRIPT="$(realpath -s "./.evergreen/resync-specs.sh")" BRANCH_NAME="spec-resync-"$(date '+%m-%d-%Y') -# List of directories to skip -SKIP_DIRECTORIES=("asynchronous" "__pycache__") -# we have a list of specs that we manually override *if the git diff is that specific line, then don't change it -# *ask in python channel -SKIP_FILES=() -# ask steve for how to create PR from evergreen account(?) -# for now, treat it like a command line thing and git add *, git commit, git push - -# Clone the repo if the directory does not exist +# Clone the spec repo if the directory does not exist if [[ ! -d $SPEC_SRC ]]; then git clone $SRC_URL $SPEC_SRC if [[ $? -ne 0 ]]; then @@ -24,76 +18,23 @@ if [[ ! -d $SPEC_SRC ]]; then fi fi -# Set environment variable to the cloned repo for resync-specs.sh +# Set environment variable to the cloned spec repo for resync-specs.sh export MDB_SPECS="$SPEC_SRC" -# Check that resync script exists and is executable +# Check that resync-specs.sh exists and is executable if [[ ! -x $SCRIPT ]]; then echo "Error: $SCRIPT not found or is not executable." exit 1 fi -# List to store names of specs that were changed or errored during change -changed_specs=() -errored_specs=() +PR_DESC="spec_sync.txt" -# Create branch and switch to it -#git checkout -b $BRANCH_NAME 2>/dev/null || git checkout $BRANCH_NAME - -for item in "$SPEC_DEST"/*; do - item_name=$(basename "$item") - if [[ " ${SKIP_DIRECTORIES[*]} " =~ ${item_name} ]]; then - continue - fi +# run python script that actually does all the resyncing +/opt/devtools/bin/python3.11 ./.evergreen/scripts/resync-all-specs.py "$PR_DESC" - # Check that item is not a python file - if [[ $item != *.py ]]; then - echo " doing $item_name" - output=$($SCRIPT "$item_name" 2>&1) - # Check if the script ran successfully - if [[ $? -ne 0 ]]; then - echo "an error occurred" - errored_specs+=($"$item_name\n\`\`\`$output\`\`\`\n\n") - fi - fi -done - -# Output the list of changed specs -if git diff --quiet && [[ ${#errored_specs[@]} -eq 0 ]]; then - # no changes made and no errors - exit 0 -fi -pr_body=$'Spec sync results:\n\n' -if ! git diff --quiet; then - pr_body+=$'The following specs were changed:\n' - pr_body+="$(git diff --name-only | awk -F'/' '{print $2}' | sort | uniq)" +if [[ -f $PR_DESC ]]; then + # changes were made -> call scrypt to create PR for us + .evergreen/scripts/create-pr.sh "$PR_DESC" + rm "$PR_DESC" fi - -# Output the list of errored specs -if [[ ${#errored_specs[@]} -gt 0 ]]; then - pr_body+=$"\n\nThe following spec syncs encountered errors:\n" - for spec in "${errored_specs[@]}"; do - pr_body+=" - $spec\n" - done -else - pr_body+=$"\nNo errors were encountered in any specs syncs.\n" -fi - -# Output the PR body (optional step for verification) -echo "PR body" -echo "$pr_body" -echo "$pr_body" >> spec_sync.txt - -echo "BEGINNING OF DIFF" -git diff -echo "END OF DIFF" - -# call scrypt to create PR for us -.evergreen/scripts/create-pr.sh spec_sync.txt - -rm spec_sync.txt -#git add $SPEC_DEST -#git commit -m $BRANCH_NAME -#git push -u origin $BRANCH_NAME -#gh pr create --title "[Spec Resync] $(date '+%m-%d-%Y')" --body "Resyncing specs for review" --base main --head $BRANCH_NAME --draft diff --git a/.evergreen/specs.patch b/.evergreen/specs.patch index c7eb9852ee..f0a5a09166 100644 --- a/.evergreen/specs.patch +++ b/.evergreen/specs.patch @@ -86,3 +86,1242 @@ index 346c050f..d42fba91 100644 "component": "serverSelection", "data": { "message": "Waiting for suitable server to become available", +diff --git a/test/client-side-encryption/spec/unified/fle2v2-BypassQueryAnalysis.json b/test/client-side-encryption/spec/unified/fle2v2-BypassQueryAnalysis.json +new file mode 100644 +index 00000000..0817508f +--- /dev/null ++++ b/test/client-side-encryption/spec/unified/fle2v2-BypassQueryAnalysis.json +@@ -0,0 +1,322 @@ ++{ ++ "description": "fle2v2-BypassQueryAnalysis", ++ "schemaVersion": "1.23", ++ "runOnRequirements": [ ++ { ++ "minServerVersion": "7.0.0", ++ "serverless": "forbid", ++ "csfle": true, ++ "topologies": [ ++ "replicaset", ++ "sharded", ++ "load-balanced" ++ ] ++ } ++ ], ++ "createEntities": [ ++ { ++ "client": { ++ "id": "client0", ++ "autoEncryptOpts": { ++ "kmsProviders": { ++ "local": { ++ "key": "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk" ++ } ++ }, ++ "keyVaultNamespace": "keyvault.datakeys", ++ "bypassQueryAnalysis": true ++ }, ++ "observeEvents": [ ++ "commandStartedEvent" ++ ] ++ } ++ }, ++ { ++ "database": { ++ "id": "encryptedDB", ++ "client": "client0", ++ "databaseName": "default" ++ } ++ }, ++ { ++ "collection": { ++ "id": "encryptedColl", ++ "database": "encryptedDB", ++ "collectionName": "default" ++ } ++ }, ++ { ++ "client": { ++ "id": "client1" ++ } ++ }, ++ { ++ "database": { ++ "id": "unencryptedDB", ++ "client": "client1", ++ "databaseName": "default" ++ } ++ }, ++ { ++ "collection": { ++ "id": "unencryptedColl", ++ "database": "unencryptedDB", ++ "collectionName": "default" ++ } ++ } ++ ], ++ "initialData": [ ++ { ++ "databaseName": "keyvault", ++ "collectionName": "datakeys", ++ "documents": [ ++ { ++ "_id": { ++ "$binary": { ++ "base64": "EjRWeBI0mHYSNBI0VniQEg==", ++ "subType": "04" ++ } ++ }, ++ "keyMaterial": { ++ "$binary": { ++ "base64": "sHe0kz57YW7v8g9VP9sf/+K1ex4JqKc5rf/URX3n3p8XdZ6+15uXPaSayC6adWbNxkFskuMCOifDoTT+rkqMtFkDclOy884RuGGtUysq3X7zkAWYTKi8QAfKkajvVbZl2y23UqgVasdQu3OVBQCrH/xY00nNAs/52e958nVjBuzQkSb1T8pKJAyjZsHJ60+FtnfafDZSTAIBJYn7UWBCwQ==", ++ "subType": "00" ++ } ++ }, ++ "creationDate": { ++ "$date": { ++ "$numberLong": "1648914851981" ++ } ++ }, ++ "updateDate": { ++ "$date": { ++ "$numberLong": "1648914851981" ++ } ++ }, ++ "status": { ++ "$numberInt": "0" ++ }, ++ "masterKey": { ++ "provider": "local" ++ } ++ } ++ ] ++ }, ++ { ++ "databaseName": "default", ++ "collectionName": "default", ++ "documents": [], ++ "createOptions": { ++ "encryptedFields": { ++ "fields": [ ++ { ++ "keyId": { ++ "$binary": { ++ "base64": "EjRWeBI0mHYSNBI0VniQEg==", ++ "subType": "04" ++ } ++ }, ++ "path": "encryptedIndexed", ++ "bsonType": "string", ++ "queries": { ++ "queryType": "equality", ++ "contention": { ++ "$numberLong": "0" ++ } ++ } ++ }, ++ { ++ "keyId": { ++ "$binary": { ++ "base64": "q83vqxI0mHYSNBI0VniQEg==", ++ "subType": "04" ++ } ++ }, ++ "path": "encryptedUnindexed", ++ "bsonType": "string" ++ } ++ ] ++ } ++ } ++ } ++ ], ++ "tests": [ ++ { ++ "description": "BypassQueryAnalysis decrypts", ++ "operations": [ ++ { ++ "object": "encryptedColl", ++ "name": "insertOne", ++ "arguments": { ++ "document": { ++ "_id": 1, ++ "encryptedIndexed": { ++ "$binary": { ++ "base64": "C18BAAAFZAAgAAAAANnt+eLTkv4GdDPl8IAfJOvTzArOgFJQ2S/DcLza4W0DBXMAIAAAAAD2u+omZme3P2gBPehMQyQHQ153tPN1+z7bksYA9jKTpAVwADAAAAAAUnCOQqIvmR65YKyYnsiVfVrg9hwUVO3RhhKExo3RWOzgaS0QdsBL5xKFS0JhZSoWBXUAEAAAAAQSNFZ4EjSYdhI0EjRWeJASEHQAAgAAAAV2AFAAAAAAEjRWeBI0mHYSNBI0VniQEpQbp/ZJpWBKeDtKLiXb0P2E9wvc0g3f373jnYQYlJquOrlPOoEy3ngsHPJuSUijvWDsrQzqYa349K7G/66qaXEFZQAgAAAAAOuac/eRLYakKX6B0vZ1r3QodOQFfjqJD+xlGiPu4/PsBWwAIAAAAACkm0o9bj6j0HuADKc0svbqO2UHj6GrlNdF6yKNxh63xRJrAAAAAAAAAAAAAA==", ++ "subType": "06" ++ } ++ } ++ } ++ } ++ }, ++ { ++ "object": "encryptedColl", ++ "name": "find", ++ "arguments": { ++ "filter": { ++ "_id": 1 ++ } ++ }, ++ "expectResult": [ ++ { ++ "_id": 1, ++ "encryptedIndexed": "123" ++ } ++ ] ++ }, ++ { ++ "object": "unencryptedColl", ++ "name": "find", ++ "arguments": { ++ "filter": {} ++ }, ++ "expectResult": [ ++ { ++ "_id": 1, ++ "encryptedIndexed": { ++ "$$type": "binData" ++ }, ++ "__safeContent__": [ ++ { ++ "$binary": { ++ "base64": "31eCYlbQoVboc5zwC8IoyJVSkag9PxREka8dkmbXJeY=", ++ "subType": "00" ++ } ++ } ++ ] ++ } ++ ] ++ } ++ ], ++ "expectEvents": [ ++ { ++ "client": "client0", ++ "events": [ ++ { ++ "commandStartedEvent": { ++ "command": { ++ "listCollections": 1, ++ "filter": { ++ "name": "default" ++ } ++ }, ++ "commandName": "listCollections" ++ } ++ }, ++ { ++ "commandStartedEvent": { ++ "command": { ++ "insert": "default", ++ "documents": [ ++ { ++ "_id": 1, ++ "encryptedIndexed": { ++ "$binary": { ++ "base64": "C18BAAAFZAAgAAAAANnt+eLTkv4GdDPl8IAfJOvTzArOgFJQ2S/DcLza4W0DBXMAIAAAAAD2u+omZme3P2gBPehMQyQHQ153tPN1+z7bksYA9jKTpAVwADAAAAAAUnCOQqIvmR65YKyYnsiVfVrg9hwUVO3RhhKExo3RWOzgaS0QdsBL5xKFS0JhZSoWBXUAEAAAAAQSNFZ4EjSYdhI0EjRWeJASEHQAAgAAAAV2AFAAAAAAEjRWeBI0mHYSNBI0VniQEpQbp/ZJpWBKeDtKLiXb0P2E9wvc0g3f373jnYQYlJquOrlPOoEy3ngsHPJuSUijvWDsrQzqYa349K7G/66qaXEFZQAgAAAAAOuac/eRLYakKX6B0vZ1r3QodOQFfjqJD+xlGiPu4/PsBWwAIAAAAACkm0o9bj6j0HuADKc0svbqO2UHj6GrlNdF6yKNxh63xRJrAAAAAAAAAAAAAA==", ++ "subType": "06" ++ } ++ } ++ } ++ ], ++ "ordered": true, ++ "encryptionInformation": { ++ "type": 1, ++ "schema": { ++ "default.default": { ++ "escCollection": "enxcol_.default.esc", ++ "ecocCollection": "enxcol_.default.ecoc", ++ "fields": [ ++ { ++ "keyId": { ++ "$binary": { ++ "base64": "EjRWeBI0mHYSNBI0VniQEg==", ++ "subType": "04" ++ } ++ }, ++ "path": "encryptedIndexed", ++ "bsonType": "string", ++ "queries": { ++ "queryType": "equality", ++ "contention": { ++ "$numberLong": "0" ++ } ++ } ++ }, ++ { ++ "keyId": { ++ "$binary": { ++ "base64": "q83vqxI0mHYSNBI0VniQEg==", ++ "subType": "04" ++ } ++ }, ++ "path": "encryptedUnindexed", ++ "bsonType": "string" ++ } ++ ] ++ } ++ } ++ } ++ }, ++ "commandName": "insert" ++ } ++ }, ++ { ++ "commandStartedEvent": { ++ "command": { ++ "find": "default", ++ "filter": { ++ "_id": 1 ++ } ++ }, ++ "commandName": "find" ++ } ++ }, ++ { ++ "commandStartedEvent": { ++ "command": { ++ "find": "datakeys", ++ "filter": { ++ "$or": [ ++ { ++ "_id": { ++ "$in": [ ++ { ++ "$binary": { ++ "base64": "EjRWeBI0mHYSNBI0VniQEg==", ++ "subType": "04" ++ } ++ } ++ ] ++ } ++ }, ++ { ++ "keyAltNames": { ++ "$in": [] ++ } ++ } ++ ] ++ }, ++ "$db": "keyvault", ++ "readConcern": { ++ "level": "majority" ++ } ++ }, ++ "commandName": "find" ++ } ++ } ++ ] ++ } ++ ] ++ } ++ ] ++} +diff --git a/test/client-side-encryption/spec/unified/fle2v2-EncryptedFields-vs-EncryptedFieldsMap.json b/test/client-side-encryption/spec/unified/fle2v2-EncryptedFields-vs-EncryptedFieldsMap.json +new file mode 100644 +index 00000000..b5f848c0 +--- /dev/null ++++ b/test/client-side-encryption/spec/unified/fle2v2-EncryptedFields-vs-EncryptedFieldsMap.json +@@ -0,0 +1,256 @@ ++{ ++ "description": "fle2v2-EncryptedFields-vs-EncryptedFieldsMap", ++ "schemaVersion": "1.23", ++ "runOnRequirements": [ ++ { ++ "minServerVersion": "7.0.0", ++ "serverless": "forbid", ++ "csfle": true, ++ "topologies": [ ++ "replicaset", ++ "sharded", ++ "load-balanced" ++ ] ++ } ++ ], ++ "createEntities": [ ++ { ++ "client": { ++ "id": "client0", ++ "autoEncryptOpts": { ++ "kmsProviders": { ++ "local": { ++ "key": "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk" ++ } ++ }, ++ "keyVaultNamespace": "keyvault.datakeys", ++ "encryptedFieldsMap": { ++ "default.default": { ++ "fields": [] ++ } ++ } ++ }, ++ "observeEvents": [ ++ "commandStartedEvent" ++ ] ++ } ++ }, ++ { ++ "database": { ++ "id": "encryptedDB", ++ "client": "client0", ++ "databaseName": "default" ++ } ++ }, ++ { ++ "collection": { ++ "id": "encryptedColl", ++ "database": "encryptedDB", ++ "collectionName": "default" ++ } ++ } ++ ], ++ "initialData": [ ++ { ++ "databaseName": "keyvault", ++ "collectionName": "datakeys", ++ "documents": [ ++ { ++ "_id": { ++ "$binary": { ++ "base64": "q83vqxI0mHYSNBI0VniQEg==", ++ "subType": "04" ++ } ++ }, ++ "keyMaterial": { ++ "$binary": { ++ "base64": "HBk9BWihXExNDvTp1lUxOuxuZK2Pe2ZdVdlsxPEBkiO1bS4mG5NNDsQ7zVxJAH8BtdOYp72Ku4Y3nwc0BUpIKsvAKX4eYXtlhv5zUQxWdeNFhg9qK7qb8nqhnnLeT0f25jFSqzWJoT379hfwDeu0bebJHr35QrJ8myZdPMTEDYF08QYQ48ShRBli0S+QzBHHAQiM2iJNr4svg2WR8JSeWQ==", ++ "subType": "00" ++ } ++ }, ++ "creationDate": { ++ "$date": { ++ "$numberLong": "1648914851981" ++ } ++ }, ++ "updateDate": { ++ "$date": { ++ "$numberLong": "1648914851981" ++ } ++ }, ++ "status": { ++ "$numberInt": "0" ++ }, ++ "masterKey": { ++ "provider": "local" ++ } ++ } ++ ] ++ }, ++ { ++ "databaseName": "default", ++ "collectionName": "default", ++ "documents": [], ++ "createOptions": { ++ "encryptedFields": { ++ "fields": [ ++ { ++ "keyId": { ++ "$binary": { ++ "base64": "EjRWeBI0mHYSNBI0VniQEg==", ++ "subType": "04" ++ } ++ }, ++ "path": "encryptedIndexed", ++ "bsonType": "string", ++ "queries": { ++ "queryType": "equality", ++ "contention": { ++ "$numberLong": "0" ++ } ++ } ++ }, ++ { ++ "keyId": { ++ "$binary": { ++ "base64": "q83vqxI0mHYSNBI0VniQEg==", ++ "subType": "04" ++ } ++ }, ++ "path": "encryptedUnindexed", ++ "bsonType": "string" ++ } ++ ] ++ } ++ } ++ } ++ ], ++ "tests": [ ++ { ++ "description": "encryptedFieldsMap is preferred over remote encryptedFields", ++ "operations": [ ++ { ++ "object": "encryptedColl", ++ "name": "insertOne", ++ "arguments": { ++ "document": { ++ "_id": 1, ++ "encryptedUnindexed": { ++ "$binary": { ++ "base64": "BqvN76sSNJh2EjQSNFZ4kBICTQaVZPWgXp41I7mPV1rLFTtw1tXzjcdSEyxpKKqujlko5TeizkB9hHQ009dVY1+fgIiDcefh+eQrm3CkhQ==", ++ "subType": "06" ++ } ++ } ++ } ++ } ++ }, ++ { ++ "object": "encryptedColl", ++ "name": "find", ++ "arguments": { ++ "filter": { ++ "_id": 1 ++ } ++ }, ++ "expectResult": [ ++ { ++ "_id": 1, ++ "encryptedUnindexed": "value123" ++ } ++ ] ++ } ++ ], ++ "expectEvents": [ ++ { ++ "client": "client0", ++ "events": [ ++ { ++ "commandStartedEvent": { ++ "databaseName": "default", ++ "commandName": "insert", ++ "command": { ++ "insert": "default", ++ "documents": [ ++ { ++ "_id": 1, ++ "encryptedUnindexed": { ++ "$binary": { ++ "base64": "BqvN76sSNJh2EjQSNFZ4kBICTQaVZPWgXp41I7mPV1rLFTtw1tXzjcdSEyxpKKqujlko5TeizkB9hHQ009dVY1+fgIiDcefh+eQrm3CkhQ==", ++ "subType": "06" ++ } ++ } ++ } ++ ], ++ "ordered": true ++ } ++ } ++ }, ++ { ++ "commandStartedEvent": { ++ "databaseName": "default", ++ "commandName": "find", ++ "command": { ++ "find": "default", ++ "filter": { ++ "_id": 1 ++ } ++ } ++ } ++ }, ++ { ++ "commandStartedEvent": { ++ "databaseName": "keyvault", ++ "commandName": "find", ++ "command": { ++ "find": "datakeys", ++ "filter": { ++ "$or": [ ++ { ++ "_id": { ++ "$in": [ ++ { ++ "$binary": { ++ "base64": "q83vqxI0mHYSNBI0VniQEg==", ++ "subType": "04" ++ } ++ } ++ ] ++ } ++ }, ++ { ++ "keyAltNames": { ++ "$in": [] ++ } ++ } ++ ] ++ }, ++ "$db": "keyvault", ++ "readConcern": { ++ "level": "majority" ++ } ++ } ++ } ++ } ++ ] ++ } ++ ], ++ "outcome": [ ++ { ++ "collectionName": "default", ++ "databaseName": "default", ++ "documents": [ ++ { ++ "_id": 1, ++ "encryptedUnindexed": { ++ "$binary": { ++ "base64": "BqvN76sSNJh2EjQSNFZ4kBICTQaVZPWgXp41I7mPV1rLFTtw1tXzjcdSEyxpKKqujlko5TeizkB9hHQ009dVY1+fgIiDcefh+eQrm3CkhQ==", ++ "subType": "06" ++ } ++ } ++ } ++ ] ++ } ++ ] ++ } ++ ] ++} +diff --git a/test/client-side-encryption/spec/unified/localSchema.json b/test/client-side-encryption/spec/unified/localSchema.json +new file mode 100644 +index 00000000..a7acccac +--- /dev/null ++++ b/test/client-side-encryption/spec/unified/localSchema.json +@@ -0,0 +1,342 @@ ++{ ++ "description": "localSchema", ++ "schemaVersion": "1.23", ++ "runOnRequirements": [ ++ { ++ "minServerVersion": "4.1.10", ++ "csfle": true ++ } ++ ], ++ "createEntities": [ ++ { ++ "client": { ++ "id": "client0", ++ "autoEncryptOpts": { ++ "schemaMap": { ++ "default.default": { ++ "properties": { ++ "encrypted_w_altname": { ++ "encrypt": { ++ "keyId": "/altname", ++ "bsonType": "string", ++ "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" ++ } ++ }, ++ "encrypted_string": { ++ "encrypt": { ++ "keyId": [ ++ { ++ "$binary": { ++ "base64": "AAAAAAAAAAAAAAAAAAAAAA==", ++ "subType": "04" ++ } ++ } ++ ], ++ "bsonType": "string", ++ "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" ++ } ++ }, ++ "random": { ++ "encrypt": { ++ "keyId": [ ++ { ++ "$binary": { ++ "base64": "AAAAAAAAAAAAAAAAAAAAAA==", ++ "subType": "04" ++ } ++ } ++ ], ++ "bsonType": "string", ++ "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" ++ } ++ }, ++ "encrypted_string_equivalent": { ++ "encrypt": { ++ "keyId": [ ++ { ++ "$binary": { ++ "base64": "AAAAAAAAAAAAAAAAAAAAAA==", ++ "subType": "04" ++ } ++ } ++ ], ++ "bsonType": "string", ++ "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" ++ } ++ } ++ }, ++ "bsonType": "object" ++ } ++ }, ++ "keyVaultNamespace": "keyvault.datakeys", ++ "kmsProviders": { ++ "aws": { ++ "accessKeyId": { ++ "$$placeholder": 1 ++ }, ++ "secretAccessKey": { ++ "$$placeholder": 1 ++ }, ++ "sessionToken": { ++ "$$placeholder": 1 ++ } ++ } ++ } ++ }, ++ "observeEvents": [ ++ "commandStartedEvent" ++ ] ++ } ++ }, ++ { ++ "client": { ++ "id": "client1", ++ "autoEncryptOpts": { ++ "schemaMap": { ++ "default.default": { ++ "properties": { ++ "test": { ++ "bsonType": "string" ++ } ++ }, ++ "bsonType": "object", ++ "required": [ ++ "test" ++ ] ++ } ++ }, ++ "keyVaultNamespace": "keyvault.datakeys", ++ "kmsProviders": { ++ "aws": { ++ "accessKeyId": { ++ "$$placeholder": 1 ++ }, ++ "secretAccessKey": { ++ "$$placeholder": 1 ++ }, ++ "sessionToken": { ++ "$$placeholder": 1 ++ } ++ } ++ } ++ }, ++ "observeEvents": [ ++ "commandStartedEvent" ++ ] ++ } ++ }, ++ { ++ "database": { ++ "id": "encryptedDB", ++ "client": "client0", ++ "databaseName": "default" ++ } ++ }, ++ { ++ "collection": { ++ "id": "encryptedColl", ++ "database": "encryptedDB", ++ "collectionName": "default" ++ } ++ }, ++ { ++ "database": { ++ "id": "encryptedDB2", ++ "client": "client1", ++ "databaseName": "default" ++ } ++ }, ++ { ++ "collection": { ++ "id": "encryptedColl2", ++ "database": "encryptedDB2", ++ "collectionName": "default" ++ } ++ } ++ ], ++ "initialData": [ ++ { ++ "databaseName": "keyvault", ++ "collectionName": "datakeys", ++ "documents": [ ++ { ++ "status": 1, ++ "_id": { ++ "$binary": { ++ "base64": "AAAAAAAAAAAAAAAAAAAAAA==", ++ "subType": "04" ++ } ++ }, ++ "masterKey": { ++ "provider": "aws", ++ "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", ++ "region": "us-east-1" ++ }, ++ "updateDate": { ++ "$date": { ++ "$numberLong": "1552949630483" ++ } ++ }, ++ "keyMaterial": { ++ "$binary": { ++ "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", ++ "subType": "00" ++ } ++ }, ++ "creationDate": { ++ "$date": { ++ "$numberLong": "1552949630483" ++ } ++ }, ++ "keyAltNames": [ ++ "altname", ++ "another_altname" ++ ] ++ } ++ ] ++ }, ++ { ++ "databaseName": "default", ++ "collectionName": "default", ++ "documents": [] ++ } ++ ], ++ "tests": [ ++ { ++ "description": "A local schema should override", ++ "operations": [ ++ { ++ "object": "encryptedColl", ++ "name": "insertOne", ++ "arguments": { ++ "document": { ++ "_id": 1, ++ "encrypted_string": "string0" ++ } ++ } ++ }, ++ { ++ "object": "encryptedColl", ++ "name": "find", ++ "arguments": { ++ "filter": { ++ "_id": 1 ++ } ++ }, ++ "expectResult": [ ++ { ++ "_id": 1, ++ "encrypted_string": "string0" ++ } ++ ] ++ } ++ ], ++ "expectEvents": [ ++ { ++ "client": "client0", ++ "events": [ ++ { ++ "commandStartedEvent": { ++ "databaseName": "keyvault", ++ "commandName": "find", ++ "command": { ++ "find": "datakeys", ++ "filter": { ++ "$or": [ ++ { ++ "_id": { ++ "$in": [ ++ { ++ "$binary": { ++ "base64": "AAAAAAAAAAAAAAAAAAAAAA==", ++ "subType": "04" ++ } ++ } ++ ] ++ } ++ }, ++ { ++ "keyAltNames": { ++ "$in": [] ++ } ++ } ++ ] ++ }, ++ "readConcern": { ++ "level": "majority" ++ } ++ } ++ } ++ }, ++ { ++ "commandStartedEvent": { ++ "commandName": "insert", ++ "command": { ++ "insert": "default", ++ "documents": [ ++ { ++ "_id": 1, ++ "encrypted_string": { ++ "$binary": { ++ "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", ++ "subType": "06" ++ } ++ } ++ } ++ ], ++ "ordered": true ++ } ++ } ++ }, ++ { ++ "commandStartedEvent": { ++ "commandName": "find", ++ "command": { ++ "find": "default", ++ "filter": { ++ "_id": 1 ++ } ++ } ++ } ++ } ++ ] ++ } ++ ], ++ "outcome": [ ++ { ++ "collectionName": "default", ++ "databaseName": "default", ++ "documents": [ ++ { ++ "_id": 1, ++ "encrypted_string": { ++ "$binary": { ++ "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", ++ "subType": "06" ++ } ++ } ++ } ++ ] ++ } ++ ] ++ }, ++ { ++ "description": "A local schema with no encryption is an error", ++ "operations": [ ++ { ++ "object": "encryptedColl2", ++ "name": "insertOne", ++ "arguments": { ++ "document": { ++ "_id": 1, ++ "encrypted_string": "string0" ++ } ++ }, ++ "expectError": { ++ "isClientError": true ++ } ++ } ++ ] ++ } ++ ] ++} +diff --git a/test/client-side-encryption/spec/unified/maxWireVersion.json b/test/client-side-encryption/spec/unified/maxWireVersion.json +new file mode 100644 +index 00000000..d0af75ac +--- /dev/null ++++ b/test/client-side-encryption/spec/unified/maxWireVersion.json +@@ -0,0 +1,101 @@ ++{ ++ "description": "maxWireVersion", ++ "schemaVersion": "1.23", ++ "runOnRequirements": [ ++ { ++ "maxServerVersion": "4.0.99", ++ "csfle": true ++ } ++ ], ++ "createEntities": [ ++ { ++ "client": { ++ "id": "client0", ++ "autoEncryptOpts": { ++ "kmsProviders": { ++ "aws": {} ++ }, ++ "keyVaultNamespace": "keyvault.datakeys", ++ "extraOptions": { ++ "mongocryptdBypassSpawn": true ++ } ++ } ++ } ++ }, ++ { ++ "database": { ++ "id": "database0", ++ "client": "client0", ++ "databaseName": "default" ++ } ++ }, ++ { ++ "collection": { ++ "id": "collection0", ++ "database": "database0", ++ "collectionName": "default" ++ } ++ } ++ ], ++ "initialData": [ ++ { ++ "databaseName": "keyvault", ++ "collectionName": "datakeys", ++ "documents": [ ++ { ++ "status": 1, ++ "_id": { ++ "$binary": { ++ "base64": "AAAAAAAAAAAAAAAAAAAAAA==", ++ "subType": "04" ++ } ++ }, ++ "masterKey": { ++ "provider": "aws", ++ "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", ++ "region": "us-east-1" ++ }, ++ "updateDate": { ++ "$date": { ++ "$numberLong": "1552949630483" ++ } ++ }, ++ "keyMaterial": { ++ "$binary": { ++ "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", ++ "subType": "00" ++ } ++ }, ++ "creationDate": { ++ "$date": { ++ "$numberLong": "1552949630483" ++ } ++ }, ++ "keyAltNames": [ ++ "altname", ++ "another_altname" ++ ] ++ } ++ ] ++ } ++ ], ++ "tests": [ ++ { ++ "description": "operation fails with maxWireVersion < 8", ++ "operations": [ ++ { ++ "name": "insertOne", ++ "object": "collection0", ++ "arguments": { ++ "document": { ++ "encrypted_string": "string0" ++ } ++ }, ++ "expectError": { ++ "errorContains": "Auto-encryption requires a minimum MongoDB version of 4.2" ++ } ++ } ++ ] ++ } ++ ] ++} +diff --git a/test/unified-test-format/valid-pass/poc-queryable-encryption.json b/test/unified-test-format/valid-pass/poc-queryable-encryption.json +new file mode 100644 +index 00000000..9788977c +--- /dev/null ++++ b/test/unified-test-format/valid-pass/poc-queryable-encryption.json +@@ -0,0 +1,188 @@ ++{ ++ "description": "poc-queryable-encryption", ++ "schemaVersion": "1.23", ++ "runOnRequirements": [ ++ { ++ "minServerVersion": "7.0", ++ "csfle": true ++ } ++ ], ++ "createEntities": [ ++ { ++ "client": { ++ "id": "client0", ++ "autoEncryptOpts": { ++ "keyVaultNamespace": "keyvault.datakeys", ++ "kmsProviders": { ++ "local": { ++ "key": "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk" ++ } ++ } ++ } ++ } ++ }, ++ { ++ "database": { ++ "id": "encryptedDB", ++ "client": "client0", ++ "databaseName": "poc-queryable-encryption" ++ } ++ }, ++ { ++ "collection": { ++ "id": "encryptedColl", ++ "database": "encryptedDB", ++ "collectionName": "encrypted" ++ } ++ }, ++ { ++ "client": { ++ "id": "client1" ++ } ++ }, ++ { ++ "database": { ++ "id": "unencryptedDB", ++ "client": "client1", ++ "databaseName": "poc-queryable-encryption" ++ } ++ }, ++ { ++ "collection": { ++ "id": "unencryptedColl", ++ "database": "unencryptedDB", ++ "collectionName": "encrypted" ++ } ++ } ++ ], ++ "initialData": [ ++ { ++ "databaseName": "keyvault", ++ "collectionName": "datakeys", ++ "documents": [ ++ { ++ "_id": { ++ "$binary": { ++ "base64": "EjRWeBI0mHYSNBI0VniQEg==", ++ "subType": "04" ++ } ++ }, ++ "keyMaterial": { ++ "$binary": { ++ "base64": "sHe0kz57YW7v8g9VP9sf/+K1ex4JqKc5rf/URX3n3p8XdZ6+15uXPaSayC6adWbNxkFskuMCOifDoTT+rkqMtFkDclOy884RuGGtUysq3X7zkAWYTKi8QAfKkajvVbZl2y23UqgVasdQu3OVBQCrH/xY00nNAs/52e958nVjBuzQkSb1T8pKJAyjZsHJ60+FtnfafDZSTAIBJYn7UWBCwQ==", ++ "subType": "00" ++ } ++ }, ++ "creationDate": { ++ "$date": { ++ "$numberLong": "1641024000000" ++ } ++ }, ++ "updateDate": { ++ "$date": { ++ "$numberLong": "1641024000000" ++ } ++ }, ++ "status": 1, ++ "masterKey": { ++ "provider": "local" ++ } ++ } ++ ] ++ }, ++ { ++ "databaseName": "poc-queryable-encryption", ++ "collectionName": "encrypted", ++ "documents": [], ++ "createOptions": { ++ "encryptedFields": { ++ "fields": [ ++ { ++ "keyId": { ++ "$binary": { ++ "base64": "EjRWeBI0mHYSNBI0VniQEg==", ++ "subType": "04" ++ } ++ }, ++ "path": "encryptedInt", ++ "bsonType": "int", ++ "queries": { ++ "queryType": "equality", ++ "contention": { ++ "$numberLong": "0" ++ } ++ } ++ } ++ ] ++ } ++ } ++ } ++ ], ++ "tests": [ ++ { ++ "description": "insert, replace, and find with queryable encryption", ++ "operations": [ ++ { ++ "object": "encryptedColl", ++ "name": "insertOne", ++ "arguments": { ++ "document": { ++ "_id": 1, ++ "encryptedInt": 11 ++ } ++ } ++ }, ++ { ++ "object": "encryptedColl", ++ "name": "replaceOne", ++ "arguments": { ++ "filter": { ++ "encryptedInt": 11 ++ }, ++ "replacement": { ++ "encryptedInt": 22 ++ } ++ } ++ }, ++ { ++ "object": "encryptedColl", ++ "name": "find", ++ "arguments": { ++ "filter": { ++ "encryptedInt": 22 ++ } ++ }, ++ "expectResult": [ ++ { ++ "_id": 1, ++ "encryptedInt": 22 ++ } ++ ] ++ }, ++ { ++ "object": "unencryptedColl", ++ "name": "find", ++ "arguments": { ++ "filter": {} ++ }, ++ "expectResult": [ ++ { ++ "_id": 1, ++ "encryptedInt": { ++ "$$type": "binData" ++ }, ++ "__safeContent__": [ ++ { ++ "$binary": { ++ "base64": "rhS16TJojgDDBtbluxBokvcotP1mQTGeYpNt8xd3MJQ=", ++ "subType": "00" ++ } ++ } ++ ] ++ } ++ ] ++ } ++ ] ++ } ++ ] ++} From 67b995aadb97a249c94d589615711f0b8489c833 Mon Sep 17 00:00:00 2001 From: Iris Ho Date: Wed, 25 Jun 2025 14:30:42 -0700 Subject: [PATCH 11/22] remove comment --- .evergreen/scripts/create-pr.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/.evergreen/scripts/create-pr.sh b/.evergreen/scripts/create-pr.sh index 4897cbe785..104874004a 100755 --- a/.evergreen/scripts/create-pr.sh +++ b/.evergreen/scripts/create-pr.sh @@ -58,6 +58,3 @@ echo $resp | jq '.html_url' echo "Creating the PR... done." rm -rf $tools - -# use file names or reg-ex patterns -# or automate which version of the spec we support (like schema version) From 53e89459cb4d2e281d09405c1464600991333d94 Mon Sep 17 00:00:00 2001 From: Iris Ho Date: Wed, 25 Jun 2025 14:37:34 -0700 Subject: [PATCH 12/22] remove comment pt2 --- .evergreen/scripts/create-pr.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/.evergreen/scripts/create-pr.sh b/.evergreen/scripts/create-pr.sh index 104874004a..11aa32d5d3 100755 --- a/.evergreen/scripts/create-pr.sh +++ b/.evergreen/scripts/create-pr.sh @@ -33,8 +33,6 @@ popd echo "Creating the git checkout..." branch="spec-resync-"$(date '+%m-%d-%Y') -#git config user.email "167856002+mongodb-dbx-release-bot[bot]@users.noreply.github.com" -#git config user.name "mongodb-dbx-release-bot[bot]" git remote set-url origin https://x-access-token:${token}@github.com/$owner/$repo.git git checkout -b $branch "origin/master" git add ./test From 9f6f727811e833953b23ddf66e56b429e26e464a Mon Sep 17 00:00:00 2001 From: Iris Ho Date: Wed, 25 Jun 2025 15:10:13 -0700 Subject: [PATCH 13/22] 9am pst is 4pm utc i think? --- .evergreen/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.evergreen/config.yml b/.evergreen/config.yml index e5719061ca..753c1ac28b 100644 --- a/.evergreen/config.yml +++ b/.evergreen/config.yml @@ -58,7 +58,7 @@ buildvariants: - name: resync_specs display_name: "Resync Specs" run_on: rhel80-small - cron: '0 9 * * MON' + cron: '0 16 * * MON' patchable: false tasks: - name: resync_specs From 3144383343eecdf1b3c54688b3ddf65ae81f9cfe Mon Sep 17 00:00:00 2001 From: Iris Ho Date: Wed, 25 Jun 2025 15:52:54 -0700 Subject: [PATCH 14/22] remove unused vars and cleanup debugging prints --- .evergreen/scripts/create-pr.sh | 12 +++--------- .evergreen/scripts/resync-all-specs.sh | 2 -- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/.evergreen/scripts/create-pr.sh b/.evergreen/scripts/create-pr.sh index 11aa32d5d3..b02f7444e4 100755 --- a/.evergreen/scripts/create-pr.sh +++ b/.evergreen/scripts/create-pr.sh @@ -2,9 +2,8 @@ tools="../drivers-evergreen-tools" git clone https://github.com/mongodb-labs/drivers-evergreen-tools.git $tools -body="$(cat "$1")" -pushd $tools/.evergreen/github_app +pushd $tools/.evergreen/github_app || exit owner="mongodb" repo="mongo-python-driver" @@ -23,11 +22,11 @@ echo "Getting github token..." token=$(bash ./get-access-token.sh $repo $owner) if [ -z "${token}" ]; then echo "Failed to get github access token!" - popd + popd || exit exit 1 fi echo "Getting github token... done." -popd +popd || exit # Make the git checkout and create a new branch. echo "Creating the git checkout..." @@ -40,10 +39,7 @@ git apply -R .evergreen/specs.patch git commit -am "resyncing specs test?" echo "Creating the git checkout... done." -echo "THIS IS THE BODY" -echo "$body" git push origin $branch -echo "{\"title\":\"[Spec Resync] $(date '+%m-%d-%Y')\",\"body\":\"$(cat "$1")\",\"head\":\"${branch}\",\"base\":\"master\"}" resp=$(curl -L \ -X POST \ -H "Accept: application/vnd.github+json" \ @@ -51,8 +47,6 @@ resp=$(curl -L \ -H "X-GitHub-Api-Version: 2022-11-28" \ -d "{\"title\":\"[Spec Resync] $(date '+%m-%d-%Y')\",\"body\":\"$(cat "$1")\",\"head\":\"${branch}\",\"base\":\"master\"}" \ --url https://api.github.com/repos/$owner/$repo/pulls) -echo $resp -echo $resp | jq '.html_url' echo "Creating the PR... done." rm -rf $tools diff --git a/.evergreen/scripts/resync-all-specs.sh b/.evergreen/scripts/resync-all-specs.sh index 217628d554..f0464ae6f2 100755 --- a/.evergreen/scripts/resync-all-specs.sh +++ b/.evergreen/scripts/resync-all-specs.sh @@ -2,12 +2,10 @@ # Run spec syncing script and create PR # SETUP -SPEC_DEST="$(realpath -s "./test")" SRC_URL="https://github.com/mongodb/specifications.git" # needs to be set for resunc-specs.sh SPEC_SRC="$(realpath -s "../specifications")" SCRIPT="$(realpath -s "./.evergreen/resync-specs.sh")" -BRANCH_NAME="spec-resync-"$(date '+%m-%d-%Y') # Clone the spec repo if the directory does not exist if [[ ! -d $SPEC_SRC ]]; then From 2bea24bc736545c4fe030c02cdc65d84aa977319 Mon Sep 17 00:00:00 2001 From: Iris Ho Date: Thu, 26 Jun 2025 09:08:02 -0700 Subject: [PATCH 15/22] oops accidentally deleted this line --- .evergreen/scripts/create-pr.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/.evergreen/scripts/create-pr.sh b/.evergreen/scripts/create-pr.sh index b02f7444e4..4dd76f789b 100755 --- a/.evergreen/scripts/create-pr.sh +++ b/.evergreen/scripts/create-pr.sh @@ -47,6 +47,7 @@ resp=$(curl -L \ -H "X-GitHub-Api-Version: 2022-11-28" \ -d "{\"title\":\"[Spec Resync] $(date '+%m-%d-%Y')\",\"body\":\"$(cat "$1")\",\"head\":\"${branch}\",\"base\":\"master\"}" \ --url https://api.github.com/repos/$owner/$repo/pulls) +echo $resp | jq '.html_url' echo "Creating the PR... done." rm -rf $tools From 4bef7ca8747da829c3b565e0e8b991038a90d61a Mon Sep 17 00:00:00 2001 From: Iris Ho Date: Thu, 26 Jun 2025 09:48:02 -0700 Subject: [PATCH 16/22] fix resync commit msg --- .evergreen/scripts/create-pr.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.evergreen/scripts/create-pr.sh b/.evergreen/scripts/create-pr.sh index 4dd76f789b..5f23d82b01 100755 --- a/.evergreen/scripts/create-pr.sh +++ b/.evergreen/scripts/create-pr.sh @@ -36,7 +36,7 @@ git remote set-url origin https://x-access-token:${token}@github.com/$owner/$rep git checkout -b $branch "origin/master" git add ./test git apply -R .evergreen/specs.patch -git commit -am "resyncing specs test?" +git commit -am "resyncing specs $(date '+%m-%d-%Y')" echo "Creating the git checkout... done." git push origin $branch From 8aaf7915495d63788ec89ac18cf8adc1f61d6cf2 Mon Sep 17 00:00:00 2001 From: Iris Ho Date: Thu, 26 Jun 2025 09:51:14 -0700 Subject: [PATCH 17/22] add / fix comments --- .evergreen/scripts/resync-all-specs.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.evergreen/scripts/resync-all-specs.py b/.evergreen/scripts/resync-all-specs.py index 1bc07433bf..eb0f420ce5 100644 --- a/.evergreen/scripts/resync-all-specs.py +++ b/.evergreen/scripts/resync-all-specs.py @@ -7,6 +7,7 @@ def resync_specs(directory: pathlib.Path, errored: dict[str, str]) -> list[str]: + """Actually sync the specs""" for spec in os.scandir(directory): if not spec.is_dir(): continue @@ -35,6 +36,7 @@ def resync_specs(directory: pathlib.Path, errored: dict[str, str]) -> list[str]: def check_new_spec_directories(directory: pathlib.Path) -> list[str]: + """Check to see if there are any directories in the spec repo that don't exist in pymongo/test""" spec_dir = pathlib.Path(os.environ["MDB_SPECS"]) / "source" spec_set = { entry.name.replace("-", "_") @@ -64,6 +66,7 @@ def check_new_spec_directories(directory: pathlib.Path) -> list[str]: def write_summary(succeeded: list[str], errored: dict[str, str], new: list[str]) -> None: + """Generate the PR description""" pr_body = "" if len(succeeded) > 0: pr_body += "The following specs were changed:\n- " @@ -81,7 +84,7 @@ def write_summary(succeeded: list[str], errored: dict[str, str], new: list[str]) if pr_body != "": with open("spec_sync.txt", "w") as f: - # replacements made for to be json + # replacements made for proper json f.write(pr_body.replace("\n", "\\n").replace("\t", "\\t")) From 413b46362c552f45697706ec55ec106fc0138a95 Mon Sep 17 00:00:00 2001 From: Iris Ho Date: Thu, 26 Jun 2025 13:55:00 -0700 Subject: [PATCH 18/22] check=True, catch error instead --- .evergreen/scripts/resync-all-specs.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/.evergreen/scripts/resync-all-specs.py b/.evergreen/scripts/resync-all-specs.py index eb0f420ce5..b94547777b 100644 --- a/.evergreen/scripts/resync-all-specs.py +++ b/.evergreen/scripts/resync-all-specs.py @@ -4,6 +4,7 @@ import os import pathlib import subprocess +from subprocess import CalledProcessError def resync_specs(directory: pathlib.Path, errored: dict[str, str]) -> list[str]: @@ -14,15 +15,15 @@ def resync_specs(directory: pathlib.Path, errored: dict[str, str]) -> list[str]: if spec.name in ["asynchronous"]: continue - process = subprocess.run( - ["bash", "./.evergreen/resync-specs.sh", spec.name], # noqa: S603, S607 - capture_output=True, - text=True, - check=False, - ) - - if process.returncode != 0: - errored[spec.name] = process.stderr + try: + subprocess.run( + ["bash", "./.evergreen/resync-specs.sh", spec.name], # noqa: S603, S607 + capture_output=True, + text=True, + check=True, + ) + except CalledProcessError as exc: + errored[spec.name] = exc.stderr process = subprocess.run( ["git diff --name-only | awk -F'/' '{print $2}' | sort | uniq"], # noqa: S607 From 1a3d87f51c37f9f375bd24d253da8f0abc4102da Mon Sep 17 00:00:00 2001 From: Iris Ho Date: Fri, 27 Jun 2025 11:57:31 -0700 Subject: [PATCH 19/22] multiple patch files --- .evergreen/{specs.patch => patch/diff.patch} | 0 .evergreen/patch/new.patch | 0 .evergreen/patch/update.patch | 0 .evergreen/scripts/create-pr.sh | 2 +- CONTRIBUTING.md | 19 +++++++++++++++++++ 5 files changed, 20 insertions(+), 1 deletion(-) rename .evergreen/{specs.patch => patch/diff.patch} (100%) create mode 100644 .evergreen/patch/new.patch create mode 100644 .evergreen/patch/update.patch diff --git a/.evergreen/specs.patch b/.evergreen/patch/diff.patch similarity index 100% rename from .evergreen/specs.patch rename to .evergreen/patch/diff.patch diff --git a/.evergreen/patch/new.patch b/.evergreen/patch/new.patch new file mode 100644 index 0000000000..e69de29bb2 diff --git a/.evergreen/patch/update.patch b/.evergreen/patch/update.patch new file mode 100644 index 0000000000..e69de29bb2 diff --git a/.evergreen/scripts/create-pr.sh b/.evergreen/scripts/create-pr.sh index 5f23d82b01..9298d76963 100755 --- a/.evergreen/scripts/create-pr.sh +++ b/.evergreen/scripts/create-pr.sh @@ -35,7 +35,7 @@ branch="spec-resync-"$(date '+%m-%d-%Y') git remote set-url origin https://x-access-token:${token}@github.com/$owner/$repo.git git checkout -b $branch "origin/master" git add ./test -git apply -R .evergreen/specs.patch +git apply -R --allow-empty .evergreen/patch/* git commit -am "resyncing specs $(date '+%m-%d-%Y')" echo "Creating the git checkout... done." diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ca98584602..89f02a0801 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -432,6 +432,25 @@ update in PyMongo. This is primarily helpful if you are implementing a new feature in PyMongo that has spec tests already implemented, or if you are attempting to validate new spec tests in PyMongo. +### Automated Specification Test Resyncing +`/.evergreen/scripts/resync-all-specs.sh` is a script that will +automatically run once a week. This script calls a python script +`.evergreen/scripts/resync-all-specs.py` that actually does all +the resyncing. If appropriate, the bash script then calls +`.evergreen/scripts/create-pr.sh` that actually publishes a PR. + +There are three patch files that contain test differences between +pymongo tests and the specs +`.evergreen/patch/diff.patch`: These contain tests that we know we +differ in and do not plan to fix. (This is likely an instance of the +Python driver having a different behaviour.) +`.evergreen/patch/new.patch`: This is for newly added test files that +we fail. +`.evergreen/patch/update.patch`: This is for test changes that were +updated and now fail. In this case, we want to keep the old passing +version, add the appropriate `git diff` to this patch file, and open +a new ticket to unskip these. + ## Making a Release Follow the [Python Driver Release Process Wiki](https://wiki.corp.mongodb.com/display/DRIVERS/Python+Driver+Release+Process). From 4f3cb61f79486b8877af998ab4d177d4f3371cb4 Mon Sep 17 00:00:00 2001 From: Iris Ho Date: Fri, 27 Jun 2025 12:26:07 -0700 Subject: [PATCH 20/22] update contributing to explain patch files --- CONTRIBUTING.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 89f02a0801..ad55bd89f1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -436,7 +436,9 @@ you are attempting to validate new spec tests in PyMongo. `/.evergreen/scripts/resync-all-specs.sh` is a script that will automatically run once a week. This script calls a python script `.evergreen/scripts/resync-all-specs.py` that actually does all -the resyncing. If appropriate, the bash script then calls +the resyncing. Then, any desired un-syncing will be accomplished +with the help of patch files through a `git apply -R`. If +appropriate, the bash script then calls `.evergreen/scripts/create-pr.sh` that actually publishes a PR. There are three patch files that contain test differences between @@ -448,9 +450,14 @@ Python driver having a different behaviour.) we fail. `.evergreen/patch/update.patch`: This is for test changes that were updated and now fail. In this case, we want to keep the old passing -version, add the appropriate `git diff` to this patch file, and open +version, add the diff to this patch file, and open a new ticket to unskip these. +#### Adding to a patch file +Assuming the changes are committed somewhere, to add to any of the +patch files, run `git diff` to show the desired changes and paste the +results into the patch file. + ## Making a Release Follow the [Python Driver Release Process Wiki](https://wiki.corp.mongodb.com/display/DRIVERS/Python+Driver+Release+Process). From ec50afff81691f34af7325471bf6c9ca77834c79 Mon Sep 17 00:00:00 2001 From: Iris <58442094+sleepyStick@users.noreply.github.com> Date: Fri, 27 Jun 2025 12:53:37 -0700 Subject: [PATCH 21/22] Update CONTRIBUTING.md Co-authored-by: Noah Stapp --- CONTRIBUTING.md | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ad55bd89f1..b664f8c609 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -441,17 +441,12 @@ with the help of patch files through a `git apply -R`. If appropriate, the bash script then calls `.evergreen/scripts/create-pr.sh` that actually publishes a PR. -There are three patch files that contain test differences between -pymongo tests and the specs -`.evergreen/patch/diff.patch`: These contain tests that we know we -differ in and do not plan to fix. (This is likely an instance of the -Python driver having a different behaviour.) -`.evergreen/patch/new.patch`: This is for newly added test files that -we fail. -`.evergreen/patch/update.patch`: This is for test changes that were -updated and now fail. In this case, we want to keep the old passing -version, add the diff to this patch file, and open -a new ticket to unskip these. +There are three patch files that contain known test differences between +PyMongo's tests and the specification: +`.evergreen/patch/diff.patch`: tests where +PyMongo intentionally behaves differently than the specification. This file should rarely be modified, as most of these represent fundamental differences in design or behavior. +`.evergreen/patch/new.patch`: tests for new features that have not yet been implemented in PyMongo. Tests must be removed from this file as part of the PR that implements their feature. +`.evergreen/patch/update.patch`: tests that have been updated in a way that causes them to fail until their associated driver change is implemented. Tests must be removed from this file as part of the PR that implements the fix or behavioral change. #### Adding to a patch file Assuming the changes are committed somewhere, to add to any of the From 579c194f8e7a3d4a2dcef0d26fc8638ec952b3e5 Mon Sep 17 00:00:00 2001 From: Iris Ho Date: Fri, 27 Jun 2025 13:07:43 -0700 Subject: [PATCH 22/22] explain what syncing is, add example, and modify spacing --- CONTRIBUTING.md | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b664f8c609..9a774d2973 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -433,26 +433,34 @@ new feature in PyMongo that has spec tests already implemented, or if you are attempting to validate new spec tests in PyMongo. ### Automated Specification Test Resyncing -`/.evergreen/scripts/resync-all-specs.sh` is a script that will -automatically run once a week. This script calls a python script -`.evergreen/scripts/resync-all-specs.py` that actually does all -the resyncing. Then, any desired un-syncing will be accomplished -with the help of patch files through a `git apply -R`. If -appropriate, the bash script then calls -`.evergreen/scripts/create-pr.sh` that actually publishes a PR. +There is a script (`/.evergreen/scripts/resync-all-specs.sh`) that will +automatically run once a week to resync all the specs with the [specifications +repo](https://github.com/mongodb/specifications). +If there are changes, a PR will be generated by mongodb-drivers-pr-bot. +If any errors occurred, the PR description will display the name of the spec along +with stderr from the `bash resync-spec.sh ` command. There are three patch files that contain known test differences between PyMongo's tests and the specification: -`.evergreen/patch/diff.patch`: tests where -PyMongo intentionally behaves differently than the specification. This file should rarely be modified, as most of these represent fundamental differences in design or behavior. -`.evergreen/patch/new.patch`: tests for new features that have not yet been implemented in PyMongo. Tests must be removed from this file as part of the PR that implements their feature. -`.evergreen/patch/update.patch`: tests that have been updated in a way that causes them to fail until their associated driver change is implemented. Tests must be removed from this file as part of the PR that implements the fix or behavioral change. +`.evergreen/patch/diff.patch`: tests where PyMongo intentionally behaves differently than the specification. +This file should rarely be modified, as most of these represent fundamental differences in design or behavior. +`.evergreen/patch/new.patch`: tests for new features that have not yet been implemented in PyMongo. +Tests must be removed from this file as part of the PR that implements their feature. +`.evergreen/patch/update.patch`: tests that have been updated in a way that causes them to fail until their +associated driver change is implemented. Tests must be removed from this file as part of the PR that implements +the fix or behavioral change. #### Adding to a patch file Assuming the changes are committed somewhere, to add to any of the patch files, run `git diff` to show the desired changes and paste the results into the patch file. +For example, there are new test files on the most recent commit of the current branch that are failing. +To add those changes to `new.patch`, I would do the following: +```bash +git diff HEAD~1 path/to/new/file >> .evergreen/patch/new.patch +``` + ## Making a Release Follow the [Python Driver Release Process Wiki](https://wiki.corp.mongodb.com/display/DRIVERS/Python+Driver+Release+Process).