• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2#
3#   Copyright 2018 - The Android Open Source Project
4#
5#   Licensed under the Apache License, Version 2.0 (the "License");
6#   you may not use this file except in compliance with the License.
7#   You may obtain a copy of the License at
8#
9#       http://www.apache.org/licenses/LICENSE-2.0
10#
11#   Unless required by applicable law or agreed to in writing, software
12#   distributed under the License is distributed on an "AS IS" BASIS,
13#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14#   See the License for the specific language governing permissions and
15#   limitations under the License.
16
17import os
18
19from acts.libs.proc.job import Error
20
21
22def http_file_download_by_curl(fd,
23                               url,
24                               out_path='/tmp/',
25                               curl_loc='/bin/curl',
26                               remove_file_after_check=True,
27                               timeout=3600,
28                               limit_rate=None,
29                               additional_args=None,
30                               retry=3):
31    """Download http file by ssh curl.
32
33    Args:
34        fd: Fuchsia Device Object.
35        url: The url that file to be downloaded from.
36        out_path: Optional. Where to download file to.
37            out_path is /tmp by default.
38        curl_loc: Location of curl binary on fd.
39        remove_file_after_check: Whether to remove the downloaded file after
40            check.
41        timeout: timeout for file download to complete.
42        limit_rate: download rate in bps. None, if do not apply rate limit.
43        additional_args: Any additional args for curl.
44        retry: the retry request times provided in curl command.
45    """
46    file_directory, file_name = _generate_file_directory_and_file_name(
47        url, out_path)
48    file_path = os.path.join(file_directory, file_name)
49    curl_cmd = curl_loc
50    if limit_rate:
51        curl_cmd += ' --limit-rate %s' % limit_rate
52    if retry:
53        curl_cmd += ' --retry %s' % retry
54    if additional_args:
55        curl_cmd += ' %s' % additional_args
56    curl_cmd += ' --url %s > %s' % (url, file_path)
57    try:
58        fd.log.info(
59            'Download %s to %s by ssh command %s' % (url, file_path, curl_cmd))
60
61        status = fd.send_command_ssh(curl_cmd, timeout=timeout)
62        if isinstance(status, Error):
63            status = status.result
64        if not status.stderr:
65            if int(status.exit_status) != 0:
66                fd.log.warning('Curl command: "%s" failed with error %s' %
67                               (curl_cmd, status.exit_status))
68                return False
69
70            if _check_file_existence(fd, file_path):
71                fd.log.info(
72                    '%s is downloaded to %s successfully' % (url, file_path))
73                return True
74        else:
75            fd.log.warning('Fail to download %s' % url)
76            return False
77    except Exception as e:
78        fd.log.warning('Download %s failed with exception %s' % (url, e))
79        return False
80    finally:
81        if remove_file_after_check:
82            fd.log.info('Remove the downloaded file %s' % file_path)
83            fd.send_command_ssh('rm %s' % file_path)
84
85
86def _generate_file_directory_and_file_name(url, out_path):
87    """Splits the file from the url and specifies the appropriate location of
88       where to store the downloaded file.
89
90    Args:
91        url: A url to the file that is going to be downloaded.
92        out_path: The location of where to store the file that is downloaded.
93
94    Returns:
95        file_directory: The directory of where to store the downloaded file.
96        file_name: The name of the file that is being downloaded.
97    """
98    file_name = url.split('/')[-1]
99    if not out_path:
100        file_directory = '/tmp/'
101    elif not out_path.endswith('/'):
102        file_directory, file_name = os.path.split(out_path)
103    else:
104        file_directory = out_path
105    return file_directory, file_name
106
107
108def _check_file_existence(fd, file_path):
109    """Check file existence by file_path. If expected_file_size
110       is provided, then also check if the file meet the file size requirement.
111
112    Args:
113        fd: A fuchsia device
114        file_path: Where to store the file on the fuchsia device.
115    """
116    out = fd.send_command_ssh('ls -al "%s"' % file_path)
117    if isinstance(out, Error):
118        out = out.result
119    if 'No such file or directory' in out.stdout:
120        fd.log.debug('File %s does not exist.' % file_path)
121        return False
122    else:
123        fd.log.debug('File %s exists.' % file_path)
124        return True
125