[osx_sdk] Add TestApi to allow mocking macOS version.

Some downstream repos rely on the 'current platform' detection and
would like to mock it in their tests. Give a real API for doing this
instead of having downstream recipes key on the internal step name
here.

R=athom, jeffyoon@google.com, whesse

Change-Id: If9d049c568c70cac9ddee1c06f2bd04ac4f572a9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/5428682
Reviewed-by: Alexander Thomas <athom@google.com>
Auto-Submit: Robbie Iannucci <iannucci@chromium.org>
Commit-Queue: Alexander Thomas <athom@google.com>
Reviewed-by: William Hesse <whesse@google.com>
changes/82/5428682/6
Robert Iannucci 1 year ago committed by LUCI CQ
parent 246580c7b8
commit 1a776cf430

@ -721,7 +721,7 @@ Args:
&mdash; **def [upload](/recipes/recipe_modules/gsutil/api.py#98)(self, source, bucket, dest, args=None, link_name='gsutil.upload', metadata=None, unauthenticated_url=False, \*\*kwargs):**
### *recipe_modules* / [osx\_sdk](/recipes/recipe_modules/osx_sdk)
[DEPS](/recipes/recipe_modules/osx_sdk/__init__.py#7): [recipe\_engine/cipd][recipe_engine/recipe_modules/cipd], [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step], [recipe\_engine/version][recipe_engine/recipe_modules/version]
[DEPS](/recipes/recipe_modules/osx_sdk/__init__.py#7): [recipe\_engine/cipd][recipe_engine/recipe_modules/cipd], [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step], [recipe\_engine/version][recipe_engine/recipe_modules/version]
The `osx_sdk` module provides safe functions to access a semi-hermetic
@ -729,11 +729,11 @@ XCode installation.
Available only to Google-run bots.
#### **class [OSXSDKApi](/recipes/recipe_modules/osx_sdk/api.py#40)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
#### **class [OSXSDKApi](/recipes/recipe_modules/osx_sdk/api.py#44)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
API for using OS X SDK distributed via CIPD.
&emsp; **@contextmanager**<br>&mdash; **def [\_\_call\_\_](/recipes/recipe_modules/osx_sdk/api.py#58)(self, kind):**
&emsp; **@contextmanager**<br>&mdash; **def [\_\_call\_\_](/recipes/recipe_modules/osx_sdk/api.py#62)(self, kind):**
Sets up the XCode SDK environment.
@ -781,7 +781,7 @@ Args:
Raises:
StepFailure or InfraFailure.
&mdash; **def [initialize](/recipes/recipe_modules/osx_sdk/api.py#51)(self):**
&mdash; **def [initialize](/recipes/recipe_modules/osx_sdk/api.py#55)(self):**
### *recipe_modules* / [presubmit](/recipes/recipe_modules/presubmit)
[DEPS](/recipes/recipe_modules/presubmit/__init__.py#13): [bot\_update](#recipe_modules-bot_update), [depot\_tools](#recipe_modules-depot_tools), [gclient](#recipe_modules-gclient), [git](#recipe_modules-git), [tryserver](#recipe_modules-tryserver), [recipe\_engine/buildbucket][recipe_engine/recipe_modules/buildbucket], [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/cq][recipe_engine/recipe_modules/cq], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/resultdb][recipe_engine/recipe_modules/resultdb], [recipe\_engine/step][recipe_engine/recipe_modules/step]

@ -10,6 +10,7 @@ DEPS = [
'recipe_engine/json',
'recipe_engine/path',
'recipe_engine/platform',
'recipe_engine/properties',
'recipe_engine/raw_io',
'recipe_engine/step',
'recipe_engine/version',

@ -22,6 +22,10 @@ _PROPERTY_DEFAULTS = {
#
# Maps from OS version to the maximum supported version of Xcode for that OS.
#
# These correspond to package instance tags for:
#
# https://chrome-infra-packages.appspot.com/p/infra_internal/ios/xcode/xcode_binaries/mac-amd64
#
# Keep this sorted by OS version.
_DEFAULT_VERSION_MAP = [
('10.12.6', '9c40b'),
@ -131,8 +135,8 @@ class OSXSDKApi(recipe_api.RecipeApi):
find_os = self.m.step(
'find macOS version', ['sw_vers', '-productVersion'],
stdout=self.m.raw_io.output_text(),
step_test_data=(
lambda: self.m.raw_io.test_api.stream_output_text('14.4')))
step_test_data=(lambda: self.m.raw_io.test_api.stream_output_text(
self.test_api.DEFAULT_MACOS_VERSION)))
cur_os = self.m.version.parse(find_os.stdout.strip())
find_os.presentation.step_text = f'Running on {str(cur_os)!r}.'
for target_os, xcode in reversed(_DEFAULT_VERSION_MAP):

@ -36,7 +36,7 @@
"infra_step": true,
"name": "find macOS version",
"~followup_annotations": [
"@@@STEP_TEXT@Running on '10.1.0'.@@@"
"@@@STEP_TEXT@Running on '10.1'.@@@"
]
},
{

@ -27,21 +27,29 @@ def GenTests(api):
yield api.test(
'explicit_version',
api.platform.name('mac'),
api.properties(**{'$depot_tools/osx_sdk': {
'sdk_version': 'deadbeef',
}})
api.osx_sdk.pick_sdk_version('deadbeef'),
)
yield api.test(
'automatic_version',
api.platform.name('mac'),
api.step_data('find macOS version',
stdout=api.raw_io.output_text('10.15.6')),
api.osx_sdk.macos_version('10.15.6'),
)
yield api.test(
'ancient_version',
api.platform.name('mac'),
api.step_data('find macOS version',
stdout=api.raw_io.output_text('10.1.0')),
api.osx_sdk.macos_version('10.1'),
)
bad_versions = [
'meep.morp',
'1.2.3.4',
'10',
]
for version in bad_versions:
try:
api.osx_sdk.macos_version(version)
assert False, f'macos_version regex failure, allowed {version=}' # pragma: no cover
except ValueError:
pass

@ -0,0 +1,59 @@
# Copyright 2024 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import re
from recipe_engine import recipe_test_api
class OSXSDKTestApi(recipe_test_api.RecipeTestApi):
# In tests, this will be the version that we simulate macOS to be.
DEFAULT_MACOS_VERSION = '14.4'
def macos_version(
self,
major_minor: str = DEFAULT_MACOS_VERSION) -> recipe_test_api.TestData:
"""Mock the macOS Major.Minor[.Patch] version that osx_sdk will use to pick
the Xcode SDK version from its internal table.
This will only be used if the recipe does not explicitly select an SDK
version via the osx_sdk properties (which can be mocked via the
`pick_sdk_version` method below).
Example use:
yield api.test(
'my-test-name',
api.osx_sdk.macos_version('13.3'),
)
"""
if not re.match(r'^\d+(\.\d+){1,2}$', major_minor):
raise ValueError(
f'Expected Major.Minor[.Patch] (e.g. 14.4), got {major_minor=}')
return self.step_data('find macOS version',
stdout=self.m.raw_io.output_text(major_minor))
def pick_sdk_version(self,
sdk_version: str = 'deadbeef'
) -> recipe_test_api.TestData:
"""This should be used to pick a precise SDK version.
Recipes used on builders which configure the XCode version via properties
should use this to more accurately reflect how these recipes will run in
production. Specifically, when the XCode version is selected via properties,
the osx_sdk module will not need or attempt to discover the current macOS
version (which is mockable with the `macos_version` method above).
Example use:
yield api.test(
'my-test-name',
api.osx_sdk.pick_sdk_version('13c100'),
)
"""
return self.m.properties(
**{"$depot_tools/osx_sdk": {
"sdk_version": sdk_version,
}})
Loading…
Cancel
Save