From 135fb0ed3ac7eeac14979acfedda0092d291b8cf Mon Sep 17 00:00:00 2001 From: Nicolas De Loof Date: Wed, 19 Aug 2026 17:09:41 +0200 Subject: [PATCH] =?UTF-8?q?e2e:=20jobs=20scenarios=20=E2=80=94=20scheduled?= =?UTF-8?q?=20rejection,=20manual=20run,=20env=5Ffile,=20job=20chain?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Scenario-DSL coverage for the jobs entry points: - up refuses a project declaring an active scheduled job before creating any resource; - run executes a manual job like a service, starting its depends_on services first, and refuses a schedule-only job; - a job's own env_file feeds its environment through run — the materialization happens before environment resolution; - a job depending on another job runs the dependency to completion first, through the exact machinery a service dependency uses. Co-Authored-By: Claude Fable 5 Signed-off-by: Nicolas De Loof --- pkg/e2e/jobs_test.go | 67 +++++++++++++++++++ .../TestRunJobDependsOnJob/compose.yaml | 22 ++++++ .../testdata/TestRunJobEnvFile/compose.yaml | 7 ++ pkg/e2e/testdata/TestRunJobEnvFile/db.env | 1 + .../testdata/TestRunManualJob/compose.yaml | 20 ++++++ .../TestUpRejectsScheduledJobs/compose.yaml | 12 ++++ 6 files changed, 129 insertions(+) create mode 100644 pkg/e2e/jobs_test.go create mode 100644 pkg/e2e/testdata/TestRunJobDependsOnJob/compose.yaml create mode 100644 pkg/e2e/testdata/TestRunJobEnvFile/compose.yaml create mode 100644 pkg/e2e/testdata/TestRunJobEnvFile/db.env create mode 100644 pkg/e2e/testdata/TestRunManualJob/compose.yaml create mode 100644 pkg/e2e/testdata/TestUpRejectsScheduledJobs/compose.yaml diff --git a/pkg/e2e/jobs_test.go b/pkg/e2e/jobs_test.go new file mode 100644 index 000000000..1b17264e6 --- /dev/null +++ b/pkg/e2e/jobs_test.go @@ -0,0 +1,67 @@ +//go:build e2e + +/* + Copyright 2020 Docker Compose CLI authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package e2e + +import ( + "testing" +) + +// Scheduled jobs cannot run in this version: silently not scheduling them +// would break the user's expectations, so up must refuse the whole project. +func TestUpRejectsScheduledJobs(t *testing.T) { + NewScenario(t, "up must reject a project declaring active scheduled jobs, before creating anything"). + Step("up fails naming the scheduled job", + ComposeCmd("up", "-d").MayFail(), + StderrContains("scheduled jobs are not supported in this version: backup"), + ServiceNotCreated("web")) +} + +// A manual-trigger job runs through `compose run` exactly like a service +// would: its declared dependencies start first, its output and exit flow +// back. A schedule-only job stays out of reach. +func TestRunManualJob(t *testing.T) { + NewScenario(t, "run must execute a manual job like a service, starting its depends_on services first"). + Step("run executes the job after starting its dependency", + ComposeCmd("run", "--rm", "migrate"), + OutputContains("migration done"), + ServiceState("db", "running")). + Step("a schedule-only job cannot be run", + ComposeCmd("run", "--rm", "backup").MayFail(), + StderrContains(`job "backup" has no manual trigger`)) +} + +// A job's own env_file resolves exactly like a selected service's would: the +// materialization happens before environment resolution, not after. +func TestRunJobEnvFile(t *testing.T) { + NewScenario(t, "a job's env_file must feed its environment through run"). + Step("the job sees the env_file variable", + ComposeCmd("run", "--rm", "migrate"), + OutputContains("DB_URL=postgres://db:5432/app")) +} + +// A job may depend on another job: the dependency job runs to completion +// first — through the exact machinery a service dependency does — then the +// target runs. +func TestRunJobDependsOnJob(t *testing.T) { + NewScenario(t, "a job depending on a job must run the dependency to completion first"). + Step("the dependency job completes before the target runs", + ComposeCmd("run", "--rm", "deploy"), + OutputContains("deploy done"), + ServiceState("db", "running")) +} diff --git a/pkg/e2e/testdata/TestRunJobDependsOnJob/compose.yaml b/pkg/e2e/testdata/TestRunJobDependsOnJob/compose.yaml new file mode 100644 index 000000000..35765a5f9 --- /dev/null +++ b/pkg/e2e/testdata/TestRunJobDependsOnJob/compose.yaml @@ -0,0 +1,22 @@ +services: + db: + image: alpine + init: true + command: sleep infinity +jobs: + prep: + image: alpine + command: sh -c 'echo "prep done"' + triggers: + manual: true + depends_on: + db: + condition: service_started + deploy: + image: alpine + command: sh -c 'echo "deploy done"' + triggers: + manual: true + depends_on: + prep: + condition: service_completed_successfully diff --git a/pkg/e2e/testdata/TestRunJobEnvFile/compose.yaml b/pkg/e2e/testdata/TestRunJobEnvFile/compose.yaml new file mode 100644 index 000000000..3865e4945 --- /dev/null +++ b/pkg/e2e/testdata/TestRunJobEnvFile/compose.yaml @@ -0,0 +1,7 @@ +jobs: + migrate: + image: alpine + command: sh -c 'echo "DB_URL=$$DB_URL"' + env_file: db.env + triggers: + manual: true diff --git a/pkg/e2e/testdata/TestRunJobEnvFile/db.env b/pkg/e2e/testdata/TestRunJobEnvFile/db.env new file mode 100644 index 000000000..d819a83fa --- /dev/null +++ b/pkg/e2e/testdata/TestRunJobEnvFile/db.env @@ -0,0 +1 @@ +DB_URL=postgres://db:5432/app diff --git a/pkg/e2e/testdata/TestRunManualJob/compose.yaml b/pkg/e2e/testdata/TestRunManualJob/compose.yaml new file mode 100644 index 000000000..675477855 --- /dev/null +++ b/pkg/e2e/testdata/TestRunManualJob/compose.yaml @@ -0,0 +1,20 @@ +services: + db: + image: alpine + init: true + command: sleep infinity +jobs: + migrate: + image: alpine + command: sh -c 'echo "migration done"' + triggers: + manual: true + depends_on: + db: + condition: service_started + backup: + image: alpine + command: echo backup + triggers: + schedule: + - cron: "0 3 * * *" diff --git a/pkg/e2e/testdata/TestUpRejectsScheduledJobs/compose.yaml b/pkg/e2e/testdata/TestUpRejectsScheduledJobs/compose.yaml new file mode 100644 index 000000000..5efd658bb --- /dev/null +++ b/pkg/e2e/testdata/TestUpRejectsScheduledJobs/compose.yaml @@ -0,0 +1,12 @@ +services: + web: + image: alpine + init: true + command: sleep infinity +jobs: + backup: + image: alpine + command: echo backup + triggers: + schedule: + - cron: "0 3 * * *"