tests: share server across tests, suppress probe noise
- Add session-scoped shared_server fixture to avoid 27+ server start/stop cycles - Refactor test_tcp.py and test_features.py to use shared server - Suppress server health-check probe stderr noise in common.py
This commit is contained in:
@@ -1,5 +1,17 @@
|
|||||||
"""Shared pytest configuration for integration tests."""
|
"""Shared pytest configuration for integration tests."""
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
import pytest
|
||||||
|
|
||||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "integration"))
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "integration"))
|
||||||
|
|
||||||
|
from common import ServerManager
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="session")
|
||||||
|
def shared_server():
|
||||||
|
"""One server for the entire test session. Avoids 27+ server start/stop cycles."""
|
||||||
|
server = ServerManager()
|
||||||
|
server.start()
|
||||||
|
yield server
|
||||||
|
server.stop()
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class ServerManager:
|
|||||||
cmd = SERVER_CMD + ["-p", str(self._port)]
|
cmd = SERVER_CMD + ["-p", str(self._port)]
|
||||||
if extra_args:
|
if extra_args:
|
||||||
cmd += extra_args
|
cmd += extra_args
|
||||||
self._proc = subprocess.Popen(cmd, stdout=subprocess.DEVNULL, stderr=None)
|
self._proc = subprocess.Popen(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||||
_wait_for_port(self._port, timeout=5)
|
_wait_for_port(self._port, timeout=5)
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
"""Feature tests: incremental sync, bandwidth limiting, dry run, metadata, filters."""
|
"""Feature tests: incremental sync, bandwidth limiting, dry run, metadata, filters."""
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
import pytest
|
import pytest
|
||||||
@@ -9,7 +8,7 @@ import pytest
|
|||||||
sys.path.insert(0, os.path.dirname(__file__))
|
sys.path.insert(0, os.path.dirname(__file__))
|
||||||
from common import (
|
from common import (
|
||||||
PROJECT_ROOT, BUILD_DIR, TEST_DATA_DIR,
|
PROJECT_ROOT, BUILD_DIR, TEST_DATA_DIR,
|
||||||
ServerManager, run_client,
|
run_client,
|
||||||
generate_test_files, verify_transfer, clean_dir, make_result,
|
generate_test_files, verify_transfer, clean_dir, make_result,
|
||||||
get_dest_received_dir, CLIENT_CMD,
|
get_dest_received_dir, CLIENT_CMD,
|
||||||
)
|
)
|
||||||
@@ -38,13 +37,12 @@ class TestDryRun:
|
|||||||
|
|
||||||
|
|
||||||
class TestArchiveMode:
|
class TestArchiveMode:
|
||||||
def test_archive_mode(self):
|
def test_archive_mode(self, shared_server):
|
||||||
clean_dir(DEST_DIR)
|
clean_dir(DEST_DIR)
|
||||||
with ServerManager() as server:
|
|
||||||
result, dur = run_client(
|
result, dur = run_client(
|
||||||
SOURCE_DIR, DEST_DIR,
|
SOURCE_DIR, DEST_DIR,
|
||||||
flags=["-a"],
|
flags=["-a"],
|
||||||
port=server.port,
|
port=shared_server.port,
|
||||||
)
|
)
|
||||||
if result.returncode != 0:
|
if result.returncode != 0:
|
||||||
pytest.fail(f"Exit {result.returncode}: {(result.stderr or result.stdout)[:200]}")
|
pytest.fail(f"Exit {result.returncode}: {(result.stderr or result.stdout)[:200]}")
|
||||||
@@ -55,64 +53,56 @@ class TestArchiveMode:
|
|||||||
|
|
||||||
|
|
||||||
class TestExclude:
|
class TestExclude:
|
||||||
def test_exclude_single(self):
|
def test_exclude_single(self, shared_server):
|
||||||
clean_dir(DEST_DIR)
|
clean_dir(DEST_DIR)
|
||||||
with ServerManager() as server:
|
|
||||||
result, dur = run_client(
|
result, dur = run_client(
|
||||||
SOURCE_DIR, DEST_DIR,
|
SOURCE_DIR, DEST_DIR,
|
||||||
flags=["--exclude", "small.txt"],
|
flags=["--exclude", "small.txt"],
|
||||||
port=server.port,
|
port=shared_server.port,
|
||||||
)
|
)
|
||||||
if result.returncode != 0:
|
if result.returncode != 0:
|
||||||
pytest.fail(f"Exit {result.returncode}: {(result.stderr or result.stdout)[:200]}")
|
pytest.fail(f"Exit {result.returncode}: {(result.stderr or result.stdout)[:200]}")
|
||||||
received = get_dest_received_dir(DEST_DIR, SOURCE_DIR)
|
received = get_dest_received_dir(DEST_DIR, SOURCE_DIR)
|
||||||
mismatches, missing = verify_transfer(SOURCE_DIR, received)
|
mismatches, missing = verify_transfer(SOURCE_DIR, received)
|
||||||
# small.txt should be missing (excluded)
|
assert "small.txt" in missing, "small.txt should be excluded but was transferred"
|
||||||
assert "small.txt" in missing, f"small.txt should be excluded but was transferred"
|
|
||||||
# all other files should be present
|
|
||||||
other_missing = [m for m in missing if m != "small.txt"]
|
other_missing = [m for m in missing if m != "small.txt"]
|
||||||
assert not other_missing, f"Other files missing: {other_missing}"
|
assert not other_missing, f"Other files missing: {other_missing}"
|
||||||
assert not mismatches, f"Mismatch: {mismatches}"
|
assert not mismatches, f"Mismatch: {mismatches}"
|
||||||
|
|
||||||
def test_exclude_glob(self):
|
def test_exclude_glob(self, shared_server):
|
||||||
clean_dir(DEST_DIR)
|
clean_dir(DEST_DIR)
|
||||||
with ServerManager() as server:
|
|
||||||
result, dur = run_client(
|
result, dur = run_client(
|
||||||
SOURCE_DIR, DEST_DIR,
|
SOURCE_DIR, DEST_DIR,
|
||||||
flags=["--exclude", "*.txt"],
|
flags=["--exclude", "*.txt"],
|
||||||
port=server.port,
|
port=shared_server.port,
|
||||||
)
|
)
|
||||||
if result.returncode != 0:
|
if result.returncode != 0:
|
||||||
pytest.fail(f"Exit {result.returncode}: {(result.stderr or result.stdout)[:200]}")
|
pytest.fail(f"Exit {result.returncode}: {(result.stderr or result.stdout)[:200]}")
|
||||||
received = get_dest_received_dir(DEST_DIR, SOURCE_DIR)
|
received = get_dest_received_dir(DEST_DIR, SOURCE_DIR)
|
||||||
# Only binary.bin and bulk files should be present
|
|
||||||
assert not os.path.exists(os.path.join(received, "small.txt")), "small.txt should be excluded"
|
assert not os.path.exists(os.path.join(received, "small.txt")), "small.txt should be excluded"
|
||||||
assert os.path.exists(os.path.join(received, "binary.bin")), "binary.bin should be present"
|
assert os.path.exists(os.path.join(received, "binary.bin")), "binary.bin should be present"
|
||||||
|
|
||||||
|
|
||||||
class TestInclude:
|
class TestInclude:
|
||||||
def test_include_single(self):
|
def test_include_single(self, shared_server):
|
||||||
clean_dir(DEST_DIR)
|
clean_dir(DEST_DIR)
|
||||||
with ServerManager() as server:
|
|
||||||
result, dur = run_client(
|
result, dur = run_client(
|
||||||
SOURCE_DIR, DEST_DIR,
|
SOURCE_DIR, DEST_DIR,
|
||||||
flags=["--include", "binary.bin"],
|
flags=["--include", "binary.bin"],
|
||||||
port=server.port,
|
port=shared_server.port,
|
||||||
)
|
)
|
||||||
if result.returncode != 0:
|
if result.returncode != 0:
|
||||||
pytest.fail(f"Exit {result.returncode}: {(result.stderr or result.stdout)[:200]}")
|
pytest.fail(f"Exit {result.returncode}: {(result.stderr or result.stdout)[:200]}")
|
||||||
received = get_dest_received_dir(DEST_DIR, SOURCE_DIR)
|
received = get_dest_received_dir(DEST_DIR, SOURCE_DIR)
|
||||||
# Only binary.bin should be present
|
|
||||||
assert os.path.exists(os.path.join(received, "binary.bin")), "binary.bin should be included"
|
assert os.path.exists(os.path.join(received, "binary.bin")), "binary.bin should be included"
|
||||||
assert not os.path.exists(os.path.join(received, "small.txt")), "small.txt should not be included"
|
assert not os.path.exists(os.path.join(received, "small.txt")), "small.txt should not be included"
|
||||||
|
|
||||||
def test_include_glob(self):
|
def test_include_glob(self, shared_server):
|
||||||
clean_dir(DEST_DIR)
|
clean_dir(DEST_DIR)
|
||||||
with ServerManager() as server:
|
|
||||||
result, dur = run_client(
|
result, dur = run_client(
|
||||||
SOURCE_DIR, DEST_DIR,
|
SOURCE_DIR, DEST_DIR,
|
||||||
flags=["--include", "*.bin"],
|
flags=["--include", "*.bin"],
|
||||||
port=server.port,
|
port=shared_server.port,
|
||||||
)
|
)
|
||||||
if result.returncode != 0:
|
if result.returncode != 0:
|
||||||
pytest.fail(f"Exit {result.returncode}: {(result.stderr or result.stdout)[:200]}")
|
pytest.fail(f"Exit {result.returncode}: {(result.stderr or result.stdout)[:200]}")
|
||||||
@@ -121,101 +111,81 @@ class TestInclude:
|
|||||||
|
|
||||||
|
|
||||||
class TestSizeFilters:
|
class TestSizeFilters:
|
||||||
def test_max_size(self):
|
def test_max_size(self, shared_server):
|
||||||
"""Files larger than --max-size should be skipped."""
|
|
||||||
clean_dir(DEST_DIR)
|
clean_dir(DEST_DIR)
|
||||||
with ServerManager() as server:
|
|
||||||
result, dur = run_client(
|
result, dur = run_client(
|
||||||
SOURCE_DIR, DEST_DIR,
|
SOURCE_DIR, DEST_DIR,
|
||||||
flags=["--max-size", "100"], # 100 bytes
|
flags=["--max-size", "100"],
|
||||||
port=server.port,
|
port=shared_server.port,
|
||||||
)
|
)
|
||||||
if result.returncode != 0:
|
if result.returncode != 0:
|
||||||
pytest.fail(f"Exit {result.returncode}: {(result.stderr or result.stdout)[:200]}")
|
pytest.fail(f"Exit {result.returncode}: {(result.stderr or result.stdout)[:200]}")
|
||||||
received = get_dest_received_dir(DEST_DIR, SOURCE_DIR)
|
received = get_dest_received_dir(DEST_DIR, SOURCE_DIR)
|
||||||
# small.txt (12 bytes) should be present, medium.txt (220k+) should be skipped
|
|
||||||
assert os.path.exists(os.path.join(received, "small.txt")), "small.txt should be present"
|
assert os.path.exists(os.path.join(received, "small.txt")), "small.txt should be present"
|
||||||
assert not os.path.exists(os.path.join(received, "medium.txt")), "medium.txt should be skipped"
|
assert not os.path.exists(os.path.join(received, "medium.txt")), "medium.txt should be skipped"
|
||||||
|
|
||||||
def test_min_size(self):
|
def test_min_size(self, shared_server):
|
||||||
"""Files smaller than --min-size should be skipped."""
|
|
||||||
clean_dir(DEST_DIR)
|
clean_dir(DEST_DIR)
|
||||||
with ServerManager() as server:
|
|
||||||
result, dur = run_client(
|
result, dur = run_client(
|
||||||
SOURCE_DIR, DEST_DIR,
|
SOURCE_DIR, DEST_DIR,
|
||||||
flags=["--min-size", "1000"], # 1 KB
|
flags=["--min-size", "1000"],
|
||||||
port=server.port,
|
port=shared_server.port,
|
||||||
)
|
)
|
||||||
if result.returncode != 0:
|
if result.returncode != 0:
|
||||||
pytest.fail(f"Exit {result.returncode}: {(result.stderr or result.stdout)[:200]}")
|
pytest.fail(f"Exit {result.returncode}: {(result.stderr or result.stdout)[:200]}")
|
||||||
received = get_dest_received_dir(DEST_DIR, SOURCE_DIR)
|
received = get_dest_received_dir(DEST_DIR, SOURCE_DIR)
|
||||||
# small.txt (12 bytes) should be skipped, medium.txt should be present
|
|
||||||
assert not os.path.exists(os.path.join(received, "small.txt")), "small.txt should be skipped"
|
assert not os.path.exists(os.path.join(received, "small.txt")), "small.txt should be skipped"
|
||||||
assert os.path.exists(os.path.join(received, "medium.txt")), "medium.txt should be present"
|
assert os.path.exists(os.path.join(received, "medium.txt")), "medium.txt should be present"
|
||||||
|
|
||||||
|
|
||||||
class TestIncremental:
|
class TestIncremental:
|
||||||
def test_incremental_skips_unchanged(self):
|
def test_incremental_skips_unchanged(self, shared_server):
|
||||||
"""Second sync with --incremental should be fast (skips unchanged files)."""
|
|
||||||
# First sync: populate dest
|
|
||||||
clean_dir(DEST_DIR)
|
clean_dir(DEST_DIR)
|
||||||
with ServerManager() as server:
|
|
||||||
result, dur = run_client(
|
result, dur = run_client(
|
||||||
SOURCE_DIR, DEST_DIR,
|
SOURCE_DIR, DEST_DIR,
|
||||||
flags=["-M"],
|
flags=["-M"],
|
||||||
port=server.port,
|
port=shared_server.port,
|
||||||
)
|
)
|
||||||
assert result.returncode == 0, f"First sync failed: {result.stderr[:100]}"
|
assert result.returncode == 0, f"First sync failed: {result.stderr[:100]}"
|
||||||
|
|
||||||
# Second sync with --incremental (should be near-instant)
|
|
||||||
with ServerManager() as server:
|
|
||||||
start = time.monotonic()
|
start = time.monotonic()
|
||||||
result, dur = run_client(
|
result, dur = run_client(
|
||||||
SOURCE_DIR, DEST_DIR,
|
SOURCE_DIR, DEST_DIR,
|
||||||
flags=["-M", "--incremental"],
|
flags=["-M", "--incremental"],
|
||||||
port=server.port,
|
port=shared_server.port,
|
||||||
)
|
)
|
||||||
incremental_time = time.monotonic() - start
|
incremental_time = time.monotonic() - start
|
||||||
|
|
||||||
assert result.returncode == 0, f"Incremental sync failed: {(result.stderr or result.stdout)[:200]}"
|
assert result.returncode == 0, f"Incremental sync failed: {(result.stderr or result.stdout)[:200]}"
|
||||||
|
|
||||||
# Verify files are still correct
|
|
||||||
received = get_dest_received_dir(DEST_DIR, SOURCE_DIR)
|
received = get_dest_received_dir(DEST_DIR, SOURCE_DIR)
|
||||||
mismatches, missing = verify_transfer(SOURCE_DIR, received)
|
mismatches, missing = verify_transfer(SOURCE_DIR, received)
|
||||||
assert not missing, f"Missing: {missing}"
|
assert not missing, f"Missing: {missing}"
|
||||||
assert not mismatches, f"Mismatch: {mismatches}"
|
assert not mismatches, f"Mismatch: {mismatches}"
|
||||||
|
|
||||||
def test_incremental_detects_changes(self):
|
def test_incremental_detects_changes(self, shared_server):
|
||||||
"""Incremental sync should transfer modified files."""
|
|
||||||
# First sync
|
|
||||||
clean_dir(DEST_DIR)
|
clean_dir(DEST_DIR)
|
||||||
with ServerManager() as server:
|
|
||||||
result, _ = run_client(
|
result, _ = run_client(
|
||||||
SOURCE_DIR, DEST_DIR,
|
SOURCE_DIR, DEST_DIR,
|
||||||
flags=["-M"],
|
flags=["-M"],
|
||||||
port=server.port,
|
port=shared_server.port,
|
||||||
)
|
)
|
||||||
assert result.returncode == 0
|
assert result.returncode == 0
|
||||||
|
|
||||||
# Modify a file
|
|
||||||
modified_file = os.path.join(SOURCE_DIR, "small.txt")
|
modified_file = os.path.join(SOURCE_DIR, "small.txt")
|
||||||
with open(modified_file, "wb") as f:
|
with open(modified_file, "wb") as f:
|
||||||
f.write(b"modified content for incremental test\n")
|
f.write(b"modified content for incremental test\n")
|
||||||
|
|
||||||
# Second sync with --incremental
|
|
||||||
with ServerManager() as server:
|
|
||||||
result, dur = run_client(
|
result, dur = run_client(
|
||||||
SOURCE_DIR, DEST_DIR,
|
SOURCE_DIR, DEST_DIR,
|
||||||
flags=["-M", "--incremental"],
|
flags=["-M", "--incremental"],
|
||||||
port=server.port,
|
port=shared_server.port,
|
||||||
)
|
)
|
||||||
assert result.returncode == 0
|
assert result.returncode == 0
|
||||||
|
|
||||||
# Restore original content
|
|
||||||
with open(modified_file, "wb") as f:
|
with open(modified_file, "wb") as f:
|
||||||
f.write(b"hello world\n")
|
f.write(b"hello world\n")
|
||||||
|
|
||||||
# Verify the modified content was transferred
|
|
||||||
received = get_dest_received_dir(DEST_DIR, SOURCE_DIR)
|
received = get_dest_received_dir(DEST_DIR, SOURCE_DIR)
|
||||||
received_file = os.path.join(received, "small.txt")
|
received_file = os.path.join(received, "small.txt")
|
||||||
assert os.path.exists(received_file), "Modified file should be present"
|
assert os.path.exists(received_file), "Modified file should be present"
|
||||||
@@ -225,19 +195,15 @@ class TestIncremental:
|
|||||||
|
|
||||||
|
|
||||||
class TestDelete:
|
class TestDelete:
|
||||||
def test_delete_removes_extra_files(self):
|
def test_delete_removes_extra_files(self, shared_server):
|
||||||
"""--delete should remove files on dest that aren't in source."""
|
|
||||||
# First sync: populate dest
|
|
||||||
clean_dir(DEST_DIR)
|
clean_dir(DEST_DIR)
|
||||||
with ServerManager() as server:
|
|
||||||
result, _ = run_client(
|
result, _ = run_client(
|
||||||
SOURCE_DIR, DEST_DIR,
|
SOURCE_DIR, DEST_DIR,
|
||||||
flags=["-M"],
|
flags=["-M"],
|
||||||
port=server.port,
|
port=shared_server.port,
|
||||||
)
|
)
|
||||||
assert result.returncode == 0
|
assert result.returncode == 0
|
||||||
|
|
||||||
# Add extra files to destination
|
|
||||||
received = get_dest_received_dir(DEST_DIR, SOURCE_DIR)
|
received = get_dest_received_dir(DEST_DIR, SOURCE_DIR)
|
||||||
extra_file = os.path.join(received, "extra_file.txt")
|
extra_file = os.path.join(received, "extra_file.txt")
|
||||||
extra_dir = os.path.join(received, "extra_dir")
|
extra_dir = os.path.join(received, "extra_dir")
|
||||||
@@ -247,50 +213,41 @@ class TestDelete:
|
|||||||
with open(os.path.join(extra_dir, "nested.txt"), "w") as f:
|
with open(os.path.join(extra_dir, "nested.txt"), "w") as f:
|
||||||
f.write("nested extra")
|
f.write("nested extra")
|
||||||
|
|
||||||
# Second sync with --delete
|
|
||||||
with ServerManager() as server:
|
|
||||||
result, dur = run_client(
|
result, dur = run_client(
|
||||||
SOURCE_DIR, DEST_DIR,
|
SOURCE_DIR, DEST_DIR,
|
||||||
flags=["-M", "--delete"],
|
flags=["-M", "--delete"],
|
||||||
port=server.port,
|
port=shared_server.port,
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result.returncode == 0, f"Delete sync failed: {(result.stderr or result.stdout)[:200]}"
|
assert result.returncode == 0, f"Delete sync failed: {(result.stderr or result.stdout)[:200]}"
|
||||||
assert not os.path.exists(extra_file), "extra_file.txt should be deleted"
|
assert not os.path.exists(extra_file), "extra_file.txt should be deleted"
|
||||||
assert not os.path.exists(extra_dir), "extra_dir should be deleted"
|
assert not os.path.exists(extra_dir), "extra_dir should be deleted"
|
||||||
|
|
||||||
# Verify remaining files are correct
|
|
||||||
mismatches, missing = verify_transfer(SOURCE_DIR, received)
|
mismatches, missing = verify_transfer(SOURCE_DIR, received)
|
||||||
assert not missing, f"Missing: {missing}"
|
assert not missing, f"Missing: {missing}"
|
||||||
assert not mismatches, f"Mismatch: {mismatches}"
|
assert not mismatches, f"Mismatch: {mismatches}"
|
||||||
|
|
||||||
|
|
||||||
class TestProgress:
|
class TestProgress:
|
||||||
def test_progress_output(self):
|
def test_progress_output(self, shared_server):
|
||||||
"""--progress should produce some output."""
|
|
||||||
clean_dir(DEST_DIR)
|
clean_dir(DEST_DIR)
|
||||||
with ServerManager() as server:
|
|
||||||
result, dur = run_client(
|
result, dur = run_client(
|
||||||
SOURCE_DIR, DEST_DIR,
|
SOURCE_DIR, DEST_DIR,
|
||||||
flags=["--progress"],
|
flags=["--progress"],
|
||||||
port=server.port,
|
port=shared_server.port,
|
||||||
)
|
)
|
||||||
assert result.returncode == 0, f"Exit {result.returncode}: {result.stderr[:100]}"
|
assert result.returncode == 0, f"Exit {result.returncode}: {result.stderr[:100]}"
|
||||||
# Progress output goes to stderr or stdout
|
|
||||||
output = result.stdout + result.stderr
|
output = result.stdout + result.stderr
|
||||||
# Just verify it ran successfully; progress output format may vary
|
assert len(output) >= 0
|
||||||
assert len(output) >= 0 # No assertion on specific output format
|
|
||||||
|
|
||||||
|
|
||||||
class TestBandwidthLimit:
|
class TestBandwidthLimit:
|
||||||
def test_bwlimit_runs(self):
|
def test_bwlimit_runs(self, shared_server):
|
||||||
"""--bwlimit should run without error."""
|
|
||||||
clean_dir(DEST_DIR)
|
clean_dir(DEST_DIR)
|
||||||
with ServerManager() as server:
|
|
||||||
result, dur = run_client(
|
result, dur = run_client(
|
||||||
SOURCE_DIR, DEST_DIR,
|
SOURCE_DIR, DEST_DIR,
|
||||||
flags=["--bwlimit", "10240"],
|
flags=["--bwlimit", "10240"],
|
||||||
port=server.port,
|
port=shared_server.port,
|
||||||
)
|
)
|
||||||
assert result.returncode == 0, f"Exit {result.returncode}: {(result.stderr or result.stdout)[:200]}"
|
assert result.returncode == 0, f"Exit {result.returncode}: {(result.stderr or result.stdout)[:200]}"
|
||||||
received = get_dest_received_dir(DEST_DIR, SOURCE_DIR)
|
received = get_dest_received_dir(DEST_DIR, SOURCE_DIR)
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
"""TCP transport correctness tests."""
|
"""TCP transport correctness tests."""
|
||||||
import os
|
import os
|
||||||
|
import shutil
|
||||||
import sys
|
import sys
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
sys.path.insert(0, os.path.dirname(__file__))
|
sys.path.insert(0, os.path.dirname(__file__))
|
||||||
from common import (
|
from common import (
|
||||||
PROJECT_ROOT, BUILD_DIR, TEST_DATA_DIR,
|
PROJECT_ROOT, BUILD_DIR, TEST_DATA_DIR,
|
||||||
ServerManager, run_client, run_client_posix,
|
run_client, run_client_posix,
|
||||||
generate_test_files, verify_transfer, clean_dir, make_result,
|
generate_test_files, verify_transfer, clean_dir, make_result,
|
||||||
get_dest_received_dir, CLIENT_CMD,
|
get_dest_received_dir, CLIENT_CMD,
|
||||||
)
|
)
|
||||||
@@ -20,22 +21,20 @@ def setup_test_data():
|
|||||||
generate_test_files(SOURCE_DIR, full=False)
|
generate_test_files(SOURCE_DIR, full=False)
|
||||||
clean_dir(DEST_DIR)
|
clean_dir(DEST_DIR)
|
||||||
yield
|
yield
|
||||||
import shutil
|
|
||||||
shutil.rmtree(TEST_DATA_DIR, ignore_errors=True)
|
shutil.rmtree(TEST_DATA_DIR, ignore_errors=True)
|
||||||
|
|
||||||
|
|
||||||
def _run_tcp_test(name, flags, use_metadata=True, posix=False):
|
def _run_tcp_test(name, port, flags, use_metadata=True, posix=False):
|
||||||
"""Run a single TCP test case with a fresh server."""
|
"""Run a single TCP test case against a shared server."""
|
||||||
clean_dir(DEST_DIR)
|
clean_dir(DEST_DIR)
|
||||||
with ServerManager() as server:
|
|
||||||
if posix:
|
if posix:
|
||||||
result, dur = run_client_posix(SOURCE_DIR, DEST_DIR,
|
result, dur = run_client_posix(SOURCE_DIR, DEST_DIR,
|
||||||
flags=(["-M"] if use_metadata else []) + flags,
|
flags=(["-M"] if use_metadata else []) + flags,
|
||||||
port=server.port)
|
port=port)
|
||||||
else:
|
else:
|
||||||
result, dur = run_client(SOURCE_DIR, DEST_DIR,
|
result, dur = run_client(SOURCE_DIR, DEST_DIR,
|
||||||
flags=(["-M"] if use_metadata else []) + flags,
|
flags=(["-M"] if use_metadata else []) + flags,
|
||||||
port=server.port)
|
port=port)
|
||||||
|
|
||||||
if result.returncode != 0:
|
if result.returncode != 0:
|
||||||
return make_result(name, False, dur, f"Exit {result.returncode}: {(result.stderr or result.stdout)[:100]}")
|
return make_result(name, False, dur, f"Exit {result.returncode}: {(result.stderr or result.stdout)[:100]}")
|
||||||
@@ -50,62 +49,62 @@ def _run_tcp_test(name, flags, use_metadata=True, posix=False):
|
|||||||
|
|
||||||
|
|
||||||
class TestTCPStandard:
|
class TestTCPStandard:
|
||||||
def test_standard(self):
|
def test_standard(self, shared_server):
|
||||||
r = _run_tcp_test("Standard", [])
|
r = _run_tcp_test("Standard", shared_server.port, [])
|
||||||
assert r["status"] == "Success", r["error"]
|
assert r["status"] == "Success", r["error"]
|
||||||
|
|
||||||
def test_posix_args(self):
|
def test_posix_args(self, shared_server):
|
||||||
r = _run_tcp_test("Posix Args", [], posix=True)
|
r = _run_tcp_test("Posix Args", shared_server.port, [], posix=True)
|
||||||
assert r["status"] == "Success", r["error"]
|
assert r["status"] == "Success", r["error"]
|
||||||
|
|
||||||
def test_no_metadata(self):
|
def test_no_metadata(self, shared_server):
|
||||||
r = _run_tcp_test("Standard (no metadata)", [], use_metadata=False)
|
r = _run_tcp_test("Standard (no metadata)", shared_server.port, [], use_metadata=False)
|
||||||
assert r["status"] == "Success", r["error"]
|
assert r["status"] == "Success", r["error"]
|
||||||
|
|
||||||
|
|
||||||
class TestTCPFlags:
|
class TestTCPFlags:
|
||||||
def test_multithreading(self):
|
def test_multithreading(self, shared_server):
|
||||||
r = _run_tcp_test("Multithreading (-m)", ["-m"])
|
r = _run_tcp_test("Multithreading (-m)", shared_server.port, ["-m"])
|
||||||
assert r["status"] == "Success", r["error"]
|
assert r["status"] == "Success", r["error"]
|
||||||
|
|
||||||
def test_compression(self):
|
def test_compression(self, shared_server):
|
||||||
r = _run_tcp_test("Compression (-c)", ["-c"])
|
r = _run_tcp_test("Compression (-c)", shared_server.port, ["-c"])
|
||||||
assert r["status"] == "Success", r["error"]
|
assert r["status"] == "Success", r["error"]
|
||||||
|
|
||||||
def test_chunk_serialization(self):
|
def test_chunk_serialization(self, shared_server):
|
||||||
r = _run_tcp_test("Chunk Serialization (-s)", ["-s"])
|
r = _run_tcp_test("Chunk Serialization (-s)", shared_server.port, ["-s"])
|
||||||
assert r["status"] == "Success", r["error"]
|
assert r["status"] == "Success", r["error"]
|
||||||
|
|
||||||
def test_compression_chunk(self):
|
def test_compression_chunk(self, shared_server):
|
||||||
r = _run_tcp_test("Compression + Chunk (-c -s)", ["-c", "-s"])
|
r = _run_tcp_test("Compression + Chunk (-c -s)", shared_server.port, ["-c", "-s"])
|
||||||
assert r["status"] == "Success", r["error"]
|
assert r["status"] == "Success", r["error"]
|
||||||
|
|
||||||
def test_multithread_compression(self):
|
def test_multithread_compression(self, shared_server):
|
||||||
r = _run_tcp_test("Multithreading + Compression (-m -c)", ["-m", "-c"])
|
r = _run_tcp_test("Multithreading + Compression (-m -c)", shared_server.port, ["-m", "-c"])
|
||||||
assert r["status"] == "Success", r["error"]
|
assert r["status"] == "Success", r["error"]
|
||||||
|
|
||||||
def test_multithread_chunk(self):
|
def test_multithread_chunk(self, shared_server):
|
||||||
r = _run_tcp_test("Multithreading + Chunk (-m -s)", ["-m", "-s"])
|
r = _run_tcp_test("Multithreading + Chunk (-m -s)", shared_server.port, ["-m", "-s"])
|
||||||
assert r["status"] == "Success", r["error"]
|
assert r["status"] == "Success", r["error"]
|
||||||
|
|
||||||
def test_all_flags(self):
|
def test_all_flags(self, shared_server):
|
||||||
r = _run_tcp_test("Multithread + Compression + Chunk (-m -c -s)", ["-m", "-c", "-s"])
|
r = _run_tcp_test("Multithread + Compression + Chunk (-m -c -s)", shared_server.port, ["-m", "-c", "-s"])
|
||||||
assert r["status"] == "Success", r["error"]
|
assert r["status"] == "Success", r["error"]
|
||||||
|
|
||||||
def test_sendfile(self):
|
def test_sendfile(self, shared_server):
|
||||||
r = _run_tcp_test("Sendfile (-f)", ["-f"])
|
r = _run_tcp_test("Sendfile (-f)", shared_server.port, ["-f"])
|
||||||
assert r["status"] == "Success", r["error"]
|
assert r["status"] == "Success", r["error"]
|
||||||
|
|
||||||
def test_sendfile_multithread(self):
|
def test_sendfile_multithread(self, shared_server):
|
||||||
r = _run_tcp_test("Sendfile + Multithreading (-f -m)", ["-f", "-m"])
|
r = _run_tcp_test("Sendfile + Multithreading (-f -m)", shared_server.port, ["-f", "-m"])
|
||||||
assert r["status"] == "Success", r["error"]
|
assert r["status"] == "Success", r["error"]
|
||||||
|
|
||||||
|
|
||||||
class TestTCPChunkSize:
|
class TestTCPChunkSize:
|
||||||
def test_custom_chunk_size(self):
|
def test_custom_chunk_size(self, shared_server):
|
||||||
r = _run_tcp_test("Chunk size 5MB", ["--chunk-size", "5242880"])
|
r = _run_tcp_test("Chunk size 5MB", shared_server.port, ["--chunk-size", "5242880"])
|
||||||
assert r["status"] == "Success", r["error"]
|
assert r["status"] == "Success", r["error"]
|
||||||
|
|
||||||
def test_small_chunk_size(self):
|
def test_small_chunk_size(self, shared_server):
|
||||||
r = _run_tcp_test("Chunk size 1KB", ["--chunk-size", "1024"])
|
r = _run_tcp_test("Chunk size 1KB", shared_server.port, ["--chunk-size", "1024"])
|
||||||
assert r["status"] == "Success", r["error"]
|
assert r["status"] == "Success", r["error"]
|
||||||
|
|||||||
Reference in New Issue
Block a user