def __validate_input_params(self): """ Validate Input Parameters Only prompt the questions when the input is empty or not correct. This routine serves mainly use for bench/debug testing but is always called to validate input and offer corrective action. :return: """ # UUT Params --------------- while not validate_sernum(self.quack2_data['uut_sernum']): log.warning( "Could not validate Serial Number; prompting for input...") self.quack2_data['uut_sernum'] = aplib.ask_question( "UUT\n\nEnter Cisco System " "Serial Number (LLLYYWWSSSS): ") while not validate_pid(self.quack2_data['uut_pid']): log.warning("Could not validate Base PID; prompting for input...") self.quack2_data['uut_pid'] = aplib.ask_question( "UUT\n\nEnter Base PID (18 max chars): ") # Quack Cert Params --------------- if not self.quack2_data['cert_params']: raise Exception("Could not validate Quack2 Cert parameters.") return True
def lock_engage(self, reason): mode = lib.get_apollo_mode() if mode is 'DEBUG': logger.info('Debug mode, lock will be dismissed') self.reset_counts() return lib.PASS else: for i in range(3): questions = 'Too many FAILS because of {},Stop testing and contact TE now!'.format( reason) check_answer = lib.ask_question(question=questions, picture_path='images/fail.jpg', picture_size='small', timeout=1000) if 'debug' in check_answer: self.faillock_debug_menu() return lib.PASS elif config_fail_lock.password in check_answer: self.reset_counts() return lib.PASS elif check_answer not in config_fail_lock.password: text = 'Wrong answer!' lib.ask_question(question=text) else: logger.info('Wrong answers, count reset fail!') raise Exception("Wrong password! Unable to proceed test!")
def _menu_uut_config(self): ans = aplib.ask_question( "Select what to show:", answers=['ALL-compact', 'ALL-exploded', 'LOOKUP'], timeout=30) if ans == 'ALL-exploded': self._ud.print_uut_config(exploded=True) elif ans == 'ALL-compact': self._ud.print_uut_config() elif ans == 'LOOKUP': ans = aplib.ask_question("Enter key:") if ans in self._ud.uut_config: log.debug(print_large_dict(self._ud.uut_config[ans])) else: log.debug("Does not exist in uut_config.") return aplib.PASS
def sign_chip(self, **kwargs): """ QUACK2 Sign Note: The uut_config is also used as input. :menu: (enable=True, name=QUACK2, section=Diags, num=1, args={'menu': True}) :param (dict) kwargs: 'device_instance' :return (str): aplib.PASS/FAIL """ # Process input menu = kwargs.get('menu', False) self.device_instance = kwargs.get('device_instance', self._ud.device_instance) # TODO: check below condition, if safe then remove it # Sanity check. # identity_protection_type = self._ud.uut_config.get('identity_protection_type', None) # if not identity_protection_type: # log.error("Unknown Identity Protection type.") # log.error("Ensure the product definition is loaded and has an 'identity_protection_type' entry.") # return aplib.FAIL, "IdPro undefined." # if 'QUACK2' not in identity_protection_type: # log.warning("The UUT Identity Protection Type ='{0}'.".format(identity_protection_type)) # log.warning("Nothing to do here (not QUACK2).") # # Note: Skip since QUACK2 does not apply and we don't want to penalize the menu selection (if called). # return aplib.SKIPPED if self.device_instance is None or menu: # Get the device ID to program. # Do this first to satisfy unittest blind prompting. while self.device_instance is None or not str( self.device_instance).isdigit(): self.device_instance = aplib.ask_question( "Device instance [int]:") self.device_instance = int(self.device_instance) if not 0 <= self.device_instance < 10: raise Exception( "Device instance for Quack2 is invalid (must be 0 to 10).") # Check mode if not self._mode_mgr.is_mode('STARDUST'): log.warning( "Wrong mode ({0}) for this operation. Mode 'STARDUST' is required." .format(self._mode_mgr.current_mode)) return aplib.FAIL, "Wrong mode for QUACK2." # Arrange UUT required params # Ensure the PUID Keys are set appropriately: # 1. 'SYSTEM_SERIAL_NUM'/'SERIAL_NUM', 'MODEL_NUM' for main units # 2. 'SN', 'VPN' for peripherals self.uut_pid = self._ud.puid.pid self.uut_sernum = self._ud.puid.sernum # Perform the action log.debug("Device Instance = {0}".format(self.device_instance)) log.debug("PID = {0}".format(self.uut_pid)) log.debug("S/N = {0}".format(self.uut_sernum)) result = self.__sign_chip() return aplib.PASS if result else (aplib.FAIL, "Quack2 signing error.")
def faillock_debug_menu(self): logger.info('The container number is {}'.format(self.container)) menu1 = """Select an item to run? 0. EXIT 1. Show current count 2. Clear all Fail counts 3. Remove count files (Wipe out the serial number counts) 4. Show current count reset duration 5. Show history failtimes 6. Clear step fail counts""" menu2 = """Run item {} success. """ + menu1 menu3 = """Run item {} failed - {}. """ + menu1 menu = menu1 while True: try: answer = lib.ask_question(menu) if answer == '0': break elif answer == '1': num = self.get_data(self.container) lib.ask_question('The current count is {}'.format(num)) elif answer == '2': self.reset_counts() elif answer == '3': os.remove( '/opt/cisco/constellation/apollo/logs/faillock.db') elif answer == '4': lib.ask_questions( questions='The current duration is {}'.format( str(config_fail_lock.reset_time))) elif answer == '5': i = self.get_data(self.timestampkey) for i in range(i): key = self.container + str(i) time = self.get_data(key) lib.ask_question('the time{0} is {1}'.format(i, time)) elif answer == '6': self.write_data(config_fail_lock.designated_failstep1, 0) self.write_data(config_fail_lock.designated_failstep2, 0) self.write_data(config_fail_lock.designated_failstep3, 0) self.write_data(config_fail_lock.designated_failstep4, 0) menu = menu2.format(answer) except Exception, ex: menu = menu3.format(answer, str(ex))
def _menu_cof(self, preset=None): answer = aplib.ask_question( 'COF-Continue On Fail [{0}]:'.format(self.menu_cof), answers=['True', 'False']) if preset is None else preset if answer == 'True': self._ud.cof = True elif answer == 'False': self._ud.cof = False return aplib.PASS
def module_load(): first_exception = None config_data = lib.apdicts.configuration_data lib.apdicts.userdict['STATUS_buff'] = None logger.warning('Syncing Windows Machine {}'.format(config_data['win' + mb_tst_info['slot']]['windos_addr'])) global windows windows = WinConnectPM2(port=config_data['win'+mb_tst_info['slot']]['ctrl_port'], win_addr=config_data['win'+mb_tst_info['slot']]['windos_addr']) if first_exception is not None: if 'Address already in use' in first_exception: lib.ask_question(question='Please restart the apollo to reset the connection') raise first_exception logger.info('Successfully sync with Windows machine {} at port {}' .format(config_data['win' + mb_tst_info['slot']]['windos_addr'], config_data['win' + mb_tst_info['slot']]['ctrl_port'])) # Station config test build_windows_station_cofig(config_dict=config_data['win'+str(mb_tst_info['slot'])]) msg, step_name = load_step_parameter(ctrl_handle=windows) # step parameter test logger.warning(msg['msg']) return lib.PASS
def uut_power_on(mode=None): """ Connect UUT, and Set switch to power on UUT :return: """ global switch # switch2 has POE feature switch = switch2 # if set loop_on_error, hopes it will have a reminder to operator for connection check if lib.apdicts.test_info.current_status != 'PASS': logger.info('the current status is {}'.format( lib.apdicts.test_info.current_status)) uut.close() lib.ask_question( 'UUT seems NOT to power on, pls check cable connection !!') uut.open() time.sleep(5) power_off() time.sleep(10) power_on(mode) uut.jump_to_uboot(power_cycle=True) return lib.PASS
def manual_select(self, **kwargs): if self.pd: self.pd.product_selection = aplib.ask_question( "Select peripheral:", answers=self.pd.products_available) log.debug("Peripheral Selection = {0}".format( self.pd.get_flash_params())) if 'pcamaps' not in self._ud.uut_config: self._ud.uut_config['pcamaps'] = {} self._ud.uut_config['pcamaps'].update( self.pd.uut_config.get('pcamaps', {})) else: log.warning("There is no Peripheral UutDescriptor.") log.warning( "Ensure a valid Peripheral class has been initialized.") log.warning("The selection will be null.") return aplib.PASS
def __process_input_params(self): """ Only prompt the questions when the input is empty or not correct. This routine is mainly used for bench/debug testing. :return: """ # UUT Params --------------- while not validate_sernum(self.x509_data['uut_sernum']): log.warning("Could not validate Serial Number; prompting for input...") self.x509_data['uut_sernum'] = aplib.ask_question("UUT\n\nEnter Cisco System Serial Number (LLLYYWWSSSS): ") while not validate_mac_addr(self.x509_data['uut_mac']): log.warning("Could not validate MAC; prompting for input...") self.x509_data['uut_mac'] = \ self.__format_mac(aplib.ask_question("UUT\n\nEnter MAC Address (hex form): ")) while not validate_pid(self.x509_data['uut_pid']): log.warning("Could not validate Base PID; prompting for input...") self.x509_data['uut_pid'] = aplib.ask_question("UUT\n\nEnter Base PID (18 max chars): ") # SUDI Params --------------- if not self.__validate_request_type(): # Note: The cesiumlib forces the request type to only 'PROD'; need to determine if this remains. # This input has no effect as a param doesn't exist for the call. log.warning("Could not validate X.509 Request Type; prompting for input...") self.x509_data['request_type'] = \ aplib.ask_question("X.509 SUDI\n\nSelect request type: ", answers=X509Sudi.X509_REQUEST_TYPES) if not self.__validate_cert_method(): log.warning("Could not validate X.509 Cert Method; prompting for input...") self.x509_data['cert_method'] = \ aplib.ask_question("X.509 SUDI\n\nSelect Cert Method: ", answers=X509Sudi.X509_CERT_METHODS) if self.x509_data['cert_method'] == 'CERT_ONLY' and not self.__validate_public_key_file(): log.warning("Could not validate Public Key File when using CERT_ONLY method; prompting for input...") self.x509_data['public_key'] = aplib.ask_question("X.509 SUDI\n\nEnter Public Key File (incl path): ") if not self.__validate_sudi_hash(): log.warning("Could not validate SUDI Hash Type(s); prompting for input...") ans = aplib.ask_question("X.509 SUDI\n\nSelect Hash Type: ", answers=X509Sudi.SUDI_HASH_SELECT_LIST.keys()) self.x509_data['sudi_hash'] = [ans] self.x509_data['key_size'] = [X509Sudi.SUDI_HASH_SELECT_LIST[ans].size] # Other derived Params -------------- self.x509_data['common_name'] = "{0}-{1}".format(self.x509_data['uut_pid'], self.x509_data['uut_mac']) return
def prestep__chamber_staging(area): """ Chamber Staging Run by Supercontainer Operator selects which UUT slots to run for the chamber. :param (str) area: Test Area :return: """ info = aplib.get_pre_sequence_info() active_chamber_slots = '0' max_chamber_slots = len(info.containers) log.debug("MAX Chamber SLots = {0}".format(max_chamber_slots)) ans_good = False while not ans_good: ans = aplib.ask_question( "Enter sequential UUT slots for chamber testing [Default = 1-{0}]:\n" " Ex1. 1-10,12,15\n" " Ex2. 2,4,6,8\n" " Ex3. 2-11\n".format(max_chamber_slots)) ans = '1-{0}'.format(max_chamber_slots) if ans == '' else ans ans_good = True if re.match("(^[0-9]+[0-9,\-]*$)", ans) else False if ans.upper() == 'ABORT': raise apexceptions.AbortException( "Operator aborted chamber staging of UUT slots.") active_chamber_slots = common_utils.expand_comma_dash_num_list(ans) if max(active_chamber_slots) > max_chamber_slots: log.warning( "Chamber UUT slot selection exceeds maximum available; please re-enter." ) ans_good = False log.debug( "Active Chamber SLots accepted: {0}".format(active_chamber_slots)) ACTIVECS_KEY, MAXCS_KEY = get_chamber_slots_keys() aplib.cache_data(ACTIVECS_KEY, active_chamber_slots) aplib.cache_data(MAXCS_KEY, str(max_chamber_slots)) # Reset globals reset_globals() return aplib.PASS
def sign_certificate(self, **kwargs): """ X509 SUDI Sign Note: The uut_config is also used as input. :menu: (enable=True, name=X509 SUDI, section=Diags, num=1, args={'menu': True}) :param (dict) kwargs: 'device_instance' :return (str): aplib.PASS/FAIL """ # Process input self.device_instance = kwargs.get('device_instance', self._ud.device_instance) self.keytype = kwargs.get('keytype', None) x509_sudi_hash = kwargs.get('x509_sudi_hash', []) menu = kwargs.get('menu', False) # Sanity checks identity_protection_type = self._ud.uut_config.get('identity_protection_type', None) if not identity_protection_type: log.error("Unknown Identity Protection type.") log.error("Ensure the product definition is loaded and has an 'identity_protection_type' entry.") return aplib.FAIL, "IdPro undefined." if 'ACT2' not in identity_protection_type and 'QUACK2' not in identity_protection_type: log.warning("The UUT Identity Protection Type ='{0}'.".format(identity_protection_type)) log.warning("Nothing to do here.") # Note: Skip since this does not apply and we don't want to penalize the menu selection (if called). return aplib.SKIPPED if self.device_instance is None or menu: # Get the device ID to program. # Do this first to satisfy unittest blind prompting. while not self.device_instance or not str(self.device_instance).isdigit(): self.device_instance = aplib.ask_question("Device instance [int]:") self.device_instance = int(self.device_instance) if not 0 <= self.device_instance <= 10000: raise Exception("Device instance for X.509 SUDI (ACT2 chip) is invalid (must be 0 to 10000).") if self.device_instance != 0: # Check the device ID for motherboard/supervisor only. # This does NOT apply to peripherals. log.error("X509 SUDI certs typically apply to motherboards/supervisors ONLY.") log.error("A non-zero device instance was specified!") log.error("The device will need a MAC, S/N, & Base-PID to be properly signed.") log.error("If a non-motherboard needs an X.509 cert, please consult the Cisco Prod Ops TDE.") raise Exception("Non-zero device instance for X.509 certs.") if not x509_sudi_hash or menu: ans = aplib.ask_question('Choose an X.509 SUDI Hash:', answers=self.SUDI_HASH_SELECT_LIST.keys()) x509_sudi_hash = [ans] if not isinstance(x509_sudi_hash, list): x509_sudi_hash = [x509_sudi_hash] if len(x509_sudi_hash) > 1: log.warning("Multiple SUDI hashes detected: {0}".format(x509_sudi_hash)) log.warning("X.509 SUDI certs must be done in a specific order; successive programming is not allowed.") log.warning("For automation, please see 'Identification Protection' (IdPro).") log.warning("Please choose one hash only.") ans = aplib.ask_question('Choose an X.509 SUDI Hash:', answers=x509_sudi_hash) x509_sudi_hash = [ans] if not self.keytype or menu: if x509_sudi_hash in ['SHA256', 'CMCA2']: self.keytype = aplib.ask_question("Select SHA256 keytype:", answers=['QUACK2', 'ACT2-RSA']) elif x509_sudi_hash in ['CMCA3']: self.keytype = 'ACT2-HARSA' else: log.debug("Don't care about key_type.") # Verify and arrange UUT required params self.x509_data['uut_mac'] = self.__format_mac(self._ud.uut_config.get('MAC_ADDR')) self.x509_data['uut_sernum'] = self._ud.puid.sernum self.x509_data['uut_pid'] = self._ud.puid.pid # UUT Base PID ! (not Cfg PID) self.x509_data['sudi_hash'] = x509_sudi_hash # 'SHA1', 'SHA256', etc. or a list # Check mode if not self._mode_mgr.is_mode('STARDUST'): log.warning("Wrong mode ({0}) for this operation. Mode 'STARDUST' is required.".format(self._mode_mgr.current_mode)) return aplib.FAIL # Perform the action result = self.__sign_certificate() return aplib.PASS if result else aplib.FAIL
def load_hw_images(self, **kwargs): """ Load Mfg Images :menu: (enable=True, name=LOAD IMAGES, section=Upgrade, num=1, args={'master_list': None}) :menu: (enable=True, name=LOAD ALL IMAGES, section=Upgrade, num=1, args={}) :param (dict) kwargs: (list) master_list: key names of file items to load from product_definition e.g. ['btldr', 'linux', 'diag', 'fpga', 'mcu', 'SBC_CFG'] If a master_list is NOT provided the user will be asked to manually enter the files. 'DEFAULT' file name entry will use the existing product_definition specified files. (bool) force: True means to overwrite any existing :return (str): aplib.PASS/FAIL """ DEFAULT_IMAGE_TYPES = [ 'btldr', 'linux', 'diag', 'fpga', 'mcu', 'nic', 'SBC_CFG' ] # Process input master_list = kwargs.get('master_list', DEFAULT_IMAGE_TYPES) force = kwargs.get('force', True) ignore_result = kwargs.get('ignore_result', False) # Check mode if not self.mode_mgr.is_mode('LINUX'): errmsg = "Must be in LINUX mode to download files." log.error(errmsg) return aplib.FAIL, errmsg src_files = [] if not master_list: # Menu/Operator Option answer = aplib.ask_question( "Enter the image names to download.\n" "Comma separated if more than one.\n" "(Note1: Syntax = file1, file2, subdir1/file3, ...)\n" "(Note2: 'MASTER=x,y,z,...' will use a new master list.)\n" "(Note3: 'DEFAULT' will automatically choose the standard " "images from the product_definitions' master list: [{0}].)\n". format(master_list)) if 'MASTER=' in answer: tmp = answer.split('=') master_list = tmp[1].split(',') elif answer != 'DEFAULT': src_files = [i.strip() for i in answer.split(',')] else: # Override the master list if empty master_list = DEFAULT_IMAGE_TYPES if not master_list else master_list if not src_files: # Explicit param list option OR 'DEFAULT' user option. # Create source file list uut_target_list = list(set(master_list) & set(self.ud.uut_config)) src_files = [] log.debug( "UUT Target key list for TFTP: {0}".format(uut_target_list)) for item in uut_target_list: item_data = self.ud.uut_config.get(item, None) if not item_data: log.warning( "{0} has no data specified; confirm product_definition file data." .format(item)) continue source_items = [] if isinstance(item_data, dict): if 'image' in item_data: source_items.append(item_data['image']) source_items.append(item_data.get('cfg', None)) if 'image2' in item_data: source_items.append(item_data['image2']) source_items.append(item_data.get('cfg2', None)) elif 'images' in item_data: source_items.append(item_data['images']) elif len(item_data.keys()) > 0: for k, v in item_data.items(): if not isinstance(v, bool) and not isinstance( v, int): if 'image' in v: source_items.append(v['image']) else: source_items.append(item_data) for source_item in source_items: if source_item: log.debug("{0:<10} = {1}".format(item, source_item)) if isinstance(source_item, str): src_files.append( source_item) if source_item else None elif isinstance(source_item, dict): for sub_dir, image_list in source_item.items(): for item2 in image_list: src_files.append( os.path.join(sub_dir, item2)) if item2 else None elif isinstance(source_item, list): for item2 in source_item: src_files.append(item2) if item2 else None else: log.warning( "{0} type is unknown; check product_definition file for correct nomenclature." .format(source_item)) log.warning("It will be ignored.") # Remove duplicates src_files = list(set(src_files)) tftpargs = { 'src_files': src_files, 'dst_files': 'SAME', 'direction': 'get', 'force': force } log.debug("src_files={0}".format(src_files)) ret = self.linux.tftp(**tftpargs) if ret != aplib.PASS and ignore_result: log.warning("*** TFTP results will be IGNORED! ***") ret = aplib.PASS return ret
def run(self): """ Run the Menu System Note: ALL _menu_xxx() functions must return the Apollo PASS/FAIL result. Many menu items directly call the step functions used in production; this should be from the 'common_test_step_collection' AND '<product>_test_step_collection'. :return: """ # Now add any dynamic menu items based on Test Step Collection docstrings. self._dynamic_menu_build() menu_dict = collections.OrderedDict(self._md) menu_list = menu_dict.keys() try: # Loop on Menu until user quits. cmd = None while cmd != 'QUIT' and cmd != 'SOFT QUIT' and not aplib.need_to_abort( ): log.info(' ') log.info('Engineering Utility') log.info('=' * 20) ps = ' ({})'.format( self._ud.product_selection ) if self._ud.product_selection != self._ud.product_codename else '' msg = '{0} {1} {2} v{3}\n Product: {4}{10} PUID: [{5} {6}, {7} {8}, {9}]'.\ format(self._ud.product_line, self._ud.product_family.upper(), __title__, __version__, self._ud.product_codename, self._ud.puid.pid, self._ud.puid.vid, self._ud.puid.partnum, self._ud.puid.partnum_rev, self._ud.puid.sernum, ps) cmd = aplib.ask_question(msg, answers=menu_list, multi_select=False) log.info("Cmd = '{0}'".format(cmd)) if cmd not in menu_dict.keys(): log.error("Fatal error with menu; command not recognized!") log.error( "This can occur when using the Apollo CLI with the '--body' option " "and input items become out of sync.") log.error( "This can also occur when Apollo has an orphaned process via abort." ) raise Exception("Eng Menu sync.") if menu_dict[cmd] and cmd[0:3] != '___': if isinstance(menu_dict[cmd][0], str): func = getattr(self, menu_dict[cmd][0], None) elif inspect.isfunction(menu_dict[cmd][0]): func = menu_dict[cmd][0] else: func = None kwargs = menu_dict[cmd][1] # Execute function and collect results if func: full_result = func(**kwargs) if kwargs else func() if isinstance(full_result, tuple): result = full_result[0] msg = full_result[1] else: result = full_result msg = '' if result == aplib.PASS: self.result_list.append((cmd, True, msg)) elif result == aplib.SKIPPED: # SKIPPED is a don't care therefore allow pass. self.result_list.append((cmd, True, msg)) elif result == aplib.FAIL: self.result_list.append((cmd, False, msg)) else: # Other unknown results are a fail by default. self.result_list.append((cmd, False, msg)) # Print results log.info("Cmd Result: {0}.".format(result)) if not self.menu_cof and not all(self.result_list): break else: log.debug( "Cannot find function for menu entry: {0}".format( menu_dict[cmd][0])) else: # Exit the menu # Check for user abort if aplib.need_to_abort(): log.warning("An ABORT was requested!") self.result_list.append((cmd, False, 'ABORT')) else: # Graceful exit self.result_list.append((cmd, True, '')) except (aplib.apexceptions.AbortException, aplib.apexceptions.ScriptAbortException, Exception) as e: log.exception(e) log.warning("Aborting Menu Utility") self.result_list.append(('ABORT', False, 'Menu ABORT')) self._menu_quit_soft() finally: # Consolidate for final result ret = aplib.PASS if all([r for c, r, m in self.result_list ]) else aplib.FAIL log.debug("Final menu: {0}".format(ret)) return ret
def ask_change_probe(path): lib.ask_question(question='Change to port {}'.format(str(path)), picture_size='large', picture_path='media/station_cal_info.jpg') return lib.PASS
def _menu_uut_category(self): self._ud.category = aplib.ask_question("Select the UUT Category:", answers=self._category) log.info("UUT category = {0}".format(self._ud.category)) return aplib.PASS
def _menu_config_remote_station(self): ud = aplib.apdicts.userdict # A Remote host server (hop for when the Apollo server cannot directly access the T/S or UUT) input_done = False ud['remote_station'] = { 'server': { 'ip': '', 'user': '', 'password': '' }, 'uut': { 'ip': '', 'port': '', 'user': '', 'password': '' } } while not input_done: ud['remote_station']['server']['ip'] = aplib.ask_question( "Enter Remote Station Server IP (blank=none):") input_done = validate_ip_addr(ud['remote_station']['server']['ip']) if \ ud['remote_station']['server']['ip'] else True if ud['remote_station']['server']['ip']: input_done = False while not input_done: ud['remote_station']['server']['user'] = aplib.ask_question( "Enter Remote Station Username:"******"Enter Remote Station Password:"******"Enter Remote Station UUT Console T/S IP:") input_done = validate_ip_addr(ud['remote_station']['uut']['ip']) ud['remote_station']['uut']['port'] = aplib.ask_question( "Enter Remote Station UUT Console T/S Port:") if ud['remote_station']['uut']['ip']: ud['remote_station']['uut']['user'] = aplib.ask_question( "Enter T/S Username:"******"Enter T/S Password:"******"Remote Station") log.info("-" * 50) log.info(" Server IP = '{0}'".format( ud['remote_station']['server']['ip'])) log.info(" Server User = '******'".format( ud['remote_station']['server']['user'])) log.info(" UUT Console T/S IP = '{0}'".format( ud['remote_station']['uut']['ip'])) log.info(" UUT Console T/S Port = '{0}'".format( ud['remote_station']['uut']['port'])) log.info(" UUT Console T/S User = '******'".format( ud['remote_station']['uut']['user'])) log.info(" UUT Console T/S Pswd = '{0}'".format( ud['remote_station']['uut']['password'])) return aplib.PASS