From be0a4f3f229a1677727fab99762521344670e3f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= <karel.koci@nic.cz> Date: Wed, 15 Jul 2020 09:39:40 +0200 Subject: [PATCH] nsfarm: use ABC class to define abstract classes This is arguably better than raising NotImplementedError. It also catches inconsistencies much sooner. --- nsfarm/board/_board.py | 25 +++++++++++++------------ nsfarm/board/omnia.py | 4 ++++ nsfarm/cli.py | 8 ++++---- nsfarm/lxd/device.py | 5 +++-- 4 files changed, 24 insertions(+), 18 deletions(-) diff --git a/nsfarm/board/_board.py b/nsfarm/board/_board.py index 178959e..a8c974d 100644 --- a/nsfarm/board/_board.py +++ b/nsfarm/board/_board.py @@ -1,6 +1,7 @@ """This defines generic board and its helpers. """ import sys +import abc import time import logging import serial @@ -14,7 +15,7 @@ MINITERM_DEFAULT_MENU = '\x14' # Ctrl+T MINITERM_ENCODING = sys.getdefaultencoding() -class Board: +class Board(abc.ABC): """General abstract class defining handle for board. """ @@ -62,10 +63,11 @@ class Board: self._pexpect.sendline("") return cli.Uboot(self._pexpect) - def bootup(self, device_wan): + def bootup(self, device_wan, os_branch): """Boot board using TFTP boot. This ensures that board is booted up and ready to accept commands. device_wan: Wan device to board. This is instance of nsfarm.lxd.NetInterface. + os_branch: Turris OS branch to download medkit from. Returns instance of cli.Shell """ @@ -74,7 +76,7 @@ class Board: # Now load image from TFTP with Container("boot", devices=[device_wan, ]) as cont: ccli = cli.Shell(cont.pexpect()) - ccli.run("prepare_turris_image") + ccli.run(f"prepare_turris_image {os_branch}") uboot.run('setenv ipaddr 192.168.1.142') uboot.run('setenv serverip 192.168.1.1') self._board_bootup(uboot) @@ -85,12 +87,12 @@ class Board: shell.run("sysctl -w kernel.printk='0 4 1 7'") # disable kernel print to not confuse console flow return shell + @abc.abstractmethod def _board_bootup(self, uboot): """Board specific bootup routine. It has to implement TFTP uboot routines. """ - raise NotImplementedError def serial_miniterm(self): """Runs interactive miniterm on serial TTY interface. @@ -116,26 +118,25 @@ class Board: sys.stderr.write("\n--- Miniterm exit ---\n") - @property + @abc.abstractproperty def wan(self): """Network interface name for WAN interface in router """ - raise NotImplementedError - @property + @abc.abstractproperty def lan1(self): """Network interface name for LAN1 interface in router + Note that this not matches lan1 port on router but rather is primary lan port. """ - raise NotImplementedError - @property + @abc.abstractproperty def lan2(self): """Network interface name for LAN2 interface in router + Note that this not matches lan2 port on router but rather is secondary test port (such as different switch). """ - raise NotImplementedError - @property + @abc.abstractproperty def lan3(self): """Network interface name for LAN3 interface in router + Note that this not matches lan3 port on router but rather is tercial test port (such as different switch). """ - raise NotImplementedError diff --git a/nsfarm/board/omnia.py b/nsfarm/board/omnia.py index 8e4572b..8c736e2 100644 --- a/nsfarm/board/omnia.py +++ b/nsfarm/board/omnia.py @@ -25,3 +25,7 @@ class Omnia(Board): @property def lan2(self): return "lan3" + + @property + def lan3(self): + return "lan4" diff --git a/nsfarm/cli.py b/nsfarm/cli.py index f1ebdd6..e934cd1 100644 --- a/nsfarm/cli.py +++ b/nsfarm/cli.py @@ -8,6 +8,7 @@ support for shell and u-boot. They differ in a way how they handle prompt and m # There are new line character matches in regular expressions. Correct one is \r\n but some serial controlles for some # reason also use \n\r so we match both alternatives. # +import abc import logging import base64 @@ -31,7 +32,7 @@ def run_exit_code_zero(exit_code): return 0 -class Cli: +class Cli(abc.ABC): """This is generic abstraction on top of pexpect for command line interface. """ @@ -44,20 +45,19 @@ class Cli: # Just propagate anything we do not implement to pexect handle return getattr(self._pe, name) + @abc.abstractmethod def prompt(self, **kwargs): """Follow output until prompt is reached and parse it. Exit code is returned. All keyword arguments are passed to pexpect's expect call. """ - raise NotImplementedError - @property + @abc.abstractproperty def output(self): """All output before latest prompt. This is everything not matched till prompt is located. Note that this is for some implementations same as pexpect before but in others it can differ so you should always use this property instead of before. """ - raise NotImplementedError def command(self, cmd=""): """Calls pexpect sendline and expect cmd with trailing new line. diff --git a/nsfarm/lxd/device.py b/nsfarm/lxd/device.py index cd680fe..32b8750 100644 --- a/nsfarm/lxd/device.py +++ b/nsfarm/lxd/device.py @@ -1,8 +1,9 @@ """Devices management and assigment to containers. """ +import abc -class Device: +class Device(abc.ABC): """Generic device handler for LXD container. This is device handler that can be assigned to containers. Note that it can be assigned to only one container at the @@ -34,11 +35,11 @@ class Device: self._assignment[-2].unfreeze() self._assignment.remove(container) + @abc.abstractmethod def _definition(self): """This method has to be implemented by child class and should return definition of device that is later provided to caller as result of calling acquire(). """ - raise NotImplementedError @property def container(self): -- GitLab