def setUp(self):
        self.tty = '/tmp/ttySRT'
        self.baud = 500000
        self.redirect = None

        self.serial = self._serial(self.tty, self.baud)
        wait_tty(self.tty, mock.Mock(side_effect=RuntimeError()), 5)
Beispiel #2
0
 def test_wait_tty(self):
     """ Test running wait_tty fct """
     logger = mock.Mock()
     self.assertEquals(0, common.wait_tty('/dev/null', logger, 0))
     self.assertEquals(0, logger.error.call_count)
     self.assertEquals(1, common.wait_tty('no_tty_file', logger, 0))
     self.assertEquals(1, logger.error.call_count)
Beispiel #3
0
    def setup(self, firmware_path):
        """ Flash open node, create serial redirection """
        ret_val = 0

        common.wait_no_tty(self.TTY)
        ret_val += common.wait_tty(self.TTY, LOGGER)
        ret_val += self.flash(firmware_path)
        ret_val += self.serial_redirection.start()
        return ret_val
Beispiel #4
0
 def teardown(self):
     """ Stop serial redirection and flash idle firmware """
     ret_val = 0
     common.wait_no_tty(self.TTY, timeout=0)
     ret_val += common.wait_tty(self.TTY, LOGGER, timeout=0)
     # cleanup debugger before flashing
     ret_val += self.debug_stop()
     ret_val += self.serial_redirection.stop()
     ret_val += self.flash(None)
     return ret_val
    def setup(self, firmware_path):
        """ Flash open node, create serial redirection """
        self._in_debug = False
        ret_val = 0

        common.wait_no_tty(self.TTY)
        ret_val += common.wait_tty(self.TTY, LOGGER)
        ret_val += self.flash(firmware_path)
        ret_val += self.serial_redirection.start()
        return ret_val
Beispiel #6
0
    def setup(self, _firmware, debug=True):  # pylint: disable=unused-argument
        """ Wait that open nodes tty appears and start A8 boot log """
        ret_val = 0
        common.wait_no_tty(self.TTY)
        ret_val += common.wait_tty(self.TTY, LOGGER, self.A8_TTY_DETECT_TIME)
        ret_val += self.serial_redirection.start()

        if ret_val == 0 and debug:
            # Timeout 15 minutes for boot (we saw 10minutes boot already)
            self._debug_boot_start(15 * 60)
        return ret_val
Beispiel #7
0
    def setup(self, _firmware, debug=True):  # pylint: disable=arguments-differ
        """ Wait that open nodes tty appears and start RPi3 boot log """
        ret_val = 0
        common.wait_no_tty(self.TTY)
        ret_val += common.wait_tty(self.TTY, LOGGER, self.RPI3_TTY_DETECT_TIME)
        ret_val += self.serial_redirection.start()

        if ret_val == 0 and debug:
            # Timeout 15 minutes for boot (we saw 10minutes boot already)
            self._debug_boot_start(15 * 60)
        return ret_val
