Skip to content
Draft
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
39 changes: 0 additions & 39 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,6 @@ jobs:
fail-fast: false
matrix:
include:
- tox_env: py27-m_ans-ans2.10
- tox_env: py27-m_ans-ans4

- tox_env: py36-m_ans-ans2.10
- tox_env: py36-m_ans-ans4

- tox_env: py27-m_mtg
- tox_env: py36-m_mtg

Expand Down Expand Up @@ -86,34 +80,6 @@ jobs:
fail-fast: false
matrix:
include:
- tox_env: py311-m_ans-ans2.10
python_version: '3.11'
- tox_env: py311-m_ans-ans3
python_version: '3.11'
- tox_env: py311-m_ans-ans4
python_version: '3.11'
- tox_env: py311-m_ans-ans5
python_version: '3.11'
- tox_env: py313-m_ans-ans6
python_version: '3.13'
- tox_env: py313-m_ans-ans7
python_version: '3.13'
- tox_env: py313-m_ans-ans8
python_version: '3.13'
- tox_env: py314-m_ans-ans9
python_version: '3.14'
- tox_env: py314-m_ans-ans10
python_version: '3.14'
- tox_env: py314-m_ans-ans11
python_version: '3.14'
- tox_env: py314-m_ans-ans12
python_version: '3.14'
- tox_env: py314-m_ans-ans13
python_version: '3.14'

- tox_env: py314-m_ans-ans13-s_lin
python_version: '3.14'

- tox_env: py314-m_mtg
python_version: '3.14'

Expand Down Expand Up @@ -161,11 +127,6 @@ jobs:
fail-fast: false
matrix:
include:
- tox_env: py314-m_lcl-ans13
python_version: '3.14'
- tox_env: py314-m_lcl-ans13-s_lin
python_version: '3.14'

- tox_env: py314-m_mtg
python_version: '3.14'

Expand Down
17 changes: 13 additions & 4 deletions mitogen/parent.py
Original file line number Diff line number Diff line change
Expand Up @@ -1415,7 +1415,6 @@ def __repr__(self):
# W: write side of interpreter stdin.
# r: read side of core_src FD.
# w: write side of core_src FD.
# C: the decompressed core source.

# Final os.close(STDOUT_FILENO) to avoid --py-debug build corrupting stream with
# "[1234 refs]" during exit.
Expand All @@ -1437,8 +1436,17 @@ def _first_stage():
os.environ['ARGV0']=sys.executable
os.execl(sys.executable,sys.executable+'(mitogen:%s)'%sys.argv[2])
os.write(1,'MITO000\n'.encode())
# Read `len(compressed preamble)` bytes sent by our Mitogen parent.
# `select()` handles non-blocking stdin (e.g. sudo + log_output).
# `C` accumulates compressed bytes.
# `c` supports detecting EOF (`<stdin>.read(...) -> b''`).
C=''.encode()
while int(sys.argv[3])-len(C)and select.select([0],[],[]):C+=os.read(0,int(sys.argv[3])-len(C))
c=1
while c and int(sys.argv[3])-len(C)and select.select([0],[],[]):
c=os.read(0,int(sys.argv[3])-len(C))
# Raises `TypeError` if non-blocking read returns `None`
C+=c
# Raises `zlib.error` if compressed preamble is truncated or invalid
C=zlib.decompress(C)
f=os.fdopen(W,'wb',0)
f.write(C)
Expand All @@ -1463,8 +1471,9 @@ def get_python_argv(self):
return [self.options.python_path]

def get_boot_command(self):
source = inspect.getsource(self._first_stage)
source = textwrap.dedent('\n'.join(source.strip().split('\n')[2:]))
lines = inspect.getsourcelines(self._first_stage)[0][2:]
# Remove line comments, leading indentation, trailing newline
source = textwrap.dedent(''.join(s for s in lines if '#' not in s))[:-1]
source = source.replace(' ', ' ')
compressor = zlib.compressobj(
zlib.Z_BEST_COMPRESSION, zlib.DEFLATED, -zlib.MAX_WBITS,
Expand Down
27 changes: 27 additions & 0 deletions tests/first_stage_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,30 @@ def test_valid_syntax(self):
)
finally:
fp.close()

def test_stage(self):
options = mitogen.parent.Options(max_message_size=123)
conn = mitogen.parent.Connection(options, self.router)
conn.context = mitogen.core.Context(None, 123)

proc = subprocess.Popen(
args=conn.get_boot_command(),
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=subprocess.PIPE,
)
stdout, stderr = proc.communicate(conn.get_preamble())

# proc is killed by SIGTERM as the broker kills itself
self.assertEqual(-15, proc.returncode)
expected_stdout_prefix = b("%s\n%s\n%s\n") % (
mitogen.parent.BootstrapProtocol.EC0_MARKER,
mitogen.parent.BootstrapProtocol.EC1_MARKER,
mitogen.parent.BootstrapProtocol.EC2_MARKER,
)
self.assertTrue(
stdout.startswith(expected_stdout_prefix),
"%r not at start of %r" % (expected_stdout_prefix, stdout),
)
self.assertIn(b'shutting down', stdout)
self.assertEqual(b(""), stderr)