Files
wehub-resource-sync 7a0da7932b
Backwards Compatibility / Verify Encryption Constants (push) Waiting to run
Backwards Compatibility / PyPI Version Compatibility (push) Waiting to run
Backwards Compatibility / Database Migration Tests (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
CodeQL Advanced / Analyze (python) (push) Waiting to run
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Blocked by required conditions
Docker Tests (Consolidated) / detect-changes (push) Waiting to run
Docker Tests (Consolidated) / Build Test Image (push) Waiting to run
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Blocked by required conditions
Docker Tests (Consolidated) / Accessibility Tests (push) Blocked by required conditions
Docker Tests (Consolidated) / LLM Unit Tests (push) Blocked by required conditions
Docker Tests (Consolidated) / LLM Example Tests (push) Blocked by required conditions
Docker Tests (Consolidated) / Production Image Smoke Test (push) Blocked by required conditions
Docker Tests (Consolidated) / Infrastructure Tests (push) Blocked by required conditions
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Waiting to run
OSV-Scanner (Scheduled) / scan-scheduled (push) Failing after 0s
Create Release / test-gate (push) Has been cancelled
Create Release / release-gate (push) Has been cancelled
Create Release / ci-gate (push) Has been cancelled
Create Release / version-check (push) Has been cancelled
Create Release / e2e-test-gate (push) Has been cancelled
Create Release / responsive-test-gate (push) Has been cancelled
Create Release / compat-test-gate (push) Has been cancelled
Create Release / compose-integration-gate (push) Has been cancelled
Create Release / vulture-gate (push) Has been cancelled
Create Release / build (push) Has been cancelled
Create Release / provenance (push) Has been cancelled
Create Release / prerelease-docker (push) Has been cancelled
Create Release / publish-docker (push) Has been cancelled
Create Release / create-release (push) Has been cancelled
Create Release / cleanup-changelog (push) Has been cancelled
Create Release / trigger-pypi (push) Has been cancelled
Create Release / monitor-pypi (push) Has been cancelled
Create Release / Clean up orphan prerelease tags and signatures (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:08:55 +08:00

912 lines
27 KiB
Python

"""
Tests for benchmarks/efficiency/resource_monitor.py
Tests cover:
- ResourceMonitor initialization
- Start/stop monitoring
- Resource data collection
- Summary generation
- Context manager usage
"""
import time
class TestResourceMonitorInit:
"""Tests for ResourceMonitor initialization."""
def test_init_default_params(self):
"""Test initialization with default parameters."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
)
monitor = ResourceMonitor()
assert monitor.sampling_interval == 1.0
assert monitor.track_process is True
assert monitor.track_system is True
assert monitor.monitoring is False
assert monitor.process_data == []
assert monitor.system_data == []
def test_init_custom_params(self):
"""Test initialization with custom parameters."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
)
monitor = ResourceMonitor(
sampling_interval=0.5,
track_process=False,
track_system=True,
)
assert monitor.sampling_interval == 0.5
assert monitor.track_process is False
assert monitor.track_system is True
class TestResourceMonitorStartStop:
"""Tests for start/stop monitoring."""
def test_start_without_psutil(self):
"""Test starting without psutil available."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
)
monitor = ResourceMonitor()
monitor.can_monitor = False
# Should not raise, just log warning
monitor.start()
assert monitor.monitoring is False
def test_start_already_monitoring(self):
"""Test starting when already monitoring."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
)
monitor = ResourceMonitor()
monitor.monitoring = True
# Should not start another thread
monitor.start()
# Should remain monitoring
assert monitor.monitoring is True
def test_stop_not_monitoring(self):
"""Test stopping when not monitoring."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
)
monitor = ResourceMonitor()
# Should not raise
monitor.stop()
assert monitor.monitoring is False
def test_stop_clears_monitoring_flag(self):
"""Test that stop clears the monitoring flag."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
)
monitor = ResourceMonitor()
monitor.monitoring = True
monitor.monitor_thread = None
monitor.stop()
assert monitor.monitoring is False
assert monitor.end_time is not None
class TestResourceMonitorStats:
"""Tests for resource stats generation."""
def test_get_process_stats_no_data(self):
"""Test get_process_stats with no data."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
)
monitor = ResourceMonitor()
stats = monitor.get_process_stats()
assert stats == {}
def test_get_system_stats_no_data(self):
"""Test get_system_stats with no data."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
)
monitor = ResourceMonitor()
stats = monitor.get_system_stats()
assert stats == {}
def test_get_process_stats_with_data(self):
"""Test get_process_stats with process data."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
)
monitor = ResourceMonitor()
monitor.start_time = time.time() - 10
monitor.end_time = time.time()
monitor.process_data = [
{
"timestamp": time.time(),
"cpu_percent": 50.0,
"memory_rss": 100_000_000,
"memory_vms": 200_000_000,
"num_threads": 4,
},
{
"timestamp": time.time(),
"cpu_percent": 60.0,
"memory_rss": 110_000_000,
"memory_vms": 210_000_000,
"num_threads": 5,
},
]
stats = monitor.get_process_stats()
assert stats["sample_count"] == 2
assert stats["cpu_avg"] == 55.0
assert stats["cpu_max"] == 60.0
assert stats["cpu_min"] == 50.0
assert stats["thread_max"] == 5
def test_get_system_stats_with_data(self):
"""Test get_system_stats with system data."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
)
monitor = ResourceMonitor()
monitor.start_time = time.time() - 10
monitor.end_time = time.time()
monitor.system_data = [
{
"timestamp": time.time(),
"cpu_percent": 30.0,
"memory_percent": 50.0,
"disk_percent": 60.0,
"memory_total": 16_000_000_000,
"disk_total": 500_000_000_000,
},
{
"timestamp": time.time(),
"cpu_percent": 40.0,
"memory_percent": 55.0,
"disk_percent": 61.0,
"memory_total": 16_000_000_000,
"disk_total": 500_000_000_000,
},
]
stats = monitor.get_system_stats()
assert stats["sample_count"] == 2
assert stats["cpu_avg"] == 35.0
assert stats["cpu_max"] == 40.0
assert stats["memory_avg_percent"] == 52.5
def test_get_combined_stats(self):
"""Test get_combined_stats returns combined data."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
)
monitor = ResourceMonitor()
monitor.start_time = time.time() - 10
monitor.end_time = time.time()
monitor.process_data = [
{
"timestamp": time.time(),
"cpu_percent": 50.0,
"memory_rss": 100_000_000,
"num_threads": 4,
},
]
monitor.system_data = [
{
"timestamp": time.time(),
"cpu_percent": 30.0,
"memory_percent": 50.0,
"disk_percent": 60.0,
"memory_total": 16_000_000_000,
"disk_total": 500_000_000_000,
},
]
stats = monitor.get_combined_stats()
assert "duration" in stats
assert "process_sample_count" in stats
assert "system_sample_count" in stats
def test_print_summary(self, capsys):
"""Test print_summary outputs correctly."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
)
monitor = ResourceMonitor()
monitor.start_time = time.time() - 10
monitor.end_time = time.time()
monitor.process_data = [
{
"timestamp": time.time(),
"cpu_percent": 50.0,
"memory_rss": 100_000_000,
"num_threads": 4,
},
]
monitor.print_summary()
captured = capsys.readouterr()
assert "RESOURCE USAGE SUMMARY" in captured.out
def test_export_data(self):
"""Test export_data returns all collected data."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
)
monitor = ResourceMonitor()
monitor.start_time = time.time() - 10
monitor.end_time = time.time()
monitor.process_data = [{"test": "data"}]
monitor.system_data = [{"system": "data"}]
data = monitor.export_data()
assert data["start_time"] == monitor.start_time
assert data["end_time"] == monitor.end_time
assert data["sampling_interval"] == monitor.sampling_interval
assert data["process_data"] == monitor.process_data
assert data["system_data"] == monitor.system_data
class TestResourceMonitorContextManager:
"""Tests for context manager functionality."""
def test_context_manager(self):
"""Test using ResourceMonitor as context manager."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
)
monitor = ResourceMonitor()
monitor.can_monitor = False # Disable actual monitoring
with monitor.monitor():
pass
# Should have stopped monitoring
assert monitor.monitoring is False
class TestResourceMonitorThreadSafety:
"""Tests for thread safety."""
def test_multiple_start_calls(self):
"""Test that multiple start calls don't create multiple threads."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
)
monitor = ResourceMonitor()
monitor.can_monitor = False
# Should be safe to call multiple times
monitor.start()
monitor.start()
monitor.start()
# Should not be monitoring (psutil not available)
assert monitor.monitoring is False
class TestPsutilAvailability:
"""Tests for psutil availability handling."""
def test_psutil_available_flag(self):
"""Test that PSUTIL_AVAILABLE flag is set correctly."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
PSUTIL_AVAILABLE,
)
# Should be a boolean
assert isinstance(PSUTIL_AVAILABLE, bool)
def test_monitor_with_psutil_unavailable(self):
"""Test monitoring when psutil is not available."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
)
monitor = ResourceMonitor()
# Simulate psutil not being available
original_can_monitor = monitor.can_monitor
monitor.can_monitor = False
monitor.start()
assert monitor.monitoring is False
# Restore
monitor.can_monitor = original_can_monitor
class TestResourceMonitorDataCollection:
"""Tests for data collection methods."""
def test_process_data_structure(self):
"""Test that process data has expected structure."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
)
monitor = ResourceMonitor()
monitor.process_data = [
{
"timestamp": time.time(),
"cpu_percent": 25.0,
"memory_rss": 50_000_000,
"memory_vms": 100_000_000,
"memory_shared": 10_000_000,
"num_threads": 4,
"open_files": 10,
"status": "running",
}
]
# Check structure
data = monitor.process_data[0]
assert "timestamp" in data
assert "cpu_percent" in data
assert "memory_rss" in data
def test_system_data_structure(self):
"""Test that system data has expected structure."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
)
monitor = ResourceMonitor()
monitor.system_data = [
{
"timestamp": time.time(),
"cpu_percent": 30.0,
"cpu_per_core": [25.0, 35.0],
"memory_total": 16_000_000_000,
"memory_used": 8_000_000_000,
"memory_percent": 50.0,
}
]
data = monitor.system_data[0]
assert "timestamp" in data
assert "cpu_percent" in data
class TestResourceMonitorDuration:
"""Tests for duration tracking."""
def test_duration_calculation(self):
"""Test that duration is calculated correctly."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
)
monitor = ResourceMonitor()
start = time.time() - 5.0
end = time.time()
monitor.start_time = start
monitor.end_time = end
monitor.process_data = [
{
"timestamp": start,
"cpu_percent": 50.0,
"memory_rss": 100_000_000,
"num_threads": 4,
},
]
stats = monitor.get_process_stats()
assert 4.9 < stats["duration"] < 5.1 # Allow for small variance
class TestResourceMonitorSamplingInterval:
"""Tests for sampling interval configuration."""
def test_default_sampling_interval(self):
"""Test default sampling interval is 1.0 seconds."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
)
monitor = ResourceMonitor()
assert monitor.sampling_interval == 1.0
def test_custom_sampling_interval(self):
"""Test custom sampling interval is stored correctly."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
)
monitor = ResourceMonitor(sampling_interval=0.25)
assert monitor.sampling_interval == 0.25
def test_very_small_sampling_interval(self):
"""Test very small sampling interval is accepted."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
)
monitor = ResourceMonitor(sampling_interval=0.01)
assert monitor.sampling_interval == 0.01
class TestResourceMonitorTrackingOptions:
"""Tests for process/system tracking options."""
def test_track_process_only(self):
"""Test tracking only process resources."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
)
monitor = ResourceMonitor(track_process=True, track_system=False)
assert monitor.track_process is True
assert monitor.track_system is False
def test_track_system_only(self):
"""Test tracking only system resources."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
)
monitor = ResourceMonitor(track_process=False, track_system=True)
assert monitor.track_process is False
assert monitor.track_system is True
def test_track_both(self):
"""Test tracking both process and system resources."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
)
monitor = ResourceMonitor(track_process=True, track_system=True)
assert monitor.track_process is True
assert monitor.track_system is True
def test_track_neither(self):
"""Test tracking neither process nor system resources."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
)
monitor = ResourceMonitor(track_process=False, track_system=False)
assert monitor.track_process is False
assert monitor.track_system is False
class TestResourceMonitorMemoryCalculations:
"""Tests for memory calculation logic."""
def test_memory_rss_conversion_to_mb(self):
"""Test that memory RSS is correctly converted to MB."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
)
monitor = ResourceMonitor()
monitor.start_time = time.time() - 10
monitor.end_time = time.time()
# 100 MB in bytes
monitor.process_data = [
{
"timestamp": time.time(),
"cpu_percent": 50.0,
"memory_rss": 104_857_600, # 100 MB in bytes
"num_threads": 4,
},
]
stats = monitor.get_process_stats()
# Should be converted to MB
assert 99 < stats["memory_max_mb"] < 101
def test_memory_stats_min_max_avg(self):
"""Test memory min/max/avg calculations."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
)
monitor = ResourceMonitor()
monitor.start_time = time.time() - 10
monitor.end_time = time.time()
monitor.process_data = [
{
"timestamp": time.time(),
"cpu_percent": 50.0,
"memory_rss": 50_000_000, # ~47.68 MB
"num_threads": 4,
},
{
"timestamp": time.time(),
"cpu_percent": 50.0,
"memory_rss": 100_000_000, # ~95.37 MB
"num_threads": 4,
},
{
"timestamp": time.time(),
"cpu_percent": 50.0,
"memory_rss": 150_000_000, # ~143.05 MB
"num_threads": 4,
},
]
stats = monitor.get_process_stats()
assert (
stats["memory_min_mb"]
< stats["memory_avg_mb"]
< stats["memory_max_mb"]
)
class TestResourceMonitorCPUCalculations:
"""Tests for CPU calculation logic."""
def test_cpu_stats_with_varying_values(self):
"""Test CPU stats with varying values."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
)
monitor = ResourceMonitor()
monitor.start_time = time.time() - 10
monitor.end_time = time.time()
monitor.process_data = [
{
"timestamp": time.time(),
"cpu_percent": 10.0,
"memory_rss": 100_000_000,
"num_threads": 4,
},
{
"timestamp": time.time(),
"cpu_percent": 50.0,
"memory_rss": 100_000_000,
"num_threads": 4,
},
{
"timestamp": time.time(),
"cpu_percent": 90.0,
"memory_rss": 100_000_000,
"num_threads": 4,
},
]
stats = monitor.get_process_stats()
assert stats["cpu_min"] == 10.0
assert stats["cpu_max"] == 90.0
assert stats["cpu_avg"] == 50.0
class TestResourceMonitorSystemStats:
"""Tests for system stats calculations."""
def test_system_disk_stats(self):
"""Test system disk stats calculation."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
)
monitor = ResourceMonitor()
monitor.start_time = time.time() - 10
monitor.end_time = time.time()
monitor.system_data = [
{
"timestamp": time.time(),
"cpu_percent": 30.0,
"memory_percent": 50.0,
"disk_percent": 40.0,
"memory_total": 16_000_000_000,
"disk_total": 500_000_000_000,
},
{
"timestamp": time.time(),
"cpu_percent": 40.0,
"memory_percent": 55.0,
"disk_percent": 60.0,
"memory_total": 16_000_000_000,
"disk_total": 500_000_000_000,
},
]
stats = monitor.get_system_stats()
assert stats["disk_min_percent"] == 40.0
assert stats["disk_max_percent"] == 60.0
assert stats["disk_avg_percent"] == 50.0
def test_system_memory_total_conversion(self):
"""Test that system memory total is converted to GB."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
)
monitor = ResourceMonitor()
monitor.start_time = time.time() - 10
monitor.end_time = time.time()
# 16 GB in bytes
monitor.system_data = [
{
"timestamp": time.time(),
"cpu_percent": 30.0,
"memory_percent": 50.0,
"disk_percent": 40.0,
"memory_total": 17_179_869_184, # 16 GB
"disk_total": 500_000_000_000,
},
]
stats = monitor.get_system_stats()
assert 15.9 < stats["memory_total_gb"] < 16.1
class TestResourceMonitorCombinedStats:
"""Additional tests for combined stats."""
def test_combined_stats_process_memory_percent(self):
"""Test that combined stats calculates process memory percent."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
)
monitor = ResourceMonitor()
monitor.start_time = time.time() - 10
monitor.end_time = time.time()
# Process using 1GB of 16GB system memory
monitor.process_data = [
{
"timestamp": time.time(),
"cpu_percent": 50.0,
"memory_rss": 1_073_741_824, # 1 GB
"num_threads": 4,
},
]
monitor.system_data = [
{
"timestamp": time.time(),
"cpu_percent": 30.0,
"memory_percent": 50.0,
"disk_percent": 40.0,
"memory_total": 17_179_869_184, # 16 GB
"disk_total": 500_000_000_000,
},
]
stats = monitor.get_combined_stats()
# 1 GB / 16 GB = 6.25%
assert "process_memory_percent" in stats
assert 6.0 < stats["process_memory_percent"] < 6.5
def test_combined_stats_includes_duration(self):
"""Test that combined stats includes duration."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
)
monitor = ResourceMonitor()
monitor.start_time = time.time() - 5.0
monitor.end_time = time.time()
stats = monitor.get_combined_stats()
assert "duration" in stats
assert 4.9 < stats["duration"] < 5.1
class TestResourceMonitorExport:
"""Tests for data export functionality."""
def test_export_data_includes_timestamps(self):
"""Test that exported data includes timestamps."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
)
monitor = ResourceMonitor()
monitor.start_time = time.time() - 10
monitor.end_time = time.time()
data = monitor.export_data()
assert "start_time" in data
assert "end_time" in data
assert data["start_time"] is not None
assert data["end_time"] is not None
def test_export_data_includes_sampling_interval(self):
"""Test that exported data includes sampling interval."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
)
monitor = ResourceMonitor(sampling_interval=0.5)
data = monitor.export_data()
assert data["sampling_interval"] == 0.5
def test_export_data_includes_empty_lists_when_no_data(self):
"""Test that export returns empty lists when no data collected."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
)
monitor = ResourceMonitor()
data = monitor.export_data()
assert data["process_data"] == []
assert data["system_data"] == []
class TestResourceMonitorEdgeCases:
"""Edge case tests for ResourceMonitor."""
def test_stats_with_single_sample(self):
"""Test stats calculation with single sample."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
)
monitor = ResourceMonitor()
monitor.start_time = time.time() - 1
monitor.end_time = time.time()
monitor.process_data = [
{
"timestamp": time.time(),
"cpu_percent": 50.0,
"memory_rss": 100_000_000,
"num_threads": 4,
},
]
stats = monitor.get_process_stats()
# With single sample, min == max == avg
assert stats["cpu_min"] == stats["cpu_max"] == stats["cpu_avg"]
def test_duration_none_when_end_time_not_set(self):
"""Test that duration is None when end_time not set."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
)
monitor = ResourceMonitor()
monitor.start_time = time.time()
monitor.end_time = None
monitor.process_data = [
{
"timestamp": time.time(),
"cpu_percent": 50.0,
"memory_rss": 100_000_000,
"num_threads": 4,
},
]
stats = monitor.get_process_stats()
assert stats["duration"] is None
def test_thread_max_tracking(self):
"""Test that max thread count is tracked correctly."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
)
monitor = ResourceMonitor()
monitor.start_time = time.time() - 10
monitor.end_time = time.time()
monitor.process_data = [
{
"timestamp": time.time(),
"cpu_percent": 50.0,
"memory_rss": 100_000_000,
"num_threads": 4,
},
{
"timestamp": time.time(),
"cpu_percent": 50.0,
"memory_rss": 100_000_000,
"num_threads": 8,
},
{
"timestamp": time.time(),
"cpu_percent": 50.0,
"memory_rss": 100_000_000,
"num_threads": 6,
},
]
stats = monitor.get_process_stats()
assert stats["thread_max"] == 8
def test_print_summary_with_empty_data(self, capsys):
"""Test print_summary handles empty data gracefully."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
)
monitor = ResourceMonitor()
# Should not raise
monitor.print_summary()
captured = capsys.readouterr()
assert "RESOURCE USAGE SUMMARY" in captured.out
class TestResourceMonitorCanMonitorFlag:
"""Tests for can_monitor flag behavior."""
def test_can_monitor_matches_psutil_available(self):
"""Test that can_monitor matches PSUTIL_AVAILABLE."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
PSUTIL_AVAILABLE,
)
monitor = ResourceMonitor()
assert monitor.can_monitor == PSUTIL_AVAILABLE
def test_start_does_nothing_when_cannot_monitor(self):
"""Test that start does nothing when can_monitor is False."""
from local_deep_research.benchmarks.efficiency.resource_monitor import (
ResourceMonitor,
)
monitor = ResourceMonitor()
monitor.can_monitor = False
monitor.start()
assert monitor.monitoring is False
assert monitor.start_time is None