Beispiel #8
0
 def setup(self, firmware_path):
     """ Flash open node, create serial redirection """
     ret_val = 0
     # it appears that /dev/ttyON_ZIGDUINO need some time to be detected
     common.wait_no_tty(self.TTY, timeout=common.TTY_DETECT_TIME)
     ret_val += common.wait_tty(self.TTY,
                                LOGGER,
                                timeout=common.TTY_DETECT_TIME)
     ret_val += self.flash(firmware_path, redirect=False)
     ret_val += self.disable_dtr()
     ret_val += self.serial_redirection.start()
     return ret_val
    def do_flash(self,
                 firmware_path=None,
                 binary=False,
                 offset=0,
                 redirect=True):  # pylint:disable=unused-argument
        """ Flash the given firmware on Zigduino node
        :param firmware_path: Path to the firmware to be flashed on `node`.
            If None, flash 'idle' firmware
        :param binary: whether to flash a binary file
        :param offset: at which offset to flash the binary file
        :param redirect: whether to stop the serial redirection before flashing
        """
        if binary:
            LOGGER.error('FLASH: binary mode not supported with Zigduino')
            return 1

        if offset != 0:
            LOGGER.error('FLASH: flash offset is not supported with Zigduino')
            return 1

        ret_val = 0
        firmware_path = firmware_path or self.FW_IDLE
        LOGGER.info('Flash firmware on Zigduino: %s', firmware_path)
        # First stop serial redirection, flash hangup if an
        # user session is openened on port 20000
        common.wait_no_tty(self.TTY, timeout=common.TTY_DETECT_TIME)
        ret_val += common.wait_tty(self.TTY,
                                   LOGGER,
                                   timeout=common.TTY_DETECT_TIME)
        if redirect:
            ret_val += self.serial_redirection.stop()
        # Then flash
        ret_val += self.avrdude.flash(firmware_path)
        ret_val += common.wait_tty(self.TTY, LOGGER, timeout=10)
        # Finally restore serial redirection
        if redirect:
            ret_val += self.disable_dtr()
            ret_val += self.serial_redirection.start()
        LOGGER.info("end flash")
        return ret_val
 def teardown(self):
     """ Stop serial redirection and flash idle firmware """
     ret_val = 0
     # ON may have been stopped at the end of the experiment.
     # And then restarted again in cn teardown.
     # This leads to problem where the TTY disappears and reappears during
     # the first 2 seconds. So let some time if it wants to disappear first.
     common.wait_no_tty(self.TTY)
     ret_val += common.wait_tty(self.TTY, LOGGER)
     # cleanup debugger before flashing
     ret_val += self.serial_redirection.stop()
     ret_val += self.flash(None)
     return ret_val
    def flash(self, firmware_path=None):
        """ Flash the given firmware on Leonardo node

        :param firmware_path: Path to the firmware to be flashed on `node`.
                              If None, flash 'idle' firmware """
        if AvrDude.trigger_bootloader(self.TTY, self.TTY_PROG, timeout=15):
            LOGGER.error("FLASH : Leonardo's jtag port not available")
            return 1
        ret_val = 0
        firmware_path = firmware_path or self.FW_IDLE
        LOGGER.info('Flash firmware on Leonardo: %s', firmware_path)
        ret_val += self.avrdude.flash(firmware_path)
        ret_val += common.wait_tty(self.TTY, LOGGER, self.TTY_RESTORE_TIME)
        return ret_val
    def flash(self, firmware_path=None):
        """ Flash the given firmware on Leonardo node

        :param firmware_path: Path to the firmware to be flashed on `node`.
                              If None, flash 'idle' firmware """
        if AvrDude.trigger_bootloader(self.TTY, self.TTY_PROG, timeout=15):
            LOGGER.error("FLASH : Leonardo's jtag port not available")
            return 1
        ret_val = 0
        firmware_path = firmware_path or self.FW_IDLE
        LOGGER.info('Flash firmware on Leonardo: %s', firmware_path)
        ret_val += self.avrdude.flash(firmware_path)
        ret_val += common.wait_tty(self.TTY, LOGGER, self.TTY_RESTORE_TIME)
        return ret_val
Beispiel #13
0
    def flash(self, firmware_path=None):
        """ Flash the given firmware on openocd node

        :param firmware_path: Path to the firmware to be flashed on `node`.
                              If None, flash 'idle' firmware.
        """
        firmware_path = firmware_path or self.FW_IDLE
        LOGGER.info('Flash firmware on OpenOCD: %s', firmware_path)
        ret_val = self.openocd.flash(firmware_path)
        if hasattr(self, 'JLINK_SERIAL') and self.JLINK_SERIAL:
            ret_val += common.wait_tty(self.TTY, LOGGER)
        if hasattr(self, 'DIRTY_SERIAL') and self.DIRTY_SERIAL:
            ret_val += self.clear_serial()
        return ret_val
Beispiel #14
0
 def teardown(self):
     """ Stop serial redirection and flash idle firmware """
     ret_val = 0
     # ON may have been stopped at the end of the experiment.
     # And then restarted again in cn teardown.
     # This leads to problem where the TTY disappears and reappears during
     # the first 2 seconds. So let some time if it wants to disappear first.
     common.wait_no_tty(self.TTY)
     ret_val += common.wait_tty(self.TTY, LOGGER)
     # cleanup debugger before flashing
     ret_val += self.debug_stop()
     ret_val += self.serial_redirection.stop()
     ret_val += self.flash(None)
     return ret_val
