blob: abb88fc3d640cbefeb4c372cb2573f2506c6af80 [file]
# Copyright 2022 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.project_builder_prefs"""
import argparse
import copy
from pathlib import Path
import shutil
import tempfile
from typing import Any
import unittest
from parameterized import parameterized # type: ignore
from pw_build.project_builder_argparse import add_project_builder_arguments
from pw_build.project_builder_prefs import (
ProjectBuilderPrefs,
default_config,
load_defaults_from_argparse,
)
_BAZEL_COMMAND = 'bazel'
# Prefer bazelisk if available.
if shutil.which('bazelisk'):
_BAZEL_COMMAND = 'bazelisk'
def _create_tempfile(content: str) -> Path:
with tempfile.NamedTemporaryFile(
prefix=f'{__package__}', delete=False
) as output_file:
output_file.write(content.encode('UTF-8'))
return Path(output_file.name)
class TestProjectBuilderPrefs(unittest.TestCase):
"""Tests for ProjectBuilderPrefs."""
maxDiff = None
def test_load_no_existing_files(self) -> None:
# Create a prefs instance with no loaded config.
prefs = ProjectBuilderPrefs(
load_argparse_arguments=add_project_builder_arguments,
project_file=False,
project_user_file=False,
user_file=False,
)
# Construct an expected result config.
expected_config: dict[Any, Any] = {}
# Apply default build_system_commands and build_directories.
expected_config.update(default_config())
expected_config.update(
load_defaults_from_argparse(add_project_builder_arguments)
)
self.assertEqual(
prefs._config, expected_config # pylint: disable=protected-access
)
@parameterized.expand(
[
(
'Manual --build-system-commands on the command line',
# Argparse input
[
'--build-system-command',
'out',
'bazel build',
'--build-system-command',
'out',
'bazel test',
],
# Expected changed config
{
'default_build_targets': [],
'build_directories': [],
'build_system_commands': {
'out': {
'commands': [
{
'command': 'bazel',
'extra_args': ['build'],
},
{
'command': 'bazel',
'extra_args': ['test'],
},
],
},
},
},
),
(
'Empty build directory (no -C) with targets. '
'Ninja manually specified.',
# Argparse input
'--default-build-system ninja docs python.lint'.split(),
# Expected changed config
{
'default_build_system': 'ninja',
'default_build_targets': ['docs', 'python.lint'],
'build_directories': [],
'build_system_commands': {
'default': {
'commands': [{'command': 'ninja', 'extra_args': []}]
}
},
},
),
(
'Empty build directory (no -C) with targets. '
'Ninja not specified.',
# Argparse input
'docs python.lint'.split(),
# Expected changed config
{
'default_build_targets': ['docs', 'python.lint'],
'build_directories': [],
'build_system_commands': {
'default': {
'commands': [{'command': 'ninja', 'extra_args': []}]
}
},
},
),
(
'Empty build directory (no -C) with targets (bazel).',
# Argparse input
(
'--default-build-system bazel //pw_watch/... //pw_build/...'
).split(),
# Expected changed config
{
'default_build_system': 'bazel',
'default_build_targets': [
'//pw_watch/...',
'//pw_build/...',
],
'build_directories': [],
'build_system_commands': {
'default': {
'commands': [
{
'command': _BAZEL_COMMAND,
'extra_args': ['build'],
},
{
'command': _BAZEL_COMMAND,
'extra_args': ['test'],
},
]
}
},
},
),
(
'Targets with no build directory and an additional build '
'directory with targets.',
# Argparse input
'docs python.lint -C out2 python.tests'.split(),
# Expected changed config
{
'default_build_targets': ['docs', 'python.lint'],
'build_directories': [['out2', 'python.tests']],
'build_system_commands': {
'default': {
'commands': [{'command': 'ninja', 'extra_args': []}]
}
},
},
),
(
'',
# Argparse input
'docs python.lint -C out2 python.tests'.split(),
# Expected changed config
{
'default_build_targets': ['docs', 'python.lint'],
'build_directories': [['out2', 'python.tests']],
'build_system_commands': {
'default': {
'commands': [{'command': 'ninja', 'extra_args': []}]
}
},
},
),
(
'Two build directories; one with build system commands the '
'other with none defined.',
# Argparse input
[
'-C',
'out/gn',
'python.lint',
'-C',
'out/bazel',
'//...',
'--build-system-command',
'out/bazel',
'bazel build',
'--build-system-command',
'out/bazel',
'bazel test',
'--logfile',
'out/build.txt',
],
# Expected changed config
{
'default_build_targets': [],
'build_directories': [
['out/gn', 'python.lint'],
['out/bazel', '//...'],
],
'build_system_commands': {
'default': {
'commands': [{'command': 'ninja', 'extra_args': []}]
},
'out/bazel': {
'commands': [
{
'command': 'bazel',
'extra_args': ['build'],
},
{
'command': 'bazel',
'extra_args': ['test'],
},
],
},
},
'logfile': Path('out/build.txt'),
},
),
]
)
def test_apply_command_line_args(
self,
_name,
argparse_args,
expected_config_changes,
):
"""Check command line args are applied to ProjectBuilderPrefs."""
# Load default command line arg values.
parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter,
)
parser = add_project_builder_arguments(parser)
argparse_output = parser.parse_args(argparse_args)
# Create a prefs instance with the test config file.
prefs = ProjectBuilderPrefs(
load_argparse_arguments=add_project_builder_arguments,
project_file=False,
project_user_file=False,
user_file=False,
)
# Save config before apply_command_line_args
# pylint: disable=protected-access
expected_config = copy.deepcopy(prefs._config)
# Run apply_command_line_args
prefs.apply_command_line_args(argparse_output)
# Add the expected changes to the base
expected_config.update(expected_config_changes)
# Check equality
self.assertEqual(prefs._config, expected_config)
# pylint: enable=protected-access
if __name__ == '__main__':
unittest.main()