Don't ignore unexpected exceptions.  Have the mock report the playback errors inline with the other calls.

Signed-off-by: Jean-Marc Eurin <jmeurin@google.com>


git-svn-id: http://test.kernel.org/svn/autotest/trunk@4458 592f7852-d20e-0410-864c-8624ca9c26a4
diff --git a/cli/cli_mock.py b/cli/cli_mock.py
index 7d010f4..c24a375 100644
--- a/cli/cli_mock.py
+++ b/cli/cli_mock.py
@@ -29,7 +29,7 @@
 class cli_unittest(unittest.TestCase):
     def setUp(self):
         super(cli_unittest, self).setUp()
-        self.god = mock.mock_god(debug=CLI_UT_DEBUG)
+        self.god = mock.mock_god(debug=CLI_UT_DEBUG, ut=self)
         self.god.stub_class_method(rpc.afe_comm, 'run')
         self.god.stub_function(sys, 'exit')
 
diff --git a/cli/threads.py b/cli/threads.py
index 7738b0a..eabefca 100644
--- a/cli/threads.py
+++ b/cli/threads.py
@@ -56,7 +56,7 @@
     def _start_threads(self, nthreads):
         """ Start up threads to spawn workers. """
         self.numthreads += nthreads
-        for i in range(nthreads):
+        for i in xrange(nthreads):
             thread = threading.Thread(target=self._new_worker)
             thread.setDaemon(True)
             self.threads.put(thread)
@@ -72,7 +72,7 @@
                 return
             try:
                 self.function(data)
-            except Exception:
-                # We don't want one function that raises to kill everything.
-                # TODO: Maybe keep a list of errors or something?
-                pass
+            except Exception, full_error:
+                # Put a catch all here.
+                print ('Unexpected failure in the thread calling %s: %s' %
+                       (self.function.__name__, full_error))
diff --git a/cli/topic_common.py b/cli/topic_common.py
index 1c8c3d3..958a0b9 100644
--- a/cli/topic_common.py
+++ b/cli/topic_common.py
@@ -59,6 +59,7 @@
 import socket, urllib2
 from autotest_lib.cli import rpc
 from autotest_lib.frontend.afe.json_rpc import proxy
+from autotest_lib.client.common_lib.test_utils import mock
 
 
 # Maps the AFE keys to printable names.
@@ -479,6 +480,8 @@
                                  what_failed=("Timed-out contacting "
                                               "the Autotest server"))
                     raise CliError("Timed-out contacting the Autotest server")
+            except mock.CheckPlaybackError:
+                raise
             except Exception, full_error:
                 # There are various exceptions throwns by JSON,
                 # urllib & httplib, so catch them all.
diff --git a/client/common_lib/test_utils/mock.py b/client/common_lib/test_utils/mock.py
index 7ce93ac..a8afa01 100644
--- a/client/common_lib/test_utils/mock.py
+++ b/client/common_lib/test_utils/mock.py
@@ -1,7 +1,7 @@
 __author__ = "raphtee@google.com (Travis Miller)"
 
 
-import re, collections, StringIO, sys
+import re, collections, StringIO, sys, unittest
 
 
 class StubNotFoundError(Exception):
@@ -269,7 +269,7 @@
 class mock_god:
     NONEXISTENT_ATTRIBUTE = object()
 
-    def __init__(self, debug=False, fail_fast=True):
+    def __init__(self, debug=False, fail_fast=True, ut=None):
         """
         With debug=True, all recorded method calls will be printed as
         they happen.
@@ -282,6 +282,7 @@
         self._stubs = []
         self._debug = debug
         self._fail_fast = fail_fast
+        self._ut = ut
 
 
     def set_fail_fast(self, fail_fast):
@@ -516,10 +517,15 @@
                 print '\nPlayback errors:'
             for error in self.errors:
                 print >> sys.__stdout__, error
+            self._ut.fail('\n'.join(self.errors))
             raise CheckPlaybackError
         elif len(self.recording) != 0:
+            errors = []
             for func_call in self.recording:
-                print >> sys.__stdout__, "%s not called" % (func_call)
+                error = "%s not called" % (func_call,)
+                errors.append(error)
+                print >> sys.__stdout__, error
+            self._ut.fail('\n'.join(errors))
             raise CheckPlaybackError
         self.recording.clear()