18c2ecf20Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci 38c2ecf20Sopenharmony_cifrom __future__ import print_function 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ciimport os 68c2ecf20Sopenharmony_ciimport sys 78c2ecf20Sopenharmony_ciimport glob 88c2ecf20Sopenharmony_ciimport optparse 98c2ecf20Sopenharmony_ciimport tempfile 108c2ecf20Sopenharmony_ciimport logging 118c2ecf20Sopenharmony_ciimport shutil 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_citry: 148c2ecf20Sopenharmony_ci import configparser 158c2ecf20Sopenharmony_ciexcept ImportError: 168c2ecf20Sopenharmony_ci import ConfigParser as configparser 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_cidef data_equal(a, b): 198c2ecf20Sopenharmony_ci # Allow multiple values in assignment separated by '|' 208c2ecf20Sopenharmony_ci a_list = a.split('|') 218c2ecf20Sopenharmony_ci b_list = b.split('|') 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci for a_item in a_list: 248c2ecf20Sopenharmony_ci for b_item in b_list: 258c2ecf20Sopenharmony_ci if (a_item == b_item): 268c2ecf20Sopenharmony_ci return True 278c2ecf20Sopenharmony_ci elif (a_item == '*') or (b_item == '*'): 288c2ecf20Sopenharmony_ci return True 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci return False 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ciclass Fail(Exception): 338c2ecf20Sopenharmony_ci def __init__(self, test, msg): 348c2ecf20Sopenharmony_ci self.msg = msg 358c2ecf20Sopenharmony_ci self.test = test 368c2ecf20Sopenharmony_ci def getMsg(self): 378c2ecf20Sopenharmony_ci return '\'%s\' - %s' % (self.test.path, self.msg) 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ciclass Notest(Exception): 408c2ecf20Sopenharmony_ci def __init__(self, test, arch): 418c2ecf20Sopenharmony_ci self.arch = arch 428c2ecf20Sopenharmony_ci self.test = test 438c2ecf20Sopenharmony_ci def getMsg(self): 448c2ecf20Sopenharmony_ci return '[%s] \'%s\'' % (self.arch, self.test.path) 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ciclass Unsup(Exception): 478c2ecf20Sopenharmony_ci def __init__(self, test): 488c2ecf20Sopenharmony_ci self.test = test 498c2ecf20Sopenharmony_ci def getMsg(self): 508c2ecf20Sopenharmony_ci return '\'%s\'' % self.test.path 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ciclass Event(dict): 538c2ecf20Sopenharmony_ci terms = [ 548c2ecf20Sopenharmony_ci 'cpu', 558c2ecf20Sopenharmony_ci 'flags', 568c2ecf20Sopenharmony_ci 'type', 578c2ecf20Sopenharmony_ci 'size', 588c2ecf20Sopenharmony_ci 'config', 598c2ecf20Sopenharmony_ci 'sample_period', 608c2ecf20Sopenharmony_ci 'sample_type', 618c2ecf20Sopenharmony_ci 'read_format', 628c2ecf20Sopenharmony_ci 'disabled', 638c2ecf20Sopenharmony_ci 'inherit', 648c2ecf20Sopenharmony_ci 'pinned', 658c2ecf20Sopenharmony_ci 'exclusive', 668c2ecf20Sopenharmony_ci 'exclude_user', 678c2ecf20Sopenharmony_ci 'exclude_kernel', 688c2ecf20Sopenharmony_ci 'exclude_hv', 698c2ecf20Sopenharmony_ci 'exclude_idle', 708c2ecf20Sopenharmony_ci 'mmap', 718c2ecf20Sopenharmony_ci 'comm', 728c2ecf20Sopenharmony_ci 'freq', 738c2ecf20Sopenharmony_ci 'inherit_stat', 748c2ecf20Sopenharmony_ci 'enable_on_exec', 758c2ecf20Sopenharmony_ci 'task', 768c2ecf20Sopenharmony_ci 'watermark', 778c2ecf20Sopenharmony_ci 'precise_ip', 788c2ecf20Sopenharmony_ci 'mmap_data', 798c2ecf20Sopenharmony_ci 'sample_id_all', 808c2ecf20Sopenharmony_ci 'exclude_host', 818c2ecf20Sopenharmony_ci 'exclude_guest', 828c2ecf20Sopenharmony_ci 'exclude_callchain_kernel', 838c2ecf20Sopenharmony_ci 'exclude_callchain_user', 848c2ecf20Sopenharmony_ci 'wakeup_events', 858c2ecf20Sopenharmony_ci 'bp_type', 868c2ecf20Sopenharmony_ci 'config1', 878c2ecf20Sopenharmony_ci 'config2', 888c2ecf20Sopenharmony_ci 'branch_sample_type', 898c2ecf20Sopenharmony_ci 'sample_regs_user', 908c2ecf20Sopenharmony_ci 'sample_stack_user', 918c2ecf20Sopenharmony_ci ] 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci def add(self, data): 948c2ecf20Sopenharmony_ci for key, val in data: 958c2ecf20Sopenharmony_ci log.debug(" %s = %s" % (key, val)) 968c2ecf20Sopenharmony_ci self[key] = val 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci def __init__(self, name, data, base): 998c2ecf20Sopenharmony_ci log.debug(" Event %s" % name); 1008c2ecf20Sopenharmony_ci self.name = name; 1018c2ecf20Sopenharmony_ci self.group = '' 1028c2ecf20Sopenharmony_ci self.add(base) 1038c2ecf20Sopenharmony_ci self.add(data) 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci def equal(self, other): 1068c2ecf20Sopenharmony_ci for t in Event.terms: 1078c2ecf20Sopenharmony_ci log.debug(" [%s] %s %s" % (t, self[t], other[t])); 1088c2ecf20Sopenharmony_ci if t not in self or t not in other: 1098c2ecf20Sopenharmony_ci return False 1108c2ecf20Sopenharmony_ci if not data_equal(self[t], other[t]): 1118c2ecf20Sopenharmony_ci return False 1128c2ecf20Sopenharmony_ci return True 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci def optional(self): 1158c2ecf20Sopenharmony_ci if 'optional' in self and self['optional'] == '1': 1168c2ecf20Sopenharmony_ci return True 1178c2ecf20Sopenharmony_ci return False 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci def diff(self, other): 1208c2ecf20Sopenharmony_ci for t in Event.terms: 1218c2ecf20Sopenharmony_ci if t not in self or t not in other: 1228c2ecf20Sopenharmony_ci continue 1238c2ecf20Sopenharmony_ci if not data_equal(self[t], other[t]): 1248c2ecf20Sopenharmony_ci log.warning("expected %s=%s, got %s" % (t, self[t], other[t])) 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci# Test file description needs to have following sections: 1278c2ecf20Sopenharmony_ci# [config] 1288c2ecf20Sopenharmony_ci# - just single instance in file 1298c2ecf20Sopenharmony_ci# - needs to specify: 1308c2ecf20Sopenharmony_ci# 'command' - perf command name 1318c2ecf20Sopenharmony_ci# 'args' - special command arguments 1328c2ecf20Sopenharmony_ci# 'ret' - expected command return value (0 by default) 1338c2ecf20Sopenharmony_ci# 'arch' - architecture specific test (optional) 1348c2ecf20Sopenharmony_ci# comma separated list, ! at the beginning 1358c2ecf20Sopenharmony_ci# negates it. 1368c2ecf20Sopenharmony_ci# 1378c2ecf20Sopenharmony_ci# [eventX:base] 1388c2ecf20Sopenharmony_ci# - one or multiple instances in file 1398c2ecf20Sopenharmony_ci# - expected values assignments 1408c2ecf20Sopenharmony_ciclass Test(object): 1418c2ecf20Sopenharmony_ci def __init__(self, path, options): 1428c2ecf20Sopenharmony_ci parser = configparser.SafeConfigParser() 1438c2ecf20Sopenharmony_ci parser.read(path) 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_ci log.warning("running '%s'" % path) 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ci self.path = path 1488c2ecf20Sopenharmony_ci self.test_dir = options.test_dir 1498c2ecf20Sopenharmony_ci self.perf = options.perf 1508c2ecf20Sopenharmony_ci self.command = parser.get('config', 'command') 1518c2ecf20Sopenharmony_ci self.args = parser.get('config', 'args') 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci try: 1548c2ecf20Sopenharmony_ci self.ret = parser.get('config', 'ret') 1558c2ecf20Sopenharmony_ci except: 1568c2ecf20Sopenharmony_ci self.ret = 0 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_ci try: 1598c2ecf20Sopenharmony_ci self.arch = parser.get('config', 'arch') 1608c2ecf20Sopenharmony_ci log.warning("test limitation '%s'" % self.arch) 1618c2ecf20Sopenharmony_ci except: 1628c2ecf20Sopenharmony_ci self.arch = '' 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_ci self.expect = {} 1658c2ecf20Sopenharmony_ci self.result = {} 1668c2ecf20Sopenharmony_ci log.debug(" loading expected events"); 1678c2ecf20Sopenharmony_ci self.load_events(path, self.expect) 1688c2ecf20Sopenharmony_ci 1698c2ecf20Sopenharmony_ci def is_event(self, name): 1708c2ecf20Sopenharmony_ci if name.find("event") == -1: 1718c2ecf20Sopenharmony_ci return False 1728c2ecf20Sopenharmony_ci else: 1738c2ecf20Sopenharmony_ci return True 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_ci def skip_test(self, myarch): 1768c2ecf20Sopenharmony_ci # If architecture not set always run test 1778c2ecf20Sopenharmony_ci if self.arch == '': 1788c2ecf20Sopenharmony_ci # log.warning("test for arch %s is ok" % myarch) 1798c2ecf20Sopenharmony_ci return False 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci # Allow multiple values in assignment separated by ',' 1828c2ecf20Sopenharmony_ci arch_list = self.arch.split(',') 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci # Handle negated list such as !s390x,ppc 1858c2ecf20Sopenharmony_ci if arch_list[0][0] == '!': 1868c2ecf20Sopenharmony_ci arch_list[0] = arch_list[0][1:] 1878c2ecf20Sopenharmony_ci log.warning("excluded architecture list %s" % arch_list) 1888c2ecf20Sopenharmony_ci for arch_item in arch_list: 1898c2ecf20Sopenharmony_ci # log.warning("test for %s arch is %s" % (arch_item, myarch)) 1908c2ecf20Sopenharmony_ci if arch_item == myarch: 1918c2ecf20Sopenharmony_ci return True 1928c2ecf20Sopenharmony_ci return False 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ci for arch_item in arch_list: 1958c2ecf20Sopenharmony_ci # log.warning("test for architecture '%s' current '%s'" % (arch_item, myarch)) 1968c2ecf20Sopenharmony_ci if arch_item == myarch: 1978c2ecf20Sopenharmony_ci return False 1988c2ecf20Sopenharmony_ci return True 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_ci def load_events(self, path, events): 2018c2ecf20Sopenharmony_ci parser_event = configparser.SafeConfigParser() 2028c2ecf20Sopenharmony_ci parser_event.read(path) 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ci # The event record section header contains 'event' word, 2058c2ecf20Sopenharmony_ci # optionaly followed by ':' allowing to load 'parent 2068c2ecf20Sopenharmony_ci # event' first as a base 2078c2ecf20Sopenharmony_ci for section in filter(self.is_event, parser_event.sections()): 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_ci parser_items = parser_event.items(section); 2108c2ecf20Sopenharmony_ci base_items = {} 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_ci # Read parent event if there's any 2138c2ecf20Sopenharmony_ci if (':' in section): 2148c2ecf20Sopenharmony_ci base = section[section.index(':') + 1:] 2158c2ecf20Sopenharmony_ci parser_base = configparser.SafeConfigParser() 2168c2ecf20Sopenharmony_ci parser_base.read(self.test_dir + '/' + base) 2178c2ecf20Sopenharmony_ci base_items = parser_base.items('event') 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_ci e = Event(section, parser_items, base_items) 2208c2ecf20Sopenharmony_ci events[section] = e 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_ci def run_cmd(self, tempdir): 2238c2ecf20Sopenharmony_ci junk1, junk2, junk3, junk4, myarch = (os.uname()) 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_ci if self.skip_test(myarch): 2268c2ecf20Sopenharmony_ci raise Notest(self, myarch) 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_ci cmd = "PERF_TEST_ATTR=%s %s %s -o %s/perf.data %s" % (tempdir, 2298c2ecf20Sopenharmony_ci self.perf, self.command, tempdir, self.args) 2308c2ecf20Sopenharmony_ci ret = os.WEXITSTATUS(os.system(cmd)) 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_ci log.info(" '%s' ret '%s', expected '%s'" % (cmd, str(ret), str(self.ret))) 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_ci if not data_equal(str(ret), str(self.ret)): 2358c2ecf20Sopenharmony_ci raise Unsup(self) 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_ci def compare(self, expect, result): 2388c2ecf20Sopenharmony_ci match = {} 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_ci log.debug(" compare"); 2418c2ecf20Sopenharmony_ci 2428c2ecf20Sopenharmony_ci # For each expected event find all matching 2438c2ecf20Sopenharmony_ci # events in result. Fail if there's not any. 2448c2ecf20Sopenharmony_ci for exp_name, exp_event in expect.items(): 2458c2ecf20Sopenharmony_ci exp_list = [] 2468c2ecf20Sopenharmony_ci res_event = {} 2478c2ecf20Sopenharmony_ci log.debug(" matching [%s]" % exp_name) 2488c2ecf20Sopenharmony_ci for res_name, res_event in result.items(): 2498c2ecf20Sopenharmony_ci log.debug(" to [%s]" % res_name) 2508c2ecf20Sopenharmony_ci if (exp_event.equal(res_event)): 2518c2ecf20Sopenharmony_ci exp_list.append(res_name) 2528c2ecf20Sopenharmony_ci log.debug(" ->OK") 2538c2ecf20Sopenharmony_ci else: 2548c2ecf20Sopenharmony_ci log.debug(" ->FAIL"); 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_ci log.debug(" match: [%s] matches %s" % (exp_name, str(exp_list))) 2578c2ecf20Sopenharmony_ci 2588c2ecf20Sopenharmony_ci # we did not any matching event - fail 2598c2ecf20Sopenharmony_ci if not exp_list: 2608c2ecf20Sopenharmony_ci if exp_event.optional(): 2618c2ecf20Sopenharmony_ci log.debug(" %s does not match, but is optional" % exp_name) 2628c2ecf20Sopenharmony_ci else: 2638c2ecf20Sopenharmony_ci if not res_event: 2648c2ecf20Sopenharmony_ci log.debug(" res_event is empty"); 2658c2ecf20Sopenharmony_ci else: 2668c2ecf20Sopenharmony_ci exp_event.diff(res_event) 2678c2ecf20Sopenharmony_ci raise Fail(self, 'match failure'); 2688c2ecf20Sopenharmony_ci 2698c2ecf20Sopenharmony_ci match[exp_name] = exp_list 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_ci # For each defined group in the expected events 2728c2ecf20Sopenharmony_ci # check we match the same group in the result. 2738c2ecf20Sopenharmony_ci for exp_name, exp_event in expect.items(): 2748c2ecf20Sopenharmony_ci group = exp_event.group 2758c2ecf20Sopenharmony_ci 2768c2ecf20Sopenharmony_ci if (group == ''): 2778c2ecf20Sopenharmony_ci continue 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_ci for res_name in match[exp_name]: 2808c2ecf20Sopenharmony_ci res_group = result[res_name].group 2818c2ecf20Sopenharmony_ci if res_group not in match[group]: 2828c2ecf20Sopenharmony_ci raise Fail(self, 'group failure') 2838c2ecf20Sopenharmony_ci 2848c2ecf20Sopenharmony_ci log.debug(" group: [%s] matches group leader %s" % 2858c2ecf20Sopenharmony_ci (exp_name, str(match[group]))) 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_ci log.debug(" matched") 2888c2ecf20Sopenharmony_ci 2898c2ecf20Sopenharmony_ci def resolve_groups(self, events): 2908c2ecf20Sopenharmony_ci for name, event in events.items(): 2918c2ecf20Sopenharmony_ci group_fd = event['group_fd']; 2928c2ecf20Sopenharmony_ci if group_fd == '-1': 2938c2ecf20Sopenharmony_ci continue; 2948c2ecf20Sopenharmony_ci 2958c2ecf20Sopenharmony_ci for iname, ievent in events.items(): 2968c2ecf20Sopenharmony_ci if (ievent['fd'] == group_fd): 2978c2ecf20Sopenharmony_ci event.group = iname 2988c2ecf20Sopenharmony_ci log.debug('[%s] has group leader [%s]' % (name, iname)) 2998c2ecf20Sopenharmony_ci break; 3008c2ecf20Sopenharmony_ci 3018c2ecf20Sopenharmony_ci def run(self): 3028c2ecf20Sopenharmony_ci tempdir = tempfile.mkdtemp(); 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_ci try: 3058c2ecf20Sopenharmony_ci # run the test script 3068c2ecf20Sopenharmony_ci self.run_cmd(tempdir); 3078c2ecf20Sopenharmony_ci 3088c2ecf20Sopenharmony_ci # load events expectation for the test 3098c2ecf20Sopenharmony_ci log.debug(" loading result events"); 3108c2ecf20Sopenharmony_ci for f in glob.glob(tempdir + '/event*'): 3118c2ecf20Sopenharmony_ci self.load_events(f, self.result); 3128c2ecf20Sopenharmony_ci 3138c2ecf20Sopenharmony_ci # resolve group_fd to event names 3148c2ecf20Sopenharmony_ci self.resolve_groups(self.expect); 3158c2ecf20Sopenharmony_ci self.resolve_groups(self.result); 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_ci # do the expectation - results matching - both ways 3188c2ecf20Sopenharmony_ci self.compare(self.expect, self.result) 3198c2ecf20Sopenharmony_ci self.compare(self.result, self.expect) 3208c2ecf20Sopenharmony_ci 3218c2ecf20Sopenharmony_ci finally: 3228c2ecf20Sopenharmony_ci # cleanup 3238c2ecf20Sopenharmony_ci shutil.rmtree(tempdir) 3248c2ecf20Sopenharmony_ci 3258c2ecf20Sopenharmony_ci 3268c2ecf20Sopenharmony_cidef run_tests(options): 3278c2ecf20Sopenharmony_ci for f in glob.glob(options.test_dir + '/' + options.test): 3288c2ecf20Sopenharmony_ci try: 3298c2ecf20Sopenharmony_ci Test(f, options).run() 3308c2ecf20Sopenharmony_ci except Unsup as obj: 3318c2ecf20Sopenharmony_ci log.warning("unsupp %s" % obj.getMsg()) 3328c2ecf20Sopenharmony_ci except Notest as obj: 3338c2ecf20Sopenharmony_ci log.warning("skipped %s" % obj.getMsg()) 3348c2ecf20Sopenharmony_ci 3358c2ecf20Sopenharmony_cidef setup_log(verbose): 3368c2ecf20Sopenharmony_ci global log 3378c2ecf20Sopenharmony_ci level = logging.CRITICAL 3388c2ecf20Sopenharmony_ci 3398c2ecf20Sopenharmony_ci if verbose == 1: 3408c2ecf20Sopenharmony_ci level = logging.WARNING 3418c2ecf20Sopenharmony_ci if verbose == 2: 3428c2ecf20Sopenharmony_ci level = logging.INFO 3438c2ecf20Sopenharmony_ci if verbose >= 3: 3448c2ecf20Sopenharmony_ci level = logging.DEBUG 3458c2ecf20Sopenharmony_ci 3468c2ecf20Sopenharmony_ci log = logging.getLogger('test') 3478c2ecf20Sopenharmony_ci log.setLevel(level) 3488c2ecf20Sopenharmony_ci ch = logging.StreamHandler() 3498c2ecf20Sopenharmony_ci ch.setLevel(level) 3508c2ecf20Sopenharmony_ci formatter = logging.Formatter('%(message)s') 3518c2ecf20Sopenharmony_ci ch.setFormatter(formatter) 3528c2ecf20Sopenharmony_ci log.addHandler(ch) 3538c2ecf20Sopenharmony_ci 3548c2ecf20Sopenharmony_ciUSAGE = '''%s [OPTIONS] 3558c2ecf20Sopenharmony_ci -d dir # tests dir 3568c2ecf20Sopenharmony_ci -p path # perf binary 3578c2ecf20Sopenharmony_ci -t test # single test 3588c2ecf20Sopenharmony_ci -v # verbose level 3598c2ecf20Sopenharmony_ci''' % sys.argv[0] 3608c2ecf20Sopenharmony_ci 3618c2ecf20Sopenharmony_cidef main(): 3628c2ecf20Sopenharmony_ci parser = optparse.OptionParser(usage=USAGE) 3638c2ecf20Sopenharmony_ci 3648c2ecf20Sopenharmony_ci parser.add_option("-t", "--test", 3658c2ecf20Sopenharmony_ci action="store", type="string", dest="test") 3668c2ecf20Sopenharmony_ci parser.add_option("-d", "--test-dir", 3678c2ecf20Sopenharmony_ci action="store", type="string", dest="test_dir") 3688c2ecf20Sopenharmony_ci parser.add_option("-p", "--perf", 3698c2ecf20Sopenharmony_ci action="store", type="string", dest="perf") 3708c2ecf20Sopenharmony_ci parser.add_option("-v", "--verbose", 3718c2ecf20Sopenharmony_ci default=0, action="count", dest="verbose") 3728c2ecf20Sopenharmony_ci 3738c2ecf20Sopenharmony_ci options, args = parser.parse_args() 3748c2ecf20Sopenharmony_ci if args: 3758c2ecf20Sopenharmony_ci parser.error('FAILED wrong arguments %s' % ' '.join(args)) 3768c2ecf20Sopenharmony_ci return -1 3778c2ecf20Sopenharmony_ci 3788c2ecf20Sopenharmony_ci setup_log(options.verbose) 3798c2ecf20Sopenharmony_ci 3808c2ecf20Sopenharmony_ci if not options.test_dir: 3818c2ecf20Sopenharmony_ci print('FAILED no -d option specified') 3828c2ecf20Sopenharmony_ci sys.exit(-1) 3838c2ecf20Sopenharmony_ci 3848c2ecf20Sopenharmony_ci if not options.test: 3858c2ecf20Sopenharmony_ci options.test = 'test*' 3868c2ecf20Sopenharmony_ci 3878c2ecf20Sopenharmony_ci try: 3888c2ecf20Sopenharmony_ci run_tests(options) 3898c2ecf20Sopenharmony_ci 3908c2ecf20Sopenharmony_ci except Fail as obj: 3918c2ecf20Sopenharmony_ci print("FAILED %s" % obj.getMsg()) 3928c2ecf20Sopenharmony_ci sys.exit(-1) 3938c2ecf20Sopenharmony_ci 3948c2ecf20Sopenharmony_ci sys.exit(0) 3958c2ecf20Sopenharmony_ci 3968c2ecf20Sopenharmony_ciif __name__ == '__main__': 3978c2ecf20Sopenharmony_ci main() 398