|
1 | 1 | # (C) Datadog, Inc. 2023-present |
2 | 2 | # All rights reserved |
3 | 3 | # Licensed under a 3-clause BSD style license (see LICENSE) |
4 | | -from .conftest import NEW_PYTHON_VERSION, OLD_PYTHON_VERSION |
5 | 4 |
|
6 | 5 |
|
7 | | -def test_update_py_config(fake_repo, ddev): |
8 | | - constant_file = fake_repo.path / 'ddev' / 'src' / 'ddev' / 'repo' / 'constants.py' |
9 | | - contents = constant_file.read_text() |
| 6 | +def setup_python_update_files(fake_repo): |
| 7 | + """Add PYTHON_VERSION_FULL and Dockerfiles to fake_repo.""" |
| 8 | + # Update constants.py to include PYTHON_VERSION_FULL |
| 9 | + constants_file = fake_repo.path / 'ddev' / 'src' / 'ddev' / 'repo' / 'constants.py' |
| 10 | + content = constants_file.read_text() |
| 11 | + content += "PYTHON_VERSION_FULL = '3.13.7'\n" |
| 12 | + constants_file.write_text(content) |
10 | 13 |
|
11 | | - assert f'PYTHON_VERSION = {OLD_PYTHON_VERSION!r}' in contents |
12 | | - assert f'PYTHON_VERSION = {NEW_PYTHON_VERSION!r}' not in contents |
| 14 | + # Create Linux ARM64 Dockerfile |
| 15 | + linux_aarch64_dir = fake_repo.path / '.builders' / 'images' / 'linux-aarch64' |
| 16 | + linux_aarch64_dir.mkdir(parents=True, exist_ok=True) |
| 17 | + (linux_aarch64_dir / 'Dockerfile').write_text("""FROM ubuntu:22.04 |
13 | 18 |
|
14 | | - result = ddev('meta', 'scripts', 'update-python-config', NEW_PYTHON_VERSION) |
| 19 | +# Install Python |
| 20 | +ENV PYTHON3_VERSION=3.13.7 |
| 21 | +RUN DOWNLOAD_URL="https://python.org/ftp/python/{{version}}/Python-{{version}}.tgz" \\ |
| 22 | + VERSION="${PYTHON3_VERSION}" \\ |
| 23 | + SHA256="6c9d80839cfa20024f34d9a6dd31ae2a9cd97ff5e980e969209746037a5153b2" \\ |
| 24 | + bash install-from-source.sh |
| 25 | +
|
| 26 | +CMD ["/bin/bash"] |
| 27 | +""") |
| 28 | + |
| 29 | + # Create Linux x86_64 Dockerfile |
| 30 | + linux_x86_64_dir = fake_repo.path / '.builders' / 'images' / 'linux-x86_64' |
| 31 | + linux_x86_64_dir.mkdir(parents=True, exist_ok=True) |
| 32 | + (linux_x86_64_dir / 'Dockerfile').write_text("""FROM ubuntu:22.04 |
| 33 | +
|
| 34 | +# Install Python |
| 35 | +ENV PYTHON3_VERSION=3.13.7 |
| 36 | +RUN DOWNLOAD_URL="https://python.org/ftp/python/{{version}}/Python-{{version}}.tgz" \\ |
| 37 | + VERSION="${PYTHON3_VERSION}" \\ |
| 38 | + SHA256="6c9d80839cfa20024f34d9a6dd31ae2a9cd97ff5e980e969209746037a5153b2" \\ |
| 39 | + bash install-from-source.sh |
| 40 | +
|
| 41 | +CMD ["/bin/bash"] |
| 42 | +""") |
| 43 | + |
| 44 | + # Create Windows Dockerfile |
| 45 | + windows_dockerfile_dir = fake_repo.path / '.builders' / 'images' / 'windows-x86_64' |
| 46 | + windows_dockerfile_dir.mkdir(parents=True, exist_ok=True) |
| 47 | + (windows_dockerfile_dir / 'Dockerfile').write_text("""FROM mcr.microsoft.com/windows/servercore:ltsc2022 |
| 48 | +
|
| 49 | +# Install Python |
| 50 | +ENV PYTHON_VERSION="3.13.7" |
| 51 | +RUN powershell -Command " \\ |
| 52 | + Invoke-WebRequest -OutFile python-$Env:PYTHON_VERSION-amd64.exe \\ |
| 53 | + https://www.python.org/ftp/python/$Env:PYTHON_VERSION/python-$Env:PYTHON_VERSION-amd64.exe \\ |
| 54 | + -Hash '48652a4e6af29c2f1fde2e2e6bbf3734a82ce3f577e9fd5c95c83f68e29e1eaa'" |
| 55 | +
|
| 56 | +CMD ["powershell"] |
| 57 | +""") |
| 58 | + |
| 59 | + # Create macOS workflow file |
| 60 | + workflows_dir = fake_repo.path / '.github' / 'workflows' |
| 61 | + workflows_dir.mkdir(parents=True, exist_ok=True) |
| 62 | + (workflows_dir / 'resolve-build-deps.yaml').write_text("""name: Resolve build dependencies |
| 63 | +
|
| 64 | +on: |
| 65 | + workflow_dispatch: |
| 66 | +
|
| 67 | +env: |
| 68 | + PYTHON3_DOWNLOAD_URL: "https://www.python.org/ftp/python/3.13.7/python-3.13.7-macos11.pkg" |
| 69 | +
|
| 70 | +jobs: |
| 71 | + build: |
| 72 | + runs-on: macos-latest |
| 73 | + steps: |
| 74 | + - run: echo "test" |
| 75 | +""") |
| 76 | + |
| 77 | + |
| 78 | +def test_update_python_version_success(fake_repo, ddev, mocker): |
| 79 | + """Test successful Python version update.""" |
| 80 | + setup_python_update_files(fake_repo) |
| 81 | + # Mock network calls |
| 82 | + mocker.patch('ddev.cli.meta.scripts.update_python.get_latest_python_version', return_value='3.13.9') |
| 83 | + mocker.patch( |
| 84 | + 'ddev.cli.meta.scripts.update_python.get_python_sha256_hashes', |
| 85 | + return_value={ |
| 86 | + 'linux_source_sha256': 'c4c066af19c98fb7835d473bebd7e23be84f6e9874d47db9e39a68ee5d0ce35c', |
| 87 | + 'windows_amd64_sha256': '200ddff856bbff949d2cc1be42e8807c07538abd6b6966d5113a094cf628c5c5', |
| 88 | + }, |
| 89 | + ) |
| 90 | + |
| 91 | + result = ddev('meta', 'scripts', 'update-python-version') |
| 92 | + |
| 93 | + assert result.exit_code == 0, result.output |
| 94 | + assert 'Updating Python from 3.13.7 to 3.13.9' in result.output |
| 95 | + assert 'Passed: 5' in result.output |
| 96 | + assert 'Python version updated from 3.13.7 to 3.13.9' in result.output |
| 97 | + |
| 98 | + # Verify constants.py was updated |
| 99 | + constants_file = fake_repo.path / 'ddev' / 'src' / 'ddev' / 'repo' / 'constants.py' |
| 100 | + contents = constants_file.read_text() |
| 101 | + assert "PYTHON_VERSION_FULL = '3.13.9'" in contents |
| 102 | + assert "PYTHON_VERSION_FULL = '3.13.7'" not in contents |
| 103 | + |
| 104 | + # Verify Linux Dockerfile was updated |
| 105 | + linux_dockerfile = fake_repo.path / '.builders' / 'images' / 'linux-aarch64' / 'Dockerfile' |
| 106 | + contents = linux_dockerfile.read_text() |
| 107 | + assert 'ENV PYTHON3_VERSION=3.13.9' in contents |
| 108 | + assert 'SHA256="c4c066af19c98fb7835d473bebd7e23be84f6e9874d47db9e39a68ee5d0ce35c"' in contents |
| 109 | + assert 'ENV PYTHON3_VERSION=3.13.7' not in contents |
| 110 | + |
| 111 | + # Verify Windows Dockerfile was updated |
| 112 | + windows_dockerfile = fake_repo.path / '.builders' / 'images' / 'windows-x86_64' / 'Dockerfile' |
| 113 | + contents = windows_dockerfile.read_text() |
| 114 | + assert 'ENV PYTHON_VERSION="3.13.9"' in contents |
| 115 | + assert '-Hash \'200ddff856bbff949d2cc1be42e8807c07538abd6b6966d5113a094cf628c5c5\'' in contents |
| 116 | + assert 'ENV PYTHON_VERSION="3.13.7"' not in contents |
| 117 | + |
| 118 | + # Verify macOS workflow was updated |
| 119 | + workflow_file = fake_repo.path / '.github' / 'workflows' / 'resolve-build-deps.yaml' |
| 120 | + contents = workflow_file.read_text() |
| 121 | + assert 'python-3.13.9-macos11.pkg' in contents |
| 122 | + assert 'python-3.13.7-macos11.pkg' not in contents |
| 123 | + |
| 124 | + |
| 125 | +def test_update_python_version_already_latest(fake_repo, ddev, mocker): |
| 126 | + setup_python_update_files(fake_repo) |
| 127 | + mocker.patch('ddev.cli.meta.scripts.update_python.get_latest_python_version', return_value='3.13.7') |
| 128 | + |
| 129 | + result = ddev('meta', 'scripts', 'update-python-version') |
15 | 130 |
|
16 | 131 | assert result.exit_code == 0, result.output |
17 | | - assert result.output.endswith('Python upgrades\n\nPassed: 9\n') |
18 | | - |
19 | | - contents = constant_file.read_text() |
20 | | - assert f'PYTHON_VERSION = {OLD_PYTHON_VERSION!r}' not in contents |
21 | | - assert f'PYTHON_VERSION = {NEW_PYTHON_VERSION!r}' in contents |
22 | | - |
23 | | - ci_file = fake_repo.path / '.github' / 'workflows' / 'build-ddev.yml' |
24 | | - contents = ci_file.read_text() |
25 | | - assert f'PYTHON_VERSION: "{OLD_PYTHON_VERSION}"' not in contents |
26 | | - assert f'PYTHON_VERSION: "{NEW_PYTHON_VERSION}"' in contents |
27 | | - |
28 | | - hatch_file = fake_repo.path / 'dummy' / 'hatch.toml' |
29 | | - contents = hatch_file.read_text() |
30 | | - assert f'python = ["{OLD_PYTHON_VERSION}"]' not in contents |
31 | | - assert f'python = ["{NEW_PYTHON_VERSION}"]' in contents |
32 | | - |
33 | | - for integration in ('dummy', 'datadog_checks_dependency_provider', 'logs_only'): |
34 | | - pyproject_file = fake_repo.path / integration / 'pyproject.toml' |
35 | | - contents = pyproject_file.read_text() |
36 | | - assert f'Programming Language :: Python :: {OLD_PYTHON_VERSION}' not in contents |
37 | | - assert f'Programming Language :: Python :: {NEW_PYTHON_VERSION}' in contents |
38 | | - |
39 | | - template_file = ( |
40 | | - fake_repo.path |
41 | | - / 'datadog_checks_dev' |
42 | | - / 'datadog_checks' |
43 | | - / 'dev' |
44 | | - / 'tooling' |
45 | | - / 'templates' |
46 | | - / 'integration' |
47 | | - / 'check' |
48 | | - / '{check_name}' |
49 | | - / 'pyproject.toml' |
| 132 | + assert 'Already at latest Python version: 3.13.7' in result.output |
| 133 | + |
| 134 | + |
| 135 | +def test_update_python_version_no_new_version_found(fake_repo, ddev, mocker): |
| 136 | + setup_python_update_files(fake_repo) |
| 137 | + mocker.patch('ddev.cli.meta.scripts.update_python.get_latest_python_version', return_value=None) |
| 138 | + |
| 139 | + result = ddev('meta', 'scripts', 'update-python-version') |
| 140 | + |
| 141 | + assert result.exit_code == 1, result.output |
| 142 | + assert 'Could not find latest Python version' in result.output |
| 143 | + |
| 144 | + |
| 145 | +def test_update_python_version_invalid_hash_format(fake_repo, ddev, mocker): |
| 146 | + setup_python_update_files(fake_repo) |
| 147 | + mocker.patch('ddev.cli.meta.scripts.update_python.get_latest_python_version', return_value='3.13.9') |
| 148 | + mocker.patch( |
| 149 | + 'ddev.cli.meta.scripts.update_python.get_python_sha256_hashes', |
| 150 | + return_value={'linux_source_sha256': 'not-a-valid-hash', 'windows_amd64_sha256': 'also-invalid'}, |
50 | 151 | ) |
51 | | - contents = template_file.read_text() |
52 | | - assert f'Programming Language :: Python :: {OLD_PYTHON_VERSION}' not in contents |
53 | | - assert f'Programming Language :: Python :: {NEW_PYTHON_VERSION}' in contents |
| 152 | + |
| 153 | + result = ddev('meta', 'scripts', 'update-python-version') |
| 154 | + |
| 155 | + assert result.exit_code == 1, result.output |
| 156 | + assert 'Invalid Linux SHA256 hash format' in result.output or 'Invalid Windows SHA256 hash format' in result.output |
0 commit comments