blob: 213017f016921bea0e1f1aa71ab8ce32a15ed51b [file] [log] [blame]
# Copyright 2020 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.
"""Recipe for testing Pigweed using developer env setup scripts."""
from __future__ import annotations
import re
from typing import TYPE_CHECKING
from PB.recipes.pigweed.envtest import InputProperties
if TYPE_CHECKING: # pragma: no cover
from typing import Generator
from recipe_engine import config_types, recipe_api, recipe_test_api
DEPS = [
'fuchsia/macos_sdk',
'pigweed/checkout',
'pigweed/ci_status',
'pigweed/save_logs',
'recipe_engine/context',
'recipe_engine/defer',
'recipe_engine/file',
'recipe_engine/path',
'recipe_engine/platform',
'recipe_engine/properties',
'recipe_engine/step',
]
PROPERTIES = InputProperties
def RunSteps(api: recipe_api.RecipeScriptApi, props: InputProperties):
if res := api.ci_status.exit_early_in_recipe_testing_if_failing():
return res # pragma: no cover
checkout: api.checkout.CheckoutContext = api.checkout(
props.checkout_options
)
run: config_types.Path = api.path.start_dir / 'run'
api.file.ensure_directory('mkdir run', run)
setup_path: config_types.Path = checkout.root / (
props.setup_path or 'bootstrap.sh'
)
env: dict[str, str] = {}
for entry in props.environment_variables:
k, v = entry.split(u'=', 1)
env[str(k)] = str(v)
env_root: config_types.Path = api.path.start_dir / 'environment'
env['PW_ENVIRONMENT_ROOT'] = env_root
env['PW_PRESUBMIT_DISABLE_SUBPROCESS_CAPTURE'] = '1'
env['PW_ENVIRONMENT_NO_ERROR_ON_UNRECOGNIZED'] = '1'
setup_path_dir: config_types.Path = api.path.abs_to_path(
api.path.dirname(setup_path)
)
if api.platform.is_win and api.path.splitext(setup_path)[1] == '.sh':
setup_name: str = api.path.basename(setup_path)
setup_name: str = api.path.splitext(setup_name)[0] + '.bat'
setup_path: config_types.Path = setup_path_dir / setup_name
command: str = (
str(props.command)
or 'pw --directory $PW_ROOT --loglevel debug presubmit '
'--step gn_clang_build'
)
# Replace '$ABC' with '%ABC%' on Windows.
if api.platform.is_win:
command = re.sub(r'\$([\w_]+)\b', r'%\1%', command)
bootstrap_command: str = '{dot}{env_setup}'.format(
dot='call ' if api.platform.is_win else '. ',
# Without the replace here we end up with paths that have no
# separators. Not sure why, but this fixes it.
env_setup=api.path.realpath(setup_path).replace('\\', '\\\\'),
)
commands: list[str] = []
# Call bootstrap multiple times because occasionally there are issues with
# subsequent calls but not the first.
for _ in range(props.bootstrap_count or 2):
commands.append(bootstrap_command)
commands.append(command)
sh_source: str = ''.join(x + '\n' for x in commands)
base: str = 'run.bat' if api.platform.is_win else 'run.sh'
sh_path: config_types.Path = setup_path_dir / base
api.file.write_text(f'write {base}', sh_path, sh_source)
with api.macos_sdk(), api.defer.context() as defer:
with api.context(cwd=run, env=env):
if api.platform.is_win:
result = defer(api.step, base, [sh_path])
else:
result = defer(
api.step, base, [props.shell or 'sh', '-x', sh_path]
)
api.save_logs(
dirs=(env_root,),
step_passed=result.is_ok(),
step_name='envtest',
)
def GenTests(api) -> Generator[recipe_test_api.TestData, None, None]:
def properties(**kwargs):
props = InputProperties(**kwargs)
props.checkout_options.CopyFrom(api.checkout.git_options())
return api.properties(props)
yield api.test(
'pigweed',
properties(),
api.checkout.ci_test_data(),
)
yield api.test(
'windows',
properties(),
api.platform.name('win'),
api.checkout.ci_test_data(),
)
yield api.test(
'fail',
properties(),
api.checkout.ci_test_data(),
api.step_data('run.sh', retcode=1),
status='FAILURE',
)
yield api.test(
'environment_variables',
properties(environment_variables=['PW_BOOTSTRAP_PY27=1']),
)