Home | History | Annotate | Download | only in platform_SyncCrash
      1 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 import logging
      6 import traceback
      7 from autotest_lib.client.common_lib import error
      8 from autotest_lib.server import test
      9 
     10 class platform_SyncCrash(test.test):
     11     """Tests syncing to the file system before a crash.
     12 
     13     This test works in conjunction with testsync (found in
     14     punybench) to test various forms of sync. Testsync runs
     15     on the client to create a file, fill it with data, sync
     16     that data and crash the system.  The server side (this
     17     code), waits for the client to restart and then invokes
     18     testsync to verify the data did sync.
     19 
     20     Testsync has different phases for testing sync
     21     writer - syncs a file using fsync
     22     mapper - syncs a memory mapped file using msync
     23     verifier - verifies that content of the file
     24 
     25     The tests are run on both the stateful partition
     26     and ecryptfs mounted on a directory in the stateful
     27     partition.
     28     """
     29     version = 1
     30     _STATEFUL_DIR = '/usr/local/CrashDir/'
     31     _ECRYPT_DIR = '/usr/local/ecryptfs_tst/'
     32     _ECRYPT_MOUNT_POINT = '/usr/local/ecryptfs_mnt/'
     33     _ECRYPT_TEST_DIR = '%s/CrashDir/' % _ECRYPT_MOUNT_POINT
     34     _FILE = 'xyzzy'
     35     _Testsync = '/usr/local/opt/punybench/bin/testsync'
     36 
     37 
     38     def _run(self, cmd):
     39         """Run the given command and log results
     40 
     41         @param cmd: command to be run
     42         """
     43         result = self.client.run(cmd)
     44         if result.exit_status != 0:
     45             logging.error('%s: %s', cmd, result.stdout)
     46         else:
     47             logging.info('%s', cmd)
     48 
     49 
     50     def _testsync_crash(self, args):
     51         """Run testsync on the client
     52 
     53         Since testsync forces a crash of the system, the code
     54         waits for the reboot.
     55 
     56         @param args: arguments to pass testsync
     57         """
     58         logging.info('Crash: %s', self.client.hostname)
     59         try:
     60             cmd = '%s %s' % (self._Testsync, args)
     61             logging.info('Crash: %s', cmd)
     62             self.client.reboot(reboot_cmd=cmd)
     63         except error.AutoservRebootError as e:
     64             raise error.TestFail('%s.\nTest failed with error %s' % (
     65                     traceback.format_exc(), str(e)))
     66 
     67 
     68     def _testsync_verify(self, args):
     69         """Verify the results from previous testsync
     70 
     71         @param args: arguments to pass to testsync
     72         """
     73         cmd = '%s %s -p verifier' % (self._Testsync, args)
     74         result = self.client.run(cmd)
     75         if result.exit_status != 0:
     76             logging.error('%s: %s', cmd, result.stdout)
     77 
     78 
     79     def _ecrypt_setup(self):
     80         """Setup an eCrypt File System and mount it
     81         """
     82         edir = self._ECRYPT_DIR
     83         mnt = self._ECRYPT_MOUNT_POINT
     84         options = ('-o'
     85                    ' key=passphrase:passphrase_passwd=secret'
     86                    ',ecryptfs_cipher=aes'
     87                    ',ecryptfs_key_bytes=32'
     88                    ',no_sig_cache'
     89                    ',ecryptfs_passthrough=no'
     90                    ',ecryptfs_enable_filename_crypto=no')
     91         self._run('mkdir -p %s %s' % (edir, mnt))
     92         self._run('mount -t ecryptfs %s %s %s' %
     93                            (options, edir, mnt))
     94 
     95 
     96     def _ecrypt_teardown(self):
     97         """Teardown the eCrypt File System
     98         """
     99         edir = self._ECRYPT_DIR
    100         mnt = self._ECRYPT_MOUNT_POINT
    101         self._run('umount %s' % mnt)
    102         self._run('rm -R %s %s' % (edir, mnt))
    103 
    104 
    105     def _sync_stateful(self, dir, phase):
    106         """Crash the stateful file system while changing it
    107 
    108         @param dir - directory where test files are created
    109         @param phase - which phase of testsync to invoke
    110         """
    111         size = 0x1000
    112         file = dir + self._FILE
    113         self._run('mkdir -p %s' % dir)
    114         self._testsync_crash('-f %s -z %s -p %s' % (file, size, phase))
    115         self._testsync_verify('-f %s -z %s' % (file, size))
    116         self._run('rm -r %s' % dir)
    117 
    118 
    119     def _sync_ecryptfs(self, dir, phase):
    120         """Crash an ecryptfs file system right after a sync
    121 
    122         @param edir - directory used for the encrypted file system
    123         @param mnt - mount point for the encrypted file system
    124         @param dir - directory where test files are created
    125         @param phase - which phase of testsync to invoke
    126         """
    127         size = 0x1000
    128         file = dir + self._FILE
    129         self._ecrypt_setup()
    130         self._run('mkdir -p %s' % dir)
    131         self._testsync_crash('-f %s -z %s -p %s' % (file, size, phase))
    132         self._ecrypt_setup()
    133         self._testsync_verify('-f %s -z %s' % (file, size))
    134         self._run('rm -r %s' % dir)
    135         self._ecrypt_teardown()
    136 
    137 
    138     def run_once(self, host=None):
    139         """run_once runs the test.
    140 
    141         1. Runs a crash test on stateful partition
    142         2. Create an ecryptfs volume and run the same
    143            crash test
    144 
    145         @param host - the host machine running the test
    146         """
    147         self.client = host
    148 
    149         self._sync_stateful(self._STATEFUL_DIR, 'writer')
    150         self._sync_stateful(self._STATEFUL_DIR, 'mapper')
    151 
    152         self._sync_ecryptfs(self._ECRYPT_TEST_DIR, 'writer')
    153         self._sync_ecryptfs(self._ECRYPT_TEST_DIR, 'mapper')
    154