test(sync): 登记 S-02 生产验收

This commit is contained in:
2026-09-09 09:39:27 +08:00
parent 35192619b8
commit 48d828a0e8
4 changed files with 260 additions and 1 deletions
+128
View File
@@ -378,6 +378,7 @@ impl Workspace {
#[cfg(test)]
mod tests {
use super::*;
use std::fs;
#[test]
fn inbox_reopen_before_and_after_file_commit_never_advances_cursor_early() {
for committed in [false, true] {
@@ -430,4 +431,131 @@ mod tests {
assert!(!ws.sync_apply_pending(&binding.id).unwrap());
}
}
fn s02_revision(file_id: &str) -> RemoteRevision {
RemoteRevision {
vault_id: "remote-vault".into(),
sequence: 1,
file_id: file_id.into(),
base_revision: 0,
path: "nested/a.md".into(),
operation: "put".into(),
hash: Some(hash(b"remote-content")),
size: 14,
operation_id: Uuid::new_v4().to_string(),
}
}
#[test]
#[ignore = "helper process killed by the S-02 parent at a durable pull boundary"]
fn s02_pull_boundary_worker() {
let root = std::path::PathBuf::from(
std::env::var("OPENNEXUS_S02_ROOT").expect("controlled S-02 root"),
);
let boundary = std::env::var("OPENNEXUS_S02_BOUNDARY").expect("S-02 boundary");
let revision: RemoteRevision = serde_json::from_slice(
&fs::read(root.join(".s02-revision.json")).expect("S-02 revision fixture"),
)
.unwrap();
let mut ws = Workspace::open(&root).unwrap();
let binding = ws.sync_binding().unwrap().unwrap();
ws.sync_store_bytes(b"remote-content").unwrap();
if boundary != "spool" {
ws.sync_set_boundary(&binding.id, 1).unwrap();
ws.sync_stage(&binding.id, &revision).unwrap();
}
if boundary == "file" {
let operation: String = ws
.db
.query_row("SELECT operation_id FROM sync_inbox", [], |row| row.get(0))
.unwrap();
ws.write_with_identity(
"nested/a.md",
"",
b"remote-content",
"remote",
&operation,
Some(&revision.file_id),
)
.unwrap();
} else if boundary == "cursor" {
assert!(ws.sync_apply_pending(&binding.id).unwrap());
}
fs::write(root.join(".s02-boundary-ready"), boundary).unwrap();
loop {
std::thread::sleep(std::time::Duration::from_secs(60));
}
}
#[test]
#[ignore = "80 real process kills; run through the S-02 production acceptance driver"]
fn s02_pull_each_persistence_boundary_survives_twenty_process_kills() {
use std::process::{Command, Stdio};
for boundary in ["spool", "stage", "file", "cursor"] {
for round in 0..20 {
let root = tempfile::tempdir().unwrap();
let mut ws = Workspace::open(root.path()).unwrap();
let binding = ws
.sync_bind_download("https://sync.example", "remote-vault", "account")
.unwrap();
let file_id = Uuid::new_v4().to_string();
let revision = s02_revision(&file_id);
fs::write(
root.path().join(".s02-revision.json"),
serde_json::to_vec(&revision).unwrap(),
)
.unwrap();
drop(ws);
let mut worker = Command::new(std::env::current_exe().unwrap())
.args([
"--ignored",
"--exact",
"sync_inbox::tests::s02_pull_boundary_worker",
])
.env("OPENNEXUS_S02_ROOT", root.path())
.env("OPENNEXUS_S02_BOUNDARY", boundary)
.stdin(Stdio::null())
.stdout(Stdio::null())
.stderr(Stdio::null())
.spawn()
.unwrap();
let marker = root.path().join(".s02-boundary-ready");
let deadline = std::time::Instant::now() + std::time::Duration::from_secs(10);
while !marker.exists() {
assert!(
worker.try_wait().unwrap().is_none(),
"S-02 {boundary} worker exited in round {round}"
);
assert!(
std::time::Instant::now() < deadline,
"S-02 {boundary} timeout in round {round}"
);
std::thread::sleep(std::time::Duration::from_millis(10));
}
worker.kill().unwrap();
worker.wait().unwrap();
let mut ws = Workspace::open(root.path()).unwrap();
let expected_cursor = i64::from(boundary == "cursor");
assert_eq!(
ws.sync_binding().unwrap().unwrap().cursor,
expected_cursor,
"cursor advanced early at {boundary} round {round}"
);
if expected_cursor == 0 {
ws.sync_store_bytes(b"remote-content").unwrap();
ws.sync_set_boundary(&binding.id, 1).unwrap();
ws.sync_stage(&binding.id, &revision).unwrap();
while ws.sync_apply_pending(&binding.id).unwrap() {}
} else {
assert!(!ws.sync_apply_pending(&binding.id).unwrap());
}
assert_eq!(ws.sync_binding().unwrap().unwrap().cursor, 1);
let document = ws.read("nested/a.md").unwrap();
assert_eq!(document.content, "remote-content");
assert_eq!(document.entry.file_id, file_id);
assert_eq!(document.entry.hash, hash(b"remote-content"));
assert_eq!(ws.pending_count().unwrap(), 0);
}
}
}
}