| 695 | |
| 696 | #[test] |
| 697 | fn persistent_root_lock_rejects_cross_process_open() -> anyhow::Result<()> { |
| 698 | let root = tempfile::TempDir::new()?; |
| 699 | let child = Command::new(env!("CARGO_BIN_EXE_pglite-proxy")) |
| 700 | .arg("--root") |
| 701 | .arg(root.path()) |
| 702 | .args(["--tcp", "127.0.0.1:0", "--print-uri"]) |
| 703 | .stdout(Stdio::piped()) |
| 704 | .stderr(Stdio::piped()) |
| 705 | .spawn()?; |
| 706 | let mut child = ChildGuard::new(child, "pglite-proxy")?; |
| 707 | |
| 708 | let stdout = child |
| 709 | .child_mut() |
| 710 | .stdout |
| 711 | .take() |
| 712 | .ok_or_else(|| anyhow::anyhow!("missing pglite-proxy stdout"))?; |
| 713 | let mut line = String::new(); |
| 714 | let read = BufReader::new(stdout).read_line(&mut line)?; |
| 715 | if read == 0 { |
| 716 | let stderr = child.collect_stderr(); |
| 717 | anyhow::bail!("pglite-proxy exited before printing URI\n\nstderr:\n{stderr}"); |
| 718 | } |
| 719 | assert!(line.starts_with("postgresql://"), "{line:?}"); |
| 720 | |
| 721 | let err = match Pglite::builder().path(root.path()).open() { |
| 722 | Ok(mut db) => { |
| 723 | let close = db.close(); |
| 724 | let stderr = child.collect_stderr(); |
| 725 | anyhow::bail!( |
| 726 | "direct open unexpectedly succeeded while another process owns the root lock; close={close:?}\n\nstderr:\n{stderr}" |
| 727 | ); |
| 728 | } |
| 729 | Err(err) => err, |
| 730 | }; |
| 731 | let message = format!("{err:#}"); |
| 732 | if !message.contains("PGlite root is already in use") { |
| 733 | let stderr = child.collect_stderr(); |
| 734 | anyhow::bail!("unexpected cross-process root-lock error: {message}\n\nstderr:\n{stderr}"); |
| 735 | } |
| 736 | Ok(()) |
| 737 | } |
| 738 | |
| 739 | #[test] |
| 740 | fn runtime_smoke() -> anyhow::Result<()> { |