From 15e1a041ddd6bdbc6dc30b350e16c864f8d4c334 Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Thu, 12 Aug 2010 22:08:56 -0700 Subject: Make IpcDaemonTestCase demonstrate an EbuildIpcDaemon based replacement for EBUILD_EXIT_STATUS_FILE. --- bin/ebuild-ipc.py | 17 +++++---- pym/_emerge/EbuildIpcDaemon.py | 20 +++++------ pym/portage/tests/ebuild/test_ipc_daemon.py | 53 +++++++++++++++++++++++------ 3 files changed, 60 insertions(+), 30 deletions(-) diff --git a/bin/ebuild-ipc.py b/bin/ebuild-ipc.py index 2edd66559..761e07a2a 100755 --- a/bin/ebuild-ipc.py +++ b/bin/ebuild-ipc.py @@ -51,18 +51,17 @@ class EbuildIpc(object): output_file.flush() events = select.select([input_file], [], []) - if input_file in events[0]: - reply = pickle.load(input_file) - else: - reply = None - + reply = pickle.load(input_file) output_file.close() input_file.close() - if reply == 'OK': - rval = os.EX_OK - else: - rval = 1 + (out, err, rval) = reply + + if out: + portage.util.writemsg_stdout(out, noiselevel=-1) + + if err: + portage.util.writemsg(out, noiselevel=-1) return rval diff --git a/pym/_emerge/EbuildIpcDaemon.py b/pym/_emerge/EbuildIpcDaemon.py index 48f58224b..2f4d8933c 100644 --- a/pym/_emerge/EbuildIpcDaemon.py +++ b/pym/_emerge/EbuildIpcDaemon.py @@ -24,7 +24,7 @@ class EbuildIpcDaemon(FifoIpcDaemon): left orphan processes running in the backgraound (as in bug 278895). """ - __slots__ = () + __slots__ = ('commands',) def _input_handler(self, fd, event): @@ -38,15 +38,15 @@ class EbuildIpcDaemon(FifoIpcDaemon): if buf: obj = pickle.loads(buf.tostring()) - if isinstance(obj, list) and \ - obj and \ - obj[0] == 'exit': - output_fd = os.open(self.output_fifo, os.O_WRONLY|os.O_NONBLOCK) - output_file = os.fdopen(output_fd, 'wb') - pickle.dump('OK', output_file) - output_file.close() - self._unregister() - self.wait() + cmd_key = obj[0] + cmd_handler = self.commands[cmd_key] + cmd_handler(obj, self._send_reply) self._unregister_if_appropriate(event) return self._registered + + def _send_reply(self, reply): + output_fd = os.open(self.output_fifo, os.O_WRONLY|os.O_NONBLOCK) + output_file = os.fdopen(output_fd, 'wb') + pickle.dump(reply, output_file) + output_file.close() diff --git a/pym/portage/tests/ebuild/test_ipc_daemon.py b/pym/portage/tests/ebuild/test_ipc_daemon.py index 488bd3999..bd27a38d1 100644 --- a/pym/portage/tests/ebuild/test_ipc_daemon.py +++ b/pym/portage/tests/ebuild/test_ipc_daemon.py @@ -12,6 +12,28 @@ from _emerge.SpawnProcess import SpawnProcess from _emerge.EbuildIpcDaemon import EbuildIpcDaemon from _emerge.TaskScheduler import TaskScheduler +class ExitCommand(object): + + def __init__(self): + self.callback = None + self.exitcode = None + + def __call__(self, argv, send_reply): + duplicate = False + if self.exitcode is not None: + # Ignore all but the first call, since if die is called + # then we certainly want to honor that exitcode, even + # the ebuild process manages to send a second exit + # command. + duplicate = True + else: + self.exitcode = int(argv[1]) + + # (stdout, stderr, returncode) + send_reply(('', '', 0)) + if not duplicate and self.callback is not None: + self.callback() + class IpcDaemonTestCase(TestCase): def testIpcDaemon(self): @@ -25,16 +47,25 @@ class IpcDaemonTestCase(TestCase): output_fifo = os.path.join(tmpdir, '.ipc_out') os.mkfifo(input_fifo) os.mkfifo(output_fifo) - task_scheduler = TaskScheduler(max_jobs=2) - daemon = EbuildIpcDaemon(input_fifo=input_fifo, - output_fifo=output_fifo, - scheduler=task_scheduler.sched_iface) - proc = SpawnProcess( - args=[BASH_BINARY, "-c", '"$PORTAGE_BIN_PATH"/ebuild-ipc exit 0'], - env=env, scheduler=task_scheduler.sched_iface) - task_scheduler.add(daemon) - task_scheduler.add(proc) - task_scheduler.run() - self.assertEqual(proc.returncode, os.EX_OK) + for exitcode in (0, 1, 2): + task_scheduler = TaskScheduler(max_jobs=2) + exit_command = ExitCommand() + commands = {'exit' : exit_command} + daemon = EbuildIpcDaemon(commands=commands, + input_fifo=input_fifo, + output_fifo=output_fifo, + scheduler=task_scheduler.sched_iface) + proc = SpawnProcess( + args=[BASH_BINARY, "-c", + '"$PORTAGE_BIN_PATH"/ebuild-ipc exit %d' % exitcode], + env=env, scheduler=task_scheduler.sched_iface) + def exit_command_callback(): + daemon.cancel() + proc.cancel() + exit_command.callback = exit_command_callback + task_scheduler.add(daemon) + task_scheduler.add(proc) + task_scheduler.run() + self.assertEqual(exit_command.exitcode, exitcode) finally: shutil.rmtree(tmpdir) -- cgit v1.2.3-1-g7c22