blob: 9c3ec96acc0996da942a263c1711abeea10e83d6 [file] [log] [blame]
# Copyright 2017 Google Inc.
#
# 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.
from __future__ import absolute_import
import tempfile
import unittest
import fixpath # This has to be the first local import.
import gsutil
import app_info
from actions.action_error import ProcessError
import mock
from six.moves import range
TEST_APP_INFO = app_info.AppInfo('test_intent', 'test_package_chrome',
'test_name', 'test_version', None)
REPORT_DATA = {'report_folder': 'report/folder',
'platform': 'Android',
'report_file': 'test_1',
'description': 'description',
'start_time': '2019-01-09T09:12:21.111',
'stop_time': '2019-01-09T09:12:22.111'}
class TestGsutilDownload(unittest.TestCase):
def setUp(self):
super(TestGsutilDownload, self).setUp()
self.temp_mkdir_mock = mock.patch('tempfile.mkdtemp', autospec=True).start()
self.temp_mkdir_mock.return_value = '/tmp/temp_folder'
@mock.patch('subprocess.check_output', autospec=True)
@mock.patch('device_info.GetAndroidCPUInformation', autospec=True)
@mock.patch('device_info.GetAndroidAPILevel', autospec=True)
@mock.patch('device_info.GetAndroidBuildType', autospec=True)
@mock.patch('subprocess.check_call', autospec=True)
def testDownloadAndroidApp(self, mock_check_call, mock_device_info_build_type,
mock_device_info_api, mock_device_info_cpu,
mock_check_output):
test_version = '12.34.56.78'
expected_string = '%s/%s/\n' % (gsutil._GSUTIL_BUCKET_PREFIX,
test_version)
mock_check_output.return_value = expected_string
mock_device_info_cpu.return_value = 'arm'
mock_device_info_api.side_effect = [
19,
23,
25,
20,
26,
22,
]
mock_device_info_build_type.side_effect = [
'user',
'userdebug',
]
test_app_path_chrome = ('gs://chrome-signed/android-B0urB0N'
'/12.34.56.78/arm/ChromeBeta.apk')
test_app_path_chrome_modern = ('gs://chrome-signed/android-B0urB0N'
'/12.34.56.78/arm/ChromeModernBeta.apk')
test_app_path_monochrome = ('gs://chrome-signed/android-B0urB0N'
'/12.34.56.78/arm/MonochromeBeta.apk')
test_app_path_webview = ('gs://chrome-signed/android-B0urB0N'
'/12.34.56.78/arm/AndroidWebview.apk')
test_app_path_webview_unsigned = ('gs://chrome-unsigned/android-B0urB0N'
'/12.34.56.78/arm/AndroidWebview.apk')
tmp_dir = tempfile.mkdtemp()
channel = 'Beta'
device_id = 'ZX1G223BPN'
gsutil.DownloadAndroidApp(test_version, channel, device_id, False)
self.assertEqual(mock_check_call.call_args_list[0][0][0],
['gsutil', 'cp', test_app_path_chrome, tmp_dir])
gsutil.DownloadAndroidApp(test_version, channel, device_id, False)
self.assertEqual(mock_check_call.call_args_list[1][0][0],
['gsutil', 'cp', test_app_path_chrome_modern, tmp_dir])
gsutil.DownloadAndroidApp(test_version, channel, device_id, False)
self.assertEqual(mock_check_call.call_args_list[2][0][0],
['gsutil', 'cp', test_app_path_monochrome, tmp_dir])
gsutil.DownloadAndroidApp(test_version, channel, device_id, True)
self.assertEqual(mock_check_call.call_args_list[3][0][0],
['gsutil', 'cp', test_app_path_webview, tmp_dir])
gsutil.DownloadAndroidApp(test_version, channel, device_id, True)
self.assertEqual(mock_check_call.call_args_list[4][0][0],
['gsutil', 'cp', test_app_path_monochrome, tmp_dir])
gsutil.DownloadAndroidApp(test_version, channel, device_id, True)
self.assertEqual(mock_check_call.call_args_list[5][0][0],
['gsutil', 'cp', test_app_path_webview_unsigned, tmp_dir])
@mock.patch('subprocess.check_output', autospec=True)
@mock.patch('subprocess.call', autospec=True)
@mock.patch('logging.error', autospec=True)
def testGetLatestChromeVersion(self, mock_log, mock_subprocess_call,
mock_subprocess_check_output):
test_ver = '1.1.1.%s/'
test_values = []
for i in range(2, 7):
test_str = 'gs://chrome-signed/android-B0urB0N/%s' % (test_ver % i)
test_values.append(test_str)
# Manually add at end to make sure sorting works.
test_str = 'gs://chrome-signed/android-B0urB0N/%s' % (test_ver % 1)
test_values.append(test_str)
mock_subprocess_check_output.return_value = '\n'.join(test_values)
mock_subprocess_call.return_value = 0
self.assertEqual(
'1.1.1.6',
gsutil.GetLatestChromeVersion(
'gs://chrome-signed/android-B0urB0N', 'arm_64',
'AndroidWebview.apk'))
mock_subprocess_check_output.return_value = 'unmatching string'
mock_subprocess_call.return_value = 0
self.assertEqual(
'0.0.0.0',
gsutil.GetLatestChromeVersion(
'gs://chrome-signed/android-B0urB0N', 'arm_64',
'AndroidWebview.apk'))
self.assertTrue(mock_log.called)
mock_subprocess_check_output.return_value = '\n'.join(test_values)
mock_subprocess_call.return_value = 1
self.assertEqual(
'0.0.0.0',
gsutil.GetLatestChromeVersion(
'gs://chrome-signed/android-B0urB0N', 'arm_64',
'AndroidWebview.apk'))
def testGetGsutilUploadPath(self):
name = 'report_name'
result = gsutil._GetGsutilUploadPath(name, TEST_APP_INFO,
'Android')
self.assertEqual(
result, 'gs://franky-reports/android/test_version_test_name/%s' % name)
webview_app_info = app_info.AppInfo('test_intent', 'test_package',
'test_name', 'test_version', 'webview')
result = gsutil._GetGsutilUploadPath(name, webview_app_info,
'Android')
self.assertEqual(
result,
'gs://franky-reports/android/webview/test_version_test_name/%s' % name)
@mock.patch('subprocess.check_output', autospec=True)
@mock.patch('gsutil._GetGsutilUploadPath', autospec=True)
def testCopyHTMLReportToCloudStorage(self, mock_path, mock_subprocess):
mock_path.return_value = 'some_path'
report_name = 'test_file_name'
gsutil.CopyHTMLReportToCloudStorage(report_name, 'some_path')
result_cmd = [
'gsutil', 'cp', '-v', '-z', 'html', '-a', 'public-read', report_name,
'some_path'
]
self.assertEqual(mock_subprocess.call_args_list[0][0][0], result_cmd)
@mock.patch('tempfile.NamedTemporaryFile', autospec=True)
@mock.patch('gsutil.GetPackagePathOnDevice', autospec=True)
@mock.patch('utilities.util.RunADBProcess', autospec=True)
def testPullAppFoundPackage(self, mock_adb_call, mock_get_package, mock_tmp):
tmp_file = '/tmp/temp_folder/temp_file'
mock_adb_call.return_value = ''
mock_tmp.return_value.name = tmp_file
test_output = gsutil.PullApp('com.sample.test_package',
'device_id')
self.assertIn(tmp_file, test_output)
self.assertTrue(mock_get_package.called)
@mock.patch('utilities.util.RunADBProcess', autospec=True)
def testGetPackagePathOnDeviceNotFoundPackage(self, mock_adb_call):
not_found_package = 'com.not.found.package'
msg = 'Not found any apk for package %s!' % not_found_package
mock_adb_call.return_value = ''
try:
gsutil.GetPackagePathOnDevice(not_found_package, 'device_id')
raise Exception('"Package not found" exception not occurred!')
except ProcessError as expected:
self.assertEqual(expected.message, msg)
@mock.patch('utilities.util.RunADBProcess', autospec=True)
def testGetPackagePathOnDeviceFoundPackage(self, mock_adb_call):
package = 'com.found.package'
package_path = '/data/app/%s-cache/base.apk' % package
mock_adb_call.return_value = 'package:%s' % package_path
path = gsutil.GetPackagePathOnDevice(package, 'device_id')
self.assertEqual('/data/app/%s-cache/base.apk' % package, path)
@mock.patch('utilities.util.RunADBProcess', autospec=True)
def testGetPackagePathOnDeviceFoundSystemPackage(self, mock_adb_call):
package = 'com.found.package'
package_path = '/system/priv-app/SysPackage/SysPackage.apk'
mock_adb_call.return_value = 'package:%s' % package_path
path = gsutil.GetPackagePathOnDevice(package, 'device_id')
self.assertEqual('/system/priv-app/SysPackage/SysPackage.apk', path)
@mock.patch('utilities.util.RunADBProcess', autospec=True)
def testGetPackagePathOnDeviceNotFoundBaseApk(self, mock_adb_call):
package = 'com.found.package'
package_path = '\n'.join([
'/data/app/%s-cache/not_base.apk' % package,
'/data/app/%s-cache/additional_base.apk' % package
])
mock_adb_call.return_value = 'package:%s' % package_path
msg = 'Not found %s apk for package %s!' % ('base.apk', package)
try:
gsutil.GetPackagePathOnDevice(package, 'device_id')
raise Exception('"base.apk not found" exception not occurred!')
except ProcessError as expected:
self.assertEqual(expected.message, msg)
@mock.patch('utilities.util.RunADBProcess', autospec=True)
@mock.patch('gsutil.GetPackagePathOnDevice', autospec=True)
@mock.patch('gsutil._CopyFileOnSdcard', autospec=True)
def testPullApp(self, mock_copy_on_sdcard, mock_get_package_path,
mock_adb_call):
mock_adb_call.return_value = ''
mock_get_package_path.return_value = '/data/app/package_name'
gsutil.PullApp('package-1', 'device_id')
self.assertEqual(0, len(mock_copy_on_sdcard.mock_calls))
self.assertEqual(1, len(mock_adb_call.mock_calls))
@mock.patch('utilities.util.RunADBProcess', autospec=True)
@mock.patch('gsutil.GetPackagePathOnDevice', autospec=True)
@mock.patch('gsutil._CopyFileOnSdcard', autospec=True)
def testPullAppNotAllowToCopyData(self, mock_copy_on_sdcard,
mock_get_package_path, mock_adb_call):
mock_adb_call.return_value = ''.join([
'adb: error: remote object ',
'\'/data/app/package/base.apk\' does not exist'
])
mock_get_package_path.return_value = '/data/app/package_name'
gsutil.PullApp('package-1', 'device_id')
self.assertEqual(1, len(mock_copy_on_sdcard.mock_calls))
self.assertEqual(3, len(mock_adb_call.mock_calls))
@mock.patch('utilities.util.RunADBProcess', autospec=True)
def testCopyFileOnSdcard(self, mock_adb_call):
mock_adb_call.return_value = ''
gsutil._CopyFileOnSdcard('/data/app/package-1/base.apk',
'device_id')
self.assertEqual(2, len(mock_adb_call.mock_calls))
@mock.patch('utilities.util.RunADBProcess', autospec=True)
def testCopyFileOnSdcardOnDeviceWithoutSdcard(self, mock_adb_call):
mock_adb_call.return_value = 'No /sdcard/ on device'
try:
gsutil._CopyFileOnSdcard('/data/app/package-1/base.apk',
'device_id')
raise Exception('"Not sdcard on the device!" exception not occurred!')
except ProcessError as expected:
self.assertEqual(
expected.message, ''.join([
'Can not copy file /data/app/package-1/base.apk ',
'to /sdcard/ (no sdcard on device_id!'
]))
self.assertEqual(1, len(mock_adb_call.mock_calls))
@mock.patch('subprocess.check_call', autospec=True)
@mock.patch('gsutil._GetGsutilUploadPath', autospec=True)
def testUploadFolder(self, mock_path, mock_check_call):
mock_path.return_value = 'some_path'
report_data = REPORT_DATA
report_data['copy_to_cloud_storage'] = True
report_data['webview_provider_package'] = 'N/A'
gsutil.UploadFolder('report/folder', 'gs_path')
result_cmd = ['gsutil', 'cp', '-v', '-a', 'public-read',
'-r', 'report/folder', 'gs_path']
self.assertEqual(mock_check_call.call_args_list[0][0][0], result_cmd)
@mock.patch('tarfile.open', autospec=True)
@mock.patch('zipfile.ZipFile', autospec=True)
@mock.patch('subprocess.check_output', autospec=True)
@mock.patch('subprocess.check_call', autospec=True)
def testDownloadIOSApp(self, mock_check_call, mock_check_output, mock_tar,
mock_zip):
test_version = '12.34.56.78'
expected_string = '%s/%s/\n' % (gsutil._IOS_GSUTIL_BUCKET_PREFIX,
test_version)
mock_check_output.return_value = expected_string
test_app_path_chrome = ('gs://bling-archive'
'/12.34.56.78/*/*/*/*/beta.tar.gz')
tmp_dir = tempfile.mkdtemp()
mock_tar.return_value.name = 'beta.tar.gz'
mock_zip.return_value.name = 'beta.ipa'
channel = 'Beta'
gsutil.DownloadIOSApp(test_version, channel)
self.assertEqual(mock_check_call.call_args_list[0][0][0],
['gsutil', 'cp', test_app_path_chrome, tmp_dir])
@mock.patch('subprocess.check_output', autospec=True)
def testGetLatestIOSChromeVersion(self, mock_subprocess_check_output):
test_ver = '1.1.1.%s/'
test_values = []
for i in range(2, 7):
test_str = 'gs://bling-archive/%s' % (test_ver % i)
test_values.append(test_str)
# Manually add at end to make sure sorting works.
test_str = 'gs://bling-archive/%s' % (test_ver % 1)
test_values.append(test_str)
mock_subprocess_check_output.return_value = '\n'.join(test_values)
self.assertEqual(
'1.1.1.6',
gsutil.GetLatestIOSChromeVersion(channel='Canary'))
if __name__ == '__main__':
unittest.main()