diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 1c61c14..a99715c 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -10,6 +10,7 @@ on: - "*.md" - "*.example" - ".gitignore" + - "benchmarks/**" permissions: contents: read diff --git a/.gitignore b/.gitignore index 6867ad0..256a140 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ # Experimental src/diy -benchmarks # Rust /target diff --git a/benchmarks/.gitignore b/benchmarks/.gitignore new file mode 100644 index 0000000..13b0d6c --- /dev/null +++ b/benchmarks/.gitignore @@ -0,0 +1 @@ +memray* \ No newline at end of file diff --git a/benchmarks/14kb.txt b/benchmarks/14kb.txt new file mode 100644 index 0000000..402df6b --- /dev/null +++ b/benchmarks/14kb.txt @@ -0,0 +1,176 @@ +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 +Jbnzn8w587Atb4JArzuCGpnV+mtw1/hjYw== diff --git a/benchmarks/1kb.txt b/benchmarks/1kb.txt new file mode 100644 index 0000000..8642b71 --- /dev/null +++ b/benchmarks/1kb.txt @@ -0,0 +1,14 @@ +vNhkX6rKRYly7yfCXdpbIDRJ902Qv8YhBApgZ7sdtCdmP1MHCxxoErS4CEMOButjHjfwwMrBTiG6 +7ukJgCWwmFJMl4br2iv/yfFk4Ulf09N5Eu3NSjUnOWRmbRQYHUZNEEsr47LI3GEli9hbxqk8n+fN +8N04BhCFJcDli5a4owCDoI6OT2ULhBxbyirjdkK1OLgcARFrQDoGd7gvq9uoMz2qc1h96F5/dLpn +/dIqI9D2ijej7tJvyRvyr/tQenxO0vPvoTlTOPLrM0EbdIxANlwHjq6beiw5N0keOxX26KYKAH+F +83n7pcQD1XKEsBcUj58IruK7OqgpP58MHpBSxfx4YEJ9YgCcuLss4lyr2jsqbKts8TFduNMTnlEg +B3k1/DwnH6BiIY/g4AFOx3r0Ckk5uOdck4cqnOuR7M3sv6DzJoYpMArhQ2pVwEJeJSVnIFXPc6Mq +uZFAN6hFPtYQkJEHcETqhZjRC5A/D6kL6j9rNlgNQFHbEiUFZnCxRyMvLaiWl9XTvAxz9qIj0p1K +UBAKW3eDt+N8zMFQEua+bZB2L5xVdFyWK5mUQa+4NFi6jhvkyo409jDjG4ZYUMbdbkftg6KhV2up +pJeaUKNrZK5SoN+aHyizHo/bvWdZ3PVaCwJAPArn6ptKpe0dTTyH5Aa4XKuf9g3tbKVvL68VJl05 +nQ3KZDCz7b98+Y9geTJS1LpUAdasLUUdt+R3JaCt2wnJ9p5Y/GnuVZFMrqGxGnjfIRcd/rf7arDk +dcvCWhiEa11bQDa+TwIVEGELgEMKQ/yisSnUWuV9lNzq0WvwnSuR0Gm9tU8LnI4HBcyKPEpEMRii +2yeeM0ml+jAmw1+4e3cGe5LZcSfFRSrMAGKm9eK48vgXfEyzlb7KimKUkCKcvvRA+VEvDUHn7tXS +sDRDNn8dV7qUJ1hugIb3/RTgxvlQTzWcaqvIy0S6vnUMikWDSDzonM0QFhqUXfT4e1WRBi7i0NCD +DhGdIcOQg+no diff --git a/benchmarks/64kb.txt b/benchmarks/64kb.txt new file mode 100644 index 0000000..5441131 --- /dev/null +++ b/benchmarks/64kb.txt @@ -0,0 +1,843 @@ +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 +lrB7b3yq diff --git a/benchmarks/README.md b/benchmarks/README.md new file mode 100644 index 0000000..2975a20 --- /dev/null +++ b/benchmarks/README.md @@ -0,0 +1,36 @@ + +## Install benchmarking requirements +First, you will either need to have your own test target, putting that information in the `target.json` file in this directory. +Alternatively, you can install Docker or Podman, then build the hussh-test-server image in the `tests/setup/` directory of this repo. +Then you can start the test server with this command +```bash +docker run --rm -d -p 8022:22 hussh-test-server +``` +Once either of those are satisfied, install the libraries to be benchmarked by running this command in this directory. +```bash +pip install -r requirements.txt +``` + +## Running all benchmark scripts +To run the test scripts, you can either manually run each one, or use this bash loop. +```bash +for file in bench_*.py; do echo "$file"; python "$file"; done +``` +This will also create a memray output file for each script ran. +We'll use these in the next step. + +## Getting the total memory consumption for all benchmarks +This loop will get summaries for each benchmark's memory consumption and pull out the total memory and allocations. +```bash +for file in memray-bench_*; do echo "$file"; memray summary -r 1 "$file" | grep " at " | tr -d '[:space:]' | awk -F '│' '{print "Memory: " $3 ", Allocations: " $7}'; done +``` + +## Cleanup +You likely don't want the memray files to hang around, so you can easily delete them by running this. +```bash +rm -f memray-bench_* +``` + +# ToDo +- Improve reporting by putting it all in a nice table. +- Remove the need to execute commands manually by scripting it all. diff --git a/benchmarks/bench_fabric.py b/benchmarks/bench_fabric.py new file mode 100644 index 0000000..ad507ea --- /dev/null +++ b/benchmarks/bench_fabric.py @@ -0,0 +1,75 @@ +import json +import memray +import timeit +from pathlib import Path + +with memray.Tracker("memray-bench_fabric.bin"): + start_time = timeit.default_timer() + + from fabric import Connection + + import_time = timeit.default_timer() - start_time + host_info = json.loads(Path("target.json").read_text()) + + temp_time = timeit.default_timer() + conn = Connection( + host=host_info["host"], + port=host_info["port"], + user=host_info["username"], + connect_kwargs={ + "password": host_info["password"], + "look_for_keys": False, + "allow_agent": False, + }, + ) + conn.open() + connect_time = timeit.default_timer() - temp_time + + temp_time = timeit.default_timer() + result = conn.run("echo test") + run_time = timeit.default_timer() - temp_time + + # small file (1kb) + temp_time = timeit.default_timer() + conn.put("1kb.txt", "/root/1kb.txt") + s_put_time = timeit.default_timer() - temp_time + + temp_time = timeit.default_timer() + conn.get("/root/1kb.txt", "small.txt") + s_get_time = timeit.default_timer() - temp_time + Path("small.txt").unlink() + + # medium file (14kb) + temp_time = timeit.default_timer() + conn.put("14kb.txt", "/root/14kb.txt") + m_put_time = timeit.default_timer() - temp_time + + temp_time = timeit.default_timer() + conn.get("/root/14kb.txt", "medium.txt") + m_get_time = timeit.default_timer() - temp_time + Path("medium.txt").unlink() + + # large file (64kb) + temp_time = timeit.default_timer() + conn.put("64kb.txt", "/root/64kb.txt") + l_put_time = timeit.default_timer() - temp_time + + temp_time = timeit.default_timer() + conn.get("/root/64kb.txt", "large.txt") + l_get_time = timeit.default_timer() - temp_time + Path("large.txt").unlink() + + conn.close() + + total_time = timeit.default_timer() - start_time + +print(f"import_time: {import_time * 1000:.2f} ms") +print(f"connect_time: {connect_time * 1000:.2f} ms") +print(f"run_time: {run_time * 1000:.2f} ms") +print(f"s_put_time: {s_put_time * 1000:.2f} ms") +print(f"s_get_time: {s_get_time * 1000:.2f} ms") +print(f"m_put_time: {m_put_time * 1000:.2f} ms") +print(f"m_get_time: {m_get_time * 1000:.2f} ms") +print(f"l_put_time: {l_put_time * 1000:.2f} ms") +print(f"l_get_time: {l_get_time * 1000:.2f} ms") +print(f"total_time: {total_time * 1000:.2f} ms") diff --git a/benchmarks/bench_hussh.py b/benchmarks/bench_hussh.py new file mode 100644 index 0000000..c40cb41 --- /dev/null +++ b/benchmarks/bench_hussh.py @@ -0,0 +1,67 @@ +import json +import memray +import timeit +from pathlib import Path + + +with memray.Tracker("memray-bench_hussh.bin"): + start_time = timeit.default_timer() + from hussh import Connection + import_time = timeit.default_timer() - start_time + + host_info = json.loads(Path("target.json").read_text()) + + temp_time = timeit.default_timer() + conn = Connection( + host=host_info["host"], + port=host_info["port"], + password=host_info["password"], + ) + connect_time = timeit.default_timer() - temp_time + + temp_time = timeit.default_timer() + result = conn.execute("echo test") + run_time = timeit.default_timer() - temp_time + + # small file (1kb) + temp_time = timeit.default_timer() + conn.sftp_write("1kb.txt", "/root/1kb.txt") + s_put_time = timeit.default_timer() - temp_time + + temp_time = timeit.default_timer() + conn.sftp_read("/root/1kb.txt", "small.txt") + s_get_time = timeit.default_timer() - temp_time + Path("small.txt").unlink() + + # medium file (14kb) + temp_time = timeit.default_timer() + conn.sftp_write("14kb.txt", "/root/14kb.txt") + m_put_time = timeit.default_timer() - temp_time + + temp_time = timeit.default_timer() + conn.sftp_read("/root/14kb.txt", "medium.txt") + m_get_time = timeit.default_timer() - temp_time + Path("medium.txt").unlink() + + # large file (64kb) + temp_time = timeit.default_timer() + conn.sftp_write("64kb.txt", "/root/64kb.txt") + l_put_time = timeit.default_timer() - temp_time + + temp_time = timeit.default_timer() + conn.sftp_read("/root/64kb.txt", "large.txt") + l_get_time = timeit.default_timer() - temp_time + Path("large.txt").unlink() + + total_time = timeit.default_timer() - start_time + +print(f"import_time: {import_time * 1000:.2f} ms") +print(f"connect_time: {connect_time * 1000:.2f} ms") +print(f"run_time: {run_time * 1000:.2f} ms") +print(f"s_put_time: {s_put_time * 1000:.2f} ms") +print(f"s_get_time: {s_get_time * 1000:.2f} ms") +print(f"m_put_time: {m_put_time * 1000:.2f} ms") +print(f"m_get_time: {m_get_time * 1000:.2f} ms") +print(f"l_put_time: {l_put_time * 1000:.2f} ms") +print(f"l_get_time: {l_get_time * 1000:.2f} ms") +print(f"total_time: {total_time * 1000:.2f} ms") diff --git a/benchmarks/bench_paramiko.py b/benchmarks/bench_paramiko.py new file mode 100644 index 0000000..66c3db0 --- /dev/null +++ b/benchmarks/bench_paramiko.py @@ -0,0 +1,78 @@ +import json +import memray +import timeit +from pathlib import Path + + +with memray.Tracker("memray-bench_paramiko.bin"): + start_time = timeit.default_timer() + import paramiko + import_time = timeit.default_timer() - start_time + + host_info = json.loads(Path("target.json").read_text()) + + temp_time = timeit.default_timer() + ssh = paramiko.SSHClient() + ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + ssh.connect( + hostname=host_info["host"], + port=host_info["port"], + username=host_info["username"], + password=host_info["password"], + look_for_keys=False, + allow_agent=False, + ) + connect_time = timeit.default_timer() - temp_time + + temp_time = timeit.default_timer() + stdin, stdout, stderr = ssh.exec_command("echo test") + result = stdout.read() + run_time = timeit.default_timer() - temp_time + + + # small file (1kb) + temp_time = timeit.default_timer() + sftp = ssh.open_sftp() + sftp.put("1kb.txt", "/root/1kb.txt") + s_put_time = timeit.default_timer() - temp_time + + temp_time = timeit.default_timer() + sftp.get("/root/1kb.txt", "small.txt") + s_get_time = timeit.default_timer() - temp_time + Path("small.txt").unlink() + + # medium file (14kb) + temp_time = timeit.default_timer() + sftp.put("14kb.txt", "/root/14kb.txt") + m_put_time = timeit.default_timer() - temp_time + + temp_time = timeit.default_timer() + sftp.get("/root/14kb.txt", "medium.txt") + m_get_time = timeit.default_timer() - temp_time + Path("medium.txt").unlink() + + # large file (64kb) + temp_time = timeit.default_timer() + sftp.put("64kb.txt", "/root/64kb.txt") + l_put_time = timeit.default_timer() - temp_time + + temp_time = timeit.default_timer() + sftp.get("/root/64kb.txt", "large.txt") + l_get_time = timeit.default_timer() - temp_time + Path("large.txt").unlink() + + sftp.close() + ssh.close() + + total_time = timeit.default_timer() - start_time + +print(f"import_time: {import_time * 1000:.2f} ms") +print(f"connect_time: {connect_time * 1000:.2f} ms") +print(f"run_time: {run_time * 1000:.2f} ms") +print(f"s_put_time: {s_put_time * 1000:.2f} ms") +print(f"s_get_time: {s_get_time * 1000:.2f} ms") +print(f"m_put_time: {m_put_time * 1000:.2f} ms") +print(f"m_get_time: {m_get_time * 1000:.2f} ms") +print(f"l_put_time: {l_put_time * 1000:.2f} ms") +print(f"l_get_time: {l_get_time * 1000:.2f} ms") +print(f"total_time: {total_time * 1000:.2f} ms") \ No newline at end of file diff --git a/benchmarks/bench_ssh2_python.py b/benchmarks/bench_ssh2_python.py new file mode 100644 index 0000000..e0d076b --- /dev/null +++ b/benchmarks/bench_ssh2_python.py @@ -0,0 +1,110 @@ +import json +import memray +import timeit +from pathlib import Path + + +with memray.Tracker("memray-bench_ssh2_python.bin"): + start_time = timeit.default_timer() + import socket + from ssh2.session import Session + from ssh2 import sftp + import_time = timeit.default_timer() - start_time + + host_info = json.loads(Path("target.json").read_text()) + + # connect to the server + temp_time = timeit.default_timer() + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.connect((host_info["host"], host_info["port"])) + session = Session() + session.handshake(sock) + session.userauth_password(host_info["username"], host_info["password"]) + connect_time = timeit.default_timer() - temp_time + + # execute a command + temp_time = timeit.default_timer() + channel = session.open_session() + channel.execute("echo test") + channel.wait_eof() + channel.close() + channel.wait_closed() + size, data = channel.read() + stdout = "" + while size > 0: + stdout += data.decode("utf-8") + size, data = channel.read() + stderr = channel.read_stderr() + status = channel.get_exit_status() + run_time = timeit.default_timer() - temp_time + + # small file (1kb) + temp_time = timeit.default_timer() + SFTP_MODE = ( + sftp.LIBSSH2_SFTP_S_IRUSR + | sftp.LIBSSH2_SFTP_S_IWUSR + | sftp.LIBSSH2_SFTP_S_IRGRP + | sftp.LIBSSH2_SFTP_S_IROTH + ) + FILE_FLAGS = ( + sftp.LIBSSH2_FXF_CREAT | sftp.LIBSSH2_FXF_WRITE | sftp.LIBSSH2_FXF_TRUNC + ) + data = Path("1kb.txt").read_bytes() + sftp_conn = session.sftp_init() + with sftp_conn.open("/root/1kb.txt", FILE_FLAGS, SFTP_MODE) as f: + f.write(data) + s_put_time = timeit.default_timer() - temp_time + + temp_time = timeit.default_timer() + with sftp_conn.open("/root/1kb.txt", sftp.LIBSSH2_FXF_READ, sftp.LIBSSH2_SFTP_S_IRUSR) as f: + read_data= b"" + for _rc, data in f: + read_data += data + Path("small.txt").write_bytes(read_data) + s_get_time = timeit.default_timer() - temp_time + Path("small.txt").unlink() + + # medium file (14kb) + temp_time = timeit.default_timer() + data = Path("14kb.txt").read_bytes() + with sftp_conn.open("/root/14kb.txt", FILE_FLAGS, SFTP_MODE) as f: + f.write(data) + m_put_time = timeit.default_timer() - temp_time + + temp_time = timeit.default_timer() + with sftp_conn.open("/root/14kb.txt", sftp.LIBSSH2_FXF_READ, sftp.LIBSSH2_SFTP_S_IRUSR) as f: + read_data= b"" + for _rc, data in f: + read_data += data + Path("medium.txt").write_bytes(read_data) + m_get_time = timeit.default_timer() - temp_time + Path("medium.txt").unlink() + + # large file (64kb) + temp_time = timeit.default_timer() + data = Path("64kb.txt").read_bytes() + with sftp_conn.open("/root/14kb.txt", FILE_FLAGS, SFTP_MODE) as f: + f.write(data) + l_put_time = timeit.default_timer() - temp_time + + temp_time = timeit.default_timer() + with sftp_conn.open("/root/64kb.txt", sftp.LIBSSH2_FXF_READ, sftp.LIBSSH2_SFTP_S_IRUSR) as f: + read_data= b"" + for _rc, data in f: + read_data += data + Path("large.txt").write_bytes(read_data) + l_get_time = timeit.default_timer() - temp_time + Path("large.txt").unlink() + + total_time = timeit.default_timer() - start_time + +print(f"import_time: {import_time * 1000:.2f} ms") +print(f"connect_time: {connect_time * 1000:.2f} ms") +print(f"run_time: {run_time * 1000:.2f} ms") +print(f"s_put_time: {s_put_time * 1000:.2f} ms") +print(f"s_get_time: {s_get_time * 1000:.2f} ms") +print(f"m_put_time: {m_put_time * 1000:.2f} ms") +print(f"m_get_time: {m_get_time * 1000:.2f} ms") +print(f"l_put_time: {l_put_time * 1000:.2f} ms") +print(f"l_get_time: {l_get_time * 1000:.2f} ms") +print(f"total_time: {total_time * 1000:.2f} ms") diff --git a/benchmarks/requirements.txt b/benchmarks/requirements.txt new file mode 100644 index 0000000..64b4052 --- /dev/null +++ b/benchmarks/requirements.txt @@ -0,0 +1,8 @@ +# requirements for benchmarking common ssh libraries +hussh +fabric # also fulfills paramiko +# pylibssh +ssh2-python312 + +# used for benchmarking memory usage +memray diff --git a/benchmarks/target.json b/benchmarks/target.json new file mode 100644 index 0000000..1562a9b --- /dev/null +++ b/benchmarks/target.json @@ -0,0 +1,6 @@ +{ + "host": "localhost", + "port": 8022, + "username": "root", + "password": "toor" +} \ No newline at end of file diff --git a/src/connection.rs b/src/connection.rs index 94fb4c8..e32c681 100644 --- a/src/connection.rs +++ b/src/connection.rs @@ -226,6 +226,7 @@ impl Connection { #[pymethods] impl Connection { #[new] + #[pyo3(text_signature = "(host, /, port=22, username='root', password=None, private_key=None, timeout=0)")] fn new( host: String, port: Option, @@ -407,8 +408,10 @@ impl Connection { } /// Writes a file over SFTP. - fn sftp_write(&mut self, local_path: String, remote_path: String) -> PyResult<()> { + /// If `remote_path` is not provided, the local file is written to the same path on the remote system. + fn sftp_write(&mut self, local_path: String, remote_path: Option) -> PyResult<()> { let mut local_file = std::fs::File::open(&local_path).unwrap(); + let remote_path = remote_path.unwrap_or_else(|| local_path.clone()); let metadata = local_file.metadata().unwrap(); let mut remote_file = self.sftp().create(Path::new(&remote_path)).unwrap(); // create a variable-sized buffer to read the file and loop until EOF @@ -484,8 +487,8 @@ impl Connection { /// Note: This is best used as a context manager /// ```python /// with conn.shell() as shell: - /// shell.send("ls") - /// shell.send("pwd") + /// shell.send("ls") + /// shell.send("pwd") /// print(shell.exit_result.stdout) /// ``` fn shell(&self, pty: Option) -> PyResult {