| #!/usr/bin/python |
| # Copyright 2012 Google Inc. All Rights Reserved. |
| |
| """This Class writes test progress/error/result to files. |
| |
| This file defines the logging function of the automation test. It |
| logs test progress, results, error/warning to different files: |
| |
| results.txt: this is the file to log the test output |
| error.txt: all test errors are logged into this file |
| prompt.txt: a copy of terminal output, which hints the progress |
| of the current test. |
| """ |
| |
| __author__ = 'Lehan Meng (lmeng@google.com)' |
| |
| |
| import datetime |
| |
| |
| class Logging(object): |
| """This Class collects and writes test information to log files.""" |
| |
| params = {'std_out': '1', |
| 'f_result': 'result.log', |
| 'f_error': 'error.log', |
| 'f_progress': 'progress.log', |
| 'delimiter': '\t'} |
| |
| def __init__(self, **kwargs): |
| """initiate the logging instance. |
| |
| Args: |
| kwargs['f_result']: file name for test result |
| kwargs['f_error']: file name for test errors |
| kwargs['f_progres']: file name for test progres |
| kwargs['std_out']: by default, send a copy of the log info to stdout |
| """ |
| for s in ('f_result', 'f_error', 'f_progress', 'std_out'): |
| if s in kwargs: |
| self.params[s] = kwargs[s] |
| |
| self.rst_file = open(self.params['f_result'], 'w') |
| self.err_file = open(self.params['f_error'], 'w') |
| self.prg_file = open(self.params['f_progress'], 'w') |
| self.NewTestStart() |
| |
| def SendLineToResult(self, test_info, result_info): |
| """Send test result (one-line) information to the result file. |
| |
| Args: |
| test_info: test case related info: testID, start_time, key_word, etc |
| result_info: test results {Pass_Fail: pass, note: Extra_Information} |
| Returns: |
| return the status of file write operation |
| """ |
| now = datetime.datetime.now() |
| if test_info is not None: |
| line = (now.strftime('%Y-%m-%d %H:%M') + self.params['delimiter'] |
| + 'testID:' + test_info['testID'] |
| + self.params['delimiter'] + 'TestStartAt:' |
| + test_info['start_time'] |
| + self.params['delimiter'] + 'Keyword:' + test_info['key_word'] |
| + self.params['delimiter'] + result_info['Pass_Fail'] |
| + self.params['delimiter'] + result_info['note'] + '\n') |
| else: |
| line = ('Result log information should have testInfo available! ' |
| + self.params['delimiter'] + 'No logging performed') |
| |
| if self.params['std_out'] > 0: |
| print line |
| return self.rst_file.write(line) |
| |
| def NewTestStart(self): |
| """Mark the start of a new test in the file.""" |
| self.rst_file.write( |
| '################### NEW TEST STARTED ###################\n') |
| self.err_file.write( |
| '################### NEW TEST STARTED ###################\n') |
| self.prg_file.write( |
| '################### NEW TEST STARTED ###################\n') |
| |
| def SendLineToError(self, test_info, error_info): |
| """Send test error (one-line) information to the error file. |
| |
| Args: |
| test_info: test case related info: testID, start_time, key_word, etc |
| error_info: test errors, severity: critical/intermediate/low, and info |
| Returns: |
| returns the status of file write operation |
| """ |
| now = datetime.datetime.now() |
| if test_info is not None: |
| line = (now.strftime('%Y-%m-%d %H:%M') + self.params['delimiter'] |
| + 'testID:' + test_info['testID'] + self.params['delimiter'] |
| + 'TestStartAt:' + test_info['start_time'] |
| + self.params['delimiter'] + 'Keyword:' |
| + test_info['key_word'] + self.params['delimiter'] |
| + error_info['severity'] + self.params['delimiter'] |
| + error_info['note'] + '\n') |
| else: |
| line = (now.strftime('%Y-%m-%d %H:%M') + self.params['delimiter'] + |
| error_info['severity'] + self.params['delimiter'] |
| + error_info['note'] + '\n') |
| |
| if self.params['std_out'] > 0: |
| print line |
| return self.err_file.write(line) |
| |
| def SendLineToProgress(self, test_info, progress_info): |
| """Send test progress (one-line) information to the progress file. |
| |
| Args: |
| test_info: test case related info: testID, start_time, key_word, etc |
| progress_info: test progress indication |
| {percent: [0-100]%, note: Information} |
| Returns: |
| returns the status of file write operation |
| """ |
| now = datetime.datetime.now() |
| if test_info is not None: |
| line = (now.strftime('%Y-%m-%d %H:%M') + self.params['delimiter'] |
| + 'testID:' + test_info['testID'] + self.params['delimiter'] |
| + 'TestStartAt:'+ test_info['start_time'] |
| + self.params['delimiter'] + 'Keyword:' + test_info['key_word'] |
| + self.params['delimiter'] + progress_info['percent'] |
| + self.params['delimiter'] + progress_info['note'] + '\n') |
| else: |
| line = (now.strftime('%Y-%m-%d %H:%M') + self.params['delimiter'] |
| + progress_info['percent'] + self.params['delimiter'] |
| + progress_info['note'] + '\n') |
| |
| if self.params['std_out'] > 0: |
| print line |
| return self.prg_file.write(line) |
| |
| def SendLine(self, test_info, info): |
| """Send test (one-line) information to the corresponding log file. |
| |
| Args: |
| test_info: test case related info: testID, start_time, key_word, etc |
| info: test results/error/progress information (single line) |
| test_info could be "None" for class other than TestCase |
| Returns: |
| return the status of file write operation |
| """ |
| if info['type'] == 'result': |
| return self.SendLineToResult(test_info, info) |
| elif info['type'] == 'error': |
| return self.SendLineToError(test_info, info) |
| elif info['type'] == 'progress': |
| return self.SendLineToProgress(test_info, info) |
| |
| def SendTestData(self, data_list): |
| """Send test data to result file.""" |
| for line in data_list: |
| self.rst_file.write(line + '\n') |
| self.err_file.flush() |
| |
| def SendLines(self, test_info, info): |
| """Send test output (multiple lines) to the corresponding log file. |
| |
| Args: |
| test_info: test case related info: testID, start_time, key_word, etc |
| info: test results/error/progress information (single line) |
| test_info could be "None" for class other than TestCase |
| Returns: |
| return 1 when succeed |
| """ |
| if info['type'] == 'result': |
| for line in info['note'].split('\n'): |
| if line == info['note'].split('\n')[0]: |
| dup_info = info.copy() |
| dup_info['note'] = line |
| self.SendLineToResult(test_info, dup_info) |
| else: |
| self.rst_file.write(line + '\n') |
| if self.params['std_out']: print line |
| self.rst_file.flush() |
| elif info['type'] == 'error': |
| for line in info['note'].split('\n'): |
| if line == info['note'].split('\n')[0]: |
| dup_info = info.copy() |
| dup_info['note'] = line |
| self.SendLineToError(test_info, dup_info) |
| else: |
| self.err_file.write(line + '\n') |
| if self.params['std_out']: print line |
| self.err_file.flush() |
| elif info['type'] == 'progress': |
| for line in info['note'].split('\n'): |
| if line == info['note'].split('\n')[0]: |
| dup_info = info.copy() |
| dup_info['note'] = line |
| self.SendLineToProgress(test_info, dup_info) |
| else: |
| self.prg_file.write(line + '\n') |
| if self.params['std_out']: print line |
| self.prg_file.flush() |
| return 1 |
| |
| def CreateResultInfo(self, status='Pass', msg=''): |
| """Create the result Info structure for logging. |
| |
| Args: |
| status: has value 'Pass' or 'Fail' |
| msg: test results information line(s) |
| Returns: |
| returns the infomation structure that should be logged to file |
| """ |
| d = {} |
| d.setdefault('type', 'result') |
| d.setdefault('Pass_Fail', status) |
| d.setdefault('note', msg) |
| return d |
| |
| def CreateErrorInfo(self, severity='intermediate', msg=''): |
| """Create the error Info structure for logging. |
| |
| Args: |
| severity: has value 'low', 'intermediate' or 'critical' |
| msg: test error information line(s) |
| Returns: |
| returns the infomation structure that should be logged to file |
| """ |
| d = {} |
| d.setdefault('type', 'error') |
| d.setdefault('severity', severity) |
| d.setdefault('note', msg) |
| return d |
| |
| def CreateProgressInfo(self, percent='0%', msg=''): |
| """Create the progress Info structure for logging. |
| |
| Args: |
| percent: completeness of test progress, in % |
| msg: test progress information line(s) |
| Returns: |
| returns the infomation structure that should be logged to file |
| """ |
| d = {} |
| d.setdefault('percent', percent) |
| d.setdefault('type', 'progress') |
| d.setdefault('note', msg) |
| return d |
| |
| def __del__(self): |
| """Close the log files.""" |
| self.rst_file.close() |
| self.err_file.close() |
| self.prg_file.close() |