1 #!/usr/bin/python 2 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 """Short integration tests for full_release_test.""" 8 9 import mox 10 import os 11 import tempfile 12 import shutil 13 import unittest 14 15 import common 16 from autotest_lib.site_utils.autoupdate import full_release_test 17 # This is convoluted because of the way we pull in gsutil_util. 18 # pylint: disable-msg=W0611 19 from autotest_lib.site_utils.autoupdate import test_image 20 from test_image import gsutil_util 21 22 23 def _ControlFileContainsLine(control_file, line): 24 """Returns true if the string |control_file| contains line |line|.""" 25 for current_line in control_file.splitlines(): 26 if current_line == line: 27 return True 28 else: 29 return False 30 31 32 def _DoesControlFileHaveSourceTarget(control_file_path, src, target): 33 """Returns true if control file has src and target correctly filled in.""" 34 with open(control_file_path, 'r') as f: 35 control_file = f.read() 36 if not _ControlFileContainsLine( 37 control_file, "source_release = '%s'" % src): 38 print 'source_release does not match' 39 return False 40 41 if not _ControlFileContainsLine( 42 control_file, "target_release = '%s'" % target): 43 print 'target_release does not match' 44 return False 45 46 return True 47 48 49 class ParseVersionsTests(unittest.TestCase): 50 """Tests various version parsing functions.""" 51 52 def setUp(self): 53 self.config_gen = full_release_test.TestConfigGenerator 54 55 def testParseBuildVersion(self): 56 """Tests for _parse_build_version.""" 57 build_version = 'R27-3905.0.0' 58 self.assertEquals(('R27', '3905.0.0'), 59 self.config_gen._parse_build_version(build_version)) 60 build_version = 'R41-6588.0.2014_12_16_1130-a1' 61 self.assertEquals(('R41', '6588.0.2014_12_16_1130-a1'), 62 self.config_gen._parse_build_version(build_version)) 63 64 def testParseDeltaFilename(self): 65 """"Tests for _parse_delta_filename.""" 66 delta_filename = 'chromeos_R27-390.0.0_R29-395.0.0_stumpy_delta_dev.bin' 67 self.assertEquals(('R27-390.0.0', 'R29-395.0.0'), 68 self.config_gen._parse_delta_filename(delta_filename)) 69 70 # On non-release builds, delta filenames have a date portion as well. 71 delta_filename = 'chromeos_R41-6588.0.2014_12_16_1130-a1_R41-6588.0.2014_12_16_1130-a1_stumpy_delta_dev.bin' 72 self.assertEquals(('R41-6588.0.2014_12_16_1130-a1', 'R41-6588.0.2014_12_16_1130-a1'), 73 self.config_gen._parse_delta_filename(delta_filename)) 74 75 class FullReleaseTestTests(mox.MoxTestBase): 76 """Tests for the full_release_test.py test harness.""" 77 78 79 def setUp(self): 80 """Common setUp creates tmpdir.""" 81 mox.MoxTestBase.setUp(self) 82 self.mox.StubOutWithMock(gsutil_util, 'GSUtilRun') 83 self.tmpdir = tempfile.mkdtemp('control') 84 85 86 def tearDown(self): 87 """Common tearDown removes tmpdir.""" 88 mox.MoxTestBase.tearDown(self) 89 shutil.rmtree(self.tmpdir) 90 91 92 def testIntegrationNmoBoard(self): 93 """Tests that we successfully generate a nmo control file.""" 94 board = 'x86-mario' 95 branch = '24' 96 target = '3000.0.0' 97 src = '2999.0.0' 98 99 argv = ['--nmo', 100 '--dump_dir', self.tmpdir, 101 '--dump', 102 target, board] 103 104 # Return npo delta 105 gsutil_util.GSUtilRun(mox.And( 106 mox.StrContains('gsutil cat'), 107 mox.StrContains('%s/UPLOADED' % target)), mox.IgnoreArg()).\ 108 AndReturn('chromeos_R%s-%s_R%s-%s_%s_delta_dev.bin' % ( 109 branch, src, branch, target, board)) 110 # Return target full payload 111 gsutil_util.GSUtilRun(mox.And( 112 mox.StrContains('gsutil cat'), 113 mox.StrContains('%s/UPLOADED' % src)), mox.IgnoreArg()).\ 114 AndReturn('chromeos_R%s-%s_%s_full_dev.bin' % ( 115 branch, src, board)) 116 117 self.mox.ReplayAll() 118 self.assertEquals(full_release_test.main(argv), 0) 119 self.assertTrue(_DoesControlFileHaveSourceTarget( 120 os.path.join(self.tmpdir, board, 'control.nmo_delta_%s' % src), 121 src, target)) 122 self.mox.VerifyAll() 123 124 125 def testIntegrationNpoBoard(self): 126 """Tests that we successfully generate a npo control file.""" 127 board = 'x86-mario' 128 branch = '24' 129 target = '3000.0.0' 130 src = '3000.0.0' 131 132 argv = ['--npo', 133 '--dump_dir', self.tmpdir, 134 '--dump', 135 target, board] 136 137 # Return npo delta 138 gsutil_util.GSUtilRun(mox.And( 139 mox.StrContains('gsutil cat'), 140 mox.StrContains('%s/UPLOADED' % target)), mox.IgnoreArg()).\ 141 AndReturn('chromeos_R%s-%s_R%s-%s_%s_delta_dev.bin' % ( 142 branch, src, branch, target, board)) 143 # Return target full payload 144 gsutil_util.GSUtilRun(mox.And( 145 mox.StrContains('gsutil cat'), 146 mox.StrContains('%s/UPLOADED' % src)), mox.IgnoreArg()).\ 147 AndReturn('chromeos_R%s-%s_%s_full_dev.bin' % ( 148 branch, src, board)) 149 self.mox.ReplayAll() 150 self.assertEquals(full_release_test.main(argv), 0) 151 self.assertTrue(_DoesControlFileHaveSourceTarget( 152 os.path.join(self.tmpdir, board, 'control.npo_delta_%s' % src), 153 src, target)) 154 self.mox.VerifyAll() 155 156 157 def testIntegrationNpoWithArchiveUrl(self): 158 """Successfully generate a npo control file with custom url.""" 159 board = 'x86-mario' 160 branch = '24' 161 target = '3000.0.0' 162 src = '3000.0.0' 163 archive_url = 'gs://chromeos-image-archive/blah-dir/not_a_version' 164 165 argv = ['--npo', 166 '--dump_dir', self.tmpdir, 167 '--dump', 168 '--archive_url', archive_url, 169 target, board] 170 171 # Return npo delta 172 gsutil_util.GSUtilRun(mox.And( 173 mox.StrContains('gsutil cat'), 174 mox.StrContains(archive_url)), mox.IgnoreArg()).\ 175 AndReturn('chromeos_R%s-%s_R%s-%s_%s_delta_dev.bin' % ( 176 branch, src, branch, target, board)) 177 # Return target full payload 178 gsutil_util.GSUtilRun(mox.And( 179 mox.StrContains('gsutil cat'), 180 mox.StrContains(archive_url)), mox.IgnoreArg()).\ 181 AndReturn('chromeos_R%s-%s_%s_full_dev.bin' % ( 182 branch, src, board)) 183 self.mox.ReplayAll() 184 self.assertEquals(full_release_test.main(argv), 0) 185 self.assertTrue(_DoesControlFileHaveSourceTarget( 186 os.path.join(self.tmpdir, board, 'control.npo_delta_%s' % src), 187 src, target)) 188 self.mox.VerifyAll() 189 190 191 def testIntegrationNpoAllBoards(self): 192 """Tests that we successfully generate a npo control file 4 all boards. 193 """ 194 boards = ['stumpy', 'lumpy', 'bumpy'] 195 branch = '24' 196 target = '3000.0.0' 197 src = '3000.0.0' 198 199 argv = ['--npo', 200 '-n', 201 target] + boards 202 203 for board in boards: 204 # Return npo delta 205 gsutil_util.GSUtilRun(mox.And( 206 mox.StrContains('gsutil cat'), 207 mox.StrContains('%s/UPLOADED' % target)), mox.IgnoreArg()).\ 208 AndReturn('chromeos_R%s-%s_R%s-%s_%s_delta_dev.bin' % ( 209 branch, src, branch, target, board)) 210 # Return target full payload 211 gsutil_util.GSUtilRun(mox.And( 212 mox.StrContains('gsutil cat'), 213 mox.StrContains('%s/UPLOADED' % src)), mox.IgnoreArg()).\ 214 AndReturn('chromeos_R%s-%s_%s_full_dev.bin' % ( 215 branch, src, board)) 216 217 self.mox.ReplayAll() 218 self.assertEquals(full_release_test.main(argv), 0) 219 self.mox.VerifyAll() 220 221 self.mox.ResetAll() 222 # Verify we still run all of them even if one fails. 223 bad_board = 'stumpy' 224 for board in boards: 225 # Return npo delta 226 if board == bad_board: 227 gsutil_util.GSUtilRun(mox.And( 228 mox.StrContains('gsutil cat'), 229 mox.StrContains('%s/UPLOADED' % target)), 230 mox.IgnoreArg()).\ 231 AndReturn('NO DELTAS FOR YOU') 232 continue 233 234 gsutil_util.GSUtilRun(mox.And( 235 mox.StrContains('gsutil cat'), 236 mox.StrContains('%s/UPLOADED' % target)), mox.IgnoreArg()).\ 237 AndReturn('chromeos_R%s-%s_R%s-%s_%s_delta_dev.bin' % ( 238 branch, src, branch, target, board)) 239 240 # Return target full payload 241 gsutil_util.GSUtilRun(mox.And( 242 mox.StrContains('gsutil cat'), 243 mox.StrContains('%s/UPLOADED' % src)), mox.IgnoreArg()).\ 244 AndReturn('chromeos_R%s-%s_%s_full_dev.bin' % ( 245 branch, src, board)) 246 247 self.mox.ReplayAll() 248 self.assertEquals(full_release_test.main(argv), 0) 249 self.mox.VerifyAll() 250 251 252 def testIntegrationSpecificBoard(self): 253 """Tests that we successfully generate a specific control file.""" 254 board = 'x86-mario' 255 branch = '24' 256 target = '3000.0.0' 257 src = '1234.0.0' 258 259 argv = ['--specific', src, 260 '--dump_dir', self.tmpdir, 261 '--dump', 262 target, board] 263 264 # Return target full payload 265 gsutil_util.GSUtilRun(mox.And( 266 mox.StrContains('gsutil cat'), 267 mox.StrContains('%s/UPLOADED' % target)), mox.IgnoreArg()).\ 268 AndReturn('chromeos_R%s-%s_%s_full_dev.bin' % ( 269 branch, target, board)) 270 # Return src full payload 271 gsutil_util.GSUtilRun(mox.And( 272 mox.StrContains('gsutil cat'), 273 mox.StrContains('%s/UPLOADED' % src)), mox.IgnoreArg()).\ 274 AndReturn('chromeos_R%s-%s_%s_full_dev.bin' % ( 275 branch, src, board)) 276 self.mox.ReplayAll() 277 self.assertEquals(full_release_test.main(argv), 0) 278 self.assertTrue(_DoesControlFileHaveSourceTarget( 279 os.path.join(self.tmpdir, board, 280 'control.specific_full_%s' % src), 281 src, target)) 282 self.mox.VerifyAll() 283 284 285 def testIntegrationSpecificBoardFail(self): 286 """Tests we don't generate a specific test if either payload missing.""" 287 board = 'x86-mario' 288 branch = '24' 289 target = '3000.0.0' 290 src = '1234.0.0' 291 292 argv = ['--specific', src, 293 '--dump_dir', self.tmpdir, 294 '--dump', 295 target, board] 296 297 # Return target full payload 298 gsutil_util.GSUtilRun(mox.And( 299 mox.StrContains('gsutil cat'), 300 mox.StrContains('%s/UPLOADED' % target)), mox.IgnoreArg()).\ 301 AndReturn('chromeos_R%s-%s_%s_full_dev.bin' % ( 302 branch, target, board)) 303 # No src full payload 304 gsutil_util.GSUtilRun(mox.And( 305 mox.StrContains('gsutil cat'), 306 mox.StrContains('%s/UPLOADED' % src)), mox.IgnoreArg()).\ 307 AndReturn('SOME OTHER DATA') 308 self.mox.ReplayAll() 309 self.assertEquals(full_release_test.main(argv), 1) 310 self.mox.VerifyAll() 311 312 self.mox.ResetAll() 313 # Return target full payload 314 gsutil_util.GSUtilRun(mox.And( 315 mox.StrContains('gsutil cat'), 316 mox.StrContains('%s/UPLOADED' % target)), mox.IgnoreArg()).\ 317 AndReturn('SOME OTHER DATA') 318 self.mox.ReplayAll() 319 self.assertEquals(full_release_test.main(argv), 1) 320 self.mox.VerifyAll() 321 322 323 if __name__ == '__main__': 324 unittest.main() 325