diff --git a/.github/scripts/verify_otel_api_compatibility.py b/.github/scripts/verify_otel_api_compatibility.py index b0e88c7aa..2ff92fd69 100644 --- a/.github/scripts/verify_otel_api_compatibility.py +++ b/.github/scripts/verify_otel_api_compatibility.py @@ -142,11 +142,14 @@ def run_matrix(args: argparse.Namespace) -> int: for view in ("otel-invocation", "otel-execution"): name = f"{label}-api{version}-{view}" negative = label == "old-old" and version == "1.49.0" + incompatible_core = label == "old-new" case: dict[str, object] = {"name": name, "expected_negative_control": negative, + "expected_core_rejection": incompatible_core, "api": jar_facts(api), "context": jar_facts(context)} command = [args.java, "-cp", os.pathsep.join(map(str, [classes, core, plugin, *dependencies])), PROBE, str(core), str(plugin), str(api), str(context), view, - str(negative).lower(), str(version == "1.66.0").lower()] + str(negative).lower(), str(version == "1.66.0").lower(), + str(incompatible_core).lower()] try: log = output / f"{name}.log" execute(command, log, env=probe_environment(view), timeout=90) @@ -155,6 +158,8 @@ def run_matrix(args: argparse.Namespace) -> int: raise RuntimeError("Probe did not report successful completion") if negative and "NEGATIVE_CONTROL_REPRODUCED" not in contents: raise RuntimeError("Released negative control did not reproduce the reported failure") + if incompatible_core and "CORE_LIFECYCLE_REJECTION_CONFIRMED" not in contents: + raise RuntimeError("Old core must reject the new plugin before invocation startup") case["passed"] = True except RuntimeError as error: failures += 1 diff --git a/.github/workflows/otel-conformance-tests.yml b/.github/workflows/otel-conformance-tests.yml index 452db089d..c227f1d51 100644 --- a/.github/workflows/otel-conformance-tests.yml +++ b/.github/workflows/otel-conformance-tests.yml @@ -49,6 +49,7 @@ on: conformance_test_ref: description: Optional conformance test commit SHA or branch name required: false + default: "75987d46a915bc37409eed3ea9c3617a924c9756" type: string permissions: {} @@ -68,14 +69,14 @@ jobs: actions: write contents: read id-token: write - uses: aws/aws-durable-execution-conformance-tests/.github/workflows/opentelemetry-orchestrator.yml@a66037abbbfa55fde97f714e30f0bc262edefd63 + uses: aws/aws-durable-execution-conformance-tests/.github/workflows/opentelemetry-orchestrator.yml@bdb4f1cd0f9252c1aaa978bb8b341b71f2b9d9dc with: runs_on: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository && 'ubuntu-latest' || format('codebuild-github-actions-runner-{0}-{1}', github.run_id, github.run_attempt) }} language: java resource_prefix: j sdk_repository: aws/aws-durable-execution-sdk-java sdk_ref: ${{ github.event.pull_request.head.sha || github.sha }} - conformance_test_ref: ${{ inputs.conformance_test_ref || '02d6dca971a38c13d94d6233d12f687e55b2a572' }} + conformance_test_ref: ${{ inputs.conformance_test_ref || '75987d46a915bc37409eed3ea9c3617a924c9756' }} checkout_sdk: true # Build the handlers from this repo's checked-out module instead of the conformance repo's # bundled examples/java. Path is relative to the conformance workspace where the SDK is diff --git a/conformance-tests-otel/README.md b/conformance-tests-otel/README.md new file mode 100644 index 000000000..a25ce65a6 --- /dev/null +++ b/conformance-tests-otel/README.md @@ -0,0 +1,74 @@ +# Java OpenTelemetry conformance handlers + +The shared conformance repository owns the requirements and validators. This +module supplies public-API handlers and SAM resources for both tracing views. +Existing cases 1–20 and their resources are unchanged by the additions below. + +| Case | Scenario | Behavior | +| --- | --- | --- | +| 21 | `completed-step-replay` | Complete a step, suspend on a one-second durable wait, then complete another step. The first step body is skipped on replay. | +| 22 | `user-function-context` | Probe handler entry/restoration/resume, step, child, concurrent parallel branches and map iterations, and their nested steps. | +| 23 | `callback-function-context` | Probe step retry attempts, condition checks, callback submission, a wrapped retry helper's body and strategy, and a virtual child after the asynchronous work finishes. | +| 24 | `invocation-retry-status` | Throw the public retryable execution exception after a checkpointed step, then recover on replay. | +| 25 | `wait-for-callback-failure` | Reuse case 17’s public handler; the driver fails its callback without Error only after invocation completion. The shared validator checks the observed empty error payload and leaf status. | +| 26 | `external-callback-completion-replay` | Observe a root callback completion, checkpoint its result, then revisit it through two later callback barriers without duplicate terminal export. | + +Cases 22 and 23 require a valid active `SpanContext` and create/end ordinary +`conformance.