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