blob: 2314cc7f14330ffce49b574fa3cb9aefadd38bf4 [file] [log] [blame]
# Copyright 2021 The Pigweed Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
"""Tests for pw_build.create_python_tree"""
import os
from pathlib import Path
import tempfile
from typing import List
import unittest
from parameterized import parameterized # type: ignore
from pw_build.python_package import PythonPackage
from pw_build.create_python_tree import build_python_tree, copy_extra_files
def _setup_cfg(package_name: str) -> str:
return f'''
[metadata]
name = {package_name}
version = 0.0.1
author = Pigweed Authors
author_email = pigweed-developers@googlegroups.com
description = Pigweed swiss-army knife
[options]
packages = find:
zip_safe = False
[options.package_data]
{package_name} =
py.typed
'''
def _create_fake_python_package(location: Path, files: List[str],
package_name: str) -> None:
for file in files:
destination = location / file
destination.parent.mkdir(parents=True, exist_ok=True)
text = f'"""{package_name}"""'
if str(destination).endswith('setup.cfg'):
text = _setup_cfg(package_name)
destination.write_text(text)
class TestCreatePythonTree(unittest.TestCase):
"""Integration tests for create_python_tree."""
def setUp(self):
self.maxDiff = None # pylint: disable=invalid-name
# Save the starting working directory for returning to later.
self.start_dir = Path.cwd()
# Create a temp out directory
self.temp_dir = tempfile.TemporaryDirectory()
def tearDown(self):
# cd to the starting dir before cleaning up the temp out directory
os.chdir(self.start_dir)
# Delete the TemporaryDirectory
self.temp_dir.cleanup()
def _check_result_paths_equal(self, install_dir, expected_results) -> None:
# Normalize path strings to posix before comparing.
expected_paths = set(Path(p).as_posix() for p in expected_results)
actual_paths = set(
p.relative_to(install_dir).as_posix()
for p in install_dir.glob('**/*') if p.is_file())
self.assertEqual(expected_paths, actual_paths)
@parameterized.expand([
(
# Test name
'working case',
# Package name
'mars',
# File list
[
'planets/BUILD.mars_rocket',
'planets/mars/__init__.py',
'planets/mars/__main__.py',
'planets/mars/moons/__init__.py',
'planets/mars/moons/deimos.py',
'planets/mars/moons/phobos.py',
'planets/hohmann_transfer_test.py',
'planets/pyproject.toml',
'planets/setup.cfg',
],
# Extra_files
[],
# Package definition
{
'generate_setup': {
'metadata': {
'name': 'mars',
'version': '0.0.1'
},
},
'inputs': [
],
'setup_sources': [
'planets/pyproject.toml',
'planets/setup.cfg',
],
'sources': [
'planets/mars/__init__.py',
'planets/mars/__main__.py',
'planets/mars/moons/__init__.py',
'planets/mars/moons/deimos.py',
'planets/mars/moons/phobos.py',
],
'tests': [
'planets/hohmann_transfer_test.py',
],
},
# Output file list
[
'mars/__init__.py',
'mars/__main__.py',
'mars/moons/__init__.py',
'mars/moons/deimos.py',
'mars/moons/phobos.py',
'mars/tests/hohmann_transfer_test.py',
],
),
(
# Test name
'with extra files',
# Package name
'saturn',
# File list
[
'planets/BUILD.saturn_rocket',
'planets/hohmann_transfer_test.py',
'planets/pyproject.toml',
'planets/saturn/__init__.py',
'planets/saturn/__main__.py',
'planets/saturn/misson.py',
'planets/saturn/moons/__init__.py',
'planets/saturn/moons/enceladus.py',
'planets/saturn/moons/iapetus.py',
'planets/saturn/moons/rhea.py',
'planets/saturn/moons/titan.py',
'planets/setup.cfg',
'planets/setup.py',
],
# Extra files
[
'planets/BUILD.saturn_rocket > out/saturn/BUILD.rocket',
],
# Package definition
{
'inputs': [
],
'setup_sources': [
'planets/pyproject.toml',
'planets/setup.cfg',
'planets/setup.py',
],
'sources': [
'planets/saturn/__init__.py',
'planets/saturn/__main__.py',
'planets/saturn/misson.py',
'planets/saturn/moons/__init__.py',
'planets/saturn/moons/enceladus.py',
'planets/saturn/moons/iapetus.py',
'planets/saturn/moons/rhea.py',
'planets/saturn/moons/titan.py',
],
'tests': [
'planets/hohmann_transfer_test.py',
]
},
# Output file list
[
'saturn/BUILD.rocket',
'saturn/__init__.py',
'saturn/__main__.py',
'saturn/misson.py',
'saturn/moons/__init__.py',
'saturn/moons/enceladus.py',
'saturn/moons/iapetus.py',
'saturn/moons/rhea.py',
'saturn/moons/titan.py',
'saturn/tests/hohmann_transfer_test.py',
],
),
]) # yapf: disable
def test_build_python_tree(
self,
_test_name,
package_name,
file_list,
extra_files,
package_definition,
expected_file_list,
) -> None:
"""Check results of build_python_tree and copy_extra_files."""
temp_root = Path(self.temp_dir.name)
_create_fake_python_package(temp_root, file_list, package_name)
os.chdir(temp_root)
install_dir = temp_root / 'out'
package = PythonPackage.from_dict(**package_definition)
build_python_tree(python_packages=[package],
tree_destination_dir=install_dir,
include_tests=True)
copy_extra_files(extra_files)
# Check expected files are in place.
self._check_result_paths_equal(install_dir, expected_file_list)
@parameterized.expand([
(
# Test name
'everything in correct locations',
# Package name
'planets',
# File list
[
'BUILD.mars_rocket',
],
# Extra_files
[
'BUILD.mars_rocket > out/mars/BUILD.rocket',
],
# Output file list
[
'mars/BUILD.rocket',
],
# Should raise exception
None,
),
(
# Test name
'missing source files',
# Package name
'planets',
# File list
[
'BUILD.mars_rocket',
],
# Extra_files
[
'BUILD.venus_rocket > out/venus/BUILD.rocket',
],
# Output file list
[],
# Should raise exception
FileNotFoundError,
),
(
# Test name
'existing destination files',
# Package name
'planets',
# File list
[
'BUILD.jupiter_rocket',
'out/jupiter/BUILD.rocket',
],
# Extra_files
[
'BUILD.jupiter_rocket > out/jupiter/BUILD.rocket',
],
# Output file list
[],
# Should raise exception
FileExistsError,
),
]) # yapf: disable
def test_copy_extra_files(
self,
_test_name,
package_name,
file_list,
extra_files,
expected_file_list,
should_raise_exception,
) -> None:
"""Check results of build_python_tree and copy_extra_files."""
temp_root = Path(self.temp_dir.name)
_create_fake_python_package(temp_root, file_list, package_name)
os.chdir(temp_root)
install_dir = temp_root / 'out'
# If exceptions should be raised
if should_raise_exception:
with self.assertRaises(should_raise_exception):
copy_extra_files(extra_files)
return
# Do the copy
copy_extra_files(extra_files)
# Check expected files are in place.
self._check_result_paths_equal(install_dir, expected_file_list)
if __name__ == '__main__':
unittest.main()