Arrow / Mbed OS DAPLink Reset
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers test_info.py Source File

test_info.py

00001 #
00002 # DAPLink Interface Firmware
00003 # Copyright (c) 2009-2016, ARM Limited, All Rights Reserved
00004 # SPDX-License-Identifier: Apache-2.0
00005 #
00006 # Licensed under the Apache License, Version 2.0 (the "License"); you may
00007 # not use this file except in compliance with the License.
00008 # You may obtain a copy of the License at
00009 #
00010 # http://www.apache.org/licenses/LICENSE-2.0
00011 #
00012 # Unless required by applicable law or agreed to in writing, software
00013 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00014 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015 # See the License for the specific language governing permissions and
00016 # limitations under the License.
00017 #
00018  
00019 from __future__ import absolute_import
00020 from __future__ import print_function
00021 import six
00022 import sys
00023 import time
00024 
00025 
00026 class TestInfo(object):
00027     # Higher number = more severe
00028     SUBTEST = 0
00029     INFO = 1
00030     WARNING = 2
00031     FAILURE = 3
00032 
00033     _MSG_TYPES = set((INFO, WARNING, FAILURE))
00034     _MSG_LEVEL_TO_FMT_STR = {
00035         INFO: "Info: %s",
00036         WARNING: "Warning: %s",
00037         FAILURE: "Failure: %s",
00038     }
00039 
00040     def __init__(self, name, init_print=True):
00041         self._all = []
00042         self.failures = 0
00043         self.warnings = 0
00044         self.infos = 0
00045         self.name = name
00046         if init_print:
00047             self._print_msg("SubTest: " + name)
00048 
00049     def failure(self, msg):
00050         assert isinstance(msg, six.string_types)
00051         self._add_entry(self.FAILURE, msg)
00052 
00053     def warning(self, msg):
00054         assert isinstance(msg, six.string_types)
00055         self._add_entry(self.WARNING, msg)
00056 
00057     def info(self, msg):
00058         assert isinstance(msg, six.string_types)
00059         self._add_entry(self.INFO, msg)
00060 
00061     def print_msg(self, warning_level, max_recursion=0, spacing=2,
00062                   log_file=sys.stdout, _recursion_level=0):
00063         """
00064         Print problems at the given level
00065 
00066         By default only the top level passes and fails are printed.
00067         Set max_recursion to the number of subtests to be printed, or
00068         to None if all levels should be printed.
00069         """
00070         assert warning_level in self._MSG_TYPES
00071         assert max_recursion is None or max_recursion >= 0
00072 
00073         if self.get_failed():
00074             result_str = 'Failure'
00075             test_level = self.FAILURE
00076         elif self.get_warning():
00077             result_str = 'Warning'
00078             test_level = self.WARNING
00079         else:
00080             result_str = 'Pass'
00081             test_level = self.INFO
00082         prefix = ' ' * (_recursion_level * spacing)
00083 
00084         # Check if test should be printed - the waning level
00085         # is enabled, or this is the top level test
00086         if test_level < warning_level and _recursion_level != 0:
00087             return
00088 
00089         # Print test header
00090         print(prefix + "Test: %s: %s" % (self.name, result_str),
00091               file=log_file)
00092 
00093         # Check for recursion termination
00094         if max_recursion is not None and _recursion_level > max_recursion:
00095             return
00096         _recursion_level += 1
00097 
00098         # Print messages
00099         prefix = ' ' * (_recursion_level * spacing)
00100         for msg_level, msg in self._all:
00101             if msg_level == self.SUBTEST:
00102                 test_info = msg
00103                 test_info.print_msg(warning_level, max_recursion,
00104                                     spacing, log_file, _recursion_level)
00105             else:
00106                 fmt = prefix + self._MSG_LEVEL_TO_FMT_STR[msg_level]
00107                 if msg_level >= warning_level:
00108                     print(fmt % msg, file=log_file)
00109 
00110     def get_failed(self):
00111         self._update_counts()
00112         return self.failures != 0
00113 
00114     def get_warning(self):
00115         self._update_counts()
00116         return self.warnings != 0
00117 
00118     def get_name(self):
00119         return self.name
00120 
00121     def create_subtest(self, name):
00122         assert isinstance(name, six.string_types)
00123         test_info = TestInfo(name)
00124         self._add_entry(self.SUBTEST, test_info)
00125         return test_info
00126 
00127     def attach_subtest(self, subtest):
00128         assert isinstance(subtest, TestInfo)
00129         self._add_entry(self.SUBTEST, subtest)
00130 
00131     def get_counts(self):
00132         """
00133         Return the number of events that occured
00134 
00135         Return the number of even messages as a
00136         tuple containing (failure_count, warning_count, info_count).
00137         """
00138         self._update_counts()
00139         return self.failures, self.warnings, self.infos
00140 
00141     def _update_counts(self):
00142         self.failures, self.warnings, self.infos = 0, 0, 0
00143         for msg_level, msg in self._all:
00144             if msg_level == self.SUBTEST:
00145                 test_info = msg
00146                 failures, warnings, infos = test_info.get_counts()
00147                 self.failures += failures
00148                 self.warnings += warnings
00149                 self.infos += infos
00150             else:
00151                 if msg_level == self.FAILURE:
00152                     self.failures += 1
00153                 elif msg_level == self.WARNING:
00154                     self.warnings += 1
00155                 elif msg_level == self.INFO:
00156                     self.infos += 1
00157                 else:
00158                     # Should never get here
00159                     assert False
00160 
00161     def _add_entry(self, entry_type, msg):
00162         if entry_type is self.SUBTEST:
00163             assert isinstance(msg, TestInfo)
00164             # Test name printed in constructor
00165         else:
00166             assert isinstance(msg, six.string_types)
00167             self._print_msg(msg)
00168         self._all.append((entry_type, msg))
00169 
00170     @staticmethod
00171     def _print_msg(msg):
00172         print(get_timestamp_tag() + msg)
00173 
00174 
00175 class TestInfoStub(TestInfo):
00176 
00177     def __init__(self):
00178         super(TestInfoStub, self).__init__('stub test', False)
00179 
00180     def create_subtest(self, name):
00181         assert isinstance(name, six.string_types)
00182         return TestInfoStub()
00183 
00184     @staticmethod
00185     def _print_msg(msg):
00186         print(get_timestamp_tag() + "%s"%(msg,))
00187 
00188 def get_timestamp_tag():
00189     return "[{:0<17f}] ".format(time.time())