diff --git a/apps/boards/boards.py b/apps/boards/boards.py index 77e5d8b..6b4f6be 100644 --- a/apps/boards/boards.py +++ b/apps/boards/boards.py @@ -3,7 +3,7 @@ """ from abc import ABC, abstractmethod -from tester import Tty +from tester import PyTty class Boards(ABC): @@ -25,7 +25,7 @@ def power_cycle(self, *args, **kwargs): """ @abstractmethod - def get_console(self, *args, **kwargs) -> Tty: + def get_console(self, *args, **kwargs) -> PyTty: """ Get the console of the board. """ diff --git a/apps/boards/bpif3.py b/apps/boards/bpif3.py index 3522a48..8e97036 100644 --- a/apps/boards/bpif3.py +++ b/apps/boards/bpif3.py @@ -20,13 +20,13 @@ def flash(self, shell: Exec, img: str, dsk="/dev/sda"): """ Flash the board with given image. """ - self.sdwirec.to_ts() + # self.sdwirec.to_ts() sleep(0.5) - shell.assert_script_sudo( - f"dd if={img} of={dsk} status=progress", 600) - shell.assert_script_sudo("sync") + shell.script_sudo( + f"dd if={img} of={dsk} status=progress bs=4M ", 600) + shell.script_sudo("sync") sleep(0.5) - self.sdwirec.to_dut() + # self.sdwirec.to_dut() sleep(0.5) def power_cycle(self): diff --git a/apps/bpif3_armbian.py b/apps/bpif3_armbian.py index dc24e48..52d6cc6 100644 --- a/apps/bpif3_armbian.py +++ b/apps/bpif3_armbian.py @@ -19,17 +19,21 @@ def default_proc(): local_shell = Shell("/bin/bash") local_shell = Tee(local_shell, "run.log") - local_shell.write(b"uname -a\n") - local_shell.read() asciicast = Asciicast(local_shell) asciicast.begin() e = Exec(asciicast) + e.script_run("uname -a") + + e.script_run("uname -a") + + + e.script_run("uname -a") + board = BPiF3("id = 0\n", "/dev/ttyUSB0", 115200) - # url = "/Armbian-bpi-SpacemiT_24.5.0-trunk_Bananapif3_mantic_legacy_6.1.15_xfce_desktop.img.xz" # 度盘,dummy url = "https://mirrors.tuna.tsinghua.edu.cn/armbian-releases/bananapif3/archive/Armbian_24.8.1_Bananapif3_noble_legacy_6.1.15_minimal.img.xz" work_dir = "/home/lw/Work/plct/boards/bpif3/armbian" img = wget_image(url, work_dir) @@ -44,7 +48,7 @@ def default_proc(): info("Begin flashing board...") - board.flash(e, img, "/dev/mmcblk0") + board.flash(e, img, "/dev/sda") info("Flash board ended...") @@ -61,6 +65,7 @@ def default_proc(): system = Armbian(e) + system.setup() system.loggin() asciicast = e.exit() diff --git a/apps/bpif3_bianbu.py b/apps/bpif3_bianbu.py new file mode 100644 index 0000000..dc0bc36 --- /dev/null +++ b/apps/bpif3_bianbu.py @@ -0,0 +1,86 @@ +""" +Gives a configuration, +runs a default procedure, +generates a default log. +""" + +from boards.bpif3 import BPiF3 +from system.generic import Generic +from utils.maintain_img import * +from utils.utils import swap_tty + +from tester import * + + +def default_proc(): + """ + Default procedure for testing. + """ + + local_shell = Shell("bash") + local_shell = Tee(local_shell, "run.log") + local_shell.write(b"uname -a\n") + local_shell.read() + + asciicast = Asciicast(local_shell) + asciicast.begin() + + e = Exec(asciicast) + + board = BPiF3("id = 0\n", "/dev/ttyUSB0", 115200) + + url = "https://archive.spacemit.com/image/k1/version/bianbu/v2.0rc1/bianbu-24.04-desktop-k1-v2.0rc1-release-20240909135447.img.zip" + work_dir = "/home/lw/Work/plct/boards/bpif3/bianbu" + img = wget_image(url, work_dir) + if img is None: + print("Download failed.") + return + img = extract_image(img) + if img is None: + print("Extract failed.") + return + info(f"Image is ready at {img}") + + info("Begin flashing board...") + + board.flash(e, img, "/dev/mmcblk0") + + info("Flash board ended...") + + console = board.get_console() + console = Tee(console, "con.log") + + asciicast = e.exit() + local_shell = swap_tty(asciicast, console) + e = Exec(asciicast) + + board.power_cycle() + + info(f"Begin system test...") + + system = Generic("root", "bianbu", e) + + system.setup() + system.loggin() + + asciicast = e.exit() + logger = PyTty("wrap=true\nsimple_recorder=true\n", asciicast) + logger.begin() + e = Exec(logger) + system.tty = e + + system.get_info() + + logger = e.exit() + info_log = logger.end() + asciicast = logger.exit() + res = asciicast.end() + + with open("res.cast", "w") as f: + f.write(res) + + with open("info.log", "w") as f: + f.write(info_log) + +if __name__ == "__main__": + default_proc() diff --git a/apps/system/armbian.py b/apps/system/armbian.py index bf046ef..a59a5df 100644 --- a/apps/system/armbian.py +++ b/apps/system/armbian.py @@ -5,13 +5,7 @@ from time import sleep from tester import Exec - -def slp(t=0.5): - """ - Sleep for t second. - """ - sleep(t) - +from system.system import slp class Armbian: """ @@ -35,9 +29,9 @@ def wit(self, wait: str, timeout: int = 600): self.tty.wait_serial(wait, timeout) slp() - def loggin(self): + def setup(self): """ - Loggin to the board. + Setup the armbian. """ # init settings @@ -82,13 +76,16 @@ def loggin(self): self.wit("#?") self.wln("1") - # Loggin + def loggin(self): + """ + Login to the board. + """ self.wit("root@") def get_info(self): """ Get system information. """ - self.tty.assert_script_run("uname -a") - self.tty.assert_script_run("cat /etc/os-release") - self.tty.assert_script_run("cat /proc/cpuinfo") + self.tty.script_run("uname -a") + self.tty.script_run("cat /etc/os-release") + self.tty.script_run("cat /proc/cpuinfo") diff --git a/apps/system/generic.py b/apps/system/generic.py new file mode 100644 index 0000000..719c114 --- /dev/null +++ b/apps/system/generic.py @@ -0,0 +1,49 @@ +""" +Generic means this system is out of box, no need to do anything. +""" + +from time import sleep +from tester import Exec + +from system.system import slp + +class Generic: + """ + System class for Generic Linux + """ + + def __init__(self, username, password, tty) -> None: + self.username = username + self.password = password + self.tty = tty + + def setup(self): + """ + Setup the system. + """ + pass + + def loggin(self): + """ + Loggin to the system. + """ + self.tty.wait_serial("login:", 600) + slp() + self.tty.writeln(self.username) + slp() + slp(10) # Some system would gives you "密码" instead of "Password"... Just sleep for a while. + slp() + self.tty.writeln(self.password) + slp() + self.tty.wait_serial(self.username) + slp() + + def get_info(self): + """ + Get system information. + """ + self.tty.script_run("uname -a") + slp() + self.tty.script_run("cat /etc/os-release") + slp() + self.tty.script_run("cat /proc/cpuinfo") diff --git a/apps/system/system.py b/apps/system/system.py new file mode 100644 index 0000000..8244e0a --- /dev/null +++ b/apps/system/system.py @@ -0,0 +1,37 @@ +""" +This module contains the abstract class for all systems. +""" + +from abc import ABC, abstractmethod +from time import sleep +from tester import Exec + + +def slp(t=0.5): + """ + Sleep for t second. + """ + sleep(t) + +class Systems(ABC): + """ + Abstract class for all systems. + This is mainly an interface definition, instead of a base class. + """ + @abstractmethod + def loggin(self): + """ + Loggin to the board. + """ + + @abstractmethod + def setup(self, *args, **kwargs): + """ + some system may need initial setup. + """ + + @abstractmethod + def get_info(self): + """ + Get system information. + """ diff --git a/apps/utils/maintain_img.py b/apps/utils/maintain_img.py index e1464cc..ac0d6d4 100644 --- a/apps/utils/maintain_img.py +++ b/apps/utils/maintain_img.py @@ -3,13 +3,13 @@ Functions: wget_image(url: str, dir_path: str) -> str - return the path of image file after download - If download failed, return None - If file already exists, return the path of image file + res = the path of image file after download + If download failed, res = None + If file already exists, res = the path of image file extract_image(file: str) -> str - return the path of image file after extract - If file is not image, return None + res = the path of image file after extract + If file is not image, res = None For now support .tar, .tar.gz, .tar.bz2, .tar.xz, .zip """ import os @@ -17,73 +17,81 @@ def wget_image(url: str, dir_path: str) -> str: """ - Download image from url and save to dir_path, return the path of image file. - If download failed, return None. - If file already exists, return the path of image file. + Download image from url and save to dir_path, res = the path of image file. + If download failed, res = None. + If file already exists, res = the path of image file. """ # get file name file_name = url.split('/')[-1] file_path = os.path.join(dir_path, file_name) if os.path.exists(file_path): - return file_path + res = file_path + return res # The image is tend to be REALLY large... So just use wget in shell and wait for it... os.system(f"wget {url} -O {file_path}") if os.path.exists(file_path): - return file_path + res = file_path else: - return None + res = None + return res def extract_image(file: str) -> str: """ - Extract image from file and return the path of image file. - If file is not image, return None. + Extract image from file and res = the path of image file. + If file is not image, res = None. """ + curr = os.getcwd() + os.chdir(os.path.dirname(file)) + res = None # check file type if not os.path.exists(file): - return None - if not os.path.isfile(file): - return None + os.chdir(curr) + res = None + elif not os.path.isfile(file): + os.chdir(curr) + res = None # For now support .tar, .tar.gz, .tar.bz2, .tar.xz, .zip - if file.endswith(".tar"): + elif file.endswith(".tar"): if os.path.exists(file[:-4]): - return file[:-4] + res = file[:-4] os.system(f"tar -xf {file}") - return file[:-4] - if file.endswith(".tar.gz"): + res = file[:-4] + elif file.endswith(".tar.gz"): if os.path.exists(file[:-7]): - return file[:-7] + res = file[:-7] os.system(f"tar -xzf {file}") - return file[:-7] - if file.endswith(".tar.bz2"): + res = file[:-7] + elif file.endswith(".tar.bz2"): if os.path.exists(file[:-8]): - return file[:-8] + res = file[:-8] os.system(f"tar -xjf {file}") - return file[:-8] - if file.endswith(".tar.xz"): + res = file[:-8] + elif file.endswith(".tar.xz"): if os.path.exists(file[:-8]): - return file[:-8] + res = file[:-8] os.system(f"tar -xJf {file}") - return file[:-8] - if file.endswith(".zip"): + res = file[:-8] + elif file.endswith(".zip"): if os.path.exists(file[:-4]): - return file[:-4] - os.system(f"unzip -k {file}") - return file[:-4] - if file.endswith(".xz"): + res = file[:-4] + os.system(f"unzip {file}") + res = file[:-4] + elif file.endswith(".xz"): if os.path.exists(file[:-3]): - return file[:-3] + res = file[:-3] os.system(f"unxz -k {file}") - return file[:-3] - if file.endswith(".gz"): + res = file[:-3] + elif file.endswith(".gz"): if os.path.exists(file[:-3]): - return file[:-3] + res = file[:-3] os.system(f"gunzip -k {file}") - return file[:-3] - if file.endswith(".bz2"): + res = file[:-3] + elif file.endswith(".bz2"): if os.path.exists(file[:-4]): - return file[:-4] + res = file[:-4] os.system(f"bunzip2 -k {file}") - return file[:-4] - return None + res = file[:-4] + os.chdir(curr) + return res diff --git a/tests/test_shell.py b/tests/test_shell.py index fdba73b..025a92d 100644 --- a/tests/test_shell.py +++ b/tests/test_shell.py @@ -2,7 +2,9 @@ if __name__ == "__main__": s = tester.Shell("bash") + s = tester.Tee(s, "run.log") e = tester.Exec(s) + e.script_run("echo 'Hello, world'") e.script_run("uname -a") e.script_run("ls") e.script_run("uname -a")