Re-land "Split up artifacts to download some in the foreground/background.""
This refactors the devserver to place artifacts into their own classes and
enables us to download certain artifacts in the foreground and some in the
background. I also add wait_for_status, an RPC you can call using the same
archive_url to determine whether background artifacts have finished
downloading (a blocking call).
My next change is to modify the dynamic_suite code to do:
Download()
Process Duts
Wait_For_Status
Run tests.
BUG=chromium-os:27285
TEST=Ran all unittests + pylint -- added a whole bunch of tests.
Ran downloader from localhost?downloader and saw artifacts staged correctly.
Change-Id: I14c888dcc08cf4df2719915fe2fe88d52fbcdc62
Reviewed-on: https://gerrit.chromium.org/gerrit/19244
Tested-by: Chris Sosa <sosa@chromium.org>
Reviewed-by: Scott Zawalski <scottz@chromium.org>
Commit-Ready: Chris Sosa <sosa@chromium.org>
diff --git a/gsutil_util_unittest.py b/gsutil_util_unittest.py
new file mode 100755
index 0000000..0813be7
--- /dev/null
+++ b/gsutil_util_unittest.py
@@ -0,0 +1,67 @@
+#!/usr/bin/python
+#
+# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Unit tests for gsutil_util module."""
+
+import mox
+import subprocess
+import unittest
+
+import gsutil_util
+
+
+class GSUtilUtilTest(mox.MoxTestBase):
+
+ def setUp(self):
+ mox.MoxTestBase.setUp(self)
+
+ self._good_mock_process = self.mox.CreateMock(subprocess.Popen)
+ self._good_mock_process.returncode = 0
+ self._bad_mock_process = self.mox.CreateMock(subprocess.Popen)
+ self._bad_mock_process.returncode = 1
+
+ def _CallRunGS(self, str_should_contain, attempts=1):
+ """Helper that wraps a RunGS for tests."""
+ for attempt in range(attempts):
+ if attempt == gsutil_util.GSUTIL_ATTEMPTS:
+ # We can't mock more than we can attempt.
+ return
+
+ # Return 1's for all but last attempt.
+ if attempt != attempts - 1:
+ mock_process = self._bad_mock_process
+ else:
+ mock_process = self._good_mock_process
+
+ subprocess.Popen(mox.StrContains(str_should_contain), shell=True,
+ stdout=subprocess.PIPE).AndReturn(mock_process)
+ mock_process.communicate().AndReturn(('Does not matter', None))
+
+ def testDownloadFromGS(self):
+ """Tests that we can run download build from gs with one error."""
+ self.mox.StubOutWithMock(subprocess, 'Popen', use_mock_anything=True)
+
+ # Make sure we our retry works.
+ self._CallRunGS('from to', attempts=2)
+ self.mox.ReplayAll()
+ gsutil_util.DownloadFromGS('from', 'to')
+ self.mox.VerifyAll()
+
+ def testDownloadFromGSButGSDown(self):
+ """Tests that we fail correctly if we can't reach GS."""
+ self.mox.StubOutWithMock(subprocess, 'Popen', use_mock_anything=True)
+ self._CallRunGS('from to', attempts=gsutil_util.GSUTIL_ATTEMPTS + 1)
+
+ self.mox.ReplayAll()
+ self.assertRaises(
+ gsutil_util.GSUtilError,
+ gsutil_util.DownloadFromGS,
+ 'from', 'to')
+ self.mox.VerifyAll()
+
+
+if __name__ == '__main__':
+ unittest.main()