Skip to content

Commit 1fca0b7

Browse files
committed
[linear2] fix MuxProcess test fixture and some merge fallout
1 parent e93762b commit 1fca0b7

File tree

3 files changed

+69
-42
lines changed

3 files changed

+69
-42
lines changed

ansible_mitogen/process.py

Lines changed: 49 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -114,14 +114,17 @@ def get_worker_model():
114114
return _worker_model
115115

116116

117-
def get_classic_worker_model():
117+
def get_classic_worker_model(**kwargs):
118118
"""
119119
Return the single :class:`ClassicWorkerModel` instance, constructing it if
120120
necessary.
121121
"""
122122
global _classic_worker_model
123+
assert _classic_worker_model is None or (not kwargs), \
124+
"ClassicWorkerModel kwargs supplied but model already constructed"
125+
123126
if _classic_worker_model is None:
124-
_classic_worker_model = ClassicWorkerModel()
127+
_classic_worker_model = ClassicWorkerModel(**kwargs)
125128
return _classic_worker_model
126129

127130

@@ -417,9 +420,9 @@ def _initialize(self):
417420
For testing, if :data:`False`, don't initialize logging.
418421
"""
419422
common_setup(_init_logging=self._init_logging)
423+
420424
MuxProcess.cls_parent_sock, \
421425
MuxProcess.cls_child_sock = socket.socketpair()
422-
423426
mitogen.core.set_cloexec(MuxProcess.cls_parent_sock.fileno())
424427
mitogen.core.set_cloexec(MuxProcess.cls_child_sock.fileno())
425428

@@ -434,6 +437,28 @@ def _initialize(self):
434437
MuxProcess.cls_child_sock.close()
435438
MuxProcess.cls_child_sock = None
436439

440+
def _test_reset(self):
441+
"""
442+
Used to clean up in unit tests.
443+
"""
444+
# TODO: split this up a bit.
445+
global _classic_worker_model
446+
assert MuxProcess.cls_parent_sock is not None
447+
MuxProcess.cls_parent_sock.close()
448+
MuxProcess.cls_parent_sock = None
449+
self.listener_path = None
450+
self.router = None
451+
self.parent = None
452+
453+
for mux in self._muxes:
454+
pid, status = os.waitpid(mux.pid, 0)
455+
status = mitogen.fork._convert_exit_status(status)
456+
LOG.debug('mux PID %d %s', pid,
457+
mitogen.parent.returncode_to_str(status))
458+
459+
_classic_worker_model = None
460+
set_worker_model(None)
461+
437462
def on_strategy_start(self):
438463
"""
439464
See WorkerModel.on_strategy_start().
@@ -461,22 +486,26 @@ def get_binding(self, inventory_name):
461486
return ClassicBinding(self)
462487

463488
def on_binding_close(self):
464-
if self.broker:
465-
self.broker.shutdown()
466-
self.broker.join()
467-
self.router = None
468-
self.broker = None
489+
if not self.broker:
490+
return
491+
492+
self.broker.shutdown()
493+
self.broker.join()
494+
self.router = None
495+
self.broker = None
496+
self.listener_path = None
497+
self.initialized = False
469498

470-
# #420: Ansible executes "meta" actions in the top-level process,
471-
# meaning "reset_connection" will cause :class:`mitogen.core.Latch`
472-
# FDs to be cached and erroneously shared by children on subsequent
473-
# WorkerProcess forks. To handle that, call on_fork() to ensure any
474-
# shared state is discarded.
475-
# #490: only attempt to clean up when it's known that some
476-
# resources exist to cleanup, otherwise later __del__ double-call
477-
# to close() due to GC at random moment may obliterate an unrelated
478-
# Connection's related resources.
479-
mitogen.fork.on_fork()
499+
# #420: Ansible executes "meta" actions in the top-level process,
500+
# meaning "reset_connection" will cause :class:`mitogen.core.Latch` FDs
501+
# to be cached and erroneously shared by children on subsequent
502+
# WorkerProcess forks. To handle that, call on_fork() to ensure any
503+
# shared state is discarded.
504+
# #490: only attempt to clean up when it's known that some resources
505+
# exist to cleanup, otherwise later __del__ double-call to close() due
506+
# to GC at random moment may obliterate an unrelated Connection's
507+
# related resources.
508+
mitogen.fork.on_fork()
480509

481510

482511
class MuxProcess(object):
@@ -514,28 +543,14 @@ class of problems this worker is intended to avoid.
514543
#: applied to locally executed commands and modules.
515544
cls_original_env = None
516545

517-
#: In both processes, this a list of the temporary UNIX sockets used for
518-
#: forked WorkerProcesses to contact the forked mux processes.
519-
cls_listener_paths = None
520-
521-
@classmethod
522-
def _reset(cls):
523-
"""
524-
Used to clean up in unit tests.
525-
"""
526-
assert cls.worker_sock is not None
527-
cls.worker_sock.close()
528-
cls.worker_sock = None
529-
os.waitpid(cls.worker_pid, 0)
530-
531546
def __init__(self, index):
532547
self.index = index
533548
#: Individual path of this process.
534549
self.path = mitogen.unix.make_socket_path()
535550

536551
def start(self):
537-
pid = os.fork()
538-
if pid:
552+
self.pid = os.fork()
553+
if self.pid:
539554
# Wait for child to boot before continuing.
540555
mitogen.core.io_op(MuxProcess.cls_parent_sock.recv, 1)
541556
return

mitogen/fork.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,19 @@ def handle_child_crash():
121121
os._exit(1)
122122

123123

124+
def _convert_exit_status(status):
125+
"""
126+
Convert a :func:`os.waitpid`-style exit status to a :mod:`subprocess` style
127+
exit status.
128+
"""
129+
if os.WIFEXITED(status):
130+
return os.WEXITSTATUS(status)
131+
elif os.WIFSIGNALED(status):
132+
return -os.WTERMSIG(status)
133+
elif os.WIFSTOPPED(status):
134+
return -os.WSTOPSIG(status)
135+
136+
124137
class Process(mitogen.parent.Process):
125138
def poll(self):
126139
try:
@@ -134,12 +147,7 @@ def poll(self):
134147

135148
if not pid:
136149
return
137-
if os.WIFEXITED(status):
138-
return os.WEXITSTATUS(status)
139-
elif os.WIFSIGNALED(status):
140-
return -os.WTERMSIG(status)
141-
elif os.WIFSTOPPED(status):
142-
return -os.WSTOPSIG(status)
150+
return _convert_exit_status(status)
143151

144152

145153
class Options(mitogen.parent.Options):

tests/ansible/tests/connection_test.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,17 @@ class MuxProcessMixin(object):
2626
@classmethod
2727
def setUpClass(cls):
2828
#mitogen.utils.log_to_file()
29-
ansible_mitogen.process.MuxProcess.start(_init_logging=False)
29+
cls.model = ansible_mitogen.process.get_classic_worker_model(
30+
_init_logging=False
31+
)
32+
ansible_mitogen.process.set_worker_model(cls.model)
33+
cls.model.on_strategy_start()
3034
super(MuxProcessMixin, cls).setUpClass()
3135

3236
@classmethod
3337
def tearDownClass(cls):
38+
cls.model._test_reset()
3439
super(MuxProcessMixin, cls).tearDownClass()
35-
ansible_mitogen.process.MuxProcess._reset()
3640

3741

3842
class ConnectionMixin(MuxProcessMixin):

0 commit comments

Comments
 (0)