Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions crates/busbar-plane-a2a/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,15 @@ fn main() -> Result<(), Box<dyn Error>> {
.join("tests/root/mod.rs")
.display()
);
// THE BLACK-BOX CASES' ADDRESS (the same `links` row): the root's black-box runner boots the
// real binary against every case file here, reading it as `DEP_BUSBAR_DOOR_CELLS_<CRATE>_BLACKBOX`.
println!(
"cargo::metadata=blackbox={}",
PathBuf::from(std::env::var("CARGO_MANIFEST_DIR")?)
.join("tests/blackbox")
.display()
);
println!("cargo:rerun-if-changed=tests/blackbox");
let out_dir = PathBuf::from(std::env::var("OUT_DIR")?);
let descriptor_path = out_dir.join("a2a-descriptor.bin");
let mut config = prost_build::Config::new();
Expand Down
10 changes: 10 additions & 0 deletions crates/busbar-plane-a2a/tests/blackbox/binary-answers-version.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"schema": "blackbox/1",
"case": "the binary carrying this door answers --version",
"_comment": "The seed case that proves the root resolves this crate's black-box directory; the plane's served cases are written beside it.",
"oracle": "cli|--version",
"requires": {"sections": ["agents"]},
"steps": [
{"validate": {"args": ["--version"], "exit": 0, "stdout_contains": ["busbar "]}}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
{
"schema": "blackbox/1",
"requires": {
"sections": [
"agents"
],
"features": [
"auth-admin-tokens"
]
},
"credentials": {
"signing_key": true
},
"vars": {
"MOCK_KEY": "x",
"BUSBAR_ADMIN_TOKEN": "{admin_token}"
},
"case": "law7: an agents section mounts the agent plane",
"_comment": "Law 7's control: the same binary with the `agents:` section serves the agent admin paths, lists the section as an overlay section, and answers its door as a plane door (RFC 6750) to an unauthenticated caller.",
"files": {
"config.yaml": "listen: \"127.0.0.1:{data_port}\"\nadmin_listen: \"127.0.0.1:{admin_port}\"\nadvanced:\n allow_destinations: [\"127.0.0.1\"]\nstore: {module: memory}\npublic_url: \"http://127.0.0.1:{data_port}\"\nidentity-providers:\n admin-tokens:\n module: admin-tokens\n token: { env: BUSBAR_ADMIN_TOKEN }\nauth:\n chain: [keys]\n signing_key: { file: \"{signing_key_file}\" }\n admin_auth: [admin-tokens]\nproviders:\n mock:\n api_key: { env: MOCK_KEY }\nmodels:\n test-model:\n provider: mock\nagents:\n a1: { url: \"https://a.example/card\", pin: { mechanism: unpinned } }\n",
"providers.yaml": "mock:\n protocol: anthropic\n base_url: \"http://127.0.0.1:9\"\n api_key_env: MOCK_KEY\n"
},
"steps": [
{
"boot": {
"listening": [
"data",
"admin"
],
"within_secs": 120
}
},
{
"call": {
"port": "admin",
"method": "GET",
"path": "/api/v1/admin/agents",
"bearer": "{admin_token}",
"status": 200
}
},
{
"call": {
"port": "admin",
"method": "DELETE",
"path": "/api/v1/admin/overlay/limits",
"bearer": "{admin_token}",
"body_contains": [
"`agents`"
]
}
},
{
"call": {
"port": "data",
"method": "POST",
"path": "/a2a",
"status": 401,
"body_contains": [
"error_description"
]
}
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
{
"schema": "blackbox/1",
"requires": {
"sections": [
"agents"
],
"features": [
"auth-admin-tokens"
]
},
"credentials": {
"signing_key": true
},
"vars": {
"MOCK_KEY": "x",
"BUSBAR_ADMIN_TOKEN": "{admin_token}"
},
"case": "law7: a 1.5.5 config leaves the agent plane unmounted",
"_comment": "Law 7 (core loads a plugin iff its configuration section is present): with no `agents:` section, every agent admin path answers as an unmounted path does, the overlay list names no agent section, and the agent door falls to the catch-all rather than answering as a plane door.",
"files": {
"config.yaml": "listen: \"127.0.0.1:{data_port}\"\nadmin_listen: \"127.0.0.1:{admin_port}\"\nadvanced:\n allow_destinations: [\"127.0.0.1\"]\nstore: {module: memory}\npublic_url: \"http://127.0.0.1:{data_port}\"\nidentity-providers:\n admin-tokens:\n module: admin-tokens\n token: { env: BUSBAR_ADMIN_TOKEN }\nauth:\n chain: [keys]\n signing_key: { file: \"{signing_key_file}\" }\n admin_auth: [admin-tokens]\nproviders:\n mock:\n api_key: { env: MOCK_KEY }\nmodels:\n test-model:\n provider: mock\n",
"providers.yaml": "mock:\n protocol: anthropic\n base_url: \"http://127.0.0.1:9\"\n api_key_env: MOCK_KEY\n"
},
"steps": [
{
"boot": {
"listening": [
"data",
"admin"
],
"within_secs": 120
}
},
{
"call": {
"port": "admin",
"method": "GET",
"path": "/api/v1/admin/no-such-path",
"bearer": "{admin_token}",
"status": 404
}
},
{
"call": {
"port": "admin",
"method": "GET",
"path": "/api/v1/admin/agents",
"bearer": "{admin_token}",
"status": 404
}
},
{
"call": {
"port": "admin",
"method": "GET",
"path": "/api/v1/admin/agents/x",
"bearer": "{admin_token}",
"status": 404
}
},
{
"call": {
"port": "admin",
"method": "PATCH",
"path": "/api/v1/admin/agents/x/settings",
"bearer": "{admin_token}",
"status": 404
}
},
{
"call": {
"port": "admin",
"method": "POST",
"path": "/api/v1/admin/agents/x/connect",
"bearer": "{admin_token}",
"status": 404
}
},
{
"call": {
"port": "admin",
"method": "POST",
"path": "/api/v1/admin/agents/x/approve",
"bearer": "{admin_token}",
"status": 404
}
},
{
"call": {
"port": "admin",
"method": "DELETE",
"path": "/api/v1/admin/overlay/limits",
"bearer": "{admin_token}",
"status": 400,
"body_lacks": [
"`agents`"
]
}
},
{
"call": {
"port": "admin",
"method": "DELETE",
"path": "/api/v1/admin/overlay/agents",
"bearer": "{admin_token}",
"status": 400
}
},
{
"call": {
"port": "data",
"method": "POST",
"path": "/a2a",
"body_lacks": [
"error_description"
]
}
}
]
}
27 changes: 25 additions & 2 deletions crates/busbar/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,12 @@ fn main() {
for cfg in linked_axis_cfgs(&manifest, &enabled).1 {
println!("cargo::rustc-check-cfg=cfg({cfg})");
}
// `BUSBAR_LINKED_AXES`: the same set as data, space-separated, so a black-box case's `requires`
// reads it at run time rather than a test spelling a `cfg` per axis.
println!(
"cargo:rustc-env=BUSBAR_LINKED_AXES={}",
linked_axis_cfgs(&manifest, &enabled).0.join(" ")
);
for cfg in linked_axis_cfgs(&manifest, &enabled).0 {
println!("cargo::rustc-cfg={cfg}");
}
Expand Down Expand Up @@ -419,13 +425,25 @@ fn door_cells_source(manifest: &str, enabled: &dyn Fn(&str) -> bool) -> (String,
let mut cells: Vec<String> = Vec::new();
let mut missing: Vec<String> = Vec::new();
let mut files: Vec<String> = Vec::new();
let mut blackbox: Vec<String> = Vec::new();
for (feature, krate) in metadata_map(manifest, "package.metadata.busbar.linked") {
let is_door = axes
.iter()
.any(|(f, a)| *f == feature && a.split_whitespace().any(|x| x == PLANE_DOOR_AXIS));
if !(enabled(&feature) && is_door) {
continue;
}
// THE BLACK-BOX CASES the crate states beside its cells (`blackbox=<dir>`, the same
// `links` name): read for every door, cells or none, so the runner sees each.
let box_var = format!(
"DEP_{}_BLACKBOX",
door_cells_links(&krate).to_uppercase().replace('-', "_")
);
println!("cargo:rerun-if-env-changed={box_var}");
if let Ok(dir) = env::var(&box_var) {
println!("cargo:rerun-if-changed={dir}");
blackbox.push(format!(" ({krate:?}, {dir:?}),\n"));
}
let var = format!(
"DEP_{}_CELLS",
door_cells_links(&krate).to_uppercase().replace('-', "_")
Expand Down Expand Up @@ -472,8 +490,13 @@ fn door_cells_source(manifest: &str, enabled: &dyn Fn(&str) -> bool) -> (String,
/// Every door plane's root cells: the path the ledger cites them by (the crate's census\n\
/// mount, `crates/<crate>/tests/root/mod.rs`) and the file its crate states.\n\
#[allow(dead_code)]\n\
static DOOR_CELLS_FILES: &[(&str, &str)] = &[\n{}];\n",
files.concat()
static DOOR_CELLS_FILES: &[(&str, &str)] = &[\n{}];\n\
/// Every door plane's black-box case directory (`blackbox=<dir>` under its `links` name):\n\
/// its crate and the directory its crate states.\n\
#[allow(dead_code)]\n\
static DOOR_BLACKBOX: &[(&str, &str)] = &[\n{}];\n",
files.concat(),
blackbox.concat()
);
(out, files)
}
Expand Down
Loading