cros deploy: install all packages together instead of 1-by-1

If packages have requirements on each other, installing them one at
a time prevents that from ever working.  Rework the loop so we copy
all packages over and then install them in one pass.

This puts more strain on the storage where the packages are staged,
but there's no other solution here than holding the packages all at
once.  If people run into that situation, they'll have to manually
break up the install into multiple cros deploy calls.  This seems
to rarely come up though, so we can wait for someone to notice and
figure out something else instead.

BUG=chromium:1164732
TEST=`cros deploy` with multiple packages still works

Change-Id: I719559774e0800e763aed7429d1e7fa6bc0cc602
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/chromite/+/2657807
Reviewed-by: Mike Frysinger <vapier@chromium.org>
Commit-Queue: Mike Frysinger <vapier@chromium.org>
Tested-by: Mike Frysinger <vapier@chromium.org>
diff --git a/cli/deploy_unittest.py b/cli/deploy_unittest.py
index bb4500e..1126e50 100644
--- a/cli/deploy_unittest.py
+++ b/cli/deploy_unittest.py
@@ -12,6 +12,8 @@
 import os
 import sys
 
+import mock
+
 from chromite.cli import command
 from chromite.cli import deploy
 from chromite.lib import cros_build_lib
@@ -90,8 +92,8 @@
 
 class BrilloDeployOperationFake(deploy.BrilloDeployOperation):
   """Fake for deploy.BrilloDeployOperation."""
-  def __init__(self, pkg_count, emerge, queue):
-    super(BrilloDeployOperationFake, self).__init__(pkg_count, emerge)
+  def __init__(self, emerge, queue):
+    super(BrilloDeployOperationFake, self).__init__(emerge)
     self._queue = queue
 
   def ParseOutput(self, output=None):
@@ -344,7 +346,9 @@
     self.get_packages_paths.assert_called_once_with(
         [package_info.SplitCPV(p) for p in cpvs], True, 'sysroot')
     # Check that deploy._Emerge is called the right number of times.
-    self.assertEqual(self.emerge.call_count, len(packages))
+    self.emerge.assert_called_once_with(mock.ANY, [
+        '/path/to/foo-1.2.3.tbz2', '/path/to/bar-1.2.5.tbz2',
+        '/path/to/foobar-2.0.tbz2'], '/', extra_args=None)
     self.assertEqual(self.unmerge.call_count, 0)
 
   def testDeployEmergeDLC(self):
@@ -390,7 +394,7 @@
     self.get_packages_paths.assert_called_once_with(
         [package_info.SplitCPV(p) for p in cpvs], True, 'sysroot')
     # Check that deploy._Emerge is called the right number of times.
-    self.assertEqual(self.emerge.call_count, len(packages))
+    self.assertEqual(self.emerge.call_count, 1)
     self.assertEqual(self.unmerge.call_count, 0)
 
     self.assertEqual(self.device.device.cmds,
@@ -459,7 +463,7 @@
 
     queue = multiprocessing.Queue()
     # Emerge one package.
-    op = BrilloDeployOperationFake(1, True, queue)
+    op = BrilloDeployOperationFake(True, queue)
 
     with self.OutputCapturer():
       op.Run(func, queue)
@@ -477,7 +481,7 @@
 
     queue = multiprocessing.Queue()
     # Unmerge one package.
-    op = BrilloDeployOperationFake(1, False, queue)
+    op = BrilloDeployOperationFake(False, queue)
 
     with self.OutputCapturer():
       op.Run(func, queue)