1#!/usr/bin/python 2 3import unittest, os, time, re, glob, logging 4import common 5from autotest_lib.client.common_lib.test_utils import mock 6from autotest_lib.client.bin import kernel, job, utils, kernelexpand 7from autotest_lib.client.bin import kernel_config, boottool, os_dep 8 9 10class TestAddKernelToBootLoader(unittest.TestCase): 11 12 def add_to_bootloader(self, base_args, args, bootloader_args, 13 bootloader_root, tag='image', image='image', 14 initrd='initrd'): 15 god = mock.mock_god() 16 bootloader = god.create_mock_class(boottool.boottool, "boottool") 17 18 # record 19 bootloader.remove_kernel.expect_call(tag) 20 bootloader.add_kernel.expect_call(image, tag, initrd=initrd, 21 args='_dummy_', root=bootloader_root) 22 23 for a in bootloader_args.split(): 24 bootloader.add_args.expect_call(kernel=tag, args=a) 25 bootloader.remove_args.expect_call(kernel=tag, args='_dummy_') 26 27 # run and check 28 kernel._add_kernel_to_bootloader(bootloader, base_args, tag, args, 29 image, initrd) 30 god.check_playback() 31 32 33 def test_add_kernel_to_bootloader(self): 34 self.add_to_bootloader(base_args='baseargs', args='', 35 bootloader_args='baseargs', bootloader_root=None) 36 self.add_to_bootloader(base_args='arg1 root=/dev/oldroot arg2', 37 args='root=/dev/newroot arg3', 38 bootloader_args='arg1 arg2 arg3', 39 bootloader_root='/dev/newroot') 40 41 42class TestBootableKernel(unittest.TestCase): 43 44 def setUp(self): 45 self.god = mock.mock_god() 46 self.god.stub_function(time, "time") 47 self.god.stub_function(utils, "system") 48 self.god.stub_function(kernel, "_add_kernel_to_bootloader") 49 job_ = self.god.create_mock_class(job.job, "job") 50 self.kernel = kernel.BootableKernel(job_) 51 self.kernel.job.bootloader = self.god.create_mock_class( 52 boottool.boottool, "boottool") 53 54 55 def tearDown(self): 56 # note: time.time() can only be unstubbed via tearDown() 57 self.god.unstub_all() 58 59 60 def boot_kernel(self, ident_check): 61 notes = "applied_patches" 62 when = 1 63 args = '' 64 base_args = 'base_args' 65 tag = 'ident' 66 subdir = 'subdir' 67 self.kernel.image = 'image' 68 self.kernel.initrd = 'initrd' 69 self.kernel.installed_as = tag 70 71 # record 72 args_ = args 73 if ident_check: 74 time.time.expect_call().and_return(when) 75 args_ += " IDENT=%d" % when 76 status = ["job.end_reboot_and_verify", when, tag, subdir, notes] 77 else: 78 status = ["job.end_reboot", subdir, tag, notes] 79 self.kernel.job.next_step_prepend.expect_call(status) 80 self.kernel.job.config_get.expect_call( 81 'boot.default_args').and_return(base_args) 82 kernel._add_kernel_to_bootloader.expect_call( 83 self.kernel.job.bootloader, base_args, tag, 84 args_, self.kernel.image, self.kernel.initrd) 85 utils.system.expect_call('touch /fastboot') 86 self.kernel.job.start_reboot.expect_call() 87 self.kernel.job.reboot.expect_call(tag=tag) 88 89 # run and check 90 self.kernel._boot_kernel(args=args, ident_check=ident_check, 91 expected_ident=tag, subdir=subdir, notes=notes) 92 self.god.check_playback() 93 94 95 def test_boot_kernel(self): 96 self.boot_kernel(ident_check=False) 97 self.boot_kernel(ident_check=True) 98 99 100class TestKernel(unittest.TestCase): 101 def setUp(self): 102 self.god = mock.mock_god() 103 104 logging.disable(logging.CRITICAL) 105 106 self.god.stub_function(time, "time") 107 self.god.stub_function(os, "mkdir") 108 self.god.stub_function(os, "chdir") 109 self.god.stub_function(os, "symlink") 110 self.god.stub_function(os, "remove") 111 self.god.stub_function(os.path, "isdir") 112 self.god.stub_function(os.path, "exists") 113 self.god.stub_function(os.path, "isfile") 114 self.god.stub_function(os_dep, "commands") 115 self.god.stub_function(kernel, "open") 116 self.god.stub_function(utils, "system") 117 self.god.stub_function(utils, "system_output") 118 self.god.stub_function(utils, "get_file") 119 self.god.stub_function(utils, "get_current_kernel_arch") 120 self.god.stub_function(utils, "cat_file_to_cmd") 121 self.god.stub_function(utils, "force_copy") 122 self.god.stub_function(utils, "extract_tarball_to_dir") 123 self.god.stub_function(utils, "count_cpus") 124 self.god.stub_function(utils, "get_os_vendor") 125 self.god.stub_function(kernelexpand, "expand_classic") 126 self.god.stub_function(kernel_config, "modules_needed") 127 self.god.stub_function(glob, "glob") 128 def dummy_mark(filename, msg): 129 pass 130 self.god.stub_with(kernel, '_mark', dummy_mark) 131 132 self.job = self.god.create_mock_class(job.job, "job") 133 self.job.bootloader = self.god.create_mock_class(boottool.boottool, 134 "boottool") 135 136 class DummyLoggingManager(object): 137 def tee_redirect_debug_dir(self, *args, **kwargs): 138 pass 139 140 141 def restore(self, *args, **kwargs): 142 pass 143 144 self.job.logging = DummyLoggingManager() 145 146 self.job.autodir = "autodir" 147 self.base_tree = "2.6.24" 148 self.tmp_dir = "tmpdir" 149 self.subdir = "subdir" 150 151 152 def tearDown(self): 153 self.god.unstub_all() 154 155 156 def construct_kernel(self): 157 self.kernel = kernel.kernel.__new__(kernel.kernel) 158 self.god.stub_function(self.kernel, "extract") 159 160 # setup 161 self.src_dir = os.path.join(self.tmp_dir, 'src') 162 self.build_dir = os.path.join(self.tmp_dir, "build_dir") 163 self.config_dir = os.path.join(self.subdir, 'config') 164 self.log_dir = os.path.join(self.subdir, 'debug') 165 self.results_dir = os.path.join(self.subdir, 'results') 166 167 # record 168 os.path.isdir.expect_call(self.src_dir).and_return(True) 169 utils.system.expect_call('rm -rf ' + self.src_dir) 170 os.path.isdir.expect_call(self.build_dir).and_return(True) 171 utils.system.expect_call('rm -rf ' + self.build_dir) 172 os.path.exists.expect_call(self.src_dir).and_return(False) 173 os.mkdir.expect_call(self.src_dir) 174 for path in [self.config_dir, self.log_dir, self.results_dir]: 175 os.path.exists.expect_call(path).and_return(True) 176 utils.system.expect_call('rm -rf ' + path) 177 os.mkdir.expect_call(path) 178 179 logpath = os.path.join(self.log_dir, 'build_log') 180 self.logfile = self.god.create_mock_class(file, "file") 181 kernel.open.expect_call(logpath, 'w+').and_return(self.logfile) 182 utils.get_current_kernel_arch.expect_call().and_return('ia64') 183 self.logfile.write.expect_call('BASE: %s\n' % self.base_tree) 184 self.kernel.extract.expect_call(self.base_tree) 185 186 # finish creation of kernel object and test (and unstub extract) 187 self.kernel.__init__(self.job, self.base_tree, self.subdir, 188 self.tmp_dir, "build_dir") 189 self.god.check_playback() 190 self.god.unstub(self.kernel, "extract") 191 192 193 def test_constructor(self): 194 self.construct_kernel() 195 196 197 def test_kernelexpand1(self): 198 self.construct_kernel() 199 200 ret_val = self.kernel.kernelexpand("/path/to/kernel") 201 self.assertEquals(ret_val, ["/path/to/kernel"]) 202 self.god.check_playback() 203 204 205 def test_kernel_expand2(self): 206 self.construct_kernel() 207 kernel = "kernel.tar.gz" 208 209 # record 210 self.job.config_get.expect_call('mirror.mirrors').and_return('mirror') 211 kernelexpand.expand_classic.expect_call(kernel, 212 'mirror').and_return('patches') 213 214 # run 215 self.assertEquals(self.kernel.kernelexpand(kernel), 'patches') 216 self.god.check_playback() 217 218 219 def test_kernel_expand3(self): 220 self.construct_kernel() 221 kernel = "kernel.tar.gz" 222 223 # record 224 self.job.config_get.expect_call('mirror.mirrors') 225 self.job.config_get.expect_call( 226 'mirror.ftp_kernel_org').and_return('mirror') 227 korg = 'http://www.kernel.org/pub/linux/kernel' 228 mirrors = [ 229 [ korg + '/v2.6', 'mirror' + '/v2.6' ], 230 [ korg + '/people/akpm/patches/2.6', 'mirror' + '/akpm' ], 231 [ korg + '/people/mbligh', 'mirror' + '/mbligh' ], 232 ] 233 kernelexpand.expand_classic.expect_call(kernel, 234 mirrors).and_return('patches') 235 236 # run 237 self.assertEquals(self.kernel.kernelexpand(kernel), 'patches') 238 self.god.check_playback() 239 240 241 def test_extract1(self): 242 self.construct_kernel() 243 244 # setup 245 self.god.stub_function(self.kernel, "get_kernel_tree") 246 247 # record 248 os.path.exists.expect_call(self.base_tree).and_return(True) 249 self.kernel.get_kernel_tree.expect_call(self.base_tree) 250 self.job.record.expect_call('GOOD', self.subdir, 'kernel.extract') 251 252 # run 253 self.kernel.extract(self.base_tree) 254 self.god.check_playback() 255 self.god.unstub(self.kernel, "get_kernel_tree") 256 257 258 def test_extract2(self): 259 self.construct_kernel() 260 261 # setup 262 self.god.stub_function(self.kernel, "kernelexpand") 263 self.god.stub_function(self.kernel, "get_kernel_tree") 264 self.god.stub_function(self.kernel, "patch") 265 266 # record 267 os.path.exists.expect_call(self.base_tree).and_return(False) 268 components = ["component0", "component1"] 269 self.kernel.kernelexpand.expect_call(self.base_tree).and_return( 270 components) 271 self.kernel.get_kernel_tree.expect_call(components[0]) 272 self.kernel.patch.expect_call(components[1]) 273 self.job.record.expect_call('GOOD', self.subdir, 'kernel.extract') 274 275 # run 276 self.kernel.extract(self.base_tree) 277 self.god.check_playback() 278 self.god.unstub(self.kernel, "kernelexpand") 279 self.god.unstub(self.kernel, "get_kernel_tree") 280 self.god.unstub(self.kernel, "patch") 281 282 283 def test_patch1(self): 284 self.construct_kernel() 285 patches = ('patch1', 'patch2') 286 self.god.stub_function(self.kernel, "apply_patches") 287 self.god.stub_function(self.kernel, "get_patches") 288 289 #record 290 self.kernel.get_patches.expect_call(patches).and_return(patches) 291 self.kernel.apply_patches.expect_call(patches) 292 self.job.record.expect_call('GOOD', self.subdir, 'kernel.patch') 293 294 #run 295 self.kernel.patch(*patches) 296 self.god.check_playback() 297 self.god.unstub(self.kernel, "apply_patches") 298 self.god.unstub(self.kernel, "get_patches") 299 300 301 def test_patch2(self): 302 self.construct_kernel() 303 patches = [] 304 305 # record 306 self.job.record.expect_call('GOOD', self.subdir, 'kernel.patch') 307 308 # run 309 self.kernel.patch(*patches) 310 self.god.check_playback() 311 312 313 def test_config(self): 314 self.construct_kernel() 315 316 # setup 317 self.god.stub_function(self.kernel, "set_cross_cc") 318 self.god.stub_class(kernel_config, "kernel_config") 319 320 # record 321 self.kernel.set_cross_cc.expect_call() 322 kernel_config.kernel_config.expect_new(self.job, self.build_dir, 323 self.config_dir, '', None, 324 False, self.base_tree, None) 325 self.job.record.expect_call('GOOD', self.subdir, 'kernel.config') 326 327 # run 328 self.kernel.config() 329 self.god.check_playback() 330 self.god.unstub(self.kernel, "set_cross_cc") 331 332 333 def test_get_patches(self): 334 self.construct_kernel() 335 336 # setup 337 patches = ['patch1', 'patch2', 'patch3'] 338 local_patches = [] 339 340 # record 341 for patch in patches: 342 dest = os.path.join(self.src_dir, os.path.basename(patch)) 343 utils.get_file.expect_call(patch, dest) 344 utils.system_output.expect_call( 345 'md5sum ' + dest).and_return('md5sum') 346 local_patches.append((patch, dest, 'md5sum')) 347 348 # run and check 349 self.assertEquals(self.kernel.get_patches(patches), local_patches) 350 self.god.check_playback() 351 352 353 def test_apply_patches(self): 354 self.construct_kernel() 355 356 # setup 357 patches = [] 358 patches.append(('patch1', 'patch1.gz', 'md5sum1')) 359 patches.append(('patch2', 'patch2.bz2', 'md5sum2')) 360 patches.append(('patch3', 'patch3', 'md5sum3')) 361 applied_patches = [] 362 363 # record 364 os.chdir.expect_call(self.build_dir) 365 366 patch_id = "%s %s %s" % ('patch1', 'patch1', 'md5sum1') 367 log = "PATCH: " + patch_id + "\n" 368 utils.cat_file_to_cmd.expect_call('patch1.gz', 369 'patch -p1 > /dev/null') 370 self.logfile.write.expect_call(log) 371 applied_patches.append(patch_id) 372 373 patch_id = "%s %s %s" % ('patch2', 'patch2', 'md5sum2') 374 log = "PATCH: " + patch_id + "\n" 375 utils.cat_file_to_cmd.expect_call('patch2.bz2', 376 'patch -p1 > /dev/null') 377 self.logfile.write.expect_call(log) 378 applied_patches.append(patch_id) 379 380 utils.force_copy.expect_call('patch3', 381 self.results_dir).and_return('local_patch3') 382 self.job.relative_path.expect_call('local_patch3').and_return( 383 'rel_local_patch3') 384 patch_id = "%s %s %s" % ('patch3', 'rel_local_patch3', 'md5sum3') 385 log = "PATCH: " + patch_id + "\n" 386 utils.cat_file_to_cmd.expect_call('patch3', 387 'patch -p1 > /dev/null') 388 self.logfile.write.expect_call(log) 389 applied_patches.append(patch_id) 390 391 # run and test 392 self.kernel.apply_patches(patches) 393 self.assertEquals(self.kernel.applied_patches, applied_patches) 394 self.god.check_playback() 395 396 397 def test_get_kernel_tree1(self): 398 self.construct_kernel() 399 400 # record 401 os.path.isdir.expect_call(self.base_tree).and_return(True) 402 os.symlink.expect_call(self.base_tree, self.build_dir) 403 404 # run and check 405 self.kernel.get_kernel_tree(self.base_tree) 406 self.god.check_playback() 407 408 409 def test_get_kernel_tree2(self): 410 self.construct_kernel() 411 412 # record 413 os.path.isdir.expect_call(self.base_tree).and_return(False) 414 os.chdir.expect_call(os.path.dirname(self.src_dir)) 415 tarball = os.path.join(self.src_dir, os.path.basename(self.base_tree)) 416 utils.get_file.expect_call(self.base_tree, tarball) 417 utils.extract_tarball_to_dir.expect_call(tarball, 418 self.build_dir) 419 420 # run and check 421 self.kernel.get_kernel_tree(self.base_tree) 422 self.god.check_playback() 423 424 425 def test_extraversion(self): 426 self.construct_kernel() 427 tag = "tag" 428 # setup 429 self.god.stub_function(self.kernel, "config") 430 431 # record 432 os.chdir.expect_call(self.build_dir) 433 extraversion_sub = r's/^CONFIG_LOCALVERSION=\s*"\(.*\)"/CONFIG_LOCALVERSION=' 434 cfg = self.build_dir + '/.config' 435 p = extraversion_sub + '"\\1-%s"/' % tag 436 utils.system.expect_call('mv %s %s.old' % (cfg, cfg)) 437 utils.system.expect_call("sed '%s' < %s.old > %s" % (p, cfg, cfg)) 438 self.kernel.config.expect_call(make='oldconfig') 439 440 # run and check 441 self.kernel.extraversion(tag) 442 self.god.check_playback() 443 444 445 def test_build(self): 446 self.construct_kernel() 447 self.god.stub_function(self.kernel, "extraversion") 448 self.god.stub_function(self.kernel, "set_cross_cc") 449 self.god.stub_function(self.kernel, "get_kernel_build_ver") 450 self.kernel.build_target = 'build_target' 451 452 # record 453 os_dep.commands.expect_call('gcc', 'make') 454 logfile = os.path.join(self.log_dir, 'kernel_build') 455 os.chdir.expect_call(self.build_dir) 456 self.kernel.extraversion.expect_call('autotest') 457 self.kernel.set_cross_cc.expect_call() 458 utils.system.expect_call('make dep', ignore_status=True) 459 utils.count_cpus.expect_call().and_return(4) 460 threads = 2 * 4 461 build_string = 'make -j %d %s %s' % (threads, '', 'build_target') 462 utils.system.expect_call(build_string) 463 kernel_config.modules_needed.expect_call('.config').and_return(True) 464 utils.system.expect_call('make -j %d modules' % (threads)) 465 self.kernel.get_kernel_build_ver.expect_call().and_return('2.6.24') 466 kernel_version = re.sub('-autotest', '', '2.6.24') 467 self.logfile.write.expect_call('BUILD VERSION: %s\n' % kernel_version) 468 utils.force_copy.expect_call(self.build_dir+'/System.map', 469 self.results_dir) 470 self.job.record.expect_call('GOOD', self.subdir, 'kernel.build') 471 472 # run and check 473 self.kernel.build() 474 self.god.check_playback() 475 476 477 def test_build_timed(self): 478 self.construct_kernel() 479 self.god.stub_function(self.kernel, "set_cross_cc") 480 self.god.stub_function(self.kernel, "clean") 481 482 # record 483 os.chdir.expect_call(self.build_dir) 484 self.kernel.set_cross_cc.expect_call() 485 self.kernel.clean.expect_call() 486 build_string = "/usr/bin/time -o /dev/null make -j 8 vmlinux" 487 build_string += ' > /dev/null 2>&1' 488 utils.system.expect_call(build_string) 489 os.path.isfile.expect_call('vmlinux').and_return(True) 490 491 # run and check 492 self.kernel.build_timed(threads=8) 493 self.god.check_playback() 494 495 496 def test_clean(self): 497 self.construct_kernel() 498 499 # record 500 os.chdir.expect_call(self.build_dir) 501 utils.system.expect_call('make clean > /dev/null 2> /dev/null') 502 self.job.record.expect_call('GOOD', self.subdir, 'kernel.clean') 503 504 # run and check 505 self.kernel.clean() 506 self.god.check_playback() 507 508 509 def test_mkinitrd(self): 510 self.construct_kernel() 511 512 # record 513 utils.get_os_vendor.expect_call().and_return('Ubuntu') 514 os.path.isfile.expect_call('initrd').and_return(True) 515 os.remove.expect_call('initrd') 516 self.job.config_get.expect_call( 517 'kernel.mkinitrd_extra_args').and_return(None) 518 args = '' 519 glob.glob.expect_call('/lib/modules/2.6.24*').and_return(['2.6.24']) 520 os.path.isfile.expect_call('/usr/sbin/mkinitrd').and_return(True) 521 cmd = '/usr/sbin/mkinitrd' 522 utils.system.expect_call('%s %s -o initrd 2.6.24' % (cmd, args)) 523 self.job.record.expect_call('GOOD', self.subdir, 'kernel.mkinitrd') 524 525 # run and check 526 self.kernel.mkinitrd(version="2.6.24", image="image", 527 system_map="system_map", initrd="initrd") 528 self.god.check_playback() 529 530 531 def test_install(self): 532 self.construct_kernel() 533 tag = 'autotest' 534 prefix = '/' 535 self.kernel.build_image = None 536 self.kernel.build_target = 'build_target' 537 self.god.stub_function(self.kernel, "get_kernel_build_ver") 538 self.god.stub_function(self.kernel, "mkinitrd") 539 540 # record 541 os.chdir.expect_call(self.build_dir) 542 os.path.isdir.expect_call(prefix).and_return(False) 543 os.mkdir.expect_call(prefix) 544 boot_dir = os.path.join(prefix, 'boot') 545 os.path.isdir.expect_call(boot_dir).and_return(False) 546 os.mkdir.expect_call(boot_dir) 547 glob.glob.expect_call( 548 'arch/*/boot/' + 'build_target').and_return('') 549 build_image = self.kernel.build_target 550 utils.force_copy.expect_call('vmlinux', 551 '/boot/vmlinux-autotest') 552 utils.force_copy.expect_call('build_target', 553 '/boot/vmlinuz-autotest') 554 utils.force_copy.expect_call('System.map', 555 '/boot/System.map-autotest') 556 utils.force_copy.expect_call('.config', 557 '/boot/config-autotest') 558 kernel_config.modules_needed.expect_call('.config').and_return(True) 559 utils.system.expect_call('make modules_install INSTALL_MOD_PATH=%s' 560 % prefix) 561 initrd = boot_dir + '/initrd-' + tag 562 self.kernel.get_kernel_build_ver.expect_call().and_return('2.6.24') 563 self.kernel.mkinitrd.expect_call('2.6.24', '/boot/vmlinuz-autotest', 564 '/boot/System.map-autotest', '/boot/initrd-autotest') 565 self.job.record.expect_call('GOOD', self.subdir, 'kernel.install') 566 567 # run and check 568 self.kernel.install() 569 self.god.check_playback() 570 571 572 def test_get_kernel_build_arch1(self): 573 self.construct_kernel() 574 575 # record 576 utils.get_current_kernel_arch.expect_call().and_return("i386") 577 578 # run and check 579 self.assertEquals(self.kernel.get_kernel_build_arch(), "i386") 580 self.god.check_playback() 581 582 583 def test_get_kernel_build_arch2(self): 584 self.construct_kernel() 585 586 # run and check 587 self.assertEquals(self.kernel.get_kernel_build_arch('i586'), "i386") 588 self.god.check_playback() 589 590 591 def test_get_kernel_build_release(self): 592 self.construct_kernel() 593 mock_file = self.god.create_mock_class(file, "file") 594 595 # record 596 for f in [self.build_dir + "/include/linux/version.h", 597 self.build_dir + "/include/linux/utsrelease.h"]: 598 os.path.exists.expect_call(f).and_return(True) 599 kernel.open.expect_call(f, 'r').and_return(mock_file) 600 mock_file.readlines.expect_call().and_return("Some lines") 601 mock_file.close.expect_call() 602 603 for f in [self.build_dir + "/include/linux/compile.h", 604 self.build_dir + "/include/generated/utsrelease.h", 605 self.build_dir + "/include/generated/compile.h"]: 606 os.path.exists.expect_call(f).and_return(False) 607 608 # run and test 609 self.kernel.get_kernel_build_release() 610 self.god.check_playback() 611 612 613 def test_get_kernel_build_ident(self): 614 self.construct_kernel() 615 self.god.stub_function(self.kernel, "get_kernel_build_release") 616 617 # record 618 self.kernel.get_kernel_build_release.expect_call().and_return( 619 ("AwesomeRelease", "1.0")) 620 621 # run and check 622 self.assertEquals(self.kernel.get_kernel_build_ident(), 623 "AwesomeRelease::1.0") 624 self.god.check_playback() 625 626 627 def test_boot(self): 628 self.construct_kernel() 629 self.god.stub_function(self.kernel, "get_kernel_build_ident") 630 self.god.stub_function(self.kernel, "install") 631 self.god.stub_function(self.kernel, "_boot_kernel") 632 self.kernel.applied_patches = "applied_patches" 633 self.kernel.installed_as = None 634 args = '' 635 expected_ident = 'ident' 636 ident = True 637 638 # record 639 self.kernel.install.expect_call() 640 self.kernel.get_kernel_build_ident.expect_call( 641 ).and_return(expected_ident) 642 self.kernel._boot_kernel.expect_call( 643 args, ident, expected_ident, 644 self.subdir, self.kernel.applied_patches) 645 646 # run and check 647 self.kernel.boot(args=args, ident=ident) 648 self.god.check_playback() 649 650 651if __name__ == "__main__": 652 unittest.main() 653