1# SPDX-License-Identifier: GPL-2.0 2 3import builtins 4import inspect 5import time 6import traceback 7from .consts import KSFT_MAIN_NAME 8 9KSFT_RESULT = None 10 11 12class KsftSkipEx(Exception): 13 pass 14 15 16class KsftXfailEx(Exception): 17 pass 18 19 20def ksft_pr(*objs, **kwargs): 21 print("#", *objs, **kwargs) 22 23 24def _fail(*args): 25 global KSFT_RESULT 26 KSFT_RESULT = False 27 28 frame = inspect.stack()[2] 29 ksft_pr("At " + frame.filename + " line " + str(frame.lineno) + ":") 30 ksft_pr(*args) 31 32 33def ksft_eq(a, b, comment=""): 34 global KSFT_RESULT 35 if a != b: 36 _fail("Check failed", a, "!=", b, comment) 37 38 39def ksft_true(a, comment=""): 40 if not a: 41 _fail("Check failed", a, "does not eval to True", comment) 42 43 44def ksft_in(a, b, comment=""): 45 if a not in b: 46 _fail("Check failed", a, "not in", b, comment) 47 48 49def ksft_ge(a, b, comment=""): 50 if a < b: 51 _fail("Check failed", a, "<", b, comment) 52 53 54def ksft_busy_wait(cond, sleep=0.005, deadline=1, comment=""): 55 end = time.monotonic() + deadline 56 while True: 57 if cond(): 58 return 59 if time.monotonic() > end: 60 _fail("Waiting for condition timed out", comment) 61 return 62 time.sleep(sleep) 63 64 65def ktap_result(ok, cnt=1, case="", comment=""): 66 res = "" 67 if not ok: 68 res += "not " 69 res += "ok " 70 res += str(cnt) + " " 71 res += KSFT_MAIN_NAME 72 if case: 73 res += "." + str(case.__name__) 74 if comment: 75 res += " # " + comment 76 print(res) 77 78 79def ksft_run(cases, args=()): 80 totals = {"pass": 0, "fail": 0, "skip": 0, "xfail": 0} 81 82 print("KTAP version 1") 83 print("1.." + str(len(cases))) 84 85 global KSFT_RESULT 86 cnt = 0 87 for case in cases: 88 KSFT_RESULT = True 89 cnt += 1 90 try: 91 case(*args) 92 except KsftSkipEx as e: 93 ktap_result(True, cnt, case, comment="SKIP " + str(e)) 94 totals['skip'] += 1 95 continue 96 except KsftXfailEx as e: 97 ktap_result(True, cnt, case, comment="XFAIL " + str(e)) 98 totals['xfail'] += 1 99 continue 100 except Exception as e: 101 tb = traceback.format_exc() 102 for line in tb.strip().split('\n'): 103 ksft_pr("Exception|", line) 104 ktap_result(False, cnt, case) 105 totals['fail'] += 1 106 continue 107 108 ktap_result(KSFT_RESULT, cnt, case) 109 totals['pass'] += 1 110 111 print( 112 f"# Totals: pass:{totals['pass']} fail:{totals['fail']} xfail:{totals['xfail']} xpass:0 skip:{totals['skip']} error:0" 113 ) 114