| name: Tests |
| |
| # gh-84728: "paths-ignore" is not used to skip documentation-only PRs, because |
| # it prevents to mark a job as mandatory. A PR cannot be merged if a job is |
| # mandatory but not scheduled because of "paths-ignore". |
| on: |
| workflow_dispatch: |
| push: |
| branches: |
| - 'main' |
| - '3.12' |
| - '3.11' |
| - '3.10' |
| - '3.9' |
| - '3.8' |
| - '3.7' |
| pull_request: |
| branches: |
| - 'main' |
| - '3.12' |
| - '3.11' |
| - '3.10' |
| - '3.9' |
| - '3.8' |
| - '3.7' |
| |
| permissions: |
| contents: read |
| |
| concurrency: |
| group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} |
| cancel-in-progress: true |
| |
| jobs: |
| check_source: |
| name: 'Check for source changes' |
| runs-on: ubuntu-latest |
| timeout-minutes: 10 |
| outputs: |
| run_tests: ${{ steps.check.outputs.run_tests }} |
| run_hypothesis: ${{ steps.check.outputs.run_hypothesis }} |
| config_hash: ${{ steps.config_hash.outputs.hash }} |
| steps: |
| - uses: actions/checkout@v3 |
| - name: Check for source changes |
| id: check |
| run: | |
| if [ -z "$GITHUB_BASE_REF" ]; then |
| echo "run_tests=true" >> $GITHUB_OUTPUT |
| else |
| git fetch origin $GITHUB_BASE_REF --depth=1 |
| # git diff "origin/$GITHUB_BASE_REF..." (3 dots) may be more |
| # reliable than git diff "origin/$GITHUB_BASE_REF.." (2 dots), |
| # but it requires to download more commits (this job uses |
| # "git fetch --depth=1"). |
| # |
| # git diff "origin/$GITHUB_BASE_REF..." (3 dots) works with Git |
| # 2.26, but Git 2.28 is stricter and fails with "no merge base". |
| # |
| # git diff "origin/$GITHUB_BASE_REF.." (2 dots) should be enough on |
| # GitHub, since GitHub starts by merging origin/$GITHUB_BASE_REF |
| # into the PR branch anyway. |
| # |
| # https://github.com/python/core-workflow/issues/373 |
| git diff --name-only origin/$GITHUB_BASE_REF.. | grep -qvE '(\.rst$|^Doc|^Misc)' && echo "run_tests=true" >> $GITHUB_OUTPUT || true |
| fi |
| |
| # Check if we should run hypothesis tests |
| GIT_BRANCH=${GITHUB_BASE_REF:-${GITHUB_REF#refs/heads/}} |
| echo $GIT_BRANCH |
| if $(echo "$GIT_BRANCH" | grep -q -w '3\.\(8\|9\|10\|11\)'); then |
| echo "Branch too old for hypothesis tests" |
| echo "run_hypothesis=false" >> $GITHUB_OUTPUT |
| else |
| echo "Run hypothesis tests" |
| echo "run_hypothesis=true" >> $GITHUB_OUTPUT |
| fi |
| - name: Compute hash for config cache key |
| id: config_hash |
| run: | |
| echo "hash=${{ hashFiles('configure', 'configure.ac', '.github/workflows/build.yml') }}" >> $GITHUB_OUTPUT |
| |
| check_generated_files: |
| name: 'Check if generated files are up to date' |
| runs-on: ubuntu-latest |
| timeout-minutes: 60 |
| needs: check_source |
| if: needs.check_source.outputs.run_tests == 'true' |
| steps: |
| - uses: actions/checkout@v3 |
| - name: Restore config.cache |
| uses: actions/cache@v3 |
| with: |
| path: config.cache |
| key: ${{ github.job }}-${{ runner.os }}-${{ needs.check_source.outputs.config_hash }} |
| - uses: actions/setup-python@v3 |
| - name: Install Dependencies |
| run: sudo ./.github/workflows/posix-deps-apt.sh |
| - name: Add ccache to PATH |
| run: echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV |
| - name: Configure ccache action |
| uses: hendrikmuhs/ccache-action@v1.2 |
| - name: Check Autoconf version 2.69 and aclocal 1.16.3 |
| run: | |
| grep "Generated by GNU Autoconf 2.69" configure |
| grep "aclocal 1.16.3" aclocal.m4 |
| grep -q "runstatedir" configure |
| grep -q "PKG_PROG_PKG_CONFIG" aclocal.m4 |
| - name: Configure CPython |
| run: | |
| # Build Python with the libpython dynamic library |
| ./configure --config-cache --with-pydebug --enable-shared |
| - name: Regenerate autoconf files with container image |
| run: make regen-configure |
| - name: Build CPython |
| run: | |
| # Deepfreeze will usually cause global objects to be added or removed, |
| # so we run it before regen-global-objects gets rum (in regen-all). |
| make regen-deepfreeze |
| make -j4 regen-all |
| make regen-stdlib-module-names |
| - name: Check for changes |
| run: | |
| git add -u |
| changes=$(git status --porcelain) |
| # Check for changes in regenerated files |
| if test -n "$changes"; then |
| echo "Generated files not up to date." |
| echo "Perhaps you forgot to run make regen-all or build.bat --regen. ;)" |
| echo "configure files must be regenerated with a specific version of autoconf." |
| echo "$changes" |
| echo "" |
| git diff --staged || true |
| exit 1 |
| fi |
| - name: Check exported libpython symbols |
| run: make smelly |
| - name: Check limited ABI symbols |
| run: make check-limited-abi |
| - name: Check for unsupported C global variables |
| if: github.event_name == 'pull_request' # $GITHUB_EVENT_NAME |
| run: make check-c-globals |
| |
| build_win32: |
| name: 'Windows (x86)' |
| runs-on: windows-latest |
| timeout-minutes: 60 |
| needs: check_source |
| if: needs.check_source.outputs.run_tests == 'true' |
| env: |
| IncludeUwp: 'true' |
| steps: |
| - uses: actions/checkout@v3 |
| - name: Build CPython |
| run: .\PCbuild\build.bat -e -d -p Win32 |
| - name: Display build info |
| run: .\python.bat -m test.pythoninfo |
| - name: Tests |
| run: .\PCbuild\rt.bat -p Win32 -d -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0 |
| |
| build_win_amd64: |
| name: 'Windows (x64)' |
| runs-on: windows-latest |
| timeout-minutes: 60 |
| needs: check_source |
| if: needs.check_source.outputs.run_tests == 'true' |
| env: |
| IncludeUwp: 'true' |
| steps: |
| - uses: actions/checkout@v3 |
| - name: Register MSVC problem matcher |
| run: echo "::add-matcher::.github/problem-matchers/msvc.json" |
| - name: Build CPython |
| run: .\PCbuild\build.bat -e -d -p x64 |
| - name: Display build info |
| run: .\python.bat -m test.pythoninfo |
| - name: Tests |
| run: .\PCbuild\rt.bat -p x64 -d -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0 |
| |
| build_macos: |
| name: 'macOS' |
| runs-on: macos-latest |
| timeout-minutes: 60 |
| needs: check_source |
| if: needs.check_source.outputs.run_tests == 'true' |
| env: |
| HOMEBREW_NO_ANALYTICS: 1 |
| HOMEBREW_NO_AUTO_UPDATE: 1 |
| HOMEBREW_NO_INSTALL_CLEANUP: 1 |
| PYTHONSTRICTEXTENSIONBUILD: 1 |
| steps: |
| - uses: actions/checkout@v3 |
| - name: Restore config.cache |
| uses: actions/cache@v3 |
| with: |
| path: config.cache |
| key: ${{ github.job }}-${{ runner.os }}-${{ needs.check_source.outputs.config_hash }} |
| - name: Install Homebrew dependencies |
| run: brew install pkg-config openssl@1.1 xz gdbm tcl-tk |
| - name: Configure CPython |
| run: | |
| CFLAGS="-I$(brew --prefix gdbm)/include -I$(brew --prefix xz)/include" \ |
| LDFLAGS="-L$(brew --prefix gdbm)/lib -I$(brew --prefix xz)/lib" \ |
| PKG_CONFIG_PATH="$(brew --prefix tcl-tk)/lib/pkgconfig" \ |
| ./configure \ |
| --config-cache \ |
| --with-pydebug \ |
| --prefix=/opt/python-dev \ |
| --with-openssl="$(brew --prefix openssl@1.1)" |
| - name: Build CPython |
| run: make -j4 |
| - name: Display build info |
| run: make pythoninfo |
| - name: Tests |
| run: make buildbottest TESTOPTS="-j4 -uall,-cpu" |
| |
| build_ubuntu: |
| name: 'Ubuntu' |
| runs-on: ubuntu-20.04 |
| timeout-minutes: 60 |
| needs: check_source |
| if: needs.check_source.outputs.run_tests == 'true' |
| env: |
| OPENSSL_VER: 1.1.1t |
| PYTHONSTRICTEXTENSIONBUILD: 1 |
| steps: |
| - uses: actions/checkout@v3 |
| - name: Register gcc problem matcher |
| run: echo "::add-matcher::.github/problem-matchers/gcc.json" |
| - name: Install Dependencies |
| run: sudo ./.github/workflows/posix-deps-apt.sh |
| - name: Configure OpenSSL env vars |
| run: | |
| echo "MULTISSL_DIR=${GITHUB_WORKSPACE}/multissl" >> $GITHUB_ENV |
| echo "OPENSSL_DIR=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}" >> $GITHUB_ENV |
| echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}/lib" >> $GITHUB_ENV |
| - name: 'Restore OpenSSL build' |
| id: cache-openssl |
| uses: actions/cache@v3 |
| with: |
| path: ./multissl/openssl/${{ env.OPENSSL_VER }} |
| key: ${{ runner.os }}-multissl-openssl-${{ env.OPENSSL_VER }} |
| - name: Install OpenSSL |
| if: steps.cache-openssl.outputs.cache-hit != 'true' |
| run: python3 Tools/ssl/multissltests.py --steps=library --base-directory $MULTISSL_DIR --openssl $OPENSSL_VER --system Linux |
| - name: Add ccache to PATH |
| run: | |
| echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV |
| - name: Configure ccache action |
| uses: hendrikmuhs/ccache-action@v1.2 |
| - name: Setup directory envs for out-of-tree builds |
| run: | |
| echo "CPYTHON_RO_SRCDIR=$(realpath -m ${GITHUB_WORKSPACE}/../cpython-ro-srcdir)" >> $GITHUB_ENV |
| echo "CPYTHON_BUILDDIR=$(realpath -m ${GITHUB_WORKSPACE}/../cpython-builddir)" >> $GITHUB_ENV |
| - name: Create directories for read-only out-of-tree builds |
| run: mkdir -p $CPYTHON_RO_SRCDIR $CPYTHON_BUILDDIR |
| - name: Bind mount sources read-only |
| run: sudo mount --bind -o ro $GITHUB_WORKSPACE $CPYTHON_RO_SRCDIR |
| - name: Restore config.cache |
| uses: actions/cache@v3 |
| with: |
| path: ${{ env.CPYTHON_BUILDDIR }}/config.cache |
| key: ${{ github.job }}-${{ runner.os }}-${{ needs.check_source.outputs.config_hash }} |
| - name: Configure CPython out-of-tree |
| working-directory: ${{ env.CPYTHON_BUILDDIR }} |
| run: | |
| ../cpython-ro-srcdir/configure \ |
| --config-cache \ |
| --with-pydebug \ |
| --with-openssl=$OPENSSL_DIR |
| - name: Build CPython out-of-tree |
| working-directory: ${{ env.CPYTHON_BUILDDIR }} |
| run: make -j4 |
| - name: Display build info |
| working-directory: ${{ env.CPYTHON_BUILDDIR }} |
| run: make pythoninfo |
| - name: Remount sources writable for tests |
| # some tests write to srcdir, lack of pyc files slows down testing |
| run: sudo mount $CPYTHON_RO_SRCDIR -oremount,rw |
| - name: Tests |
| working-directory: ${{ env.CPYTHON_BUILDDIR }} |
| run: xvfb-run make buildbottest TESTOPTS="-j4 -uall,-cpu" |
| |
| build_ubuntu_ssltests: |
| name: 'Ubuntu SSL tests with OpenSSL' |
| runs-on: ubuntu-20.04 |
| timeout-minutes: 60 |
| needs: check_source |
| if: needs.check_source.outputs.run_tests == 'true' |
| strategy: |
| fail-fast: false |
| matrix: |
| openssl_ver: [1.1.1t, 3.0.8, 3.1.0-beta1] |
| env: |
| OPENSSL_VER: ${{ matrix.openssl_ver }} |
| MULTISSL_DIR: ${{ github.workspace }}/multissl |
| OPENSSL_DIR: ${{ github.workspace }}/multissl/openssl/${{ matrix.openssl_ver }} |
| LD_LIBRARY_PATH: ${{ github.workspace }}/multissl/openssl/${{ matrix.openssl_ver }}/lib |
| steps: |
| - uses: actions/checkout@v3 |
| - name: Restore config.cache |
| uses: actions/cache@v3 |
| with: |
| path: config.cache |
| key: ${{ github.job }}-${{ runner.os }}-${{ needs.check_source.outputs.config_hash }} |
| - name: Register gcc problem matcher |
| run: echo "::add-matcher::.github/problem-matchers/gcc.json" |
| - name: Install Dependencies |
| run: sudo ./.github/workflows/posix-deps-apt.sh |
| - name: Configure OpenSSL env vars |
| run: | |
| echo "MULTISSL_DIR=${GITHUB_WORKSPACE}/multissl" >> $GITHUB_ENV |
| echo "OPENSSL_DIR=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}" >> $GITHUB_ENV |
| echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}/lib" >> $GITHUB_ENV |
| - name: 'Restore OpenSSL build' |
| id: cache-openssl |
| uses: actions/cache@v3 |
| with: |
| path: ./multissl/openssl/${{ env.OPENSSL_VER }} |
| key: ${{ runner.os }}-multissl-openssl-${{ env.OPENSSL_VER }} |
| - name: Install OpenSSL |
| if: steps.cache-openssl.outputs.cache-hit != 'true' |
| run: python3 Tools/ssl/multissltests.py --steps=library --base-directory $MULTISSL_DIR --openssl $OPENSSL_VER --system Linux |
| - name: Add ccache to PATH |
| run: | |
| echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV |
| - name: Configure ccache action |
| uses: hendrikmuhs/ccache-action@v1.2 |
| - name: Configure CPython |
| run: ./configure --config-cache --with-pydebug --with-openssl=$OPENSSL_DIR |
| - name: Build CPython |
| run: make -j4 |
| - name: Display build info |
| run: make pythoninfo |
| - name: SSL tests |
| run: ./python Lib/test/ssltests.py |
| |
| test_hypothesis: |
| name: "Hypothesis tests on Ubuntu" |
| runs-on: ubuntu-20.04 |
| timeout-minutes: 60 |
| needs: check_source |
| if: needs.check_source.outputs.run_tests == 'true' && needs.check_source.outputs.run_hypothesis == 'true' |
| env: |
| OPENSSL_VER: 1.1.1t |
| PYTHONSTRICTEXTENSIONBUILD: 1 |
| steps: |
| - uses: actions/checkout@v3 |
| - name: Register gcc problem matcher |
| run: echo "::add-matcher::.github/problem-matchers/gcc.json" |
| - name: Install Dependencies |
| run: sudo ./.github/workflows/posix-deps-apt.sh |
| - name: Configure OpenSSL env vars |
| run: | |
| echo "MULTISSL_DIR=${GITHUB_WORKSPACE}/multissl" >> $GITHUB_ENV |
| echo "OPENSSL_DIR=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}" >> $GITHUB_ENV |
| echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}/lib" >> $GITHUB_ENV |
| - name: 'Restore OpenSSL build' |
| id: cache-openssl |
| uses: actions/cache@v3 |
| with: |
| path: ./multissl/openssl/${{ env.OPENSSL_VER }} |
| key: ${{ runner.os }}-multissl-openssl-${{ env.OPENSSL_VER }} |
| - name: Install OpenSSL |
| if: steps.cache-openssl.outputs.cache-hit != 'true' |
| run: python3 Tools/ssl/multissltests.py --steps=library --base-directory $MULTISSL_DIR --openssl $OPENSSL_VER --system Linux |
| - name: Add ccache to PATH |
| run: | |
| echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV |
| - name: Configure ccache action |
| uses: hendrikmuhs/ccache-action@v1.2 |
| - name: Setup directory envs for out-of-tree builds |
| run: | |
| echo "CPYTHON_RO_SRCDIR=$(realpath -m ${GITHUB_WORKSPACE}/../cpython-ro-srcdir)" >> $GITHUB_ENV |
| echo "CPYTHON_BUILDDIR=$(realpath -m ${GITHUB_WORKSPACE}/../cpython-builddir)" >> $GITHUB_ENV |
| - name: Create directories for read-only out-of-tree builds |
| run: mkdir -p $CPYTHON_RO_SRCDIR $CPYTHON_BUILDDIR |
| - name: Bind mount sources read-only |
| run: sudo mount --bind -o ro $GITHUB_WORKSPACE $CPYTHON_RO_SRCDIR |
| - name: Restore config.cache |
| uses: actions/cache@v3 |
| with: |
| path: ${{ env.CPYTHON_BUILDDIR }}/config.cache |
| key: ${{ github.job }}-${{ runner.os }}-${{ needs.check_source.outputs.config_hash }} |
| - name: Configure CPython out-of-tree |
| working-directory: ${{ env.CPYTHON_BUILDDIR }} |
| run: | |
| ../cpython-ro-srcdir/configure \ |
| --config-cache \ |
| --with-pydebug \ |
| --with-openssl=$OPENSSL_DIR |
| - name: Build CPython out-of-tree |
| working-directory: ${{ env.CPYTHON_BUILDDIR }} |
| run: make -j4 |
| - name: Display build info |
| working-directory: ${{ env.CPYTHON_BUILDDIR }} |
| run: make pythoninfo |
| - name: Remount sources writable for tests |
| # some tests write to srcdir, lack of pyc files slows down testing |
| run: sudo mount $CPYTHON_RO_SRCDIR -oremount,rw |
| - name: Setup directory envs for out-of-tree builds |
| run: | |
| echo "CPYTHON_BUILDDIR=$(realpath -m ${GITHUB_WORKSPACE}/../cpython-builddir)" >> $GITHUB_ENV |
| - name: "Create hypothesis venv" |
| working-directory: ${{ env.CPYTHON_BUILDDIR }} |
| run: | |
| VENV_LOC=$(realpath -m .)/hypovenv |
| VENV_PYTHON=$VENV_LOC/bin/python |
| echo "HYPOVENV=${VENV_LOC}" >> $GITHUB_ENV |
| echo "VENV_PYTHON=${VENV_PYTHON}" >> $GITHUB_ENV |
| ./python -m venv $VENV_LOC && $VENV_PYTHON -m pip install -U hypothesis |
| - name: 'Restore Hypothesis database' |
| id: cache-hypothesis-database |
| uses: actions/cache@v3 |
| with: |
| path: ./hypothesis |
| key: hypothesis-database-${{ github.head_ref || github.run_id }} |
| restore-keys: | |
| - hypothesis-database- |
| - name: "Run tests" |
| working-directory: ${{ env.CPYTHON_BUILDDIR }} |
| run: | |
| # Most of the excluded tests are slow test suites with no property tests |
| # |
| # (GH-104097) test_sysconfig is skipped because it has tests that are |
| # failing when executed from inside a virtual environment. |
| ${{ env.VENV_PYTHON }} -m test \ |
| -W \ |
| -o \ |
| -j4 \ |
| -x test_asyncio \ |
| -x test_multiprocessing_fork \ |
| -x test_multiprocessing_forkserver \ |
| -x test_multiprocessing_spawn \ |
| -x test_concurrent_futures \ |
| -x test_socket \ |
| -x test_subprocess \ |
| -x test_signal \ |
| -x test_sysconfig |
| - uses: actions/upload-artifact@v3 |
| if: always() |
| with: |
| name: hypothesis-example-db |
| path: .hypothesis/examples/ |
| |
| |
| build_asan: |
| name: 'Address sanitizer' |
| runs-on: ubuntu-20.04 |
| timeout-minutes: 60 |
| needs: check_source |
| if: needs.check_source.outputs.run_tests == 'true' |
| env: |
| OPENSSL_VER: 1.1.1t |
| PYTHONSTRICTEXTENSIONBUILD: 1 |
| ASAN_OPTIONS: detect_leaks=0:allocator_may_return_null=1:handle_segv=0 |
| steps: |
| - uses: actions/checkout@v3 |
| - name: Restore config.cache |
| uses: actions/cache@v3 |
| with: |
| path: config.cache |
| key: ${{ github.job }}-${{ runner.os }}-${{ needs.check_source.outputs.config_hash }} |
| - name: Register gcc problem matcher |
| run: echo "::add-matcher::.github/problem-matchers/gcc.json" |
| - name: Install Dependencies |
| run: sudo ./.github/workflows/posix-deps-apt.sh |
| - name: Set up GCC-10 for ASAN |
| uses: egor-tensin/setup-gcc@v1 |
| with: |
| version: 10 |
| - name: Configure OpenSSL env vars |
| run: | |
| echo "MULTISSL_DIR=${GITHUB_WORKSPACE}/multissl" >> $GITHUB_ENV |
| echo "OPENSSL_DIR=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}" >> $GITHUB_ENV |
| echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}/lib" >> $GITHUB_ENV |
| - name: 'Restore OpenSSL build' |
| id: cache-openssl |
| uses: actions/cache@v3 |
| with: |
| path: ./multissl/openssl/${{ env.OPENSSL_VER }} |
| key: ${{ runner.os }}-multissl-openssl-${{ env.OPENSSL_VER }} |
| - name: Install OpenSSL |
| if: steps.cache-openssl.outputs.cache-hit != 'true' |
| run: python3 Tools/ssl/multissltests.py --steps=library --base-directory $MULTISSL_DIR --openssl $OPENSSL_VER --system Linux |
| - name: Add ccache to PATH |
| run: | |
| echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV |
| - name: Configure ccache action |
| uses: hendrikmuhs/ccache-action@v1.2 |
| - name: Configure CPython |
| run: ./configure --config-cache --with-address-sanitizer --without-pymalloc |
| - name: Build CPython |
| run: make -j4 |
| - name: Display build info |
| run: make pythoninfo |
| - name: Tests |
| run: xvfb-run make buildbottest TESTOPTS="-j4 -uall,-cpu" |