From: Christian Herdtweck Date: Thu, 22 Jan 2015 16:21:24 +0000 (+0100) Subject: added saving of history and results and function to load and print stats about them X-Git-Url: http://developer.intra2net.com/git/?a=commitdiff_plain;h=4c50ece18fc3260f2634712bc6ef31c81f13fd28;p=pingcheck added saving of history and results and function to load and print stats about them --- diff --git a/test/long_term_test.py b/test/long_term_test.py index 989a1ed..98146eb 100755 --- a/test/long_term_test.py +++ b/test/long_term_test.py @@ -28,6 +28,8 @@ from os.path import expanduser, dirname, isdir from os import mkdir, EX_OK from connd_state import ConndState #import signal +import pickle +from strftimedelta import strftimedelta logger_base = logging.getLogger('long_term_test') @@ -655,6 +657,11 @@ def parse_args(): + "using tell-connd and checks log for correct output", \ epilog="(c) Christian Herdtweck, Intra2net AG, 2015") + # option to show saved data + parser.add_argument('--show-saved-data', '-s', metavar='SAVE_FILE.pickle', \ + default='', type=str, \ + help='Do not run test but instead print info saved by earlier test run') + # binaries parser.add_argument('--pingcheck-binary', '-p', metavar='PATH', \ default=default_pingcheck_bin, \ @@ -755,15 +762,14 @@ def setup_logging(opts): #end: setup_logging -def handle_sigchild(log, pinger, tester, signum, curr_frame): - print("\n!received sigchild!\n") +def handle_sigchild(signum, curr_frame, log, cleanup_args): log.error('Received SIGCHLD') log.info('with args {0} and {1}'.format(signum, curr_frame)) - cleanup(log, pinger, tester) + cleanup(*cleanup_args) -def cleanup(log, pinger, tester, line_iter): +def cleanup(log, pinger, tester, line_iter, save_file): """ the stuff from finally clause in main loop; also called from handle_sigchild """ return_code = 255 @@ -838,6 +844,9 @@ def main(): opts = parse_args() + if opts.show_saved_data: + return Tester.show_saved_data(opts.show_saved_data) + base_dir = dirname(opts.output_prefix + "_test") if not isdir(base_dir): mkdir(base_dir) @@ -853,10 +862,12 @@ def main(): #test_version(opts.pingcheck_binary, log) config_file, n_hosts = create_conf_file(opts.output_prefix) + save_file = opts.output_prefix + '_save.pickle' log.info('created config file {0}'.format(config_file)) #signal.signal(signal.SIGCHLD, \ - # lambda signum, curr_frame: handle_sigchild(log, pinger, tester, signum, curr_frame)) + # lambda signum, curr_frame: handle_sigchild(signum, curr_frame, log, \ + # (log, pinger, tester, line_iter, save_file) ) # pingcheck subprocess pinger = subprocess.Popen([opts.pingcheck_binary, '--log-level', opts.pinger_log_level, \ diff --git a/test/strftimedelta.py b/test/strftimedelta.py new file mode 100644 index 0000000..4596c2a --- /dev/null +++ b/test/strftimedelta.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python3 + +""" give a nice string representation for a duration + +Christian Herdtweck, Intra2net, November 2014 +Licensed under GPL +""" + +from datetime import timedelta + +# Version History +# 24/11/14 Christian Herdtweck: started creation by copying strftimedelta + + +def strftimedelta(delta, max_parts=2, only_up_to_hours=False): + """ nice and length-adjustable text representation of a timespan + + will output the most significant non-zero time units, e.g. + '2h23m50s' or '3d50s12ms' (skipping 0 minutes), or '3y63d12h' + or for max_parts=2: '2h23m' / '3d50s' / '3y63d' + + Assumes that each year has 365 days, every day 24h, every hour 60 mins, ... + not accounting for leap years / leap days, changes of timezones, etc + + @delta:timedelta or anything that can be converted to float; + if numeric, this is interpreted as number of seconds + @param max_parts: precision (i.e., length) of output (default: 2) + set to None if always want precision down to microseconds + @param only_up_to_hours: set to True to never give number of days/years + (e.g. to get '40h' instead of '1d16h') + default: False + + returns a string + """ + + units = '\u00B5s', 'ms', 's', 'm', 'h', 'd', 'y' + + if (max_parts is None) or (max_parts < 1): + max_parts = 100 + + # get number of seconds and sign + if isinstance(delta, timedelta): + seconds = delta.total_seconds() + else: + seconds = float(delta) + negative = False + if seconds < 0: + negative = True + seconds = abs(seconds) + + # split sub-second part + seconds, second_part = divmod(seconds, 1) + milliseconds, milli_part = divmod(second_part*1000, 1) + microseconds = int(round(milli_part*1000)) + seconds = int(seconds) # convert to int here --> all other variables will be int + vals = [microseconds, int(milliseconds), ] + + # split longer units + minutes = hours = days = years = 0 + if seconds > 0: + minutes, seconds = divmod(seconds, 60) + if minutes > 0: + hours, minutes = divmod(minutes, 60) + if hours > 0 and not only_up_to_hours: + days, hours = divmod(hours, 24) + if days > 0: + years, days = divmod(days, 365) + vals.append(seconds) + vals.append(minutes) + vals.append(hours) + vals.append(days) + vals.append(years) + + # build string + str_parts = [] + if negative: + str_parts.append('-') + + n_used = 0 + for val,unit in zip( reversed(vals), reversed(units) ): + if val == 0: + continue + str_parts.append(str(val)) + str_parts.append(unit) + n_used += 1 + if n_used >= max_parts: + break + return ''.join(str_parts) + +#end: strftimedelta + + + +def main(): + """ Main function, called when running file as script; currently raises a NotImplementedError + """ + raise NotImplementedError('nothing to run here -- only a lib!') +#end: function main + + +if __name__ == '__main__': + main() + +# (created using vim -- the world's best text editor) +