Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 62 additions & 62 deletions eng/ci/official-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,67 +52,67 @@ extends:
- stage: BuildPythonWorker
jobs:
- template: /eng/templates/official/jobs/build-artifacts.yml@self
- stage: RunWorkerE2ETests
dependsOn: BuildPythonWorker
jobs:
- template: /eng/templates/official/jobs/ci-e2e-tests.yml@self
- stage: RunWorkerEmulatorTests
dependsOn: BuildPythonWorker
jobs:
- template: /eng/templates/jobs/ci-emulator-tests.yml@self
parameters:
PoolName: 1es-pool-azfunc
- stage: RunWorkerUnitTests
dependsOn: BuildPythonWorker
jobs:
- template: /eng/templates/jobs/ci-unit-tests.yml@self
parameters:
PoolName: 1es-pool-azfunc
- stage: RunWorkerDockerConsumptionTests
dependsOn: BuildPythonWorker
jobs:
- template: /eng/templates/official/jobs/ci-docker-consumption-tests.yml@self
- stage: RunWorkerDockerDedicatedTests
dependsOn: BuildPythonWorker
jobs:
- template: /eng/templates/official/jobs/ci-docker-dedicated-tests.yml@self
- stage: RunWorkerLinuxConsumptionTests
dependsOn: BuildPythonWorker
jobs:
- template: /eng/templates/official/jobs/ci-lc-tests.yml@self
# - stage: RunWorkerE2ETests
# dependsOn: BuildPythonWorker
# jobs:
# - template: /eng/templates/official/jobs/ci-e2e-tests.yml@self
# - stage: RunWorkerEmulatorTests
# dependsOn: BuildPythonWorker
# jobs:
# - template: /eng/templates/jobs/ci-emulator-tests.yml@self
# parameters:
# PoolName: 1es-pool-azfunc
# - stage: RunWorkerUnitTests
# dependsOn: BuildPythonWorker
# jobs:
# - template: /eng/templates/jobs/ci-unit-tests.yml@self
# parameters:
# PoolName: 1es-pool-azfunc
# - stage: RunWorkerDockerConsumptionTests
# dependsOn: BuildPythonWorker
# jobs:
# - template: /eng/templates/official/jobs/ci-docker-consumption-tests.yml@self
# - stage: RunWorkerDockerDedicatedTests
# dependsOn: BuildPythonWorker
# jobs:
# - template: /eng/templates/official/jobs/ci-docker-dedicated-tests.yml@self
# - stage: RunWorkerLinuxConsumptionTests
# dependsOn: BuildPythonWorker
# jobs:
# - template: /eng/templates/official/jobs/ci-lc-tests.yml@self

# Python V2 Library Build and Test Stages
- stage: BuildV2Library
dependsOn: []
jobs:
- template: /eng/templates/official/jobs/build-library.yml@self
parameters:
PROJECT_NAME: 'Python V2 Library'
PROJECT_DIRECTORY: 'runtimes/v2'
ARTIFACT_NAME: 'azure-functions-runtime'
- stage: RunV2LibraryUnitTests
dependsOn: BuildV2Library
jobs:
- template: /eng/templates/jobs/ci-library-unit-tests.yml@self
parameters:
PROJECT_NAME: 'Python V2 Library'
PROJECT_DIRECTORY: 'runtimes/v2'
PoolName: 1es-pool-azfunc
# # Python V2 Library Build and Test Stages
# - stage: BuildV2Library
# dependsOn: []
# jobs:
# - template: /eng/templates/official/jobs/build-library.yml@self
# parameters:
# PROJECT_NAME: 'Python V2 Library'
# PROJECT_DIRECTORY: 'runtimes/v2'
# ARTIFACT_NAME: 'azure-functions-runtime'
# - stage: RunV2LibraryUnitTests
# dependsOn: BuildV2Library
# jobs:
# - template: /eng/templates/jobs/ci-library-unit-tests.yml@self
# parameters:
# PROJECT_NAME: 'Python V2 Library'
# PROJECT_DIRECTORY: 'runtimes/v2'
# PoolName: 1es-pool-azfunc

