Skip to content

Commit c18f1f1

Browse files
Merge branch 'main' into SNOW-2129602-ensure-scheme-in-gcs-stage-endpoints
2 parents 3fdec6b + 3f9edc2 commit c18f1f1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+1727
-458
lines changed

.github/workflows/build_test.yml

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ jobs:
173173
- name: Run tests
174174
# To run a single test on GHA use the below command:
175175
# run: python -m tox run -e `echo py${PYTHON_VERSION/\./}-single-ci | sed 's/ /,/g'`
176-
run: python -m tox run -e `echo py${PYTHON_VERSION/\./}-{extras,unit,integ,pandas,sso}-ci | sed 's/ /,/g'`
176+
run: python -m tox run -e `echo py${PYTHON_VERSION/\./}-{extras,unit-parallel,integ-parallel,pandas-parallel,sso}-ci | sed 's/ /,/g'`
177177

178178
env:
179179
PYTHON_VERSION: ${{ matrix.python-version }}
@@ -193,6 +193,12 @@ jobs:
193193
path: |
194194
.tox/.coverage
195195
.tox/coverage.xml
196+
- uses: actions/upload-artifact@v4
197+
with:
198+
include-hidden-files: true
199+
name: junit_${{ matrix.os.download_name }}-${{ matrix.python-version }}-${{ matrix.cloud-provider }}
200+
path: |
201+
.tox/junit.*.xml
196202
197203
test-olddriver:
198204
name: Old Driver Test ${{ matrix.os.download_name }}-${{ matrix.python-version }}-${{ matrix.cloud-provider }}
@@ -307,6 +313,12 @@ jobs:
307313
path: |
308314
.coverage
309315
coverage.xml
316+
- uses: actions/upload-artifact@v4
317+
with:
318+
include-hidden-files: true
319+
name: junit_linux-fips-3.9-${{ matrix.cloud-provider }}
320+
path: |
321+
junit.*.xml
310322
311323
test-lambda:
312324
name: Test Lambda linux-${{ matrix.python-version }}-${{ matrix.cloud-provider }}
@@ -354,6 +366,12 @@ jobs:
354366
path: |
355367
.coverage.py${{ env.shortver }}-lambda-ci
356368
junit.py${{ env.shortver }}-lambda-ci-dev.xml
369+
- uses: actions/upload-artifact@v4
370+
with:
371+
include-hidden-files: true
372+
name: junit_linux-lambda-${{ matrix.python-version }}-${{ matrix.cloud-provider }}
373+
path: |
374+
junit.py${{ env.shortver }}-lambda-ci-dev.xml
357375
358376
combine-coverage:
359377
if: ${{ success() || failure() }}
@@ -388,6 +406,21 @@ jobs:
388406
dst_file = dst_dir / ".coverage.{}".format(src_file.parent.name[9:])
389407
print("{} copy to {}".format(src_file, dst_file))
390408
shutil.copy(str(src_file), str(dst_file))'
409+
- name: Collect all JUnit XML files to one dir
410+
run: |
411+
python -c '
412+
from pathlib import Path
413+
import shutil
414+
415+
src_dir = Path("artifacts")
416+
dst_dir = Path(".") / "junit_results"
417+
dst_dir.mkdir()
418+
# Collect all JUnit XML files with different naming patterns
419+
for pattern in ["*/junit.*.xml", "*/junit.py*-lambda-ci-dev.xml"]:
420+
for src_file in src_dir.glob(pattern):
421+
dst_file = dst_dir / src_file.name
422+
print("{} copy to {}".format(src_file, dst_file))
423+
shutil.copy(str(src_file), str(dst_file))'
391424
- name: Combine coverages
392425
run: python -m tox run -e coverage
393426
- name: Publish html coverage
@@ -406,3 +439,9 @@ jobs:
406439
with:
407440
files: .tox/coverage.xml
408441
token: ${{ secrets.CODECOV_TOKEN }}
442+
- name: Upload test results to Codecov
443+
if: ${{ !cancelled() }}
444+
uses: codecov/test-results-action@v1
445+
with:
446+
token: ${{ secrets.CODECOV_TOKEN }}
447+
files: junit_results/junit.*.xml
Binary file not shown.

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,3 +129,8 @@ src/snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_arrow_iterator.cpp
129129
# Prober files
130130
prober/parameters.json
131131
prober/snowflake_prober.egg-info/
132+
133+
# SSH private key for WIF tests
134+
ci/wif/parameters/rsa_wif_aws_azure
135+
ci/wif/parameters/rsa_wif_gcp
136+
ci/wif/parameters/parameters_wif.json

