blob: 3071825a03776818a2d9608cde5afe14300e05c8 [file] [log] [blame]
Chris Sosa47a7d4e2012-03-28 18:26:551#!/usr/bin/python
2#
3# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7"""Unit tests for gsutil_util module."""
8
Chris Sosa47a7d4e2012-03-28 18:26:559import subprocess
Chris Sosa101fd862012-06-13 00:44:5310import time
Chris Sosa47a7d4e2012-03-28 18:26:5511import unittest
12
Gilad Arnoldabb352e2012-09-23 08:24:2713import mox
14
Chris Sosa47a7d4e2012-03-28 18:26:5515import gsutil_util
16
17
Chris Sosa76e44b92013-01-31 20:11:3818# pylint: disable=W0212
Chris Sosa47a7d4e2012-03-28 18:26:5519class GSUtilUtilTest(mox.MoxTestBase):
20
21 def setUp(self):
22 mox.MoxTestBase.setUp(self)
23
24 self._good_mock_process = self.mox.CreateMock(subprocess.Popen)
25 self._good_mock_process.returncode = 0
26 self._bad_mock_process = self.mox.CreateMock(subprocess.Popen)
27 self._bad_mock_process.returncode = 1
Chris Sosa47a7d4e2012-03-28 18:26:5528
Gilad Arnold2136ce12013-11-15 20:05:3629 self._gs_run_setup = False
30
Chris Sosa47a7d4e2012-03-28 18:26:5531 def _CallRunGS(self, str_should_contain, attempts=1):
32 """Helper that wraps a RunGS for tests."""
Gilad Arnold2136ce12013-11-15 20:05:3633 # Setup necessary stubs for gsutil invocation (just once).
34 if not self._gs_run_setup:
35 self._gs_run_setup = True
36 self.mox.StubOutWithMock(subprocess, 'Popen', use_mock_anything=True)
37 # Sleep only occurs if we expect to have multiple retry attempts.
38 if min(attempts, gsutil_util.GSUTIL_ATTEMPTS) > 1:
39 self.mox.StubOutWithMock(time, 'sleep')
40 time.sleep(mox.IgnoreArg()).MultipleTimes()
41
Chris Sosa47a7d4e2012-03-28 18:26:5542 for attempt in range(attempts):
43 if attempt == gsutil_util.GSUTIL_ATTEMPTS:
44 # We can't mock more than we can attempt.
45 return
46
47 # Return 1's for all but last attempt.
48 if attempt != attempts - 1:
49 mock_process = self._bad_mock_process
50 else:
51 mock_process = self._good_mock_process
52
Chris Sosa6de29302013-03-14 22:27:3653 subprocess.Popen(mox.StrContains(str_should_contain),
54 shell=True, stdout=subprocess.PIPE,
55 stderr=subprocess.PIPE).AndReturn(mock_process)
Chris Sosa47a7d4e2012-03-28 18:26:5556 mock_process.communicate().AndReturn(('Does not matter', None))
57
58 def testDownloadFromGS(self):
59 """Tests that we can run download build from gs with one error."""
Gilad Arnold2136ce12013-11-15 20:05:3660 # Make sure our retry works (but only if actually configured).
61 self._CallRunGS('from to',
62 attempts=min(2, gsutil_util.GSUTIL_ATTEMPTS))
Chris Sosa47a7d4e2012-03-28 18:26:5563 self.mox.ReplayAll()
64 gsutil_util.DownloadFromGS('from', 'to')
65 self.mox.VerifyAll()
66
67 def testDownloadFromGSButGSDown(self):
68 """Tests that we fail correctly if we can't reach GS."""
Chris Sosa47a7d4e2012-03-28 18:26:5569 self._CallRunGS('from to', attempts=gsutil_util.GSUTIL_ATTEMPTS + 1)
Chris Sosa47a7d4e2012-03-28 18:26:5570 self.mox.ReplayAll()
71 self.assertRaises(
72 gsutil_util.GSUtilError,
73 gsutil_util.DownloadFromGS,
74 'from', 'to')
75 self.mox.VerifyAll()
76
Chris Sosa76e44b92013-01-31 20:11:3877 def testGetGSNamesWithWait(self):
78 """Test that we get the target artifact that is available."""
79 archive_url = ('gs://chromeos-image-archive/x86-mario-release/'
80 'R17-1413.0.0-a1-b1346')
81 name = 'chromeos_R17-1413.0.0-a1_x86-mario_full_dev.bin'
Gilad Arnold950569b2013-08-27 21:38:0182 pattern = '*_full_*'
Chris Sosa76e44b92013-01-31 20:11:3883 mock_data = 'mock data\nmock_data\nmock_data'
84 msg = 'UNIT TEST'
85
86 self.mox.StubOutWithMock(gsutil_util, 'GSUtilRun')
Chris Sosa76e44b92013-01-31 20:11:3887
88 # GSUtil cat gs://archive_url_prefix/UPLOADED.
89 gsutil_util.GSUtilRun(mox.StrContains(gsutil_util.UPLOADED_LIST),
Gilad Arnold950569b2013-08-27 21:38:0190 mox.IgnoreArg()).AndReturn(
91 '%s\n%s' % (mock_data, name))
Chris Sosa76e44b92013-01-31 20:11:3892
93 self.mox.ReplayAll()
Chris Sosa6de29302013-03-14 22:27:3694 # Timeout explicitly set to 0 to test that we always run at least once.
Chris Sosa76e44b92013-01-31 20:11:3895 returned_names = gsutil_util.GetGSNamesWithWait(
Chris Sosa6de29302013-03-14 22:27:3696 pattern, archive_url, msg, delay=1, timeout=0)
Chris Sosa76e44b92013-01-31 20:11:3897 self.assertEqual([name], returned_names)
98 self.mox.VerifyAll()
99
Gilad Arnoldc703c8c2013-08-29 17:41:27100 def testGetGSNamesWithWaitWithDirectStat(self):
101 """We should directly stat an artifact whose name is fully spelled out."""
102 archive_url = ('gs://chromeos-image-archive/x86-mario-release/'
103 'R17-1413.0.0-a1-b1346')
104 name = 'chromeos_R17-1413.0.0-a1_x86-mario_full_dev.bin'
105 pattern = 'chromeos_R17-1413.0.0-a1_x86-mario_full_dev.bin'
106 mock_data = 'mock data\nmock_data\nmock_data'
107 msg = 'UNIT TEST'
108
109 self.mox.StubOutWithMock(gsutil_util, 'GSUtilRun')
110
111 # GSUtil cat gs://archive_url_prefix/UPLOADED.
Yu-Ju Hongc853b6e2014-11-17 23:04:55112 gsutil_util.GSUtilRun(mox.StrContains('gsutil stat %s/%s' %
Gilad Arnoldc703c8c2013-08-29 17:41:27113 (archive_url, pattern)),
114 mox.IgnoreArg()).AndReturn(
115 '%s\n%s' % (mock_data, name))
116
117 self.mox.ReplayAll()
118 # Timeout explicitly set to 0 to test that we always run at least once.
119 returned_names = gsutil_util.GetGSNamesWithWait(
120 pattern, archive_url, msg, delay=1, timeout=0)
121 self.assertEqual([name], returned_names)
122 self.mox.VerifyAll()
123
Chris Sosa76e44b92013-01-31 20:11:38124 def testGetGSNamesWithWaitWithRetry(self):
125 """Test that we can poll until all target artifacts are available."""
126 archive_url = ('gs://chromeos-image-archive/x86-mario-release/'
127 'R17-1413.0.0-a1-b1346')
128 name = 'chromeos_R17-1413.0.0-a1_x86-mario_full_dev.bin'
Gilad Arnold950569b2013-08-27 21:38:01129 pattern = '*_full_*'
Chris Sosa76e44b92013-01-31 20:11:38130 mock_data = 'mock data\nmock_data\nmock_data'
131 msg = 'UNIT TEST'
132
133 self.mox.StubOutWithMock(gsutil_util, 'GSUtilRun')
Chris Sosa76e44b92013-01-31 20:11:38134
135 # GSUtil cat gs://archive_url_prefix/UPLOADED.
136 gsutil_util.GSUtilRun(mox.StrContains(gsutil_util.UPLOADED_LIST),
137 mox.IgnoreArg()).AndReturn(mock_data)
Chris Sosa76e44b92013-01-31 20:11:38138
139 gsutil_util.GSUtilRun(mox.StrContains(gsutil_util.UPLOADED_LIST),
Gilad Arnold950569b2013-08-27 21:38:01140 mox.IgnoreArg()).AndReturn(
141 '%s\n%s' % (mock_data, name))
Chris Sosa76e44b92013-01-31 20:11:38142
143 self.mox.ReplayAll()
144 returned_names = gsutil_util.GetGSNamesWithWait(
Chris Sosa6de29302013-03-14 22:27:36145 pattern, archive_url, msg, delay=1, timeout=3)
Chris Sosa76e44b92013-01-31 20:11:38146 self.assertEqual(name, returned_names[0])
147 self.mox.VerifyAll()
148
149 def testGetGSNamesWithWaitTimeout(self):
150 """Test that we wait for the target artifacts until timeout occurs."""
151 archive_url = ('gs://chromeos-image-archive/x86-mario-release/'
152 'R17-1413.0.0-a1-b1346')
Gilad Arnold950569b2013-08-27 21:38:01153 pattern = '*_full_*'
Chris Sosa76e44b92013-01-31 20:11:38154 mock_data = 'mock data\nmock_data\nmock_data'
155 msg = 'UNIT TEST'
156
157 self.mox.StubOutWithMock(gsutil_util, 'GSUtilRun')
Chris Sosa76e44b92013-01-31 20:11:38158
159 # GSUtil cat gs://archive_url_prefix/UPLOADED.
160 gsutil_util.GSUtilRun(mox.StrContains(gsutil_util.UPLOADED_LIST),
161 mox.IgnoreArg()).AndReturn(mock_data)
Chris Sosa76e44b92013-01-31 20:11:38162
163 self.mox.ReplayAll()
164 returned_name = gsutil_util.GetGSNamesWithWait(
165 pattern, archive_url, msg, delay=2, timeout=1)
166 self.assertEqual(returned_name, None)
167 self.mox.VerifyAll()
168
joychenf8f07e22013-07-13 00:45:51169 def testGetLatestVersionFromGSDir(self):
170 """Test that we can get the most recent version from gsutil calls."""
171 self.mox.StubOutWithMock(gsutil_util, 'GSUtilRun')
172 mock_data1 = '''gs://chromeos-releases/stable-channel/parrot/3701.96.0/
173 gs://chromeos-releases/stable-channel/parrot/3701.98.0/
174 gs://chromeos-releases/stable-channel/parrot/3912.100.0/
175 gs://chromeos-releases/stable-channel/parrot/3912.101.0/
176 gs://chromeos-releases/stable-channel/parrot/3912.79.0/
177 gs://chromeos-releases/stable-channel/parrot/3912.79.1/'''
178 gsutil_util.GSUtilRun(mox.IgnoreArg(),
179 mox.IgnoreArg()).AndReturn(mock_data1)
180 mock_data2 = '''gs://chromeos-image-archive/parrot-release/R28-3912.101.0/a
181 gs://chromeos-image-archive/parrot-release/R28-3912.101.0/image.zip
182 gs://chromeos-image-archive/parrot-release/R28-3912.101.0/index.html
183 gs://chromeos-image-archive/parrot-release/R28-3912.101.0/metadata.json
184 gs://chromeos-image-archive/parrot-release/R28-3912.101.0/stateful.tgz'''
185 gsutil_util.GSUtilRun(mox.IgnoreArg(),
186 mox.IgnoreArg()).AndReturn(mock_data2)
187 self.mox.ReplayAll()
188 url = ''
Gilad Arnold950569b2013-08-27 21:38:01189 self.assertEqual(
190 gsutil_util.GetLatestVersionFromGSDir(url, with_release=False),
191 '3912.101.0')
192 self.assertEqual(
193 gsutil_util.GetLatestVersionFromGSDir(url, with_release=True),
194 'R28-3912.101.0')
joychenf8f07e22013-07-13 00:45:51195 self.mox.VerifyAll()
Chris Sosa47a7d4e2012-03-28 18:26:55196
197if __name__ == '__main__':
198 unittest.main()