autotest: Write all logs returned from collect_cros_au to disk.

Since the RPC call returns multiple logs, the caller should write all of
the files returned to disk.

I have also changed the order it is called within auto_update so the logs are
read and saved first before handler_cleanup is called to delete them.
This required me to update the unittest too.

BUG=chromium:709710
TEST=collect_cros_au RPC call
TEST=Tested with and without CL:503616
TEST=dev_server.auto_update()
TEST=dev_server.auto_update(payload_filename=...)

Change-Id: Ie6a5e9de73a1b10e8b0efd7409c88383d3dfc0e9
Reviewed-on: https://chromium-review.googlesource.com/503537
Commit-Ready: David Haddock <dhaddock@chromium.org>
Tested-by: David Haddock <dhaddock@chromium.org>
Reviewed-by: David Haddock <dhaddock@chromium.org>
diff --git a/client/common_lib/cros/dev_server.py b/client/common_lib/cros/dev_server.py
index 8e1c4a6..22aa972 100644
--- a/client/common_lib/cros/dev_server.py
+++ b/client/common_lib/cros/dev_server.py
@@ -1733,9 +1733,24 @@
         write_file = self._get_au_log_filename(
                 log_dir, kwargs['host_name'], kwargs['pid'])
         logging.debug('Saving auto-update logs into %s', write_file)
+
+        try:
+            au_logs = json.loads(response)
+            for k, v in au_logs['host_logs'].items():
+                log_name = '%s_%s_%s' % (k, kwargs['host_name'], kwargs['pid'])
+                log_path = os.path.join(log_dir, log_name)
+                with open(log_path, 'w') as out_log:
+                    out_log.write(v)
+            cros_au_log = au_logs['cros_au_log']
+        except ValueError:
+            logging.debug('collect_cros_au_log response was not json.')
+            cros_au_log = response
+        except:
+          raise DevServerException('Failed to write auto-update hostlogs')
+
         try:
             with open(write_file, 'w') as out_log:
-                out_log.write(response)
+                out_log.write(cros_au_log)
         except:
             raise DevServerException('Failed to write auto-update logs into '
                                      '%s' % write_file)
@@ -2062,13 +2077,6 @@
             else:
                 raised_error, pid = self.wait_for_auto_update_finished(response,
                                                                        **kwargs)
-                # Error happens in _clean_track_log won't be raised. Auto-update
-                # process will be retried.
-                # TODO(xixuan): Change kwargs['host_name'] back to host_name
-                # if crbug.com/651974 is fixed: host_name represents the host
-                # name of the host, and kwargs['host_name'] could be host_name
-                # or the IP of this host.
-                is_clean_success = self.clean_track_log(kwargs['host_name'], pid)
                 # Error happens in _collect_au_log won't be raised. Auto-update
                 # process will be retried.
                 if au_log_dir:
@@ -2076,8 +2084,17 @@
                             kwargs['host_name'], pid, au_log_dir)
                 else:
                     is_collect_success = True
+
+                # Error happens in _clean_track_log won't be raised. Auto-update
+                # process will be retried.
+                # TODO(xixuan): Change kwargs['host_name'] back to host_name
+                # if crbug.com/651974 is fixed: host_name represents the host
+                # name of the host, and kwargs['host_name'] could be host_name
+                # or the IP of this host.
+                is_clean_success = self.clean_track_log(kwargs['host_name'],
+                                                        pid)
                 # If any error is raised previously, log it and retry
-                # auto-update. Otherwise, claim a success CrOS auto-update.
+                # auto-update. Otherwise, claim a successful CrOS auto-update.
                 if not raised_error and is_clean_success and is_collect_success:
                     logging.debug('CrOS auto-update succeed for host %s',
                                   host_name)
diff --git a/client/common_lib/cros/dev_server_unittest.py b/client/common_lib/cros/dev_server_unittest.py
index fab162f..ae1dc10 100755
--- a/client/common_lib/cros/dev_server_unittest.py
+++ b/client/common_lib/cros/dev_server_unittest.py
@@ -447,9 +447,9 @@
         argument2 = mox.And(mox.StrContains(self._HOST),
                             mox.StrContains('get_au_status'))
         argument3 = mox.And(mox.StrContains(self._HOST),
-                            mox.StrContains('handler_cleanup'))
-        argument4 = mox.And(mox.StrContains(self._HOST),
                             mox.StrContains('collect_cros_au_log'))
+        argument4 = mox.And(mox.StrContains(self._HOST),
+                            mox.StrContains('handler_cleanup'))
         argument5 = mox.And(mox.StrContains(self._HOST),
                             mox.StrContains('kill_au_proc'))
 
@@ -487,21 +487,21 @@
                 dev_server.ImageServerBase.run_call(argument2).AndReturn(
                         json.dumps(response2))
 
-        if 'handler_cleanup_error' in kwargs:
-            if kwargs['handler_cleanup_error']:
+        if 'collect_au_log_error' in kwargs:
+            if kwargs['collect_au_log_error']:
                 dev_server.ImageServerBase.run_call(argument3).AndRaise(
                         raised_error)
             else:
-                dev_server.ImageServerBase.run_call(argument3).AndReturn('True')
+                dev_server.ImageServerBase.run_call(argument3).AndReturn('log')
+                os.path.exists(mox.IgnoreArg()).AndReturn(True)
+                self._mockWriteFile()
 
-        if 'collect_au_log_error' in kwargs:
-            if kwargs['collect_au_log_error']:
+        if 'handler_cleanup_error' in kwargs:
+            if kwargs['handler_cleanup_error']:
                 dev_server.ImageServerBase.run_call(argument4).AndRaise(
                         raised_error)
             else:
-                dev_server.ImageServerBase.run_call(argument4).AndReturn('log')
-                os.path.exists(mox.IgnoreArg()).AndReturn(True)
-                self._mockWriteFile()
+                dev_server.ImageServerBase.run_call(argument4).AndReturn('True')
 
         if 'kill_au_proc_error' in kwargs:
             if kwargs['kill_au_proc_error']: