def get_board_workdir( ma: linux.LinuxShell, ) -> str: p2 = ma.workdir / tbot.selectable.Board.name if not p2.exists(): ma.exec0("mkdir", "-p", p2) return p2
def get_toolchain_dir( ma: linux.LinuxShell, ) -> str: """ return path where toolchains are installed. :param LinuxMachine: Linux machine """ p2 = ma.workdir / "toolchain" if not p2.exists(): ma.exec0("mkdir", "-p", p2) return p2
def lx_check_dmesg( ma: linux.LinuxShell, dmesg_strings = None, dmesg_false_strings = None, ) -> bool: """ check if dmesg output contains strings in dmesg_list :param machine ma: machine on which dmesg command is executed :param list dmesg_strings: list of strings which must be in dmesg :param list dmesg_false_strings: list of strings which sould not occur in dmesg """ buf = ma.exec0("dmesg") ret = True if dmesg_strings != None: for s in dmesg_strings: if s not in buf: msg = f"String {s} not in dmesg output." tbot.log.message(msg) ret = False if dmesg_false_strings != None: for s in dmesg_false_strings: if s in buf: msg = f"String {s} in dmesg output." tbot.log.message(msg) ret = False return ret
def ensure_sd_unit(lnx: linux.LinuxShell, services: typing.List[str]) -> None: """ check if all systemd services in list services run on linux machine lnx. If not, try to start them. :param lnx: linux shell :param services: list of systemd services """ if lnx.name not in _SERVICES_CACHE: _SERVICES_CACHE[lnx.name] = {} for s in services: if s in _SERVICES_CACHE[lnx.name]: continue if not lnx.test("systemctl", "is-active", s): lnx.exec0("sudo", "systemctl", "start", s) _SERVICES_CACHE[lnx.name][s] = True
def find_ip_address( lnx: linux.LinuxShell, route_target: typing.Optional[str] = None, force: bool = False, ) -> str: """ Find out an IP-address of a host. In times where most hosts have many IP addresses, this is not as trivial as one would like. This testcase approaches the problem by trying to find the IP-address, the host would use on a certain route. By default, this is the route to reach a theoretical host at ``1.0.0.0``. This will yield a sensible result in *most* cases but of course will not always be the address you want. For more fine-grained control you can pass a ``route_target``. This is the IP-address of this theoretical host to reach. :param linux.LinuxShell lnx: The host to work on. :param str route_target: An optional route target. Defaults to ``1.0.0.0``. :param bool force: By default, this testcase caches results for faster lookup when called multiple times. This parameter enforces a re-check which might be useful when the network configuration on ``lnx`` changed. :rtype: str :returns: The IP-address which was found. .. versionadded:: 0.8.3 .. versionchanged:: 0.9.2 Fixed ``find_ip_address()`` not working properly when the route target is a local address. """ if route_target is None: # 1 equals to 1.0.0.0 which will probably yield a sensible route in # most cases. route_target = "1" if (lnx, route_target) not in _IP_CACHE: if shell.check_for_tool(lnx, "ip"): output = strip_ansi_escapes( lnx.exec0("ip", "route", "get", route_target, linux.Pipe, "cat")) match = re.match( r"(?:local\s+)?\S+\s+(?:via\s+\S+\s+)?dev\s+\S+\s+src\s+(\S+).*", output, re.DOTALL, ) assert match is not None, f"Failed to parse `ip route` output ({output!r})!" ip = match.group(1) else: raise NotImplementedError("Found no way to find out ip-address") _IP_CACHE[(lnx, route_target)] = ip return _IP_CACHE[(lnx, route_target)]
def lx_replace_line_in_file( ma: linux.LinuxShell, filename, searchstring, newvalue, use_sudo = False, dumpfile = True, ) -> bool: """ replace a line in filename which contains searchstring with line containing newvalue :param machine ma: machine on which commands are executed :param filename str: filename of file on which testcase runs :param searchstring str: line which contain this string gets deleted :param newvalue str: newline which get added to the end of file :param use_sudo bool: use sudo default False :param dumpfile bool: dump file with cat before and after replace string default True """ pre = [] if use_sudo: pre = ["sudo"] if dumpfile: ma.exec0(*pre, "cat", filename) ma.exec0(*pre, "sed", "-i", f"/{searchstring}/d", filename) ma.exec0(*pre, "echo", newvalue, linux.Raw(">>"), filename) if dumpfile: ma.exec0(*pre, "cat", filename) return True
def lx_devmem2_get( ma: linux.LinuxShell, addr, typ, ) -> str: strings = ['Value at address', 'Read at address'] ret = ma.exec0("devmem2", addr, typ).splitlines() for l in ret: if any(s in l for s in strings): val = l.split(" ") return val[-1] raise RuntimeError("devmem2 unexpected output")
def lx_create_revfile( ma: linux.LinuxShell, revfile, startaddr, endaddr, mask = '0xffffffff', readtype = 'w', ) -> bool: # check if devmem exist ret = lx_cmd_exists(ma, 'devmem2') if ret == False: return False try: fd = open(revfile, 'w') except IOError: raise RuntimeError("Could not open: " + revfile) ret = ma.exec0("uname", "-a").splitlines() vers = ret[0] processor = "ToDo" hw = 'ToDo' fd.write("# pinmux\n") fd.write("# processor: %s\n" % processor) fd.write("# hardware : %s\n" % hw) fd.write("# Linux : %s\n" % vers) fd.write("# regaddr mask type defval\n") start = int(startaddr, 16) stop = int(endaddr, 16) if readtype == 'w': step = 4 if readtype == 'h': step = 2 if readtype == 'b': step = 1 for i in iter(range(start, stop, step)): val = lx_devmem2_get(ma, hex(i), readtype) fd.write('%-10s %10s %10s %10s\n' % (hex(i), mask, readtype, val)) fd.close() return True
def lx_check_cmd( ma: linux.LinuxShell, cmd_dict, ) -> bool: """ check commands in list of dictionaries cmd_dict. for each element in list execute command cmd_dict["cmd"] and if cmd_dict["val"] != "undef" check if cmd_dict["val"] is in command output :param machine ma: machine on which commands are executed :param dict cmd_dict: list of dictionary with command and return values. """ for c in cmd_dict: cmdret = ma.exec0(linux.Raw(c["cmd"])) if c["val"] != "undef": if c["val"] not in cmdret: raise RuntimeError(c["val"] + " not found in " + cmdret) return True
def _uboot_prepare(h: linux.LinuxShell) -> uboot.UBootBuilder: remote = h.workdir / "selftest-ub-remote" if remote.exists(): h.exec0("rm", "-rf", remote) h.exec0("mkdir", remote) h.exec0("git", "-C", remote, "init") repo = git.GitRepository(target=remote, clean=False) makefile = """\ all: \t@echo "Making all ..." \ttest ${CC} = "dummy-none-gcc" \texit 1 defconfig: \t@echo "Configuring ..." \ttouch .config mrproper: \t@echo "Cleaning ..." \trm -f .config \ttouch .cleaned .PHONY: all defconfig mrproper """ h.exec0("echo", makefile, linux.RedirStdout(repo / "Makefile")) repo.add(repo / "Makefile") repo.commit("U-Boot Dummy", author="tbot selftest <tbot@tbot>") # Create Patch patch = """\ From 1d78601502661ae531b00540bf86e145a317f23f Mon Sep 17 00:00:00 2001 From: tbot Selftest <none@none> Date: Wed, 30 Jan 2019 13:31:12 +0100 Subject: [PATCH] Fix Makefile --- Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/Makefile b/Makefile index b5319d7..0f01838 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,6 @@ all: \t@echo "Making all ..." \ttest ${CC} = "dummy-none-gcc" -\texit 1 \n defconfig: \t@echo "Configuring ..." -- \n2.20.1 """ patchfile = h.workdir / "uboot-selftest.patch" h.exec0("echo", patch, linux.RedirStdout(patchfile)) class UBootBuilder(uboot.UBootBuilder): name = "tbot-selftest" remote = repo._local_str() defconfig = "defconfig" toolchain = "selftest-toolchain" def do_patch(self, repo: git.GitRepository) -> None: patch = repo.host.workdir / "uboot-selftest.patch" repo.am(patch) return UBootBuilder()
def connect(self, mach: linux.LinuxShell) -> channel.Channel: # Make sure the terminal is wide enough to not cause breaks. mach.exec0("stty", "cols", "1024") return mach.open_channel("bash", "--posix", "--norc", "--noprofile", "--noediting")
def _uboot_prepare(h: linux.LinuxShell) -> uboot.UBootBuilder: remote = h.workdir / "selftest-ub-remote" # Git committer and author information in case the user's git # environment is not set up yet h.env("GIT_AUTHOR_NAME", "tbot selftest") h.env("GIT_AUTHOR_EMAIL", "*****@*****.**") h.env("GIT_COMMITTER_NAME", "tbot selftest") h.env("GIT_COMMITTER_EMAIL", "*****@*****.**") if remote.exists(): h.exec0("rm", "-rf", remote) h.exec0("mkdir", remote) h.exec0("git", "-C", remote, "init") repo = git.GitRepository(target=remote, clean=False) makefile = """\ all: \t@echo "Making all ..." \ttest ${CC} = "dummy-none-gcc" \texit 1 defconfig: \t@echo "Configuring ..." \ttouch .config mrproper: \t@echo "Cleaning ..." \trm -f .config \ttouch .cleaned olddefconfig: .PHONY: all defconfig mrproper olddefconfig """ (repo / "Makefile").write_text(makefile) repo.add(repo / "Makefile") repo.commit("U-Boot Dummy", author="tbot selftest <tbot@tbot>") # Create Patch patch = """\ From 1d78601502661ae531b00540bf86e145a317f23f Mon Sep 17 00:00:00 2001 From: tbot Selftest <none@none> Date: Wed, 30 Jan 2019 13:31:12 +0100 Subject: [PATCH] Fix Makefile --- Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/Makefile b/Makefile index e76351696ad0..fe143c6d4054 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,6 @@ all: \t@echo "Making all ..." \ttest ${CC} = "dummy-none-gcc" -\texit 1 \n defconfig: \t@echo "Configuring ..." -- \n2.20.1 """ patchfile = h.workdir / "uboot-selftest.patch" patchfile.write_text(patch) class UBootBuilder(uboot.UBootBuilder): name = "tbot-selftest" remote = repo.at_host(h) defconfig = "defconfig" toolchain = "selftest-toolchain" def do_patch(self, repo: git.GitRepository) -> None: patch = repo.host.workdir / "uboot-selftest.patch" # Git committer and author information in case the user's git # environment is not set up yet repo.host.env("GIT_AUTHOR_NAME", "tbot selftest") repo.host.env("GIT_AUTHOR_EMAIL", "*****@*****.**") repo.host.env("GIT_COMMITTER_NAME", "tbot selftest") repo.host.env("GIT_COMMITTER_EMAIL", "*****@*****.**") repo.am(patch) return UBootBuilder()
def prepare(h: linux.LinuxShell) -> None: h.exec0( "echo", "export CC=dummy-none-gcc", linux.RedirStdout(h.workdir / ".selftest-toolchain.sh"), )
def selftest_decorated_linux(lnx: linux.LinuxShell) -> None: lnx.exec0("uname", "-a")
def lx_check_iperf( lh: linux.LinuxShell, lnx: linux.LinuxShell, intervall = "1", cycles = "10", minval = "80", filename = "iperf.dat", showlog = False, ) -> bool: """ check networkperformance with iperf intervall: "-i" iperf paramter in seconds cycles: "-t" iperf parameter minval: if bandwith is lower than this value, fail """ result = [] ymax = "0" unit = "MBits/sec" error = False # check on labhost, if iperf server runs # if not start it ret = lh.exec0("ps", "afx", linux.Pipe , "grep", "iperf") start = True for l in ret.split("\n"): if "iperf" in l and not "grep" in l: start = False if start: #ret = lh.exec("iperf", "-s", linux.Background) lh.ch.sendline("iperf -s &") time.sleep(1) oldverbosity = log.VERBOSITY if showlog: log.VERBOSITY = log.Verbosity.STDOUT xmax = str(int(cycles) * int(intervall)) log_event.doc_tag("iperf_unit", unit) log_event.doc_tag("iperf_minval", minval) log_event.doc_tag("iperf_cycles", cycles) log_event.doc_tag("iperf_intervall", intervall) log_event.doc_begin("iperf_test") ret = lnx.exec0("iperf", "-c", lh.serverip, "-i", intervall, "-t", xmax) lowestval = "1000000" step = str(float(intervall) / 2) for l in ret.split("\n"): if "Mbits/sec" in l or "Kbits/sec" in l or "bits/sec" in l: tmp = l.split(" ") val = tmp[-2] if "Kbits/sec" in l: val = str(float(val) / 1000) if "bits/sec" in l and not ("Mbits/sec" in l or "Kbits/sec" in l): val = str(float(val) / 1000) result.append({"bandwith" : val, "step" : step}) if float(ymax) < float(val): ymax = val if float(val) < float(minval): if error == False: tbot.log.message(tbot.log.c(f"Not enough Bandwith {val} < {minval}").red) error = True if float(lowestval) > float(val): lowestval = val step = str(float(step) + float(intervall)) if error: log_event.doc_tag("iperf_result", f"not enough Bandwith {lowestval} {unit} < {minval} {unit}") else: log_event.doc_tag("iperf_result", f"enough Bandwith {lowestval} {unit} >= {minval} {unit}") log_event.doc_end("iperf_test") log.VERBOSITY = oldverbosity # remove last line, as it is not a measurement result = result[:-1] step = 0 # round up ymax ymax = str(int(math.ceil(float(ymax) / 10.0)) * 10) fd = open('results/iperf/' + filename, 'w') # save the xmax and ymax value behind the headlines # gnuplot uses them for setting the correct xmax / ymax values fd.write(f"step bandwith minimum {xmax} {ymax}\n") for el in result: s = str(step) fd.write(f'{el["step"]} {el["bandwith"]} {minval}\n') step += int(intervall) fd.close() if error: raise RuntimeError(f"Not enough Bandwith {lowestval} < {minval}") else: tbot.log.message(tbot.log.c(f"Bandwith always above minimum {minval} MBit/s").green) return True
def set_toolchain( ma: linux.LinuxShell, arch = "armv7-eabihf", libc = "glibc", typ = "stable", date = "2018.11-1", ) -> None: """ download and set a toolchain from: https://toolchains.bootlin.com/downloads/releases/toolchains/ !! Bootlin toolchain does not work for U-Boot as there are problems with relocate-sdk.sh script !! Also, this part is integrated into tbot now: tbot/machine/linux/build/toolchain.py search for EnvSetBootlinToolchain :param LinuxMachine: Linux machine: :param str arch: architecture, default "armv7-eabihf" :param str libc: used libc. default "glibc" :param str typ: "stable" or "bleeding-edge", defaule "stable" :param str date: "2018.11-1" """ log_event.doc_tag("set_bootlin_toolchain_arch_fixlen", arch) log_event.doc_tag("set_bootlin_toolchain_libc_fixlen", libc) log_event.doc_tag("set_bootlin_toolchain_typ_fixlen", typ) log_event.doc_tag("set_bootlin_toolchain_date_fixlen", date) log_event.doc_begin("set_toolchain_check_installed") td = get_toolchain_dir(ma) ma.exec0("cd", td) fn = arch + "--" + libc + "--" + typ + "-" + date fn2 = arch + "/tarballs/" + fn ending = ".tar.bz2" tooldir = td / fn / "bin" ret = ma.exec("test", "-d", tooldir) log_event.doc_end("set_toolchain_check_installed") if ret[0] == 1: log_event.doc_begin("set_toolchain_install") msg = "Get toolchain " + fn tbot.log.message(msg) ma.exec0("wget", "https://toolchains.bootlin.com/downloads/releases/toolchains/" + fn2 + ending) ma.exec0("tar", "xfj", fn + ending) ma.exec0("cd", fn) ma.exec0("./relocate-sdk.sh") log_event.doc_end("set_toolchain_install") ret = ma.exec("printenv", "PATH", tbot.machine.linux.Pipe, "grep", "--color=never", tooldir) if ret[0] == 1: log_event.doc_begin("set_toolchain_add") tbot.log.message(f"Add toolchain to PATH ({tooldir})") old_path = ma.env("PATH") ma.env("PATH", linux.F("{}:{}", tooldir, old_path)) log_event.doc_end("set_toolchain_add") ma.exec0("printenv", "PATH") if "arm" in arch: log_event.doc_begin("set_toolchain_set_shell_vars") ma.exec0("export", "ARCH=arm" ) ma.exec0("CROSS_COMPILE=arm-linux-") log_event.doc_end("set_toolchain_set_shell_vars")
def lx_gpio( ma: linux.LinuxShell, nr: str, state: str, mode: str = "set", ) -> str: """ if {mode} == "set" (default): set gpio {nr} to {state} "on" or "off" else if {mode} == "get" return state of gpio 0 = "off", 1 = "on" returns state """ ret = ma.exec("ls", f"{path_gpio}/gpio{nr}") if ret[0] != 0: ma.exec0("echo", nr, linux.Raw(">"), f"{path_gpio}/export") ma.exec0("ls", f"{path_gpio}/gpio{nr}") if mode == "get": ma.exec0("echo", "in", linux.Raw(">"), f"{path_gpio}/gpio{nr}/direction") ret = ma.exec0("cat", f"{path_gpio}/gpio{nr}/value") if ret.strip() == "0": return "off" elif ret.strip() == "1": return "on" else: raise RuntimeError(f"unknown gpio state {ret}") elif mode == "set": if state == "on": val = "1" else: val = "0" ma.exec0("echo", "out", linux.Raw(">"), f"{path_gpio}/gpio{nr}/direction") ma.exec0("echo", val, linux.Raw(">"), f"{path_gpio}/gpio{nr}/value") else: raise RuntimeError(f"unknown mode {mode}") return state
def lx_get_uboot_var( ma: linux.LinuxShell, varname, ) -> str: ret = ma.exec0("fw_printenv", varname) return ret