Return compact activation summaries instead of discovery schemas
ci / check (push) Failing after 2m40s
ci / check (push) Failing after 2m40s
Card: SAU-158
This commit is contained in:
@@ -43,6 +43,86 @@ fn fixture(version: usize) -> PathBuf {
|
||||
})[version - 1]
|
||||
.clone()
|
||||
}
|
||||
fn fixture_hash(version: usize) -> String {
|
||||
use sha2::{Digest, Sha256};
|
||||
format!(
|
||||
"{:x}",
|
||||
Sha256::digest(std::fs::read(fixture(version)).unwrap())
|
||||
)
|
||||
}
|
||||
|
||||
/// PROTOCOL 10.3: summaries omit even large schemas and report sorted main-method diffs.
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn summarizes_method_changes() {
|
||||
let mut old = document("unchanged");
|
||||
old["methods"] = json!([
|
||||
{"name":"z_removed"}, {"name":"a_removed"}, {"name":"direct", "params":[]},
|
||||
{"name":"referenced", "result":{"schema":{"$ref":"#/components/schemas/Node"}}},
|
||||
{"name":"unrelated", "result":{"schema":{"type":"string"}}}
|
||||
]);
|
||||
old["components"]["schemas"] = json!({
|
||||
"Node":{"properties":{"next":{"$ref":"#/components/schemas/Node"}, "value":{"$ref":"#/components/schemas/Value"}}},
|
||||
"Value":{"type":"string"}, "Unused":{"type":"string"}
|
||||
});
|
||||
let mut next = old.clone();
|
||||
next["methods"].as_array_mut().unwrap().drain(..2);
|
||||
next["methods"][0]["params"] = json!([{"name":"limit","schema":{"type":"integer"}}]);
|
||||
next["methods"].as_array_mut().unwrap().extend(
|
||||
json!([
|
||||
{"name":"z_added"}, {"name":"a_added"}
|
||||
])
|
||||
.as_array()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.cloned(),
|
||||
);
|
||||
next["components"]["schemas"]["Value"]["type"] = json!("integer");
|
||||
next["components"]["schemas"]["Unused"]["description"] = json!("x".repeat(220_000));
|
||||
let world = TestWorld::new();
|
||||
world.plugin("notes", old, next.clone());
|
||||
let host = world.start().await;
|
||||
let result = activate(&host, "notes").await.unwrap();
|
||||
assert_eq!(result["notes"]["method_count"], 5);
|
||||
assert_eq!(result["notes"]["added"], json!(["a_added", "z_added"]));
|
||||
assert_eq!(
|
||||
result["notes"]["removed"],
|
||||
json!(["a_removed", "z_removed"])
|
||||
);
|
||||
assert_eq!(result["notes"]["changed"], json!(["direct", "referenced"]));
|
||||
assert!(result.to_string().len() < 1024);
|
||||
assert_eq!(call(&host, "notes.rpc.discover", json!({})).await, next);
|
||||
assert_eq!(
|
||||
call(
|
||||
&host,
|
||||
"notes.read",
|
||||
json!({"path":"/proc/core/plugins/notes/discover.json"})
|
||||
)
|
||||
.await,
|
||||
next
|
||||
);
|
||||
host.stop().await;
|
||||
}
|
||||
|
||||
/// PROTOCOL 10.3: first installation has no previous build; a no-op has no method changes.
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn summarizes_first_install_and_noop() {
|
||||
let world = TestWorld::new();
|
||||
world.plugin("notes", document("add"), document("add"));
|
||||
std::fs::remove_file(world.0.join("plugins/notes/plugin.wasm")).unwrap();
|
||||
let host = world.start().await;
|
||||
let result = activate(&host, "notes").await.unwrap();
|
||||
assert_eq!(result["notes"]["previous"], Value::Null);
|
||||
assert_eq!(result["notes"]["added"], json!(["add"]));
|
||||
assert_eq!(result["notes"]["hash"], fixture_hash(2));
|
||||
let result = activate(&host, "notes").await.unwrap();
|
||||
assert_eq!(result["notes"]["previous"], fixture_hash(2));
|
||||
for field in ["added", "removed", "changed"] {
|
||||
assert_eq!(result["notes"][field], json!([]));
|
||||
}
|
||||
assert!(!world.0.join("plugins/notes/plugin.prev.wasm").exists());
|
||||
host.stop().await;
|
||||
}
|
||||
|
||||
struct TestWorld(PathBuf);
|
||||
impl TestWorld {
|
||||
/// Creates an isolated world with two version documents per plugin.
|
||||
@@ -481,7 +561,19 @@ async fn activates_copy() {
|
||||
world.plugin("notes", document("add"), document("add"));
|
||||
let host = world.start().await;
|
||||
let result = activate(&host, "notes").await.unwrap();
|
||||
assert!(result["notes"]["methods"].is_array());
|
||||
assert_eq!(
|
||||
result,
|
||||
json!({"notes": {
|
||||
"plugin":"notes", "wasm":"/plugins/notes/plugin.wasm",
|
||||
"hash":fixture_hash(2), "previous":fixture_hash(1),
|
||||
"method_count":1, "added":[], "removed":[], "changed":[],
|
||||
"interface_check":"passed"
|
||||
}})
|
||||
);
|
||||
assert_eq!(
|
||||
call(&host, "notes.rpc.discover", json!({})).await,
|
||||
document("add")
|
||||
);
|
||||
assert_eq!(
|
||||
call(&host, "notes.version", json!({})).await["version"],
|
||||
"2"
|
||||
@@ -577,7 +669,12 @@ async fn activates_group() {
|
||||
consumer("notes", document("other")),
|
||||
);
|
||||
let host = world.start().await;
|
||||
call(&host,"core.activate",json!({"plugins":[{"plugin":"notes","wasm":"/state/notes/next.wasm"},{"plugin":"agent","wasm":"/state/agent/next.wasm"}]})).await;
|
||||
let result = call(&host,"core.activate",json!({"plugins":[{"plugin":"notes","wasm":"/state/notes/next.wasm"},{"plugin":"agent","wasm":"/state/agent/next.wasm"}]})).await;
|
||||
assert_eq!(result.as_object().unwrap().len(), 2);
|
||||
assert_eq!(result["notes"]["added"], json!(["other"]));
|
||||
assert_eq!(result["notes"]["removed"], json!(["add"]));
|
||||
assert_eq!(result["agent"]["method_count"], 1);
|
||||
assert_eq!(result["agent"]["interface_check"], "passed");
|
||||
assert_eq!(
|
||||
call(&host, "agent.version", json!({})).await["version"],
|
||||
"2"
|
||||
@@ -594,12 +691,13 @@ async fn force_skips_checks() {
|
||||
consumer("absent", document("add")),
|
||||
);
|
||||
let host = world.start().await;
|
||||
call(
|
||||
let result = call(
|
||||
&host,
|
||||
"core.activate",
|
||||
json!({"plugin":"notes","wasm":"/state/notes/next.wasm","force":true}),
|
||||
)
|
||||
.await;
|
||||
assert_eq!(result["notes"]["interface_check"], "skipped");
|
||||
host.stop().await;
|
||||
}
|
||||
/// PROTOCOL 10.3: revert activates the previous copy and preserves the replaced version.
|
||||
@@ -609,7 +707,11 @@ async fn reverts_previous_version() {
|
||||
world.plugin("notes", document("add"), document("add"));
|
||||
let host = world.start().await;
|
||||
activate(&host, "notes").await.unwrap();
|
||||
call(&host, "core.revert", json!({"plugin":"notes"})).await;
|
||||
let result = call(&host, "core.revert", json!({"plugin":"notes"})).await;
|
||||
assert_eq!(result["notes"]["hash"], fixture_hash(1));
|
||||
assert_eq!(result["notes"]["previous"], fixture_hash(2));
|
||||
assert_eq!(result["notes"]["interface_check"], "passed");
|
||||
assert!(result["notes"].get("methods").is_none());
|
||||
assert_eq!(
|
||||
call(&host, "notes.version", json!({})).await["version"],
|
||||
"1"
|
||||
|
||||
Reference in New Issue
Block a user