From 9a3da217110ef2c5304de85da6586f54c93606aa Mon Sep 17 00:00:00 2001 From: David Leong <116610336+leongdl@users.noreply.github.com> Date: Sat, 25 Jul 2026 15:03:09 -0700 Subject: [PATCH] test: Add conformance fixtures for two template-parsing divergences Both were found while reviewing RFC 0008 wrap-action support across the two implementations, and each is currently red on exactly one of them. EXPR/jobs/7.3--task-file-direct-property-access: RFC 0005 declares Task.File. as path-typed and shows property access directly in a format string ({{Task.File.Run.name}}). The existing 7.3--task-file-expr-properties fixture only reaches the property through a let binding, and a property inside a function call parses differently again, so the direct member-access form the RFC uses was uncovered. openjd-rs rejects it at validation ('references undefined embedded file Run.name') while its own runtime resolves it and its environment-template validator accepts the Env.File equivalent. EXPR/job_templates/3--int-literal-above-int64-max.invalid: RFC 0005 section 3 bounds integers to -2^63..2^63-1. A literal timeout of 2^63 must be rejected at validation. openjd-model accepts it, so the problem is only discovered at run time -- and before it was bounded there, it overflowed the runtime's duration type. Verified against both CLIs: fixture 1 passes on the Python stack and fails on openjd-rs; fixture 2 passes on openjd-rs and fails on the Python stack. Signed-off-by: David Leong <116610336+leongdl@users.noreply.github.com> --- ...--int-literal-above-int64-max.invalid.yaml | 26 +++++++++++ ...task-file-direct-property-access.test.yaml | 44 +++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 conformance-tests/2023-09/EXPR/job_templates/3--int-literal-above-int64-max.invalid.yaml create mode 100644 conformance-tests/2023-09/EXPR/jobs/7.3--task-file-direct-property-access.test.yaml diff --git a/conformance-tests/2023-09/EXPR/job_templates/3--int-literal-above-int64-max.invalid.yaml b/conformance-tests/2023-09/EXPR/job_templates/3--int-literal-above-int64-max.invalid.yaml new file mode 100644 index 0000000..406392d --- /dev/null +++ b/conformance-tests/2023-09/EXPR/job_templates/3--int-literal-above-int64-max.invalid.yaml @@ -0,0 +1,26 @@ +# RFC 0005 section 3 ("64-bit Signed Integer Type"): integer values use 64-bit +# two's complement representation, with a range of -2^63 to 2^63-1, and any +# operation that produces a value outside that range is an error. +# +# A literal integer field is therefore invalid above 2^63-1. This template's +# `timeout` is 2^63 (9223372036854775808), one past the maximum, so validation +# must reject it. +# +# An implementation whose model has no upper bound accepts this template and only +# discovers the problem at run time -- or, worse, converts it into a native +# duration type and overflows. Rejecting it at validation is what lets a +# submitter see the error before the job is ever scheduled. +specificationVersion: jobtemplate-2023-09 +extensions: +- EXPR +name: TestJob +steps: +- name: Step1 + script: + actions: + onRun: + command: python + args: + - -c + - print() + timeout: 9223372036854775808 diff --git a/conformance-tests/2023-09/EXPR/jobs/7.3--task-file-direct-property-access.test.yaml b/conformance-tests/2023-09/EXPR/jobs/7.3--task-file-direct-property-access.test.yaml new file mode 100644 index 0000000..2e88062 --- /dev/null +++ b/conformance-tests/2023-09/EXPR/jobs/7.3--task-file-direct-property-access.test.yaml @@ -0,0 +1,44 @@ +# RFC 0005 declares `Task.File.` and `Env.File.` as `path` typed, and +# shows property access on one directly inside a format string: +# +# echo "Script: {{Task.File.Run.name}}" +# +# (rfcs/0005-expression-language.md, "Since Session.WorkingDirectory, +# Task.File., and Env.File. are path typed ..."). +# +# The existing 7.3--task-file-expr-properties fixture only reaches the property +# through a `let` binding (`cfg = Task.File.config`, then `cfg.parent`), and a +# property reached inside a function call (`len(Task.File.Run.name)`) parses +# differently again -- so neither covers the direct member-access form the RFC +# uses. An implementation whose template validator resolves a `Task.File.*` +# reference by looking the whole dotted tail up as an embedded-file key rejects +# this template with "references undefined embedded file 'Run.name'", even though +# its own runtime resolves the expression correctly and its environment-template +# validator accepts the equivalent `Env.File..name`. +# +# `filename` is set so the expected value of `.name` is deterministic. +template: + specificationVersion: jobtemplate-2023-09 + extensions: + - EXPR + name: TestJob + steps: + - name: Step1 + script: + embeddedFiles: + - name: Run + type: TEXT + filename: run.txt + data: "contents\n" + actions: + onRun: + command: python + args: + - -c + - | + print(r'NAME:{{Task.File.Run.name}}') + print(r'SUFFIX:{{Task.File.Run.suffix}}') +expected: + output: + - "NAME:run.txt" + - "SUFFIX:.txt"