Add support for nosetests multiprocessing plugin.
[sawsim.git] / pysawsim / invoke.py
index bb051d7ad8c36e17090d188dc2763800401a0915..2d8103fab178e6dab14ae1eb298e3e881c89ec23 100644 (file)
@@ -24,15 +24,55 @@ from subprocess import Popen, PIPE
 import sys
 
 
+_multiprocess_can_split_ = True
+"""Allow nosetests to split tests between processes.
+"""
+
+
 class CommandError(Exception):
-    def __init__(self, command, status, stdout, stderr):
-        strerror = ["Command failed (%d):\n  %s\n" % (status, stderr),
-                    "while executing\n  %s" % command]
-        Exception.__init__(self, "\n".join(strerror))
+    """Represent errors in command execution.
+
+    Instances are picklable (for passing through `multiprocessing.Queue`\s).
+
+    >>> import pickle
+    >>> a = CommandError('somefunc', 1, '', 'could not find "somefunc"')
+    >>> x = pickle.dumps(a)
+    >>> b = pickle.loads(x)
+    >>> print b
+    Command failed (1):
+      could not find "somefunc"
+    <BLANKLINE>
+    while executing
+      somefunc
+    >>> print repr(b)  # doctest: +NORMALIZE_WHITESPACE
+    CommandError(command='somefunc', status=1, stdout='',
+                 stderr='could not find "somefunc"')
+    """
+    def __init__(self, command=None, status=None, stdout=None, stderr=None):
         self.command = command
         self.status = status
         self.stdout = stdout
         self.stderr = stderr
+        Exception.__init__(self, self.__str__())
+
+    def __getstate__(self):
+        return self.__dict__
+
+    def __setstate__(self, data):
+        self.__dict__.update(data)
+
+    def __str__(self):
+        return "\n".join([
+                "Command failed (%s):\n  %s\n" % (self.status, self.stderr),
+                "while executing\n  %s" % self.command,
+                ])
+
+    def __repr__(self):
+        return '%s(%s)' % (
+            self.__class__.__name__,
+            ', '.join(['%s=%s' % (attr, repr(getattr(self, attr)))
+                       for attr in ['command', 'status', 'stdout', 'stderr']]))
+
 
 def invoke(cmd_string, stdin=None, expect=(0,), cwd=None, verbose=False):
     """