Beispiel #15
0
 def flash(self, firmware_path=None, redirect=True):
     """ Flash the given firmware on Zigduino node
     :param firmware_path: Path to the firmware to be flashed on `node`.
         If None, flash 'idle' firmware """
     ret_val = 0
     firmware_path = firmware_path or self.FW_IDLE
     LOGGER.info('Flash firmware on Zigduino: %s', firmware_path)
     # First stop serial redirection, flash hangup if an
     # user session is openened on port 20000
     common.wait_no_tty(self.TTY, timeout=common.TTY_DETECT_TIME)
     ret_val += common.wait_tty(self.TTY,
                                LOGGER,
                                timeout=common.TTY_DETECT_TIME)
     if redirect:
         ret_val += self.serial_redirection.stop()
     # Then flash
     ret_val += self.avrdude.flash(firmware_path)
     ret_val += common.wait_tty(self.TTY, LOGGER, timeout=10)
     # Finally restore serial redirection
     if redirect:
         ret_val += self.disable_dtr()
         ret_val += self.serial_redirection.start()
     LOGGER.info("end flash")
     return ret_val
Beispiel #16
0
    def _wait_tty_ready(self):
        """Wait that the tty is ready to use.

        Node may have been stopped at the end of the experiment.
        And then restarted again in cn teardown.
        This leads to problem where the TTY disappears and reappears during
        the first 2 seconds. So let some time if it wants to disappear first.

        Also, got some problems when using the tty directly after appearing, so
        git it some delay.
        """
        common.wait_no_tty(self.TTY)
        ret = common.wait_tty(self.TTY, LOGGER)
        # wait tty ready to speak
        time.sleep(self.TTY_READY_DELAY)
        return ret
    def _wait_tty_ready(self):
        """Wait that the tty is ready to use.

        Node may have been stopped at the end of the experiment.
        And then restarted again in cn teardown.
        This leads to problem where the TTY disappears and reappears during
        the first 2 seconds. So let some time if it wants to disappear first.

        Also, got some problems when using the tty directly after appearing, so
        git it some delay.
        """
        common.wait_no_tty(self.TTY)
        ret = common.wait_tty(self.TTY, LOGGER)
        # wait tty ready to speak
        time.sleep(self.TTY_READY_DELAY)
        return ret
Beispiel #18
0
    def flash(self, firmware_path=None, binary=False, offset=0):
        """ Flash the given firmware on openocd node

        :param firmware_path: Path to the firmware to be flashed on `node`.
                              If None, flash 'idle' firmware.
        :param binary: if True, flashes a binary file
        :param offset: the offset at which to flash the binary file
        """
        firmware_path = firmware_path or self.FW_IDLE
        LOGGER.info('Flash firmware on OpenOCD: %s', firmware_path)
        offset = int(self.ROM_START_ADDR) + offset
        ret_val = self.openocd.flash(firmware_path, binary, offset)
        if hasattr(self, 'JLINK_SERIAL') and self.JLINK_SERIAL:
            ret_val += common.wait_tty(self.TTY, LOGGER)
        if hasattr(self, 'DIRTY_SERIAL') and self.DIRTY_SERIAL:
            ret_val += self.clear_serial()
        return ret_val
Beispiel #19
0
    def trigger_bootloader(tty, tty_prog, timeout=10, baudrate=1200):
        """ Trigger leonardo bootloader

        To be programed the Leonardo has to be in his bootloader sequence.
        While in the bootloader, the Leonardo wait for a new program during 8s
        There are two way to launch the bootloader:
        - The first one physical by pressing the reset button
        - The software way by opening and closing the serial port at 1200bauds
        This method perform the second method. """
        LOGGER.info("Triggering bootloader")
        try:
            LOGGER.info("Trigerring bootloader")
            serial.Serial(tty, baudrate).close()
            # Wait the programming interface to be available
            return common.wait_tty(tty_prog, LOGGER, timeout)
        except (OSError, serial.SerialException) as err:
            LOGGER.warning("Error while opening TTY %s: %r", tty, err)
            return 1
