Add PDU controller that allows to reboot Nordic dev-kits. (#1201)

This commit is contained in:
Przemysław Fierek
2017-02-15 09:11:38 -08:00
committed by Jonathan Hui
parent b6699cf9b3
commit 629516244d
4 changed files with 162 additions and 27 deletions
@@ -42,7 +42,7 @@ import time
import unittest
from autothreadharness import settings
from autothreadharness.apc_pdu_controller import ApcPduController
from autothreadharness.pdu_controller_factory import PduControllerFactory
from autothreadharness.harness_controller import HarnessController
from autothreadharness.helpers import HistoryHelper
from autothreadharness.open_thread_controller import OpenThreadController
@@ -167,7 +167,7 @@ class HarnessCase(unittest.TestCase):
if self.manual_reset:
raw_input('Reset golden devices and press enter to continue..')
return
elif not settings.APC_HOST:
elif not settings.PDU_CONTROLLER_TYPE:
if settings.GOLDEN_DEVICE_TYPE != 'OpenThread':
logger.warning('All golden devices may not be resetted')
return
@@ -188,9 +188,12 @@ class HarnessCase(unittest.TestCase):
return
tries = 3
pdu_factory = PduControllerFactory()
while True:
try:
apc = ApcPduController(settings.APC_HOST)
pdu = pdu_factory.create_pdu_controller(settings.PDU_CONTROLLER_TYPE)
pdu.open(**settings.PDU_CONTROLLER_OPEN_PARAMS)
except EOFError:
logger.warning('Failed to connect to telnet')
tries = tries - 1
@@ -201,8 +204,8 @@ class HarnessCase(unittest.TestCase):
logger.error('Fatal error: cannot connect to apc')
raise
else:
apc.reboot(settings.APC_OUTLET)
apc.close()
pdu.reboot(**settings.PDU_CONTROLLER_REBOOT_PARAMS)
pdu.close()
break
time.sleep(20)
@@ -27,26 +27,47 @@
# POSSIBILITY OF SUCH DAMAGE.
#
import logging
import os
import re
import telnetlib
import time
import re
logger = logging.getLogger(__name__)
class ApcPduController(object):
def __init__(self, ip, port=23):
"""Create APC PDU controller
Args:
ip (str), ip address or hostname
port (int), port number
"""
self.port = port
self.ip = ip
class PduController(object):
def open(self, **params):
"""Open PDU controller connection"""
raise NotImplementedError
def reboot(self, **params):
"""Reboot an outlet or a board passed as params"""
raise NotImplementedError
def close(self):
"""Close PDU controller connection"""
raise NotImplementedError
class DummyPduController(PduController):
"""Dummy implementation which only says that PDU controller is not connected"""
def open(self, **params):
pass
def reboot(self, **params):
print('No PDU controller connected.')
def close(self):
pass
class ApcPduController(PduController):
def __init__(self):
self.tn = None
self._init()
def __del__(self):
self.close()
@@ -61,6 +82,21 @@ class ApcPduController(object):
self.tn.write('apc\r\n')
self.until_done()
def open(self, **params):
"""Open telnet connection
Args:
params (dict), must contain two parameters "ip" - ip address or hostname and "port" - port number
Example:
params = {'port': 23, 'ip': 'localhost'}
"""
logger.info('opening telnet')
self.port = params['port']
self.ip = params['ip']
self.tn = None
self._init()
def close(self):
"""Close telnet connection"""
logger.info('closing telnet')
@@ -79,9 +115,17 @@ class ApcPduController(object):
r = re.compile(regex, re.M)
self.tn.expect([r])
def reboot(self, outlet=1):
def reboot(self, **params):
"""Reboot outlet
Args:
params (dict), must contain parameter "outlet" - outlet number
Example:
params = {'outlet': 1}
"""
outlet = params['outlet']
# main menu
self.tn.write('\x1b\r\n')
self.until_done()
@@ -117,6 +161,26 @@ class ApcPduController(object):
self.tn.write('\r\n')
self.until_done()
class NordicBoardPduController(PduController):
def open(self, **params):
pass
def _pin_reset(self, serial_number):
os.system('nrfjprog -f NRF52 --snr {} -p'.format(serial_number))
def reboot(self, **params):
boards_serial_numbers = params['boards_serial_numbers']
for serial_number in boards_serial_numbers:
print('Resetting board with the serial number: {}'.format(serial_number))
self._pin_reset(serial_number)
def close(self):
pass
if __name__ == '__main__':
apc = ApcPduController('192.168.1.88')
apc.reboot()
@@ -0,0 +1,40 @@
# Copyright (c) 2016, The OpenThread Authors.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. Neither the name of the copyright holder nor the
# names of its contributors may be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
import pdu_controller
class PduControllerFactory(object):
"""Factory that creates PDU controllers."""
def create_pdu_controller(self, _type):
if _type == 'NORDIC_BOARD_PDU_CONTOLLER':
return pdu_controller.NordicBoardPduController()
elif _type == 'APC_PDU_CONTROLLER':
return pdu_controller.ApcPduController()
else:
return pdu_controller.DummyPduController()
@@ -65,15 +65,6 @@ HARNESS_HOME = 'C:\\GRL\\Thread1.1'
HARNESS_URL = 'http://127.0.0.1:8000'
"""str: Harness front-end url"""
APC_HOST = None
"""str: PDU controller host.
Keep this None if no APC PDU available.
"""
APC_OUTLET = 1
"""int: PDU outlet, only needed when APC_HOST is not None."""
TESTER_NAME = 'Thread Open'
"""str: Who are you"""
@@ -87,3 +78,40 @@ It should be something like [('COM1', 'OpenThread'), ('COM2', 'ARM')] on Windows
OUTPUT_PATH = '.\\output'
"""str: Path to store results and logs, MUST be writable."""
PDU_CONTROLLER_TYPE = None
"""str: Type of connected PDU controller.
Keep this None if no PDU controller available.
Types of supported PDU controllers:
- None - when no PDU controller connected
- 'APC_PDU_CONTROLLER' - when APC PDU controller connected
- 'NORDIC_BOARD_PDU_CONTOLLER' - when Nordic boards PDU controller connected
"""
PDU_CONTROLLER_OPEN_PARAMS = {'port': 23, 'ip': '127.0.0.1'}
"""dict: Parameters pass to the "open" method of PDU controller.
Example parameters for the 'APC_PDU_CONTROLLER':
{'port': 23, 'ip': '127.0.0.1'}
Example parameters for the 'NORDIC_BOARD_PDU_CONTOLLER':
{} - empty dictionary
"""
PDU_CONTROLLER_REBOOT_PARAMS = {'outlet': 1}
"""dict: Parameters pass to the "reboot" method of PDU controller.
Example parameters for the 'APC_PDU_CONTROLLER':
{'outlet': 1}
Example parameters for the 'NORDIC_BOARD_PDU_CONTOLLER':
{'boards_serial_numbers': ('12345123', ...)}
"""
HARNESS_VERSION = 35
"""int: Version of the installed Thread Harness."""
GOLDEN_DEVICE_TYPE = 'OpenThread'
"""str: Type of the Golden Device."""