def execute(logger, command, args=None): """Execute a shell command. :param logger: Output from the command will be logged here. :param command: Command to execute, as a string. :param args: Optional list of arguments for `command`. :raises LaunchpadScriptFailure: If the command returns failure. """ command_line = [command] if args is not None: command_line += args description = ' '.join(command_line) logger.debug("Execute: %s", description) # Some of these commands can take a long time. Use CommandSpawner # and friends to provide "live" log output. Simpler ways of running # commands tend to save it all up and then dump it at the end, or # have trouble logging it as neat lines. stderr_logger = OutputLineHandler(logger.info) stdout_logger = OutputLineHandler(logger.debug) receiver = ReturnCodeReceiver() spawner = CommandSpawner() spawner.start( command_line, completion_handler=receiver, stderr_handler=stderr_logger, stdout_handler=stdout_logger) spawner.complete() stdout_logger.finalize() stderr_logger.finalize() if receiver.returncode != 0: raise LaunchpadScriptFailure( "Failure while running command: %s" % description)
def runAptWithArgs(self, apt_config_filename, *args): """Run apt-ftparchive in subprocesses. :raise: AptFTPArchiveFailure if any of the apt-ftparchive commands failed. """ self.log.debug("Filepath: %s" % apt_config_filename) stdout_handler = OutputLineHandler(self.log.debug, "a-f: ") stderr_handler = OutputLineHandler(self.log.info, "a-f: ") base_command = ["apt-ftparchive"] + list(args) + [apt_config_filename] spawner = CommandSpawner() returncodes = {} completion_handler = ReturnCodeReceiver() returncodes['all'] = completion_handler spawner.start( base_command, stdout_handler=stdout_handler, stderr_handler=stderr_handler, completion_handler=completion_handler) spawner.complete() stdout_handler.finalize() stderr_handler.finalize() failures = sorted([ (tag, receiver.returncode) for tag, receiver in returncodes.iteritems() if receiver.returncode != 0]) if len(failures) > 0: by_arch = ["%s (returned %d)" % failure for failure in failures] raise AptFTPArchiveFailure( "Failure(s) from apt-ftparchive: %s" % ", ".join(by_arch))
def test_can_add_multiple_processes(self): spawner = CommandSpawner() first_process = FakeProcess() instrument_spawn(spawner, first_process) spawner.start(["/bin/echo", "1"]) second_process = FakeProcess() instrument_spawn(spawner, second_process) spawner.start(["/bin/echo", "2"]) self.assertContentEqual( [first_process, second_process], spawner.running_processes)
def _makeSpawnerAndProcess(self, returncode=None): """Create a `CommandSpawner` and instrument it with a `FakeProcess`. :return: A tuple of the spawner and the fake process it will "run." """ spawner = CommandSpawner() process = FakeProcess(returncode=returncode) instrument_spawn(spawner, process) return spawner, process
def test_handles_multiple_processes(self): spawner = CommandSpawner() handler = FakeMethod() first_process = FakeProcess(returncode=1) instrument_spawn(spawner, first_process) spawner.start(["/bin/echo", "1"], completion_handler=handler) second_process = FakeProcess(returncode=2) instrument_spawn(spawner, second_process) spawner.start(["/bin/echo", "2"], completion_handler=handler) spawner.complete() self.assertContentEqual([(1, ), (2, )], handler.extract_args())
def runAptWithArgs(self, apt_config_filename, *args): """Run apt-ftparchive in subprocesses. :raise: AptFTPArchiveFailure if any of the apt-ftparchive commands failed. """ self.log.debug("Filepath: %s" % apt_config_filename) stdout_handler = OutputLineHandler(self.log.debug, "a-f: ") stderr_handler = OutputLineHandler(self.log.info, "a-f: ") base_command = ["apt-ftparchive"] + list(args) + [apt_config_filename] spawner = CommandSpawner() returncodes = {} completion_handler = ReturnCodeReceiver() returncodes['all'] = completion_handler spawner.start(base_command, stdout_handler=stdout_handler, stderr_handler=stderr_handler, completion_handler=completion_handler) spawner.complete() stdout_handler.finalize() stderr_handler.finalize() failures = sorted([(tag, receiver.returncode) for tag, receiver in returncodes.iteritems() if receiver.returncode != 0]) if len(failures) > 0: by_arch = ["%s (returned %d)" % failure for failure in failures] raise AptFTPArchiveFailure("Failure(s) from apt-ftparchive: %s" % ", ".join(by_arch))
def execute(logger, command, args=None): """Execute a shell command. :param logger: Output from the command will be logged here. :param command: Command to execute, as a string. :param args: Optional list of arguments for `command`. :raises LaunchpadScriptFailure: If the command returns failure. """ command_line = [command] if args is not None: command_line += args description = ' '.join(command_line) logger.debug("Execute: %s", description) # Some of these commands can take a long time. Use CommandSpawner # and friends to provide "live" log output. Simpler ways of running # commands tend to save it all up and then dump it at the end, or # have trouble logging it as neat lines. stderr_logger = OutputLineHandler(logger.info) stdout_logger = OutputLineHandler(logger.debug) receiver = ReturnCodeReceiver() spawner = CommandSpawner() spawner.start(command_line, completion_handler=receiver, stderr_handler=stderr_logger, stdout_handler=stdout_logger) spawner.complete() stdout_logger.finalize() stderr_logger.finalize() if receiver.returncode != 0: raise LaunchpadScriptFailure("Failure while running command: %s" % description)
def test_can_add_multiple_processes(self): spawner = CommandSpawner() first_process = FakeProcess() instrument_spawn(spawner, first_process) spawner.start(["/bin/echo", "1"]) second_process = FakeProcess() instrument_spawn(spawner, second_process) spawner.start(["/bin/echo", "2"]) self.assertContentEqual([first_process, second_process], spawner.running_processes)
def test_kill_works_with_no_processes(self): spawner = CommandSpawner() spawner.kill() self.assertEqual({}, spawner.running_processes)
def test_completes_with_no_processes(self): spawner = CommandSpawner() spawner.complete() self.assertEqual({}, spawner.running_processes)
def test_starts_out_with_no_processes(self): spawner = CommandSpawner() self.assertEqual({}, spawner.running_processes)
def _makeSpawner(self): """Create a `CommandSpawner`, and make sure it gets cleaned up.""" spawner = CommandSpawner() self.addCleanup(spawner.complete) self.addCleanup(spawner.kill) return spawner