Beispiel #20
0
    def trigger_bootloader(tty, tty_prog, timeout=10, baudrate=1200):
        """ Trigger leonardo bootloader

        To be programed the Leonardo has to be in his bootloader sequence.
        While in the bootloader, the Leonardo wait for a new program during 8s
        There are two way to launch the bootloader:
        - The first one physical by pressing the reset button
        - The software way by opening and closing the serial port at 1200bauds
        This method perform the second method. """
        LOGGER.info("Triggering bootloader")
        try:
            LOGGER.info("Trigerring bootloader")
            serial.Serial(tty, baudrate).close()
            # Wait the programming interface to be available
            return common.wait_tty(tty_prog, LOGGER, timeout)
        except (OSError, serial.SerialException) as err:
            LOGGER.warning("Error while opening TTY %s: %r", tty, err)
            return 1
Beispiel #21
0
    def reset(self):
        """ Reset the Zigduino node using DTR"""
        ret_val = 0

        # Check if Zigduino is up before DTR reset
        try:
            ser = serial.Serial(self.TTY, self.BAUDRATE)
        except SerialException:
            LOGGER.error("No serial port found")
            return 1

        try:
            ser.setDTR(False)
            time.sleep(0.5)
            ser.setDTR(True)
            time.sleep(0.5)
            ser.close()
        except OSError:
            LOGGER.warning("Nothing to reset")
        ret_val += common.wait_tty(self.TTY, LOGGER, timeout=10)
        return ret_val
Beispiel #22
0
    def flash(self, firmware_path=None, binary=False, offset=0):
        """ Flash the given firmware on Leonardo node

        :param firmware_path: Path to the firmware to be flashed on `node`.
                              If None, flash 'idle' firmware
        :param binary: whether to flash a binary file
        :param offset: at which offset to flash the binary file """

        if AvrDude.trigger_bootloader(self.TTY, self.TTY_PROG, timeout=15):
            LOGGER.error("FLASH : Leonardo's jtag port not available")
            return 1
        if binary:
            LOGGER.error('FLASH: binary mode not supported with Leonardo')
            return 1
        if offset != 0:
            LOGGER.error('FLASH: flash offset is not supported with Leonardo')
            return 1

        ret_val = 0
        firmware_path = firmware_path or self.FW_IDLE
        LOGGER.info('Flash firmware on Leonardo: %s', firmware_path)
        ret_val += self.avrdude.flash(firmware_path)
        ret_val += common.wait_tty(self.TTY, LOGGER, self.TTY_RESTORE_TIME)
        return ret_val
 def reset(self):
     """ Reset the Leonardo node using jtag """
     ret_val = 0
     ret_val += AvrDude.trigger_bootloader(self.TTY, self.TTY_PROG)
     ret_val += common.wait_tty(self.TTY, LOGGER, self.TTY_RESTORE_TIME)
     return ret_val
Beispiel #24
0
 def reset(self):
     """ Reset the Leonardo node using jtag """
     ret_val = 0
     ret_val += AvrDude.trigger_bootloader(self.TTY, self.TTY_PROG)
     ret_val += common.wait_tty(self.TTY, LOGGER, self.TTY_RESTORE_TIME)
     return ret_val
    def _run_simple_experiment_node(self, board_class):
        """
        Run a simple experiment on a node without profile
        Try the different node features
        """
        # start exp with idle firmware
        files = [file_tuple('firmware', board_class.FW_IDLE)]
        ret = self.server.post(EXP_START, upload_files=files)
        self.assertEqual(0, ret.json['ret'])

        # wait firmware started
        time.sleep(1)

        # idle firmware, there should be no reply
        self._check_node_echo(echo=False)

        # flash echo firmware
        ret = self._flash(board_class.FW_AUTOTEST)
        self.assertEqual(0, ret.json['ret'])

        # Should echo <message>
        self._check_node_echo(echo=True)

        # open node reset and start stop
        self.assertEqual(0, self.server.put('/open/reset').json['ret'])
        if self.control_node_has('open_node_power'):
            self.assertEqual(0, self.server.put('/open/stop').json['ret'])
            self.assertEqual(0, self.server.put('/open/start').json['ret'])

        # It is normal to fail if you flash just after starting a node
        # In these tests, I want the node to be "ready" so I ensure that
        wait_no_tty(self.g_m.open_node.TTY, timeout=10)
        wait_tty(self.g_m.open_node.TTY, GATEWAY_LOGGER, timeout=15)

        time.sleep(1)  # wait firmware started

        # Some node can leave their serial port dirty (st-lrwan1 for example)
        if hasattr(board_class, "DIRTY_SERIAL") and board_class.DIRTY_SERIAL:
            # Clear log error
            self.log_error.clear()

        # No log error
        self.log_error.check()

        # Check debug
        self._check_debug(board_class)
        self.log_error.clear()

        if self.control_node_has('open_node_power'):
            # Stop should work with stopped node
            self.assertEqual(0, self.server.put('/open/stop').json['ret'])
        # stop exp
        self.assertEqual(0, self.server.delete('/exp/stop').json['ret'])

        # Got no error during tests (use call_args_list for printing on error)
        self.log_error.check()

        if self.control_node_has('open_node_power'):
            # reset firmware should fail and logger error will be called
            self.assertLessEqual(1, self.server.put('/open/reset').json['ret'])
            self.assertNotEqual('', str(self.log_error))
