def update_usb_interface(self, usb_interface): """Update the usb interface of the ComPort.""" if usb_interface and re.match( r"[0-9]+-[0-9]+(\.[0-9]+)*:[0-9]+(\.[0-9]+)?", usb_interface): self.usb_interface = usb_interface else: swilog.warning("%s is an invalid usb interface" % usb_interface)
def wait_for_usb_dev(self, timeout=300): """Wait for usb device to show up in sys fs.""" time_elapsed = time.time() end_time = time.time() + timeout if not self.name: return False while time_elapsed <= end_time: swilog.info("Waiting for USB device {} to be up...".format( self.name)) dev_path = self.get_device_path() if not dev_path: swilog.warning("Don't know how to check if {} is up".format( self.name)) return True if os.path.exists(dev_path): swilog.info("USB device {} is present!".format(self.name)) return True time.sleep(1) time_elapsed = time.time() return False
def device(self): """Create a device instance using ComPortDevice.""" if self.name() is None: return None device_name = self.name() if device_name.startswith("usb:"): device_name = self.name().replace("usb:", "") elif device_name.startswith("COM"): return device_name com_port_device = com.ComPortDevice(device_name) if com_port_device.is_usb_interface(): return com_port_device.get_dev_tty() elif com_port_device.is_usb_id(): if self.port_detector: return self.detect_ports() else: usb_dev = get_tty_device(device_name) if not usb_dev: swilog.warning( "No device found for USB %s at the moment" % device_name ) return None return "/dev/%s" % usb_dev elif com_port_device.is_dev_tty(): return com_port_device.name elif com_port_device.is_pcie_interface(): return com_port_device.name else: swilog.warning("Unrecognized device name: %s" % device_name) return None
def _find_matched_module_config(xml_dir_name, file_name): """Find the matched module config. e.g. wp7603.xml -> wp76xx.xml """ all_modules = os.listdir(xml_dir_name) matched_prefix_array = [] for module_name in all_modules: sequence_matcher = SequenceMatcher(None, file_name, module_name) all_matches = sequence_matcher.get_matching_blocks() prefix_match_length = 0 for _match in all_matches: if _match.a == 0 and _match.b == 0: prefix_match_length = _match.size matched_prefix_array.append(prefix_match_length) max_matched = max(matched_prefix_array) resolved_xml_file = None if max_matched >= 4: # Match at least four digits prefix. WPXX, ARXX, etc. # e.g. wp7604 will match wp76xx.xml xml_file_name_index = matched_prefix_array.index(max_matched) candidate_xml_file_name = all_modules[xml_file_name_index] resolved_xml_file = os.path.join(xml_dir_name, candidate_xml_file_name) swilog.warning("{} will be used!".format(resolved_xml_file)) return resolved_xml_file
def login(self, timeout=90): """Login to the embedded Linux console.""" delay = 10 count = int(timeout / delay) while self.check_communication() != 0: count -= 1 if count <= 0: swilog.error("No communication with the target after %ds.", timeout) break swilog.warning( "No communication with the target. Trying again in %ds.", delay) time.sleep(delay) try: super(target_ssh_qct, self).login(self.target_ip, "root", auto_prompt_reset=False, port=self.ssh_port) setup_linux_login(self) except Exception as inst: if not setup_linux_login(self): raise ComException("Unable to login") exit_code = 1 count = 0 while exit_code != 0: exit_code, rsp = self.run("stty columns %d" % TTY_SIZE, withexitstatus=1) count += 1 assert count != 5, "Impossible to send command stty to target"
def __init__(self, dev_tty=None, baudrate=115200, rtscts=False, **kwargs): self.tty = SerialPort.open(dev_tty, baudrate, rtscts=rtscts) if not self.tty: swilog.warning("Unable to open tty %s baudrate[%d] rtscts[%s]" % (dev_tty, baudrate, rtscts)) return ttyspawn.__init__(self, fd=self.tty.fd, **kwargs) target_qct.__init__(self, dev_tty=dev_tty, baudrate=baudrate, **kwargs)
def test_debug_level(): """Test debug values in different levels.""" print("test debug starts") swilog.debug("debug level message") swilog.info("info level message") swilog.warning("warning level message") swilog.error("error level message") swilog.critical("critical level message") print("test debug ends")
def reinit(self): """Reinit the link based on the port_type.""" swilog.warning("%s port may be gone!", self.port_type) swilog.info("Try to reconnect the %s port...", self.port_type) dev_tty = self.module.port_detector.get_com_port(self.port_type) self.info.update_name(dev_tty) self.close() self.init() self.update_alias()
def open(self, port, baudrate=115200): """Open the specified port.""" try: self.serial_port = com.SerialPort.open(port, baudrate) self.tty_session = com.ttyspawn(self.serial_port.fd) except: swilog.warning("Unable to open %s" % port) return False return True
def init(self): """Provide a generic way to initialize a link.""" swilog.debug("[Link %s] init" % self.name) if callable(self.init_cb): try: return self.init_cb(self) except Exception as e: swilog.debug(e) raise SlinkException(e) swilog.warning("No init function has been provided for link %s" % self.name) return None
def _get_baudrate(self, com_port_name): baudrate = self.com_port_info[com_port_name].baudrate default_baudrate = 115200 if not baudrate: swilog.warning( "Undefined baudrate for %s, so the default baudrate %d would be used" % (com_port_name, default_baudrate) ) return default_baudrate # the most common baudrate for swi modules return baudrate
def __init__(self, dev_tty=None, baudrate=115200, rtscts=False, **kwargs): self.dev_tty = dev_tty self.rtscts = rtscts self.save_kwargs = kwargs self.tty = SerialPort.open(dev_tty, baudrate, rtscts=rtscts) if self.tty: ttyspawn.__init__(self, fd=self.tty.fd, **kwargs) target_at.__init__(self, dev_tty, baudrate) else: swilog.warning("AT port %s is inaccessible at the moment" % dev_tty)
def _set_target_alias(self): """Assign every methods from the link object to the module.""" for fn in dir(self.__obj): if not hasattr(self.module, fn): # A method can be already implemented in the upper class. try: setattr(self.module, fn, getattr(self.__obj, fn)) if fn not in self.list_attr: self.list_attr.append(fn) except Exception as e: swilog.debug(e) swilog.warning("Warning: Impossible to set attribute")
def test_swilog_call(): """Activate the debug level to see all the messages. Usage:: "letp run --dbg-lvl 0 test/host/scenario/test_swilog.py" """ swilog.debug("debug message") swilog.info("info message") # to highlight a particular step in the test swilog.step("step message") swilog.warning("warning message") swilog.error("error message") swilog.critical("critical message")
def expect(self, *args, **kwargs): r"""Expect function from the pexpect library. Avoid too much backtraces. Send a command and expect some patterns (reg exp) with target.expect (list of regexp to wait), target.expect_exact (list of exact patterns to wait) or target.expect_in_order (wait patterns in the order of the list). If the expected pattern is found, target.before are the data before the pattern. target.after is the found pattern. .. code-block:: python # Timeout of 60s APP_TIMEOUT = 60 # Start the application target.send("app start %s\r" % APP_NAME) # Wait for "Failures: \d+" or timeout id = target.expect([pexpect.TIMEOUT, "Failures: \d+"], APP_TIMEOUT) # if id == 0, it is a timeout # if id == 1, "Failures: \d+" was found assert id == 1, "Timeout received!" # Check there is 0 failure in the response assert "Failures: 0" in target.after, "Some tests failed!" target.sendline("ls \/") # Wait for "data", then "bin", "boot", and at the end "var" rsp = target.expect_in_order(["data", "bin", "boot", "var"], 10) """ try: return super(target_ssh_qct, self).expect(*args, **kwargs) except (EOFError, pexpect.EOF): swilog.warning("EOF received") timeout = 60 assert self.wait_for_device_up( timeout) == 0, "Device was not started" self.reinit() # Retry, not protected this time return super(target_ssh_qct, self).expect(*args, **kwargs) except Exception as e: swilog.warning(e) if self.closed: raise ComException("Connection to the device is lost")
def setup(self): """Setup TCP server.""" if not hasattr(self.server, "max_size"): swilog.warning( "[TCP SERVER] server.max_size not defined. Set it to default 128" ) self.server.max_size = 10 * 1024 if not hasattr(self.server, "responder"): swilog.warning( "[TCP SERVER] server.responder not defined. Set it to default True" ) self.server.responder = True if not hasattr(self.server, "cur_data"): self.server.cur_data = b"" if not hasattr(self.server, "wait_after_transaction"): self.server.wait_after_transaction = 5
def _get_com_port_device_lst(self, com_port_name=com.ComPortType.CLI.name): """Iterate over the list of com port. Find possible matches based on. com_port_name. The look up order should be usb-interface (e.g. 5-2:1.3) -> com port description. Returns: A list of possible usb com port device name. """ possible_devices_lst = [] most_likely_dev_tty = None com_port_info = self.com_port_info[com_port_name] if not com_port_info: raise Exception("No description for port %s" % com_port_name) usb_interface = com_port_info.usb_interface com_port_device = com.ComPortDevice(usb_interface) if com_port_device.is_usb_interface(): # Look up usb-interface most_likely_dev_tty = com_port_device.get_dev_tty() swilog.info( "%s is likely the %s port" % (most_likely_dev_tty, com_port_name) ) if most_likely_dev_tty: possible_devices_lst.append(most_likely_dev_tty) return possible_devices_lst com_port_desc = com_port_info.desc if not com_port_desc: swilog.warning( "Unable to find the description of the port %s", com_port_name ) return possible_devices_lst # Look up port description for port_obj in serial.tools.list_ports.comports(): device = port_obj.device device_description = port_obj.description if com_port_desc in device_description: possible_devices_lst.append(device) return possible_devices_lst
def get_testCfg(name): """Get Test specific configuration if there is any in json.""" test_list = TestConfig.test_list if test_list == []: return [] raw_name = name.split("[")[0] for i, test in enumerate(test_list[0]): if raw_name in test[0]: ret = [test[1]] # In case a test function is called several times but with # several configurations, # delete this one because it should not be used next time. # For the moment it is not applicable to parametrized tests # unless you specify # all the parametrized tests one by one in the json such as: # "name": "legato/foo.py::my_test_function[param1]" # "name": "legato/foo.py::my_test_function[param2]" if "[" not in name or ("[" in name and "[" in test[0]): swilog.warning("Remove config of {}".format( test_list[0][i])) del test_list[0][i] else: # Check it is the only parametrized test. # If not, assert to tell that # having several tests with several configs are not supported # Get all the tests all_tests = [ test[0] for i, test in enumerate(test_list[0]) if raw_name in test[0] ] assert len(all_tests) == 1, ( "If you want to call the test %s " "several times with several " % name + "configurations in the json file, you must specify all " "the parametrized " 'tests in the json file: \n"name": ' '"legato/foo.py::my_test_function[param1]" ' '\ninstead of \n"name": "legato/foo.py::my_test_function""' ) return ret # In the case the test in the json file is not exactly # the run test (folder, module name or Atlas .aut) swilog.warning("Did not find the test '%s' in the json file. " "No specific configuration can be applied." % name) return []
def run(self, cmd, timeout=-1, local_echo=True, withexitstatus=False, check=True): r"""Run a command, check the exit status by default and returns the response. :param cmd: command to execute :param timeout: timeout of the command in second :param local_echo: read the echo of the command before :param withexitstatus: return the exit status with the :param response: in a tuple (exit, rsp) :param check: If False do not assert if the command exit status is not 0 :returns: stdout/stderr of the command or a tuple (exit, stdout/stderr of the command) if withexitstatus is set .. code-block:: python # Test if "PASSED" is in the logs rsp = target.run("/sbin/logread") assert "PASSED" in rsp, "test returned [FAILED]" # Check that the exit status of the command is not 0. Use withexitstatus. exit, rsp = target.run(" [ -e %s ]" % (testFilePath), withexitstatus=True) assert exit != 0, "[FAILED] file is created after the write operation" """ try: return self.run_main(cmd, timeout, local_echo, withexitstatus, check) except (EOFError, pexpect.EOF): swilog.warning("EOF received") assert self.wait_for_device_up( timeout) == 0, "Device was not started" self.reinit() # Retry, not protected this time return self.run_main(cmd, timeout, local_echo, withexitstatus, check) except Exception as e: swilog.warning(e) raise ComException( "Unable to send the cmd {} through ssh link".format(cmd))
def power_supply(request, read_config_default): """Get the power supply object if configured. Control target power via hardware switch in test. Example: Power supply management .. code-block:: python def L_ps_0001(power_supply): power_supply.cycle() """ ret = None if read_config_default.findtext("hardware/power_supply") is not None: # get the power supply element xml_pwr_supply = read_config_default.find("hardware/power_supply") controller_type = xml_pwr_supply.findtext("type") ret = request.node.config.controller[controller_type](xml_pwr_supply) else: swilog.warning( "No hardware configuration supplied: reboot manually your target!") yield ret
def wait_for_device_up(self, timeout=180): """Check if device is up by testing all ports are responsive.""" time_elapsed = time.time() end_time = time.time() + timeout while time_elapsed <= end_time: swilog.info("Wait for device is up...") if not self.is_port_accessible(com.ComPortType.AT.name): swilog.warning("checking at port") self.get_link(com.ComPortType.AT.name).reinit() elif self.links[1].info.is_used() and not self.is_port_accessible( com.ComPortType.CLI.name ): self.get_link(com.ComPortType.CLI.name).reinit() else: swilog.info("Device is up!") return 0 time.sleep(1) time_elapsed = time.time() swilog.warning("Device may be at some bad state") return 1
def __init__(self, target_name, target_ip, ssh_add, ssh_port, config_target, inst_name): super(ModuleLinux, self).__init__(target_name) self.ssh2 = self.ssh_logread = None self.ssh_cmd = { "network_if": "%s/ssh/network_if", "config_eth0": "ifconfig eth0 %s", "config_ecm0": "ifconfig ecm0 %s", } self._target_ip = target_ip self.config_target = config_target.getroot() self._ssh_add = ssh_add self._ssh_port = ssh_port self.inst_name = inst_name # Link 1 = Console self.links[1].port_type = com.ComPortType.CLI.name self.links[1].init_cb = self.init_cli_port # Link 2 = AT self.links[2].port_type = com.ComPortType.AT.name self.links[2].init_cb = self.init_at_port for idx in [1, 2]: self.links[idx].info = SlinkInfo( config_target, self.pathed_slink_template % (inst_name, idx)) self.links[idx].add_alias(self.links[idx].info.desc()) self.links[idx].add_alias(self.slink_template % idx) if (ssh_add is not None and self.config_target.find( "%s/ssh" % inst_name).get("used") == "1"): # the second (ssh2) and third ssh (ssh_logread) # link will be added dynamically # if needed in the test by a fixture self.links["ssh"] = ModuleLink(self, "ssh") self.links["ssh"].init_cb = self.init_ssh_link self.links["ssh"].add_alias("ssh") ssh_desc = self.config_target.findtext("%s/ssh/desc" % inst_name) self.links["ssh"].add_alias(ssh_desc) assert (self.slink1 is not None or self.slink2 is not None or self.ssh is not None ), "target fixture needs at least one communication link!" ssh_main_link = self.config_target.find("%s/ssh" % inst_name).get("main_link") if self.ssh is not None and ssh_main_link == "1": self.set_link_alias("ssh", "target") try: if self.ssh is not None and self.slink1 is not None: # Change the default target to serial link self.set_link_alias(1, "target") network_if = self.config_target.findtext( self.ssh_cmd["network_if"] % self.inst_name) if self.ssh.check_communication() != 0 or ( self.slink1.login() and self.get_ip_addr(network_if) != self.ssh.target_ip): self.get_ip_addr(network_if) self.configure_board_for_ssh() self.ssh.login() # Restore ssh as default link self.set_link_alias("ssh", "target") # For the long lines, change the terminal length. Unfortunately, # not available for serial link self.ssh.setwinsize(com.TTY_SIZE, 200) self.login() # Set the mac address if needed target_mac_add = self.config_target.findtext("%s/target/mac_add" % self.inst_name) if target_mac_add is not None: self.set_mac(target_mac_add) except Exception as e: swilog.warning("Error during initialization: %s" % e)
def configure_board_for_ssh(self): """Use uart to configure SSH.""" swilog.debug("configure_board_for_ssh") if self.is_autoconf(): swilog.debug("configure_board_for_ssh: skipping config") return # Change default link to serial link self.target = self.slink1 self.login() if self.config_target.findtext("%s/ssh/ip_method" % self.inst_name) == "fixed": ip_addr = self.config_target.findtext("%s/ssh/ip_address" % self.inst_name) else: ip_addr = "" if (self.config_target.findtext(self.ssh_cmd["network_if"] % self.inst_name) == "eth0"): # Set the mac address if needed target_mac_addr = self.config_target.findtext("%s/target/mac_add" % self.inst_name) if target_mac_addr is not None: self.set_mac(target_mac_addr) # Wait a little. It seems that udhcpc does not work sometimes # if configure_eth is done just after reboot time.sleep(10) self.configure_eth(ip_addr) # Open ssh port self.open_port(22) else: self.configure_ecm(ip_addr) # Open ssh port self.open_port(22) # Open DHCP ports self.open_port(67, "udp") self.open_port(68, "udp") host_ip = self.config_target.findtext("host/ip_address") split_target_ip = self.ssh.target_ip.split(".") self.slink1.sendline("ifconfig %s" % self.config_target.findtext( self.ssh_cmd["network_if"] % self.inst_name)) slink_id = self.slink1.expect( [pexpect.TIMEOUT, r"Mask:(\d*\.\d*\.\d*\.\d*)"], 5) # Set the default count to 1. Only the upper # part of the IP address will be checked count = 1 if slink_id == 1: # Ignore if timeout in case the response from ifconfig change mask = self.slink1.match.group(1) # Set count to the number of part to check in the IP address count = mask.count("255") self.slink1.prompt() if (host_ip is not None and host_ip != "" and host_ip.split(".")[0:count] != split_target_ip[0:count]): swilog.warning( "host ip %s and target ip %s in xml not in the same subnet!" % (host_ip, self.ssh.target_ip)) self.slink1.run("iptables -I INPUT -j ACCEPT") itf = self.config_target.findtext(self.ssh_cmd["network_if"] % self.inst_name) self.wait_for_itf(itf, 20) self.new_target_ip = self.get_ip_addr(itf) # Restore default link self.target = self.ssh if self.new_target_ip != self.ssh.target_ip: swilog.debug("Old target ip address %s" % self.ssh.target_ip) self.ssh.target_ip = self.new_target_ip self.target.target_ip = self.new_target_ip os.environ["TARGET_IP"] = self.new_target_ip self.ssh.reinit() # Reconfigure the other ssh links if hasattr(self, "ssh2") and self.ssh2: self.ssh2.target_ip = self.ssh.target_ip self.ssh2.reinit() if hasattr(self, "ssh_logread") and self.ssh_logread: self.ssh_logread.target_ip = self.ssh.target_ip self.ssh_logread.reinit()