Bug 789496 - DeviceManagerSUT: always consume prompt after receiving agent warning. r=wlach
authorMark Cote <mcote@mozilla.com>
Mon, 10 Sep 2012 11:33:11 -0400
changeset 108309 5b4cd3e706fd78661cf9896b4652e5d46b898432
parent 108308 d2001c2c36e51b267e31ab1db782f2fa07d582a6
child 108310 cfa4b00ab701e2e915fde71f76553267d2911e59
push idunknown
push userunknown
push dateunknown
reviewerswlach
bugs789496
milestone18.0a1
Bug 789496 - DeviceManagerSUT: always consume prompt after receiving agent warning. r=wlach
testing/mozbase/mozdevice/mozdevice/devicemanagerSUT.py
testing/mozbase/mozdevice/tests/sut.py
--- a/testing/mozbase/mozdevice/mozdevice/devicemanagerSUT.py
+++ b/testing/mozbase/mozdevice/mozdevice/devicemanagerSUT.py
@@ -204,16 +204,17 @@ class DeviceManagerSUT(DeviceManager):
       # Check if the command should close the socket
       shouldCloseSocket = self._shouldCmdCloseSocket(cmd['cmd'])
 
       # Handle responses from commands
       if (self._cmdNeedsResponse(cmd['cmd'])):
         found = False
         loopguard = 0
         data = ""
+        commandFailed = False
 
         while (found == False and (loopguard < recvGuard)):
           temp = ''
           if (self.debug >= 4): print "recv'ing..."
 
           # Get our response
           try:
              # Wait up to a second for socket to become ready for reading...
@@ -227,20 +228,22 @@ class DeviceManagerSUT(DeviceManager):
             if err[0] == errno.ECONNRESET:
               raise AgentError("Automation error: Error receiving data from socket (possible reboot). cmd=%s; err=%s" % (cmd, err))
             raise AgentError("Error receiving data from socket. cmd=%s; err=%s" % (cmd, err))
 
           data += temp
 
           # If something goes wrong in the agent it will send back a string that
           # starts with '##AGENT-WARNING##'
-          errorMatch = self.agentErrorRE.match(data)
-          if errorMatch:
-            raise AgentError("Agent Error processing command '%s'; err='%s'" %
-                             (cmd['cmd'], errorMatch.group(1)), fatal=True)
+          if not commandFailed:
+            errorMatch = self.agentErrorRE.match(data)
+            if errorMatch:
+              # We still need to consume the prompt, so raise an error after
+              # draining the rest of the buffer.
+              commandFailed = True
 
           for line in data.splitlines():
             if promptre.match(line):
               found = True
               data = self._stripPrompt(data)
               break
 
           # periodically flush data to output file to make sure it doesn't get
@@ -249,16 +252,20 @@ class DeviceManagerSUT(DeviceManager):
               outputfile.write(data[0:1024])
               data = data[1024:]
 
           # If we violently lose the connection to the device, this loop tends to spin,
           # this guard prevents that
           if (temp == ''):
             loopguard += 1
 
+        if commandFailed:
+          raise AgentError("Agent Error processing command '%s'; err='%s'" %
+                           (cmd['cmd'], errorMatch.group(1)), fatal=True)
+
         # Write any remaining data to outputfile
         outputfile.write(data)
 
     if shouldCloseSocket:
       try:
         self._sock.close()
         self._sock = None
       except:
--- a/testing/mozbase/mozdevice/tests/sut.py
+++ b/testing/mozbase/mozdevice/tests/sut.py
@@ -6,41 +6,59 @@
 import socket
 import mozdevice
 from threading import Thread
 import unittest
 
 class BasicTest(unittest.TestCase):
 
     def _serve_thread(self):
-        need_connection = True
+        conn, addr = self._sock.accept()
+        conn.send("$>\x00")
         while self.commands:
             (command, response) = self.commands.pop(0)
-            if need_connection:
-                conn, addr = self._sock.accept()
-                need_connection = False
-            conn.send("$>\x00")
             data = conn.recv(1024).strip()
             self.assertEqual(data, command)
+            # send response and prompt separately to test for bug 789496
             conn.send("%s\n" % response)
             conn.send("$>\x00")
 
     def _serve(self, commands):
         self.commands = commands
         thread = Thread(target=self._serve_thread)
         thread.start()
         return thread
 
     def test_init(self):
+        """Tests DeviceManager initialization."""
         self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
         self._sock.bind(("127.0.0.1", 0))
         self._sock.listen(1)
 
         thread = self._serve([("testroot", "/mnt/sdcard"),
                               ("cd /mnt/sdcard/tests", ""),
-                              ("cwd", "/mnt/sdcard/tests")])
+                              ("cwd", "/mnt/sdcard/tests"),
+                              ("ver", "SUTAgentAndroid Version XX")])
+        
+        port = self._sock.getsockname()[1]
+        mozdevice.DroidSUT.debug = 4
+        d = mozdevice.DroidSUT("127.0.0.1", port=port)
+        thread.join()
+
+    def test_err(self):
+        """Tests error handling during initialization."""
+        self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        self._sock.bind(("127.0.0.1", 0))
+        self._sock.listen(1)
+
+        thread = self._serve([("testroot", "/mnt/sdcard"),
+                              ("cd /mnt/sdcard/tests", "##AGENT-WARNING## no such file or directory"),
+                              ("cd /mnt/sdcard/tests", "##AGENT-WARNING## no such file or directory"),
+                              ("mkdr /mnt/sdcard/tests", "/mnt/sdcard/tests successfully created"),
+                              ("ver", "SUTAgentAndroid Version XX")])
 
         port = self._sock.getsockname()[1]
-        d = mozdevice.DroidSUT("127.0.0.1", port=port)
+        mozdevice.DroidSUT.debug = 4
+        dm = mozdevice.DroidSUT("127.0.0.1", port=port)
         thread.join()
 
 if __name__ == '__main__':
     unittest.main()