xref: /aosp_15_r20/external/angle/build/fuchsia/gcs_download_test.py (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker#!/usr/bin/env vpython3
2*8975f5c5SAndroid Build Coastguard Worker# Copyright 2022 The Chromium Authors
3*8975f5c5SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker# found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker
6*8975f5c5SAndroid Build Coastguard Workerimport os
7*8975f5c5SAndroid Build Coastguard Workerimport subprocess
8*8975f5c5SAndroid Build Coastguard Workerimport tarfile
9*8975f5c5SAndroid Build Coastguard Workerimport unittest
10*8975f5c5SAndroid Build Coastguard Workerfrom unittest import mock
11*8975f5c5SAndroid Build Coastguard Worker
12*8975f5c5SAndroid Build Coastguard Workerfrom gcs_download import DownloadAndUnpackFromCloudStorage
13*8975f5c5SAndroid Build Coastguard Worker
14*8975f5c5SAndroid Build Coastguard Worker
15*8975f5c5SAndroid Build Coastguard Workerdef _mock_task(status_code: int = 0, stderr: str = '') -> mock.Mock:
16*8975f5c5SAndroid Build Coastguard Worker  task_mock = mock.Mock()
17*8975f5c5SAndroid Build Coastguard Worker  attrs = {
18*8975f5c5SAndroid Build Coastguard Worker      'returncode': status_code,
19*8975f5c5SAndroid Build Coastguard Worker      'wait.return_value': status_code,
20*8975f5c5SAndroid Build Coastguard Worker      'communicate.return_value': (None, stderr.encode()),
21*8975f5c5SAndroid Build Coastguard Worker  }
22*8975f5c5SAndroid Build Coastguard Worker  task_mock.configure_mock(**attrs)
23*8975f5c5SAndroid Build Coastguard Worker
24*8975f5c5SAndroid Build Coastguard Worker  return task_mock
25*8975f5c5SAndroid Build Coastguard Worker
26*8975f5c5SAndroid Build Coastguard Worker
27*8975f5c5SAndroid Build Coastguard Worker@mock.patch('tempfile.TemporaryDirectory')
28*8975f5c5SAndroid Build Coastguard Worker@mock.patch('gs_util_wrapper.subprocess.run')
29*8975f5c5SAndroid Build Coastguard Worker@mock.patch('tarfile.open')
30*8975f5c5SAndroid Build Coastguard Worker@unittest.skipIf(os.name == 'nt', 'Fuchsia tests not supported on Windows')
31*8975f5c5SAndroid Build Coastguard Workerclass TestDownloadAndUnpackFromCloudStorage(unittest.TestCase):
32*8975f5c5SAndroid Build Coastguard Worker  def testHappyPath(self, mock_tarfile, mock_run, mock_tmp_dir):
33*8975f5c5SAndroid Build Coastguard Worker    mock_run.return_value = _mock_task()
34*8975f5c5SAndroid Build Coastguard Worker
35*8975f5c5SAndroid Build Coastguard Worker    tmp_dir = os.path.join('some', 'tmp', 'dir')
36*8975f5c5SAndroid Build Coastguard Worker    mock_tmp_dir.return_value.__enter__.return_value = tmp_dir
37*8975f5c5SAndroid Build Coastguard Worker
38*8975f5c5SAndroid Build Coastguard Worker    mock_seq = mock.Mock()
39*8975f5c5SAndroid Build Coastguard Worker    mock_seq.attach_mock(mock_run, 'Run')
40*8975f5c5SAndroid Build Coastguard Worker    mock_seq.attach_mock(mock_tarfile, 'Untar')
41*8975f5c5SAndroid Build Coastguard Worker    mock_seq.attach_mock(mock_tmp_dir, 'MkTmpD')
42*8975f5c5SAndroid Build Coastguard Worker
43*8975f5c5SAndroid Build Coastguard Worker    output_dir = os.path.join('output', 'dir')
44*8975f5c5SAndroid Build Coastguard Worker    DownloadAndUnpackFromCloudStorage('gs://some/url', output_dir)
45*8975f5c5SAndroid Build Coastguard Worker
46*8975f5c5SAndroid Build Coastguard Worker    image_tgz_path = os.path.join(tmp_dir, 'image.tgz')
47*8975f5c5SAndroid Build Coastguard Worker    mock_seq.assert_has_calls([
48*8975f5c5SAndroid Build Coastguard Worker        mock.call.MkTmpD(),
49*8975f5c5SAndroid Build Coastguard Worker        mock.call.MkTmpD().__enter__(),
50*8975f5c5SAndroid Build Coastguard Worker        mock.call.Run(mock.ANY, check=True),
51*8975f5c5SAndroid Build Coastguard Worker        mock.call.Untar(name=image_tgz_path, mode='r|gz'),
52*8975f5c5SAndroid Build Coastguard Worker        mock.call.Untar().extractall(path=output_dir),
53*8975f5c5SAndroid Build Coastguard Worker        mock.call.MkTmpD().__exit__(None, None, None)
54*8975f5c5SAndroid Build Coastguard Worker    ],
55*8975f5c5SAndroid Build Coastguard Worker                              any_order=False)
56*8975f5c5SAndroid Build Coastguard Worker
57*8975f5c5SAndroid Build Coastguard Worker    # Verify cmd.
58*8975f5c5SAndroid Build Coastguard Worker    cmd = ' '.join(mock_run.call_args[0][0])
59*8975f5c5SAndroid Build Coastguard Worker    self.assertRegex(
60*8975f5c5SAndroid Build Coastguard Worker        cmd,
61*8975f5c5SAndroid Build Coastguard Worker        r'.*python3?\s.*gsutil.py\s+cp\s+gs://some/url\s+' + image_tgz_path)
62*8975f5c5SAndroid Build Coastguard Worker
63*8975f5c5SAndroid Build Coastguard Worker  def testFailedTarOpen(self, mock_tarfile, mock_run, mock_tmp_dir):
64*8975f5c5SAndroid Build Coastguard Worker    mock_run.return_value = _mock_task(stderr='some error')
65*8975f5c5SAndroid Build Coastguard Worker    mock_tarfile.side_effect = tarfile.ReadError()
66*8975f5c5SAndroid Build Coastguard Worker
67*8975f5c5SAndroid Build Coastguard Worker    with self.assertRaises(tarfile.ReadError):
68*8975f5c5SAndroid Build Coastguard Worker      DownloadAndUnpackFromCloudStorage('', '')
69*8975f5c5SAndroid Build Coastguard Worker      mock_tmp_dir.assert_called_once()
70*8975f5c5SAndroid Build Coastguard Worker      mock_run.assert_called_once()
71*8975f5c5SAndroid Build Coastguard Worker      mock_tarfile.assert_called_once()
72*8975f5c5SAndroid Build Coastguard Worker
73*8975f5c5SAndroid Build Coastguard Worker  def testBadTaskStatusCode(self, mock_tarfile, mock_run, mock_tmp_dir):
74*8975f5c5SAndroid Build Coastguard Worker    mock_run.side_effect = subprocess.CalledProcessError(cmd='some/command',
75*8975f5c5SAndroid Build Coastguard Worker                                                         returncode=1)
76*8975f5c5SAndroid Build Coastguard Worker
77*8975f5c5SAndroid Build Coastguard Worker    with self.assertRaises(subprocess.CalledProcessError):
78*8975f5c5SAndroid Build Coastguard Worker      DownloadAndUnpackFromCloudStorage('', '')
79*8975f5c5SAndroid Build Coastguard Worker      mock_run.assert_called_once()
80*8975f5c5SAndroid Build Coastguard Worker      mock_tarfile.assert_not_called()
81*8975f5c5SAndroid Build Coastguard Worker      mock_tmp_dir.assert_called_once()
82*8975f5c5SAndroid Build Coastguard Worker
83*8975f5c5SAndroid Build Coastguard Worker
84*8975f5c5SAndroid Build Coastguard Workerif __name__ == '__main__':
85*8975f5c5SAndroid Build Coastguard Worker  unittest.main()
86