tdc.py (2a267e7c41aa88215de2b542de797d03d16ecdfd) | tdc.py (489ce2f42514b4324e5c63e93ae7570cab995254) |
---|---|
1#!/usr/bin/env python3 2# SPDX-License-Identifier: GPL-2.0 3 4""" 5tdc.py - Linux tc (Traffic Control) unit test driver 6 7Copyright (C) 2017 Lucas Bates <lucasb@mojatatu.com> 8""" --- 11 unchanged lines hidden (view full) --- 20from string import Template 21 22from tdc_config import * 23from tdc_helper import * 24 25import TdcPlugin 26from TdcResults import * 27 | 1#!/usr/bin/env python3 2# SPDX-License-Identifier: GPL-2.0 3 4""" 5tdc.py - Linux tc (Traffic Control) unit test driver 6 7Copyright (C) 2017 Lucas Bates <lucasb@mojatatu.com> 8""" --- 11 unchanged lines hidden (view full) --- 20from string import Template 21 22from tdc_config import * 23from tdc_helper import * 24 25import TdcPlugin 26from TdcResults import * 27 |
28class PluginDependencyException(Exception): 29 def __init__(self, missing_pg): 30 self.missing_pg = missing_pg |
|
28 29class PluginMgrTestFail(Exception): 30 def __init__(self, stage, output, message): 31 self.stage = stage 32 self.output = output 33 self.message = message 34 35class PluginMgr: 36 def __init__(self, argparser): 37 super().__init__() 38 self.plugins = {} 39 self.plugin_instances = [] | 31 32class PluginMgrTestFail(Exception): 33 def __init__(self, stage, output, message): 34 self.stage = stage 35 self.output = output 36 self.message = message 37 38class PluginMgr: 39 def __init__(self, argparser): 40 super().__init__() 41 self.plugins = {} 42 self.plugin_instances = [] |
40 self.args = [] | 43 self.failed_plugins = {} |
41 self.argparser = argparser 42 43 # TODO, put plugins in order 44 plugindir = os.getenv('TDC_PLUGIN_DIR', './plugins') 45 for dirpath, dirnames, filenames in os.walk(plugindir): 46 for fn in filenames: 47 if (fn.endswith('.py') and 48 not fn == '__init__.py' and 49 not fn.startswith('#') and 50 not fn.startswith('.#')): 51 mn = fn[0:-3] 52 foo = importlib.import_module('plugins.' + mn) 53 self.plugins[mn] = foo 54 self.plugin_instances.append(foo.SubPlugin()) 55 | 44 self.argparser = argparser 45 46 # TODO, put plugins in order 47 plugindir = os.getenv('TDC_PLUGIN_DIR', './plugins') 48 for dirpath, dirnames, filenames in os.walk(plugindir): 49 for fn in filenames: 50 if (fn.endswith('.py') and 51 not fn == '__init__.py' and 52 not fn.startswith('#') and 53 not fn.startswith('.#')): 54 mn = fn[0:-3] 55 foo = importlib.import_module('plugins.' + mn) 56 self.plugins[mn] = foo 57 self.plugin_instances.append(foo.SubPlugin()) 58 |
59 def load_plugin(self, pgdir, pgname): 60 pgname = pgname[0:-3] 61 foo = importlib.import_module('{}.{}'.format(pgdir, pgname)) 62 self.plugins[pgname] = foo 63 self.plugin_instances.append(foo.SubPlugin()) 64 self.plugin_instances[-1].check_args(self.args, None) 65 66 def get_required_plugins(self, testlist): 67 ''' 68 Get all required plugins from the list of test cases and return 69 all unique items. 70 ''' 71 reqs = [] 72 for t in testlist: 73 try: 74 if 'requires' in t['plugins']: 75 if isinstance(t['plugins']['requires'], list): 76 reqs.extend(t['plugins']['requires']) 77 else: 78 reqs.append(t['plugins']['requires']) 79 except KeyError: 80 continue 81 reqs = get_unique_item(reqs) 82 return reqs 83 84 def load_required_plugins(self, reqs, parser, args, remaining): 85 ''' 86 Get all required plugins from the list of test cases and load any plugin 87 that is not already enabled. 88 ''' 89 pgd = ['plugin-lib', 'plugin-lib-custom'] 90 pnf = [] 91 92 for r in reqs: 93 if r not in self.plugins: 94 fname = '{}.py'.format(r) 95 source_path = [] 96 for d in pgd: 97 pgpath = '{}/{}'.format(d, fname) 98 if os.path.isfile(pgpath): 99 source_path.append(pgpath) 100 if len(source_path) == 0: 101 print('ERROR: unable to find required plugin {}'.format(r)) 102 pnf.append(fname) 103 continue 104 elif len(source_path) > 1: 105 print('WARNING: multiple copies of plugin {} found, using version found') 106 print('at {}'.format(source_path[0])) 107 pgdir = source_path[0] 108 pgdir = pgdir.split('/')[0] 109 self.load_plugin(pgdir, fname) 110 if len(pnf) > 0: 111 raise PluginDependencyException(pnf) 112 113 parser = self.call_add_args(parser) 114 (args, remaining) = parser.parse_known_args(args=remaining, namespace=args) 115 return args 116 |
|
56 def call_pre_suite(self, testcount, testidlist): 57 for pgn_inst in self.plugin_instances: 58 pgn_inst.pre_suite(testcount, testidlist) 59 60 def call_post_suite(self, index): 61 for pgn_inst in reversed(self.plugin_instances): 62 pgn_inst.post_suite(index) 63 --- 29 unchanged lines hidden (view full) --- 93 for pgn_inst in self.plugin_instances: 94 pgn_inst.check_args(args, remaining) 95 96 def call_adjust_command(self, stage, command): 97 for pgn_inst in self.plugin_instances: 98 command = pgn_inst.adjust_command(stage, command) 99 return command 100 | 117 def call_pre_suite(self, testcount, testidlist): 118 for pgn_inst in self.plugin_instances: 119 pgn_inst.pre_suite(testcount, testidlist) 120 121 def call_post_suite(self, index): 122 for pgn_inst in reversed(self.plugin_instances): 123 pgn_inst.post_suite(index) 124 --- 29 unchanged lines hidden (view full) --- 154 for pgn_inst in self.plugin_instances: 155 pgn_inst.check_args(args, remaining) 156 157 def call_adjust_command(self, stage, command): 158 for pgn_inst in self.plugin_instances: 159 command = pgn_inst.adjust_command(stage, command) 160 return command 161 |
162 def set_args(self, args): 163 self.args = args 164 |
|
101 @staticmethod 102 def _make_argparser(args): 103 self.argparser = argparse.ArgumentParser( 104 description='Linux TC unit tests') 105 106def replace_keywords(cmd): 107 """ 108 For a given executable command, substitute any known --- 436 unchanged lines hidden (view full) --- 545 print('considering category {}'.format(catg)) 546 for tc in testlist: 547 if catg in tc['category'] and tc['id'] not in test_ids: 548 answer.append(tc) 549 test_ids.append(tc['id']) 550 551 return answer 552 | 165 @staticmethod 166 def _make_argparser(args): 167 self.argparser = argparse.ArgumentParser( 168 description='Linux TC unit tests') 169 170def replace_keywords(cmd): 171 """ 172 For a given executable command, substitute any known --- 436 unchanged lines hidden (view full) --- 609 print('considering category {}'.format(catg)) 610 for tc in testlist: 611 if catg in tc['category'] and tc['id'] not in test_ids: 612 answer.append(tc) 613 test_ids.append(tc['id']) 614 615 return answer 616 |
617 |
|
553def get_test_cases(args): 554 """ 555 If a test case file is specified, retrieve tests from that file. 556 Otherwise, glob for all json files in subdirectories and load from 557 each one. 558 Also, if requested, filter by category, and add tests matching 559 certain ids. 560 """ --- 45 unchanged lines hidden (view full) --- 606 else: 607 # just accept the existing value of alltestcases, 608 # which has been filtered by file/directory 609 pass 610 611 return allcatlist, allidlist, testcases_by_cats, alltestcases 612 613 | 618def get_test_cases(args): 619 """ 620 If a test case file is specified, retrieve tests from that file. 621 Otherwise, glob for all json files in subdirectories and load from 622 each one. 623 Also, if requested, filter by category, and add tests matching 624 certain ids. 625 """ --- 45 unchanged lines hidden (view full) --- 671 else: 672 # just accept the existing value of alltestcases, 673 # which has been filtered by file/directory 674 pass 675 676 return allcatlist, allidlist, testcases_by_cats, alltestcases 677 678 |
614def set_operation_mode(pm, args): | 679def set_operation_mode(pm, parser, args, remaining): |
615 """ 616 Load the test case data and process remaining arguments to determine 617 what the script should do for this run, and call the appropriate 618 function. 619 """ 620 ucat, idlist, testcases, alltests = get_test_cases(args) 621 622 if args.gen_id: --- 21 unchanged lines hidden (view full) --- 644 exit(0) 645 646 if args.list: 647 if args.list: 648 list_test_cases(alltests) 649 exit(0) 650 651 if len(alltests): | 680 """ 681 Load the test case data and process remaining arguments to determine 682 what the script should do for this run, and call the appropriate 683 function. 684 """ 685 ucat, idlist, testcases, alltests = get_test_cases(args) 686 687 if args.gen_id: --- 21 unchanged lines hidden (view full) --- 709 exit(0) 710 711 if args.list: 712 if args.list: 713 list_test_cases(alltests) 714 exit(0) 715 716 if len(alltests): |
717 req_plugins = pm.get_required_plugins(alltests) 718 try: 719 args = pm.load_required_plugins(req_plugins, parser, args, remaining) 720 except PluginDependencyException as pde: 721 print('The following plugins were not found:') 722 print('{}'.format(pde.missing_pg)) |
|
652 catresults = test_runner(pm, args, alltests) 653 if args.format == 'none': 654 print('Test results output suppression requested\n') 655 else: 656 print('\nAll test results: \n') 657 if args.format == 'xunit': 658 suffix = 'xml' 659 res = catresults.format_xunit() --- 21 unchanged lines hidden (view full) --- 681 and start operations. 682 """ 683 parser = args_parse() 684 parser = set_args(parser) 685 pm = PluginMgr(parser) 686 parser = pm.call_add_args(parser) 687 (args, remaining) = parser.parse_known_args() 688 args.NAMES = NAMES | 723 catresults = test_runner(pm, args, alltests) 724 if args.format == 'none': 725 print('Test results output suppression requested\n') 726 else: 727 print('\nAll test results: \n') 728 if args.format == 'xunit': 729 suffix = 'xml' 730 res = catresults.format_xunit() --- 21 unchanged lines hidden (view full) --- 752 and start operations. 753 """ 754 parser = args_parse() 755 parser = set_args(parser) 756 pm = PluginMgr(parser) 757 parser = pm.call_add_args(parser) 758 (args, remaining) = parser.parse_known_args() 759 args.NAMES = NAMES |
760 pm.set_args(args) |
|
689 check_default_settings(args, remaining, pm) 690 if args.verbose > 2: 691 print('args is {}'.format(args)) 692 | 761 check_default_settings(args, remaining, pm) 762 if args.verbose > 2: 763 print('args is {}'.format(args)) 764 |
693 set_operation_mode(pm, args) | 765 set_operation_mode(pm, parser, args, remaining) |
694 695 exit(0) 696 697 698if __name__ == "__main__": 699 main() | 766 767 exit(0) 768 769 770if __name__ == "__main__": 771 main() |