def test_run_with_lowercase_HTM(self, mock_popen, mock_verifier, mock_copy_file): mock_verifier.return_value = {'target_id': '123', 'platform_name': 'K64F', 'mount_point': 'path/'} mock_stdout = mock.Mock() mock_out = mock.Mock(side_effect=[b"no-htm", b"test.htm", b"no-htm"]) mock_stdout.read = mock_out mock_popen.return_value.stdout = mock_stdout mock_popen.return_value.communicate.return_value = ('', '') flasher = Flash() ret = flasher.flash(build=self.bin_path, target_id='123', platform_name='K64F', device_mapping_table=[{ 'target_id': '123', 'platform_name': 'K64F', 'mount_point': '', }], method='simple', no_reset=True) self.assertEqual(ret, 0) self.assertEqual(2, mock_out.call_count)
def allocate(self, name: str = None) -> Optional[BleDevice]: for alloc in self.allocation: if alloc.ble_device is None: # Flash if a binary is provided and the board hasn't been flashed yet platform = alloc.description['platform_name'] binary = self.binaries.get(platform) if alloc.flashed is False and binary: if self.flasher is None: self.flasher = Flash() self.flasher.flash( build=binary, target_id=alloc.description["target_id"]) alloc.flashed = True # Create the serial connection connection = SerialConnection( port=alloc.description["serial_port"], baudrate=115200) connection.open() # Create the serial device serial_device = SerialDevice(connection, name) serial_device.reset(duration=1) serial_device.flush(1) # Create the BleDevice alloc.ble_device = BleDevice(serial_device) alloc.ble_device.send('set --retcode true', 'retcode: 0') alloc.ble_device.send('echo off', 'retcode: 0') alloc.ble_device.send('set --vt100 off', 'retcode: 0') return alloc.ble_device return None
def parse_id_to_devices(self, tid): """ :param tid: target id """ flasher = Flash() available = flasher.get_available_device_mapping() target_ids = [] available_target_ids = [] if not available: print("Could not find any connected device") return EXIT_CODE_DEVICES_MISSING if 'all' in tid: for device in available: target_ids.append(device['target_id']) else: for item in tid: for device in available: available_target_ids.append(device['target_id']) if device['target_id'] == item or \ device['target_id'].startswith(item): if device['target_id'] not in target_ids: target_ids.append(device['target_id']) if not target_ids: print("Could not find given target_id from attached devices") print("Available target_ids:") print(available_target_ids) return EXIT_CODE_COULD_NOT_MAP_DEVICE if len(target_ids) == 1: return target_ids[0] return target_ids
def allocate(self, name: str = None) -> Optional[SerialDevice]: for alloc in self.allocation: if alloc.ble_device is None: # Flash if a binary is provided and the board hasn't been flashed yet platform = alloc.description['platform_name'] binary = self.binaries.get(platform) if alloc.flashed is False and binary: if self.flasher is None: self.flasher = Flash() self.flasher.flash( build=binary, target_id=alloc.description["target_id"]) alloc.flashed = True # Create the serial connection connection = SerialConnection( port=alloc.description["serial_port"], baudrate=self.baudrate, inter_byte_delay=self.serial_inter_byte_delay) connection.open() # Create the serial device serial_device = SerialDevice(connection, name) serial_device.reset(duration=1) serial_device.flush(1) # Create the SerialDevice alloc.ble_device = serial_device return alloc.ble_device return None
class BoardAllocator: def __init__(self, platforms_supported: List[str], binaries: Mapping[str, str]): mbed_ls = mbed_lstools.create() boards = mbed_ls.list_mbeds(filter_function=lambda m: m[ 'platform_name'] in platforms_supported) self.board_description = boards self.binaries = binaries self.allocation = [] # type: List[BoardAllocation] self.flasher = None for desc in boards: self.allocation.append(BoardAllocation(desc)) def allocate(self, name: str = None) -> Optional[BleDevice]: for alloc in self.allocation: if alloc.ble_device is None: # Flash if a binary is provided and the board hasn't been flashed yet platform = alloc.description['platform_name'] binary = self.binaries.get(platform) if alloc.flashed is False and binary: if self.flasher is None: self.flasher = Flash() self.flasher.flash( build=binary, target_id=alloc.description["target_id"]) alloc.flashed = True # Create the serial connection connection = SerialConnection( port=alloc.description["serial_port"], baudrate=115200) connection.open() # Create the serial device serial_device = SerialDevice(connection, name) serial_device.reset(duration=1) serial_device.flush(1) # Create the BleDevice alloc.ble_device = BleDevice(serial_device) alloc.ble_device.send('set --retcode true', 'retcode: 0') alloc.ble_device.send('echo off', 'retcode: 0') alloc.ble_device.send('set --vt100 off', 'retcode: 0') return alloc.ble_device return None def release(self, ble_device: BleDevice) -> None: for alloc in self.allocation: if alloc.ble_device == ble_device and alloc.ble_device is not None: # Restore the board alloc.ble_device.send('echo on', 'retcode: 0') alloc.ble_device.send('set --vt100 on', 'retcode: 0') alloc.ble_device.send('set retcode false') # Stop activities alloc.ble_device.device.stop() alloc.ble_device.device.serial.close() # Cleanup alloc.ble_device = None
def test_run_fail_binary(self, mock_stdout): mbeds = mbed_lstools.create() targets = mbeds.list_mbeds() target_id = None mount_point = None fail_bin_path = os.path.join('test', 'fail.bin') for target in targets: if target['platform_name'] == 'K64F': if 'target_id' in target and 'mount_point' in target: target_id = target['target_id'] mount_point = target['mount_point'] break with open(fail_bin_path, 'w') as new_file: new_file.write("0000000000000000000000000000000000") with self.assertRaises(FlashError) as cm: flasher = Flash() flasher.flash(build=fail_bin_path, target_id=target_id, platform_name='K64F', device_mapping_table=None, method='simple') if platform.system() == 'Windows': os.system('del /F %s' % os.path.join(mount_point, 'FAIL.TXT')) os.system('del %s' % os.path.join(os.getcwd(), fail_bin_path)) else: os.system('rm -f %s' % os.path.join(mount_point, 'FAIL.TXT')) os.system('rm %s' % os.path.join(os.getcwd(), fail_bin_path)) self.assertEqual(cm.exception.return_code, EXIT_CODE_DAPLINK_USER_ERROR)
def subcmd_list_platforms(self, args): """ list platform command """ flasher = Flash() print(json.dumps(flasher.get_supported_targets())) return EXIT_CODE_SUCCESS
def subcmd_list_flashers(self, args): """ list flasher command handler """ flasher = Flash() print(json.dumps(flasher.get_supported_flashers())) return EXIT_CODE_SUCCESS
def test_run_with_file_with_target_id_all(self): flasher = Flash() ret = flasher.flash(build=self.bin_path, target_id='all', platform_name=False, device_mapping_table=None, method='simple') self.assertEqual(ret, 40)
def test_run_with_file_with_one_target_id(self): flasher = Flash() ret = flasher.flash(build=self.bin_path, target_id='0240000029164e45002f0012706e0006f301000097969900', platform_name=False, device_mapping_table=None, method='simple') self.assertEqual(ret, 55)
class BoardAllocator: def __init__(self, platforms_supported: List[str], binaries: Mapping[str, str], serial_inter_byte_delay: float, baudrate: int, command_delay: float): mbed_ls = mbed_lstools.create() boards = mbed_ls.list_mbeds(filter_function=lambda m: m[ 'platform_name'] in platforms_supported) self.board_description = boards self.binaries = binaries self.allocation = [] # type: List[BoardAllocation] self.flasher = None self.serial_inter_byte_delay = serial_inter_byte_delay self.baudrate = baudrate self.command_delay = command_delay for desc in boards: self.allocation.append(BoardAllocation(desc)) def allocate(self, name: str = None) -> Optional[SerialDevice]: for alloc in self.allocation: if alloc.ble_device is None: # Flash if a binary is provided and the board hasn't been flashed yet platform = alloc.description['platform_name'] binary = self.binaries.get(platform) if alloc.flashed is False and binary: if self.flasher is None: self.flasher = Flash() self.flasher.flash( build=binary, target_id=alloc.description["target_id"]) alloc.flashed = True # Create the serial connection connection = SerialConnection( port=alloc.description["serial_port"], baudrate=self.baudrate, inter_byte_delay=self.serial_inter_byte_delay) connection.open() # Create the serial device serial_device = SerialDevice(connection, name) serial_device.reset(duration=1) serial_device.flush(1) # Create the SerialDevice alloc.ble_device = serial_device return alloc.ble_device return None def release(self, ble_device: SerialDevice) -> None: for alloc in self.allocation: if alloc.ble_device == ble_device and alloc.ble_device is not None: # Stop activities alloc.ble_device.stop() alloc.ble_device.serial.close() # Cleanup alloc.ble_device = None
def test_run_file_does_not_exist(self): flasher = Flash() with self.assertRaises(SyntaxError) as context: flasher.flash(build='file.bin', target_id=None, platform_name=None, device_mapping_table=None, method='simple') self.assertIn("target_id or target_name is required", context.exception.msg)
def test_run_target_id_and_platform_missing(self): flasher = Flash() with self.assertRaises(FlashError) as cm: flasher.flash(build='file.bin', target_id=True, platform_name=False, device_mapping_table=None, method='simple') self.assertEqual(cm.exception.return_code, EXIT_CODE_FILE_MISSING)
def test_run_with_file_with_prefix(self, mock_stdout): flasher = Flash() ret = flasher.flash(build=self.bin_path, target_id='02', platform_name='K64F', device_mapping_table=None, method='simple') self.assertEqual(ret, EXIT_CODE_SUCCESS) if mock_stdout: pass
def test_raises_with_bad_file_extension(self): flasher = Flash() with self.assertRaises(FlashError) as cm: flasher.flash( build=__file__, target_id='0240000029164e45002f0012706e0006f301000097969900', platform_name=False, device_mapping_table=None, method='simple') self.assertEqual(cm.exception.return_code, EXIT_CODE_DAPLINK_USER_ERROR)
def test_run_with_file_with_target_id_all(self, mock_device_mapping): flasher = Flash() mock_device_mapping.return_value = [] with self.assertRaises(FlashError) as cm: flasher.flash(build=self.bin_path, target_id='all', platform_name=False, device_mapping_table=None, method='simple') self.assertEqual(cm.exception.return_code, EXIT_CODE_COULD_NOT_MAP_TARGET_ID_TO_DEVICE)
def test_run_with_file_with_one_target_id(self, mock_sleep): flasher = Flash() with self.assertRaises(FlashError) as cm: flasher.flash( build=self.bin_path, target_id='0240000029164e45002f0012706e0006f301000097969900', platform_name=False, device_mapping_table=None, method='simple') self.assertEqual(cm.exception.return_code, EXIT_CODE_COULD_NOT_MAP_DEVICE)
def allocate(self, name: str = None) -> Optional[BleDevice]: for alloc in self.allocation: if alloc.ble_device is None: # Flash if a binary is provided and the board hasn't been flashed yet platform = alloc.description['platform_name'] binary = self.binaries.get(platform) if alloc.flashed is False and binary: if self.flasher is None: self.flasher = Flash() self.flasher.flash( build=binary, target_id=alloc.description["target_id"]) alloc.flashed = True # Create the serial connection connection = SerialConnection( port=alloc.description["serial_port"], baudrate=self.baudrate, inter_byte_delay=self.serial_inter_byte_delay) connection.open() retry = BoardAllocator.ALLOCATION_RETRIES serial_device = None while True: try: # Create the serial device serial_device = SerialDevice(connection, name) serial_device.reset(duration=1) serial_device.flush(1) # Create the BleDevice alloc.ble_device = BleDevice( serial_device, command_delay=self.command_delay) alloc.ble_device.send('set --retcode true', 'retcode: 0', wait_for_response=5) alloc.ble_device.send('echo off', 'retcode: 0') alloc.ble_device.send('set --vt100 off', 'retcode: 0') break except serial_device.BoardCommunicationFailed: if retry: retry -= 1 self.release(serial_device) log.warning("Board failed to allocate, retrying") else: raise return alloc.ble_device return None
def test_verify_hw_flash_no_reset(self): mbeds = mbed_lstools.create() targets = mbeds.list_mbeds() flasher = Flash() resetter = Reset() target_id = None serial_port = None for target in targets: if target['platform_name'] == 'K64F': if 'serial_port' and 'target_id' in target: target_id = target['target_id'] serial_port = target['serial_port'] break if target_id and serial_port: second_binary = find_second_binary() self.assertIsNotNone(second_binary, 'Second binary not found') ret = flasher.flash(build=second_binary, target_id=target_id, platform_name='K64F', device_mapping_table=False, method='simple') self.assertEqual(ret, 0) if not verify_output_per_device(serial_port, 'help', 'echo'): self.assertEqual( verify_output_per_device(serial_port, 'help', 'echo'), True) ret = flasher.flash(build=second_binary, target_id=target_id, platform_name='K64F', device_mapping_table=False, method='simple', no_reset=True) self.assertEqual(ret, 0) self.assertEqual( verify_output_per_device(serial_port, 'help', 'echo'), False) ret = resetter.reset(target_id=target_id, method='simple') self.assertEqual(ret, 0) if not verify_output_per_device(serial_port, 'help', 'echo'): self.assertEqual( verify_output_per_device(serial_port, 'help', 'echo'), True) ret = flasher.flash(build=self.bin_path, target_id=target_id, platform_name='K64F', device_mapping_table=False, method='simple') self.assertEqual(ret, 0) self.assertEqual( verify_output_per_device(serial_port, 'help', 'echo'), False)
def test_hw_flash(self): mbeds = mbed_lstools.create() targets = mbeds.list_mbeds() target_id = None for target in targets: if target['platform_name'] == 'K64F': if 'target_id' in target: target_id = target['target_id'] break if target_id: flasher = Flash() ret = flasher.flash(build=self.bin_path, target_id=target_id, platform_name=False, device_mapping_table=None, method='simple') self.assertEqual(ret, EXIT_CODE_SUCCESS)
def test_run_with_lowercase_HTM(self, mock_refresh_target, mock_copy_file): mock_refresh_target.return_value = { 'target_id': '123', 'platform_name': 'K64F', 'mount_point': 'path/' } flasher = Flash() ret = flasher.flash(build=self.bin_path, target_id='123', platform_name='K64F', device_mapping_table=[{ 'target_id': '123', 'platform_name': 'K64F', 'mount_point': '', }], method='simple', no_reset=True) self.assertEqual(ret, EXIT_CODE_SUCCESS)
def test_run_with_file_with_one_target_id_wrong_platform(self): mbeds = mbed_lstools.create() targets = mbeds.list_mbeds() target_id = None for target in targets: if target['platform_name'] == 'K64F': if 'target_id' in target: target_id = target['target_id'] break if target_id: flasher = Flash() with self.assertRaises(NotImplementedError) as context: flasher.flash(build=self.bin_path, target_id=target_id, platform_name='K65G', device_mapping_table=None, method='simple') self.assertIn("Platform 'K65G' is not supported by mbed-flasher", str(context.exception))
def test_verify_hw_flash(self): mbeds = mbed_lstools.create() targets = mbeds.list_mbeds() flasher = Flash() target_id = None serial_port = None for target in targets: if target['platform_name'] == 'K64F': if 'serial_port' and 'target_id' in target: target_id = target['target_id'] serial_port = target['serial_port'] break if target_id and serial_port: ret = flasher.flash(build=self.bin_path, target_id=target_id, platform_name='K64F', device_mapping_table=False, method='simple') self.assertEqual(ret, EXIT_CODE_SUCCESS) self.assertEqual( verify_output_per_device(serial_port, 'help', 'echo'), False) ret = flasher.flash(build=self.second_bin_path, target_id=target_id, platform_name='K64F', device_mapping_table=False, method='simple') self.assertEqual(ret, EXIT_CODE_SUCCESS) if not verify_output_per_device(serial_port, 'help', 'echo'): self.assertEqual( verify_output_per_device(serial_port, 'help', 'echo'), True) ret = flasher.flash(build=self.bin_path, target_id=target_id, platform_name='K64F', device_mapping_table=False, method='simple') self.assertEqual(ret, EXIT_CODE_SUCCESS) self.assertEqual( verify_output_per_device(serial_port, 'help', 'echo'), False)
def parse_id_to_devices(self, tid): """ :param tid: target id """ flasher = Flash() available = Common(self.logger).get_available_device_mapping( flasher.get_all_flashers(), tid) target_ids = [] available_target_ids = [] if not available: msg = "Could not find any connected device" print(msg) raise GeneralFatalError(message=msg, return_code=EXIT_CODE_DEVICES_MISSING) if 'all' in tid: for device in available: target_ids.append(device['target_id']) else: for item in tid: for device in available: available_target_ids.append(device['target_id']) if device['target_id'] == item or \ device['target_id'].startswith(item): if device['target_id'] not in target_ids: target_ids.append(device['target_id']) if not target_ids: print("Could not find given target_id from attached devices") print("Available target_ids:") print(available_target_ids) raise GeneralFatalError(message="Could not map device", return_code=EXIT_CODE_COULD_NOT_MAP_DEVICE) if len(target_ids) == 1: return target_ids[0] return target_ids
def flash(self, binary, forceflash=None): # pylint: disable=too-many-branches """ Flash a binary to the target device using mbed-flasher. :param binary: Binary to flash to device :param forceflash: Boolean :return: False if an error was encountered during flashing. True if flasher retcode == 0 :raises: ImportError if mbed-flasher not installed. :raises: DutConnectionError if Build initialization fails (binary not found usually). """ error_occured = False if Flash is None: self.logger.warning("mbed-flasher not installed. " "(https://github.com/ARMmbed/mbed-flasher)") raise ImportError("Mbed-flasher not installed.") try: # Create build object. self.build = Build.init(binary) except NotImplementedError as error: self.logger.error( "Build initialization failed. Check your build location.") self.logger.debug(error) raise DutConnectionError(error) # Check if flashing is needed. Depends on forceflash-option. if not self._flash_needed(forceflash=forceflash): self.logger.info("Skipping flash, not needed.") return True if "logger" in getargspec(Flash.__init__).args: # get_resourceprovider_logger returns previous logger if one already exists. # If no logger with name mbed-flasher exists, a new one is created. logger = get_resourceprovider_logger("mbed-flasher", "FLS") flasher = Flash(logger=logger) else: # Backwards compatibility for older mbed-flasher versions. flasher = Flash() retcode = None try: if self.device: buildfile = self.build.get_file() if not buildfile: raise DutConnectionError( "Binary {} not found".format(buildfile)) self.logger.info('Flashing dev: %s', self.device['target_id']) target_id = self.device.get("target_id") retcode = flasher.flash(build=buildfile, target_id=target_id, device_mapping_table=[self.device]) else: error_occured = True except FLASHER_ERRORS as error: if error.__class__ == NotImplementedError: self.logger.error("Flashing not supported for this platform!") elif error.__class__ == SyntaxError: self.logger.error("target_id required by mbed-flasher!") if FlashError is not None: if error.__class__ == FlashError: self.logger.error( "Flasher raised the following error: %s Error code: %i", error.message, error.return_code) raise DutConnectionError(error) if retcode != 0: error_occured = True else: self.dutinformation.build_binary_sha1 = self.build.sha1 return not error_occured
def subcmd_flash_handler(self, args): """ flash command handler """ if not args.tid: msg = "Target_id is missing" raise FlashError(message=msg, return_code=EXIT_CODE_TARGET_ID_MISSING) check_file(self.logger, args.target_filename or args.input) check_file(self.logger, args.input) check_file_exists(self.logger, args.input) check_file_extension(self.logger, args.target_filename or args.input) flasher = Flash() available = Common(self.logger).get_available_device_mapping( flasher.get_all_flashers(), args.tid) available_target_ids = [] retcode = EXIT_CODE_SUCCESS if args.platform_name: if args.platform_name not in flasher.get_supported_targets(): self.logger.error("Not supported platform: %s", args.platform_name) self.logger.error("Supported platforms: %s", flasher.get_supported_targets()) raise FlashError(message="Platform {} not supported".format( args.platform_name), return_code=EXIT_CODE_NOT_SUPPORTED_PLATFORM) if 'all' in args.tid: retcode = flasher.flash(build=args.input, target_id='all', platform_name=args.platform_name, target_filename=args.target_filename, method=args.method, no_reset=args.no_reset) if len(available) <= 0: msg = "Could not find any connected device" raise FlashError(message=msg, return_code=EXIT_CODE_DEVICES_MISSING) available_platforms, target_ids_to_flash = \ self.prepare_platforms_and_targets(available, args.tid, available_target_ids) if not target_ids_to_flash: self.logger.error( "Could not find given target_id from attached devices") self.logger.error("Available target_ids: %s", available_target_ids) raise FlashError(message="Could not map device", return_code=EXIT_CODE_COULD_NOT_MAP_DEVICE) elif len(available_platforms) > 1: if not args.platform_name: self.logger.error( "More than one platform detected for given target_id") self.logger.error( "Please specify the platform with -t <PLATFORM_NAME>") self.logger.error("Found platforms: %s", available_platforms) raise FlashError( message= "More than one platform detected for given target id", return_code=EXIT_CODE_PLATFORM_REQUIRED) else: retcode = flasher.flash(build=args.input, target_id=target_ids_to_flash, target_filename=args.target_filename, platform_name=available_platforms[0], method=args.method, no_reset=args.no_reset) return retcode
def test_flash_logger_not_created(self, mock_logger): mock_logger.return_value = mock.MagicMock() very_real_logger = mock.MagicMock() flash = Flash(logger=very_real_logger) mock_logger.assert_not_called() self.assertEqual(very_real_logger, flash.logger)
def test_flash_logger_created(self, mock_logger): # pylint: disable=no-self-use mock_logger.return_value = mock.MagicMock() flash = Flash() # pylint: disable=unused-variable mock_logger.assert_called_once_with("mbed-flasher")
class BoardAllocator: ALLOCATION_RETRIES = 3 def __init__(self, platforms_supported: List[str], binaries: Mapping[str, str], serial_inter_byte_delay: float, baudrate: int, command_delay: float): mbed_ls = mbed_lstools.create() boards = mbed_ls.list_mbeds(filter_function=lambda m: m[ 'platform_name'] in platforms_supported) self.board_description = boards self.binaries = binaries self.allocation = [] # type: List[BoardAllocation] self.flasher = None self.serial_inter_byte_delay = serial_inter_byte_delay self.baudrate = baudrate self.command_delay = command_delay for desc in boards: self.allocation.append(BoardAllocation(desc)) def allocate(self, name: str = None) -> Optional[BleDevice]: for alloc in self.allocation: if alloc.ble_device is None: # Flash if a binary is provided and the board hasn't been flashed yet platform = alloc.description['platform_name'] binary = self.binaries.get(platform) if alloc.flashed is False and binary: if self.flasher is None: self.flasher = Flash() self.flasher.flash( build=binary, target_id=alloc.description["target_id"]) alloc.flashed = True # Create the serial connection connection = SerialConnection( port=alloc.description["serial_port"], baudrate=self.baudrate, inter_byte_delay=self.serial_inter_byte_delay) connection.open() retry = BoardAllocator.ALLOCATION_RETRIES serial_device = None while True: try: # Create the serial device serial_device = SerialDevice(connection, name) serial_device.reset(duration=1) serial_device.flush(1) # Create the BleDevice alloc.ble_device = BleDevice( serial_device, command_delay=self.command_delay) alloc.ble_device.send('set --retcode true', 'retcode: 0', wait_for_response=5) alloc.ble_device.send('echo off', 'retcode: 0') alloc.ble_device.send('set --vt100 off', 'retcode: 0') break except serial_device.BoardCommunicationFailed: if retry: retry -= 1 self.release(serial_device) log.warning("Board failed to allocate, retrying") else: raise return alloc.ble_device return None def release(self, ble_device: BleDevice) -> None: for alloc in self.allocation: if alloc.ble_device == ble_device and alloc.ble_device is not None: # Restore the board alloc.ble_device.send('echo on', 'retcode: 0') alloc.ble_device.send('set --vt100 on', 'retcode: 0') alloc.ble_device.send('set retcode false') # Stop activities alloc.ble_device.device.stop() alloc.ble_device.device.serial.close() # Cleanup alloc.ble_device = None
def test_run_target_id_and_platform_missing(self): flasher = Flash() ret = flasher.flash(build='file.bin', target_id=True, platform_name=False, device_mapping_table=None, method='simple') self.assertEqual(ret, 45)