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

Reply via email to