1# Copyright 2018 - The Android Open Source Project 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14"""Tests for remote_image_local_instance.""" 15 16import unittest 17from collections import namedtuple 18import os 19import mock 20 21from acloud import errors 22from acloud.create import create_common 23from acloud.create import remote_image_local_instance 24from acloud.internal.lib import android_build_client 25from acloud.internal.lib import auth 26from acloud.internal.lib import driver_test_lib 27from acloud.internal.lib import utils 28from acloud.setup import setup_common 29 30 31# pylint: disable=invalid-name, protected-access 32class RemoteImageLocalInstanceTest(driver_test_lib.BaseDriverTest): 33 """Test remote_image_local_instance methods.""" 34 35 def setUp(self): 36 """Initialize remote_image_local_instance.""" 37 super(RemoteImageLocalInstanceTest, self).setUp() 38 self.build_client = mock.MagicMock() 39 self.Patch( 40 android_build_client, 41 "AndroidBuildClient", 42 return_value=self.build_client) 43 self.Patch(auth, "CreateCredentials", return_value=mock.MagicMock()) 44 self.RemoteImageLocalInstance = remote_image_local_instance.RemoteImageLocalInstance() 45 self._fake_remote_image = {"build_target" : "aosp_cf_x86_phone-userdebug", 46 "build_id": "1234"} 47 self._extract_path = "/tmp/acloud_image_artifacts/1234" 48 49 @mock.patch.object(remote_image_local_instance, "DownloadAndProcessImageFiles") 50 def testGetImageArtifactsPath(self, mock_proc): 51 """Test get image artifacts path.""" 52 avd_spec = mock.MagicMock() 53 # raise errors.NoCuttlefishCommonInstalled 54 self.Patch(setup_common, "PackageInstalled", return_value=False) 55 self.assertRaises(errors.NoCuttlefishCommonInstalled, 56 self.RemoteImageLocalInstance.GetImageArtifactsPath, 57 avd_spec) 58 59 # Valid _DownloadAndProcessImageFiles run. 60 self.Patch(setup_common, "PackageInstalled", return_value=True) 61 self.Patch(remote_image_local_instance, 62 "ConfirmDownloadRemoteImageDir", return_value="/tmp") 63 self.Patch(os.path, "exists", return_value=True) 64 self.RemoteImageLocalInstance.GetImageArtifactsPath(avd_spec) 65 mock_proc.assert_called_once_with(avd_spec) 66 67 @mock.patch.object(create_common, "DownloadRemoteArtifact") 68 def testDownloadAndProcessImageFiles(self, mock_download): 69 """Test process remote cuttlefish image.""" 70 avd_spec = mock.MagicMock() 71 avd_spec.cfg = mock.MagicMock() 72 avd_spec.remote_image = self._fake_remote_image 73 avd_spec.image_download_dir = "/tmp" 74 self.Patch(os.path, "exists", return_value=False) 75 self.Patch(os, "makedirs") 76 remote_image_local_instance.DownloadAndProcessImageFiles(avd_spec) 77 build_id = "1234" 78 build_target = "aosp_cf_x86_phone-userdebug" 79 checkfile1 = "aosp_cf_x86_phone-img-1234.zip" 80 checkfile2 = "cvd-host_package.tar.gz" 81 82 # To validate DownloadArtifact runs twice. 83 self.assertEqual(mock_download.call_count, 2) 84 85 # To validate DownloadArtifact arguments correct. 86 mock_download.assert_has_calls([ 87 mock.call(avd_spec.cfg, build_target, build_id, checkfile1, 88 self._extract_path, decompress=True), 89 mock.call(avd_spec.cfg, build_target, build_id, checkfile2, 90 self._extract_path, decompress=True)], any_order=True) 91 92 def testConfirmDownloadRemoteImageDir(self): 93 """Test confirm download remote image dir""" 94 self.Patch(os.path, "exists", return_value=True) 95 self.Patch(os, "makedirs") 96 # Default minimum avail space should be more than 10G 97 # then return download_dir directly. 98 self.Patch(os, "statvfs", return_value=namedtuple( 99 "statvfs", "f_bavail, f_bsize")(11, 1073741824)) 100 download_dir = "/tmp" 101 self.assertEqual( 102 remote_image_local_instance.ConfirmDownloadRemoteImageDir( 103 download_dir), "/tmp") 104 105 # Test when insuficient disk space and input 'q' to exit. 106 self.Patch(os, "statvfs", return_value=namedtuple( 107 "statvfs", "f_bavail, f_bsize")(9, 1073741824)) 108 self.Patch(utils, "InteractWithQuestion", return_value="q") 109 self.assertRaises(SystemExit, 110 remote_image_local_instance.ConfirmDownloadRemoteImageDir, 111 download_dir) 112 113 # If avail space detect as 9GB, and 2nd input 7GB both less than 10GB 114 # 3rd input over 10GB, so return path should be "/tmp3". 115 self.Patch(os, "statvfs", side_effect=[ 116 namedtuple("statvfs", "f_bavail, f_bsize")(9, 1073741824), 117 namedtuple("statvfs", "f_bavail, f_bsize")(7, 1073741824), 118 namedtuple("statvfs", "f_bavail, f_bsize")(11, 1073741824)]) 119 self.Patch(utils, "InteractWithQuestion", side_effect=["/tmp2", 120 "/tmp3"]) 121 self.assertEqual( 122 remote_image_local_instance.ConfirmDownloadRemoteImageDir( 123 download_dir), "/tmp3") 124 125 # Test when path not exist, define --image-download-dir 126 # enter anything else to exit out. 127 download_dir = "/image_download_dir1" 128 self.Patch(os.path, "exists", return_value=False) 129 self.Patch(utils, "InteractWithQuestion", return_value="") 130 self.assertRaises(SystemExit, 131 remote_image_local_instance.ConfirmDownloadRemoteImageDir, 132 download_dir) 133 134 # Test using --image-dowload-dir and makedirs. 135 # enter 'y' to create it. 136 self.Patch(utils, "InteractWithQuestion", return_value="y") 137 self.Patch(os, "statvfs", return_value=namedtuple( 138 "statvfs", "f_bavail, f_bsize")(10, 1073741824)) 139 self.assertEqual( 140 remote_image_local_instance.ConfirmDownloadRemoteImageDir( 141 download_dir), "/image_download_dir1") 142 143 # Test when 1st check fails for insufficient disk space, user inputs an 144 # alternate dir but it doesn't exist and the user choose to exit. 145 self.Patch(os, "statvfs", side_effect=[ 146 namedtuple("statvfs", "f_bavail, f_bsize")(9, 1073741824), 147 namedtuple("statvfs", "f_bavail, f_bsize")(11, 1073741824)]) 148 self.Patch(os.path, "exists", side_effect=[True, False]) 149 self.Patch(utils, "InteractWithQuestion", 150 side_effect=["~/nopath", "not_y"]) 151 self.assertRaises( 152 SystemExit, 153 remote_image_local_instance.ConfirmDownloadRemoteImageDir, 154 download_dir) 155 156 # Test when 1st check fails for insufficient disk space, user inputs an 157 # alternate dir but it doesn't exist and they request to create it. 158 self.Patch(os, "statvfs", side_effect=[ 159 namedtuple("statvfs", "f_bavail, f_bsize")(9, 1073741824), 160 namedtuple("statvfs", "f_bavail, f_bsize")(10, 1073741824)]) 161 self.Patch(os.path, "exists", side_effect=[True, False]) 162 self.Patch(utils, "InteractWithQuestion", side_effect=["~/nopath", "y"]) 163 self.assertEqual( 164 remote_image_local_instance.ConfirmDownloadRemoteImageDir( 165 download_dir), os.path.expanduser("~/nopath")) 166 167 168if __name__ == "__main__": 169 unittest.main() 170