Research-Stack/4-Infrastructure/NoDupeLabs/tests/scanner_engine/test_progress.py

340 lines
10 KiB
Python

"""Tests for progress tracker module."""
import time
from unittest.mock import MagicMock
import pytest
class TestProgressTracker:
"""Test ProgressTracker class."""
def test_initialization(self):
"""Test tracker initialization."""
from nodupe.tools.scanner_engine.progress import ProgressTracker
tracker = ProgressTracker()
assert tracker._total_items == 0
assert tracker._completed_items == 0
assert tracker._total_bytes == 0
assert tracker._processed_bytes == 0
assert tracker._status == "not_started"
def test_start(self):
"""Test starting progress tracking."""
from nodupe.tools.scanner_engine.progress import ProgressTracker
tracker = ProgressTracker()
tracker.start(total_items=100, total_bytes=1000)
assert tracker._total_items == 100
assert tracker._total_bytes == 1000
assert tracker._completed_items == 0
assert tracker._status == "in_progress"
def test_update(self):
"""Test updating progress."""
from nodupe.tools.scanner_engine.progress import ProgressTracker
tracker = ProgressTracker()
tracker.start(total_items=100)
tracker.update(items_completed=10, bytes_processed=100)
assert tracker._completed_items == 10
assert tracker._processed_bytes == 100
def test_complete(self):
"""Test marking as complete."""
from nodupe.tools.scanner_engine.progress import ProgressTracker
tracker = ProgressTracker()
tracker.start(total_items=100)
tracker.complete()
assert tracker._status == "completed"
def test_error(self):
"""Test recording an error."""
from nodupe.tools.scanner_engine.progress import ProgressTracker
tracker = ProgressTracker()
tracker.start()
tracker.error()
assert tracker._error_count == 1
def test_get_progress(self):
"""Test getting progress information."""
from nodupe.tools.scanner_engine.progress import ProgressTracker
tracker = ProgressTracker()
tracker.start(total_items=100, total_bytes=1000)
tracker.update(items_completed=50, bytes_processed=500)
progress = tracker.get_progress()
assert progress['status'] == 'in_progress'
assert progress['total_items'] == 100
assert progress['completed_items'] == 50
assert progress['remaining_items'] == 50
assert progress['total_bytes'] == 1000
assert progress['processed_bytes'] == 500
def test_get_progress_before_start(self):
"""Test getting progress before starting."""
from nodupe.tools.scanner_engine.progress import ProgressTracker
tracker = ProgressTracker()
progress = tracker.get_progress()
assert progress['status'] == 'not_started'
assert progress['elapsed_time'] == 0
def test_get_progress_percent_complete(self):
"""Test percent complete calculation."""
from nodupe.tools.scanner_engine.progress import ProgressTracker
tracker = ProgressTracker()
tracker.start(total_items=100)
tracker.update(items_completed=25)
progress = tracker.get_progress()
assert progress['percent_complete'] == 25.0
def test_get_progress_time_remaining(self):
"""Test time remaining calculation."""
from nodupe.tools.scanner_engine.progress import ProgressTracker
tracker = ProgressTracker()
tracker.start(total_items=100)
# Add some items processed
time.sleep(0.01)
tracker.update(items_completed=10)
progress = tracker.get_progress()
# Should have a time remaining estimate
assert 'time_remaining' in progress
assert progress['time_remaining'] >= 0
def test_get_progress_rates(self):
"""Test rate calculation."""
from nodupe.tools.scanner_engine.progress import ProgressTracker
tracker = ProgressTracker()
tracker.start(total_items=100, total_bytes=1000)
time.sleep(0.01)
tracker.update(items_completed=10, bytes_processed=100)
progress = tracker.get_progress()
assert progress['items_per_second'] >= 0
assert progress['bytes_per_second'] >= 0
def test_report_progress(self):
"""Test reporting progress via callback."""
from nodupe.tools.scanner_engine.progress import ProgressTracker
tracker = ProgressTracker()
tracker.start(total_items=100)
tracker.update(items_completed=50)
callback_called = []
def on_progress(progress):
"""Callback function for progress updates."""
callback_called.append(progress)
tracker.report_progress(on_progress)
assert len(callback_called) == 1
assert callback_called[0]['completed_items'] == 50
def test_report_progress_no_callback(self):
"""Test reporting progress without callback."""
from nodupe.tools.scanner_engine.progress import ProgressTracker
tracker = ProgressTracker()
tracker.start()
# Should not raise
tracker.report_progress(None)
def test_reset(self):
"""Test resetting progress tracker."""
from nodupe.tools.scanner_engine.progress import ProgressTracker
tracker = ProgressTracker()
tracker.start(total_items=100, total_bytes=1000)
tracker.update(items_completed=50)
tracker.error()
tracker.reset()
assert tracker._total_items == 0
assert tracker._completed_items == 0
assert tracker._total_bytes == 0
assert tracker._processed_bytes == 0
assert tracker._status == "not_started"
assert tracker._error_count == 0
def test_get_elapsed_time(self):
"""Test getting elapsed time."""
from nodupe.tools.scanner_engine.progress import ProgressTracker
tracker = ProgressTracker()
tracker.start()
time.sleep(0.01)
elapsed = tracker.get_elapsed_time()
assert elapsed > 0
def test_get_elapsed_time_not_started(self):
"""Test getting elapsed time when not started."""
from nodupe.tools.scanner_engine.progress import ProgressTracker
tracker = ProgressTracker()
elapsed = tracker.get_elapsed_time()
assert elapsed == 0
def test_get_status(self):
"""Test getting status."""
from nodupe.tools.scanner_engine.progress import ProgressTracker
tracker = ProgressTracker()
assert tracker.get_status() == "not_started"
tracker.start()
assert tracker.get_status() == "in_progress"
tracker.complete()
assert tracker.get_status() == "completed"
def test_is_complete(self):
"""Test is_complete method."""
from nodupe.tools.scanner_engine.progress import ProgressTracker
tracker = ProgressTracker()
assert tracker.is_complete() is False
tracker.start()
assert tracker.is_complete() is False
tracker.complete()
assert tracker.is_complete() is True
def test_get_error_count(self):
"""Test getting error count."""
from nodupe.tools.scanner_engine.progress import ProgressTracker
tracker = ProgressTracker()
tracker.start()
tracker.error()
tracker.error()
assert tracker.get_error_count() == 2
def test_format_progress(self):
"""Test formatting progress as string."""
from nodupe.tools.scanner_engine.progress import ProgressTracker
tracker = ProgressTracker()
tracker.start(total_items=100)
tracker.update(items_completed=50)
formatted = tracker.format_progress()
assert "Status:" in formatted
assert "Progress:" in formatted
assert "Items:" in formatted
assert "50/100" in formatted
def test_format_progress_with_dict(self):
"""Test formatting progress with custom dict."""
from nodupe.tools.scanner_engine.progress import ProgressTracker
tracker = ProgressTracker()
progress_dict = {
'status': 'completed',
'percent_complete': 100.0,
'elapsed_time': 10.0,
'time_remaining': 0.0,
'completed_items': 100,
'total_items': 100,
'error_count': 0
}
formatted = tracker.format_progress(progress_dict)
assert "completed" in formatted.lower()
assert "100.0%" in formatted
def test_thread_safety(self):
"""Test thread safety of progress tracker."""
import threading
from nodupe.tools.scanner_engine.progress import ProgressTracker
tracker = ProgressTracker()
tracker.start(total_items=1000)
def update_progress():
"""Update progress in a thread."""
for _ in range(100):
tracker.update(items_completed=1)
threads = [threading.Thread(target=update_progress) for _ in range(10)]
for t in threads:
t.start()
for t in threads:
t.join()
progress = tracker.get_progress()
assert progress['completed_items'] == 1000
class TestCreateProgressTracker:
"""Test create_progress_tracker factory function."""
def test_create_progress_tracker(self):
"""Test creating progress tracker."""
from nodupe.tools.scanner_engine.progress import create_progress_tracker
tracker = create_progress_tracker()
assert tracker is not None
assert tracker._status == "not_started"