# Python V1 Library Build and Test Stages
- stage: BuildV1Library
dependsOn: []
jobs:
- template: /eng/templates/official/jobs/build-library.yml@self
parameters:
PROJECT_NAME: 'Python V1 Library'
PROJECT_DIRECTORY: 'runtimes/v1'
ARTIFACT_NAME: 'azure-functions-runtime-v1'
- stage: RunV1LibraryUnitTests
dependsOn: BuildV1Library
jobs:
- template: /eng/templates/jobs/ci-library-unit-tests.yml@self
parameters:
PROJECT_NAME: 'Python V1 Library'
PROJECT_DIRECTORY: 'runtimes/v1'
PoolName: 1es-pool-azfunc
# # Python V1 Library Build and Test Stages
# - stage: BuildV1Library
# dependsOn: []
# jobs:
# - template: /eng/templates/official/jobs/build-library.yml@self
# parameters:
# PROJECT_NAME: 'Python V1 Library'
# PROJECT_DIRECTORY: 'runtimes/v1'
# ARTIFACT_NAME: 'azure-functions-runtime-v1'
# - stage: RunV1LibraryUnitTests
# dependsOn: BuildV1Library
# jobs:
# - template: /eng/templates/jobs/ci-library-unit-tests.yml@self
# parameters:
# PROJECT_NAME: 'Python V1 Library'
# PROJECT_DIRECTORY: 'runtimes/v1'
# PoolName: 1es-pool-azfunc
2 changes: 2 additions & 0 deletions eng/pack/scripts/nix_arm64_deps.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ docker rm my-arm64-container
copy_list=(
"azure"
"azure_functions_worker"
"azure_functions_runtime"
"azure_functions_runtime_v1"
"azurefunctions"
"dateutil"
"google"
Expand Down
36 changes: 26 additions & 10 deletions eng/templates/shared/github-release-branch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,35 @@ steps:
Write-Host "Operating based on $stagingDirectory/azure-functions-python-worker"
git checkout -b "$newBranch"

# Modify Runtime Version in pyproject.toml
Write-Host "Replacing Runtime version in worker's pyproject.toml"
((Get-Content workers/pyproject.toml) -replace '"${{ parameters.PROJECT_NAME }}==[^";]+', "`"${{ parameters.PROJECT_NAME }}==$newLibraryVersion") -join "`n" | Set-Content -NoNewline workers/pyproject.toml
# Runtime Release Only
if (${{ parameters.PROJECT_DIRECTORY}} -ne "workers")
{
# Modify Runtime Version in workers/pyproject.toml
Write-Host "Replacing Runtime version in worker's pyproject.toml"
((Get-Content workers/pyproject.toml) -replace '"${{ parameters.PROJECT_NAME }}==[^";]+', "`"${{ parameters.PROJECT_NAME }}==$newLibraryVersion") -join "`n" | Set-Content -NoNewline workers/pyproject.toml

# Change ${{ parameters.PROJECT_DIRECTORY}}/version.py version
Write-Host "Change version number in version.py to $newWorkerVersion"
((Get-Content $versionFile) -replace "VERSION = '(\d+).(\d+).*'", "VERSION = '$newWorkerVersion'" -join "`n") + "`n" | Set-Content -NoNewline $versionFile

git add workers/pyproject.toml
git add $versionFile
}

