• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2#
3# Copyright 2016 - 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"""Tests for acloud.internal.lib.android_build_client."""
18
19import io
20import time
21
22import unittest
23
24from unittest import mock
25
26import apiclient
27
28from acloud import errors
29from acloud.internal import constants
30from acloud.internal.lib import android_build_client
31from acloud.internal.lib import driver_test_lib
32
33
34# pylint: disable=protected-access
35class AndroidBuildClientTest(driver_test_lib.BaseDriverTest):
36    """Test AndroidBuildClient."""
37
38    BUILD_BRANCH = "fake_branch"
39    BUILD_TARGET = "fake_target"
40    BUILD_ID = 12345
41    RESOURCE_ID = "avd-system.tar.gz"
42    LOCAL_DEST = "/fake/local/path"
43    DESTINATION_BUCKET = "fake_bucket"
44
45    def setUp(self):
46        """Set up test."""
47        super().setUp()
48        self.Patch(android_build_client.AndroidBuildClient,
49                   "InitResourceHandle")
50        self.client = android_build_client.AndroidBuildClient(mock.MagicMock())
51        self.client._service = mock.MagicMock()
52
53    # pylint: disable=no-member
54    def testDownloadArtifact(self):
55        """Test DownloadArtifact."""
56        # Create mocks.
57        mock_file = mock.MagicMock()
58        mock_file_io = mock.MagicMock()
59        mock_file_io.__enter__.return_value = mock_file
60        mock_downloader = mock.MagicMock()
61        mock_downloader.next_chunk = mock.MagicMock(
62            side_effect=[(mock.MagicMock(), False), (mock.MagicMock(), True)])
63        mock_api = mock.MagicMock()
64        self.Patch(io, "FileIO", return_value=mock_file_io)
65        self.Patch(
66            apiclient.http,
67            "MediaIoBaseDownload",
68            return_value=mock_downloader)
69        mock_resource = mock.MagicMock()
70        self.client._service.buildartifact = mock.MagicMock(
71            return_value=mock_resource)
72        mock_resource.get_media = mock.MagicMock(return_value=mock_api)
73        # Make the call to the api
74        self.client.DownloadArtifact(self.BUILD_TARGET, self.BUILD_ID,
75                                     self.RESOURCE_ID, self.LOCAL_DEST)
76        # Verify
77        mock_resource.get_media.assert_called_with(
78            buildId=self.BUILD_ID,
79            target=self.BUILD_TARGET,
80            attemptId="0",
81            resourceId=self.RESOURCE_ID)
82        io.FileIO.assert_called_with(self.LOCAL_DEST, mode="wb")
83        mock_call = mock.call(
84            mock_file,
85            mock_api,
86            chunksize=android_build_client.AndroidBuildClient.
87            DEFAULT_CHUNK_SIZE)
88        apiclient.http.MediaIoBaseDownload.assert_has_calls([mock_call])
89        self.assertEqual(mock_downloader.next_chunk.call_count, 2)
90
91    def testDownloadArtifactOSError(self):
92        """Test DownloadArtifact when OSError is raised."""
93        self.Patch(io, "FileIO", side_effect=OSError("fake OSError"))
94        self.assertRaises(errors.DriverError, self.client.DownloadArtifact,
95                          self.BUILD_TARGET, self.BUILD_ID, self.RESOURCE_ID,
96                          self.LOCAL_DEST)
97
98    def testCopyTo(self):
99        """Test CopyTo."""
100        mock_resource = mock.MagicMock()
101        self.client._service.buildartifact = mock.MagicMock(
102            return_value=mock_resource)
103        self.client.CopyTo(
104            build_target=self.BUILD_TARGET,
105            build_id=self.BUILD_ID,
106            artifact_name=self.RESOURCE_ID,
107            destination_bucket=self.DESTINATION_BUCKET,
108            destination_path=self.RESOURCE_ID)
109        mock_resource.copyTo.assert_called_once_with(
110            buildId=self.BUILD_ID,
111            target=self.BUILD_TARGET,
112            attemptId=self.client.DEFAULT_ATTEMPT_ID,
113            artifactName=self.RESOURCE_ID,
114            destinationBucket=self.DESTINATION_BUCKET,
115            destinationPath=self.RESOURCE_ID)
116
117    def testCopyToWithRetry(self):
118        """Test CopyTo with retry."""
119        self.Patch(time, "sleep")
120        mock_resource = mock.MagicMock()
121        mock_api_request = mock.MagicMock()
122        mock_resource.copyTo.return_value = mock_api_request
123        self.client._service.buildartifact.return_value = mock_resource
124        mock_api_request.execute.side_effect = errors.HttpError(503,
125                                                                "fake error")
126        self.assertRaises(
127            errors.HttpError,
128            self.client.CopyTo,
129            build_id=self.BUILD_ID,
130            build_target=self.BUILD_TARGET,
131            artifact_name=self.RESOURCE_ID,
132            destination_bucket=self.DESTINATION_BUCKET,
133            destination_path=self.RESOURCE_ID)
134        self.assertEqual(mock_api_request.execute.call_count, 6)
135
136    def testGetBranch(self):
137        """Test GetBuild."""
138        build_info = {"branch": "aosp-master"}
139        mock_api = mock.MagicMock()
140        mock_build = mock.MagicMock()
141        mock_build.get.return_value = mock_api
142        self.client._service.build = mock.MagicMock(return_value=mock_build)
143        mock_api.execute = mock.MagicMock(return_value=build_info)
144        branch = self.client.GetBranch(self.BUILD_TARGET, self.BUILD_ID)
145        mock_build.get.assert_called_once_with(
146            target=self.BUILD_TARGET,
147            buildId=self.BUILD_ID)
148        self.assertEqual(branch, build_info["branch"])
149
150    def testGetLKGB(self):
151        """Test GetLKGB."""
152        build_info = {"nextPageToken":"Test", "builds": [{"buildId": "3950000"}]}
153        mock_api = mock.MagicMock()
154        mock_build = mock.MagicMock()
155        mock_build.list.return_value = mock_api
156        self.client._service.build = mock.MagicMock(return_value=mock_build)
157        mock_api.execute = mock.MagicMock(return_value=build_info)
158        build_id = self.client.GetLKGB(self.BUILD_TARGET, self.BUILD_BRANCH)
159        mock_build.list.assert_called_once_with(
160            target=self.BUILD_TARGET,
161            branch=self.BUILD_BRANCH,
162            buildAttemptStatus=self.client.BUILD_STATUS_COMPLETE,
163            buildType=self.client.BUILD_TYPE_SUBMITTED,
164            maxResults=self.client.ONE_RESULT,
165            successful=self.client.BUILD_SUCCESSFUL)
166        self.assertEqual(build_id, build_info.get("builds")[0].get("buildId"))
167
168    def testGetFetchBuildArgs(self):
169        """Test GetFetchBuildArgs."""
170        default_build = {constants.BUILD_ID: "1234",
171                         constants.BUILD_BRANCH: "base_branch",
172                         constants.BUILD_TARGET: "base_target"}
173        system_build = {constants.BUILD_ID: "2345",
174                        constants.BUILD_BRANCH: "system_branch",
175                        constants.BUILD_TARGET: "system_target"}
176        kernel_build = {constants.BUILD_ID: "3456",
177                        constants.BUILD_BRANCH: "kernel_branch",
178                        constants.BUILD_TARGET: "kernel_target"}
179        ota_build = {constants.BUILD_ID: "4567",
180                     constants.BUILD_BRANCH: "ota_branch",
181                     constants.BUILD_TARGET: "ota_target"}
182        boot_build = {constants.BUILD_ID: "5678",
183                      constants.BUILD_BRANCH: "boot_branch",
184                      constants.BUILD_TARGET: "boot_target",
185                      constants.BUILD_ARTIFACT: "boot-5.10.img"}
186
187        # Test base image.
188        expected_args = ["-default_build=1234/base_target"]
189        self.assertEqual(
190            expected_args,
191            self.client.GetFetchBuildArgs(default_build, {}, {}, {}, {}, {}))
192
193        # Test base image with system image.
194        expected_args = ["-default_build=1234/base_target",
195                         "-system_build=2345/system_target"]
196        self.assertEqual(
197            expected_args,
198            self.client.GetFetchBuildArgs(
199                default_build, system_build, {}, {}, {}, {}))
200
201        # Test base image with kernel image.
202        expected_args = ["-default_build=1234/base_target",
203                         "-kernel_build=3456/kernel_target"]
204        self.assertEqual(
205            expected_args,
206            self.client.GetFetchBuildArgs(
207                default_build, {}, kernel_build, {}, {}, {}))
208
209        # Test base image with boot image.
210        expected_args = ["-default_build=1234/base_target",
211                         "-boot_build=5678/boot_target",
212                         "-boot_artifact=boot-5.10.img"]
213        self.assertEqual(
214            expected_args,
215            self.client.GetFetchBuildArgs(
216                default_build, {}, {}, boot_build, {}, {}))
217
218        # Test base image with otatools.
219        expected_args = ["-default_build=1234/base_target",
220                         "-otatools_build=4567/ota_target"]
221        self.assertEqual(
222            expected_args,
223            self.client.GetFetchBuildArgs(
224                default_build, {}, {}, {}, {}, ota_build))
225
226    def testGetFetchCertArg(self):
227        """Test GetFetchCertArg."""
228        cert_file_path = "fake_path"
229        certification = (
230            "{"
231            "  \"data\": ["
232            "    {"
233            "      \"credential\": {"
234            "        \"access_token\": \"fake_token\""
235            "      }"
236            "    }"
237            "  ]"
238            "}"
239        )
240        expected_arg = "-credential_source=fake_token"
241        with mock.patch("builtins.open",
242                        mock.mock_open(read_data=certification)):
243            cert_arg = self.client.GetFetchCertArg(cert_file_path)
244            self.assertEqual(expected_arg, cert_arg)
245
246    def testProcessBuild(self):
247        """Test creating "cuttlefish build" strings."""
248        build_id = constants.BUILD_ID
249        branch = constants.BUILD_BRANCH
250        build_target = constants.BUILD_TARGET
251        self.assertEqual(
252            self.client.ProcessBuild(
253                {build_id: "123", branch: "abc", build_target: "def"}),
254            "123/def")
255        self.assertEqual(
256            self.client.ProcessBuild(
257                {build_id: None, branch: "abc", build_target: "def"}),
258            "abc/def")
259        self.assertEqual(
260            self.client.ProcessBuild(
261                {build_id: "123", branch: None, build_target: "def"}),
262            "123/def")
263        self.assertEqual(
264            self.client.ProcessBuild(
265                {build_id: "123", branch: "abc", build_target: None}),
266            "123")
267        self.assertEqual(
268            self.client.ProcessBuild(
269                {build_id: None, branch: "abc", build_target: None}),
270            "abc")
271        self.assertEqual(
272            self.client.ProcessBuild(
273                {build_id: "123", branch: None, build_target: None}),
274            "123")
275        self.assertEqual(
276            self.client.ProcessBuild(
277                {build_id: None, branch: None, build_target: None}),
278            None)
279
280
281if __name__ == "__main__":
282    unittest.main()
283