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
4 changes: 2 additions & 2 deletions src/openjd/model/v2023_09/_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -2893,7 +2893,7 @@ class JobTemplate(OpenJDModel_v2023_09):
"""

specificationVersion: Literal[TemplateSpecificationVersion.JOBTEMPLATE_v2023_09] # noqa: N815
extensions: Optional[ExtensionNameList] = None
extensions: Optional[ExtensionNameList] = Field(default=None, validate_default=True)
name: JobTemplateName
steps: StepTemplateList
description: Optional[Description] = None
Expand Down Expand Up @@ -3116,7 +3116,7 @@ class EnvironmentTemplate(OpenJDModel_v2023_09):
"""

specificationVersion: Literal[TemplateSpecificationVersion.ENVIRONMENT_v2023_09]
extensions: Optional[ExtensionNameList] = None
extensions: Optional[ExtensionNameList] = Field(default=None, validate_default=True)
parameterDefinitions: Optional[JobParameterDefinitionList] = None
environment: Environment

Expand Down
55 changes: 54 additions & 1 deletion test/openjd/model/v2023_09/test_feature_bundle_1.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import pytest
from pydantic import ValidationError

from openjd.model import create_job
from openjd.model import create_job, decode_job_template
from openjd.model._parse import _parse_model
from openjd.model.v2023_09 import (
Action,
Expand Down Expand Up @@ -57,6 +57,59 @@ def test_extension_not_supported(self) -> None:
assert "FEATURE_BUNDLE_1" in str(excinfo.value)


class TestExtensionFieldEnablement:
"""Tests for extension enablement based on template's extensions field and supported_extensions."""

@pytest.mark.parametrize(
"template_declares_ext,supported_extensions,param_count,should_pass",
[
# Template declares extension, supported includes it - passes with 51 params
(True, ["FEATURE_BUNDLE_1"], 51, True),
# Template declares extension, supported excludes it - fails (unsupported ext)
(True, ["TASK_CHUNKING"], 51, False),
# Template declares extension, supported is None - fails (unsupported ext)
(True, None, 51, False),
# Template omits extension, supported includes it - fails (50 param limit)
(False, ["FEATURE_BUNDLE_1"], 51, False),
# Template omits extension, all supported - fails (50 param limit)
(False, ["TASK_CHUNKING", "REDACTED_ENV_VARS", "FEATURE_BUNDLE_1"], 51, False),
# Template omits extension, none supported - fails (50 param limit)
(False, [], 51, False),
# Template omits extension, supported is None - fails (50 param limit)
(False, None, 51, False),
# Template within default limit - passes regardless
(False, ["FEATURE_BUNDLE_1"], 50, True),
# Template omits extension, supported is None, within limit - passes
(False, None, 50, True),
],
)
def test_extension_enablement(
self,
template_declares_ext: bool,
supported_extensions: list[str],
param_count: int,
should_pass: bool,
) -> None:
"""Test that extension features require explicit declaration in template."""
params = [{"name": f"P{i}", "type": "INT", "default": i} for i in range(param_count)]
data: dict = {
"specificationVersion": "jobtemplate-2023-09",
"name": "Test",
"parameterDefinitions": params,
"steps": [{"name": "s", "script": STEP_SCRIPT}],
}
if template_declares_ext:
data["extensions"] = ["FEATURE_BUNDLE_1"]

if should_pass:
result = decode_job_template(template=data, supported_extensions=supported_extensions)
assert result.parameterDefinitions is not None
assert len(result.parameterDefinitions) == param_count
else:
with pytest.raises(Exception):
decode_job_template(template=data, supported_extensions=supported_extensions)


class TestActionTimeoutFormatString:
"""Tests for timeout format string support in Action."""

Expand Down
Loading