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(())
}
|