Projects, Jobs, Spans
Projects
DAGZ identifies files and test suites using Projects.
The Project URI is the unique identifier in DAGZ. You can have multiple projects in the same git repository at different sub-directories, and they will be treated as separate projects in DAGZ.
It is recommended to create a persistent project configuration (.dagz/config.yaml) using zb init, and check it into git.
zb init derives the project URI from git origin URL and the relative path in the worktree, but you can edit it if necessary.
This ensures that your project URI is stable and doesn't change based on where you run it from.
When you're running without a git worktree (e.g., in a Docker container),
make sure every folder copied into the Docker has been initialized with zb init,
and have its .dagz/config.yaml copied over as well.
Test runs in new directories automatically infer their project URI from the git worktree, but it is still recommended to create a stable configuration with zb init.
Jobs
A job is one execution of your test suite.
Jobs can combine multiple pytest --dagz invocations in a parallel CI step (e.g., GitLab parallel jobs).
In this case, the first process to come up becomes the scheduler for the entire parallel step.
Each job gets a unique ID.
The short form looks like j10 for the 10th job today, or j1201.1 for December 1st's first job.
Jobs are the primary unit in the dashboard. You can drill into any job to see its selected tests, skipped tests, failures, timing, and selection traces.
Jobs are the equivalent of OpenTelemetry's "traces", though they're typically much longer.
Spans
A span is a single execution flow. Spans are nested in a tree that also includes spans from sub-processes or external services. They are largely equivalent to OpenTelemetry's "spans". Unlike OpenTelemetry, DAGZ's spans have a free-text type field.
Span types include:
- test: A test case execution. See below.
- program.load: A load-time phase.
- py.import: A module's module-level code execution.
Tests
A test is a span of type "test". It corresponds to a single test case in your codebase. Tests are the primary unit of selection and reporting.
Test spans can have nested:
- fixture spans for any fixtures they use
- cache spans for any cache lookups they trigger
- subproc spans for any subprocesses they launch
- test.call for the actual test body, excluding setup/teardown
For how baselines drive test selection and how the scheduler, vassals, and workers fit together, see Test Selection and Scheduling.