Beispiel #26
0
    def exp_start(self, user, exp_id,  # pylint: disable=R0913
                  firmware_path=None, profile_dict=None, timeout=0):
        """
        Start an experiment

        :param exp_id: experiment id
        :param user: user running the experiment
        :param firmware_path: path of the firmware file to use, can be None
        :param profile_dict: monitoring profile
        :param timeout: Experiment expiration timeout. On 0 no timeout.

        Experiment start steps

        1) Prepare Gateway: User experiment files and log:
        2) Prepare Control node: Start communication and power on open node
        3) Prepare Open node: Check OK, setup firmware and serial redirection
        4) Configure Control Node Profile and experiment
        5) Set Experiment expiration timer

        """
        if self.experiment_is_running:
            LOGGER.debug('Experiment running. Stop previous experiment')
            self.exp_stop()

        try:
            profile = self.board_cfg.profile_from_dict(profile_dict)
        except ValueError as err:
            LOGGER.error('%r', err)
            return 1
        if not elftarget.is_compatible_with_node(firmware_path,
                                                 self.open_node):
            LOGGER.error('Invalid firmware target, aborting experiment.')
            return 1

        ret_val = 0

        self.experiment_is_running = True
        self.exp_id = exp_id
        self.user = user

        if (self.board_cfg.robot_type == 'turtlebot2' or
                self.board_cfg.cn_class.TYPE == 'no'):  # pragma: no cover
            LOGGER.info('Create user exp folder')
            self._create_user_exp_folders(user, exp_id)

        self.exp_files = self.create_user_exp_files(self.board_cfg.node_id,
                                                    user, exp_id)

        # Create user log
        self.user_log_handler = gateway_logging.user_logger(
            self.exp_files['log'])
        LOGGER.addHandler(self.user_log_handler)
        LOGGER.info('Start experiment: %s-%i', user, exp_id)

        # Init ControlNode
        ret_val += self.control_node.start(self.exp_id, self.exp_files)

        # with Pycom boards, trigger 2 power-cycle to ensure REPL is correctly
        # started
        if self.open_node.TYPE == 'pycom':
            for _ in range(2):
                LOGGER.debug("Power cycle %s board", self.open_node.TYPE)
                ret_val += self.control_node.open_stop()
                ret_val += wait_no_tty(self.open_node.TTY, timeout=10)
                ret_val += self.control_node.open_start()
                ret_val += wait_tty(self.open_node.TTY, LOGGER, timeout=10)
        # Configure Open Node
        ret_val += self.open_node.setup(firmware_path)
        # Configure experiment and monitoring on ControlNode
        ret_val += self.control_node.start_experiment(profile)

        # nrf52dk and nrf52840dk needs a power cycle before their serial
        # becomes fully usable.
        if (firmware_path is not None and
                self._board_require_power_cycle(self.open_node.TYPE)):
            LOGGER.info("Power cycle node %s",
                        self.control_node.node_id.replace('_', '-'))
            ret_val += self.control_node.open_stop()
            ret_val += self.control_node.open_start()

        if timeout != 0:
            LOGGER.debug("Setting timeout to: %d", timeout)
            self.timeout_timer = Timer(timeout, self._timeout_exp_stop,
                                       args=(exp_id, user))
            self.timeout_timer.start()
        LOGGER.info("Start experiment succeeded")
        return ret_val