1#!/usr/bin/env python 2# 3# Copyright (C) 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# 17 18import os 19import unittest 20 21try: 22 from unittest import mock 23except ImportError: 24 import mock 25 26from host_controller import common 27from host_controller.command_processor import command_upload 28 29 30def side_effect(value): 31 return value 32 33 34class CommandUploadTest(unittest.TestCase): 35 """Tests for upload command processor""" 36 37 @mock.patch("host_controller.console.Console") 38 @mock.patch("host_controller.command_processor.command_upload.open") 39 @mock.patch("host_controller.command_processor.command_upload.cmd_utils") 40 @mock.patch("host_controller.command_processor.command_upload.SuiteResMsg") 41 @mock.patch("host_controller.command_processor.command_upload.SchedCfgMsg") 42 def testUploadReportBootupErr(self, mock_sched_config_msg, 43 mock_suite_res_msg, mock_cmd_util, mock_open, 44 mock_console): 45 mock_open.__enter__ = mock.Mock(return_value=mock_open) 46 mock_open.__exit__ = mock.Mock(return_value=None) 47 mock_cmd_util.ExecuteOneShellCommand = mock.Mock( 48 return_value=("", "", 0)) 49 mock_console.vti_endpoint_client.CheckBootUpStatus.return_value = False 50 mock_console.FormatString.side_effect = side_effect 51 mock_console.fetch_info = { 52 "branch": "git_device_branch", 53 "target": "device-userdebug", 54 "build_id": "1234567", 55 "account_id": common._DEFAULT_ACCOUNT_ID, 56 } 57 mock_console.detailed_fetch_info = { 58 "device": { 59 "branch": "git_device_branch", 60 "target": "device-userdebug", 61 "build_id": "1234567", 62 "account_id": common._DEFAULT_ACCOUNT_ID, 63 "fetch_signed_build": False, 64 }, 65 "gsi": { 66 "branch": "git_aosp_gsi_branch", 67 "target": "gsi-userdebug", 68 "build_id": "2345678", 69 "account_id": common._DEFAULT_ACCOUNT_ID_INTERNAL, 70 } 71 } 72 mock_console.tmp_logdir = "tmp/log" 73 mock_console.device_image_info = { 74 "bootloader.img": "path/to/bootloader.img" 75 } 76 mock_pb2 = mock.Mock() 77 mock_pb2.repacked_image_path = [] 78 mock_pb2.schedule_config.build_target = [] 79 mock_build_sched_config_pb2 = mock.Mock() 80 mock_build_sched_config_pb2.test_schedule = [] 81 mock_test_sched_config_pb2 = mock.Mock() 82 mock_suite_res_msg.TestSuiteResultMessage.return_value = mock_pb2 83 mock_sched_config_msg.BuildScheduleConfigMessage.return_value = ( 84 mock_build_sched_config_pb2) 85 mock_sched_config_msg.TestScheduleConfigMessage.return_value = ( 86 mock_test_sched_config_pb2) 87 command = command_upload.CommandUpload() 88 command._SetUp(mock_console) 89 command.UploadReport("/path/to/bin/gsutil", "gs://report-bucket/", 90 "tmp/console.log", "tmp/result.log", "vts", 91 "some_plan") 92 self.assertEqual(mock_pb2.build_id, "1234567") 93 self.assertEqual(mock_pb2.suite_name, "vts") 94 self.assertEqual(mock_pb2.suite_plan, "some_plan") 95 self.assertEqual(mock_pb2.suite_build_number, mock_pb2.build_id) 96 self.assertEqual(mock_pb2.build_system_fingerprint, 97 "git_aosp_gsi_branch/gsi-userdebug/2345678") 98 self.assertEqual(mock_pb2.build_vendor_fingerprint, 99 "git_device_branch/device-userdebug/1234567") 100 self.assertEqual(mock_pb2.repacked_image_path, ["{repack_path}"]) 101 self.assertEqual(mock_pb2.schedule_config.manifest_branch, 102 "git_device_branch") 103 self.assertEqual(mock_pb2.schedule_config.pab_account_id, 104 common._DEFAULT_ACCOUNT_ID) 105 106 self.assertTrue(mock_build_sched_config_pb2.has_bootloader_img) 107 self.assertFalse(mock_build_sched_config_pb2.has_radio_img) 108 109 self.assertEqual(mock_test_sched_config_pb2.gsi_branch, 110 "git_aosp_gsi_branch") 111 self.assertEqual(mock_test_sched_config_pb2.gsi_build_target, 112 "gsi-userdebug") 113 self.assertEqual(mock_test_sched_config_pb2.gsi_pab_account_id, 114 common._DEFAULT_ACCOUNT_ID_INTERNAL) 115 mock_cmd_util.ExecuteOneShellCommand.assert_called_with( 116 "/path/to/bin/gsutil cp tmp/log/{timestamp_time}.bin " 117 "gs://report-bucket/{timestamp_time}.bin") 118 119 @mock.patch("host_controller.console.Console") 120 @mock.patch("host_controller.command_processor.command_upload.open") 121 @mock.patch("host_controller.command_processor.command_upload.cmd_utils") 122 @mock.patch("host_controller.command_processor.command_upload.SuiteResMsg") 123 @mock.patch("host_controller.command_processor.command_upload.os") 124 @mock.patch("host_controller.command_processor.command_upload.xml_utils") 125 @mock.patch("host_controller.command_processor.command_upload.SchedCfgMsg") 126 def testUploadReportBootupOk(self, mock_sched_config_msg, mock_xml_util, 127 mock_os, mock_suite_res_msg, mock_cmd_util, 128 mock_open, mock_console): 129 mock_open.__enter__ = mock.Mock(return_value=mock_open) 130 mock_open.__exit__ = mock.Mock(return_value=None) 131 mock_cmd_util.ExecuteOneShellCommand = mock.Mock( 132 return_value=("", "", 0)) 133 mock_console.vti_endpoint_client.CheckBootUpStatus.return_value = True 134 mock_console.FormatString.side_effect = side_effect 135 mock_console.tmp_logdir = "tmp/log" 136 mock_pb2 = mock.Mock() 137 mock_pb2.repacked_image_path = [] 138 mock_pb2.schedule_config.build_target = [] 139 mock_build_sched_config_pb2 = mock.Mock() 140 mock_build_sched_config_pb2.test_schedule = [] 141 mock_test_sched_config_pb2 = mock.Mock() 142 mock_suite_res_msg.TestSuiteResultMessage.return_value = mock_pb2 143 mock_sched_config_msg.BuildScheduleConfigMessage.return_value = ( 144 mock_build_sched_config_pb2) 145 mock_sched_config_msg.TestScheduleConfigMessage.return_value = ( 146 mock_test_sched_config_pb2) 147 mock_os.listdir.return_value = ["1", "2", "3"] 148 mock_os.path.isdir.return_value = True 149 mock_os.path.islink.return_value = False 150 mock_os.path.join = os.path.join 151 mock_os.path.basename = os.path.basename 152 mock_xml_util.GetAttributes.return_value = { 153 common._SUITE_NAME_ATTR_KEY: 154 "vts", 155 common._SUITE_PLAN_ATTR_KEY: 156 "some_plan", 157 common._SUITE_VERSION_ATTR_KEY: 158 "8.0_R1", 159 common._SUITE_BUILD_NUM_ATTR_KEY: 160 "1234567", 161 common._START_TIME_ATTR_KEY: 162 "0", 163 common._END_TIME_ATTR_KEY: 164 "1", 165 common._HOST_NAME_ATTR_KEY: 166 "this-host", 167 common._FINGERPRINT_ATTR_KEY: 168 "git_device_branch/device-userdebug/1234567", 169 common._SYSTEM_FINGERPRINT_ATTR_KEY: 170 "git_aosp_gsi_branch/gsi-userdebug/2345678", 171 common._VENDOR_FINGERPRINT_ATTR_KEY: 172 "git_device_branch/device-userdebug/1234567", 173 common._PASSED_ATTR_KEY: 174 "1265", 175 common._FAILED_ATTR_KEY: 176 "43", 177 common._MODULES_TOTAL_ATTR_KEY: 178 "100", 179 common._MODULES_DONE_ATTR_KEY: 180 "98", 181 } 182 command = command_upload.CommandUpload() 183 command._SetUp(mock_console) 184 command.UploadReport("/path/to/bin/gsutil", "gs://report-bucket/", 185 "tmp/console.log", "tmp/vts/results", "vts", 186 "some_plan") 187 self.assertEqual(mock_pb2.build_id, "1234567") 188 self.assertEqual(mock_pb2.suite_name, "vts") 189 self.assertEqual(mock_pb2.suite_plan, "some_plan") 190 self.assertEqual(mock_pb2.suite_version, "8.0_R1") 191 self.assertEqual(mock_pb2.suite_build_number, mock_pb2.build_id) 192 self.assertEqual(mock_pb2.start_time, 0) 193 self.assertEqual(mock_pb2.end_time, 1) 194 self.assertEqual(mock_pb2.host_name, "this-host") 195 self.assertEqual(mock_pb2.build_system_fingerprint, 196 "git_aosp_gsi_branch/gsi-userdebug/2345678") 197 self.assertEqual(mock_pb2.build_vendor_fingerprint, 198 "git_device_branch/device-userdebug/1234567") 199 self.assertEqual(mock_pb2.passed_test_case_count, 1265) 200 self.assertEqual(mock_pb2.failed_test_case_count, 43) 201 self.assertEqual(mock_pb2.modules_total, 100) 202 self.assertEqual(mock_pb2.modules_done, 98) 203 self.assertEqual(mock_pb2.repacked_image_path, ["{repack_path}"]) 204 mock_cmd_util.ExecuteOneShellCommand.assert_called_with( 205 "/path/to/bin/gsutil cp tmp/log/{timestamp_time}.bin " 206 "gs://report-bucket/{timestamp_time}.bin") 207 208 @mock.patch("host_controller.console.Console") 209 @mock.patch("host_controller.command_processor.command_upload.os") 210 @mock.patch("host_controller.command_processor.command_upload.logging") 211 def testUploadReportResultDirAbsent(self, mock_logger, mock_os, 212 mock_console): 213 mock_console.vti_endpoint_client.CheckBootUpStatus.return_value = True 214 mock_console.FormatString.side_effect = side_effect 215 mock_console.tmp_logdir = "tmp/log" 216 mock_os.listdir.return_value = [] 217 command = command_upload.CommandUpload() 218 command._SetUp(mock_console) 219 ret = command.UploadReport("/path/to/bin/gsutil", 220 "gs://report-bucket/", "tmp/console.log", 221 "tmp/result.log", "vts", "some_plan") 222 self.assertFalse(ret) 223 mock_logger.error.assert_called_with("No test result found.") 224 225 @mock.patch("host_controller.console.Console") 226 @mock.patch("host_controller.command_processor.command_upload.gcs_utils") 227 @mock.patch("host_controller.command_processor.command_upload.logging") 228 def testCommandUploadGsutilAbsent(self, mock_logger, mock_gcs_util, 229 mock_console): 230 mock_gcs_util.GetGsutilPath.return_value = "" 231 command = command_upload.CommandUpload() 232 command.UploadReport = mock.Mock() 233 command._SetUp(mock_console) 234 ret = command._Run("--src=tmp/result.log --dest=gs://report-bucket/") 235 self.assertFalse(ret) 236 mock_logger.error.assert_called_with( 237 "Please check gsutil is installed and on your PATH") 238 239 @mock.patch("host_controller.console.Console") 240 @mock.patch("host_controller.command_processor.command_upload.gcs_utils") 241 @mock.patch("host_controller.command_processor.command_upload.logging") 242 def testCommandUploadLatestSrc(self, mock_logger, mock_gcs_util, 243 mock_console): 244 mock_gcs_util.GetGsutilPath.return_value = "/path/to/bin/gsutil" 245 command = command_upload.CommandUpload() 246 command.UploadReport = mock.Mock() 247 command._SetUp(mock_console) 248 ret = command._Run( 249 "--src=latest-something.img --dest=gs://report-bucket/") 250 self.assertFalse(ret) 251 mock_logger.error.assert_called_with( 252 "Unable to find something.img in device_image_info") 253 254 @mock.patch("host_controller.console.Console") 255 @mock.patch("host_controller.command_processor.command_upload.gcs_utils") 256 @mock.patch("host_controller.command_processor.command_upload.os") 257 def testCommandUploadLatestLegitSrc(self, mock_os, mock_gcs_util, 258 mock_console): 259 mock_os.path.isfile.return_value = True 260 mock_console.device_image_info = {"system.img": "path/to/system.img"} 261 mock_console.FormatString.side_effect = side_effect 262 mock_gcs_util.GetGsutilPath.return_value = "/path/to/bin/gsutil" 263 command = command_upload.CommandUpload() 264 command.UploadReport = mock.Mock() 265 command._SetUp(mock_console) 266 ret = command._Run( 267 "--src=latest-system.img --dest=gs://report-bucket/dir " 268 "--clear_dest") 269 self.assertIsNone(ret) 270 mock_gcs_util.Remove.assert_called_with( 271 "/path/to/bin/gsutil", "gs://report-bucket/dir", recursive=True) 272 mock_gcs_util.Copy.assert_called_with('/path/to/bin/gsutil', 273 'path/to/system.img', 274 'gs://report-bucket/dir') 275 276 @mock.patch("host_controller.console.Console") 277 @mock.patch("host_controller.command_processor.command_upload.gcs_utils") 278 @mock.patch("host_controller.command_processor.command_upload.os") 279 @mock.patch("host_controller.command_processor.command_upload.logging") 280 def testCommandUploadFalseDest(self, mock_logger, mock_os, mock_gcs_util, 281 mock_console): 282 mock_os.path.isfile.return_value = True 283 mock_console.device_image_info = {"system.img": "path/to/system.img"} 284 mock_console.FormatString.side_effect = side_effect 285 mock_gcs_util.GetGsutilPath.return_value = "/path/to/bin/gsutil" 286 command = command_upload.CommandUpload() 287 command.UploadReport = mock.Mock() 288 command._SetUp(mock_console) 289 ret = command._Run("--src=latest-system.img --dest=/report-bucket/") 290 self.assertFalse(ret) 291 mock_logger.error.assert_called_with( 292 "/report-bucket/ is not correct GCS url.") 293 294 @mock.patch("host_controller.console.Console") 295 @mock.patch("host_controller.command_processor.command_upload.gcs_utils") 296 @mock.patch("host_controller.command_processor.command_upload.os") 297 def testCommandUploadMultipleFiles(self, mock_os, mock_gcs_util, 298 mock_console): 299 mock_os.path.isfile.return_value = True 300 mock_console.FormatString.side_effect = side_effect 301 mock_gcs_util.GetGsutilPath.return_value = "/path/to/bin/gsutil" 302 command = command_upload.CommandUpload() 303 command.UploadReport = mock.Mock() 304 command._SetUp(mock_console) 305 ret = command._Run("--src=result.zip --dest=gs://report-bucket/") 306 self.assertIsNone(ret) 307 mock_gcs_util.Copy.assert_called_with( 308 '/path/to/bin/gsutil', 'result.zip', 'gs://report-bucket/') 309 310 311if __name__ == "__main__": 312 unittest.main() 313