Merge ~sylvain-pineau/checkbox-support:fwts_test_no_syslog into checkbox-support:master

Proposed by Sylvain Pineau
Status: Merged
Approved by: Sylvain Pineau
Approved revision: 47e1157017fb62c3e543694167bf01d566872b9e
Merged at revision: 1b7847741010f40b8135fb54fb1a5761b85f1b2f
Proposed branch: ~sylvain-pineau/checkbox-support:fwts_test_no_syslog
Merge into: checkbox-support:master
Diff against target: 219 lines (+37/-104)
1 file modified
checkbox_support/scripts/fwts_test.py (+37/-104)
Reviewer Review Type Date Requested Status
Maciej Kisielewski Approve
Sylvain Pineau (community) Needs Resubmitting
Review via email: mp+354789@code.launchpad.net

Description of the change

Compute suspend/resume timings from fwts logs to deprecate using syslog.

Tested using suspend/suspend_advanced and a modified version to suspend just 3 times with:

  set -o pipefail; checkbox-support-fwts_test -f none -l $PLAINBOX_SESSION_SHARE/suspend_single -s s3 --s3-sleep-delay=7 --s3-device-check --s3-device-check-delay=15 --s3-multiple=3 | tee $PLAINBOX_SESSION_SHARE/suspend_single_times.log

To post a comment you must log in.
Revision history for this message
Maciej Kisielewski (kissiel) wrote :

Nice stuff. I found one way I think could improve it (see below).
+1

review: Approve
Revision history for this message
Sylvain Pineau (sylvain-pineau) wrote :

fixed following Maciej's advice

review: Needs Resubmitting
Revision history for this message
Maciej Kisielewski (kissiel) wrote :

