blob: 5fe7e1537a9b6a7e9c9cf4e61afe7aaea8f27ee8 [file] [log] [blame]
xixuan44b55452016-09-06 15:35:56 -07001#!/usr/bin/env python2
joychen3cb228e2013-06-12 12:13:13 -07002
3# Copyright (c) 2013 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 xbuddy.py."""
8
Gilad Arnold5f46d8e2015-02-19 12:17:55 -08009from __future__ import print_function
10
Gilad Arnold896c6d82015-03-13 16:20:29 -070011import ConfigParser
joychen3cb228e2013-06-12 12:13:13 -070012import os
13import shutil
joychen921e1fb2013-06-28 11:12:20 -070014import tempfile
joychen3cb228e2013-06-12 12:13:13 -070015import time
16import unittest
17
18import mox
19
20import xbuddy
21
xixuan44b55452016-09-06 15:35:56 -070022# Make sure that chromite is available to import.
23import setup_chromite # pylint: disable=unused-import
24
25try:
26 from chromite.lib import gs
27except ImportError as e:
28 gs = None
29
joychen3cb228e2013-06-12 12:13:13 -070030#pylint: disable=W0212
xixuan44b55452016-09-06 15:35:56 -070031#pylint: disable=no-value-for-parameter
Simran Basi99e63c02014-05-20 10:39:52 -070032
33GS_ALTERNATE_DIR = 'gs://chromeos-alternate-archive/'
34
joychen3cb228e2013-06-12 12:13:13 -070035class xBuddyTest(mox.MoxTestBase):
36 """Regression tests for xbuddy."""
37 def setUp(self):
38 mox.MoxTestBase.setUp(self)
39
joychen921e1fb2013-06-28 11:12:20 -070040 self.static_image_dir = tempfile.mkdtemp('xbuddy_unittest_static')
joychen3cb228e2013-06-12 12:13:13 -070041
joychen921e1fb2013-06-28 11:12:20 -070042 self.mock_xb = xbuddy.XBuddy(
Gilad Arnold5f46d8e2015-02-19 12:17:55 -080043 True,
44 static_dir=self.static_image_dir
joychen921e1fb2013-06-28 11:12:20 -070045 )
46 self.images_dir = tempfile.mkdtemp('xbuddy_unittest_images')
47 self.mock_xb.images_dir = self.images_dir
joychen3cb228e2013-06-12 12:13:13 -070048
49 def tearDown(self):
50 """Removes testing files."""
51 shutil.rmtree(self.static_image_dir)
joychen921e1fb2013-06-28 11:12:20 -070052 shutil.rmtree(self.images_dir)
joychen3cb228e2013-06-12 12:13:13 -070053
54 def testParseBoolean(self):
55 """Check that some common True/False strings are handled."""
56 self.assertEqual(xbuddy.XBuddy.ParseBoolean(None), False)
57 self.assertEqual(xbuddy.XBuddy.ParseBoolean('false'), False)
58 self.assertEqual(xbuddy.XBuddy.ParseBoolean('bs'), False)
59 self.assertEqual(xbuddy.XBuddy.ParseBoolean('true'), True)
60 self.assertEqual(xbuddy.XBuddy.ParseBoolean('y'), True)
61
xixuan44b55452016-09-06 15:35:56 -070062 def testGetLatestVersionFromGsDir(self):
63 """Test that we can get the most recent version from gsutil calls."""
64 self.mox.StubOutWithMock(self.mock_xb, '_LS')
65 mock_data1 = """gs://chromeos-releases/stable-channel/parrot/3701.96.0/
66 gs://chromeos-releases/stable-channel/parrot/3701.98.0/
67 gs://chromeos-releases/stable-channel/parrot/3912.100.0/
68 gs://chromeos-releases/stable-channel/parrot/3912.101.0/
69 gs://chromeos-releases/stable-channel/parrot/3912.79.0/
70 gs://chromeos-releases/stable-channel/parrot/3912.79.1/"""
71
72 mock_data2 = """gs://chromeos-image-archive/parrot-release/R26-3912.101.0
73 gs://chromeos-image-archive/parrot-release/R27-3912.101.0
74 gs://chromeos-image-archive/parrot-release/R28-3912.101.0"""
75
76 self.mock_xb._LS(mox.IgnoreArg(), list_subdirectory=False).AndReturn(
77 mock_data1.splitlines())
78 self.mock_xb._LS(mox.IgnoreArg(), list_subdirectory=True).AndReturn(
79 mock_data2.splitlines())
80
81 self.mox.ReplayAll()
82 url = ''
83 self.assertEqual(
84 self.mock_xb._GetLatestVersionFromGsDir(url, with_release=False),
85 '3912.101.0')
86 self.assertEqual(
87 self.mock_xb._GetLatestVersionFromGsDir(url, list_subdirectory=True,
88 with_release=True),
89 'R28-3912.101.0')
90 self.mox.VerifyAll()
91
joychenf8f07e22013-07-12 17:45:51 -070092 def testLookupOfficial(self):
93 """Basic test of _LookupOfficial. Checks that a given suffix is handled."""
xixuan44b55452016-09-06 15:35:56 -070094 self.mox.StubOutWithMock(gs.GSContext, 'Cat')
95 gs.GSContext.Cat(mox.IgnoreArg()).AndReturn('v')
joychenf8f07e22013-07-12 17:45:51 -070096 expected = 'b-s/v'
97 self.mox.ReplayAll()
Gilad Arnold896c6d82015-03-13 16:20:29 -070098 self.assertEqual(self.mock_xb._LookupOfficial('b', suffix='-s'), expected)
joychenf8f07e22013-07-12 17:45:51 -070099 self.mox.VerifyAll()
100
101 def testLookupChannel(self):
102 """Basic test of _LookupChannel. Checks that a given suffix is handled."""
xixuan44b55452016-09-06 15:35:56 -0700103 self.mox.StubOutWithMock(self.mock_xb, '_GetLatestVersionFromGsDir')
joychenf8f07e22013-07-12 17:45:51 -0700104 mock_data1 = '4100.68.0'
xixuan44b55452016-09-06 15:35:56 -0700105 self.mock_xb._GetLatestVersionFromGsDir(
joychen562699a2013-08-13 15:22:14 -0700106 mox.IgnoreArg(), with_release=False).AndReturn(mock_data1)
joychenf8f07e22013-07-12 17:45:51 -0700107 mock_data2 = 'R28-4100.68.0'
xixuan44b55452016-09-06 15:35:56 -0700108 self.mock_xb._GetLatestVersionFromGsDir(
109 mox.IgnoreArg(), list_subdirectory=True).AndReturn(mock_data2)
joychenf8f07e22013-07-12 17:45:51 -0700110 self.mox.ReplayAll()
111 expected = 'b-release/R28-4100.68.0'
Gilad Arnold896c6d82015-03-13 16:20:29 -0700112 self.assertEqual(self.mock_xb._LookupChannel('b', '-release'),
Simran Basi99e63c02014-05-20 10:39:52 -0700113 expected)
joychenf8f07e22013-07-12 17:45:51 -0700114 self.mox.VerifyAll()
115
Gilad Arnold896c6d82015-03-13 16:20:29 -0700116 def testLookupAliasPathRewrite(self):
Gilad Arnold38e828c2015-04-24 13:52:07 -0700117 """Tests LookupAlias of path rewrite, including keyword substitution."""
Gilad Arnoldd04fcab2015-02-19 12:00:45 -0800118 alias = 'foobar'
119 path = 'remote/BOARD/VERSION/test'
120 self.mox.StubOutWithMock(self.mock_xb.config, 'get')
Gilad Arnold896c6d82015-03-13 16:20:29 -0700121 self.mock_xb.config.get('LOCATION_SUFFIXES', alias).AndRaise(
122 ConfigParser.Error())
123 self.mock_xb.config.get('PATH_REWRITES', alias).AndReturn(path)
Gilad Arnoldd04fcab2015-02-19 12:00:45 -0800124 self.mox.ReplayAll()
Gilad Arnold896c6d82015-03-13 16:20:29 -0700125 self.assertEqual(('remote/parrot/1.2.3/test', '-release'),
Gilad Arnold38e828c2015-04-24 13:52:07 -0700126 self.mock_xb.LookupAlias(alias, board='parrot',
127 version='1.2.3'))
Gilad Arnold896c6d82015-03-13 16:20:29 -0700128
129 def testLookupAliasSuffix(self):
Gilad Arnold38e828c2015-04-24 13:52:07 -0700130 """Tests LookupAlias of location suffix."""
Gilad Arnold896c6d82015-03-13 16:20:29 -0700131 alias = 'foobar'
132 suffix = '-random'
133 self.mox.StubOutWithMock(self.mock_xb.config, 'get')
134 self.mock_xb.config.get('LOCATION_SUFFIXES', alias).AndReturn(suffix)
135 self.mock_xb.config.get('PATH_REWRITES', alias).AndRaise(
136 ConfigParser.Error())
137 self.mox.ReplayAll()
138 self.assertEqual((alias, suffix),
Gilad Arnold38e828c2015-04-24 13:52:07 -0700139 self.mock_xb.LookupAlias(alias, board='parrot',
140 version='1.2.3'))
Gilad Arnold896c6d82015-03-13 16:20:29 -0700141
142 def testLookupAliasPathRewriteAndSuffix(self):
Gilad Arnold38e828c2015-04-24 13:52:07 -0700143 """Tests LookupAlias with both path rewrite and suffix."""
Gilad Arnold896c6d82015-03-13 16:20:29 -0700144 alias = 'foobar'
145 path = 'remote/BOARD/VERSION/test'
146 suffix = '-random'
147 self.mox.StubOutWithMock(self.mock_xb.config, 'get')
148 self.mock_xb.config.get('LOCATION_SUFFIXES', alias).AndReturn(suffix)
149 self.mock_xb.config.get('PATH_REWRITES', alias).AndReturn(path)
150 self.mox.ReplayAll()
151 self.assertEqual(('remote/parrot/1.2.3/test', suffix),
Gilad Arnold38e828c2015-04-24 13:52:07 -0700152 self.mock_xb.LookupAlias(alias, board='parrot',
153 version='1.2.3'))
Gilad Arnoldd04fcab2015-02-19 12:00:45 -0800154
Chris Sosaea734d92013-10-11 11:28:58 -0700155 def testResolveVersionToBuildId_Official(self):
156 """Check _ResolveVersionToBuildId recognizes aliases for official builds."""
joychenf8f07e22013-07-12 17:45:51 -0700157 board = 'b'
Gilad Arnold896c6d82015-03-13 16:20:29 -0700158 suffix = '-s'
joychenf8f07e22013-07-12 17:45:51 -0700159
160 # aliases that should be redirected to LookupOfficial
Chris Sosaea734d92013-10-11 11:28:58 -0700161
joychenf8f07e22013-07-12 17:45:51 -0700162 self.mox.StubOutWithMock(self.mock_xb, '_LookupOfficial')
Gilad Arnold896c6d82015-03-13 16:20:29 -0700163 self.mock_xb._LookupOfficial(board, suffix, image_dir=None)
164 self.mock_xb._LookupOfficial(board, suffix,
Simran Basi99e63c02014-05-20 10:39:52 -0700165 image_dir=GS_ALTERNATE_DIR)
166 self.mock_xb._LookupOfficial(board, 'paladin', image_dir=None)
167 self.mock_xb._LookupOfficial(board, 'paladin',
168 image_dir=GS_ALTERNATE_DIR)
joychenf8f07e22013-07-12 17:45:51 -0700169
170 self.mox.ReplayAll()
171 version = 'latest-official'
Gilad Arnold896c6d82015-03-13 16:20:29 -0700172 self.mock_xb._ResolveVersionToBuildId(board, suffix, version)
173 self.mock_xb._ResolveVersionToBuildId(board, suffix, version,
Simran Basi99e63c02014-05-20 10:39:52 -0700174 image_dir=GS_ALTERNATE_DIR)
joychenf8f07e22013-07-12 17:45:51 -0700175 version = 'latest-official-paladin'
Gilad Arnold896c6d82015-03-13 16:20:29 -0700176 self.mock_xb._ResolveVersionToBuildId(board, suffix, version)
177 self.mock_xb._ResolveVersionToBuildId(board, suffix, version,
Simran Basi99e63c02014-05-20 10:39:52 -0700178 image_dir=GS_ALTERNATE_DIR)
joychenf8f07e22013-07-12 17:45:51 -0700179 self.mox.VerifyAll()
180
Chris Sosaea734d92013-10-11 11:28:58 -0700181 def testResolveVersionToBuildId_Channel(self):
182 """Check _ResolveVersionToBuildId recognizes aliases for channels."""
joychenf8f07e22013-07-12 17:45:51 -0700183 board = 'b'
Gilad Arnold896c6d82015-03-13 16:20:29 -0700184 suffix = '-s'
joychenf8f07e22013-07-12 17:45:51 -0700185
186 # aliases that should be redirected to LookupChannel
187 self.mox.StubOutWithMock(self.mock_xb, '_LookupChannel')
Gilad Arnold896c6d82015-03-13 16:20:29 -0700188 self.mock_xb._LookupChannel(board, suffix, image_dir=None)
189 self.mock_xb._LookupChannel(board, suffix, image_dir=GS_ALTERNATE_DIR)
190 self.mock_xb._LookupChannel(board, suffix, channel='dev', image_dir=None)
191 self.mock_xb._LookupChannel(board, suffix, channel='dev',
192 image_dir=GS_ALTERNATE_DIR)
joychenf8f07e22013-07-12 17:45:51 -0700193
194 self.mox.ReplayAll()
195 version = 'latest'
Gilad Arnold896c6d82015-03-13 16:20:29 -0700196 self.mock_xb._ResolveVersionToBuildId(board, suffix, version)
197 self.mock_xb._ResolveVersionToBuildId(board, suffix, version,
Simran Basi99e63c02014-05-20 10:39:52 -0700198 image_dir=GS_ALTERNATE_DIR)
joychenf8f07e22013-07-12 17:45:51 -0700199 version = 'latest-dev'
Gilad Arnold896c6d82015-03-13 16:20:29 -0700200 self.mock_xb._ResolveVersionToBuildId(board, suffix, version)
201 self.mock_xb._ResolveVersionToBuildId(board, suffix, version,
Simran Basi99e63c02014-05-20 10:39:52 -0700202 image_dir=GS_ALTERNATE_DIR)
joychenf8f07e22013-07-12 17:45:51 -0700203 self.mox.VerifyAll()
joychen3cb228e2013-06-12 12:13:13 -0700204
Don Garrett80e24112016-06-21 16:22:49 -0700205 # TODO(dgarrett): Re-enable when crbug.com/585914 is fixed.
206 # def testResolveVersionToBuildId_BaseVersion(self):
207 # """Check _ResolveVersionToBuildId handles a base version."""
208 # board = 'b'
209 # suffix = '-s'
Gilad Arnold869e8ab2015-02-19 23:34:49 -0800210
Don Garrett80e24112016-06-21 16:22:49 -0700211 # self.mox.StubOutWithMock(self.mock_xb, '_ResolveBuildVersion')
212 # self.mock_xb._ResolveBuildVersion(board, suffix, '1.2.3').AndReturn(
213 # 'R12-1.2.3')
214 # self.mox.StubOutWithMock(self.mock_xb, '_RemoteBuildId')
215 # self.mock_xb._RemoteBuildId(board, suffix, 'R12-1.2.3')
216 # self.mox.ReplayAll()
Gilad Arnold869e8ab2015-02-19 23:34:49 -0800217
Don Garrett80e24112016-06-21 16:22:49 -0700218 # self.mock_xb._ResolveVersionToBuildId(board, suffix, '1.2.3')
219 # self.mox.VerifyAll()
Gilad Arnold869e8ab2015-02-19 23:34:49 -0800220
joychen3cb228e2013-06-12 12:13:13 -0700221 def testBasicInterpretPath(self):
222 """Basic checks for splitting a path"""
joychen121fc9b2013-08-02 14:30:30 -0700223 path = 'parrot/R27-2455.0.0/test'
joychen7df67f72013-07-18 14:21:12 -0700224 expected = ('test', 'parrot', 'R27-2455.0.0', True)
joychen121fc9b2013-08-02 14:30:30 -0700225 self.assertEqual(self.mock_xb._InterpretPath(path=path), expected)
joychen7df67f72013-07-18 14:21:12 -0700226
joychen121fc9b2013-08-02 14:30:30 -0700227 path = 'parrot/R27-2455.0.0/full_payload'
228 expected = ('full_payload', 'parrot', 'R27-2455.0.0', True)
229 self.assertEqual(self.mock_xb._InterpretPath(path=path), expected)
230
231 path = 'parrot/R27-2455.0.0'
Chris Sosa0eecf962014-02-03 14:14:39 -0800232 expected = ('ANY', 'parrot', 'R27-2455.0.0', True)
joychen121fc9b2013-08-02 14:30:30 -0700233 self.assertEqual(self.mock_xb._InterpretPath(path=path), expected)
234
235 path = 'remote/parrot/R27-2455.0.0'
236 expected = ('test', 'parrot', 'R27-2455.0.0', False)
237 self.assertEqual(self.mock_xb._InterpretPath(path=path), expected)
238
239 path = 'local/parrot/R27-2455.0.0'
Chris Sosa0eecf962014-02-03 14:14:39 -0800240 expected = ('ANY', 'parrot', 'R27-2455.0.0', True)
joychen121fc9b2013-08-02 14:30:30 -0700241 self.assertEqual(self.mock_xb._InterpretPath(path=path), expected)
242
243 path = ''
Chris Sosa0eecf962014-02-03 14:14:39 -0800244 expected = ('ANY', None, 'latest', True)
245 self.assertEqual(self.mock_xb._InterpretPath(path=path), expected)
joychen3cb228e2013-06-12 12:13:13 -0700246
joychen121fc9b2013-08-02 14:30:30 -0700247 path = 'local'
Chris Sosa0eecf962014-02-03 14:14:39 -0800248 expected = ('ANY', None, 'latest', True)
249 self.assertEqual(self.mock_xb._InterpretPath(path=path), expected)
joychen7df67f72013-07-18 14:21:12 -0700250
joychenc3944cb2013-08-19 10:42:07 -0700251 path = 'local/parrot/latest/ANY'
252 expected = ('ANY', 'parrot', 'latest', True)
253 self.assertEqual(self.mock_xb._InterpretPath(path=path), expected)
254
Gilad Arnoldd04fcab2015-02-19 12:00:45 -0800255 def testInterpretPathWithDefaults(self):
256 """Test path splitting with default board/version."""
257 path = ''
258 expected = ('ANY', 'parrot', 'latest', True)
259 self.assertEqual(expected, self.mock_xb._InterpretPath(
260 path=path, default_board='parrot'))
261
262 path = ''
263 expected = ('ANY', None, '1.2.3', True)
264 self.assertEqual(expected, self.mock_xb._InterpretPath(
265 path=path, default_version='1.2.3'))
266
267 path = ''
268 expected = ('ANY', 'parrot', '1.2.3', True)
269 self.assertEqual(expected, self.mock_xb._InterpretPath(
270 path=path, default_board='parrot', default_version='1.2.3'))
271
272 path = '1.2.3'
273 expected = ('ANY', None, '1.2.3', True)
274 self.assertEqual(expected, self.mock_xb._InterpretPath(
275 path=path, default_version='1.2.3'))
276
277 path = 'latest'
278 expected = ('ANY', None, 'latest', True)
279 self.assertEqual(expected, self.mock_xb._InterpretPath(
280 path=path, default_version='1.2.3'))
281
282 path = '1.2.3'
283 expected = ('ANY', 'parrot', '1.2.3', True)
284 self.assertEqual(expected, self.mock_xb._InterpretPath(
285 path=path, default_board='parrot', default_version='1.2.3'))
286
287 path = 'parrot'
288 expected = ('ANY', 'parrot', '1.2.3', True)
289 self.assertEqual(expected, self.mock_xb._InterpretPath(
290 path=path, default_version='1.2.3'))
joychen7df67f72013-07-18 14:21:12 -0700291
joychen3cb228e2013-06-12 12:13:13 -0700292 def testTimestampsAndList(self):
293 """Creation and listing of builds according to their timestamps."""
294 # make 3 different timestamp files
joychen921e1fb2013-06-28 11:12:20 -0700295 b_id11 = 'b1/v1'
296 b_id12 = 'b1/v2'
297 b_id23 = 'b2/v3'
298 xbuddy.Timestamp.UpdateTimestamp(self.mock_xb._timestamp_folder, b_id11)
299 time.sleep(0.05)
300 xbuddy.Timestamp.UpdateTimestamp(self.mock_xb._timestamp_folder, b_id12)
301 time.sleep(0.05)
302 xbuddy.Timestamp.UpdateTimestamp(self.mock_xb._timestamp_folder, b_id23)
joychen3cb228e2013-06-12 12:13:13 -0700303
304 # reference second one again
joychen921e1fb2013-06-28 11:12:20 -0700305 time.sleep(0.05)
306 xbuddy.Timestamp.UpdateTimestamp(self.mock_xb._timestamp_folder, b_id12)
joychen3cb228e2013-06-12 12:13:13 -0700307
308 # check that list returns the same 3 things, in last referenced order
joychen921e1fb2013-06-28 11:12:20 -0700309 result = self.mock_xb._ListBuildTimes()
310 self.assertEqual(result[0][0], b_id12)
311 self.assertEqual(result[1][0], b_id23)
312 self.assertEqual(result[2][0], b_id11)
313
314 def testSyncRegistry(self):
315 # check that there are no builds initially
316 result = self.mock_xb._ListBuildTimes()
317 self.assertEqual(len(result), 0)
318
319 # set up the dummy build/images directory with images
320 boards = ['a', 'b']
321 versions = ['v1', 'v2']
322 for b in boards:
323 os.makedirs(os.path.join(self.mock_xb.images_dir, b))
324 for v in versions:
325 os.makedirs(os.path.join(self.mock_xb.images_dir, b, v))
326
327 # Sync and check that they've been added to xBuddy's registry
328 self.mock_xb._SyncRegistryWithBuildImages()
329 result = self.mock_xb._ListBuildTimes()
330 self.assertEqual(len(result), 4)
joychen3cb228e2013-06-12 12:13:13 -0700331
332 ############### Public Methods
333 def testXBuddyCaching(self):
334 """Caching & replacement of timestamp files."""
joychen121fc9b2013-08-02 14:30:30 -0700335 path_a = ('remote', 'a', 'R0', 'test')
336 path_b = ('remote', 'b', 'R0', 'test')
xixuan44b55452016-09-06 15:35:56 -0700337 self.mox.StubOutWithMock(gs.GSContext, 'LS')
Chris Sosaea734d92013-10-11 11:28:58 -0700338 self.mox.StubOutWithMock(self.mock_xb, '_Download')
joychen3cb228e2013-06-12 12:13:13 -0700339 for _ in range(8):
Chris Sosa75490802013-09-30 17:21:45 -0700340 self.mock_xb._Download(mox.IsA(str), mox.In(mox.IsA(str)))
joychen3cb228e2013-06-12 12:13:13 -0700341
Chris Sosaea734d92013-10-11 11:28:58 -0700342 # All non-release urls are invalid so we can meet expectations.
xixuan44b55452016-09-06 15:35:56 -0700343 gs.GSContext.LS(
344 mox.Not(mox.StrContains('-release'))).MultipleTimes().AndRaise(
345 gs.GSContextException('bad url'))
346 gs.GSContext.LS(mox.StrContains('-release')).MultipleTimes()
Chris Sosaea734d92013-10-11 11:28:58 -0700347
joychen3cb228e2013-06-12 12:13:13 -0700348 self.mox.ReplayAll()
349
350 # requires default capacity
351 self.assertEqual(self.mock_xb.Capacity(), '5')
352
353 # Get 6 different images: a,b,c,d,e,f
joychen921e1fb2013-06-28 11:12:20 -0700354 images = ['a', 'b', 'c', 'd', 'e', 'f']
355 for c in images:
joychen562699a2013-08-13 15:22:14 -0700356 self.mock_xb.Get(('remote', c, 'R0', 'test'))
joychen921e1fb2013-06-28 11:12:20 -0700357 time.sleep(0.05)
joychen3cb228e2013-06-12 12:13:13 -0700358
359 # check that b,c,d,e,f are still stored
joychen921e1fb2013-06-28 11:12:20 -0700360 result = self.mock_xb._ListBuildTimes()
joychen3cb228e2013-06-12 12:13:13 -0700361 self.assertEqual(len(result), 5)
joychen921e1fb2013-06-28 11:12:20 -0700362
363 # Flip the list to get reverse chronological order
364 images.reverse()
365 for i in range(5):
joychenf8f07e22013-07-12 17:45:51 -0700366 self.assertEqual(result[i][0], '%s-release/R0' % images[i])
joychen3cb228e2013-06-12 12:13:13 -0700367
368 # Get b,a
joychen562699a2013-08-13 15:22:14 -0700369 self.mock_xb.Get(path_b)
joychen921e1fb2013-06-28 11:12:20 -0700370 time.sleep(0.05)
joychen562699a2013-08-13 15:22:14 -0700371 self.mock_xb.Get(path_a)
joychen921e1fb2013-06-28 11:12:20 -0700372 time.sleep(0.05)
joychen3cb228e2013-06-12 12:13:13 -0700373
374 # check that d,e,f,b,a are still stored
joychen921e1fb2013-06-28 11:12:20 -0700375 result = self.mock_xb._ListBuildTimes()
joychen3cb228e2013-06-12 12:13:13 -0700376 self.assertEqual(len(result), 5)
joychen921e1fb2013-06-28 11:12:20 -0700377 images_expected = ['a', 'b', 'f', 'e', 'd']
378 for i in range(5):
joychenf8f07e22013-07-12 17:45:51 -0700379 self.assertEqual(result[i][0], '%s-release/R0' % images_expected[i])
joychen3cb228e2013-06-12 12:13:13 -0700380
381 self.mox.VerifyAll()
382
383
384if __name__ == '__main__':
385 unittest.main()