Skip to content
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

gh-127432: Add CI test for cross-builds #127447

Closed
Closed
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
44 changes: 44 additions & 0 deletions .github/workflows/cross-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Cross-Builds

on:
push:
branches:
- main
pull_request:
branches:
- main

jobs:
cross-build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.x'

- name: Install dependencies
run: sudo apt-get install -y build-essential

- name: Build host Python
run: |
./configure --prefix=$PWD/workdir/host-python
make -j4
make install

- name: Configure cross-build
run: |
./configure --with-build-python=$PWD/workdir/host-python/bin/python --prefix=$PWD/workdir/cross-python
make -j4

- name: Run tests in build directory
run: ./python -m test test_sysconfig test_site test_embed

- name: Install cross-build
run: make install

- name: Run tests with installed Python
run: $PWD/workdir/cross-python/bin/python -m test test_sysconfig test_site test_embed
35 changes: 35 additions & 0 deletions .github/workflows/jit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,38 @@ jobs:
- name: Run tests
run: |
./python -m test --multiprocess 0 --timeout 4500 --verbose2 --verbose3

cross-build:
name: Cross-Builds
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.x'

- name: Install dependencies
run: sudo apt-get install -y build-essential

- name: Build host Python
run: |
./configure --prefix=$PWD/workdir/host-python
make -j4
make install

- name: Configure cross-build
run: |
./configure --with-build-python=$PWD/workdir/host-python/bin/python --prefix=$PWD/workdir/cross-python
make -j4

- name: Run tests in build directory
run: ./python -m test test_sysconfig test_site test_embed

- name: Install cross-build
run: make install

- name: Run tests with installed Python
run: $PWD/workdir/cross-python/bin/python -m test test_sysconfig test_site test_embed
36 changes: 36 additions & 0 deletions Lib/test/test_dependencies.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import unittest
import os
import sys

class TestDependencies(unittest.TestCase):

def test_pyvenv_cfg_exists(self):
venv_path = os.path.join(sys.prefix, 'pyvenv.cfg')
self.assertTrue(os.path.exists(venv_path), f"{venv_path} does not exist")

def test_shared_memory_access(self):
try:
import multiprocessing.shared_memory
except ImportError:
self.fail("multiprocessing.shared_memory module is not available")

def test_ssl_module(self):
try:
import ssl
except ImportError:
self.fail("ssl module is not available")

def test_pdb_module(self):
try:
import pdb
except ImportError:
self.fail("pdb module is not available")

def test_warnings_module(self):
try:
import warnings
except ImportError:
self.fail("warnings module is not available")

if __name__ == '__main__':
unittest.main()
24 changes: 24 additions & 0 deletions Lib/test/test_embed.py
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,30 @@ def test_getargs_reset_static_parser(self):
out, err = self.run_embedded_interpreter("test_repeated_init_exec", code)
self.assertEqual(out, '1\n2\n3\n' * INIT_LOOPS)

def test_cross_build(self):
# Build a host Python
host_build_dir = tempfile.mkdtemp()
host_install_dir = os.path.join(host_build_dir, 'host-python')
subprocess.run(['./configure', f'--prefix={host_install_dir}'], check=True)
subprocess.run(['make', 'install'], check=True)

# Configure a new build using --with-build-python
cross_build_dir = tempfile.mkdtemp()
cross_install_dir = os.path.join(cross_build_dir, 'cross-python')
build_python = os.path.join(host_install_dir, 'bin', 'python')
subprocess.run(['./configure', f'--with-build-python={build_python}', f'--prefix={cross_install_dir}'], check=True)
subprocess.run(['make'], check=True)

# Run the tests in the build directory
subprocess.run([os.path.join(cross_build_dir, 'python'), '-m', 'test', 'test_sysconfig', 'test_site', 'test_embed'], check=True)

# Install the cross-build
subprocess.run(['make', 'install'], check=True)

# Run the tests again with the installed Python
installed_python = os.path.join(cross_install_dir, 'bin', 'python')
subprocess.run([installed_python, '-m', 'test', 'test_sysconfig', 'test_site', 'test_embed'], check=True)


def config_dev_mode(preconfig, config):
preconfig['allocator'] = PYMEM_ALLOCATOR_DEBUG
Expand Down
48 changes: 48 additions & 0 deletions Lib/test/test_multiprocessing_forkserver.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import unittest
import multiprocessing
import os
import signal
import time

class TestForkserver(unittest.TestCase):

def setUp(self):
self.manager = multiprocessing.Manager()
self.shared_dict = self.manager.dict()

def tearDown(self):
self.manager.shutdown()

def test_shared_memory_access(self):
def worker(shared_dict):
shared_dict['key'] = 'value'

process = multiprocessing.Process(target=worker, args=(self.shared_dict,))
process.start()
process.join()

self.assertEqual(self.shared_dict['key'], 'value')

def test_forkserver_process_return_code(self):
def worker():
os._exit(1)

process = multiprocessing.Process(target=worker)
process.start()
process.join()

self.assertEqual(process.exitcode, 1)

def test_forkserver_signal_handling(self):
def worker():
time.sleep(5)

process = multiprocessing.Process(target=worker)
process.start()
os.kill(process.pid, signal.SIGTERM)
process.join()

self.assertEqual(process.exitcode, -signal.SIGTERM)

if __name__ == '__main__':
unittest.main()
Loading