Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .github/workflows/xtest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ on:
type: string
default: ""
description: "Comma-separated feature names to treat as supported regardless of what each SDK's `cli.sh supports` reports. Use when evaluating a fix that has not been released yet: the version gates live in this repo and answer 'no' for exactly those unreleased builds, so the cells would otherwise skip. An unknown name fails the run rather than being ignored."
force-platform-supports:
required: false
type: string
default: ""
description: "Comma-separated platform features to treat as supported. Does not override SDK gates or enable service configuration. Unknown names fail the run."
workflow_call:
inputs:
platform-ref:
Expand Down Expand Up @@ -86,6 +91,11 @@ on:
required: false
type: string
default: ""
force-platform-supports:
required: false
type: string
default: ""
description: "Comma-separated platform features to treat as supported. Does not override SDK gates or enable service configuration. Unknown names fail the run."
schedule:
- cron: "30 6 * * *" # 0630 UTC
- cron: "0 5 * * 1,3" # 500 UTC (Monday, Wednesday)
Expand All @@ -101,6 +111,7 @@ concurrency:
# nothing" -- so the PR gate and the nightlies are unaffected.
env:
XT_FORCE_SUPPORTS: ${{ inputs.force-supports }}
XT_FORCE_PLATFORM_SUPPORTS: ${{ inputs.force-platform-supports }}

jobs:
resolve-versions:
Expand Down
4 changes: 4 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ See `xtest/AGENTS.md` for the full table of `--sdks`, `--containers`,
- `XT_FORCE_SUPPORTS` — comma-separated feature names to treat as supported
regardless of what each SDK's `cli.sh supports` reports. See below.

- `XT_FORCE_PLATFORM_SUPPORTS` — comma-separated platform features to treat as
supported, independent of SDK overrides. It does not enable service settings.
In CI, use `force-platform-supports`. See `xtest/README.md` for usage.

### Evaluating an unreleased fix: `XT_FORCE_SUPPORTS`

`SDK.supports(feature)` answers from the `supports` case statements in
Expand Down
1 change: 1 addition & 0 deletions xtest/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ Beyond the repo-wide ones in `../AGENTS.md`:
|----------|---------|
| `XT_TMP_DIR` | Root for generated fixtures and ciphertexts (default `tmp/`). Point at a large volume for `medium`/`large` runs. |
| `XT_FORCE_SUPPORTS` | Comma-separated features to treat as supported, bypassing the `cli.sh supports` gate. For evaluating a fix before it releases — see `../AGENTS.md`. Unknown names raise. |
| `XT_FORCE_PLATFORM_SUPPORTS` | Comma-separated platform features to treat as supported. Independent of SDK overrides; does not enable service configuration. Unknown names raise. |

## Authoring a New Test

Expand Down
7 changes: 7 additions & 0 deletions xtest/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,13 @@ uv sync --extra dev
pytest
```

#### Testing unreleased platform features

Set `XT_FORCE_PLATFORM_SUPPORTS` to a comma-separated list of platform features
to bypass their test gates. In CI, use the `force-platform-supports` input.
SDK overrides use `XT_FORCE_SUPPORTS` separately. These overrides do not enable
service configuration.

#### Run TDF Tests

```shell
Expand Down
27 changes: 22 additions & 5 deletions xtest/tdfs.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import zipfile
from collections.abc import Callable
from pathlib import Path
from typing import Any, Literal, TypeIs, get_args
from typing import Any, Literal, TypeIs, cast, get_args

import jsonschema
import pytest
Expand Down Expand Up @@ -207,8 +207,10 @@ def is_sdk_type(val: str) -> TypeIs[sdk_type]:
]


def _parse_forced_supports(raw: str) -> frozenset[str]:
"""Parse ``XT_FORCE_SUPPORTS`` into a set of feature names.
def _parse_forced_supports(
raw: str, *, source: str = "XT_FORCE_SUPPORTS"
) -> frozenset[feature_type]:
"""Parse an SDK or platform override into validated feature names.

An unrecognised name is a hard error rather than a no-op. The override
exists to turn a skip into a real result, so a typo that quietly left the
Expand All @@ -220,10 +222,10 @@ def _parse_forced_supports(raw: str) -> frozenset[str]:
unknown = names - known
if unknown:
raise ValueError(
f"XT_FORCE_SUPPORTS names unknown feature(s) {sorted(unknown)}; "
f"{source} names unknown feature(s) {sorted(unknown)}; "
f"valid features are {sorted(known)}"
)
return frozenset(names)
return cast(frozenset[feature_type], frozenset(names))


