Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(538)

Unified Diff: testing/legion/rpc_methods.py

Issue 1001833005: Update from https://crrev.com/320343 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Supress Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « testing/legion/examples/subprocess/subprocess_test.py ('k') | testing/legion/run_task.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: testing/legion/rpc_methods.py
diff --git a/testing/legion/rpc_methods.py b/testing/legion/rpc_methods.py
index 7f17e2387e38b2e3c1bdd95e86fd031c74486481..1a59f288afde5fb03c1f8fb3d0ebf4fa6de5bae4 100644
--- a/testing/legion/rpc_methods.py
+++ b/testing/legion/rpc_methods.py
@@ -41,6 +41,10 @@ class RPCMethods(object):
logging.info('Echoing %s', message)
return 'echo %s' % str(message)
+ def AbsPath(self, path):
+ """Returns the absolute path."""
+ return os.path.abspath(path)
+
def Quit(self):
"""Call _server.shutdown in another thread.
@@ -58,6 +62,10 @@ class Subprocess(object):
This non-blocking subprocess allows the caller to continue operating while
also able to interact with this subprocess based on a key returned to
the caller at the time of creation.
+
+ Creation args are set via Set* methods called after calling Process but
+ before calling Start. This is due to a limitation of the XML-RPC
+ implementation not supporting keyword arguments.
"""
_processes = {}
@@ -65,23 +73,38 @@ class Subprocess(object):
_creation_lock = threading.Lock()
def __init__(self, cmd):
- self.proc = subprocess42.Popen(cmd, stdout=subprocess42.PIPE,
- stderr=subprocess42.PIPE)
self.stdout = ''
self.stderr = ''
+ self.cmd = cmd
+ self.proc = None
+ self.cwd = None
+ self.verbose = False
+ self.detached = False
self.data_lock = threading.Lock()
- threading.Thread(target=self._run).start()
- def _run(self):
+ def __str__(self):
+ return '%r, cwd=%r, verbose=%r, detached=%r' % (
+ self.cmd, self.cwd, self.verbose, self.detached)
+
+ def _reader(self):
for pipe, data in self.proc.yield_any():
with self.data_lock:
if pipe == 'stdout':
self.stdout += data
+ if self.verbose:
+ sys.stdout.write(data)
else:
self.stderr += data
+ if self.verbose:
+ sys.stderr.write(data)
+
+ @classmethod
+ def KillAll(cls):
+ for key in cls._processes:
+ cls.Kill(key)
@classmethod
- def Popen(cls, cmd):
+ def Process(cls, cmd):
with cls._creation_lock:
key = 'Process%d' % cls._process_next_id
cls._process_next_id += 1
@@ -90,18 +113,50 @@ class Subprocess(object):
cls._processes[key] = process
return key
+ def _Start(self):
+ logging.info('Starting process %s', self)
+ self.proc = subprocess42.Popen(self.cmd, stdout=subprocess42.PIPE,
+ stderr=subprocess42.PIPE,
+ detached=self.detached, cwd=self.cwd)
+ threading.Thread(target=self._reader).start()
+
+ @classmethod
+ def Start(cls, key):
+ cls._processes[key]._Start()
+
+ @classmethod
+ def SetCwd(cls, key, cwd):
+ """Sets the process's cwd."""
+ logging.debug('Setting %s cwd to %s', key, cwd)
+ cls._processes[key].cwd = cwd
+
+ @classmethod
+ def SetDetached(cls, key):
+ """Creates a detached process."""
+ logging.debug('Setting %s to run detached', key)
+ cls._processes[key].detached = True
+
+ @classmethod
+ def SetVerbose(cls, key):
+ """Sets the stdout and stderr to be emitted locally."""
+ logging.debug('Setting %s to be verbose', key)
+ cls._processes[key].verbose = True
+
@classmethod
def Terminate(cls, key):
- logging.debug('Terminating and deleting process %s', key)
- return cls._processes.pop(key).proc.terminate()
+ logging.debug('Terminating process %s', key)
+ cls._processes[key].proc.terminate()
@classmethod
def Kill(cls, key):
- logging.debug('Killing and deleting process %s', key)
- return cls._processes.pop(key).proc.kill()
+ logging.debug('Killing process %s', key)
+ cls._processes[key].proc.kill()
@classmethod
def Delete(cls, key):
+ if cls.GetReturncode(key) is None:
+ logging.warning('Killing %s before deleting it', key)
+ cls.Kill(key)
logging.debug('Deleting process %s', key)
cls._processes.pop(key)
@@ -139,6 +194,14 @@ class Subprocess(object):
return stderr
@classmethod
+ def ReadOutput(cls, key):
+ """Returns the (stdout, stderr) since the last Read* call.
+
+ See ReadStdout for additional details.
+ """
+ return cls.ReadStdout(key), cls.ReadStderr(key)
+
+ @classmethod
def Wait(cls, key):
return cls._processes[key].proc.wait()
« no previous file with comments | « testing/legion/examples/subprocess/subprocess_test.py ('k') | testing/legion/run_task.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698