blob: 200972e210204b7ba698e886bb7935c3de6bddf5 [file] [log] [blame]
Frank Farzan37761d12011-12-01 14:29:08 -08001#!/usr/bin/python
2#
Chris Sosa781ba6d2012-04-11 12:44:43 -07003# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Frank Farzan37761d12011-12-01 14:29:08 -08004# 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 devserver_util module."""
8
Chris Sosaea148d92012-03-06 16:22:04 -08009import mox
Frank Farzan37761d12011-12-01 14:29:08 -080010import os
11import shutil
Chris Sosaea148d92012-03-06 16:22:04 -080012import subprocess
Frank Farzan37761d12011-12-01 14:29:08 -080013import tempfile
14import unittest
15
16import devserver_util
Chris Sosa47a7d4e2012-03-28 11:26:55 -070017import downloadable_artifact
18import gsutil_util
Frank Farzan37761d12011-12-01 14:29:08 -080019
20
21# Fake Dev Server Layout:
22TEST_LAYOUT = {
23 'test-board-1': ['R17-1413.0.0-a1-b1346', 'R17-18.0.0-a1-b1346'],
Scott Zawalski16954532012-03-20 15:31:36 -040024 'test-board-2': ['R16-2241.0.0-a0-b2', 'R17-2.0.0-a1-b1346'],
25 'test-board-3': []
Frank Farzan37761d12011-12-01 14:29:08 -080026}
27
28
Chris Sosaea148d92012-03-06 16:22:04 -080029class DevServerUtilTest(mox.MoxTestBase):
Frank Farzan37761d12011-12-01 14:29:08 -080030
31 def setUp(self):
Chris Sosaea148d92012-03-06 16:22:04 -080032 mox.MoxTestBase.setUp(self)
Chris Sosa47a7d4e2012-03-28 11:26:55 -070033 self._static_dir = tempfile.mkdtemp('devserver_util_unittest')
34 self._outside_sandbox_dir = tempfile.mkdtemp('devserver_util_unittest')
35 self._install_dir = tempfile.mkdtemp('devserver_util_unittest')
Frank Farzan37761d12011-12-01 14:29:08 -080036
37 for board, builds in TEST_LAYOUT.iteritems():
38 board_path = os.path.join(self._static_dir, board)
39 os.mkdir(board_path)
40 for build in builds:
41 build_path = os.path.join(board_path, build)
42 os.mkdir(build_path)
43 with open(os.path.join(build_path,
Chris Sosa47a7d4e2012-03-28 11:26:55 -070044 downloadable_artifact.TEST_IMAGE), 'w') as f:
Frank Farzan37761d12011-12-01 14:29:08 -080045 f.write('TEST_IMAGE')
Chris Sosa47a7d4e2012-03-28 11:26:55 -070046 with open(os.path.join(
47 build_path, downloadable_artifact.STATEFUL_UPDATE), 'w') as f:
Frank Farzan37761d12011-12-01 14:29:08 -080048 f.write('STATEFUL_UPDATE')
49 with open(os.path.join(build_path,
Chris Sosa47a7d4e2012-03-28 11:26:55 -070050 downloadable_artifact.ROOT_UPDATE), 'w') as f:
Frank Farzan37761d12011-12-01 14:29:08 -080051 f.write('ROOT_UPDATE')
52 # AU payloads.
53 au_dir = os.path.join(build_path, devserver_util.AU_BASE)
54 nton_dir = os.path.join(au_dir, build + devserver_util.NTON_DIR_SUFFIX)
55 os.makedirs(nton_dir)
56 with open(os.path.join(nton_dir,
Chris Sosa47a7d4e2012-03-28 11:26:55 -070057 downloadable_artifact.ROOT_UPDATE), 'w') as f:
Frank Farzan37761d12011-12-01 14:29:08 -080058 f.write('ROOT_UPDATE')
59 mton_dir = os.path.join(au_dir, build + devserver_util.MTON_DIR_SUFFIX)
60 os.makedirs(mton_dir)
61 with open(os.path.join(mton_dir,
Chris Sosa47a7d4e2012-03-28 11:26:55 -070062 downloadable_artifact.ROOT_UPDATE), 'w') as f:
Frank Farzan37761d12011-12-01 14:29:08 -080063 f.write('ROOT_UPDATE')
64
Chris Sosaea148d92012-03-06 16:22:04 -080065 self._good_mock_process = self.mox.CreateMock(subprocess.Popen)
66 self._good_mock_process.returncode = 0
67 self._bad_mock_process = self.mox.CreateMock(subprocess.Popen)
68 self._bad_mock_process.returncode = 1
69
Frank Farzan37761d12011-12-01 14:29:08 -080070 def tearDown(self):
71 shutil.rmtree(self._static_dir)
72 shutil.rmtree(self._outside_sandbox_dir)
Chris Sosa47a7d4e2012-03-28 11:26:55 -070073 shutil.rmtree(self._install_dir)
Frank Farzan37761d12011-12-01 14:29:08 -080074
75 def testParsePayloadList(self):
Chris Sosa1228a1a2012-05-22 17:12:13 -070076 """Tests we can parse the payload list into urls."""
Frank Farzan37761d12011-12-01 14:29:08 -080077 archive_url_prefix = ('gs://chromeos-image-archive/x86-mario-release/'
Yu-Ju Hong825ddc32012-08-13 18:47:10 -070078 'R17-1413.0.0-a1-b1346')
79 mton_basename = ('chromeos_R17-1412.0.0-a1-b1345_R17-1413.0.0-a1_'
80 'x86-mario_delta_dev.bin')
81 nton_basename = ('chromeos_R17-1413.0.0-a1_R17-1413.0.0-a1_'
82 'x86-mario_delta_dev.bin')
83 full_basename = ('chromeos_R17-1413.0.0-a1_x86-mario_full_dev.bin')
84
85 mton_url = '/'.join([archive_url_prefix, mton_basename])
86 nton_url = '/'.join([archive_url_prefix, nton_basename])
87 full_url = '/'.join([archive_url_prefix, full_basename])
88
Frank Farzan37761d12011-12-01 14:29:08 -080089 full_url_out, nton_url_out, mton_url_out = (
Yu-Ju Hong825ddc32012-08-13 18:47:10 -070090 devserver_util.ParsePayloadList(archive_url_prefix,
91 [full_basename, nton_basename,
92 mton_basename]))
Frank Farzan37761d12011-12-01 14:29:08 -080093 self.assertEqual([full_url, nton_url, mton_url],
94 [full_url_out, nton_url_out, mton_url_out])
95
96 archive_url_prefix = ('gs://chromeos-image-archive/x86-alex_he-release/'
97 'R18-1420.0.0-a1-b541')
Yu-Ju Hong825ddc32012-08-13 18:47:10 -070098
99 mton_basename = ('chromeos_R18-1418.0.0-a1-b54a0_R18-1420.0.0-a1'
100 '_x86-alex_he_delta_dev.bin')
101 nton_basename = ('chromeos_R18-1420.0.0-a1_R18-1420.0.0-a1_'
102 'x86-alex_he_delta_dev.bin')
103 full_basename = ('chromeos_R18-1420.0.0-a1_x86-alex_he_full_dev.bin')
104
105 mton_url = '/'.join([archive_url_prefix, mton_basename])
106 nton_url = '/'.join([archive_url_prefix, nton_basename])
107 full_url = '/'.join([archive_url_prefix, full_basename])
108
Frank Farzan37761d12011-12-01 14:29:08 -0800109 full_url_out, nton_url_out, mton_url_out = (
Yu-Ju Hong825ddc32012-08-13 18:47:10 -0700110 devserver_util.ParsePayloadList(archive_url_prefix,
111 [full_basename, nton_basename,
112 mton_basename]))
Frank Farzan37761d12011-12-01 14:29:08 -0800113 self.assertEqual([full_url, nton_url, mton_url],
114 [full_url_out, nton_url_out, mton_url_out])
115
Chris Sosa1228a1a2012-05-22 17:12:13 -0700116 def testParsePayloadListWithoutDeltas(self):
117 """Tests we can parse the payload list when no delta updates exist."""
118 archive_url_prefix = ('gs://chromeos-image-archive/x86-mario-release/'
Yu-Ju Hong825ddc32012-08-13 18:47:10 -0700119 'R17-1413.0.0-a1-b1346')
120 full_basename = ('chromeos_R17-1413.0.0-a1_x86-mario_full_dev.bin')
121 full_url = '/'.join([archive_url_prefix, full_basename])
Chris Sosa1228a1a2012-05-22 17:12:13 -0700122 full_url_out, nton_url_out, mton_url_out = (
Yu-Ju Hong825ddc32012-08-13 18:47:10 -0700123 devserver_util.ParsePayloadList(archive_url_prefix,
124 [full_basename, '', '']))
Chris Sosa1228a1a2012-05-22 17:12:13 -0700125 self.assertEqual([full_url, None, None],
126 [full_url_out, nton_url_out, mton_url_out])
127
Chris Sosa781ba6d2012-04-11 12:44:43 -0700128 def testParsePartialPayloadList(self):
129 """Tests that we can parse a payload list with missing optional payload."""
130 archive_url_prefix = ('gs://chromeos-image-archive/x86-mario-release/'
131 'R17-1413.0.0-a1-b1346/')
Yu-Ju Hong825ddc32012-08-13 18:47:10 -0700132 nton_basename = ('chromeos_R17-1413.0.0-a1_R17-1413.0.0-a1_x86-'
133 'mario_delta_dev.bin')
134 full_basename = ('chromeos_R17-1413.0.0-a1_x86-mario_full_dev.bin')
135
136 nton_url = '/'.join([archive_url_prefix, nton_basename])
137 full_url = '/'.join([archive_url_prefix, full_basename])
138
Chris Sosa781ba6d2012-04-11 12:44:43 -0700139 full_url_out, nton_url_out, mton_url_out = (
Yu-Ju Hong825ddc32012-08-13 18:47:10 -0700140 devserver_util.ParsePayloadList(archive_url_prefix,
141 [full_basename, nton_basename]))
Chris Sosa781ba6d2012-04-11 12:44:43 -0700142 self.assertEqual([full_url, nton_url, None],
143 [full_url_out, nton_url_out, mton_url_out])
144
Frank Farzan37761d12011-12-01 14:29:08 -0800145 def testInstallBuild(self):
Simon Glassf5019de2012-03-20 12:14:41 -0700146 # TODO(frankf): Implement this test
147 # self.fail('Not implemented.')
148 pass
Frank Farzan37761d12011-12-01 14:29:08 -0800149
150 def testPrepareAutotestPkgs(self):
Simon Glassf5019de2012-03-20 12:14:41 -0700151 # TODO(frankf): Implement this test
152 # self.fail('Not implemented.')
Scott Zawalski16954532012-03-20 15:31:36 -0400153 # TODO: implement
Simon Glassf5019de2012-03-20 12:14:41 -0700154 pass
Frank Farzan37761d12011-12-01 14:29:08 -0800155
156 def testSafeSandboxAccess(self):
157 # Path is in sandbox.
158 self.assertTrue(
159 devserver_util.SafeSandboxAccess(
160 self._static_dir, os.path.join(self._static_dir, 'some-board')))
161
162 # Path is sandbox.
163 self.assertFalse(
164 devserver_util.SafeSandboxAccess(self._static_dir, self._static_dir))
165
166 # Path is outside the sandbox.
167 self.assertFalse(
168 devserver_util.SafeSandboxAccess(self._static_dir,
169 self._outside_sandbox_dir))
170
171 # Path contains '..'.
172 self.assertFalse(
173 devserver_util.SafeSandboxAccess(
174 self._static_dir, os.path.join(self._static_dir, os.pardir)))
175
176 # Path contains symbolic link references.
177 os.chdir(self._static_dir)
178 os.symlink(os.pardir, 'parent')
179 self.assertFalse(
180 devserver_util.SafeSandboxAccess(
181 self._static_dir, os.path.join(self._static_dir, os.pardir)))
182
183 def testAcquireReleaseLocks(self):
Gilad Arnold5174ca22012-09-12 10:49:09 -0700184 # Successful lock and unlock, removing the newly created directory.
Frank Farzan37761d12011-12-01 14:29:08 -0800185 lock_file = devserver_util.AcquireLock(self._static_dir, 'test-lock')
186 self.assertTrue(os.path.exists(lock_file))
Gilad Arnold5174ca22012-09-12 10:49:09 -0700187 devserver_util.ReleaseLock(self._static_dir, 'test-lock',
188 destroy=True)
Frank Farzan37761d12011-12-01 14:29:08 -0800189 self.assertFalse(os.path.exists(lock_file))
190
Gilad Arnold5174ca22012-09-12 10:49:09 -0700191 # Attempt to freshly create and lock an existing directory.
192 devserver_util.AcquireLock(self._static_dir, 'test-lock')
193 devserver_util.ReleaseLock(self._static_dir, 'test-lock')
194 self.assertRaises(devserver_util.DevServerUtilError,
195 devserver_util.AcquireLock, self._static_dir, 'test-lock')
196 devserver_util.AcquireLock(self._static_dir, 'test-lock', create_once=False)
197 devserver_util.ReleaseLock(self._static_dir, 'test-lock',
198 destroy=True)
199
200 # Sucessfully re-lock a pre-existing directory.
201 devserver_util.AcquireLock(self._static_dir, 'test-lock')
202 devserver_util.ReleaseLock(self._static_dir, 'test-lock')
203 devserver_util.AcquireLock(self._static_dir, 'test-lock',
204 create_once=False)
205 devserver_util.ReleaseLock(self._static_dir, 'test-lock',
206 destroy=True)
207
208 # Attempt to lock an already locked directory.
Frank Farzan37761d12011-12-01 14:29:08 -0800209 devserver_util.AcquireLock(self._static_dir, 'test-lock')
210 self.assertRaises(devserver_util.DevServerUtilError,
211 devserver_util.AcquireLock, self._static_dir, 'test-lock')
Gilad Arnold5174ca22012-09-12 10:49:09 -0700212 devserver_util.ReleaseLock(self._static_dir, 'test-lock',
213 destroy=True)
Frank Farzan37761d12011-12-01 14:29:08 -0800214
215 def testFindMatchingBoards(self):
216 for key in TEST_LAYOUT:
217 # Partial match with multiple boards.
218 self.assertEqual(
219 set(devserver_util.FindMatchingBoards(self._static_dir, key[:-5])),
220 set(TEST_LAYOUT.keys()))
221
222 # Absolute match.
223 self.assertEqual(
224 devserver_util.FindMatchingBoards(self._static_dir, key), [key])
225
226 # Invalid partial match.
227 self.assertEqual(
228 devserver_util.FindMatchingBoards(self._static_dir, 'asdfsadf'), [])
229
230 def testFindMatchingBuilds(self):
231 # Try a partial board and build match with single match.
232 self.assertEqual(
233 devserver_util.FindMatchingBuilds(self._static_dir, 'test-board',
234 'R17-1413'),
235 [('test-board-1', 'R17-1413.0.0-a1-b1346')])
236
237 # Try a partial board and build match with multiple match.
238 actual = set(devserver_util.FindMatchingBuilds(
239 self._static_dir, 'test-board', 'R17'))
240 expected = set([('test-board-1', 'R17-1413.0.0-a1-b1346'),
241 ('test-board-1', 'R17-18.0.0-a1-b1346'),
242 ('test-board-2', 'R17-2.0.0-a1-b1346')])
243 self.assertEqual(actual, expected)
244
245 def testGetLatestBuildVersion(self):
246 self.assertEqual(
247 devserver_util.GetLatestBuildVersion(self._static_dir, 'test-board-1'),
248 'R17-1413.0.0-a1-b1346')
249
Scott Zawalski16954532012-03-20 15:31:36 -0400250 def testGetLatestBuildVersionLatest(self):
251 """Test that we raise DevServerUtilError when a build dir is empty."""
252 self.assertRaises(devserver_util.DevServerUtilError,
253 devserver_util.GetLatestBuildVersion,
254 self._static_dir, 'test-board-3')
Frank Farzan37761d12011-12-01 14:29:08 -0800255
Scott Zawalski16954532012-03-20 15:31:36 -0400256 def testGetLatestBuildVersionUnknownBuild(self):
257 """Test that we raise DevServerUtilError when a build dir does not exist."""
258 self.assertRaises(devserver_util.DevServerUtilError,
259 devserver_util.GetLatestBuildVersion,
260 self._static_dir, 'bad-dir')
Frank Farzan37761d12011-12-01 14:29:08 -0800261
Scott Zawalski16954532012-03-20 15:31:36 -0400262 def testGetLatestBuildVersionMilestone(self):
263 """Test that we can get builds based on milestone."""
264 expected_build_str = 'R16-2241.0.0-a0-b2'
265 milestone = 'R16'
266 build_str = devserver_util.GetLatestBuildVersion(
267 self._static_dir, 'test-board-2', milestone)
268 self.assertEqual(expected_build_str, build_str)
Frank Farzan37761d12011-12-01 14:29:08 -0800269
270 def testCloneBuild(self):
271 test_prefix = 'abc'
272 test_tag = test_prefix + '/123'
273 abc_path = os.path.join(self._static_dir, devserver_util.DEV_BUILD_PREFIX,
274 test_tag)
275
276 os.mkdir(os.path.join(self._static_dir, test_prefix))
277
278 # Verify leaf path is created and proper values returned.
279 board, builds = TEST_LAYOUT.items()[0]
280 dev_build = devserver_util.CloneBuild(self._static_dir, board, builds[0],
281 test_tag)
282 self.assertEquals(dev_build, abc_path)
283 self.assertTrue(os.path.exists(abc_path))
284 self.assertTrue(os.path.isfile(os.path.join(
Chris Sosa47a7d4e2012-03-28 11:26:55 -0700285 abc_path, downloadable_artifact.TEST_IMAGE)))
Frank Farzan37761d12011-12-01 14:29:08 -0800286 self.assertTrue(os.path.isfile(os.path.join(
Chris Sosa47a7d4e2012-03-28 11:26:55 -0700287 abc_path, downloadable_artifact.ROOT_UPDATE)))
Frank Farzan37761d12011-12-01 14:29:08 -0800288 self.assertTrue(os.path.isfile(os.path.join(
Chris Sosa47a7d4e2012-03-28 11:26:55 -0700289 abc_path, downloadable_artifact.STATEFUL_UPDATE)))
Frank Farzan37761d12011-12-01 14:29:08 -0800290
291 # Verify force properly removes the old directory.
292 junk_path = os.path.join(dev_build, 'junk')
293 with open(junk_path, 'w') as f:
294 f.write('hello!')
295 remote_dir = devserver_util.CloneBuild(
296 self._static_dir, board, builds[0], test_tag, force=True)
297 self.assertEquals(remote_dir, abc_path)
298 self.assertTrue(os.path.exists(abc_path))
299 self.assertTrue(os.path.isfile(os.path.join(
Chris Sosa47a7d4e2012-03-28 11:26:55 -0700300 abc_path, downloadable_artifact.TEST_IMAGE)))
Frank Farzan37761d12011-12-01 14:29:08 -0800301 self.assertTrue(os.path.isfile(os.path.join(
Chris Sosa47a7d4e2012-03-28 11:26:55 -0700302 abc_path, downloadable_artifact.ROOT_UPDATE)))
Frank Farzan37761d12011-12-01 14:29:08 -0800303 self.assertTrue(os.path.isfile(os.path.join(
Chris Sosa47a7d4e2012-03-28 11:26:55 -0700304 abc_path, downloadable_artifact.STATEFUL_UPDATE)))
Frank Farzan37761d12011-12-01 14:29:08 -0800305 self.assertFalse(os.path.exists(junk_path))
306
307 def testGetControlFile(self):
308 control_file_dir = os.path.join(
Chris Sosaea148d92012-03-06 16:22:04 -0800309 self._static_dir, 'test-board-1', 'R17-1413.0.0-a1-b1346', 'autotest',
310 'server', 'site_tests', 'network_VPN')
Frank Farzan37761d12011-12-01 14:29:08 -0800311 os.makedirs(control_file_dir)
312 with open(os.path.join(control_file_dir, 'control'), 'w') as f:
313 f.write('hello!')
314
315 control_content = devserver_util.GetControlFile(
Chris Sosaea148d92012-03-06 16:22:04 -0800316 self._static_dir, 'test-board-1/R17-1413.0.0-a1-b1346',
Frank Farzan37761d12011-12-01 14:29:08 -0800317 os.path.join('server', 'site_tests', 'network_VPN', 'control'))
318 self.assertEqual(control_content, 'hello!')
319
320 def testListAutoupdateTargets(self):
321 for board, builds in TEST_LAYOUT.iteritems():
322 for build in builds:
323 au_targets = devserver_util.ListAutoupdateTargets(self._static_dir,
324 board, build)
325 self.assertEqual(set(au_targets),
326 set([build + devserver_util.NTON_DIR_SUFFIX,
327 build + devserver_util.MTON_DIR_SUFFIX]))
328
Chris Sosa47a7d4e2012-03-28 11:26:55 -0700329 def testGatherArtifactDownloads(self):
330 """Tests that we can gather the correct download requirements."""
331 build = 'R17-1413.0.0-a1-b1346'
332 archive_url_prefix = ('gs://chromeos-image-archive/x86-mario-release/' +
333 build)
Yu-Ju Hong825ddc32012-08-13 18:47:10 -0700334 mock_data = 'mock data\nmock_data'
Chris Sosa47a7d4e2012-03-28 11:26:55 -0700335 payloads = map(lambda x: '/'.join([archive_url_prefix, x]),
336 ['p1', 'p2', 'p3'])
337 expected_payloads = payloads + map(
338 lambda x: '/'.join([archive_url_prefix, x]),
Chris Masone3fe44db2012-05-02 10:50:21 -0700339 [downloadable_artifact.STATEFUL_UPDATE,
Yu-Ju Hong825ddc32012-08-13 18:47:10 -0700340 downloadable_artifact.AUTOTEST_ZIPPED_PACKAGE,
Chris Sosa47a7d4e2012-03-28 11:26:55 -0700341 downloadable_artifact.TEST_SUITES_PACKAGE])
342 self.mox.StubOutWithMock(gsutil_util, 'GSUtilRun')
Yu-Ju Hong825ddc32012-08-13 18:47:10 -0700343 self.mox.StubOutWithMock(devserver_util, 'IsAvailable')
Chris Sosa47a7d4e2012-03-28 11:26:55 -0700344 self.mox.StubOutWithMock(devserver_util, 'ParsePayloadList')
345
Yu-Ju Hong825ddc32012-08-13 18:47:10 -0700346 # GSUtil cat gs://archive_url_prefix/UPLOADED.
347 gsutil_util.GSUtilRun(mox.StrContains(devserver_util.UPLOADED_LIST),
Chris Sosa47a7d4e2012-03-28 11:26:55 -0700348 mox.IgnoreArg()).AndReturn(mock_data)
Yu-Ju Hong825ddc32012-08-13 18:47:10 -0700349 devserver_util.IsAvailable(mox.IgnoreArg(),
350 mock_data.splitlines()).AndReturn(True)
351 devserver_util.ParsePayloadList(archive_url_prefix,
352 mock_data.splitlines()).AndReturn(payloads)
Chris Sosa47a7d4e2012-03-28 11:26:55 -0700353
354 self.mox.ReplayAll()
355 artifacts = devserver_util.GatherArtifactDownloads(
Chris Masone3fe44db2012-05-02 10:50:21 -0700356 self._static_dir, archive_url_prefix, build, self._install_dir)
Chris Sosa47a7d4e2012-03-28 11:26:55 -0700357 for index, artifact in enumerate(artifacts):
358 self.assertEqual(artifact._gs_path, expected_payloads[index])
359 self.assertTrue(artifact._tmp_staging_dir.startswith(self._static_dir))
Chris Sosa47a7d4e2012-03-28 11:26:55 -0700360
361 self.mox.VerifyAll()
362
Chris Sosa781ba6d2012-04-11 12:44:43 -0700363 def testGatherArtifactDownloadsWithoutMton(self):
364 """Gather the correct download requirements without mton delta."""
365 build = 'R17-1413.0.0-a1-b1346'
366 archive_url_prefix = ('gs://chromeos-image-archive/x86-mario-release/' +
367 build)
Yu-Ju Hong825ddc32012-08-13 18:47:10 -0700368 mock_data = 'mock data\nmock_data\nmock_data'
Chris Sosa781ba6d2012-04-11 12:44:43 -0700369 payloads = map(lambda x: '/'.join([archive_url_prefix, x]),
370 ['p1', 'p2'])
371 expected_payloads = payloads + map(
372 lambda x: '/'.join([archive_url_prefix, x]),
Chris Masone3fe44db2012-05-02 10:50:21 -0700373 [downloadable_artifact.STATEFUL_UPDATE,
Yu-Ju Hong825ddc32012-08-13 18:47:10 -0700374 downloadable_artifact.AUTOTEST_ZIPPED_PACKAGE,
Chris Sosa781ba6d2012-04-11 12:44:43 -0700375 downloadable_artifact.TEST_SUITES_PACKAGE])
376 self.mox.StubOutWithMock(gsutil_util, 'GSUtilRun')
Yu-Ju Hong825ddc32012-08-13 18:47:10 -0700377 self.mox.StubOutWithMock(devserver_util, 'IsAvailable')
Chris Sosa781ba6d2012-04-11 12:44:43 -0700378 self.mox.StubOutWithMock(devserver_util, 'ParsePayloadList')
379
Yu-Ju Hong825ddc32012-08-13 18:47:10 -0700380 # GSUtil cat gs://archive_url_prefix/UPLOADED.
381 gsutil_util.GSUtilRun(mox.StrContains(devserver_util.UPLOADED_LIST),
Chris Sosa781ba6d2012-04-11 12:44:43 -0700382 mox.IgnoreArg()).AndReturn(mock_data)
Yu-Ju Hong825ddc32012-08-13 18:47:10 -0700383 devserver_util.IsAvailable(mox.IgnoreArg(),
384 mock_data.splitlines()).AndReturn(True)
385 devserver_util.ParsePayloadList(archive_url_prefix,
386 mock_data.splitlines()
387 ).AndReturn(payloads + [None])
Chris Sosa781ba6d2012-04-11 12:44:43 -0700388
389 self.mox.ReplayAll()
390 artifacts = devserver_util.GatherArtifactDownloads(
Chris Masone3fe44db2012-05-02 10:50:21 -0700391 self._static_dir, archive_url_prefix, build, self._install_dir)
Chris Sosa781ba6d2012-04-11 12:44:43 -0700392 for index, artifact in enumerate(artifacts):
393 self.assertEqual(artifact._gs_path, expected_payloads[index])
394 self.assertTrue(artifact._tmp_staging_dir.startswith(self._static_dir))
Chris Sosa1228a1a2012-05-22 17:12:13 -0700395
396 self.mox.VerifyAll()
397
398 def testGatherArtifactDownloadsWithoutMtonOrNton(self):
399 """Gather the correct download requirements without delta payloads."""
400 build = 'R17-1413.0.0-a1-b1346'
401 archive_url_prefix = ('gs://chromeos-image-archive/x86-mario-release/' +
402 build)
403 mock_data = 'mock data\nmock_data'
Yu-Ju Hong825ddc32012-08-13 18:47:10 -0700404
Chris Sosa1228a1a2012-05-22 17:12:13 -0700405 payloads = map(lambda x: '/'.join([archive_url_prefix, x]),
406 ['p1'])
407 expected_payloads = payloads + map(
408 lambda x: '/'.join([archive_url_prefix, x]),
409 [downloadable_artifact.STATEFUL_UPDATE,
Yu-Ju Hong825ddc32012-08-13 18:47:10 -0700410 downloadable_artifact.AUTOTEST_ZIPPED_PACKAGE,
Chris Sosa1228a1a2012-05-22 17:12:13 -0700411 downloadable_artifact.TEST_SUITES_PACKAGE])
412 self.mox.StubOutWithMock(gsutil_util, 'GSUtilRun')
Yu-Ju Hong825ddc32012-08-13 18:47:10 -0700413 self.mox.StubOutWithMock(devserver_util, 'IsAvailable')
Chris Sosa1228a1a2012-05-22 17:12:13 -0700414 self.mox.StubOutWithMock(devserver_util, 'ParsePayloadList')
415
Yu-Ju Hong825ddc32012-08-13 18:47:10 -0700416 # GSUtil cat gs://archive_url_prefix/UPLOADED.
417 gsutil_util.GSUtilRun(mox.StrContains(devserver_util.UPLOADED_LIST),
Chris Sosa1228a1a2012-05-22 17:12:13 -0700418 mox.IgnoreArg()).AndReturn(mock_data)
Yu-Ju Hong825ddc32012-08-13 18:47:10 -0700419 devserver_util.IsAvailable(mox.IgnoreArg(),
420 mock_data.splitlines()).AndReturn(True)
421 devserver_util.ParsePayloadList(archive_url_prefix,
422 mock_data.splitlines()
423 ).AndReturn(payloads + [None, None])
Chris Sosa1228a1a2012-05-22 17:12:13 -0700424
425 self.mox.ReplayAll()
426 artifacts = devserver_util.GatherArtifactDownloads(
427 self._static_dir, archive_url_prefix, build, self._install_dir)
428 for index, artifact in enumerate(artifacts):
429 self.assertEqual(artifact._gs_path, expected_payloads[index])
430 self.assertTrue(artifact._tmp_staging_dir.startswith(self._static_dir))
Chris Sosa781ba6d2012-04-11 12:44:43 -0700431
432 self.mox.VerifyAll()
433
Chris Masone816e38c2012-05-02 12:22:36 -0700434 def testGatherSymbolArtifactDownloads(self):
435 """Tests that we can find debug symbol artifacts to download."""
436 build = 'R17-1413.0.0-a1-b1346'
437 archive_url_prefix = ('gs://chromeos-image-archive/x86-mario-release/' +
438 build)
Yu-Ju Hong825ddc32012-08-13 18:47:10 -0700439 symbol_url = '/'.join([archive_url_prefix,
440 downloadable_artifact.DEBUG_SYMBOLS])
441 uploaded_list_url = '/'.join([archive_url_prefix,
442 devserver_util.UPLOADED_LIST])
443 mock_data = 'mock-tarball.tgz\nmock-debug.tgz'
Chris Masone816e38c2012-05-02 12:22:36 -0700444 self.mox.StubOutWithMock(gsutil_util, 'GSUtilRun')
Chris Masone816e38c2012-05-02 12:22:36 -0700445
Yu-Ju Hong825ddc32012-08-13 18:47:10 -0700446 # GSUtil cat gs://archive_url_prefix/UPLOADED.
447 gsutil_util.GSUtilRun(mox.StrContains(devserver_util.UPLOADED_LIST),
Chris Masone816e38c2012-05-02 12:22:36 -0700448 mox.IgnoreArg()).AndReturn(mock_data)
449
450 self.mox.ReplayAll()
451 artifacts = devserver_util.GatherSymbolArtifactDownloads(
452 self._static_dir, archive_url_prefix, self._install_dir)
453 for index, artifact in enumerate(artifacts):
454 self.assertEqual(artifact._gs_path, symbol_url)
455 self.assertTrue(artifact._tmp_staging_dir.startswith(self._static_dir))
456
457 self.mox.VerifyAll()
458
Yu-Ju Hong825ddc32012-08-13 18:47:10 -0700459 def testIsAvailable(self):
460 """Test that we can detect whether the target artifacts are avaialble."""
461 # Test when the all target files are available
462 pattern_list = ['_full_', 'autotest.tar']
463 uploaded_list = ['chromeos_R17-1413.0.0-a1_x86-mario_full_dev.bin',
464 'debug.tgz',
465 'autotest.tar.bz2']
466
467 available = devserver_util.IsAvailable(pattern_list, uploaded_list)
468 self.assertTrue(available)
469
470 # Test when some target files are missing
471 pattern_list = ['_full_', 'autotest.tar']
472 uploaded_list = ['chromeos_R17-1413.0.0-a1_x86-mario_full_dev.bin',
473 'debug.tgz']
474
475 available = devserver_util.IsAvailable(pattern_list, uploaded_list)
476 self.assertFalse(available)
477
478 def testWaitUntilAvailable(self):
479 """Test that we can poll until all target artifacts are available."""
Chris Masone816e38c2012-05-02 12:22:36 -0700480 build = 'R17-1413.0.0-a1-b1346'
Yu-Ju Hong825ddc32012-08-13 18:47:10 -0700481 archive_url = ('gs://chromeos-image-archive/x86-mario-release/'
482 'R17-1413.0.0-a1-b1346')
483 to_wait_list = ['_full_']
Chris Masone816e38c2012-05-02 12:22:36 -0700484 mock_data = 'mock data\nmock_data\nmock_data'
Chris Masone816e38c2012-05-02 12:22:36 -0700485
Yu-Ju Hong825ddc32012-08-13 18:47:10 -0700486 self.mox.StubOutWithMock(gsutil_util, 'GSUtilRun')
487 self.mox.StubOutWithMock(devserver_util, 'IsAvailable')
488
489 # GSUtil cat gs://archive_url_prefix/UPLOADED.
490 gsutil_util.GSUtilRun(mox.StrContains(devserver_util.UPLOADED_LIST),
Chris Masone816e38c2012-05-02 12:22:36 -0700491 mox.IgnoreArg()).AndReturn(mock_data)
Yu-Ju Hong825ddc32012-08-13 18:47:10 -0700492 devserver_util.IsAvailable(mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(True)
Chris Masone816e38c2012-05-02 12:22:36 -0700493
494 self.mox.ReplayAll()
Yu-Ju Hong825ddc32012-08-13 18:47:10 -0700495 uploaded_list = devserver_util.WaitUntilAvailable(to_wait_list, archive_url,
496 'UNIT TEST', delay=1)
497 self.assertEqual(uploaded_list, mock_data.splitlines())
Chris Masone816e38c2012-05-02 12:22:36 -0700498 self.mox.VerifyAll()
499
Yu-Ju Hong825ddc32012-08-13 18:47:10 -0700500 def testWaitUntilAvailableWithRetry(self):
501 """Test that we can poll until all target artifacts are available."""
Chris Masone816e38c2012-05-02 12:22:36 -0700502 build = 'R17-1413.0.0-a1-b1346'
Yu-Ju Hong825ddc32012-08-13 18:47:10 -0700503 archive_url = ('gs://chromeos-image-archive/x86-mario-release/'
504 'R17-1413.0.0-a1-b1346')
505 to_wait_list = ['_full_']
506 mock_data = 'mock data\nmock_data\nmock_data'
Chris Masone816e38c2012-05-02 12:22:36 -0700507
Yu-Ju Hong825ddc32012-08-13 18:47:10 -0700508 self.mox.StubOutWithMock(gsutil_util, 'GSUtilRun')
509 self.mox.StubOutWithMock(devserver_util, 'IsAvailable')
510
511 # GSUtil cat gs://archive_url_prefix/UPLOADED.
512 gsutil_util.GSUtilRun(mox.StrContains(devserver_util.UPLOADED_LIST),
513 mox.IgnoreArg()).AndReturn(mock_data)
514 devserver_util.IsAvailable(mox.IgnoreArg(),
515 mox.IgnoreArg()).AndReturn(False)
516
517 gsutil_util.GSUtilRun(mox.StrContains(devserver_util.UPLOADED_LIST),
518 mox.IgnoreArg()).AndReturn(mock_data)
519 devserver_util.IsAvailable(mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(True)
Chris Masone816e38c2012-05-02 12:22:36 -0700520
521 self.mox.ReplayAll()
Yu-Ju Hong825ddc32012-08-13 18:47:10 -0700522 uploaded_list = devserver_util.WaitUntilAvailable(to_wait_list, archive_url,
523 'UNIT TEST', delay=1)
524 self.assertEqual(uploaded_list, mock_data.splitlines())
Chris Masone816e38c2012-05-02 12:22:36 -0700525 self.mox.VerifyAll()
526
Yu-Ju Hong825ddc32012-08-13 18:47:10 -0700527 def testWaitUntilAvailableTimeout(self):
528 """Test that we wait for the target artifacts until timeout occurs."""
529 build = 'R17-1413.0.0-a1-b1346'
530 archive_url = ('gs://chromeos-image-archive/x86-mario-release/'
531 'R17-1413.0.0-a1-b1346')
532 to_wait_list = ['_full_']
533 mock_data = 'mock data\nmock_data\nmock_data'
534
535 self.mox.StubOutWithMock(gsutil_util, 'GSUtilRun')
536 self.mox.StubOutWithMock(devserver_util, 'IsAvailable')
537
538 # GSUtil cat gs://archive_url_prefix/UPLOADED.
539 gsutil_util.GSUtilRun(mox.StrContains(devserver_util.UPLOADED_LIST),
540 mox.IgnoreArg()).AndReturn(mock_data)
541 devserver_util.IsAvailable(mox.IgnoreArg(),
542 mox.IgnoreArg()).AndReturn(False)
543
544 self.mox.ReplayAll()
545 self.assertRaises(devserver_util.DevServerUtilError,
546 devserver_util.WaitUntilAvailable,
547 to_wait_list,
548 archive_url,
549 'UNIT TEST',
550 delay=2,
551 timeout=1)
552 self.mox.VerifyAll()
Frank Farzan37761d12011-12-01 14:29:08 -0800553
554if __name__ == '__main__':
555 unittest.main()