Set a maximum time for collecting DUT measurements

If the DUT has a stuck finger, or finger reports caused by noise, it may
continue to send measurements indefinitely, causing testing to stall.
This CL adds a maximum time for collecting measurements from the DUT to
prevent stalling.

BUG=b:148627899
TEST=Perform tests with and without manually adding a "stuck" finger to
the DUT. Works as expected.

Change-Id: If761b15a6fc5e67bc650143bd848ba5ac81a0f48
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/optofidelity_TPPT/+/2714062
Commit-Queue: Sean O'Brien <seobrien@chromium.org>
Tested-by: Sean O'Brien <seobrien@chromium.org>
Reviewed-by: Harry Cutts <hcutts@chromium.org>
diff --git a/TPPTcommon/Measurement/Base.py b/TPPTcommon/Measurement/Base.py
index f425aad..6df59bc 100644
--- a/TPPTcommon/Measurement/Base.py
+++ b/TPPTcommon/Measurement/Base.py
@@ -80,15 +80,17 @@
         self.results = None
         self.thread = Thread(target=self._thread_main)
 
-    def start(self, timeout=0.5, start_timeout=6.0):
+    def start(self, timeout=0.5, start_timeout=6.0, max_time=60.0):
         '''
         Start continuous measurement in a separate thread.
         :param timeout: Timeout in seconds between consecutive measurements.
         :param start_timeout: Timeout in seconds for the first measurement.
+        :param max_time: Maximum time in seconds to spend, even if new measurements are coming in.
         '''
 
         self.timeout = timeout
         self.start_timeout = start_timeout
+        self.max_time = max_time
         self.results = []
 
         self._start()
diff --git a/TPPTcommon/Measurement/DeviceSocket.py b/TPPTcommon/Measurement/DeviceSocket.py
index 0837cd6..b618a38 100644
--- a/TPPTcommon/Measurement/DeviceSocket.py
+++ b/TPPTcommon/Measurement/DeviceSocket.py
@@ -20,7 +20,11 @@
 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 """
 from .Base import *
+import logging
 import queue
+import time
+
+logger = logging.getLogger(__name__)
 
 class TapMeasurementDeviceSocket(TapMeasurement):
     '''
@@ -56,6 +60,7 @@
 
     def _read_results(self):
         try:
+            start_time = time.time()
             # Read first event with timeout that should be sufficiently long for effector to reach DUT surface.
             item = self.dsock.queue.get(timeout=self.start_timeout)
             self.dsock.queue.task_done()
@@ -68,5 +73,8 @@
             # Read events until timeout is exceeded
             for touch in self.dsock.CLine(timeout=self.timeout):
                 self.results.append(touch)
+                if time.time() - start_time > self.max_time:
+                    logger.warn("Measurement time exceeded {} seconds. Stopping measurement.".format(self.max_time))
+                    return
         except queue.Empty:
             pass # There was no event reported within timeout. This ends the measurement.
\ No newline at end of file