blob: a0765cae14b3fdd09e1c2e5fbfc4ee3633a104af [file] [log] [blame]
#!/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 argparse
import json
import os
import shutil
import sys
import unittest
from collections import defaultdict
from contextlib import contextmanager
from pathlib import Path
from tempfile import TemporaryDirectory
from typing import List
from unittest.mock import patch
# Import the real devshell `fx publish` python implementation.
import publish
@contextmanager
def patch_cwd(path):
assert path and os.path.isdir(path), f"Expected {path} to be a directory."
path = Path(path)
cwd = os.getcwd()
with TemporaryDirectory() as temp_dir:
working_dir = Path(temp_dir) / path
# Avoid polluting the build dir: Keep test hermetic by copying the test
# dir to a working temporary directory.
shutil.copytree(path, working_dir)
# "./{path}" should resolve to an equivalent directory for cwd="{cwd}"
# and cwd="{working_dir}".
target = Path(*[".."] * (len(path.parts) - 1))
symlink = working_dir / path
symlink.parent.mkdir(parents=True, exist_ok=True)
symlink.symlink_to(target)
try:
os.chdir(working_dir)
yield
finally:
os.chdir(cwd)
symlink.unlink()
class FxPublishTest(unittest.TestCase):
TEST_DIR = None
EXPECTED_CACHE_PACKAGES = []
def setUp(self) -> None:
self.fx_commands = defaultdict(lambda: [])
def fake_fx_command(self, subcommand: str, *args: str) -> List[str]:
self.fx_commands[subcommand].append(args)
return ["true", subcommand, *args]
def _test_publish_cache(self, test_dir: str) -> None:
with (
patch(
"sys.argv",
[
publish.__file__,
"cache",
"--quiet",
],
),
patch("publish.fx_command", self.fake_fx_command),
patch_cwd(test_dir),
):
# Launches the real devshell publish tool under the fake build
# directory.
self.assertEqual(publish.main(), 0)
# Check that the right ninja targets are built.
self.assertEqual(
[set(build_args) for build_args in self.fx_commands["build"]],
[
set(
[
"//build/images/updates:prepare_publish",
"//build/images/updates:assembly_cache_packages.list",
]
)
],
)
# Check that the required packages are published.
repo_targets = json.loads(
Path("amber-files/repository/targets.json").read_text()
)
for cache_package in FxPublishTest.EXPECTED_CACHE_PACKAGES:
self.assertIn(
cache_package, repo_targets["signed"]["targets"].keys()
)
def test_publish_cache(self) -> None:
self._test_publish_cache(FxPublishTest.TEST_DIR)
def main() -> None:
parser = argparse.ArgumentParser(
description="An integration test for `fx publish`."
)
parser.add_argument(
"--test-dir",
required=True,
help="The fake fx publish working directory.",
)
parser.add_argument(
"--expect-cache-packages",
nargs="*",
default=[],
help="A list of cache packages that are expected to be published.",
)
args, unknownargs = parser.parse_known_args()
FxPublishTest.TEST_DIR = args.test_dir
FxPublishTest.EXPECTED_CACHE_PACKAGES = args.expect_cache_packages
unittest.main(argv=[sys.argv[0], *unknownargs])
if __name__ == "__main__":
main()