mirror of
https://github.com/ModernRelay/omnigraph.git
synced 2026-06-18 02:24:27 +02:00
feat(cli): no-default-graph errors list candidate graphs (RFC-011 D7) (#245)
When a server/cluster scope resolves with no --graph and no default_graph, the CLI auto-uses a sole graph (cluster) or errors listing the candidate graph ids (cluster catalog; multi-graph server via best-effort GET /graphs), never a silent pick. GraphClient::resolve becomes async; flat/single-graph servers and happy paths are unaffected.
This commit is contained in:
parent
b395757e21
commit
1bc0ea6b51
10 changed files with 262 additions and 62 deletions
|
|
@ -1006,21 +1006,80 @@ fn optimize_unknown_cluster_graph_id_errors() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn cluster_without_graph_demands_a_graph_selector() {
|
||||
// A cluster holds many graphs; `--cluster` alone can't pick one. The scope
|
||||
// resolver demands `--graph <id>` (replacing the old `--cluster-graph`
|
||||
// requirement) before it ever touches cluster state.
|
||||
fn optimize_auto_uses_the_sole_cluster_graph() {
|
||||
// RFC-011 D7: a cluster with exactly one applied graph needs no --graph —
|
||||
// the resolver enumerates the catalog and uses the only candidate.
|
||||
let temp = applied_knowledge_cluster();
|
||||
let out = output_success(
|
||||
cli()
|
||||
.arg("optimize")
|
||||
.arg("--cluster")
|
||||
.arg(temp.path())
|
||||
.arg("--json"),
|
||||
);
|
||||
assert!(
|
||||
parse_stdout_json(&out)["tables"].as_array().is_some(),
|
||||
"optimize should auto-resolve the sole cluster graph"
|
||||
);
|
||||
}
|
||||
|
||||
/// Stand up an applied cluster with two graphs (`knowledge`, `archive`).
|
||||
fn applied_two_graph_cluster() -> tempfile::TempDir {
|
||||
let temp = tempdir().unwrap();
|
||||
let root = temp.path();
|
||||
fs::write(
|
||||
root.join("people.pg"),
|
||||
"node Person {\n name: String @key\n age: I32?\n}\n",
|
||||
)
|
||||
.unwrap();
|
||||
fs::write(root.join("base.policy.yaml"), "rules: []\n").unwrap();
|
||||
fs::write(
|
||||
root.join("cluster.yaml"),
|
||||
r#"
|
||||
version: 1
|
||||
metadata:
|
||||
name: two-graph
|
||||
state:
|
||||
backend: cluster
|
||||
lock: true
|
||||
graphs:
|
||||
knowledge:
|
||||
schema: ./people.pg
|
||||
archive:
|
||||
schema: ./people.pg
|
||||
policies:
|
||||
base:
|
||||
file: ./base.policy.yaml
|
||||
applies_to: [knowledge, archive]
|
||||
"#,
|
||||
)
|
||||
.unwrap();
|
||||
init_named_cluster_graph(root, "knowledge", "people.pg");
|
||||
init_named_cluster_graph(root, "archive", "people.pg");
|
||||
assert_eq!(cluster_json(root, "import")["ok"], true);
|
||||
assert_eq!(cluster_json(root, "apply")["converged"], true);
|
||||
temp
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn optimize_on_multi_graph_cluster_without_graph_lists_candidates() {
|
||||
// RFC-011 D7: >1 graph and no --graph → error naming every candidate,
|
||||
// never an auto-pick.
|
||||
let temp = applied_two_graph_cluster();
|
||||
let out = output_failure(
|
||||
cli()
|
||||
.arg("optimize")
|
||||
.arg("--cluster")
|
||||
.arg(".")
|
||||
.arg(temp.path())
|
||||
.arg("--json"),
|
||||
);
|
||||
let stderr = String::from_utf8_lossy(&out.stderr);
|
||||
assert!(
|
||||
stderr.contains("--graph <id>"),
|
||||
"expected --cluster to demand --graph; got: {stderr}"
|
||||
stderr.contains("2 graphs")
|
||||
&& stderr.contains("archive")
|
||||
&& stderr.contains("knowledge")
|
||||
&& stderr.contains("--graph <id>"),
|
||||
"expected a candidate-listing error; got: {stderr}"
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1136,5 +1136,27 @@ auth:
|
|||
.collect();
|
||||
assert_eq!(ids, vec!["alpha"]);
|
||||
|
||||
// RFC-011 D7: addressing the multi-graph server via `--server <url>` with no
|
||||
// `--graph` errors and lists the candidate graphs (the resolver probes
|
||||
// GET /graphs; the default-env token authorizes it).
|
||||
let no_graph = cli()
|
||||
.env("OMNIGRAPH_BEARER_TOKEN", "admin-token")
|
||||
.arg("query")
|
||||
.arg("--server")
|
||||
.arg(&server.base_url)
|
||||
.arg("-e")
|
||||
.arg("query q { match { $p: Person { name: \"x\" } } return { $p.name } }")
|
||||
.output()
|
||||
.unwrap();
|
||||
assert!(
|
||||
!no_graph.status.success(),
|
||||
"multi-graph server with no --graph must error"
|
||||
);
|
||||
let stderr = String::from_utf8_lossy(&no_graph.stderr);
|
||||
assert!(
|
||||
stderr.contains("alpha") && stderr.contains("--graph <id>"),
|
||||
"expected a candidate-listing error naming alpha; got: {stderr}"
|
||||
);
|
||||
|
||||
drop(server);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue