|
|
@@ -235,6 +235,15 @@ class TimeOut(Attribute): |
|
|
|
@_tbprinter |
|
|
|
async def timeout_coro(self): |
|
|
|
async with self._brd.lock: |
|
|
|
# we don't want to cancel ourselves while |
|
|
|
# releasing the board, otherwise it'll stop |
|
|
|
# in the middle! |
|
|
|
# |
|
|
|
# Note: not sure if we need to await on the |
|
|
|
# task to clean things up though. |
|
|
|
|
|
|
|
self._task = None |
|
|
|
|
|
|
|
await self._brd.release() |
|
|
|
|
|
|
|
def timeout_callback(self): |
|
|
@@ -280,7 +289,15 @@ class BoardImpl: |
|
|
|
be destroyed before the operation completes. |
|
|
|
''' |
|
|
|
|
|
|
|
def __init__(self, name, brdclass, options): |
|
|
|
def __init__(self, name: str, brdclass: str, options): |
|
|
|
''' |
|
|
|
name: name of the board. |
|
|
|
brdclass: class that the board belongs to. |
|
|
|
options: list of tuples, the first item of the tuple, |
|
|
|
being the factory to call, and the second item, the |
|
|
|
keyword args to use when calling the factory. |
|
|
|
''' |
|
|
|
|
|
|
|
self.name = name |
|
|
|
self.brdclass = brdclass |
|
|
|
self.options = options |
|
|
@@ -302,42 +319,72 @@ class BoardImpl: |
|
|
|
return repr(Board.from_orm(self)) |
|
|
|
|
|
|
|
async def reserve(self): |
|
|
|
'''Reserve the board.''' |
|
|
|
|
|
|
|
assert self.lock.locked() and not self.reserved |
|
|
|
|
|
|
|
self.reserved = True |
|
|
|
|
|
|
|
await self.activate() |
|
|
|
|
|
|
|
async def release(self): |
|
|
|
'''Release the board.''' |
|
|
|
|
|
|
|
assert self.lock.locked() and self.reserved |
|
|
|
|
|
|
|
await self.deactivate() |
|
|
|
|
|
|
|
self.reserved = False |
|
|
|
|
|
|
|
async def update_attrs(self, **attrs): |
|
|
|
'''Set the various attrs that are specified.''' |
|
|
|
|
|
|
|
assert self.lock.locked() and self.reserved |
|
|
|
|
|
|
|
for i in attrs: |
|
|
|
self.attrcache[i] = await self.attrmap[i].setvalue(attrs[i]) |
|
|
|
|
|
|
|
async def update(self): |
|
|
|
'''Update the attr cache w/ current values.''' |
|
|
|
|
|
|
|
for i in self.attrmap: |
|
|
|
self.attrcache[i] = await self.attrmap[i].getvalue() |
|
|
|
|
|
|
|
async def activate(self): |
|
|
|
'''Activate the attributes. This means that the board |
|
|
|
has been reserved. This is for things like adding an |
|
|
|
ethernet interface to the jail's vnet, or starting the |
|
|
|
timeout.''' |
|
|
|
|
|
|
|
assert self.lock.locked() and self.reserved |
|
|
|
|
|
|
|
for i in self.attrmap.values(): |
|
|
|
await i.activate(self) |
|
|
|
|
|
|
|
async def deactivate(self): |
|
|
|
'''Deactivate the attributes. This should be called |
|
|
|
just before release. This is to clean up anything like |
|
|
|
scheduled tasks.''' |
|
|
|
|
|
|
|
assert self.lock.locked() and self.reserved |
|
|
|
|
|
|
|
for i in self.attrmap.values(): |
|
|
|
await i.deactivate(self) |
|
|
|
|
|
|
|
def add_info(self, d): |
|
|
|
'''Add some additional data that will be returned for |
|
|
|
the current reservation. All the data added here will |
|
|
|
be removed when the board is deactivated, by clean_info. |
|
|
|
''' |
|
|
|
|
|
|
|
self.attrcache.update(d) |
|
|
|
|
|
|
|
def clean_info(self): |
|
|
|
# clean up attributes |
|
|
|
'''Remove any attributes that aren't in the attrmap. |
|
|
|
|
|
|
|
This is to clean up after the add_info call. |
|
|
|
''' |
|
|
|
|
|
|
|
for i in set(self.attrcache) - set(self.attrmap): |
|
|
|
del self.attrcache[i] |
|
|
|
|
|
|
@@ -1007,7 +1054,7 @@ class TestWebSocket(TestCommon): |
|
|
|
# IsolatedAsyncioTestCase was added. The tearDown has to happen |
|
|
|
# with the event loop running, otherwise the task and other things |
|
|
|
# do not get cleaned up properly. |
|
|
|
class TestBiteLab(TestCommon): |
|
|
|
class TestBiteLabAPI(TestCommon): |
|
|
|
async def asyncSetUp(self): |
|
|
|
await super().asyncSetUp() |
|
|
|
|
|
|
@@ -1059,7 +1106,7 @@ class TestBiteLab(TestCommon): |
|
|
|
# that when the setup script will fail |
|
|
|
wrap_subprocess_exec(cse, stderr=b'error', retcode=1) |
|
|
|
|
|
|
|
# that the cora-1 board is reserved |
|
|
|
# and that the cora-1 board is reserved |
|
|
|
data = self.data |
|
|
|
brd = self.brdmgr.boards['cora-1'] |
|
|
|
attrs = dict(iface='a', ip='b', devfsrule='c') |
|
|
@@ -1377,6 +1424,11 @@ class TestBiteLab(TestCommon): |
|
|
|
self.assertEqual(res.json(), info) |
|
|
|
|
|
|
|
class TestBoardImpl(unittest.IsolatedAsyncioTestCase): |
|
|
|
async def xtest_reserve(self): |
|
|
|
# that when the board is reserved |
|
|
|
async with brd.lock: |
|
|
|
await brd.reserve() |
|
|
|
|
|
|
|
async def test_activate(self): |
|
|
|
# that a board impl |
|
|
|
opttup = create_autospec, dict(spec=Attribute) |
|
|
@@ -1385,7 +1437,6 @@ class TestBoardImpl(unittest.IsolatedAsyncioTestCase): |
|
|
|
|
|
|
|
async with brd.lock: |
|
|
|
await brd.reserve() |
|
|
|
await brd.activate() |
|
|
|
|
|
|
|
opt.activate.assert_called_with(brd) |
|
|
|
|
|
|
@@ -1397,7 +1448,7 @@ class TestBoardImpl(unittest.IsolatedAsyncioTestCase): |
|
|
|
|
|
|
|
async with brd.lock: |
|
|
|
await brd.reserve() |
|
|
|
await brd.deactivate() |
|
|
|
await brd.release() |
|
|
|
|
|
|
|
opt.deactivate.assert_called_with(brd) |
|
|
|
|
|
|
@@ -1625,7 +1676,6 @@ class TestAttrs(unittest.IsolatedAsyncioTestCase): |
|
|
|
# that when reserved/activated |
|
|
|
async with brd.lock: |
|
|
|
await brd.reserve() |
|
|
|
await brd.activate() |
|
|
|
|
|
|
|
evt = asyncio.Event() |
|
|
|
loop = asyncio.get_running_loop() |
|
|
@@ -1638,9 +1688,7 @@ class TestAttrs(unittest.IsolatedAsyncioTestCase): |
|
|
|
# that when reserved/activated/deactivated/released |
|
|
|
async with brd.lock: |
|
|
|
await brd.reserve() |
|
|
|
await brd.activate() |
|
|
|
exp = to._exp |
|
|
|
await brd.deactivate() |
|
|
|
await brd.release() |
|
|
|
|
|
|
|
# that the expiration is no longer there |
|
|
|