blob: 907901eb3909316a2070a29e1fb53ef639b397a9 [file] [log] [blame]
Chris Sosa47a7d4e2012-03-28 11:26:55 -07001#!/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 11:26:55 -07009import subprocess
Chris Sosa101fd862012-06-12 17:44:53 -070010import time
Chris Sosa47a7d4e2012-03-28 11:26:55 -070011import unittest
12
Gilad Arnoldabb352e2012-09-23 01:24:27 -070013import mox
14
Chris Sosa47a7d4e2012-03-28 11:26:55 -070015import gsutil_util
16
17
Chris Sosa76e44b92013-01-31 12:11:38 -080018# pylint: disable=W0212
Chris Sosa47a7d4e2012-03-28 11:26:55 -070019class 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 11:26:55 -070028
29 def _CallRunGS(self, str_should_contain, attempts=1):
30 """Helper that wraps a RunGS for tests."""
31 for attempt in range(attempts):
32 if attempt == gsutil_util.GSUTIL_ATTEMPTS:
33 # We can't mock more than we can attempt.
34 return
35
36 # Return 1's for all but last attempt.
37 if attempt != attempts - 1:
38 mock_process = self._bad_mock_process
39 else:
40 mock_process = self._good_mock_process
41
Chris Sosa6de29302013-03-14 15:27:36 -070042 subprocess.Popen(mox.StrContains(str_should_contain),
43 shell=True, stdout=subprocess.PIPE,
44 stderr=subprocess.PIPE).AndReturn(mock_process)
Chris Sosa47a7d4e2012-03-28 11:26:55 -070045 mock_process.communicate().AndReturn(('Does not matter', None))
46
47 def testDownloadFromGS(self):
48 """Tests that we can run download build from gs with one error."""
Chris Sosa76e44b92013-01-31 12:11:38 -080049 self.mox.StubOutWithMock(time, 'sleep')
50 time.sleep(mox.IgnoreArg()).MultipleTimes()
Chris Sosa47a7d4e2012-03-28 11:26:55 -070051 self.mox.StubOutWithMock(subprocess, 'Popen', use_mock_anything=True)
52
53 # Make sure we our retry works.
54 self._CallRunGS('from to', attempts=2)
55 self.mox.ReplayAll()
56 gsutil_util.DownloadFromGS('from', 'to')
57 self.mox.VerifyAll()
58
59 def testDownloadFromGSButGSDown(self):
60 """Tests that we fail correctly if we can't reach GS."""
Chris Sosa76e44b92013-01-31 12:11:38 -080061 self.mox.StubOutWithMock(time, 'sleep')
62 time.sleep(mox.IgnoreArg()).MultipleTimes()
Chris Sosa47a7d4e2012-03-28 11:26:55 -070063 self.mox.StubOutWithMock(subprocess, 'Popen', use_mock_anything=True)
64 self._CallRunGS('from to', attempts=gsutil_util.GSUTIL_ATTEMPTS + 1)
65
66 self.mox.ReplayAll()
67 self.assertRaises(
68 gsutil_util.GSUtilError,
69 gsutil_util.DownloadFromGS,
70 'from', 'to')
71 self.mox.VerifyAll()
72
Chris Sosa76e44b92013-01-31 12:11:38 -080073 def testGetGSNamesWithWait(self):
74 """Test that we get the target artifact that is available."""
75 archive_url = ('gs://chromeos-image-archive/x86-mario-release/'
76 'R17-1413.0.0-a1-b1346')
77 name = 'chromeos_R17-1413.0.0-a1_x86-mario_full_dev.bin'
Gilad Arnold950569b2013-08-27 14:38:01 -070078 pattern = '*_full_*'
Chris Sosa76e44b92013-01-31 12:11:38 -080079 mock_data = 'mock data\nmock_data\nmock_data'
80 msg = 'UNIT TEST'
81
82 self.mox.StubOutWithMock(gsutil_util, 'GSUtilRun')
Chris Sosa76e44b92013-01-31 12:11:38 -080083
84 # GSUtil cat gs://archive_url_prefix/UPLOADED.
85 gsutil_util.GSUtilRun(mox.StrContains(gsutil_util.UPLOADED_LIST),
Gilad Arnold950569b2013-08-27 14:38:01 -070086 mox.IgnoreArg()).AndReturn(
87 '%s\n%s' % (mock_data, name))
Chris Sosa76e44b92013-01-31 12:11:38 -080088
89 self.mox.ReplayAll()
Chris Sosa6de29302013-03-14 15:27:36 -070090 # Timeout explicitly set to 0 to test that we always run at least once.
Chris Sosa76e44b92013-01-31 12:11:38 -080091 returned_names = gsutil_util.GetGSNamesWithWait(
Chris Sosa6de29302013-03-14 15:27:36 -070092 pattern, archive_url, msg, delay=1, timeout=0)
Chris Sosa76e44b92013-01-31 12:11:38 -080093 self.assertEqual([name], returned_names)
94 self.mox.VerifyAll()
95
Gilad Arnoldc703c8c2013-08-29 10:41:27 -070096 def testGetGSNamesWithWaitWithDirectStat(self):
97 """We should directly stat an artifact whose name is fully spelled out."""
98 archive_url = ('gs://chromeos-image-archive/x86-mario-release/'
99 'R17-1413.0.0-a1-b1346')
100 name = 'chromeos_R17-1413.0.0-a1_x86-mario_full_dev.bin'
101 pattern = 'chromeos_R17-1413.0.0-a1_x86-mario_full_dev.bin'
102 mock_data = 'mock data\nmock_data\nmock_data'
103 msg = 'UNIT TEST'
104
105 self.mox.StubOutWithMock(gsutil_util, 'GSUtilRun')
106
107 # GSUtil cat gs://archive_url_prefix/UPLOADED.
Chris Sosa6317e9a2013-09-06 16:43:44 -0700108 gsutil_util.GSUtilRun(mox.StrContains('gsutil du %s/%s' %
Gilad Arnoldc703c8c2013-08-29 10:41:27 -0700109 (archive_url, pattern)),
110 mox.IgnoreArg()).AndReturn(
111 '%s\n%s' % (mock_data, name))
112
113 self.mox.ReplayAll()
114 # Timeout explicitly set to 0 to test that we always run at least once.
115 returned_names = gsutil_util.GetGSNamesWithWait(
116 pattern, archive_url, msg, delay=1, timeout=0)
117 self.assertEqual([name], returned_names)
118 self.mox.VerifyAll()
119
Chris Sosa76e44b92013-01-31 12:11:38 -0800120 def testGetGSNamesWithWaitWithRetry(self):
121 """Test that we can poll until all target artifacts are available."""
122 archive_url = ('gs://chromeos-image-archive/x86-mario-release/'
123 'R17-1413.0.0-a1-b1346')
124 name = 'chromeos_R17-1413.0.0-a1_x86-mario_full_dev.bin'
Gilad Arnold950569b2013-08-27 14:38:01 -0700125 pattern = '*_full_*'
Chris Sosa76e44b92013-01-31 12:11:38 -0800126 mock_data = 'mock data\nmock_data\nmock_data'
127 msg = 'UNIT TEST'
128
129 self.mox.StubOutWithMock(gsutil_util, 'GSUtilRun')
Chris Sosa76e44b92013-01-31 12:11:38 -0800130
131 # GSUtil cat gs://archive_url_prefix/UPLOADED.
132 gsutil_util.GSUtilRun(mox.StrContains(gsutil_util.UPLOADED_LIST),
133 mox.IgnoreArg()).AndReturn(mock_data)
Chris Sosa76e44b92013-01-31 12:11:38 -0800134
135 gsutil_util.GSUtilRun(mox.StrContains(gsutil_util.UPLOADED_LIST),
Gilad Arnold950569b2013-08-27 14:38:01 -0700136 mox.IgnoreArg()).AndReturn(
137 '%s\n%s' % (mock_data, name))
Chris Sosa76e44b92013-01-31 12:11:38 -0800138
139 self.mox.ReplayAll()
140 returned_names = gsutil_util.GetGSNamesWithWait(
Chris Sosa6de29302013-03-14 15:27:36 -0700141 pattern, archive_url, msg, delay=1, timeout=3)
Chris Sosa76e44b92013-01-31 12:11:38 -0800142 self.assertEqual(name, returned_names[0])
143 self.mox.VerifyAll()
144
145 def testGetGSNamesWithWaitTimeout(self):
146 """Test that we wait for the target artifacts until timeout occurs."""
147 archive_url = ('gs://chromeos-image-archive/x86-mario-release/'
148 'R17-1413.0.0-a1-b1346')
Gilad Arnold950569b2013-08-27 14:38:01 -0700149 pattern = '*_full_*'
Chris Sosa76e44b92013-01-31 12:11:38 -0800150 mock_data = 'mock data\nmock_data\nmock_data'
151 msg = 'UNIT TEST'
152
153 self.mox.StubOutWithMock(gsutil_util, 'GSUtilRun')
Chris Sosa76e44b92013-01-31 12:11:38 -0800154
155 # GSUtil cat gs://archive_url_prefix/UPLOADED.
156 gsutil_util.GSUtilRun(mox.StrContains(gsutil_util.UPLOADED_LIST),
157 mox.IgnoreArg()).AndReturn(mock_data)
Chris Sosa76e44b92013-01-31 12:11:38 -0800158
159 self.mox.ReplayAll()
160 returned_name = gsutil_util.GetGSNamesWithWait(
161 pattern, archive_url, msg, delay=2, timeout=1)
162 self.assertEqual(returned_name, None)
163 self.mox.VerifyAll()
164
joychenf8f07e22013-07-12 17:45:51 -0700165 def testGetLatestVersionFromGSDir(self):
166 """Test that we can get the most recent version from gsutil calls."""
167 self.mox.StubOutWithMock(gsutil_util, 'GSUtilRun')
168 mock_data1 = '''gs://chromeos-releases/stable-channel/parrot/3701.96.0/
169 gs://chromeos-releases/stable-channel/parrot/3701.98.0/
170 gs://chromeos-releases/stable-channel/parrot/3912.100.0/
171 gs://chromeos-releases/stable-channel/parrot/3912.101.0/
172 gs://chromeos-releases/stable-channel/parrot/3912.79.0/
173 gs://chromeos-releases/stable-channel/parrot/3912.79.1/'''
174 gsutil_util.GSUtilRun(mox.IgnoreArg(),
175 mox.IgnoreArg()).AndReturn(mock_data1)
176 mock_data2 = '''gs://chromeos-image-archive/parrot-release/R28-3912.101.0/a
177 gs://chromeos-image-archive/parrot-release/R28-3912.101.0/image.zip
178 gs://chromeos-image-archive/parrot-release/R28-3912.101.0/index.html
179 gs://chromeos-image-archive/parrot-release/R28-3912.101.0/metadata.json
180 gs://chromeos-image-archive/parrot-release/R28-3912.101.0/stateful.tgz'''
181 gsutil_util.GSUtilRun(mox.IgnoreArg(),
182 mox.IgnoreArg()).AndReturn(mock_data2)
183 self.mox.ReplayAll()
184 url = ''
Gilad Arnold950569b2013-08-27 14:38:01 -0700185 self.assertEqual(
186 gsutil_util.GetLatestVersionFromGSDir(url, with_release=False),
187 '3912.101.0')
188 self.assertEqual(
189 gsutil_util.GetLatestVersionFromGSDir(url, with_release=True),
190 'R28-3912.101.0')
joychenf8f07e22013-07-12 17:45:51 -0700191 self.mox.VerifyAll()
Chris Sosa47a7d4e2012-03-28 11:26:55 -0700192
193if __name__ == '__main__':
194 unittest.main()