From 7e71fd4537e7f3deb54d1d14eea7904e4eeb99df Mon Sep 17 00:00:00 2001 From: hanhsuan Date: Thu, 23 May 2024 10:33:11 +0800 Subject: [PATCH] modify functions to provide add new DUTs to cert google sheet --- .../configs/google_sheet_link.json | 2 +- .../cert_team_google_sheet_handler.py | 389 ++++++++++-------- .../handlers/hic_handler.py | 109 +++-- Tools/PC/transfer-hw-to-cert/main.py | 120 +++--- .../test_cert_team_google_sheet_handler.py | 7 + .../tests/test_utils_common.py | 14 + Tools/PC/transfer-hw-to-cert/utils/common.py | 38 +- 7 files changed, 406 insertions(+), 273 deletions(-) diff --git a/Tools/PC/transfer-hw-to-cert/configs/google_sheet_link.json b/Tools/PC/transfer-hw-to-cert/configs/google_sheet_link.json index d1ed4fc..ff3fdbf 100644 --- a/Tools/PC/transfer-hw-to-cert/configs/google_sheet_link.json +++ b/Tools/PC/transfer-hw-to-cert/configs/google_sheet_link.json @@ -1,4 +1,4 @@ { "sheet_link": "14LouOL8as5fPaCWcat_lpsufLmzOsKVjCNNztiOrR0c", - "tables": ["TEL-L3", "TEL-L5", "TEL-L6"] + "tables": ["TEL-L3", "TEL-L4", "TEL-L5", "TEL-L6"] } diff --git a/Tools/PC/transfer-hw-to-cert/handlers/cert_team_google_sheet_handler.py b/Tools/PC/transfer-hw-to-cert/handlers/cert_team_google_sheet_handler.py index 6cd15a7..7e623ac 100644 --- a/Tools/PC/transfer-hw-to-cert/handlers/cert_team_google_sheet_handler.py +++ b/Tools/PC/transfer-hw-to-cert/handlers/cert_team_google_sheet_handler.py @@ -2,7 +2,7 @@ is_valid_cid, is_valid_location, read_json_config, - parse_location + parse_location, ) from GoogleSheet.google_sheet_api import GoogleSheetOperator @@ -12,7 +12,7 @@ in the Cert Team's Google Sheet. """ -GOOGLE_SHEET_CONF = read_json_config('./configs/google_sheet_link.json') +GOOGLE_SHEET_CONF = read_json_config("./configs/google_sheet_link.json") def create_google_sheet_instance(): @@ -23,31 +23,31 @@ def create_google_sheet_instance(): def is_valid_input_data(data: list[dict]) -> tuple[bool, list]: - """ Check the input data's content is valid. - Currently, this function checks the value of CID and Location - - @param:data, a list contains the bunch of dictionary data, each - data has the following keys, CID, Location and the link - of GM image. - e.g. - data = [ - { - 'cid': '202304-12345', - 'location': 'TEL-L3-F24-S5-P2' - 'gm_image_link': '' - }, - { - 'cid': '202311-12346', - 'location': 'TEL-L3-F23-S5-P2' - 'gm_image_link': 'http://oem-share' - } - ] - @return - bool: True if all data are valid, otherwise False - list: invalid list. It shows all invalid data in a list + """Check the input data's content is valid. + Currently, this function checks the value of CID and Location + + @param:data, a list contains the bunch of dictionary data, each + data has the following keys, CID, Location and the link + of GM image. + e.g. + data = [ + { + 'cid': '202304-12345', + 'location': 'TEL-L3-F24-S5-P2' + 'gm_image_link': '' + }, + { + 'cid': '202311-12346', + 'location': 'TEL-L3-F23-S5-P2' + 'gm_image_link': 'http://oem-share' + } + ] + @return + bool: True if all data are valid, otherwise False + list: invalid list. It shows all invalid data in a list """ invalid_list = [] - mandatory_keys = ['cid', 'location', 'gm_image_link'] + mandatory_keys = ["cid", "location", "gm_image_link"] for d in data: is_data_valid = True @@ -61,8 +61,9 @@ def is_valid_input_data(data: list[dict]) -> tuple[bool, list]: invalid_list.append(d) continue - is_data_valid = is_valid_cid(d['cid']) and \ - is_valid_location(d['location']) + is_data_valid = is_valid_cid(d["cid"]) and is_valid_location( + d["location"] + ) if not is_data_valid: invalid_list.append(d) @@ -71,202 +72,245 @@ def is_valid_input_data(data: list[dict]) -> tuple[bool, list]: def get_sheet_data() -> dict: - """ Get the data from Google Sheet and generate the customized dictionary - - @reutrn: return a customized dictionary which contains the index of - header and the indexed_table. - - e,g. - # TEL-L5: is the name of table (sheet) on Google Sheet. - # headers: shows the index of columns which make us can find the - target quickly. - # indexed_table: use the location as key to build an hash table, - there are some values can help us find the target - cell quickly. - - { 'TEL-L5': { - 'headers': { - 'CID': 0, - 'Certified_OEM_Image': 9, - 'Frame': 17, - 'Lab': 16, - 'Partition': 19, - 'Shelf': 18}, - 'indexed_table': { - 'TEL-L5-F01-S1-P1': { - 'CID': '202112-39487', - 'Certified_OEM_Image': '', - 'row_index': 2}, - 'TEL-L5-F01-S1-P2': { - 'CID': '202304-23456', - 'Certified_OEM_Image': '', - 'row_index': 3}, - } + """Get the data from Google Sheet and generate the customized dictionary + + @reutrn: return a customized dictionary which contains the index of + header and the indexed_table. + + e,g. + # TEL-L5: is the name of table (sheet) on Google Sheet. + # headers: shows the index of columns which make us can find the + target quickly. + # indexed_table: use the location as key to build an hash table, + there are some values can help us find the target + cell quickly. + + { 'TEL-L5': { + 'headers': { + 'CID': 0, + 'Certified_OEM_Image': 9, + 'Frame': 17, + 'Lab': 16, + 'Partition': 19, + 'Shelf': 18}, + 'indexed_table': { + 'TEL-L5-F01-S1-P1': { + 'CID': '202112-39487', + 'Certified_OEM_Image': '', + 'row_index': 2}, + 'TEL-L5-F01-S1-P2': { + 'CID': '202304-23456', + 'Certified_OEM_Image': '', + 'row_index': 3}, } + } """ sheet_data = {} gs_obj = create_google_sheet_instance() wanted_headers = [ - 'CID', 'Certified_OEM_Image', 'Lab', 'Frame', 'Shelf', 'Partition'] + "CID", + "Certified_OEM_Image", + "Lab", + "Frame", + "Shelf", + "Partition", + "MAC", + "IP", + ] # t is TEL-L3, TEL-L5 or TEL-L6 - for t in GOOGLE_SHEET_CONF['tables']: + for t in GOOGLE_SHEET_CONF["tables"]: sheet_data[t] = {} # Get the first row (a.k.a header), such as CID, Lab, Frame ... - headers = gs_obj.get_range_data(f'{t}!1:1', major_dimension="ROWS") + headers = gs_obj.get_range_data(f"{t}!1:1", major_dimension="ROWS") # Generate the mapping of headers columns = {} for wh in wanted_headers: columns[wh] = headers[0].index(wh) - sheet_data[t]['headers'] = columns + sheet_data[t]["headers"] = columns # Get data without header offset = 2 # offest is the bias of start row number at google sheet data = gs_obj.get_range_data( - f'{t}!A{offset}:Z', major_dimension="ROWS") + f"{t}!A{offset}:Z", major_dimension="ROWS" + ) # Build the indexed table (indexed by Location) indexed_table = {} for idx, v in enumerate(data): - location = ( - f"{v[columns['Lab']]}-{v[columns['Frame']]}-" - f"{'S' + v[columns['Shelf']]}-{'P' + v[columns['Partition']]}" - ) + try: + if v[columns['Lab']] == "TEL-L4": + p = "" + else: + p = "P" + location = ( + f"{v[columns['Lab']]}-{v[columns['Frame']]}-" + f"{'S' + v[columns['Shelf']]}-{p}{v[columns['Partition']]}" + ) + except IndexError: + continue indexed_table[location] = { - 'row_index': idx + offset, - 'CID': v[columns['CID']], - 'Certified_OEM_Image': v[columns['Certified_OEM_Image']] + "row_index": idx + offset, + "CID": v[columns["CID"]], + "Certified_OEM_Image": v[columns["Certified_OEM_Image"]], } - sheet_data[t]['indexed_table'] = indexed_table + sheet_data[t]["indexed_table"] = indexed_table return sheet_data def are_candidated_sheet_cells_empty( - data: list[dict], sheet_data: dict) -> tuple[bool, list]: - """ Check the cells are empty on Cert Lab Google Sheet - Currently, this function checks the value of CID and - Certified_OEM_Image - - @param:data, a list contains the bunch of dictionary data, each - data has the following keys, cid, location and the - gm_image_link - e.g. - data = [ - { - 'cid': '202312-12345', - 'location': 'TEL-L3-F24-S5-P2', - 'gm_image_link': '' - }, - { - 'cid': '202302-12346', - 'location': 'TEL-L3-F23-S5-P2', - 'gm_image_link': 'http://oem-share' - } - ] - @param:sheet_data, a dictionary which is from get_sheet_data function - - @return - bool: True if all candidated cells are empty, otherwise False - list: non empty list. It shows all record whose CID cell is empty + data: list[dict], sheet_data: dict +) -> tuple[bool, list]: + """Check the cells are empty on Cert Lab Google Sheet + Currently, this function checks the value of CID and + Certified_OEM_Image + + @param:data, a list contains the bunch of dictionary data, each + data has the following keys, cid, location and the + gm_image_link + e.g. + data = [ + { + 'cid': '202312-12345', + 'location': 'TEL-L3-F24-S5-P2', + 'gm_image_link': '' + }, + { + 'cid': '202302-12346', + 'location': 'TEL-L3-F23-S5-P2', + 'gm_image_link': 'http://oem-share' + } + ] + @param:sheet_data, a dictionary which is from get_sheet_data function + + @return + bool: True if all candidated cells are empty, otherwise False + list: non empty list. It shows all record whose CID cell is empty """ all_empty = True non_empty_list = [] for d in data: - lab = parse_location(d['location']).get('Lab', None) + lab = parse_location(d["location"]).get("Lab", None) if not lab or lab not in sheet_data: - raise Exception(f"Error: Lab \'{lab}\' is not in indexed table") + raise Exception(f"Error: Lab '{lab}' is not in indexed table") # get the indexed table of specific lab - indexed_table = sheet_data[lab]['indexed_table'] - indexed_cid = indexed_table[d['location']]['CID'] + indexed_table = sheet_data[lab]["indexed_table"] + indexed_cid = indexed_table[d["location"]]["CID"] # check the CID cell is not empty - if indexed_cid and indexed_cid != d['cid']: + if indexed_cid and indexed_cid != d["cid"]: all_empty = False message = ( - f"try to fill \'{d['cid']}\' in the CID cell but there\'s " - f"\'{indexed_cid}\' occupies the cell" + f"try to fill '{d['cid']}' in the CID cell but there's " + f"'{indexed_cid}' occupies the cell" + ) + non_empty_list.append( + { + "message": message, + "row_index": indexed_table[d["location"]]["row_index"], + "location": d["location"], + } ) - non_empty_list.append({ - 'message': message, - 'row_index': indexed_table[d['location']]['row_index'], - 'location': d['location'] - }) return all_empty, non_empty_list def fill_in_google_sheet(data: list[dict], sheet_data: dict) -> bool: - """ Fill the data in the Google Sheet - - @param:data, a list contains the bunch of dictionary data, each - data has the following keys, cid, location and the - gm_image_link - e.g. - data = [ - { - 'cid': '202312-12345', - 'location': 'TEL-L3-F24-S5-P2', - 'gm_image_link': '' - }, - { - 'cid': '202302-12346', - 'location': 'TEL-L3-F23-S5-P2', - 'gm_image_link': 'http://oem-share' - } - ] - @param:sheet_data, a dictionary which is from get_sheet_data function + """Fill the data in the Google Sheet + + @param:data, a list contains the bunch of dictionary data, each + data has the following keys, cid, location and the + gm_image_link + e.g. + data = [ + { + 'cid': '202312-12345', + 'location': 'TEL-L3-F24-S5-P2', + 'gm_image_link': '', + 'mac': '', + 'ip': '' + }, + { + 'cid': '202302-12346', + 'location': 'TEL-L3-F23-S5-P2', + 'gm_image_link': 'http://oem-share', + 'mac': '', + 'ip': '' + } + ] + @param:sheet_data, a dictionary which is from get_sheet_data function """ gs_obj = create_google_sheet_instance() batch_update_data = [] for d in data: - table = parse_location(d['location'])['Lab'] - headers = sheet_data[table]['headers'] - indexed_table = sheet_data[table]['indexed_table'] - row_index = indexed_table[d['location']]['row_index'] - cid_column_chr = chr(65 + headers['CID']) - gm_image_link_chr = chr(65 + headers['Certified_OEM_Image']) + table = parse_location(d["location"])["Lab"] + headers = sheet_data[table]["headers"] + indexed_table = sheet_data[table]["indexed_table"] + row_index = indexed_table[d["location"]]["row_index"] + cid_column_chr = chr(65 + headers["CID"]) + gm_image_link_chr = chr(65 + headers["Certified_OEM_Image"]) + mac_chr = chr(65 + headers["MAC"]) + ip_chr = chr(65 + headers["IP"]) # append cid data who is to be filled in cid_data = { - 'range': f'{table}!{cid_column_chr}{row_index}', - 'values': [[d['cid']]] + "range": f"{table}!{cid_column_chr}{row_index}", + "values": [[d["cid"]]], } batch_update_data.append(cid_data) # append gm_image_link_data data who is to be filled in gm_image_link_data = { - 'range': f'{table}!{gm_image_link_chr}{row_index}', - 'values': [[d['gm_image_link']]] + "range": f"{table}!{gm_image_link_chr}{row_index}", + "values": [[d["gm_image_link"]]], } batch_update_data.append(gm_image_link_data) + # append mac data who is to be filled in + mac_data = { + "range": f"{table}!{mac_chr}{row_index}", + "values": [[d["mac"]]], + } + batch_update_data.append(mac_data) + + # append ip data who is to be filled in + ip_data = { + "range": f"{table}!{ip_chr}{row_index}", + "values": [[d["ip"]]], + } + batch_update_data.append(ip_data) + res = gs_obj.update_range_data(data=batch_update_data) print(res) def update_cert_lab_google_sheet(data: list[dict]) -> dict: - """ Fill the DUT information to the Cert Lab Google Sheet - - @param:data, a list contains the bunch of dictionary data, each - data has the following keys, cid, location and the - gm_image_link - e.g. - data = [ - { - 'cid': '202312-12345', - 'location': 'TEL-L3-F24-S5-P2', - 'gm_image_link': '' - }, - { - 'cid': '202302-12346', - 'location': 'TEL-L3-F23-S5-P2', - 'gm_image_link': 'http://oem-share' - } - ] - @return - bool: True if all data are valid, otherwise False - list: invalid list. It shows all invalid data in a list + """Fill the DUT information to the Cert Lab Google Sheet + + @param:data, a list contains the bunch of dictionary data, each + data has the following keys, cid, location and the + gm_image_link + e.g. + data = [ + { + 'cid': '202312-12345', + 'location': 'TEL-L3-F24-S5-P2', + 'gm_image_link': '', + 'mac': '', + 'ip': '' + }, + { + 'cid': '202302-12346', + 'location': 'TEL-L3-F23-S5-P2', + 'gm_image_link': 'http://oem-share', + 'mac': '', + 'ip': '' + } + ] + @return + bool: True if all data are valid, otherwise False + list: invalid list. It shows all invalid data in a list """ # Sanitize data valid, invalid_list = is_valid_input_data(data) @@ -280,10 +324,7 @@ def update_cert_lab_google_sheet(data: list[dict]) -> dict: sheet_data = get_sheet_data() # Check those cells are empty - empty, non_empty_list = are_candidated_sheet_cells_empty( - data, - sheet_data - ) + empty, non_empty_list = are_candidated_sheet_cells_empty(data, sheet_data) if not empty: raise Exception( @@ -295,19 +336,23 @@ def update_cert_lab_google_sheet(data: list[dict]) -> dict: return response -if __name__ == '__main__': +if __name__ == "__main__": # get_sheet_data() data = [ { - 'cid': '20230405-12345', - 'location': 'TEL-L3-F24-S5-P2', - 'gm_image_link': '', - 'sku': '' + "cid": "20230405-12345", + "location": "TEL-L3-F24-S5-P2", + "gm_image_link": "", + "sku": "", + "mac": "", + "ip": "", }, { - 'cid': '20230405-12346', - 'location': 'TEL-L5-F20-S1-P1', - 'gm_image_link': 'http://oem-share' - } + "cid": "20230405-12346", + "location": "TEL-L5-F20-S1-P1", + "gm_image_link": "http://oem-share", + "mac": "", + "ip": "", + }, ] update_cert_lab_google_sheet(data) diff --git a/Tools/PC/transfer-hw-to-cert/handlers/hic_handler.py b/Tools/PC/transfer-hw-to-cert/handlers/hic_handler.py index 6e96723..7fca165 100644 --- a/Tools/PC/transfer-hw-to-cert/handlers/hic_handler.py +++ b/Tools/PC/transfer-hw-to-cert/handlers/hic_handler.py @@ -1,42 +1,89 @@ import requests import json -HIC_URL = 'http://10.102.180.14:5000' +HIC_URL = "http://10.102.180.14:5000" -def query_database() -> dict: - """ Query the databse to get whole mapping +def hic_request(parameter: str) -> dict: + """Query the databse to get whole mapping - @return, a dictionary data like below - { - "48:9e:bd:ea:d3:d4": "Varc-PV-SKU6-1_202302-31212", - "00:be:43:bd:cf:16": "TRM-DVT1-L10-C1_202304-31528" - } + @return, a dictionary data """ mapping = {} try: - response = requests.request( - 'GET', - f'{HIC_URL}/q' - ) + response = requests.request("GET", f"{HIC_URL}/{parameter}") if response.status_code < 200 or response.status_code > 299: response.raise_for_status() return response.json() except Exception as e: - print(f"====Unable to query the HIC database.==== " - f"Please check your connection. Error: {e}") + print( + f"====Unable to query the HIC database.==== " + f"Please check your connection. Error: {e}" + ) return mapping +def query_database() -> dict: + """Query the databse to get whole mapping + + @return, a dictionary data like below + { + "48:9e:bd:ea:d3:d4": "Varc-PV-SKU6-1_202302-31212", + "00:be:43:bd:cf:16": "TRM-DVT1-L10-C1_202304-31528" + } + """ + return hic_request("q") + + +def query_ip() -> dict: + """Query the databse to get whole mapping + + @return, a dictionary data like below + { + "LUSA14-PV-SKU8_202401-33447": ["10.102.183.232"], + "PX-SIT-C6_202404-33916":["10.102.182.246","10.102.182.104"] + } + """ + return hic_request("q?db=ipo") + + +def get_dut_info(cid: str, macs: dict, ips: dict) -> dict: + """mapping the dut data with mac, ip and cid + + @return, a dictionary data + """ + info = {} + for k, v in macs.items(): + if cid in v: + info["MAC"] = k + for k, v in ips.items(): + if cid in k: + info["IP"] = v[0] + return info + + +def get_duts_info(cids: list[str]) -> dict: + """mapping all the duts data with mac, ip and cid + + @return, a dictionary data + """ + macs = query_database() + ips = query_ip() + duts_info = {} + for cid in cids: + duts_info[cid] = get_dut_info(cid, macs, ips) + return duts_info + + def delete_duts(cids: list[str]) -> None: - """ Remove DUTs from HIC site + """Remove DUTs from HIC site - @param:cids, a list which contains CIDs - e.g cids: ['202306-12345'] + @param:cids, a list which contains CIDs + e.g cids: ['202306-12345'] """ if not cids: - print('Do nothing due to empty cids list received') + print("Do nothing due to empty cids list received") return # Query database to get whole records @@ -44,37 +91,33 @@ def delete_duts(cids: list[str]) -> None: duts = [] for cid in cids: - temp_d = { - 'sku_name': '', - 'mac_addresses': [] - } + temp_d = {"sku_name": "", "mac_addresses": []} # Find designated DUT from mapping # Get its mac addresses into temp_d for k, v in mapping.items(): if cid in v: - temp_d['sku_name'] = v - temp_d['mac_addresses'].append(k) - if not temp_d['sku_name']: - print(f"Ignore {cid} since there\'s no record on HIC") + temp_d["sku_name"] = v + temp_d["mac_addresses"].append(k) + if not temp_d["sku_name"]: + print(f"Ignore {cid} since there's no record on HIC") continue - if temp_d['sku_name']: + if temp_d["sku_name"]: duts.append(temp_d) if len(duts) == 0: - print('All of the following DUTs have been removed') + print("All of the following DUTs have been removed") print(cids) return - print('Will remove the following DUTs from HIC...') + print("Will remove the following DUTs from HIC...") print(json.dumps(duts, indent=2)) success = 1 for d in duts: - for mac in d['mac_addresses']: + for mac in d["mac_addresses"]: try: response = requests.request( - 'GET', - f'{HIC_URL}/d?db=sku&k={mac}' + "GET", f"{HIC_URL}/d?db=sku&k={mac}" ) if response.status_code < 200 or response.status_code > 299: response.raise_for_status() @@ -83,4 +126,4 @@ def delete_duts(cids: list[str]) -> None: print(f"Error: Unable to remove {d['sku_name']} ({mac})") print(e) if not success: - print('Error: Some DUTs cannot be removed from HIC!') + print("Error: Some DUTs cannot be removed from HIC!") diff --git a/Tools/PC/transfer-hw-to-cert/main.py b/Tools/PC/transfer-hw-to-cert/main.py index b665608..ece11fc 100644 --- a/Tools/PC/transfer-hw-to-cert/main.py +++ b/Tools/PC/transfer-hw-to-cert/main.py @@ -4,40 +4,47 @@ from handlers.cqt_handler import get_candidate_duts from handlers.telops_handler import create_send_dut_to_cert_card_in_telops from handlers.cert_team_google_sheet_handler import ( - update_cert_lab_google_sheet + update_cert_lab_google_sheet, ) from handlers.c3_handler import update_duts_info_on_c3 from handlers.notifier import add_comment -from handlers.hic_handler import delete_duts as delete_duts_from_hic +from handlers.hic_handler import ( + delete_duts as delete_duts_from_hic, + get_duts_info as get_duts_info_from_hic, +) from utils.common import is_valid_cid, is_valid_location def register_arguments(): parser = ArgumentParser() parser.add_argument( - '-k', '--key', - help='The key string of specific Jira Card. e.g. CQT-2023', + "-k", + "--key", + help="The key string of specific Jira Card. e.g. CQT-2023", type=str, - required=True + required=True, ) parser.add_argument( - '-j', '--jenkins-job-link', - help='The link of jenkins job.', + "-j", + "--jenkins-job-link", + help="The link of jenkins job.", type=str, - default='http:///view/qa-services/job/qa-transfer-hw-to-cert-lab/', + default="http:///view/qa-services/job/qa-transfer-hw-to-cert-lab/", ) parser.add_argument( - '-c', '--c3-holder', - help='The DUT holder on C3. Please feed the launchpad id', + "-c", + "--c3-holder", + help="The DUT holder on C3. Please feed the launchpad id", type=str, - default='kevinyeh' + default="kevinyeh", ) parser.add_argument( - '-s', '--scenario', - help='The scenarios of this transfer hardware. Default is qa_process', + "-s", + "--scenario", + help="The scenarios of this transfer hardware. Default is qa_process", type=str, - choices=['qa_process', 'contractor_process'], - default='qa_process', + choices=["qa_process", "contractor_process"], + default="qa_process", ) return parser.parse_args() @@ -47,67 +54,82 @@ def main(): key = args.key try: - print('-' * 5 + 'Retrieving data from Jira Card' + '-' * 5) + print("-" * 5 + "Retrieving data from Jira Card" + "-" * 5) # Get data from specific Jira Card data = get_candidate_duts(key) print(json.dumps(data, indent=2)) # Sanitize - for d in data['data']: + for d in data["data"]: # Don't care the Location data - if not is_valid_cid(d['cid']): - raise Exception( - f'Error: Invalid CID in Jira Card {key}') + if not is_valid_cid(d["cid"]): + raise Exception(f"Error: Invalid CID in Jira Card {key}") - if args.scenario == 'qa_process': + if args.scenario == "qa_process": # Sanitize - for d in data['data']: - if not is_valid_location(d['location']): + for d in data["data"]: + if not is_valid_location(d["location"]): raise Exception( - f'Error: Invalid Location in Jira Card {key}') + f"Error: Invalid Location in Jira Card {key}" + ) + # collect all cid + cids = [d["cid"] for d in data["data"]] # Update Cert Lab Google Sheet - gm_image_link = data['gm_image_link'] - for d in data['data']: - d['gm_image_link'] = gm_image_link - print('-' * 5 + 'Updating Cert Lab Google Sheet' + '-' * 5) - update_cert_lab_google_sheet(data['data']) - # Update DUT holder and location on C3 - print('-' * 5 + 'Updating C3' + '-' * 5) - update_duts_info_on_c3( - data=data['data'], new_holder=args.c3_holder) - # Remove DUTs from HIC site - print('-' * 5 + 'Removing from HIC' + '-' * 5) - delete_duts_from_hic(cids=[d['cid'] for d in data['data']]) + gm_image_link = data["gm_image_link"] + if gm_image_link == "" or gm_image_link is None: + # setup duts in Lab4 to make cc-lab-manager + # could generate testflinger-agnet config + + # get mac and ip from HIC for each CID + cid_infos = get_duts_info_from_hic(cids) + + for d in data["data"]: + d["mac"] = cid_infos[d["cid"]]["MAC"] + d["ip"] = cid_infos[d["cid"]]["IP"] + d["gm_image_link"] = "" + + print("-" * 5 + "Updating Cert Lab Google Sheet" + "-" * 5) + update_cert_lab_google_sheet(data["data"]) + return + else: + for d in data["data"]: + d["gm_image_link"] = gm_image_link + print("-" * 5 + "Updating Cert Lab Google Sheet" + "-" * 5) + update_cert_lab_google_sheet(data["data"]) + # Update DUT holder and location on C3 + print("-" * 5 + "Updating C3" + "-" * 5) + update_duts_info_on_c3( + data=data["data"], new_holder=args.c3_holder + ) + # Remove DUTs from HIC site + print("-" * 5 + "Removing from HIC" + "-" * 5) + delete_duts_from_hic(cids) # Create Jira card to TELOPS board # No matter the process is qa_process or contractor process # There's always need cards in TELOPS board - print('-' * 5 + 'Creating card to TELOPS board' + '-' * 5) + print("-" * 5 + "Creating card to TELOPS board" + "-" * 5) create_send_dut_to_cert_card_in_telops( cqt_card=key, - description_original_data=data['description_original_data'], - assignee_original_id=data['assignee_original_id'], - data=data['data'] + description_original_data=data["description_original_data"], + assignee_original_id=data["assignee_original_id"], + data=data["data"], ) # notify: leave successful comment to Jira card add_comment( - comment_type='success', + comment_type="success", key=key, - data={ - 'jenkins_job_link': args.jenkins_job_link - } + data={"jenkins_job_link": args.jenkins_job_link}, ) except Exception: # notify: leave failed comment to Jira card add_comment( - comment_type='error', + comment_type="error", key=key, - data={ - 'jenkins_job_link': args.jenkins_job_link - } + data={"jenkins_job_link": args.jenkins_job_link}, ) raise -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/Tools/PC/transfer-hw-to-cert/tests/test_cert_team_google_sheet_handler.py b/Tools/PC/transfer-hw-to-cert/tests/test_cert_team_google_sheet_handler.py index 63255c0..e53f833 100644 --- a/Tools/PC/transfer-hw-to-cert/tests/test_cert_team_google_sheet_handler.py +++ b/Tools/PC/transfer-hw-to-cert/tests/test_cert_team_google_sheet_handler.py @@ -25,6 +25,13 @@ def test_valid_data(self): 'location': 'TEL-L3-F23-S5-P1', 'gm_image_link': '' }, + { + 'cid': '202304-28635', + 'location': 'TEL-L3-F23-S5-P1', + 'gm_image_link': '', + 'mac': '', + 'ip': '' + }, ] is_valid, invalid_list = is_valid_input_data(data) self.assertEqual(True, is_valid) diff --git a/Tools/PC/transfer-hw-to-cert/tests/test_utils_common.py b/Tools/PC/transfer-hw-to-cert/tests/test_utils_common.py index 39598f2..024043d 100644 --- a/Tools/PC/transfer-hw-to-cert/tests/test_utils_common.py +++ b/Tools/PC/transfer-hw-to-cert/tests/test_utils_common.py @@ -73,6 +73,10 @@ def test_valid_location(self): { 'name': 'correct location 4', 'location': 'TEL-L6-R02-S10-P1', + }, + { + 'name': 'correct location 5', + 'location': 'TEL-L4-F25-S8-1', } ] @@ -160,6 +164,16 @@ def test_parse_valid_location(self): 'Partition': '1' }, }, + { + 'name': 'correct location 3', + 'location': 'TEL-L4-F25-S8-1', + 'expected_result': { + 'Lab': 'TEL-L4', + 'Frame': 'F25', + 'Shelf': '8', + 'Partition': '1' + }, + }, ] for case in test_cases: actual_result = parse_location(case['location']) diff --git a/Tools/PC/transfer-hw-to-cert/utils/common.py b/Tools/PC/transfer-hw-to-cert/utils/common.py index 9feec31..946b270 100644 --- a/Tools/PC/transfer-hw-to-cert/utils/common.py +++ b/Tools/PC/transfer-hw-to-cert/utils/common.py @@ -3,21 +3,20 @@ def is_valid_cid(cid: str) -> bool: - """ Check if it's valid of the format of CID - The format of CID is yyyymm-{5 random number} - Valid range of yyyy is from 2000 to 2099 - Valid range of mm is 01 to 12 + """Check if it's valid of the format of CID + The format of CID is yyyymm-{5 random number} + Valid range of yyyy is from 2000 to 2099 + Valid range of mm is 01 to 12 """ - pattern = re.compile(r'^20\d{2}0[1-9]-\d{5}$|^20\d{2}1[0-2]-\d{5}$') + pattern = re.compile(r"^20\d{2}0[1-9]-\d{5}$|^20\d{2}1[0-2]-\d{5}$") return True if re.match(pattern, cid) else False def is_valid_location(location: str) -> bool: - """ Check if it's valid of the format of Location - """ + """Check if it's valid of the format of Location""" pattern = re.compile( - r'^TEL-(L\d-R\d{2}-S\d{1,2}-P[01]|L[356]-F\d{2}-S[1-8]-P[123])$' - ) + r"^TEL-(L\d-R\d{2}-S\d{1,2}-P[01]|L[3456]-F\d{2}-S[1-8]-(P[123]|[12]))$" # noqa: W605, E501 + ) return True if re.match(pattern, location) else False @@ -30,15 +29,18 @@ def read_json_config(config_path: str) -> dict: def parse_location(location: str) -> dict: - """ Parse the location data - """ + """Parse the location data""" part_re = re.compile( - '(?PTEL-L\d)-(?P[FR]\d+)-S(?P\d+)-P(?P\d+)' # noqa: W605, E501 + "(?PTEL-L\d)-(?P[FR]\d+)-S(?P\d+)-P{0,1}(?P\d+)" # noqa: W605, E501 ) match = re.search(part_re, location) - return {} if not match else { - 'Lab': match.group('Lab'), - 'Frame': match.group('Frame'), - 'Shelf': match.group('Shelf'), - 'Partition': match.group('Partition') - } + return ( + {} + if not match + else { + "Lab": match.group("Lab"), + "Frame": match.group("Frame"), + "Shelf": match.group("Shelf"), + "Partition": match.group("Partition"), + } + )