"""Tests for net.i2p.util Tier 1 — file & system utilities. TDD — tests for FileUtil, PasswordManager, ShellCommand, TempDirScanner. """ from __future__ import annotations import os import tempfile import zipfile import pytest from i2p_util.file_util import ( copy_file, rm_dir, extract_zip, verify_zip, file_checksum, read_file, write_file, ) from i2p_util.password import PasswordManager from i2p_util.shell import shell_command from i2p_util.temp_scanner import scan_temp_dir # --------------------------------------------------------------------------- # FileUtil # --------------------------------------------------------------------------- class TestFileUtil: """File utility operations.""" def test_copy_file(self): with tempfile.TemporaryDirectory() as td: src = os.path.join(td, "src.txt") dst = os.path.join(td, "dst.txt") with open(src, "w") as f: f.write("hello") assert copy_file(src, dst) is True assert os.path.exists(dst) with open(dst) as f: assert f.read() == "hello" def test_copy_file_missing_source(self): with tempfile.TemporaryDirectory() as td: assert copy_file("/nonexistent", os.path.join(td, "dst")) is False def test_write_and_read_file(self): with tempfile.TemporaryDirectory() as td: path = os.path.join(td, "data.bin") data = b"binary data here" assert write_file(path, data) is True result = read_file(path) assert result == data def test_read_file_missing(self): assert read_file("/nonexistent/file.bin") is None def test_rm_dir(self): with tempfile.TemporaryDirectory() as td: sub = os.path.join(td, "sub") os.makedirs(sub) with open(os.path.join(sub, "f.txt"), "w") as f: f.write("x") assert rm_dir(sub) is True assert not os.path.exists(sub) def test_rm_dir_missing(self): assert rm_dir("/nonexistent/dir") is False def test_extract_zip(self): with tempfile.TemporaryDirectory() as td: zp = os.path.join(td, "test.zip") with zipfile.ZipFile(zp, "w") as zf: zf.writestr("hello.txt", "world") dest = os.path.join(td, "out") os.makedirs(dest) assert extract_zip(zp, dest) is True assert os.path.exists(os.path.join(dest, "hello.txt")) def test_verify_zip_valid(self): with tempfile.TemporaryDirectory() as td: zp = os.path.join(td, "good.zip") with zipfile.ZipFile(zp, "w") as zf: zf.writestr("a.txt", "data") assert verify_zip(zp) is True def test_verify_zip_invalid(self): with tempfile.TemporaryDirectory() as td: bad = os.path.join(td, "bad.zip") with open(bad, "wb") as f: f.write(b"not a zip") assert verify_zip(bad) is False def test_file_checksum_sha256(self): with tempfile.TemporaryDirectory() as td: path = os.path.join(td, "f.txt") with open(path, "wb") as f: f.write(b"test data") cs = file_checksum(path, "sha256") assert isinstance(cs, str) assert len(cs) == 64 # hex SHA-256 def test_file_checksum_missing(self): assert file_checksum("/nonexistent", "sha256") is None # --------------------------------------------------------------------------- # PasswordManager # --------------------------------------------------------------------------- class TestPasswordManager: """Password hashing and verification.""" def test_create_and_check(self): pm = PasswordManager() hashed = pm.create_hash("my_password") assert hashed is not None assert pm.check_password("my_password", hashed) is True def test_wrong_password_fails(self): pm = PasswordManager() hashed = pm.create_hash("correct") assert pm.check_password("wrong", hashed) is False def test_generate_password(self): pm = PasswordManager() pwd = pm.generate_password(length=32) assert isinstance(pwd, str) assert len(pwd) >= 32 def test_different_hashes_for_same_password(self): """Salt should make hashes unique.""" pm = PasswordManager() h1 = pm.create_hash("same") h2 = pm.create_hash("same") assert h1 != h2 # --------------------------------------------------------------------------- # ShellCommand # --------------------------------------------------------------------------- class TestShellCommand: """Shell command execution.""" def test_echo(self): rc, stdout, stderr = shell_command("echo hello") assert rc == 0 assert "hello" in stdout def test_exit_code(self): rc, _, _ = shell_command("false") assert rc != 0 def test_timeout(self): rc, _, _ = shell_command("sleep 60", timeout=1.0) assert rc != 0 # should be killed def test_stderr(self): rc, _, stderr = shell_command("echo err >&2") assert rc == 0 assert "err" in stderr # --------------------------------------------------------------------------- # TempDirScanner # --------------------------------------------------------------------------- class TestTempDirScanner: """Temp directory cleanup.""" def test_scan_removes_old_files(self): with tempfile.TemporaryDirectory() as td: old = os.path.join(td, "old.tmp") with open(old, "w") as f: f.write("x") # Set mtime to 1 hour ago old_time = os.path.getmtime(old) - 3600 os.utime(old, (old_time, old_time)) removed = scan_temp_dir(td, max_age_secs=60) assert old in removed assert not os.path.exists(old) def test_scan_keeps_recent_files(self): with tempfile.TemporaryDirectory() as td: recent = os.path.join(td, "recent.tmp") with open(recent, "w") as f: f.write("x") removed = scan_temp_dir(td, max_age_secs=3600) assert len(removed) == 0 assert os.path.exists(recent) def test_scan_empty_dir(self): with tempfile.TemporaryDirectory() as td: removed = scan_temp_dir(td, max_age_secs=60) assert removed == []