use anyhow::{bail, Result}; use assert_cmd::{cargo::cargo_bin, Command}; use rexpect::session::{spawn_command, PtySession}; use tempfile::TempDir; struct TestContext { workdir: TempDir, ssh_port: u32, docker_process: PtySession, } fn build_docker_image() -> Result<()> { let mut command = std::process::Command::new("docker"); command.args([ "build", "-t", "shackle-server", "--build-arg", &format!("SHELL={}", cargo_bin(env!("CARGO_PKG_NAME")).display()), "./", ]); let status = command.status()?; if !status.success() { bail!("Failed to build dockerfile"); } Ok(()) } fn spawn_ssh_server() -> Result { build_docker_image()?; let workdir = tempfile::tempdir()?; let mut command = std::process::Command::new("docker"); // TODO: randomize port? command.args(["run", "-it", "-p", "2022:22", "shackle-server"]); command.current_dir(&workdir); let docker_process = spawn_command(command, Some(3000))?; Ok(TestContext { workdir, ssh_port: 2022, docker_process, }) } fn connect_to_ssh_server_interactively(c: &TestContext) -> Result { let mut command = std::process::Command::new("ssh"); command.args(["-p", &c.ssh_port.to_string(), "shukkie@localhost"]); command.current_dir(&c.workdir); let mut p = spawn_command(command, Some(3000))?; expect_prompt(&mut p)?; Ok(p) } fn expect_prompt(p: &mut PtySession) -> Result<()> { p.exp_string("> ")?; Ok(()) } #[test] fn shows_a_prompt() -> Result<()> { let c = spawn_ssh_server()?; connect_to_ssh_server_interactively(&c)?; Ok(()) }