Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(44)

Unified Diff: client/tests/wb_kupdate/wb_kupdate.py

Issue 6539001: Merge remote branch 'cros/upstream' into master. (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/autotest.git@master
Patch Set: patch Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « client/tests/wb_kupdate/control ('k') | client/tests/wb_kupdate/wb_kupdate_unittest.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: client/tests/wb_kupdate/wb_kupdate.py
diff --git a/client/tests/wb_kupdate/wb_kupdate.py b/client/tests/wb_kupdate/wb_kupdate.py
new file mode 100644
index 0000000000000000000000000000000000000000..9d77ed8f2cbde50fc9842229630c3ce99cef06ce
--- /dev/null
+++ b/client/tests/wb_kupdate/wb_kupdate.py
@@ -0,0 +1,269 @@
+import datetime, logging, os, time
+from autotest_lib.client.bin import test, utils
+from autotest_lib.client.common_lib import error
+
+class wb_kupdate(test.test):
+ version = 1
+
+
+ def _check_parameters(self, mount_point, write_size, file_count,
+ old_cleanup=False):
+ """
+ Check all test parameters.
+
+ @param mount_point: the path to the desired mount_point.
+ @param write_size: the size of data in MB to write.
+ @param file_count: the number of files to write.
+ @param old_cleanup: removes previous mount_point if it exists and is
+ not mounted. Default is False.
+ """
+ # Check mount_point.
+ if not os.path.exists(mount_point):
+ logging.info('%s does not exist. Creating directory.', mount_point)
+ elif not os.path.ismount(mount_point) and old_cleanup:
+ logging.info('Removing previous mount_point directory')
+ os.rmdir(mount_point)
+ logging.info('Creating new mount_point.')
+ else:
+ raise error.TestError('Mount point: %s already exists.' %
+ mount_point)
+
+ os.makedirs(mount_point)
+ # Check write_size > 0.
+ if not (write_size > 0):
+ raise error.TestError('Write size should be a positive integer.')
+
+ # Check file_count > 0.
+ if not (file_count > 0) :
+ raise error.TestError('File count shoulde be a positive integer.')
+
+
+ def _reset_device(self):
+ """
+ Reset the test. Reinitialize sparse file.
+ """
+ # Umount device.
+ logging.debug('Cleanup - unmounting loopback device.')
+ utils.system('umount %s' % self.mount_point, ignore_status=True)
+
+ # Remove sparse_file.
+ logging.debug('Cleanup - removing sparse file.')
+ os.remove(self.sparse_file)
+
+ # Remove mount_point directory.
+ logging.debug('Cleanup - removing the mount_point.')
+ os.rmdir(self.mount_point)
+
+
+ def _create_partition(self):
+ """
+ Create and initialize the sparse file.
+ """
+ # Recreate sparse_file.
+ utils.system('dd if=/dev/zero of=%s bs=1M seek=1024 count=1' %
+ self.sparse_file)
+
+ # Format sparse_file.
+ utils.system('echo "y" | mkfs -t %s %s' %
+ (self.file_system, self.sparse_file))
+
+ # Mount sparse_file.
+ utils.system('mount -o loop -t %s %s %s' %
+ (self.file_system, self.sparse_file, self.mount_point))
+
+
+ def _needs_more_time(self, start_time, duration, _now=None):
+ """
+ Checks to see if the test has run its course.
+
+ @param start_time: a datetime object specifying the start time of the
+ test.
+ @param duration: test duration in minutes.
+ @param _now: used mostly for testing - ensures that the function returns
+ pass/fail depnding on the value of _now.
+
+ @return: True if the test still needs to run longer.
+ False if the test has run for 'duration' minutes.
+ """
+ if not _now:
+ time_diff = datetime.datetime.now() - start_time
+ else:
+ time_diff = _now - start_time
+ return time_diff <= datetime.timedelta(seconds=duration*60)
+
+
+ def _write_data(self, destination, counter, write_size):
+ """
+ Writes data to the cache/memory.
+
+ @param destination: the absolute path to where the data needs to be
+ written.
+ @param counter: the file counter.
+ @param write_size: the size of data to be written.
+
+ @return: the time when the write completed as a datetime object.
+ """
+ # Write data to disk.
+ file_name = os.path.join(destination, 'test_file_%s' % counter)
+ write_cmd = ('dd if=/dev/zero of=%s bs=1M count=%s' %
+ (file_name, write_size))
+ utils.system(write_cmd)
+
+ # Time the write operation.
+ write_completion_time = datetime.datetime.now()
+
+ # Return write completion time.
+ return write_completion_time
+
+
+ def _get_disk_usage(self, file_name):
+ """
+ Returns the disk usage of given file.
+
+ @param file_name: the name of the file.
+
+ @return: the disk usage as an integer.
+ """
+ # Check du stats.
+ cmd = '%s %s' % (self._DU_CMD, file_name)
+
+ # Expected value for output = '1028\tfoo'
+ output = utils.system_output(cmd)
+
+ # Desired ouput = (1028, foo)
+ output = output.split('\t')
+
+ return int(output[0])
+
+
+ def _wait_until_data_flushed(self, start_time, max_wait_time):
+ """
+ Check to see if the sparse file size increases.
+
+ @param start_time: the time when data was actually written into the
+ cache.
+ @param max_wait_time: the max amount of time to wait.
+
+ @return: time waited as a datetime.timedelta object.
+ """
+ current_size = self._get_disk_usage(self.sparse_file)
+ flushed_size = current_size
+
+ logging.debug('current_size: %s' % current_size)
+ logging.debug('flushed_size: %s' % flushed_size)
+
+ # Keep checking until du value changes.
+ while current_size == flushed_size:
+ # Get flushed_size.
+ flushed_size = self._get_disk_usage(self.sparse_file)
+ logging.debug('flushed_size: %s' % flushed_size)
+ time.sleep(1)
+
+ # Check if data has been synced to disk.
+ if not self._needs_more_time(start_time, max_wait_time):
+ raise error.TestError('Data not flushed. Waited for %s minutes '
+ 'for data to flush out.' % max_wait_time)
+
+ # Return time waited.
+ return datetime.datetime.now() - start_time
+
+
+ def initialize(self):
+ """
+ Initialize all private and global member variables.
+ """
+ self._DU_CMD = 'du'
+ self.partition = None
+ self.mount_point = ''
+ self.sparse_file = ''
+ self.result_map = {}
+ self.file_system = None
+
+
+ def run_once(self, mount_point, file_count, write_size,
+ max_flush_time=1, file_system=None, remove_previous=False,
+ sparse_file=os.path.join(os.getcwd(),'sparse_file'),
+ old_cleanup=False):
+ """
+ Control execution of the test.
+
+ @param mount_point: the absolute path to the mount point.
+ @param file_count: the number of files to write.
+ @param write_size: the size of each file in MB.
+ @param max_flush_time: the maximum time to wait for the writeback to
+ flush dirty data to disk. Default = 1 minute.
+ @param file_system: the new file system to be mounted, if any.
+ Default = None.
+ @param remove_previous: boolean that allows the removal of previous
+ files before creating a new one. Default = False.
+ @param sparse_file: the absolute path to the sparse file.
+ @param old_cleanup: removes previous mount_point if it exists and is
+ not mounted. Default is False.
+ """
+ # Check validity of parameters.
+ self._check_parameters(mount_point, write_size, file_count,
+ old_cleanup)
+
+ # Initialize class variables.
+ self.mount_point = mount_point
+ self.sparse_file = sparse_file
+ self.file_system = file_system
+
+ # Initialize partition values.
+ self._create_partition()
+
+ # Flush read and write cache.
+ utils.drop_caches()
+
+ # Start iterations.
+ logging.info('Starting test operations.')
+ test_start_time = datetime.datetime.now()
+ counter = 1
+
+ # Run test until file_count files are successfully written to disk.
+ while counter < file_count:
+ logging.info('Iteration %s.', counter)
+
+ # Write data to disk.
+ write_completion_time = self._write_data(self.mount_point, counter,
+ write_size)
+ logging.debug('Write time:%s',
+ write_completion_time.strftime("%H:%M:%S"))
+
+ # Wait until data get synced to disk.
+ time_taken = self._wait_until_data_flushed(write_completion_time,
+ max_flush_time)
+
+ # Log time statistics.
+ logging.info('Time taken to flush data: %s seconds.',
+ time_taken.seconds)
+
+ # Check if there is a need to remove the previously written file.
+ if remove_previous:
+ logging.debug('Removing previous file instance.')
+ os.remove(file_name)
+ else:
+ logging.debug('Not removing previous file instance.')
+
+ # Flush cache.
+ logging.debug('Flush cache between iterations.')
+ utils.drop_caches()
+
+ # Update the result map.
+ self.result_map[counter] = time_taken.seconds
+
+ # Increment the counter.
+ counter += 1
+
+
+ def postprocess(self):
+ """
+ Cleanup routine.
+ """
+ # Write out keyval map.
+ self.write_perf_keyval(self.result_map)
+
+ # Cleanup device.
+ self._reset_device()
+
+ logging.info('Test operations completed.')
« no previous file with comments | « client/tests/wb_kupdate/control ('k') | client/tests/wb_kupdate/wb_kupdate_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698