153 lines
5.3 KiB
Python
153 lines
5.3 KiB
Python
# 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)
|