blob: 4f15ee0f269f75cef54ea1c095065a18d9ad124a [file]
# Copyright 2019 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.
"""Test API for cq_deps."""
from __future__ import annotations
import json
from recipe_engine import post_process, recipe_test_api
from PB.recipe_modules.pigweed.cq_deps.properties import InputProperties
class CqDepsTestApi(recipe_test_api.RecipeTestApi):
def properties(self, **kwargs) -> dict[str, InputProperties]:
return {'$pigweed/cq_deps': InputProperties(**kwargs)}
def lookup_cl(
self,
commit_hash: str,
number: int | None = None,
prefix: str = '',
found: bool = True,
) -> recipe_test_api.StepTestData:
if not found:
return self.override_step_data(
f'{prefix}resolve CL deps.number {commit_hash}',
self.m.json.output(None),
)
return self.override_step_data(
f'{prefix}resolve CL deps.number {commit_hash}',
self.m.json.output([{'_number': number}] if number else []),
)
def _step_name(self, prefix: str, name: str, n: int | None) -> str:
return '{}resolve CL deps.details {}{}'.format(
prefix,
name,
' ({})'.format(n) if n and n > 1 else '',
)
def patches_json(
self,
origin: str,
*reqs: str,
prefix: str = '',
) -> recipe_test_api.StepTestData:
"""Test data for the retrieval of patches.json.
Args:
origin: The Gerrit name plus the change number, separated by a colon
(e.g., "pigweed:12345")
reqs: A list of requirements of the origin, in the same format as
the origin.
prefix: Prefix for the step name.
"""
if prefix and not prefix.endswith('.'):
# Next line is really only here for tests outside this module.
prefix += '.' # pragma: no cover
patches = []
for req in reqs:
host, number = req.split(':')
number = int(number)
patches.append({'gerrit_name': host, 'number': number})
return self.m.gitiles.fetch(
f'{prefix}resolve CL deps.resolve deps for {origin}.'
'fetch patches.json',
json.dumps(patches).encode(),
)
def patches_json_error(
self,
origin: str,
status_code: int = 404,
**kwargs,
) -> recipe_test_api.StepTestData:
"""Test data for the unsuccessful retrieval of patches.json.
Args:
origin: The Gerrit name plus the change number, separated by a colon
(e.g., "pigweed:12345")
status_code: The HTTP error code from the attempt to read
patches.json.
prefix: Prefix for the step name.
"""
prefix = kwargs.pop('prefix', '')
assert not kwargs
if prefix and not prefix.endswith('.'):
# Next line is really only here for tests outside this module.
prefix += '.' # pragma: no cover
return self.m.url.error(
f'{prefix}resolve CL deps.resolve deps for {origin}.'
'fetch patches.json',
status_code,
'error',
**kwargs,
)
def details(
self,
name: str,
message: str = '',
status: str = 'NEW',
project: str = 'project',
patchset: int = 1,
prefix: str = '',
commit_hash: str = 'HASH',
parent: str | None = None,
n: int | None = None,
patches_json: bool = False,
topic: str | None = None,
) -> recipe_test_api.StepTestData:
"""Test data for the retrieval of change details from Gerrit."""
number = int(name.split(':')[1])
if not parent:
parent = f'parent-{number}'
assert status in ('NEW', 'MERGED', 'ABANDONED')
if patches_json:
files = {'patches.json': {'status': 'A'}}
else:
files = {'foo.py': {'status': 'A'}}
return self.override_step_data(
self._step_name(prefix, name, n),
self.m.json.output(
{
'_number': number,
'current_revision': commit_hash,
'project': project,
'revisions': {
commit_hash: {
'_number': patchset,
'commit': {
'message': message,
'parents': [
{
'commit': parent,
}
],
},
'files': files,
},
},
'status': status,
'topic': topic or '',
}
),
)
def transient(
self,
name: str,
prefix: str = '',
n: int | None = None,
) -> recipe_test_api.StepTestData:
return self.override_step_data(
self._step_name(prefix, name, n),
self.m.json.output({'transient': True}),
retcode=1,
)
def forbidden(
self,
name: str,
prefix: str = '',
attempts: int = 2,
) -> recipe_test_api.StepTestData:
data = []
for i in range(0, attempts):
data.append(
self.override_step_data(
self._step_name(prefix, name, i + 1),
self.m.json.output({}),
retcode=1,
)
)
return sum(data[1:], data[0])
def has_deps(self, *names: str) -> recipe_test_api.StepTestData:
results = []
for name in names:
results.append(
self.post_process(
post_process.MustRun,
f'final deps.{name}',
)
)
return sum(results[1:], results[0])
def lacks_deps(self, *names: str) -> recipe_test_api.StepTestData:
results = []
for name in names:
results.append(
self.post_process(
post_process.DoesNotRun,
f'final deps.{name}',
)
)
return sum(results[1:], results[0])