| # 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']), |
| ) |