#: Features to treat as supported no matter what the SDK reports.
Expand All @@ -248,6 +250,20 @@ def _parse_forced_supports(raw: str) -> frozenset[str]:
)


# Platform overrides are independent of SDK overrides and service configuration.
FORCED_PLATFORM_SUPPORTS = _parse_forced_supports(
os.environ.get("XT_FORCE_PLATFORM_SUPPORTS", ""),
source="XT_FORCE_PLATFORM_SUPPORTS",
)

if FORCED_PLATFORM_SUPPORTS:
logger.warning(
"XT_FORCE_PLATFORM_SUPPORTS is set: treating %s as supported by the "
"platform. SDK gates and service configuration are unchanged.",
", ".join(sorted(FORCED_PLATFORM_SUPPORTS)),
)


container_version = Literal["4.2.2", "4.3.0"]

policy_type = Literal["plaintext", "encrypted"]
Expand All @@ -266,6 +282,7 @@ class PlatformFeatureSet(BaseModel):

def __init__(self, **kwargs: dict[str, Any]):
super().__init__(**kwargs)
self.features.update(FORCED_PLATFORM_SUPPORTS)
v = os.getenv("PLATFORM_VERSION")
if not v:
print("PLATFORM_VERSION unset or empty; defaulting to 0.9.0")
Expand Down
56 changes: 56 additions & 0 deletions xtest/test_tdfs_units.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,62 @@ def test_unknown_name_raises(self):
tdfs._parse_forced_supports("hexles")


# --- Platform forced support ------------------------------------------------


@pytest.mark.parametrize("platform_version", ["0.12.0", "main", ""])
@pytest.mark.parametrize("forced", [False, True])
def test_platform_forced_supports(
monkeypatch: pytest.MonkeyPatch, platform_version: str, forced: bool
):
monkeypatch.setenv("PLATFORM_VERSION", platform_version)
# A source tag alone must not imply feature support.
monkeypatch.setenv("PLATFORM_TAG", "main")
monkeypatch.setattr(tdfs, "FORCED_SUPPORTS", tdfs._parse_forced_supports("dpop"))
monkeypatch.setattr(
tdfs,
"FORCED_PLATFORM_SUPPORTS",
tdfs._parse_forced_supports("dpop_nonce_challenge" if forced else ""),
)
monkeypatch.setattr(tdfs, "_fetch_well_known", lambda: None)

features = tdfs.PlatformFeatureSet()
assert ("dpop_nonce_challenge" in features.features) is forced
# An SDK override must not force the corresponding platform feature.
assert "dpop" not in features.features


def test_platform_forced_supports_do_not_leak(monkeypatch: pytest.MonkeyPatch):
monkeypatch.setenv("PLATFORM_VERSION", "main")
monkeypatch.setattr(
tdfs,
"FORCED_PLATFORM_SUPPORTS",
tdfs._parse_forced_supports("dpop_nonce_challenge"),
)
forced = tdfs.PlatformFeatureSet()
monkeypatch.setattr(tdfs, "FORCED_PLATFORM_SUPPORTS", frozenset())
unforced = tdfs.PlatformFeatureSet()
assert "dpop_nonce_challenge" in forced.features
assert "dpop_nonce_challenge" not in unforced.features


def test_platform_override_does_not_override_sdk(monkeypatch: pytest.MonkeyPatch):
monkeypatch.setattr(tdfs, "FORCED_SUPPORTS", frozenset())
monkeypatch.setattr(
tdfs,
"FORCED_PLATFORM_SUPPORTS",
tdfs._parse_forced_supports("dpop_nonce_challenge"),
)
sdk = object.__new__(tdfs.SDK)
sdk._supports = {"dpop_nonce_challenge": False}
assert not sdk.supports("dpop_nonce_challenge")


def test_unknown_platform_override_names_source():
with pytest.raises(ValueError, match="XT_FORCE_PLATFORM_SUPPORTS names unknown"):
tdfs._parse_forced_supports("dpop_typo", source="XT_FORCE_PLATFORM_SUPPORTS")


# --- tdfs.zip64_reader_is_broken ----------------------------------------------


Expand Down
Loading