# Change ${{ parameters.PROJECT_DIRECTORY}}/version.py version
cd ${{ parameters.PROJECT_DIRECTORY}}
Write-Host "Change version number in version.py to $newWorkerVersion"
((Get-Content $versionFile) -replace "VERSION = '(\d+).(\d+).*'", "VERSION = '$newWorkerVersion'" -join "`n") + "`n" | Set-Content -NoNewline $versionFile
# Worker Release Only
if (${{ parameters.PROJECT_DIRECTORY}} -eq "workers")
{
# Change azure_functions_worker version
Write-Host "Change version number in version.py to $newWorkerVersion"
((Get-Content $versionFile) -replace "VERSION = '(\d+).(\d+).*'", "VERSION = '$newWorkerVersion'" -join "`n") + "`n" | Set-Content -NoNewline ${{ parameters.PROJECT_DIRECTORY}}/azure_functions_worker/version.py

git add $versionFile
# Change proxy_worker version
Write-Host "Change version number in version.py to $newWorkerVersion"
((Get-Content $versionFile) -replace "VERSION = '(\d+).(\d+).*'", "VERSION = '$newWorkerVersion'" -join "`n") + "`n" | Set-Content -NoNewline ${{ parameters.PROJECT_DIRECTORY}}/proxy_worker/version.py

cd ..
git add workers/pyproject.toml
git add ${{ parameters.PROJECT_DIRECTORY}}/azure_functions_worker/version.py
git add ${{ parameters.PROJECT_DIRECTORY}}/proxy_worker/version.py
}

git commit -m "build: update ${{ parameters.PROJECT_DIRECTORY}} version to $newWorkerVersion"

