Add 'touch /fastboot' to kernel rpm boot method used by client tests. Also, factor out shared boot method for kernels installed from source or from rpm, in client/bin/kernel and its unittest.
Using fastboot for boots into the target test kernel has greatly reduced our rate of failed boots due to fsck's bringing back the default kernel. Signed-off-by: Duane Sand <[email protected]> --- client/bin/kernel.py | 119 +++++++++++++-------------- client/bin/kernel_unittest.py | 177 +++++++++++++++++++++++------------------ 2 files changed, 155 insertions(+), 141 deletions(-) diff --git a/client/bin/kernel.py b/client/bin/kernel.py index b398697..da91389 100644 --- a/client/bin/kernel.py +++ b/client/bin/kernel.py @@ -64,7 +64,51 @@ def _add_kernel_to_bootloader(bootloader, base_args, tag, args, image, initrd): root=root) -class kernel(object): +class BootableKernel(object): + + def __init__(self, job): + self.job = job + self.installed_as = None # kernel choice in bootloader menu + self.image = None + self.initrd = '' + + + def _boot_kernel(self, args, ident_check, expected_ident, subdir, notes): + """ + Boot a kernel, with post-boot kernel id check + + @param args: kernel cmdline arguments + @param ident_check: check kernel id after boot + @param expected_ident: + @param subdir: job-step qualifier in status log + @param notes: additional comment in status log + """ + + # If we can check the kernel identity do so. + if ident_check: + when = int(time.time()) + args += " IDENT=%d" % when + self.job.next_step_prepend(["job.end_reboot_and_verify", when, + expected_ident, subdir, notes]) + else: + self.job.next_step_prepend(["job.end_reboot", subdir, + expected_ident, notes]) + + # Point bootloader to the selected tag. + _add_kernel_to_bootloader(self.job.bootloader, + self.job.config_get('boot.default_args'), + self.installed_as, args, self.image, + self.initrd) + + # defer fsck for next reboot, to avoid reboots back to default kernel + utils.system('touch /fastboot') # this file is removed automatically + + # Boot it. + self.job.start_reboot() + self.job.reboot(tag=self.installed_as) + + +class kernel(BootableKernel): """ Class for compiling kernels. Data for the object includes the src files @@ -109,7 +153,7 @@ class kernel(object): leave Boolean, whether to leave existing tmpdir or not """ - self.job = job + super(kernel, self).__init__(job) self.autodir = job.autodir self.src_dir = os.path.join(tmp_dir, 'src') @@ -120,8 +164,6 @@ class kernel(object): self.results_dir = os.path.join(subdir, 'results') self.subdir = os.path.basename(subdir) - self.installed_as = None - if not leave: if os.path.isdir(self.src_dir): utils.system('rm -rf ' + self.src_dir) @@ -450,16 +492,6 @@ class kernel(object): self.system_map, self.initrd) - def add_to_bootloader(self, tag='autotest', args=''): - """ add this kernel to bootloader, taking an - optional parameter of space separated parameters - e.g.: kernel.add_to_bootloader('mykernel', 'ro acpi=off') - """ - _add_kernel_to_bootloader(self.job.bootloader, - self.job.config_get('boot.default_args'), - tag, args, self.image, self.initrd) - - def get_kernel_build_arch(self, arch=None): """ Work out the current kernel architecture (as a kernel arch) @@ -526,29 +558,14 @@ class kernel(object): just make it happen. """ - # If we can check the kernel identity do so. - expected_ident = self.get_kernel_build_ident() - if ident: - when = int(time.time()) - args += " IDENT=%d" % (when) - self.job.next_step_prepend(["job.end_reboot_and_verify", when, - expected_ident, self.subdir, - self.applied_patches]) - else: - self.job.next_step_prepend(["job.end_reboot", self.subdir, - expected_ident, self.applied_patches]) - - # Check if the kernel has been installed, if not install - # as the default tag and boot that. + # If the kernel has not yet been installed, + # install it now as default tag. if not self.installed_as: self.install() - # Boot the selected tag. - self.add_to_bootloader(args=args, tag=self.installed_as) - - # Boot it. - self.job.start_reboot() - self.job.reboot(tag=self.installed_as) + expected_ident = self.get_kernel_build_ident() + self._boot_kernel(args, ident, expected_ident, + self.subdir, self.applied_patches) def get_kernel_build_ver(self): @@ -646,20 +663,19 @@ class kernel(object): pickle.dump(temp, open(filename, 'w')) -class rpm_kernel(object): +class rpm_kernel(BootableKernel): """ Class for installing a binary rpm kernel package """ def __init__(self, job, rpm_package, subdir): - self.job = job + super(rpm_kernel, self).__init__(job) self.rpm_package = rpm_package self.log_dir = os.path.join(subdir, 'debug') self.subdir = os.path.basename(subdir) if os.path.exists(self.log_dir): utils.system('rm -rf ' + self.log_dir) os.mkdir(self.log_dir) - self.installed_as = None def build(self, *args, **dargs): @@ -725,44 +741,23 @@ class rpm_kernel(object): % (vmlinux, rpm_pack)) - def add_to_bootloader(self, tag='autotest', args=''): - """ Add this kernel to bootloader - """ - _add_kernel_to_bootloader(self.job.bootloader, - self.job.config_get('boot.default_args'), - tag, args, self.image, self.initrd) - - def boot(self, args='', ident=True): """ install and boot this kernel """ - # Check if the kernel has been installed, if not install - # as the default tag and boot that. + # If the kernel has not yet been installed, + # install it now as default tag. if not self.installed_as: self.install() - # If we can check the kernel identity do so. expected_ident = self.full_version if not expected_ident: expected_ident = '-'.join([self.version, self.rpm_flavour, self.release]) - if ident: - when = int(time.time()) - args += " IDENT=%d" % (when) - self.job.next_step_prepend(["job.end_reboot_and_verify", - when, expected_ident, None, 'rpm']) - else: - self.job.next_step_prepend(["job.end_reboot", None, - expected_ident, []]) - - # Boot the selected tag. - self.add_to_bootloader(args=args, tag=self.installed_as) - # Boot it. - self.job.start_reboot() - self.job.reboot(tag=self.installed_as) + self._boot_kernel(args, ident, expected_ident, + None, 'rpm') class rpm_kernel_suse(rpm_kernel): diff --git a/client/bin/kernel_unittest.py b/client/bin/kernel_unittest.py index 88d822d..fe40e6a 100755 --- a/client/bin/kernel_unittest.py +++ b/client/bin/kernel_unittest.py @@ -6,6 +6,94 @@ from autotest_lib.client.common_lib.test_utils import mock from autotest_lib.client.bin import kernel, job, utils, kernelexpand from autotest_lib.client.bin import kernel_config, boottool, os_dep + +class TestAddKernelToBootLoader(unittest.TestCase): + + def add_to_bootloader(self, base_args, args, bootloader_args, + bootloader_root, tag='image', image='image', + initrd='initrd'): + god = mock.mock_god() + bootloader = god.create_mock_class(boottool.boottool, "boottool") + + # record + bootloader.remove_kernel.expect_call(tag) + bootloader.add_kernel.expect_call(image, tag, initrd=initrd, + args=bootloader_args, + root=bootloader_root) + + # run and check + kernel._add_kernel_to_bootloader(bootloader, base_args, tag, args, + image, initrd) + god.check_playback() + + + def test_add_kernel_to_bootloader(self): + self.add_to_bootloader(base_args='baseargs', args='', + bootloader_args='baseargs', bootloader_root=None) + self.add_to_bootloader(base_args='arg1 root=/dev/oldroot arg2', + args='root=/dev/newroot arg3', + bootloader_args='arg1 arg2 arg3', + bootloader_root='/dev/newroot') + + +class TestBootableKernel(unittest.TestCase): + + def setUp(self): + self.god = mock.mock_god() + self.god.stub_function(time, "time") + self.god.stub_function(utils, "system") + self.god.stub_function(kernel, "_add_kernel_to_bootloader") + job_ = self.god.create_mock_class(job.job, "job") + self.kernel = kernel.BootableKernel(job_) + self.kernel.job.bootloader = self.god.create_mock_class( + boottool.boottool, "boottool") + + + def tearDown(self): + # note: time.time() can only be unstubbed via tearDown() + self.god.unstub_all() + + + def boot_kernel(self, ident_check): + notes = "applied_patches" + when = 1 + args = '' + base_args = 'base_args' + tag = 'ident' + subdir = 'subdir' + self.kernel.image = 'image' + self.kernel.initrd = 'initrd' + self.kernel.installed_as = tag + + # record + args_ = args + if ident_check: + time.time.expect_call().and_return(when) + args_ += " IDENT=%d" % when + status = ["job.end_reboot_and_verify", when, tag, subdir, notes] + else: + status = ["job.end_reboot", subdir, tag, notes] + self.kernel.job.next_step_prepend.expect_call(status) + self.kernel.job.config_get.expect_call( + 'boot.default_args').and_return(base_args) + kernel._add_kernel_to_bootloader.expect_call( + self.kernel.job.bootloader, base_args, tag, + args_, self.kernel.image, self.kernel.initrd) + utils.system.expect_call('touch /fastboot') + self.kernel.job.start_reboot.expect_call() + self.kernel.job.reboot.expect_call(tag=tag) + + # run and check + self.kernel._boot_kernel(args=args, ident_check=ident_check, + expected_ident=tag, subdir=subdir, notes=notes) + self.god.check_playback() + + + def test_boot_kernel(self): + self.boot_kernel(ident_check=False) + self.boot_kernel(ident_check=True) + + class TestKernel(unittest.TestCase): def setUp(self): self.god = mock.mock_god() @@ -473,47 +561,6 @@ class TestKernel(unittest.TestCase): self.god.check_playback() - def _setup_add_to_bootloader(self, tag='autotest', args='', image='image', - initrd='initrd', base_args='baseargs', - bootloader_args='baseargs', - bootloader_root=None): - self.construct_kernel() - - # setup - self.kernel.image = image - self.kernel.initrd = initrd - - # record - self.job.config_get.expect_call( - 'boot.default_args').and_return(base_args) - self.job.bootloader.remove_kernel.expect_call(tag) - self.job.bootloader.add_kernel.expect_call( - image, tag, initrd=initrd, args=bootloader_args, - root=bootloader_root) - - - def test_add_to_bootloader(self): - # setup - self._setup_add_to_bootloader() - - # run and check - self.kernel.add_to_bootloader() - self.god.check_playback() - - - def test_add_to_bootloader_root_args(self): - # setup - args = 'root=/dev/newroot arg3' - self._setup_add_to_bootloader(args=args, - base_args='arg1 root=/dev/oldroot arg2', - bootloader_args='arg1 arg2 arg3', - bootloader_root='/dev/newroot') - - # run and check - self.kernel.add_to_bootloader(args=args) - self.god.check_playback() - - def test_get_kernel_build_arch1(self): self.construct_kernel() @@ -573,51 +620,23 @@ class TestKernel(unittest.TestCase): self.construct_kernel() self.god.stub_function(self.kernel, "get_kernel_build_ident") self.god.stub_function(self.kernel, "install") - self.god.stub_function(self.kernel, "add_to_bootloader") + self.god.stub_function(self.kernel, "_boot_kernel") self.kernel.applied_patches = "applied_patches" - when = 1 - args = '' - self.kernel.installed_as = False - - # record - self.kernel.get_kernel_build_ident.expect_call().and_return("ident") - time.time.expect_call().and_return(when) - args += " IDENT=%d" % (when) - self.job.next_step_prepend.expect_call(["job.end_reboot_and_verify", - when, "ident", self.subdir, self.kernel.applied_patches]) - self.kernel.install.expect_call() - self.kernel.add_to_bootloader.expect_call(args=args, - tag=False) - self.job.start_reboot.expect_call() - self.job.reboot.expect_call(tag=False) - - # run and check - self.kernel.boot() - self.god.check_playback() - - - def test_boot_without_ident(self): - self.construct_kernel() - self.god.stub_function(self.kernel, "get_kernel_build_ident") - self.god.stub_function(self.kernel, "install") - self.god.stub_function(self.kernel, "add_to_bootloader") - self.kernel.applied_patches = "applied_patches" - when = 1 + self.kernel.installed_as = None args = '' - self.kernel.installed_as = False + expected_ident = 'ident' + ident = True # record - self.kernel.get_kernel_build_ident.expect_call().and_return("ident") - self.job.next_step_prepend.expect_call(["job.end_reboot", - self.subdir, "ident", self.kernel.applied_patches]) self.kernel.install.expect_call() - self.kernel.add_to_bootloader.expect_call(args=args, - tag=False) - self.job.start_reboot.expect_call() - self.job.reboot.expect_call(tag=False) + self.kernel.get_kernel_build_ident.expect_call( + ).and_return(expected_ident) + self.kernel._boot_kernel.expect_call( + args, ident, expected_ident, + self.subdir, self.kernel.applied_patches) # run and check - self.kernel.boot(ident=False) + self.kernel.boot(args=args, ident=ident) self.god.check_playback() -- 1.7.2.1 _______________________________________________ Autotest mailing list [email protected] http://test.kernel.org/cgi-bin/mailman/listinfo/autotest
