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 subprocess 20 21from unittest import mock 22 23from acloud import errors 24from acloud.create import remote_image_local_instance 25from acloud.internal.lib import android_build_client 26from acloud.internal.lib import auth 27from acloud.internal.lib import driver_test_lib 28from acloud.internal.lib import utils 29from acloud.setup import setup_common 30 31 32# pylint: disable=invalid-name, protected-access 33class RemoteImageLocalInstanceTest(driver_test_lib.BaseDriverTest): 34 """Test remote_image_local_instance methods.""" 35 36 def setUp(self): 37 """Initialize remote_image_local_instance.""" 38 super().setUp() 39 self.build_client = mock.MagicMock() 40 self.Patch( 41 android_build_client, 42 "AndroidBuildClient", 43 return_value=self.build_client) 44 self.Patch(auth, "CreateCredentials", return_value=mock.MagicMock()) 45 self.RemoteImageLocalInstance = remote_image_local_instance.RemoteImageLocalInstance() 46 self._fake_remote_image = {"build_target" : "aosp_cf_x86_phone-userdebug", 47 "build_id": "1234", 48 "branch": "aosp_master"} 49 self._extract_path = "/tmp/acloud_image_artifacts/1234" 50 51 @mock.patch.object(remote_image_local_instance, "DownloadAndProcessImageFiles") 52 def testGetImageArtifactsPath(self, mock_proc): 53 """Test get image artifacts path.""" 54 mock_proc.return_value = "/unit/test" 55 avd_spec = mock.MagicMock() 56 # raise errors.NoCuttlefishCommonInstalled 57 self.Patch(setup_common, "PackageInstalled", return_value=False) 58 self.assertRaises(errors.NoCuttlefishCommonInstalled, 59 self.RemoteImageLocalInstance.GetImageArtifactsPath, 60 avd_spec) 61 62 # Valid _DownloadAndProcessImageFiles run. 63 self.Patch(setup_common, "PackageInstalled", return_value=True) 64 self.Patch(remote_image_local_instance, 65 "ConfirmDownloadRemoteImageDir", return_value="/tmp") 66 self.Patch(os.path, "exists", return_value=True) 67 paths = self.RemoteImageLocalInstance.GetImageArtifactsPath(avd_spec) 68 mock_proc.assert_called_once_with(avd_spec) 69 self.assertEqual(paths.image_dir, "/unit/test") 70 self.assertEqual(paths.host_bins, "/unit/test") 71 72 def testDownloadAndProcessImageFiles(self): 73 """Test process remote cuttlefish image.""" 74 avd_spec = mock.MagicMock() 75 avd_spec.cfg = mock.MagicMock() 76 avd_spec.cfg.creds_cache_file = "cache.file" 77 avd_spec.remote_image = self._fake_remote_image 78 avd_spec.image_download_dir = "/tmp" 79 self.Patch(os.path, "exists", return_value=False) 80 self.Patch(os, "makedirs") 81 self.Patch(subprocess, "check_call") 82 remote_image_local_instance.DownloadAndProcessImageFiles(avd_spec) 83 84 self.assertEqual(self.build_client.GetFetchBuildArgs.call_count, 1) 85 self.assertEqual(self.build_client.GetFetchCertArg.call_count, 1) 86 87 def testConfirmDownloadRemoteImageDir(self): 88 """Test confirm download remote image dir""" 89 self.Patch(os.path, "exists", return_value=True) 90 self.Patch(os, "makedirs") 91 # Default minimum avail space should be more than 10G 92 # then return download_dir directly. 93 self.Patch(os, "statvfs", return_value=namedtuple( 94 "statvfs", "f_bavail, f_bsize")(11, 1073741824)) 95 download_dir = "/tmp" 96 self.assertEqual( 97 remote_image_local_instance.ConfirmDownloadRemoteImageDir( 98 download_dir), "/tmp") 99 100 # Test when insuficient disk space and input 'q' to exit. 101 self.Patch(os, "statvfs", return_value=namedtuple( 102 "statvfs", "f_bavail, f_bsize")(9, 1073741824)) 103 self.Patch(utils, "InteractWithQuestion", return_value="q") 104 self.assertRaises(SystemExit, 105 remote_image_local_instance.ConfirmDownloadRemoteImageDir, 106 download_dir) 107 108 # If avail space detect as 9GB, and 2nd input 7GB both less than 10GB 109 # 3rd input over 10GB, so return path should be "/tmp3". 110 self.Patch(os, "statvfs", side_effect=[ 111 namedtuple("statvfs", "f_bavail, f_bsize")(9, 1073741824), 112 namedtuple("statvfs", "f_bavail, f_bsize")(7, 1073741824), 113 namedtuple("statvfs", "f_bavail, f_bsize")(11, 1073741824)]) 114 self.Patch(utils, "InteractWithQuestion", side_effect=["/tmp2", 115 "/tmp3"]) 116 self.assertEqual( 117 remote_image_local_instance.ConfirmDownloadRemoteImageDir( 118 download_dir), "/tmp3") 119 120 # Test when path not exist, define --image-download-dir 121 # enter anything else to exit out. 122 download_dir = "/image_download_dir1" 123 self.Patch(os.path, "exists", return_value=False) 124 self.Patch(utils, "InteractWithQuestion", return_value="") 125 self.assertRaises(SystemExit, 126 remote_image_local_instance.ConfirmDownloadRemoteImageDir, 127 download_dir) 128 129 # Test using --image-dowload-dir and makedirs. 130 # enter 'y' to create it. 131 self.Patch(utils, "InteractWithQuestion", return_value="y") 132 self.Patch(os, "statvfs", return_value=namedtuple( 133 "statvfs", "f_bavail, f_bsize")(10, 1073741824)) 134 self.assertEqual( 135 remote_image_local_instance.ConfirmDownloadRemoteImageDir( 136 download_dir), "/image_download_dir1") 137 138 # Test when 1st check fails for insufficient disk space, user inputs an 139 # alternate dir but it doesn't exist and the user choose to exit. 140 self.Patch(os, "statvfs", side_effect=[ 141 namedtuple("statvfs", "f_bavail, f_bsize")(9, 1073741824), 142 namedtuple("statvfs", "f_bavail, f_bsize")(11, 1073741824)]) 143 self.Patch(os.path, "exists", side_effect=[True, False]) 144 self.Patch(utils, "InteractWithQuestion", 145 side_effect=["~/nopath", "not_y"]) 146 self.assertRaises( 147 SystemExit, 148 remote_image_local_instance.ConfirmDownloadRemoteImageDir, 149 download_dir) 150 151 # Test when 1st check fails for insufficient disk space, user inputs an 152 # alternate dir but it doesn't exist and they request to create it. 153 self.Patch(os, "statvfs", side_effect=[ 154 namedtuple("statvfs", "f_bavail, f_bsize")(9, 1073741824), 155 namedtuple("statvfs", "f_bavail, f_bsize")(10, 1073741824)]) 156 self.Patch(os.path, "exists", side_effect=[True, False]) 157 self.Patch(utils, "InteractWithQuestion", side_effect=["~/nopath", "y"]) 158 self.assertEqual( 159 remote_image_local_instance.ConfirmDownloadRemoteImageDir( 160 download_dir), os.path.expanduser("~/nopath")) 161 162 163if __name__ == "__main__": 164 unittest.main() 165