1# Copyright 2019 - 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 GoldfishLocalImageLocalInstance.""" 15 16import os 17import shutil 18import tempfile 19import unittest 20 21from unittest import mock 22 23from acloud import errors 24import acloud.create.goldfish_local_image_local_instance as instance_module 25from acloud.internal.lib import driver_test_lib 26 27 28class GoldfishLocalImageLocalInstance(driver_test_lib.BaseDriverTest): 29 """Test GoldfishLocalImageLocalInstance methods.""" 30 31 def setUp(self): 32 self._goldfish = instance_module.GoldfishLocalImageLocalInstance() 33 self._temp_dir = tempfile.mkdtemp() 34 self._image_dir = os.path.join(self._temp_dir, "images") 35 self._tool_dir = os.path.join(self._temp_dir, "tool") 36 self._instance_dir = os.path.join(self._temp_dir, "instance") 37 self._emulator_is_running = False 38 self._mock_lock = mock.Mock() 39 self._mock_lock.Lock.return_value = True 40 self._mock_lock.LockIfNotInUse.side_effect = (False, True) 41 self._mock_proc = mock.Mock() 42 self._mock_proc.poll.side_effect = ( 43 lambda: None if self._emulator_is_running else 0) 44 45 os.mkdir(self._image_dir) 46 os.mkdir(self._tool_dir) 47 48 # Create emulator binary 49 self._emulator_path = os.path.join(self._tool_dir, "emulator", 50 "emulator") 51 self._CreateEmptyFile(self._emulator_path) 52 53 def tearDown(self): 54 shutil.rmtree(self._temp_dir, ignore_errors=True) 55 56 @staticmethod 57 def _CreateEmptyFile(path): 58 parent_dir = os.path.dirname(path) 59 if not os.path.exists(parent_dir): 60 os.makedirs(parent_dir) 61 with open(path, "w") as _: 62 pass 63 64 def _MockMixDiskImage(self, output_dir, *_args): 65 """Mock goldfish_utils.MixDiskImage.""" 66 self.assertEqual(os.path.join(self._instance_dir, "mix_disk"), 67 output_dir) 68 output_path = os.path.join(output_dir, "mixed_disk.img") 69 self._CreateEmptyFile(output_path) 70 return output_path 71 72 def _MockMixWithBootImage(self, output_dir, *_args): 73 """Mock goldfish_utils.MixWithBootImage.""" 74 self.assertEqual(os.path.join(self._instance_dir, "mix_kernel"), 75 output_dir) 76 return (os.path.join(output_dir, "kernel"), 77 os.path.join(output_dir, "ramdisk")) 78 79 def _MockPopen(self, *_args, **_kwargs): 80 self._emulator_is_running = True 81 return self._mock_proc 82 83 def _MockEmuCommand(self, *args): 84 if not self._emulator_is_running: 85 # Connection refused 86 return 1 87 88 if args == ("kill",): 89 self._emulator_is_running = False 90 return 0 91 92 if args == (): 93 return 0 94 95 raise ValueError("Unexpected arguments " + str(args)) 96 97 def _SetUpMocks(self, mock_popen, mock_utils, mock_instance, 98 mock_gf_utils): 99 mock_utils.IsSupportedPlatform.return_value = True 100 101 mock_adb_tools = mock.Mock(side_effect=self._MockEmuCommand) 102 103 mock_instance_object = mock.Mock(ip="127.0.0.1", 104 adb_port=5555, 105 console_port="5554", 106 device_serial="unittest", 107 instance_dir=self._instance_dir, 108 adb=mock_adb_tools) 109 # name is a positional argument of Mock(). 110 mock_instance_object.name = "local-goldfish-instance" 111 112 mock_instance.return_value = mock_instance_object 113 mock_instance.GetLockById.return_value = self._mock_lock 114 mock_instance.GetMaxNumberOfInstances.return_value = 2 115 116 mock_popen.side_effect = self._MockPopen 117 118 mock_gf_utils.SYSTEM_QEMU_IMAGE_NAME = "system-qemu.img" 119 mock_gf_utils.VERIFIED_BOOT_PARAMS_FILE_NAME = ( 120 "VerifiedBootParams.textproto") 121 mock_gf_utils.MixDiskImage.side_effect = self._MockMixDiskImage 122 mock_gf_utils.MixWithBootImage.side_effect = self._MockMixWithBootImage 123 mock_gf_utils.ConvertAvdSpecToArgs.return_value = ["-gpu", "auto"] 124 125 def _CreateMockAvdSpec(self, local_instance_id, autoconnect=True, 126 boot_timeout_secs=None, 127 local_instance_dir=None, local_kernel_image=None, 128 local_system_image=None, local_tool_dirs=None): 129 """Return a mock avd_spec.AvdSpec with needed attributes.""" 130 attr_dict = { 131 "autoconnect": autoconnect, 132 "boot_timeout_secs": boot_timeout_secs, 133 "flavor": "phone", 134 "local_image_dir": self._image_dir, 135 "local_instance_id": local_instance_id, 136 "local_instance_dir": local_instance_dir, 137 "local_kernel_image": local_kernel_image, 138 "local_system_image": local_system_image, 139 "local_tool_dirs": local_tool_dirs or [], 140 } 141 mock_avd_spec = mock.Mock(spec=list(attr_dict), **attr_dict) 142 return mock_avd_spec 143 144 def _GetExpectedEmulatorArgs(self, *extra_args): 145 cmd = [ 146 self._emulator_path, "-verbose", "-show-kernel", "-read-only", 147 "-ports", "5554,5555", 148 "-logcat-output", 149 os.path.join(self._instance_dir, "logcat.txt"), 150 "-stdouterr-file", 151 os.path.join(self._instance_dir, "kernel.log"), 152 "-gpu", "auto" 153 ] 154 cmd.extend(extra_args) 155 return cmd 156 157 def _GetExpectedDevicesInReport(self): 158 logcat_path = os.path.join(self._instance_dir, "logcat.txt") 159 stdouterr_path = os.path.join(self._instance_dir, "kernel.log") 160 return [ 161 { 162 "instance_name": "local-goldfish-instance", 163 "ip": "127.0.0.1:5555", 164 "adb_port": 5555, 165 "device_serial": "unittest", 166 "logs": [ 167 {"path": logcat_path, "type": "LOGCAT"}, 168 {"path": stdouterr_path, "type": "KERNEL_LOG"} 169 ] 170 } 171 ] 172 173 # pylint: disable=protected-access 174 @mock.patch("acloud.create.goldfish_local_image_local_instance.instance." 175 "LocalGoldfishInstance") 176 @mock.patch("acloud.create.goldfish_local_image_local_instance.utils") 177 @mock.patch("acloud.create.goldfish_local_image_local_instance." 178 "subprocess.Popen") 179 @mock.patch("acloud.create.goldfish_local_image_local_instance." 180 "goldfish_utils") 181 def testCreateAVDInBuildEnvironment(self, mock_gf_utils, mock_popen, 182 mock_utils, mock_instance): 183 """Test _CreateAVD with build environment variables and files.""" 184 self._SetUpMocks(mock_popen, mock_utils, mock_instance, mock_gf_utils) 185 186 self._CreateEmptyFile(os.path.join(self._image_dir, 187 "system-qemu.img")) 188 self._CreateEmptyFile(os.path.join(self._image_dir, "system", 189 "build.prop")) 190 191 mock_environ = {"ANDROID_EMULATOR_PREBUILTS": 192 os.path.join(self._tool_dir, "emulator")} 193 194 mock_avd_spec = self._CreateMockAvdSpec(local_instance_id=1, 195 boot_timeout_secs=100) 196 197 # Test deleting an existing instance. 198 self._emulator_is_running = True 199 200 with mock.patch.dict("acloud.create." 201 "goldfish_local_image_local_instance.os.environ", 202 mock_environ, clear=True): 203 report = self._goldfish._CreateAVD(mock_avd_spec, no_prompts=False) 204 205 self.assertEqual(report.data.get("devices"), 206 self._GetExpectedDevicesInReport()) 207 208 self._mock_lock.Lock.assert_called_once() 209 self._mock_lock.SetInUse.assert_called_once_with(True) 210 self._mock_lock.Unlock.assert_called_once() 211 212 mock_instance.assert_called_once_with(1, avd_flavor="phone") 213 214 self.assertTrue(os.path.isdir(self._instance_dir)) 215 216 mock_utils.SetExecutable.assert_called_with(self._emulator_path) 217 mock_popen.assert_called_once() 218 self.assertEqual(mock_popen.call_args[0][0], 219 self._GetExpectedEmulatorArgs()) 220 self._mock_proc.poll.assert_called() 221 222 # pylint: disable=protected-access 223 @mock.patch("acloud.create.goldfish_local_image_local_instance.instance." 224 "LocalGoldfishInstance") 225 @mock.patch("acloud.create.goldfish_local_image_local_instance.utils") 226 @mock.patch("acloud.create.goldfish_local_image_local_instance." 227 "subprocess.Popen") 228 @mock.patch("acloud.create.goldfish_local_image_local_instance." 229 "goldfish_utils") 230 def testCreateAVDFromSdkRepository(self, mock_gf_utils, mock_popen, 231 mock_utils, mock_instance): 232 """Test _CreateAVD with SDK repository files.""" 233 self._SetUpMocks(mock_popen, mock_utils, mock_instance, mock_gf_utils) 234 235 self._CreateEmptyFile(os.path.join(self._image_dir, "x86", 236 "system.img")) 237 self._CreateEmptyFile(os.path.join(self._image_dir, "x86", 238 "build.prop")) 239 240 instance_dir = os.path.join(self._temp_dir, "local_instance_dir") 241 os.mkdir(instance_dir) 242 243 mock_avd_spec = self._CreateMockAvdSpec( 244 local_instance_id=2, 245 local_instance_dir=instance_dir, 246 local_tool_dirs=[self._tool_dir]) 247 248 with mock.patch.dict("acloud.create." 249 "goldfish_local_image_local_instance.os.environ", 250 dict(), clear=True): 251 report = self._goldfish._CreateAVD(mock_avd_spec, no_prompts=True) 252 253 self.assertEqual(report.data.get("devices"), 254 self._GetExpectedDevicesInReport()) 255 256 self._mock_lock.Lock.assert_called_once() 257 self._mock_lock.SetInUse.assert_called_once_with(True) 258 self._mock_lock.Unlock.assert_called_once() 259 260 mock_instance.assert_called_once_with(2, avd_flavor="phone") 261 262 self.assertTrue(os.path.isdir(self._instance_dir) and 263 os.path.islink(self._instance_dir)) 264 265 mock_utils.SetExecutable.assert_called_with(self._emulator_path) 266 mock_popen.assert_called_once() 267 self.assertEqual(mock_popen.call_args[0][0], 268 self._GetExpectedEmulatorArgs()) 269 self._mock_proc.poll.assert_called() 270 271 self.assertTrue(os.path.isfile( 272 os.path.join(self._image_dir, "x86", "system", "build.prop"))) 273 274 # pylint: disable=protected-access 275 @mock.patch("acloud.create.goldfish_local_image_local_instance.instance." 276 "LocalGoldfishInstance") 277 @mock.patch("acloud.create.goldfish_local_image_local_instance.utils") 278 @mock.patch("acloud.create.goldfish_local_image_local_instance." 279 "subprocess.Popen") 280 @mock.patch("acloud.create.goldfish_local_image_local_instance." 281 "goldfish_utils") 282 def testCreateAVDTimeout(self, mock_gf_utils, mock_popen, mock_utils, mock_instance): 283 """Test _CreateAVD with SDK repository files and timeout error.""" 284 self._SetUpMocks(mock_popen, mock_utils, mock_instance, mock_gf_utils) 285 mock_utils.PollAndWait.side_effect = errors.DeviceBootTimeoutError( 286 "timeout") 287 288 self._CreateEmptyFile(os.path.join(self._image_dir, "system.img")) 289 self._CreateEmptyFile(os.path.join(self._image_dir, "build.prop")) 290 291 mock_avd_spec = self._CreateMockAvdSpec( 292 local_instance_id=2, 293 local_tool_dirs=[self._tool_dir]) 294 295 with mock.patch.dict("acloud.create." 296 "goldfish_local_image_local_instance.os.environ", 297 dict(), clear=True): 298 report = self._goldfish._CreateAVD(mock_avd_spec, no_prompts=True) 299 300 self._mock_lock.Lock.assert_called_once() 301 self._mock_lock.SetInUse.assert_called_once_with(True) 302 self._mock_lock.Unlock.assert_called_once() 303 304 self.assertEqual(report.data.get("devices_failing_boot"), 305 self._GetExpectedDevicesInReport()) 306 self.assertEqual(report.errors, ["timeout"]) 307 308 # pylint: disable=protected-access 309 @mock.patch("acloud.create.goldfish_local_image_local_instance.instance." 310 "LocalGoldfishInstance") 311 @mock.patch("acloud.create.goldfish_local_image_local_instance.utils") 312 @mock.patch("acloud.create.goldfish_local_image_local_instance." 313 "subprocess.Popen") 314 @mock.patch("acloud.create.goldfish_local_image_local_instance." 315 "goldfish_utils") 316 def testCreateAVDWithoutReport(self, mock_gf_utils, mock_popen, mock_utils, 317 mock_instance): 318 """Test _CreateAVD with SDK repository files and no report.""" 319 self._SetUpMocks(mock_popen, mock_utils, mock_instance, mock_gf_utils) 320 321 mock_avd_spec = self._CreateMockAvdSpec( 322 local_instance_id=0, 323 local_tool_dirs=[self._tool_dir]) 324 325 with mock.patch.dict("acloud.create." 326 "goldfish_local_image_local_instance.os.environ", 327 dict(), clear=True): 328 with self.assertRaises(errors.GetLocalImageError): 329 self._goldfish._CreateAVD(mock_avd_spec, no_prompts=True) 330 331 self._mock_lock.Lock.assert_not_called() 332 self.assertEqual(2, self._mock_lock.LockIfNotInUse.call_count) 333 self._mock_lock.SetInUse.assert_not_called() 334 self._mock_lock.Unlock.assert_called_once() 335 336 # pylint: disable=protected-access 337 @mock.patch("acloud.create.goldfish_local_image_local_instance.instance." 338 "LocalGoldfishInstance") 339 @mock.patch("acloud.create.goldfish_local_image_local_instance.utils") 340 @mock.patch("acloud.create.goldfish_local_image_local_instance." 341 "subprocess.Popen") 342 @mock.patch("acloud.create.goldfish_local_image_local_instance.ota_tools") 343 @mock.patch("acloud.create.goldfish_local_image_local_instance." 344 "goldfish_utils") 345 def testCreateAVDWithMixedImages(self, mock_gf_utils, mock_ota_tools, 346 mock_popen, mock_utils, mock_instance): 347 """Test _CreateAVD with mixed images and SDK repository files.""" 348 self._SetUpMocks(mock_popen, mock_utils, mock_instance, mock_gf_utils) 349 350 system_image_path = os.path.join(self._image_dir, "x86", "system.img") 351 self._CreateEmptyFile(system_image_path) 352 self._CreateEmptyFile(os.path.join(self._image_dir, "x86", "system", 353 "build.prop")) 354 params_path = os.path.join(self._image_dir, "x86", 355 "VerifiedBootParams.textproto") 356 self._CreateEmptyFile(params_path) 357 358 mock_avd_spec = self._CreateMockAvdSpec( 359 local_instance_id=3, 360 autoconnect=False, 361 local_system_image=system_image_path, 362 local_tool_dirs=[self._tool_dir]) 363 364 with mock.patch.dict("acloud.create." 365 "goldfish_local_image_local_instance.os.environ", 366 dict(), clear=True): 367 report = self._goldfish._CreateAVD(mock_avd_spec, no_prompts=True) 368 369 self.assertEqual(report.data.get("devices"), 370 self._GetExpectedDevicesInReport()) 371 372 mock_instance.assert_called_once_with(3, avd_flavor="phone") 373 374 self.assertTrue(os.path.isdir(self._instance_dir)) 375 376 mock_ota_tools.FindOtaTools.assert_called_once_with([self._tool_dir]) 377 378 mock_gf_utils.MixDiskImage.assert_called_once_with( 379 mock.ANY, os.path.join(self._image_dir, "x86"), system_image_path, 380 None, mock_ota_tools.FindOtaTools.return_value) 381 self.assertTrue(os.path.isfile(params_path + ".bak-non-mixed")) 382 with open(params_path, "r", encoding="utf-8") as params_file: 383 self.assertEqual( 384 params_file.read(), 385 '\nparam: "androidboot.verifiedbootstate=orange"\n') 386 387 mock_utils.SetExecutable.assert_called_with(self._emulator_path) 388 mock_popen.assert_called_once() 389 self.assertEqual(mock_popen.call_args[0][0], 390 self._GetExpectedEmulatorArgs("-no-window")) 391 self._mock_proc.poll.assert_called() 392 393 # pylint: disable=protected-access 394 @mock.patch("acloud.create.goldfish_local_image_local_instance.instance." 395 "LocalGoldfishInstance") 396 @mock.patch("acloud.create.goldfish_local_image_local_instance.utils") 397 @mock.patch("acloud.create.goldfish_local_image_local_instance." 398 "subprocess.Popen") 399 @mock.patch("acloud.create.goldfish_local_image_local_instance.ota_tools") 400 @mock.patch("acloud.create.goldfish_local_image_local_instance." 401 "goldfish_utils") 402 def testCreateAVDWithBootImage(self, mock_gf_utils, mock_ota_tools, 403 mock_popen, mock_utils, mock_instance): 404 """Test _CreateAVD with a boot image and SDK repository files.""" 405 self._SetUpMocks(mock_popen, mock_utils, mock_instance, mock_gf_utils) 406 407 image_subdir = os.path.join(self._image_dir, "x86") 408 boot_image_path = os.path.join(self._temp_dir, "kernel_images", 409 "boot-5.10.img") 410 self.CreateFile(boot_image_path, b"ANDROID!") 411 self._CreateEmptyFile(os.path.join(image_subdir, "system.img")) 412 self._CreateEmptyFile(os.path.join(image_subdir, "build.prop")) 413 414 mock_avd_spec = self._CreateMockAvdSpec( 415 local_instance_id=3, 416 local_kernel_image=os.path.dirname(boot_image_path), 417 local_tool_dirs=[self._tool_dir]) 418 419 with mock.patch.dict("acloud.create." 420 "goldfish_local_image_local_instance.os.environ", 421 dict(), clear=True): 422 report = self._goldfish._CreateAVD(mock_avd_spec, no_prompts=True) 423 424 self.assertEqual(report.data.get("devices"), 425 self._GetExpectedDevicesInReport()) 426 427 mock_gf_utils.MixWithBootImage.assert_called_once_with( 428 mock.ANY, os.path.join(image_subdir), boot_image_path, 429 mock_ota_tools.FindOtaTools.return_value) 430 431 mock_popen.assert_called_once() 432 self.assertEqual( 433 mock_popen.call_args[0][0], 434 self._GetExpectedEmulatorArgs( 435 "-kernel", 436 os.path.join(self._instance_dir, "mix_kernel", "kernel"), 437 "-ramdisk", 438 os.path.join(self._instance_dir, "mix_kernel", "ramdisk"))) 439 440 # pylint: disable=protected-access 441 @mock.patch("acloud.create.goldfish_local_image_local_instance.instance." 442 "LocalGoldfishInstance") 443 @mock.patch("acloud.create.goldfish_local_image_local_instance.utils") 444 @mock.patch("acloud.create.goldfish_local_image_local_instance." 445 "subprocess.Popen") 446 @mock.patch("acloud.create.goldfish_local_image_local_instance.ota_tools") 447 @mock.patch("acloud.create.goldfish_local_image_local_instance." 448 "goldfish_utils") 449 def testCreateAVDWithKernelImages(self, mock_gf_utils, mock_ota_tools, 450 mock_popen, mock_utils, mock_instance): 451 """Test _CreateAVD with kernel images and SDK repository files.""" 452 self._SetUpMocks(mock_popen, mock_utils, mock_instance, mock_gf_utils) 453 454 kernel_subdir = os.path.join(self._temp_dir, "kernel_images", "x86") 455 kernel_image_path = os.path.join(kernel_subdir, "kernel-ranchu") 456 ramdisk_image_path = os.path.join(kernel_subdir, "ramdisk.img") 457 mock_gf_utils.FindKernelImages.return_value = (kernel_image_path, 458 ramdisk_image_path) 459 460 os.makedirs(kernel_subdir) 461 self._CreateEmptyFile(os.path.join(self._image_dir, "x86", 462 "system.img")) 463 self._CreateEmptyFile(os.path.join(self._image_dir, "x86", 464 "build.prop")) 465 466 mock_avd_spec = self._CreateMockAvdSpec( 467 local_instance_id=3, 468 local_kernel_image=os.path.dirname(kernel_subdir), 469 local_tool_dirs=[self._tool_dir]) 470 471 with mock.patch.dict("acloud.create." 472 "goldfish_local_image_local_instance.os.environ", 473 dict(), clear=True): 474 report = self._goldfish._CreateAVD(mock_avd_spec, no_prompts=True) 475 476 self.assertEqual(report.data.get("devices"), 477 self._GetExpectedDevicesInReport()) 478 479 mock_ota_tools.FindOtaTools.assert_not_called() 480 mock_gf_utils.FindKernelImages.assert_called_once_with(kernel_subdir) 481 482 mock_popen.assert_called_once() 483 self.assertEqual( 484 mock_popen.call_args[0][0], 485 self._GetExpectedEmulatorArgs( 486 "-kernel", kernel_image_path, 487 "-ramdisk", ramdisk_image_path)) 488 489 # pylint: disable=protected-access 490 @mock.patch("acloud.create.goldfish_local_image_local_instance.instance." 491 "LocalGoldfishInstance") 492 @mock.patch("acloud.create.goldfish_local_image_local_instance.utils") 493 @mock.patch("acloud.create.goldfish_local_image_local_instance." 494 "subprocess.Popen") 495 @mock.patch("acloud.create.goldfish_local_image_local_instance.ota_tools") 496 @mock.patch("acloud.create.goldfish_local_image_local_instance." 497 "goldfish_utils") 498 def testCreateAVDWithMixedImageDirs(self, mock_gf_utils, mock_ota_tools, 499 mock_popen, mock_utils, mock_instance): 500 """Test _CreateAVD with mixed images in build environment.""" 501 self._SetUpMocks(mock_popen, mock_utils, mock_instance, mock_gf_utils) 502 503 system_image_path = os.path.join(self._image_dir, "system.img") 504 self._CreateEmptyFile(system_image_path) 505 disk_image_path = os.path.join(self._image_dir, "system-qemu.img") 506 self._CreateEmptyFile(disk_image_path) 507 self._CreateEmptyFile(os.path.join(self._image_dir, "system", 508 "build.prop")) 509 params_path = os.path.join(self._image_dir, 510 "VerifiedBootParams.textproto") 511 self._CreateEmptyFile(params_path) 512 513 mock_environ = {"ANDROID_EMULATOR_PREBUILTS": 514 os.path.join(self._tool_dir, "emulator"), 515 "ANDROID_HOST_OUT": 516 os.path.join(self._tool_dir, "host"), 517 "ANDROID_SOONG_HOST_OUT": 518 os.path.join(self._tool_dir, "soong")} 519 520 mock_avd_spec = self._CreateMockAvdSpec( 521 local_instance_id=3, 522 autoconnect=False, 523 local_system_image=self._image_dir) 524 525 with mock.patch.dict("acloud.create." 526 "goldfish_local_image_local_instance.os.environ", 527 mock_environ, clear=True): 528 report = self._goldfish._CreateAVD(mock_avd_spec, no_prompts=True) 529 530 self.assertEqual(report.data.get("devices"), 531 self._GetExpectedDevicesInReport()) 532 533 mock_instance.assert_called_once_with(3, avd_flavor="phone") 534 535 self.assertTrue(os.path.isdir(self._instance_dir)) 536 537 mock_ota_tools.FindOtaTools.assert_called_once_with([ 538 os.path.join(self._tool_dir, "soong"), 539 os.path.join(self._tool_dir, "host")]) 540 541 mock_gf_utils.MixDiskImage.assert_called_once_with( 542 mock.ANY, self._image_dir, system_image_path, None, 543 mock_ota_tools.FindOtaTools.return_value) 544 self.assertTrue(os.path.isfile(disk_image_path + ".bak-non-mixed")) 545 self.assertTrue(os.path.isfile(params_path + ".bak-non-mixed")) 546 with open(params_path, "r", encoding="utf-8") as params_file: 547 self.assertEqual( 548 params_file.read(), 549 '\nparam: "androidboot.verifiedbootstate=orange"\n') 550 551 mock_utils.SetExecutable.assert_called_with(self._emulator_path) 552 mock_popen.assert_called_once() 553 self.assertEqual(mock_popen.call_args[0][0], 554 self._GetExpectedEmulatorArgs("-no-window")) 555 self._mock_proc.poll.assert_called() 556 557 558if __name__ == "__main__": 559 unittest.main() 560