Expand Down
4 changes: 2 additions & 2 deletions eng/templates/utils/official-variables.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ variables:
- template: /ci/variables/cfs.yml@eng
- group: python-integration-resources
- name: prodV4Path
value: 'python/prodV4/worker.py'
value: 'workers/python/prodV4/worker.py'
- name: proxyV4Path
value: 'python/proxyV4/worker.py'
value: 'workers/python/proxyV4/worker.py'
26 changes: 19 additions & 7 deletions workers/tests/unittest_proxy/test_dispatcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,11 @@ def fake_import(name, globals=None, locals=None, fromlist=(), level=0):
@patch("builtins.__import__", side_effect=fake_import)
@patch("proxy_worker.dispatcher.protos.StreamingMessage",
return_value="mocked_streaming_response")
@patch("proxy_worker.dispatcher.check_python_eol")
@pytest.mark.asyncio
async def test_worker_init_v2_import(
mock_streaming, mock_import, mock_exists, mock_logger, mock_prioritize,
mock_eol, mock_streaming, mock_import, mock_exists,
mock_logger, mock_prioritize,
mock_should_load
):
dispatcher = Dispatcher(asyncio.get_event_loop(), "localhost", 7071, "worker123",
Expand All @@ -130,9 +132,11 @@ async def test_worker_init_v2_import(
@patch("builtins.__import__", side_effect=fake_import)
@patch("proxy_worker.dispatcher.protos.StreamingMessage",
return_value="mocked_streaming_response")
@patch("proxy_worker.dispatcher.check_python_eol")
@pytest.mark.asyncio
async def test_worker_init_fallback_to_v1(
mock_streaming, mock_import, mock_exists, mock_logger, mock_prioritize,
mock_eol, mock_streaming, mock_import, mock_exists,
mock_logger, mock_prioritize,
mock_should_load
):
dispatcher = Dispatcher(asyncio.get_event_loop(), "localhost", 7071, "worker123",
Expand All @@ -154,9 +158,10 @@ async def test_worker_init_fallback_to_v1(
@patch("builtins.__import__", side_effect=fake_import)
@patch("proxy_worker.dispatcher.protos.StreamingMessage",
return_value="mocked_reload_response")
@patch("proxy_worker.dispatcher.check_python_eol")
@pytest.mark.asyncio
async def test_function_environment_reload_v2_import(
mock_streaming, mock_import, mock_exists, mock_logger, mock_prioritize
mock_eol, mock_streaming, mock_import, mock_exists, mock_logger, mock_prioritize
):
dispatcher = Dispatcher(asyncio.get_event_loop(), "localhost", 7071,
"worker123", "req789", 5.0)
Expand All @@ -177,9 +182,10 @@ async def test_function_environment_reload_v2_import(
@patch("builtins.__import__", side_effect=fake_import)
@patch("proxy_worker.dispatcher.protos.StreamingMessage",
return_value="mocked_reload_response")
@patch("proxy_worker.dispatcher.check_python_eol")
@pytest.mark.asyncio
async def test_function_environment_reload_fallback_to_v1(
mock_streaming, mock_import, mock_exists, mock_logger, mock_prioritize
mock_eol, mock_streaming, mock_import, mock_exists, mock_logger, mock_prioritize
):
dispatcher = Dispatcher(asyncio.get_event_loop(), "localhost", 7071, "worker123",
"req789", 5.0)
Expand Down Expand Up @@ -301,8 +307,10 @@ def get_threadpool_executor():
@patch("builtins.__import__")
@patch("proxy_worker.dispatcher.protos.StreamingMessage",
return_value="mocked_init_response")
@patch("proxy_worker.dispatcher.check_python_eol")
@pytest.mark.asyncio
async def test_worker_init_starts_threadpool(mock_streaming, mock_import, *_mocks):
async def test_worker_init_starts_threadpool(mock_eol, mock_streaming,
mock_import, *_mocks):
runtime_module = _make_runtime_module(with_threadpool=True)

def fake_import(name, *a, **k):
Expand All @@ -327,8 +335,10 @@ def fake_import(name, *a, **k):
@patch("builtins.__import__")
@patch("proxy_worker.dispatcher.protos.StreamingMessage",
return_value="mocked_reload_response")
@patch("proxy_worker.dispatcher.check_python_eol")
@pytest.mark.asyncio
async def test_env_reload_starts_threadpool(mock_streaming, mock_import, *_mocks):
async def test_env_reload_starts_threadpool(mock_eol, mock_streaming,
mock_import, *_mocks):
runtime_module = _make_runtime_module(with_threadpool=True)

def fake_import(name, *a, **k):
Expand Down Expand Up @@ -359,8 +369,10 @@ def fake_import(name, *a, **k):
@patch("builtins.__import__")
@patch("proxy_worker.dispatcher.protos.StreamingMessage",
return_value="mocked_init_response")
@patch("proxy_worker.dispatcher.check_python_eol")
@pytest.mark.asyncio
async def test_worker_init_missing_threadpool_apis(mock_streaming, mock_import,
async def test_worker_init_missing_threadpool_apis(mock_eol,
mock_streaming, mock_import,
mock_exists, mock_logger, *_):
runtime_module = _make_runtime_module(with_threadpool=False)

Expand Down
14 changes: 6 additions & 8 deletions workers/tests/unittest_proxy/test_utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,14 @@

class TestCheckPythonEOL(unittest.TestCase):
def setUp(self):
self.version = "3.9"
self.version = "3.13"
self.eol_date = datetime.strptime(PYTHON_EOL_DATES[self.version], "%Y-%m")
self.warning_date = self.eol_date.replace(
day=1) - (self.eol_date
- datetime.strptime("2025-04", "%Y-%m"))
self.warning_date = self.eol_date.replace(year=2029, month=4, day=1)

@patch("proxy_worker.utils.common.sys.version_info")
def test_between_warning_and_eol(self, mock_version):
mock_version.major, mock_version.minor = (3, 9)
test_date = datetime(2025, 5, 1) # Between warning and EOL
mock_version.major, mock_version.minor = (3, 13)
test_date = datetime(2029, 6, 1) # Between warning and EOL
with patch("proxy_worker.utils.common.datetime") as mock_datetime:
mock_datetime.utcnow.return_value = test_date
mock_datetime.strptime = datetime.strptime
Expand All @@ -32,8 +30,8 @@ def test_between_warning_and_eol(self, mock_version):

@patch("proxy_worker.utils.common.sys.version_info")
def test_after_eol(self, mock_version):
mock_version.major, mock_version.minor = (3, 9)
test_date = datetime(2026, 1, 1) # After EOL
mock_version.major, mock_version.minor = (3, 13)
test_date = datetime(2030, 1, 1) # After EOL
with patch("proxy_worker.utils.common.datetime") as mock_datetime:
mock_datetime.utcnow.return_value = test_date
mock_datetime.strptime = datetime.strptime
Expand Down
Loading