blob: d20e5010426efde1fc56c5881b522f590052799e [file] [log] [blame] [edit]
#!/usr/bin/env fuchsia-vendored-python
# Copyright 2023 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import os
import subprocess
import sys
import tempfile
import unittest
from pathlib import Path
from unittest import mock
import dlwrap
import cl_utils
import remote_action
import remotetool
from typing import Tuple
class MainArgParserTests(unittest.TestCase):
def test_defaults(self):
args = dlwrap._MAIN_ARG_PARSER.parse_args([])
self.assertFalse(args.verbose)
self.assertFalse(args.dry_run)
self.assertFalse(args.undownload)
self.assertEqual(args.download, [])
self.assertEqual(args.download_list, [])
self.assertEqual(args.command, [])
def test_verbose(self):
args = dlwrap._MAIN_ARG_PARSER.parse_args(['--verbose'])
self.assertTrue(args.verbose)
def test_dry_run(self):
args = dlwrap._MAIN_ARG_PARSER.parse_args(['--dry-run'])
self.assertTrue(args.dry_run)
def test_undownload(self):
args = dlwrap._MAIN_ARG_PARSER.parse_args(['--undownload'])
self.assertTrue(args.undownload)
def test_download(self):
args = dlwrap._MAIN_ARG_PARSER.parse_args(
['--download', 'aa.o', 'bb.o'])
self.assertEqual(args.download, [Path('aa.o'), Path('bb.o')])
def test_download_list(self):
args = dlwrap._MAIN_ARG_PARSER.parse_args(
['--download_list', 'f1.rsp', 'f2.rsp'])
self.assertEqual(args.download_list, [Path('f1.rsp'), Path('f2.rsp')])
def test_command(self):
args = dlwrap._MAIN_ARG_PARSER.parse_args(['--', 'cat', 'dog.txt'])
self.assertEqual(args.command, ['cat', 'dog.txt'])
_fake_downloader = remotetool.RemoteTool(
reproxy_cfg={
"service": "foo.build.service:443",
"instance": "my-project/remote/instances/default",
})
def _fake_download(
packed_args: Tuple[Path, remotetool.RemoteTool, Path]
) -> Tuple[Path, cl_utils.SubprocessResult]:
# For mocking dlwrap._download_for_mp.
# defined because multiprocessing cannot serialize mocks
stub_path, downloader, working_dir_abs = packed_args
return (stub_path, cl_utils.SubprocessResult(0))
def _fake_download_fail(
packed_args: Tuple[Path, remotetool.RemoteTool, Path]
) -> Tuple[Path, cl_utils.SubprocessResult]:
# For mocking dlwrap._download_for_mp.
# defined because multiprocessing cannot serialize mocks
stub_path, downloader, working_dir_abs = packed_args
return (stub_path, cl_utils.SubprocessResult(1))
class DownloadArtifactsTests(unittest.TestCase):
def _stub_info(self, path: Path) -> remote_action.DownloadStubInfo:
return remote_action.DownloadStubInfo(
path=path,
type="file",
blob_digest='f33333df44444ce/124',
action_digest='47ac8eb38351/41',
build_id='50f93-a38e-b112',
)
def test_success(self):
path = 'road/to/perdition.obj'
exec_root = Path('/exec/root')
working_dir = exec_root / 'work'
download_status = 0
with mock.patch.object(dlwrap, '_download_for_mp',
new=_fake_download) as mock_download:
status = dlwrap.download_artifacts(
[path],
downloader=_fake_downloader,
working_dir_abs=working_dir)
self.assertEqual(status, download_status)
def test_failure(self):
path = 'highway/to/hell.obj'
exec_root = Path('/exec/root')
working_dir = exec_root / 'work'
download_status = 1
with mock.patch.object(dlwrap, '_download_for_mp',
new=_fake_download_fail) as mock_download:
status = dlwrap.download_artifacts(
[path],
downloader=_fake_downloader,
working_dir_abs=working_dir)
self.assertEqual(status, download_status)
class MainTests(unittest.TestCase):
def test_dry_run(self):
path = 'dir/file.o'
exec_root = Path('/exec/root')
working_dir = exec_root / 'work'
with mock.patch.object(dlwrap, 'download_artifacts',
return_value=0) as mock_download:
with mock.patch.object(subprocess, 'call') as mock_run:
status = dlwrap._main(
['--dry-run', '--', 'cat', 'foo'],
downloader=_fake_downloader,
working_dir_abs=working_dir)
self.assertEqual(status, 0)
mock_run.assert_not_called()
def test_download_fail(self):
path = 'dir/file.o'
exec_root = Path('/exec/root')
working_dir = exec_root / 'work'
with mock.patch.object(dlwrap, 'download_artifacts',
return_value=1) as mock_download:
with mock.patch.object(subprocess, 'call') as mock_run:
status = dlwrap._main(
['--', 'cat', 'foo'],
downloader=_fake_downloader,
working_dir_abs=working_dir)
mock_download.assert_called_once()
self.assertEqual(status, 1)
mock_run.assert_not_called()
def test_no_command(self):
path = 'dir/file.o'
exec_root = Path('/exec/root')
working_dir = exec_root / 'work'
with mock.patch.object(dlwrap, 'download_artifacts',
return_value=0) as mock_download:
with mock.patch.object(subprocess, 'call',
return_value=0) as mock_run:
status = dlwrap._main(
[],
downloader=_fake_downloader,
working_dir_abs=working_dir)
self.assertEqual(status, 0)
mock_run.assert_not_called()
def test_success(self):
path = 'dir/file.o'
exec_root = Path('/exec/root')
working_dir = exec_root / 'work'
with mock.patch.object(dlwrap, 'download_artifacts',
return_value=0) as mock_download:
with mock.patch.object(subprocess, 'call',
return_value=0) as mock_run:
status = dlwrap._main(
['--', 'cat', 'foo'],
downloader=_fake_downloader,
working_dir_abs=working_dir)
self.assertEqual(status, 0)
mock_run.assert_called_with(['cat', 'foo'])
def test_success_from_list(self):
path = 'dir/file.o'
rspfile = 'f.rsp'
exec_root = Path('/exec/root')
working_dir = exec_root / 'work'
with mock.patch.object(dlwrap, 'download_artifacts',
return_value=0) as mock_download:
with mock.patch.object(subprocess, 'call',
return_value=0) as mock_run:
with mock.patch.object(cl_utils, 'expand_paths_from_files',
return_value=iter(
[Path(path)])) as mock_expand_files:
status = dlwrap._main(
['--download_list', rspfile, '--', 'cat', 'foo'],
downloader=_fake_downloader,
working_dir_abs=working_dir)
self.assertEqual(status, 0)
mock_expand_files.assert_called_with([Path(rspfile)])
mock_run.assert_called_with(['cat', 'foo'])
def test_undownload(self):
path = 'dir/file.o'
exec_root = Path('/exec/root')
working_dir = exec_root / 'work'
with mock.patch.object(dlwrap, 'download_artifacts',
return_value=0) as mock_download:
with mock.patch.object(remote_action,
'undownload') as mock_undownload:
with mock.patch.object(subprocess, 'call',
return_value=0) as mock_run:
status = dlwrap._main(
[
'--download', 'fetch.me', '--undownload', '--',
'cat', 'foo'
],
downloader=_fake_downloader,
working_dir_abs=working_dir)
self.assertEqual(status, 0)
mock_download.assert_not_called()
mock_undownload.assert_called()
mock_run.assert_not_called()
if __name__ == '__main__':
unittest.main()