Help us shape the future of Go! Take the 2026 Go Developer Survey

test/

directory
v0.5.8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 1, 2026 License: Apache-2.0

README

The test suites, and when each one runs

Dexaflow has several test trees and they answer different questions. This page says which is which, what each one proves, and when CI runs it, so a contributor can tell whether the suite that stayed silent was meant to speak.

The suites

suite what it proves what it does NOT prove when it runs
Go unit tests (internal/, pkg/) logic, in isolation, with a coverage floor per package that the pieces work together, or against a real database every pull request
Integration (//go:build integration) the SQL and the storage layer against a real Postgres anything about Kubernetes every pull request
test/e2e/lite-*.sh Lite boots, serves, and runs a DAG on the subprocess executor the Pro or Kubernetes paths every pull request
test/e2e/e2e.sh, split-two-process.sh, dbt-e2e.sh, deploy-e2e.sh the Kubernetes paths on k3d: pod-per-task, the two-process split, dbt, and build-then-deploy against a registry NetworkPolicy enforcement, ReadWriteMany, QoS, or anything k3d's CNI cannot show every pull request, unless the gate below skips them
test/e2e/perf-gates-on.sh, run by lite-login.sh and e2e.sh under e2e-gates.yaml that every opt-in performance gate (scheduler.dispatch.buffer_size, database.scheduler_max_conns and statement_timeout_ms, executor.collect_settled_run_pods, observability.metrics.drop_legacy_names, ui.etag_revalidation, logs.tail.publish=on_demand, logs.sink.layout=segmented) takes effect in the running control plane, on the Lite and the k3d legs the gates' behavior under load (that is test/load/), and warm pools, which the same workflow's own E2E warm pools (k3d) job covers (test/e2e/warm-pool-e2e.sh), as does the warm pools leg of deploy-e2e, below, on pull requests, merge queue runs and pushes that touch their path pushes to main and release-*, and on demand; not on pull requests, to spare the runner queue
test/e2e/daemonless-deploy-e2e.sh, under e2e-daemonless-deploy.yaml the daemonless deploy journey (#1888): dexaflow deploy examples/taskflow_sales from the dexaflow-cli image with no container daemon reachable takes the dependency layer from wheels with uv, then the code layer, and the version runs green on k3d a dependency that uv must resolve and install (the example has none), the remote builder, or a daemon build rc tags and on demand (make e2e-daemonless-deploy, and make rc-smoke on Linux); not on pull requests, to spare the runner queue
test/e2e/pro-netpol-rwx.sh real NetworkPolicy enforcement and a real RWX volume, on kind with Calico and NFS cloud-specific behavior on demand
test/soak/ that a control plane dispatching for hours stays healthy, and that the cost of a tick does not track table growth anything about a single request, and it is not an at-most-once proof (see test/soak/README.md) a short harness smoke in CI; long runs are scheduled locally
test/load/ one cost at one instant behavior over time on demand
test/gcp/ what only a real cloud cluster can answer: enforcing CNI, real node counts, warm pools anything that k3d already answers, and it costs real money on demand, never in CI
test/release/ that the published artifact installs, and installs over a previous install anything about the code inside it on a release tag
test/om-contract/, test/ui-contract/ that our API and UI keep the contracts they claim that the behavior behind the contract is right every pull request

When the heavy Kubernetes jobs are skipped

The four k3d jobs (operator-e2e, split-e2e, e2e-dbt, deploy-e2e) cost about six to eight minutes each. A pull request that touches only the paths below cannot change what they test, so scripts/ci-heavy-gate.sh skips them:

docs/
spec/
test/load/
website/
\.changes/
.*\.md$
path what it is why it cannot affect a cluster run
docs/ generated API and CLI reference rendered output, never executed
spec/ specification sources not built into any image
test/load/ the load harness a different suite, run on demand
website/ the documentation site built and deployed by its own workflows
.changes/ changelog fragments (see .changie.yaml) inert data the release cut reads
*.md prose anywhere in the tree prose

Anything else runs them, including Makefile, scripts/, .github/ and the chart. The rule is deliberately one-sided: a file we have not thought about runs the jobs rather than skipping them.

This table is checked, not decorative. The fenced skip-paths block above is read by scripts/ci-heavy-gate.sh --self-test, which fails when it and the gate disagree. Editing one without the other turns the build red, which is the point: the same list living in prose and in code with nothing between them is how .changes/ came to be missing from the gate for a whole release cycle (#1234).

The warm pools leg of the deploy job

deploy-e2e runs twice, as a matrix: once at the shipped default and once with warm pools on (DEXAFLOW_E2E_WARM_POOLS=on, #1707). The default leg keeps the gate above. The warm pools leg costs as much again, so it runs only when a file on the warm placement or deploy path changed (--scope warm-pools), and on every event decides by that path: a pull request against its base branch, a merge queue run against the queue's base and a push against the commit before it. Prose under these paths does not count, as in the gate above.

internal/dispatch/
internal/executor/
internal/agentrpc/
internal/agent/
internal/kubeexchange/
internal/scheduler/
internal/storage/scheduler_store\.go
internal/storage/agent_store\.go
internal/storage/queries/runs\.sql
internal/domain/resource_unit\.go
internal/domain/default_limits\.go
internal/auth/agent_token\.go
internal/cli/deploy
internal/build/
cmd/dexaflow-agent/
proto/
test/e2e/deploy-e2e\.sh
test/e2e/lib\.sh
scripts/ci-heavy-gate\.sh

They are warm placement and the warm worker (dispatch, executor, the agent, its binary and its RPC side, the agent protocol, the agent token, the token exchange warm pools require), the scheduler that picks the version a task is dispatched for, the storage that resolves that version, the warm targets and the warm binding (BindWarmAttempt in runs.sql, and its generated runs.sql.go), the warm eligibility rules (resource_unit.go, default_limits.go), the deploy command and the image build, and the leg itself. The server wiring (cmd/dexaflow-server/), internal/config/, go.mod and ci.yaml are left out on purpose: with them the leg ran on 57 of 100 merges; with this list it runs on 37 of the last 100. A change confined to those paths that affects warm pools says in its pull request how warm pools were checked, for example with DEXAFLOW_E2E_WARM_POOLS=on bash test/e2e/deploy-e2e.sh on a local k3d. The same --self-test checks this block against the gate.

printf '%s\n' internal/api/dags.go | scripts/ci-heavy-gate.sh --decide-warm
# skip

printf '%s\n' internal/dispatch/dispatch.go | scripts/ci-heavy-gate.sh --decide-warm
# run

Asking the gate a question

printf '%s\n' README.md .changes/unreleased/x.yaml | scripts/ci-heavy-gate.sh --decide
# skip

printf '%s\n' internal/executor/reconcile.go | scripts/ci-heavy-gate.sh --decide
# run

The gate runs inside each job, on purpose

Not as a paths: filter and not as a job-level if:. A skipped job reports nothing, so a failure already recorded on that commit stays red forever: rerunning a pull_request run replays the original event payload, so the condition evaluates the same way every time and no remedy can clear the check. .github/workflows/changelog-guard.yaml carries that lesson, learned from the v0.4.7 cut (#1176).

Directories

Path Synopsis
load
deploy_p50 command
Command deploy_p50 is Load Experiment 7: the time of a code-only deploy and the warm-up of the pool after it (#1892).
Command deploy_p50 is Load Experiment 7: the time of a code-only deploy and the warm-up of the pool after it (#1892).
query_plans command
Command query_plans is Load Experiment 6: query plans at scale.
Command query_plans is Load Experiment 6: query plans at scale.
scheduler_ceiling command
Command scheduler_ceiling is Load Experiment 1: the scheduler ceiling.
Command scheduler_ceiling is Load Experiment 1: the scheduler ceiling.
ui_refresh command
Command ui_refresh is Load Experiment 4: what one auto-refresh cycle of the UI costs the control plane, and so how many viewers an interval allows (#1196).
Command ui_refresh is Load Experiment 4: what one auto-refresh cycle of the UI costs the control plane, and so how many viewers an interval allows (#1196).
usage_settle command
Command usage_settle is Load Experiment 8: what the usage event trigger of ADR 0096 adds to the writes that finish task attempts.
Command usage_settle is Load Experiment 8: what the usage event trigger of ADR 0096 adds to the writes that finish task attempts.
uuid_keys command
Command uuid_keys is Load Experiment 9 (#525): what a random UUIDv4 primary key costs the hot tables against a time-ordered UUIDv7, at insert time.
Command uuid_keys is Load Experiment 9 (#525): what a random UUIDv4 primary key costs the hot tables against a time-ordered UUIDv7, at insert time.
soak
fixture command
Command fixture is the soak battery's local HTTP endpoint.
Command fixture is the soak battery's local HTTP endpoint.
monitor command
Command monitor is the soak battery's continuous invariant checker.
Command monitor is the soak battery's continuous invariant checker.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL