def disconnect(self): try: self.rpscontrol.turn_outlet_off(self.cutter_channel) except self.RPSError as e: logger.error(e) logger.error("Unable to turn off outlet " + self.cutter_channel) raise e
def _enter_test_mode(self): """ Enter test mode by booting from sd card Returns: None Raises: aft.errors.AFTDeviceError if the device failed to enter the test mode """ # device by default boots from sd card, so if everything has gone well, # we can just power cycle to boot the testable image logger.info("Entering test mode") for _ in range(self._TEST_MODE_RETRY_ATTEMPTS): try: self._power_cycle() self.dev_ip = self._wait_for_responsive_ip() if self.dev_ip and self._verify_mode( self.parameters["test_mode"]): return else: logger.warning("Failed to enter test mode") except KeyboardInterrupt: raise except: _err = sys.exc_info() logger.error(str(_err[0]).split("'")[1] + ": " + str(_err[1])) raise errors.AFTDeviceError("Could not set the device in test mode")
def remote_execute(remote_ip, command, timeout = 60, ignore_return_codes = None, user = "******", connect_timeout = 15): """ Execute a Bash command over ssh on a remote device with IP 'remote_ip'. Returns combines stdout and stderr if there are no errors. On error raises subprocess32 errors. """ ssh_args = ["ssh", "-i", "".join([os.path.expanduser("~"), "/.ssh/id_rsa_testing_harness"]), "-o", "UserKnownHostsFile=/dev/null", "-o", "StrictHostKeyChecking=no", "-o", "BatchMode=yes", "-o", "LogLevel=ERROR", "-o", "ConnectTimeout=" + str(connect_timeout), user + "@" + str(remote_ip), _get_proxy_settings(),] logger.info("Executing " + " ".join(command), filename="ssh.log") ret = "" try: ret = tools.local_execute(ssh_args + command, timeout, ignore_return_codes) except subprocess32.CalledProcessError as err: logger.error("Command raised exception: " + str(err), filename="ssh.log") logger.error("Output: " + str(err.output), filename="ssh.log") raise err return ret
def _enter_mode(self, target, keystrokes): """ Try to put the device into the specified mode. Args: keystrokes (string): Path to keystrokes file for booting target (string): Boot target: 'test_mode' or 'service_mode' Raises: aft.errors.AFTDeviceError if device fails to enter the mode or if keyboard emulator fails to connect """ if not (target == "test_mode" or target == "service_mode"): raise errors.AFTDeviceError( "Bad argument: target=" + target + " for pcdevice.py: _enter_mode function") # Sometimes booting to a mode fails. logger.info("Trying to enter " + target + " up to " + str(self._RETRY_ATTEMPTS) + " times.") for _ in range(self._RETRY_ATTEMPTS): try: self._power_cycle() if self.kb_emulator: logger.info("Using " + type(self.kb_emulator).__name__ + " to send keyboard sequence " + keystrokes) self.kb_emulator.send_keystrokes(keystrokes) else: logger.warning( "No keyboard emulator defined for the device") ip_address = self._wait_for_responsive_ip() if ip_address: if target == "test_mode" and not \ self._verify_mode(self._service_mode_name): logger.info("Correctly booted target image") return if target == "service_mode" and \ self._verify_mode(self._service_mode_name): logger.info("Correctly booted support image") return else: logger.warning("Failed entering " + target + ".") except KeyboardInterrupt: raise except: _err = sys.exc_info() logger.error(str(_err[0]).split("'")[1] + ": " + str(_err[1])) logger.critical("Unable to get the device in mode " + target) raise errors.AFTDeviceError("Could not set the device in mode " + target)
def try_flash_model(self, args): ''' Reserve and flash a machine. By default it tries to flash 2 times, Args: args: AFT arguments Returns: device, tester: Reserved machine and tester handles. ''' device = self.reserve() if args.testplan: device.test_plan = args.testplan tester = Tester(device) if args.record: device.record_serial() if not self.check_libcomposite_service_running(): self.stop_image_usb_emulation(device.leases_file_name) if args.emulateusb: self.start_image_usb_emulation(args, device.leases_file_name) inject_ssh_keys_to_image(args.file_name) return device, tester if args.noflash: return device, tester flash_attempt = 0 flash_retries = args.flash_retries while flash_attempt < flash_retries: flash_attempt += 1 try: print("Flashing " + str(device.name) + ", attempt " + str(flash_attempt) + " of " + str(flash_retries) + ".") device.write_image(args.file_name) print("Flashing successful.") return device, tester except KeyboardInterrupt: raise except: _err = sys.exc_info() _err = str(_err[0]).split("'")[1] + ": " + str(_err[1]) logger.error(_err) print(_err) if (flash_retries - flash_attempt) == 0: print("Flashing failed " + str(flash_attempt) + " times") self.release(device) raise elif (flash_retries - flash_attempt) == 1: print("Flashing failed, trying again one more time") elif (flash_retries - flash_attempt) > 1: print("Flashing failed, trying again " + str(flash_retries - flash_attempt) + " more times")
def send_a_key(self, key, timeout=20): ''' HID keyboard message length is 8 bytes and format is: [modifier, reserved, Key1, Key2, Key3, Key4, Key6, Key7] So first byte is for modifier key and all bytes after third one are for normal keys. After sending a key stroke, empty message with zeroes has to be sent to stop the key being pressed. Messages are sent by writing to the emulated HID usb port in /dev/. US HID keyboard hex codes are used for translating keys. Args: key: A key to send, for example: "a", "z", "3", "F2", "ENTER" timeout: how long sending a key will be tried until quitting [s] ''' def writer(path, message, empty): while True: try: with open(path, "w") as emulator: emulator.write(message.decode()) # Send the key emulator.write(empty) # Stop the key being pressed except IOError: sleep(1) else: return 0 # Empty message which will be sent to stop any keys being pressed empty = "\x00\x00\x00\x00\x00\x00\x00\x00" usb_message = bytearray(empty.encode()) # Initialize usb message hex_key, _modifier = self.key_to_hex(key) # Translate key to hex code # Override self.modifier if the key needs a specific one if _modifier: modifier = _modifier else: modifier = self.modifier usb_message[2] = hex_key usb_message[0] = modifier # Do the writing in a subprocess as it hangs in some rare cases writer = Process(target=writer, args=(self.emulator, usb_message, empty)) writer.start() writer.join(20) if writer.is_alive(): writer.terminate() msg = "Keyboard emulator couldn't connect to host or it froze" logger.error(msg, "kb_emulator.log") raise TimeoutError(msg) logger.info( "Sent key: " + key.ljust(5) + " hex code: " + format(hex_key, '#04x') + " modifier: " + format(modifier, '#04x'), "kb_emulator.log") return 0
def _enter_mode(self, target, keystrokes): """ Try to put the device into the specified mode. Args: keystrokes (string): Path to keystrokes file for booting target (string): Boot target: 'test_mode' or 'service_mode' Raises: aft.errors.AFTDeviceError if device fails to enter the mode or if keyboard emulator fails to connect """ if not (target=="test_mode" or target=="service_mode"): raise errors.AFTDeviceError("Bad argument: target=" + target + " for pcdevice.py: _enter_mode function") # Sometimes booting to a mode fails. logger.info("Trying to enter " + target + " up to " + str(self._RETRY_ATTEMPTS) + " times.") for _ in range(self._RETRY_ATTEMPTS): try: self._power_cycle() if self.kb_emulator: logger.info("Using " + type(self.kb_emulator).__name__ + " to send keyboard sequence " + keystrokes) self.kb_emulator.send_keystrokes(keystrokes) else: logger.warning("No keyboard emulator defined for the device") ip_address = self._wait_for_responsive_ip() if ip_address: if target == "test_mode" and not \ self._verify_mode(self._service_mode_name): logger.info("Correctly booted target image") return if target == "service_mode" and \ self._verify_mode(self._service_mode_name): logger.info("Correctly booted support image") return else: logger.warning("Failed entering " + target + ".") except KeyboardInterrupt: raise except: _err = sys.exc_info() logger.error(str(_err[0]).split("'")[1] + ": " + str(_err[1])) logger.critical( "Unable to get the device in mode " + target) raise errors.AFTDeviceError( "Could not set the device in mode " + target)
def disconnect(self): """ Turns power off """ try: self._set_gpio_pin(self._GPIO_CUTTER_OFF) except GpioCutterError as e: logger.error(e) logger.error("Unable to set GPIO controlled cutter off") raise e
def send_a_key(self, key, timeout=20): ''' HID keyboard message length is 8 bytes and format is: [modifier, reserved, Key1, Key2, Key3, Key4, Key6, Key7] So first byte is for modifier key and all bytes after third one are for normal keys. After sending a key stroke, empty message with zeroes has to be sent to stop the key being pressed. Messages are sent by writing to the emulated HID usb port in /dev/. US HID keyboard hex codes are used for translating keys. Args: key: A key to send, for example: "a", "z", "3", "F2", "ENTER" timeout: how long sending a key will be tried until quitting [s] ''' def writer(path, message, empty): while True: try: with open(path, "w") as emulator: emulator.write(message.decode()) # Send the key emulator.write(empty) # Stop the key being pressed except IOError: sleep(1) else: return 0 # Empty message which will be sent to stop any keys being pressed empty = "\x00\x00\x00\x00\x00\x00\x00\x00" usb_message = bytearray(empty.encode()) # Initialize usb message hex_key, _modifier = self.key_to_hex(key) # Translate key to hex code # Override self.modifier if the key needs a specific one if _modifier: modifier = _modifier else: modifier = self.modifier usb_message[2] = hex_key usb_message[0] = modifier # Do the writing in a subprocess as it hangs in some rare cases writer = Process(target=writer, args=(self.emulator, usb_message, empty)) writer.start() writer.join(20) if writer.is_alive(): writer.terminate() msg = "Keyboard emulator couldn't connect to host or it froze" logger.error(msg, "kb_emulator.log") raise TimeoutError(msg) logger.info("Sent key: " + key.ljust(5) + " hex code: " + format(hex_key, '#04x') + " modifier: " + format(modifier, '#04x'), "kb_emulator.log") return 0
def main(argv=None): """ Entry point for library-like use. """ try: logger.set_process_prefix() config.parse() if argv != None: backup_argv = sys.argv sys.argv = argv args = parse_args() if args.debug: logger.level(logging.DEBUG) device_manager = DevicesManager(args) if args.device: device, tester = device_manager.try_flash_specific(args) else: device, tester = device_manager.try_flash_model(args) if not args.notest: print("Testing " + str(device.name) + ".") tester.execute() if not args.nopoweroff: device.detach() if args.boot: device_manager.boot_device_to_mode(device, args) device_manager.release(device) if "backup_argv" in locals(): sys.argv = backup_argv return 0 except KeyboardInterrupt: print("Keyboard interrupt, stopping aft") logger.error("Keyboard interrupt, stopping aft.") sys.exit(0) except: _err = sys.exc_info() logger.error(str(_err[0]).split("'")[1] + ": " + str(_err[1])) raise finally: thread_handler.set_flag(thread_handler.RECORDERS_STOP) for thread in thread_handler.get_threads(): thread.join(5)
def _enter_mode(self, mode): """ Try to put the device into the specified mode. Args: mode (Dictionary): Dictionary that contains the mode specific information Returns: None Raises: aft.errors.AFTDeviceError if device fails to enter the mode or if keyboard emulator fails to connect """ # Sometimes booting to a mode fails. logger.info("Trying to enter " + mode["name"] + " mode up to " + str(self._RETRY_ATTEMPTS) + " times.") for _ in range(self._RETRY_ATTEMPTS): try: self._power_cycle() if self.kb_emulator: logger.info("Using " + type(self.kb_emulator).__name__ + " to send keyboard sequence " + mode["sequence"]) self.kb_emulator.send_keystrokes(mode["sequence"]) else: logger.warning( "No keyboard emulator defined for the device") ip_address = self._wait_for_responsive_ip() if ip_address: if self._verify_mode(mode["name"]): return else: logger.warning("Failed entering " + mode["name"] + " mode.") except KeyboardInterrupt: raise except: _err = sys.exc_info() logger.error(str(_err[0]).split("'")[1] + ": " + str(_err[1])) logger.critical("Unable to get the device in mode " + mode["name"]) raise errors.AFTDeviceError("Could not set the device in mode " + mode["name"])
def __init__(self, config): from devauto.rps.control import RPSControl from devauto.rps.base import RPSError self.RPSError = RPSError self.rpscontrol = RPSControl() try: self.rpscontrol.change_rps_model(config["netbooter_model"]) except RPSError as e: logger.error(e) logger.error("Wrong netbooter model specified, exiting") raise e self.cutter_channel = config["channel"]
def send_a_key(self, key, timeout=20): ''' HID keyboard message length is 8 bytes and format is: [modifier, reserved, Key1, Key2, Key3, Key4, Key6, Key7] So first byte is for modifier key and all bytes after third one are for normal keys. After sending a key stroke, empty message with zeroes has to be sent to stop the key being pressed. Messages are sent by writing to the emulated HID usb port in /dev/. US HID keyboard hex codes are used for translating keys. Args: key: A key to send, for example: "a", "z", "3", "F2", "ENTER" timeout: how long sending a key will be tried until quitting [s] ''' usb_message = bytearray(self.empty.encode()) # Initialize usb message hex_key, _modifier = self.key_to_hex(key) # Translate key to hex code # Override self.modifier if the key needs a specific one if _modifier: modifier = _modifier else: modifier = self.modifier usb_message[2] = hex_key usb_message[0] = modifier time = 0 while time < timeout: try: with open(self.emulator, self.write_mode) as emulator: emulator.write(usb_message.decode()) # Send the key emulator.write(self.empty) # Stop the key being pressed except IOError: logger.warning("Couldn't connect to host", "kb_emulator.log") time += 1 sleep(1) else: logger.info( "Sent key: " + key.ljust(5) + " hex code: " + format(hex_key, '#04x') + " modifier: " + format(modifier, '#04x'), "kb_emulator.log") return 0 msg = "Keyboard emulator couldn't connect to host" logger.error(msg, "kb_emulator.log") raise TimeoutError(msg)
def remote_execute(remote_ip, command, timeout=60, ignore_return_codes=None, user="******", connect_timeout=15): """ Execute a Bash command over ssh on a remote device with IP 'remote_ip'. Returns combines stdout and stderr if there are no errors. On error raises subprocess32 errors. """ ssh_args = [ "ssh", "-i", "".join([os.path.expanduser("~"), "/.ssh/id_rsa_testing_harness"]), "-o", "UserKnownHostsFile=/dev/null", "-o", "StrictHostKeyChecking=no", "-o", "BatchMode=yes", "-o", "LogLevel=ERROR", "-o", "ConnectTimeout=" + str(connect_timeout), user + "@" + str(remote_ip), _get_proxy_settings(), ] logger.info("Executing " + " ".join(command), filename="ssh.log") ret = "" try: ret = tools.local_execute(ssh_args + command, timeout, ignore_return_codes) except subprocess32.CalledProcessError as err: logger.error("Command raised exception: " + str(err), filename="ssh.log") logger.error("Output: " + str(err.output), filename="ssh.log") raise err return ret
def open_virt_file(): gpio_abs_path = "{0}/{1}/value".format(self._GPIOS_BASE_DIR, self._GPIO_PIN) if not os.path.isfile(gpio_abs_path): emsg = "GPIO file {0} is not found".format(gpio_abs_path) logger.error(emsg) raise GpioCutterError(emsg) fd = None try: fd = open(gpio_abs_path, 'w') except (OSError, IOError) as e: logger.error(e) emsg = "GPIO file {0} can not be opened".format(gpio_abs_path) logger.error(emsg) raise GpioCutterError("GPIO file can not be loaded") return fd
def open_virt_file(): gpio_abs_path = "{0}/{1}/value".format( self._GPIOS_BASE_DIR, self._GPIO_PIN ) if not os.path.isfile(gpio_abs_path): emsg = "GPIO file {0} is not found".format(gpio_abs_path) logger.error(emsg) raise GpioCutterError(emsg) fd = None try: fd = open(gpio_abs_path, 'w') except (OSError, IOError) as e: logger.error(e) emsg = "GPIO file {0} can not be opened".format(gpio_abs_path) logger.error(emsg) raise GpioCutterError("GPIO file can not be loaded") return fd
def try_flash_model(args, device_manager): ''' Reserve and flash a machine. By default it tries to flash 2 times with 2 different machines. If flashing fails machine will be blacklisted. Args: args: AFT arguments device_manager: Device manager object Returns: device, tester: Reserved machine and tester handles. ''' machine_attempt = 0 machine_retries = args.machine_retries while machine_attempt < machine_retries: machine_attempt += 1 device = device_manager.reserve() tester = Tester(device) if args.record: device.record_serial() if args.noflash: return device, tester flash_attempt = 0 flash_retries = args.flash_retries while flash_attempt < flash_retries: flash_attempt += 1 try: print("Flashing " + str(device.name) + ", attempt " + str(flash_attempt) + " of " + str(flash_retries) + ".") device.write_image(args.file_name) print("Flashing successful.") return device, tester except KeyboardInterrupt: raise except: _err = sys.exc_info() _err = str(_err[0]).split("'")[1] + ": " + str(_err[1]) logger.error(_err) print(_err) if (flash_retries - flash_attempt) == 0: msg = "Flashing failed " + str(flash_attempt) + " times" print(msg + ", blacklisting " + str(device.name)) logger.info(msg + ", blacklisting " + str(device.name)) common.blacklist_device(device.dev_id, device.name, msg) device_manager.release(device) if machine_attempt < machine_retries: print("Attempting flashing another machine") else: raise elif (flash_retries - flash_attempt) == 1: print("Flashing failed, trying again one more time") elif (flash_retries - flash_attempt) > 1: print("Flashing failed, trying again " + str(flash_retries - flash_attempt) + " more times")
def main(argv=None): """ Entry point for library-like use. """ try: logger.init_root_logger() logger.init_thread() config.parse() if argv != None: backup_argv = sys.argv sys.argv = argv args = parse_args() if args.debug: logger.level(logging.DEBUG) if args.configure: builder = TopologyBuilder(args) builder.build_topology() return 0 if args.check: results = device_config.check(args) logger.info(results[1]) print(results[1]) if results[0] == True: return 0 else: return 1 elif args.checkall: results = device_config.check_all(args) logger.info(results[1]) print(results[1]) if results[0] == True: logger.info("All tests passed") return 0 else: logger.info("There were failures") return 1 device_manager = DevicesManager(args) if args.blacklist: if not args.device: print("Device must be specified for blacklisting") return 1 device_manager.blacklist_device(args.device, args.reason) return 0 if args.unblacklist: if not args.device: print("Device must be specified for unblacklisting") return 1 device_manager.unblacklist_device(args.device) return 0 if args.blacklist_print: device_manager.blacklist_print() return 0 if args.recover_edisons: recover_edisons(device_manager, args.verbose) return 0 if not args.machine: print("Both machine and image must be specified") return 1 if not args.noflash: if not args.file_name: print("Both machine and image must be specified") return 1 if not os.path.isfile(args.file_name): print("Didn't find image: " + args.file_name) logger.error("Didn't find image: " + args.file_name) return 1 if args.device: device, tester = try_flash_specific(args, device_manager) else: device, tester = try_flash_model(args, device_manager) if not args.notest: print("Testing " + str(device.name) + ".") tester.execute() if not args.nopoweroff: device.detach() device_manager.release(device) if "backup_argv" in locals(): sys.argv = backup_argv return 0 except KeyboardInterrupt: print("Keyboard interrupt, stopping aft") logger.error("Keyboard interrupt, stopping aft.") sys.exit(0) except: _err = sys.exc_info() logger.error(str(_err[0]).split("'")[1] + ": " + str(_err[1])) raise finally: thread_handler.set_flag(thread_handler.RECORDERS_STOP) for thread in thread_handler.get_threads(): thread.join(5)
def _enter_service_mode(self): """ Enter service mode by booting support image over nfs Interrupts regular boot, and enters the necessary u-boot commands to boot the nfs based support image rather than the image stored on the SD-card Returns: None Raises: aft.errors.AFTDeviceError if the device failed to enter the service mode """ logger.info("Trying to enter service mode up to " + str(self._SERVICE_MODE_RETRY_ATTEMPTS) + " times.") for _ in range(self._SERVICE_MODE_RETRY_ATTEMPTS): try: self._power_cycle() stream = serial.Serial(self.parameters["serial_port"], self.parameters["serial_bauds"], timeout=0.01, xonxoff=True) counter = 100 # enter uboot console for _ in range(counter): serial_write(stream, " ", 0.1) # Load kernel image and device tree binary from usb serial_write( stream, "setenv bootargs 'console=ttyO0,115200n8, root=/dev/sda1 rootwait rootfstype=ext4 rw'", 1) serial_write(stream, "usb start", 5) serial_write( stream, "ext4load usb 0:1 0x81000000 /boot/vmlinuz-4.4.9-ti-r25", 10) serial_write( stream, "ext4load usb 0:1 0x80000000 /boot/dtbs/4.4.9-ti-r25/am335x-boneblack.dtb", 5) stream.close() self.dev_ip = self._wait_for_responsive_ip() if (self.dev_ip and self._verify_mode( self.parameters["service_mode"])): return else: logger.warning("Failed to enter service mode") except KeyboardInterrupt: raise except: _err = sys.exc_info() logger.error(str(_err[0]).split("'")[1] + ": " + str(_err[1])) raise errors.AFTDeviceError("Could not set the device in service mode")
def main(argv=None): """ Entry point for library-like use. """ try: logger.set_process_prefix() config.parse() if argv != None: backup_argv = sys.argv sys.argv = argv args = parse_args() if args.debug: logger.level(logging.DEBUG) device_manager = DevicesManager(args) device, tester = device_manager.try_flash_model(args) if args.emulateusb: device.boot_usb_test_mode() if not args.notest: if not args.emulateusb: device.boot_internal_test_mode() print("Testing " + str(device.name) + ".") tester.execute() if not args.nopoweroff: device.detach() if args.emulateusb: device_manager.stop_image_usb_emulation( device.leases_file_name) if not args.emulateusb: if args.boot == "test_mode": device.boot_internal_test_mode() elif args.boot == "service_mode": device.boot_usb_service_mode() device_manager.release(device) if "backup_argv" in locals(): sys.argv = backup_argv return 0 except KeyboardInterrupt: print("Keyboard interrupt, stopping aft") logger.error("Keyboard interrupt, stopping aft.") sys.exit(0) except: _err = sys.exc_info() logger.error(str(_err[0]).split("'")[1] + ": " + str(_err[1])) raise finally: thread_handler.set_flag(thread_handler.RECORDERS_STOP) for thread in thread_handler.get_threads(): thread.join(5)