| # Copyright 2016 The Fuchsia Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| from recipe_engine import recipe_test_api |
| from RECIPE_MODULES.fuchsia.jiri.api import JiriApi |
| |
| |
| class JiriTestApi(recipe_test_api.RecipeTestApi): |
| # Exposed for use in examples |
| RebaseError = JiriApi.RebaseError |
| |
| @staticmethod |
| def read_manifest_element( |
| api, |
| manifest, # pylint: disable=unused-argument |
| element_type, # pylint: disable=unused-argument |
| element_name, |
| test_output, |
| nesting=None): |
| """Simulates a call to JiriApi.read_manifest_element. |
| |
| Use this in-favor of creating testing step data directly in a test case. It |
| prevents the need for a test_data= parameter JiriApi.read_manfiest_element, |
| the need to put test code inline with production code, and the need to |
| understand how the returned step provides output (via step_result.sdout, |
| step_result.json.output, etc). Calling this is like "injecting a step" into |
| the execution pipeline. |
| |
| Args: |
| api (RecipeTestApi): The test api. |
| test_output (Dict): The data to use as JSON in the step's stdout response. |
| nesting (str or None): The name of the parent step, if not None. |
| |
| (See JiriApi for docs on remaining args) |
| |
| Returns: |
| recipe_test_api.TestData simulating a step to read data from a manifest. |
| """ |
| # `manifest` and `element_type` are not used by this method. Including them |
| # as parameters is intentionally done for parity between this method's and |
| # JiriApi.read_manifest_element's signatures. |
| |
| step_name = 'read_manifest_%s.jiri manifest' % element_name |
| if nesting: |
| step_name = '%s.%s' % (nesting, step_name) # pragma: no cover |
| step_output = api.json.output(test_output) |
| return api.step_data(step_name, stdout=step_output) |
| |
| @property |
| def read_manifest_project_output(self): |
| """A dict simulating output of reading a <project> from a manifest.""" |
| return { |
| 'gerrithost': 'project_gerrit_host', |
| 'githooks': 'project_githooks', |
| 'historydepth': 'project_historydepth', |
| 'name': 'project_name', |
| 'path': 'project_path', |
| 'remote': 'project_remote', |
| 'revision': 'project_revision', |
| } |
| |
| @property |
| def example_revision(self): # pragma: no cover |
| return 'c22471f4e3f842ae18dd9adec82ed9eb78ed1127' |
| |
| @property |
| def example_snapshot(self): |
| return """<manifest> |
| <projects> |
| <project name="manifest" path="manifest" remote="https://fuchsia.googlesource.com/manifest" revision="4c2b0da3c06341db5cebe4d02c78c93c3b2bd78b"/> |
| </projects> |
| </manifest>""" |
| |
| @property |
| def example_diff(self): |
| return { |
| 'new_projects': [{ |
| 'name': 'new_test_name', |
| 'path': 'new_test_path', |
| 'remote': 'new_test_remote', |
| 'revision': 'new_test_rev', |
| }], |
| 'deleted_projects': [{ |
| 'name': 'deleted_test_project', |
| 'path': 'deleted_test_path', |
| 'remote': 'deleted_test_remote', |
| 'revision': 'deleted_test_rev', |
| }], |
| 'updated_projects': [{ |
| 'name': 'updated_test_name', |
| 'path': 'updated_test_path', |
| 'remote': 'updated_test_remote', |
| 'revision': 'updated_test_rev', |
| 'old_revision': 'old_test_rev', |
| 'old_path': 'old_test_path', |
| 'cls': [{ |
| 'number': 'test_num', |
| 'url': 'test_url', |
| 'commit': 'test_commit', |
| 'subject': 'test_sub', |
| }], |
| 'has_more_cls': True, |
| 'error': 'error in retrieving CL', |
| }] |
| } |
| |
| @property |
| def example_source_manifest(self): |
| return { |
| 'directories': { |
| 'manifest': { |
| 'git_checkout': { |
| 'repo_url': 'https://fuchsia.googlesource.com/manifest', |
| 'revision': '4c2b0da3c06341db5cebe4d02c78c93c3b2bd78b', |
| } |
| } |
| } |
| } |
| |
| def example_resolve_data(self, package): |
| """Creates example data for jiri resolve subcommand. |
| |
| Args: |
| package: A string with the package name to generate data for. |
| |
| Returns: |
| A StepTestData with a multiline string in stdout. The multiline string |
| has the subdirectory package in one line and the package, platforms and |
| version in a second line. |
| """ |
| test_data = ['@Subdir %s' % package] |
| if package.endswith('${platform}'): |
| prefix = package[0:package.index('/${platform}')] |
| platform_str = ('%s/${platform=linux-amd64,mac-amd64} ' |
| 'version:2.5.0' % (prefix)) |
| test_data.append(platform_str) |
| else: |
| test_data.append('%s version:2.5.0' % package) |
| data = '\n'.join(test_data) |
| return self.m.raw_io.output(data) |
| |
| def example_edit(self, imports, projects, packages): |
| """Creates example JSON output for the Jiri edit subcommand. |
| |
| The data returned by this command is similar to the data generated when |
| `Jiri edit` is invoked with the -json-output flag. |
| |
| Args: |
| imports (List(tuple)): A list of (name, revision) tuples representing |
| imports to update in the manifest. |
| projects (List(tuple)): A list of (name, revision) tuples representing |
| projects to update in the manifest. |
| packages (List(tuple)): A list of (name, version) tuples representing |
| packages to update in the manifest. |
| |
| Returns: |
| A dict representing JSON that matches the output of the Jiri edit |
| subcommand. The dict has the following structure: |
| |
| { |
| 'imports': [ |
| { |
| 'name': ... |
| 'remote': ... |
| 'old_revision': ... |
| 'new_revision': ... |
| }, |
| ... |
| ], |
| 'projects': [ |
| { |
| 'name': ... |
| 'remote': ... |
| 'path: ... |
| 'old_revision': ... |
| 'new_revision': ... |
| }, |
| ... |
| ], |
| 'packages': [ |
| { |
| 'name': ... |
| 'old_version': ... |
| 'new_version': ... |
| }, |
| ... |
| ], |
| } |
| |
| Where each entry in imports, projects and packages is a dict representing |
| an edit to an import, project and package, respectively. |
| """ |
| project_edits = [] |
| for project in projects: |
| name, revision = project |
| project_edits.append({ |
| 'name': name, |
| 'remote': 'http://example.com', |
| 'path': '/path/to/' + name, |
| 'old_revision': '[OLD_REVISION]', |
| 'new_revision': revision, |
| }) |
| |
| import_edits = [] |
| for imp in imports: |
| name, revision = imp |
| import_edits.append({ |
| 'name': name, |
| 'remote': 'http://example.com', |
| 'old_revision': '[OLD_REVISION]', |
| 'new_revision': revision, |
| }) |
| |
| package_edits = [] |
| for package in packages: |
| name, version = package |
| package_edits.append({ |
| 'name': name, |
| 'old_version': '[OLD_VERSION]', |
| 'new_version': version, |
| }) |
| |
| return { |
| 'projects': project_edits, |
| 'imports': import_edits, |
| 'packages': package_edits |
| } |
| |
| def project(self, projects): |
| """Provides test mock for the `project` method.""" |
| assert projects is not None |
| return self.m.json.output(projects) |
| |
| def package(self, packages): |
| """Provides test mock for the `package` method.""" |
| assert packages is not None |
| return self.m.json.output(packages) |
| |
| def snapshot(self, data): |
| """Provides test mock for the `snapshot` method.""" |
| assert data is not None |
| return self.m.raw_io.output(data, name='snapshot') |
| |
| def diff(self, diff): |
| """Provides test mock for the `diff` method.""" |
| assert diff is not None |
| return self.m.json.output(diff) |
| |
| def source_manifest(self, data): |
| """Provides test mock for the `source_manifest` method.""" |
| assert data is not None |
| return self.m.json.output(data, name='source manifest') |