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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« 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 »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 import datetime, logging, os, time
2 from autotest_lib.client.bin import test, utils
3 from autotest_lib.client.common_lib import error
4
5 class wb_kupdate(test.test):
6 version = 1
7
8
9 def _check_parameters(self, mount_point, write_size, file_count,
10 old_cleanup=False):
11 """
12 Check all test parameters.
13
14 @param mount_point: the path to the desired mount_point.
15 @param write_size: the size of data in MB to write.
16 @param file_count: the number of files to write.
17 @param old_cleanup: removes previous mount_point if it exists and is
18 not mounted. Default is False.
19 """
20 # Check mount_point.
21 if not os.path.exists(mount_point):
22 logging.info('%s does not exist. Creating directory.', mount_point)
23 elif not os.path.ismount(mount_point) and old_cleanup:
24 logging.info('Removing previous mount_point directory')
25 os.rmdir(mount_point)
26 logging.info('Creating new mount_point.')
27 else:
28 raise error.TestError('Mount point: %s already exists.' %
29 mount_point)
30
31 os.makedirs(mount_point)
32 # Check write_size > 0.
33 if not (write_size > 0):
34 raise error.TestError('Write size should be a positive integer.')
35
36 # Check file_count > 0.
37 if not (file_count > 0) :
38 raise error.TestError('File count shoulde be a positive integer.')
39
40
41 def _reset_device(self):
42 """
43 Reset the test. Reinitialize sparse file.
44 """
45 # Umount device.
46 logging.debug('Cleanup - unmounting loopback device.')
47 utils.system('umount %s' % self.mount_point, ignore_status=True)
48
49 # Remove sparse_file.
50 logging.debug('Cleanup - removing sparse file.')
51 os.remove(self.sparse_file)
52
53 # Remove mount_point directory.
54 logging.debug('Cleanup - removing the mount_point.')
55 os.rmdir(self.mount_point)
56
57
58 def _create_partition(self):
59 """
60 Create and initialize the sparse file.
61 """
62 # Recreate sparse_file.
63 utils.system('dd if=/dev/zero of=%s bs=1M seek=1024 count=1' %
64 self.sparse_file)
65
66 # Format sparse_file.
67 utils.system('echo "y" | mkfs -t %s %s' %
68 (self.file_system, self.sparse_file))
69
70 # Mount sparse_file.
71 utils.system('mount -o loop -t %s %s %s' %
72 (self.file_system, self.sparse_file, self.mount_point))
73
74
75 def _needs_more_time(self, start_time, duration, _now=None):
76 """
77 Checks to see if the test has run its course.
78
79 @param start_time: a datetime object specifying the start time of the
80 test.
81 @param duration: test duration in minutes.
82 @param _now: used mostly for testing - ensures that the function returns
83 pass/fail depnding on the value of _now.
84
85 @return: True if the test still needs to run longer.
86 False if the test has run for 'duration' minutes.
87 """
88 if not _now:
89 time_diff = datetime.datetime.now() - start_time
90 else:
91 time_diff = _now - start_time
92 return time_diff <= datetime.timedelta(seconds=duration*60)
93
94
95 def _write_data(self, destination, counter, write_size):
96 """
97 Writes data to the cache/memory.
98
99 @param destination: the absolute path to where the data needs to be
100 written.
101 @param counter: the file counter.
102 @param write_size: the size of data to be written.
103
104 @return: the time when the write completed as a datetime object.
105 """
106 # Write data to disk.
107 file_name = os.path.join(destination, 'test_file_%s' % counter)
108 write_cmd = ('dd if=/dev/zero of=%s bs=1M count=%s' %
109 (file_name, write_size))
110 utils.system(write_cmd)
111
112 # Time the write operation.
113 write_completion_time = datetime.datetime.now()
114
115 # Return write completion time.
116 return write_completion_time
117
118
119 def _get_disk_usage(self, file_name):
120 """
121 Returns the disk usage of given file.
122
123 @param file_name: the name of the file.
124
125 @return: the disk usage as an integer.
126 """
127 # Check du stats.
128 cmd = '%s %s' % (self._DU_CMD, file_name)
129
130 # Expected value for output = '1028\tfoo'
131 output = utils.system_output(cmd)
132
133 # Desired ouput = (1028, foo)
134 output = output.split('\t')
135
136 return int(output[0])
137
138
139 def _wait_until_data_flushed(self, start_time, max_wait_time):
140 """
141 Check to see if the sparse file size increases.
142
143 @param start_time: the time when data was actually written into the
144 cache.
145 @param max_wait_time: the max amount of time to wait.
146
147 @return: time waited as a datetime.timedelta object.
148 """
149 current_size = self._get_disk_usage(self.sparse_file)
150 flushed_size = current_size
151
152 logging.debug('current_size: %s' % current_size)
153 logging.debug('flushed_size: %s' % flushed_size)
154
155 # Keep checking until du value changes.
156 while current_size == flushed_size:
157 # Get flushed_size.
158 flushed_size = self._get_disk_usage(self.sparse_file)
159 logging.debug('flushed_size: %s' % flushed_size)
160 time.sleep(1)
161
162 # Check if data has been synced to disk.
163 if not self._needs_more_time(start_time, max_wait_time):
164 raise error.TestError('Data not flushed. Waited for %s minutes '
165 'for data to flush out.' % max_wait_time)
166
167 # Return time waited.
168 return datetime.datetime.now() - start_time
169
170
171 def initialize(self):
172 """
173 Initialize all private and global member variables.
174 """
175 self._DU_CMD = 'du'
176 self.partition = None
177 self.mount_point = ''
178 self.sparse_file = ''
179 self.result_map = {}
180 self.file_system = None
181
182
183 def run_once(self, mount_point, file_count, write_size,
184 max_flush_time=1, file_system=None, remove_previous=False,
185 sparse_file=os.path.join(os.getcwd(),'sparse_file'),
186 old_cleanup=False):
187 """
188 Control execution of the test.
189
190 @param mount_point: the absolute path to the mount point.
191 @param file_count: the number of files to write.
192 @param write_size: the size of each file in MB.
193 @param max_flush_time: the maximum time to wait for the writeback to
194 flush dirty data to disk. Default = 1 minute.
195 @param file_system: the new file system to be mounted, if any.
196 Default = None.
197 @param remove_previous: boolean that allows the removal of previous
198 files before creating a new one. Default = False.
199 @param sparse_file: the absolute path to the sparse file.
200 @param old_cleanup: removes previous mount_point if it exists and is
201 not mounted. Default is False.
202 """
203 # Check validity of parameters.
204 self._check_parameters(mount_point, write_size, file_count,
205 old_cleanup)
206
207 # Initialize class variables.
208 self.mount_point = mount_point
209 self.sparse_file = sparse_file
210 self.file_system = file_system
211
212 # Initialize partition values.
213 self._create_partition()
214
215 # Flush read and write cache.
216 utils.drop_caches()
217
218 # Start iterations.
219 logging.info('Starting test operations.')
220 test_start_time = datetime.datetime.now()
221 counter = 1
222
223 # Run test until file_count files are successfully written to disk.
224 while counter < file_count:
225 logging.info('Iteration %s.', counter)
226
227 # Write data to disk.
228 write_completion_time = self._write_data(self.mount_point, counter,
229 write_size)
230 logging.debug('Write time:%s',
231 write_completion_time.strftime("%H:%M:%S"))
232
233 # Wait until data get synced to disk.
234 time_taken = self._wait_until_data_flushed(write_completion_time,
235 max_flush_time)
236
237 # Log time statistics.
238 logging.info('Time taken to flush data: %s seconds.',
239 time_taken.seconds)
240
241 # Check if there is a need to remove the previously written file.
242 if remove_previous:
243 logging.debug('Removing previous file instance.')
244 os.remove(file_name)
245 else:
246 logging.debug('Not removing previous file instance.')
247
248 # Flush cache.
249 logging.debug('Flush cache between iterations.')
250 utils.drop_caches()
251
252 # Update the result map.
253 self.result_map[counter] = time_taken.seconds
254
255 # Increment the counter.
256 counter += 1
257
258
259 def postprocess(self):
260 """
261 Cleanup routine.
262 """
263 # Write out keyval map.
264 self.write_perf_keyval(self.result_map)
265
266 # Cleanup device.
267 self._reset_device()
268
269 logging.info('Test operations completed.')
OLDNEW
« 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