From 9b543969bad2fba09ed845b7c130886c7ec6a073 Mon Sep 17 00:00:00 2001 From: John-Mark Gurney Date: Fri, 5 Mar 2021 01:04:36 -0800 Subject: [PATCH] fix handling of failures during activating board resources and report the errors properly... This will now release the board when activating them fails, not leaving the board in reserved state w/o the user knowning.. --- bitelab/__init__.py | 48 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/bitelab/__init__.py b/bitelab/__init__.py index 6e15fb5..dd21778 100644 --- a/bitelab/__init__.py +++ b/bitelab/__init__.py @@ -370,7 +370,11 @@ class BoardImpl: self._user = user self.reserved = True - await self.activate() + try: + await self.activate() + except Exception: + await self.release() + raise async def release(self): '''Release the board.''' @@ -749,13 +753,12 @@ async def reserve_board(board_id_or_class, await brd.reserve(user, sshpubkey) except Exception as e: if isinstance(e, RuntimeError): - retcode, stderr = e.args raise BITEError( status_code=HTTP_500_INTERNAL_SERVER_ERROR, errobj=Error(error= - 'Failed to init board, ret: %d, stderr: %s' % - (retcode, repr(stderr)), - board=Board.from_orm(brd)), + 'Failed to init board: %s' % + repr(e.args), + board=Board.from_orm(brd)), ) raise @@ -1403,7 +1406,7 @@ class TestBiteLabAPI(TestCommon): self.assertEqual(res.status_code, HTTP_500_INTERNAL_SERVER_ERROR) # and returns the correct data - info = Error(error='Failed to init board, ret: 1, stderr: b\'error\'', + info = Error(error='Failed to init board: (1, b\'error\')', board=Board(name='cora-1', brdclass='cora-z7s', reserved=False, @@ -1522,6 +1525,39 @@ class TestBiteLabAPI(TestCommon): # and deactivated attributes bideact.assert_called() + bideact.reset_mock() + + # when one of the atributes fails to activate + errtxt = 'some error to pass' + biact.side_effect = RuntimeError(errtxt) + + # that reserving the board + res = await self.client.post('/board/cora-1/reserve', + json=dict(sshpubkey=keydata), + auth=BiteAuth('thisisanapikey')) + + # the reservation fails + self.assertEqual(res.status_code, + HTTP_500_INTERNAL_SERVER_ERROR) + + # and returns the correct errtxt + info = { + 'error': 'Failed to init board: %s' % repr((errtxt,)), + 'board': dict(attrs=dict(power=False), + brdclass='cora-z7s', name='cora-1', user=None, + reserved=False), + } + self.assertEqual(res.json(), info) + + # and that the board is not reserved + self.assertFalse(self.brdmgr.boards['cora-1'].reserved) + + # and deactivated attributes + bideact.assert_called() + + # that when activate is reset + biact.reset_mock(side_effect=True) + # that it can be reserved by a different user res = await self.client.post('/board/cora-1/reserve', auth=BiteAuth('anotherlongapikey'))