+1!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/checkbox_support/scripts/fwts_test.py b/checkbox_support/scripts/fwts_test.py
index f5be29f..3111217 100644
--- a/checkbox_support/scripts/fwts_test.py
+++ b/checkbox_support/scripts/fwts_test.py
@@ -2,10 +2,8 @@
22
3import sys3import sys
4import re4import re
5from time import time
6from argparse import ArgumentParser, RawTextHelpFormatter, REMAINDER5from argparse import ArgumentParser, RawTextHelpFormatter, REMAINDER
7from subprocess import Popen, PIPE6from subprocess import Popen, PIPE, DEVNULL
8from syslog import syslog, LOG_INFO
9from shutil import which7from shutil import which
10import os8import os
119
@@ -48,42 +46,29 @@ HWE_TESTS = ['version',
48 'oops']46 'oops']
49# By default, we launch all the tests47# By default, we launch all the tests
50TESTS = sorted(list(set(QA_TESTS + HWE_TESTS)))48TESTS = sorted(list(set(QA_TESTS + HWE_TESTS)))
49SLEEP_TIME_RE = re.compile('(Suspend|Resume):\s+([\d\.]+)\s+seconds.')
5150
5251
53def get_sleep_times(start_marker, end_marker, sleep_time, resume_time):52def get_sleep_times(log, start_marker):
54 logfile = '/var/log/syslog'53 suspend_time = ''
55 log_fh = open(logfile, 'r', encoding='UTF-8')54 resume_time = ''
56 line = ''55 with open(log, 'r', encoding='UTF-8', errors = 'ignore') as f:
57 run = 'FAIL'56 line = ''
58 sleep_start_time = 0.057 while start_marker not in line:
59 sleep_end_time = 0.058 line = f.readline()
60 resume_start_time = 0.059 if start_marker in line:
61 resume_end_time = 0.060 loglist = f.readlines()
6261 for i, l in enumerate(loglist):
63 while start_marker not in line:62 if 'Suspend/Resume Timings:' in l:
64 try:63 suspend_line = loglist[i+1]
65 line = log_fh.readline()64 resume_line = loglist[i+2]
66 except UnicodeDecodeError:65 match = SLEEP_TIME_RE.search(suspend_line)
67 continue66 if match:
68 if start_marker in line:67 suspend_time = float(match.group(2))
69 loglist = log_fh.readlines()68 match = SLEEP_TIME_RE.search(resume_line)
7069 if match:
71 for idx in range(0, len(loglist)):70 resume_time = float(match.group(2))
72 if 'PM: Syncing filesystems' in loglist[idx]:71 return (suspend_time, resume_time)
73 sleep_start_time = re.split('[\[\]]', loglist[idx])[1].strip()
74 if 'ACPI: Low-level resume complete' in loglist[idx]:
75 sleep_end_time = re.split('[\[\]]', loglist[idx - 1])[1].strip()
76 resume_start_time = re.split('[\[\]]', loglist[idx])[1].strip()
77 idx += 1
78 if 'Restarting tasks' in loglist[idx]:
79 resume_end_time = re.split('[\[\]]', loglist[idx])[1].strip()
80 if end_marker in loglist[idx]:
81 run = 'PASS'
82 break
83
84 sleep_elapsed = float(sleep_end_time) - float(sleep_start_time)
85 resume_elapsed = float(resume_end_time) - float(resume_start_time)
86 return (run, sleep_elapsed, resume_elapsed)
8772
8873
89def average_times(runs):74def average_times(runs):
@@ -92,8 +77,8 @@ def average_times(runs):
92 run_count = 077 run_count = 0
93 for run in runs.keys():78 for run in runs.keys():
94 run_count += 179 run_count += 1
95 sleep_total += runs[run][1]80 sleep_total += runs[run][0]
96 resume_total += runs[run][2]81 resume_total += runs[run][1]
97 sleep_avg = sleep_total / run_count82 sleep_avg = sleep_total / run_count
98 resume_avg = resume_total / run_count83 resume_avg = resume_total / run_count
99 print('Average time to sleep: %0.5f' % sleep_avg)84 print('Average time to sleep: %0.5f' % sleep_avg)
@@ -163,25 +148,6 @@ def main():
163 'test as FAILED_CRITICAL. You will still be '148 'test as FAILED_CRITICAL. You will still be '
164 'notified of all FWTS test failures. '149 'notified of all FWTS test failures. '
165 '[Default level: %(default)s]'))150 '[Default level: %(default)s]'))
166 sleep_args = parser.add_argument_group('Sleep Options',
167 ('The following arguments are to '
168 'only be used with the '
169 '--sleep test option'))
170 sleep_args.add_argument('--sleep-time',
171 dest='sleep_time',
172 action='store',
173 help=('The max time in seconds that a system '
174 'should take\nto completely enter sleep. '
175 'Anything more than this\ntime will cause '
176 'that test iteration to fail.\n'
177 '[Default: 10s]'))
178 sleep_args.add_argument('--resume-time',
179 dest='resume_time',
180 action='store',
181 help=('Same as --sleep-time, except this applies '
182 'to the\ntime it takes a system to fully '
183 'wake from sleep.\n[Default: 3s]'))
184
185 group = parser.add_mutually_exclusive_group()151 group = parser.add_mutually_exclusive_group()
186 group.add_argument('-t', '--test',152 group.add_argument('-t', '--test',
187 action='append',153 action='append',
@@ -242,10 +208,6 @@ def main():
242 'FAILED_ABORTED': -1}208 'FAILED_ABORTED': -1}
243 fail_priority = fail_levels[args.fail_level]209 fail_priority = fail_levels[args.fail_level]
244210
245 # Enforce only using sleep opts with --sleep
246 if args.sleep_time or args.resume_time and not args.sleep:
247 parser.error('--sleep-time and --resume-time only apply to the '
248 '--sleep testing option.')
249 if args.fwts_help:211 if args.fwts_help:
250 Popen('fwts -h', shell=True).communicate()[0]212 Popen('fwts -h', shell=True).communicate()[0]
251 return 0213 return 0
@@ -278,23 +240,6 @@ def main():
278 if s4 in args.sleep:240 if s4 in args.sleep:
279 iterations = int(args.sleep.pop(args.sleep.index(s4) + 1))241 iterations = int(args.sleep.pop(args.sleep.index(s4) + 1))
280 args.sleep.remove(s4)242 args.sleep.remove(s4)
281 # if we've passed our custom sleep arguments for resume or sleep
282 # time, we need to intercept those as well.
283 resume_time_arg = '--resume-time'
284 sleep_time_arg = '--sleep-time'
285 if resume_time_arg in args.sleep:
286 args.resume_time = int(args.sleep.pop(
287 args.sleep.index(resume_time_arg) + 1))
288 args.sleep.remove(resume_time_arg)
289 if sleep_time_arg in args.sleep:
290 args.sleep_time = int(args.sleep.pop(
291 args.sleep.index(sleep_time_arg) + 1))
292 args.sleep.remove(sleep_time_arg)
293 # if we still haven't set a sleep or resume time, use defauts.
294 if not args.sleep_time:
295 args.sleep_time = 10
296 if not args.resume_time:
297 args.resume_time = 3
298 tests.extend(args.sleep)243 tests.extend(args.sleep)
299 else:244 else:
300 tests.extend(TESTS)245 tests.extend(TESTS)
@@ -306,31 +251,22 @@ def main():
306 progress_indicator = None251 progress_indicator = None
307 if detect_progress_indicator():252 if detect_progress_indicator():
308 progress_indicator = Popen(detect_progress_indicator(),253 progress_indicator = Popen(detect_progress_indicator(),
309 stdin=PIPE)254 stdin=PIPE, stderr=DEVNULL)
310 for iteration in range(0, iterations):255 for iteration in range(1, iterations+1):
311 timestamp = int(time())256 marker = '{:=^80}\n'.format(' Iteration {} '.format(iteration))
312 start_marker = 'CHECKBOX SLEEP TEST START %s' % timestamp257 with open(args.log + '.log', 'a') as f:
313 end_marker = 'CHECKBOX SLEEP TEST STOP %s' % timestamp258 f.write(marker)
314 syslog(LOG_INFO, '---' + start_marker + '---' + str(time()))
315 command = ('fwts -q --stdout-summary -r %s %s'259 command = ('fwts -q --stdout-summary -r %s %s'
316 % (args.log, ' '.join(tests)))260 % (args.log, ' '.join(tests)))
317 results['sleep'] = (Popen(command, stdout=PIPE, shell=True)261 results['sleep'] = (Popen(command, stdout=PIPE, shell=True)
318 .communicate()[0].strip()).decode()262 .communicate()[0].strip()).decode()
319 syslog(LOG_INFO, '---' + end_marker + '---' + str(time()))
320 if 's4' not in args.sleep:263 if 's4' not in args.sleep:
321 sleep_times = get_sleep_times(start_marker,264 suspend_time, resume_time = get_sleep_times(args.log + '.log',
322 end_marker,265 marker)
323 args.sleep_time,266 iteration_results[iteration] = (suspend_time, resume_time)
324 args.resume_time)267 progress_string = (
325 iteration_results[iteration] = sleep_times268 'Cycle %s/%s - Suspend: %0.2f s - Resume: %0.2f s'
326 progress_tuple = (iteration,269 % (iteration, iterations, suspend_time, resume_time))
327 iteration_results[iteration][0],
328 iteration_results[iteration][1],
329 iteration_results[iteration][2])
330 progress_string = (' - Cycle %s: Status: %s '
331 'Sleep Elapsed: %0.5f '
332 'Resume Elapsed: '
333 ' %0.5f' % progress_tuple)
334 progress_pct = "{}".format(int(100 * iteration / iterations))270 progress_pct = "{}".format(int(100 * iteration / iterations))
335 if "zenity" in detect_progress_indicator():271 if "zenity" in detect_progress_indicator():
336 progress_indicator.stdin.write("# {}\n".format(272 progress_indicator.stdin.write("# {}\n".format(
@@ -354,15 +290,11 @@ def main():
354 if progress_indicator.poll() is None:290 if progress_indicator.poll() is None:
355 progress_indicator.stdin.flush()291 progress_indicator.stdin.flush()
356 else:292 else:
357 print(progress_string)293 print(progress_string, flush=True)
358 if detect_progress_indicator():294 if detect_progress_indicator():
359 progress_indicator.terminate()295 progress_indicator.terminate()
360
361 if 's4' not in args.sleep:296 if 's4' not in args.sleep:
362 average_times(iteration_results)297 average_times(iteration_results)
363 for run in iteration_results.keys():
364 if 'FAIL' in iteration_results[run]:
365 results['sleep'] = 'FAILED_CRITICAL'
366 else:298 else:
367 for test in tests:299 for test in tests:
368 # ACPI tests can now be run with --acpitests (fwts >= 15.07.00)300 # ACPI tests can now be run with --acpitests (fwts >= 15.07.00)
@@ -451,5 +383,6 @@ def main():
451383
452 return 0384 return 0
453385
386
454if __name__ == '__main__':387if __name__ == '__main__':
455 sys.exit(main())388 sys.exit(main())

Subscribers

People subscribed via source and target branches