# Copyright (c) 2012 The Chromium OS Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import os from autotest_lib.client.bin import utils from autotest_lib.client.cros import storage as storage_mod from autotest_lib.client.common_lib import autotemp, error class hardware_UsbBasicFileOperations(storage_mod.StorageTester): version = 1 preserve_srcdir = True _src, _dst = None, None def run_once(self, volume_filter={'bus':'usb'}): storage = self.wait_for_device(volume_filter, cycles=1, mount_volume=True)[0] mount_point = storage['mountpoint'] # -> Megabytes size = 1*1024*1024 self._src = autotemp.tempfile(unique_id='tmpfile', dir=mount_point) self._dst = autotemp.tempfile(unique_id='autotest', dir=self.tmpdir) # Step 1: check if file creation works try: storage_mod.create_file(self._src.name, size) except error.CmdError, e: msg = ('fatal error occurred during file creation: ' 'basic file operation failed: %s' % e) raise error.TestFail(msg) # not part of current check, remember the value for later use src_md5 = storage_mod.checksum_file(self._src.name) # Step 2: check if open works try: f = open(self._src.name, 'rb') except Exception, e: msg = ('fatal error occurred during open(): ' 'basic file operation failed: %s' % e) raise error.TestFail(msg) try: f.read() except Exception, e: msg = ('fatal error occurred during read(): ' 'basic file operation failed: %s' % e) raise error.TestFail(msg) try: f.close() except Exception, e: msg = ('fatal error occurred during close(): ' 'basic file operation failed: %s' % e) raise error.TestFail(msg) # Step 3: check if file copy works try: utils.force_copy(self._src.name, self._dst.name) except Exception, e: msg = ('fatal error occurred during a file copy: ' 'basic file operation failed: %s' % e) raise error.TestFail(msg) if src_md5 != storage_mod.checksum_file(self._dst.name): msg = ('fatal error occurred during a file copy, ' 'md5 from origin and from destination are different: ' 'basic file operation failed') raise error.TestFail(msg) # Step 4: check if file removal works try: os.remove(self._src.name) except OSError, e: msg = ('fatal error occurred during file removal: ' 'basic file operation failed: %s' % e) raise error.TestFail(msg) if os.path.isfile(self._src.name): msg = ('fatal error occurred during file removal: ' 'file still present after command, ' 'basic file operation failed') raise error.TestFail(msg) utils.drop_caches() if os.path.isfile(self._src.name): msg = ('fatal error occurred during file removal: ' 'file still present after command issued and ' 'disk cached flushed), ' 'basic file operation failed') raise error.TestFail(msg) # Step 5: check if modification to a file are persistent # copy file, modify src and modify dst the same way, checksum storage_mod.create_file(self._src.name, size) utils.force_copy(self._src.name, self._dst.name) # apply the same change to both files (which are identical in origin) src_md5 = modify_file(self._src.name) dst_md5 = modify_file(self._dst.name) # both copy of they file have to be the same if src_md5 != dst_md5: msg = ('fatal error occurred after modifying src and dst: ' 'md5 checksums differ - %s / %s ,' 'basic file operation failed' % (src_md5, dst_md5)) raise error.TestFail(msg) def cleanup(self): if self._src: self._src.clean() if self._dst: self._dst.clean() self.scanner.unmount_all() super(hardware_UsbBasicFileOperations, self).cleanup() def modify_file(path): '''Modify a file returning its new MD5 Open |path|, change a byte within the file and return the new md5. The change applied to the file is based on the file content and size. This means that identical files will result in identical changes and thus will return the same MD5. @param path: a path to the file to be modified @return the MD5 of |path| after the modification ''' position = os.path.getsize(path) / 2 # modify the file means: read a char, increase its value and write it back # given the same file (identical in size and bytes) it will apply the same # change f = open(path, 'r+b') f.seek(position) c = f.read(1) f.seek(position) f.write(chr(ord(c)+1)) f.close() return storage_mod.checksum_file(path)