DESCRIPTION.md

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,26 @@ https://docs.snowflake.com/
77
Source code is also available at: https://github.com/snowflakedb/snowflake-connector-python
88

99
# Release Notes
10-
- v3.16(TBD)
11-
- Bumped numpy dependency from <2.1.0 to <=2.2.4
12-
- Added Windows support for Python 3.13.
13-
- Add `bulk_upload_chunks` parameter to `write_pandas` function. Setting this parameter to True changes the behaviour of write_pandas function to first write all the data chunks to the local disk and then perform the wildcard upload of the chunks folder to the stage. In default behaviour the chunks are being saved, uploaded and deleted one by one.
10+
- v3.16.1(TBD)
11+
- Added in-band OCSP exception telemetry.
12+
- Added `APPLICATION_PATH` within `CLIENT_ENVIRONMENT` to distinguish between multiple scripts using the PythonConnector in the same environment.
13+
- Disabled token caching for OAuth Client Credentials authentication
14+
- Added in-band HTTP exception telemetry.
15+
- Fixed a bug where timezoned timestamps fetched as pandas.DataFrame or pyarrow.Table would overflow for the sake of unnecessary precision. In the case where an overflow cannot be prevented a clear error will be raised now.
16+
- Fix OAuth authenticator values.
17+
- Add `unsafe_skip_file_permissions_check` flag to skip file permissions check on cache and config.
18+
- Introduce snowflake_version property to the connection
1419
- Fix GCS staging by ensuring the endpoint has a scheme.
20+
21+
- v3.16.0(July 04,2025)
22+
- Bumped numpy dependency from <2.1.0 to <=2.2.4.
23+
- Added Windows support for Python 3.13.
24+
- Added `bulk_upload_chunks` parameter to `write_pandas` function. Setting this parameter to True changes the behaviour of write_pandas function to first write all the data chunks to the local disk and then perform the wildcard upload of the chunks folder to the stage. In default behaviour the chunks are being saved, uploaded and deleted one by one.
1525
- Added support for new authentication mechanism PAT with external session ID.
1626
- Added `client_fetch_use_mp` parameter that enables multiprocessed fetching of result batches.
17-
18-
- v3.15.1(May 20, 2025)
1927
- Added basic arrow support for Interval types.
20-
- Fix `write_pandas` special characters usage in the location name.
21-
- Fix usage of `use_virtual_url` when building the location for gcs storage client.
22-
- Bind cryptography to <=44.0.3 to avoid issues with 45.0.0.
28+
- Fixed `write_pandas` special characters usage in the location name.
29+
- Fixed usage of `use_virtual_url` when building the location for gcs storage client.
2330
- Added support for Snowflake OAuth for local applications.
2431

2532
- v3.15.0(Apr 29,2025)

