def join_command(cmd): """ Shell escape the command for BgJob. grmbl. @param cmd: Command list. """ result = [] for arg in cmd: arg = '"%s"' % utils.sh_escape(arg) result += [arg] return ' '.join(result)
def git_cmd(self, cmd, ignore_status=False): ''' Wraps git commands. @param cmd: Command to be executed. @param ignore_status: Whether we should supress error.CmdError exceptions if the command did return exit code !=0 (True), or not supress them (False). ''' os.chdir(self.destination_dir) return utils.run(r"%s %s" % (self.cmd, utils.sh_escape(cmd)), ignore_status=ignore_status)
def run_gsctool_cmd_with_password(self, password, cmd, name, expect_error): """Run a gsctool command and input the password Args: password: The cr50 password string cmd: The gsctool command name: The name to give the job expect_error: True if the command should fail """ set_pwd_cmd = utils.sh_escape(cmd) full_ssh_command = '%s "%s"' % (self.host.ssh_command(options='-tt'), set_pwd_cmd) stdout = StringIO.StringIO() # Start running the gsctool Command in the background. gsctool_job = utils.BgJob(full_ssh_command, nickname='%s_with_password' % name, stdout_tee=stdout, stderr_tee=utils.TEE_TO_LOGS, stdin=subprocess.PIPE) if gsctool_job == None: raise error.TestFail('could not start gsctool command %r', cmd) try: # Wait for enter prompt gsctool_job.process_output() logging.info(stdout.getvalue().strip()) # Enter the password gsctool_job.sp.stdin.write(password + '\n') # Wait for re-enter prompt gsctool_job.process_output() logging.info(stdout.getvalue().strip()) # Re-enter the password gsctool_job.sp.stdin.write(password + '\n') time.sleep(self.cr50.CONSERVATIVE_CCD_WAIT) gsctool_job.process_output() finally: exit_status = utils.nuke_subprocess(gsctool_job.sp) output = stdout.getvalue().strip() logging.info('%s stdout: %s', name, output) logging.info('%s exit status: %s', name, exit_status) if exit_status: message = ('gsctool %s failed using %r: %s %s' % (name, password, exit_status, output)) if expect_error: logging.info(message) else: raise error.TestFail(message) elif expect_error: raise error.TestFail('%s with %r did not fail when expected' % (name, password))
def attach_run(self, command, bash=True): """Attach to a given container and run the given command. @param command: Command to run in the container. @param bash: Run the command through bash -c "command". This allows pipes to be used in command. Default is set to True. @return: The output of the command. @raise error.CmdError: If container does not exist, or not running. """ cmd = 'sudo lxc-attach -P %s -n %s' % (self.container_path, self.name) if bash and not command.startswith('bash -c'): command = 'bash -c "%s"' % utils.sh_escape(command) cmd += ' -- %s' % command # TODO(dshi): crbug.com/459344 Set sudo to default to False when test # container can be unprivileged container. return utils.run(cmd)
def ccd_open_from_ap(self): """Start the open process and press the power button.""" self._ccd_open_last_len = 0 self._ccd_open_stdout = StringIO.StringIO() ccd_open_cmd = utils.sh_escape('gsctool -a -o') full_ssh_cmd = '%s "%s"' % (self.host.ssh_command(options='-tt'), ccd_open_cmd) # Start running the Cr50 Open process in the background. self._ccd_open_job = utils.BgJob(full_ssh_cmd, nickname='ccd_open', stdout_tee=self._ccd_open_stdout, stderr_tee=utils.TEE_TO_LOGS) if self._ccd_open_job == None: raise error.TestFail('could not start ccd open') try: # Wait for the first gsctool power button prompt before starting the # open process. logging.info(self._get_ccd_open_output()) # Cr50 starts out by requesting 5 quick presses then 4 longer # power button presses. Run the quick presses without looking at the # command output, because getting the output can take some time. For # the presses that require a 1 minute wait check the output between # presses, so we can catch errors # # run quick presses for 30 seconds. It may take a couple of seconds # for open to start. 10 seconds should be enough. 30 is just used # because it will definitely be enough, and this process takes 300 # seconds, so doing quick presses for 30 seconds won't matter. end_time = time.time() + 30 while time.time() < end_time: self.servo.power_short_press() logging.info('short int power button press') time.sleep(self.PP_SHORT_INTERVAL) # Poll the output and press the power button for the longer presses. utils.wait_for_value(self._check_open_and_press_power_button, expected_value=True, timeout_sec=self.cr50.PP_LONG) except Exception, e: logging.info(e) raise
def get_recording_params(self): """ Get recording parameters from media profiles """ xml_content = utils.system_output([ 'android-sh', '-c', 'cat "%s"' % utils.sh_escape(self.media_profiles_path) ]) root = xml.etree.ElementTree.fromstring(xml_content) recording_params = Set() for camcorder_profiles in root.findall('CamcorderProfiles'): for encoder_profile in camcorder_profiles.findall( 'EncoderProfile'): video = encoder_profile.find('Video') recording_params.add( '%s:%s:%s:%s' % (camcorder_profiles.get('cameraId'), video.get('width'), video.get('height'), video.get('frameRate'))) return '--recording_params=' + ','.join(recording_params)
def run(self, command, timeout=3600, ignore_status=False, stdout_tee=utils.TEE_TO_LOGS, stderr_tee=utils.TEE_TO_LOGS, connect_timeout=30, ssh_failure_retry_ok=False, options='', stdin=None, verbose=True, args=()): """Run a command on the servo host. Extends method `run` in SSHHost. If the servo host is a remote device, it will call `run` in SSHost without changing anything. If the servo host is 'localhost', it will call utils.system_output. @param command: The command line string. @param timeout: Time limit in seconds before attempting to kill the running process. The run() function will take a few seconds longer than 'timeout' to complete if it has to kill the process. @param ignore_status: Do not raise an exception, no matter what the exit code of the command is. @param stdout_tee/stderr_tee: Where to tee the stdout/stderr. @param connect_timeout: SSH connection timeout (in seconds) Ignored if host is 'localhost'. @param options: String with additional ssh command options Ignored if host is 'localhost'. @param ssh_failure_retry_ok: when True and ssh connection failure is suspected, OK to retry command (but not compulsory, and likely not needed here) @param stdin: Stdin to pass (a string) to the executed command. @param verbose: Log the commands. @param args: Sequence of strings to pass as arguments to command by quoting them in " and escaping their contents if necessary. @returns: A utils.CmdResult object. @raises AutoservRunError if the command failed. @raises AutoservSSHTimeout SSH connection has timed out. Only applies when servo host is not 'localhost'. """ run_args = { 'command': command, 'timeout': timeout, 'ignore_status': ignore_status, 'stdout_tee': stdout_tee, 'stderr_tee': stderr_tee, 'stdin': stdin, 'verbose': verbose, 'args': args } if self.is_localhost(): if self._sudo_required: run_args['command'] = 'sudo -n sh -c "%s"' % utils.sh_escape( command) try: return utils.run(**run_args) except error.CmdError as e: logging.error(e) raise error.AutoservRunError('command execution error', e.result_obj) else: run_args['connect_timeout'] = connect_timeout run_args['options'] = options return super(ServoHost, self).run(**run_args)
def close(self): """Cleanup after we're done.""" for tmp_dir in self.tmp_dirs: self.run('rm -rf "%s"' % (utils.sh_escape(tmp_dir)), ignore_status=True)