mz_testdrive/action/
psql.rs1use anyhow::{Context, bail};
11use mz_ore::option::OptionExt;
12use tokio::process::Command;
13
14use crate::action::{ControlFlow, State};
15use crate::parser::BuiltinCommand;
16use crate::util::text;
17
18pub async fn run_execute(
19    mut cmd: BuiltinCommand,
20    state: &State,
21) -> Result<ControlFlow, anyhow::Error> {
22    let command = cmd.args.string("command")?;
23    cmd.args.done()?;
24
25    let expected_output = cmd.input.join("\n");
26    let output = Command::new("psql")
27        .args([
28            "--no-psqlrc",
31            "--pset",
32            "footer=off",
33            "--command",
34            &command,
35            &format!(
36                "postgres://{}@{}",
37                state.materialize.user, state.materialize.sql_addr
38            ),
39        ])
40        .output()
41        .await
42        .context("execution of `psql` failed")?;
43    if !output.status.success() {
44        bail!(
45            "psql reported failure with exit code {}: {}",
46            output.status.code().display_or("unknown"),
47            String::from_utf8_lossy(&output.stderr),
48        );
49    }
50    let stdout = text::trim_trailing_space(&String::from_utf8_lossy(&output.stdout));
51    if expected_output != stdout {
52        text::print_diff(&expected_output, &*stdout);
53        bail!("psql returned unexpected output (diff above)");
54    }
55    Ok(ControlFlow::Continue)
56}