1#!/usr/bin/env python
2#
3# Copyright (C) 2017 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 sys
20import unittest
21
22try:
23    from unittest import mock
24except ImportError:
25    import mock
26
27from host_controller.build import build_flasher
28
29
30class BuildFlasherTest(unittest.TestCase):
31    """Tests for Build Flasher"""
32
33    @mock.patch(
34        "host_controller.build.build_flasher.android_device")
35    @mock.patch("host_controller.build.build_flasher.os")
36    def testFlashGSIBadPath(self, mock_os, mock_class):
37        flasher = build_flasher.BuildFlasher("thisismyserial")
38        mock_os.path.exists.return_value = False
39        with self.assertRaises(ValueError) as cm:
40            flasher.FlashGSI("notexists.img")
41        self.assertEqual("Couldn't find system image at notexists.img",
42                         str(cm.exception))
43
44    @mock.patch(
45        "host_controller.build.build_flasher.android_device")
46    @mock.patch("host_controller.build.build_flasher.os")
47    def testFlashGSISystemOnly(self, mock_os, mock_class):
48        mock_device = mock.Mock()
49        mock_class.AndroidDevice.return_value = mock_device
50        flasher = build_flasher.BuildFlasher("thisismyserial")
51        mock_os.path.exists.return_value = True
52        flasher.FlashGSI("exists.img")
53        mock_device.fastboot.erase.assert_any_call('system')
54        mock_device.fastboot.flash.assert_any_call('system', 'exists.img')
55        mock_device.fastboot.erase.assert_any_call('metadata')
56
57    @mock.patch(
58        "host_controller.build.build_flasher.android_device")
59    def testFlashall(self, mock_class):
60        mock_device = mock.Mock()
61        mock_class.AndroidDevice.return_value = mock_device
62        flasher = build_flasher.BuildFlasher("thisismyserial")
63        flasher.Flashall("path/to/dir")
64        mock_device.fastboot.flashall.assert_called_with()
65
66    @mock.patch(
67        "host_controller.build.build_flasher.android_device")
68    def testEmptySerial(self, mock_class):
69        mock_class.list_adb_devices.return_value = ['oneserial']
70        flasher = build_flasher.BuildFlasher(serial="")
71        mock_class.AndroidDevice.assert_called_with(
72            "oneserial", device_callback_port=-1)
73
74    @mock.patch(
75        "host_controller.build.build_flasher.android_device")
76    def testFlashUsingCustomBinary(self, mock_class):
77        """Test for FlashUsingCustomBinary().
78
79            Tests if the method passes right args to customflasher
80            and the execution path of the method.
81        """
82        mock_device = mock.Mock()
83        mock_class.AndroidDevice.return_value = mock_device
84        flasher = build_flasher.BuildFlasher("mySerial", "myCustomBinary")
85
86        mock_device.isBootloaderMode = False
87        device_images = {"img": "my/image/path"}
88        flasher.FlashUsingCustomBinary(device_images, "reboottowhatever",
89                                       ["myarg"])
90        mock_device.adb.reboot.assert_called_with("reboottowhatever")
91        mock_device.customflasher.ExecCustomFlasherCmd.assert_called_with(
92            "myarg", "my/image/path")
93
94        mock_device.reset_mock()
95        mock_device.isBootloaderMode = True
96        device_images["img"] = "my/other/image/path"
97        flasher.FlashUsingCustomBinary(device_images, "reboottowhatever",
98                                       ["myarg"])
99        mock_device.adb.reboot.assert_not_called()
100        mock_device.customflasher.ExecCustomFlasherCmd.assert_called_with(
101            "myarg", "my/other/image/path")
102
103    @mock.patch("host_controller.build.build_flasher.android_device")
104    @mock.patch("host_controller.build.build_flasher.logging")
105    @mock.patch("host_controller.build.build_flasher.cmd_utils")
106    @mock.patch("host_controller.build.build_flasher.os")
107    @mock.patch("host_controller.build.build_flasher.open",
108                new_callable=mock.mock_open)
109    def testRepackageArtifacts(self, mock_open, mock_os, mock_cmd_utils,
110                               mock_logger, mock_class):
111        """Test for RepackageArtifacts().
112
113            Tests if the method executes in correct path regarding
114            given arguments.
115        """
116        mock_device = mock.Mock()
117        mock_class.AndroidDevice.return_value = mock_device
118        flasher = build_flasher.BuildFlasher("serial")
119        device_images = {
120            "system.img": "/my/tmp/path/system.img",
121            "vendor.img": "/my/tmp/path/vendor.img"
122        }
123        mock_cmd_utils.ExecuteOneShellCommand.return_value = "", "", 0
124        ret = flasher.RepackageArtifacts(device_images, "tar.md5")
125        self.assertEqual(ret, True)
126        self.assertIsNotNone(device_images["img"])
127
128        ret = flasher.RepackageArtifacts(device_images, "incorrect")
129        self.assertFalse(ret)
130        mock_logger.error.assert_called_with(
131            "Please specify correct repackage form: --repackage=%s" ,"incorrect")
132
133
134if __name__ == "__main__":
135    unittest.main()
136