summaryrefslogtreecommitdiff
path: root/tests/server_shell.rs
blob: 858f123fa45fabc2296ab7d3b18075a1d8ac7155 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
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");

    let absolute_shell_path = cargo_bin(env!("CARGO_PKG_NAME"));
    let relative_shell_path = absolute_shell_path.strip_prefix(std::fs::canonicalize(".")?)?;
    command.args([
        "build",
        "--quiet",
        "-t",
        "shackle-server",
        "--build-arg",
        &format!("SHELL={}", relative_shell_path.display()),
        "./",
    ]);

    let status = command.status()?;
    if !status.success() {
        bail!("Failed to build dockerfile");
    }

    Ok(())
}

fn spawn_ssh_server() -> Result<TestContext> {
    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<PtySession> {
    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(())
}