128 fast activate/revert cycles are not a realistic load. restarts_service covers the restart of a service after an upgrade. nix flake check runs the normal tests only.
115 lines
4.5 KiB
Rust
115 lines
4.5 KiB
Rust
//! Raw discovery and lifecycle guest for activation protocol tests.
|
|
use serde_json::{Value, json};
|
|
use std::io::{self, BufRead, Write};
|
|
/// Emits one flushed JSON-RPC response.
|
|
fn send(value: Value) {
|
|
println!("{value}");
|
|
io::stdout().flush().unwrap();
|
|
}
|
|
/// Calls a provider after activation releases an old consumer process.
|
|
fn deferred(request: &Value, plugin: &str, lines: &mut impl Iterator<Item = io::Result<String>>) {
|
|
send(
|
|
json!({"jsonrpc":"2.0","id":request["id"],"result":std::env::var("SAUSAGE_PID").unwrap()}),
|
|
);
|
|
let before = std::time::Instant::now();
|
|
while !std::path::Path::new(&format!("/state/{plugin}/release-call")).exists() {
|
|
assert!(before.elapsed() < std::time::Duration::from_secs(30));
|
|
}
|
|
send(json!({"jsonrpc":"2.0","id":"deferred","method":"notes.legacy","params":{}}));
|
|
for line in lines {
|
|
let response: Value = serde_json::from_str(&line.unwrap()).unwrap();
|
|
if response["id"] == "deferred" {
|
|
std::fs::write(format!("/state/{plugin}/call-result"), response.to_string()).unwrap();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
/// Answers a method that version two removes from its interface.
|
|
fn legacy(request: &Value, document: &Value, version: &str) {
|
|
if document["methods"]
|
|
.as_array()
|
|
.unwrap()
|
|
.iter()
|
|
.any(|m| m["name"] == "legacy")
|
|
{
|
|
send(json!({"jsonrpc":"2.0","id":request["id"],"result":version}));
|
|
} else {
|
|
send(
|
|
json!({"jsonrpc":"2.0","id":request["id"],"error":{"code":-32601,"message":"legacy removed","data":{"version":version}}}),
|
|
);
|
|
}
|
|
}
|
|
/// Reads a version-specific discovery document without the SDK.
|
|
fn main() {
|
|
let version = env!("FIXTURE_VERSION");
|
|
let plugin = std::env::var("SAUSAGE_PLUGIN").unwrap();
|
|
let mut lines = io::stdin().lock().lines();
|
|
let request: Value = serde_json::from_str(&lines.next().unwrap().unwrap()).unwrap();
|
|
let document: Value =
|
|
serde_json::from_slice(&std::fs::read(format!("/state/{plugin}/{version}.json")).unwrap())
|
|
.unwrap();
|
|
let result = match request["method"].as_str().unwrap() {
|
|
"deferred" => {
|
|
deferred(&request, &plugin, &mut lines);
|
|
return;
|
|
}
|
|
"legacy" => {
|
|
legacy(&request, &document, version);
|
|
return;
|
|
}
|
|
"rpc.discover" => {
|
|
if document["x-test-no-answer"] == true {
|
|
for _ in &mut lines {}
|
|
return;
|
|
}
|
|
if document["x-test-wait"] == true {
|
|
std::fs::write(format!("/state/{plugin}/discover-started"), "ready").unwrap();
|
|
let before = std::time::Instant::now();
|
|
while !std::path::Path::new(&format!("/state/{plugin}/discover-release")).exists() {
|
|
assert!(before.elapsed() < std::time::Duration::from_secs(30));
|
|
}
|
|
}
|
|
document
|
|
}
|
|
"read" => {
|
|
let text =
|
|
std::fs::read_to_string(request["params"]["path"].as_str().unwrap()).unwrap();
|
|
serde_json::from_str(&text).unwrap_or(json!(text))
|
|
}
|
|
"rpc.retired" => {
|
|
std::fs::write(
|
|
format!("/state/{plugin}/retired"),
|
|
request["params"]["previous"].as_str().unwrap(),
|
|
)
|
|
.unwrap();
|
|
json!({"retired":version})
|
|
}
|
|
"serve" | "hold" => {
|
|
send(json!({"jsonrpc":"2.0","id":request["id"],"result":{"version":version}}));
|
|
if request["method"] == "serve" {
|
|
std::fs::write(format!("/state/{plugin}/service"), version).unwrap();
|
|
}
|
|
for _ in lines {}
|
|
std::fs::write(format!("/state/{plugin}/ended-{version}"), "ended").unwrap();
|
|
return;
|
|
}
|
|
_ => json!({"version":version}),
|
|
};
|
|
send(json!({"jsonrpc":"2.0","id":request["id"],"result":result}));
|
|
if request["method"] == "rpc.discover" && result["x-test-linger"] == true {
|
|
if result["x-test-stubborn"] == true {
|
|
let before = std::time::Instant::now();
|
|
while !std::path::Path::new(&format!("/state/{plugin}/discovery-exit")).exists() {
|
|
assert!(before.elapsed() < std::time::Duration::from_secs(30));
|
|
}
|
|
} else {
|
|
for _ in lines {}
|
|
}
|
|
std::fs::write(
|
|
format!("/state/{plugin}/discovery-ended-{version}"),
|
|
"ended",
|
|
)
|
|
.unwrap();
|
|
}
|
|
}
|