318 lines
10 KiB
Python
318 lines
10 KiB
Python
# 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
|
|
from pw_build.generate_python_package import _PYPROJECT_FILE as PYPROJECT_TEXT
|
|
|
|
|
|
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)
|
|
elif str(destination).endswith('pyproject.toml'):
|
|
# Make sure pyproject.toml file has valid syntax.
|
|
text = PYPROJECT_TEXT
|
|
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()
|