Jenkinsfile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,18 @@ timestamps {
7171
'''.stripMargin()
7272
}
7373
}
74+
},
75+
'Test WIF': {
76+
stage('Test WIF') {
77+
withCredentials([
78+
string(credentialsId: 'sfctest0-parameters-secret', variable: 'PARAMETERS_SECRET')
79+
]) {
80+
sh '''\
81+
|#!/bin/bash -e
82+
|$WORKSPACE/ci/test_wif.sh
83+
'''.stripMargin()
84+
}
85+
}
7486
}
7587
)
7688
}

ci/container/test_authentication.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ set -o pipefail
66
export WORKSPACE=${WORKSPACE:-/mnt/workspace}
77
export SOURCE_ROOT=${SOURCE_ROOT:-/mnt/host}
88

9-
MVNW_EXE=$SOURCE_ROOT/mvnw
109
AUTH_PARAMETER_FILE=./.github/workflows/parameters/private/parameters_aws_auth_tests.json
1110
eval $(jq -r '.authtestparams | to_entries | map("export \(.key)=\(.value|tostring)")|.[]' $AUTH_PARAMETER_FILE)
1211

ci/test_authentication.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,5 @@ docker run \
2323
-v $(cd $THIS_DIR/.. && pwd):/mnt/host \
2424
-v $WORKSPACE:/mnt/workspace \
2525
--rm \
26-
nexus.int.snowflakecomputing.com:8086/docker/snowdrivers-test-external-browser-python:1 \
26+
nexus.int.snowflakecomputing.com:8086/docker/snowdrivers-test-external-browser-python:2 \
2727
"/mnt/host/ci/container/test_authentication.sh"

ci/test_fips.sh

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ curl https://repo1.maven.org/maven2/org/wiremock/wiremock-standalone/3.11.0/wire
1414
python3 -m venv fips_env
1515
source fips_env/bin/activate
1616
pip install -U setuptools pip
17+
18+
# Install pytest-xdist for parallel execution
19+
pip install pytest-xdist
20+
1721
pip install "${CONNECTOR_WHL}[pandas,secure-local-storage,development]"
1822

1923
echo "!!! Environment description !!!"
@@ -24,6 +28,8 @@ python -c "from cryptography.hazmat.backends.openssl import backend;print('Cryp
2428
pip freeze
2529

2630
cd $CONNECTOR_DIR
27-
pytest -vvv --cov=snowflake.connector --cov-report=xml:coverage.xml test
31+
32+
# Run tests in parallel using pytest-xdist
33+
pytest -n auto -vvv --cov=snowflake.connector --cov-report=xml:coverage.xml test
2834

2935
deactivate

ci/test_linux.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ else
4040
echo "[Info] Testing with ${PYTHON_VERSION}"
4141
SHORT_VERSION=$(python3.10 -c "print('${PYTHON_VERSION}'.replace('.', ''))")
4242
CONNECTOR_WHL=$(ls $CONNECTOR_DIR/dist/snowflake_connector_python*cp${SHORT_VERSION}*manylinux2014*.whl | sort -r | head -n 1)
43-
TEST_LIST=`echo py${PYTHON_VERSION/\./}-{unit,integ,pandas,sso}-ci | sed 's/ /,/g'`
43+
TEST_LIST=`echo py${PYTHON_VERSION/\./}-{unit-parallel,integ,pandas-parallel,sso}-ci | sed 's/ /,/g'`
4444
TEST_ENVLIST=fix_lint,$TEST_LIST,py${PYTHON_VERSION/\./}-coverage
4545
echo "[Info] Running tox for ${TEST_ENVLIST}"
4646

ci/test_wif.sh

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#!/bin/bash -e
2+
3+
set -o pipefail
4+
5+
export THIS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
6+
export RSA_KEY_PATH_AWS_AZURE="$THIS_DIR/wif/parameters/rsa_wif_aws_azure"
7+
export RSA_KEY_PATH_GCP="$THIS_DIR/wif/parameters/rsa_wif_gcp"
8+
export PARAMETERS_FILE_PATH="$THIS_DIR/wif/parameters/parameters_wif.json"
9+
10+
run_tests_and_set_result() {
11+
local provider="$1"
12+
local host="$2"
13+
local snowflake_host="$3"
14+
local rsa_key_path="$4"
15+
16+
ssh -i "$rsa_key_path" -o IdentitiesOnly=yes -p 443 "$host" env BRANCH="$BRANCH" SNOWFLAKE_TEST_WIF_HOST="$snowflake_host" SNOWFLAKE_TEST_WIF_PROVIDER="$provider" SNOWFLAKE_TEST_WIF_ACCOUNT="$SNOWFLAKE_TEST_WIF_ACCOUNT" bash << EOF
17+
set -e
18+
set -o pipefail
19+
docker run \
20+
--rm \
21+
-e BRANCH \
22+
-e SNOWFLAKE_TEST_WIF_PROVIDER \
23+
-e SNOWFLAKE_TEST_WIF_HOST \
24+
-e SNOWFLAKE_TEST_WIF_ACCOUNT \
25+
snowflakedb/client-python-test:1 \
26+
bash -c "
27+
echo 'Running tests on branch: \$BRANCH'
28+
if [[ \"\$BRANCH\" =~ ^PR-[0-9]+\$ ]]; then
29+
curl -L https://github.com/snowflakedb/snowflake-connector-python/archive/refs/pull/\$(echo \$BRANCH | cut -d- -f2)/head.tar.gz | tar -xz
30+
mv snowflake-connector-python-* snowflake-connector-python
31+
else
32+
curl -L https://github.com/snowflakedb/snowflake-connector-python/archive/refs/heads/\$BRANCH.tar.gz | tar -xz
33+
mv snowflake-connector-python-\$BRANCH snowflake-connector-python
34+
fi
35+
cd snowflake-connector-python
36+
bash ci/wif/test_wif.sh
37+
"
38+
EOF
39+
local status=$?
40+
41+
if [[ $status -ne 0 ]]; then
42+
echo "$provider tests failed with exit status: $status"
43+
EXIT_STATUS=1
44+
else
45+
echo "$provider tests passed"
46+
fi
47+
}
48+
49+
get_branch() {
50+
local branch
51+
branch=$(git rev-parse --abbrev-ref HEAD)
52+
if [[ "$branch" == "HEAD" ]]; then
53+
branch=$(git name-rev --name-only HEAD | sed 's#^remotes/origin/##;s#^origin/##')
54+
fi
55+
echo "$branch"
56+
}
57+
58+
setup_parameters() {
59+
gpg --quiet --batch --yes --decrypt --passphrase="$PARAMETERS_SECRET" --output "$RSA_KEY_PATH_AWS_AZURE" "${RSA_KEY_PATH_AWS_AZURE}.gpg"
60+
gpg --quiet --batch --yes --decrypt --passphrase="$PARAMETERS_SECRET" --output "$RSA_KEY_PATH_GCP" "${RSA_KEY_PATH_GCP}.gpg"
61+
chmod 600 "$RSA_KEY_PATH_AWS_AZURE"
62+
chmod 600 "$RSA_KEY_PATH_GCP"
63+
gpg --quiet --batch --yes --decrypt --passphrase="$PARAMETERS_SECRET" --output "$PARAMETERS_FILE_PATH" "${PARAMETERS_FILE_PATH}.gpg"
64+
eval $(jq -r '.wif | to_entries | map("export \(.key)=\(.value|tostring)")|.[]' $PARAMETERS_FILE_PATH)
65+
}
66+
67+
BRANCH=$(get_branch)
68+
export BRANCH
69+
setup_parameters
70+
71+
# Run tests for all cloud providers
72+
EXIT_STATUS=0
73+
set +e # Don't exit on first failure
74+
run_tests_and_set_result "AZURE" "$HOST_AZURE" "$SNOWFLAKE_TEST_WIF_HOST_AZURE" "$RSA_KEY_PATH_AWS_AZURE"
75+
run_tests_and_set_result "AWS" "$HOST_AWS" "$SNOWFLAKE_TEST_WIF_HOST_AWS" "$RSA_KEY_PATH_AWS_AZURE"
76+
run_tests_and_set_result "GCP" "$HOST_GCP" "$SNOWFLAKE_TEST_WIF_HOST_GCP" "$RSA_KEY_PATH_GCP"
77+
set -e # Re-enable exit on error
78+
echo "Exit status: $EXIT_STATUS"
79+
exit $EXIT_STATUS

0 commit comments

Comments
 (0)