1*cfb92d14SAndroid Build Coastguard Worker#!/usr/bin/env python 2*cfb92d14SAndroid Build Coastguard Worker# 3*cfb92d14SAndroid Build Coastguard Worker# Copyright (c) 2020, The OpenThread Authors. 4*cfb92d14SAndroid Build Coastguard Worker# All rights reserved. 5*cfb92d14SAndroid Build Coastguard Worker# 6*cfb92d14SAndroid Build Coastguard Worker# Redistribution and use in source and binary forms, with or without 7*cfb92d14SAndroid Build Coastguard Worker# modification, are permitted provided that the following conditions are met: 8*cfb92d14SAndroid Build Coastguard Worker# 1. Redistributions of source code must retain the above copyright 9*cfb92d14SAndroid Build Coastguard Worker# notice, this list of conditions and the following disclaimer. 10*cfb92d14SAndroid Build Coastguard Worker# 2. Redistributions in binary form must reproduce the above copyright 11*cfb92d14SAndroid Build Coastguard Worker# notice, this list of conditions and the following disclaimer in the 12*cfb92d14SAndroid Build Coastguard Worker# documentation and/or other materials provided with the distribution. 13*cfb92d14SAndroid Build Coastguard Worker# 3. Neither the name of the copyright holder nor the 14*cfb92d14SAndroid Build Coastguard Worker# names of its contributors may be used to endorse or promote products 15*cfb92d14SAndroid Build Coastguard Worker# derived from this software without specific prior written permission. 16*cfb92d14SAndroid Build Coastguard Worker# 17*cfb92d14SAndroid Build Coastguard Worker# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18*cfb92d14SAndroid Build Coastguard Worker# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19*cfb92d14SAndroid Build Coastguard Worker# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20*cfb92d14SAndroid Build Coastguard Worker# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21*cfb92d14SAndroid Build Coastguard Worker# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22*cfb92d14SAndroid Build Coastguard Worker# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23*cfb92d14SAndroid Build Coastguard Worker# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24*cfb92d14SAndroid Build Coastguard Worker# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25*cfb92d14SAndroid Build Coastguard Worker# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26*cfb92d14SAndroid Build Coastguard Worker# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27*cfb92d14SAndroid Build Coastguard Worker# POSSIBILITY OF SUCH DAMAGE. 28*cfb92d14SAndroid Build Coastguard Worker# 29*cfb92d14SAndroid Build Coastguard Worker""" 30*cfb92d14SAndroid Build Coastguard Workerparse_topofile.py 31*cfb92d14SAndroid Build Coastguard Worker----------------- 32*cfb92d14SAndroid Build Coastguard WorkerThis script is used to parse TopologyConfig.txt file to list vendor device info 33*cfb92d14SAndroid Build Coastguard Workerwhen preparing for the Thread Certification testbed 34*cfb92d14SAndroid Build Coastguard Worker 35*cfb92d14SAndroid Build Coastguard Workerusage: parse_topofile.py [-h] [-f TOPO_FILE] [-c CASE_LIST [CASE_LIST ...]] 36*cfb92d14SAndroid Build Coastguard Worker 37*cfb92d14SAndroid Build Coastguard Worker parse TopologyConfig file and list all devices by case 38*cfb92d14SAndroid Build Coastguard Worker 39*cfb92d14SAndroid Build Coastguard Worker optional arguments: 40*cfb92d14SAndroid Build Coastguard Worker -h, --help show this help message and exit 41*cfb92d14SAndroid Build Coastguard Worker -f TOPO_FILE Topology config file (default: C:/GRL/Thread1.1/Thread 42*cfb92d14SAndroid Build Coastguard Worker _Harness/TestScripts/TopologyConfig.txt) 43*cfb92d14SAndroid Build Coastguard Worker -c CASE_LIST [CASE_LIST ...] 44*cfb92d14SAndroid Build Coastguard Worker Test case list (e.g. 5.1.1 9.2.1, default: all) 45*cfb92d14SAndroid Build Coastguard Worker 46*cfb92d14SAndroid Build Coastguard WorkerExamples: 47*cfb92d14SAndroid Build Coastguard Worker 1. Get case 5.1.1 vendor info 48*cfb92d14SAndroid Build Coastguard Worker cmd: python parse_topofile.py -f TopologyConfig.txt -c 5.1.1 49*cfb92d14SAndroid Build Coastguard Worker output: 50*cfb92d14SAndroid Build Coastguard Worker case 5.1.1: 51*cfb92d14SAndroid Build Coastguard Worker role-vendor pair: [('Leader', 'ARM'), ('Router_1', 'ARM')] 52*cfb92d14SAndroid Build Coastguard Worker vendor devices : {'ARM': 2} 53*cfb92d14SAndroid Build Coastguard Worker 54*cfb92d14SAndroid Build Coastguard Worker Testbed needed vendor devices:{'ARM': 2} 55*cfb92d14SAndroid Build Coastguard Worker 56*cfb92d14SAndroid Build Coastguard Worker 2. Get case 5.1.1 and 5.2.1 vendor info 57*cfb92d14SAndroid Build Coastguard Worker cmd: python parse_topofile.py -f TopologyConfig.txt -c 5.1.1 5.2.1 58*cfb92d14SAndroid Build Coastguard Worker output: 59*cfb92d14SAndroid Build Coastguard Worker case 5.1.1: 60*cfb92d14SAndroid Build Coastguard Worker role-vendor pair: [('Leader', 'ARM'), ('Router_1', 'ARM')] 61*cfb92d14SAndroid Build Coastguard Worker vendor devices : {'ARM': 2} 62*cfb92d14SAndroid Build Coastguard Worker case 5.2.1: 63*cfb92d14SAndroid Build Coastguard Worker role-vendor pair: [('Leader', 'OpenThread'), ('REED_1', 'Kirale'), ('MED_1', 'SiLabs')] 64*cfb92d14SAndroid Build Coastguard Worker vendor devices : {'OpenThread': 1, 'Kirale': 1, 'SiLabs': 1} 65*cfb92d14SAndroid Build Coastguard Worker 66*cfb92d14SAndroid Build Coastguard Worker Testbed needed vendor devices:{'ARM': 2, 'OpenThread': 1, 'Kirale': 1, 'SiLabs': 1} 67*cfb92d14SAndroid Build Coastguard Worker 68*cfb92d14SAndroid Build Coastguard Worker 3. Get all cases vendor info 69*cfb92d14SAndroid Build Coastguard Worker cmd: python parse_topofile.py -f TopologyConfig.txt 70*cfb92d14SAndroid Build Coastguard Worker output: 71*cfb92d14SAndroid Build Coastguard Worker ... ... ... 72*cfb92d14SAndroid Build Coastguard Worker 73*cfb92d14SAndroid Build Coastguard Worker Testbed needed vendor devices:{'ARM': 4, 'NXP': 5, 'OpenThread': 5, 'Kirale': 6, 'SiLabs': 5, 'Any': 7} 74*cfb92d14SAndroid Build Coastguard Worker 75*cfb92d14SAndroid Build Coastguard WorkerNotes: 76*cfb92d14SAndroid Build Coastguard Worker The result is just for reference, the exact requirement per vendor may be equal or less than what is generated by the script. 77*cfb92d14SAndroid Build Coastguard Worker 78*cfb92d14SAndroid Build Coastguard Worker""" 79*cfb92d14SAndroid Build Coastguard Worker 80*cfb92d14SAndroid Build Coastguard Workerimport argparse 81*cfb92d14SAndroid Build Coastguard Workerimport logging 82*cfb92d14SAndroid Build Coastguard Workerimport re 83*cfb92d14SAndroid Build Coastguard Workerfrom collections import Counter 84*cfb92d14SAndroid Build Coastguard Worker 85*cfb92d14SAndroid Build Coastguard Workerlogging.basicConfig(format='%(message)s', level=logging.DEBUG) 86*cfb92d14SAndroid Build Coastguard WorkerMAX_VENDOR_DEVICE = 32 87*cfb92d14SAndroid Build Coastguard Worker 88*cfb92d14SAndroid Build Coastguard Worker 89*cfb92d14SAndroid Build Coastguard Workerdef device_calculate(topo_file, case_list): 90*cfb92d14SAndroid Build Coastguard Worker testbed_vendor_dict = Counter() 91*cfb92d14SAndroid Build Coastguard Worker with open(topo_file, 'r') as f: 92*cfb92d14SAndroid Build Coastguard Worker for line in f: 93*cfb92d14SAndroid Build Coastguard Worker 94*cfb92d14SAndroid Build Coastguard Worker case_vendor_dict = Counter() 95*cfb92d14SAndroid Build Coastguard Worker 96*cfb92d14SAndroid Build Coastguard Worker if not line: 97*cfb92d14SAndroid Build Coastguard Worker break 98*cfb92d14SAndroid Build Coastguard Worker line = line.strip() 99*cfb92d14SAndroid Build Coastguard Worker 100*cfb92d14SAndroid Build Coastguard Worker # line example : 101*cfb92d14SAndroid Build Coastguard Worker # 5.5.1-Leader:Kirale,Router_1:OpenThread 102*cfb92d14SAndroid Build Coastguard Worker try: 103*cfb92d14SAndroid Build Coastguard Worker if re.match(r'\s*#.*', line): 104*cfb92d14SAndroid Build Coastguard Worker continue 105*cfb92d14SAndroid Build Coastguard Worker 106*cfb92d14SAndroid Build Coastguard Worker matched_case = re.match(r'(.*)-(.*)', line, re.M | re.I) 107*cfb92d14SAndroid Build Coastguard Worker 108*cfb92d14SAndroid Build Coastguard Worker if 'all' not in case_list and matched_case.group(1) not in case_list: 109*cfb92d14SAndroid Build Coastguard Worker continue 110*cfb92d14SAndroid Build Coastguard Worker 111*cfb92d14SAndroid Build Coastguard Worker logging.info('case %s:' % matched_case.group(1)) 112*cfb92d14SAndroid Build Coastguard Worker if 'all' not in case_list: 113*cfb92d14SAndroid Build Coastguard Worker case_list.remove(matched_case.group(1)) 114*cfb92d14SAndroid Build Coastguard Worker role_vendor_str = matched_case.group(2) 115*cfb92d14SAndroid Build Coastguard Worker role_vendor_raw_list = re.split(',', role_vendor_str) 116*cfb92d14SAndroid Build Coastguard Worker role_vendor_list = [] 117*cfb92d14SAndroid Build Coastguard Worker 118*cfb92d14SAndroid Build Coastguard Worker for device_pair in role_vendor_raw_list: 119*cfb92d14SAndroid Build Coastguard Worker device_pair = re.split(':', device_pair) 120*cfb92d14SAndroid Build Coastguard Worker role_vendor_list.append(tuple(device_pair)) 121*cfb92d14SAndroid Build Coastguard Worker logging.info('\trole-vendor pair: %s' % role_vendor_list) 122*cfb92d14SAndroid Build Coastguard Worker except Exception as e: 123*cfb92d14SAndroid Build Coastguard Worker logging.info('Unrecognized format: %s\n%s' % (line, format(e))) 124*cfb92d14SAndroid Build Coastguard Worker raise 125*cfb92d14SAndroid Build Coastguard Worker 126*cfb92d14SAndroid Build Coastguard Worker for _, vendor in role_vendor_list: 127*cfb92d14SAndroid Build Coastguard Worker case_vendor_dict[vendor] += 1 128*cfb92d14SAndroid Build Coastguard Worker testbed_vendor_dict[vendor] = max(testbed_vendor_dict[vendor], case_vendor_dict[vendor]) 129*cfb92d14SAndroid Build Coastguard Worker 130*cfb92d14SAndroid Build Coastguard Worker logging.info('\tvendor devices : %s' % dict(case_vendor_dict)) 131*cfb92d14SAndroid Build Coastguard Worker 132*cfb92d14SAndroid Build Coastguard Worker if case_list and 'all' not in case_list: 133*cfb92d14SAndroid Build Coastguard Worker logging.info('Case %s not found' % str(case_list)[1:-1]) 134*cfb92d14SAndroid Build Coastguard Worker 135*cfb92d14SAndroid Build Coastguard Worker # vendor 'Any' stands for any other vendors 136*cfb92d14SAndroid Build Coastguard Worker # override 'Any' counter when overlapping with other vendors 137*cfb92d14SAndroid Build Coastguard Worker count_any = MAX_VENDOR_DEVICE 138*cfb92d14SAndroid Build Coastguard Worker for key in testbed_vendor_dict: 139*cfb92d14SAndroid Build Coastguard Worker if key != 'Any': 140*cfb92d14SAndroid Build Coastguard Worker count_any -= testbed_vendor_dict[key] 141*cfb92d14SAndroid Build Coastguard Worker if 'Any' in testbed_vendor_dict: 142*cfb92d14SAndroid Build Coastguard Worker testbed_vendor_dict['Any'] = count_any 143*cfb92d14SAndroid Build Coastguard Worker 144*cfb92d14SAndroid Build Coastguard Worker logging.info('\nTestbed needed vendor devices:%s' % dict(testbed_vendor_dict)) 145*cfb92d14SAndroid Build Coastguard Worker 146*cfb92d14SAndroid Build Coastguard Worker 147*cfb92d14SAndroid Build Coastguard Workerdef main(): 148*cfb92d14SAndroid Build Coastguard Worker parser = argparse.ArgumentParser(description='parse TopologyConfig file and list all devices by case') 149*cfb92d14SAndroid Build Coastguard Worker parser.add_argument( 150*cfb92d14SAndroid Build Coastguard Worker '-f', 151*cfb92d14SAndroid Build Coastguard Worker dest='topo_file', 152*cfb92d14SAndroid Build Coastguard Worker default='C:/GRL/Thread1.1/Thread_Harness/TestScripts/TopologyConfig.txt', 153*cfb92d14SAndroid Build Coastguard Worker help='Topology config file (default: C:/GRL/Thread1.1/Thread_Harness/TestScripts/TopologyConfig.txt)', 154*cfb92d14SAndroid Build Coastguard Worker ) 155*cfb92d14SAndroid Build Coastguard Worker 156*cfb92d14SAndroid Build Coastguard Worker parser.add_argument('-c', 157*cfb92d14SAndroid Build Coastguard Worker dest='case_list', 158*cfb92d14SAndroid Build Coastguard Worker nargs='+', 159*cfb92d14SAndroid Build Coastguard Worker default=['all'], 160*cfb92d14SAndroid Build Coastguard Worker help='Test case list (e.g. 5.1.1 9.2.1, default: all) ') 161*cfb92d14SAndroid Build Coastguard Worker args = parser.parse_args() 162*cfb92d14SAndroid Build Coastguard Worker device_calculate(args.topo_file, args.case_list) 163*cfb92d14SAndroid Build Coastguard Worker 164*cfb92d14SAndroid Build Coastguard Worker 165*cfb92d14SAndroid Build Coastguard Workerif __name__ == '__main__': 166*cfb92d14SAndroid Build Coastguard Worker main() 167