| #!/usr/bin/env python3 |
| # |
| # Copyright 2018 - The Android Open Source Project |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| import os |
| from acts.controllers.fuchsia_lib.ssh import FuchsiaSSHError |
| |
| |
| def http_file_download_by_curl(fd, |
| url, |
| out_path='/tmp/', |
| curl_loc='/bin/curl', |
| remove_file_after_check=True, |
| timeout=3600, |
| limit_rate=None, |
| additional_args=None, |
| retry=3): |
| """Download http file by ssh curl. |
| |
| Args: |
| fd: Fuchsia Device Object. |
| url: The url that file to be downloaded from. |
| out_path: Optional. Where to download file to. |
| out_path is /tmp by default. |
| curl_loc: Location of curl binary on fd. |
| remove_file_after_check: Whether to remove the downloaded file after |
| check. |
| timeout: timeout for file download to complete. |
| limit_rate: download rate in bps. None, if do not apply rate limit. |
| additional_args: Any additional args for curl. |
| retry: the retry request times provided in curl command. |
| """ |
| file_directory, file_name = _generate_file_directory_and_file_name( |
| url, out_path) |
| file_path = os.path.join(file_directory, file_name) |
| curl_cmd = curl_loc |
| if limit_rate: |
| curl_cmd += f' --limit-rate {limit_rate}' |
| if retry: |
| curl_cmd += f' --retry {retry}' |
| if additional_args: |
| curl_cmd += f' {additional_args}' |
| curl_cmd += f' --url {url} > {file_path}' |
| |
| fd.log.info(f'Download {url} to {file_path} by ssh command {curl_cmd}') |
| try: |
| fd.ssh.run(curl_cmd, timeout_sec=timeout) |
| if _check_file_existence(fd, file_path): |
| fd.log.info(f'{url} is downloaded to {file_path} successfully') |
| return True |
| |
| fd.log.warning(f'Fail to download {url}') |
| return False |
| except FuchsiaSSHError as e: |
| fd.log.warning(f'Command "{curl_cmd}" failed with error {e}') |
| return False |
| except Exception as e: |
| fd.log.error(f'Download {url} failed with unexpected exception {e}') |
| return False |
| finally: |
| if remove_file_after_check: |
| fd.log.info(f'Remove the downloaded file {file_path}') |
| try: |
| fd.ssh.run(f'rm {file_path}') |
| except FuchsiaSSHError: |
| pass |
| |
| |
| def _generate_file_directory_and_file_name(url, out_path): |
| """Splits the file from the url and specifies the appropriate location of |
| where to store the downloaded file. |
| |
| Args: |
| url: A url to the file that is going to be downloaded. |
| out_path: The location of where to store the file that is downloaded. |
| |
| Returns: |
| file_directory: The directory of where to store the downloaded file. |
| file_name: The name of the file that is being downloaded. |
| """ |
| file_name = url.split('/')[-1] |
| if not out_path: |
| file_directory = '/tmp/' |
| elif not out_path.endswith('/'): |
| file_directory, file_name = os.path.split(out_path) |
| else: |
| file_directory = out_path |
| return file_directory, file_name |
| |
| |
| def _check_file_existence(fd, file_path): |
| """Check file existence by file_path. If expected_file_size |
| is provided, then also check if the file meet the file size requirement. |
| |
| Args: |
| fd: A fuchsia device |
| file_path: Where to store the file on the fuchsia device. |
| """ |
| try: |
| result = fd.ssh.run(f'ls -al "{file_path}"') |
| fd.log.debug(f'File {file_path} exists.') |
| return True |
| except FuchsiaSSHError as e: |
| if 'No such file or directory' in e.result.stderr: |
| fd.log.debug(f'File {file_path} does not exist.') |
| return False |
| raise e |