diff --git a/bitelab/__init__.py b/bitelab/__init__.py index b7141a5..e5992ca 100644 --- a/bitelab/__init__.py +++ b/bitelab/__init__.py @@ -72,6 +72,9 @@ def new_parse_socket_addr(domain, addr): tcp_server.parse_socket_addr = new_parse_socket_addr +class SerialConsole(DefROAttribute): + defattrname = 'console' + class BoardImpl: def __init__(self, name, brdclass, options): self.name = name @@ -825,3 +828,13 @@ class TestBiteLab(unittest.IsolatedAsyncioTestCase): 'attrs': { 'power': True }, } self.assertEqual(res.json(), info) + +class TestAttrs(unittest.IsolatedAsyncioTestCase): + async def test_serialconsole(self): + data = 'somepath' + sc = SerialConsole(data) + + self.assertEqual(data, await sc.getvalue()) + + with self.assertRaises(TypeError): + await sc.setvalue(data) diff --git a/bitelab/abstract.py b/bitelab/abstract.py index 22cbcf7..7c01837 100644 --- a/bitelab/abstract.py +++ b/bitelab/abstract.py @@ -41,5 +41,19 @@ class Attribute: async def setvalue(self, v): # pragma: no cover raise NotImplementedError +class ROAttribute(Attribute): + '''A read-only attribute class. This implements setvalue, but + raises a TypeError when setvalue is called.''' + + async def setvalue(self, v): + raise TypeError('%s is read-only.' % self.__class__.__name__) + +class DefROAttribute(ROAttribute): + def __init__(self, val): + self._value = val + + async def getvalue(self): + return self._value + class Power(Attribute): defattrname = 'power' diff --git a/bitelab/testing.py b/bitelab/testing.py index 623148d..f4601f7 100644 --- a/bitelab/testing.py +++ b/bitelab/testing.py @@ -30,5 +30,5 @@ from .snmp import TestSNMPPower, TestSNMPWrapper from .data import TestDatabase -from . import TestBiteLab, TestUnhashLRU +from . import TestBiteLab, TestUnhashLRU, TestAttrs from .__main__ import TestClient