Problem
Commands defined in bugatti.config.toml are global — every test file gets the same commands. There's no way to customize a command for a specific test file without workarounds like wrapper scripts or separate config directories.
Example use case: In ai-barometer, admin tests need additional env vars passed to the ultraman start command:
env ADMIN_GITHUB_LOGINS=cadence-test ultraman start
Currently the only options are wrapper scripts, separate config directories, or baking conditional logic into the command itself.
Proposed solution
Extend [overrides] in .test.toml files to support command overrides, following the same pattern as the existing [overrides.provider]:
name = "Admin tests"
[overrides.commands.server]
cmd = "env ADMIN_GITHUB_LOGINS=cadence-test ultraman start"
[[steps]]
instruction = "Verify admin panel loads"
Semantics
- Any
CommandDef field except kind can be overridden (cmd, readiness_url, readiness_urls, readiness_timeout_secs)
- Uses the same
Option-based merge logic as provider overrides: None = keep global, Some = replace
- Only existing global commands can be overridden — unknown command names are warned and ignored
- No changes needed to
command.rs, cli.rs, executor.rs, or main.rs — they already consume the merged Config
More examples
Override readiness settings:
[overrides.commands.server]
readiness_timeout_secs = 120
Override multiple commands:
[overrides.commands.server]
cmd = "env ADMIN_GITHUB_LOGINS=cadence-test ultraman start"
[overrides.commands.migrate]
cmd = "cargo sqlx migrate run --with-admin-seeds"
Implementation plan
Files to change
1. src/test_file.rs
- Add
CommandOverrides struct (all fields from CommandDef except kind, wrapped in Option)
- Add
commands: Option<BTreeMap<String, CommandOverrides>> to TestOverrides
- Add
use std::collections::BTreeMap
- Add parse tests for the new TOML syntax
#[derive(Debug, Clone, Default, Deserialize, PartialEq)]
#[serde(deny_unknown_fields)]
pub struct CommandOverrides {
pub cmd: Option<String>,
pub readiness_url: Option<String>,
pub readiness_urls: Option<Vec<String>>,
pub readiness_timeout_secs: Option<u64>,
}
2. src/config.rs
- Add
CommandDef::merge_overrides(&self, &CommandOverrides) -> CommandDef method
- Update
effective_config() to merge command overrides (same pattern as provider merge)
- Update import to include
CommandOverrides
- Fix all existing test constructors to include
commands: None
- Add merge tests (full override, partial, unknown name ignored, None preserves global)
impl CommandDef {
pub fn merge_overrides(&self, overrides: &CommandOverrides) -> CommandDef {
CommandDef {
kind: self.kind.clone(), // never overridden
cmd: overrides.cmd.clone().unwrap_or_else(|| self.cmd.clone()),
readiness_url: overrides.readiness_url.clone().or_else(|| self.readiness_url.clone()),
readiness_urls: overrides.readiness_urls.clone().unwrap_or_else(|| self.readiness_urls.clone()),
readiness_timeout_secs: overrides.readiness_timeout_secs.or(self.readiness_timeout_secs),
}
}
}
Update effective_config():
let commands = match test_file.overrides.as_ref().and_then(|o| o.commands.as_ref()) {
Some(cmd_overrides) => {
let mut merged = global.commands.clone();
for (name, overrides) in cmd_overrides {
if let Some(global_def) = global.commands.get(name) {
merged.insert(name.clone(), global_def.merge_overrides(overrides));
}
}
merged
}
None => global.commands.clone(),
};
3. tests/pipeline_integration.rs
- Add integration test for command override merging
What does NOT change
src/command.rs — consumes &Config which already has merged commands
src/cli.rs — no new CLI flags needed
src/executor.rs, src/main.rs, src/run.rs — untouched
Problem
Commands defined in
bugatti.config.tomlare global — every test file gets the same commands. There's no way to customize a command for a specific test file without workarounds like wrapper scripts or separate config directories.Example use case: In ai-barometer, admin tests need additional env vars passed to the
ultraman startcommand:Currently the only options are wrapper scripts, separate config directories, or baking conditional logic into the command itself.
Proposed solution
Extend
[overrides]in.test.tomlfiles to support command overrides, following the same pattern as the existing[overrides.provider]:Semantics
CommandDeffield exceptkindcan be overridden (cmd,readiness_url,readiness_urls,readiness_timeout_secs)Option-based merge logic as provider overrides:None= keep global,Some= replacecommand.rs,cli.rs,executor.rs, ormain.rs— they already consume the mergedConfigMore examples
Override readiness settings:
Override multiple commands:
Implementation plan
Files to change
1.
src/test_file.rsCommandOverridesstruct (all fields fromCommandDefexceptkind, wrapped inOption)commands: Option<BTreeMap<String, CommandOverrides>>toTestOverridesuse std::collections::BTreeMap2.
src/config.rsCommandDef::merge_overrides(&self, &CommandOverrides) -> CommandDefmethodeffective_config()to merge command overrides (same pattern as provider merge)CommandOverridescommands: NoneUpdate
effective_config():3.
tests/pipeline_integration.rsWhat does NOT change
src/command.rs— consumes&Configwhich already has merged commandssrc/cli.rs— no new CLI flags neededsrc/executor.rs,src/main.rs,src/run.rs— untouched