class GitDaemon(SimplePlugin): """ Runs git daemon """ command = "git daemon " \ "--export-all " \ "--listen=0.0.0.0 --base-path=%s" def __init__(self, bus, base_path, working_dir): SimplePlugin.__init__(self, bus) self.command = self.command % base_path self.daemon = Executer(self.command, working_dir) self.base_path = base_path self.working_dir = working_dir def start(self): self.daemon.execute() if self.daemon.poll(): self.bus.log('Could not run git daemon, check if you already have a git daemon running at port 9418.') self.bus.log('Detailed problem:\n%s' % self.daemon.result.log) raise SystemExit(1) self.bus.log('Git daemon plugin is running.\n%s' % self.command) self.bus.log('Exporting all repositories under %s' % self.base_path) def stop(self): self.graceful() self.bus.log("Cleaning up GitDaemon's shell executer") del self.daemon def graceful(self): self.bus.log('Killing git daemon, pid %d' % self.daemon.process.pid) kill(self.daemon.process.pid, 9) self.bus.log('git daemon is now dead')
def shell(self, command, base_path=None): executer = Executer(command=command, working_dir=base_path) executer.execute() while not executer.poll(): pass return executer.result.exit_code, executer.result.log
class ShellExecuter(object): def __init__(self, verbose=False): self.start_execute = None self.finish_execute = None self.execute_beat = None self.timed_out = None self.verbose = verbose def log(self, message): if self.verbose: cherrypy.log(message, '[SHELLEXECUTER]') def ellapsed(self, start_time=None, end_time=None): '''The number of milliseconds that this story took to run.''' if start_time is None: return 0 if end_time is None: return time.time() - start_time return end_time - start_time def execute(self, command, base_path, change_dir=True, timeout=None): try: start_time = time.time() self.executer = Executer(command=command, working_dir=base_path) if self.start_execute: self.start_execute(executer=self.executer) self.executer.execute() while not self.executer.poll(): if self.execute_beat: self.execute_beat(executer=self.executer) time.sleep(1) self.log("[%s] - %.2f secs" % (command, self.ellapsed(start_time=start_time))) if timeout and self.ellapsed(start_time=start_time) > timeout: self.executer.process.stop() if self.timed_out: self.timed_out(executer=self.executer) error_message = "\nThe build timed out after %d seconds!!! \n\nLOG: \n%s" % (timeout, self.executer.result.log) return ExecuteResult(command, error_message, 1) log = self.executer.result.log if self.finish_execute: self.finish_execute(executer=self.executer) self.log("[%s] - Finished after %.2f secs" % (command, self.ellapsed(start_time=start_time))) return ExecuteResult(command, log, self.executer.result.exit_code) except Exception, err: error_message = "An error occured while executing command %s: %s" % (command, err) return ExecuteResult(command, error_message, 1)
def test_very_large_commands(): command = "%s -c 'print \"a\" * 1000 * 1000'" % sys.executable executer = Executer(command=command) executer.execute() while not executer.poll(): time.sleep(0.5) expected_str = "a" * 1000 * 1000 expected_str = expected_str + "\n" assert executer.result.log == expected_str, "They differ in length expected %d got %d" % (len(expected_str), len(executer.result.log))
def test_can_perform_ls(): max_loops = 10 executer = Executer(command="ls -la") executer.execute() for i in range(max_loops): if executer.poll(): break time.sleep(0.1) assert executer.result.status == Status.success, \ "Expected status: %s Got: %s" % \ (Status.success, executer.result.status) assert executer.result.log assert executer.result.exit_code == 0
def test_can_read_output_of_a_running_command(): max_loops = 30 executer = Executer(command="ls -la && sleep 4") executer.execute() items_read = 0 for i in range(max_loops): if executer.poll(): break assert executer.result.log, "Expected log to be filled but it was empty." items_read += 1 time.sleep(0.1) assert executer.result.status == Status.success, \ "Expected status: %s Got: %s" % \ (Status.success, executer.result.status) assert items_read > 10, "Expected greater than %s, got %s" % (10, items_read)
def test_can_clone_a_git_repository_and_show_log(): repo_url = "git://github.com/heynemann/pyccuracy.git" executer = Executer(command="rm -rf /tmp/pyccuracy && cd /tmp/ && git clone %s" % repo_url) executer.execute() items_read = 0 while not executer.poll(): print "%d %s" % (items_read, executer.result.log) if executer.result.log: items_read += 1 time.sleep(0.1) print executer.result.log assert executer.result.status == Status.success, \ "Expected status: %s Got: %s" % \ (Status.success, executer.result.status) assert items_read > 10, "Expected greater than %s, got %s" % (10, items_read)
def test_loop_and_show_log(): command = "for i in 1 2 3 4 5 6 7 8 9 10; do echo \"Welcome $i times\" && sleep 1; done" max_loops = 30 executer = Executer(command=command) executer.execute() items_read = 0 for i in range(max_loops): if executer.poll(): break print executer.result.log assert executer.result.log, "Expected log to be filled but it was empty." items_read += 1 time.sleep(1) assert executer.result.status == Status.success, \ "Expected status: %s Got: %s" % \ (Status.success, executer.result.status) assert items_read > 8, "Expected greater than %s, got %s" % (8, items_read)