-
Notifications
You must be signed in to change notification settings - Fork 4.5k
sdks/python/scripts: fix posargs for run_pytest.sh
#35733
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
344a9ce
3a94a87
4d5f702
864683c
b819b70
0f6d8c0
151e278
f53d37b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| { | ||
| "comment": "Modify this file in a trivial way to cause this test suite to run.", | ||
| "modification": 4 | ||
| "modification": 29 | ||
| } | ||
|
|
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -30,8 +30,15 @@ envname=${1?First argument required: suite base name} | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| posargs=$2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pytest_args=$3 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # strip leading/trailing quotes from posargs because it can get double quoted as its passed through. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| posargs=$(sed -e 's/^"//' -e 's/"$//' -e "s/'$//" -e "s/^'//" <<<$posargs) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # strip leading/trailing quotes from posargs because it can get double quoted as | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # its passed through. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ $posargs == '"'*'"' ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # If wrapped in double quotes, remove them | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| posargs="${posargs:1:${#posargs}-2}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| elif [[ $posargs == "'"*"'" ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # If wrapped in single quotes, remove them. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| posargs="${posargs:1:${#posargs}-2}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "pytest_args: $pytest_args" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "posargs: $posargs" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -41,15 +48,26 @@ marker_regex="-m\s+('[^']+'|\"[^\"]+\"|[^ ]+)" | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Initialize the user_marker variable. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| user_marker="" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Isolate the user-provided -m argument (matching only). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ $pytest_args =~ "-m" ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Extract the marker value using the defined regex. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| user_marker=$(echo "$pytest_args" | sed -nE "s/.*$marker_regex.*/\1/p") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Define regex pattern for quoted strings | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| quotes_regex="^[\"\'](.*)[\"\']$" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Remove the -m argument from pytest_args (substitution only). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ -n $user_marker ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pytest_args=$(echo "$pytest_args" | sed -E "s/$marker_regex//") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Extract the user markers. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ $posargs =~ $marker_regex ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Get the full match including -m and the marker. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| full_match="${BASH_REMATCH[0]}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Get the marker with quotes (this is the first capture group). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| quoted_marker="${BASH_REMATCH[1]}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Remove any quotes around the marker. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ $quoted_marker =~ $quotes_regex ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| user_marker="${BASH_REMATCH[1]}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| user_marker="$quoted_marker" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
mohamedawnallah marked this conversation as resolved.
Show resolved
Hide resolved
mohamedawnallah marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Remove the entire -m marker portion from posargs. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| posargs="${posargs/$full_match/}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Combine user-provided marker with script's internal logic. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -58,20 +76,65 @@ marker_for_sequential_tests="no_xdist" | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ -n $user_marker ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Combine user marker with internal markers. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| marker_for_parallel_tests="($user_marker) and ($marker_for_parallel_tests)" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| marker_for_sequential_tests="($user_marker) and ($marker_for_sequential_tests)" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| marker_for_parallel_tests="$user_marker and ($marker_for_parallel_tests)" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| marker_for_sequential_tests="$user_marker and ($marker_for_sequential_tests)" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Parse posargs to separate pytest options from test paths. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| options="" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| test_paths="" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Safely split the posargs string into individual arguments. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| eval "set -- $posargs" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The use of For example, a user could pass Please replace
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @gemini-code-assist Other alternatives would result in adding more complexity to this script in terms of looping through tokens, handling quotes, ...etc. Also
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I understand your concerns regarding increased complexity and the review process in CI environments. However, the use of Even in a controlled CI setting, a successful exploit could lead to severe consequences, such as data exfiltration, system compromise, or disruption of the build process. While parsing shell arguments safely can be complex, the security implications of I maintain that this is a
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @gemini-code-assist please give me alternative that fits nicely in this script instead of eval "set -- $posargs"
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I understand your request for an alternative that "fits nicely" within the existing script structure while addressing the To safely parse the arguments, respecting quotes, without using This code snippet replaces the
Suggested change
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @gemini-code-assist We can do this change in follow-up PR? Bash is tricky and take me a bit of time to test them. I can say I am confident that current changes
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we don't need to worry about this. We're directly invoking this script and control what arguments are passed in. If anyone invokes this script, they already have full permissions to run arbitrary code.
mohamedawnallah marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Iterate through arguments. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| while [[ $# -gt 0 ]]; do | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| arg="$1" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| shift | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # If argument starts with dash, it's an option. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ "$arg" == -* ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| options+=" $arg" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Check if there's a next argument and it doesn't start with a dash. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # This assumes it's a value for the current option. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ $# -gt 0 && "$1" != -* ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Get the next argument. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| next_arg="$1" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Check if it's quoted and remove quotes if needed. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ $next_arg =~ $quotes_regex ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Extract the content inside quotes. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| next_arg="${BASH_REMATCH[1]}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
mohamedawnallah marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Add the unquoted value to options. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| options+=" $next_arg" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| shift | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Otherwise it's a test path. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| test_paths+=" $arg" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| done | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Construct the final pytest command arguments. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pyargs_section="" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ -n "$test_paths" ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pyargs_section="--pyargs $test_paths" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pytest_command_args="$options $pyargs_section" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Run tests in parallel. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Running parallel tests with: pytest -m \"$marker_for_parallel_tests\" $pytest_args" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Running parallel tests with: pytest -m \"$marker_for_parallel_tests\" $pytest_command_args" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pytest -v -rs -o junit_suite_name=${envname} \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --junitxml=pytest_${envname}.xml -m "$marker_for_parallel_tests" -n 6 --import-mode=importlib ${pytest_args} --pyargs ${posargs} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --junitxml=pytest_${envname}.xml -m "$marker_for_parallel_tests" -n 6 --import-mode=importlib ${pytest_args} ${pytest_command_args} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| status1=$? | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Run tests sequentially. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Running sequential tests with: pytest -m \"$marker_for_sequential_tests\" $pytest_args" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Running sequential tests with: pytest -m \"$marker_for_sequential_tests\" $pytest_command_args" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pytest -v -rs -o junit_suite_name=${envname}_no_xdist \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --junitxml=pytest_${envname}_no_xdist.xml -m "$marker_for_sequential_tests" --import-mode=importlib ${pytest_args} --pyargs ${posargs} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --junitxml=pytest_${envname}_no_xdist.xml -m "$marker_for_sequential_tests" --import-mode=importlib ${pytest_args} ${pytest_command_args} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| status2=$? | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Exit with error if no tests were run in either suite (status code 5). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.