| @@ -50,6 +50,7 @@ from .mocks import * | |||
| import asyncio | |||
| import contextlib | |||
| import json | |||
| import logging | |||
| import orm | |||
| import os | |||
| import socket | |||
| @@ -356,8 +357,18 @@ async def release_board(board_id, user: str = Depends(lookup_user), | |||
| settings.setup_script, 'release', brd.name, user, | |||
| stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |||
| stdout, stderr = await sub.communicate() | |||
| if sub.returncode: | |||
| raise RuntimeError(sub.returncode, stderr) | |||
| retcode = sub.returncode | |||
| if retcode: | |||
| logging.error('release script failure: ' + | |||
| 'board: %s, ret: %s, stderr: %s' % (repr(brd.name), | |||
| retcode, repr(stderr))) | |||
| raise BITEError( | |||
| status_code=HTTP_500_INTERNAL_SERVER_ERROR, | |||
| errobj=Error(error= | |||
| 'Failed to release board, ret: %d, stderr: %s' % | |||
| (retcode, repr(stderr)), | |||
| board=Board.from_orm(brd)), | |||
| ) | |||
| await data.BoardStatus.delete(brduser) | |||
| await brd.release() | |||
| @@ -509,6 +520,47 @@ class TestBiteLab(unittest.IsolatedAsyncioTestCase): | |||
| self.assertEqual(res.json(), { 'cora-z7s': BoardClassInfo(**{ | |||
| 'arch': 'arm-armv7', 'clsname': 'cora-z7s', }) }) | |||
| @patch('asyncio.create_subprocess_exec') | |||
| @patch('bitelab.snmp.snmpget') | |||
| @patch('logging.error') | |||
| async def test_board_release_script_fail(self, le, sg, cse): | |||
| # that when snmpget returns False | |||
| sg.return_value = False | |||
| # that when the setup script will fail | |||
| wrap_subprocess_exec(cse, stderr=b'error', retcode=1) | |||
| # that the cora-1 board is reserved | |||
| data = self.data | |||
| brd = self.brdmgr.boards['cora-1'] | |||
| async with brd.lock: | |||
| await brd.reserve() | |||
| obrdreq = await data.BoardStatus.objects.create( | |||
| board='cora-1', user='foo') | |||
| # that when the correct user releases the board | |||
| res = await self.client.post('/board/cora-1/release', | |||
| auth=BiteAuth('thisisanapikey')) | |||
| # it fails | |||
| self.assertEqual(res.status_code, HTTP_500_INTERNAL_SERVER_ERROR) | |||
| # and returns the correct data | |||
| info = Error(error='Failed to release board, ret: 1, stderr: b\'error\'', | |||
| board=Board(name='cora-1', | |||
| brdclass='cora-z7s', | |||
| reserved=True, | |||
| ), | |||
| ).dict() | |||
| self.assertEqual(res.json(), info) | |||
| # and that it called the release script | |||
| cse.assert_called_with(self.settings.setup_script, 'release', | |||
| 'cora-1', 'foo', stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |||
| # and that the error got logged | |||
| le.assert_called_with('release script failure: board: \'cora-1\', ret: 1, stderr: b\'error\'') | |||
| @patch('asyncio.create_subprocess_exec') | |||
| @patch('bitelab.snmp.snmpget') | |||
| async def test_board_reserve_release(self, sg, cse): | |||